diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index cf3a84baa3..400db26dc5 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -10,3 +10,8 @@ # Date: Fri Sep 16 00:53:24 2022 +0100 # Renormalise line endings 84f8a6848a8b05502d7618ca7af8cca74f2c3bae + +# Author: clang-format-bot +# Date: 9/22/2022 9:26:05 PM +# Apply clang-format to code base +ddb0522bbf2aa8aa7c9e139ff7395fb8ed6a841f diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b381d6cb5e..8bd6c60fd5 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -123,12 +123,12 @@ Ubuntu_GCC: Clang_Format: extends: .Ubuntu_Image stage: checks - # TODO: Remove this once the entire project is formatted. - allow_failure: true cache: key: Ubuntu_Clang_Format.ubuntu_22.04.v1 paths: - apt-cache/ + variables: + CLANG_FORMAT: clang-format-14 before_script: - CI/install_debian_deps.sh openmw-clang-format script: diff --git a/CI/check_clang_format.sh b/CI/check_clang_format.sh index 9ae45d48af..109849a98a 100755 --- a/CI/check_clang_format.sh +++ b/CI/check_clang_format.sh @@ -1,23 +1,25 @@ #!/bin/bash -CLANG_FORMAT="clang-format-14" +CLANG_FORMAT="${CLANG_FORMAT:-clang-format}" HAS_DIFFS=0 +check_format_file() { + local item=$1 + "$CLANG_FORMAT" --dry-run -Werror "$item" &>/dev/null + if [[ $? = 1 ]]; then + "${CLANG_FORMAT}" "${item}" | git diff --color=always --no-index "${item}" - + HAS_DIFFS=1 + fi +} + check_format() { local path=$1 - local tempfile=$(mktemp) - for item in $(find $path -type f -name "*"); + find "$path" -type f -name "*" | while read item; do if [[ "$item" =~ .*\.(cpp|hpp|h) ]]; then - echo "Checking code formatting on $item" - $CLANG_FORMAT $item > $tempfile - git diff --color=always --no-index $item $tempfile - if [[ $? = 1 ]]; then - HAS_DIFFS=1 - fi + check_format_file "$item" fi; done; - rm -f $tempfile } check_format "./apps" diff --git a/apps/benchmarks/detournavigator/navmeshtilescache.cpp b/apps/benchmarks/detournavigator/navmeshtilescache.cpp index 79726955c9..f1d024a25f 100644 --- a/apps/benchmarks/detournavigator/navmeshtilescache.cpp +++ b/apps/benchmarks/detournavigator/navmeshtilescache.cpp @@ -56,11 +56,16 @@ namespace { switch (index) { - case 0: return AreaType_null; - case 1: return AreaType_water; - case 2: return AreaType_door; - case 3: return AreaType_pathgrid; - case 4: return AreaType_ground; + case 0: + return AreaType_null; + case 1: + return AreaType_water; + case 2: + return AreaType_door; + case 3: + return AreaType_pathgrid; + case 4: + return AreaType_ground; } return AreaType_null; } @@ -83,7 +88,7 @@ namespace { std::uniform_real_distribution distribution(0.0, 1.0); std::generate_n(out, count, [&] { - return CellWater {generateVec2i(1000, random), Water {ESM::Land::REAL_SIZE, distribution(random)}}; + return CellWater{ generateVec2i(1000, random), Water{ ESM::Land::REAL_SIZE, distribution(random) } }; }); } @@ -97,7 +102,8 @@ namespace if (distribution(random) < 0.939) { generateVertices(std::back_inserter(vertices), triangles * 2.467, random); - generateIndices(std::back_inserter(indices), static_cast(vertices.size() / 3) - 1, vertices.size() * 1.279, random); + generateIndices(std::back_inserter(indices), static_cast(vertices.size() / 3) - 1, + vertices.size() * 1.279, random); generateAreaTypes(std::back_inserter(areaTypes), indices.size() / 3, random); } return Mesh(std::move(indices), std::move(vertices), std::move(areaTypes)); @@ -113,10 +119,8 @@ namespace result.mMinHeight = distribution(random); result.mMaxHeight = result.mMinHeight + 1.0; result.mLength = static_cast(ESM::Land::LAND_SIZE); - std::generate_n(std::back_inserter(result.mHeights), ESM::Land::LAND_NUM_VERTS, [&] - { - return distribution(random); - }); + std::generate_n( + std::back_inserter(result.mHeights), ESM::Land::LAND_NUM_VERTS, [&] { return distribution(random); }); result.mOriginalSize = ESM::Land::LAND_SIZE; result.mMinX = 0; result.mMinY = 0; @@ -140,16 +144,16 @@ namespace const CollisionShapeType agentShapeType = CollisionShapeType::Aabb; const osg::Vec3f agentHalfExtents = generateAgentHalfExtents(0.5, 1.5, random); const TilePosition tilePosition = generateVec2i(10000, random); - const Version version { + const Version version{ .mGeneration = std::uniform_int_distribution(0, 100)(random), .mRevision = std::uniform_int_distribution(0, 10000)(random), }; Mesh mesh = generateMesh(triangles, random); std::vector water; generateWater(std::back_inserter(water), 1, random); - RecastMesh recastMesh(version, std::move(mesh), std::move(water), - {generateHeightfield(random)}, {generateFlatHeightfield(random)}, {}); - return Key {AgentBounds {agentShapeType, agentHalfExtents}, tilePosition, std::move(recastMesh)}; + RecastMesh recastMesh(version, std::move(mesh), std::move(water), { generateHeightfield(random) }, + { generateFlatHeightfield(random) }, {}); + return Key{ AgentBounds{ agentShapeType, agentHalfExtents }, tilePosition, std::move(recastMesh) }; } constexpr std::size_t trianglesPerTile = 239; @@ -168,8 +172,7 @@ namespace while (true) { Key key = generateKey(trianglesPerTile, random); - cache.set(key.mAgentBounds, key.mTilePosition, key.mRecastMesh, - std::make_unique()); + cache.set(key.mAgentBounds, key.mTilePosition, key.mRecastMesh, std::make_unique()); *out++ = std::move(key); const std::size_t newSize = cache.getStats().mNavMeshCacheSize; if (size >= newSize) @@ -250,8 +253,8 @@ namespace while (state.KeepRunning()) { const auto& key = keys[n++ % keys.size()]; - const auto result = cache.set(key.mAgentBounds, key.mTilePosition, key.mRecastMesh, - std::make_unique()); + const auto result = cache.set( + key.mAgentBounds, key.mTilePosition, key.mRecastMesh, std::make_unique()); benchmark::DoNotOptimize(result); } } diff --git a/apps/bsatool/bsatool.cpp b/apps/bsatool/bsatool.cpp index d17a81c4f2..d2189a96e0 100644 --- a/apps/bsatool/bsatool.cpp +++ b/apps/bsatool/bsatool.cpp @@ -1,15 +1,15 @@ #include #include -#include #include +#include #include #include #include -#include #include #include +#include #include #define BSATOOL_VERSION 1.1 @@ -29,7 +29,7 @@ struct Arguments bool fullpath; }; -bool parseOptions (int argc, char** argv, Arguments &info) +bool parseOptions(int argc, char** argv, Arguments& info) { bpo::options_description desc(R"(Inspect and extract files from Bethesda BSA archives @@ -61,7 +61,7 @@ Allowed options)"); auto addHiddenOption = hidden.add_options(); addHiddenOption("mode,m", bpo::value(), "bsatool mode"); - addHiddenOption("input-file,i", bpo::value< Files::MaybeQuotedPathContainer >(), "input file"); + addHiddenOption("input-file,i", bpo::value(), "input file"); bpo::positional_options_description p; p.add("mode", 1).add("input-file", 3); @@ -73,53 +73,50 @@ Allowed options)"); bpo::variables_map variables; try { - bpo::parsed_options valid_opts = bpo::command_line_parser(argc, argv) - .options(all).positional(p).run(); + bpo::parsed_options valid_opts = bpo::command_line_parser(argc, argv).options(all).positional(p).run(); bpo::store(valid_opts, variables); } - catch(std::exception &e) + catch (std::exception& e) { - std::cout << "ERROR parsing arguments: " << e.what() << "\n\n" - << desc << std::endl; + std::cout << "ERROR parsing arguments: " << e.what() << "\n\n" << desc << std::endl; return false; } bpo::notify(variables); - if (variables.count ("help")) + if (variables.count("help")) { std::cout << desc << std::endl; return false; } - if (variables.count ("version")) + if (variables.count("version")) { std::cout << "BSATool version " << BSATOOL_VERSION << std::endl; return false; } if (!variables.count("mode")) { - std::cout << "ERROR: no mode specified!\n\n" - << desc << std::endl; + std::cout << "ERROR: no mode specified!\n\n" << desc << std::endl; return false; } info.mode = variables["mode"].as(); - if (!(info.mode == "list" || info.mode == "extract" || info.mode == "extractall" || info.mode == "add" || info.mode == "create")) + if (!(info.mode == "list" || info.mode == "extract" || info.mode == "extractall" || info.mode == "add" + || info.mode == "create")) { - std::cout << std::endl << "ERROR: invalid mode \"" << info.mode << "\"\n\n" - << desc << std::endl; + std::cout << std::endl << "ERROR: invalid mode \"" << info.mode << "\"\n\n" << desc << std::endl; return false; } if (!variables.count("input-file")) { - std::cout << "\nERROR: missing BSA archive\n\n" - << desc << std::endl; + std::cout << "\nERROR: missing BSA archive\n\n" << desc << std::endl; return false; } - auto inputFiles = variables["input-file"].as< Files::MaybeQuotedPathContainer >(); + auto inputFiles = variables["input-file"].as(); - info.filename = inputFiles[0].u8string(); // This call to u8string is redundant, but required to build on MSVC 14.26 due to implementation bugs. + info.filename = inputFiles[0].u8string(); // This call to u8string is redundant, but required to build on MSVC 14.26 + // due to implementation bugs. // Default output to the working directory info.outdir = std::filesystem::current_path(); @@ -128,28 +125,30 @@ Allowed options)"); { if (inputFiles.size() < 2) { - std::cout << "\nERROR: file to extract unspecified\n\n" - << desc << std::endl; + std::cout << "\nERROR: file to extract unspecified\n\n" << desc << std::endl; return false; } if (inputFiles.size() > 1) - info.extractfile = inputFiles[1].u8string(); // This call to u8string is redundant, but required to build on MSVC 14.26 due to implementation bugs. + info.extractfile = inputFiles[1].u8string(); // This call to u8string is redundant, but required to build on + // MSVC 14.26 due to implementation bugs. if (inputFiles.size() > 2) - info.outdir = inputFiles[2].u8string(); // This call to u8string is redundant, but required to build on MSVC 14.26 due to implementation bugs. + info.outdir = inputFiles[2].u8string(); // This call to u8string is redundant, but required to build on + // MSVC 14.26 due to implementation bugs. } else if (info.mode == "add") { if (inputFiles.empty()) { - std::cout << "\nERROR: file to add unspecified\n\n" - << desc << std::endl; + std::cout << "\nERROR: file to add unspecified\n\n" << desc << std::endl; return false; } if (inputFiles.size() > 1) - info.addfile = inputFiles[1].u8string(); // This call to u8string is redundant, but required to build on MSVC 14.26 due to implementation bugs. + info.addfile = inputFiles[1].u8string(); // This call to u8string is redundant, but required to build on + // MSVC 14.26 due to implementation bugs. } else if (inputFiles.size() > 1) - info.outdir = inputFiles[1].u8string(); // This call to u8string is redundant, but required to build on MSVC 14.26 due to implementation bugs. + info.outdir = inputFiles[1].u8string(); // This call to u8string is redundant, but required to build on + // MSVC 14.26 due to implementation bugs. info.longformat = variables.count("long") != 0; info.fullpath = variables.count("full-path") != 0; @@ -157,14 +156,14 @@ Allowed options)"); return true; } -template +template int list(std::unique_ptr& bsa, Arguments& info) { // List all files - const auto &files = bsa->getList(); + const auto& files = bsa->getList(); for (const auto& file : files) { - if(info.longformat) + if (info.longformat) { // Long format std::ios::fmtflags f(std::cout.flags()); @@ -180,7 +179,7 @@ int list(std::unique_ptr& bsa, Arguments& info) return 0; } -template +template int extract(std::unique_ptr& bsa, Arguments& info) { auto archivePath = info.extractfile.u8string(); @@ -207,7 +206,7 @@ int extract(std::unique_ptr& bsa, Arguments& info) } // Get the target path (the path the file will be extracted to) - std::filesystem::path relPath (extractPath); + std::filesystem::path relPath(extractPath); std::filesystem::path target; if (info.fullpath) @@ -221,14 +220,16 @@ int extract(std::unique_ptr& bsa, Arguments& info) std::filesystem::file_status s = std::filesystem::status(target.parent_path()); if (!std::filesystem::is_directory(s)) { - std::cout << "ERROR: " << Files::pathToUnicodeString(target.parent_path()) << " is not a directory." << std::endl; + std::cout << "ERROR: " << Files::pathToUnicodeString(target.parent_path()) << " is not a directory." + << std::endl; return 3; } std::ofstream out(target, std::ios::binary); // Write the file to disk - std::cout << "Extracting " << Files::pathToUnicodeString(info.extractfile) << " to " << Files::pathToUnicodeString(target) << std::endl; + std::cout << "Extracting " << Files::pathToUnicodeString(info.extractfile) << " to " + << Files::pathToUnicodeString(target) << std::endl; out << stream->rdbuf(); out.close(); @@ -236,10 +237,10 @@ int extract(std::unique_ptr& bsa, Arguments& info) return 0; } -template +template int extractAll(std::unique_ptr& bsa, Arguments& info) { - for (const auto &file : bsa->getList()) + for (const auto& file : bsa->getList()) { std::string extractPath(file.name()); Misc::StringUtils::replaceAll(extractPath, "\\", "/"); @@ -271,7 +272,7 @@ int extractAll(std::unique_ptr& bsa, Arguments& info) return 0; } -template +template int add(std::unique_ptr& bsa, Arguments& info) { std::fstream stream(info.addfile, std::ios_base::binary | std::ios_base::out | std::ios_base::in); @@ -280,7 +281,7 @@ int add(std::unique_ptr& bsa, Arguments& info) return 0; } -template +template int call(Arguments& info) { std::unique_ptr bsa = std::make_unique(); diff --git a/apps/bulletobjecttool/main.cpp b/apps/bulletobjecttool/main.cpp index a274fd9209..4169ef271a 100644 --- a/apps/bulletobjecttool/main.cpp +++ b/apps/bulletobjecttool/main.cpp @@ -1,11 +1,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -15,8 +17,6 @@ #include #include #include -#include -#include #include @@ -27,7 +27,6 @@ #include #include - namespace { namespace bpo = boost::program_options; @@ -44,33 +43,41 @@ namespace addOption("version", "print version information and quit"); - addOption("data", bpo::value()->default_value(Files::MaybeQuotedPathContainer(), "data") - ->multitoken()->composing(), "set data directories (later directories have higher priority)"); - - addOption("data-local", bpo::value()->default_value(Files::MaybeQuotedPathContainer::value_type(), ""), - "set local data directory (highest priority)"); - - addOption("fallback-archive", bpo::value()->default_value(StringsVector(), "fallback-archive") - ->multitoken()->composing(), "set fallback BSA archives (later archives have higher priority)"); - - addOption("resources", bpo::value()->default_value(Files::MaybeQuotedPath(), "resources"), - "set resources directory"); - - addOption("content", bpo::value()->default_value(StringsVector(), "") - ->multitoken()->composing(), "content file(s): esm/esp, or omwgame/omwaddon/omwscripts"); - - addOption("fs-strict", bpo::value()->implicit_value(true) - ->default_value(false), "strict file system handling (no case folding)"); - - addOption("encoding", bpo::value()-> - default_value("win1252"), - "Character encoding used in OpenMW game messages:\n" - "\n\twin1250 - Central and Eastern European such as Polish, Czech, Slovak, Hungarian, Slovene, Bosnian, Croatian, Serbian (Latin script), Romanian and Albanian languages\n" - "\n\twin1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages\n" - "\n\twin1252 - Western European (Latin) alphabet, used by default"); - - addOption("fallback", bpo::value()->default_value(FallbackMap(), "") - ->multitoken()->composing(), "fallback values"); + addOption("data", + bpo::value() + ->default_value(Files::MaybeQuotedPathContainer(), "data") + ->multitoken() + ->composing(), + "set data directories (later directories have higher priority)"); + + addOption("data-local", + bpo::value()->default_value( + Files::MaybeQuotedPathContainer::value_type(), ""), + "set local data directory (highest priority)"); + + addOption("fallback-archive", + bpo::value()->default_value(StringsVector(), "fallback-archive")->multitoken()->composing(), + "set fallback BSA archives (later archives have higher priority)"); + + addOption("resources", + bpo::value()->default_value(Files::MaybeQuotedPath(), "resources"), + "set resources directory"); + + addOption("content", bpo::value()->default_value(StringsVector(), "")->multitoken()->composing(), + "content file(s): esm/esp, or omwgame/omwaddon/omwscripts"); + + addOption("fs-strict", bpo::value()->implicit_value(true)->default_value(false), + "strict file system handling (no case folding)"); + + addOption("encoding", bpo::value()->default_value("win1252"), + "Character encoding used in OpenMW game messages:\n" + "\n\twin1250 - Central and Eastern European such as Polish, Czech, Slovak, Hungarian, Slovene, Bosnian, " + "Croatian, Serbian (Latin script), Romanian and Albanian languages\n" + "\n\twin1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages\n" + "\n\twin1252 - Western European (Latin) alphabet, used by default"); + + addOption("fallback", bpo::value()->default_value(FallbackMap(), "")->multitoken()->composing(), + "fallback values"); ; Files::ConfigurationManager::addCommonOptions(result); @@ -81,7 +88,7 @@ namespace { const float (&mValue)[3]; - friend std::ostream& operator <<(std::ostream& stream, const WriteArray& value) + friend std::ostream& operator<<(std::ostream& stream, const WriteArray& value) { for (std::size_t i = 0; i < 2; ++i) stream << std::setprecision(std::numeric_limits::max_exponent10) << value.mValue[i] << ", "; @@ -104,14 +111,13 @@ namespace return buffer; } - int runBulletObjectTool(int argc, char *argv[]) + int runBulletObjectTool(int argc, char* argv[]) { Platform::init(); bpo::options_description desc = makeOptionsDescription(); - bpo::parsed_options options = bpo::command_line_parser(argc, argv) - .options(desc).allow_unregistered().run(); + bpo::parsed_options options = bpo::command_line_parser(argc, argv).options(desc).allow_unregistered().run(); bpo::variables_map variables; bpo::store(options, variables); @@ -168,25 +174,28 @@ namespace query.mLoadGameSettings = true; query.mLoadLands = true; query.mLoadStatics = true; - const EsmLoader::EsmData esmData = EsmLoader::loadEsmData(query, contentFiles, fileCollections, readers, &encoder); + const EsmLoader::EsmData esmData + = EsmLoader::loadEsmData(query, contentFiles, fileCollections, readers, &encoder); Resource::ImageManager imageManager(&vfs); Resource::NifFileManager nifFileManager(&vfs); Resource::SceneManager sceneManager(&vfs, &imageManager, &nifFileManager); Resource::BulletShapeManager bulletShapeManager(&vfs, &sceneManager, &nifFileManager); - Resource::forEachBulletObject(readers, vfs, bulletShapeManager, esmData, - [] (const ESM::Cell& cell, const Resource::BulletObject& object) - { + Resource::forEachBulletObject( + readers, vfs, bulletShapeManager, esmData, [](const ESM::Cell& cell, const Resource::BulletObject& object) { Log(Debug::Verbose) << "Found bullet object in " << (cell.isExterior() ? "exterior" : "interior") - << " cell \"" << cell.getDescription() << "\":" - << " fileName=\"" << object.mShape->mFileName << '"' - << " fileHash=" << toHex(object.mShape->mFileHash) - << " collisionShape=" << std::boolalpha << (object.mShape->mCollisionShape == nullptr) - << " avoidCollisionShape=" << std::boolalpha << (object.mShape->mAvoidCollisionShape == nullptr) - << " position=(" << WriteArray {object.mPosition.pos} << ')' - << " rotation=(" << WriteArray {object.mPosition.rot} << ')' - << " scale=" << std::setprecision(std::numeric_limits::max_exponent10) << object.mScale; + << " cell \"" << cell.getDescription() << "\":" + << " fileName=\"" << object.mShape->mFileName << '"' + << " fileHash=" << toHex(object.mShape->mFileHash) + << " collisionShape=" << std::boolalpha + << (object.mShape->mCollisionShape == nullptr) + << " avoidCollisionShape=" << std::boolalpha + << (object.mShape->mAvoidCollisionShape == nullptr) << " position=(" + << WriteArray{ object.mPosition.pos } << ')' << " rotation=(" + << WriteArray{ object.mPosition.rot } << ')' + << " scale=" << std::setprecision(std::numeric_limits::max_exponent10) + << object.mScale; }); Log(Debug::Info) << "Done"; @@ -195,7 +204,7 @@ namespace } } -int main(int argc, char *argv[]) +int main(int argc, char* argv[]) { return wrapApplication(runBulletObjectTool, argc, argv, "BulletObjectTool"); } diff --git a/apps/esmtool/arguments.hpp b/apps/esmtool/arguments.hpp index bc5795942f..296b697089 100644 --- a/apps/esmtool/arguments.hpp +++ b/apps/esmtool/arguments.hpp @@ -1,9 +1,9 @@ #ifndef OPENMW_ESMTOOL_ARGUMENTS_H #define OPENMW_ESMTOOL_ARGUMENTS_H -#include -#include #include +#include +#include #include diff --git a/apps/esmtool/esmtool.cpp b/apps/esmtool/esmtool.cpp index f2c12869f4..f20a9f287b 100644 --- a/apps/esmtool/esmtool.cpp +++ b/apps/esmtool/esmtool.cpp @@ -1,54 +1,53 @@ -#include -#include +#include #include +#include +#include +#include #include -#include #include -#include -#include #include #include -#include +#include +#include #include +#include #include #include -#include -#include -#include #include #include +#include +#include -#include "record.hpp" -#include "labels.hpp" #include "arguments.hpp" +#include "labels.hpp" +#include "record.hpp" #include "tes4.hpp" namespace { -using namespace EsmTool; - -constexpr unsigned majorVersion = 1; -constexpr unsigned minorVersion = 3; + using namespace EsmTool; -// Create a local alias for brevity -namespace bpo = boost::program_options; + constexpr unsigned majorVersion = 1; + constexpr unsigned minorVersion = 3; -struct ESMData -{ - ESM::Header mHeader; - std::deque> mRecords; - // Value: (Reference, Deleted flag) - std::map > > mCellRefs; - std::map mRecordStats; - -}; + // Create a local alias for brevity + namespace bpo = boost::program_options; -bool parseOptions (int argc, char** argv, Arguments &info) -{ - bpo::options_description desc(R"(Inspect and extract from Morrowind ES files (ESM, ESP, ESS) + struct ESMData + { + ESM::Header mHeader; + std::deque> mRecords; + // Value: (Reference, Deleted flag) + std::map>> mCellRefs; + std::map mRecordStats; + }; + + bool parseOptions(int argc, char** argv, Arguments& info) + { + bpo::options_description desc(R"(Inspect and extract from Morrowind ES files (ESM, ESP, ESS) Syntax: esmtool [options] mode infile [outfile] Allowed modes: dump Dumps all readable data from the input file. @@ -56,148 +55,148 @@ Allowed modes: comp Compares the given files. Allowed options)"); - auto addOption = desc.add_options(); - addOption("help,h", "print help message."); - addOption("version,v", "print version information and quit."); - addOption("raw,r", bpo::value(), - "Show an unformatted list of all records and subrecords of given format:\n" - "\n\tTES3" - "\n\tTES4"); + auto addOption = desc.add_options(); + addOption("help,h", "print help message."); + addOption("version,v", "print version information and quit."); + addOption("raw,r", bpo::value(), + "Show an unformatted list of all records and subrecords of given format:\n" + "\n\tTES3" + "\n\tTES4"); // The intention is that this option would interact better // with other modes including clone, dump, and raw. - addOption("type,t", bpo::value< std::vector >(), - "Show only records of this type (four character record code). May " - "be specified multiple times. Only affects dump mode."); - addOption("name,n", bpo::value(), - "Show only the record with this name. Only affects dump mode."); - addOption("plain,p", "Print contents of dialogs, books and scripts. " - "(skipped by default)" - "Only affects dump mode."); - addOption("quiet,q", "Suppress all record information. Useful for speed tests."); - addOption("loadcells,C", "Browse through contents of all cells."); - - addOption( "encoding,e", bpo::value(&(info.encoding))-> - default_value("win1252"), - "Character encoding used in ESMTool:\n" - "\n\twin1250 - Central and Eastern European such as Polish, Czech, Slovak, Hungarian, Slovene, Bosnian, Croatian, Serbian (Latin script), Romanian and Albanian languages\n" - "\n\twin1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages\n" - "\n\twin1252 - Western European (Latin) alphabet, used by default") - ; - - std::string finalText = "\nIf no option is given, the default action is to parse all records in the archive\nand display diagnostic information."; - - // input-file is hidden and used as a positional argument - bpo::options_description hidden("Hidden Options"); - auto addHiddenOption = hidden.add_options(); - addHiddenOption( "mode,m", bpo::value(), "esmtool mode"); - addHiddenOption( "input-file,i", bpo::value< Files::MaybeQuotedPathContainer >(), "input file"); - - bpo::positional_options_description p; - p.add("mode", 1).add("input-file", 2); - - // there might be a better way to do this - bpo::options_description all; - all.add(desc).add(hidden); - bpo::variables_map variables; + addOption("type,t", bpo::value>(), + "Show only records of this type (four character record code). May " + "be specified multiple times. Only affects dump mode."); + addOption("name,n", bpo::value(), "Show only the record with this name. Only affects dump mode."); + addOption("plain,p", + "Print contents of dialogs, books and scripts. " + "(skipped by default)" + "Only affects dump mode."); + addOption("quiet,q", "Suppress all record information. Useful for speed tests."); + addOption("loadcells,C", "Browse through contents of all cells."); + + addOption("encoding,e", bpo::value(&(info.encoding))->default_value("win1252"), + "Character encoding used in ESMTool:\n" + "\n\twin1250 - Central and Eastern European such as Polish, Czech, Slovak, Hungarian, Slovene, Bosnian, " + "Croatian, Serbian (Latin script), Romanian and Albanian languages\n" + "\n\twin1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages\n" + "\n\twin1252 - Western European (Latin) alphabet, used by default"); + + std::string finalText + = "\nIf no option is given, the default action is to parse all records in the archive\nand display " + "diagnostic information."; + + // input-file is hidden and used as a positional argument + bpo::options_description hidden("Hidden Options"); + auto addHiddenOption = hidden.add_options(); + addHiddenOption("mode,m", bpo::value(), "esmtool mode"); + addHiddenOption("input-file,i", bpo::value(), "input file"); + + bpo::positional_options_description p; + p.add("mode", 1).add("input-file", 2); + + // there might be a better way to do this + bpo::options_description all; + all.add(desc).add(hidden); + bpo::variables_map variables; + + try + { + bpo::parsed_options valid_opts = bpo::command_line_parser(argc, argv).options(all).positional(p).run(); - try - { - bpo::parsed_options valid_opts = bpo::command_line_parser(argc, argv) - .options(all).positional(p).run(); + bpo::store(valid_opts, variables); + } + catch (std::exception& e) + { + std::cout << "ERROR parsing arguments: " << e.what() << std::endl; + return false; + } - bpo::store(valid_opts, variables); - } - catch(std::exception &e) - { - std::cout << "ERROR parsing arguments: " << e.what() << std::endl; - return false; - } + bpo::notify(variables); - bpo::notify(variables); + if (variables.count("help")) + { + std::cout << desc << finalText << std::endl; + return false; + } + if (variables.count("version")) + { + std::cout << "ESMTool version " << majorVersion << '.' << minorVersion << std::endl; + return false; + } + if (!variables.count("mode")) + { + std::cout << "No mode specified!\n\n" << desc << finalText << std::endl; + return false; + } - if (variables.count ("help")) - { - std::cout << desc << finalText << std::endl; - return false; - } - if (variables.count ("version")) - { - std::cout << "ESMTool version " << majorVersion << '.' << minorVersion << std::endl; - return false; - } - if (!variables.count("mode")) - { - std::cout << "No mode specified!\n\n" - << desc << finalText << std::endl; - return false; - } + if (variables.count("type") > 0) + info.types = variables["type"].as>(); + if (variables.count("name") > 0) + info.name = variables["name"].as(); - if (variables.count("type") > 0) - info.types = variables["type"].as< std::vector >(); - if (variables.count("name") > 0) - info.name = variables["name"].as(); + info.mode = variables["mode"].as(); + if (!(info.mode == "dump" || info.mode == "clone" || info.mode == "comp")) + { + std::cout << "\nERROR: invalid mode \"" << info.mode << "\"\n\n" << desc << finalText << std::endl; + return false; + } - info.mode = variables["mode"].as(); - if (!(info.mode == "dump" || info.mode == "clone" || info.mode == "comp")) - { - std::cout << "\nERROR: invalid mode \"" << info.mode << "\"\n\n" - << desc << finalText << std::endl; - return false; - } + if (!variables.count("input-file")) + { + std::cout << "\nERROR: missing ES file\n\n"; + std::cout << desc << finalText << std::endl; + return false; + } - if ( !variables.count("input-file") ) - { - std::cout << "\nERROR: missing ES file\n\n"; - std::cout << desc << finalText << std::endl; - return false; - } + // handling gracefully the user adding multiple files + /* if (variables["input-file"].as< std::vector >().size() > 1) + { + std::cout << "\nERROR: more than one ES file specified\n\n"; + std::cout << desc << finalText << std::endl; + return false; + }*/ + + const auto inputFiles = variables["input-file"].as(); + info.filename = inputFiles[0].u8string(); // This call to u8string is redundant, but required to build on + // MSVC 14.26 due to implementation bugs. + if (inputFiles.size() > 1) + info.outname = inputFiles[1].u8string(); // This call to u8string is redundant, but required to build on + // MSVC 14.26 due to implementation bugs. + + if (const auto it = variables.find("raw"); it != variables.end()) + info.mRawFormat = ESM::parseFormat(it->second.as()); + + info.quiet_given = variables.count("quiet") != 0; + info.loadcells_given = variables.count("loadcells") != 0; + info.plain_given = variables.count("plain") != 0; + + // Font encoding settings + info.encoding = variables["encoding"].as(); + if (info.encoding != "win1250" && info.encoding != "win1251" && info.encoding != "win1252") + { + std::cout << info.encoding << " is not a valid encoding option.\n"; + info.encoding = "win1252"; + } + std::cout << ToUTF8::encodingUsingMessage(info.encoding) << std::endl; - // handling gracefully the user adding multiple files -/* if (variables["input-file"].as< std::vector >().size() > 1) - { - std::cout << "\nERROR: more than one ES file specified\n\n"; - std::cout << desc << finalText << std::endl; - return false; - }*/ - - const auto inputFiles = variables["input-file"].as< Files::MaybeQuotedPathContainer >(); - info.filename = inputFiles[0].u8string(); // This call to u8string is redundant, but required to build on MSVC 14.26 due to implementation bugs. - if (inputFiles.size() > 1) - info.outname = inputFiles[1].u8string(); // This call to u8string is redundant, but required to build on MSVC 14.26 due to implementation bugs. - - if (const auto it = variables.find("raw"); it != variables.end()) - info.mRawFormat = ESM::parseFormat(it->second.as()); - - info.quiet_given = variables.count ("quiet") != 0; - info.loadcells_given = variables.count ("loadcells") != 0; - info.plain_given = variables.count("plain") != 0; - - // Font encoding settings - info.encoding = variables["encoding"].as(); - if(info.encoding != "win1250" && info.encoding != "win1251" && info.encoding != "win1252") - { - std::cout << info.encoding << " is not a valid encoding option.\n"; - info.encoding = "win1252"; + return true; } - std::cout << ToUTF8::encodingUsingMessage(info.encoding) << std::endl; - - return true; -} -void loadCell(const Arguments& info, ESM::Cell &cell, ESM::ESMReader &esm, ESMData* data); + void loadCell(const Arguments& info, ESM::Cell& cell, ESM::ESMReader& esm, ESMData* data); -int load(const Arguments& info, ESMData* data); -int clone(const Arguments& info); -int comp(const Arguments& info); + int load(const Arguments& info, ESMData* data); + int clone(const Arguments& info); + int comp(const Arguments& info); } -int main(int argc, char**argv) +int main(int argc, char** argv) { try { Arguments info; - if(!parseOptions (argc, argv, info)) + if (!parseOptions(argc, argv, info)) return 1; if (info.mode == "dump") @@ -224,370 +223,379 @@ int main(int argc, char**argv) namespace { -void loadCell(const Arguments& info, ESM::Cell &cell, ESM::ESMReader &esm, ESMData* data) -{ - bool quiet = (info.quiet_given || info.mode == "clone"); - bool save = (info.mode == "clone"); - - // Skip back to the beginning of the reference list - // FIXME: Changes to the references backend required to support multiple plugins have - // almost certainly broken this following line. I'll leave it as is for now, so that - // the compiler does not complain. - cell.restore(esm, 0); - - // Loop through all the references - ESM::CellRef ref; - if(!quiet) std::cout << " References:\n"; - - bool deleted = false; - ESM::MovedCellRef movedCellRef; - bool moved = false; - while(cell.getNextRef(esm, ref, deleted, movedCellRef, moved)) + void loadCell(const Arguments& info, ESM::Cell& cell, ESM::ESMReader& esm, ESMData* data) { - if (data != nullptr && save) - data->mCellRefs[&cell].push_back(std::make_pair(ref, deleted)); - - if(quiet) continue; - - std::cout << " - Refnum: " << ref.mRefNum.mIndex << '\n'; - std::cout << " ID: " << ref.mRefID << '\n'; - std::cout << " Position: (" << ref.mPos.pos[0] << ", " << ref.mPos.pos[1] << ", " << ref.mPos.pos[2] << ")\n"; - if (ref.mScale != 1.f) - std::cout << " Scale: " << ref.mScale << '\n'; - if (!ref.mOwner.empty()) - std::cout << " Owner: " << ref.mOwner << '\n'; - if (!ref.mGlobalVariable.empty()) - std::cout << " Global: " << ref.mGlobalVariable << '\n'; - if (!ref.mFaction.empty()) - std::cout << " Faction: " << ref.mFaction << '\n'; - if (!ref.mFaction.empty() || ref.mFactionRank != -2) - std::cout << " Faction rank: " << ref.mFactionRank << '\n'; - std::cout << " Enchantment charge: " << ref.mEnchantmentCharge << '\n'; - std::cout << " Uses/health: " << ref.mChargeInt << '\n'; - std::cout << " Gold value: " << ref.mGoldValue << '\n'; - std::cout << " Blocked: " << static_cast(ref.mReferenceBlocked) << '\n'; - std::cout << " Deleted: " << deleted << '\n'; - if (!ref.mKey.empty()) - std::cout << " Key: " << ref.mKey << '\n'; - std::cout << " Lock level: " << ref.mLockLevel << '\n'; - if (!ref.mTrap.empty()) - std::cout << " Trap: " << ref.mTrap << '\n'; - if (!ref.mSoul.empty()) - std::cout << " Soul: " << ref.mSoul << '\n'; - if (ref.mTeleport) - { - std::cout << " Destination position: (" << ref.mDoorDest.pos[0] << ", " - << ref.mDoorDest.pos[1] << ", " << ref.mDoorDest.pos[2] << ")\n"; - if (!ref.mDestCell.empty()) - std::cout << " Destination cell: " << ref.mDestCell << '\n'; - } - std::cout << " Moved: " << std::boolalpha << moved << std::noboolalpha << '\n'; - if (moved) + bool quiet = (info.quiet_given || info.mode == "clone"); + bool save = (info.mode == "clone"); + + // Skip back to the beginning of the reference list + // FIXME: Changes to the references backend required to support multiple plugins have + // almost certainly broken this following line. I'll leave it as is for now, so that + // the compiler does not complain. + cell.restore(esm, 0); + + // Loop through all the references + ESM::CellRef ref; + if (!quiet) + std::cout << " References:\n"; + + bool deleted = false; + ESM::MovedCellRef movedCellRef; + bool moved = false; + while (cell.getNextRef(esm, ref, deleted, movedCellRef, moved)) { - std::cout << " Moved refnum: " << movedCellRef.mRefNum.mIndex << '\n'; - std::cout << " Moved content file: " << movedCellRef.mRefNum.mContentFile << '\n'; - std::cout << " Target: " << movedCellRef.mTarget[0] << ", " << movedCellRef.mTarget[1] << '\n'; + if (data != nullptr && save) + data->mCellRefs[&cell].push_back(std::make_pair(ref, deleted)); + + if (quiet) + continue; + + std::cout << " - Refnum: " << ref.mRefNum.mIndex << '\n'; + std::cout << " ID: " << ref.mRefID << '\n'; + std::cout << " Position: (" << ref.mPos.pos[0] << ", " << ref.mPos.pos[1] << ", " << ref.mPos.pos[2] + << ")\n"; + if (ref.mScale != 1.f) + std::cout << " Scale: " << ref.mScale << '\n'; + if (!ref.mOwner.empty()) + std::cout << " Owner: " << ref.mOwner << '\n'; + if (!ref.mGlobalVariable.empty()) + std::cout << " Global: " << ref.mGlobalVariable << '\n'; + if (!ref.mFaction.empty()) + std::cout << " Faction: " << ref.mFaction << '\n'; + if (!ref.mFaction.empty() || ref.mFactionRank != -2) + std::cout << " Faction rank: " << ref.mFactionRank << '\n'; + std::cout << " Enchantment charge: " << ref.mEnchantmentCharge << '\n'; + std::cout << " Uses/health: " << ref.mChargeInt << '\n'; + std::cout << " Gold value: " << ref.mGoldValue << '\n'; + std::cout << " Blocked: " << static_cast(ref.mReferenceBlocked) << '\n'; + std::cout << " Deleted: " << deleted << '\n'; + if (!ref.mKey.empty()) + std::cout << " Key: " << ref.mKey << '\n'; + std::cout << " Lock level: " << ref.mLockLevel << '\n'; + if (!ref.mTrap.empty()) + std::cout << " Trap: " << ref.mTrap << '\n'; + if (!ref.mSoul.empty()) + std::cout << " Soul: " << ref.mSoul << '\n'; + if (ref.mTeleport) + { + std::cout << " Destination position: (" << ref.mDoorDest.pos[0] << ", " << ref.mDoorDest.pos[1] + << ", " << ref.mDoorDest.pos[2] << ")\n"; + if (!ref.mDestCell.empty()) + std::cout << " Destination cell: " << ref.mDestCell << '\n'; + } + std::cout << " Moved: " << std::boolalpha << moved << std::noboolalpha << '\n'; + if (moved) + { + std::cout << " Moved refnum: " << movedCellRef.mRefNum.mIndex << '\n'; + std::cout << " Moved content file: " << movedCellRef.mRefNum.mContentFile << '\n'; + std::cout << " Target: " << movedCellRef.mTarget[0] << ", " << movedCellRef.mTarget[1] << '\n'; + } } } -} -void printRawTes3(const std::filesystem::path &path) -{ - std::cout << "TES3 RAW file listing: " << Files::pathToUnicodeString(path) << '\n'; - ESM::ESMReader esm; - esm.openRaw(path); - while(esm.hasMoreRecs()) + void printRawTes3(const std::filesystem::path& path) { - ESM::NAME n = esm.getRecName(); - std::cout << "Record: " << n.toStringView() << '\n'; - esm.getRecHeader(); - while(esm.hasMoreSubs()) + std::cout << "TES3 RAW file listing: " << Files::pathToUnicodeString(path) << '\n'; + ESM::ESMReader esm; + esm.openRaw(path); + while (esm.hasMoreRecs()) { - size_t offs = esm.getFileOffset(); - esm.getSubName(); - esm.skipHSub(); - n = esm.retSubName(); - std::ios::fmtflags f(std::cout.flags()); - std::cout << " " << n.toStringView() << " - " << esm.getSubSize() - << " bytes @ 0x" << std::hex << offs << '\n'; - std::cout.flags(f); + ESM::NAME n = esm.getRecName(); + std::cout << "Record: " << n.toStringView() << '\n'; + esm.getRecHeader(); + while (esm.hasMoreSubs()) + { + size_t offs = esm.getFileOffset(); + esm.getSubName(); + esm.skipHSub(); + n = esm.retSubName(); + std::ios::fmtflags f(std::cout.flags()); + std::cout << " " << n.toStringView() << " - " << esm.getSubSize() << " bytes @ 0x" << std::hex + << offs << '\n'; + std::cout.flags(f); + } } } -} -int loadTes3(const Arguments& info, std::unique_ptr&& stream, ESMData* data) -{ - std::cout << "Loading TES3 file: " << info.filename << '\n'; + int loadTes3(const Arguments& info, std::unique_ptr&& stream, ESMData* data) + { + std::cout << "Loading TES3 file: " << info.filename << '\n'; - ESM::ESMReader esm; - ToUTF8::Utf8Encoder encoder (ToUTF8::calculateEncoding(info.encoding)); - esm.setEncoder(&encoder); + ESM::ESMReader esm; + ToUTF8::Utf8Encoder encoder(ToUTF8::calculateEncoding(info.encoding)); + esm.setEncoder(&encoder); - std::unordered_set skipped; + std::unordered_set skipped; - try - { - bool quiet = (info.quiet_given || info.mode == "clone"); - bool loadCells = (info.loadcells_given || info.mode == "clone"); - bool save = (info.mode == "clone"); + try + { + bool quiet = (info.quiet_given || info.mode == "clone"); + bool loadCells = (info.loadcells_given || info.mode == "clone"); + bool save = (info.mode == "clone"); - esm.open(std::move(stream), info.filename); + esm.open(std::move(stream), info.filename); - if (data != nullptr) - data->mHeader = esm.getHeader(); + if (data != nullptr) + data->mHeader = esm.getHeader(); - if (!quiet) - { - std::cout << "Author: " << esm.getAuthor() << '\n' - << "Description: " << esm.getDesc() << '\n' - << "File format version: " << esm.getFVer() << '\n'; - std::vector masterData = esm.getGameFiles(); - if (!masterData.empty()) + if (!quiet) { - std::cout << "Masters:" << '\n'; - for(const auto& master : masterData) - std::cout << " " << master.name << ", " << master.size << " bytes\n"; + std::cout << "Author: " << esm.getAuthor() << '\n' + << "Description: " << esm.getDesc() << '\n' + << "File format version: " << esm.getFVer() << '\n'; + std::vector masterData = esm.getGameFiles(); + if (!masterData.empty()) + { + std::cout << "Masters:" << '\n'; + for (const auto& master : masterData) + std::cout << " " << master.name << ", " << master.size << " bytes\n"; + } } - } - - // Loop through all records - while(esm.hasMoreRecs()) - { - const ESM::NAME n = esm.getRecName(); - uint32_t flags; - esm.getRecHeader(flags); - auto record = EsmTool::RecordBase::create(n); - if (record == nullptr) + // Loop through all records + while (esm.hasMoreRecs()) { - if (!quiet && skipped.count(n.toInt()) == 0) + const ESM::NAME n = esm.getRecName(); + uint32_t flags; + esm.getRecHeader(flags); + + auto record = EsmTool::RecordBase::create(n); + if (record == nullptr) { - std::cout << "Skipping " << n.toStringView() << " records.\n"; - skipped.emplace(n.toInt()); + if (!quiet && skipped.count(n.toInt()) == 0) + { + std::cout << "Skipping " << n.toStringView() << " records.\n"; + skipped.emplace(n.toInt()); + } + + esm.skipRecord(); + if (quiet) + break; + std::cout << " Skipping\n"; + + continue; } - esm.skipRecord(); - if (quiet) break; - std::cout << " Skipping\n"; + record->setFlags(static_cast(flags)); + record->setPrintPlain(info.plain_given); + record->load(esm); - continue; - } + // Is the user interested in this record type? + bool interested = true; + if (!info.types.empty() + && std::find(info.types.begin(), info.types.end(), n.toStringView()) == info.types.end()) + interested = false; - record->setFlags(static_cast(flags)); - record->setPrintPlain(info.plain_given); - record->load(esm); + if (!info.name.empty() && !Misc::StringUtils::ciEqual(info.name, record->getId())) + interested = false; - // Is the user interested in this record type? - bool interested = true; - if (!info.types.empty() && std::find(info.types.begin(), info.types.end(), n.toStringView()) == info.types.end()) - interested = false; + if (!quiet && interested) + { + std::cout << "\nRecord: " << n.toStringView() << " '" << record->getId() << "'\n" + << "Record flags: " << recordFlags(record->getFlags()) << '\n'; + record->print(); + } - if (!info.name.empty() && !Misc::StringUtils::ciEqual(info.name, record->getId())) - interested = false; + if (record->getType().toInt() == ESM::REC_CELL && loadCells && interested) + { + loadCell(info, record->cast()->get(), esm, data); + } - if(!quiet && interested) - { - std::cout << "\nRecord: " << n.toStringView() << " '" << record->getId() << "'\n" - << "Record flags: " << recordFlags(record->getFlags()) << '\n'; - record->print(); + if (data != nullptr) + { + if (save) + data->mRecords.push_back(std::move(record)); + ++data->mRecordStats[n.toInt()]; + } } + } + catch (const std::exception& e) + { + std::cout << "\nERROR:\n\n " << e.what() << std::endl; + if (data != nullptr) + data->mRecords.clear(); + return 1; + } - if (record->getType().toInt() == ESM::REC_CELL && loadCells && interested) - { - loadCell(info, record->cast()->get(), esm, data); - } + return 0; + } - if (data != nullptr) + int load(const Arguments& info, ESMData* data) + { + if (info.mRawFormat.has_value() && info.mode == "dump") + { + switch (*info.mRawFormat) { - if (save) - data->mRecords.push_back(std::move(record)); - ++data->mRecordStats[n.toInt()]; + case ESM::Format::Tes3: + printRawTes3(info.filename); + break; + case ESM::Format::Tes4: + std::cout << "Printing raw TES4 file is not supported: " + << Files::pathToUnicodeString(info.filename) << "\n"; + break; } + return 0; } - } - catch (const std::exception &e) - { - std::cout << "\nERROR:\n\n " << e.what() << std::endl; - if (data != nullptr) - data->mRecords.clear(); - return 1; - } - return 0; -} + auto stream = Files::openBinaryInputFileStream(info.filename); + if (!stream->is_open()) + { + std::cout << "Failed to open file: " << std::strerror(errno) << '\n'; + return -1; + } -int load(const Arguments& info, ESMData* data) -{ - if (info.mRawFormat.has_value() && info.mode == "dump") - { - switch (*info.mRawFormat) + const ESM::Format format = ESM::readFormat(*stream); + stream->seekg(0); + + switch (format) { case ESM::Format::Tes3: - printRawTes3(info.filename); - break; + return loadTes3(info, std::move(stream), data); case ESM::Format::Tes4: - std::cout << "Printing raw TES4 file is not supported: " << Files::pathToUnicodeString(info.filename) << "\n"; - break; + if (data != nullptr) + { + std::cout << "Collecting data from esm file is not supported for TES4\n"; + return -1; + } + return loadTes4(info, std::move(stream)); } - return 0; - } - auto stream = Files::openBinaryInputFileStream(info.filename); - if (!stream->is_open()) - { - std::cout << "Failed to open file: " << std::strerror(errno) << '\n'; + std::cout << "Unsupported ESM format: " << ESM::NAME(format).toStringView() << '\n'; + return -1; } - const ESM::Format format = ESM::readFormat(*stream); - stream->seekg(0); - - switch (format) + int clone(const Arguments& info) { - case ESM::Format::Tes3: - return loadTes3(info, std::move(stream), data); - case ESM::Format::Tes4: - if (data != nullptr) - { - std::cout << "Collecting data from esm file is not supported for TES4\n"; - return -1; - } - return loadTes4(info, std::move(stream)); - } - - std::cout << "Unsupported ESM format: " << ESM::NAME(format).toStringView() << '\n'; - - return -1; -} + if (info.outname.empty()) + { + std::cout << "You need to specify an output name" << std::endl; + return 1; + } -int clone(const Arguments& info) -{ - if (info.outname.empty()) - { - std::cout << "You need to specify an output name" << std::endl; - return 1; - } + ESMData data; + if (load(info, &data) != 0) + { + std::cout << "Failed to load, aborting." << std::endl; + return 1; + } - ESMData data; - if (load(info, &data) != 0) - { - std::cout << "Failed to load, aborting." << std::endl; - return 1; - } + size_t recordCount = data.mRecords.size(); - size_t recordCount = data.mRecords.size(); + int digitCount = 1; // For a nicer output + if (recordCount > 0) + digitCount = (int)std::log10(recordCount) + 1; - int digitCount = 1; // For a nicer output - if (recordCount > 0) - digitCount = (int)std::log10(recordCount) + 1; + std::cout << "Loaded " << recordCount << " records:\n\n"; - std::cout << "Loaded " << recordCount << " records:\n\n"; + int i = 0; + for (std::pair stat : data.mRecordStats) + { + ESM::NAME name; + name = stat.first; + int amount = stat.second; + std::cout << std::setw(digitCount) << amount << " " << name.toStringView() << " "; + if (++i % 3 == 0) + std::cout << '\n'; + } - int i = 0; - for (std::pair stat : data.mRecordStats) - { - ESM::NAME name; - name = stat.first; - int amount = stat.second; - std::cout << std::setw(digitCount) << amount << " " << name.toStringView() << " "; - if (++i % 3 == 0) + if (i % 3 != 0) std::cout << '\n'; - } - - if (i % 3 != 0) - std::cout << '\n'; - std::cout << "\nSaving records to: " << Files::pathToUnicodeString(info.outname) << "...\n"; + std::cout << "\nSaving records to: " << Files::pathToUnicodeString(info.outname) << "...\n"; - ESM::ESMWriter esm; - ToUTF8::Utf8Encoder encoder (ToUTF8::calculateEncoding(info.encoding)); - esm.setEncoder(&encoder); - esm.setHeader(data.mHeader); - esm.setVersion(ESM::VER_13); - esm.setRecordCount (recordCount); + ESM::ESMWriter esm; + ToUTF8::Utf8Encoder encoder(ToUTF8::calculateEncoding(info.encoding)); + esm.setEncoder(&encoder); + esm.setHeader(data.mHeader); + esm.setVersion(ESM::VER_13); + esm.setRecordCount(recordCount); - std::fstream save(info.outname, std::fstream::out | std::fstream::binary); - esm.save(save); + std::fstream save(info.outname, std::fstream::out | std::fstream::binary); + esm.save(save); - int saved = 0; - for (auto& record : data.mRecords) - { - if (i <= 0) - break; + int saved = 0; + for (auto& record : data.mRecords) + { + if (i <= 0) + break; - const ESM::NAME typeName = record->getType(); + const ESM::NAME typeName = record->getType(); - esm.startRecord(typeName, record->getFlags()); + esm.startRecord(typeName, record->getFlags()); - record->save(esm); - if (typeName.toInt() == ESM::REC_CELL) { - ESM::Cell *ptr = &record->cast()->get(); - if (!data.mCellRefs[ptr].empty()) + record->save(esm); + if (typeName.toInt() == ESM::REC_CELL) { - for (std::pair &ref : data.mCellRefs[ptr]) - ref.first.save(esm, ref.second); + ESM::Cell* ptr = &record->cast()->get(); + if (!data.mCellRefs[ptr].empty()) + { + for (std::pair& ref : data.mCellRefs[ptr]) + ref.first.save(esm, ref.second); + } } - } - esm.endRecord(typeName); + esm.endRecord(typeName); - saved++; - int perc = recordCount == 0 ? 100 : (int)((saved / (float)recordCount)*100); - if (perc % 10 == 0) - { - std::cerr << "\r" << perc << "%"; + saved++; + int perc = recordCount == 0 ? 100 : (int)((saved / (float)recordCount) * 100); + if (perc % 10 == 0) + { + std::cerr << "\r" << perc << "%"; + } } - } - std::cout << "\rDone!" << std::endl; + std::cout << "\rDone!" << std::endl; - esm.close(); - save.close(); + esm.close(); + save.close(); - return 0; -} + return 0; + } -int comp(const Arguments& info) -{ - if (info.filename.empty() || info.outname.empty()) + int comp(const Arguments& info) { - std::cout << "You need to specify two input files" << std::endl; - return 1; - } + if (info.filename.empty() || info.outname.empty()) + { + std::cout << "You need to specify two input files" << std::endl; + return 1; + } - Arguments fileOne; - Arguments fileTwo; + Arguments fileOne; + Arguments fileTwo; - fileOne.mode = "clone"; - fileTwo.mode = "clone"; + fileOne.mode = "clone"; + fileTwo.mode = "clone"; - fileOne.encoding = info.encoding; - fileTwo.encoding = info.encoding; + fileOne.encoding = info.encoding; + fileTwo.encoding = info.encoding; - fileOne.filename = info.filename; - fileTwo.filename = info.outname; + fileOne.filename = info.filename; + fileTwo.filename = info.outname; - ESMData dataOne; - if (load(fileOne, &dataOne) != 0) - { - std::cout << "Failed to load " << Files::pathToUnicodeString(info.filename) << ", aborting comparison." << std::endl; - return 1; - } + ESMData dataOne; + if (load(fileOne, &dataOne) != 0) + { + std::cout << "Failed to load " << Files::pathToUnicodeString(info.filename) << ", aborting comparison." + << std::endl; + return 1; + } - ESMData dataTwo; - if (load(fileTwo, &dataTwo) != 0) - { - std::cout << "Failed to load " << Files::pathToUnicodeString(info.outname) << ", aborting comparison." << std::endl; - return 1; - } + ESMData dataTwo; + if (load(fileTwo, &dataTwo) != 0) + { + std::cout << "Failed to load " << Files::pathToUnicodeString(info.outname) << ", aborting comparison." + << std::endl; + return 1; + } - if (dataOne.mRecords.size() != dataTwo.mRecords.size()) - { - std::cout << "Not equal, different amount of records." << std::endl; - return 1; - } + if (dataOne.mRecords.size() != dataTwo.mRecords.size()) + { + std::cout << "Not equal, different amount of records." << std::endl; + return 1; + } - return 0; -} + return 0; + } } diff --git a/apps/esmtool/labels.cpp b/apps/esmtool/labels.cpp index 9737511274..d88a608466 100644 --- a/apps/esmtool/labels.cpp +++ b/apps/esmtool/labels.cpp @@ -19,7 +19,7 @@ std::string_view bodyPartLabel(int idx) { if (idx >= 0 && idx <= 26) { - static constexpr std::string_view bodyPartLabels[] = { + static constexpr std::string_view bodyPartLabels[] = { "Head", "Hair", "Neck", @@ -58,7 +58,7 @@ std::string_view meshPartLabel(int idx) { if (idx >= 0 && idx <= ESM::BodyPart::MP_Tail) { - static constexpr std::string_view meshPartLabels[] = { + static constexpr std::string_view meshPartLabels[] = { "Head", "Hair", "Neck", @@ -85,7 +85,7 @@ std::string_view meshTypeLabel(int idx) { if (idx >= 0 && idx <= ESM::BodyPart::MT_Armor) { - static constexpr std::string_view meshTypeLabels[] = { + static constexpr std::string_view meshTypeLabels[] = { "Skin", "Clothing", "Armor", @@ -122,7 +122,7 @@ std::string_view armorTypeLabel(int idx) { if (idx >= 0 && idx <= 10) { - static constexpr std::string_view armorTypeLabels[] = { + static constexpr std::string_view armorTypeLabels[] = { "Helmet", "Cuirass", "Left Pauldron", @@ -243,11 +243,16 @@ std::string_view aiTypeLabel(ESM::AiPackageType type) { switch (type) { - case ESM::AI_Wander: return "Wander"; - case ESM::AI_Travel: return "Travel"; - case ESM::AI_Follow: return "Follow"; - case ESM::AI_Escort: return "Escort"; - case ESM::AI_Activate: return "Activate"; + case ESM::AI_Wander: + return "Wander"; + case ESM::AI_Travel: + return "Travel"; + case ESM::AI_Follow: + return "Follow"; + case ESM::AI_Escort: + return "Escort"; + case ESM::AI_Activate: + return "Activate"; } return "Invalid"; } @@ -256,7 +261,7 @@ std::string_view magicEffectLabel(int idx) { if (idx >= 0 && idx <= 142) { - static constexpr std::string_view magicEffectLabels [] = { + static constexpr std::string_view magicEffectLabels[] = { "Water Breathing", "Swift Swim", "Water Walking", @@ -411,7 +416,7 @@ std::string_view attributeLabel(int idx) { if (idx >= 0 && idx <= 7) { - static constexpr std::string_view attributeLabels [] = { + static constexpr std::string_view attributeLabels[] = { "Strength", "Intelligence", "Willpower", @@ -431,7 +436,7 @@ std::string_view spellTypeLabel(int idx) { if (idx >= 0 && idx <= 5) { - static constexpr std::string_view spellTypeLabels [] = { + static constexpr std::string_view spellTypeLabels[] = { "Spells", "Abilities", "Blight Disease", @@ -449,7 +454,7 @@ std::string_view specializationLabel(int idx) { if (idx >= 0 && idx <= 2) { - static constexpr std::string_view specializationLabels [] = { + static constexpr std::string_view specializationLabels[] = { "Combat", "Magic", "Stealth", @@ -464,7 +469,7 @@ std::string_view skillLabel(int idx) { if (idx >= 0 && idx <= 26) { - static constexpr std::string_view skillLabels [] = { + static constexpr std::string_view skillLabels[] = { "Block", "Armorer", "Medium Armor", @@ -503,7 +508,7 @@ std::string_view apparatusTypeLabel(int idx) { if (idx >= 0 && idx <= 3) { - static constexpr std::string_view apparatusTypeLabels [] = { + static constexpr std::string_view apparatusTypeLabels[] = { "Mortar", "Alembic", "Calcinator", @@ -519,7 +524,7 @@ std::string_view rangeTypeLabel(int idx) { if (idx >= 0 && idx <= 2) { - static constexpr std::string_view rangeTypeLabels [] = { + static constexpr std::string_view rangeTypeLabels[] = { "Self", "Touch", "Target", @@ -534,7 +539,7 @@ std::string_view schoolLabel(int idx) { if (idx >= 0 && idx <= 5) { - static constexpr std::string_view schoolLabels [] = { + static constexpr std::string_view schoolLabels[] = { "Alteration", "Conjuration", "Destruction", @@ -552,7 +557,7 @@ std::string_view enchantTypeLabel(int idx) { if (idx >= 0 && idx <= 3) { - static constexpr std::string_view enchantTypeLabels [] = { + static constexpr std::string_view enchantTypeLabels[] = { "Cast Once", "Cast When Strikes", "Cast When Used", @@ -656,13 +661,15 @@ std::string_view ruleFunction(int idx) std::string bodyPartFlags(int flags) { std::string properties; - if (flags == 0) properties += "[None] "; - if (flags & ESM::BodyPart::BPF_Female) properties += "Female "; - if (flags & ESM::BodyPart::BPF_NotPlayable) properties += "NotPlayable "; - int unused = (0xFFFFFFFF ^ - (ESM::BodyPart::BPF_Female| - ESM::BodyPart::BPF_NotPlayable)); - if (flags & unused) properties += "Invalid "; + if (flags == 0) + properties += "[None] "; + if (flags & ESM::BodyPart::BPF_Female) + properties += "Female "; + if (flags & ESM::BodyPart::BPF_NotPlayable) + properties += "NotPlayable "; + int unused = (0xFFFFFFFF ^ (ESM::BodyPart::BPF_Female | ESM::BodyPart::BPF_NotPlayable)); + if (flags & unused) + properties += "Invalid "; properties += Misc::StringUtils::format("(0x%08X)", flags); return properties; } @@ -670,20 +677,23 @@ std::string bodyPartFlags(int flags) std::string cellFlags(int flags) { std::string properties; - 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 "; - if (flags & ESM::Cell::QuasiEx) properties += "QuasiEx "; + 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 "; + if (flags & ESM::Cell::QuasiEx) + properties += "QuasiEx "; // This used value is not in the ESM component. - if (flags & 0x00000040) properties += "Unknown "; - int unused = (0xFFFFFFFF ^ - (ESM::Cell::HasWater| - ESM::Cell::Interior| - ESM::Cell::NoSleep| - ESM::Cell::QuasiEx| - 0x00000040)); - if (flags & unused) properties += "Invalid "; + if (flags & 0x00000040) + properties += "Unknown "; + int unused = (0xFFFFFFFF + ^ (ESM::Cell::HasWater | ESM::Cell::Interior | ESM::Cell::NoSleep | ESM::Cell::QuasiEx | 0x00000040)); + if (flags & unused) + properties += "Invalid "; properties += Misc::StringUtils::format("(0x%08X)", flags); return properties; } @@ -691,15 +701,17 @@ std::string cellFlags(int flags) std::string containerFlags(int flags) { std::string properties; - if (flags == 0) properties += "[None] "; - if (flags & ESM::Container::Unknown) properties += "Unknown "; - if (flags & ESM::Container::Organic) properties += "Organic "; - if (flags & ESM::Container::Respawn) properties += "Respawn "; - int unused = (0xFFFFFFFF ^ - (ESM::Container::Unknown| - ESM::Container::Organic| - ESM::Container::Respawn)); - if (flags & unused) properties += "Invalid "; + if (flags == 0) + properties += "[None] "; + if (flags & ESM::Container::Unknown) + properties += "Unknown "; + if (flags & ESM::Container::Organic) + properties += "Organic "; + if (flags & ESM::Container::Respawn) + properties += "Respawn "; + int unused = (0xFFFFFFFF ^ (ESM::Container::Unknown | ESM::Container::Organic | ESM::Container::Respawn)); + if (flags & unused) + properties += "Invalid "; properties += Misc::StringUtils::format("(0x%08X)", flags); return properties; } @@ -707,25 +719,29 @@ std::string containerFlags(int flags) std::string creatureFlags(int flags) { std::string properties; - if (flags == 0) properties += "[None] "; - if (flags & ESM::Creature::Base) properties += "Base "; - if (flags & ESM::Creature::Walks) properties += "Walks "; - if (flags & ESM::Creature::Swims) properties += "Swims "; - if (flags & ESM::Creature::Flies) properties += "Flies "; - if (flags & ESM::Creature::Bipedal) properties += "Bipedal "; - if (flags & ESM::Creature::Respawn) properties += "Respawn "; - if (flags & ESM::Creature::Weapon) properties += "Weapon "; - if (flags & ESM::Creature::Essential) properties += "Essential "; - int unused = (0xFFFFFFFF ^ - (ESM::Creature::Base| - ESM::Creature::Walks| - ESM::Creature::Swims| - ESM::Creature::Flies| - ESM::Creature::Bipedal| - ESM::Creature::Respawn| - ESM::Creature::Weapon| - ESM::Creature::Essential)); - if (flags & unused) properties += "Invalid "; + if (flags == 0) + properties += "[None] "; + if (flags & ESM::Creature::Base) + properties += "Base "; + if (flags & ESM::Creature::Walks) + properties += "Walks "; + if (flags & ESM::Creature::Swims) + properties += "Swims "; + if (flags & ESM::Creature::Flies) + properties += "Flies "; + if (flags & ESM::Creature::Bipedal) + properties += "Bipedal "; + if (flags & ESM::Creature::Respawn) + properties += "Respawn "; + if (flags & ESM::Creature::Weapon) + properties += "Weapon "; + if (flags & ESM::Creature::Essential) + properties += "Essential "; + int unused = (0xFFFFFFFF + ^ (ESM::Creature::Base | ESM::Creature::Walks | ESM::Creature::Swims | ESM::Creature::Flies + | ESM::Creature::Bipedal | ESM::Creature::Respawn | ESM::Creature::Weapon | ESM::Creature::Essential)); + if (flags & unused) + properties += "Invalid "; properties += Misc::StringUtils::format("(0x%02X)", flags); return properties; } @@ -733,9 +749,12 @@ std::string creatureFlags(int flags) std::string enchantmentFlags(int flags) { std::string properties; - if (flags == 0) properties += "[None] "; - if (flags & ESM::Enchantment::Autocalc) properties += "Autocalc "; - if (flags & (0xFFFFFFFF ^ ESM::Enchantment::Autocalc)) properties += "Invalid "; + if (flags == 0) + properties += "[None] "; + if (flags & ESM::Enchantment::Autocalc) + properties += "Autocalc "; + if (flags & (0xFFFFFFFF ^ ESM::Enchantment::Autocalc)) + properties += "Invalid "; properties += Misc::StringUtils::format("(0x%08X)", flags); return properties; } @@ -746,11 +765,16 @@ std::string landFlags(int flags) // The ESM component says that this first four bits are used, but // only the first three bits are used as far as I can tell. // There's also no enumeration of the bit in the ESM component. - if (flags == 0) properties += "[None] "; - if (flags & 0x00000001) properties += "Unknown1 "; - if (flags & 0x00000004) properties += "Unknown3 "; - if (flags & 0x00000002) properties += "Unknown2 "; - if (flags & 0xFFFFFFF8) properties += "Invalid "; + if (flags == 0) + properties += "[None] "; + if (flags & 0x00000001) + properties += "Unknown1 "; + if (flags & 0x00000004) + properties += "Unknown3 "; + if (flags & 0x00000002) + properties += "Unknown2 "; + if (flags & 0xFFFFFFF8) + properties += "Invalid "; properties += Misc::StringUtils::format("(0x%08X)", flags); return properties; } @@ -758,13 +782,15 @@ std::string landFlags(int flags) std::string itemListFlags(int flags) { std::string properties; - if (flags == 0) properties += "[None] "; - if (flags & ESM::ItemLevList::AllLevels) properties += "AllLevels "; - if (flags & ESM::ItemLevList::Each) properties += "Each "; - int unused = (0xFFFFFFFF ^ - (ESM::ItemLevList::AllLevels| - ESM::ItemLevList::Each)); - if (flags & unused) properties += "Invalid "; + if (flags == 0) + properties += "[None] "; + if (flags & ESM::ItemLevList::AllLevels) + properties += "AllLevels "; + if (flags & ESM::ItemLevList::Each) + properties += "Each "; + int unused = (0xFFFFFFFF ^ (ESM::ItemLevList::AllLevels | ESM::ItemLevList::Each)); + if (flags & unused) + properties += "Invalid "; properties += Misc::StringUtils::format("(0x%08X)", flags); return properties; } @@ -772,10 +798,13 @@ std::string itemListFlags(int flags) std::string creatureListFlags(int flags) { std::string properties; - if (flags == 0) properties += "[None] "; - if (flags & ESM::CreatureLevList::AllLevels) properties += "AllLevels "; + if (flags == 0) + properties += "[None] "; + if (flags & ESM::CreatureLevList::AllLevels) + properties += "AllLevels "; int unused = (0xFFFFFFFF ^ ESM::CreatureLevList::AllLevels); - if (flags & unused) properties += "Invalid "; + if (flags & unused) + properties += "Invalid "; properties += Misc::StringUtils::format("(0x%08X)", flags); return properties; } @@ -783,27 +812,31 @@ std::string creatureListFlags(int flags) std::string lightFlags(int flags) { std::string properties; - if (flags == 0) properties += "[None] "; - if (flags & ESM::Light::Dynamic) properties += "Dynamic "; - if (flags & ESM::Light::Fire) properties += "Fire "; - if (flags & ESM::Light::Carry) properties += "Carry "; - if (flags & ESM::Light::Flicker) properties += "Flicker "; - if (flags & ESM::Light::FlickerSlow) properties += "FlickerSlow "; - if (flags & ESM::Light::Pulse) properties += "Pulse "; - if (flags & ESM::Light::PulseSlow) properties += "PulseSlow "; - if (flags & ESM::Light::Negative) properties += "Negative "; - if (flags & ESM::Light::OffDefault) properties += "OffDefault "; - int unused = (0xFFFFFFFF ^ - (ESM::Light::Dynamic| - ESM::Light::Fire| - ESM::Light::Carry| - ESM::Light::Flicker| - ESM::Light::FlickerSlow| - ESM::Light::Pulse| - ESM::Light::PulseSlow| - ESM::Light::Negative| - ESM::Light::OffDefault)); - if (flags & unused) properties += "Invalid "; + if (flags == 0) + properties += "[None] "; + if (flags & ESM::Light::Dynamic) + properties += "Dynamic "; + if (flags & ESM::Light::Fire) + properties += "Fire "; + if (flags & ESM::Light::Carry) + properties += "Carry "; + if (flags & ESM::Light::Flicker) + properties += "Flicker "; + if (flags & ESM::Light::FlickerSlow) + properties += "FlickerSlow "; + if (flags & ESM::Light::Pulse) + properties += "Pulse "; + if (flags & ESM::Light::PulseSlow) + properties += "PulseSlow "; + if (flags & ESM::Light::Negative) + properties += "Negative "; + if (flags & ESM::Light::OffDefault) + properties += "OffDefault "; + int unused = (0xFFFFFFFF + ^ (ESM::Light::Dynamic | ESM::Light::Fire | ESM::Light::Carry | ESM::Light::Flicker | ESM::Light::FlickerSlow + | ESM::Light::Pulse | ESM::Light::PulseSlow | ESM::Light::Negative | ESM::Light::OffDefault)); + if (flags & unused) + properties += "Invalid "; properties += Misc::StringUtils::format("(0x%08X)", flags); return properties; } @@ -811,27 +844,47 @@ std::string lightFlags(int flags) std::string magicEffectFlags(int flags) { std::string properties; - if (flags == 0) properties += "[None] "; - if (flags & ESM::MagicEffect::TargetAttribute) properties += "TargetAttribute "; - if (flags & ESM::MagicEffect::TargetSkill) properties += "TargetSkill "; - if (flags & ESM::MagicEffect::NoDuration) properties += "NoDuration "; - if (flags & ESM::MagicEffect::NoMagnitude) properties += "NoMagnitude "; - if (flags & ESM::MagicEffect::Harmful) properties += "Harmful "; - if (flags & ESM::MagicEffect::ContinuousVfx) properties += "ContinuousVFX "; - if (flags & ESM::MagicEffect::CastSelf) properties += "CastSelf "; - if (flags & ESM::MagicEffect::CastTouch) properties += "CastTouch "; - if (flags & ESM::MagicEffect::CastTarget) properties += "CastTarget "; - if (flags & ESM::MagicEffect::AppliedOnce) properties += "AppliedOnce "; - if (flags & ESM::MagicEffect::Stealth) properties += "Stealth "; - if (flags & ESM::MagicEffect::NonRecastable) properties += "NonRecastable "; - if (flags & ESM::MagicEffect::IllegalDaedra) properties += "IllegalDaedra "; - if (flags & ESM::MagicEffect::Unreflectable) properties += "Unreflectable "; - if (flags & ESM::MagicEffect::CasterLinked) properties += "CasterLinked "; - if (flags & ESM::MagicEffect::AllowSpellmaking) properties += "AllowSpellmaking "; - if (flags & ESM::MagicEffect::AllowEnchanting) properties += "AllowEnchanting "; - if (flags & ESM::MagicEffect::NegativeLight) properties += "NegativeLight "; - - if (flags & 0xFFFC0000) properties += "Invalid "; + if (flags == 0) + properties += "[None] "; + if (flags & ESM::MagicEffect::TargetAttribute) + properties += "TargetAttribute "; + if (flags & ESM::MagicEffect::TargetSkill) + properties += "TargetSkill "; + if (flags & ESM::MagicEffect::NoDuration) + properties += "NoDuration "; + if (flags & ESM::MagicEffect::NoMagnitude) + properties += "NoMagnitude "; + if (flags & ESM::MagicEffect::Harmful) + properties += "Harmful "; + if (flags & ESM::MagicEffect::ContinuousVfx) + properties += "ContinuousVFX "; + if (flags & ESM::MagicEffect::CastSelf) + properties += "CastSelf "; + if (flags & ESM::MagicEffect::CastTouch) + properties += "CastTouch "; + if (flags & ESM::MagicEffect::CastTarget) + properties += "CastTarget "; + if (flags & ESM::MagicEffect::AppliedOnce) + properties += "AppliedOnce "; + if (flags & ESM::MagicEffect::Stealth) + properties += "Stealth "; + if (flags & ESM::MagicEffect::NonRecastable) + properties += "NonRecastable "; + if (flags & ESM::MagicEffect::IllegalDaedra) + properties += "IllegalDaedra "; + if (flags & ESM::MagicEffect::Unreflectable) + properties += "Unreflectable "; + if (flags & ESM::MagicEffect::CasterLinked) + properties += "CasterLinked "; + if (flags & ESM::MagicEffect::AllowSpellmaking) + properties += "AllowSpellmaking "; + if (flags & ESM::MagicEffect::AllowEnchanting) + properties += "AllowEnchanting "; + if (flags & ESM::MagicEffect::NegativeLight) + properties += "NegativeLight "; + + if (flags & 0xFFFC0000) + properties += "Invalid "; properties += Misc::StringUtils::format("(0x%08X)", flags); return properties; } @@ -839,21 +892,24 @@ std::string magicEffectFlags(int flags) std::string npcFlags(int flags) { std::string properties; - if (flags == 0) properties += "[None] "; - if (flags & ESM::NPC::Base) properties += "Base "; - 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 "; + if (flags == 0) + properties += "[None] "; + if (flags & ESM::NPC::Base) + properties += "Base "; + 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 "; // Whether corpses persist is a bit that is unaccounted for, // however relatively few NPCs have this bit set. - int unused = (0xFF ^ - (ESM::NPC::Base| - ESM::NPC::Autocalc| - ESM::NPC::Female| - ESM::NPC::Respawn| - ESM::NPC::Essential)); - if (flags & unused) properties += "Invalid "; + int unused + = (0xFF ^ (ESM::NPC::Base | ESM::NPC::Autocalc | ESM::NPC::Female | ESM::NPC::Respawn | ESM::NPC::Essential)); + if (flags & unused) + properties += "Invalid "; properties += Misc::StringUtils::format("(0x%02X)", flags); return properties; } @@ -861,14 +917,16 @@ std::string npcFlags(int flags) std::string raceFlags(int flags) { std::string properties; - if (flags == 0) properties += "[None] "; + if (flags == 0) + properties += "[None] "; // All races have the playable flag set in Bethesda files. - if (flags & ESM::Race::Playable) properties += "Playable "; - if (flags & ESM::Race::Beast) properties += "Beast "; - int unused = (0xFFFFFFFF ^ - (ESM::Race::Playable| - ESM::Race::Beast)); - if (flags & unused) properties += "Invalid "; + if (flags & ESM::Race::Playable) + properties += "Playable "; + if (flags & ESM::Race::Beast) + properties += "Beast "; + int unused = (0xFFFFFFFF ^ (ESM::Race::Playable | ESM::Race::Beast)); + if (flags & unused) + properties += "Invalid "; properties += Misc::StringUtils::format("(0x%08X)", flags); return properties; } @@ -876,15 +934,17 @@ std::string raceFlags(int flags) std::string spellFlags(int flags) { std::string properties; - if (flags == 0) properties += "[None] "; - if (flags & ESM::Spell::F_Autocalc) properties += "Autocalc "; - if (flags & ESM::Spell::F_PCStart) properties += "PCStart "; - if (flags & ESM::Spell::F_Always) properties += "Always "; - int unused = (0xFFFFFFFF ^ - (ESM::Spell::F_Autocalc| - ESM::Spell::F_PCStart| - ESM::Spell::F_Always)); - if (flags & unused) properties += "Invalid "; + if (flags == 0) + properties += "[None] "; + if (flags & ESM::Spell::F_Autocalc) + properties += "Autocalc "; + if (flags & ESM::Spell::F_PCStart) + properties += "PCStart "; + if (flags & ESM::Spell::F_Always) + properties += "Always "; + int unused = (0xFFFFFFFF ^ (ESM::Spell::F_Autocalc | ESM::Spell::F_PCStart | ESM::Spell::F_Always)); + if (flags & unused) + properties += "Invalid "; properties += Misc::StringUtils::format("(0x%08X)", flags); return properties; } @@ -892,16 +952,18 @@ std::string spellFlags(int flags) std::string weaponFlags(int flags) { std::string properties; - if (flags == 0) properties += "[None] "; + if (flags == 0) + properties += "[None] "; // The interpretation of the flags are still unclear to me. // Apparently you can't be Silver without being Magical? Many of // the "Magical" weapons don't have enchantments of any sort. - if (flags & ESM::Weapon::Magical) properties += "Magical "; - if (flags & ESM::Weapon::Silver) properties += "Silver "; - int unused = (0xFFFFFFFF ^ - (ESM::Weapon::Magical| - ESM::Weapon::Silver)); - if (flags & unused) properties += "Invalid "; + if (flags & ESM::Weapon::Magical) + properties += "Magical "; + if (flags & ESM::Weapon::Silver) + properties += "Silver "; + int unused = (0xFFFFFFFF ^ (ESM::Weapon::Magical | ESM::Weapon::Silver)); + if (flags & unused) + properties += "Invalid "; properties += Misc::StringUtils::format("(0x%08X)", flags); return properties; } @@ -909,13 +971,19 @@ std::string weaponFlags(int flags) std::string recordFlags(uint32_t flags) { std::string properties; - if (flags == 0) properties += "[None] "; - if (flags & ESM::FLAG_Deleted) properties += "Deleted "; - if (flags & ESM::FLAG_Persistent) properties += "Persistent "; - if (flags & ESM::FLAG_Ignored) properties += "Ignored "; - if (flags & ESM::FLAG_Blocked) properties += "Blocked "; + if (flags == 0) + properties += "[None] "; + if (flags & ESM::FLAG_Deleted) + properties += "Deleted "; + if (flags & ESM::FLAG_Persistent) + properties += "Persistent "; + if (flags & ESM::FLAG_Ignored) + properties += "Ignored "; + if (flags & ESM::FLAG_Blocked) + properties += "Blocked "; int unused = ~(ESM::FLAG_Deleted | ESM::FLAG_Persistent | ESM::FLAG_Ignored | ESM::FLAG_Blocked); - if (flags & unused) properties += "Invalid "; + if (flags & unused) + properties += "Invalid "; properties += Misc::StringUtils::format("(0x%08X)", flags); return properties; } \ No newline at end of file diff --git a/apps/esmtool/record.cpp b/apps/esmtool/record.cpp index c7d9d372ec..78c55343c4 100644 --- a/apps/esmtool/record.cpp +++ b/apps/esmtool/record.cpp @@ -9,1349 +9,1364 @@ namespace { -void printAIPackage(const ESM::AIPackage& p) -{ - std::cout << " AI Type: " << aiTypeLabel(p.mType) - << " (" << Misc::StringUtils::format("0x%08X", p.mType) << ")" << std::endl; - if (p.mType == ESM::AI_Wander) - { - std::cout << " Distance: " << p.mWander.mDistance << std::endl; - std::cout << " Duration: " << p.mWander.mDuration << std::endl; - std::cout << " Time of Day: " << (int)p.mWander.mTimeOfDay << std::endl; - if (p.mWander.mShouldRepeat != 1) - std::cout << " Should repeat: " << static_cast(p.mWander.mShouldRepeat != 0) << std::endl; - - std::cout << " Idle: "; - for (int i = 0; i != 8; i++) - std::cout << (int)p.mWander.mIdle[i] << " "; - std::cout << std::endl; - } - else if (p.mType == ESM::AI_Travel) + void printAIPackage(const ESM::AIPackage& p) { - std::cout << " Travel Coordinates: (" << p.mTravel.mX << "," - << p.mTravel.mY << "," << p.mTravel.mZ << ")" << std::endl; - std::cout << " Should repeat: " << static_cast(p.mTravel.mShouldRepeat != 0) << std::endl; - } - else if (p.mType == ESM::AI_Follow || p.mType == ESM::AI_Escort) - { - std::cout << " Follow Coordinates: (" << p.mTarget.mX << "," - << p.mTarget.mY << "," << p.mTarget.mZ << ")" << std::endl; - std::cout << " Duration: " << p.mTarget.mDuration << std::endl; - std::cout << " Target ID: " << p.mTarget.mId.toString() << std::endl; - std::cout << " Should repeat: " << static_cast(p.mTarget.mShouldRepeat != 0) << std::endl; + std::cout << " AI Type: " << aiTypeLabel(p.mType) << " (" << Misc::StringUtils::format("0x%08X", p.mType) + << ")" << std::endl; + if (p.mType == ESM::AI_Wander) + { + std::cout << " Distance: " << p.mWander.mDistance << std::endl; + std::cout << " Duration: " << p.mWander.mDuration << std::endl; + std::cout << " Time of Day: " << (int)p.mWander.mTimeOfDay << std::endl; + if (p.mWander.mShouldRepeat != 1) + std::cout << " Should repeat: " << static_cast(p.mWander.mShouldRepeat != 0) << std::endl; + + std::cout << " Idle: "; + for (int i = 0; i != 8; i++) + std::cout << (int)p.mWander.mIdle[i] << " "; + std::cout << std::endl; + } + else if (p.mType == ESM::AI_Travel) + { + std::cout << " Travel Coordinates: (" << p.mTravel.mX << "," << p.mTravel.mY << "," << p.mTravel.mZ + << ")" << std::endl; + std::cout << " Should repeat: " << static_cast(p.mTravel.mShouldRepeat != 0) << std::endl; + } + else if (p.mType == ESM::AI_Follow || p.mType == ESM::AI_Escort) + { + std::cout << " Follow Coordinates: (" << p.mTarget.mX << "," << p.mTarget.mY << "," << p.mTarget.mZ + << ")" << std::endl; + std::cout << " Duration: " << p.mTarget.mDuration << std::endl; + std::cout << " Target ID: " << p.mTarget.mId.toString() << std::endl; + std::cout << " Should repeat: " << static_cast(p.mTarget.mShouldRepeat != 0) << std::endl; + } + else if (p.mType == ESM::AI_Activate) + { + std::cout << " Name: " << p.mActivate.mName.toString() << std::endl; + std::cout << " Should repeat: " << static_cast(p.mActivate.mShouldRepeat != 0) << std::endl; + } + else + { + std::cout << " BadPackage: " << Misc::StringUtils::format("0x%08X", p.mType) << std::endl; + } + + if (!p.mCellName.empty()) + std::cout << " Cell Name: " << p.mCellName << std::endl; } - else if (p.mType == ESM::AI_Activate) + + std::string ruleString(const ESM::DialInfo::SelectStruct& ss) { - std::cout << " Name: " << p.mActivate.mName.toString() << std::endl; - std::cout << " Should repeat: " << static_cast(p.mActivate.mShouldRepeat != 0) << std::endl; - } - else { - std::cout << " BadPackage: " << Misc::StringUtils::format("0x%08X", p.mType) << std::endl; - } + std::string rule = ss.mSelectRule; - if (!p.mCellName.empty()) - std::cout << " Cell Name: " << p.mCellName << std::endl; -} + if (rule.length() < 5) + return "INVALID"; -std::string ruleString(const ESM::DialInfo::SelectStruct& ss) -{ - std::string rule = ss.mSelectRule; + char type = rule[1]; + char indicator = rule[2]; - if (rule.length() < 5) - return "INVALID"; + std::string type_str = "INVALID"; + std::string func_str = Misc::StringUtils::format("INVALID=%s", rule.substr(1, 3)); + int func; + std::istringstream iss(rule.substr(2, 2)); + iss >> func; - char type = rule[1]; - char indicator = rule[2]; + switch (type) + { + case '1': + type_str = "Function"; + func_str = std::string(ruleFunction(func)); + break; + case '2': + if (indicator == 's') + type_str = "Global short"; + else if (indicator == 'l') + type_str = "Global long"; + else if (indicator == 'f') + type_str = "Global float"; + break; + case '3': + if (indicator == 's') + type_str = "Local short"; + else if (indicator == 'l') + type_str = "Local long"; + else if (indicator == 'f') + type_str = "Local float"; + break; + case '4': + if (indicator == 'J') + type_str = "Journal"; + break; + case '5': + if (indicator == 'I') + type_str = "Item type"; + break; + case '6': + if (indicator == 'D') + type_str = "NPC Dead"; + break; + case '7': + if (indicator == 'X') + type_str = "Not ID"; + break; + case '8': + if (indicator == 'F') + type_str = "Not Faction"; + break; + case '9': + if (indicator == 'C') + type_str = "Not Class"; + break; + case 'A': + if (indicator == 'R') + type_str = "Not Race"; + break; + case 'B': + if (indicator == 'L') + type_str = "Not Cell"; + break; + case 'C': + if (indicator == 's') + type_str = "Not Local"; + break; + default: + break; + } - std::string type_str = "INVALID"; - std::string func_str = Misc::StringUtils::format("INVALID=%s", rule.substr(1,3)); - int func; - std::istringstream iss(rule.substr(2,2)); - iss >> func; + // Append the variable name to the function string if any. + if (type != '1') + func_str = rule.substr(5); - switch(type) - { - case '1': - type_str = "Function"; - func_str = std::string(ruleFunction(func)); - break; - case '2': - if (indicator == 's') type_str = "Global short"; - else if (indicator == 'l') type_str = "Global long"; - else if (indicator == 'f') type_str = "Global float"; - break; - case '3': - if (indicator == 's') type_str = "Local short"; - else if (indicator == 'l') type_str = "Local long"; - else if (indicator == 'f') type_str = "Local float"; - break; - case '4': if (indicator == 'J') type_str = "Journal"; break; - case '5': if (indicator == 'I') type_str = "Item type"; break; - case '6': if (indicator == 'D') type_str = "NPC Dead"; break; - case '7': if (indicator == 'X') type_str = "Not ID"; break; - case '8': if (indicator == 'F') type_str = "Not Faction"; break; - case '9': if (indicator == 'C') type_str = "Not Class"; break; - case 'A': if (indicator == 'R') type_str = "Not Race"; break; - case 'B': if (indicator == 'L') type_str = "Not Cell"; break; - case 'C': if (indicator == 's') type_str = "Not Local"; break; - default: break; - } + // In the previous switch, we assumed that the second char was X + // for all types not qual to one. If this wasn't true, go back to + // the error message. + if (type != '1' && rule[3] != 'X') + func_str = Misc::StringUtils::format("INVALID=%s", rule.substr(1, 3)); - // Append the variable name to the function string if any. - if (type != '1') func_str = rule.substr(5); + char oper = rule[4]; + std::string oper_str = "??"; + switch (oper) + { + case '0': + oper_str = "=="; + break; + case '1': + oper_str = "!="; + break; + case '2': + oper_str = "> "; + break; + case '3': + oper_str = ">="; + break; + case '4': + oper_str = "< "; + break; + case '5': + oper_str = "<="; + break; + default: + break; + } - // In the previous switch, we assumed that the second char was X - // for all types not qual to one. If this wasn't true, go back to - // the error message. - if (type != '1' && rule[3] != 'X') - func_str = Misc::StringUtils::format("INVALID=%s", rule.substr(1,3)); + std::ostringstream stream; + stream << ss.mValue; - char oper = rule[4]; - std::string oper_str = "??"; - switch (oper) - { - case '0': oper_str = "=="; break; - case '1': oper_str = "!="; break; - case '2': oper_str = "> "; break; - case '3': oper_str = ">="; break; - case '4': oper_str = "< "; break; - case '5': oper_str = "<="; break; - default: break; + std::string result + = Misc::StringUtils::format("%-12s %-32s %2s %s", type_str, func_str, oper_str, stream.str()); + return result; } - std::ostringstream stream; - stream << ss.mValue; - - std::string result = Misc::StringUtils::format("%-12s %-32s %2s %s", type_str, func_str, oper_str, stream.str()); - return result; -} - -void printEffectList(const ESM::EffectList& effects) -{ - int i = 0; - for (const ESM::ENAMstruct& effect : effects.mList) + void printEffectList(const ESM::EffectList& effects) { - std::cout << " Effect[" << i << "]: " << magicEffectLabel(effect.mEffectID) - << " (" << effect.mEffectID << ")" << std::endl; - if (effect.mSkill != -1) - std::cout << " Skill: " << skillLabel(effect.mSkill) - << " (" << (int)effect.mSkill << ")" << std::endl; - if (effect.mAttribute != -1) - std::cout << " Attribute: " << attributeLabel(effect.mAttribute) - << " (" << (int)effect.mAttribute << ")" << std::endl; - std::cout << " Range: " << rangeTypeLabel(effect.mRange) - << " (" << effect.mRange << ")" << std::endl; - // Area is always zero if range type is "Self" - if (effect.mRange != ESM::RT_Self) - std::cout << " Area: " << effect.mArea << std::endl; - std::cout << " Duration: " << effect.mDuration << std::endl; - std::cout << " Magnitude: " << effect.mMagnMin << "-" << effect.mMagnMax << std::endl; - i++; + int i = 0; + for (const ESM::ENAMstruct& effect : effects.mList) + { + std::cout << " Effect[" << i << "]: " << magicEffectLabel(effect.mEffectID) << " (" << effect.mEffectID + << ")" << std::endl; + if (effect.mSkill != -1) + std::cout << " Skill: " << skillLabel(effect.mSkill) << " (" << (int)effect.mSkill << ")" + << std::endl; + if (effect.mAttribute != -1) + std::cout << " Attribute: " << attributeLabel(effect.mAttribute) << " (" << (int)effect.mAttribute + << ")" << std::endl; + std::cout << " Range: " << rangeTypeLabel(effect.mRange) << " (" << effect.mRange << ")" << std::endl; + // Area is always zero if range type is "Self" + if (effect.mRange != ESM::RT_Self) + std::cout << " Area: " << effect.mArea << std::endl; + std::cout << " Duration: " << effect.mDuration << std::endl; + std::cout << " Magnitude: " << effect.mMagnMin << "-" << effect.mMagnMax << std::endl; + i++; + } } -} -void printTransport(const std::vector& transport) -{ - for (const ESM::Transport::Dest& dest : transport) + void printTransport(const std::vector& transport) { - std::cout << " Destination Position: " - << Misc::StringUtils::format("%12.3f", dest.mPos.pos[0]) << "," - << Misc::StringUtils::format("%12.3f", dest.mPos.pos[1]) << "," - << Misc::StringUtils::format("%12.3f", dest.mPos.pos[2]) << ")" << std::endl; - std::cout << " Destination Rotation: " - << Misc::StringUtils::format("%9.6f", dest.mPos.rot[0]) << "," - << Misc::StringUtils::format("%9.6f", dest.mPos.rot[1]) << "," - << Misc::StringUtils::format("%9.6f", dest.mPos.rot[2]) << ")" << std::endl; - if (!dest.mCellName.empty()) - std::cout << " Destination Cell: " << dest.mCellName << std::endl; + for (const ESM::Transport::Dest& dest : transport) + { + std::cout << " Destination Position: " << Misc::StringUtils::format("%12.3f", dest.mPos.pos[0]) << "," + << Misc::StringUtils::format("%12.3f", dest.mPos.pos[1]) << "," + << Misc::StringUtils::format("%12.3f", dest.mPos.pos[2]) << ")" << std::endl; + std::cout << " Destination Rotation: " << Misc::StringUtils::format("%9.6f", dest.mPos.rot[0]) << "," + << Misc::StringUtils::format("%9.6f", dest.mPos.rot[1]) << "," + << Misc::StringUtils::format("%9.6f", dest.mPos.rot[2]) << ")" << std::endl; + if (!dest.mCellName.empty()) + std::cout << " Destination Cell: " << dest.mCellName << std::endl; + } } -} } -namespace EsmTool { - -std::unique_ptr RecordBase::create(const ESM::NAME type) +namespace EsmTool { - std::unique_ptr record; - switch (type.toInt()) - { - case ESM::REC_ACTI: - { - record = std::make_unique>(); - break; - } - case ESM::REC_ALCH: - { - record = std::make_unique>(); - break; - } - case ESM::REC_APPA: - { - record = std::make_unique>(); - break; - } - case ESM::REC_ARMO: + std::unique_ptr RecordBase::create(const ESM::NAME type) { - record = std::make_unique>(); - break; - } - case ESM::REC_BODY: - { - record = std::make_unique>(); - break; - } - case ESM::REC_BOOK: - { - record = std::make_unique>(); - break; - } - case ESM::REC_BSGN: - { - record = std::make_unique>(); - break; - } - case ESM::REC_CELL: - { - record = std::make_unique>(); - break; - } - case ESM::REC_CLAS: - { - record = std::make_unique>(); - break; - } - case ESM::REC_CLOT: - { - record = std::make_unique>(); - break; - } - case ESM::REC_CONT: - { - record = std::make_unique>(); - break; - } - case ESM::REC_CREA: - { - record = std::make_unique>(); - break; - } - case ESM::REC_DIAL: - { - record = std::make_unique>(); - break; - } - case ESM::REC_DOOR: - { - record = std::make_unique>(); - break; - } - case ESM::REC_ENCH: - { - record = std::make_unique>(); - break; - } - case ESM::REC_FACT: - { - record = std::make_unique>(); - break; - } - case ESM::REC_GLOB: - { - record = std::make_unique>(); - break; + std::unique_ptr record; + + switch (type.toInt()) + { + case ESM::REC_ACTI: + { + record = std::make_unique>(); + break; + } + case ESM::REC_ALCH: + { + record = std::make_unique>(); + break; + } + case ESM::REC_APPA: + { + record = std::make_unique>(); + break; + } + case ESM::REC_ARMO: + { + record = std::make_unique>(); + break; + } + case ESM::REC_BODY: + { + record = std::make_unique>(); + break; + } + case ESM::REC_BOOK: + { + record = std::make_unique>(); + break; + } + case ESM::REC_BSGN: + { + record = std::make_unique>(); + break; + } + case ESM::REC_CELL: + { + record = std::make_unique>(); + break; + } + case ESM::REC_CLAS: + { + record = std::make_unique>(); + break; + } + case ESM::REC_CLOT: + { + record = std::make_unique>(); + break; + } + case ESM::REC_CONT: + { + record = std::make_unique>(); + break; + } + case ESM::REC_CREA: + { + record = std::make_unique>(); + break; + } + case ESM::REC_DIAL: + { + record = std::make_unique>(); + break; + } + case ESM::REC_DOOR: + { + record = std::make_unique>(); + break; + } + case ESM::REC_ENCH: + { + record = std::make_unique>(); + break; + } + case ESM::REC_FACT: + { + record = std::make_unique>(); + break; + } + case ESM::REC_GLOB: + { + record = std::make_unique>(); + break; + } + case ESM::REC_GMST: + { + record = std::make_unique>(); + break; + } + case ESM::REC_INFO: + { + record = std::make_unique>(); + break; + } + case ESM::REC_INGR: + { + record = std::make_unique>(); + break; + } + case ESM::REC_LAND: + { + record = std::make_unique>(); + break; + } + case ESM::REC_LEVI: + { + record = std::make_unique>(); + break; + } + case ESM::REC_LEVC: + { + record = std::make_unique>(); + break; + } + case ESM::REC_LIGH: + { + record = std::make_unique>(); + break; + } + case ESM::REC_LOCK: + { + record = std::make_unique>(); + break; + } + case ESM::REC_LTEX: + { + record = std::make_unique>(); + break; + } + case ESM::REC_MISC: + { + record = std::make_unique>(); + break; + } + case ESM::REC_MGEF: + { + record = std::make_unique>(); + break; + } + case ESM::REC_NPC_: + { + record = std::make_unique>(); + break; + } + case ESM::REC_PGRD: + { + record = std::make_unique>(); + break; + } + case ESM::REC_PROB: + { + record = std::make_unique>(); + break; + } + case ESM::REC_RACE: + { + record = std::make_unique>(); + break; + } + case ESM::REC_REGN: + { + record = std::make_unique>(); + break; + } + case ESM::REC_REPA: + { + record = std::make_unique>(); + break; + } + case ESM::REC_SCPT: + { + record = std::make_unique>(); + break; + } + case ESM::REC_SKIL: + { + record = std::make_unique>(); + break; + } + case ESM::REC_SNDG: + { + record = std::make_unique>(); + break; + } + case ESM::REC_SOUN: + { + record = std::make_unique>(); + break; + } + case ESM::REC_SPEL: + { + record = std::make_unique>(); + break; + } + case ESM::REC_STAT: + { + record = std::make_unique>(); + break; + } + case ESM::REC_WEAP: + { + record = std::make_unique>(); + break; + } + case ESM::REC_SSCR: + { + record = std::make_unique>(); + break; + } + default: + break; + } + if (record) + { + record->mType = type; + } + return record; } - case ESM::REC_GMST: + + template <> + void Record::print() { - record = std::make_unique>(); - break; + std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Deleted: " << mIsDeleted << std::endl; } - case ESM::REC_INFO: + + template <> + void Record::print() { - record = std::make_unique>(); - break; + std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Icon: " << mData.mIcon << std::endl; + if (!mData.mScript.empty()) + std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Weight: " << mData.mData.mWeight << std::endl; + std::cout << " Value: " << mData.mData.mValue << std::endl; + std::cout << " AutoCalc: " << mData.mData.mAutoCalc << std::endl; + printEffectList(mData.mEffects); + std::cout << " Deleted: " << mIsDeleted << std::endl; } - case ESM::REC_INGR: + + template <> + void Record::print() { - record = std::make_unique>(); - break; + std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Icon: " << mData.mIcon << std::endl; + if (!mData.mScript.empty()) + std::cout << " Script: " << mData.mScript << std::endl; + if (!mData.mEnchant.empty()) + std::cout << " Enchantment: " << mData.mEnchant << std::endl; + std::cout << " Type: " << armorTypeLabel(mData.mData.mType) << " (" << mData.mData.mType << ")" << std::endl; + std::cout << " Weight: " << mData.mData.mWeight << std::endl; + std::cout << " Value: " << mData.mData.mValue << std::endl; + std::cout << " Health: " << mData.mData.mHealth << std::endl; + std::cout << " Armor: " << mData.mData.mArmor << std::endl; + std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl; + for (const ESM::PartReference& part : mData.mParts.mParts) + { + std::cout << " Body Part: " << bodyPartLabel(part.mPart) << " (" << (int)(part.mPart) << ")" << std::endl; + std::cout << " Male Name: " << part.mMale << std::endl; + if (!part.mFemale.empty()) + std::cout << " Female Name: " << part.mFemale << std::endl; + } + + std::cout << " Deleted: " << mIsDeleted << std::endl; } - case ESM::REC_LAND: + + template <> + void Record::print() { - record = std::make_unique>(); - break; + std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Icon: " << mData.mIcon << std::endl; + std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Type: " << apparatusTypeLabel(mData.mData.mType) << " (" << mData.mData.mType << ")" + << std::endl; + std::cout << " Weight: " << mData.mData.mWeight << std::endl; + std::cout << " Value: " << mData.mData.mValue << std::endl; + std::cout << " Quality: " << mData.mData.mQuality << std::endl; + std::cout << " Deleted: " << mIsDeleted << std::endl; } - case ESM::REC_LEVI: + + template <> + void Record::print() { - record = std::make_unique>(); - break; + std::cout << " Race: " << mData.mRace << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Type: " << meshTypeLabel(mData.mData.mType) << " (" << (int)mData.mData.mType << ")" + << std::endl; + std::cout << " Flags: " << bodyPartFlags(mData.mData.mFlags) << std::endl; + std::cout << " Part: " << meshPartLabel(mData.mData.mPart) << " (" << (int)mData.mData.mPart << ")" + << std::endl; + std::cout << " Vampire: " << (int)mData.mData.mVampire << std::endl; + std::cout << " Deleted: " << mIsDeleted << std::endl; } - case ESM::REC_LEVC: + + template <> + void Record::print() { - record = std::make_unique>(); - break; + std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Icon: " << mData.mIcon << std::endl; + if (!mData.mScript.empty()) + std::cout << " Script: " << mData.mScript << std::endl; + if (!mData.mEnchant.empty()) + std::cout << " Enchantment: " << mData.mEnchant << std::endl; + std::cout << " Weight: " << mData.mData.mWeight << std::endl; + std::cout << " Value: " << mData.mData.mValue << std::endl; + std::cout << " IsScroll: " << mData.mData.mIsScroll << std::endl; + std::cout << " SkillId: " << mData.mData.mSkillId << std::endl; + std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl; + if (mPrintPlain) + { + std::cout << " Text:" << std::endl; + std::cout << "START--------------------------------------" << std::endl; + std::cout << mData.mText << std::endl; + std::cout << "END----------------------------------------" << std::endl; + } + else + { + std::cout << " Text: [skipped]" << std::endl; + } + std::cout << " Deleted: " << mIsDeleted << std::endl; } - case ESM::REC_LIGH: + + template <> + void Record::print() { - record = std::make_unique>(); - break; + std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Texture: " << mData.mTexture << std::endl; + std::cout << " Description: " << mData.mDescription << std::endl; + for (const std::string& power : mData.mPowers.mList) + std::cout << " Power: " << power << std::endl; + std::cout << " Deleted: " << mIsDeleted << std::endl; } - case ESM::REC_LOCK: + + template <> + void Record::print() { - record = std::make_unique>(); - break; + // None of the cells have names... + if (!mData.mName.empty()) + std::cout << " Name: " << mData.mName << std::endl; + if (!mData.mRegion.empty()) + std::cout << " Region: " << mData.mRegion << std::endl; + std::cout << " Flags: " << cellFlags(mData.mData.mFlags) << std::endl; + + std::cout << " Coordinates: " + << " (" << mData.getGridX() << "," << mData.getGridY() << ")" << std::endl; + + if (mData.mData.mFlags & ESM::Cell::Interior && !(mData.mData.mFlags & ESM::Cell::QuasiEx)) + { + if (mData.hasAmbient()) + { + // TODO: see if we can change the integer representation to something more sensible + std::cout << " Ambient Light Color: " << mData.mAmbi.mAmbient << std::endl; + std::cout << " Sunlight Color: " << mData.mAmbi.mSunlight << std::endl; + std::cout << " Fog Color: " << mData.mAmbi.mFog << std::endl; + std::cout << " Fog Density: " << mData.mAmbi.mFogDensity << std::endl; + } + else + { + std::cout << " No Ambient Information" << std::endl; + } + std::cout << " Water Level: " << mData.mWater << std::endl; + } + else + std::cout << " Map Color: " << Misc::StringUtils::format("0x%08X", mData.mMapColor) << std::endl; + std::cout << " Water Level Int: " << mData.mWaterInt << std::endl; + std::cout << " RefId counter: " << mData.mRefNumCounter << std::endl; + std::cout << " Deleted: " << mIsDeleted << std::endl; } - case ESM::REC_LTEX: + + template <> + void Record::print() { - record = std::make_unique>(); - break; - } - case ESM::REC_MISC: + std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Description: " << mData.mDescription << std::endl; + std::cout << " Playable: " << mData.mData.mIsPlayable << std::endl; + std::cout << " AutoCalc: " << mData.mData.mCalc << std::endl; + std::cout << " Attribute1: " << attributeLabel(mData.mData.mAttribute[0]) << " (" << mData.mData.mAttribute[0] + << ")" << std::endl; + std::cout << " Attribute2: " << attributeLabel(mData.mData.mAttribute[1]) << " (" << mData.mData.mAttribute[1] + << ")" << std::endl; + std::cout << " Specialization: " << specializationLabel(mData.mData.mSpecialization) << " (" + << mData.mData.mSpecialization << ")" << std::endl; + for (int i = 0; i != 5; i++) + std::cout << " Minor Skill: " << skillLabel(mData.mData.mSkills[i][0]) << " (" << mData.mData.mSkills[i][0] + << ")" << std::endl; + for (int i = 0; i != 5; i++) + std::cout << " Major Skill: " << skillLabel(mData.mData.mSkills[i][1]) << " (" << mData.mData.mSkills[i][1] + << ")" << std::endl; + std::cout << " Deleted: " << mIsDeleted << std::endl; + } + + template <> + void Record::print() { - record = std::make_unique>(); - break; + std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Icon: " << mData.mIcon << std::endl; + if (!mData.mScript.empty()) + std::cout << " Script: " << mData.mScript << std::endl; + if (!mData.mEnchant.empty()) + std::cout << " Enchantment: " << mData.mEnchant << std::endl; + std::cout << " Type: " << clothingTypeLabel(mData.mData.mType) << " (" << mData.mData.mType << ")" + << std::endl; + std::cout << " Weight: " << mData.mData.mWeight << std::endl; + std::cout << " Value: " << mData.mData.mValue << std::endl; + std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl; + for (const ESM::PartReference& part : mData.mParts.mParts) + { + std::cout << " Body Part: " << bodyPartLabel(part.mPart) << " (" << (int)(part.mPart) << ")" << std::endl; + std::cout << " Male Name: " << part.mMale << std::endl; + if (!part.mFemale.empty()) + std::cout << " Female Name: " << part.mFemale << std::endl; + } + std::cout << " Deleted: " << mIsDeleted << std::endl; } - case ESM::REC_MGEF: + + template <> + void Record::print() { - record = std::make_unique>(); - break; + std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + if (!mData.mScript.empty()) + std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Flags: " << containerFlags(mData.mFlags) << std::endl; + std::cout << " Weight: " << mData.mWeight << std::endl; + for (const ESM::ContItem& item : mData.mInventory.mList) + std::cout << " Inventory: Count: " << Misc::StringUtils::format("%4d", item.mCount) + << " Item: " << item.mItem << std::endl; + std::cout << " Deleted: " << mIsDeleted << std::endl; } - case ESM::REC_NPC_: + + template <> + void Record::print() { - record = std::make_unique>(); - break; - } - case ESM::REC_PGRD: + std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Flags: " << creatureFlags((int)mData.mFlags) << std::endl; + std::cout << " Blood Type: " << mData.mBloodType + 1 << std::endl; + std::cout << " Original: " << mData.mOriginal << std::endl; + std::cout << " Scale: " << mData.mScale << std::endl; + + std::cout << " Type: " << creatureTypeLabel(mData.mData.mType) << " (" << mData.mData.mType << ")" + << std::endl; + std::cout << " Level: " << mData.mData.mLevel << std::endl; + + std::cout << " Attributes:" << std::endl; + std::cout << " Strength: " << mData.mData.mStrength << std::endl; + std::cout << " Intelligence: " << mData.mData.mIntelligence << std::endl; + std::cout << " Willpower: " << mData.mData.mWillpower << std::endl; + std::cout << " Agility: " << mData.mData.mAgility << std::endl; + std::cout << " Speed: " << mData.mData.mSpeed << std::endl; + std::cout << " Endurance: " << mData.mData.mEndurance << std::endl; + std::cout << " Personality: " << mData.mData.mPersonality << std::endl; + std::cout << " Luck: " << mData.mData.mLuck << std::endl; + + std::cout << " Health: " << mData.mData.mHealth << std::endl; + std::cout << " Magicka: " << mData.mData.mMana << std::endl; + std::cout << " Fatigue: " << mData.mData.mFatigue << std::endl; + std::cout << " Soul: " << mData.mData.mSoul << std::endl; + std::cout << " Combat: " << mData.mData.mCombat << std::endl; + std::cout << " Magic: " << mData.mData.mMagic << std::endl; + std::cout << " Stealth: " << mData.mData.mStealth << std::endl; + std::cout << " Attack1: " << mData.mData.mAttack[0] << "-" << mData.mData.mAttack[1] << std::endl; + std::cout << " Attack2: " << mData.mData.mAttack[2] << "-" << mData.mData.mAttack[3] << std::endl; + std::cout << " Attack3: " << mData.mData.mAttack[4] << "-" << mData.mData.mAttack[5] << std::endl; + std::cout << " Gold: " << mData.mData.mGold << std::endl; + + for (const ESM::ContItem& item : mData.mInventory.mList) + std::cout << " Inventory: Count: " << Misc::StringUtils::format("%4d", item.mCount) + << " Item: " << item.mItem << std::endl; + + for (const std::string& spell : mData.mSpells.mList) + std::cout << " Spell: " << spell << std::endl; + + printTransport(mData.getTransport()); + + std::cout << " Artificial Intelligence: " << std::endl; + std::cout << " AI Hello:" << (int)mData.mAiData.mHello << std::endl; + std::cout << " AI Fight:" << (int)mData.mAiData.mFight << std::endl; + std::cout << " AI Flee:" << (int)mData.mAiData.mFlee << std::endl; + std::cout << " AI Alarm:" << (int)mData.mAiData.mAlarm << std::endl; + std::cout << " AI U1:" << (int)mData.mAiData.mU1 << std::endl; + std::cout << " AI U2:" << (int)mData.mAiData.mU2 << std::endl; + std::cout << " AI U3:" << (int)mData.mAiData.mU3 << std::endl; + std::cout << " AI Services:" << Misc::StringUtils::format("0x%08X", mData.mAiData.mServices) << std::endl; + + for (const ESM::AIPackage& package : mData.mAiPackage.mList) + printAIPackage(package); + std::cout << " Deleted: " << mIsDeleted << std::endl; + } + + template <> + void Record::print() + { + std::cout << " Type: " << dialogTypeLabel(mData.mType) << " (" << (int)mData.mType << ")" << std::endl; + std::cout << " Deleted: " << mIsDeleted << std::endl; + // Sadly, there are no DialInfos, because the loader dumps as it + // loads, rather than loading and then dumping. :-( Anyone mind if + // I change this? + for (const ESM::DialInfo& info : mData.mInfo) + std::cout << "INFO!" << info.mId << std::endl; + } + + template <> + void Record::print() { - record = std::make_unique>(); - break; + std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " OpenSound: " << mData.mOpenSound << std::endl; + std::cout << " CloseSound: " << mData.mCloseSound << std::endl; + std::cout << " Deleted: " << mIsDeleted << std::endl; } - case ESM::REC_PROB: + + template <> + void Record::print() { - record = std::make_unique>(); - break; + std::cout << " Type: " << enchantTypeLabel(mData.mData.mType) << " (" << mData.mData.mType << ")" << std::endl; + std::cout << " Cost: " << mData.mData.mCost << std::endl; + std::cout << " Charge: " << mData.mData.mCharge << std::endl; + std::cout << " Flags: " << enchantmentFlags(mData.mData.mFlags) << std::endl; + printEffectList(mData.mEffects); + std::cout << " Deleted: " << mIsDeleted << std::endl; } - case ESM::REC_RACE: + + template <> + void Record::print() { - record = std::make_unique>(); - break; + std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Hidden: " << mData.mData.mIsHidden << std::endl; + std::cout << " Attribute1: " << attributeLabel(mData.mData.mAttribute[0]) << " (" << mData.mData.mAttribute[0] + << ")" << std::endl; + std::cout << " Attribute2: " << attributeLabel(mData.mData.mAttribute[1]) << " (" << mData.mData.mAttribute[1] + << ")" << std::endl; + for (int skill : mData.mData.mSkills) + if (skill != -1) + std::cout << " Skill: " << skillLabel(skill) << " (" << skill << ")" << std::endl; + for (int i = 0; i != 10; i++) + if (!mData.mRanks[i].empty()) + { + std::cout << " Rank: " << mData.mRanks[i] << std::endl; + std::cout << " Attribute1 Requirement: " << mData.mData.mRankData[i].mAttribute1 << std::endl; + std::cout << " Attribute2 Requirement: " << mData.mData.mRankData[i].mAttribute2 << std::endl; + std::cout << " One Skill at Level: " << mData.mData.mRankData[i].mPrimarySkill << std::endl; + std::cout << " Two Skills at Level: " << mData.mData.mRankData[i].mFavouredSkill << std::endl; + std::cout << " Faction Reaction: " << mData.mData.mRankData[i].mFactReaction << std::endl; + } + for (const auto& reaction : mData.mReactions) + std::cout << " Reaction: " << reaction.second << " = " << reaction.first << std::endl; + std::cout << " Deleted: " << mIsDeleted << std::endl; + } + + template <> + void Record::print() + { + std::cout << " " << mData.mValue << std::endl; + std::cout << " Deleted: " << mIsDeleted << std::endl; + } + + template <> + void Record::print() + { + std::cout << " " << mData.mValue << std::endl; + } + + template <> + void Record::print() + { + std::cout << " Id: " << mData.mId << std::endl; + if (!mData.mPrev.empty()) + std::cout << " Previous ID: " << mData.mPrev << std::endl; + if (!mData.mNext.empty()) + std::cout << " Next ID: " << mData.mNext << std::endl; + std::cout << " Text: " << mData.mResponse << std::endl; + if (!mData.mActor.empty()) + std::cout << " Actor: " << mData.mActor << std::endl; + if (!mData.mRace.empty()) + std::cout << " Race: " << mData.mRace << std::endl; + if (!mData.mClass.empty()) + std::cout << " Class: " << mData.mClass << std::endl; + std::cout << " Factionless: " << mData.mFactionLess << std::endl; + if (!mData.mFaction.empty()) + std::cout << " NPC Faction: " << mData.mFaction << std::endl; + if (mData.mData.mRank != -1) + std::cout << " NPC Rank: " << (int)mData.mData.mRank << std::endl; + if (!mData.mPcFaction.empty()) + std::cout << " PC Faction: " << mData.mPcFaction << std::endl; + // CHANGE? non-standard capitalization mPCrank -> mPCRank (mPcRank?) + if (mData.mData.mPCrank != -1) + std::cout << " PC Rank: " << (int)mData.mData.mPCrank << std::endl; + if (!mData.mCell.empty()) + std::cout << " Cell: " << mData.mCell << std::endl; + if (mData.mData.mDisposition > 0) + std::cout << " Disposition/Journal index: " << mData.mData.mDisposition << std::endl; + if (mData.mData.mGender != ESM::DialInfo::NA) + std::cout << " Gender: " << mData.mData.mGender << std::endl; + if (!mData.mSound.empty()) + std::cout << " Sound File: " << mData.mSound << std::endl; + + std::cout << " Quest Status: " << questStatusLabel(mData.mQuestStatus) << " (" << mData.mQuestStatus << ")" + << std::endl; + std::cout << " Unknown1: " << mData.mData.mUnknown1 << std::endl; + std::cout << " Unknown2: " << (int)mData.mData.mUnknown2 << std::endl; + + for (const ESM::DialInfo::SelectStruct& rule : mData.mSelects) + std::cout << " Select Rule: " << ruleString(rule) << std::endl; + + if (!mData.mResultScript.empty()) + { + if (mPrintPlain) + { + std::cout << " Result Script:" << std::endl; + std::cout << "START--------------------------------------" << std::endl; + std::cout << mData.mResultScript << std::endl; + std::cout << "END----------------------------------------" << std::endl; + } + else + { + std::cout << " Result Script: [skipped]" << std::endl; + } + } + std::cout << " Deleted: " << mIsDeleted << std::endl; } - case ESM::REC_REGN: + + template <> + void Record::print() { - record = std::make_unique>(); - break; + std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Icon: " << mData.mIcon << std::endl; + if (!mData.mScript.empty()) + std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Weight: " << mData.mData.mWeight << std::endl; + std::cout << " Value: " << mData.mData.mValue << std::endl; + for (int i = 0; i != 4; i++) + { + // A value of -1 means no effect + if (mData.mData.mEffectID[i] == -1) + continue; + std::cout << " Effect: " << magicEffectLabel(mData.mData.mEffectID[i]) << " (" << mData.mData.mEffectID[i] + << ")" << std::endl; + std::cout << " Skill: " << skillLabel(mData.mData.mSkills[i]) << " (" << mData.mData.mSkills[i] << ")" + << std::endl; + std::cout << " Attribute: " << attributeLabel(mData.mData.mAttributes[i]) << " (" + << mData.mData.mAttributes[i] << ")" << std::endl; + } + std::cout << " Deleted: " << mIsDeleted << std::endl; } - case ESM::REC_REPA: + + template <> + void Record::print() { - record = std::make_unique>(); - break; + std::cout << " Coordinates: (" << mData.mX << "," << mData.mY << ")" << std::endl; + std::cout << " Flags: " << landFlags(mData.mFlags) << std::endl; + std::cout << " DataTypes: " << mData.mDataTypes << std::endl; + + if (const ESM::Land::LandData* data = mData.getLandData(mData.mDataTypes)) + { + std::cout << " Height Offset: " << data->mHeightOffset << std::endl; + // Lots of missing members. + std::cout << " Unknown1: " << data->mUnk1 << std::endl; + std::cout << " Unknown2: " << data->mUnk2 << std::endl; + } + mData.unloadData(); + std::cout << " Deleted: " << mIsDeleted << std::endl; } - case ESM::REC_SCPT: + + template <> + void Record::print() { - record = std::make_unique>(); - break; + std::cout << " Chance for None: " << (int)mData.mChanceNone << std::endl; + std::cout << " Flags: " << creatureListFlags(mData.mFlags) << std::endl; + std::cout << " Number of items: " << mData.mList.size() << std::endl; + for (const ESM::LevelledListBase::LevelItem& item : mData.mList) + std::cout << " Creature: Level: " << item.mLevel << " Creature: " << item.mId << std::endl; + std::cout << " Deleted: " << mIsDeleted << std::endl; } - case ESM::REC_SKIL: + + template <> + void Record::print() { - record = std::make_unique>(); - break; + std::cout << " Chance for None: " << (int)mData.mChanceNone << std::endl; + std::cout << " Flags: " << itemListFlags(mData.mFlags) << std::endl; + std::cout << " Number of items: " << mData.mList.size() << std::endl; + for (const ESM::LevelledListBase::LevelItem& item : mData.mList) + std::cout << " Inventory: Level: " << item.mLevel << " Item: " << item.mId << std::endl; + std::cout << " Deleted: " << mIsDeleted << std::endl; } - case ESM::REC_SNDG: + + template <> + void Record::print() { - record = std::make_unique>(); - break; + if (!mData.mName.empty()) + std::cout << " Name: " << mData.mName << std::endl; + if (!mData.mModel.empty()) + std::cout << " Model: " << mData.mModel << std::endl; + if (!mData.mIcon.empty()) + std::cout << " Icon: " << mData.mIcon << std::endl; + if (!mData.mScript.empty()) + std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Flags: " << lightFlags(mData.mData.mFlags) << std::endl; + std::cout << " Weight: " << mData.mData.mWeight << std::endl; + std::cout << " Value: " << mData.mData.mValue << std::endl; + std::cout << " Sound: " << mData.mSound << std::endl; + std::cout << " Duration: " << mData.mData.mTime << std::endl; + std::cout << " Radius: " << mData.mData.mRadius << std::endl; + std::cout << " Color: " << mData.mData.mColor << std::endl; + std::cout << " Deleted: " << mIsDeleted << std::endl; } - case ESM::REC_SOUN: + + template <> + void Record::print() { - record = std::make_unique>(); - break; + std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Icon: " << mData.mIcon << std::endl; + if (!mData.mScript.empty()) + std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Weight: " << mData.mData.mWeight << std::endl; + std::cout << " Value: " << mData.mData.mValue << std::endl; + std::cout << " Quality: " << mData.mData.mQuality << std::endl; + std::cout << " Uses: " << mData.mData.mUses << std::endl; + std::cout << " Deleted: " << mIsDeleted << std::endl; } - case ESM::REC_SPEL: + + template <> + void Record::print() { - record = std::make_unique>(); - break; + std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Icon: " << mData.mIcon << std::endl; + if (!mData.mScript.empty()) + std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Weight: " << mData.mData.mWeight << std::endl; + std::cout << " Value: " << mData.mData.mValue << std::endl; + std::cout << " Quality: " << mData.mData.mQuality << std::endl; + std::cout << " Uses: " << mData.mData.mUses << std::endl; + std::cout << " Deleted: " << mIsDeleted << std::endl; } - case ESM::REC_STAT: + + template <> + void Record::print() { - record = std::make_unique>(); - break; + std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Icon: " << mData.mIcon << std::endl; + if (!mData.mScript.empty()) + std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Weight: " << mData.mData.mWeight << std::endl; + std::cout << " Value: " << mData.mData.mValue << std::endl; + std::cout << " Quality: " << mData.mData.mQuality << std::endl; + std::cout << " Uses: " << mData.mData.mUses << std::endl; + std::cout << " Deleted: " << mIsDeleted << std::endl; } - case ESM::REC_WEAP: + + template <> + void Record::print() { - record = std::make_unique>(); - break; + std::cout << " Id: " << mData.mId << std::endl; + std::cout << " Index: " << mData.mIndex << std::endl; + std::cout << " Texture: " << mData.mTexture << std::endl; + std::cout << " Deleted: " << mIsDeleted << std::endl; } - case ESM::REC_SSCR: + + template <> + void Record::print() { - record = std::make_unique>(); - break; - } - default: - break; - } - if (record) + std::cout << " Index: " << magicEffectLabel(mData.mIndex) << " (" << mData.mIndex << ")" << std::endl; + std::cout << " Description: " << mData.mDescription << std::endl; + std::cout << " Icon: " << mData.mIcon << std::endl; + std::cout << " Flags: " << magicEffectFlags(mData.mData.mFlags) << std::endl; + std::cout << " Particle Texture: " << mData.mParticle << std::endl; + if (!mData.mCasting.empty()) + std::cout << " Casting Static: " << mData.mCasting << std::endl; + if (!mData.mCastSound.empty()) + std::cout << " Casting Sound: " << mData.mCastSound << std::endl; + if (!mData.mBolt.empty()) + std::cout << " Bolt Static: " << mData.mBolt << std::endl; + if (!mData.mBoltSound.empty()) + std::cout << " Bolt Sound: " << mData.mBoltSound << std::endl; + if (!mData.mHit.empty()) + std::cout << " Hit Static: " << mData.mHit << std::endl; + if (!mData.mHitSound.empty()) + std::cout << " Hit Sound: " << mData.mHitSound << std::endl; + if (!mData.mArea.empty()) + std::cout << " Area Static: " << mData.mArea << std::endl; + if (!mData.mAreaSound.empty()) + std::cout << " Area Sound: " << mData.mAreaSound << std::endl; + std::cout << " School: " << schoolLabel(mData.mData.mSchool) << " (" << mData.mData.mSchool << ")" + << std::endl; + std::cout << " Base Cost: " << mData.mData.mBaseCost << std::endl; + std::cout << " Unknown 1: " << mData.mData.mUnknown1 << std::endl; + std::cout << " Speed: " << mData.mData.mSpeed << std::endl; + std::cout << " Unknown 2: " << mData.mData.mUnknown2 << std::endl; + std::cout << " RGB Color: " + << "(" << mData.mData.mRed << "," << mData.mData.mGreen << "," << mData.mData.mBlue << ")" + << std::endl; + } + + template <> + void Record::print() { - record->mType = type; + std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + std::cout << " Icon: " << mData.mIcon << std::endl; + if (!mData.mScript.empty()) + std::cout << " Script: " << mData.mScript << std::endl; + std::cout << " Weight: " << mData.mData.mWeight << std::endl; + std::cout << " Value: " << mData.mData.mValue << std::endl; + std::cout << " Is Key: " << mData.mData.mIsKey << std::endl; + std::cout << " Deleted: " << mIsDeleted << std::endl; } - return record; -} - -template<> -void Record::print() -{ - std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Model: " << mData.mModel << std::endl; - std::cout << " Script: " << mData.mScript << std::endl; - std::cout << " Deleted: " << mIsDeleted << std::endl; -} -template<> -void Record::print() -{ - std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Model: " << mData.mModel << std::endl; - std::cout << " Icon: " << mData.mIcon << std::endl; - if (!mData.mScript.empty()) - std::cout << " Script: " << mData.mScript << std::endl; - std::cout << " Weight: " << mData.mData.mWeight << std::endl; - std::cout << " Value: " << mData.mData.mValue << std::endl; - std::cout << " AutoCalc: " << mData.mData.mAutoCalc << std::endl; - printEffectList(mData.mEffects); - std::cout << " Deleted: " << mIsDeleted << std::endl; -} - -template<> -void Record::print() -{ - std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Model: " << mData.mModel << std::endl; - std::cout << " Icon: " << mData.mIcon << std::endl; - if (!mData.mScript.empty()) - std::cout << " Script: " << mData.mScript << std::endl; - if (!mData.mEnchant.empty()) - std::cout << " Enchantment: " << mData.mEnchant << std::endl; - std::cout << " Type: " << armorTypeLabel(mData.mData.mType) - << " (" << mData.mData.mType << ")" << std::endl; - std::cout << " Weight: " << mData.mData.mWeight << std::endl; - std::cout << " Value: " << mData.mData.mValue << std::endl; - std::cout << " Health: " << mData.mData.mHealth << std::endl; - std::cout << " Armor: " << mData.mData.mArmor << std::endl; - std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl; - for (const ESM::PartReference &part : mData.mParts.mParts) + template <> + void Record::print() { - std::cout << " Body Part: " << bodyPartLabel(part.mPart) - << " (" << (int)(part.mPart) << ")" << std::endl; - std::cout << " Male Name: " << part.mMale << std::endl; - if (!part.mFemale.empty()) - std::cout << " Female Name: " << part.mFemale << std::endl; - } - - std::cout << " Deleted: " << mIsDeleted << std::endl; -} + std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Animation: " << mData.mModel << std::endl; + std::cout << " Hair Model: " << mData.mHair << std::endl; + std::cout << " Head Model: " << mData.mHead << std::endl; + std::cout << " Race: " << mData.mRace << std::endl; + std::cout << " Class: " << mData.mClass << std::endl; + if (!mData.mScript.empty()) + std::cout << " Script: " << mData.mScript << std::endl; + if (!mData.mFaction.empty()) + std::cout << " Faction: " << mData.mFaction << std::endl; + std::cout << " Flags: " << npcFlags((int)mData.mFlags) << std::endl; + if (mData.mBloodType != 0) + std::cout << " Blood Type: " << mData.mBloodType + 1 << std::endl; + + if (mData.mNpdtType == ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS) + { + std::cout << " Level: " << mData.mNpdt.mLevel << std::endl; + std::cout << " Reputation: " << (int)mData.mNpdt.mReputation << std::endl; + std::cout << " Disposition: " << (int)mData.mNpdt.mDisposition << std::endl; + std::cout << " Rank: " << (int)mData.mNpdt.mRank << std::endl; + std::cout << " Gold: " << mData.mNpdt.mGold << std::endl; + } + else + { + std::cout << " Level: " << mData.mNpdt.mLevel << std::endl; + std::cout << " Reputation: " << (int)mData.mNpdt.mReputation << std::endl; + std::cout << " Disposition: " << (int)mData.mNpdt.mDisposition << std::endl; + std::cout << " Rank: " << (int)mData.mNpdt.mRank << std::endl; + + std::cout << " Attributes:" << std::endl; + std::cout << " Strength: " << (int)mData.mNpdt.mStrength << std::endl; + std::cout << " Intelligence: " << (int)mData.mNpdt.mIntelligence << std::endl; + std::cout << " Willpower: " << (int)mData.mNpdt.mWillpower << std::endl; + std::cout << " Agility: " << (int)mData.mNpdt.mAgility << std::endl; + std::cout << " Speed: " << (int)mData.mNpdt.mSpeed << std::endl; + std::cout << " Endurance: " << (int)mData.mNpdt.mEndurance << std::endl; + std::cout << " Personality: " << (int)mData.mNpdt.mPersonality << std::endl; + std::cout << " Luck: " << (int)mData.mNpdt.mLuck << std::endl; + + std::cout << " Skills:" << std::endl; + for (int i = 0; i != ESM::Skill::Length; i++) + std::cout << " " << skillLabel(i) << ": " << (int)(mData.mNpdt.mSkills[i]) << std::endl; + + std::cout << " Health: " << mData.mNpdt.mHealth << std::endl; + std::cout << " Magicka: " << mData.mNpdt.mMana << std::endl; + std::cout << " Fatigue: " << mData.mNpdt.mFatigue << std::endl; + std::cout << " Gold: " << mData.mNpdt.mGold << std::endl; + } -template<> -void Record::print() -{ - std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Model: " << mData.mModel << std::endl; - std::cout << " Icon: " << mData.mIcon << std::endl; - std::cout << " Script: " << mData.mScript << std::endl; - std::cout << " Type: " << apparatusTypeLabel(mData.mData.mType) - << " (" << mData.mData.mType << ")" << std::endl; - std::cout << " Weight: " << mData.mData.mWeight << std::endl; - std::cout << " Value: " << mData.mData.mValue << std::endl; - std::cout << " Quality: " << mData.mData.mQuality << std::endl; - std::cout << " Deleted: " << mIsDeleted << std::endl; -} + for (const ESM::ContItem& item : mData.mInventory.mList) + std::cout << " Inventory: Count: " << Misc::StringUtils::format("%4d", item.mCount) + << " Item: " << item.mItem << std::endl; -template<> -void Record::print() -{ - std::cout << " Race: " << mData.mRace << std::endl; - std::cout << " Model: " << mData.mModel << std::endl; - std::cout << " Type: " << meshTypeLabel(mData.mData.mType) - << " (" << (int)mData.mData.mType << ")" << std::endl; - std::cout << " Flags: " << bodyPartFlags(mData.mData.mFlags) << std::endl; - std::cout << " Part: " << meshPartLabel(mData.mData.mPart) - << " (" << (int)mData.mData.mPart << ")" << std::endl; - std::cout << " Vampire: " << (int)mData.mData.mVampire << std::endl; - std::cout << " Deleted: " << mIsDeleted << std::endl; -} + for (const std::string& spell : mData.mSpells.mList) + std::cout << " Spell: " << spell << std::endl; -template<> -void Record::print() -{ - std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Model: " << mData.mModel << std::endl; - std::cout << " Icon: " << mData.mIcon << std::endl; - if (!mData.mScript.empty()) - std::cout << " Script: " << mData.mScript << std::endl; - if (!mData.mEnchant.empty()) - std::cout << " Enchantment: " << mData.mEnchant << std::endl; - std::cout << " Weight: " << mData.mData.mWeight << std::endl; - std::cout << " Value: " << mData.mData.mValue << std::endl; - std::cout << " IsScroll: " << mData.mData.mIsScroll << std::endl; - std::cout << " SkillId: " << mData.mData.mSkillId << std::endl; - std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl; - if (mPrintPlain) - { - std::cout << " Text:" << std::endl; - std::cout << "START--------------------------------------" << std::endl; - std::cout << mData.mText << std::endl; - std::cout << "END----------------------------------------" << std::endl; - } - else - { - std::cout << " Text: [skipped]" << std::endl; - } - std::cout << " Deleted: " << mIsDeleted << std::endl; -} + printTransport(mData.getTransport()); -template<> -void Record::print() -{ - std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Texture: " << mData.mTexture << std::endl; - std::cout << " Description: " << mData.mDescription << std::endl; - for (const std::string &power : mData.mPowers.mList) - std::cout << " Power: " << power << std::endl; - std::cout << " Deleted: " << mIsDeleted << std::endl; -} + std::cout << " Artificial Intelligence: " << std::endl; + std::cout << " AI Hello:" << (int)mData.mAiData.mHello << std::endl; + std::cout << " AI Fight:" << (int)mData.mAiData.mFight << std::endl; + std::cout << " AI Flee:" << (int)mData.mAiData.mFlee << std::endl; + std::cout << " AI Alarm:" << (int)mData.mAiData.mAlarm << std::endl; + std::cout << " AI U1:" << (int)mData.mAiData.mU1 << std::endl; + std::cout << " AI U2:" << (int)mData.mAiData.mU2 << std::endl; + std::cout << " AI U3:" << (int)mData.mAiData.mU3 << std::endl; + std::cout << " AI Services:" << Misc::StringUtils::format("0x%08X", mData.mAiData.mServices) << std::endl; -template<> -void Record::print() -{ - // None of the cells have names... - if (!mData.mName.empty()) - std::cout << " Name: " << mData.mName << std::endl; - if (!mData.mRegion.empty()) - std::cout << " Region: " << mData.mRegion << std::endl; - std::cout << " Flags: " << cellFlags(mData.mData.mFlags) << std::endl; + for (const ESM::AIPackage& package : mData.mAiPackage.mList) + printAIPackage(package); - std::cout << " Coordinates: " << " (" << mData.getGridX() << "," - << mData.getGridY() << ")" << std::endl; + std::cout << " Deleted: " << mIsDeleted << std::endl; + } - if (mData.mData.mFlags & ESM::Cell::Interior && - !(mData.mData.mFlags & ESM::Cell::QuasiEx)) + template <> + void Record::print() { - if (mData.hasAmbient()) + std::cout << " Cell: " << mData.mCell << std::endl; + std::cout << " Coordinates: (" << mData.mData.mX << "," << mData.mData.mY << ")" << std::endl; + std::cout << " Unknown S1: " << mData.mData.mS1 << std::endl; + if ((unsigned int)mData.mData.mS2 != mData.mPoints.size()) + std::cout << " Reported Point Count: " << mData.mData.mS2 << std::endl; + std::cout << " Point Count: " << mData.mPoints.size() << std::endl; + std::cout << " Edge Count: " << mData.mEdges.size() << std::endl; + + int i = 0; + for (const ESM::Pathgrid::Point& point : mData.mPoints) { - // TODO: see if we can change the integer representation to something more sensible - std::cout << " Ambient Light Color: " << mData.mAmbi.mAmbient << std::endl; - std::cout << " Sunlight Color: " << mData.mAmbi.mSunlight << std::endl; - std::cout << " Fog Color: " << mData.mAmbi.mFog << std::endl; - std::cout << " Fog Density: " << mData.mAmbi.mFogDensity << std::endl; + std::cout << " Point[" << i << "]:" << std::endl; + std::cout << " Coordinates: (" << point.mX << "," << point.mY << "," << point.mZ << ")" << std::endl; + std::cout << " Auto-Generated: " << (int)point.mAutogenerated << std::endl; + std::cout << " Connections: " << (int)point.mConnectionNum << std::endl; + std::cout << " Unknown: " << point.mUnknown << std::endl; + i++; } - else + + i = 0; + for (const ESM::Pathgrid::Edge& edge : mData.mEdges) { - std::cout << " No Ambient Information" << std::endl; + std::cout << " Edge[" << i << "]: " << edge.mV0 << " -> " << edge.mV1 << std::endl; + if (edge.mV0 >= mData.mData.mS2 || edge.mV1 >= mData.mData.mS2) + std::cout << " BAD POINT IN EDGE!" << std::endl; + i++; } - std::cout << " Water Level: " << mData.mWater << std::endl; - } - else - std::cout << " Map Color: " << Misc::StringUtils::format("0x%08X", mData.mMapColor) << std::endl; - std::cout << " Water Level Int: " << mData.mWaterInt << std::endl; - std::cout << " RefId counter: " << mData.mRefNumCounter << std::endl; - std::cout << " Deleted: " << mIsDeleted << std::endl; - -} - -template<> -void Record::print() -{ - std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Description: " << mData.mDescription << std::endl; - std::cout << " Playable: " << mData.mData.mIsPlayable << std::endl; - std::cout << " AutoCalc: " << mData.mData.mCalc << std::endl; - std::cout << " Attribute1: " << attributeLabel(mData.mData.mAttribute[0]) - << " (" << mData.mData.mAttribute[0] << ")" << std::endl; - std::cout << " Attribute2: " << attributeLabel(mData.mData.mAttribute[1]) - << " (" << mData.mData.mAttribute[1] << ")" << std::endl; - std::cout << " Specialization: " << specializationLabel(mData.mData.mSpecialization) - << " (" << mData.mData.mSpecialization << ")" << std::endl; - for (int i = 0; i != 5; i++) - std::cout << " Minor Skill: " << skillLabel(mData.mData.mSkills[i][0]) - << " (" << mData.mData.mSkills[i][0] << ")" << std::endl; - for (int i = 0; i != 5; i++) - std::cout << " Major Skill: " << skillLabel(mData.mData.mSkills[i][1]) - << " (" << mData.mData.mSkills[i][1] << ")" << std::endl; - std::cout << " Deleted: " << mIsDeleted << std::endl; -} -template<> -void Record::print() -{ - std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Model: " << mData.mModel << std::endl; - std::cout << " Icon: " << mData.mIcon << std::endl; - if (!mData.mScript.empty()) - std::cout << " Script: " << mData.mScript << std::endl; - if (!mData.mEnchant.empty()) - std::cout << " Enchantment: " << mData.mEnchant << std::endl; - std::cout << " Type: " << clothingTypeLabel(mData.mData.mType) - << " (" << mData.mData.mType << ")" << std::endl; - std::cout << " Weight: " << mData.mData.mWeight << std::endl; - std::cout << " Value: " << mData.mData.mValue << std::endl; - std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl; - for (const ESM::PartReference &part : mData.mParts.mParts) - { - std::cout << " Body Part: " << bodyPartLabel(part.mPart) - << " (" << (int)(part.mPart) << ")" << std::endl; - std::cout << " Male Name: " << part.mMale << std::endl; - if (!part.mFemale.empty()) - std::cout << " Female Name: " << part.mFemale << std::endl; + std::cout << " Deleted: " << mIsDeleted << std::endl; } - std::cout << " Deleted: " << mIsDeleted << std::endl; -} -template<> -void Record::print() -{ - std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Model: " << mData.mModel << std::endl; - if (!mData.mScript.empty()) - std::cout << " Script: " << mData.mScript << std::endl; - std::cout << " Flags: " << containerFlags(mData.mFlags) << std::endl; - std::cout << " Weight: " << mData.mWeight << std::endl; - for (const ESM::ContItem &item : mData.mInventory.mList) - std::cout << " Inventory: Count: " << Misc::StringUtils::format("%4d", item.mCount) - << " Item: " << item.mItem << std::endl; - std::cout << " Deleted: " << mIsDeleted << std::endl; -} + template <> + void Record::print() + { + static const char* sAttributeNames[8] + = { "Strength", "Intelligence", "Willpower", "Agility", "Speed", "Endurance", "Personality", "Luck" }; -template<> -void Record::print() -{ - std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Model: " << mData.mModel << std::endl; - std::cout << " Script: " << mData.mScript << std::endl; - std::cout << " Flags: " << creatureFlags((int)mData.mFlags) << std::endl; - std::cout << " Blood Type: " << mData.mBloodType+1 << std::endl; - std::cout << " Original: " << mData.mOriginal << std::endl; - std::cout << " Scale: " << mData.mScale << std::endl; - - std::cout << " Type: " << creatureTypeLabel(mData.mData.mType) - << " (" << mData.mData.mType << ")" << std::endl; - std::cout << " Level: " << mData.mData.mLevel << std::endl; - - std::cout << " Attributes:" << std::endl; - std::cout << " Strength: " << mData.mData.mStrength << std::endl; - std::cout << " Intelligence: " << mData.mData.mIntelligence << std::endl; - std::cout << " Willpower: " << mData.mData.mWillpower << std::endl; - std::cout << " Agility: " << mData.mData.mAgility << std::endl; - std::cout << " Speed: " << mData.mData.mSpeed << std::endl; - std::cout << " Endurance: " << mData.mData.mEndurance << std::endl; - std::cout << " Personality: " << mData.mData.mPersonality << std::endl; - std::cout << " Luck: " << mData.mData.mLuck << std::endl; - - std::cout << " Health: " << mData.mData.mHealth << std::endl; - std::cout << " Magicka: " << mData.mData.mMana << std::endl; - std::cout << " Fatigue: " << mData.mData.mFatigue << std::endl; - std::cout << " Soul: " << mData.mData.mSoul << std::endl; - std::cout << " Combat: " << mData.mData.mCombat << std::endl; - std::cout << " Magic: " << mData.mData.mMagic << std::endl; - std::cout << " Stealth: " << mData.mData.mStealth << std::endl; - std::cout << " Attack1: " << mData.mData.mAttack[0] - << "-" << mData.mData.mAttack[1] << std::endl; - std::cout << " Attack2: " << mData.mData.mAttack[2] - << "-" << mData.mData.mAttack[3] << std::endl; - std::cout << " Attack3: " << mData.mData.mAttack[4] - << "-" << mData.mData.mAttack[5] << std::endl; - std::cout << " Gold: " << mData.mData.mGold << std::endl; - - for (const ESM::ContItem &item : mData.mInventory.mList) - std::cout << " Inventory: Count: " << Misc::StringUtils::format("%4d", item.mCount) - << " Item: " << item.mItem << std::endl; - - for (const std::string &spell : mData.mSpells.mList) - std::cout << " Spell: " << spell << std::endl; - - printTransport(mData.getTransport()); - - std::cout << " Artificial Intelligence: " << std::endl; - std::cout << " AI Hello:" << (int)mData.mAiData.mHello << std::endl; - std::cout << " AI Fight:" << (int)mData.mAiData.mFight << std::endl; - std::cout << " AI Flee:" << (int)mData.mAiData.mFlee << std::endl; - std::cout << " AI Alarm:" << (int)mData.mAiData.mAlarm << std::endl; - std::cout << " AI U1:" << (int)mData.mAiData.mU1 << std::endl; - std::cout << " AI U2:" << (int)mData.mAiData.mU2 << std::endl; - std::cout << " AI U3:" << (int)mData.mAiData.mU3 << std::endl; - std::cout << " AI Services:" << Misc::StringUtils::format("0x%08X", mData.mAiData.mServices) << std::endl; - - for (const ESM::AIPackage &package : mData.mAiPackage.mList) - printAIPackage(package); - std::cout << " Deleted: " << mIsDeleted << std::endl; -} + std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Description: " << mData.mDescription << std::endl; + std::cout << " Flags: " << raceFlags(mData.mData.mFlags) << std::endl; -template<> -void Record::print() -{ - std::cout << " Type: " << dialogTypeLabel(mData.mType) - << " (" << (int)mData.mType << ")" << std::endl; - std::cout << " Deleted: " << mIsDeleted << std::endl; - // Sadly, there are no DialInfos, because the loader dumps as it - // loads, rather than loading and then dumping. :-( Anyone mind if - // I change this? - for (const ESM::DialInfo &info : mData.mInfo) - std::cout << "INFO!" << info.mId << std::endl; -} + for (int i = 0; i < 2; ++i) + { + bool male = i == 0; -template<> -void Record::print() -{ - std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Model: " << mData.mModel << std::endl; - std::cout << " Script: " << mData.mScript << std::endl; - std::cout << " OpenSound: " << mData.mOpenSound << std::endl; - std::cout << " CloseSound: " << mData.mCloseSound << std::endl; - std::cout << " Deleted: " << mIsDeleted << std::endl; -} + std::cout << (male ? " Male:" : " Female:") << std::endl; -template<> -void Record::print() -{ - std::cout << " Type: " << enchantTypeLabel(mData.mData.mType) - << " (" << mData.mData.mType << ")" << std::endl; - std::cout << " Cost: " << mData.mData.mCost << std::endl; - std::cout << " Charge: " << mData.mData.mCharge << std::endl; - std::cout << " Flags: " << enchantmentFlags(mData.mData.mFlags) << std::endl; - printEffectList(mData.mEffects); - std::cout << " Deleted: " << mIsDeleted << std::endl; -} + for (int j = 0; j < 8; ++j) + std::cout << " " << sAttributeNames[j] << ": " << mData.mData.mAttributeValues[j].getValue(male) + << std::endl; -template<> -void Record::print() -{ - std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Hidden: " << mData.mData.mIsHidden << std::endl; - std::cout << " Attribute1: " << attributeLabel(mData.mData.mAttribute[0]) - << " (" << mData.mData.mAttribute[0] << ")" << std::endl; - std::cout << " Attribute2: " << attributeLabel(mData.mData.mAttribute[1]) - << " (" << mData.mData.mAttribute[1] << ")" << std::endl; - for (int skill : mData.mData.mSkills) - if (skill != -1) - std::cout << " Skill: " << skillLabel(skill) << " (" << skill << ")" << std::endl; - for (int i = 0; i != 10; i++) - if (!mData.mRanks[i].empty()) - { - std::cout << " Rank: " << mData.mRanks[i] << std::endl; - std::cout << " Attribute1 Requirement: " - << mData.mData.mRankData[i].mAttribute1 << std::endl; - std::cout << " Attribute2 Requirement: " - << mData.mData.mRankData[i].mAttribute2 << std::endl; - std::cout << " One Skill at Level: " - << mData.mData.mRankData[i].mPrimarySkill << std::endl; - std::cout << " Two Skills at Level: " - << mData.mData.mRankData[i].mFavouredSkill << std::endl; - std::cout << " Faction Reaction: " - << mData.mData.mRankData[i].mFactReaction << std::endl; + std::cout << " Height: " << mData.mData.mHeight.getValue(male) << std::endl; + std::cout << " Weight: " << mData.mData.mWeight.getValue(male) << std::endl; } - for (const auto &reaction : mData.mReactions) - std::cout << " Reaction: " << reaction.second << " = " << reaction.first << std::endl; - std::cout << " Deleted: " << mIsDeleted << std::endl; -} - -template<> -void Record::print() -{ - std::cout << " " << mData.mValue << std::endl; - std::cout << " Deleted: " << mIsDeleted << std::endl; -} -template<> -void Record::print() -{ - std::cout << " " << mData.mValue << std::endl; -} + for (int i = 0; i != 7; i++) + // Not all races have 7 skills. + if (mData.mData.mBonus[i].mSkill != -1) + std::cout << " Skill: " << skillLabel(mData.mData.mBonus[i].mSkill) << " (" + << mData.mData.mBonus[i].mSkill << ") = " << mData.mData.mBonus[i].mBonus << std::endl; -template<> -void Record::print() -{ - std::cout << " Id: " << mData.mId << std::endl; - if (!mData.mPrev.empty()) - std::cout << " Previous ID: " << mData.mPrev << std::endl; - if (!mData.mNext.empty()) - std::cout << " Next ID: " << mData.mNext << std::endl; - std::cout << " Text: " << mData.mResponse << std::endl; - if (!mData.mActor.empty()) - std::cout << " Actor: " << mData.mActor << std::endl; - if (!mData.mRace.empty()) - std::cout << " Race: " << mData.mRace << std::endl; - if (!mData.mClass.empty()) - std::cout << " Class: " << mData.mClass << std::endl; - std::cout << " Factionless: " << mData.mFactionLess << std::endl; - if (!mData.mFaction.empty()) - std::cout << " NPC Faction: " << mData.mFaction << std::endl; - if (mData.mData.mRank != -1) - std::cout << " NPC Rank: " << (int)mData.mData.mRank << std::endl; - if (!mData.mPcFaction.empty()) - std::cout << " PC Faction: " << mData.mPcFaction << std::endl; - // CHANGE? non-standard capitalization mPCrank -> mPCRank (mPcRank?) - if (mData.mData.mPCrank != -1) - std::cout << " PC Rank: " << (int)mData.mData.mPCrank << std::endl; - if (!mData.mCell.empty()) - std::cout << " Cell: " << mData.mCell << std::endl; - if (mData.mData.mDisposition > 0) - std::cout << " Disposition/Journal index: " << mData.mData.mDisposition << std::endl; - if (mData.mData.mGender != ESM::DialInfo::NA) - std::cout << " Gender: " << mData.mData.mGender << std::endl; - if (!mData.mSound.empty()) - std::cout << " Sound File: " << mData.mSound << std::endl; + for (const std::string& power : mData.mPowers.mList) + std::cout << " Power: " << power << std::endl; + std::cout << " Deleted: " << mIsDeleted << std::endl; + } - std::cout << " Quest Status: " << questStatusLabel(mData.mQuestStatus) - << " (" << mData.mQuestStatus << ")" << std::endl; - std::cout << " Unknown1: " << mData.mData.mUnknown1 << std::endl; - std::cout << " Unknown2: " << (int)mData.mData.mUnknown2 << std::endl; + template <> + void Record::print() + { + std::cout << " Name: " << mData.mName << std::endl; - for (const ESM::DialInfo::SelectStruct &rule : mData.mSelects) - std::cout << " Select Rule: " << ruleString(rule) << std::endl; + std::cout << " Weather:" << std::endl; + std::cout << " Clear: " << (int)mData.mData.mClear << std::endl; + std::cout << " Cloudy: " << (int)mData.mData.mCloudy << std::endl; + std::cout << " Foggy: " << (int)mData.mData.mFoggy << std::endl; + std::cout << " Overcast: " << (int)mData.mData.mOvercast << std::endl; + std::cout << " Rain: " << (int)mData.mData.mOvercast << std::endl; + std::cout << " Thunder: " << (int)mData.mData.mThunder << std::endl; + std::cout << " Ash: " << (int)mData.mData.mAsh << std::endl; + std::cout << " Blight: " << (int)mData.mData.mBlight << std::endl; + std::cout << " Snow: " << (int)mData.mData.mSnow << std::endl; + std::cout << " Blizzard: " << (int)mData.mData.mBlizzard << std::endl; + std::cout << " Map Color: " << mData.mMapColor << std::endl; + if (!mData.mSleepList.empty()) + std::cout << " Sleep List: " << mData.mSleepList << std::endl; + for (const ESM::Region::SoundRef& soundref : mData.mSoundList) + std::cout << " Sound: " << (int)soundref.mChance << " = " << soundref.mSound << std::endl; + } + + template <> + void Record::print() + { + std::cout << " Name: " << mData.mId << std::endl; + + std::cout << " Num Shorts: " << mData.mData.mNumShorts << std::endl; + std::cout << " Num Longs: " << mData.mData.mNumLongs << std::endl; + std::cout << " Num Floats: " << mData.mData.mNumFloats << std::endl; + std::cout << " Script Data Size: " << mData.mData.mScriptDataSize << std::endl; + std::cout << " Table Size: " << mData.mData.mStringTableSize << std::endl; + + for (const std::string& variable : mData.mVarNames) + std::cout << " Variable: " << variable << std::endl; + + std::cout << " ByteCode: "; + for (const unsigned char& byte : mData.mScriptData) + std::cout << Misc::StringUtils::format("%02X", (int)(byte)); + std::cout << std::endl; - if (!mData.mResultScript.empty()) - { if (mPrintPlain) { - std::cout << " Result Script:" << std::endl; + std::cout << " Script:" << std::endl; std::cout << "START--------------------------------------" << std::endl; - std::cout << mData.mResultScript << std::endl; + std::cout << mData.mScriptText << std::endl; std::cout << "END----------------------------------------" << std::endl; } else { - std::cout << " Result Script: [skipped]" << std::endl; + std::cout << " Script: [skipped]" << std::endl; } + + std::cout << " Deleted: " << mIsDeleted << std::endl; } - std::cout << " Deleted: " << mIsDeleted << std::endl; -} -template<> -void Record::print() -{ - std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Model: " << mData.mModel << std::endl; - std::cout << " Icon: " << mData.mIcon << std::endl; - if (!mData.mScript.empty()) - std::cout << " Script: " << mData.mScript << std::endl; - std::cout << " Weight: " << mData.mData.mWeight << std::endl; - std::cout << " Value: " << mData.mData.mValue << std::endl; - for (int i = 0; i !=4; i++) + template <> + void Record::print() { - // A value of -1 means no effect - if (mData.mData.mEffectID[i] == -1) continue; - std::cout << " Effect: " << magicEffectLabel(mData.mData.mEffectID[i]) - << " (" << mData.mData.mEffectID[i] << ")" << std::endl; - std::cout << " Skill: " << skillLabel(mData.mData.mSkills[i]) - << " (" << mData.mData.mSkills[i] << ")" << std::endl; - std::cout << " Attribute: " << attributeLabel(mData.mData.mAttributes[i]) - << " (" << mData.mData.mAttributes[i] << ")" << std::endl; + std::cout << " ID: " << skillLabel(mData.mIndex) << " (" << mData.mIndex << ")" << std::endl; + std::cout << " Description: " << mData.mDescription << std::endl; + std::cout << " Governing Attribute: " << attributeLabel(mData.mData.mAttribute) << " (" + << mData.mData.mAttribute << ")" << std::endl; + std::cout << " Specialization: " << specializationLabel(mData.mData.mSpecialization) << " (" + << mData.mData.mSpecialization << ")" << std::endl; + for (int i = 0; i != 4; i++) + std::cout << " UseValue[" << i << "]:" << mData.mData.mUseValue[i] << std::endl; } - std::cout << " Deleted: " << mIsDeleted << std::endl; -} - -template<> -void Record::print() -{ - std::cout << " Coordinates: (" << mData.mX << "," << mData.mY << ")" << std::endl; - std::cout << " Flags: " << landFlags(mData.mFlags) << std::endl; - std::cout << " DataTypes: " << mData.mDataTypes << std::endl; - if (const ESM::Land::LandData *data = mData.getLandData (mData.mDataTypes)) + template <> + void Record::print() { - std::cout << " Height Offset: " << data->mHeightOffset << std::endl; - // Lots of missing members. - std::cout << " Unknown1: " << data->mUnk1 << std::endl; - std::cout << " Unknown2: " << data->mUnk2 << std::endl; + if (!mData.mCreature.empty()) + std::cout << " Creature: " << mData.mCreature << std::endl; + std::cout << " Sound: " << mData.mSound << std::endl; + std::cout << " Type: " << soundTypeLabel(mData.mType) << " (" << mData.mType << ")" << std::endl; + std::cout << " Deleted: " << mIsDeleted << std::endl; } - mData.unloadData(); - std::cout << " Deleted: " << mIsDeleted << std::endl; -} - -template<> -void Record::print() -{ - std::cout << " Chance for None: " << (int)mData.mChanceNone << std::endl; - std::cout << " Flags: " << creatureListFlags(mData.mFlags) << std::endl; - std::cout << " Number of items: " << mData.mList.size() << std::endl; - for (const ESM::LevelledListBase::LevelItem &item : mData.mList) - std::cout << " Creature: Level: " << item.mLevel - << " Creature: " << item.mId << std::endl; - std::cout << " Deleted: " << mIsDeleted << std::endl; -} -template<> -void Record::print() -{ - std::cout << " Chance for None: " << (int)mData.mChanceNone << std::endl; - std::cout << " Flags: " << itemListFlags(mData.mFlags) << std::endl; - std::cout << " Number of items: " << mData.mList.size() << std::endl; - for (const ESM::LevelledListBase::LevelItem &item : mData.mList) - std::cout << " Inventory: Level: " << item.mLevel - << " Item: " << item.mId << std::endl; - std::cout << " Deleted: " << mIsDeleted << std::endl; -} + template <> + void Record::print() + { + std::cout << " Sound: " << mData.mSound << std::endl; + std::cout << " Volume: " << (int)mData.mData.mVolume << std::endl; + if (mData.mData.mMinRange != 0 && mData.mData.mMaxRange != 0) + std::cout << " Range: " << (int)mData.mData.mMinRange << " - " << (int)mData.mData.mMaxRange << std::endl; + std::cout << " Deleted: " << mIsDeleted << std::endl; + } -template<> -void Record::print() -{ - if (!mData.mName.empty()) + template <> + void Record::print() + { std::cout << " Name: " << mData.mName << std::endl; - if (!mData.mModel.empty()) - std::cout << " Model: " << mData.mModel << std::endl; - if (!mData.mIcon.empty()) - std::cout << " Icon: " << mData.mIcon << std::endl; - if (!mData.mScript.empty()) - std::cout << " Script: " << mData.mScript << std::endl; - std::cout << " Flags: " << lightFlags(mData.mData.mFlags) << std::endl; - std::cout << " Weight: " << mData.mData.mWeight << std::endl; - std::cout << " Value: " << mData.mData.mValue << std::endl; - std::cout << " Sound: " << mData.mSound << std::endl; - std::cout << " Duration: " << mData.mData.mTime << std::endl; - std::cout << " Radius: " << mData.mData.mRadius << std::endl; - std::cout << " Color: " << mData.mData.mColor << std::endl; - std::cout << " Deleted: " << mIsDeleted << std::endl; -} - -template<> -void Record::print() -{ - std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Model: " << mData.mModel << std::endl; - std::cout << " Icon: " << mData.mIcon << std::endl; - if (!mData.mScript.empty()) - std::cout << " Script: " << mData.mScript << std::endl; - std::cout << " Weight: " << mData.mData.mWeight << std::endl; - std::cout << " Value: " << mData.mData.mValue << std::endl; - std::cout << " Quality: " << mData.mData.mQuality << std::endl; - std::cout << " Uses: " << mData.mData.mUses << std::endl; - std::cout << " Deleted: " << mIsDeleted << std::endl; -} - -template<> -void Record::print() -{ - std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Model: " << mData.mModel << std::endl; - std::cout << " Icon: " << mData.mIcon << std::endl; - if (!mData.mScript.empty()) - std::cout << " Script: " << mData.mScript << std::endl; - std::cout << " Weight: " << mData.mData.mWeight << std::endl; - std::cout << " Value: " << mData.mData.mValue << std::endl; - std::cout << " Quality: " << mData.mData.mQuality << std::endl; - std::cout << " Uses: " << mData.mData.mUses << std::endl; - std::cout << " Deleted: " << mIsDeleted << std::endl; -} - -template<> -void Record::print() -{ - std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Model: " << mData.mModel << std::endl; - std::cout << " Icon: " << mData.mIcon << std::endl; - if (!mData.mScript.empty()) - std::cout << " Script: " << mData.mScript << std::endl; - std::cout << " Weight: " << mData.mData.mWeight << std::endl; - std::cout << " Value: " << mData.mData.mValue << std::endl; - std::cout << " Quality: " << mData.mData.mQuality << std::endl; - std::cout << " Uses: " << mData.mData.mUses << std::endl; - std::cout << " Deleted: " << mIsDeleted << std::endl; -} - -template<> -void Record::print() -{ - std::cout << " Id: " << mData.mId << std::endl; - std::cout << " Index: " << mData.mIndex << std::endl; - std::cout << " Texture: " << mData.mTexture << std::endl; - std::cout << " Deleted: " << mIsDeleted << std::endl; -} - -template<> -void Record::print() -{ - std::cout << " Index: " << magicEffectLabel(mData.mIndex) - << " (" << mData.mIndex << ")" << std::endl; - std::cout << " Description: " << mData.mDescription << std::endl; - std::cout << " Icon: " << mData.mIcon << std::endl; - std::cout << " Flags: " << magicEffectFlags(mData.mData.mFlags) << std::endl; - std::cout << " Particle Texture: " << mData.mParticle << std::endl; - if (!mData.mCasting.empty()) - std::cout << " Casting Static: " << mData.mCasting << std::endl; - if (!mData.mCastSound.empty()) - std::cout << " Casting Sound: " << mData.mCastSound << std::endl; - if (!mData.mBolt.empty()) - std::cout << " Bolt Static: " << mData.mBolt << std::endl; - if (!mData.mBoltSound.empty()) - std::cout << " Bolt Sound: " << mData.mBoltSound << std::endl; - if (!mData.mHit.empty()) - std::cout << " Hit Static: " << mData.mHit << std::endl; - if (!mData.mHitSound.empty()) - std::cout << " Hit Sound: " << mData.mHitSound << std::endl; - if (!mData.mArea.empty()) - std::cout << " Area Static: " << mData.mArea << std::endl; - if (!mData.mAreaSound.empty()) - std::cout << " Area Sound: " << mData.mAreaSound << std::endl; - std::cout << " School: " << schoolLabel(mData.mData.mSchool) - << " (" << mData.mData.mSchool << ")" << std::endl; - std::cout << " Base Cost: " << mData.mData.mBaseCost << std::endl; - std::cout << " Unknown 1: " << mData.mData.mUnknown1 << std::endl; - std::cout << " Speed: " << mData.mData.mSpeed << std::endl; - std::cout << " Unknown 2: " << mData.mData.mUnknown2 << std::endl; - std::cout << " RGB Color: " << "(" - << mData.mData.mRed << "," - << mData.mData.mGreen << "," - << mData.mData.mBlue << ")" << std::endl; -} - -template<> -void Record::print() -{ - std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Model: " << mData.mModel << std::endl; - std::cout << " Icon: " << mData.mIcon << std::endl; - if (!mData.mScript.empty()) - std::cout << " Script: " << mData.mScript << std::endl; - std::cout << " Weight: " << mData.mData.mWeight << std::endl; - std::cout << " Value: " << mData.mData.mValue << std::endl; - std::cout << " Is Key: " << mData.mData.mIsKey << std::endl; - std::cout << " Deleted: " << mIsDeleted << std::endl; -} - -template<> -void Record::print() -{ - std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Animation: " << mData.mModel << std::endl; - std::cout << " Hair Model: " << mData.mHair << std::endl; - std::cout << " Head Model: " << mData.mHead << std::endl; - std::cout << " Race: " << mData.mRace << std::endl; - std::cout << " Class: " << mData.mClass << std::endl; - if (!mData.mScript.empty()) - std::cout << " Script: " << mData.mScript << std::endl; - if (!mData.mFaction.empty()) - std::cout << " Faction: " << mData.mFaction << std::endl; - std::cout << " Flags: " << npcFlags((int)mData.mFlags) << std::endl; - if (mData.mBloodType != 0) - std::cout << " Blood Type: " << mData.mBloodType+1 << std::endl; + std::cout << " Type: " << spellTypeLabel(mData.mData.mType) << " (" << mData.mData.mType << ")" << std::endl; + std::cout << " Flags: " << spellFlags(mData.mData.mFlags) << std::endl; + std::cout << " Cost: " << mData.mData.mCost << std::endl; + printEffectList(mData.mEffects); + std::cout << " Deleted: " << mIsDeleted << std::endl; + } - if (mData.mNpdtType == ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS) + template <> + void Record::print() { - std::cout << " Level: " << mData.mNpdt.mLevel << std::endl; - std::cout << " Reputation: " << (int)mData.mNpdt.mReputation << std::endl; - std::cout << " Disposition: " << (int)mData.mNpdt.mDisposition << std::endl; - std::cout << " Rank: " << (int)mData.mNpdt.mRank << std::endl; - std::cout << " Gold: " << mData.mNpdt.mGold << std::endl; + std::cout << " Start Script: " << mData.mId << std::endl; + std::cout << " Start Data: " << mData.mData << std::endl; + std::cout << " Deleted: " << mIsDeleted << std::endl; } - else { - std::cout << " Level: " << mData.mNpdt.mLevel << std::endl; - std::cout << " Reputation: " << (int)mData.mNpdt.mReputation << std::endl; - std::cout << " Disposition: " << (int)mData.mNpdt.mDisposition << std::endl; - std::cout << " Rank: " << (int)mData.mNpdt.mRank << std::endl; - std::cout << " Attributes:" << std::endl; - std::cout << " Strength: " << (int)mData.mNpdt.mStrength << std::endl; - std::cout << " Intelligence: " << (int)mData.mNpdt.mIntelligence << std::endl; - std::cout << " Willpower: " << (int)mData.mNpdt.mWillpower << std::endl; - std::cout << " Agility: " << (int)mData.mNpdt.mAgility << std::endl; - std::cout << " Speed: " << (int)mData.mNpdt.mSpeed << std::endl; - std::cout << " Endurance: " << (int)mData.mNpdt.mEndurance << std::endl; - std::cout << " Personality: " << (int)mData.mNpdt.mPersonality << std::endl; - std::cout << " Luck: " << (int)mData.mNpdt.mLuck << std::endl; - - std::cout << " Skills:" << std::endl; - for (int i = 0; i != ESM::Skill::Length; i++) - std::cout << " " << skillLabel(i) << ": " - << (int)(mData.mNpdt.mSkills[i]) << std::endl; - - std::cout << " Health: " << mData.mNpdt.mHealth << std::endl; - std::cout << " Magicka: " << mData.mNpdt.mMana << std::endl; - std::cout << " Fatigue: " << mData.mNpdt.mFatigue << std::endl; - std::cout << " Gold: " << mData.mNpdt.mGold << std::endl; + template <> + void Record::print() + { + std::cout << " Model: " << mData.mModel << std::endl; } - for (const ESM::ContItem &item : mData.mInventory.mList) - std::cout << " Inventory: Count: " << Misc::StringUtils::format("%4d", item.mCount) - << " Item: " << item.mItem << std::endl; - - for (const std::string &spell : mData.mSpells.mList) - std::cout << " Spell: " << spell << std::endl; - - printTransport(mData.getTransport()); - - std::cout << " Artificial Intelligence: " << std::endl; - std::cout << " AI Hello:" << (int)mData.mAiData.mHello << std::endl; - std::cout << " AI Fight:" << (int)mData.mAiData.mFight << std::endl; - std::cout << " AI Flee:" << (int)mData.mAiData.mFlee << std::endl; - std::cout << " AI Alarm:" << (int)mData.mAiData.mAlarm << std::endl; - std::cout << " AI U1:" << (int)mData.mAiData.mU1 << std::endl; - std::cout << " AI U2:" << (int)mData.mAiData.mU2 << std::endl; - std::cout << " AI U3:" << (int)mData.mAiData.mU3 << std::endl; - std::cout << " AI Services:" << Misc::StringUtils::format("0x%08X", mData.mAiData.mServices) << std::endl; - - for (const ESM::AIPackage &package : mData.mAiPackage.mList) - printAIPackage(package); - - std::cout << " Deleted: " << mIsDeleted << std::endl; -} - -template<> -void Record::print() -{ - std::cout << " Cell: " << mData.mCell << std::endl; - std::cout << " Coordinates: (" << mData.mData.mX << "," << mData.mData.mY << ")" << std::endl; - std::cout << " Unknown S1: " << mData.mData.mS1 << std::endl; - if ((unsigned int)mData.mData.mS2 != mData.mPoints.size()) - std::cout << " Reported Point Count: " << mData.mData.mS2 << std::endl; - std::cout << " Point Count: " << mData.mPoints.size() << std::endl; - std::cout << " Edge Count: " << mData.mEdges.size() << std::endl; - - int i = 0; - for (const ESM::Pathgrid::Point &point : mData.mPoints) + template <> + void Record::print() { - std::cout << " Point[" << i << "]:" << std::endl; - std::cout << " Coordinates: (" << point.mX << "," - << point.mY << "," << point.mZ << ")" << std::endl; - std::cout << " Auto-Generated: " << (int)point.mAutogenerated << std::endl; - std::cout << " Connections: " << (int)point.mConnectionNum << std::endl; - std::cout << " Unknown: " << point.mUnknown << std::endl; - i++; + // No names on VFX bolts + if (!mData.mName.empty()) + std::cout << " Name: " << mData.mName << std::endl; + std::cout << " Model: " << mData.mModel << std::endl; + // No icons on VFX bolts or magic bolts + if (!mData.mIcon.empty()) + std::cout << " Icon: " << mData.mIcon << std::endl; + if (!mData.mScript.empty()) + std::cout << " Script: " << mData.mScript << std::endl; + if (!mData.mEnchant.empty()) + std::cout << " Enchantment: " << mData.mEnchant << std::endl; + std::cout << " Type: " << weaponTypeLabel(mData.mData.mType) << " (" << mData.mData.mType << ")" << std::endl; + std::cout << " Flags: " << weaponFlags(mData.mData.mFlags) << std::endl; + std::cout << " Weight: " << mData.mData.mWeight << std::endl; + std::cout << " Value: " << mData.mData.mValue << std::endl; + std::cout << " Health: " << mData.mData.mHealth << std::endl; + std::cout << " Speed: " << mData.mData.mSpeed << std::endl; + std::cout << " Reach: " << mData.mData.mReach << std::endl; + std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl; + if (mData.mData.mChop[0] != 0 && mData.mData.mChop[1] != 0) + std::cout << " Chop: " << (int)mData.mData.mChop[0] << "-" << (int)mData.mData.mChop[1] << std::endl; + if (mData.mData.mSlash[0] != 0 && mData.mData.mSlash[1] != 0) + std::cout << " Slash: " << (int)mData.mData.mSlash[0] << "-" << (int)mData.mData.mSlash[1] << std::endl; + if (mData.mData.mThrust[0] != 0 && mData.mData.mThrust[1] != 0) + std::cout << " Thrust: " << (int)mData.mData.mThrust[0] << "-" << (int)mData.mData.mThrust[1] << std::endl; + std::cout << " Deleted: " << mIsDeleted << std::endl; } - i = 0; - for (const ESM::Pathgrid::Edge &edge : mData.mEdges) + template <> + std::string Record::getId() const { - std::cout << " Edge[" << i << "]: " << edge.mV0 << " -> " << edge.mV1 << std::endl; - if (edge.mV0 >= mData.mData.mS2 || edge.mV1 >= mData.mData.mS2) - std::cout << " BAD POINT IN EDGE!" << std::endl; - i++; + return mData.mName; } - std::cout << " Deleted: " << mIsDeleted << std::endl; -} - -template<> -void Record::print() -{ - static const char *sAttributeNames[8] = + template <> + std::string Record::getId() const { - "Strength", "Intelligence", "Willpower", "Agility", - "Speed", "Endurance", "Personality", "Luck" - }; - - std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Description: " << mData.mDescription << std::endl; - std::cout << " Flags: " << raceFlags(mData.mData.mFlags) << std::endl; + return std::string(); // No ID for Land record + } - for (int i=0; i<2; ++i) + template <> + std::string Record::getId() const { - bool male = i==0; - - std::cout << (male ? " Male:" : " Female:") << std::endl; - - for (int j=0; j<8; ++j) - std::cout << " " << sAttributeNames[j] << ": " - << mData.mData.mAttributeValues[j].getValue (male) << std::endl; - - std::cout << " Height: " << mData.mData.mHeight.getValue (male) << std::endl; - std::cout << " Weight: " << mData.mData.mWeight.getValue (male) << std::endl; + return std::string(); // No ID for MagicEffect record } - for (int i = 0; i != 7; i++) - // Not all races have 7 skills. - if (mData.mData.mBonus[i].mSkill != -1) - std::cout << " Skill: " - << skillLabel(mData.mData.mBonus[i].mSkill) - << " (" << mData.mData.mBonus[i].mSkill << ") = " - << mData.mData.mBonus[i].mBonus << std::endl; - - for (const std::string &power : mData.mPowers.mList) - std::cout << " Power: " << power << std::endl; - - std::cout << " Deleted: " << mIsDeleted << std::endl; -} - -template<> -void Record::print() -{ - std::cout << " Name: " << mData.mName << std::endl; - - std::cout << " Weather:" << std::endl; - std::cout << " Clear: " << (int)mData.mData.mClear << std::endl; - std::cout << " Cloudy: " << (int)mData.mData.mCloudy << std::endl; - std::cout << " Foggy: " << (int)mData.mData.mFoggy << std::endl; - std::cout << " Overcast: " << (int)mData.mData.mOvercast << std::endl; - std::cout << " Rain: " << (int)mData.mData.mOvercast << std::endl; - std::cout << " Thunder: " << (int)mData.mData.mThunder << std::endl; - std::cout << " Ash: " << (int)mData.mData.mAsh << std::endl; - std::cout << " Blight: " << (int)mData.mData.mBlight << std::endl; - std::cout << " Snow: " << (int)mData.mData.mSnow << std::endl; - std::cout << " Blizzard: " << (int)mData.mData.mBlizzard << std::endl; - std::cout << " Map Color: " << mData.mMapColor << std::endl; - if (!mData.mSleepList.empty()) - std::cout << " Sleep List: " << mData.mSleepList << std::endl; - for (const ESM::Region::SoundRef &soundref : mData.mSoundList) - std::cout << " Sound: " << (int)soundref.mChance << " = " << soundref.mSound << std::endl; -} - -template<> -void Record::print() -{ - std::cout << " Name: " << mData.mId << std::endl; - - std::cout << " Num Shorts: " << mData.mData.mNumShorts << std::endl; - std::cout << " Num Longs: " << mData.mData.mNumLongs << std::endl; - std::cout << " Num Floats: " << mData.mData.mNumFloats << std::endl; - std::cout << " Script Data Size: " << mData.mData.mScriptDataSize << std::endl; - std::cout << " Table Size: " << mData.mData.mStringTableSize << std::endl; - - for (const std::string &variable : mData.mVarNames) - std::cout << " Variable: " << variable << std::endl; - - std::cout << " ByteCode: "; - for (const unsigned char &byte : mData.mScriptData) - std::cout << Misc::StringUtils::format("%02X", (int)(byte)); - std::cout << std::endl; - - if (mPrintPlain) + template <> + std::string Record::getId() const { - std::cout << " Script:" << std::endl; - std::cout << "START--------------------------------------" << std::endl; - std::cout << mData.mScriptText << std::endl; - std::cout << "END----------------------------------------" << std::endl; + return std::string(); // No ID for Pathgrid record } - else + + template <> + std::string Record::getId() const { - std::cout << " Script: [skipped]" << std::endl; + return std::string(); // No ID for Skill record } - std::cout << " Deleted: " << mIsDeleted << std::endl; -} - -template<> -void Record::print() -{ - std::cout << " ID: " << skillLabel(mData.mIndex) - << " (" << mData.mIndex << ")" << std::endl; - std::cout << " Description: " << mData.mDescription << std::endl; - std::cout << " Governing Attribute: " << attributeLabel(mData.mData.mAttribute) - << " (" << mData.mData.mAttribute << ")" << std::endl; - std::cout << " Specialization: " << specializationLabel(mData.mData.mSpecialization) - << " (" << mData.mData.mSpecialization << ")" << std::endl; - for (int i = 0; i != 4; i++) - std::cout << " UseValue[" << i << "]:" << mData.mData.mUseValue[i] << std::endl; -} - -template<> -void Record::print() -{ - if (!mData.mCreature.empty()) - std::cout << " Creature: " << mData.mCreature << std::endl; - std::cout << " Sound: " << mData.mSound << std::endl; - std::cout << " Type: " << soundTypeLabel(mData.mType) - << " (" << mData.mType << ")" << std::endl; - std::cout << " Deleted: " << mIsDeleted << std::endl; -} - -template<> -void Record::print() -{ - std::cout << " Sound: " << mData.mSound << std::endl; - std::cout << " Volume: " << (int)mData.mData.mVolume << std::endl; - if (mData.mData.mMinRange != 0 && mData.mData.mMaxRange != 0) - std::cout << " Range: " << (int)mData.mData.mMinRange << " - " - << (int)mData.mData.mMaxRange << std::endl; - std::cout << " Deleted: " << mIsDeleted << std::endl; -} - -template<> -void Record::print() -{ - std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Type: " << spellTypeLabel(mData.mData.mType) - << " (" << mData.mData.mType << ")" << std::endl; - std::cout << " Flags: " << spellFlags(mData.mData.mFlags) << std::endl; - std::cout << " Cost: " << mData.mData.mCost << std::endl; - printEffectList(mData.mEffects); - std::cout << " Deleted: " << mIsDeleted << std::endl; -} - -template<> -void Record::print() -{ - std::cout << " Start Script: " << mData.mId << std::endl; - std::cout << " Start Data: " << mData.mData << std::endl; - std::cout << " Deleted: " << mIsDeleted << std::endl; -} - -template<> -void Record::print() -{ - std::cout << " Model: " << mData.mModel << std::endl; -} - -template<> -void Record::print() -{ - // No names on VFX bolts - if (!mData.mName.empty()) - std::cout << " Name: " << mData.mName << std::endl; - std::cout << " Model: " << mData.mModel << std::endl; - // No icons on VFX bolts or magic bolts - if (!mData.mIcon.empty()) - std::cout << " Icon: " << mData.mIcon << std::endl; - if (!mData.mScript.empty()) - std::cout << " Script: " << mData.mScript << std::endl; - if (!mData.mEnchant.empty()) - std::cout << " Enchantment: " << mData.mEnchant << std::endl; - std::cout << " Type: " << weaponTypeLabel(mData.mData.mType) - << " (" << mData.mData.mType << ")" << std::endl; - std::cout << " Flags: " << weaponFlags(mData.mData.mFlags) << std::endl; - std::cout << " Weight: " << mData.mData.mWeight << std::endl; - std::cout << " Value: " << mData.mData.mValue << std::endl; - std::cout << " Health: " << mData.mData.mHealth << std::endl; - std::cout << " Speed: " << mData.mData.mSpeed << std::endl; - std::cout << " Reach: " << mData.mData.mReach << std::endl; - std::cout << " Enchantment Points: " << mData.mData.mEnchant << std::endl; - if (mData.mData.mChop[0] != 0 && mData.mData.mChop[1] != 0) - std::cout << " Chop: " << (int)mData.mData.mChop[0] << "-" - << (int)mData.mData.mChop[1] << std::endl; - if (mData.mData.mSlash[0] != 0 && mData.mData.mSlash[1] != 0) - std::cout << " Slash: " << (int)mData.mData.mSlash[0] << "-" - << (int)mData.mData.mSlash[1] << std::endl; - if (mData.mData.mThrust[0] != 0 && mData.mData.mThrust[1] != 0) - std::cout << " Thrust: " << (int)mData.mData.mThrust[0] << "-" - << (int)mData.mData.mThrust[1] << std::endl; - std::cout << " Deleted: " << mIsDeleted << std::endl; -} - -template<> -std::string Record::getId() const -{ - return mData.mName; -} - -template<> -std::string Record::getId() const -{ - return std::string(); // No ID for Land record -} - -template<> -std::string Record::getId() const -{ - return std::string(); // No ID for MagicEffect record -} - -template<> -std::string Record::getId() const -{ - return std::string(); // No ID for Pathgrid record -} - -template<> -std::string Record::getId() const -{ - return std::string(); // No ID for Skill record -} - } // end namespace diff --git a/apps/esmtool/record.hpp b/apps/esmtool/record.hpp index ef90dd1310..46987c44b2 100644 --- a/apps/esmtool/record.hpp +++ b/apps/esmtool/record.hpp @@ -1,8 +1,8 @@ #ifndef OPENMW_ESMTOOL_RECORD_H #define OPENMW_ESMTOOL_RECORD_H -#include #include +#include #include @@ -14,7 +14,8 @@ namespace ESM namespace EsmTool { - template class Record; + template + class Record; class RecordBase { @@ -25,9 +26,9 @@ namespace EsmTool bool mPrintPlain; public: - RecordBase () - : mFlags(0) - , mPrintPlain(false) + RecordBase() + : mFlags(0) + , mPrintPlain(false) { } @@ -35,32 +36,25 @@ namespace EsmTool virtual std::string getId() const = 0; - uint32_t getFlags() const { - return mFlags; - } + uint32_t getFlags() const { return mFlags; } - void setFlags(uint32_t flags) { - mFlags = flags; - } + void setFlags(uint32_t flags) { mFlags = flags; } - ESM::NAME getType() const { - return mType; - } + ESM::NAME getType() const { return mType; } - void setPrintPlain(bool plain) { - mPrintPlain = plain; - } + void setPrintPlain(bool plain) { mPrintPlain = plain; } - virtual void load(ESM::ESMReader &esm) = 0; - virtual void save(ESM::ESMWriter &esm) = 0; + virtual void load(ESM::ESMReader& esm) = 0; + virtual void save(ESM::ESMWriter& esm) = 0; virtual void print() = 0; static std::unique_ptr create(ESM::NAME type); // just make it a bit shorter template - Record *cast() { - return static_cast *>(this); + Record* cast() + { + return static_cast*>(this); } }; @@ -73,75 +67,115 @@ namespace EsmTool public: Record() : mIsDeleted(false) - {} - - std::string getId() const override { - return mData.mId; + { } - T &get() { - return mData; - } + std::string getId() const override { return mData.mId; } - void save(ESM::ESMWriter &esm) override { - mData.save(esm, mIsDeleted); - } + T& get() { return mData; } - void load(ESM::ESMReader &esm) override { - mData.load(esm, mIsDeleted); - } + void save(ESM::ESMWriter& esm) override { mData.save(esm, mIsDeleted); } + + void load(ESM::ESMReader& esm) override { mData.load(esm, mIsDeleted); } void print() override; }; - - template<> std::string Record::getId() const; - template<> std::string Record::getId() const; - template<> std::string Record::getId() const; - template<> std::string Record::getId() const; - template<> std::string Record::getId() const; - - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); - template<> void Record::print(); + + template <> + std::string Record::getId() const; + template <> + std::string Record::getId() const; + template <> + std::string Record::getId() const; + template <> + std::string Record::getId() const; + template <> + std::string Record::getId() const; + + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); + template <> + void Record::print(); } #endif diff --git a/apps/esmtool/tes4.cpp b/apps/esmtool/tes4.cpp index d635545f6e..f72175ec93 100644 --- a/apps/esmtool/tes4.cpp +++ b/apps/esmtool/tes4.cpp @@ -21,79 +21,115 @@ namespace EsmTool explicit Params(const Arguments& info) : mQuite(info.quiet_given || info.mode == "clone") - {} + { + } }; std::string toString(ESM4::GroupType type) { switch (type) { - case ESM4::Grp_RecordType: return "RecordType"; - case ESM4::Grp_WorldChild: return "WorldChild"; - case ESM4::Grp_InteriorCell: return "InteriorCell"; - case ESM4::Grp_InteriorSubCell: return "InteriorSubCell"; - case ESM4::Grp_ExteriorCell: return "ExteriorCell"; - case ESM4::Grp_ExteriorSubCell: return "ExteriorSubCell"; - case ESM4::Grp_CellChild: return "CellChild"; - case ESM4::Grp_TopicChild: return "TopicChild"; - case ESM4::Grp_CellPersistentChild: return "CellPersistentChild"; - case ESM4::Grp_CellTemporaryChild: return "CellTemporaryChild"; - case ESM4::Grp_CellVisibleDistChild: return "CellVisibleDistChild"; + case ESM4::Grp_RecordType: + return "RecordType"; + case ESM4::Grp_WorldChild: + return "WorldChild"; + case ESM4::Grp_InteriorCell: + return "InteriorCell"; + case ESM4::Grp_InteriorSubCell: + return "InteriorSubCell"; + case ESM4::Grp_ExteriorCell: + return "ExteriorCell"; + case ESM4::Grp_ExteriorSubCell: + return "ExteriorSubCell"; + case ESM4::Grp_CellChild: + return "CellChild"; + case ESM4::Grp_TopicChild: + return "TopicChild"; + case ESM4::Grp_CellPersistentChild: + return "CellPersistentChild"; + case ESM4::Grp_CellTemporaryChild: + return "CellTemporaryChild"; + case ESM4::Grp_CellVisibleDistChild: + return "CellVisibleDistChild"; } return "Unknown (" + std::to_string(type) + ")"; } template > - struct HasFormId : std::false_type {}; + struct HasFormId : std::false_type + { + }; template - struct HasFormId> : std::true_type {}; + struct HasFormId> : std::true_type + { + }; template constexpr bool hasFormId = HasFormId::value; template > - struct HasFlags : std::false_type {}; + struct HasFlags : std::false_type + { + }; template - struct HasFlags> : std::true_type {}; + struct HasFlags> : std::true_type + { + }; template constexpr bool hasFlags = HasFlags::value; template > - struct HasEditorId : std::false_type {}; + struct HasEditorId : std::false_type + { + }; template - struct HasEditorId> : std::true_type {}; + struct HasEditorId> : std::true_type + { + }; template constexpr bool hasEditorId = HasEditorId::value; template > - struct HasModel : std::false_type {}; + struct HasModel : std::false_type + { + }; template - struct HasModel> : std::true_type {}; + struct HasModel> : std::true_type + { + }; template constexpr bool hasModel = HasModel::value; template > - struct HasNif : std::false_type {}; + struct HasNif : std::false_type + { + }; template - struct HasNif> : std::true_type {}; + struct HasNif> : std::true_type + { + }; template constexpr bool hasNif = HasNif::value; template > - struct HasKf : std::false_type {}; + struct HasKf : std::false_type + { + }; template - struct HasKf> : std::true_type {}; + struct HasKf> : std::true_type + { + }; template constexpr bool hasKf = HasKf::value; @@ -150,148 +186,286 @@ namespace EsmTool { switch (static_cast(reader.hdr().record.typeId)) { - case ESM4::REC_AACT: break; - case ESM4::REC_ACHR: return readTypedRecord(params, reader); - case ESM4::REC_ACRE: return readTypedRecord(params, reader); - case ESM4::REC_ACTI: return readTypedRecord(params, reader); - case ESM4::REC_ADDN: break; - case ESM4::REC_ALCH: return readTypedRecord(params, reader); - case ESM4::REC_ALOC: return readTypedRecord(params, reader); - case ESM4::REC_AMMO: return readTypedRecord(params, reader); - case ESM4::REC_ANIO: return readTypedRecord(params, reader); - case ESM4::REC_APPA: return readTypedRecord(params, reader); - case ESM4::REC_ARMA: return readTypedRecord(params, reader); - case ESM4::REC_ARMO: return readTypedRecord(params, reader); - case ESM4::REC_ARTO: break; - case ESM4::REC_ASPC: return readTypedRecord(params, reader); - case ESM4::REC_ASTP: break; - case ESM4::REC_AVIF: break; - case ESM4::REC_BOOK: return readTypedRecord(params, reader); - case ESM4::REC_BPTD: return readTypedRecord(params, reader); - case ESM4::REC_CAMS: break; - case ESM4::REC_CCRD: break; - case ESM4::REC_CELL: return readTypedRecord(params, reader); - case ESM4::REC_CLAS: return readTypedRecord(params, reader); - case ESM4::REC_CLFM: return readTypedRecord(params, reader); - case ESM4::REC_CLMT: break; - case ESM4::REC_CLOT: return readTypedRecord(params, reader); - case ESM4::REC_CMNY: break; - case ESM4::REC_COBJ: break; - case ESM4::REC_COLL: break; - case ESM4::REC_CONT: return readTypedRecord(params, reader); - case ESM4::REC_CPTH: break; - case ESM4::REC_CREA: return readTypedRecord(params, reader); - case ESM4::REC_CSTY: break; - case ESM4::REC_DEBR: break; - case ESM4::REC_DIAL: return readTypedRecord(params, reader); - case ESM4::REC_DLBR: break; - case ESM4::REC_DLVW: break; - case ESM4::REC_DOBJ: return readTypedRecord(params, reader); - case ESM4::REC_DOOR: return readTypedRecord(params, reader); - case ESM4::REC_DUAL: break; - case ESM4::REC_ECZN: break; - case ESM4::REC_EFSH: break; - case ESM4::REC_ENCH: break; - case ESM4::REC_EQUP: break; - case ESM4::REC_EXPL: break; - case ESM4::REC_EYES: return readTypedRecord(params, reader); - case ESM4::REC_FACT: break; - case ESM4::REC_FLOR: return readTypedRecord(params, reader); - case ESM4::REC_FLST: return readTypedRecord(params, reader); - case ESM4::REC_FSTP: break; - case ESM4::REC_FSTS: break; - case ESM4::REC_FURN: return readTypedRecord(params, reader); - case ESM4::REC_GLOB: return readTypedRecord(params, reader); - case ESM4::REC_GMST: break; - case ESM4::REC_GRAS: return readTypedRecord(params, reader); - case ESM4::REC_GRUP: break; - case ESM4::REC_HAIR: return readTypedRecord(params, reader); - case ESM4::REC_HAZD: break; - case ESM4::REC_HDPT: return readTypedRecord(params, reader); + case ESM4::REC_AACT: + break; + case ESM4::REC_ACHR: + return readTypedRecord(params, reader); + case ESM4::REC_ACRE: + return readTypedRecord(params, reader); + case ESM4::REC_ACTI: + return readTypedRecord(params, reader); + case ESM4::REC_ADDN: + break; + case ESM4::REC_ALCH: + return readTypedRecord(params, reader); + case ESM4::REC_ALOC: + return readTypedRecord(params, reader); + case ESM4::REC_AMMO: + return readTypedRecord(params, reader); + case ESM4::REC_ANIO: + return readTypedRecord(params, reader); + case ESM4::REC_APPA: + return readTypedRecord(params, reader); + case ESM4::REC_ARMA: + return readTypedRecord(params, reader); + case ESM4::REC_ARMO: + return readTypedRecord(params, reader); + case ESM4::REC_ARTO: + break; + case ESM4::REC_ASPC: + return readTypedRecord(params, reader); + case ESM4::REC_ASTP: + break; + case ESM4::REC_AVIF: + break; + case ESM4::REC_BOOK: + return readTypedRecord(params, reader); + case ESM4::REC_BPTD: + return readTypedRecord(params, reader); + case ESM4::REC_CAMS: + break; + case ESM4::REC_CCRD: + break; + case ESM4::REC_CELL: + return readTypedRecord(params, reader); + case ESM4::REC_CLAS: + return readTypedRecord(params, reader); + case ESM4::REC_CLFM: + return readTypedRecord(params, reader); + case ESM4::REC_CLMT: + break; + case ESM4::REC_CLOT: + return readTypedRecord(params, reader); + case ESM4::REC_CMNY: + break; + case ESM4::REC_COBJ: + break; + case ESM4::REC_COLL: + break; + case ESM4::REC_CONT: + return readTypedRecord(params, reader); + case ESM4::REC_CPTH: + break; + case ESM4::REC_CREA: + return readTypedRecord(params, reader); + case ESM4::REC_CSTY: + break; + case ESM4::REC_DEBR: + break; + case ESM4::REC_DIAL: + return readTypedRecord(params, reader); + case ESM4::REC_DLBR: + break; + case ESM4::REC_DLVW: + break; + case ESM4::REC_DOBJ: + return readTypedRecord(params, reader); + case ESM4::REC_DOOR: + return readTypedRecord(params, reader); + case ESM4::REC_DUAL: + break; + case ESM4::REC_ECZN: + break; + case ESM4::REC_EFSH: + break; + case ESM4::REC_ENCH: + break; + case ESM4::REC_EQUP: + break; + case ESM4::REC_EXPL: + break; + case ESM4::REC_EYES: + return readTypedRecord(params, reader); + case ESM4::REC_FACT: + break; + case ESM4::REC_FLOR: + return readTypedRecord(params, reader); + case ESM4::REC_FLST: + return readTypedRecord(params, reader); + case ESM4::REC_FSTP: + break; + case ESM4::REC_FSTS: + break; + case ESM4::REC_FURN: + return readTypedRecord(params, reader); + case ESM4::REC_GLOB: + return readTypedRecord(params, reader); + case ESM4::REC_GMST: + break; + case ESM4::REC_GRAS: + return readTypedRecord(params, reader); + case ESM4::REC_GRUP: + break; + case ESM4::REC_HAIR: + return readTypedRecord(params, reader); + case ESM4::REC_HAZD: + break; + case ESM4::REC_HDPT: + return readTypedRecord(params, reader); case ESM4::REC_IDLE: // FIXME: ESM4::IdleAnimation::load does not work with Oblivion.esm // return readTypedRecord(params, reader); break; - case ESM4::REC_IDLM: return readTypedRecord(params, reader); - case ESM4::REC_IMAD: break; - case ESM4::REC_IMGS: break; - case ESM4::REC_IMOD: return readTypedRecord(params, reader); - case ESM4::REC_INFO: return readTypedRecord(params, reader); - case ESM4::REC_INGR: return readTypedRecord(params, reader); - case ESM4::REC_IPCT: break; - case ESM4::REC_IPDS: break; - case ESM4::REC_KEYM: return readTypedRecord(params, reader); - case ESM4::REC_KYWD: break; - case ESM4::REC_LAND: return readTypedRecord(params, reader); - case ESM4::REC_LCRT: break; - case ESM4::REC_LCTN: break; - case ESM4::REC_LGTM: return readTypedRecord(params, reader); - case ESM4::REC_LIGH: return readTypedRecord(params, reader); - case ESM4::REC_LSCR: break; - case ESM4::REC_LTEX: return readTypedRecord(params, reader); - case ESM4::REC_LVLC: return readTypedRecord(params, reader); - case ESM4::REC_LVLI: return readTypedRecord(params, reader); - case ESM4::REC_LVLN: return readTypedRecord(params, reader); - case ESM4::REC_LVSP: break; - case ESM4::REC_MATO: return readTypedRecord(params, reader); - case ESM4::REC_MATT: break; - case ESM4::REC_MESG: break; - case ESM4::REC_MGEF: break; - case ESM4::REC_MISC: return readTypedRecord(params, reader); - case ESM4::REC_MOVT: break; - case ESM4::REC_MSET: return readTypedRecord(params, reader); - case ESM4::REC_MSTT: return readTypedRecord(params, reader); - case ESM4::REC_MUSC: return readTypedRecord(params, reader); - case ESM4::REC_MUST: break; - case ESM4::REC_NAVI: return readTypedRecord(params, reader); - case ESM4::REC_NAVM: return readTypedRecord(params, reader); - case ESM4::REC_NOTE: return readTypedRecord(params, reader); - case ESM4::REC_NPC_: return readTypedRecord(params, reader); - case ESM4::REC_OTFT: return readTypedRecord(params, reader); - case ESM4::REC_PACK: return readTypedRecord(params, reader); - case ESM4::REC_PERK: break; - case ESM4::REC_PGRD: return readTypedRecord(params, reader); - case ESM4::REC_PGRE: return readTypedRecord(params, reader); - case ESM4::REC_PHZD: break; - case ESM4::REC_PROJ: break; - case ESM4::REC_PWAT: return readTypedRecord(params, reader); - case ESM4::REC_QUST: return readTypedRecord(params, reader); - case ESM4::REC_RACE: return readTypedRecord(params, reader); - case ESM4::REC_REFR: return readTypedRecord(params, reader); - case ESM4::REC_REGN: return readTypedRecord(params, reader); - case ESM4::REC_RELA: break; - case ESM4::REC_REVB: break; - case ESM4::REC_RFCT: break; - case ESM4::REC_ROAD: return readTypedRecord(params, reader); - case ESM4::REC_SBSP: return readTypedRecord(params, reader); - case ESM4::REC_SCEN: break; - case ESM4::REC_SCOL: return readTypedRecord(params, reader); - case ESM4::REC_SCPT: return readTypedRecord(params, reader); - case ESM4::REC_SCRL: return readTypedRecord(params, reader); - case ESM4::REC_SGST: return readTypedRecord(params, reader); - case ESM4::REC_SHOU: break; - case ESM4::REC_SLGM: return readTypedRecord(params, reader); - case ESM4::REC_SMBN: break; - case ESM4::REC_SMEN: break; - case ESM4::REC_SMQN: break; - case ESM4::REC_SNCT: break; - case ESM4::REC_SNDR: return readTypedRecord(params, reader); - case ESM4::REC_SOPM: break; - case ESM4::REC_SOUN: return readTypedRecord(params, reader); - case ESM4::REC_SPEL: break; - case ESM4::REC_SPGD: break; - case ESM4::REC_STAT: return readTypedRecord(params, reader); - case ESM4::REC_TACT: return readTypedRecord(params, reader); - case ESM4::REC_TERM: return readTypedRecord(params, reader); - case ESM4::REC_TES4: return readTypedRecord(params, reader); - case ESM4::REC_TREE: return readTypedRecord(params, reader); - case ESM4::REC_TXST: return readTypedRecord(params, reader); - case ESM4::REC_VTYP: break; - case ESM4::REC_WATR: break; - case ESM4::REC_WEAP: return readTypedRecord(params, reader); - case ESM4::REC_WOOP: break; - case ESM4::REC_WRLD: return readTypedRecord(params, reader); - case ESM4::REC_WTHR: break; + case ESM4::REC_IDLM: + return readTypedRecord(params, reader); + case ESM4::REC_IMAD: + break; + case ESM4::REC_IMGS: + break; + case ESM4::REC_IMOD: + return readTypedRecord(params, reader); + case ESM4::REC_INFO: + return readTypedRecord(params, reader); + case ESM4::REC_INGR: + return readTypedRecord(params, reader); + case ESM4::REC_IPCT: + break; + case ESM4::REC_IPDS: + break; + case ESM4::REC_KEYM: + return readTypedRecord(params, reader); + case ESM4::REC_KYWD: + break; + case ESM4::REC_LAND: + return readTypedRecord(params, reader); + case ESM4::REC_LCRT: + break; + case ESM4::REC_LCTN: + break; + case ESM4::REC_LGTM: + return readTypedRecord(params, reader); + case ESM4::REC_LIGH: + return readTypedRecord(params, reader); + case ESM4::REC_LSCR: + break; + case ESM4::REC_LTEX: + return readTypedRecord(params, reader); + case ESM4::REC_LVLC: + return readTypedRecord(params, reader); + case ESM4::REC_LVLI: + return readTypedRecord(params, reader); + case ESM4::REC_LVLN: + return readTypedRecord(params, reader); + case ESM4::REC_LVSP: + break; + case ESM4::REC_MATO: + return readTypedRecord(params, reader); + case ESM4::REC_MATT: + break; + case ESM4::REC_MESG: + break; + case ESM4::REC_MGEF: + break; + case ESM4::REC_MISC: + return readTypedRecord(params, reader); + case ESM4::REC_MOVT: + break; + case ESM4::REC_MSET: + return readTypedRecord(params, reader); + case ESM4::REC_MSTT: + return readTypedRecord(params, reader); + case ESM4::REC_MUSC: + return readTypedRecord(params, reader); + case ESM4::REC_MUST: + break; + case ESM4::REC_NAVI: + return readTypedRecord(params, reader); + case ESM4::REC_NAVM: + return readTypedRecord(params, reader); + case ESM4::REC_NOTE: + return readTypedRecord(params, reader); + case ESM4::REC_NPC_: + return readTypedRecord(params, reader); + case ESM4::REC_OTFT: + return readTypedRecord(params, reader); + case ESM4::REC_PACK: + return readTypedRecord(params, reader); + case ESM4::REC_PERK: + break; + case ESM4::REC_PGRD: + return readTypedRecord(params, reader); + case ESM4::REC_PGRE: + return readTypedRecord(params, reader); + case ESM4::REC_PHZD: + break; + case ESM4::REC_PROJ: + break; + case ESM4::REC_PWAT: + return readTypedRecord(params, reader); + case ESM4::REC_QUST: + return readTypedRecord(params, reader); + case ESM4::REC_RACE: + return readTypedRecord(params, reader); + case ESM4::REC_REFR: + return readTypedRecord(params, reader); + case ESM4::REC_REGN: + return readTypedRecord(params, reader); + case ESM4::REC_RELA: + break; + case ESM4::REC_REVB: + break; + case ESM4::REC_RFCT: + break; + case ESM4::REC_ROAD: + return readTypedRecord(params, reader); + case ESM4::REC_SBSP: + return readTypedRecord(params, reader); + case ESM4::REC_SCEN: + break; + case ESM4::REC_SCOL: + return readTypedRecord(params, reader); + case ESM4::REC_SCPT: + return readTypedRecord(params, reader); + case ESM4::REC_SCRL: + return readTypedRecord(params, reader); + case ESM4::REC_SGST: + return readTypedRecord(params, reader); + case ESM4::REC_SHOU: + break; + case ESM4::REC_SLGM: + return readTypedRecord(params, reader); + case ESM4::REC_SMBN: + break; + case ESM4::REC_SMEN: + break; + case ESM4::REC_SMQN: + break; + case ESM4::REC_SNCT: + break; + case ESM4::REC_SNDR: + return readTypedRecord(params, reader); + case ESM4::REC_SOPM: + break; + case ESM4::REC_SOUN: + return readTypedRecord(params, reader); + case ESM4::REC_SPEL: + break; + case ESM4::REC_SPGD: + break; + case ESM4::REC_STAT: + return readTypedRecord(params, reader); + case ESM4::REC_TACT: + return readTypedRecord(params, reader); + case ESM4::REC_TERM: + return readTypedRecord(params, reader); + case ESM4::REC_TES4: + return readTypedRecord(params, reader); + case ESM4::REC_TREE: + return readTypedRecord(params, reader); + case ESM4::REC_TXST: + return readTypedRecord(params, reader); + case ESM4::REC_VTYP: + break; + case ESM4::REC_WATR: + break; + case ESM4::REC_WEAP: + return readTypedRecord(params, reader); + case ESM4::REC_WOOP: + break; + case ESM4::REC_WRLD: + return readTypedRecord(params, reader); + case ESM4::REC_WTHR: + break; } if (!params.mQuite) @@ -307,8 +481,8 @@ namespace EsmTool const ESM4::RecordHeader& header = reader.hdr(); if (!params.mQuite) - std::cout << "\nGroup: " << toString(static_cast(header.group.type)) - << " " << ESM::NAME(header.group.typeId).toStringView() << '\n'; + std::cout << "\nGroup: " << toString(static_cast(header.group.type)) << " " + << ESM::NAME(header.group.typeId).toStringView() << '\n'; switch (static_cast(header.group.type)) { @@ -366,8 +540,8 @@ namespace EsmTool if (!params.mQuite) { std::cout << "Author: " << reader.getAuthor() << '\n' - << "Description: " << reader.getDesc() << '\n' - << "File format version: " << reader.esmVersion() << '\n'; + << "Description: " << reader.getDesc() << '\n' + << "File format version: " << reader.esmVersion() << '\n'; if (const std::vector& masterData = reader.getGameFiles(); !masterData.empty()) { diff --git a/apps/essimporter/convertacdt.cpp b/apps/essimporter/convertacdt.cpp index 0ebf7b6817..8342310cf6 100644 --- a/apps/essimporter/convertacdt.cpp +++ b/apps/essimporter/convertacdt.cpp @@ -1,6 +1,6 @@ -#include #include #include +#include #include @@ -18,16 +18,16 @@ namespace ESSImport return mwIndex; } - void convertACDT (const ACDT& acdt, ESM::CreatureStats& cStats) + void convertACDT(const ACDT& acdt, ESM::CreatureStats& cStats) { - for (int i=0; i<3; ++i) + for (int i = 0; i < 3; ++i) { int writeIndex = translateDynamicIndex(i); cStats.mDynamic[writeIndex].mBase = acdt.mDynamic[i][1]; cStats.mDynamic[writeIndex].mMod = 0.f; cStats.mDynamic[writeIndex].mCurrent = acdt.mDynamic[i][0]; } - for (int i=0; i<8; ++i) + for (int i = 0; i < 8; ++i) { cStats.mAttributes[i].mBase = acdt.mAttributes[i][1]; cStats.mAttributes[i].mMod = 0.f; @@ -38,14 +38,14 @@ namespace ESSImport cStats.mAttacked = (acdt.mFlags & Attacked) != 0; } - void convertACSC (const ACSC& acsc, ESM::CreatureStats& cStats) + void convertACSC(const ACSC& acsc, ESM::CreatureStats& cStats) { cStats.mDead = (acsc.mFlags & Dead) != 0; } - void convertNpcData (const ActorData& actorData, ESM::NpcStats& npcStats) + void convertNpcData(const ActorData& actorData, ESM::NpcStats& npcStats) { - for (int i=0; i #include -#include #include -#include +#include #include "importacdt.hpp" @@ -14,13 +14,12 @@ namespace ESSImport // OpenMW uses Health,Magicka,Fatigue, MW uses Health,Fatigue,Magicka int translateDynamicIndex(int mwIndex); + void convertACDT(const ACDT& acdt, ESM::CreatureStats& cStats); + void convertACSC(const ACSC& acsc, ESM::CreatureStats& cStats); - void convertACDT (const ACDT& acdt, ESM::CreatureStats& cStats); - void convertACSC (const ACSC& acsc, ESM::CreatureStats& cStats); - - void convertNpcData (const ActorData& actorData, ESM::NpcStats& npcStats); + void convertNpcData(const ActorData& actorData, ESM::NpcStats& npcStats); - void convertANIS (const ANIS& anis, ESM::AnimationState& state); + void convertANIS(const ANIS& anis, ESM::AnimationState& state); } #endif diff --git a/apps/essimporter/convertcntc.cpp b/apps/essimporter/convertcntc.cpp index 426ef44966..2b461ae3ad 100644 --- a/apps/essimporter/convertcntc.cpp +++ b/apps/essimporter/convertcntc.cpp @@ -5,7 +5,7 @@ namespace ESSImport { - void convertCNTC(const CNTC &cntc, ESM::ContainerState &state) + void convertCNTC(const CNTC& cntc, ESM::ContainerState& state) { convertInventory(cntc.mInventory, state.mInventory); } diff --git a/apps/essimporter/convertcrec.cpp b/apps/essimporter/convertcrec.cpp index 34e1c00708..f8233bcbf5 100644 --- a/apps/essimporter/convertcrec.cpp +++ b/apps/essimporter/convertcrec.cpp @@ -5,7 +5,7 @@ namespace ESSImport { - void convertCREC(const CREC &crec, ESM::CreatureState &state) + void convertCREC(const CREC& crec, ESM::CreatureState& state) { convertInventory(crec.mInventory, state.mInventory); } diff --git a/apps/essimporter/converter.cpp b/apps/essimporter/converter.cpp index d154f91ef9..8911858215 100644 --- a/apps/essimporter/converter.cpp +++ b/apps/essimporter/converter.cpp @@ -1,17 +1,17 @@ #include "converter.hpp" -#include #include +#include #include -#include #include +#include #include -#include "convertcrec.hpp" #include "convertcntc.hpp" +#include "convertcrec.hpp" #include "convertscri.hpp" namespace @@ -19,7 +19,7 @@ namespace void convertImage(char* data, int size, int width, int height, GLenum pf, const std::string& out) { - osg::ref_ptr image (new osg::Image); + osg::ref_ptr image(new osg::Image); image->allocateImage(width, height, 1, pf, GL_UNSIGNED_BYTE); memcpy(image->data(), data, size); image->flipVertical(); @@ -27,7 +27,6 @@ namespace osgDB::writeImageFile(*image, out); } - void convertCellRef(const ESSImport::CellRef& cellref, ESM::ObjectState& objstate) { objstate.mEnabled = cellref.mEnabled; @@ -51,17 +50,17 @@ namespace return false; // entirely numeric refid, this is a reference to // a dynamically created record e.g. player-enchanted weapon - std::string index = indexedRefId.substr(indexedRefId.size()-8); + std::string index = indexedRefId.substr(indexedRefId.size() - 8); return index.find_first_not_of("0123456789ABCDEF") == std::string::npos; } void splitIndexedRefId(const std::string& indexedRefId, int& refIndex, std::string& refId) { std::stringstream stream; - stream << std::hex << indexedRefId.substr(indexedRefId.size()-8,8); + stream << std::hex << indexedRefId.substr(indexedRefId.size() - 8, 8); stream >> refIndex; - refId = indexedRefId.substr(0,indexedRefId.size()-8); + refId = indexedRefId.substr(0, indexedRefId.size() - 8); } int convertActorId(const std::string& indexedRefId, ESSImport::Context& context) @@ -89,14 +88,13 @@ namespace namespace ESSImport { - struct MAPH { unsigned int size; unsigned int value; }; - void ConvertFMAP::read(ESM::ESMReader &esm) + void ConvertFMAP::read(ESM::ESMReader& esm) { MAPH maph; esm.getHNT(maph, "MAPH"); @@ -112,55 +110,55 @@ namespace ESSImport // to match openmw size // FIXME: filtering? - mGlobalMapImage->scaleImage(maph.size*2, maph.size*2, 1, GL_UNSIGNED_BYTE); + mGlobalMapImage->scaleImage(maph.size * 2, maph.size * 2, 1, GL_UNSIGNED_BYTE); } - void ConvertFMAP::write(ESM::ESMWriter &esm) + void ConvertFMAP::write(ESM::ESMWriter& esm) { int numcells = mGlobalMapImage->s() / 18; // NB truncating, doesn't divide perfectly - // with the 512x512 map the game has by default - int cellSize = mGlobalMapImage->s()/numcells; + // with the 512x512 map the game has by default + int cellSize = mGlobalMapImage->s() / numcells; // Note the upper left corner of the (0,0) cell should be at (width/2, height/2) - mContext->mGlobalMapState.mBounds.mMinX = -numcells/2; - mContext->mGlobalMapState.mBounds.mMaxX = (numcells-1)/2; - mContext->mGlobalMapState.mBounds.mMinY = -(numcells-1)/2; - mContext->mGlobalMapState.mBounds.mMaxY = numcells/2; + mContext->mGlobalMapState.mBounds.mMinX = -numcells / 2; + mContext->mGlobalMapState.mBounds.mMaxX = (numcells - 1) / 2; + mContext->mGlobalMapState.mBounds.mMinY = -(numcells - 1) / 2; + mContext->mGlobalMapState.mBounds.mMaxY = numcells / 2; - osg::ref_ptr image2 (new osg::Image); - int width = cellSize*numcells; - int height = cellSize*numcells; + osg::ref_ptr image2(new osg::Image); + int width = cellSize * numcells; + int height = cellSize * numcells; std::vector data; - data.resize(width*height*4, 0); + data.resize(width * height * 4, 0); image2->allocateImage(width, height, 1, GL_RGBA, GL_UNSIGNED_BYTE); memcpy(image2->data(), data.data(), data.size()); - for (const auto & exploredCell : mContext->mExploredCells) + for (const auto& exploredCell : mContext->mExploredCells) { if (exploredCell.first > mContext->mGlobalMapState.mBounds.mMaxX - || exploredCell.first < mContext->mGlobalMapState.mBounds.mMinX - || exploredCell.second > mContext->mGlobalMapState.mBounds.mMaxY - || exploredCell.second < mContext->mGlobalMapState.mBounds.mMinY) + || exploredCell.first < mContext->mGlobalMapState.mBounds.mMinX + || exploredCell.second > mContext->mGlobalMapState.mBounds.mMaxY + || exploredCell.second < mContext->mGlobalMapState.mBounds.mMinY) { // out of bounds, I think this could happen, since the original engine had a fixed-size map continue; } - int imageLeftSrc = mGlobalMapImage->s()/2; - int imageTopSrc = mGlobalMapImage->t()/2; + int imageLeftSrc = mGlobalMapImage->s() / 2; + int imageTopSrc = mGlobalMapImage->t() / 2; imageLeftSrc += exploredCell.first * cellSize; imageTopSrc -= exploredCell.second * cellSize; - int imageLeftDst = width/2; - int imageTopDst = height/2; + int imageLeftDst = width / 2; + int imageTopDst = height / 2; imageLeftDst += exploredCell.first * cellSize; imageTopDst -= exploredCell.second * cellSize; - for (int x=0; xdata(imageLeftSrc+x, imageTopSrc+y, 0); - *(unsigned int*)image2->data(imageLeftDst+x, imageTopDst+y, 0) = col; + unsigned int col = *(unsigned int*)mGlobalMapImage->data(imageLeftSrc + x, imageTopSrc + y, 0); + *(unsigned int*)image2->data(imageLeftDst + x, imageTopDst + y, 0) = col; } } @@ -177,7 +175,8 @@ namespace ESSImport osgDB::ReaderWriter::WriteResult result = readerwriter->writeImage(*image2, ostream); if (!result.success()) { - std::cerr << "Error: can't write global map image: " << result.message() << " code " << result.status() << std::endl; + std::cerr << "Error: can't write global map image: " << result.message() << " code " << result.status() + << std::endl; return; } @@ -189,7 +188,7 @@ namespace ESSImport esm.endRecord(ESM::REC_GMAP); } - void ConvertCell::read(ESM::ESMReader &esm) + void ConvertCell::read(ESM::ESMReader& esm) { ESM::Cell cell; bool isDeleted = false; @@ -234,15 +233,15 @@ namespace ESSImport esm.getExact(nam8, 32); - newcell.mFogOfWar.reserve(16*16); - for (int x=0; x<16; ++x) + newcell.mFogOfWar.reserve(16 * 16); + for (int x = 0; x < 16; ++x) { - for (int y=0; y<16; ++y) + for (int y = 0; y < 16; ++y) { - size_t pos = x*16+y; - size_t bytepos = pos/8; - assert(bytepos<32); - int bit = pos%8; + size_t pos = x * 16 + y; + size_t bytepos = pos / 8; + assert(bytepos < 32); + int bit = pos % 8; newcell.mFogOfWar.push_back(((nam8[bytepos] >> bit) & (0x1)) ? 0xffffffff : 0x000000ff); } } @@ -252,7 +251,8 @@ namespace ESSImport std::ostringstream filename; filename << "fog_" << cell.mData.mX << "_" << cell.mData.mY << ".tga"; - convertImage((char*)&newcell.mFogOfWar[0], newcell.mFogOfWar.size()*4, 16, 16, GL_RGBA, filename.str()); + convertImage( + (char*)&newcell.mFogOfWar[0], newcell.mFogOfWar.size() * 4, 16, 16, GL_RGBA, filename.str()); } } @@ -271,7 +271,7 @@ namespace ESSImport while (esm.hasMoreSubs() && esm.peekNextSub("FRMR")) { CellRef ref; - ref.load (esm); + ref.load(esm); cellrefs.push_back(ref); } @@ -307,14 +307,13 @@ namespace ESSImport newcell.mRefs = cellrefs; - if (cell.isExterior()) mExtCells[std::make_pair(cell.mData.mX, cell.mData.mY)] = newcell; else mIntCells[cell.mName] = newcell; } - void ConvertCell::writeCell(const Cell &cell, ESM::ESMWriter& esm) + void ConvertCell::writeCell(const Cell& cell, ESM::ESMWriter& esm) { ESM::Cell esmcell = cell.mCell; esm.startRecord(ESM::REC_CSTA); @@ -329,9 +328,9 @@ namespace ESSImport csta.mWaterLevel = esmcell.mWater; csta.save(esm); - for (const auto & cellref : cell.mRefs) + for (const auto& cellref : cell.mRefs) { - ESM::CellRef out (cellref); + ESM::CellRef out(cellref); // TODO: use mContext->mCreatures/mNpcs @@ -348,7 +347,7 @@ namespace ESSImport objstate.mRef.mRefID = idLower; objstate.mHasCustomState = false; convertCellRef(cellref, objstate); - esm.writeHNT ("OBJE", 0); + esm.writeHNT("OBJE", 0); objstate.save(esm); continue; } @@ -359,8 +358,7 @@ namespace ESSImport std::string idLower = Misc::StringUtils::lowerCase(out.mRefID); - auto npccIt = mContext->mNpcChanges.find( - std::make_pair(refIndex, out.mRefID)); + auto npccIt = mContext->mNpcChanges.find(std::make_pair(refIndex, out.mRefID)); if (npccIt != mContext->mNpcChanges.end()) { ESM::NpcState objstate; @@ -380,15 +378,15 @@ namespace ESSImport convertCellRef(cellref, objstate); objstate.mCreatureStats.mActorId = mContext->generateActorId(); - mContext->mActorIdMap.insert(std::make_pair(std::make_pair(refIndex, out.mRefID), objstate.mCreatureStats.mActorId)); + mContext->mActorIdMap.insert( + std::make_pair(std::make_pair(refIndex, out.mRefID), objstate.mCreatureStats.mActorId)); - esm.writeHNT ("OBJE", ESM::REC_NPC_); + esm.writeHNT("OBJE", ESM::REC_NPC_); objstate.save(esm); continue; } - auto cntcIt = mContext->mContainerChanges.find( - std::make_pair(refIndex, out.mRefID)); + auto cntcIt = mContext->mContainerChanges.find(std::make_pair(refIndex, out.mRefID)); if (cntcIt != mContext->mContainerChanges.end()) { ESM::ContainerState objstate; @@ -397,13 +395,12 @@ namespace ESSImport objstate.mRef.mRefID = idLower; convertCNTC(cntcIt->second, objstate); convertCellRef(cellref, objstate); - esm.writeHNT ("OBJE", ESM::REC_CONT); + esm.writeHNT("OBJE", ESM::REC_CONT); objstate.save(esm); continue; } - auto crecIt = mContext->mCreatureChanges.find( - std::make_pair(refIndex, out.mRefID)); + auto crecIt = mContext->mCreatureChanges.find(std::make_pair(refIndex, out.mRefID)); if (crecIt != mContext->mCreatureChanges.end()) { ESM::CreatureState objstate; @@ -422,9 +419,10 @@ namespace ESSImport convertCellRef(cellref, objstate); objstate.mCreatureStats.mActorId = mContext->generateActorId(); - mContext->mActorIdMap.insert(std::make_pair(std::make_pair(refIndex, out.mRefID), objstate.mCreatureStats.mActorId)); + mContext->mActorIdMap.insert( + std::make_pair(std::make_pair(refIndex, out.mRefID), objstate.mCreatureStats.mActorId)); - esm.writeHNT ("OBJE", ESM::REC_CREA); + esm.writeHNT("OBJE", ESM::REC_CREA); objstate.save(esm); continue; } @@ -438,15 +436,15 @@ namespace ESSImport esm.endRecord(ESM::REC_CSTA); } - void ConvertCell::write(ESM::ESMWriter &esm) + void ConvertCell::write(ESM::ESMWriter& esm) { - for (const auto & cell : mIntCells) + for (const auto& cell : mIntCells) writeCell(cell.second, esm); - for (const auto & cell : mExtCells) + for (const auto& cell : mExtCells) writeCell(cell.second, esm); - for (const auto & marker : mMarkers) + for (const auto& marker : mMarkers) { esm.startRecord(ESM::REC_MARK); marker.save(esm); @@ -482,11 +480,12 @@ namespace ESSImport convertBaseState(out, pnam); auto it = std::find_if(mContext->mActiveSpells.begin(), mContext->mActiveSpells.end(), - [&pnam](const SPLM::ActiveSpell& spell) -> bool { return spell.mIndex == pnam.mSplmIndex; }); + [&pnam](const SPLM::ActiveSpell& spell) -> bool { return spell.mIndex == pnam.mSplmIndex; }); if (it == mContext->mActiveSpells.end()) { - std::cerr << "Warning: Skipped conversion for magic projectile \"" << pnam.mArrowId.toString() << "\" (invalid spell link)" << std::endl; + std::cerr << "Warning: Skipped conversion for magic projectile \"" << pnam.mArrowId.toString() + << "\" (invalid spell link)" << std::endl; continue; } @@ -507,7 +506,7 @@ namespace ESSImport base.mPosition = pnam.mPosition; osg::Quat orient; - orient.makeRotate(osg::Vec3f(0,1,0), pnam.mVelocity); + orient.makeRotate(osg::Vec3f(0, 1, 0), pnam.mVelocity); base.mOrientation = orient; base.mActorId = convertActorId(pnam.mActorId.toString(), *mContext); diff --git a/apps/essimporter/converter.hpp b/apps/essimporter/converter.hpp index 59ba0ebddb..82cb10e53a 100644 --- a/apps/essimporter/converter.hpp +++ b/apps/essimporter/converter.hpp @@ -9,614 +9,619 @@ #include #include -#include -#include -#include -#include #include -#include -#include #include -#include -#include +#include #include +#include +#include +#include +#include +#include +#include +#include #include #include -#include +#include #include -#include "importcrec.hpp" #include "importcntc.hpp" +#include "importcrec.hpp" -#include "importercontext.hpp" #include "importcellref.hpp" -#include "importklst.hpp" +#include "importdial.hpp" +#include "importercontext.hpp" #include "importgame.hpp" #include "importinfo.hpp" -#include "importdial.hpp" -#include "importques.hpp" #include "importjour.hpp" -#include "importscpt.hpp" +#include "importklst.hpp" #include "importproj.h" +#include "importques.hpp" +#include "importscpt.hpp" #include "importsplm.h" #include "convertacdt.hpp" #include "convertnpcc.hpp" -#include "convertscpt.hpp" #include "convertplayer.hpp" +#include "convertscpt.hpp" namespace ESSImport { -class Converter -{ -public: - /// @return the order for writing this converter's records to the output file, in relation to other converters - virtual int getStage() { return 1; } + class Converter + { + public: + /// @return the order for writing this converter's records to the output file, in relation to other converters + virtual int getStage() { return 1; } - virtual ~Converter() {} + virtual ~Converter() {} - void setContext(Context& context) { mContext = &context; } + void setContext(Context& context) { mContext = &context; } - /// @note The load method of ESM records accept the deleted flag as a parameter. - /// I don't know can the DELE sub-record appear in saved games, so the deleted flag will be ignored. - virtual void read(ESM::ESMReader& esm) - { - } + /// @note The load method of ESM records accept the deleted flag as a parameter. + /// I don't know can the DELE sub-record appear in saved games, so the deleted flag will be ignored. + virtual void read(ESM::ESMReader& esm) {} + + /// Called after the input file has been read in completely, which may be necessary + /// if the conversion process relies on information in other records + virtual void write(ESM::ESMWriter& esm) {} + + protected: + Context* mContext; + }; - /// Called after the input file has been read in completely, which may be necessary - /// if the conversion process relies on information in other records - virtual void write(ESM::ESMWriter& esm) + /// Default converter: simply reads the record and writes it unmodified to the output + template + class DefaultConverter : public Converter { + public: + int getStage() override { return 0; } - } + void read(ESM::ESMReader& esm) override + { + T record; + bool isDeleted = false; -protected: - Context* mContext; -}; + record.load(esm, isDeleted); + mRecords[record.mId] = record; + } -/// Default converter: simply reads the record and writes it unmodified to the output -template -class DefaultConverter : public Converter -{ -public: - int getStage() override { return 0; } + void write(ESM::ESMWriter& esm) override + { + for (typename std::map::const_iterator it = mRecords.begin(); it != mRecords.end(); ++it) + { + esm.startRecord(T::sRecordId); + it->second.save(esm); + esm.endRecord(T::sRecordId); + } + } + + protected: + std::map mRecords; + }; - void read(ESM::ESMReader& esm) override + class ConvertNPC : public Converter { - T record; - bool isDeleted = false; + public: + void read(ESM::ESMReader& esm) override + { + ESM::NPC npc; + bool isDeleted = false; - record.load(esm, isDeleted); - mRecords[record.mId] = record; - } + npc.load(esm, isDeleted); + if (npc.mId != "player") + { + // Handles changes to the NPC struct, but since there is no index here + // it will apply to ALL instances of the class. seems to be the reason for the + // "feature" in MW where changing AI settings of one guard will change it for all guards of that refID. + mContext->mNpcs[Misc::StringUtils::lowerCase(npc.mId)] = npc; + } + else + { + mContext->mPlayer.mObject.mCreatureStats.mLevel = npc.mNpdt.mLevel; + mContext->mPlayerBase = npc; + // FIXME: player start spells and birthsign spells aren't listed here, + // need to fix openmw to account for this + mContext->mPlayer.mObject.mCreatureStats.mSpells.mSpells = npc.mSpells.mList; + + // Clear the list now that we've written it, this prevents issues cropping up with + // ensureCustomData() in OpenMW tripping over no longer existing spells, where an error would be fatal. + mContext->mPlayerBase.mSpells.mList.clear(); + + // Same with inventory. Actually it's strange this would contain something, since there's already an + // inventory list in NPCC. There seems to be a fair amount of redundancy in this format. + mContext->mPlayerBase.mInventory.mList.clear(); + } + } + }; - void write(ESM::ESMWriter& esm) override + class ConvertCREA : public Converter { - for (typename std::map::const_iterator it = mRecords.begin(); it != mRecords.end(); ++it) + public: + void read(ESM::ESMReader& esm) override { - esm.startRecord(T::sRecordId); - it->second.save(esm); - esm.endRecord(T::sRecordId); + // See comment in ConvertNPC + ESM::Creature creature; + bool isDeleted = false; + + creature.load(esm, isDeleted); + mContext->mCreatures[Misc::StringUtils::lowerCase(creature.mId)] = creature; } - } + }; -protected: - std::map mRecords; -}; + // Do we need ConvertCONT? + // I've seen a CONT record in a certain save file, but the container contents in it + // were identical to a corresponding CNTC record. See previous comment about redundancy... -class ConvertNPC : public Converter -{ -public: - void read(ESM::ESMReader &esm) override + class ConvertGlobal : public DefaultConverter { - ESM::NPC npc; - bool isDeleted = false; - - npc.load(esm, isDeleted); - if (npc.mId != "player") + public: + void read(ESM::ESMReader& esm) override { - // Handles changes to the NPC struct, but since there is no index here - // it will apply to ALL instances of the class. seems to be the reason for the - // "feature" in MW where changing AI settings of one guard will change it for all guards of that refID. - mContext->mNpcs[Misc::StringUtils::lowerCase(npc.mId)] = npc; + ESM::Global global; + bool isDeleted = false; + + global.load(esm, isDeleted); + if (Misc::StringUtils::ciEqual(global.mId, "gamehour")) + mContext->mHour = global.mValue.getFloat(); + if (Misc::StringUtils::ciEqual(global.mId, "day")) + mContext->mDay = global.mValue.getInteger(); + if (Misc::StringUtils::ciEqual(global.mId, "month")) + mContext->mMonth = global.mValue.getInteger(); + if (Misc::StringUtils::ciEqual(global.mId, "year")) + mContext->mYear = global.mValue.getInteger(); + mRecords[global.mId] = global; } - else + }; + + class ConvertClass : public DefaultConverter + { + public: + void read(ESM::ESMReader& esm) override { - mContext->mPlayer.mObject.mCreatureStats.mLevel = npc.mNpdt.mLevel; - mContext->mPlayerBase = npc; - // FIXME: player start spells and birthsign spells aren't listed here, - // need to fix openmw to account for this - mContext->mPlayer.mObject.mCreatureStats.mSpells.mSpells = npc.mSpells.mList; + ESM::Class class_; + bool isDeleted = false; - // Clear the list now that we've written it, this prevents issues cropping up with - // ensureCustomData() in OpenMW tripping over no longer existing spells, where an error would be fatal. - mContext->mPlayerBase.mSpells.mList.clear(); + class_.load(esm, isDeleted); + if (class_.mId == "NEWCLASSID_CHARGEN") + mContext->mCustomPlayerClassName = class_.mName; - // Same with inventory. Actually it's strange this would contain something, since there's already an - // inventory list in NPCC. There seems to be a fair amount of redundancy in this format. - mContext->mPlayerBase.mInventory.mList.clear(); + mRecords[class_.mId] = class_; } - } -}; + }; -class ConvertCREA : public Converter -{ -public: - void read(ESM::ESMReader &esm) override + class ConvertBook : public DefaultConverter { - // See comment in ConvertNPC - ESM::Creature creature; - bool isDeleted = false; + public: + void read(ESM::ESMReader& esm) override + { + ESM::Book book; + bool isDeleted = false; - creature.load(esm, isDeleted); - mContext->mCreatures[Misc::StringUtils::lowerCase(creature.mId)] = creature; - } -}; + book.load(esm, isDeleted); + if (book.mData.mSkillId == -1) + mContext->mPlayer.mObject.mNpcStats.mUsedIds.push_back(Misc::StringUtils::lowerCase(book.mId)); -// Do we need ConvertCONT? -// I've seen a CONT record in a certain save file, but the container contents in it -// were identical to a corresponding CNTC record. See previous comment about redundancy... + mRecords[book.mId] = book; + } + }; -class ConvertGlobal : public DefaultConverter -{ -public: - void read(ESM::ESMReader &esm) override - { - ESM::Global global; - bool isDeleted = false; - - global.load(esm, isDeleted); - if (Misc::StringUtils::ciEqual(global.mId, "gamehour")) - mContext->mHour = global.mValue.getFloat(); - if (Misc::StringUtils::ciEqual(global.mId, "day")) - mContext->mDay = global.mValue.getInteger(); - if (Misc::StringUtils::ciEqual(global.mId, "month")) - mContext->mMonth = global.mValue.getInteger(); - if (Misc::StringUtils::ciEqual(global.mId, "year")) - mContext->mYear = global.mValue.getInteger(); - mRecords[global.mId] = global; - } -}; - -class ConvertClass : public DefaultConverter -{ -public: - void read(ESM::ESMReader &esm) override + class ConvertNPCC : public Converter { - ESM::Class class_; - bool isDeleted = false; - - class_.load(esm, isDeleted); - if (class_.mId == "NEWCLASSID_CHARGEN") - mContext->mCustomPlayerClassName = class_.mName; - - mRecords[class_.mId] = class_; - } -}; + public: + void read(ESM::ESMReader& esm) override + { + std::string id = esm.getHNString("NAME"); + NPCC npcc; + npcc.load(esm); + if (id == "PlayerSaveGame") + { + convertNPCC(npcc, mContext->mPlayer.mObject); + } + else + { + int index = npcc.mNPDT.mIndex; + mContext->mNpcChanges.insert(std::make_pair(std::make_pair(index, id), npcc)); + } + } + }; -class ConvertBook : public DefaultConverter -{ -public: - void read(ESM::ESMReader &esm) override + class ConvertREFR : public Converter { - ESM::Book book; - bool isDeleted = false; + public: + void read(ESM::ESMReader& esm) override + { + CellRef refr; + refr.load(esm); + assert(refr.mIndexedRefId == "PlayerSaveGame"); + mContext->mPlayer.mObject.mPosition = refr.mPos; - book.load(esm, isDeleted); - if (book.mData.mSkillId == -1) - mContext->mPlayer.mObject.mNpcStats.mUsedIds.push_back(Misc::StringUtils::lowerCase(book.mId)); + ESM::CreatureStats& cStats = mContext->mPlayer.mObject.mCreatureStats; + convertACDT(refr.mActorData.mACDT, cStats); - mRecords[book.mId] = book; - } -}; + ESM::NpcStats& npcStats = mContext->mPlayer.mObject.mNpcStats; + convertNpcData(refr.mActorData, npcStats); -class ConvertNPCC : public Converter -{ -public: - void read(ESM::ESMReader &esm) override - { - std::string id = esm.getHNString("NAME"); - NPCC npcc; - npcc.load(esm); - if (id == "PlayerSaveGame") - { - convertNPCC(npcc, mContext->mPlayer.mObject); + mSelectedSpell = refr.mActorData.mSelectedSpell; + if (!refr.mActorData.mSelectedEnchantItem.empty()) + { + ESM::InventoryState& invState = mContext->mPlayer.mObject.mInventory; + + for (unsigned int i = 0; i < invState.mItems.size(); ++i) + { + // FIXME: in case of conflict (multiple items with this refID) use the already equipped one? + if (Misc::StringUtils::ciEqual( + invState.mItems[i].mRef.mRefID, refr.mActorData.mSelectedEnchantItem)) + invState.mSelectedEnchantItem = i; + } + } } - else + void write(ESM::ESMWriter& esm) override { - int index = npcc.mNPDT.mIndex; - mContext->mNpcChanges.insert(std::make_pair(std::make_pair(index,id), npcc)); + esm.startRecord(ESM::REC_ASPL); + esm.writeHNString("ID__", mSelectedSpell); + esm.endRecord(ESM::REC_ASPL); } - } -}; -class ConvertREFR : public Converter -{ -public: - void read(ESM::ESMReader &esm) override - { - CellRef refr; - refr.load(esm); - assert(refr.mIndexedRefId == "PlayerSaveGame"); - mContext->mPlayer.mObject.mPosition = refr.mPos; - - ESM::CreatureStats& cStats = mContext->mPlayer.mObject.mCreatureStats; - convertACDT(refr.mActorData.mACDT, cStats); + private: + std::string mSelectedSpell; + }; - ESM::NpcStats& npcStats = mContext->mPlayer.mObject.mNpcStats; - convertNpcData(refr.mActorData, npcStats); + class ConvertPCDT : public Converter + { + public: + ConvertPCDT() + : mFirstPersonCam(true) + , mTeleportingEnabled(true) + , mLevitationEnabled(true) + { + } - mSelectedSpell = refr.mActorData.mSelectedSpell; - if (!refr.mActorData.mSelectedEnchantItem.empty()) + void read(ESM::ESMReader& esm) override { - ESM::InventoryState& invState = mContext->mPlayer.mObject.mInventory; + PCDT pcdt; + pcdt.load(esm); - for (unsigned int i=0; imPlayer, mContext->mDialogueState.mKnownTopics, mFirstPersonCam, + mTeleportingEnabled, mLevitationEnabled, mContext->mControlsState); + } + void write(ESM::ESMWriter& esm) override + { + esm.startRecord(ESM::REC_ENAB); + esm.writeHNT("TELE", mTeleportingEnabled); + esm.writeHNT("LEVT", mLevitationEnabled); + esm.endRecord(ESM::REC_ENAB); + + esm.startRecord(ESM::REC_CAM_); + esm.writeHNT("FIRS", mFirstPersonCam); + esm.endRecord(ESM::REC_CAM_); } - } - void write(ESM::ESMWriter& esm) override - { - esm.startRecord(ESM::REC_ASPL); - esm.writeHNString("ID__", mSelectedSpell); - esm.endRecord(ESM::REC_ASPL); - } -private: - std::string mSelectedSpell; -}; - -class ConvertPCDT : public Converter -{ -public: - ConvertPCDT() - : mFirstPersonCam(true), - mTeleportingEnabled(true), - mLevitationEnabled(true) - {} - - void read(ESM::ESMReader &esm) override - { - PCDT pcdt; - pcdt.load(esm); - convertPCDT(pcdt, mContext->mPlayer, mContext->mDialogueState.mKnownTopics, mFirstPersonCam, mTeleportingEnabled, mLevitationEnabled, mContext->mControlsState); - } - void write(ESM::ESMWriter &esm) override - { - esm.startRecord(ESM::REC_ENAB); - esm.writeHNT("TELE", mTeleportingEnabled); - esm.writeHNT("LEVT", mLevitationEnabled); - esm.endRecord(ESM::REC_ENAB); - - esm.startRecord(ESM::REC_CAM_); - esm.writeHNT("FIRS", mFirstPersonCam); - esm.endRecord(ESM::REC_CAM_); - } -private: - bool mFirstPersonCam; - bool mTeleportingEnabled; - bool mLevitationEnabled; -}; - -class ConvertCNTC : public Converter -{ - void read(ESM::ESMReader &esm) override + private: + bool mFirstPersonCam; + bool mTeleportingEnabled; + bool mLevitationEnabled; + }; + + class ConvertCNTC : public Converter { - std::string id = esm.getHNString("NAME"); - CNTC cntc; - cntc.load(esm); - mContext->mContainerChanges.insert(std::make_pair(std::make_pair(cntc.mIndex,id), cntc)); - } -}; - -class ConvertCREC : public Converter -{ -public: - void read(ESM::ESMReader &esm) override + void read(ESM::ESMReader& esm) override + { + std::string id = esm.getHNString("NAME"); + CNTC cntc; + cntc.load(esm); + mContext->mContainerChanges.insert(std::make_pair(std::make_pair(cntc.mIndex, id), cntc)); + } + }; + + class ConvertCREC : public Converter { - std::string id = esm.getHNString("NAME"); - CREC crec; - crec.load(esm); - mContext->mCreatureChanges.insert(std::make_pair(std::make_pair(crec.mIndex,id), crec)); - } -}; - -class ConvertFMAP : public Converter -{ -public: - void read(ESM::ESMReader &esm) override; - void write(ESM::ESMWriter &esm) override; + public: + void read(ESM::ESMReader& esm) override + { + std::string id = esm.getHNString("NAME"); + CREC crec; + crec.load(esm); + mContext->mCreatureChanges.insert(std::make_pair(std::make_pair(crec.mIndex, id), crec)); + } + }; -private: - osg::ref_ptr mGlobalMapImage; -}; + class ConvertFMAP : public Converter + { + public: + void read(ESM::ESMReader& esm) override; + void write(ESM::ESMWriter& esm) override; -class ConvertCell : public Converter -{ -public: - void read(ESM::ESMReader& esm) override; - void write(ESM::ESMWriter& esm) override; + private: + osg::ref_ptr mGlobalMapImage; + }; -private: - struct Cell + class ConvertCell : public Converter { - ESM::Cell mCell; - std::vector mRefs; - std::vector mFogOfWar; - }; + public: + void read(ESM::ESMReader& esm) override; + void write(ESM::ESMWriter& esm) override; - std::map mIntCells; - std::map, Cell> mExtCells; + private: + struct Cell + { + ESM::Cell mCell; + std::vector mRefs; + std::vector mFogOfWar; + }; - std::vector mMarkers; + std::map mIntCells; + std::map, Cell> mExtCells; - void writeCell(const Cell& cell, ESM::ESMWriter &esm); -}; + std::vector mMarkers; -class ConvertKLST : public Converter -{ -public: - void read(ESM::ESMReader& esm) override + void writeCell(const Cell& cell, ESM::ESMWriter& esm); + }; + + class ConvertKLST : public Converter { - KLST klst; - klst.load(esm); - mKillCounter = klst.mKillCounter; + public: + void read(ESM::ESMReader& esm) override + { + KLST klst; + klst.load(esm); + mKillCounter = klst.mKillCounter; - mContext->mPlayer.mObject.mNpcStats.mWerewolfKills = klst.mWerewolfKills; - } + mContext->mPlayer.mObject.mNpcStats.mWerewolfKills = klst.mWerewolfKills; + } - void write(ESM::ESMWriter &esm) override - { - esm.startRecord(ESM::REC_DCOU); - for (auto it = mKillCounter.begin(); it != mKillCounter.end(); ++it) + void write(ESM::ESMWriter& esm) override { - esm.writeHNString("ID__", it->first); - esm.writeHNT ("COUN", it->second); + esm.startRecord(ESM::REC_DCOU); + for (auto it = mKillCounter.begin(); it != mKillCounter.end(); ++it) + { + esm.writeHNString("ID__", it->first); + esm.writeHNT("COUN", it->second); + } + esm.endRecord(ESM::REC_DCOU); } - esm.endRecord(ESM::REC_DCOU); - } -private: - std::map mKillCounter; -}; + private: + std::map mKillCounter; + }; -class ConvertFACT : public Converter -{ -public: - void read(ESM::ESMReader& esm) override + class ConvertFACT : public Converter { - ESM::Faction faction; - bool isDeleted = false; + public: + void read(ESM::ESMReader& esm) override + { + ESM::Faction faction; + bool isDeleted = false; - faction.load(esm, isDeleted); - std::string id = Misc::StringUtils::lowerCase(faction.mId); + faction.load(esm, isDeleted); + std::string id = Misc::StringUtils::lowerCase(faction.mId); - for (auto it = faction.mReactions.begin(); it != faction.mReactions.end(); ++it) - { - std::string faction2 = Misc::StringUtils::lowerCase(it->first); - mContext->mDialogueState.mChangedFactionReaction[id].insert(std::make_pair(faction2, it->second)); + for (auto it = faction.mReactions.begin(); it != faction.mReactions.end(); ++it) + { + std::string faction2 = Misc::StringUtils::lowerCase(it->first); + mContext->mDialogueState.mChangedFactionReaction[id].insert(std::make_pair(faction2, it->second)); + } } - } -}; + }; -/// Stolen items -class ConvertSTLN : public Converter -{ -public: - void read(ESM::ESMReader &esm) override + /// Stolen items + class ConvertSTLN : public Converter { - std::string itemid = esm.getHNString("NAME"); - Misc::StringUtils::lowerCaseInPlace(itemid); - - while (esm.isNextSub("FNAM") || esm.isNextSub("ONAM")) + public: + void read(ESM::ESMReader& esm) override { - if (esm.retSubName().toString() == "FNAM") - { - std::string factionid = esm.getHString(); - mStolenItems[itemid].insert(std::make_pair(Misc::StringUtils::lowerCase(factionid), true)); - } - else + std::string itemid = esm.getHNString("NAME"); + Misc::StringUtils::lowerCaseInPlace(itemid); + + while (esm.isNextSub("FNAM") || esm.isNextSub("ONAM")) { - std::string ownerid = esm.getHString(); - mStolenItems[itemid].insert(std::make_pair(Misc::StringUtils::lowerCase(ownerid), false)); + if (esm.retSubName().toString() == "FNAM") + { + std::string factionid = esm.getHString(); + mStolenItems[itemid].insert(std::make_pair(Misc::StringUtils::lowerCase(factionid), true)); + } + else + { + std::string ownerid = esm.getHString(); + mStolenItems[itemid].insert(std::make_pair(Misc::StringUtils::lowerCase(ownerid), false)); + } } } - } - void write(ESM::ESMWriter &esm) override - { - ESM::StolenItems items; - for (auto it = mStolenItems.begin(); it != mStolenItems.end(); ++it) + void write(ESM::ESMWriter& esm) override { - std::map, int> owners; - for (const auto & ownerIt : it->second) + ESM::StolenItems items; + for (auto it = mStolenItems.begin(); it != mStolenItems.end(); ++it) { - owners.insert(std::make_pair(std::make_pair(ownerIt.first, ownerIt.second) - // Since OpenMW doesn't suffer from the owner contamination bug, - // it needs a count argument. But for legacy savegames, we don't know - // this count, so must assume all items of that ID are stolen, - // like vanilla MW did. - ,std::numeric_limits::max())); + std::map, int> owners; + for (const auto& ownerIt : it->second) + { + owners.insert(std::make_pair(std::make_pair(ownerIt.first, ownerIt.second) + // Since OpenMW doesn't suffer from the owner contamination bug, + // it needs a count argument. But for legacy savegames, we don't know + // this count, so must assume all items of that ID are stolen, + // like vanilla MW did. + , + std::numeric_limits::max())); + } + + items.mStolenItems.insert(std::make_pair(it->first, owners)); } - items.mStolenItems.insert(std::make_pair(it->first, owners)); + esm.startRecord(ESM::REC_STLN); + items.write(esm); + esm.endRecord(ESM::REC_STLN); } - esm.startRecord(ESM::REC_STLN); - items.write(esm); - esm.endRecord(ESM::REC_STLN); - } - -private: - typedef std::pair Owner; // + private: + typedef std::pair Owner; // - std::map > mStolenItems; -}; + std::map> mStolenItems; + }; -/// Seen responses for a dialogue topic? -/// Each DIAL record is followed by a number of INFO records, I believe, just like in ESMs -/// Dialogue conversion problems: -/// - Journal is stored in one continuous HTML markup rather than each entry separately with associated info ID. -/// - Seen dialogue responses only store the INFO id, rather than the fulltext. -/// - Quest stages only store the INFO id, rather than the journal entry fulltext. -class ConvertINFO : public Converter -{ -public: - void read(ESM::ESMReader& esm) override + /// Seen responses for a dialogue topic? + /// Each DIAL record is followed by a number of INFO records, I believe, just like in ESMs + /// Dialogue conversion problems: + /// - Journal is stored in one continuous HTML markup rather than each entry separately with associated info ID. + /// - Seen dialogue responses only store the INFO id, rather than the fulltext. + /// - Quest stages only store the INFO id, rather than the journal entry fulltext. + class ConvertINFO : public Converter { - INFO info; - info.load(esm); - } -}; + public: + void read(ESM::ESMReader& esm) override + { + INFO info; + info.load(esm); + } + }; -class ConvertDIAL : public Converter -{ -public: - void read(ESM::ESMReader& esm) override + class ConvertDIAL : public Converter { - std::string id = esm.getHNString("NAME"); - DIAL dial; - dial.load(esm); - if (dial.mIndex > 0) - mDials[id] = dial; - } - void write(ESM::ESMWriter &esm) override - { - for (auto it = mDials.begin(); it != mDials.end(); ++it) - { - esm.startRecord(ESM::REC_QUES); - ESM::QuestState state; - state.mFinished = 0; - state.mState = it->second.mIndex; - state.mTopic = Misc::StringUtils::lowerCase(it->first); - state.save(esm); - esm.endRecord(ESM::REC_QUES); + public: + void read(ESM::ESMReader& esm) override + { + std::string id = esm.getHNString("NAME"); + DIAL dial; + dial.load(esm); + if (dial.mIndex > 0) + mDials[id] = dial; + } + void write(ESM::ESMWriter& esm) override + { + for (auto it = mDials.begin(); it != mDials.end(); ++it) + { + esm.startRecord(ESM::REC_QUES); + ESM::QuestState state; + state.mFinished = 0; + state.mState = it->second.mIndex; + state.mTopic = Misc::StringUtils::lowerCase(it->first); + state.save(esm); + esm.endRecord(ESM::REC_QUES); + } } - } -private: - std::map mDials; -}; -class ConvertQUES : public Converter -{ -public: - void read(ESM::ESMReader& esm) override - { - std::string id = esm.getHNString("NAME"); - QUES quest; - quest.load(esm); - } -}; + private: + std::map mDials; + }; -class ConvertJOUR : public Converter -{ -public: - void read(ESM::ESMReader& esm) override + class ConvertQUES : public Converter { - JOUR journal; - journal.load(esm); - } -}; + public: + void read(ESM::ESMReader& esm) override + { + std::string id = esm.getHNString("NAME"); + QUES quest; + quest.load(esm); + } + }; -class ConvertGAME : public Converter -{ -public: - ConvertGAME() - : mHasGame(false) + class ConvertJOUR : public Converter { - } + public: + void read(ESM::ESMReader& esm) override + { + JOUR journal; + journal.load(esm); + } + }; - void read(ESM::ESMReader &esm) override + class ConvertGAME : public Converter { - mGame.load(esm); - mHasGame = true; - } + public: + ConvertGAME() + : mHasGame(false) + { + } - int validateWeatherID(int weatherID) - { - if(weatherID >= -1 && weatherID < 10) + void read(ESM::ESMReader& esm) override { - return weatherID; + mGame.load(esm); + mHasGame = true; } - else + + int validateWeatherID(int weatherID) { - throw std::runtime_error("Invalid weather ID: " + std::to_string(weatherID)); + if (weatherID >= -1 && weatherID < 10) + { + return weatherID; + } + else + { + throw std::runtime_error("Invalid weather ID: " + std::to_string(weatherID)); + } } - } - void write(ESM::ESMWriter &esm) override - { - if (!mHasGame) - return; - esm.startRecord(ESM::REC_WTHR); - ESM::WeatherState weather; - weather.mTimePassed = 0.0f; - weather.mFastForward = false; - weather.mWeatherUpdateTime = mGame.mGMDT.mTimeOfNextTransition - mContext->mHour; - weather.mTransitionFactor = 1 - (mGame.mGMDT.mWeatherTransition / 100.0f); - weather.mCurrentWeather = validateWeatherID(mGame.mGMDT.mCurrentWeather); - weather.mNextWeather = validateWeatherID(mGame.mGMDT.mNextWeather); - weather.mQueuedWeather = -1; - // TODO: Determine how ModRegion modifiers are saved in Morrowind. - weather.save(esm); - esm.endRecord(ESM::REC_WTHR); - } - -private: - bool mHasGame; - GAME mGame; -}; - -/// Running global script -class ConvertSCPT : public Converter -{ -public: - void read(ESM::ESMReader &esm) override - { - SCPT script; - script.load(esm); - ESM::GlobalScript out; - convertSCPT(script, out); - mScripts.push_back(out); - } - void write(ESM::ESMWriter &esm) override + void write(ESM::ESMWriter& esm) override + { + if (!mHasGame) + return; + esm.startRecord(ESM::REC_WTHR); + ESM::WeatherState weather; + weather.mTimePassed = 0.0f; + weather.mFastForward = false; + weather.mWeatherUpdateTime = mGame.mGMDT.mTimeOfNextTransition - mContext->mHour; + weather.mTransitionFactor = 1 - (mGame.mGMDT.mWeatherTransition / 100.0f); + weather.mCurrentWeather = validateWeatherID(mGame.mGMDT.mCurrentWeather); + weather.mNextWeather = validateWeatherID(mGame.mGMDT.mNextWeather); + weather.mQueuedWeather = -1; + // TODO: Determine how ModRegion modifiers are saved in Morrowind. + weather.save(esm); + esm.endRecord(ESM::REC_WTHR); + } + + private: + bool mHasGame; + GAME mGame; + }; + + /// Running global script + class ConvertSCPT : public Converter { - for (const auto & script : mScripts) + public: + void read(ESM::ESMReader& esm) override { - esm.startRecord(ESM::REC_GSCR); - script.save(esm); - esm.endRecord(ESM::REC_GSCR); + SCPT script; + script.load(esm); + ESM::GlobalScript out; + convertSCPT(script, out); + mScripts.push_back(out); + } + void write(ESM::ESMWriter& esm) override + { + for (const auto& script : mScripts) + { + esm.startRecord(ESM::REC_GSCR); + script.save(esm); + esm.endRecord(ESM::REC_GSCR); + } } - } -private: - std::vector mScripts; -}; -/// Projectile converter -class ConvertPROJ : public Converter -{ -public: - int getStage() override { return 2; } - void read(ESM::ESMReader& esm) override; - void write(ESM::ESMWriter& esm) override; -private: - void convertBaseState(ESM::BaseProjectileState& base, const PROJ::PNAM& pnam); - PROJ mProj; -}; - -class ConvertSPLM : public Converter -{ -public: - void read(ESM::ESMReader& esm) override; - void write(ESM::ESMWriter& esm) override; -private: - SPLM mSPLM; -}; + private: + std::vector mScripts; + }; + + /// Projectile converter + class ConvertPROJ : public Converter + { + public: + int getStage() override { return 2; } + void read(ESM::ESMReader& esm) override; + void write(ESM::ESMWriter& esm) override; + + private: + void convertBaseState(ESM::BaseProjectileState& base, const PROJ::PNAM& pnam); + PROJ mProj; + }; + + class ConvertSPLM : public Converter + { + public: + void read(ESM::ESMReader& esm) override; + void write(ESM::ESMWriter& esm) override; + + private: + SPLM mSPLM; + }; } diff --git a/apps/essimporter/convertinventory.cpp b/apps/essimporter/convertinventory.cpp index 002cb4a4cf..484b9d1130 100644 --- a/apps/essimporter/convertinventory.cpp +++ b/apps/essimporter/convertinventory.cpp @@ -7,17 +7,17 @@ namespace ESSImport { - void convertInventory(const Inventory &inventory, ESM::InventoryState &state) + void convertInventory(const Inventory& inventory, ESM::InventoryState& state) { int index = 0; - for (const auto & item : inventory.mItems) + for (const auto& item : inventory.mItems) { ESM::ObjectState objstate; objstate.blank(); objstate.mRef = item; objstate.mRef.mRefID = Misc::StringUtils::lowerCase(item.mId); objstate.mCount = std::abs(item.mCount); // restocking items have negative count in the savefile - // openmw handles them differently, so no need to set any flags + // openmw handles them differently, so no need to set any flags state.mItems.push_back(objstate); if (item.mRelativeEquipmentSlot != -1) // Note we should really write the absolute slot here, which we do not know about diff --git a/apps/essimporter/convertinventory.hpp b/apps/essimporter/convertinventory.hpp index 95d134d4fc..baa10d4414 100644 --- a/apps/essimporter/convertinventory.hpp +++ b/apps/essimporter/convertinventory.hpp @@ -8,7 +8,7 @@ namespace ESSImport { - void convertInventory (const Inventory& inventory, ESM::InventoryState& state); + void convertInventory(const Inventory& inventory, ESM::InventoryState& state); } diff --git a/apps/essimporter/convertnpcc.cpp b/apps/essimporter/convertnpcc.cpp index 48d3d9232e..f049edd8d7 100644 --- a/apps/essimporter/convertnpcc.cpp +++ b/apps/essimporter/convertnpcc.cpp @@ -5,7 +5,7 @@ namespace ESSImport { - void convertNPCC(const NPCC &npcc, ESM::NpcState &npcState) + void convertNPCC(const NPCC& npcc, ESM::NpcState& npcState) { npcState.mNpcStats.mDisposition = npcc.mNPDT.mDisposition; npcState.mNpcStats.mReputation = npcc.mNPDT.mReputation; diff --git a/apps/essimporter/convertnpcc.hpp b/apps/essimporter/convertnpcc.hpp index d0a395e33e..f0c35b72ab 100644 --- a/apps/essimporter/convertnpcc.hpp +++ b/apps/essimporter/convertnpcc.hpp @@ -8,7 +8,7 @@ namespace ESSImport { - void convertNPCC (const NPCC& npcc, ESM::NpcState& npcState); + void convertNPCC(const NPCC& npcc, ESM::NpcState& npcState); } diff --git a/apps/essimporter/convertplayer.cpp b/apps/essimporter/convertplayer.cpp index 34dac06fab..3cb12c2f3a 100644 --- a/apps/essimporter/convertplayer.cpp +++ b/apps/essimporter/convertplayer.cpp @@ -8,13 +8,15 @@ namespace ESSImport { - void convertPCDT(const PCDT& pcdt, ESM::Player& out, std::vector& outDialogueTopics, bool& firstPersonCam, bool& teleportingEnabled, bool& levitationEnabled, ESM::ControlsState& controls) + void convertPCDT(const PCDT& pcdt, ESM::Player& out, std::vector& outDialogueTopics, + bool& firstPersonCam, bool& teleportingEnabled, bool& levitationEnabled, ESM::ControlsState& controls) { - out.mObject.mPosition.rot[0] = -atan2(pcdt.mPNAM.mVerticalRotation.mData[2][1], pcdt.mPNAM.mVerticalRotation.mData[2][2]); + out.mObject.mPosition.rot[0] + = -atan2(pcdt.mPNAM.mVerticalRotation.mData[2][1], pcdt.mPNAM.mVerticalRotation.mData[2][2]); out.mBirthsign = pcdt.mBirthsign; out.mObject.mNpcStats.mBounty = pcdt.mBounty; - for (const auto & essFaction : pcdt.mFactions) + for (const auto& essFaction : pcdt.mFactions) { ESM::NpcStats::Faction faction; faction.mExpelled = (essFaction.mFlags & 0x2) != 0; @@ -22,11 +24,11 @@ namespace ESSImport faction.mReputation = essFaction.mReputation; out.mObject.mNpcStats.mFactions[Misc::StringUtils::lowerCase(essFaction.mFactionName.toString())] = faction; } - for (int i=0; i<3; ++i) + for (int i = 0; i < 3; ++i) out.mObject.mNpcStats.mSpecIncreases[i] = pcdt.mPNAM.mSpecIncreases[i]; - for (int i=0; i<8; ++i) + for (int i = 0; i < 8; ++i) out.mObject.mNpcStats.mSkillIncrease[i] = pcdt.mPNAM.mSkillIncreases[i]; - for (int i=0; i<27; ++i) + for (int i = 0; i < 27; ++i) out.mObject.mNpcStats.mSkills[i].mProgress = pcdt.mPNAM.mSkillProgress[i]; out.mObject.mNpcStats.mLevelProgress = pcdt.mPNAM.mLevelProgress; @@ -39,7 +41,7 @@ namespace ESSImport teleportingEnabled = !(pcdt.mPNAM.mPlayerFlags & PCDT::PlayerFlags_TeleportingDisabled); levitationEnabled = !(pcdt.mPNAM.mPlayerFlags & PCDT::PlayerFlags_LevitationDisabled); - for (const auto & knownDialogueTopic : pcdt.mKnownDialogueTopics) + for (const auto& knownDialogueTopic : pcdt.mKnownDialogueTopics) { outDialogueTopics.push_back(Misc::StringUtils::lowerCase(knownDialogueTopic)); } diff --git a/apps/essimporter/convertplayer.hpp b/apps/essimporter/convertplayer.hpp index 73c98309f8..864a7d8540 100644 --- a/apps/essimporter/convertplayer.hpp +++ b/apps/essimporter/convertplayer.hpp @@ -3,13 +3,14 @@ #include "importplayer.hpp" -#include #include +#include namespace ESSImport { - void convertPCDT(const PCDT& pcdt, ESM::Player& out, std::vector& outDialogueTopics, bool& firstPersonCam, bool& teleportingEnabled, bool& levitationEnabled, ESM::ControlsState& controls); + void convertPCDT(const PCDT& pcdt, ESM::Player& out, std::vector& outDialogueTopics, + bool& firstPersonCam, bool& teleportingEnabled, bool& levitationEnabled, ESM::ControlsState& controls); } diff --git a/apps/essimporter/convertscpt.cpp b/apps/essimporter/convertscpt.cpp index 45cc24db1f..9d03ae3d3c 100644 --- a/apps/essimporter/convertscpt.cpp +++ b/apps/essimporter/convertscpt.cpp @@ -7,7 +7,7 @@ namespace ESSImport { - void convertSCPT(const SCPT &scpt, ESM::GlobalScript &out) + void convertSCPT(const SCPT& scpt, ESM::GlobalScript& out) { out.mId = Misc::StringUtils::lowerCase(scpt.mSCHD.mName.toString()); out.mRunning = scpt.mRunning; diff --git a/apps/essimporter/convertscpt.hpp b/apps/essimporter/convertscpt.hpp index f4a4e34fe4..854cf7c9a0 100644 --- a/apps/essimporter/convertscpt.hpp +++ b/apps/essimporter/convertscpt.hpp @@ -8,7 +8,7 @@ namespace ESSImport { -void convertSCPT(const SCPT& scpt, ESM::GlobalScript& out); + void convertSCPT(const SCPT& scpt, ESM::GlobalScript& out); } diff --git a/apps/essimporter/convertscri.cpp b/apps/essimporter/convertscri.cpp index eba48df77d..1dbe476e2b 100644 --- a/apps/essimporter/convertscri.cpp +++ b/apps/essimporter/convertscri.cpp @@ -19,12 +19,12 @@ namespace namespace ESSImport { - void convertSCRI(const SCRI &scri, ESM::Locals &locals) + void convertSCRI(const SCRI& scri, ESM::Locals& locals) { // order *is* important, as we do not have variable names available in this format - storeVariables (scri.mShorts, locals, scri.mScript); - storeVariables (scri.mLongs, locals, scri.mScript); - storeVariables (scri.mFloats, locals, scri.mScript); + storeVariables(scri.mShorts, locals, scri.mScript); + storeVariables(scri.mLongs, locals, scri.mScript); + storeVariables(scri.mFloats, locals, scri.mScript); } } diff --git a/apps/essimporter/convertscri.hpp b/apps/essimporter/convertscri.hpp index 3908dbacf2..4a1026c399 100644 --- a/apps/essimporter/convertscri.hpp +++ b/apps/essimporter/convertscri.hpp @@ -9,7 +9,7 @@ namespace ESSImport { /// Convert script variable assignments - void convertSCRI (const SCRI& scri, ESM::Locals& locals); + void convertSCRI(const SCRI& scri, ESM::Locals& locals); } diff --git a/apps/essimporter/importacdt.hpp b/apps/essimporter/importacdt.hpp index 933cf0f577..785e988200 100644 --- a/apps/essimporter/importacdt.hpp +++ b/apps/essimporter/importacdt.hpp @@ -38,7 +38,8 @@ namespace ESSImport float mDynamic[3][2]; unsigned char mUnknown3[16]; float mAttributes[8][2]; - float mMagicEffects[27]; // Effect attributes: https://wiki.openmw.org/index.php?title=Research:Magic#Effect_attributes + float mMagicEffects[27]; // Effect attributes: + // https://wiki.openmw.org/index.php?title=Research:Magic#Effect_attributes unsigned char mUnknown4[4]; unsigned int mGoldPool; unsigned char mCountDown; // seen the same value as in ACSC.mCorpseClearCountdown, maybe diff --git a/apps/essimporter/importcellref.cpp b/apps/essimporter/importcellref.cpp index 3de1f73e70..0af765d4a8 100644 --- a/apps/essimporter/importcellref.cpp +++ b/apps/essimporter/importcellref.cpp @@ -5,7 +5,7 @@ namespace ESSImport { - void CellRef::load(ESM::ESMReader &esm) + void CellRef::load(ESM::ESMReader& esm) { blank(); @@ -13,7 +13,7 @@ namespace ESSImport // this is required since openmw supports more than 255 content files int pluginIndex = (mRefNum.mIndex & 0xff000000) >> 24; - mRefNum.mContentFile = pluginIndex-1; + mRefNum.mContentFile = pluginIndex - 1; mRefNum.mIndex &= 0x00ffffff; mIndexedRefId = esm.getHNString("NAME"); @@ -39,7 +39,7 @@ namespace ESSImport esm.skipHSub(); if (esm.isNextSub("MNAM")) - esm.skipHSub(); + esm.skipHSub(); bool isDeleted = false; ESM::CellRef::loadData(esm, isDeleted); @@ -123,10 +123,10 @@ namespace ESSImport // FIXME: not all actors have this, add flag if (esm.isNextSub("CHRD")) // npc only - esm.getHExact(mActorData.mSkills, 27*2*sizeof(int)); + esm.getHExact(mActorData.mSkills, 27 * 2 * sizeof(int)); if (esm.isNextSub("CRED")) // creature only - esm.getHExact(mActorData.mCombatStats, 3*2*sizeof(int)); + esm.getHExact(mActorData.mCombatStats, 3 * 2 * sizeof(int)); mActorData.mSCRI.load(esm); @@ -146,7 +146,7 @@ namespace ESSImport // probably some identifier for the creature that has been spawned? unsigned char lvcr; esm.getHT(lvcr); - //std::cout << "LVCR: " << (int)lvcr << std::endl; + // std::cout << "LVCR: " << (int)lvcr << std::endl; } mEnabled = true; diff --git a/apps/essimporter/importcntc.cpp b/apps/essimporter/importcntc.cpp index a4b54ca7b4..41f4e50101 100644 --- a/apps/essimporter/importcntc.cpp +++ b/apps/essimporter/importcntc.cpp @@ -5,7 +5,7 @@ namespace ESSImport { - void CNTC::load(ESM::ESMReader &esm) + void CNTC::load(ESM::ESMReader& esm) { mIndex = 0; esm.getHNT(mIndex, "INDX"); diff --git a/apps/essimporter/importcrec.cpp b/apps/essimporter/importcrec.cpp index 6cef13333b..38ebd724f7 100644 --- a/apps/essimporter/importcrec.cpp +++ b/apps/essimporter/importcrec.cpp @@ -5,7 +5,7 @@ namespace ESSImport { - void CREC::load(ESM::ESMReader &esm) + void CREC::load(ESM::ESMReader& esm) { esm.getHNT(mIndex, "INDX"); @@ -14,9 +14,8 @@ namespace ESSImport float scale; esm.getHNOT(scale, "XSCL"); - while (esm.isNextSub("AI_W") || esm.isNextSub("AI_E") || esm.isNextSub("AI_T") || esm.isNextSub("AI_F") - || esm.isNextSub("AI_A")) + || esm.isNextSub("AI_A")) mAiPackages.add(esm); mInventory.load(esm); diff --git a/apps/essimporter/importdial.cpp b/apps/essimporter/importdial.cpp index 1467e43365..6c45f9d059 100644 --- a/apps/essimporter/importdial.cpp +++ b/apps/essimporter/importdial.cpp @@ -5,7 +5,7 @@ namespace ESSImport { - void DIAL::load(ESM::ESMReader &esm) + void DIAL::load(ESM::ESMReader& esm) { // See ESM::Dialogue::Type enum, not sure why we would need this here though int type = 0; diff --git a/apps/essimporter/importer.cpp b/apps/essimporter/importer.cpp index 5bc8079bd1..179e31adbd 100644 --- a/apps/essimporter/importer.cpp +++ b/apps/essimporter/importer.cpp @@ -1,26 +1,26 @@ #include "importer.hpp" -#include #include #include +#include -#include #include +#include +#include #include #include -#include -#include #include +#include #include -#include #include -#include #include #include #include +#include +#include #include @@ -35,25 +35,25 @@ namespace void writeScreenshot(const ESM::Header& fileHeader, ESM::SavedGame& out) { - if (fileHeader.mSCRS.size() != 128*128*4) + if (fileHeader.mSCRS.size() != 128 * 128 * 4) { std::cerr << "Error: unexpected screenshot size " << std::endl; return; } - osg::ref_ptr image (new osg::Image); + osg::ref_ptr image(new osg::Image); image->allocateImage(128, 128, 1, GL_RGB, GL_UNSIGNED_BYTE); // need to convert pixel format from BGRA to RGB as the jpg readerwriter doesn't support it otherwise auto it = fileHeader.mSCRS.begin(); - for (int y=0; y<128; ++y) + for (int y = 0; y < 128; ++y) { - for (int x=0; x<128; ++x) + for (int x = 0; x < 128; ++x) { - assert(image->data(x,y)); - *(image->data(x,y)+2) = *it++; - *(image->data(x,y)+1) = *it++; - *image->data(x,y) = *it++; + assert(image->data(x, y)); + *(image->data(x, y) + 2) = *it++; + *(image->data(x, y) + 1) = *it++; + *image->data(x, y) = *it++; ++it; // skip alpha } } @@ -72,7 +72,8 @@ namespace osgDB::ReaderWriter::WriteResult result = readerwriter->writeImage(*image, ostream); if (!result.success()) { - std::cerr << "Error: can't write screenshot: " << result.message() << " code " << result.status() << std::endl; + std::cerr << "Error: can't write screenshot: " << result.message() << " code " << result.status() + << std::endl; return; } @@ -85,12 +86,12 @@ namespace namespace ESSImport { - Importer::Importer(const std::filesystem::path &essfile, const std::filesystem::path &outfile, const std::string &encoding) + Importer::Importer( + const std::filesystem::path& essfile, const std::filesystem::path& outfile, const std::string& encoding) : mEssFile(essfile) , mOutFile(outfile) , mEncoding(encoding) { - } struct File @@ -112,7 +113,7 @@ namespace ESSImport std::vector mRecords; }; - void read(const std::filesystem::path &filename, File& file) + void read(const std::filesystem::path& filename, File& file) { ESM::ESMReader esm; esm.open(filename); @@ -143,14 +144,14 @@ namespace ESSImport void Importer::compare() { // data that always changes (and/or is already fully decoded) should be blacklisted - std::set > blacklist; + std::set> blacklist; blacklist.insert(std::make_pair("GLOB", "FLTV")); // gamehour blacklist.insert(std::make_pair("REFR", "DATA")); // player position blacklist.insert(std::make_pair("CELL", "NAM8")); // fog of war blacklist.insert(std::make_pair("GAME", "GMDT")); // weather data, current time always changes blacklist.insert(std::make_pair("CELL", "DELE")); // first 3 bytes are uninitialized - // this changes way too often, name suggests some renderer internal data? + // this changes way too often, name suggests some renderer internal data? blacklist.insert(std::make_pair("CELL", "ND3D")); blacklist.insert(std::make_pair("REFR", "ND3D")); @@ -160,7 +161,7 @@ namespace ESSImport read(mOutFile, file2); // todo rename variable // FIXME: use max(size1, size2) - for (unsigned int i=0; i= rec2.mSubrecords.size()) { std::ios::fmtflags f(std::cout.flags()); - std::cout << "Subrecord in file1 not present in file2: (1) 0x" << std::hex << sub.mFileOffset << std::endl; + std::cout << "Subrecord in file1 not present in file2: (1) 0x" << std::hex << sub.mFileOffset + << std::endl; std::cout.flags(f); return; } @@ -200,8 +202,9 @@ namespace ESSImport if (sub.mName != sub2.mName) { std::ios::fmtflags f(std::cout.flags()); - std::cout << "Different subrecord name (" << rec.mName << "." << sub.mName << " vs. " << sub2.mName << ") at (1) 0x" << std::hex << sub.mFileOffset - << " (2) 0x" << sub2.mFileOffset << std::endl; + std::cout << "Different subrecord name (" << rec.mName << "." << sub.mName << " vs. " << sub2.mName + << ") at (1) 0x" << std::hex << sub.mFileOffset << " (2) 0x" << sub2.mFileOffset + << std::endl; std::cout.flags(f); break; // TODO: try to recover } @@ -213,11 +216,11 @@ namespace ESSImport std::ios::fmtflags f(std::cout.flags()); - std::cout << "Different subrecord data for " << rec.mName << "." << sub.mName << " at (1) 0x" << std::hex << sub.mFileOffset - << " (2) 0x" << sub2.mFileOffset << std::endl; + std::cout << "Different subrecord data for " << rec.mName << "." << sub.mName << " at (1) 0x" + << std::hex << sub.mFileOffset << " (2) 0x" << sub2.mFileOffset << std::endl; std::cout << "Data 1:" << std::endl; - for (unsigned int k=0; k= sub2.mData.size() || sub2.mData[k] != sub.mData[k]) @@ -232,7 +235,7 @@ namespace ESSImport std::cout << std::endl; std::cout << "Data 2:" << std::endl; - for (unsigned int k=0; k= sub.mData.size() || sub.mData[k] != sub2.mData[k]) @@ -279,12 +282,12 @@ namespace ESSImport converters[ESM::REC_CREA] = std::make_unique(); converters[ESM::REC_NPCC] = std::make_unique(); converters[ESM::REC_CREC] = std::make_unique(); - converters[recREFR ] = std::make_unique(); - converters[recPCDT ] = std::make_unique(); - converters[recFMAP ] = std::make_unique(); - converters[recKLST ] = std::make_unique(); - converters[recSTLN ] = std::make_unique(); - converters[recGAME ] = std::make_unique(); + converters[recREFR] = std::make_unique(); + converters[recPCDT] = std::make_unique(); + converters[recFMAP] = std::make_unique(); + converters[recKLST] = std::make_unique(); + converters[recSTLN] = std::make_unique(); + converters[recGAME] = std::make_unique(); converters[ESM::REC_CELL] = std::make_unique(); converters[ESM::REC_ALCH] = std::make_unique>(); converters[ESM::REC_CLAS] = std::make_unique(); @@ -301,7 +304,7 @@ namespace ESSImport converters[ESM::REC_INFO] = std::make_unique(); converters[ESM::REC_DIAL] = std::make_unique(); converters[ESM::REC_QUES] = std::make_unique(); - converters[recJOUR ] = std::make_unique(); + converters[recJOUR] = std::make_unique(); converters[ESM::REC_SCPT] = std::make_unique(); converters[ESM::REC_PROJ] = std::make_unique(); converters[recSPLM] = std::make_unique(); @@ -313,7 +316,7 @@ namespace ESSImport std::set unknownRecords; - for (const auto & converter : converters) + for (const auto& converter : converters) { converter.second->setContext(context); } @@ -333,7 +336,8 @@ namespace ESSImport if (unknownRecords.insert(n.toInt()).second) { std::ios::fmtflags f(std::cerr.flags()); - std::cerr << "Error: unknown record " << n.toString() << " (0x" << std::hex << esm.getFileOffset() << ")" << std::endl; + std::cerr << "Error: unknown record " << n.toString() << " (0x" << std::hex << esm.getFileOffset() + << ")" << std::endl; std::cerr.flags(f); } @@ -343,7 +347,7 @@ namespace ESSImport ESM::ESMWriter writer; - writer.setFormat (ESM::SavedGame::sCurrentFormat); + writer.setFormat(ESM::SavedGame::sCurrentFormat); std::ofstream stream(mOutFile, std::ios::out | std::ios::binary); // all unused @@ -351,15 +355,15 @@ namespace ESSImport writer.setType(0); writer.setAuthor(""); writer.setDescription(""); - writer.setRecordCount (0); + writer.setRecordCount(0); - for (const auto & master : header.mMaster) + for (const auto& master : header.mMaster) writer.addMaster(master.name, 0); // not using the size information anyway -> use value of 0 - writer.save (stream); + writer.save(stream); ESM::SavedGame profile; - for (const auto & master : header.mMaster) + for (const auto& master : header.mMaster) { profile.mContentFiles.push_back(master.name); } @@ -379,14 +383,13 @@ namespace ESSImport writeScreenshot(header, profile); - writer.startRecord (ESM::REC_SAVE); - profile.save (writer); - writer.endRecord (ESM::REC_SAVE); + writer.startRecord(ESM::REC_SAVE); + profile.save(writer); + writer.endRecord(ESM::REC_SAVE); // Writing order should be Dynamic Store -> Cells -> Player, // so that references to dynamic records can be recognized when loading - for (auto it = converters.begin(); - it != converters.end(); ++it) + for (auto it = converters.begin(); it != converters.end(); ++it) { if (it->second->getStage() != 0) continue; @@ -398,8 +401,7 @@ namespace ESSImport context.mPlayerBase.save(writer); writer.endRecord(ESM::REC_NPC_); - for (auto it = converters.begin(); - it != converters.end(); ++it) + for (auto it = converters.begin(); it != converters.end(); ++it) { if (it->second->getStage() != 1) continue; @@ -410,8 +412,10 @@ namespace ESSImport if (context.mPlayer.mCellId.mPaged) { // exterior cell -> determine cell coordinates based on position - int cellX = static_cast(std::floor(context.mPlayer.mObject.mPosition.pos[0] / Constants::CellSizeInUnits)); - int cellY = static_cast(std::floor(context.mPlayer.mObject.mPosition.pos[1] / Constants::CellSizeInUnits)); + int cellX + = static_cast(std::floor(context.mPlayer.mObject.mPosition.pos[0] / Constants::CellSizeInUnits)); + int cellY + = static_cast(std::floor(context.mPlayer.mObject.mPosition.pos[1] / Constants::CellSizeInUnits)); context.mPlayer.mCellId.mIndex.mX = cellX; context.mPlayer.mCellId.mIndex.mY = cellY; } @@ -423,15 +427,14 @@ namespace ESSImport writer.endRecord(ESM::REC_ACTC); // Stage 2 requires cell references to be written / actors IDs assigned - for (auto it = converters.begin(); - it != converters.end(); ++it) + for (auto it = converters.begin(); it != converters.end(); ++it) { if (it->second->getStage() != 2) continue; it->second->write(writer); } - writer.startRecord (ESM::REC_DIAS); + writer.startRecord(ESM::REC_DIAS); context.mDialogueState.save(writer); writer.endRecord(ESM::REC_DIAS); @@ -440,5 +443,4 @@ namespace ESSImport writer.endRecord(ESM::REC_INPU); } - } diff --git a/apps/essimporter/importer.hpp b/apps/essimporter/importer.hpp index 9d114fad27..fba1992808 100644 --- a/apps/essimporter/importer.hpp +++ b/apps/essimporter/importer.hpp @@ -9,7 +9,8 @@ namespace ESSImport class Importer { public: - Importer(const std::filesystem::path &essfile, const std::filesystem::path &outfile, const std::string& encoding); + Importer( + const std::filesystem::path& essfile, const std::filesystem::path& outfile, const std::string& encoding); void run(); diff --git a/apps/essimporter/importercontext.hpp b/apps/essimporter/importercontext.hpp index a3a3e11884..baad8a366f 100644 --- a/apps/essimporter/importercontext.hpp +++ b/apps/essimporter/importercontext.hpp @@ -3,17 +3,16 @@ #include -#include -#include +#include #include #include #include #include -#include +#include -#include "importnpcc.hpp" -#include "importcrec.hpp" #include "importcntc.hpp" +#include "importcrec.hpp" +#include "importnpcc.hpp" #include "importsplm.h" namespace ESSImport @@ -33,7 +32,7 @@ namespace ESSImport ESM::ControlsState mControlsState; // cells which should show an explored overlay on the global map - std::set > mExploredCells; + std::set> mExploredCells; ESM::GlobalMap mGlobalMapState; @@ -64,10 +63,8 @@ namespace ESSImport playerCellId.mPaged = true; playerCellId.mIndex.mX = playerCellId.mIndex.mY = 0; mPlayer.mCellId = playerCellId; - mPlayer.mLastKnownExteriorPosition[0] - = mPlayer.mLastKnownExteriorPosition[1] - = mPlayer.mLastKnownExteriorPosition[2] - = 0.0f; + mPlayer.mLastKnownExteriorPosition[0] = mPlayer.mLastKnownExteriorPosition[1] + = mPlayer.mLastKnownExteriorPosition[2] = 0.0f; mPlayer.mHasMark = 0; mPlayer.mCurrentCrimeId = -1; // TODO mPlayer.mPaidCrimeId = -1; @@ -84,10 +81,7 @@ namespace ESSImport mPlayerBase.blank(); } - int generateActorId() - { - return mNextActorId++; - } + int generateActorId() { return mNextActorId++; } }; } diff --git a/apps/essimporter/importgame.cpp b/apps/essimporter/importgame.cpp index df36afe784..2a2572aae3 100644 --- a/apps/essimporter/importgame.cpp +++ b/apps/essimporter/importgame.cpp @@ -5,25 +5,25 @@ namespace ESSImport { -void GAME::load(ESM::ESMReader &esm) -{ - esm.getSubNameIs("GMDT"); - esm.getSubHeader(); - if (esm.getSubSize() == 92) - { - esm.getExact(&mGMDT, 92); - mGMDT.mSecundaPhase = 0; - } - else if (esm.getSubSize() == 96) + void GAME::load(ESM::ESMReader& esm) { - esm.getT(mGMDT); - } - else - esm.fail("unexpected subrecord size for GAME.GMDT"); + esm.getSubNameIs("GMDT"); + esm.getSubHeader(); + if (esm.getSubSize() == 92) + { + esm.getExact(&mGMDT, 92); + mGMDT.mSecundaPhase = 0; + } + else if (esm.getSubSize() == 96) + { + esm.getT(mGMDT); + } + else + esm.fail("unexpected subrecord size for GAME.GMDT"); - mGMDT.mWeatherTransition &= (0x000000ff); - mGMDT.mSecundaPhase &= (0x000000ff); - mGMDT.mMasserPhase &= (0x000000ff); -} + mGMDT.mWeatherTransition &= (0x000000ff); + mGMDT.mSecundaPhase &= (0x000000ff); + mGMDT.mMasserPhase &= (0x000000ff); + } } diff --git a/apps/essimporter/importgame.hpp b/apps/essimporter/importgame.hpp index d8051a527a..8b26b9d8bd 100644 --- a/apps/essimporter/importgame.hpp +++ b/apps/essimporter/importgame.hpp @@ -14,13 +14,13 @@ namespace ESSImport { struct GMDT { - char mCellName[64] {}; - int mFogColour {0}; - float mFogDensity {0.f}; - int mCurrentWeather {0}, mNextWeather {0}; - int mWeatherTransition {0}; // 0-100 transition between weathers, top 3 bytes may be garbage - float mTimeOfNextTransition {0.f}; // weather changes when gamehour == timeOfNextTransition - int mMasserPhase {0}, mSecundaPhase {0}; // top 3 bytes may be garbage + char mCellName[64]{}; + int mFogColour{ 0 }; + float mFogDensity{ 0.f }; + int mCurrentWeather{ 0 }, mNextWeather{ 0 }; + int mWeatherTransition{ 0 }; // 0-100 transition between weathers, top 3 bytes may be garbage + float mTimeOfNextTransition{ 0.f }; // weather changes when gamehour == timeOfNextTransition + int mMasserPhase{ 0 }, mSecundaPhase{ 0 }; // top 3 bytes may be garbage }; GMDT mGMDT; diff --git a/apps/essimporter/importinfo.cpp b/apps/essimporter/importinfo.cpp index 49a0c745f6..66902f6ff4 100644 --- a/apps/essimporter/importinfo.cpp +++ b/apps/essimporter/importinfo.cpp @@ -5,7 +5,7 @@ namespace ESSImport { - void INFO::load(ESM::ESMReader &esm) + void INFO::load(ESM::ESMReader& esm) { mInfo = esm.getHNString("INAM"); mActorRefId = esm.getHNString("ACDT"); diff --git a/apps/essimporter/importinventory.cpp b/apps/essimporter/importinventory.cpp index c4d11763f5..723151236d 100644 --- a/apps/essimporter/importinventory.cpp +++ b/apps/essimporter/importinventory.cpp @@ -7,7 +7,7 @@ namespace ESSImport { - void Inventory::load(ESM::ESMReader &esm) + void Inventory::load(ESM::ESMReader& esm) { while (esm.isNextSub("NPCO")) { @@ -23,7 +23,7 @@ namespace ESSImport unsigned int itemCount = std::abs(item.mCount); bool separateStacks = false; - for (unsigned int i=0;i #include +#include -#include #include +#include #include "importscri.hpp" diff --git a/apps/essimporter/importjour.cpp b/apps/essimporter/importjour.cpp index 1c46b3159c..19a2d601c2 100644 --- a/apps/essimporter/importjour.cpp +++ b/apps/essimporter/importjour.cpp @@ -5,7 +5,7 @@ namespace ESSImport { - void JOUR::load(ESM::ESMReader &esm) + void JOUR::load(ESM::ESMReader& esm) { mText = esm.getHNString("NAME"); } diff --git a/apps/essimporter/importklst.cpp b/apps/essimporter/importklst.cpp index 5d9f22a31c..d4cfc7f769 100644 --- a/apps/essimporter/importklst.cpp +++ b/apps/essimporter/importklst.cpp @@ -5,7 +5,7 @@ namespace ESSImport { - void KLST::load(ESM::ESMReader &esm) + void KLST::load(ESM::ESMReader& esm) { while (esm.isNextSub("KNAM")) { diff --git a/apps/essimporter/importklst.hpp b/apps/essimporter/importklst.hpp index d07332600f..7c1ff03bb6 100644 --- a/apps/essimporter/importklst.hpp +++ b/apps/essimporter/importklst.hpp @@ -1,8 +1,8 @@ #ifndef OPENMW_ESSIMPORT_KLST_H #define OPENMW_ESSIMPORT_KLST_H -#include #include +#include namespace ESM { diff --git a/apps/essimporter/importnpcc.cpp b/apps/essimporter/importnpcc.cpp index 4d8da66f0f..1b1a87ab8e 100644 --- a/apps/essimporter/importnpcc.cpp +++ b/apps/essimporter/importnpcc.cpp @@ -5,12 +5,12 @@ namespace ESSImport { - void NPCC::load(ESM::ESMReader &esm) + void NPCC::load(ESM::ESMReader& esm) { esm.getHNT(mNPDT, "NPDT"); while (esm.isNextSub("AI_W") || esm.isNextSub("AI_E") || esm.isNextSub("AI_T") || esm.isNextSub("AI_F") - || esm.isNextSub("AI_A")) + || esm.isNextSub("AI_A")) mAiPackages.add(esm); mInventory.load(esm); diff --git a/apps/essimporter/importnpcc.hpp b/apps/essimporter/importnpcc.hpp index d525c00743..1cc355b06c 100644 --- a/apps/essimporter/importnpcc.hpp +++ b/apps/essimporter/importnpcc.hpp @@ -29,7 +29,7 @@ namespace ESSImport Inventory mInventory; ESM::AIPackageList mAiPackages; - void load(ESM::ESMReader &esm); + void load(ESM::ESMReader& esm); }; } diff --git a/apps/essimporter/importplayer.cpp b/apps/essimporter/importplayer.cpp index 3285ac15e3..aa00e45b3e 100644 --- a/apps/essimporter/importplayer.cpp +++ b/apps/essimporter/importplayer.cpp @@ -5,7 +5,7 @@ namespace ESSImport { - void PCDT::load(ESM::ESMReader &esm) + void PCDT::load(ESM::ESMReader& esm) { while (esm.isNextSub("DNAM")) { diff --git a/apps/essimporter/importplayer.hpp b/apps/essimporter/importplayer.hpp index 83d8dc1ead..252202ccf2 100644 --- a/apps/essimporter/importplayer.hpp +++ b/apps/essimporter/importplayer.hpp @@ -1,12 +1,12 @@ #ifndef OPENMW_ESSIMPORT_PLAYER_H #define OPENMW_ESSIMPORT_PLAYER_H -#include #include +#include #include -#include #include +#include namespace ESM { @@ -16,102 +16,102 @@ namespace ESM namespace ESSImport { -/// Other player data -struct PCDT -{ - int mBounty; - std::string mBirthsign; + /// Other player data + struct PCDT + { + int mBounty; + std::string mBirthsign; - std::vector mKnownDialogueTopics; + std::vector mKnownDialogueTopics; - enum PlayerFlags - { - PlayerFlags_ViewSwitchDisabled = 0x1, - PlayerFlags_ControlsDisabled = 0x4, - PlayerFlags_Sleeping = 0x10, - PlayerFlags_Waiting = 0x40, - PlayerFlags_WeaponDrawn = 0x80, - PlayerFlags_SpellDrawn = 0x100, - PlayerFlags_InJail = 0x200, - PlayerFlags_JumpingDisabled = 0x1000, - PlayerFlags_LookingDisabled = 0x2000, - PlayerFlags_VanityModeDisabled = 0x4000, - PlayerFlags_WeaponDrawingDisabled = 0x8000, - PlayerFlags_SpellDrawingDisabled = 0x10000, - PlayerFlags_ThirdPerson = 0x20000, - PlayerFlags_TeleportingDisabled = 0x40000, - PlayerFlags_LevitationDisabled = 0x80000 - }; + enum PlayerFlags + { + PlayerFlags_ViewSwitchDisabled = 0x1, + PlayerFlags_ControlsDisabled = 0x4, + PlayerFlags_Sleeping = 0x10, + PlayerFlags_Waiting = 0x40, + PlayerFlags_WeaponDrawn = 0x80, + PlayerFlags_SpellDrawn = 0x100, + PlayerFlags_InJail = 0x200, + PlayerFlags_JumpingDisabled = 0x1000, + PlayerFlags_LookingDisabled = 0x2000, + PlayerFlags_VanityModeDisabled = 0x4000, + PlayerFlags_WeaponDrawingDisabled = 0x8000, + PlayerFlags_SpellDrawingDisabled = 0x10000, + PlayerFlags_ThirdPerson = 0x20000, + PlayerFlags_TeleportingDisabled = 0x40000, + PlayerFlags_LevitationDisabled = 0x80000 + }; #pragma pack(push) #pragma pack(1) - struct FNAM - { - unsigned char mRank; - unsigned char mUnknown1[3]; - int mReputation; - unsigned char mFlags; // 0x1: unknown, 0x2: expelled - unsigned char mUnknown2[3]; - ESM::NAME32 mFactionName; - }; - - struct PNAM - { - struct MarkLocation + struct FNAM { - float mX, mY, mZ; // worldspace position - float mRotZ; // Z angle in radians - int mCellX, mCellY; // grid coordinates; for interior cells this is always (0, 0) + unsigned char mRank; + unsigned char mUnknown1[3]; + int mReputation; + unsigned char mFlags; // 0x1: unknown, 0x2: expelled + unsigned char mUnknown2[3]; + ESM::NAME32 mFactionName; }; - struct Rotation + struct PNAM { - float mData[3][3]; + struct MarkLocation + { + float mX, mY, mZ; // worldspace position + float mRotZ; // Z angle in radians + int mCellX, mCellY; // grid coordinates; for interior cells this is always (0, 0) + }; + + struct Rotation + { + float mData[3][3]; + }; + + int mPlayerFlags; // controls, camera and draw state + unsigned int mLevelProgress; + float mSkillProgress[27]; // skill progress, non-uniform scaled + unsigned char mSkillIncreases[8]; // number of skill increases for each attribute + int mTelekinesisRangeBonus; // in units; seems redundant + float mVisionBonus; // range: <0.0, 1.0>; affected by light spells and Get/Mod/SetPCVisionBonus + int mDetectKeyMagnitude; // seems redundant + int mDetectEnchantmentMagnitude; // seems redundant + int mDetectAnimalMagnitude; // seems redundant + MarkLocation mMarkLocation; + unsigned char mUnknown3[4]; + Rotation mVerticalRotation; + unsigned char mSpecIncreases[3]; // number of skill increases for each specialization + unsigned char mUnknown4; }; - int mPlayerFlags; // controls, camera and draw state - unsigned int mLevelProgress; - float mSkillProgress[27]; // skill progress, non-uniform scaled - unsigned char mSkillIncreases[8]; // number of skill increases for each attribute - int mTelekinesisRangeBonus; // in units; seems redundant - float mVisionBonus; // range: <0.0, 1.0>; affected by light spells and Get/Mod/SetPCVisionBonus - int mDetectKeyMagnitude; // seems redundant - int mDetectEnchantmentMagnitude; // seems redundant - int mDetectAnimalMagnitude; // seems redundant - MarkLocation mMarkLocation; - unsigned char mUnknown3[4]; - Rotation mVerticalRotation; - unsigned char mSpecIncreases[3]; // number of skill increases for each specialization - unsigned char mUnknown4; - }; - - struct ENAM - { - int mCellX; - int mCellY; - }; + struct ENAM + { + int mCellX; + int mCellY; + }; - struct AADT // 44 bytes - { - int animGroupIndex; // See convertANIS() for the mapping. - unsigned char mUnknown5[40]; - }; + struct AADT // 44 bytes + { + int animGroupIndex; // See convertANIS() for the mapping. + unsigned char mUnknown5[40]; + }; #pragma pack(pop) - std::vector mFactions; - PNAM mPNAM; + std::vector mFactions; + PNAM mPNAM; - bool mHasMark; - std::string mMNAM; // mark cell name; can also be sDefaultCellname or region name + bool mHasMark; + std::string mMNAM; // mark cell name; can also be sDefaultCellname or region name - bool mHasENAM; - ENAM mENAM; // last exterior cell + bool mHasENAM; + ENAM mENAM; // last exterior cell - bool mHasAADT; - AADT mAADT; + bool mHasAADT; + AADT mAADT; - void load(ESM::ESMReader& esm); -}; + void load(ESM::ESMReader& esm); + }; } diff --git a/apps/essimporter/importproj.cpp b/apps/essimporter/importproj.cpp index aada41a778..909b228417 100644 --- a/apps/essimporter/importproj.cpp +++ b/apps/essimporter/importproj.cpp @@ -5,14 +5,14 @@ namespace ESSImport { -void ESSImport::PROJ::load(ESM::ESMReader& esm) -{ - while (esm.isNextSub("PNAM")) + void ESSImport::PROJ::load(ESM::ESMReader& esm) { - PNAM pnam; - esm.getHT(pnam); - mProjectiles.push_back(pnam); + while (esm.isNextSub("PNAM")) + { + PNAM pnam; + esm.getHT(pnam); + mProjectiles.push_back(pnam); + } } -} } diff --git a/apps/essimporter/importproj.h b/apps/essimporter/importproj.h index b8abab5fa2..d1c544f66f 100644 --- a/apps/essimporter/importproj.h +++ b/apps/essimporter/importproj.h @@ -1,9 +1,9 @@ #ifndef OPENMW_ESSIMPORT_IMPORTPROJ_H #define OPENMW_ESSIMPORT_IMPORTPROJ_H -#include #include #include +#include namespace ESM { @@ -13,34 +13,34 @@ namespace ESM namespace ESSImport { -struct PROJ -{ + struct PROJ + { #pragma pack(push) #pragma pack(1) - struct PNAM // 184 bytes - { - float mAttackStrength; - float mSpeed; - unsigned char mUnknown[4*2]; - float mFlightTime; - int mSplmIndex; // reference to a SPLM record (0 for ballistic projectiles) - unsigned char mUnknown2[4]; - ESM::Vector3 mVelocity; - ESM::Vector3 mPosition; - unsigned char mUnknown3[4*9]; - ESM::NAME32 mActorId; // indexed refID (with the exception of "PlayerSaveGame") - ESM::NAME32 mArrowId; - ESM::NAME32 mBowId; - - bool isMagic() const { return mSplmIndex != 0; } - }; + struct PNAM // 184 bytes + { + float mAttackStrength; + float mSpeed; + unsigned char mUnknown[4 * 2]; + float mFlightTime; + int mSplmIndex; // reference to a SPLM record (0 for ballistic projectiles) + unsigned char mUnknown2[4]; + ESM::Vector3 mVelocity; + ESM::Vector3 mPosition; + unsigned char mUnknown3[4 * 9]; + ESM::NAME32 mActorId; // indexed refID (with the exception of "PlayerSaveGame") + ESM::NAME32 mArrowId; + ESM::NAME32 mBowId; + + bool isMagic() const { return mSplmIndex != 0; } + }; #pragma pack(pop) - std::vector mProjectiles; + std::vector mProjectiles; - void load(ESM::ESMReader& esm); -}; + void load(ESM::ESMReader& esm); + }; } diff --git a/apps/essimporter/importques.cpp b/apps/essimporter/importques.cpp index b57083b0b3..46e08cdd9a 100644 --- a/apps/essimporter/importques.cpp +++ b/apps/essimporter/importques.cpp @@ -5,7 +5,7 @@ namespace ESSImport { - void QUES::load(ESM::ESMReader &esm) + void QUES::load(ESM::ESMReader& esm) { while (esm.isNextSub("DATA")) mInfo.push_back(esm.getHString()); diff --git a/apps/essimporter/importscpt.cpp b/apps/essimporter/importscpt.cpp index 5760d8b438..8768c27010 100644 --- a/apps/essimporter/importscpt.cpp +++ b/apps/essimporter/importscpt.cpp @@ -2,11 +2,10 @@ #include - namespace ESSImport { - void SCPT::load(ESM::ESMReader &esm) + void SCPT::load(ESM::ESMReader& esm) { esm.getHNT(mSCHD, "SCHD"); diff --git a/apps/essimporter/importscpt.hpp b/apps/essimporter/importscpt.hpp index 78c6baebe4..8f60532447 100644 --- a/apps/essimporter/importscpt.hpp +++ b/apps/essimporter/importscpt.hpp @@ -3,8 +3,8 @@ #include "importscri.hpp" -#include #include +#include namespace ESM { @@ -16,8 +16,8 @@ namespace ESSImport struct SCHD { - ESM::NAME32 mName; - ESM::Script::SCHDstruct mData; + ESM::NAME32 mName; + ESM::Script::SCHDstruct mData; }; // A running global script diff --git a/apps/essimporter/importscri.cpp b/apps/essimporter/importscri.cpp index 40a5516147..b6c1d4094c 100644 --- a/apps/essimporter/importscri.cpp +++ b/apps/essimporter/importscri.cpp @@ -2,11 +2,10 @@ #include - namespace ESSImport { - void SCRI::load(ESM::ESMReader &esm) + void SCRI::load(ESM::ESMReader& esm) { mScript = esm.getHNOString("SCRI"); @@ -22,7 +21,7 @@ namespace ESSImport if (esm.isNextSub("SLSD")) { esm.getSubHeader(); - for (int i=0; i #include #include +#include namespace ESM { @@ -13,68 +13,67 @@ namespace ESM namespace ESSImport { -struct SPLM -{ + struct SPLM + { #pragma pack(push) #pragma pack(1) - struct SPDT // 160 bytes - { - int mType; // 1 = spell, 2 = enchantment, 3 = potion - ESM::NAME32 mId; // base ID of a spell/enchantment/potion - unsigned char mUnknown[4*4]; - ESM::NAME32 mCasterId; - ESM::NAME32 mSourceId; // empty for spells - unsigned char mUnknown2[4*11]; - }; - - struct NPDT // 56 bytes - { - ESM::NAME32 mAffectedActorId; - unsigned char mUnknown[4*2]; - int mMagnitude; - float mSecondsActive; - unsigned char mUnknown2[4*2]; - }; - - struct INAM // 40 bytes - { - int mUnknown; - unsigned char mUnknown2; - ESM::FixedString<35> mItemId; // disintegrated item / bound item / item to re-equip after expiration - }; - - struct CNAM // 36 bytes - { - int mUnknown; // seems to always be 0 - ESM::NAME32 mSummonedOrCommandedActor[32]; - }; - - struct VNAM // 4 bytes - { - int mUnknown; - }; - + struct SPDT // 160 bytes + { + int mType; // 1 = spell, 2 = enchantment, 3 = potion + ESM::NAME32 mId; // base ID of a spell/enchantment/potion + unsigned char mUnknown[4 * 4]; + ESM::NAME32 mCasterId; + ESM::NAME32 mSourceId; // empty for spells + unsigned char mUnknown2[4 * 11]; + }; + + struct NPDT // 56 bytes + { + ESM::NAME32 mAffectedActorId; + unsigned char mUnknown[4 * 2]; + int mMagnitude; + float mSecondsActive; + unsigned char mUnknown2[4 * 2]; + }; + + struct INAM // 40 bytes + { + int mUnknown; + unsigned char mUnknown2; + ESM::FixedString<35> mItemId; // disintegrated item / bound item / item to re-equip after expiration + }; + + struct CNAM // 36 bytes + { + int mUnknown; // seems to always be 0 + ESM::NAME32 mSummonedOrCommandedActor[32]; + }; + + struct VNAM // 4 bytes + { + int mUnknown; + }; #pragma pack(pop) - struct ActiveEffect - { - NPDT mNPDT; - }; + struct ActiveEffect + { + NPDT mNPDT; + }; - struct ActiveSpell - { - int mIndex; - SPDT mSPDT; - std::string mTarget; - std::vector mActiveEffects; - }; + struct ActiveSpell + { + int mIndex; + SPDT mSPDT; + std::string mTarget; + std::vector mActiveEffects; + }; - std::vector mActiveSpells; + std::vector mActiveSpells; - void load(ESM::ESMReader& esm); -}; + void load(ESM::ESMReader& esm); + }; } diff --git a/apps/essimporter/main.cpp b/apps/essimporter/main.cpp index 6da7e189e7..7d3ad10bb1 100644 --- a/apps/essimporter/main.cpp +++ b/apps/essimporter/main.cpp @@ -1,5 +1,5 @@ -#include #include +#include #include @@ -9,7 +9,6 @@ namespace bpo = boost::program_options; - int main(int argc, char** argv) { try @@ -22,19 +21,18 @@ Allowed options)"); addOption("mwsave,m", bpo::value(), "morrowind .ess save file"); addOption("output,o", bpo::value(), "output file (.omwsave)"); addOption("compare,c", "compare two .ess files"); - addOption("encoding", boost::program_options::value()->default_value("win1252"), "encoding of the save file"); + addOption("encoding", boost::program_options::value()->default_value("win1252"), + "encoding of the save file"); p_desc.add("mwsave", 1).add("output", 1); Files::ConfigurationManager::addCommonOptions(desc); bpo::variables_map variables; - bpo::parsed_options parsed = bpo::command_line_parser(argc, argv) - .options(desc) - .positional(p_desc) - .run(); + bpo::parsed_options parsed = bpo::command_line_parser(argc, argv).options(desc).positional(p_desc).run(); bpo::store(parsed, variables); - if(variables.count("help") || !variables.count("mwsave") || !variables.count("output")) { + if (variables.count("help") || !variables.count("mwsave") || !variables.count("output")) + { std::cout << desc; return 0; } @@ -54,12 +52,13 @@ Allowed options)"); importer.compare(); else { - static constexpr std::u8string_view ext{u8".omwsave"}; + static constexpr std::u8string_view ext{ u8".omwsave" }; const auto length = outputFile.native().size(); if (std::filesystem::exists(outputFile) - && (length < ext.size() || outputFile.u8string().substr(length-ext.size()) != ext)) + && (length < ext.size() || outputFile.u8string().substr(length - ext.size()) != ext)) { - throw std::runtime_error("Output file already exists and does not end in .omwsave. Did you mean to use --compare?"); + throw std::runtime_error( + "Output file already exists and does not end in .omwsave. Did you mean to use --compare?"); } importer.run(); } diff --git a/apps/launcher/advancedpage.cpp b/apps/launcher/advancedpage.cpp index 0f28c28b70..6f0a8dc52f 100644 --- a/apps/launcher/advancedpage.cpp +++ b/apps/launcher/advancedpage.cpp @@ -1,32 +1,32 @@ #include "advancedpage.hpp" #include -#include #include +#include -#include #include +#include #include #include -#include #include +#include #include #include "utils/openalutil.hpp" -Launcher::AdvancedPage::AdvancedPage(Config::GameSettings &gameSettings, QWidget *parent) - : QWidget(parent) - , mGameSettings(gameSettings) +Launcher::AdvancedPage::AdvancedPage(Config::GameSettings& gameSettings, QWidget* parent) + : QWidget(parent) + , mGameSettings(gameSettings) { - setObjectName ("AdvancedPage"); + setObjectName("AdvancedPage"); setupUi(this); - for(const std::string& name : Launcher::enumerateOpenALDevices()) + for (const std::string& name : Launcher::enumerateOpenALDevices()) { audioDeviceSelectorComboBox->addItem(QString::fromStdString(name), QString::fromStdString(name)); } - for(const std::string& name : Launcher::enumerateOpenALDevicesHrtf()) + for (const std::string& name : Launcher::enumerateOpenALDevicesHrtf()) { hrtfProfileSelectorComboBox->addItem(QString::fromStdString(name), QString::fromStdString(name)); } @@ -37,14 +37,16 @@ Launcher::AdvancedPage::AdvancedPage(Config::GameSettings &gameSettings, QWidget startDefaultCharacterAtField->setCompleter(&mCellNameCompleter); } -void Launcher::AdvancedPage::loadCellsForAutocomplete(QStringList cellNames) { +void Launcher::AdvancedPage::loadCellsForAutocomplete(QStringList cellNames) +{ // Update the list of suggestions for the "Start default character at" field mCellNameCompleterModel.setStringList(cellNames); mCellNameCompleter.setCompletionMode(QCompleter::PopupCompletion); mCellNameCompleter.setCaseSensitivity(Qt::CaseSensitivity::CaseInsensitive); } -void Launcher::AdvancedPage::on_skipMenuCheckBox_stateChanged(int state) { +void Launcher::AdvancedPage::on_skipMenuCheckBox_stateChanged(int state) +{ startDefaultCharacterAtLabel->setEnabled(state == Qt::Checked); startDefaultCharacterAtField->setEnabled(state == Qt::Checked); } @@ -52,10 +54,7 @@ void Launcher::AdvancedPage::on_skipMenuCheckBox_stateChanged(int state) { void Launcher::AdvancedPage::on_runScriptAfterStartupBrowseButton_clicked() { QString scriptFile = QFileDialog::getOpenFileName( - this, - QObject::tr("Select script file"), - QDir::currentPath(), - QString(tr("Text file (*.txt)"))); + this, QObject::tr("Select script file"), QDir::currentPath(), QString(tr("Text file (*.txt)"))); if (scriptFile.isEmpty()) return; @@ -95,7 +94,8 @@ bool Launcher::AdvancedPage::loadSettings() loadSettingBool(enchantedWeaponsMagicalCheckBox, "enchanted weapons are magical", "Game"); loadSettingBool(permanentBarterDispositionChangeCheckBox, "barter disposition change is permanent", "Game"); loadSettingBool(classicReflectedAbsorbSpellsCheckBox, "classic reflected absorb spells behavior", "Game"); - loadSettingBool(requireAppropriateAmmunitionCheckBox, "only appropriate ammunition bypasses resistance", "Game"); + loadSettingBool( + requireAppropriateAmmunitionCheckBox, "only appropriate ammunition bypasses resistance", "Game"); loadSettingBool(uncappedDamageFatigueCheckBox, "uncapped damage fatigue", "Game"); loadSettingBool(normaliseRaceSpeedCheckBox, "normalise race speed", "Game"); loadSettingBool(swimUpwardCorrectionCheckBox, "swim upward correction", "Game"); @@ -124,7 +124,8 @@ bool Launcher::AdvancedPage::loadSettings() loadSettingBool(bumpMapLocalLightingCheckBox, "apply lighting to environment maps", "Shaders"); loadSettingBool(softParticlesCheckBox, "soft particles", "Shaders"); loadSettingBool(antialiasAlphaTestCheckBox, "antialias alpha test", "Shaders"); - if (Settings::Manager::getInt("antialiasing", "Video") == 0) { + if (Settings::Manager::getInt("antialiasing", "Video") == 0) + { antialiasAlphaTestCheckBox->setCheckState(Qt::Unchecked); } loadSettingBool(magicItemAnimationsCheckBox, "use magic item animations", "Game"); @@ -140,7 +141,8 @@ bool Launcher::AdvancedPage::loadSettings() const bool distantTerrain = Settings::Manager::getBool("distant terrain", "Terrain"); const bool objectPaging = Settings::Manager::getBool("object paging", "Terrain"); - if (distantTerrain && objectPaging) { + if (distantTerrain && objectPaging) + { distantLandCheckBox->setCheckState(Qt::Checked); } @@ -210,17 +212,19 @@ bool Launcher::AdvancedPage::loadSettings() // Bug fixes { loadSettingBool(preventMerchantEquippingCheckBox, "prevent merchant equipping", "Game"); - loadSettingBool(trainersTrainingSkillsBasedOnBaseSkillCheckBox, "trainers training skills based on base skill", "Game"); + loadSettingBool( + trainersTrainingSkillsBasedOnBaseSkillCheckBox, "trainers training skills based on base skill", "Game"); } // Miscellaneous { // Saves loadSettingBool(timePlayedCheckbox, "timeplayed", "Saves"); - loadSettingInt(maximumQuicksavesComboBox,"max quicksaves", "Saves"); + loadSettingInt(maximumQuicksavesComboBox, "max quicksaves", "Saves"); // Other Settings - QString screenshotFormatString = QString::fromStdString(Settings::Manager::getString("screenshot format", "General")).toUpper(); + QString screenshotFormatString + = QString::fromStdString(Settings::Manager::getString("screenshot format", "General")).toUpper(); if (screenshotFormatComboBox->findText(screenshotFormatString) == -1) screenshotFormatComboBox->addItem(screenshotFormatString); screenshotFormatComboBox->setCurrentIndex(screenshotFormatComboBox->findText(screenshotFormatString)); @@ -257,7 +261,8 @@ void Launcher::AdvancedPage::saveSettings() saveSettingBool(enchantedWeaponsMagicalCheckBox, "enchanted weapons are magical", "Game"); saveSettingBool(permanentBarterDispositionChangeCheckBox, "barter disposition change is permanent", "Game"); saveSettingBool(classicReflectedAbsorbSpellsCheckBox, "classic reflected absorb spells behavior", "Game"); - saveSettingBool(requireAppropriateAmmunitionCheckBox, "only appropriate ammunition bypasses resistance", "Game"); + saveSettingBool( + requireAppropriateAmmunitionCheckBox, "only appropriate ammunition bypasses resistance", "Game"); saveSettingBool(uncappedDamageFatigueCheckBox, "uncapped damage fatigue", "Game"); saveSettingBool(normaliseRaceSpeedCheckBox, "normalise race speed", "Game"); saveSettingBool(swimUpwardCorrectionCheckBox, "swim upward correction", "Game"); @@ -291,7 +296,8 @@ void Launcher::AdvancedPage::saveSettings() const bool distantTerrain = Settings::Manager::getBool("distant terrain", "Terrain"); const bool objectPaging = Settings::Manager::getBool("object paging", "Terrain"); const bool wantDistantLand = distantLandCheckBox->checkState(); - if (wantDistantLand != (distantTerrain && objectPaging)) { + if (wantDistantLand != (distantTerrain && objectPaging)) + { Settings::Manager::setBool("distant terrain", "Terrain", wantDistantLand); Settings::Manager::setBool("object paging", "Terrain", wantDistantLand); } @@ -343,7 +349,7 @@ void Launcher::AdvancedPage::saveSettings() const std::string& prevHRTFProfile = Settings::Manager::getString("hrtf", "Sound"); if (selectedHRTFProfileIndex != 0) { - const std::string& newHRTFProfile = hrtfProfileSelectorComboBox->currentText().toUtf8().constData(); + const std::string& newHRTFProfile = hrtfProfileSelectorComboBox->currentText().toUtf8().constData(); if (newHRTFProfile != prevHRTFProfile) Settings::Manager::setString("hrtf", "Sound", newHRTFProfile); } @@ -360,7 +366,7 @@ void Launcher::AdvancedPage::saveSettings() saveSettingBool(showMeleeInfoCheckBox, "show melee info", "Game"); saveSettingBool(showProjectileDamageCheckBox, "show projectile damage", "Game"); saveSettingBool(changeDialogTopicsCheckBox, "color topic enable", "GUI"); - saveSettingInt(showOwnedComboBox,"show owned", "Game"); + saveSettingInt(showOwnedComboBox, "show owned", "Game"); saveSettingBool(stretchBackgroundCheckBox, "stretch menu background", "GUI"); saveSettingBool(useZoomOnMapCheckBox, "allow zooming", "Map"); saveSettingBool(graphicHerbalismCheckBox, "graphic herbalism", "Game"); @@ -377,7 +383,8 @@ void Launcher::AdvancedPage::saveSettings() // Bug fixes { saveSettingBool(preventMerchantEquippingCheckBox, "prevent merchant equipping", "Game"); - saveSettingBool(trainersTrainingSkillsBasedOnBaseSkillCheckBox, "trainers training skills based on base skill", "Game"); + saveSettingBool( + trainersTrainingSkillsBasedOnBaseSkillCheckBox, "trainers training skills based on base skill", "Game"); } // Miscellaneous @@ -413,39 +420,39 @@ void Launcher::AdvancedPage::saveSettings() } } -void Launcher::AdvancedPage::loadSettingBool(QCheckBox *checkbox, const std::string &setting, const std::string &group) +void Launcher::AdvancedPage::loadSettingBool(QCheckBox* checkbox, const std::string& setting, const std::string& group) { if (Settings::Manager::getBool(setting, group)) checkbox->setCheckState(Qt::Checked); } -void Launcher::AdvancedPage::saveSettingBool(QCheckBox *checkbox, const std::string &setting, const std::string &group) +void Launcher::AdvancedPage::saveSettingBool(QCheckBox* checkbox, const std::string& setting, const std::string& group) { bool cValue = checkbox->checkState(); if (cValue != Settings::Manager::getBool(setting, group)) Settings::Manager::setBool(setting, group, cValue); } -void Launcher::AdvancedPage::loadSettingInt(QComboBox *comboBox, const std::string &setting, const std::string &group) +void Launcher::AdvancedPage::loadSettingInt(QComboBox* comboBox, const std::string& setting, const std::string& group) { int currentIndex = Settings::Manager::getInt(setting, group); comboBox->setCurrentIndex(currentIndex); } -void Launcher::AdvancedPage::saveSettingInt(QComboBox *comboBox, const std::string &setting, const std::string &group) +void Launcher::AdvancedPage::saveSettingInt(QComboBox* comboBox, const std::string& setting, const std::string& group) { int currentIndex = comboBox->currentIndex(); if (currentIndex != Settings::Manager::getInt(setting, group)) Settings::Manager::setInt(setting, group, currentIndex); } -void Launcher::AdvancedPage::loadSettingInt(QSpinBox *spinBox, const std::string &setting, const std::string &group) +void Launcher::AdvancedPage::loadSettingInt(QSpinBox* spinBox, const std::string& setting, const std::string& group) { int value = Settings::Manager::getInt(setting, group); spinBox->setValue(value); } -void Launcher::AdvancedPage::saveSettingInt(QSpinBox *spinBox, const std::string &setting, const std::string &group) +void Launcher::AdvancedPage::saveSettingInt(QSpinBox* spinBox, const std::string& setting, const std::string& group) { int value = spinBox->value(); if (value != Settings::Manager::getInt(setting, group)) diff --git a/apps/launcher/advancedpage.hpp b/apps/launcher/advancedpage.hpp index a011602da8..0d5bc258d3 100644 --- a/apps/launcher/advancedpage.hpp +++ b/apps/launcher/advancedpage.hpp @@ -8,7 +8,10 @@ #include -namespace Config { class GameSettings; } +namespace Config +{ + class GameSettings; +} namespace Launcher { @@ -17,7 +20,7 @@ namespace Launcher Q_OBJECT public: - explicit AdvancedPage(Config::GameSettings &gameSettings, QWidget *parent = nullptr); + explicit AdvancedPage(Config::GameSettings& gameSettings, QWidget* parent = nullptr); bool loadSettings(); void saveSettings(); @@ -33,7 +36,7 @@ namespace Launcher void slotSkyBlendingToggled(bool checked); private: - Config::GameSettings &mGameSettings; + Config::GameSettings& mGameSettings; QCompleter mCellNameCompleter; QStringListModel mCellNameCompleterModel; @@ -42,12 +45,12 @@ namespace Launcher * @param filePaths the file paths of the content files to be examined */ void loadCellsForAutocomplete(QStringList filePaths); - static void loadSettingBool(QCheckBox *checkbox, const std::string& setting, const std::string& group); - static void saveSettingBool(QCheckBox *checkbox, const std::string& setting, const std::string& group); - static void loadSettingInt(QComboBox *comboBox, const std::string& setting, const std::string& group); - static void saveSettingInt(QComboBox *comboBox, const std::string& setting, const std::string& group); - static void loadSettingInt(QSpinBox *spinBox, const std::string& setting, const std::string& group); - static void saveSettingInt(QSpinBox *spinBox, const std::string& setting, const std::string& group); + static void loadSettingBool(QCheckBox* checkbox, const std::string& setting, const std::string& group); + static void saveSettingBool(QCheckBox* checkbox, const std::string& setting, const std::string& group); + static void loadSettingInt(QComboBox* comboBox, const std::string& setting, const std::string& group); + static void saveSettingInt(QComboBox* comboBox, const std::string& setting, const std::string& group); + static void loadSettingInt(QSpinBox* spinBox, const std::string& setting, const std::string& group); + static void saveSettingInt(QSpinBox* spinBox, const std::string& setting, const std::string& group); }; } #endif diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index e7b03164b6..7a40d23baf 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -2,13 +2,13 @@ #include "maindialog.hpp" #include -#include -#include #include +#include +#include -#include -#include #include +#include +#include #include #include @@ -31,18 +31,18 @@ #include "ui_directorypicker.h" -const char *Launcher::DataFilesPage::mDefaultContentListName = "Default"; +const char* Launcher::DataFilesPage::mDefaultContentListName = "Default"; namespace { void contentSubdirs(const QString& path, QStringList& dirs) { - QStringList fileFilter {"*.esm", "*.esp", "*.omwaddon", "*.bsa"}; - QStringList dirFilter {"bookart", "icons", "meshes", "music", "sound", "textures"}; + QStringList fileFilter{ "*.esm", "*.esp", "*.omwaddon", "*.bsa" }; + QStringList dirFilter{ "bookart", "icons", "meshes", "music", "sound", "textures" }; QDir currentDir(path); if (!currentDir.entryInfoList(fileFilter, QDir::Files).empty() - || !currentDir.entryInfoList(dirFilter, QDir::Dirs | QDir::NoDotAndDotDot).empty()) + || !currentDir.entryInfoList(dirFilter, QDir::Dirs | QDir::NoDotAndDotDot).empty()) dirs.push_back(currentDir.canonicalPath()); for (const auto& subdir : currentDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot)) @@ -63,61 +63,44 @@ namespace Launcher HandleNavMeshToolMessage operator()(NavMeshTool::ExpectedCells&& message) const { - return HandleNavMeshToolMessage { - static_cast(message.mCount), - mExpectedMaxProgress, - static_cast(message.mCount) * 100, - mProgress - }; + return HandleNavMeshToolMessage{ static_cast(message.mCount), mExpectedMaxProgress, + static_cast(message.mCount) * 100, mProgress }; } HandleNavMeshToolMessage operator()(NavMeshTool::ProcessedCells&& message) const { - return HandleNavMeshToolMessage { - mCellsCount, - mExpectedMaxProgress, - mMaxProgress, - std::max(mProgress, static_cast(message.mCount)) - }; + return HandleNavMeshToolMessage{ mCellsCount, mExpectedMaxProgress, mMaxProgress, + std::max(mProgress, static_cast(message.mCount)) }; } HandleNavMeshToolMessage operator()(NavMeshTool::ExpectedTiles&& message) const { const int expectedMaxProgress = mCellsCount + static_cast(message.mCount); - return HandleNavMeshToolMessage { - mCellsCount, - expectedMaxProgress, - std::max(mMaxProgress, expectedMaxProgress), - mProgress - }; + return HandleNavMeshToolMessage{ mCellsCount, expectedMaxProgress, + std::max(mMaxProgress, expectedMaxProgress), mProgress }; } HandleNavMeshToolMessage operator()(NavMeshTool::GeneratedTiles&& message) const { int progress = mCellsCount + static_cast(message.mCount); if (mExpectedMaxProgress < mMaxProgress) - progress += static_cast(std::round( - (mMaxProgress - mExpectedMaxProgress) - * (static_cast(progress) / static_cast(mExpectedMaxProgress)) - )); - return HandleNavMeshToolMessage { - mCellsCount, - mExpectedMaxProgress, - mMaxProgress, - std::max(mProgress, progress) - }; + progress += static_cast(std::round((mMaxProgress - mExpectedMaxProgress) + * (static_cast(progress) / static_cast(mExpectedMaxProgress)))); + return HandleNavMeshToolMessage{ mCellsCount, mExpectedMaxProgress, mMaxProgress, + std::max(mProgress, progress) }; } }; int getMaxNavMeshDbFileSizeMiB() { - return static_cast(Settings::Manager::getInt64("max navmeshdb file size", "Navigator") / (1024 * 1024)); + return static_cast( + Settings::Manager::getInt64("max navmeshdb file size", "Navigator") / (1024 * 1024)); } } } -Launcher::DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, Config::GameSettings &gameSettings, - Config::LauncherSettings &launcherSettings, MainDialog *parent) +Launcher::DataFilesPage::DataFilesPage(Files::ConfigurationManager& cfg, Config::GameSettings& gameSettings, + Config::LauncherSettings& launcherSettings, MainDialog* parent) : QWidget(parent) , mMainDialog(parent) , mCfgMgr(cfg) @@ -125,78 +108,78 @@ Launcher::DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, Config: , mLauncherSettings(launcherSettings) , mNavMeshToolInvoker(new Process::ProcessInvoker(this)) { - ui.setupUi (this); - setObjectName ("DataFilesPage"); - mSelector = new ContentSelectorView::ContentSelector (ui.contentSelectorWidget, /*showOMWScripts=*/true); + ui.setupUi(this); + setObjectName("DataFilesPage"); + mSelector = new ContentSelectorView::ContentSelector(ui.contentSelectorWidget, /*showOMWScripts=*/true); const QString encoding = mGameSettings.value("encoding", "win1252"); mSelector->setEncoding(encoding); mNewProfileDialog = new TextInputDialog(tr("New Content List"), tr("Content List name:"), this); mCloneProfileDialog = new TextInputDialog(tr("Clone Content List"), tr("Content List name:"), this); - connect(mNewProfileDialog->lineEdit(), &LineEdit::textChanged, - this, &DataFilesPage::updateNewProfileOkButton); - connect(mCloneProfileDialog->lineEdit(), &LineEdit::textChanged, - this, &DataFilesPage::updateCloneProfileOkButton); + connect(mNewProfileDialog->lineEdit(), &LineEdit::textChanged, this, &DataFilesPage::updateNewProfileOkButton); + connect(mCloneProfileDialog->lineEdit(), &LineEdit::textChanged, this, &DataFilesPage::updateCloneProfileOkButton); connect(ui.directoryAddSubdirsButton, &QPushButton::released, this, [this]() { this->addSubdirectories(true); }); - connect(ui.directoryInsertButton, &QPushButton::released, this, [this]() { this->addSubdirectories(false); }); - connect(ui.directoryUpButton, &QPushButton::released, this, [this]() { this->moveDirectory(-1); }); - connect(ui.directoryDownButton, &QPushButton::released, this, [this]() { this->moveDirectory(1); }); - connect(ui.directoryRemoveButton, &QPushButton::released, this, [this]() { this->removeDirectory(); }); - connect(ui.archiveUpButton, &QPushButton::released, this, [this]() { this->moveArchive(-1); }); - connect(ui.archiveDownButton, &QPushButton::released, this, [this]() { this->moveArchive(1); }); - connect(ui.directoryListWidget->model(), &QAbstractItemModel::rowsMoved, this, [this]() { this->sortDirectories(); }); + connect(ui.directoryInsertButton, &QPushButton::released, this, [this]() { this->addSubdirectories(false); }); + connect(ui.directoryUpButton, &QPushButton::released, this, [this]() { this->moveDirectory(-1); }); + connect(ui.directoryDownButton, &QPushButton::released, this, [this]() { this->moveDirectory(1); }); + connect(ui.directoryRemoveButton, &QPushButton::released, this, [this]() { this->removeDirectory(); }); + connect(ui.archiveUpButton, &QPushButton::released, this, [this]() { this->moveArchive(-1); }); + connect(ui.archiveDownButton, &QPushButton::released, this, [this]() { this->moveArchive(1); }); + connect( + ui.directoryListWidget->model(), &QAbstractItemModel::rowsMoved, this, [this]() { this->sortDirectories(); }); buildView(); loadSettings(); // Connect signal and slot after the settings have been loaded. We only care about the user changing // the addons and don't want to get signals of the system doing it during startup. - connect(mSelector, &ContentSelectorView::ContentSelector::signalAddonDataChanged, - this, &DataFilesPage::slotAddonDataChanged); + connect(mSelector, &ContentSelectorView::ContentSelector::signalAddonDataChanged, this, + &DataFilesPage::slotAddonDataChanged); // Call manually to indicate all changes to addon data during startup. slotAddonDataChanged(); } void Launcher::DataFilesPage::buildView() { - QToolButton * refreshButton = mSelector->refreshButton(); + QToolButton* refreshButton = mSelector->refreshButton(); - //tool buttons - ui.newProfileButton->setToolTip ("Create a new Content List"); - ui.cloneProfileButton->setToolTip ("Clone the current Content List"); - ui.deleteProfileButton->setToolTip ("Delete an existing Content List"); + // tool buttons + ui.newProfileButton->setToolTip("Create a new Content List"); + ui.cloneProfileButton->setToolTip("Clone the current Content List"); + ui.deleteProfileButton->setToolTip("Delete an existing Content List"); - //combo box + // combo box ui.profilesComboBox->addItem(mDefaultContentListName); - ui.profilesComboBox->setPlaceholderText (QString("Select a Content List...")); + ui.profilesComboBox->setPlaceholderText(QString("Select a Content List...")); ui.profilesComboBox->setCurrentIndex(ui.profilesComboBox->findText(QLatin1String(mDefaultContentListName))); // Add the actions to the toolbuttons - ui.newProfileButton->setDefaultAction (ui.newProfileAction); - ui.cloneProfileButton->setDefaultAction (ui.cloneProfileAction); - ui.deleteProfileButton->setDefaultAction (ui.deleteProfileAction); + ui.newProfileButton->setDefaultAction(ui.newProfileAction); + ui.cloneProfileButton->setDefaultAction(ui.cloneProfileAction); + ui.deleteProfileButton->setDefaultAction(ui.deleteProfileAction); refreshButton->setDefaultAction(ui.refreshDataFilesAction); - //establish connections - connect (ui.profilesComboBox, qOverload(&::ProfilesComboBox::currentIndexChanged), - this, &DataFilesPage::slotProfileChanged); + // establish connections + connect(ui.profilesComboBox, qOverload(&::ProfilesComboBox::currentIndexChanged), this, + &DataFilesPage::slotProfileChanged); - connect (ui.profilesComboBox, &::ProfilesComboBox::profileRenamed, - this, &DataFilesPage::slotProfileRenamed); + connect(ui.profilesComboBox, &::ProfilesComboBox::profileRenamed, this, &DataFilesPage::slotProfileRenamed); - connect (ui.profilesComboBox, qOverload(&::ProfilesComboBox::signalProfileChanged), - this, &DataFilesPage::slotProfileChangedByUser); + connect(ui.profilesComboBox, qOverload(&::ProfilesComboBox::signalProfileChanged), + this, &DataFilesPage::slotProfileChangedByUser); - connect(ui.refreshDataFilesAction, &QAction::triggered, - this, &DataFilesPage::slotRefreshButtonClicked); + connect(ui.refreshDataFilesAction, &QAction::triggered, this, &DataFilesPage::slotRefreshButtonClicked); connect(ui.updateNavMeshButton, &QPushButton::clicked, this, &DataFilesPage::startNavMeshTool); connect(ui.cancelNavMeshButton, &QPushButton::clicked, this, &DataFilesPage::killNavMeshTool); - connect(mNavMeshToolInvoker->getProcess(), &QProcess::readyReadStandardOutput, this, &DataFilesPage::readNavMeshToolStdout); - connect(mNavMeshToolInvoker->getProcess(), &QProcess::readyReadStandardError, this, &DataFilesPage::readNavMeshToolStderr); - connect(mNavMeshToolInvoker->getProcess(), qOverload(&QProcess::finished), this, &DataFilesPage::navMeshToolFinished); + connect(mNavMeshToolInvoker->getProcess(), &QProcess::readyReadStandardOutput, this, + &DataFilesPage::readNavMeshToolStdout); + connect(mNavMeshToolInvoker->getProcess(), &QProcess::readyReadStandardError, this, + &DataFilesPage::readNavMeshToolStderr); + connect(mNavMeshToolInvoker->getProcess(), qOverload(&QProcess::finished), this, + &DataFilesPage::navMeshToolFinished); } bool Launcher::DataFilesPage::loadSettings() @@ -208,8 +191,8 @@ bool Launcher::DataFilesPage::loadSettings() qDebug() << "The current profile is: " << currentProfile; - for (const QString &item : profiles) - addProfile (item, false); + for (const QString& item : profiles) + addProfile(item, false); // Hack: also add the current profile if (!currentProfile.isEmpty()) @@ -267,10 +250,11 @@ void Launcher::DataFilesPage::populateFileViews(const QString& contentModelName) // deactivate data-local and global data directory: they are always included const auto tmp = currentDir.toUtf8(); - if (currentDir == mDataLocal || std::filesystem::path(Misc::StringUtils::stringToU8String(tmp)) == globalDataDir) + if (currentDir == mDataLocal + || std::filesystem::path(Misc::StringUtils::stringToU8String(tmp)) == globalDataDir) { auto flags = item->flags(); - item->setFlags(flags & ~(Qt::ItemIsDragEnabled|Qt::ItemIsDropEnabled|Qt::ItemIsEnabled)); + item->setFlags(flags & ~(Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsEnabled)); } // Add a "data file" icon if the directory contains a content file @@ -293,7 +277,7 @@ void Launcher::DataFilesPage::populateFileViews(const QString& contentModelName) QStringList selectedArchives = mLauncherSettings.getArchiveList(contentModelName); if (selectedArchives.isEmpty()) - selectedArchives = mGameSettings.getArchiveList(); + selectedArchives = mGameSettings.getArchiveList(); // sort and tick BSA according to profile int row = 0; @@ -331,27 +315,28 @@ QStringList Launcher::DataFilesPage::filesInProfile(const QString& profileName, return filepaths; } -void Launcher::DataFilesPage::saveSettings(const QString &profile) +void Launcher::DataFilesPage::saveSettings(const QString& profile) { if (const int value = ui.navMeshMaxSizeSpinBox->value(); value != getMaxNavMeshDbFileSizeMiB()) - Settings::Manager::setInt64("max navmeshdb file size", "Navigator", static_cast(value) * 1024 * 1024); + Settings::Manager::setInt64( + "max navmeshdb file size", "Navigator", static_cast(value) * 1024 * 1024); QString profileName = profile; if (profileName.isEmpty()) profileName = ui.profilesComboBox->currentText(); - //retrieve the data paths + // retrieve the data paths auto dirList = selectedDirectoriesPaths(); - //retrieve the files selected for the profile + // retrieve the files selected for the profile ContentSelectorModel::ContentFileList items = mSelector->selectedFiles(); - //set the value of the current profile (not necessarily the profile being saved!) + // set the value of the current profile (not necessarily the profile being saved!) mLauncherSettings.setCurrentContentListName(ui.profilesComboBox->currentText()); QStringList fileNames; - for (const ContentSelectorModel::EsmFile *item : items) + for (const ContentSelectorModel::EsmFile* item : items) { fileNames.append(item->fileName()); } @@ -361,49 +346,49 @@ void Launcher::DataFilesPage::saveSettings(const QString &profile) QStringList Launcher::DataFilesPage::selectedDirectoriesPaths() const { - QStringList dirList; - for (int i = 0; i < ui.directoryListWidget->count(); ++i) - { - if (ui.directoryListWidget->item(i)->flags() & Qt::ItemIsEnabled) - dirList.append(ui.directoryListWidget->item(i)->text()); - } - return dirList; + QStringList dirList; + for (int i = 0; i < ui.directoryListWidget->count(); ++i) + { + if (ui.directoryListWidget->item(i)->flags() & Qt::ItemIsEnabled) + dirList.append(ui.directoryListWidget->item(i)->text()); + } + return dirList; } QStringList Launcher::DataFilesPage::selectedArchivePaths(bool all) const { - QStringList archiveList; - for (int i = 0; i < ui.archiveListWidget->count(); ++i) - { - const auto* item = ui.archiveListWidget->item(i); - const auto archive = ui.archiveListWidget->item(i)->text(); + QStringList archiveList; + for (int i = 0; i < ui.archiveListWidget->count(); ++i) + { + const auto* item = ui.archiveListWidget->item(i); + const auto archive = ui.archiveListWidget->item(i)->text(); - if (all ||item->checkState() == Qt::Checked) - archiveList.append(item->text()); - } - return archiveList; + if (all || item->checkState() == Qt::Checked) + archiveList.append(item->text()); + } + return archiveList; } QStringList Launcher::DataFilesPage::selectedFilePaths() const { - //retrieve the files selected for the profile + // retrieve the files selected for the profile ContentSelectorModel::ContentFileList items = mSelector->selectedFiles(); QStringList filePaths; - for (const ContentSelectorModel::EsmFile *item : items) + for (const ContentSelectorModel::EsmFile* item : items) { QFile file(item->filePath()); - if(file.exists()) + if (file.exists()) filePaths.append(item->filePath()); } return filePaths; } -void Launcher::DataFilesPage::removeProfile(const QString &profile) +void Launcher::DataFilesPage::removeProfile(const QString& profile) { mLauncherSettings.removeContentList(profile); } -QAbstractItemModel *Launcher::DataFilesPage::profilesModel() const +QAbstractItemModel* Launcher::DataFilesPage::profilesModel() const { return ui.profilesComboBox->model(); } @@ -422,20 +407,20 @@ void Launcher::DataFilesPage::setProfile(int index, bool savePrevious) mPreviousProfile = current; - setProfile (previous, current, savePrevious); + setProfile(previous, current, savePrevious); } } -void Launcher::DataFilesPage::setProfile (const QString &previous, const QString ¤t, bool savePrevious) +void Launcher::DataFilesPage::setProfile(const QString& previous, const QString& current, bool savePrevious) { - //abort if no change (poss. duplicate signal) + // abort if no change (poss. duplicate signal) if (previous == current) - return; + return; if (!previous.isEmpty() && savePrevious) - saveSettings (previous); + saveSettings(previous); - ui.profilesComboBox->setCurrentProfile (ui.profilesComboBox->findText (current)); + ui.profilesComboBox->setCurrentProfile(ui.profilesComboBox->findText(current)); mNewDataDirs.clear(); mKnownArchives.clear(); @@ -451,30 +436,30 @@ void Launcher::DataFilesPage::setProfile (const QString &previous, const QString checkForDefaultProfile(); } -void Launcher::DataFilesPage::slotProfileDeleted (const QString &item) +void Launcher::DataFilesPage::slotProfileDeleted(const QString& item) { - removeProfile (item); + removeProfile(item); } -void Launcher::DataFilesPage:: refreshDataFilesView () +void Launcher::DataFilesPage::refreshDataFilesView() { QString currentProfile = ui.profilesComboBox->currentText(); saveSettings(currentProfile); populateFileViews(currentProfile); } -void Launcher::DataFilesPage::slotRefreshButtonClicked () +void Launcher::DataFilesPage::slotRefreshButtonClicked() { refreshDataFilesView(); } -void Launcher::DataFilesPage::slotProfileChangedByUser(const QString &previous, const QString ¤t) +void Launcher::DataFilesPage::slotProfileChangedByUser(const QString& previous, const QString& current) { setProfile(previous, current, true); - emit signalProfileChanged (ui.profilesComboBox->findText(current)); + emit signalProfileChanged(ui.profilesComboBox->findText(current)); } -void Launcher::DataFilesPage::slotProfileRenamed(const QString &previous, const QString ¤t) +void Launcher::DataFilesPage::slotProfileRenamed(const QString& previous, const QString& current) { if (previous.isEmpty()) return; @@ -483,7 +468,7 @@ void Launcher::DataFilesPage::slotProfileRenamed(const QString &previous, const saveSettings(); // Remove the old one - removeProfile (previous); + removeProfile(previous); loadSettings(); } @@ -494,7 +479,7 @@ void Launcher::DataFilesPage::slotProfileChanged(int index) if (ui.profilesComboBox->currentIndex() != index) ui.profilesComboBox->setCurrentIndex(index); - setProfile (index, true); + setProfile(index, true); } void Launcher::DataFilesPage::on_newProfileAction_triggered() @@ -514,16 +499,16 @@ void Launcher::DataFilesPage::on_newProfileAction_triggered() addProfile(profile, true); } -void Launcher::DataFilesPage::addProfile (const QString &profile, bool setAsCurrent) +void Launcher::DataFilesPage::addProfile(const QString& profile, bool setAsCurrent) { if (profile.isEmpty()) return; - if (ui.profilesComboBox->findText (profile) == -1) - ui.profilesComboBox->addItem (profile); + if (ui.profilesComboBox->findText(profile) == -1) + ui.profilesComboBox->addItem(profile); if (setAsCurrent) - setProfile (ui.profilesComboBox->findText (profile), false); + setProfile(ui.profilesComboBox->findText(profile), false); } void Launcher::DataFilesPage::on_cloneProfileAction_triggered() @@ -547,11 +532,11 @@ void Launcher::DataFilesPage::on_deleteProfileAction_triggered() if (profile.isEmpty()) return; - if (!showDeleteMessageBox (profile)) + if (!showDeleteMessageBox(profile)) return; // this should work since the Default profile can't be deleted and is always index 0 - int next = ui.profilesComboBox->currentIndex()-1; + int next = ui.profilesComboBox->currentIndex() - 1; // changing the profile forces a reload of plugin file views. ui.profilesComboBox->setCurrentIndex(next); @@ -562,13 +547,13 @@ void Launcher::DataFilesPage::on_deleteProfileAction_triggered() checkForDefaultProfile(); } -void Launcher::DataFilesPage::updateNewProfileOkButton(const QString &text) +void Launcher::DataFilesPage::updateNewProfileOkButton(const QString& text) { // We do this here because we need the profiles combobox text mNewProfileDialog->setOkButtonEnabled(!text.isEmpty() && ui.profilesComboBox->findText(text) == -1); } -void Launcher::DataFilesPage::updateCloneProfileOkButton(const QString &text) +void Launcher::DataFilesPage::updateCloneProfileOkButton(const QString& text) { // We do this here because we need the profiles combobox text mCloneProfileDialog->setOkButtonEnabled(!text.isEmpty() && ui.profilesComboBox->findText(text) == -1); @@ -584,7 +569,6 @@ QString Launcher::DataFilesPage::selectDirectory() return {}; return QDir(fileDialog.selectedFiles()[0]).canonicalPath(); - } void Launcher::DataFilesPage::addSubdirectories(bool append) @@ -634,12 +618,12 @@ void Launcher::DataFilesPage::addSubdirectories(bool append) for (int i = 0; i < select.dirListWidget->count(); ++i) { - const auto* dir = select.dirListWidget->item(i); - if (dir->checkState() == Qt::Checked) - { - ui.directoryListWidget->insertItem(selectedRow++, dir->text()); - mNewDataDirs.push_back(dir->text()); - } + const auto* dir = select.dirListWidget->item(i); + if (dir->checkState() == Qt::Checked) + { + ui.directoryListWidget->insertItem(selectedRow++, dir->text()); + mNewDataDirs.push_back(dir->text()); + } } refreshDataFilesView(); @@ -650,8 +634,8 @@ void Launcher::DataFilesPage::sortDirectories() // Ensure disabled entries (aka default directories) are always at the top. for (auto i = 1; i < ui.directoryListWidget->count(); ++i) { - if (!(ui.directoryListWidget->item(i)->flags() & Qt::ItemIsEnabled) && - (ui.directoryListWidget->item(i - 1)->flags() & Qt::ItemIsEnabled)) + if (!(ui.directoryListWidget->item(i)->flags() & Qt::ItemIsEnabled) + && (ui.directoryListWidget->item(i - 1)->flags() & Qt::ItemIsEnabled)) { const auto item = ui.directoryListWidget->takeItem(i); ui.directoryListWidget->insertItem(i - 1, item); @@ -728,14 +712,14 @@ void Launcher::DataFilesPage::addArchivesFromDir(const QString& path) void Launcher::DataFilesPage::checkForDefaultProfile() { - //don't allow deleting "Default" profile + // don't allow deleting "Default" profile bool success = (ui.profilesComboBox->currentText() != mDefaultContentListName); - ui.deleteProfileAction->setEnabled (success); - ui.profilesComboBox->setEditEnabled (success); + ui.deleteProfileAction->setEnabled(success); + ui.profilesComboBox->setEditEnabled(success); } -bool Launcher::DataFilesPage::showDeleteMessageBox (const QString &text) +bool Launcher::DataFilesPage::showDeleteMessageBox(const QString& text) { QMessageBox msgBox(this); msgBox.setWindowTitle(tr("Delete Content List")); @@ -743,8 +727,7 @@ bool Launcher::DataFilesPage::showDeleteMessageBox (const QString &text) msgBox.setStandardButtons(QMessageBox::Cancel); msgBox.setText(tr("Are you sure you want to delete %1?").arg(text)); - QAbstractButton *deleteButton = - msgBox.addButton(tr("Delete"), QMessageBox::ActionRole); + QAbstractButton* deleteButton = msgBox.addButton(tr("Delete"), QMessageBox::ActionRole); msgBox.exec(); @@ -754,7 +737,8 @@ bool Launcher::DataFilesPage::showDeleteMessageBox (const QString &text) void Launcher::DataFilesPage::slotAddonDataChanged() { QStringList selectedFiles = selectedFilePaths(); - if (previousSelectedFiles != selectedFiles) { + if (previousSelectedFiles != selectedFiles) + { previousSelectedFiles = selectedFiles; // Loading cells for core Morrowind + Expansions takes about 0.2 seconds, which is enough to cause a // barely perceptible UI lag. Splitting into its own thread to alleviate that. @@ -774,7 +758,7 @@ void Launcher::DataFilesPage::reloadCells(QStringList selectedFiles) // The following code will run only if there is not another thread currently running it CellNameLoader cellNameLoader; -#if QT_VERSION >= QT_VERSION_CHECK(5,14,0) +#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) QSet set = cellNameLoader.getCellNames(selectedFiles); QStringList cellNamesList(set.begin(), set.end()); #else @@ -792,9 +776,9 @@ void Launcher::DataFilesPage::startNavMeshTool() ui.navMeshProgressBar->setValue(0); ui.navMeshProgressBar->setMaximum(1); - mNavMeshToolProgress = NavMeshToolProgress {}; + mNavMeshToolProgress = NavMeshToolProgress{}; - QStringList arguments({"--write-binary-log"}); + QStringList arguments({ "--write-binary-log" }); if (ui.navMeshRemoveUnusedTilesCheckBox->checkState() == Qt::Checked) arguments.append("--remove-unused-tiles"); @@ -824,7 +808,7 @@ void Launcher::DataFilesPage::updateNavMeshProgress(int minDataSize) const std::byte* const begin = reinterpret_cast(mNavMeshToolProgress.mMessagesData.constData()); const std::byte* const end = begin + mNavMeshToolProgress.mMessagesData.size(); const std::byte* position = begin; - HandleNavMeshToolMessage handle { + HandleNavMeshToolMessage handle{ mNavMeshToolProgress.mCellsCount, mNavMeshToolProgress.mExpectedMaxProgress, ui.navMeshProgressBar->maximum(), @@ -863,7 +847,8 @@ void Launcher::DataFilesPage::readNavMeshToolStdout() void Launcher::DataFilesPage::navMeshToolFinished(int exitCode, QProcess::ExitStatus exitStatus) { updateNavMeshProgress(0); - ui.navMeshLogPlainTextEdit->appendPlainText(QString::fromUtf8(mNavMeshToolInvoker->getProcess()->readAllStandardOutput())); + ui.navMeshLogPlainTextEdit->appendPlainText( + QString::fromUtf8(mNavMeshToolInvoker->getProcess()->readAllStandardOutput())); if (exitCode == 0 && exitStatus == QProcess::ExitStatus::NormalExit) ui.navMeshProgressBar->setValue(ui.navMeshProgressBar->maximum()); ui.cancelNavMeshButton->setEnabled(false); diff --git a/apps/launcher/datafilespage.hpp b/apps/launcher/datafilespage.hpp index 0a235209f3..52b07da240 100644 --- a/apps/launcher/datafilespage.hpp +++ b/apps/launcher/datafilespage.hpp @@ -5,18 +5,27 @@ #include -#include #include #include +#include class QSortFilterProxyModel; class QAbstractItemModel; class QMenu; -namespace Files { struct ConfigurationManager; } -namespace ContentSelectorView { class ContentSelector; } -namespace Config { class GameSettings; - class LauncherSettings; } +namespace Files +{ + struct ConfigurationManager; +} +namespace ContentSelectorView +{ + class ContentSelector; +} +namespace Config +{ + class GameSettings; + class LauncherSettings; +} namespace Launcher { @@ -28,38 +37,38 @@ namespace Launcher { Q_OBJECT - ContentSelectorView::ContentSelector *mSelector; + ContentSelectorView::ContentSelector* mSelector; Ui::DataFilesPage ui; public: - explicit DataFilesPage (Files::ConfigurationManager &cfg, Config::GameSettings &gameSettings, - Config::LauncherSettings &launcherSettings, MainDialog *parent = nullptr); + explicit DataFilesPage(Files::ConfigurationManager& cfg, Config::GameSettings& gameSettings, + Config::LauncherSettings& launcherSettings, MainDialog* parent = nullptr); QAbstractItemModel* profilesModel() const; int profilesIndex() const; - //void writeConfig(QString profile = QString()); - void saveSettings(const QString &profile = ""); + // void writeConfig(QString profile = QString()); + void saveSettings(const QString& profile = ""); bool loadSettings(); signals: - void signalProfileChanged (int index); + void signalProfileChanged(int index); void signalLoadedCellsChanged(QStringList selectedFiles); public slots: - void slotProfileChanged (int index); + void slotProfileChanged(int index); private slots: - void slotProfileChangedByUser(const QString &previous, const QString ¤t); - void slotProfileRenamed(const QString &previous, const QString ¤t); - void slotProfileDeleted(const QString &item); - void slotAddonDataChanged (); - void slotRefreshButtonClicked (); + void slotProfileChangedByUser(const QString& previous, const QString& current); + void slotProfileRenamed(const QString& previous, const QString& current); + void slotProfileDeleted(const QString& item); + void slotAddonDataChanged(); + void slotRefreshButtonClicked(); - void updateNewProfileOkButton(const QString &text); - void updateCloneProfileOkButton(const QString &text); + void updateNewProfileOkButton(const QString& text); + void updateCloneProfileOkButton(const QString& text); void addSubdirectories(bool append); void sortDirectories(); void removeDirectory(); @@ -78,7 +87,7 @@ namespace Launcher public: /// Content List that is always present - const static char *mDefaultContentListName; + const static char* mDefaultContentListName; private: struct NavMeshToolProgress @@ -90,14 +99,14 @@ namespace Launcher int mExpectedMaxProgress = 0; }; - MainDialog *mMainDialog; - TextInputDialog *mNewProfileDialog; - TextInputDialog *mCloneProfileDialog; + MainDialog* mMainDialog; + TextInputDialog* mNewProfileDialog; + TextInputDialog* mCloneProfileDialog; - Files::ConfigurationManager &mCfgMgr; + Files::ConfigurationManager& mCfgMgr; - Config::GameSettings &mGameSettings; - Config::LauncherSettings &mLauncherSettings; + Config::GameSettings& mGameSettings; + Config::LauncherSettings& mLauncherSettings; QString mPreviousProfile; QStringList previousSelectedFiles; @@ -111,15 +120,15 @@ namespace Launcher void addArchive(const QString& name, Qt::CheckState selected, int row = -1); void addArchivesFromDir(const QString& dir); void buildView(); - void setProfile (int index, bool savePrevious); - void setProfile (const QString &previous, const QString ¤t, bool savePrevious); - void removeProfile (const QString &profile); - bool showDeleteMessageBox (const QString &text); - void addProfile (const QString &profile, bool setAsCurrent); + void setProfile(int index, bool savePrevious); + void setProfile(const QString& previous, const QString& current, bool savePrevious); + void removeProfile(const QString& profile); + bool showDeleteMessageBox(const QString& text); + void addProfile(const QString& profile, bool setAsCurrent); void checkForDefaultProfile(); void populateFileViews(const QString& contentModelName); void reloadCells(QStringList selectedFiles); - void refreshDataFilesView (); + void refreshDataFilesView(); void updateNavMeshProgress(int minDataSize); QString selectDirectory(); @@ -128,7 +137,7 @@ namespace Launcher * @return the file paths of all selected content files */ QStringList selectedFilePaths() const; - QStringList selectedArchivePaths(bool all=false) const; + QStringList selectedArchivePaths(bool all = false) const; QStringList selectedDirectoriesPaths() const; class PathIterator @@ -140,25 +149,24 @@ namespace Launcher QString mFilePath; public: - PathIterator (const QStringList &list) + PathIterator(const QStringList& list) { mCitBegin = list.constBegin(); mCitCurrent = mCitBegin; mCitEnd = list.constEnd(); } - QString findFirstPath (const QString &file) + QString findFirstPath(const QString& file) { mCitCurrent = mCitBegin; mFile = file; return path(); } - QString findNextPath () { return path(); } + QString findNextPath() { return path(); } private: - - QString path () + QString path() { bool success = false; QDir dir; @@ -169,8 +177,8 @@ namespace Launcher if (mCitCurrent == mCitEnd) break; - dir.setPath (*(mCitCurrent++)); - file.setFile (dir.absoluteFilePath (mFile)); + dir.setPath(*(mCitCurrent++)); + file.setFile(dir.absoluteFilePath(mFile)); success = file.exists(); } @@ -180,7 +188,6 @@ namespace Launcher return ""; } - }; QStringList filesInProfile(const QString& profileName, PathIterator& pathIterator); diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index 363f0ec03b..7ee8ac2c05 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -13,12 +13,12 @@ #include -#include #include +#include QString getAspect(int x, int y) { - int gcd = std::gcd (x, y); + int gcd = std::gcd(x, y); if (gcd == 0) return QString(); @@ -31,10 +31,10 @@ QString getAspect(int x, int y) return QString(QString::number(xaspect) + ":" + QString::number(yaspect)); } -Launcher::GraphicsPage::GraphicsPage(QWidget *parent) +Launcher::GraphicsPage::GraphicsPage(QWidget* parent) : QWidget(parent) { - setObjectName ("GraphicsPage"); + setObjectName("GraphicsPage"); setupUi(this); // Set the maximum res we can set in windowed mode @@ -42,7 +42,8 @@ Launcher::GraphicsPage::GraphicsPage(QWidget *parent) customWidthSpinBox->setMaximum(res.width()); customHeightSpinBox->setMaximum(res.height()); - connect(windowModeComboBox, qOverload(&QComboBox::currentIndexChanged), this, &GraphicsPage::slotFullScreenChanged); + connect(windowModeComboBox, qOverload(&QComboBox::currentIndexChanged), this, + &GraphicsPage::slotFullScreenChanged); connect(standardRadioButton, &QRadioButton::toggled, this, &GraphicsPage::slotStandardToggled); connect(screenComboBox, qOverload(&QComboBox::currentIndexChanged), this, &GraphicsPage::screenChanged); connect(framerateLimitCheckBox, &QCheckBox::toggled, this, &GraphicsPage::slotFramerateLimitToggled); @@ -65,7 +66,8 @@ bool Launcher::GraphicsPage::setupSDL() msgBox.setWindowTitle(tr("Error receiving number of screens")); msgBox.setIcon(QMessageBox::Critical); msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.setText(tr("
SDL_GetNumVideoDisplays failed:

") + QString::fromUtf8(SDL_GetError()) + "
"); + msgBox.setText( + tr("
SDL_GetNumVideoDisplays failed:

") + QString::fromUtf8(SDL_GetError()) + "
"); msgBox.exec(); return false; } @@ -116,10 +118,13 @@ bool Launcher::GraphicsPage::loadSettings() int resIndex = resolutionComboBox->findText(resolution, Qt::MatchStartsWith); - if (resIndex != -1) { + if (resIndex != -1) + { standardRadioButton->toggle(); resolutionComboBox->setCurrentIndex(resIndex); - } else { + } + else + { customRadioButton->toggle(); customWidthSpinBox->setValue(width); customHeightSpinBox->setValue(height); @@ -152,9 +157,8 @@ bool Launcher::GraphicsPage::loadSettings() if (Settings::Manager::getBool("enable indoor shadows", "Shadows")) indoorShadowsCheckBox->setCheckState(Qt::Checked); - shadowComputeSceneBoundsComboBox->setCurrentIndex( - shadowComputeSceneBoundsComboBox->findText( - QString(tr(Settings::Manager::getString("compute scene bounds", "Shadows").c_str())))); + shadowComputeSceneBoundsComboBox->setCurrentIndex(shadowComputeSceneBoundsComboBox->findText( + QString(tr(Settings::Manager::getString("compute scene bounds", "Shadows").c_str())))); int shadowDistLimit = Settings::Manager::getInt("maximum shadow map distance", "Shadows"); if (shadowDistLimit > 0) @@ -199,13 +203,17 @@ void Launcher::GraphicsPage::saveSettings() int cWidth = 0; int cHeight = 0; - if (standardRadioButton->isChecked()) { + if (standardRadioButton->isChecked()) + { QRegExp resolutionRe(QString("(\\d+) x (\\d+).*")); - if (resolutionRe.exactMatch(resolutionComboBox->currentText().simplified())) { + if (resolutionRe.exactMatch(resolutionComboBox->currentText().simplified())) + { cWidth = resolutionRe.cap(1).toInt(); cHeight = resolutionRe.cap(2).toInt(); } - } else { + } + else + { cWidth = customWidthSpinBox->value(); cHeight = customHeightSpinBox->value(); } @@ -232,7 +240,7 @@ void Launcher::GraphicsPage::saveSettings() } // Lighting - static std::array lightingMethodMap = {"legacy", "shaders compatibility", "shaders"}; + static std::array lightingMethodMap = { "legacy", "shaders compatibility", "shaders" }; const std::string& cLightingMethod = lightingMethodMap[lightingMethodComboBox->currentIndex()]; if (cLightingMethod != Settings::Manager::getString("lighting method", "Shaders")) Settings::Manager::setString("lighting method", "Shaders", cLightingMethod); @@ -301,7 +309,8 @@ QStringList Launcher::GraphicsPage::getAvailableResolutions(int screen) msgBox.setWindowTitle(tr("Error receiving resolutions")); msgBox.setIcon(QMessageBox::Critical); msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.setText(tr("
SDL_GetNumDisplayModes failed:

") + QString::fromUtf8(SDL_GetError()) + "
"); + msgBox.setText( + tr("
SDL_GetNumDisplayModes failed:

") + QString::fromUtf8(SDL_GetError()) + "
"); msgBox.exec(); return result; } @@ -314,7 +323,8 @@ QStringList Launcher::GraphicsPage::getAvailableResolutions(int screen) msgBox.setWindowTitle(tr("Error receiving resolutions")); msgBox.setIcon(QMessageBox::Critical); msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.setText(tr("
SDL_GetDisplayMode failed:

") + QString::fromUtf8(SDL_GetError()) + "
"); + msgBox.setText( + tr("
SDL_GetDisplayMode failed:

") + QString::fromUtf8(SDL_GetError()) + "
"); msgBox.exec(); return result; } @@ -322,10 +332,12 @@ QStringList Launcher::GraphicsPage::getAvailableResolutions(int screen) QString resolution = QString::number(mode.w) + QString(" x ") + QString::number(mode.h); QString aspect = getAspect(mode.w, mode.h); - if (aspect == QLatin1String("16:9") || aspect == QLatin1String("16:10")) { + if (aspect == QLatin1String("16:9") || aspect == QLatin1String("16:10")) + { resolution.append(tr("\t(Wide ") + aspect + ")"); - - } else if (aspect == QLatin1String("4:3")) { + } + else if (aspect == QLatin1String("4:3")) + { resolution.append(tr("\t(Standard 4:3)")); } @@ -353,7 +365,8 @@ QRect Launcher::GraphicsPage::getMaximumResolution() void Launcher::GraphicsPage::screenChanged(int screen) { - if (screen >= 0) { + if (screen >= 0) + { resolutionComboBox->clear(); resolutionComboBox->addItems(mResolutionsPerScreen[screen]); } @@ -361,13 +374,17 @@ void Launcher::GraphicsPage::screenChanged(int screen) void Launcher::GraphicsPage::slotFullScreenChanged(int mode) { - if (mode == static_cast(Settings::WindowMode::Fullscreen) || mode == static_cast(Settings::WindowMode::WindowedFullscreen)) { + if (mode == static_cast(Settings::WindowMode::Fullscreen) + || mode == static_cast(Settings::WindowMode::WindowedFullscreen)) + { standardRadioButton->toggle(); customRadioButton->setEnabled(false); customWidthSpinBox->setEnabled(false); customHeightSpinBox->setEnabled(false); windowBorderCheckBox->setEnabled(false); - } else { + } + else + { customRadioButton->setEnabled(true); customWidthSpinBox->setEnabled(true); customHeightSpinBox->setEnabled(true); @@ -377,11 +394,14 @@ void Launcher::GraphicsPage::slotFullScreenChanged(int mode) void Launcher::GraphicsPage::slotStandardToggled(bool checked) { - if (checked) { + if (checked) + { resolutionComboBox->setEnabled(true); customWidthSpinBox->setEnabled(false); customHeightSpinBox->setEnabled(false); - } else { + } + else + { resolutionComboBox->setEnabled(false); customWidthSpinBox->setEnabled(true); customHeightSpinBox->setEnabled(true); diff --git a/apps/launcher/graphicspage.hpp b/apps/launcher/graphicspage.hpp index b90cf3a66b..92bdf35ac4 100644 --- a/apps/launcher/graphicspage.hpp +++ b/apps/launcher/graphicspage.hpp @@ -5,7 +5,10 @@ #include -namespace Files { struct ConfigurationManager; } +namespace Files +{ + struct ConfigurationManager; +} namespace Launcher { @@ -16,7 +19,7 @@ namespace Launcher Q_OBJECT public: - explicit GraphicsPage(QWidget *parent = nullptr); + explicit GraphicsPage(QWidget* parent = nullptr); void saveSettings(); bool loadSettings(); diff --git a/apps/launcher/main.cpp b/apps/launcher/main.cpp index 486f771366..4aca9fc69e 100644 --- a/apps/launcher/main.cpp +++ b/apps/launcher/main.cpp @@ -1,7 +1,7 @@ #include -#include #include +#include #include #include @@ -14,7 +14,7 @@ #include "maindialog.hpp" -int runLauncher(int argc, char *argv[]) +int runLauncher(int argc, char* argv[]) { Platform::init(); @@ -22,7 +22,7 @@ int runLauncher(int argc, char *argv[]) { QApplication app(argc, argv); - // Internationalization + // Internationalization QString locale = QLocale::system().name().section('_', 0, 0); QTranslator appTranslator; @@ -54,7 +54,7 @@ int runLauncher(int argc, char *argv[]) } } -int main(int argc, char *argv[]) +int main(int argc, char* argv[]) { return wrapApplication(runLauncher, argc, argv, "Launcher"); } diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index d0f3ebf0bc..9b89edd08a 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -1,14 +1,14 @@ #include "maindialog.hpp" -#include #include +#include -#include -#include +#include #include +#include #include -#include #include +#include #include #include @@ -23,7 +23,8 @@ using namespace Process; -void cfgError(const QString& title, const QString& msg) { +void cfgError(const QString& title, const QString& msg) +{ QMessageBox msgBox; msgBox.setWindowTitle(title); msgBox.setIcon(QMessageBox::Critical); @@ -32,19 +33,19 @@ void cfgError(const QString& title, const QString& msg) { msgBox.exec(); } -Launcher::MainDialog::MainDialog(QWidget *parent) - : QMainWindow(parent), mGameSettings (mCfgMgr) +Launcher::MainDialog::MainDialog(QWidget* parent) + : QMainWindow(parent) + , mGameSettings(mCfgMgr) { setupUi(this); mGameInvoker = new ProcessInvoker(); mWizardInvoker = new ProcessInvoker(); - connect(mWizardInvoker->getProcess(), &QProcess::started, - this, &MainDialog::wizardStarted); + connect(mWizardInvoker->getProcess(), &QProcess::started, this, &MainDialog::wizardStarted); - connect(mWizardInvoker->getProcess(), qOverload(&QProcess::finished), - this, &MainDialog::wizardFinished); + connect(mWizardInvoker->getProcess(), qOverload(&QProcess::finished), this, + &MainDialog::wizardFinished); iconWidget->setViewMode(QListView::IconMode); iconWidget->setWrapping(false); @@ -56,8 +57,8 @@ Launcher::MainDialog::MainDialog(QWidget *parent) iconWidget->setCurrentRow(0); iconWidget->setFlow(QListView::LeftToRight); - auto *helpButton = new QPushButton(tr("Help")); - auto *playButton = new QPushButton(tr("Play")); + auto* helpButton = new QPushButton(tr("Help")); + auto* playButton = new QPushButton(tr("Play")); buttonBox->button(QDialogButtonBox::Close)->setText(tr("Close")); buttonBox->addButton(helpButton, QDialogButtonBox::HelpRole); buttonBox->addButton(playButton, QDialogButtonBox::AcceptRole); @@ -83,38 +84,37 @@ void Launcher::MainDialog::createIcons() if (!QIcon::hasThemeIcon("document-new")) QIcon::setThemeName("tango"); - auto *playButton = new QListWidgetItem(iconWidget); + auto* playButton = new QListWidgetItem(iconWidget); playButton->setIcon(QIcon(":/images/openmw.png")); playButton->setText(tr("Play")); playButton->setTextAlignment(Qt::AlignCenter); playButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); - auto *dataFilesButton = new QListWidgetItem(iconWidget); + auto* dataFilesButton = new QListWidgetItem(iconWidget); dataFilesButton->setIcon(QIcon(":/images/openmw-plugin.png")); dataFilesButton->setText(tr("Data Files")); dataFilesButton->setTextAlignment(Qt::AlignHCenter | Qt::AlignBottom); dataFilesButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); - auto *graphicsButton = new QListWidgetItem(iconWidget); + auto* graphicsButton = new QListWidgetItem(iconWidget); graphicsButton->setIcon(QIcon(":/images/preferences-video.png")); graphicsButton->setText(tr("Graphics")); graphicsButton->setTextAlignment(Qt::AlignHCenter | Qt::AlignBottom | Qt::AlignAbsolute); graphicsButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); - auto *settingsButton = new QListWidgetItem(iconWidget); + auto* settingsButton = new QListWidgetItem(iconWidget); settingsButton->setIcon(QIcon(":/images/preferences.png")); settingsButton->setText(tr("Settings")); settingsButton->setTextAlignment(Qt::AlignHCenter | Qt::AlignBottom); settingsButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); - auto *advancedButton = new QListWidgetItem(iconWidget); + auto* advancedButton = new QListWidgetItem(iconWidget); advancedButton->setIcon(QIcon(":/images/preferences-advanced.png")); advancedButton->setText(tr("Advanced")); advancedButton->setTextAlignment(Qt::AlignHCenter | Qt::AlignBottom); advancedButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); connect(iconWidget, &QListWidget::currentItemChanged, this, &MainDialog::changePage); - } void Launcher::MainDialog::createPages() @@ -148,7 +148,8 @@ void Launcher::MainDialog::createPages() connect(mPlayPage, &PlayPage::signalProfileChanged, mDataFilesPage, &DataFilesPage::slotProfileChanged); connect(mDataFilesPage, &DataFilesPage::signalProfileChanged, mPlayPage, &PlayPage::setProfilesIndex); // Using Qt::QueuedConnection because signal is emitted in a subthread and slot is in the main thread - connect(mDataFilesPage, &DataFilesPage::signalLoadedCellsChanged, mAdvancedPage, &AdvancedPage::slotLoadedCellsChanged, Qt::QueuedConnection); + connect(mDataFilesPage, &DataFilesPage::signalLoadedCellsChanged, mAdvancedPage, + &AdvancedPage::slotLoadedCellsChanged, Qt::QueuedConnection); } Launcher::FirstRunDialogResult Launcher::MainDialog::showFirstRunDialog() @@ -158,14 +159,15 @@ Launcher::FirstRunDialogResult Launcher::MainDialog::showFirstRunDialog() // Dialog wizard and setup will fail if the config directory does not already exist const auto& userConfigDir = mCfgMgr.getUserConfigPath(); - if ( ! exists(userConfigDir) ) { - if ( ! create_directories(userConfigDir) ) + if (!exists(userConfigDir)) + { + if (!create_directories(userConfigDir)) { cfgError(tr("Error opening OpenMW configuration file"), - tr("
Could not create directory %0

\ + tr("
Could not create directory %0

\ Please make sure you have the right permissions \ - and try again.
").arg(Files::pathToQString(canonical(userConfigDir))) - ); + and try again.
") + .arg(Files::pathToQString(canonical(userConfigDir)))); return FirstRunDialogResultFailure; } } @@ -176,15 +178,15 @@ Launcher::FirstRunDialogResult Launcher::MainDialog::showFirstRunDialog() msgBox.setWindowTitle(tr("First run")); msgBox.setIcon(QMessageBox::Question); msgBox.setStandardButtons(QMessageBox::NoButton); - msgBox.setText(tr("

Welcome to OpenMW!

\ + msgBox.setText( + tr("

Welcome to OpenMW!

\

It is recommended to run the Installation Wizard.

\

The Wizard will let you select an existing Morrowind installation, \ or install Morrowind for OpenMW to use.

")); - QAbstractButton *wizardButton = - msgBox.addButton(tr("Run &Installation Wizard"), QMessageBox::AcceptRole); // ActionRole doesn't work?! - QAbstractButton *skipButton = - msgBox.addButton(tr("Skip"), QMessageBox::RejectRole); + QAbstractButton* wizardButton + = msgBox.addButton(tr("Run &Installation Wizard"), QMessageBox::AcceptRole); // ActionRole doesn't work?! + QAbstractButton* skipButton = msgBox.addButton(tr("Skip"), QMessageBox::RejectRole); msgBox.exec(); @@ -202,7 +204,8 @@ Launcher::FirstRunDialogResult Launcher::MainDialog::showFirstRunDialog() return FirstRunDialogResultFailure; } - if (!setup() || !setupGameData()) { + if (!setup() || !setupGameData()) + { return FirstRunDialogResultFailure; } return FirstRunDialogResultContinue; @@ -225,8 +228,9 @@ void Launcher::MainDialog::setVersionLabel() // Add the compile date and time auto compileDate = QLocale(QLocale::C).toDate(QString(__DATE__).simplified(), QLatin1String("MMM d yyyy")); auto compileTime = QLocale(QLocale::C).toTime(QString(__TIME__).simplified(), QLatin1String("hh:mm:ss")); - versionLabel->setToolTip(tr("Compiled on %1 %2").arg(QLocale::system().toString(compileDate, QLocale::LongFormat), - QLocale::system().toString(compileTime, QLocale::ShortFormat))); + versionLabel->setToolTip(tr("Compiled on %1 %2") + .arg(QLocale::system().toString(compileDate, QLocale::LongFormat), + QLocale::system().toString(compileTime, QLocale::ShortFormat))); } bool Launcher::MainDialog::setup() @@ -281,7 +285,7 @@ bool Launcher::MainDialog::reloadSettings() return true; } -void Launcher::MainDialog::changePage(QListWidgetItem *current, QListWidgetItem *previous) +void Launcher::MainDialog::changePage(QListWidgetItem* current, QListWidgetItem* previous) { if (!current) current = previous; @@ -303,16 +307,19 @@ bool Launcher::MainDialog::setupLauncherSettings() paths.append(QString(Config::LauncherSettings::sLauncherConfigFileName)); paths.append(userPath + QString(Config::LauncherSettings::sLauncherConfigFileName)); - for (const QString &path : paths) + for (const QString& path : paths) { qDebug() << "Loading config file:" << path.toUtf8().constData(); QFile file(path); - if (file.exists()) { - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + if (file.exists()) + { + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) + { cfgError(tr("Error opening OpenMW configuration file"), - tr("
Could not open %0 for reading

\ + tr("
Could not open %0 for reading

\ Please make sure you have the right permissions \ - and try again.
").arg(file.fileName())); + and try again.
") + .arg(file.fileName())); return false; } QTextStream stream(&file); @@ -336,16 +343,19 @@ bool Launcher::MainDialog::setupGameSettings() QFile file; - auto loadFile = [&] (const QString& path, bool(Config::GameSettings::*reader)(QTextStream&, bool), bool ignoreContent = false) -> std::optional - { + auto loadFile = [&](const QString& path, bool (Config::GameSettings::*reader)(QTextStream&, bool), + bool ignoreContent = false) -> std::optional { qDebug() << "Loading config file:" << path.toUtf8().constData(); file.setFileName(path); - if (file.exists()) { - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + if (file.exists()) + { + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) + { cfgError(tr("Error opening OpenMW configuration file"), - tr("
Could not open %0 for reading

\ + tr("
Could not open %0 for reading

\ Please make sure you have the right permissions \ - and try again.
").arg(file.fileName())); + and try again.
") + .arg(file.fileName())); return {}; } QTextStream stream(&file); @@ -360,19 +370,19 @@ bool Launcher::MainDialog::setupGameSettings() // Load the user config file first, separately // So we can write it properly, uncontaminated - if(!loadFile(userPath + QLatin1String("openmw.cfg"), &Config::GameSettings::readUserFile)) + if (!loadFile(userPath + QLatin1String("openmw.cfg"), &Config::GameSettings::readUserFile)) return false; // Now the rest - priority: user > local > global - if(auto result = loadFile(localPath + QString("openmw.cfg"), &Config::GameSettings::readFile, true)) + if (auto result = loadFile(localPath + QString("openmw.cfg"), &Config::GameSettings::readFile, true)) { // Load global if local wasn't found - if(!*result && !loadFile(globalPath + QString("openmw.cfg"), &Config::GameSettings::readFile, true)) + if (!*result && !loadFile(globalPath + QString("openmw.cfg"), &Config::GameSettings::readFile, true)) return false; } else return false; - if(!loadFile(userPath + QString("openmw.cfg"), &Config::GameSettings::readFile)) + if (!loadFile(userPath + QString("openmw.cfg"), &Config::GameSettings::readFile)) return false; return true; @@ -387,7 +397,10 @@ bool Launcher::MainDialog::setupGameData() { QDir dir(path3); QStringList filters; - filters << "*.esp" << "*.esm" << "*.omwgame" << "*.omwaddon"; + filters << "*.esp" + << "*.esm" + << "*.omwgame" + << "*.omwaddon"; if (!dir.entryList(filters).isEmpty()) dataDirs.append(path3); @@ -399,13 +412,12 @@ bool Launcher::MainDialog::setupGameData() msgBox.setWindowTitle(tr("Error detecting Morrowind installation")); msgBox.setIcon(QMessageBox::Warning); msgBox.setStandardButtons(QMessageBox::NoButton); - msgBox.setText(tr("
Could not find the Data Files location

\ + msgBox.setText( + tr("
Could not find the Data Files location

\ The directory containing the data files was not found.")); - QAbstractButton *wizardButton = - msgBox.addButton(tr("Run &Installation Wizard..."), QMessageBox::ActionRole); - QAbstractButton *skipButton = - msgBox.addButton(tr("Skip"), QMessageBox::RejectRole); + QAbstractButton* wizardButton = msgBox.addButton(tr("Run &Installation Wizard..."), QMessageBox::ActionRole); + QAbstractButton* skipButton = msgBox.addButton(tr("Skip"), QMessageBox::RejectRole); Q_UNUSED(skipButton); // Suppress compiler unused warning @@ -423,7 +435,7 @@ bool Launcher::MainDialog::setupGameData() bool Launcher::MainDialog::setupGraphicsSettings() { - Settings::Manager::clear(); // Ensure to clear previous settings in case we had already loaded settings. + Settings::Manager::clear(); // Ensure to clear previous settings in case we had already loaded settings. try { boost::program_options::variables_map variables; @@ -436,8 +448,9 @@ bool Launcher::MainDialog::setupGraphicsSettings() catch (std::exception& e) { cfgError(tr("Error reading OpenMW configuration files"), - tr("
The problem may be due to an incomplete installation of OpenMW.
\ - Reinstalling OpenMW may resolve the problem.
") + e.what()); + tr("
The problem may be due to an incomplete installation of OpenMW.
\ + Reinstalling OpenMW may resolve the problem.
") + + e.what()); return false; } } @@ -469,7 +482,6 @@ void Launcher::MainDialog::saveSettings() mLauncherSettings.setValue(QString("General/MainWindow/posy"), posY); mLauncherSettings.setValue(QString("General/firstrun"), QString("false")); - } bool Launcher::MainDialog::writeSettings() @@ -483,12 +495,15 @@ bool Launcher::MainDialog::writeSettings() const auto& userPath = mCfgMgr.getUserConfigPath(); - if (!exists(userPath)) { - if (!create_directories(userPath)) { + if (!exists(userPath)) + { + if (!create_directories(userPath)) + { cfgError(tr("Error creating OpenMW configuration directory"), - tr("
Could not create %0

\ + tr("
Could not create %0

\ Please make sure you have the right permissions \ - and try again.
").arg(Files::pathToQString(userPath))); + and try again.
") + .arg(Files::pathToQString(userPath))); return false; } } @@ -500,27 +515,30 @@ bool Launcher::MainDialog::writeSettings() QFile file(Files::pathToQString(userPath / "openmw.cfg")); #endif - if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) { + if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) + { // File cannot be opened or created cfgError(tr("Error writing OpenMW configuration file"), - tr("
Could not open or create %0 for writing

\ + tr("
Could not open or create %0 for writing

\ Please make sure you have the right permissions \ - and try again.
").arg(file.fileName())); + and try again.
") + .arg(file.fileName())); return false; } - mGameSettings.writeFileWithComments(file); file.close(); // Graphics settings const auto settingsPath = mCfgMgr.getUserConfigPath() / "settings.cfg"; - try { + try + { Settings::Manager::saveUser(settingsPath); } - catch (std::exception& e) { - std::string msg = "
Error writing settings.cfg

" + - Files::pathToUnicodeString(settingsPath) + "

" + e.what(); + catch (std::exception& e) + { + std::string msg = "
Error writing settings.cfg

" + Files::pathToUnicodeString(settingsPath) + + "

" + e.what(); cfgError(tr("Error writing user settings file"), tr(msg.c_str())); return false; } @@ -528,12 +546,14 @@ bool Launcher::MainDialog::writeSettings() // Launcher settings file.setFileName(Files::pathToQString(userPath / Config::LauncherSettings::sLauncherConfigFileName)); - if (!file.open(QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate)) { + if (!file.open(QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate)) + { // File cannot be opened or created cfgError(tr("Error writing Launcher configuration file"), - tr("
Could not open or create %0 for writing

\ + tr("
Could not open or create %0 for writing

\ Please make sure you have the right permissions \ - and try again.
").arg(file.fileName())); + and try again.
") + .arg(file.fileName())); return false; } @@ -547,7 +567,7 @@ bool Launcher::MainDialog::writeSettings() return true; } -void Launcher::MainDialog::closeEvent(QCloseEvent *event) +void Launcher::MainDialog::closeEvent(QCloseEvent* event) { writeSettings(); event->accept(); @@ -575,12 +595,14 @@ void Launcher::MainDialog::play() if (!writeSettings()) return qApp->quit(); - if (!mGameSettings.hasMaster()) { + if (!mGameSettings.hasMaster()) + { QMessageBox msgBox; msgBox.setWindowTitle(tr("No game file selected")); msgBox.setIcon(QMessageBox::Warning); msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.setText(tr("
You do not have a game file selected.

\ + msgBox.setText( + tr("
You do not have a game file selected.

\ OpenMW will not start without a game file selected.
")); msgBox.exec(); return; diff --git a/apps/launcher/maindialog.hpp b/apps/launcher/maindialog.hpp index ca198cef54..6644012df8 100644 --- a/apps/launcher/maindialog.hpp +++ b/apps/launcher/maindialog.hpp @@ -1,7 +1,6 @@ #ifndef MAINDIALOG_H #define MAINDIALOG_H - #ifndef Q_MOC_RUN #include @@ -44,7 +43,7 @@ namespace Launcher Q_OBJECT public: - explicit MainDialog(QWidget *parent = nullptr); + explicit MainDialog(QWidget* parent = nullptr); ~MainDialog() override; FirstRunDialogResult showFirstRunDialog(); @@ -53,7 +52,7 @@ namespace Launcher bool writeSettings(); public slots: - void changePage(QListWidgetItem *current, QListWidgetItem *previous); + void changePage(QListWidgetItem* current, QListWidgetItem* previous); void play(); void help(); @@ -77,25 +76,27 @@ namespace Launcher void loadSettings(); void saveSettings(); - inline bool startProgram(const QString &name, bool detached = false) { return startProgram(name, QStringList(), detached); } - bool startProgram(const QString &name, const QStringList &arguments, bool detached = false); + inline bool startProgram(const QString& name, bool detached = false) + { + return startProgram(name, QStringList(), detached); + } + bool startProgram(const QString& name, const QStringList& arguments, bool detached = false); - void closeEvent(QCloseEvent *event) override; + void closeEvent(QCloseEvent* event) override; - PlayPage *mPlayPage; - GraphicsPage *mGraphicsPage; - DataFilesPage *mDataFilesPage; - SettingsPage *mSettingsPage; - AdvancedPage *mAdvancedPage; + PlayPage* mPlayPage; + GraphicsPage* mGraphicsPage; + DataFilesPage* mDataFilesPage; + SettingsPage* mSettingsPage; + AdvancedPage* mAdvancedPage; - Process::ProcessInvoker *mGameInvoker; - Process::ProcessInvoker *mWizardInvoker; + Process::ProcessInvoker* mGameInvoker; + Process::ProcessInvoker* mWizardInvoker; Files::ConfigurationManager mCfgMgr; Config::GameSettings mGameSettings; Config::LauncherSettings mLauncherSettings; - }; } #endif diff --git a/apps/launcher/playpage.cpp b/apps/launcher/playpage.cpp index 9ecfaa8fce..c3c87e03fb 100644 --- a/apps/launcher/playpage.cpp +++ b/apps/launcher/playpage.cpp @@ -2,19 +2,19 @@ #include -Launcher::PlayPage::PlayPage(QWidget *parent) : QWidget(parent) +Launcher::PlayPage::PlayPage(QWidget* parent) + : QWidget(parent) { - setObjectName ("PlayPage"); + setObjectName("PlayPage"); setupUi(this); profilesComboBox->setView(new QListView()); connect(profilesComboBox, qOverload(&QComboBox::activated), this, &PlayPage::signalProfileChanged); connect(playButton, &QPushButton::clicked, this, &PlayPage::slotPlayClicked); - } -void Launcher::PlayPage::setProfilesModel(QAbstractItemModel *model) +void Launcher::PlayPage::setProfilesModel(QAbstractItemModel* model) { profilesComboBox->setModel(model); } diff --git a/apps/launcher/playpage.hpp b/apps/launcher/playpage.hpp index 8f414dc6aa..8e658d6d2c 100644 --- a/apps/launcher/playpage.hpp +++ b/apps/launcher/playpage.hpp @@ -14,8 +14,8 @@ namespace Launcher Q_OBJECT public: - PlayPage(QWidget *parent = nullptr); - void setProfilesModel(QAbstractItemModel *model); + PlayPage(QWidget* parent = nullptr); + void setProfilesModel(QAbstractItemModel* model); signals: void signalProfileChanged(int index); @@ -26,9 +26,6 @@ namespace Launcher private slots: void slotPlayClicked(); - - - }; } #endif diff --git a/apps/launcher/settingspage.cpp b/apps/launcher/settingspage.cpp index 474b1a1c72..d65b8732a6 100644 --- a/apps/launcher/settingspage.cpp +++ b/apps/launcher/settingspage.cpp @@ -1,21 +1,20 @@ #include "settingspage.hpp" -#include -#include #include #include +#include +#include #include #include -#include "utils/textinputdialog.hpp" #include "datafilespage.hpp" +#include "utils/textinputdialog.hpp" using namespace Process; -Launcher::SettingsPage::SettingsPage(Files::ConfigurationManager &cfg, - Config::GameSettings &gameSettings, - Config::LauncherSettings &launcherSettings, MainDialog *parent) +Launcher::SettingsPage::SettingsPage(Files::ConfigurationManager& cfg, Config::GameSettings& gameSettings, + Config::LauncherSettings& launcherSettings, MainDialog* parent) : QWidget(parent) , mCfgMgr(cfg) , mGameSettings(gameSettings) @@ -25,12 +24,7 @@ Launcher::SettingsPage::SettingsPage(Files::ConfigurationManager &cfg, setupUi(this); QStringList languages; - languages << tr("English") - << tr("French") - << tr("German") - << tr("Italian") - << tr("Polish") - << tr("Russian") + languages << tr("English") << tr("French") << tr("German") << tr("Italian") << tr("Polish") << tr("Russian") << tr("Spanish"); languageComboBox->addItems(languages); @@ -39,27 +33,24 @@ Launcher::SettingsPage::SettingsPage(Files::ConfigurationManager &cfg, mImporterInvoker = new ProcessInvoker(); resetProgressBar(); - connect(mWizardInvoker->getProcess(), &QProcess::started, - this, &SettingsPage::wizardStarted); + connect(mWizardInvoker->getProcess(), &QProcess::started, this, &SettingsPage::wizardStarted); - connect(mWizardInvoker->getProcess(), qOverload(&QProcess::finished), - this, &SettingsPage::wizardFinished); + connect(mWizardInvoker->getProcess(), qOverload(&QProcess::finished), this, + &SettingsPage::wizardFinished); - connect(mImporterInvoker->getProcess(), &QProcess::started, - this, &SettingsPage::importerStarted); + connect(mImporterInvoker->getProcess(), &QProcess::started, this, &SettingsPage::importerStarted); - connect(mImporterInvoker->getProcess(), qOverload(&QProcess::finished), - this, &SettingsPage::importerFinished); + connect(mImporterInvoker->getProcess(), qOverload(&QProcess::finished), this, + &SettingsPage::importerFinished); mProfileDialog = new TextInputDialog(tr("New Content List"), tr("Content List name:"), this); - connect(mProfileDialog->lineEdit(), &LineEdit::textChanged, - this, &SettingsPage::updateOkButton); + connect(mProfileDialog->lineEdit(), &LineEdit::textChanged, this, &SettingsPage::updateOkButton); // Detect Morrowind configuration files QStringList iniPaths; - for (const QString &path : mGameSettings.getDataDirs()) + for (const QString& path : mGameSettings.getDataDirs()) { QDir dir(path); dir.setPath(dir.canonicalPath()); // Resolve symlinks @@ -76,10 +67,13 @@ Launcher::SettingsPage::SettingsPage(Files::ConfigurationManager &cfg, } } - if (!iniPaths.isEmpty()) { + if (!iniPaths.isEmpty()) + { settingsComboBox->addItems(iniPaths); importerButton->setEnabled(true); - } else { + } + else + { importerButton->setEnabled(false); } @@ -113,16 +107,20 @@ void Launcher::SettingsPage::on_importerButton_clicked() QFile file(Files::pathToQString(path)); #endif - if (!file.exists()) { - if (!file.open(QIODevice::ReadWrite)) { + if (!file.exists()) + { + if (!file.open(QIODevice::ReadWrite)) + { // File cannot be created QMessageBox msgBox; msgBox.setWindowTitle(tr("Error writing OpenMW configuration file")); msgBox.setIcon(QMessageBox::Critical); msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.setText(tr("

Could not open or create %1 for writing

\ + msgBox.setText( + tr("

Could not open or create %1 for writing

\

Please make sure you have the right permissions \ - and try again.

").arg(file.fileName())); + and try again.

") + .arg(file.fileName())); msgBox.exec(); return; } @@ -159,12 +157,8 @@ void Launcher::SettingsPage::on_importerButton_clicked() void Launcher::SettingsPage::on_browseButton_clicked() { - QString iniFile = QFileDialog::getOpenFileName( - this, - QObject::tr("Select configuration file"), - QDir::currentPath(), - QString(tr("Morrowind configuration file (*.ini)"))); - + QString iniFile = QFileDialog::getOpenFileName(this, QObject::tr("Select configuration file"), QDir::currentPath(), + QString(tr("Morrowind configuration file (*.ini)"))); if (iniFile.isEmpty()) return; @@ -176,7 +170,8 @@ void Launcher::SettingsPage::on_browseButton_clicked() const QString path(QDir::toNativeSeparators(info.absoluteFilePath())); - if (settingsComboBox->findText(path) == -1) { + if (settingsComboBox->findText(path) == -1) + { settingsComboBox->addItem(path); settingsComboBox->setCurrentIndex(settingsComboBox->findText(path)); importerButton->setEnabled(true); @@ -238,19 +233,18 @@ void Launcher::SettingsPage::resetProgressBar() progressBar->reset(); } -void Launcher::SettingsPage::updateOkButton(const QString &text) +void Launcher::SettingsPage::updateOkButton(const QString& text) { // We do this here because we need to access the profiles - if (text.isEmpty()) { - mProfileDialog->setOkButtonEnabled(false); - return; + if (text.isEmpty()) + { + mProfileDialog->setOkButtonEnabled(false); + return; } const QStringList profiles(mLauncherSettings.getContentLists()); - (profiles.contains(text)) - ? mProfileDialog->setOkButtonEnabled(false) - : mProfileDialog->setOkButtonEnabled(true); + (profiles.contains(text)) ? mProfileDialog->setOkButtonEnabled(false) : mProfileDialog->setOkButtonEnabled(true); } void Launcher::SettingsPage::saveSettings() @@ -259,11 +253,16 @@ void Launcher::SettingsPage::saveSettings() mLauncherSettings.setValue(QLatin1String("Settings/language"), language); - if (language == QLatin1String("Polish")) { + if (language == QLatin1String("Polish")) + { mGameSettings.setValue(QLatin1String("encoding"), QLatin1String("win1250")); - } else if (language == QLatin1String("Russian")) { + } + else if (language == QLatin1String("Russian")) + { mGameSettings.setValue(QLatin1String("encoding"), QLatin1String("win1251")); - } else { + } + else + { mGameSettings.setValue(QLatin1String("encoding"), QLatin1String("win1252")); } } diff --git a/apps/launcher/settingspage.hpp b/apps/launcher/settingspage.hpp index fa31eb4033..8e5eefd306 100644 --- a/apps/launcher/settingspage.hpp +++ b/apps/launcher/settingspage.hpp @@ -7,9 +7,15 @@ #include "maindialog.hpp" -namespace Files { struct ConfigurationManager; } -namespace Config { class GameSettings; - class LauncherSettings; } +namespace Files +{ + struct ConfigurationManager; +} +namespace Config +{ + class GameSettings; + class LauncherSettings; +} namespace Launcher { @@ -20,13 +26,13 @@ namespace Launcher Q_OBJECT public: - SettingsPage(Files::ConfigurationManager &cfg, Config::GameSettings &gameSettings, - Config::LauncherSettings &launcherSettings, MainDialog *parent = nullptr); + SettingsPage(Files::ConfigurationManager& cfg, Config::GameSettings& gameSettings, + Config::LauncherSettings& launcherSettings, MainDialog* parent = nullptr); ~SettingsPage() override; void saveSettings(); bool loadSettings(); - + /// set progress bar on page to 0% void resetProgressBar(); @@ -42,21 +48,19 @@ namespace Launcher void importerStarted(); void importerFinished(int exitCode, QProcess::ExitStatus exitStatus); - void updateOkButton(const QString &text); + void updateOkButton(const QString& text); private: + Process::ProcessInvoker* mWizardInvoker; + Process::ProcessInvoker* mImporterInvoker; - Process::ProcessInvoker *mWizardInvoker; - Process::ProcessInvoker *mImporterInvoker; - - Files::ConfigurationManager &mCfgMgr; - - Config::GameSettings &mGameSettings; - Config::LauncherSettings &mLauncherSettings; + Files::ConfigurationManager& mCfgMgr; - MainDialog *mMain; - TextInputDialog *mProfileDialog; + Config::GameSettings& mGameSettings; + Config::LauncherSettings& mLauncherSettings; + MainDialog* mMain; + TextInputDialog* mProfileDialog; }; } diff --git a/apps/launcher/textslotmsgbox.hpp b/apps/launcher/textslotmsgbox.hpp index a0fefaa253..1eac6cf918 100644 --- a/apps/launcher/textslotmsgbox.hpp +++ b/apps/launcher/textslotmsgbox.hpp @@ -7,9 +7,9 @@ namespace Launcher { class TextSlotMsgBox : public QMessageBox { - Q_OBJECT - public slots: - void setTextSlot(const QString& string); + Q_OBJECT + public slots: + void setTextSlot(const QString& string); }; } #endif diff --git a/apps/launcher/utils/cellnameloader.cpp b/apps/launcher/utils/cellnameloader.cpp index 4cb8b545aa..2f2bddbfb5 100644 --- a/apps/launcher/utils/cellnameloader.cpp +++ b/apps/launcher/utils/cellnameloader.cpp @@ -1,28 +1,31 @@ #include "cellnameloader.hpp" -#include #include +#include -QSet CellNameLoader::getCellNames(QStringList &contentPaths) +QSet CellNameLoader::getCellNames(QStringList& contentPaths) { QSet cellNames; ESM::ESMReader esmReader; // Loop through all content files - for (auto &contentPath : contentPaths) { + for (auto& contentPath : contentPaths) + { if (contentPath.endsWith(".omwscripts", Qt::CaseInsensitive)) continue; esmReader.open(contentPath.toStdString()); // Loop through all records - while(esmReader.hasMoreRecs()) + while (esmReader.hasMoreRecs()) { ESM::NAME recordName = esmReader.getRecName(); esmReader.getRecHeader(); - if (isCellRecord(recordName)) { + if (isCellRecord(recordName)) + { QString cellName = getCellName(esmReader); - if (!cellName.isEmpty()) { + if (!cellName.isEmpty()) + { cellNames.insert(cellName); } } @@ -35,12 +38,12 @@ QSet CellNameLoader::getCellNames(QStringList &contentPaths) return cellNames; } -bool CellNameLoader::isCellRecord(ESM::NAME &recordName) +bool CellNameLoader::isCellRecord(ESM::NAME& recordName) { return recordName.toInt() == ESM::REC_CELL; } -QString CellNameLoader::getCellName(ESM::ESMReader &esmReader) +QString CellNameLoader::getCellName(ESM::ESMReader& esmReader) { ESM::Cell cell; bool isDeleted = false; @@ -48,4 +51,3 @@ QString CellNameLoader::getCellName(ESM::ESMReader &esmReader) return QString::fromStdString(cell.mName); } - diff --git a/apps/launcher/utils/cellnameloader.hpp b/apps/launcher/utils/cellnameloader.hpp index 6143b78bd9..24ff187f41 100644 --- a/apps/launcher/utils/cellnameloader.hpp +++ b/apps/launcher/utils/cellnameloader.hpp @@ -6,19 +6,26 @@ #include -namespace ESM {class ESMReader; struct Cell;} -namespace ContentSelectorView {class ContentSelector;} - -class CellNameLoader { +namespace ESM +{ + class ESMReader; + struct Cell; +} +namespace ContentSelectorView +{ + class ContentSelector; +} + +class CellNameLoader +{ public: - /** * Returns the names of all cells contained within the given content files * @param contentPaths the file paths of each content file to be examined * @return the names of all cells */ - QSet getCellNames(QStringList &contentPaths); + QSet getCellNames(QStringList& contentPaths); private: /** @@ -26,15 +33,14 @@ private: * @param name The name associated with the record * @return whether or not the given record is of type "Cell" */ - bool isCellRecord(ESM::NAME &name); + bool isCellRecord(ESM::NAME& name); /** * Returns the name of the cell * @param esmReader the reader currently pointed to a loaded cell * @return the name of the cell */ - QString getCellName(ESM::ESMReader &esmReader); + QString getCellName(ESM::ESMReader& esmReader); }; - -#endif //OPENMW_CELLNAMELOADER_H +#endif // OPENMW_CELLNAMELOADER_H diff --git a/apps/launcher/utils/lineedit.cpp b/apps/launcher/utils/lineedit.cpp index 7942621f0f..011acd7699 100644 --- a/apps/launcher/utils/lineedit.cpp +++ b/apps/launcher/utils/lineedit.cpp @@ -1,6 +1,6 @@ #include "lineedit.hpp" -LineEdit::LineEdit(QWidget *parent) +LineEdit::LineEdit(QWidget* parent) : QLineEdit(parent) { setupClearButton(); @@ -19,12 +19,11 @@ void LineEdit::setupClearButton() connect(this, &LineEdit::textChanged, this, &LineEdit::updateClearButton); } -void LineEdit::resizeEvent(QResizeEvent *) +void LineEdit::resizeEvent(QResizeEvent*) { QSize sz = mClearButton->sizeHint(); int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); - mClearButton->move(rect().right() - frameWidth - sz.width(), - (rect().bottom() + 1 - sz.height())/2); + mClearButton->move(rect().right() - frameWidth - sz.width(), (rect().bottom() + 1 - sz.height()) / 2); } void LineEdit::updateClearButton(const QString& text) diff --git a/apps/launcher/utils/lineedit.hpp b/apps/launcher/utils/lineedit.hpp index 89de39588a..1a06c3ee06 100644 --- a/apps/launcher/utils/lineedit.hpp +++ b/apps/launcher/utils/lineedit.hpp @@ -23,19 +23,18 @@ class LineEdit : public QLineEdit QString mPlaceholderText; public: - LineEdit(QWidget *parent = nullptr); + LineEdit(QWidget* parent = nullptr); protected: - void resizeEvent(QResizeEvent *) override; + void resizeEvent(QResizeEvent*) override; private slots: - void updateClearButton(const QString &text); + void updateClearButton(const QString& text); protected: - QToolButton *mClearButton; + QToolButton* mClearButton; void setupClearButton(); }; #endif // LIENEDIT_H - diff --git a/apps/launcher/utils/openalutil.cpp b/apps/launcher/utils/openalutil.cpp index 469872d158..1a332e9788 100644 --- a/apps/launcher/utils/openalutil.cpp +++ b/apps/launcher/utils/openalutil.cpp @@ -12,9 +12,9 @@ std::vector Launcher::enumerateOpenALDevices() { std::vector devlist; - const ALCchar *devnames; + const ALCchar* devnames; - if(alcIsExtensionPresent(nullptr, "ALC_ENUMERATE_ALL_EXT")) + if (alcIsExtensionPresent(nullptr, "ALC_ENUMERATE_ALL_EXT")) { devnames = alcGetString(nullptr, ALC_ALL_DEVICES_SPECIFIER); } @@ -23,10 +23,10 @@ std::vector Launcher::enumerateOpenALDevices() devnames = alcGetString(nullptr, ALC_DEVICE_SPECIFIER); } - while(devnames && *devnames) + while (devnames && *devnames) { devlist.emplace_back(devnames); - devnames += strlen(devnames)+1; + devnames += strlen(devnames) + 1; } return devlist; } @@ -35,10 +35,10 @@ std::vector Launcher::enumerateOpenALDevicesHrtf() { std::vector ret; - ALCdevice *device = alcOpenDevice(nullptr); - if(device) + ALCdevice* device = alcOpenDevice(nullptr); + if (device) { - if(alcIsExtensionPresent(device, "ALC_SOFT_HRTF")) + if (alcIsExtensionPresent(device, "ALC_SOFT_HRTF")) { LPALCGETSTRINGISOFT alcGetStringiSOFT = nullptr; void* funcPtr = alcGetProcAddress(device, "alcGetStringiSOFT"); @@ -46,10 +46,10 @@ std::vector Launcher::enumerateOpenALDevicesHrtf() ALCint num_hrtf; alcGetIntegerv(device, ALC_NUM_HRTF_SPECIFIERS_SOFT, 1, &num_hrtf); ret.reserve(num_hrtf); - for(ALCint i = 0;i < num_hrtf;++i) + for (ALCint i = 0; i < num_hrtf; ++i) { - const ALCchar *entry = alcGetStringiSOFT(device, ALC_HRTF_SPECIFIER_SOFT, i); - if(strcmp(entry, "") == 0) + const ALCchar* entry = alcGetStringiSOFT(device, ALC_HRTF_SPECIFIER_SOFT, i); + if (strcmp(entry, "") == 0) break; ret.emplace_back(entry); } diff --git a/apps/launcher/utils/openalutil.hpp b/apps/launcher/utils/openalutil.hpp index b084dce7ce..f0add75390 100644 --- a/apps/launcher/utils/openalutil.hpp +++ b/apps/launcher/utils/openalutil.hpp @@ -1,5 +1,5 @@ -#include #include +#include namespace Launcher { diff --git a/apps/launcher/utils/profilescombobox.cpp b/apps/launcher/utils/profilescombobox.cpp index 5ac51393f7..193dd8e4cf 100644 --- a/apps/launcher/utils/profilescombobox.cpp +++ b/apps/launcher/utils/profilescombobox.cpp @@ -1,13 +1,12 @@ -#include #include +#include #include "profilescombobox.hpp" -ProfilesComboBox::ProfilesComboBox(QWidget *parent) : - ContentSelectorView::ComboBox(parent) +ProfilesComboBox::ProfilesComboBox(QWidget* parent) + : ContentSelectorView::ComboBox(parent) { - connect(this, qOverload(&ProfilesComboBox::activated), - this, &ProfilesComboBox::slotIndexChangedByUser); + connect(this, qOverload(&ProfilesComboBox::activated), this, &ProfilesComboBox::slotIndexChangedByUser); setInsertPolicy(QComboBox::NoInsert); } @@ -17,7 +16,8 @@ void ProfilesComboBox::setEditEnabled(bool editable) if (isEditable() == editable) return; - if (!editable) { + if (!editable) + { disconnect(lineEdit(), &QLineEdit::editingFinished, this, &ProfilesComboBox::slotEditingFinished); disconnect(lineEdit(), &QLineEdit::textChanged, this, &ProfilesComboBox::slotTextChanged); return setEditable(false); @@ -27,7 +27,7 @@ void ProfilesComboBox::setEditEnabled(bool editable) setEditable(true); setValidator(mValidator); - auto *edit = new ComboBoxLineEdit(this); + auto* edit = new ComboBoxLineEdit(this); setLineEdit(edit); setCompleter(nullptr); @@ -39,16 +39,19 @@ void ProfilesComboBox::setEditEnabled(bool editable) connect(lineEdit(), &QLineEdit::textChanged, this, &ProfilesComboBox::signalProfileTextChanged); } -void ProfilesComboBox::slotTextChanged(const QString &text) +void ProfilesComboBox::slotTextChanged(const QString& text) { QPalette palette; - palette.setColor(QPalette::Text,Qt::red); + palette.setColor(QPalette::Text, Qt::red); int index = findText(text); - if (text.isEmpty() || (index != -1 && index != currentIndex())) { + if (text.isEmpty() || (index != -1 && index != currentIndex())) + { lineEdit()->setPalette(palette); - } else { + } + else + { lineEdit()->setPalette(QApplication::palette()); } } @@ -83,11 +86,12 @@ void ProfilesComboBox::slotIndexChangedByUser(int index) mOldProfile = currentText(); } -ProfilesComboBox::ComboBoxLineEdit::ComboBoxLineEdit (QWidget *parent) - : LineEdit (parent) +ProfilesComboBox::ComboBoxLineEdit::ComboBoxLineEdit(QWidget* parent) + : LineEdit(parent) { int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); setObjectName(QString("ComboBoxLineEdit")); - setStyleSheet(QString("ComboBoxLineEdit { background-color: transparent; padding-right: %1px; } ").arg(mClearButton->sizeHint().width() + frameWidth + 1)); + setStyleSheet(QString("ComboBoxLineEdit { background-color: transparent; padding-right: %1px; } ") + .arg(mClearButton->sizeHint().width() + frameWidth + 1)); } diff --git a/apps/launcher/utils/profilescombobox.hpp b/apps/launcher/utils/profilescombobox.hpp index f29ac58e12..91f4f9ef9c 100644 --- a/apps/launcher/utils/profilescombobox.hpp +++ b/apps/launcher/utils/profilescombobox.hpp @@ -16,12 +16,11 @@ public: class ComboBoxLineEdit : public LineEdit { public: - explicit ComboBoxLineEdit (QWidget *parent = nullptr); + explicit ComboBoxLineEdit(QWidget* parent = nullptr); }; public: - - explicit ProfilesComboBox(QWidget *parent = nullptr); + explicit ProfilesComboBox(QWidget* parent = nullptr); void setEditEnabled(bool editable); void setCurrentProfile(int index) { @@ -30,16 +29,16 @@ public: } signals: - void signalProfileTextChanged(const QString &item); - void signalProfileChanged(const QString &previous, const QString ¤t); + void signalProfileTextChanged(const QString& item); + void signalProfileChanged(const QString& previous, const QString& current); void signalProfileChanged(int index); - void profileRenamed(const QString &oldName, const QString &newName); + void profileRenamed(const QString& oldName, const QString& newName); private slots: void slotEditingFinished(); void slotIndexChangedByUser(int index); - void slotTextChanged(const QString &text); + void slotTextChanged(const QString& text); private: QString mOldProfile; diff --git a/apps/launcher/utils/textinputdialog.cpp b/apps/launcher/utils/textinputdialog.cpp index cffb734350..73210afdfa 100644 --- a/apps/launcher/utils/textinputdialog.cpp +++ b/apps/launcher/utils/textinputdialog.cpp @@ -1,31 +1,31 @@ #include "textinputdialog.hpp" -#include #include +#include +#include #include #include #include -#include -Launcher::TextInputDialog::TextInputDialog(const QString& title, const QString &text, QWidget *parent) : - QDialog(parent) +Launcher::TextInputDialog::TextInputDialog(const QString& title, const QString& text, QWidget* parent) + : QDialog(parent) { setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); mButtonBox = new QDialogButtonBox(this); mButtonBox->addButton(QDialogButtonBox::Ok); mButtonBox->addButton(QDialogButtonBox::Cancel); - mButtonBox->button(QDialogButtonBox::Ok)->setEnabled (false); + mButtonBox->button(QDialogButtonBox::Ok)->setEnabled(false); - auto *label = new QLabel(this); + auto* label = new QLabel(this); label->setText(text); // Line edit - QValidator *validator = new QRegExpValidator(QRegExp("^[a-zA-Z0-9_]*$"), this); // Alpha-numeric + underscore + QValidator* validator = new QRegExpValidator(QRegExp("^[a-zA-Z0-9_]*$"), this); // Alpha-numeric + underscore mLineEdit = new LineEdit(this); mLineEdit->setValidator(validator); mLineEdit->setCompleter(nullptr); - auto *dialogLayout = new QVBoxLayout(this); + auto* dialogLayout = new QVBoxLayout(this); dialogLayout->addWidget(label); dialogLayout->addWidget(mLineEdit); dialogLayout->addWidget(mButtonBox); @@ -43,9 +43,7 @@ Launcher::TextInputDialog::TextInputDialog(const QString& title, const QString & connect(mButtonBox, &QDialogButtonBox::rejected, this, &TextInputDialog::reject); } -Launcher::TextInputDialog::~TextInputDialog() -{ -} +Launcher::TextInputDialog::~TextInputDialog() {} int Launcher::TextInputDialog::exec() { @@ -56,15 +54,18 @@ int Launcher::TextInputDialog::exec() void Launcher::TextInputDialog::setOkButtonEnabled(bool enabled) { - QPushButton *okButton = mButtonBox->button(QDialogButtonBox::Ok); + QPushButton* okButton = mButtonBox->button(QDialogButtonBox::Ok); okButton->setEnabled(enabled); QPalette palette; palette.setColor(QPalette::Text, Qt::red); - if (enabled) { + if (enabled) + { mLineEdit->setPalette(QApplication::palette()); - } else { + } + else + { // Existing profile name, make the text red mLineEdit->setPalette(palette); } diff --git a/apps/launcher/utils/textinputdialog.hpp b/apps/launcher/utils/textinputdialog.hpp index ad64cb3e2a..bba79cdee4 100644 --- a/apps/launcher/utils/textinputdialog.hpp +++ b/apps/launcher/utils/textinputdialog.hpp @@ -14,20 +14,17 @@ namespace Launcher Q_OBJECT public: + explicit TextInputDialog(const QString& title, const QString& text, QWidget* parent = nullptr); + ~TextInputDialog() override; - explicit TextInputDialog(const QString& title, const QString &text, QWidget *parent = nullptr); - ~TextInputDialog () override; - - inline LineEdit *lineEdit() { return mLineEdit; } + inline LineEdit* lineEdit() { return mLineEdit; } void setOkButtonEnabled(bool enabled); int exec() override; private: - - QDialogButtonBox *mButtonBox; - LineEdit *mLineEdit; - + QDialogButtonBox* mButtonBox; + LineEdit* mLineEdit; }; } diff --git a/apps/mwiniimporter/importer.cpp b/apps/mwiniimporter/importer.cpp index 43f2b429b1..53d396a0cd 100644 --- a/apps/mwiniimporter/importer.cpp +++ b/apps/mwiniimporter/importer.cpp @@ -1,17 +1,14 @@ #include "importer.hpp" -#include -#include -#include +#include +#include #include #include #include -#include #include -#include - - - +#include +#include +#include namespace sfs = std::filesystem; @@ -19,624 +16,240 @@ MwIniImporter::MwIniImporter() : mVerbose(false) , mEncoding(ToUTF8::WINDOWS_1250) { - const char *map[][2] = - { - { "no-sound", "General:Disable Audio" }, - { 0, 0 } - }; - const char *fallback[] = { + const char* map[][2] = { { "no-sound", "General:Disable Audio" }, { 0, 0 } }; + const char* fallback[] = { // light - "LightAttenuation:UseConstant", - "LightAttenuation:ConstantValue", - "LightAttenuation:UseLinear", - "LightAttenuation:LinearMethod", - "LightAttenuation:LinearValue", - "LightAttenuation:LinearRadiusMult", - "LightAttenuation:UseQuadratic", - "LightAttenuation:QuadraticMethod", - "LightAttenuation:QuadraticValue", - "LightAttenuation:QuadraticRadiusMult", - "LightAttenuation:OutQuadInLin", + "LightAttenuation:UseConstant", "LightAttenuation:ConstantValue", "LightAttenuation:UseLinear", + "LightAttenuation:LinearMethod", "LightAttenuation:LinearValue", "LightAttenuation:LinearRadiusMult", + "LightAttenuation:UseQuadratic", "LightAttenuation:QuadraticMethod", "LightAttenuation:QuadraticValue", + "LightAttenuation:QuadraticRadiusMult", "LightAttenuation:OutQuadInLin", // inventory - "Inventory:DirectionalDiffuseR", - "Inventory:DirectionalDiffuseG", - "Inventory:DirectionalDiffuseB", - "Inventory:DirectionalAmbientR", - "Inventory:DirectionalAmbientG", - "Inventory:DirectionalAmbientB", - "Inventory:DirectionalRotationX", - "Inventory:DirectionalRotationY", - "Inventory:UniformScaling", + "Inventory:DirectionalDiffuseR", "Inventory:DirectionalDiffuseG", "Inventory:DirectionalDiffuseB", + "Inventory:DirectionalAmbientR", "Inventory:DirectionalAmbientG", "Inventory:DirectionalAmbientB", + "Inventory:DirectionalRotationX", "Inventory:DirectionalRotationY", "Inventory:UniformScaling", // map - "Map:Travel Siltstrider Red", - "Map:Travel Siltstrider Green", - "Map:Travel Siltstrider Blue", - "Map:Travel Boat Red", - "Map:Travel Boat Green", - "Map:Travel Boat Blue", - "Map:Travel Magic Red", - "Map:Travel Magic Green", - "Map:Travel Magic Blue", - "Map:Show Travel Lines", + "Map:Travel Siltstrider Red", "Map:Travel Siltstrider Green", "Map:Travel Siltstrider Blue", + "Map:Travel Boat Red", "Map:Travel Boat Green", "Map:Travel Boat Blue", "Map:Travel Magic Red", + "Map:Travel Magic Green", "Map:Travel Magic Blue", "Map:Show Travel Lines", // water - "Water:Map Alpha", - "Water:World Alpha", - "Water:SurfaceTextureSize", - "Water:SurfaceTileCount", - "Water:SurfaceFPS", - "Water:SurfaceTexture", - "Water:SurfaceFrameCount", - "Water:TileTextureDivisor", - "Water:RippleTexture", - "Water:RippleFrameCount", - "Water:RippleLifetime", - "Water:MaxNumberRipples", - "Water:RippleScale", - "Water:RippleRotSpeed", - "Water:RippleAlphas", - "Water:PSWaterReflectTerrain", - "Water:PSWaterReflectUpdate", - "Water:NearWaterRadius", - "Water:NearWaterPoints", - "Water:NearWaterUnderwaterFreq", - "Water:NearWaterUnderwaterVolume", - "Water:NearWaterIndoorTolerance", - "Water:NearWaterOutdoorTolerance", - "Water:NearWaterIndoorID", - "Water:NearWaterOutdoorID", - "Water:UnderwaterSunriseFog", - "Water:UnderwaterDayFog", - "Water:UnderwaterSunsetFog", - "Water:UnderwaterNightFog", - "Water:UnderwaterIndoorFog", - "Water:UnderwaterColor", + "Water:Map Alpha", "Water:World Alpha", "Water:SurfaceTextureSize", "Water:SurfaceTileCount", + "Water:SurfaceFPS", "Water:SurfaceTexture", "Water:SurfaceFrameCount", "Water:TileTextureDivisor", + "Water:RippleTexture", "Water:RippleFrameCount", "Water:RippleLifetime", "Water:MaxNumberRipples", + "Water:RippleScale", "Water:RippleRotSpeed", "Water:RippleAlphas", "Water:PSWaterReflectTerrain", + "Water:PSWaterReflectUpdate", "Water:NearWaterRadius", "Water:NearWaterPoints", "Water:NearWaterUnderwaterFreq", + "Water:NearWaterUnderwaterVolume", "Water:NearWaterIndoorTolerance", "Water:NearWaterOutdoorTolerance", + "Water:NearWaterIndoorID", "Water:NearWaterOutdoorID", "Water:UnderwaterSunriseFog", "Water:UnderwaterDayFog", + "Water:UnderwaterSunsetFog", "Water:UnderwaterNightFog", "Water:UnderwaterIndoorFog", "Water:UnderwaterColor", "Water:UnderwaterColorWeight", // pixelwater - "PixelWater:SurfaceFPS", - "PixelWater:TileCount", - "PixelWater:Resolution", + "PixelWater:SurfaceFPS", "PixelWater:TileCount", "PixelWater:Resolution", // fonts - "Fonts:Font 0", - "Fonts:Font 1", - "Fonts:Font 2", + "Fonts:Font 0", "Fonts:Font 1", "Fonts:Font 2", // UI colors - "FontColor:color_normal", - "FontColor:color_normal_over", - "FontColor:color_normal_pressed", - "FontColor:color_active", - "FontColor:color_active_over", - "FontColor:color_active_pressed", - "FontColor:color_disabled", - "FontColor:color_disabled_over", - "FontColor:color_disabled_pressed", - "FontColor:color_link", - "FontColor:color_link_over", - "FontColor:color_link_pressed", - "FontColor:color_journal_link", - "FontColor:color_journal_link_over", - "FontColor:color_journal_link_pressed", - "FontColor:color_journal_topic", - "FontColor:color_journal_topic_over", - "FontColor:color_journal_topic_pressed", - "FontColor:color_answer", - "FontColor:color_answer_over", - "FontColor:color_answer_pressed", - "FontColor:color_header", - "FontColor:color_notify", - "FontColor:color_big_normal", - "FontColor:color_big_normal_over", - "FontColor:color_big_normal_pressed", - "FontColor:color_big_link", - "FontColor:color_big_link_over", - "FontColor:color_big_link_pressed", - "FontColor:color_big_answer", - "FontColor:color_big_answer_over", - "FontColor:color_big_answer_pressed", - "FontColor:color_big_header", - "FontColor:color_big_notify", - "FontColor:color_background", - "FontColor:color_focus", - "FontColor:color_health", - "FontColor:color_magic", - "FontColor:color_fatigue", - "FontColor:color_misc", - "FontColor:color_weapon_fill", - "FontColor:color_magic_fill", - "FontColor:color_positive", - "FontColor:color_negative", - "FontColor:color_count", + "FontColor:color_normal", "FontColor:color_normal_over", "FontColor:color_normal_pressed", + "FontColor:color_active", "FontColor:color_active_over", "FontColor:color_active_pressed", + "FontColor:color_disabled", "FontColor:color_disabled_over", "FontColor:color_disabled_pressed", + "FontColor:color_link", "FontColor:color_link_over", "FontColor:color_link_pressed", + "FontColor:color_journal_link", "FontColor:color_journal_link_over", "FontColor:color_journal_link_pressed", + "FontColor:color_journal_topic", "FontColor:color_journal_topic_over", "FontColor:color_journal_topic_pressed", + "FontColor:color_answer", "FontColor:color_answer_over", "FontColor:color_answer_pressed", + "FontColor:color_header", "FontColor:color_notify", "FontColor:color_big_normal", + "FontColor:color_big_normal_over", "FontColor:color_big_normal_pressed", "FontColor:color_big_link", + "FontColor:color_big_link_over", "FontColor:color_big_link_pressed", "FontColor:color_big_answer", + "FontColor:color_big_answer_over", "FontColor:color_big_answer_pressed", "FontColor:color_big_header", + "FontColor:color_big_notify", "FontColor:color_background", "FontColor:color_focus", "FontColor:color_health", + "FontColor:color_magic", "FontColor:color_fatigue", "FontColor:color_misc", "FontColor:color_weapon_fill", + "FontColor:color_magic_fill", "FontColor:color_positive", "FontColor:color_negative", "FontColor:color_count", // level up messages - "Level Up:Level2", - "Level Up:Level3", - "Level Up:Level4", - "Level Up:Level5", - "Level Up:Level6", - "Level Up:Level7", - "Level Up:Level8", - "Level Up:Level9", - "Level Up:Level10", - "Level Up:Level11", - "Level Up:Level12", - "Level Up:Level13", - "Level Up:Level14", - "Level Up:Level15", - "Level Up:Level16", - "Level Up:Level17", - "Level Up:Level18", - "Level Up:Level19", - "Level Up:Level20", - "Level Up:Default", + "Level Up:Level2", "Level Up:Level3", "Level Up:Level4", "Level Up:Level5", "Level Up:Level6", + "Level Up:Level7", "Level Up:Level8", "Level Up:Level9", "Level Up:Level10", "Level Up:Level11", + "Level Up:Level12", "Level Up:Level13", "Level Up:Level14", "Level Up:Level15", "Level Up:Level16", + "Level Up:Level17", "Level Up:Level18", "Level Up:Level19", "Level Up:Level20", "Level Up:Default", // character creation multiple choice test - "Question 1:Question", - "Question 1:AnswerOne", - "Question 1:AnswerTwo", - "Question 1:AnswerThree", - "Question 1:Sound", - "Question 2:Question", - "Question 2:AnswerOne", - "Question 2:AnswerTwo", - "Question 2:AnswerThree", - "Question 2:Sound", - "Question 3:Question", - "Question 3:AnswerOne", - "Question 3:AnswerTwo", - "Question 3:AnswerThree", - "Question 3:Sound", - "Question 4:Question", - "Question 4:AnswerOne", - "Question 4:AnswerTwo", - "Question 4:AnswerThree", - "Question 4:Sound", - "Question 5:Question", - "Question 5:AnswerOne", - "Question 5:AnswerTwo", - "Question 5:AnswerThree", - "Question 5:Sound", - "Question 6:Question", - "Question 6:AnswerOne", - "Question 6:AnswerTwo", - "Question 6:AnswerThree", - "Question 6:Sound", - "Question 7:Question", - "Question 7:AnswerOne", - "Question 7:AnswerTwo", - "Question 7:AnswerThree", - "Question 7:Sound", - "Question 8:Question", - "Question 8:AnswerOne", - "Question 8:AnswerTwo", - "Question 8:AnswerThree", - "Question 8:Sound", - "Question 9:Question", - "Question 9:AnswerOne", - "Question 9:AnswerTwo", - "Question 9:AnswerThree", - "Question 9:Sound", - "Question 10:Question", - "Question 10:AnswerOne", - "Question 10:AnswerTwo", - "Question 10:AnswerThree", - "Question 10:Sound", + "Question 1:Question", "Question 1:AnswerOne", "Question 1:AnswerTwo", "Question 1:AnswerThree", + "Question 1:Sound", "Question 2:Question", "Question 2:AnswerOne", "Question 2:AnswerTwo", + "Question 2:AnswerThree", "Question 2:Sound", "Question 3:Question", "Question 3:AnswerOne", + "Question 3:AnswerTwo", "Question 3:AnswerThree", "Question 3:Sound", "Question 4:Question", + "Question 4:AnswerOne", "Question 4:AnswerTwo", "Question 4:AnswerThree", "Question 4:Sound", + "Question 5:Question", "Question 5:AnswerOne", "Question 5:AnswerTwo", "Question 5:AnswerThree", + "Question 5:Sound", "Question 6:Question", "Question 6:AnswerOne", "Question 6:AnswerTwo", + "Question 6:AnswerThree", "Question 6:Sound", "Question 7:Question", "Question 7:AnswerOne", + "Question 7:AnswerTwo", "Question 7:AnswerThree", "Question 7:Sound", "Question 8:Question", + "Question 8:AnswerOne", "Question 8:AnswerTwo", "Question 8:AnswerThree", "Question 8:Sound", + "Question 9:Question", "Question 9:AnswerOne", "Question 9:AnswerTwo", "Question 9:AnswerThree", + "Question 9:Sound", "Question 10:Question", "Question 10:AnswerOne", "Question 10:AnswerTwo", + "Question 10:AnswerThree", "Question 10:Sound", // blood textures and models - "Blood:Model 0", - "Blood:Model 1", - "Blood:Model 2", - "Blood:Texture 0", - "Blood:Texture 1", - "Blood:Texture 2", - "Blood:Texture 3", - "Blood:Texture 4", - "Blood:Texture 5", - "Blood:Texture 6", - "Blood:Texture 7", - "Blood:Texture Name 0", - "Blood:Texture Name 1", - "Blood:Texture Name 2", - "Blood:Texture Name 3", - "Blood:Texture Name 4", - "Blood:Texture Name 5", - "Blood:Texture Name 6", - "Blood:Texture Name 7", + "Blood:Model 0", "Blood:Model 1", "Blood:Model 2", "Blood:Texture 0", "Blood:Texture 1", "Blood:Texture 2", + "Blood:Texture 3", "Blood:Texture 4", "Blood:Texture 5", "Blood:Texture 6", "Blood:Texture 7", + "Blood:Texture Name 0", "Blood:Texture Name 1", "Blood:Texture Name 2", "Blood:Texture Name 3", + "Blood:Texture Name 4", "Blood:Texture Name 5", "Blood:Texture Name 6", "Blood:Texture Name 7", // movies - "Movies:Company Logo", - "Movies:Morrowind Logo", - "Movies:New Game", - "Movies:Loading", - "Movies:Options Menu", + "Movies:Company Logo", "Movies:Morrowind Logo", "Movies:New Game", "Movies:Loading", "Movies:Options Menu", // weather related values - "Weather Thunderstorm:Thunder Sound ID 0", - "Weather Thunderstorm:Thunder Sound ID 1", - "Weather Thunderstorm:Thunder Sound ID 2", - "Weather Thunderstorm:Thunder Sound ID 3", - "Weather:Sunrise Time", - "Weather:Sunset Time", - "Weather:Sunrise Duration", - "Weather:Sunset Duration", + "Weather Thunderstorm:Thunder Sound ID 0", "Weather Thunderstorm:Thunder Sound ID 1", + "Weather Thunderstorm:Thunder Sound ID 2", "Weather Thunderstorm:Thunder Sound ID 3", "Weather:Sunrise Time", + "Weather:Sunset Time", "Weather:Sunrise Duration", "Weather:Sunset Duration", "Weather:Hours Between Weather Changes", // AKA weather update time - "Weather Thunderstorm:Thunder Frequency", - "Weather Thunderstorm:Thunder Threshold", - - "Weather:EnvReduceColor", - "Weather:LerpCloseColor", - "Weather:BumpFadeColor", - "Weather:AlphaReduce", - "Weather:Minimum Time Between Environmental Sounds", - "Weather:Maximum Time Between Environmental Sounds", - "Weather:Sun Glare Fader Max", - "Weather:Sun Glare Fader Angle Max", - "Weather:Sun Glare Fader Color", - "Weather:Timescale Clouds", - "Weather:Precip Gravity", - "Weather:Rain Ripples", - "Weather:Rain Ripple Radius", - "Weather:Rain Ripples Per Drop", - "Weather:Rain Ripple Scale", - "Weather:Rain Ripple Speed", - "Weather:Fog Depth Change Speed", - "Weather:Sky Pre-Sunrise Time", - "Weather:Sky Post-Sunrise Time", - "Weather:Sky Pre-Sunset Time", - "Weather:Sky Post-Sunset Time", - "Weather:Ambient Pre-Sunrise Time", - "Weather:Ambient Post-Sunrise Time", - "Weather:Ambient Pre-Sunset Time", - "Weather:Ambient Post-Sunset Time", - "Weather:Fog Pre-Sunrise Time", - "Weather:Fog Post-Sunrise Time", - "Weather:Fog Pre-Sunset Time", - "Weather:Fog Post-Sunset Time", - "Weather:Sun Pre-Sunrise Time", - "Weather:Sun Post-Sunrise Time", - "Weather:Sun Pre-Sunset Time", - "Weather:Sun Post-Sunset Time", - "Weather:Stars Post-Sunset Start", - "Weather:Stars Pre-Sunrise Finish", - "Weather:Stars Fading Duration", - "Weather:Snow Ripples", - "Weather:Snow Ripple Radius", - "Weather:Snow Ripples Per Flake", - "Weather:Snow Ripple Scale", - "Weather:Snow Ripple Speed", - "Weather:Snow Gravity Scale", - "Weather:Snow High Kill", - "Weather:Snow Low Kill", - - "Weather Clear:Cloud Texture", - "Weather Clear:Clouds Maximum Percent", - "Weather Clear:Transition Delta", - "Weather Clear:Sky Sunrise Color", - "Weather Clear:Sky Day Color", - "Weather Clear:Sky Sunset Color", - "Weather Clear:Sky Night Color", - "Weather Clear:Fog Sunrise Color", - "Weather Clear:Fog Day Color", - "Weather Clear:Fog Sunset Color", - "Weather Clear:Fog Night Color", - "Weather Clear:Ambient Sunrise Color", - "Weather Clear:Ambient Day Color", - "Weather Clear:Ambient Sunset Color", - "Weather Clear:Ambient Night Color", - "Weather Clear:Sun Sunrise Color", - "Weather Clear:Sun Day Color", - "Weather Clear:Sun Sunset Color", - "Weather Clear:Sun Night Color", - "Weather Clear:Sun Disc Sunset Color", - "Weather Clear:Land Fog Day Depth", - "Weather Clear:Land Fog Night Depth", - "Weather Clear:Wind Speed", - "Weather Clear:Cloud Speed", - "Weather Clear:Glare View", - "Weather Clear:Ambient Loop Sound ID", - - "Weather Cloudy:Cloud Texture", - "Weather Cloudy:Clouds Maximum Percent", - "Weather Cloudy:Transition Delta", - "Weather Cloudy:Sky Sunrise Color", - "Weather Cloudy:Sky Day Color", - "Weather Cloudy:Sky Sunset Color", - "Weather Cloudy:Sky Night Color", - "Weather Cloudy:Fog Sunrise Color", - "Weather Cloudy:Fog Day Color", - "Weather Cloudy:Fog Sunset Color", - "Weather Cloudy:Fog Night Color", - "Weather Cloudy:Ambient Sunrise Color", - "Weather Cloudy:Ambient Day Color", - "Weather Cloudy:Ambient Sunset Color", - "Weather Cloudy:Ambient Night Color", - "Weather Cloudy:Sun Sunrise Color", - "Weather Cloudy:Sun Day Color", - "Weather Cloudy:Sun Sunset Color", - "Weather Cloudy:Sun Night Color", - "Weather Cloudy:Sun Disc Sunset Color", - "Weather Cloudy:Land Fog Day Depth", - "Weather Cloudy:Land Fog Night Depth", - "Weather Cloudy:Wind Speed", - "Weather Cloudy:Cloud Speed", - "Weather Cloudy:Glare View", - "Weather Cloudy:Ambient Loop Sound ID", - - "Weather Foggy:Cloud Texture", - "Weather Foggy:Clouds Maximum Percent", - "Weather Foggy:Transition Delta", - "Weather Foggy:Sky Sunrise Color", - "Weather Foggy:Sky Day Color", - "Weather Foggy:Sky Sunset Color", - "Weather Foggy:Sky Night Color", - "Weather Foggy:Fog Sunrise Color", - "Weather Foggy:Fog Day Color", - "Weather Foggy:Fog Sunset Color", - "Weather Foggy:Fog Night Color", - "Weather Foggy:Ambient Sunrise Color", - "Weather Foggy:Ambient Day Color", - "Weather Foggy:Ambient Sunset Color", - "Weather Foggy:Ambient Night Color", - "Weather Foggy:Sun Sunrise Color", - "Weather Foggy:Sun Day Color", - "Weather Foggy:Sun Sunset Color", - "Weather Foggy:Sun Night Color", - "Weather Foggy:Sun Disc Sunset Color", - "Weather Foggy:Land Fog Day Depth", - "Weather Foggy:Land Fog Night Depth", - "Weather Foggy:Wind Speed", - "Weather Foggy:Cloud Speed", - "Weather Foggy:Glare View", - "Weather Foggy:Ambient Loop Sound ID", - - "Weather Thunderstorm:Cloud Texture", - "Weather Thunderstorm:Clouds Maximum Percent", - "Weather Thunderstorm:Transition Delta", - "Weather Thunderstorm:Sky Sunrise Color", - "Weather Thunderstorm:Sky Day Color", - "Weather Thunderstorm:Sky Sunset Color", - "Weather Thunderstorm:Sky Night Color", - "Weather Thunderstorm:Fog Sunrise Color", - "Weather Thunderstorm:Fog Day Color", - "Weather Thunderstorm:Fog Sunset Color", - "Weather Thunderstorm:Fog Night Color", - "Weather Thunderstorm:Ambient Sunrise Color", - "Weather Thunderstorm:Ambient Day Color", - "Weather Thunderstorm:Ambient Sunset Color", - "Weather Thunderstorm:Ambient Night Color", - "Weather Thunderstorm:Sun Sunrise Color", - "Weather Thunderstorm:Sun Day Color", - "Weather Thunderstorm:Sun Sunset Color", - "Weather Thunderstorm:Sun Night Color", - "Weather Thunderstorm:Sun Disc Sunset Color", - "Weather Thunderstorm:Land Fog Day Depth", - "Weather Thunderstorm:Land Fog Night Depth", - "Weather Thunderstorm:Wind Speed", - "Weather Thunderstorm:Cloud Speed", - "Weather Thunderstorm:Glare View", - "Weather Thunderstorm:Rain Loop Sound ID", - "Weather Thunderstorm:Using Precip", - "Weather Thunderstorm:Rain Diameter", - "Weather Thunderstorm:Rain Height Min", - "Weather Thunderstorm:Rain Height Max", - "Weather Thunderstorm:Rain Threshold", - "Weather Thunderstorm:Max Raindrops", - "Weather Thunderstorm:Rain Entrance Speed", - "Weather Thunderstorm:Ambient Loop Sound ID", - "Weather Thunderstorm:Flash Decrement", - - "Weather Rain:Cloud Texture", - "Weather Rain:Clouds Maximum Percent", - "Weather Rain:Transition Delta", - "Weather Rain:Sky Sunrise Color", - "Weather Rain:Sky Day Color", - "Weather Rain:Sky Sunset Color", - "Weather Rain:Sky Night Color", - "Weather Rain:Fog Sunrise Color", - "Weather Rain:Fog Day Color", - "Weather Rain:Fog Sunset Color", - "Weather Rain:Fog Night Color", - "Weather Rain:Ambient Sunrise Color", - "Weather Rain:Ambient Day Color", - "Weather Rain:Ambient Sunset Color", - "Weather Rain:Ambient Night Color", - "Weather Rain:Sun Sunrise Color", - "Weather Rain:Sun Day Color", - "Weather Rain:Sun Sunset Color", - "Weather Rain:Sun Night Color", - "Weather Rain:Sun Disc Sunset Color", - "Weather Rain:Land Fog Day Depth", - "Weather Rain:Land Fog Night Depth", - "Weather Rain:Wind Speed", - "Weather Rain:Cloud Speed", - "Weather Rain:Glare View", - "Weather Rain:Rain Loop Sound ID", - "Weather Rain:Using Precip", - "Weather Rain:Rain Diameter", - "Weather Rain:Rain Height Min", - "Weather Rain:Rain Height Max", - "Weather Rain:Rain Threshold", - "Weather Rain:Rain Entrance Speed", - "Weather Rain:Ambient Loop Sound ID", + "Weather Thunderstorm:Thunder Frequency", "Weather Thunderstorm:Thunder Threshold", + + "Weather:EnvReduceColor", "Weather:LerpCloseColor", "Weather:BumpFadeColor", "Weather:AlphaReduce", + "Weather:Minimum Time Between Environmental Sounds", "Weather:Maximum Time Between Environmental Sounds", + "Weather:Sun Glare Fader Max", "Weather:Sun Glare Fader Angle Max", "Weather:Sun Glare Fader Color", + "Weather:Timescale Clouds", "Weather:Precip Gravity", "Weather:Rain Ripples", "Weather:Rain Ripple Radius", + "Weather:Rain Ripples Per Drop", "Weather:Rain Ripple Scale", "Weather:Rain Ripple Speed", + "Weather:Fog Depth Change Speed", "Weather:Sky Pre-Sunrise Time", "Weather:Sky Post-Sunrise Time", + "Weather:Sky Pre-Sunset Time", "Weather:Sky Post-Sunset Time", "Weather:Ambient Pre-Sunrise Time", + "Weather:Ambient Post-Sunrise Time", "Weather:Ambient Pre-Sunset Time", "Weather:Ambient Post-Sunset Time", + "Weather:Fog Pre-Sunrise Time", "Weather:Fog Post-Sunrise Time", "Weather:Fog Pre-Sunset Time", + "Weather:Fog Post-Sunset Time", "Weather:Sun Pre-Sunrise Time", "Weather:Sun Post-Sunrise Time", + "Weather:Sun Pre-Sunset Time", "Weather:Sun Post-Sunset Time", "Weather:Stars Post-Sunset Start", + "Weather:Stars Pre-Sunrise Finish", "Weather:Stars Fading Duration", "Weather:Snow Ripples", + "Weather:Snow Ripple Radius", "Weather:Snow Ripples Per Flake", "Weather:Snow Ripple Scale", + "Weather:Snow Ripple Speed", "Weather:Snow Gravity Scale", "Weather:Snow High Kill", "Weather:Snow Low Kill", + + "Weather Clear:Cloud Texture", "Weather Clear:Clouds Maximum Percent", "Weather Clear:Transition Delta", + "Weather Clear:Sky Sunrise Color", "Weather Clear:Sky Day Color", "Weather Clear:Sky Sunset Color", + "Weather Clear:Sky Night Color", "Weather Clear:Fog Sunrise Color", "Weather Clear:Fog Day Color", + "Weather Clear:Fog Sunset Color", "Weather Clear:Fog Night Color", "Weather Clear:Ambient Sunrise Color", + "Weather Clear:Ambient Day Color", "Weather Clear:Ambient Sunset Color", "Weather Clear:Ambient Night Color", + "Weather Clear:Sun Sunrise Color", "Weather Clear:Sun Day Color", "Weather Clear:Sun Sunset Color", + "Weather Clear:Sun Night Color", "Weather Clear:Sun Disc Sunset Color", "Weather Clear:Land Fog Day Depth", + "Weather Clear:Land Fog Night Depth", "Weather Clear:Wind Speed", "Weather Clear:Cloud Speed", + "Weather Clear:Glare View", "Weather Clear:Ambient Loop Sound ID", + + "Weather Cloudy:Cloud Texture", "Weather Cloudy:Clouds Maximum Percent", "Weather Cloudy:Transition Delta", + "Weather Cloudy:Sky Sunrise Color", "Weather Cloudy:Sky Day Color", "Weather Cloudy:Sky Sunset Color", + "Weather Cloudy:Sky Night Color", "Weather Cloudy:Fog Sunrise Color", "Weather Cloudy:Fog Day Color", + "Weather Cloudy:Fog Sunset Color", "Weather Cloudy:Fog Night Color", "Weather Cloudy:Ambient Sunrise Color", + "Weather Cloudy:Ambient Day Color", "Weather Cloudy:Ambient Sunset Color", "Weather Cloudy:Ambient Night Color", + "Weather Cloudy:Sun Sunrise Color", "Weather Cloudy:Sun Day Color", "Weather Cloudy:Sun Sunset Color", + "Weather Cloudy:Sun Night Color", "Weather Cloudy:Sun Disc Sunset Color", "Weather Cloudy:Land Fog Day Depth", + "Weather Cloudy:Land Fog Night Depth", "Weather Cloudy:Wind Speed", "Weather Cloudy:Cloud Speed", + "Weather Cloudy:Glare View", "Weather Cloudy:Ambient Loop Sound ID", + + "Weather Foggy:Cloud Texture", "Weather Foggy:Clouds Maximum Percent", "Weather Foggy:Transition Delta", + "Weather Foggy:Sky Sunrise Color", "Weather Foggy:Sky Day Color", "Weather Foggy:Sky Sunset Color", + "Weather Foggy:Sky Night Color", "Weather Foggy:Fog Sunrise Color", "Weather Foggy:Fog Day Color", + "Weather Foggy:Fog Sunset Color", "Weather Foggy:Fog Night Color", "Weather Foggy:Ambient Sunrise Color", + "Weather Foggy:Ambient Day Color", "Weather Foggy:Ambient Sunset Color", "Weather Foggy:Ambient Night Color", + "Weather Foggy:Sun Sunrise Color", "Weather Foggy:Sun Day Color", "Weather Foggy:Sun Sunset Color", + "Weather Foggy:Sun Night Color", "Weather Foggy:Sun Disc Sunset Color", "Weather Foggy:Land Fog Day Depth", + "Weather Foggy:Land Fog Night Depth", "Weather Foggy:Wind Speed", "Weather Foggy:Cloud Speed", + "Weather Foggy:Glare View", "Weather Foggy:Ambient Loop Sound ID", + + "Weather Thunderstorm:Cloud Texture", "Weather Thunderstorm:Clouds Maximum Percent", + "Weather Thunderstorm:Transition Delta", "Weather Thunderstorm:Sky Sunrise Color", + "Weather Thunderstorm:Sky Day Color", "Weather Thunderstorm:Sky Sunset Color", + "Weather Thunderstorm:Sky Night Color", "Weather Thunderstorm:Fog Sunrise Color", + "Weather Thunderstorm:Fog Day Color", "Weather Thunderstorm:Fog Sunset Color", + "Weather Thunderstorm:Fog Night Color", "Weather Thunderstorm:Ambient Sunrise Color", + "Weather Thunderstorm:Ambient Day Color", "Weather Thunderstorm:Ambient Sunset Color", + "Weather Thunderstorm:Ambient Night Color", "Weather Thunderstorm:Sun Sunrise Color", + "Weather Thunderstorm:Sun Day Color", "Weather Thunderstorm:Sun Sunset Color", + "Weather Thunderstorm:Sun Night Color", "Weather Thunderstorm:Sun Disc Sunset Color", + "Weather Thunderstorm:Land Fog Day Depth", "Weather Thunderstorm:Land Fog Night Depth", + "Weather Thunderstorm:Wind Speed", "Weather Thunderstorm:Cloud Speed", "Weather Thunderstorm:Glare View", + "Weather Thunderstorm:Rain Loop Sound ID", "Weather Thunderstorm:Using Precip", + "Weather Thunderstorm:Rain Diameter", "Weather Thunderstorm:Rain Height Min", + "Weather Thunderstorm:Rain Height Max", "Weather Thunderstorm:Rain Threshold", + "Weather Thunderstorm:Max Raindrops", "Weather Thunderstorm:Rain Entrance Speed", + "Weather Thunderstorm:Ambient Loop Sound ID", "Weather Thunderstorm:Flash Decrement", + + "Weather Rain:Cloud Texture", "Weather Rain:Clouds Maximum Percent", "Weather Rain:Transition Delta", + "Weather Rain:Sky Sunrise Color", "Weather Rain:Sky Day Color", "Weather Rain:Sky Sunset Color", + "Weather Rain:Sky Night Color", "Weather Rain:Fog Sunrise Color", "Weather Rain:Fog Day Color", + "Weather Rain:Fog Sunset Color", "Weather Rain:Fog Night Color", "Weather Rain:Ambient Sunrise Color", + "Weather Rain:Ambient Day Color", "Weather Rain:Ambient Sunset Color", "Weather Rain:Ambient Night Color", + "Weather Rain:Sun Sunrise Color", "Weather Rain:Sun Day Color", "Weather Rain:Sun Sunset Color", + "Weather Rain:Sun Night Color", "Weather Rain:Sun Disc Sunset Color", "Weather Rain:Land Fog Day Depth", + "Weather Rain:Land Fog Night Depth", "Weather Rain:Wind Speed", "Weather Rain:Cloud Speed", + "Weather Rain:Glare View", "Weather Rain:Rain Loop Sound ID", "Weather Rain:Using Precip", + "Weather Rain:Rain Diameter", "Weather Rain:Rain Height Min", "Weather Rain:Rain Height Max", + "Weather Rain:Rain Threshold", "Weather Rain:Rain Entrance Speed", "Weather Rain:Ambient Loop Sound ID", "Weather Rain:Max Raindrops", - "Weather Overcast:Cloud Texture", - "Weather Overcast:Clouds Maximum Percent", - "Weather Overcast:Transition Delta", - "Weather Overcast:Sky Sunrise Color", - "Weather Overcast:Sky Day Color", - "Weather Overcast:Sky Sunset Color", - "Weather Overcast:Sky Night Color", - "Weather Overcast:Fog Sunrise Color", - "Weather Overcast:Fog Day Color", - "Weather Overcast:Fog Sunset Color", - "Weather Overcast:Fog Night Color", - "Weather Overcast:Ambient Sunrise Color", - "Weather Overcast:Ambient Day Color", - "Weather Overcast:Ambient Sunset Color", - "Weather Overcast:Ambient Night Color", - "Weather Overcast:Sun Sunrise Color", - "Weather Overcast:Sun Day Color", - "Weather Overcast:Sun Sunset Color", - "Weather Overcast:Sun Night Color", - "Weather Overcast:Sun Disc Sunset Color", - "Weather Overcast:Land Fog Day Depth", - "Weather Overcast:Land Fog Night Depth", - "Weather Overcast:Wind Speed", - "Weather Overcast:Cloud Speed", - "Weather Overcast:Glare View", - "Weather Overcast:Ambient Loop Sound ID", - - "Weather Ashstorm:Cloud Texture", - "Weather Ashstorm:Clouds Maximum Percent", - "Weather Ashstorm:Transition Delta", - "Weather Ashstorm:Sky Sunrise Color", - "Weather Ashstorm:Sky Day Color", - "Weather Ashstorm:Sky Sunset Color", - "Weather Ashstorm:Sky Night Color", - "Weather Ashstorm:Fog Sunrise Color", - "Weather Ashstorm:Fog Day Color", - "Weather Ashstorm:Fog Sunset Color", - "Weather Ashstorm:Fog Night Color", - "Weather Ashstorm:Ambient Sunrise Color", - "Weather Ashstorm:Ambient Day Color", - "Weather Ashstorm:Ambient Sunset Color", - "Weather Ashstorm:Ambient Night Color", - "Weather Ashstorm:Sun Sunrise Color", - "Weather Ashstorm:Sun Day Color", - "Weather Ashstorm:Sun Sunset Color", - "Weather Ashstorm:Sun Night Color", - "Weather Ashstorm:Sun Disc Sunset Color", - "Weather Ashstorm:Land Fog Day Depth", - "Weather Ashstorm:Land Fog Night Depth", - "Weather Ashstorm:Wind Speed", - "Weather Ashstorm:Cloud Speed", - "Weather Ashstorm:Glare View", - "Weather Ashstorm:Ambient Loop Sound ID", + "Weather Overcast:Cloud Texture", "Weather Overcast:Clouds Maximum Percent", + "Weather Overcast:Transition Delta", "Weather Overcast:Sky Sunrise Color", "Weather Overcast:Sky Day Color", + "Weather Overcast:Sky Sunset Color", "Weather Overcast:Sky Night Color", "Weather Overcast:Fog Sunrise Color", + "Weather Overcast:Fog Day Color", "Weather Overcast:Fog Sunset Color", "Weather Overcast:Fog Night Color", + "Weather Overcast:Ambient Sunrise Color", "Weather Overcast:Ambient Day Color", + "Weather Overcast:Ambient Sunset Color", "Weather Overcast:Ambient Night Color", + "Weather Overcast:Sun Sunrise Color", "Weather Overcast:Sun Day Color", "Weather Overcast:Sun Sunset Color", + "Weather Overcast:Sun Night Color", "Weather Overcast:Sun Disc Sunset Color", + "Weather Overcast:Land Fog Day Depth", "Weather Overcast:Land Fog Night Depth", "Weather Overcast:Wind Speed", + "Weather Overcast:Cloud Speed", "Weather Overcast:Glare View", "Weather Overcast:Ambient Loop Sound ID", + + "Weather Ashstorm:Cloud Texture", "Weather Ashstorm:Clouds Maximum Percent", + "Weather Ashstorm:Transition Delta", "Weather Ashstorm:Sky Sunrise Color", "Weather Ashstorm:Sky Day Color", + "Weather Ashstorm:Sky Sunset Color", "Weather Ashstorm:Sky Night Color", "Weather Ashstorm:Fog Sunrise Color", + "Weather Ashstorm:Fog Day Color", "Weather Ashstorm:Fog Sunset Color", "Weather Ashstorm:Fog Night Color", + "Weather Ashstorm:Ambient Sunrise Color", "Weather Ashstorm:Ambient Day Color", + "Weather Ashstorm:Ambient Sunset Color", "Weather Ashstorm:Ambient Night Color", + "Weather Ashstorm:Sun Sunrise Color", "Weather Ashstorm:Sun Day Color", "Weather Ashstorm:Sun Sunset Color", + "Weather Ashstorm:Sun Night Color", "Weather Ashstorm:Sun Disc Sunset Color", + "Weather Ashstorm:Land Fog Day Depth", "Weather Ashstorm:Land Fog Night Depth", "Weather Ashstorm:Wind Speed", + "Weather Ashstorm:Cloud Speed", "Weather Ashstorm:Glare View", "Weather Ashstorm:Ambient Loop Sound ID", "Weather Ashstorm:Storm Threshold", - "Weather Blight:Cloud Texture", - "Weather Blight:Clouds Maximum Percent", - "Weather Blight:Transition Delta", - "Weather Blight:Sky Sunrise Color", - "Weather Blight:Sky Day Color", - "Weather Blight:Sky Sunset Color", - "Weather Blight:Sky Night Color", - "Weather Blight:Fog Sunrise Color", - "Weather Blight:Fog Day Color", - "Weather Blight:Fog Sunset Color", - "Weather Blight:Fog Night Color", - "Weather Blight:Ambient Sunrise Color", - "Weather Blight:Ambient Day Color", - "Weather Blight:Ambient Sunset Color", - "Weather Blight:Ambient Night Color", - "Weather Blight:Sun Sunrise Color", - "Weather Blight:Sun Day Color", - "Weather Blight:Sun Sunset Color", - "Weather Blight:Sun Night Color", - "Weather Blight:Sun Disc Sunset Color", - "Weather Blight:Land Fog Day Depth", - "Weather Blight:Land Fog Night Depth", - "Weather Blight:Wind Speed", - "Weather Blight:Cloud Speed", - "Weather Blight:Glare View", - "Weather Blight:Ambient Loop Sound ID", - "Weather Blight:Storm Threshold", + "Weather Blight:Cloud Texture", "Weather Blight:Clouds Maximum Percent", "Weather Blight:Transition Delta", + "Weather Blight:Sky Sunrise Color", "Weather Blight:Sky Day Color", "Weather Blight:Sky Sunset Color", + "Weather Blight:Sky Night Color", "Weather Blight:Fog Sunrise Color", "Weather Blight:Fog Day Color", + "Weather Blight:Fog Sunset Color", "Weather Blight:Fog Night Color", "Weather Blight:Ambient Sunrise Color", + "Weather Blight:Ambient Day Color", "Weather Blight:Ambient Sunset Color", "Weather Blight:Ambient Night Color", + "Weather Blight:Sun Sunrise Color", "Weather Blight:Sun Day Color", "Weather Blight:Sun Sunset Color", + "Weather Blight:Sun Night Color", "Weather Blight:Sun Disc Sunset Color", "Weather Blight:Land Fog Day Depth", + "Weather Blight:Land Fog Night Depth", "Weather Blight:Wind Speed", "Weather Blight:Cloud Speed", + "Weather Blight:Glare View", "Weather Blight:Ambient Loop Sound ID", "Weather Blight:Storm Threshold", "Weather Blight:Disease Chance", // for Bloodmoon - "Weather Snow:Cloud Texture", - "Weather Snow:Clouds Maximum Percent", - "Weather Snow:Transition Delta", - "Weather Snow:Sky Sunrise Color", - "Weather Snow:Sky Day Color", - "Weather Snow:Sky Sunset Color", - "Weather Snow:Sky Night Color", - "Weather Snow:Fog Sunrise Color", - "Weather Snow:Fog Day Color", - "Weather Snow:Fog Sunset Color", - "Weather Snow:Fog Night Color", - "Weather Snow:Ambient Sunrise Color", - "Weather Snow:Ambient Day Color", - "Weather Snow:Ambient Sunset Color", - "Weather Snow:Ambient Night Color", - "Weather Snow:Sun Sunrise Color", - "Weather Snow:Sun Day Color", - "Weather Snow:Sun Sunset Color", - "Weather Snow:Sun Night Color", - "Weather Snow:Sun Disc Sunset Color", - "Weather Snow:Land Fog Day Depth", - "Weather Snow:Land Fog Night Depth", - "Weather Snow:Wind Speed", - "Weather Snow:Cloud Speed", - "Weather Snow:Glare View", - "Weather Snow:Snow Diameter", - "Weather Snow:Snow Height Min", - "Weather Snow:Snow Height Max", - "Weather Snow:Snow Entrance Speed", - "Weather Snow:Max Snowflakes", - "Weather Snow:Ambient Loop Sound ID", - "Weather Snow:Snow Threshold", + "Weather Snow:Cloud Texture", "Weather Snow:Clouds Maximum Percent", "Weather Snow:Transition Delta", + "Weather Snow:Sky Sunrise Color", "Weather Snow:Sky Day Color", "Weather Snow:Sky Sunset Color", + "Weather Snow:Sky Night Color", "Weather Snow:Fog Sunrise Color", "Weather Snow:Fog Day Color", + "Weather Snow:Fog Sunset Color", "Weather Snow:Fog Night Color", "Weather Snow:Ambient Sunrise Color", + "Weather Snow:Ambient Day Color", "Weather Snow:Ambient Sunset Color", "Weather Snow:Ambient Night Color", + "Weather Snow:Sun Sunrise Color", "Weather Snow:Sun Day Color", "Weather Snow:Sun Sunset Color", + "Weather Snow:Sun Night Color", "Weather Snow:Sun Disc Sunset Color", "Weather Snow:Land Fog Day Depth", + "Weather Snow:Land Fog Night Depth", "Weather Snow:Wind Speed", "Weather Snow:Cloud Speed", + "Weather Snow:Glare View", "Weather Snow:Snow Diameter", "Weather Snow:Snow Height Min", + "Weather Snow:Snow Height Max", "Weather Snow:Snow Entrance Speed", "Weather Snow:Max Snowflakes", + "Weather Snow:Ambient Loop Sound ID", "Weather Snow:Snow Threshold", // for Bloodmoon - "Weather Blizzard:Cloud Texture", - "Weather Blizzard:Clouds Maximum Percent", - "Weather Blizzard:Transition Delta", - "Weather Blizzard:Sky Sunrise Color", - "Weather Blizzard:Sky Day Color", - "Weather Blizzard:Sky Sunset Color", - "Weather Blizzard:Sky Night Color", - "Weather Blizzard:Fog Sunrise Color", - "Weather Blizzard:Fog Day Color", - "Weather Blizzard:Fog Sunset Color", - "Weather Blizzard:Fog Night Color", - "Weather Blizzard:Ambient Sunrise Color", - "Weather Blizzard:Ambient Day Color", - "Weather Blizzard:Ambient Sunset Color", - "Weather Blizzard:Ambient Night Color", - "Weather Blizzard:Sun Sunrise Color", - "Weather Blizzard:Sun Day Color", - "Weather Blizzard:Sun Sunset Color", - "Weather Blizzard:Sun Night Color", - "Weather Blizzard:Sun Disc Sunset Color", - "Weather Blizzard:Land Fog Day Depth", - "Weather Blizzard:Land Fog Night Depth", - "Weather Blizzard:Wind Speed", - "Weather Blizzard:Cloud Speed", - "Weather Blizzard:Glare View", - "Weather Blizzard:Ambient Loop Sound ID", + "Weather Blizzard:Cloud Texture", "Weather Blizzard:Clouds Maximum Percent", + "Weather Blizzard:Transition Delta", "Weather Blizzard:Sky Sunrise Color", "Weather Blizzard:Sky Day Color", + "Weather Blizzard:Sky Sunset Color", "Weather Blizzard:Sky Night Color", "Weather Blizzard:Fog Sunrise Color", + "Weather Blizzard:Fog Day Color", "Weather Blizzard:Fog Sunset Color", "Weather Blizzard:Fog Night Color", + "Weather Blizzard:Ambient Sunrise Color", "Weather Blizzard:Ambient Day Color", + "Weather Blizzard:Ambient Sunset Color", "Weather Blizzard:Ambient Night Color", + "Weather Blizzard:Sun Sunrise Color", "Weather Blizzard:Sun Day Color", "Weather Blizzard:Sun Sunset Color", + "Weather Blizzard:Sun Night Color", "Weather Blizzard:Sun Disc Sunset Color", + "Weather Blizzard:Land Fog Day Depth", "Weather Blizzard:Land Fog Night Depth", "Weather Blizzard:Wind Speed", + "Weather Blizzard:Cloud Speed", "Weather Blizzard:Glare View", "Weather Blizzard:Ambient Loop Sound ID", "Weather Blizzard:Storm Threshold", // moons - "Moons:Secunda Size", - "Moons:Secunda Axis Offset", - "Moons:Secunda Speed", - "Moons:Secunda Daily Increment", - "Moons:Secunda Moon Shadow Early Fade Angle", - "Moons:Secunda Fade Start Angle", - "Moons:Secunda Fade End Angle", - "Moons:Secunda Fade In Start", - "Moons:Secunda Fade In Finish", - "Moons:Secunda Fade Out Start", - "Moons:Secunda Fade Out Finish", - "Moons:Masser Size", - "Moons:Masser Axis Offset", - "Moons:Masser Speed", - "Moons:Masser Daily Increment", - "Moons:Masser Moon Shadow Early Fade Angle", - "Moons:Masser Fade Start Angle", - "Moons:Masser Fade End Angle", - "Moons:Masser Fade In Start", - "Moons:Masser Fade In Finish", - "Moons:Masser Fade Out Start", - "Moons:Masser Fade Out Finish", - "Moons:Script Color", + "Moons:Secunda Size", "Moons:Secunda Axis Offset", "Moons:Secunda Speed", "Moons:Secunda Daily Increment", + "Moons:Secunda Moon Shadow Early Fade Angle", "Moons:Secunda Fade Start Angle", "Moons:Secunda Fade End Angle", + "Moons:Secunda Fade In Start", "Moons:Secunda Fade In Finish", "Moons:Secunda Fade Out Start", + "Moons:Secunda Fade Out Finish", "Moons:Masser Size", "Moons:Masser Axis Offset", "Moons:Masser Speed", + "Moons:Masser Daily Increment", "Moons:Masser Moon Shadow Early Fade Angle", "Moons:Masser Fade Start Angle", + "Moons:Masser Fade End Angle", "Moons:Masser Fade In Start", "Moons:Masser Fade In Finish", + "Moons:Masser Fade Out Start", "Moons:Masser Fade Out Finish", "Moons:Script Color", // werewolf (Bloodmoon) "General:Werewolf FOV", @@ -644,20 +257,24 @@ MwIniImporter::MwIniImporter() 0 }; - for(int i=0; map[i][0]; i++) { + for (int i = 0; map[i][0]; i++) + { mMergeMap.insert(std::make_pair(map[i][0], map[i][1])); } - for(int i=0; fallback[i]; i++) { + for (int i = 0; fallback[i]; i++) + { mMergeFallback.emplace_back(fallback[i]); } } -void MwIniImporter::setVerbose(bool verbose) { +void MwIniImporter::setVerbose(bool verbose) +{ mVerbose = verbose; } -MwIniImporter::multistrmap MwIniImporter::loadIniFile(const std::filesystem::path& filename) const { +MwIniImporter::multistrmap MwIniImporter::loadIniFile(const std::filesystem::path& filename) const +{ std::cout << "load ini file: " << Files::pathToUnicodeString(filename) << std::endl; std::string section(""); @@ -666,43 +283,51 @@ MwIniImporter::multistrmap MwIniImporter::loadIniFile(const std::filesystem::pat ToUTF8::Utf8Encoder encoder(mEncoding); std::string line; - while (std::getline(file, line)) { + while (std::getline(file, line)) + { std::string_view utf8 = encoder.getUtf8(line); // unify Unix-style and Windows file ending - if (!(utf8.empty()) && (utf8[utf8.length()-1]) == '\r') { - utf8 = utf8.substr(0, utf8.length()-1); + if (!(utf8.empty()) && (utf8[utf8.length() - 1]) == '\r') + { + utf8 = utf8.substr(0, utf8.length() - 1); } - if(utf8.empty()) { + if (utf8.empty()) + { continue; } - if(utf8[0] == '[') { + if (utf8[0] == '[') + { int pos = static_cast(utf8.find(']')); - if(pos < 2) { + if (pos < 2) + { std::cout << "Warning: ini file wrongly formatted (" << utf8 << "). Line ignored." << std::endl; continue; } - section = utf8.substr(1, utf8.find(']')-1); + section = utf8.substr(1, utf8.find(']') - 1); continue; } int comment_pos = static_cast(utf8.find(';')); - if(comment_pos > 0) { - utf8 = utf8.substr(0,comment_pos); + if (comment_pos > 0) + { + utf8 = utf8.substr(0, comment_pos); } int pos = static_cast(utf8.find('=')); - if(pos < 1) { + if (pos < 1) + { continue; } std::string key(section + ":" + std::string(utf8.substr(0, pos))); - const std::string_view value(utf8.substr(pos+1)); - if(value.empty()) { + const std::string_view value(utf8.substr(pos + 1)); + if (value.empty()) + { std::cout << "Warning: ignored empty value for key '" << key << "'." << std::endl; continue; } @@ -718,35 +343,41 @@ MwIniImporter::multistrmap MwIniImporter::loadIniFile(const std::filesystem::pat return map; } -MwIniImporter::multistrmap MwIniImporter::loadCfgFile(const std::filesystem::path& filename) { +MwIniImporter::multistrmap MwIniImporter::loadCfgFile(const std::filesystem::path& filename) +{ std::cout << "load cfg file: " << Files::pathToUnicodeString(filename) << std::endl; MwIniImporter::multistrmap map; std::ifstream file(filename); std::string line; - while (std::getline(file, line)) { + while (std::getline(file, line)) + { // we cant say comment by only looking at first char anymore int comment_pos = static_cast(line.find('#')); - if(comment_pos > 0) { - line = line.substr(0,comment_pos); + if (comment_pos > 0) + { + line = line.substr(0, comment_pos); } - if(line.empty()) { + if (line.empty()) + { continue; } int pos = static_cast(line.find('=')); - if(pos < 1) { + if (pos < 1) + { continue; } - std::string key(line.substr(0,pos)); - std::string value(line.substr(pos+1)); + std::string key(line.substr(0, pos)); + std::string value(line.substr(pos + 1)); - if(map.find(key) == map.end()) { - map.insert( std::make_pair (key, std::vector() ) ); + if (map.find(key) == map.end()) + { + map.insert(std::make_pair(key, std::vector())); } map[key].push_back(value); } @@ -754,11 +385,15 @@ MwIniImporter::multistrmap MwIniImporter::loadCfgFile(const std::filesystem::pat return map; } -void MwIniImporter::merge(multistrmap &cfg, const multistrmap &ini) const { +void MwIniImporter::merge(multistrmap& cfg, const multistrmap& ini) const +{ multistrmap::const_iterator iniIt; - for(strmap::const_iterator it=mMergeMap.begin(); it!=mMergeMap.end(); ++it) { - if((iniIt = ini.find(it->second)) != ini.end()) { - for(std::vector::const_iterator vc = iniIt->second.begin(); vc != iniIt->second.end(); ++vc) { + for (strmap::const_iterator it = mMergeMap.begin(); it != mMergeMap.end(); ++it) + { + if ((iniIt = ini.find(it->second)) != ini.end()) + { + for (std::vector::const_iterator vc = iniIt->second.begin(); vc != iniIt->second.end(); ++vc) + { cfg.erase(it->first); insertMultistrmap(cfg, it->first, *vc); } @@ -766,74 +401,82 @@ void MwIniImporter::merge(multistrmap &cfg, const multistrmap &ini) const { } } -void MwIniImporter::mergeFallback(multistrmap &cfg, const multistrmap &ini) const { +void MwIniImporter::mergeFallback(multistrmap& cfg, const multistrmap& ini) const +{ cfg.erase("fallback"); multistrmap::const_iterator iniIt; - for(std::vector::const_iterator it=mMergeFallback.begin(); it!=mMergeFallback.end(); ++it) { - if((iniIt = ini.find(*it)) != ini.end()) { - for(std::vector::const_iterator vc = iniIt->second.begin(); vc != iniIt->second.end(); ++vc) { + for (std::vector::const_iterator it = mMergeFallback.begin(); it != mMergeFallback.end(); ++it) + { + if ((iniIt = ini.find(*it)) != ini.end()) + { + for (std::vector::const_iterator vc = iniIt->second.begin(); vc != iniIt->second.end(); ++vc) + { std::string value(*it); - std::replace( value.begin(), value.end(), ' ', '_' ); - std::replace( value.begin(), value.end(), ':', '_' ); - value.append(",").append(vc->substr(0,vc->length())); + std::replace(value.begin(), value.end(), ' ', '_'); + std::replace(value.begin(), value.end(), ':', '_'); + value.append(",").append(vc->substr(0, vc->length())); insertMultistrmap(cfg, "fallback", value); } } } } -void MwIniImporter::insertMultistrmap(multistrmap &cfg, const std::string& key, const std::string& value) { +void MwIniImporter::insertMultistrmap(multistrmap& cfg, const std::string& key, const std::string& value) +{ const auto it = cfg.find(key); - if(it == cfg.end()) { - cfg.insert(std::make_pair (key, std::vector() )); + if (it == cfg.end()) + { + cfg.insert(std::make_pair(key, std::vector())); } cfg[key].push_back(value); } -void MwIniImporter::importArchives(multistrmap &cfg, const multistrmap &ini) const { +void MwIniImporter::importArchives(multistrmap& cfg, const multistrmap& ini) const +{ std::vector archives; std::string baseArchive("Archives:Archive "); std::string archive; // Search archives listed in ini file auto it = ini.begin(); - for(int i=0; it != ini.end(); i++) { + for (int i = 0; it != ini.end(); i++) + { archive = baseArchive; archive.append(std::to_string(i)); it = ini.find(archive); - if(it == ini.end()) { + if (it == ini.end()) + { break; } - for(std::vector::const_iterator entry = it->second.begin(); entry!=it->second.end(); ++entry) { + for (std::vector::const_iterator entry = it->second.begin(); entry != it->second.end(); ++entry) + { archives.push_back(*entry); } } cfg.erase("fallback-archive"); - cfg.insert( std::make_pair > ("fallback-archive", std::vector())); + cfg.insert(std::make_pair>("fallback-archive", std::vector())); // Add Morrowind.bsa by default, since Vanilla loads this archive even if it // does not appears in the ini file cfg["fallback-archive"].push_back("Morrowind.bsa"); - for(auto iter=archives.begin(); iter!=archives.end(); ++iter) { + for (auto iter = archives.begin(); iter != archives.end(); ++iter) + { cfg["fallback-archive"].push_back(*iter); } } -void MwIniImporter::dependencySortStep(std::string& element, MwIniImporter::dependencyList& source, std::vector& result) +void MwIniImporter::dependencySortStep( + std::string& element, MwIniImporter::dependencyList& source, std::vector& result) { auto iter = std::find_if( - source.begin(), - source.end(), - [&element](std::pair< std::string, std::vector >& sourceElement) - { + source.begin(), source.end(), [&element](std::pair>& sourceElement) { return sourceElement.first == element; - } - ); + }); if (iter != source.end()) { auto foundElement = std::move(*iter); @@ -856,15 +499,15 @@ std::vector MwIniImporter::dependencySort(MwIniImporter::dependency return result; } -std::vector::iterator MwIniImporter::findString(std::vector& source, const std::string& string) +std::vector::iterator MwIniImporter::findString( + std::vector& source, const std::string& string) { - return std::find_if(source.begin(), source.end(), [&string](const std::string& sourceString) - { - return Misc::StringUtils::ciEqual(sourceString, string); - }); + return std::find_if(source.begin(), source.end(), + [&string](const std::string& sourceString) { return Misc::StringUtils::ciEqual(sourceString, string); }); } -void MwIniImporter::addPaths(std::vector& output, std::vector input) { +void MwIniImporter::addPaths(std::vector& output, std::vector input) +{ for (auto& path : input) { if (path.front() == '"') @@ -876,7 +519,8 @@ void MwIniImporter::addPaths(std::vector& output, std::ve } } -void MwIniImporter::importGameFiles(multistrmap &cfg, const multistrmap &ini, const std::filesystem::path& iniFilename) const +void MwIniImporter::importGameFiles( + multistrmap& cfg, const multistrmap& ini, const std::filesystem::path& iniFilename) const { std::vector> contentFiles; std::string baseGameFile("Game Files:GameFile"); @@ -893,24 +537,24 @@ void MwIniImporter::importGameFiles(multistrmap &cfg, const multistrmap &ini, co dataPaths.push_back(iniFilename.parent_path() /= "Data Files"); auto it = ini.begin(); - for (int i=0; it != ini.end(); i++) + for (int i = 0; it != ini.end(); i++) { std::string gameFile = baseGameFile; gameFile.append(std::to_string(i)); it = ini.find(gameFile); - if(it == ini.end()) + if (it == ini.end()) break; - for(std::vector::const_iterator entry = it->second.begin(); entry!=it->second.end(); ++entry) + for (std::vector::const_iterator entry = it->second.begin(); entry != it->second.end(); ++entry) { - std::string filetype(entry->substr(entry->length()-3)); + std::string filetype(entry->substr(entry->length() - 3)); Misc::StringUtils::lowerCaseInPlace(filetype); - if(filetype.compare("esm") == 0 || filetype.compare("esp") == 0) + if (filetype.compare("esm") == 0 || filetype.compare("esp") == 0) { bool found = false; - for (auto & dataPath : dataPaths) + for (auto& dataPath : dataPaths) { std::filesystem::path path = dataPath / *entry; std::time_t time = lastWriteTime(path, defaultTime); @@ -928,7 +572,7 @@ void MwIniImporter::importGameFiles(multistrmap &cfg, const multistrmap &ini, co } cfg.erase("content"); - cfg.insert( std::make_pair("content", std::vector() ) ); + cfg.insert(std::make_pair("content", std::vector())); // sort by timestamp sort(contentFiles.begin(), contentFiles.end()); @@ -952,15 +596,15 @@ void MwIniImporter::importGameFiles(multistrmap &cfg, const multistrmap &ini, co auto sortedFiles = dependencySort(unsortedFiles); // hard-coded dependency Morrowind - Tribunal - Bloodmoon - if(findString(sortedFiles, "Morrowind.esm") != sortedFiles.end()) + if (findString(sortedFiles, "Morrowind.esm") != sortedFiles.end()) { - auto tribunalIter = findString(sortedFiles, "Tribunal.esm"); + auto tribunalIter = findString(sortedFiles, "Tribunal.esm"); auto bloodmoonIter = findString(sortedFiles, "Bloodmoon.esm"); if (bloodmoonIter != sortedFiles.end() && tribunalIter != sortedFiles.end()) { size_t bloodmoonIndex = std::distance(sortedFiles.begin(), bloodmoonIter); - size_t tribunalIndex = std::distance(sortedFiles.begin(), tribunalIter); + size_t tribunalIndex = std::distance(sortedFiles.begin(), tribunalIter); if (bloodmoonIndex < tribunalIndex) tribunalIndex++; sortedFiles.insert(bloodmoonIter, *tribunalIter); @@ -972,18 +616,21 @@ void MwIniImporter::importGameFiles(multistrmap &cfg, const multistrmap &ini, co cfg["content"].push_back(file); } -void MwIniImporter::writeToFile(std::ostream &out, const multistrmap &cfg) { +void MwIniImporter::writeToFile(std::ostream& out, const multistrmap& cfg) +{ - for(multistrmap::const_iterator it=cfg.begin(); it != cfg.end(); ++it) { - for(auto entry=it->second.begin(); entry != it->second.end(); ++entry) { + for (multistrmap::const_iterator it = cfg.begin(); it != cfg.end(); ++it) + { + for (auto entry = it->second.begin(); entry != it->second.end(); ++entry) + { out << (it->first) << "=" << (*entry) << std::endl; } } } -void MwIniImporter::setInputEncoding(const ToUTF8::FromType &encoding) +void MwIniImporter::setInputEncoding(const ToUTF8::FromType& encoding) { - mEncoding = encoding; + mEncoding = encoding; } std::time_t MwIniImporter::lastWriteTime(const std::filesystem::path& filename, std::time_t defaultTime) @@ -992,14 +639,14 @@ std::time_t MwIniImporter::lastWriteTime(const std::filesystem::path& filename, if (std::filesystem::exists(filename)) { std::filesystem::path resolved = std::filesystem::canonical(filename); - writeTime = Misc::to_time_t(std::filesystem::last_write_time (resolved)); + writeTime = Misc::to_time_t(std::filesystem::last_write_time(resolved)); // print timestamp - const int size=1024; + const int size = 1024; char timeStrBuffer[size]; if (std::strftime(timeStrBuffer, size, "%x %X", localtime(&writeTime)) > 0) - std::cout << "content file: " << resolved << " timestamp = (" << writeTime << - ") " << timeStrBuffer << std::endl; + std::cout << "content file: " << resolved << " timestamp = (" << writeTime << ") " << timeStrBuffer + << std::endl; } return writeTime; } diff --git a/apps/mwiniimporter/importer.hpp b/apps/mwiniimporter/importer.hpp index 6009b4ecb1..4c42caf5a3 100644 --- a/apps/mwiniimporter/importer.hpp +++ b/apps/mwiniimporter/importer.hpp @@ -1,40 +1,41 @@ #ifndef MWINIIMPORTER_IMPORTER #define MWINIIMPORTER_IMPORTER 1 -#include -#include -#include #include -#include #include +#include +#include +#include +#include #include -class MwIniImporter { - public: +class MwIniImporter +{ +public: typedef std::map strmap; - typedef std::map > multistrmap; - typedef std::vector< std::pair< std::string, std::vector > > dependencyList; + typedef std::map> multistrmap; + typedef std::vector>> dependencyList; MwIniImporter(); - void setInputEncoding(const ToUTF8::FromType& encoding); - void setVerbose(bool verbose); - multistrmap loadIniFile(const std::filesystem::path& filename) const; - static multistrmap loadCfgFile(const std::filesystem::path& filename); - void merge(multistrmap &cfg, const multistrmap &ini) const; - void mergeFallback(multistrmap &cfg, const multistrmap &ini) const; - void importGameFiles(multistrmap &cfg, const multistrmap &ini, - const std::filesystem::path& iniFilename) const; - void importArchives(multistrmap &cfg, const multistrmap &ini) const; - static void writeToFile(std::ostream &out, const multistrmap &cfg); + void setInputEncoding(const ToUTF8::FromType& encoding); + void setVerbose(bool verbose); + multistrmap loadIniFile(const std::filesystem::path& filename) const; + static multistrmap loadCfgFile(const std::filesystem::path& filename); + void merge(multistrmap& cfg, const multistrmap& ini) const; + void mergeFallback(multistrmap& cfg, const multistrmap& ini) const; + void importGameFiles(multistrmap& cfg, const multistrmap& ini, const std::filesystem::path& iniFilename) const; + void importArchives(multistrmap& cfg, const multistrmap& ini) const; + static void writeToFile(std::ostream& out, const multistrmap& cfg); static std::vector dependencySort(MwIniImporter::dependencyList source); - private: - static void dependencySortStep(std::string& element, MwIniImporter::dependencyList& source, std::vector& result); +private: + static void dependencySortStep( + std::string& element, MwIniImporter::dependencyList& source, std::vector& result); static std::vector::iterator findString(std::vector& source, const std::string& string); - static void insertMultistrmap(multistrmap &cfg, const std::string& key, const std::string& value); + static void insertMultistrmap(multistrmap& cfg, const std::string& key, const std::string& value); static void addPaths(std::vector& output, std::vector input); /// \return file's "last modified time", used in original MW to determine plug-in load order diff --git a/apps/mwiniimporter/main.cpp b/apps/mwiniimporter/main.cpp index d3040aca07..d17d7e747a 100644 --- a/apps/mwiniimporter/main.cpp +++ b/apps/mwiniimporter/main.cpp @@ -1,8 +1,8 @@ #include "importer.hpp" -#include #include #include +#include #include @@ -13,7 +13,8 @@ namespace bpo = boost::program_options; namespace sfs = std::filesystem; #ifndef _WIN32 -int main(int argc, char *argv[]) { +int main(int argc, char* argv[]) +{ #else // Include on Windows only @@ -22,26 +23,26 @@ int main(int argc, char *argv[]) { class utf8argv { public: - - utf8argv(int argc, wchar_t *wargv[]) + utf8argv(int argc, wchar_t* wargv[]) { args.reserve(argc); - argv = new const char *[argc]; + argv = new const char*[argc]; - for (int i = 0; i < argc; ++i) { + for (int i = 0; i < argc; ++i) + { args.push_back(boost::locale::conv::utf_to_utf(wargv[i])); argv[i] = args.back().c_str(); } } ~utf8argv() { delete[] argv; } - char **get() const { return const_cast(argv); } + char** get() const { return const_cast(argv); } private: utf8argv(const utf8argv&); utf8argv& operator=(const utf8argv&); - const char **argv; + const char** argv; std::vector args; }; @@ -52,9 +53,10 @@ private: For boost::filesystem::path::imbue see components/files/windowspath.cpp */ -int wmain(int argc, wchar_t *wargv[]) { +int wmain(int argc, wchar_t* wargv[]) +{ utf8argv converter(argc, wargv); - char **argv = converter.get(); + char** argv = converter.get(); #endif try @@ -70,43 +72,54 @@ int wmain(int argc, wchar_t *wargv[]) { addOption("game-files,g", "import esm and esp files"); addOption("fonts,f", "import bitmap fonts"); addOption("no-archives,A", "disable bsa archives import"); - addOption("encoding,e", bpo::value()-> default_value("win1252"), - "Character encoding used in OpenMW game messages:\n" - "\n\twin1250 - Central and Eastern European such as Polish, Czech, Slovak, Hungarian, Slovene, Bosnian, Croatian, Serbian (Latin script), Romanian and Albanian languages\n" - "\n\twin1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages\n" - "\n\twin1252 - Western European (Latin) alphabet, used by default"); - ; + addOption("encoding,e", bpo::value()->default_value("win1252"), + "Character encoding used in OpenMW game messages:\n" + "\n\twin1250 - Central and Eastern European such as Polish, Czech, Slovak, Hungarian, Slovene, Bosnian, " + "Croatian, Serbian (Latin script), Romanian and Albanian languages\n" + "\n\twin1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages\n" + "\n\twin1252 - Western European (Latin) alphabet, used by default"); + ; p_desc.add("ini", 1).add("cfg", 1); bpo::variables_map vm; - bpo::parsed_options parsed = bpo::command_line_parser(argc, argv) - .options(desc) - .positional(p_desc) - .run(); + bpo::parsed_options parsed = bpo::command_line_parser(argc, argv).options(desc).positional(p_desc).run(); bpo::store(parsed, vm); - if(vm.count("help") || !vm.count("ini") || !vm.count("cfg")) { + if (vm.count("help") || !vm.count("ini") || !vm.count("cfg")) + { std::cout << desc; return 0; } bpo::notify(vm); - std::filesystem::path iniFile(vm["ini"].as().u8string()); // This call to u8string is redundant, but required to build on MSVC 14.26 due to implementation bugs. - std::filesystem::path cfgFile(vm["cfg"].as().u8string()); // This call to u8string is redundant, but required to build on MSVC 14.26 due to implementation bugs. + std::filesystem::path iniFile( + vm["ini"].as().u8string()); // This call to u8string is redundant, but required to + // build on MSVC 14.26 due to implementation bugs. + std::filesystem::path cfgFile( + vm["cfg"].as().u8string()); // This call to u8string is redundant, but required to + // build on MSVC 14.26 due to implementation bugs. // if no output is given, write back to cfg file - std::filesystem::path outputFile = vm["output"].as().u8string(); // This call to u8string is redundant, but required to build on MSVC 14.26 due to implementation bugs. - if(vm["output"].defaulted()) { - outputFile = vm["cfg"].as().u8string(); // This call to u8string is redundant, but required to build on MSVC 14.26 due to implementation bugs. + std::filesystem::path outputFile = vm["output"] + .as() + .u8string(); // This call to u8string is redundant, but required to build + // on MSVC 14.26 due to implementation bugs. + if (vm["output"].defaulted()) + { + outputFile = vm["cfg"] + .as() + .u8string(); // This call to u8string is redundant, but required to build on MSVC 14.26 due + // to implementation bugs. } - if(!std::filesystem::exists(iniFile)) { + if (!std::filesystem::exists(iniFile)) + { std::cerr << "ini file does not exist" << std::endl; return -3; } - if(!std::filesystem::exists(cfgFile)) + if (!std::filesystem::exists(cfgFile)) std::cerr << "cfg file does not exist" << std::endl; MwIniImporter importer; @@ -129,11 +142,13 @@ int wmain(int argc, wchar_t *wargv[]) { importer.merge(cfg, ini); importer.mergeFallback(cfg, ini); - if(vm.count("game-files")) { + if (vm.count("game-files")) + { importer.importGameFiles(cfg, ini, iniFile); } - if(!vm.count("no-archives")) { + if (!vm.count("no-archives")) + { importer.importArchives(cfg, ini); } diff --git a/apps/navmeshtool/main.cpp b/apps/navmeshtool/main.cpp index d67db05529..cf7a3d6a4a 100644 --- a/apps/navmeshtool/main.cpp +++ b/apps/navmeshtool/main.cpp @@ -1,17 +1,21 @@ -#include "worldspacedata.hpp" #include "navmesh.hpp" +#include "worldspacedata.hpp" #include +#include #include #include #include #include +#include #include #include #include #include #include #include +#include +#include #include #include #include @@ -21,10 +25,6 @@ #include #include #include -#include -#include -#include -#include #include @@ -40,7 +40,6 @@ #include #endif - namespace NavMeshTool { namespace @@ -59,59 +58,76 @@ namespace NavMeshTool addOption("version", "print version information and quit"); - addOption("data", bpo::value()->default_value(Files::MaybeQuotedPathContainer(), "data") - ->multitoken()->composing(), "set data directories (later directories have higher priority)"); - - addOption("data-local", bpo::value()->default_value(Files::MaybeQuotedPathContainer::value_type(), ""), - "set local data directory (highest priority)"); - - addOption("fallback-archive", bpo::value()->default_value(StringsVector(), "fallback-archive") - ->multitoken()->composing(), "set fallback BSA archives (later archives have higher priority)"); - - addOption("resources", bpo::value()->default_value(Files::MaybeQuotedPath(), "resources"), - "set resources directory"); - - addOption("content", bpo::value()->default_value(StringsVector(), "") - ->multitoken()->composing(), "content file(s): esm/esp, or omwgame/omwaddon/omwscripts"); - - addOption("fs-strict", bpo::value()->implicit_value(true) - ->default_value(false), "strict file system handling (no case folding)"); - - addOption("encoding", bpo::value()-> - default_value("win1252"), - "Character encoding used in OpenMW game messages:\n" - "\n\twin1250 - Central and Eastern European such as Polish, Czech, Slovak, Hungarian, Slovene, Bosnian, Croatian, Serbian (Latin script), Romanian and Albanian languages\n" - "\n\twin1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages\n" - "\n\twin1252 - Western European (Latin) alphabet, used by default"); - - addOption("fallback", bpo::value()->default_value(Fallback::FallbackMap(), "") - ->multitoken()->composing(), "fallback values"); - - addOption("threads", bpo::value()->default_value(std::max(std::thread::hardware_concurrency() - 1, 1)), - "number of threads for parallel processing"); - - addOption("process-interior-cells", bpo::value()->implicit_value(true) - ->default_value(false), "build navmesh for interior cells"); - - addOption("remove-unused-tiles", bpo::value()->implicit_value(true) - ->default_value(false), "remove tiles from cache that will not be used with current content profile"); - - addOption("write-binary-log", bpo::value()->implicit_value(true) - ->default_value(false), "write progress in binary messages to be consumed by the launcher"); + addOption("data", + bpo::value() + ->default_value(Files::MaybeQuotedPathContainer(), "data") + ->multitoken() + ->composing(), + "set data directories (later directories have higher priority)"); + + addOption("data-local", + bpo::value()->default_value( + Files::MaybeQuotedPathContainer::value_type(), ""), + "set local data directory (highest priority)"); + + addOption("fallback-archive", + bpo::value() + ->default_value(StringsVector(), "fallback-archive") + ->multitoken() + ->composing(), + "set fallback BSA archives (later archives have higher priority)"); + + addOption("resources", + bpo::value()->default_value(Files::MaybeQuotedPath(), "resources"), + "set resources directory"); + + addOption("content", + bpo::value()->default_value(StringsVector(), "")->multitoken()->composing(), + "content file(s): esm/esp, or omwgame/omwaddon/omwscripts"); + + addOption("fs-strict", bpo::value()->implicit_value(true)->default_value(false), + "strict file system handling (no case folding)"); + + addOption("encoding", bpo::value()->default_value("win1252"), + "Character encoding used in OpenMW game messages:\n" + "\n\twin1250 - Central and Eastern European such as Polish, Czech, Slovak, Hungarian, Slovene, " + "Bosnian, Croatian, Serbian (Latin script), Romanian and Albanian languages\n" + "\n\twin1251 - Cyrillic alphabet such as Russian, Bulgarian, Serbian Cyrillic and other languages\n" + "\n\twin1252 - Western European (Latin) alphabet, used by default"); + + addOption("fallback", + bpo::value() + ->default_value(Fallback::FallbackMap(), "") + ->multitoken() + ->composing(), + "fallback values"); + + addOption("threads", + bpo::value()->default_value( + std::max(std::thread::hardware_concurrency() - 1, 1)), + "number of threads for parallel processing"); + + addOption("process-interior-cells", bpo::value()->implicit_value(true)->default_value(false), + "build navmesh for interior cells"); + + addOption("remove-unused-tiles", bpo::value()->implicit_value(true)->default_value(false), + "remove tiles from cache that will not be used with current content profile"); + + addOption("write-binary-log", bpo::value()->implicit_value(true)->default_value(false), + "write progress in binary messages to be consumed by the launcher"); Files::ConfigurationManager::addCommonOptions(result); return result; } - int runNavMeshTool(int argc, char *argv[]) + int runNavMeshTool(int argc, char* argv[]) { Platform::init(); bpo::options_description desc = makeOptionsDescription(); - bpo::parsed_options options = bpo::command_line_parser(argc, argv) - .options(desc).allow_unregistered().run(); + bpo::parsed_options options = bpo::command_line_parser(argc, argv).options(desc).allow_unregistered().run(); bpo::variables_map variables; bpo::store(options, variables); @@ -175,10 +191,13 @@ namespace NavMeshTool Settings::Manager settings; settings.load(config); - const auto agentCollisionShape = DetourNavigator::toCollisionShapeType(Settings::Manager::getInt("actor collision shape type", "Game")); - const osg::Vec3f agentHalfExtents = Settings::Manager::getVector3("default actor pathfind half extents", "Game"); - const DetourNavigator::AgentBounds agentBounds {agentCollisionShape, agentHalfExtents}; - const std::uint64_t maxDbFileSize = static_cast(Settings::Manager::getInt64("max navmeshdb file size", "Navigator")); + const auto agentCollisionShape = DetourNavigator::toCollisionShapeType( + Settings::Manager::getInt("actor collision shape type", "Game")); + const osg::Vec3f agentHalfExtents + = Settings::Manager::getVector3("default actor pathfind half extents", "Game"); + const DetourNavigator::AgentBounds agentBounds{ agentCollisionShape, agentHalfExtents }; + const std::uint64_t maxDbFileSize + = static_cast(Settings::Manager::getInt64("max navmeshdb file size", "Navigator")); const auto dbPath = Files::pathToUnicodeString(config.getUserDataPath() / "navmesh.db"); DetourNavigator::NavMeshDb db(dbPath, maxDbFileSize); @@ -192,7 +211,8 @@ namespace NavMeshTool query.mLoadGameSettings = true; query.mLoadLands = true; query.mLoadStatics = true; - const EsmLoader::EsmData esmData = EsmLoader::loadEsmData(query, contentFiles, fileCollections, readers, &encoder); + const EsmLoader::EsmData esmData + = EsmLoader::loadEsmData(query, contentFiles, fileCollections, readers, &encoder); Resource::ImageManager imageManager(&vfs); Resource::NifFileManager nifFileManager(&vfs); @@ -200,10 +220,11 @@ namespace NavMeshTool Resource::BulletShapeManager bulletShapeManager(&vfs, &sceneManager, &nifFileManager); DetourNavigator::RecastGlobalAllocator::init(); DetourNavigator::Settings navigatorSettings = DetourNavigator::makeSettingsFromSettingsManager(); - navigatorSettings.mRecast.mSwimHeightScale = EsmLoader::getGameSetting(esmData.mGameSettings, "fSwimHeightScale").getFloat(); + navigatorSettings.mRecast.mSwimHeightScale + = EsmLoader::getGameSetting(esmData.mGameSettings, "fSwimHeightScale").getFloat(); - WorldspaceData cellsData = gatherWorldspaceData(navigatorSettings, readers, vfs, bulletShapeManager, - esmData, processInteriorCells, writeBinaryLog); + WorldspaceData cellsData = gatherWorldspaceData( + navigatorSettings, readers, vfs, bulletShapeManager, esmData, processInteriorCells, writeBinaryLog); const Status status = generateAllNavMeshTiles(agentBounds, navigatorSettings, threadsNumber, removeUnusedTiles, writeBinaryLog, cellsData, std::move(db)); @@ -217,10 +238,12 @@ namespace NavMeshTool Log(Debug::Warning) << "Cancelled"; break; case Status::NotEnoughSpace: - Log(Debug::Warning) << "Navmesh generation is cancelled due to running out of disk space or limits " + Log(Debug::Warning) + << "Navmesh generation is cancelled due to running out of disk space or limits " << "for navmesh db. Check disk space at the db location \"" << dbPath << "\". If there is enough space, adjust \"max navmeshdb file size\" setting (see " - << "https://openmw.readthedocs.io/en/latest/reference/modding/settings/navigator.html?highlight=navmesh#max-navmeshdb-file-size)."; + << "https://openmw.readthedocs.io/en/latest/reference/modding/settings/" + "navigator.html?highlight=navmesh#max-navmeshdb-file-size)."; break; } @@ -229,7 +252,7 @@ namespace NavMeshTool } } -int main(int argc, char *argv[]) +int main(int argc, char* argv[]) { return wrapApplication(NavMeshTool::runNavMeshTool, argc, argv, "NavMeshTool"); } diff --git a/apps/navmeshtool/navmesh.cpp b/apps/navmeshtool/navmesh.cpp index 5a14ff3175..384c965466 100644 --- a/apps/navmeshtool/navmesh.cpp +++ b/apps/navmeshtool/navmesh.cpp @@ -2,6 +2,7 @@ #include "worldspacedata.hpp" +#include #include #include #include @@ -14,20 +15,19 @@ #include #include #include +#include #include #include -#include -#include #include #include #include #include -#include -#include #include #include +#include +#include namespace NavMeshTool { @@ -35,50 +35,48 @@ namespace NavMeshTool { using DetourNavigator::AgentBounds; using DetourNavigator::GenerateNavMeshTile; + using DetourNavigator::MeshSource; using DetourNavigator::NavMeshDb; using DetourNavigator::NavMeshTileInfo; using DetourNavigator::PreparedNavMeshData; using DetourNavigator::RecastMeshProvider; - using DetourNavigator::MeshSource; using DetourNavigator::Settings; using DetourNavigator::ShapeId; using DetourNavigator::TileId; using DetourNavigator::TilePosition; - using DetourNavigator::TileVersion; using DetourNavigator::TilesPositionsRange; + using DetourNavigator::TileVersion; using Sqlite3::Transaction; void logGeneratedTiles(std::size_t provided, std::size_t expected) { Log(Debug::Info) << provided << "/" << expected << " (" - << (static_cast(provided) / static_cast(expected) * 100) - << "%) navmesh tiles are generated"; + << (static_cast(provided) / static_cast(expected) * 100) + << "%) navmesh tiles are generated"; } template void serializeToStderr(const T& value) { const std::vector data = serialize(value); - getLockedRawStderr()->write(reinterpret_cast(data.data()), static_cast(data.size())); + getLockedRawStderr()->write( + reinterpret_cast(data.data()), static_cast(data.size())); } void logGeneratedTilesMessage(std::size_t number) { - serializeToStderr(GeneratedTiles {static_cast(number)}); + serializeToStderr(GeneratedTiles{ static_cast(number) }); } struct LogGeneratedTiles { - void operator()(std::size_t provided, std::size_t expected) const - { - logGeneratedTiles(provided, expected); - } + void operator()(std::size_t provided, std::size_t expected) const { logGeneratedTiles(provided, expected); } }; class NavMeshTileConsumer final : public DetourNavigator::NavMeshTileConsumer { public: - std::atomic_size_t mExpected {0}; + std::atomic_size_t mExpected{ 0 }; explicit NavMeshTileConsumer(NavMeshDb&& db, bool removeUnusedTiles, bool writeBinaryLog) : mDb(std::move(db)) @@ -87,7 +85,8 @@ namespace NavMeshTool , mTransaction(mDb.startTransaction(Sqlite3::TransactionMode::Immediate)) , mNextTileId(mDb.getMaxTileId() + 1) , mNextShapeId(mDb.getMaxShapeId() + 1) - {} + { + } std::size_t getProvided() const { return mProvided.load(); } @@ -107,8 +106,8 @@ namespace NavMeshTool return DetourNavigator::resolveMeshSource(mDb, source, mNextShapeId); } - std::optional find(std::string_view worldspace, const TilePosition &tilePosition, - const std::vector &input) override + std::optional find(std::string_view worldspace, const TilePosition& tilePosition, + const std::vector& input) override { std::optional result; std::lock_guard lock(mMutex); @@ -137,35 +136,38 @@ namespace NavMeshTool if (mRemoveUnusedTiles) { std::lock_guard lock(mMutex); - mDeleted += static_cast(mDb.deleteTilesAtExcept(worldspace, tilePosition, TileId {tileId})); + mDeleted += static_cast( + mDb.deleteTilesAtExcept(worldspace, tilePosition, TileId{ tileId })); } report(); } - void insert(std::string_view worldspace, const TilePosition& tilePosition, - std::int64_t version, const std::vector& input, PreparedNavMeshData& data) override + void insert(std::string_view worldspace, const TilePosition& tilePosition, std::int64_t version, + const std::vector& input, PreparedNavMeshData& data) override { { std::lock_guard lock(mMutex); if (mRemoveUnusedTiles) mDeleted += static_cast(mDb.deleteTilesAt(worldspace, tilePosition)); data.mUserId = static_cast(mNextTileId); - mDb.insertTile(mNextTileId, worldspace, tilePosition, TileVersion {version}, input, serialize(data)); + mDb.insertTile( + mNextTileId, worldspace, tilePosition, TileVersion{ version }, input, serialize(data)); ++mNextTileId; } ++mInserted; report(); } - void update(std::string_view worldspace, const TilePosition& tilePosition, - std::int64_t tileId, std::int64_t version, PreparedNavMeshData& data) override + void update(std::string_view worldspace, const TilePosition& tilePosition, std::int64_t tileId, + std::int64_t version, PreparedNavMeshData& data) override { data.mUserId = static_cast(tileId); { std::lock_guard lock(mMutex); if (mRemoveUnusedTiles) - mDeleted += static_cast(mDb.deleteTilesAtExcept(worldspace, tilePosition, TileId {tileId})); - mDb.updateTile(TileId {tileId}, TileVersion {version}, serialize(data)); + mDeleted += static_cast( + mDb.deleteTilesAtExcept(worldspace, tilePosition, TileId{ tileId })); + mDb.updateTile(TileId{ tileId }, TileVersion{ version }, serialize(data)); } ++mUpdated; report(); @@ -225,9 +227,9 @@ namespace NavMeshTool } private: - std::atomic_size_t mProvided {0}; - std::atomic_size_t mInserted {0}; - std::atomic_size_t mUpdated {0}; + std::atomic_size_t mProvided{ 0 }; + std::atomic_size_t mInserted{ 0 }; + std::atomic_size_t mUpdated{ 0 }; std::size_t mDeleted = 0; Status mStatus = Status::Ok; mutable std::mutex mMutex; @@ -252,51 +254,43 @@ namespace NavMeshTool }; } - Status generateAllNavMeshTiles(const AgentBounds& agentBounds, const Settings& settings, - std::size_t threadsNumber, bool removeUnusedTiles, bool writeBinaryLog, WorldspaceData& data, - NavMeshDb&& db) + Status generateAllNavMeshTiles(const AgentBounds& agentBounds, const Settings& settings, std::size_t threadsNumber, + bool removeUnusedTiles, bool writeBinaryLog, WorldspaceData& data, NavMeshDb&& db) { Log(Debug::Info) << "Generating navmesh tiles by " << threadsNumber << " parallel workers..."; SceneUtil::WorkQueue workQueue(threadsNumber); - auto navMeshTileConsumer = std::make_shared(std::move(db), removeUnusedTiles, writeBinaryLog); + auto navMeshTileConsumer + = std::make_shared(std::move(db), removeUnusedTiles, writeBinaryLog); std::size_t tiles = 0; std::mt19937_64 random; for (const std::unique_ptr& input : data.mNavMeshInputs) { - const auto range = DetourNavigator::makeTilesPositionsRange( - Misc::Convert::toOsgXY(input->mAabb.m_min), - Misc::Convert::toOsgXY(input->mAabb.m_max), - settings.mRecast - ); + const auto range = DetourNavigator::makeTilesPositionsRange(Misc::Convert::toOsgXY(input->mAabb.m_min), + Misc::Convert::toOsgXY(input->mAabb.m_max), settings.mRecast); if (removeUnusedTiles) navMeshTileConsumer->removeTilesOutsideRange(input->mWorldspace, range); std::vector worldspaceTiles; - DetourNavigator::getTilesPositions(range, - [&] (const TilePosition& tilePosition) { worldspaceTiles.push_back(tilePosition); }); + DetourNavigator::getTilesPositions( + range, [&](const TilePosition& tilePosition) { worldspaceTiles.push_back(tilePosition); }); tiles += worldspaceTiles.size(); if (writeBinaryLog) - serializeToStderr(ExpectedTiles {static_cast(tiles)}); + serializeToStderr(ExpectedTiles{ static_cast(tiles) }); navMeshTileConsumer->mExpected = tiles; std::shuffle(worldspaceTiles.begin(), worldspaceTiles.end(), random); for (const TilePosition& tilePosition : worldspaceTiles) - workQueue.addWorkItem(new GenerateNavMeshTile( - input->mWorldspace, - tilePosition, - RecastMeshProvider(input->mTileCachedRecastMeshManager), - agentBounds, - settings, - navMeshTileConsumer - )); + workQueue.addWorkItem(new GenerateNavMeshTile(input->mWorldspace, tilePosition, + RecastMeshProvider(input->mTileCachedRecastMeshManager), agentBounds, settings, + navMeshTileConsumer)); } const Status status = navMeshTileConsumer->wait(); @@ -307,10 +301,8 @@ namespace NavMeshTool const auto updated = navMeshTileConsumer->getUpdated(); const auto deleted = navMeshTileConsumer->getDeleted(); - Log(Debug::Info) << "Generated navmesh for " << navMeshTileConsumer->getProvided() << " tiles, " - << inserted << " are inserted, " - << updated << " updated and " - << deleted << " deleted"; + Log(Debug::Info) << "Generated navmesh for " << navMeshTileConsumer->getProvided() << " tiles, " << inserted + << " are inserted, " << updated << " updated and " << deleted << " deleted"; if (inserted + updated + deleted > 0) { diff --git a/apps/navmeshtool/navmesh.hpp b/apps/navmeshtool/navmesh.hpp index f0199ea1c4..817531a207 100644 --- a/apps/navmeshtool/navmesh.hpp +++ b/apps/navmeshtool/navmesh.hpp @@ -23,9 +23,9 @@ namespace NavMeshTool NotEnoughSpace, }; - Status generateAllNavMeshTiles(const DetourNavigator::AgentBounds& agentBounds, const DetourNavigator::Settings& settings, - std::size_t threadsNumber, bool removeUnusedTiles, bool writeBinaryLog, WorldspaceData& cellsData, - DetourNavigator::NavMeshDb&& db); + Status generateAllNavMeshTiles(const DetourNavigator::AgentBounds& agentBounds, + const DetourNavigator::Settings& settings, std::size_t threadsNumber, bool removeUnusedTiles, + bool writeBinaryLog, WorldspaceData& cellsData, DetourNavigator::NavMeshDb&& db); } #endif diff --git a/apps/navmeshtool/worldspacedata.cpp b/apps/navmeshtool/worldspacedata.cpp index e43cfec96c..f66b54dd9b 100644 --- a/apps/navmeshtool/worldspacedata.cpp +++ b/apps/navmeshtool/worldspacedata.cpp @@ -1,27 +1,27 @@ #include "worldspacedata.hpp" #include +#include #include #include #include #include -#include #include +#include #include #include #include #include +#include #include #include #include #include #include +#include #include #include #include -#include -#include -#include #include @@ -56,21 +56,28 @@ namespace NavMeshTool float mScale; ESM::Position mPos; - CellRef(ESM::RecNameInts type, ESM::RefNum refNum, std::string&& refId, float scale, const ESM::Position& pos) - : mType(type), mRefNum(refNum), mRefId(std::move(refId)), mScale(scale), mPos(pos) {} + CellRef( + ESM::RecNameInts type, ESM::RefNum refNum, std::string&& refId, float scale, const ESM::Position& pos) + : mType(type) + , mRefNum(refNum) + , mRefId(std::move(refId)) + , mScale(scale) + , mPos(pos) + { + } }; ESM::RecNameInts getType(const EsmLoader::EsmData& esmData, std::string_view refId) { - const auto it = std::lower_bound(esmData.mRefIdTypes.begin(), esmData.mRefIdTypes.end(), - refId, EsmLoader::LessById {}); + const auto it = std::lower_bound( + esmData.mRefIdTypes.begin(), esmData.mRefIdTypes.end(), refId, EsmLoader::LessById{}); if (it == esmData.mRefIdTypes.end() || it->mId != refId) return {}; return it->mType; } - std::vector loadCellRefs(const ESM::Cell& cell, const EsmLoader::EsmData& esmData, - ESM::ReadersCache& readers) + std::vector loadCellRefs( + const ESM::Cell& cell, const EsmLoader::EsmData& esmData, ESM::ReadersCache& readers) { std::vector> cellRefs; @@ -84,16 +91,17 @@ namespace NavMeshTool { Misc::StringUtils::lowerCaseInPlace(cellRef.mRefID); const ESM::RecNameInts type = getType(esmData, cellRef.mRefID); - if (type == ESM::RecNameInts {}) + if (type == ESM::RecNameInts{}) continue; - cellRefs.emplace_back(deleted, type, cellRef.mRefNum, std::move(cellRef.mRefID), - cellRef.mScale, cellRef.mPos); + cellRefs.emplace_back( + deleted, type, cellRef.mRefNum, std::move(cellRef.mRefID), cellRef.mScale, cellRef.mPos); } } Log(Debug::Debug) << "Loaded " << cellRefs.size() << " cell refs"; - const auto getKey = [] (const EsmLoader::Record& v) -> const ESM::RefNum& { return v.mValue.mRefNum; }; + const auto getKey + = [](const EsmLoader::Record& v) -> const ESM::RefNum& { return v.mValue.mRefNum; }; std::vector result = prepareRecords(cellRefs, getKey); Log(Debug::Debug) << "Prepared " << result.size() << " unique cell refs"; @@ -103,8 +111,7 @@ namespace NavMeshTool template void forEachObject(const ESM::Cell& cell, const EsmLoader::EsmData& esmData, const VFS::Manager& vfs, - Resource::BulletShapeManager& bulletShapeManager, ESM::ReadersCache& readers, - F&& f) + Resource::BulletShapeManager& bulletShapeManager, ESM::ReadersCache& readers, F&& f) { std::vector cellRefs = loadCellRefs(cell, esmData, readers); @@ -119,23 +126,24 @@ namespace NavMeshTool if (cellRef.mType != ESM::REC_STAT) model = Misc::ResourceHelpers::correctActorModelPath(model, &vfs); - osg::ref_ptr shape = [&] - { + osg::ref_ptr shape = [&] { try { return bulletShapeManager.getShape(Misc::ResourceHelpers::correctMeshPath(model, &vfs)); } catch (const std::exception& e) { - Log(Debug::Warning) << "Failed to load cell ref \"" << cellRef.mRefId << "\" model \"" << model << "\": " << e.what(); + Log(Debug::Warning) << "Failed to load cell ref \"" << cellRef.mRefId << "\" model \"" << model + << "\": " << e.what(); return osg::ref_ptr(); } - } (); + }(); if (shape == nullptr || shape->mCollisionShape == nullptr) continue; - osg::ref_ptr shapeInstance(new Resource::BulletShapeInstance(std::move(shape))); + osg::ref_ptr shapeInstance( + new Resource::BulletShapeInstance(std::move(shape))); switch (cellRef.mType) { @@ -158,35 +166,20 @@ namespace NavMeshTool struct LessByXY { - bool operator ()(const ESM::Land& lhs, const ESM::Land& rhs) const - { - return GetXY {}(lhs) < GetXY {}(rhs); - } + bool operator()(const ESM::Land& lhs, const ESM::Land& rhs) const { return GetXY{}(lhs) < GetXY{}(rhs); } - bool operator ()(const ESM::Land& lhs, const osg::Vec2i& rhs) const - { - return GetXY {}(lhs) < rhs; - } + bool operator()(const ESM::Land& lhs, const osg::Vec2i& rhs) const { return GetXY{}(lhs) < rhs; } - bool operator ()(const osg::Vec2i& lhs, const ESM::Land& rhs) const - { - return lhs < GetXY {}(rhs); - } + bool operator()(const osg::Vec2i& lhs, const ESM::Land& rhs) const { return lhs < GetXY{}(rhs); } }; btAABB getAabb(const osg::Vec2i& cellPosition, btScalar minHeight, btScalar maxHeight) { btAABB aabb; - aabb.m_min = btVector3( - static_cast(cellPosition.x() * ESM::Land::REAL_SIZE), - static_cast(cellPosition.y() * ESM::Land::REAL_SIZE), - minHeight - ); - aabb.m_max = btVector3( - static_cast((cellPosition.x() + 1) * ESM::Land::REAL_SIZE), - static_cast((cellPosition.y() + 1) * ESM::Land::REAL_SIZE), - maxHeight - ); + aabb.m_min = btVector3(static_cast(cellPosition.x() * ESM::Land::REAL_SIZE), + static_cast(cellPosition.y() * ESM::Land::REAL_SIZE), minHeight); + aabb.m_max = btVector3(static_cast((cellPosition.x() + 1) * ESM::Land::REAL_SIZE), + static_cast((cellPosition.y() + 1) * ESM::Land::REAL_SIZE), maxHeight); return aabb; } @@ -205,8 +198,9 @@ namespace NavMeshTool std::vector>& landDatas) { if (!land.has_value() || osg::Vec2i(land->mX, land->mY) != cellPosition - || (land->mDataTypes & ESM::Land::DATA_VHGT) == 0) - return {HeightfieldPlane {ESM::Land::DEFAULT_HEIGHT}, ESM::Land::DEFAULT_HEIGHT, ESM::Land::DEFAULT_HEIGHT}; + || (land->mDataTypes & ESM::Land::DATA_VHGT) == 0) + return { HeightfieldPlane{ ESM::Land::DEFAULT_HEIGHT }, ESM::Land::DEFAULT_HEIGHT, + ESM::Land::DEFAULT_HEIGHT }; ESM::Land::LandData& landData = *landDatas.emplace_back(std::make_unique()); land->loadData(ESM::Land::DATA_VHGT, &landData); @@ -216,7 +210,7 @@ namespace NavMeshTool surface.mMinHeight = landData.mMinHeight; surface.mMaxHeight = landData.mMaxHeight; surface.mSize = static_cast(ESM::Land::LAND_SIZE); - return {surface, landData.mMinHeight, landData.mMaxHeight}; + return { surface, landData.mMinHeight, landData.mMaxHeight }; } template @@ -227,7 +221,8 @@ namespace NavMeshTool } } - WorldspaceNavMeshInput::WorldspaceNavMeshInput(std::string worldspace, const DetourNavigator::RecastSettings& settings) + WorldspaceNavMeshInput::WorldspaceNavMeshInput( + std::string worldspace, const DetourNavigator::RecastSettings& settings) : mWorldspace(std::move(worldspace)) , mTileCachedRecastMeshManager(settings) { @@ -247,7 +242,7 @@ namespace NavMeshTool std::size_t objectsCounter = 0; if (writeBinaryLog) - serializeToStderr(ExpectedCells {static_cast(esmData.mCells.size())}); + serializeToStderr(ExpectedCells{ static_cast(esmData.mCells.size()) }); for (std::size_t i = 0; i < esmData.mCells.size(); ++i) { @@ -257,97 +252,100 @@ namespace NavMeshTool if (!exterior && !processInteriorCells) { if (writeBinaryLog) - serializeToStderr(ProcessedCells {static_cast(i + 1)}); + serializeToStderr(ProcessedCells{ static_cast(i + 1) }); Log(Debug::Info) << "Skipped interior" - << " cell (" << (i + 1) << "/" << esmData.mCells.size() << ") \"" << cell.getDescription() << "\""; + << " cell (" << (i + 1) << "/" << esmData.mCells.size() << ") \"" + << cell.getDescription() << "\""; continue; } - Log(Debug::Debug) << "Processing " << (exterior ? "exterior" : "interior") - << " cell (" << (i + 1) << "/" << esmData.mCells.size() << ") \"" << cell.getDescription() << "\""; + Log(Debug::Debug) << "Processing " << (exterior ? "exterior" : "interior") << " cell (" << (i + 1) << "/" + << esmData.mCells.size() << ") \"" << cell.getDescription() << "\""; const osg::Vec2i cellPosition(cell.mData.mX, cell.mData.mY); const std::size_t cellObjectsBegin = data.mObjects.size(); - WorldspaceNavMeshInput& navMeshInput = [&] () -> WorldspaceNavMeshInput& - { + WorldspaceNavMeshInput& navMeshInput = [&]() -> WorldspaceNavMeshInput& { auto it = navMeshInputs.find(cell.mCellId.mWorldspace); if (it == navMeshInputs.end()) { - it = navMeshInputs.emplace(cell.mCellId.mWorldspace, - std::make_unique(cell.mCellId.mWorldspace, settings.mRecast)).first; + it = navMeshInputs + .emplace(cell.mCellId.mWorldspace, + std::make_unique(cell.mCellId.mWorldspace, settings.mRecast)) + .first; it->second->mTileCachedRecastMeshManager.setWorldspace(cell.mCellId.mWorldspace, nullptr); } return *it->second; - } (); + }(); const TileCachedRecastMeshManager::UpdateGuard guard(navMeshInput.mTileCachedRecastMeshManager); if (exterior) { - const auto it = std::lower_bound(esmData.mLands.begin(), esmData.mLands.end(), cellPosition, LessByXY {}); - const auto [heightfieldShape, minHeight, maxHeight] = makeHeightfieldShape( - it == esmData.mLands.end() ? std::optional() : *it, - cellPosition, data.mHeightfields, data.mLandData - ); + const auto it + = std::lower_bound(esmData.mLands.begin(), esmData.mLands.end(), cellPosition, LessByXY{}); + const auto [heightfieldShape, minHeight, maxHeight] + = makeHeightfieldShape(it == esmData.mLands.end() ? std::optional() : *it, cellPosition, + data.mHeightfields, data.mLandData); - mergeOrAssign(getAabb(cellPosition, minHeight, maxHeight), - navMeshInput.mAabb, navMeshInput.mAabbInitialized); + mergeOrAssign( + getAabb(cellPosition, minHeight, maxHeight), navMeshInput.mAabb, navMeshInput.mAabbInitialized); - navMeshInput.mTileCachedRecastMeshManager.addHeightfield(cellPosition, ESM::Land::REAL_SIZE, heightfieldShape, &guard); + navMeshInput.mTileCachedRecastMeshManager.addHeightfield( + cellPosition, ESM::Land::REAL_SIZE, heightfieldShape, &guard); navMeshInput.mTileCachedRecastMeshManager.addWater(cellPosition, ESM::Land::REAL_SIZE, -1, &guard); } else { if ((cell.mData.mFlags & ESM::Cell::HasWater) != 0) - navMeshInput.mTileCachedRecastMeshManager.addWater(cellPosition, std::numeric_limits::max(), cell.mWater, &guard); + navMeshInput.mTileCachedRecastMeshManager.addWater( + cellPosition, std::numeric_limits::max(), cell.mWater, &guard); } - forEachObject(cell, esmData, vfs, bulletShapeManager, readers, - [&] (BulletObject object) - { - if (object.getShapeInstance()->mVisualCollisionType != Resource::VisualCollisionType::None) - return; + forEachObject(cell, esmData, vfs, bulletShapeManager, readers, [&](BulletObject object) { + if (object.getShapeInstance()->mVisualCollisionType != Resource::VisualCollisionType::None) + return; - const btTransform& transform = object.getCollisionObject().getWorldTransform(); - const btAABB aabb = BulletHelpers::getAabb(*object.getCollisionObject().getCollisionShape(), transform); - mergeOrAssign(aabb, navMeshInput.mAabb, navMeshInput.mAabbInitialized); - if (const btCollisionShape* avoid = object.getShapeInstance()->mAvoidCollisionShape.get()) - navMeshInput.mAabb.merge(BulletHelpers::getAabb(*avoid, transform)); + const btTransform& transform = object.getCollisionObject().getWorldTransform(); + const btAABB aabb = BulletHelpers::getAabb(*object.getCollisionObject().getCollisionShape(), transform); + mergeOrAssign(aabb, navMeshInput.mAabb, navMeshInput.mAabbInitialized); + if (const btCollisionShape* avoid = object.getShapeInstance()->mAvoidCollisionShape.get()) + navMeshInput.mAabb.merge(BulletHelpers::getAabb(*avoid, transform)); - const ObjectId objectId(++objectsCounter); - const CollisionShape shape(object.getShapeInstance(), *object.getCollisionObject().getCollisionShape(), object.getObjectTransform()); + const ObjectId objectId(++objectsCounter); + const CollisionShape shape(object.getShapeInstance(), *object.getCollisionObject().getCollisionShape(), + object.getObjectTransform()); - navMeshInput.mTileCachedRecastMeshManager.addObject(objectId, shape, transform, - DetourNavigator::AreaType_ground, &guard); + navMeshInput.mTileCachedRecastMeshManager.addObject( + objectId, shape, transform, DetourNavigator::AreaType_ground, &guard); - if (const btCollisionShape* avoid = object.getShapeInstance()->mAvoidCollisionShape.get()) - { - const CollisionShape avoidShape(object.getShapeInstance(), *avoid, object.getObjectTransform()); - navMeshInput.mTileCachedRecastMeshManager.addObject(objectId, avoidShape, transform, - DetourNavigator::AreaType_null, &guard); - } + if (const btCollisionShape* avoid = object.getShapeInstance()->mAvoidCollisionShape.get()) + { + const CollisionShape avoidShape(object.getShapeInstance(), *avoid, object.getObjectTransform()); + navMeshInput.mTileCachedRecastMeshManager.addObject( + objectId, avoidShape, transform, DetourNavigator::AreaType_null, &guard); + } - data.mObjects.emplace_back(std::move(object)); - }); + data.mObjects.emplace_back(std::move(object)); + }); const auto cellDescription = cell.getDescription(); if (writeBinaryLog) - serializeToStderr(ProcessedCells {static_cast(i + 1)}); + serializeToStderr(ProcessedCells{ static_cast(i + 1) }); - Log(Debug::Info) << "Processed " << (exterior ? "exterior" : "interior") - << " cell (" << (i + 1) << "/" << esmData.mCells.size() << ") " << cellDescription - << " with " << (data.mObjects.size() - cellObjectsBegin) << " objects"; + Log(Debug::Info) << "Processed " << (exterior ? "exterior" : "interior") << " cell (" << (i + 1) << "/" + << esmData.mCells.size() << ") " << cellDescription << " with " + << (data.mObjects.size() - cellObjectsBegin) << " objects"; } data.mNavMeshInputs.reserve(navMeshInputs.size()); std::transform(navMeshInputs.begin(), navMeshInputs.end(), std::back_inserter(data.mNavMeshInputs), - [] (auto& v) { return std::move(v.second); }); + [](auto& v) { return std::move(v.second); }); - Log(Debug::Info) << "Processed " << esmData.mCells.size() << " cells, added " - << data.mObjects.size() << " objects and " << data.mHeightfields.size() << " height fields"; + Log(Debug::Info) << "Processed " << esmData.mCells.size() << " cells, added " << data.mObjects.size() + << " objects and " << data.mHeightfields.size() << " height fields"; return data; } diff --git a/apps/navmeshtool/worldspacedata.hpp b/apps/navmeshtool/worldspacedata.hpp index ca229ad1fa..b6ccce6733 100644 --- a/apps/navmeshtool/worldspacedata.hpp +++ b/apps/navmeshtool/worldspacedata.hpp @@ -43,8 +43,8 @@ namespace DetourNavigator namespace NavMeshTool { - using DetourNavigator::TileCachedRecastMeshManager; using DetourNavigator::ObjectTransform; + using DetourNavigator::TileCachedRecastMeshManager; struct WorldspaceNavMeshInput { @@ -62,12 +62,10 @@ namespace NavMeshTool BulletObject(osg::ref_ptr&& shapeInstance, const ESM::Position& position, float localScaling) : mShapeInstance(std::move(shapeInstance)) - , mObjectTransform {position, localScaling} - , mCollisionObject(BulletHelpers::makeCollisionObject( - mShapeInstance->mCollisionShape.get(), - Misc::Convert::toBullet(position.asVec3()), - Misc::Convert::toBullet(Misc::Convert::makeOsgQuat(position)) - )) + , mObjectTransform{ position, localScaling } + , mCollisionObject(BulletHelpers::makeCollisionObject(mShapeInstance->mCollisionShape.get(), + Misc::Convert::toBullet(position.asVec3()), + Misc::Convert::toBullet(Misc::Convert::makeOsgQuat(position)))) { mShapeInstance->setLocalScaling(btVector3(localScaling, localScaling, localScaling)); } diff --git a/apps/niftest/niftest.cpp b/apps/niftest/niftest.cpp index 8fbd5d6719..632f25f5de 100644 --- a/apps/niftest/niftest.cpp +++ b/apps/niftest/niftest.cpp @@ -1,38 +1,38 @@ -///Program to test .nif files both on the FileSystem and in BSA archives. +/// Program to test .nif files both on the FileSystem and in BSA archives. -#include #include +#include +#include +#include +#include #include #include -#include -#include #include #include -#include -#include +#include #include // Create local aliases for brevity namespace bpo = boost::program_options; -///See if the file has the named extension +/// See if the file has the named extension bool hasExtension(const std::filesystem::path& filename, const std::string& extensionToFind) { const auto extension = Files::pathToUnicodeString(filename.extension()); return Misc::StringUtils::ciEqual(extension, extensionToFind); } -///See if the file has the "nif" extension. -bool isNIF(const std::filesystem::path &filename) +/// See if the file has the "nif" extension. +bool isNIF(const std::filesystem::path& filename) { - return hasExtension(filename,"nif"); + return hasExtension(filename, "nif"); } -///See if the file has the "bsa" extension. -bool isBSA(const std::filesystem::path &filename) +/// See if the file has the "bsa" extension. +bool isBSA(const std::filesystem::path& filename) { - return hasExtension(filename,"bsa"); + return hasExtension(filename, "bsa"); } /// Check all the nif files in a given VFS::Archive @@ -43,21 +43,22 @@ void readVFS(std::unique_ptr&& anArchive, const std::filesystem::p myManager.addArchive(std::move(anArchive)); myManager.buildIndex(); - for(const auto& name : myManager.getRecursiveDirectoryIterator("")) + for (const auto& name : myManager.getRecursiveDirectoryIterator("")) { - try{ - if(isNIF(name)) + try + { + if (isNIF(name)) { - // std::cout << "Decoding: " << name << std::endl; - Nif::NIFFile temp_nif(myManager.get(name),archivePath / name); + // std::cout << "Decoding: " << name << std::endl; + Nif::NIFFile temp_nif(myManager.get(name), archivePath / name); } - else if(isBSA(name)) + else if (isBSA(name)) { - if(!archivePath.empty() && !isBSA(archivePath)) + if (!archivePath.empty() && !isBSA(archivePath)) { -// std::cout << "Reading BSA File: " << name << std::endl; + // std::cout << "Reading BSA File: " << name << std::endl; readVFS(std::make_unique(archivePath / name), archivePath / name); -// std::cout << "Done with BSA File: " << name << std::endl; + // std::cout << "Done with BSA File: " << name << std::endl; } } } @@ -68,7 +69,7 @@ void readVFS(std::unique_ptr&& anArchive, const std::filesystem::p } } -bool parseOptions (int argc, char** argv, std::vector &files) +bool parseOptions(int argc, char** argv, std::vector& files) { bpo::options_description desc(R"(Ensure that OpenMW can use the provided NIF and BSA files @@ -79,34 +80,32 @@ Usages: Allowed options)"); auto addOption = desc.add_options(); addOption("help,h", "print help message."); - addOption("input-file", bpo::value< Files::MaybeQuotedPathContainer >(), "input file"); + addOption("input-file", bpo::value(), "input file"); - //Default option if none provided + // Default option if none provided bpo::positional_options_description p; p.add("input-file", -1); bpo::variables_map variables; try { - bpo::parsed_options valid_opts = bpo::command_line_parser(argc, argv). - options(desc).positional(p).run(); + bpo::parsed_options valid_opts = bpo::command_line_parser(argc, argv).options(desc).positional(p).run(); bpo::store(valid_opts, variables); bpo::notify(variables); - if (variables.count ("help")) + if (variables.count("help")) { std::cout << desc << std::endl; return false; } if (variables.count("input-file")) { - files = variables["input-file"].as< Files::MaybeQuotedPathContainer >(); + files = variables["input-file"].as(); return true; } } - catch(std::exception &e) + catch (std::exception& e) { - std::cout << "ERROR parsing arguments: " << e.what() << "\n\n" - << desc << std::endl; + std::cout << "ERROR parsing arguments: " << e.what() << "\n\n" << desc << std::endl; return false; } @@ -115,42 +114,43 @@ Allowed options)"); return false; } -int main(int argc, char **argv) +int main(int argc, char** argv) { std::vector files; - if(!parseOptions (argc, argv, files)) + if (!parseOptions(argc, argv, files)) return 1; Nif::NIFFile::setLoadUnsupportedFiles(true); -// std::cout << "Reading Files" << std::endl; - for(const auto& path : files) + // std::cout << "Reading Files" << std::endl; + for (const auto& path : files) { try { - if(isNIF(path)) + if (isNIF(path)) { - //std::cout << "Decoding: " << name << std::endl; + // std::cout << "Decoding: " << name << std::endl; Nif::NIFFile temp_nif(Files::openConstrainedFileStream(path), path); - } - else if(isBSA(path)) - { -// std::cout << "Reading BSA File: " << name << std::endl; + } + else if (isBSA(path)) + { + // std::cout << "Reading BSA File: " << name << std::endl; readVFS(std::make_unique(path)); - } - else if(std::filesystem::is_directory(path)) - { -// std::cout << "Reading All Files in: " << name << std::endl; + } + else if (std::filesystem::is_directory(path)) + { + // std::cout << "Reading All Files in: " << name << std::endl; readVFS(std::make_unique(path), path); - } - else - { - std::cerr << "ERROR: \"" << Files::pathToUnicodeString(path) << "\" is not a nif file, bsa file, or directory!" << std::endl; - } + } + else + { + std::cerr << "ERROR: \"" << Files::pathToUnicodeString(path) + << "\" is not a nif file, bsa file, or directory!" << std::endl; + } } catch (std::exception& e) { std::cerr << "ERROR, an exception has occurred: " << e.what() << std::endl; } - } - return 0; + } + return 0; } diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index b5af84d079..729b9e58c6 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -25,12 +25,18 @@ using namespace Fallback; -CS::Editor::Editor (int argc, char **argv) -: mConfigVariables(readConfiguration()), mSettingsState (mCfgMgr), mDocumentManager (mCfgMgr), - mPid(""), mLock(), mMerge (mDocumentManager), - mIpcServerName ("org.openmw.OpenCS"), mServer(nullptr), mClientSocket(nullptr) +CS::Editor::Editor(int argc, char** argv) + : mConfigVariables(readConfiguration()) + , mSettingsState(mCfgMgr) + , mDocumentManager(mCfgMgr) + , mPid("") + , mLock() + , mMerge(mDocumentManager) + , mIpcServerName("org.openmw.OpenCS") + , mServer(nullptr) + , mClientSocket(nullptr) { - std::pair > config = readConfig(); + std::pair> config = readConfig(); mViewManager = new CSVDoc::ViewManager(mDocumentManager); if (argc > 1) @@ -43,44 +49,42 @@ CS::Editor::Editor (int argc, char **argv) mDocumentManager.setFileData(mFsStrict, config.first, config.second); - mNewGame.setLocalData (mLocal); - mFileDialog.setLocalData (mLocal); - mMerge.setLocalData (mLocal); - - connect (&mDocumentManager, &CSMDoc::DocumentManager::documentAdded, - this, &Editor::documentAdded); - connect (&mDocumentManager, &CSMDoc::DocumentManager::documentAboutToBeRemoved, - this, &Editor::documentAboutToBeRemoved); - connect (&mDocumentManager, &CSMDoc::DocumentManager::lastDocumentDeleted, - this, &Editor::lastDocumentDeleted); - - connect (mViewManager, &CSVDoc::ViewManager::newGameRequest, this, &Editor::createGame); - connect (mViewManager, &CSVDoc::ViewManager::newAddonRequest, this, &Editor::createAddon); - connect (mViewManager, &CSVDoc::ViewManager::loadDocumentRequest, this, &Editor::loadDocument); - connect (mViewManager, &CSVDoc::ViewManager::editSettingsRequest, this, &Editor::showSettings); - connect (mViewManager, &CSVDoc::ViewManager::mergeDocument, this, &Editor::mergeDocument); - - connect (&mStartup, &CSVDoc::StartupDialogue::createGame, this, &Editor::createGame); - connect (&mStartup, &CSVDoc::StartupDialogue::createAddon, this, &Editor::createAddon); - connect (&mStartup, &CSVDoc::StartupDialogue::loadDocument, this, &Editor::loadDocument); - connect (&mStartup, &CSVDoc::StartupDialogue::editConfig, this, &Editor::showSettings); - - connect (&mFileDialog, &CSVDoc::FileDialog::signalOpenFiles, - this, [this](const std::filesystem::path &savePath){ this->openFiles(savePath); }); - connect (&mFileDialog, &CSVDoc::FileDialog::signalCreateNewFile, this, &Editor::createNewFile); - connect (&mFileDialog, &CSVDoc::FileDialog::rejected, this, &Editor::cancelFileDialog); - - connect (&mNewGame, &CSVDoc::NewGameDialogue::createRequest, this, &Editor::createNewGame); - connect (&mNewGame, &CSVDoc::NewGameDialogue::cancelCreateGame, this, &Editor::cancelCreateGame); + mNewGame.setLocalData(mLocal); + mFileDialog.setLocalData(mLocal); + mMerge.setLocalData(mLocal); + + connect(&mDocumentManager, &CSMDoc::DocumentManager::documentAdded, this, &Editor::documentAdded); + connect( + &mDocumentManager, &CSMDoc::DocumentManager::documentAboutToBeRemoved, this, &Editor::documentAboutToBeRemoved); + connect(&mDocumentManager, &CSMDoc::DocumentManager::lastDocumentDeleted, this, &Editor::lastDocumentDeleted); + + connect(mViewManager, &CSVDoc::ViewManager::newGameRequest, this, &Editor::createGame); + connect(mViewManager, &CSVDoc::ViewManager::newAddonRequest, this, &Editor::createAddon); + connect(mViewManager, &CSVDoc::ViewManager::loadDocumentRequest, this, &Editor::loadDocument); + connect(mViewManager, &CSVDoc::ViewManager::editSettingsRequest, this, &Editor::showSettings); + connect(mViewManager, &CSVDoc::ViewManager::mergeDocument, this, &Editor::mergeDocument); + + connect(&mStartup, &CSVDoc::StartupDialogue::createGame, this, &Editor::createGame); + connect(&mStartup, &CSVDoc::StartupDialogue::createAddon, this, &Editor::createAddon); + connect(&mStartup, &CSVDoc::StartupDialogue::loadDocument, this, &Editor::loadDocument); + connect(&mStartup, &CSVDoc::StartupDialogue::editConfig, this, &Editor::showSettings); + + connect(&mFileDialog, &CSVDoc::FileDialog::signalOpenFiles, this, + [this](const std::filesystem::path& savePath) { this->openFiles(savePath); }); + connect(&mFileDialog, &CSVDoc::FileDialog::signalCreateNewFile, this, &Editor::createNewFile); + connect(&mFileDialog, &CSVDoc::FileDialog::rejected, this, &Editor::cancelFileDialog); + + connect(&mNewGame, &CSVDoc::NewGameDialogue::createRequest, this, &Editor::createNewGame); + connect(&mNewGame, &CSVDoc::NewGameDialogue::cancelCreateGame, this, &Editor::cancelCreateGame); } -CS::Editor::~Editor () +CS::Editor::~Editor() { delete mViewManager; mPidFile.close(); - if(mServer && std::filesystem::exists(mPid)) + if (mServer && std::filesystem::exists(mPid)) std::filesystem::remove(mPid); } @@ -90,19 +94,32 @@ boost::program_options::variables_map CS::Editor::readConfiguration() boost::program_options::options_description desc("Syntax: openmw-cs \nAllowed options"); auto addOption = desc.add_options(); - addOption("data", boost::program_options::value()->default_value(Files::MaybeQuotedPathContainer(), "data")->multitoken()->composing()); - addOption("data-local", boost::program_options::value()->default_value(Files::MaybeQuotedPathContainer::value_type(), "")); + addOption("data", + boost::program_options::value() + ->default_value(Files::MaybeQuotedPathContainer(), "data") + ->multitoken() + ->composing()); + addOption("data-local", + boost::program_options::value()->default_value( + Files::MaybeQuotedPathContainer::value_type(), "")); addOption("fs-strict", boost::program_options::value()->implicit_value(true)->default_value(false)); addOption("encoding", boost::program_options::value()->default_value("win1252")); - addOption("resources", boost::program_options::value()->default_value(Files::MaybeQuotedPath(), "resources")); - addOption("fallback-archive", boost::program_options::value>()-> - default_value(std::vector(), "fallback-archive")->multitoken()); - addOption("fallback", boost::program_options::value()->default_value(FallbackMap(), "") - ->multitoken()->composing(), "fallback values"); - addOption("script-blacklist", boost::program_options::value>()->default_value(std::vector(), "") - ->multitoken(), "exclude specified script from the verifier (if the use of the blacklist is enabled)"); - addOption("script-blacklist-use", boost::program_options::value()->implicit_value(true) - ->default_value(true), "enable script blacklisting"); + addOption("resources", + boost::program_options::value()->default_value(Files::MaybeQuotedPath(), "resources")); + addOption("fallback-archive", + boost::program_options::value>() + ->default_value(std::vector(), "fallback-archive") + ->multitoken()); + addOption("fallback", + boost::program_options::value()->default_value(FallbackMap(), "")->multitoken()->composing(), + "fallback values"); + addOption("script-blacklist", + boost::program_options::value>() + ->default_value(std::vector(), "") + ->multitoken(), + "exclude specified script from the verifier (if the use of the blacklist is enabled)"); + addOption("script-blacklist-use", boost::program_options::value()->implicit_value(true)->default_value(true), + "enable script blacklisting"); Files::ConfigurationManager::addCommonOptions(desc); boost::program_options::notify(variables); @@ -114,7 +131,7 @@ boost::program_options::variables_map CS::Editor::readConfiguration() return variables; } -std::pair > CS::Editor::readConfig(bool quiet) +std::pair> CS::Editor::readConfig(bool quiet) { boost::program_options::variables_map& variables = mConfigVariables; @@ -122,22 +139,28 @@ std::pair > CS::Editor::readConfi mEncodingName = variables["encoding"].as(); mDocumentManager.setEncoding(ToUTF8::calculateEncoding(mEncodingName)); - mFileDialog.setEncoding (QString::fromUtf8(mEncodingName.c_str())); + mFileDialog.setEncoding(QString::fromUtf8(mEncodingName.c_str())); - mDocumentManager.setResourceDir (mResources = variables["resources"].as().u8string()); // This call to u8string is redundant, but required to build on MSVC 14.26 due to implementation bugs. + mDocumentManager.setResourceDir(mResources = variables["resources"] + .as() + .u8string()); // This call to u8string is redundant, but required + // to build on MSVC 14.26 due to implementation bugs. if (variables["script-blacklist-use"].as()) - mDocumentManager.setBlacklistedScripts ( - variables["script-blacklist"].as>()); + mDocumentManager.setBlacklistedScripts(variables["script-blacklist"].as>()); mFsStrict = variables["fs-strict"].as(); Files::PathContainer dataDirs, dataLocal; - if (!variables["data"].empty()) { + if (!variables["data"].empty()) + { dataDirs = asPathContainer(variables["data"].as()); } - Files::PathContainer::value_type local(variables["data-local"].as().u8string()); // This call to u8string is redundant, but required to build on MSVC 14.26 due to implementation bugs. + Files::PathContainer::value_type local(variables["data-local"] + .as() + .u8string()); // This call to u8string is redundant, but required to + // build on MSVC 14.26 due to implementation bugs. if (!local.empty()) { std::filesystem::create_directories(local); @@ -151,21 +174,23 @@ std::pair > CS::Editor::readConfi else { QMessageBox messageBox; - messageBox.setWindowTitle (tr ("No local data path available")); - messageBox.setIcon (QMessageBox::Critical); - messageBox.setStandardButtons (QMessageBox::Ok); - messageBox.setText(tr("
OpenCS is unable to access the local data directory. This may indicate a faulty configuration or a broken install.")); + messageBox.setWindowTitle(tr("No local data path available")); + messageBox.setIcon(QMessageBox::Critical); + messageBox.setStandardButtons(QMessageBox::Ok); + messageBox.setText( + tr("
OpenCS is unable to access the local data directory. This may indicate a faulty configuration " + "or a broken install.")); messageBox.exec(); - QApplication::exit (1); + QApplication::exit(1); } - dataDirs.insert (dataDirs.end(), dataLocal.begin(), dataLocal.end()); + dataDirs.insert(dataDirs.end(), dataLocal.begin(), dataLocal.end()); - //iterate the data directories and add them to the file dialog for loading + // iterate the data directories and add them to the file dialog for loading mFileDialog.addFiles(dataDirs); - return std::make_pair (dataDirs, variables["fallback-archive"].as>()); + return std::make_pair(dataDirs, variables["fallback-archive"].as>()); } void CS::Editor::createGame() @@ -198,9 +223,9 @@ void CS::Editor::createAddon() mStartup.hide(); mFileDialog.clearFiles(); - readConfig(/*quiet*/true); + readConfig(/*quiet*/ true); - mFileDialog.showDialog (CSVDoc::ContentAction_New); + mFileDialog.showDialog(CSVDoc::ContentAction_New); } void CS::Editor::cancelFileDialog() @@ -222,18 +247,20 @@ void CS::Editor::loadDocument() mStartup.hide(); mFileDialog.clearFiles(); - readConfig(/*quiet*/true); + readConfig(/*quiet*/ true); - mFileDialog.showDialog (CSVDoc::ContentAction_Edit); + mFileDialog.showDialog(CSVDoc::ContentAction_Edit); } -void CS::Editor::openFiles (const std::filesystem::path &savePath, const std::vector &discoveredFiles) +void CS::Editor::openFiles( + const std::filesystem::path& savePath, const std::vector& discoveredFiles) { std::vector files; - if(discoveredFiles.empty()) + if (discoveredFiles.empty()) { - for (const QString &path : mFileDialog.selectedFilePaths()) { + for (const QString& path : mFileDialog.selectedFilePaths()) + { files.emplace_back(Files::pathFromQString(path)); } } @@ -242,40 +269,41 @@ void CS::Editor::openFiles (const std::filesystem::path &savePath, const std::ve files = discoveredFiles; } - mDocumentManager.addDocument (files, savePath, false); + mDocumentManager.addDocument(files, savePath, false); mFileDialog.hide(); } -void CS::Editor::createNewFile (const std::filesystem::path &savePath) +void CS::Editor::createNewFile(const std::filesystem::path& savePath) { std::vector files; - for (const QString &path : mFileDialog.selectedFilePaths()) { + for (const QString& path : mFileDialog.selectedFilePaths()) + { files.emplace_back(Files::pathFromQString(path)); } - files.push_back (savePath); + files.push_back(savePath); - mDocumentManager.addDocument (files, savePath, true); + mDocumentManager.addDocument(files, savePath, true); mFileDialog.hide(); } -void CS::Editor::createNewGame (const std::filesystem::path& file) +void CS::Editor::createNewGame(const std::filesystem::path& file) { std::vector files; - files.push_back (file); + files.push_back(file); - mDocumentManager.addDocument (files, file, true); + mDocumentManager.addDocument(files, file, true); mNewGame.hide(); } void CS::Editor::showStartup() { - if(mStartup.isHidden()) + if (mStartup.isHidden()) mStartup.show(); mStartup.raise(); mStartup.activateWindow(); @@ -286,7 +314,7 @@ void CS::Editor::showSettings() if (mSettings.isHidden()) mSettings.show(); - mSettings.move (QCursor::pos()); + mSettings.move(QCursor::pos()); mSettings.raise(); mSettings.activateWindow(); } @@ -302,7 +330,7 @@ bool CS::Editor::makeIPCServer() mPidFile.open(mPid); mLock = boost::interprocess::file_lock(mPid.c_str()); - if(!mLock.try_lock()) + if (!mLock.try_lock()) { Log(Debug::Error) << "Error: OpenMW-CS is already running."; return false; @@ -316,7 +344,7 @@ bool CS::Editor::makeIPCServer() mServer = new QLocalServer(this); - if(pidExists) + if (pidExists) { // hack to get the temp directory path mServer->listen("dummy"); @@ -325,24 +353,24 @@ bool CS::Editor::makeIPCServer() fullPath.remove(QRegExp("dummy$")); fullPath += mIpcServerName; const auto path = Files::pathFromQString(fullPath); - if(exists(path)) + if (exists(path)) { // TODO: compare pid of the current process with that in the file Log(Debug::Info) << "Detected unclean shutdown."; // delete the stale file - if(remove(path)) + if (remove(path)) Log(Debug::Error) << "Error: can not remove stale connection file."; } } } - catch(const std::exception& e) + catch (const std::exception& e) { Log(Debug::Error) << "Error: " << e.what(); return false; } - if(mServer->listen(mIpcServerName)) + if (mServer->listen(mIpcServerName)) { connect(mServer, &QLocalServer::newConnection, this, &Editor::showStartup); return true; @@ -415,14 +443,14 @@ int CS::Editor::run() return QApplication::exec(); } -void CS::Editor::documentAdded (CSMDoc::Document *document) +void CS::Editor::documentAdded(CSMDoc::Document* document) { - mViewManager->addView (document); + mViewManager->addView(document); } -void CS::Editor::documentAboutToBeRemoved (CSMDoc::Document *document) +void CS::Editor::documentAboutToBeRemoved(CSMDoc::Document* document) { - if (mMerge.getDocument()==document) + if (mMerge.getDocument() == document) mMerge.cancel(); } @@ -431,9 +459,9 @@ void CS::Editor::lastDocumentDeleted() QApplication::quit(); } -void CS::Editor::mergeDocument (CSMDoc::Document *document) +void CS::Editor::mergeDocument(CSMDoc::Document* document) { - mMerge.configure (document); + mMerge.configure(document); mMerge.show(); mMerge.raise(); mMerge.activateWindow(); diff --git a/apps/opencs/editor.hpp b/apps/opencs/editor.hpp index c9dba37193..cc0ed688b8 100644 --- a/apps/opencs/editor.hpp +++ b/apps/opencs/editor.hpp @@ -6,10 +6,10 @@ #include #include -#include -#include #include #include +#include +#include #ifndef Q_MOC_RUN #include @@ -21,10 +21,10 @@ #include "model/prefs/state.hpp" -#include "view/doc/viewmanager.hpp" -#include "view/doc/startup.hpp" #include "view/doc/filedialog.hpp" #include "view/doc/newgame.hpp" +#include "view/doc/startup.hpp" +#include "view/doc/viewmanager.hpp" #include "view/prefs/dialogue.hpp" @@ -39,77 +39,77 @@ namespace CS { class Editor : public QObject { - Q_OBJECT - - Files::ConfigurationManager mCfgMgr; - boost::program_options::variables_map mConfigVariables; - CSMPrefs::State mSettingsState; - CSMDoc::DocumentManager mDocumentManager; - CSVDoc::StartupDialogue mStartup; - CSVDoc::NewGameDialogue mNewGame; - CSVPrefs::Dialogue mSettings; - CSVDoc::FileDialog mFileDialog; - std::filesystem::path mLocal; - std::filesystem::path mResources; - std::filesystem::path mPid; - boost::interprocess::file_lock mLock; - std::ofstream mPidFile; - bool mFsStrict; - CSVTools::Merge mMerge; - CSVDoc::ViewManager* mViewManager; - std::filesystem::path mFileToLoad; - Files::PathContainer mDataDirs; - std::string mEncodingName; - - boost::program_options::variables_map readConfiguration(); - ///< Calls mCfgMgr.readConfiguration; should be used before initialization of mSettingsState as it depends on the configuration. - std::pair > readConfig(bool quiet=false); - ///< \return data paths - - // not implemented - Editor (const Editor&); - Editor& operator= (const Editor&); - - public: - - Editor (int argc, char **argv); - ~Editor (); - - bool makeIPCServer(); - void connectToIPCServer(); - - int run(); - ///< \return error status - - private slots: - - void createGame(); - void createAddon(); - void cancelCreateGame(); - void cancelFileDialog(); - - void loadDocument(); - void openFiles (const std::filesystem::path &path, const std::vector &discoveredFiles = {}); - void createNewFile (const std::filesystem::path& path); - void createNewGame (const std::filesystem::path& file); - - void showStartup(); - - void showSettings(); - - void documentAdded (CSMDoc::Document *document); - - void documentAboutToBeRemoved (CSMDoc::Document *document); - - void lastDocumentDeleted(); - - void mergeDocument (CSMDoc::Document *document); - - private: - - QString mIpcServerName; - QLocalServer *mServer; - QLocalSocket *mClientSocket; + Q_OBJECT + + Files::ConfigurationManager mCfgMgr; + boost::program_options::variables_map mConfigVariables; + CSMPrefs::State mSettingsState; + CSMDoc::DocumentManager mDocumentManager; + CSVDoc::StartupDialogue mStartup; + CSVDoc::NewGameDialogue mNewGame; + CSVPrefs::Dialogue mSettings; + CSVDoc::FileDialog mFileDialog; + std::filesystem::path mLocal; + std::filesystem::path mResources; + std::filesystem::path mPid; + boost::interprocess::file_lock mLock; + std::ofstream mPidFile; + bool mFsStrict; + CSVTools::Merge mMerge; + CSVDoc::ViewManager* mViewManager; + std::filesystem::path mFileToLoad; + Files::PathContainer mDataDirs; + std::string mEncodingName; + + boost::program_options::variables_map readConfiguration(); + ///< Calls mCfgMgr.readConfiguration; should be used before initialization of mSettingsState as it depends on + ///< the configuration. + std::pair> readConfig(bool quiet = false); + ///< \return data paths + + // not implemented + Editor(const Editor&); + Editor& operator=(const Editor&); + + public: + Editor(int argc, char** argv); + ~Editor(); + + bool makeIPCServer(); + void connectToIPCServer(); + + int run(); + ///< \return error status + + private slots: + + void createGame(); + void createAddon(); + void cancelCreateGame(); + void cancelFileDialog(); + + void loadDocument(); + void openFiles( + const std::filesystem::path& path, const std::vector& discoveredFiles = {}); + void createNewFile(const std::filesystem::path& path); + void createNewGame(const std::filesystem::path& file); + + void showStartup(); + + void showSettings(); + + void documentAdded(CSMDoc::Document* document); + + void documentAboutToBeRemoved(CSMDoc::Document* document); + + void lastDocumentDeleted(); + + void mergeDocument(CSMDoc::Document* document); + + private: + QString mIpcServerName; + QLocalServer* mServer; + QLocalSocket* mClientSocket; }; } diff --git a/apps/opencs/main.cpp b/apps/opencs/main.cpp index e46a46a34e..cb843eb5c9 100644 --- a/apps/opencs/main.cpp +++ b/apps/opencs/main.cpp @@ -16,32 +16,33 @@ #include #endif -Q_DECLARE_METATYPE (std::string) +Q_DECLARE_METATYPE(std::string) class Application : public QApplication { - private: - - bool notify (QObject *receiver, QEvent *event) override +private: + bool notify(QObject* receiver, QEvent* event) override + { + try + { + return QApplication::notify(receiver, event); + } + catch (const std::exception& exception) { - try - { - return QApplication::notify (receiver, event); - } - catch (const std::exception& exception) - { - Log(Debug::Error) << "An exception has been caught: " << exception.what(); - } - - return false; + Log(Debug::Error) << "An exception has been caught: " << exception.what(); } - public: + return false; + } - Application (int& argc, char *argv[]) : QApplication (argc, argv) {} +public: + Application(int& argc, char* argv[]) + : QApplication(argc, argv) + { + } }; -int runApplication(int argc, char *argv[]) +int runApplication(int argc, char* argv[]) { Platform::init(); @@ -49,27 +50,27 @@ int runApplication(int argc, char *argv[]) setenv("OSG_GL_TEXTURE_STORAGE", "OFF", 0); #endif - Q_INIT_RESOURCE (resources); + Q_INIT_RESOURCE(resources); - qRegisterMetaType ("std::string"); - qRegisterMetaType ("CSMWorld::UniversalId"); - qRegisterMetaType ("CSMDoc::Message"); + qRegisterMetaType("std::string"); + qRegisterMetaType("CSMWorld::UniversalId"); + qRegisterMetaType("CSMDoc::Message"); - Application application (argc, argv); + Application application(argc, argv); #ifdef Q_OS_MAC QDir dir(QCoreApplication::applicationDirPath()); QDir::setCurrent(dir.absolutePath()); #endif - application.setWindowIcon (QIcon (":./openmw-cs.png")); + application.setWindowIcon(QIcon(":./openmw-cs.png")); CS::Editor editor(argc, argv); #ifdef __linux__ - setlocale(LC_NUMERIC,"C"); + setlocale(LC_NUMERIC, "C"); #endif - if(!editor.makeIPCServer()) + if (!editor.makeIPCServer()) { editor.connectToIPCServer(); return 0; @@ -78,8 +79,7 @@ int runApplication(int argc, char *argv[]) return editor.run(); } - -int main(int argc, char *argv[]) +int main(int argc, char* argv[]) { return wrapApplication(&runApplication, argc, argv, "OpenMW-CS", false); } diff --git a/apps/opencs/model/doc/blacklist.cpp b/apps/opencs/model/doc/blacklist.cpp index cd96618288..174459c3b4 100644 --- a/apps/opencs/model/doc/blacklist.cpp +++ b/apps/opencs/model/doc/blacklist.cpp @@ -4,27 +4,25 @@ #include -bool CSMDoc::Blacklist::isBlacklisted (const CSMWorld::UniversalId& id) const +bool CSMDoc::Blacklist::isBlacklisted(const CSMWorld::UniversalId& id) const { - std::map >::const_iterator iter = - mIds.find (id.getType()); + std::map>::const_iterator iter = mIds.find(id.getType()); - if (iter==mIds.end()) + if (iter == mIds.end()) return false; - return std::binary_search (iter->second.begin(), iter->second.end(), - Misc::StringUtils::lowerCase (id.getId())); + return std::binary_search(iter->second.begin(), iter->second.end(), Misc::StringUtils::lowerCase(id.getId())); } -void CSMDoc::Blacklist::add (CSMWorld::UniversalId::Type type, - const std::vector& ids) +void CSMDoc::Blacklist::add(CSMWorld::UniversalId::Type type, const std::vector& ids) { std::vector& list = mIds[type]; size_t size = list.size(); - list.resize (size+ids.size()); + list.resize(size + ids.size()); - std::transform (ids.begin(), ids.end(), list.begin()+size, [](const std::string& s) { return Misc::StringUtils::lowerCase(s); } ); - std::sort (list.begin(), list.end()); + std::transform(ids.begin(), ids.end(), list.begin() + size, + [](const std::string& s) { return Misc::StringUtils::lowerCase(s); }); + std::sort(list.begin(), list.end()); } diff --git a/apps/opencs/model/doc/blacklist.hpp b/apps/opencs/model/doc/blacklist.hpp index 9bf7f1d86f..e565aa252b 100644 --- a/apps/opencs/model/doc/blacklist.hpp +++ b/apps/opencs/model/doc/blacklist.hpp @@ -2,8 +2,8 @@ #define CSM_DOC_BLACKLIST_H #include -#include #include +#include #include "../world/universalid.hpp" @@ -12,13 +12,12 @@ namespace CSMDoc /// \brief ID blacklist sorted by UniversalId type class Blacklist { - std::map > mIds; - - public: + std::map> mIds; - bool isBlacklisted (const CSMWorld::UniversalId& id) const; + public: + bool isBlacklisted(const CSMWorld::UniversalId& id) const; - void add (CSMWorld::UniversalId::Type type, const std::vector& ids); + void add(CSMWorld::UniversalId::Type type, const std::vector& ids); }; } diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index fc076bcfaa..27cb56e94f 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -3,8 +3,8 @@ #include "state.hpp" #include -#include #include +#include #include #include "../world/defaultgmsts.hpp" @@ -18,142 +18,140 @@ void CSMDoc::Document::addGmsts() { - for (size_t i=0; i < CSMWorld::DefaultGmsts::FloatCount; ++i) + for (size_t i = 0; i < CSMWorld::DefaultGmsts::FloatCount; ++i) { ESM::GameSetting gmst; gmst.mId = CSMWorld::DefaultGmsts::Floats[i]; - gmst.mValue.setType (ESM::VT_Float); + gmst.mValue.setType(ESM::VT_Float); gmst.mRecordFlags = 0; - gmst.mValue.setFloat (CSMWorld::DefaultGmsts::FloatsDefaultValues[i]); - getData().getGmsts().add (gmst); + gmst.mValue.setFloat(CSMWorld::DefaultGmsts::FloatsDefaultValues[i]); + getData().getGmsts().add(gmst); } - for (size_t i=0; i < CSMWorld::DefaultGmsts::IntCount; ++i) + for (size_t i = 0; i < CSMWorld::DefaultGmsts::IntCount; ++i) { ESM::GameSetting gmst; gmst.mId = CSMWorld::DefaultGmsts::Ints[i]; - gmst.mValue.setType (ESM::VT_Int); + gmst.mValue.setType(ESM::VT_Int); gmst.mRecordFlags = 0; - gmst.mValue.setInteger (CSMWorld::DefaultGmsts::IntsDefaultValues[i]); - getData().getGmsts().add (gmst); + gmst.mValue.setInteger(CSMWorld::DefaultGmsts::IntsDefaultValues[i]); + getData().getGmsts().add(gmst); } - for (size_t i=0; i < CSMWorld::DefaultGmsts::StringCount; ++i) + for (size_t i = 0; i < CSMWorld::DefaultGmsts::StringCount; ++i) { ESM::GameSetting gmst; gmst.mId = CSMWorld::DefaultGmsts::Strings[i]; - gmst.mValue.setType (ESM::VT_String); + gmst.mValue.setType(ESM::VT_String); gmst.mRecordFlags = 0; - gmst.mValue.setString (""); - getData().getGmsts().add (gmst); + gmst.mValue.setString(""); + getData().getGmsts().add(gmst); } } void CSMDoc::Document::addOptionalGmsts() { - for (size_t i=0; i < CSMWorld::DefaultGmsts::OptionalFloatCount; ++i) + for (size_t i = 0; i < CSMWorld::DefaultGmsts::OptionalFloatCount; ++i) { ESM::GameSetting gmst; gmst.mId = CSMWorld::DefaultGmsts::OptionalFloats[i]; gmst.blank(); - gmst.mValue.setType (ESM::VT_Float); - addOptionalGmst (gmst); + gmst.mValue.setType(ESM::VT_Float); + addOptionalGmst(gmst); } - for (size_t i=0; i < CSMWorld::DefaultGmsts::OptionalIntCount; ++i) + for (size_t i = 0; i < CSMWorld::DefaultGmsts::OptionalIntCount; ++i) { ESM::GameSetting gmst; gmst.mId = CSMWorld::DefaultGmsts::OptionalInts[i]; gmst.blank(); - gmst.mValue.setType (ESM::VT_Int); - addOptionalGmst (gmst); + gmst.mValue.setType(ESM::VT_Int); + addOptionalGmst(gmst); } - for (size_t i=0; i < CSMWorld::DefaultGmsts::OptionalStringCount; ++i) + for (size_t i = 0; i < CSMWorld::DefaultGmsts::OptionalStringCount; ++i) { ESM::GameSetting gmst; gmst.mId = CSMWorld::DefaultGmsts::OptionalStrings[i]; gmst.blank(); - gmst.mValue.setType (ESM::VT_String); - gmst.mValue.setString (""); - addOptionalGmst (gmst); + gmst.mValue.setType(ESM::VT_String); + gmst.mValue.setString(""); + addOptionalGmst(gmst); } } void CSMDoc::Document::addOptionalGlobals() { - static const char *sGlobals[] = - { + static const char* sGlobals[] = { "DaysPassed", "PCWerewolf", "PCYear", nullptr, }; - for (int i=0; sGlobals[i]; ++i) + for (int i = 0; sGlobals[i]; ++i) { ESM::Global global; global.mId = sGlobals[i]; global.blank(); - global.mValue.setType (ESM::VT_Long); + global.mValue.setType(ESM::VT_Long); - if (i==0) - global.mValue.setInteger (1); // dayspassed starts counting at 1 + if (i == 0) + global.mValue.setInteger(1); // dayspassed starts counting at 1 - addOptionalGlobal (global); + addOptionalGlobal(global); } } void CSMDoc::Document::addOptionalMagicEffects() { - for (int i=ESM::MagicEffect::SummonFabricant; i<=ESM::MagicEffect::SummonCreature05; ++i) + for (int i = ESM::MagicEffect::SummonFabricant; i <= ESM::MagicEffect::SummonCreature05; ++i) { ESM::MagicEffect effect; effect.mIndex = i; - effect.mId = ESM::MagicEffect::indexToId (i); + effect.mId = ESM::MagicEffect::indexToId(i); effect.blank(); - addOptionalMagicEffect (effect); + addOptionalMagicEffect(effect); } } -void CSMDoc::Document::addOptionalGmst (const ESM::GameSetting& gmst) +void CSMDoc::Document::addOptionalGmst(const ESM::GameSetting& gmst) { - if (getData().getGmsts().searchId (gmst.mId)==-1) + if (getData().getGmsts().searchId(gmst.mId) == -1) { auto record = std::make_unique>(); record->mBase = gmst; record->mState = CSMWorld::RecordBase::State_BaseOnly; - getData().getGmsts().appendRecord (std::move(record)); + getData().getGmsts().appendRecord(std::move(record)); } } -void CSMDoc::Document::addOptionalGlobal (const ESM::Global& global) +void CSMDoc::Document::addOptionalGlobal(const ESM::Global& global) { - if (getData().getGlobals().searchId (global.mId)==-1) + if (getData().getGlobals().searchId(global.mId) == -1) { auto record = std::make_unique>(); record->mBase = global; record->mState = CSMWorld::RecordBase::State_BaseOnly; - getData().getGlobals().appendRecord (std::move(record)); + getData().getGlobals().appendRecord(std::move(record)); } } -void CSMDoc::Document::addOptionalMagicEffect (const ESM::MagicEffect& magicEffect) +void CSMDoc::Document::addOptionalMagicEffect(const ESM::MagicEffect& magicEffect) { - if (getData().getMagicEffects().searchId (magicEffect.mId)==-1) + if (getData().getMagicEffects().searchId(magicEffect.mId) == -1) { auto record = std::make_unique>(); record->mBase = magicEffect; record->mState = CSMWorld::RecordBase::State_BaseOnly; - getData().getMagicEffects().appendRecord (std::move(record)); + getData().getMagicEffects().appendRecord(std::move(record)); } } void CSMDoc::Document::createBase() { - static const char *sGlobals[] = - { + static const char* sGlobals[] = { "Day", "DaysPassed", "GameHour", @@ -165,33 +163,32 @@ void CSMDoc::Document::createBase() nullptr, }; - for (int i=0; sGlobals[i]; ++i) + for (int i = 0; sGlobals[i]; ++i) { ESM::Global record; record.mId = sGlobals[i]; record.mRecordFlags = 0; - record.mValue.setType (i==2 ? ESM::VT_Float : ESM::VT_Long); + record.mValue.setType(i == 2 ? ESM::VT_Float : ESM::VT_Long); - if (i==0 || i==1) - record.mValue.setInteger (1); + if (i == 0 || i == 1) + record.mValue.setInteger(1); - getData().getGlobals().add (record); + getData().getGlobals().add(record); } addGmsts(); - for (int i=0; i<27; ++i) + for (int i = 0; i < 27; ++i) { ESM::Skill record; record.mIndex = i; - record.mId = ESM::Skill::indexToId (record.mIndex); + record.mId = ESM::Skill::indexToId(record.mIndex); record.blank(); - getData().getSkills().add (record); + getData().getSkills().add(record); } - static const char *sVoice[] = - { + static const char* sVoice[] = { "Intruder", "Attack", "Hello", @@ -203,18 +200,17 @@ void CSMDoc::Document::createBase() nullptr, }; - for (int i=0; sVoice[i]; ++i) + for (int i = 0; sVoice[i]; ++i) { ESM::Dialogue record; record.mId = sVoice[i]; record.mType = ESM::Dialogue::Voice; record.blank(); - getData().getTopics().add (record); + getData().getTopics().add(record); } - static const char *sGreetings[] = - { + static const char* sGreetings[] = { "Greeting 0", "Greeting 1", "Greeting 2", @@ -228,18 +224,17 @@ void CSMDoc::Document::createBase() nullptr, }; - for (int i=0; sGreetings[i]; ++i) + for (int i = 0; sGreetings[i]; ++i) { ESM::Dialogue record; record.mId = sGreetings[i]; record.mType = ESM::Dialogue::Greeting; record.blank(); - getData().getTopics().add (record); + getData().getTopics().add(record); } - static const char *sPersuasion[] = - { + static const char* sPersuasion[] = { "Intimidate Success", "Intimidate Fail", "Service Refusal", @@ -253,47 +248,50 @@ void CSMDoc::Document::createBase() nullptr, }; - for (int i=0; sPersuasion[i]; ++i) + for (int i = 0; sPersuasion[i]; ++i) { ESM::Dialogue record; record.mId = sPersuasion[i]; record.mType = ESM::Dialogue::Persuasion; record.blank(); - getData().getTopics().add (record); + getData().getTopics().add(record); } - for (int i=0; i files,bool new_, - const std::filesystem::path& savePath, const std::filesystem::path& resDir, - ToUTF8::FromType encoding, const std::vector& blacklistedScripts, - bool fsStrict, const Files::PathContainer& dataPaths, const std::vector& archives) -: mSavePath (savePath), mContentFiles (std::move(files)), mNew (new_), mData (encoding, fsStrict, dataPaths, archives, resDir), - mTools (*this, encoding), - mProjectPath ((configuration.getUserDataPath() / "projects") / - (savePath.filename().u8string() + u8".project")), - mSavingOperation (*this, mProjectPath, encoding), - mSaving (&mSavingOperation), - mResDir(resDir), mRunner (mProjectPath), - mDirty (false), mIdCompletionManager(mData) +CSMDoc::Document::Document(const Files::ConfigurationManager& configuration, std::vector files, + bool new_, const std::filesystem::path& savePath, const std::filesystem::path& resDir, ToUTF8::FromType encoding, + const std::vector& blacklistedScripts, bool fsStrict, const Files::PathContainer& dataPaths, + const std::vector& archives) + : mSavePath(savePath) + , mContentFiles(std::move(files)) + , mNew(new_) + , mData(encoding, fsStrict, dataPaths, archives, resDir) + , mTools(*this, encoding) + , mProjectPath((configuration.getUserDataPath() / "projects") / (savePath.filename().u8string() + u8".project")) + , mSavingOperation(*this, mProjectPath, encoding) + , mSaving(&mSavingOperation) + , mResDir(resDir) + , mRunner(mProjectPath) + , mDirty(false) + , mIdCompletionManager(mData) { if (mContentFiles.empty()) - throw std::runtime_error ("Empty content file sequence"); + throw std::runtime_error("Empty content file sequence"); - if (mNew || !std::filesystem::exists (mProjectPath)) + if (mNew || !std::filesystem::exists(mProjectPath)) { auto filtersPath = configuration.getUserDataPath() / "defaultfilters"; @@ -302,7 +300,7 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, throw std::runtime_error("Can not create project file: " + Files::pathToUnicodeString(mProjectPath)); destination.exceptions(std::ios::failbit | std::ios::badbit); - if (!std::filesystem::exists (filtersPath)) + if (!std::filesystem::exists(filtersPath)) filtersPath = mResDir / "defaultfilters"; std::ifstream source(filtersPath, std::ios::in | std::ios::binary); @@ -315,35 +313,32 @@ CSMDoc::Document::Document (const Files::ConfigurationManager& configuration, if (mNew) { - if (mContentFiles.size()==1) + if (mContentFiles.size() == 1) createBase(); } - mBlacklist.add (CSMWorld::UniversalId::Type_Script, blacklistedScripts); + mBlacklist.add(CSMWorld::UniversalId::Type_Script, blacklistedScripts); addOptionalGmsts(); addOptionalGlobals(); addOptionalMagicEffects(); - connect (&mUndoStack, &QUndoStack::cleanChanged, this, &Document::modificationStateChanged); + connect(&mUndoStack, &QUndoStack::cleanChanged, this, &Document::modificationStateChanged); - connect (&mTools, &CSMTools::Tools::progress, this, qOverload(&Document::progress)); - connect (&mTools, &CSMTools::Tools::done, this, &Document::operationDone); - connect (&mTools, &CSMTools::Tools::done, this, &Document::operationDone2); - connect (&mTools, &CSMTools::Tools::mergeDone, this, &Document::mergeDone); + connect(&mTools, &CSMTools::Tools::progress, this, qOverload(&Document::progress)); + connect(&mTools, &CSMTools::Tools::done, this, &Document::operationDone); + connect(&mTools, &CSMTools::Tools::done, this, &Document::operationDone2); + connect(&mTools, &CSMTools::Tools::mergeDone, this, &Document::mergeDone); - connect (&mSaving, &OperationHolder::progress, - this, qOverload(&Document::progress)); - connect (&mSaving, &OperationHolder::done, this, &Document::operationDone2); + connect(&mSaving, &OperationHolder::progress, this, qOverload(&Document::progress)); + connect(&mSaving, &OperationHolder::done, this, &Document::operationDone2); - connect (&mSaving, &OperationHolder::reportMessage, this, &Document::reportMessage); + connect(&mSaving, &OperationHolder::reportMessage, this, &Document::reportMessage); - connect (&mRunner, &Runner::runStateChanged, this, &Document::runStateChanged); + connect(&mRunner, &Runner::runStateChanged, this, &Document::runStateChanged); } -CSMDoc::Document::~Document() -{ -} +CSMDoc::Document::~Document() {} QUndoStack& CSMDoc::Document::getUndoStack() { @@ -397,64 +392,62 @@ bool CSMDoc::Document::isNew() const void CSMDoc::Document::save() { if (mSaving.isRunning()) - throw std::logic_error ( - "Failed to initiate save, because a save operation is already running."); + throw std::logic_error("Failed to initiate save, because a save operation is already running."); mSaving.start(); - emit stateChanged (getState(), this); + emit stateChanged(getState(), this); } -CSMWorld::UniversalId CSMDoc::Document::verify (const CSMWorld::UniversalId& reportId) +CSMWorld::UniversalId CSMDoc::Document::verify(const CSMWorld::UniversalId& reportId) { - CSMWorld::UniversalId id = mTools.runVerifier (reportId); - emit stateChanged (getState(), this); + CSMWorld::UniversalId id = mTools.runVerifier(reportId); + emit stateChanged(getState(), this); return id; } - CSMWorld::UniversalId CSMDoc::Document::newSearch() { return mTools.newSearch(); } -void CSMDoc::Document::runSearch (const CSMWorld::UniversalId& searchId, const CSMTools::Search& search) +void CSMDoc::Document::runSearch(const CSMWorld::UniversalId& searchId, const CSMTools::Search& search) { - mTools.runSearch (searchId, search); - emit stateChanged (getState(), this); + mTools.runSearch(searchId, search); + emit stateChanged(getState(), this); } -void CSMDoc::Document::runMerge (std::unique_ptr target) +void CSMDoc::Document::runMerge(std::unique_ptr target) { - mTools.runMerge (std::move(target)); - emit stateChanged (getState(), this); + mTools.runMerge(std::move(target)); + emit stateChanged(getState(), this); } -void CSMDoc::Document::abortOperation (int type) +void CSMDoc::Document::abortOperation(int type) { - if (type==State_Saving) + if (type == State_Saving) mSaving.abort(); else - mTools.abortOperation (type); + mTools.abortOperation(type); } -void CSMDoc::Document::modificationStateChanged (bool clean) +void CSMDoc::Document::modificationStateChanged(bool clean) { - emit stateChanged (getState(), this); + emit stateChanged(getState(), this); } -void CSMDoc::Document::reportMessage (const CSMDoc::Message& message, int type) +void CSMDoc::Document::reportMessage(const CSMDoc::Message& message, int type) { /// \todo find a better way to get these messages to the user. Log(Debug::Info) << message.mMessage; } -void CSMDoc::Document::operationDone2 (int type, bool failed) +void CSMDoc::Document::operationDone2(int type, bool failed) { - if (type==CSMDoc::State_Saving && !failed) + if (type == CSMDoc::State_Saving && !failed) mDirty = false; - emit stateChanged (getState(), this); + emit stateChanged(getState(), this); } const CSMWorld::Data& CSMDoc::Document::getData() const @@ -467,37 +460,35 @@ CSMWorld::Data& CSMDoc::Document::getData() return mData; } -CSMTools::ReportModel *CSMDoc::Document::getReport (const CSMWorld::UniversalId& id) +CSMTools::ReportModel* CSMDoc::Document::getReport(const CSMWorld::UniversalId& id) { - return mTools.getReport (id); + return mTools.getReport(id); } -bool CSMDoc::Document::isBlacklisted (const CSMWorld::UniversalId& id) - const +bool CSMDoc::Document::isBlacklisted(const CSMWorld::UniversalId& id) const { - return mBlacklist.isBlacklisted (id); + return mBlacklist.isBlacklisted(id); } -void CSMDoc::Document::startRunning (const std::string& profile, - const std::string& startupInstruction) +void CSMDoc::Document::startRunning(const std::string& profile, const std::string& startupInstruction) { std::vector contentFiles; - for (const auto & mContentFile : mContentFiles) { + for (const auto& mContentFile : mContentFiles) + { contentFiles.emplace_back(mContentFile.filename()); } - mRunner.configure (getData().getDebugProfiles().getRecord (profile).get(), contentFiles, - startupInstruction); + mRunner.configure(getData().getDebugProfiles().getRecord(profile).get(), contentFiles, startupInstruction); int state = getState(); if (state & State_Modified) { // need to save first - mRunner.start (true); + mRunner.start(true); - new SaveWatcher (&mRunner, &mSaving); // no, that is not a memory leak. Qt is weird. + new SaveWatcher(&mRunner, &mSaving); // no, that is not a memory leak. Qt is weird. if (!(state & State_Saving)) save(); @@ -511,22 +502,22 @@ void CSMDoc::Document::stopRunning() mRunner.stop(); } -QTextDocument *CSMDoc::Document::getRunLog() +QTextDocument* CSMDoc::Document::getRunLog() { return mRunner.getLog(); } void CSMDoc::Document::runStateChanged() { - emit stateChanged (getState(), this); + emit stateChanged(getState(), this); } -void CSMDoc::Document::progress (int current, int max, int type) +void CSMDoc::Document::progress(int current, int max, int type) { - emit progress (current, max, type, 1, this); + emit progress(current, max, type, 1, this); } -CSMWorld::IdCompletionManager &CSMDoc::Document::getIdCompletionManager() +CSMWorld::IdCompletionManager& CSMDoc::Document::getIdCompletionManager() { return mIdCompletionManager; } diff --git a/apps/opencs/model/doc/document.hpp b/apps/opencs/model/doc/document.hpp index a012a7dc5a..942decb7b6 100644 --- a/apps/opencs/model/doc/document.hpp +++ b/apps/opencs/model/doc/document.hpp @@ -3,8 +3,8 @@ #include -#include #include +#include #include #include @@ -14,10 +14,10 @@ #include "../tools/tools.hpp" -#include "saving.hpp" #include "blacklist.hpp" -#include "runner.hpp" #include "operationholder.hpp" +#include "runner.hpp" +#include "saving.hpp" class QAbstractItemModel; @@ -52,133 +52,130 @@ namespace CSMDoc { class Document : public QObject { - Q_OBJECT - - private: - - std::filesystem::path mSavePath; - std::vector mContentFiles; - bool mNew; - CSMWorld::Data mData; - CSMTools::Tools mTools; - std::filesystem::path mProjectPath; - Saving mSavingOperation; - OperationHolder mSaving; - std::filesystem::path mResDir; - Blacklist mBlacklist; - Runner mRunner; - bool mDirty; + Q_OBJECT - CSMWorld::IdCompletionManager mIdCompletionManager; + private: + std::filesystem::path mSavePath; + std::vector mContentFiles; + bool mNew; + CSMWorld::Data mData; + CSMTools::Tools mTools; + std::filesystem::path mProjectPath; + Saving mSavingOperation; + OperationHolder mSaving; + std::filesystem::path mResDir; + Blacklist mBlacklist; + Runner mRunner; + bool mDirty; - // It is important that the undo stack is declared last, because on desctruction it fires a signal, that is connected to a slot, that is - // using other member variables. Unfortunately this connection is cut only in the QObject destructor, which is way too late. - QUndoStack mUndoStack; + CSMWorld::IdCompletionManager mIdCompletionManager; - // not implemented - Document (const Document&); - Document& operator= (const Document&); + // It is important that the undo stack is declared last, because on desctruction it fires a signal, that is + // connected to a slot, that is using other member variables. Unfortunately this connection is cut only in the + // QObject destructor, which is way too late. + QUndoStack mUndoStack; - void createBase(); + // not implemented + Document(const Document&); + Document& operator=(const Document&); - void addGmsts(); + void createBase(); - void addOptionalGmsts(); + void addGmsts(); - void addOptionalGlobals(); + void addOptionalGmsts(); - void addOptionalMagicEffects(); + void addOptionalGlobals(); - void addOptionalGmst (const ESM::GameSetting& gmst); + void addOptionalMagicEffects(); - void addOptionalGlobal (const ESM::Global& global); + void addOptionalGmst(const ESM::GameSetting& gmst); - void addOptionalMagicEffect (const ESM::MagicEffect& effect); + void addOptionalGlobal(const ESM::Global& global); - public: + void addOptionalMagicEffect(const ESM::MagicEffect& effect); - Document (const Files::ConfigurationManager& configuration, - std::vector< std::filesystem::path > files, bool new_, - const std::filesystem::path& savePath, const std::filesystem::path& resDir, - ToUTF8::FromType encoding, const std::vector& blacklistedScripts, - bool fsStrict, const Files::PathContainer& dataPaths, const std::vector& archives); + public: + Document(const Files::ConfigurationManager& configuration, std::vector files, bool new_, + const std::filesystem::path& savePath, const std::filesystem::path& resDir, ToUTF8::FromType encoding, + const std::vector& blacklistedScripts, bool fsStrict, const Files::PathContainer& dataPaths, + const std::vector& archives); - ~Document(); + ~Document(); - QUndoStack& getUndoStack(); + QUndoStack& getUndoStack(); - int getState() const; + int getState() const; - const std::filesystem::path& getResourceDir() const; + const std::filesystem::path& getResourceDir() const; - const std::filesystem::path& getSavePath() const; + const std::filesystem::path& getSavePath() const; - const std::filesystem::path& getProjectPath() const; + const std::filesystem::path& getProjectPath() const; - const std::vector& getContentFiles() const; - ///< \attention The last element in this collection is the file that is being edited, - /// but with its original path instead of the save path. + const std::vector& getContentFiles() const; + ///< \attention The last element in this collection is the file that is being edited, + /// but with its original path instead of the save path. - bool isNew() const; - ///< Is this a newly created content file? + bool isNew() const; + ///< Is this a newly created content file? - void save(); + void save(); - CSMWorld::UniversalId verify (const CSMWorld::UniversalId& reportId = CSMWorld::UniversalId()); + CSMWorld::UniversalId verify(const CSMWorld::UniversalId& reportId = CSMWorld::UniversalId()); - CSMWorld::UniversalId newSearch(); + CSMWorld::UniversalId newSearch(); - void runSearch (const CSMWorld::UniversalId& searchId, const CSMTools::Search& search); + void runSearch(const CSMWorld::UniversalId& searchId, const CSMTools::Search& search); - void runMerge (std::unique_ptr target); + void runMerge(std::unique_ptr target); - void abortOperation (int type); + void abortOperation(int type); - const CSMWorld::Data& getData() const; + const CSMWorld::Data& getData() const; - CSMWorld::Data& getData(); + CSMWorld::Data& getData(); - CSMTools::ReportModel *getReport (const CSMWorld::UniversalId& id); - ///< The ownership of the returned report is not transferred. + CSMTools::ReportModel* getReport(const CSMWorld::UniversalId& id); + ///< The ownership of the returned report is not transferred. - bool isBlacklisted (const CSMWorld::UniversalId& id) const; + bool isBlacklisted(const CSMWorld::UniversalId& id) const; - void startRunning (const std::string& profile, - const std::string& startupInstruction = ""); + void startRunning(const std::string& profile, const std::string& startupInstruction = ""); - void stopRunning(); + void stopRunning(); - QTextDocument *getRunLog(); + QTextDocument* getRunLog(); - CSMWorld::IdCompletionManager &getIdCompletionManager(); + CSMWorld::IdCompletionManager& getIdCompletionManager(); - void flagAsDirty(); + void flagAsDirty(); - signals: + signals: - void stateChanged (int state, CSMDoc::Document *document); + void stateChanged(int state, CSMDoc::Document* document); - void progress (int current, int max, int type, int threads, CSMDoc::Document *document); + void progress(int current, int max, int type, int threads, CSMDoc::Document* document); - /// \attention When this signal is emitted, *this hands over the ownership of the - /// document. This signal must be handled to avoid a leak. - void mergeDone (CSMDoc::Document *document); + /// \attention When this signal is emitted, *this hands over the ownership of the + /// document. This signal must be handled to avoid a leak. + void mergeDone(CSMDoc::Document* document); - void operationDone (int type, bool failed); + void operationDone(int type, bool failed); - private slots: + private slots: - void modificationStateChanged (bool clean); + void modificationStateChanged(bool clean); - void reportMessage (const CSMDoc::Message& message, int type); + void reportMessage(const CSMDoc::Message& message, int type); - void operationDone2 (int type, bool failed); + void operationDone2(int type, bool failed); - void runStateChanged(); + void runStateChanged(); - public slots: + public slots: - void progress (int current, int max, int type); + void progress(int current, int max, int type); }; } diff --git a/apps/opencs/model/doc/documentmanager.cpp b/apps/opencs/model/doc/documentmanager.cpp index 6e59baff90..b417a3ca8d 100644 --- a/apps/opencs/model/doc/documentmanager.cpp +++ b/apps/opencs/model/doc/documentmanager.cpp @@ -8,31 +8,26 @@ #include "document.hpp" -CSMDoc::DocumentManager::DocumentManager (const Files::ConfigurationManager& configuration) -: mConfiguration (configuration), mEncoding (ToUTF8::WINDOWS_1252), mFsStrict(false) +CSMDoc::DocumentManager::DocumentManager(const Files::ConfigurationManager& configuration) + : mConfiguration(configuration) + , mEncoding(ToUTF8::WINDOWS_1252) + , mFsStrict(false) { std::filesystem::path projectPath = configuration.getUserDataPath() / "projects"; - if (!std::filesystem::is_directory (projectPath)) - std::filesystem::create_directories (projectPath); + if (!std::filesystem::is_directory(projectPath)) + std::filesystem::create_directories(projectPath); - mLoader.moveToThread (&mLoaderThread); + mLoader.moveToThread(&mLoaderThread); mLoaderThread.start(); - connect (&mLoader, &Loader::documentLoaded, - this, &DocumentManager::documentLoaded); - connect (&mLoader, &Loader::documentNotLoaded, - this, &DocumentManager::documentNotLoaded); - connect (this, &DocumentManager::loadRequest, - &mLoader, &Loader::loadDocument); - connect (&mLoader, &Loader::nextStage, - this, &DocumentManager::nextStage); - connect (&mLoader, &Loader::nextRecord, - this, &DocumentManager::nextRecord); - connect (this, &DocumentManager::cancelLoading, - &mLoader, &Loader::abortLoading); - connect (&mLoader, &Loader::loadMessage, - this, &DocumentManager::loadMessage); + connect(&mLoader, &Loader::documentLoaded, this, &DocumentManager::documentLoaded); + connect(&mLoader, &Loader::documentNotLoaded, this, &DocumentManager::documentNotLoaded); + connect(this, &DocumentManager::loadRequest, &mLoader, &Loader::loadDocument); + connect(&mLoader, &Loader::nextStage, this, &DocumentManager::nextStage); + connect(&mLoader, &Loader::nextRecord, this, &DocumentManager::nextRecord); + connect(this, &DocumentManager::cancelLoading, &mLoader, &Loader::abortLoading); + connect(&mLoader, &Loader::loadMessage, this, &DocumentManager::loadMessage); } CSMDoc::DocumentManager::~DocumentManager() @@ -42,7 +37,7 @@ CSMDoc::DocumentManager::~DocumentManager() mLoader.hasThingsToDo().wakeAll(); mLoaderThread.wait(); - for (std::vector::iterator iter (mDocuments.begin()); iter!=mDocuments.end(); ++iter) + for (std::vector::iterator iter(mDocuments.begin()); iter != mDocuments.end(); ++iter) delete *iter; } @@ -51,78 +46,78 @@ bool CSMDoc::DocumentManager::isEmpty() return mDocuments.empty(); } -void CSMDoc::DocumentManager::addDocument (const std::vector& files, const std::filesystem::path& savePath, - bool new_) +void CSMDoc::DocumentManager::addDocument( + const std::vector& files, const std::filesystem::path& savePath, bool new_) { - Document *document = makeDocument (files, savePath, new_); - insertDocument (document); + Document* document = makeDocument(files, savePath, new_); + insertDocument(document); } -CSMDoc::Document *CSMDoc::DocumentManager::makeDocument ( - const std::vector< std::filesystem::path >& files, - const std::filesystem::path& savePath, bool new_) +CSMDoc::Document* CSMDoc::DocumentManager::makeDocument( + const std::vector& files, const std::filesystem::path& savePath, bool new_) { - return new Document (mConfiguration, files, new_, savePath, mResDir, mEncoding, mBlacklistedScripts, mFsStrict, mDataPaths, mArchives); + return new Document(mConfiguration, files, new_, savePath, mResDir, mEncoding, mBlacklistedScripts, mFsStrict, + mDataPaths, mArchives); } -void CSMDoc::DocumentManager::insertDocument (CSMDoc::Document *document) +void CSMDoc::DocumentManager::insertDocument(CSMDoc::Document* document) { - mDocuments.push_back (document); + mDocuments.push_back(document); - connect (document, SIGNAL (mergeDone (CSMDoc::Document*)), - this, SLOT (insertDocument (CSMDoc::Document*))); + connect(document, SIGNAL(mergeDone(CSMDoc::Document*)), this, SLOT(insertDocument(CSMDoc::Document*))); - emit loadRequest (document); + emit loadRequest(document); mLoader.hasThingsToDo().wakeAll(); } -void CSMDoc::DocumentManager::removeDocument (CSMDoc::Document *document) +void CSMDoc::DocumentManager::removeDocument(CSMDoc::Document* document) { - std::vector::iterator iter = std::find (mDocuments.begin(), mDocuments.end(), document); + std::vector::iterator iter = std::find(mDocuments.begin(), mDocuments.end(), document); - if (iter==mDocuments.end()) - throw std::runtime_error ("removing invalid document"); + if (iter == mDocuments.end()) + throw std::runtime_error("removing invalid document"); - emit documentAboutToBeRemoved (document); + emit documentAboutToBeRemoved(document); - mDocuments.erase (iter); + mDocuments.erase(iter); document->deleteLater(); if (mDocuments.empty()) emit lastDocumentDeleted(); } -void CSMDoc::DocumentManager::setResourceDir (const std::filesystem::path& parResDir) +void CSMDoc::DocumentManager::setResourceDir(const std::filesystem::path& parResDir) { mResDir = std::filesystem::absolute(parResDir); } -void CSMDoc::DocumentManager::setEncoding (ToUTF8::FromType encoding) +void CSMDoc::DocumentManager::setEncoding(ToUTF8::FromType encoding) { mEncoding = encoding; } -void CSMDoc::DocumentManager::setBlacklistedScripts (const std::vector& scriptIds) +void CSMDoc::DocumentManager::setBlacklistedScripts(const std::vector& scriptIds) { mBlacklistedScripts = scriptIds; } -void CSMDoc::DocumentManager::documentLoaded (Document *document) +void CSMDoc::DocumentManager::documentLoaded(Document* document) { - emit documentAdded (document); - emit loadingStopped (document, true, ""); + emit documentAdded(document); + emit loadingStopped(document, true, ""); } -void CSMDoc::DocumentManager::documentNotLoaded (Document *document, const std::string& error) +void CSMDoc::DocumentManager::documentNotLoaded(Document* document, const std::string& error) { - emit loadingStopped (document, false, error); + emit loadingStopped(document, false, error); if (error.empty()) // do not remove the document yet, if we have an error - removeDocument (document); + removeDocument(document); } -void CSMDoc::DocumentManager::setFileData(bool strict, const Files::PathContainer& dataPaths, const std::vector& archives) +void CSMDoc::DocumentManager::setFileData( + bool strict, const Files::PathContainer& dataPaths, const std::vector& archives) { mFsStrict = strict; mDataPaths = dataPaths; diff --git a/apps/opencs/model/doc/documentmanager.hpp b/apps/opencs/model/doc/documentmanager.hpp index 4dd5c550bb..6f1d783a20 100644 --- a/apps/opencs/model/doc/documentmanager.hpp +++ b/apps/opencs/model/doc/documentmanager.hpp @@ -1,15 +1,15 @@ #ifndef CSM_DOC_DOCUMENTMGR_H #define CSM_DOC_DOCUMENTMGR_H -#include #include +#include #include #include -#include #include #include +#include #include "loader.hpp" @@ -29,94 +29,91 @@ namespace CSMDoc class DocumentManager : public QObject { - Q_OBJECT - - std::vector mDocuments; - const Files::ConfigurationManager& mConfiguration; - QThread mLoaderThread; - Loader mLoader; - ToUTF8::FromType mEncoding; - std::vector mBlacklistedScripts; + Q_OBJECT - std::filesystem::path mResDir; + std::vector mDocuments; + const Files::ConfigurationManager& mConfiguration; + QThread mLoaderThread; + Loader mLoader; + ToUTF8::FromType mEncoding; + std::vector mBlacklistedScripts; - bool mFsStrict; - Files::PathContainer mDataPaths; - std::vector mArchives; + std::filesystem::path mResDir; - DocumentManager (const DocumentManager&); - DocumentManager& operator= (const DocumentManager&); + bool mFsStrict; + Files::PathContainer mDataPaths; + std::vector mArchives; - public: + DocumentManager(const DocumentManager&); + DocumentManager& operator=(const DocumentManager&); - DocumentManager (const Files::ConfigurationManager& configuration); + public: + DocumentManager(const Files::ConfigurationManager& configuration); - ~DocumentManager(); + ~DocumentManager(); - void addDocument (const std::vector< std::filesystem::path >& files, - const std::filesystem::path& savePath, bool new_); - ///< \param new_ Do not load the last content file in \a files and instead create in an - /// appropriate way. + void addDocument( + const std::vector& files, const std::filesystem::path& savePath, bool new_); + ///< \param new_ Do not load the last content file in \a files and instead create in an + /// appropriate way. - /// Create a new document. The ownership of the created document is transferred to - /// the calling function. The DocumentManager does not manage it. Loading has not - /// taken place at the point when the document is returned. - /// - /// \param new_ Do not load the last content file in \a files and instead create in an - /// appropriate way. - Document *makeDocument (const std::vector< std::filesystem::path >& files, - const std::filesystem::path& savePath, bool new_); + /// Create a new document. The ownership of the created document is transferred to + /// the calling function. The DocumentManager does not manage it. Loading has not + /// taken place at the point when the document is returned. + /// + /// \param new_ Do not load the last content file in \a files and instead create in an + /// appropriate way. + Document* makeDocument( + const std::vector& files, const std::filesystem::path& savePath, bool new_); - void setResourceDir (const std::filesystem::path& parResDir); + void setResourceDir(const std::filesystem::path& parResDir); - void setEncoding (ToUTF8::FromType encoding); + void setEncoding(ToUTF8::FromType encoding); - void setBlacklistedScripts (const std::vector& scriptIds); + void setBlacklistedScripts(const std::vector& scriptIds); - /// Sets the file data that gets passed to newly created documents. - void setFileData(bool strict, const Files::PathContainer& dataPaths, const std::vector& archives); + /// Sets the file data that gets passed to newly created documents. + void setFileData(bool strict, const Files::PathContainer& dataPaths, const std::vector& archives); - bool isEmpty(); + bool isEmpty(); - private slots: + private slots: - void documentLoaded (Document *document); - ///< The ownership of \a document is not transferred. + void documentLoaded(Document* document); + ///< The ownership of \a document is not transferred. - void documentNotLoaded (Document *document, const std::string& error); - ///< Document load has been interrupted either because of a call to abortLoading - /// or a problem during loading). In the former case error will be an empty string. + void documentNotLoaded(Document* document, const std::string& error); + ///< Document load has been interrupted either because of a call to abortLoading + /// or a problem during loading). In the former case error will be an empty string. - public slots: + public slots: - void removeDocument (CSMDoc::Document *document); - ///< Emits the lastDocumentDeleted signal, if applicable. + void removeDocument(CSMDoc::Document* document); + ///< Emits the lastDocumentDeleted signal, if applicable. - /// Hand over document to *this. The ownership is transferred. The DocumentManager - /// will initiate the load procedure, if necessary - void insertDocument (CSMDoc::Document *document); + /// Hand over document to *this. The ownership is transferred. The DocumentManager + /// will initiate the load procedure, if necessary + void insertDocument(CSMDoc::Document* document); - signals: + signals: - void documentAdded (CSMDoc::Document *document); + void documentAdded(CSMDoc::Document* document); - void documentAboutToBeRemoved (CSMDoc::Document *document); + void documentAboutToBeRemoved(CSMDoc::Document* document); - void loadRequest (CSMDoc::Document *document); + void loadRequest(CSMDoc::Document* document); - void lastDocumentDeleted(); + void lastDocumentDeleted(); - void loadingStopped (CSMDoc::Document *document, bool completed, - const std::string& error); + void loadingStopped(CSMDoc::Document* document, bool completed, const std::string& error); - void nextStage (CSMDoc::Document *document, const std::string& name, - int totalRecords); + void nextStage(CSMDoc::Document* document, const std::string& name, int totalRecords); - void nextRecord (CSMDoc::Document *document, int records); + void nextRecord(CSMDoc::Document* document, int records); - void cancelLoading (CSMDoc::Document *document); + void cancelLoading(CSMDoc::Document* document); - void loadMessage (CSMDoc::Document *document, const std::string& message); + void loadMessage(CSMDoc::Document* document, const std::string& message); }; } diff --git a/apps/opencs/model/doc/loader.cpp b/apps/opencs/model/doc/loader.cpp index a851707811..8a84a827b0 100644 --- a/apps/opencs/model/doc/loader.cpp +++ b/apps/opencs/model/doc/loader.cpp @@ -8,15 +8,19 @@ #include "document.hpp" -CSMDoc::Loader::Stage::Stage() : mFile (0), mRecordsLoaded (0), mRecordsLeft (false) {} - +CSMDoc::Loader::Stage::Stage() + : mFile(0) + , mRecordsLoaded(0) + , mRecordsLeft(false) +{ +} CSMDoc::Loader::Loader() : mShouldStop(false) { - mTimer = new QTimer (this); + mTimer = new QTimer(this); - connect (mTimer, &QTimer::timeout, this, &Loader::load); + connect(mTimer, &QTimer::timeout, this, &Loader::load); mTimer->start(); } @@ -35,7 +39,7 @@ void CSMDoc::Loader::load() if (mDocuments.empty()) { mMutex.lock(); - mThingsToDo.wait (&mMutex); + mThingsToDo.wait(&mMutex); mMutex.unlock(); if (mShouldStop) @@ -44,12 +48,12 @@ void CSMDoc::Loader::load() return; } - std::vector >::iterator iter = mDocuments.begin(); + std::vector>::iterator iter = mDocuments.begin(); - Document *document = iter->first; + Document* document = iter->first; - int size = static_cast (document->getContentFiles().size()); - int editedIndex = size-1; // index of the file to be edited/created + int size = static_cast(document->getContentFiles().size()); + int editedIndex = size - 1; // index of the file to be edited/created if (document->isNew()) --size; @@ -60,10 +64,10 @@ void CSMDoc::Loader::load() { if (iter->second.mRecordsLeft) { - Messages messages (Message::Severity_Error); + Messages messages(Message::Severity_Error); const int batchingSize = 50; - for (int i=0; igetData().continueLoading (messages)) + for (int i = 0; i < batchingSize; ++i) // do not flood the system with update signals + if (document->getData().continueLoading(messages)) { iter->second.mRecordsLeft = false; break; @@ -71,39 +75,39 @@ void CSMDoc::Loader::load() else ++(iter->second.mRecordsLoaded); - CSMWorld::UniversalId log (CSMWorld::UniversalId::Type_LoadErrorLog, 0); + CSMWorld::UniversalId log(CSMWorld::UniversalId::Type_LoadErrorLog, 0); { // silence a g++ warning - for (CSMDoc::Messages::Iterator messageIter (messages.begin()); - messageIter!=messages.end(); ++messageIter) - { - document->getReport (log)->add (*messageIter); - emit loadMessage (document, messageIter->mMessage); - } + for (CSMDoc::Messages::Iterator messageIter(messages.begin()); messageIter != messages.end(); + ++messageIter) + { + document->getReport(log)->add(*messageIter); + emit loadMessage(document, messageIter->mMessage); + } } - emit nextRecord (document, iter->second.mRecordsLoaded); + emit nextRecord(document, iter->second.mRecordsLoaded); return; } - if (iter->second.mFilesecond.mFile < size) // start loading the files { std::filesystem::path path = document->getContentFiles()[iter->second.mFile]; - int steps = document->getData().startLoading (path, iter->second.mFile!=editedIndex, /*project*/false); + int steps = document->getData().startLoading(path, iter->second.mFile != editedIndex, /*project*/ false); iter->second.mRecordsLeft = true; iter->second.mRecordsLoaded = 0; - emit nextStage (document, Files::pathToUnicodeString(path.filename()), steps); + emit nextStage(document, Files::pathToUnicodeString(path.filename()), steps); } - else if (iter->second.mFile==size) // start loading the last (project) file + else if (iter->second.mFile == size) // start loading the last (project) file { - int steps = document->getData().startLoading (document->getProjectPath(), /*base*/false, true); + int steps = document->getData().startLoading(document->getProjectPath(), /*base*/ false, true); iter->second.mRecordsLeft = true; iter->second.mRecordsLoaded = 0; - emit nextStage (document, "Project File", steps); + emit nextStage(document, "Project File", steps); } else { @@ -114,32 +118,31 @@ void CSMDoc::Loader::load() } catch (const std::exception& e) { - mDocuments.erase (iter); - emit documentNotLoaded (document, e.what()); + mDocuments.erase(iter); + emit documentNotLoaded(document, e.what()); return; } if (done) { - mDocuments.erase (iter); - emit documentLoaded (document); + mDocuments.erase(iter); + emit documentLoaded(document); } } -void CSMDoc::Loader::loadDocument (CSMDoc::Document *document) +void CSMDoc::Loader::loadDocument(CSMDoc::Document* document) { - mDocuments.emplace_back (document, Stage()); + mDocuments.emplace_back(document, Stage()); } -void CSMDoc::Loader::abortLoading (CSMDoc::Document *document) +void CSMDoc::Loader::abortLoading(CSMDoc::Document* document) { - for (std::vector >::iterator iter = mDocuments.begin(); - iter!=mDocuments.end(); ++iter) + for (std::vector>::iterator iter = mDocuments.begin(); iter != mDocuments.end(); ++iter) { - if (iter->first==document) + if (iter->first == document) { - mDocuments.erase (iter); - emit documentNotLoaded (document, ""); + mDocuments.erase(iter); + emit documentNotLoaded(document, ""); break; } } diff --git a/apps/opencs/model/doc/loader.hpp b/apps/opencs/model/doc/loader.hpp index ce5bc5848a..24cb069f79 100644 --- a/apps/opencs/model/doc/loader.hpp +++ b/apps/opencs/model/doc/loader.hpp @@ -3,8 +3,8 @@ #include -#include #include +#include #include #include @@ -14,65 +14,63 @@ namespace CSMDoc class Loader : public QObject { - Q_OBJECT - - struct Stage - { - int mFile; - int mRecordsLoaded; - bool mRecordsLeft; + Q_OBJECT - Stage(); - }; + struct Stage + { + int mFile; + int mRecordsLoaded; + bool mRecordsLeft; - QMutex mMutex; - QWaitCondition mThingsToDo; - std::vector > mDocuments; + Stage(); + }; - QTimer* mTimer; - bool mShouldStop; + QMutex mMutex; + QWaitCondition mThingsToDo; + std::vector> mDocuments; - public: + QTimer* mTimer; + bool mShouldStop; - Loader(); + public: + Loader(); - QWaitCondition& hasThingsToDo(); + QWaitCondition& hasThingsToDo(); - void stop(); + void stop(); - private slots: + private slots: - void load(); + void load(); - public slots: + public slots: - void loadDocument (CSMDoc::Document *document); - ///< The ownership of \a document is not transferred. + void loadDocument(CSMDoc::Document* document); + ///< The ownership of \a document is not transferred. - void abortLoading (CSMDoc::Document *document); - ///< Abort loading \a docuemnt (ignored if \a document has already finished being - /// loaded). Will result in a documentNotLoaded signal, once the Loader has finished - /// cleaning up. + void abortLoading(CSMDoc::Document* document); + ///< Abort loading \a docuemnt (ignored if \a document has already finished being + /// loaded). Will result in a documentNotLoaded signal, once the Loader has finished + /// cleaning up. - signals: + signals: - void documentLoaded (Document *document); - ///< The ownership of \a document is not transferred. + void documentLoaded(Document* document); + ///< The ownership of \a document is not transferred. - void documentNotLoaded (Document *document, const std::string& error); - ///< Document load has been interrupted either because of a call to abortLoading - /// or a problem during loading). In the former case error will be an empty string. + void documentNotLoaded(Document* document, const std::string& error); + ///< Document load has been interrupted either because of a call to abortLoading + /// or a problem during loading). In the former case error will be an empty string. - void nextStage (CSMDoc::Document *document, const std::string& name, - int totalRecords); + void nextStage(CSMDoc::Document* document, const std::string& name, int totalRecords); - void nextRecord (CSMDoc::Document *document, int records); - ///< \note This signal is only given once per group of records. The group size is - /// approximately the total number of records divided by the steps value of the - /// previous nextStage signal. + void nextRecord(CSMDoc::Document* document, int records); + ///< \note This signal is only given once per group of records. The group size is + /// approximately the total number of records divided by the steps value of the + /// previous nextStage signal. - void loadMessage (CSMDoc::Document *document, const std::string& message); - ///< Non-critical load error or warning + void loadMessage(CSMDoc::Document* document, const std::string& message); + ///< Non-critical load error or warning }; } diff --git a/apps/opencs/model/doc/messages.cpp b/apps/opencs/model/doc/messages.cpp index b70d44eda3..5d7a6ac6cb 100644 --- a/apps/opencs/model/doc/messages.cpp +++ b/apps/opencs/model/doc/messages.cpp @@ -1,38 +1,50 @@ #include "messages.hpp" -CSMDoc::Message::Message() : mSeverity(Severity_Default){} +CSMDoc::Message::Message() + : mSeverity(Severity_Default) +{ +} -CSMDoc::Message::Message (const CSMWorld::UniversalId& id, const std::string& message, - const std::string& hint, Severity severity) -: mId (id), mMessage (message), mHint (hint), mSeverity (severity) -{} +CSMDoc::Message::Message( + const CSMWorld::UniversalId& id, const std::string& message, const std::string& hint, Severity severity) + : mId(id) + , mMessage(message) + , mHint(hint) + , mSeverity(severity) +{ +} -std::string CSMDoc::Message::toString (Severity severity) +std::string CSMDoc::Message::toString(Severity severity) { switch (severity) { - case CSMDoc::Message::Severity_Info: return "Information"; - case CSMDoc::Message::Severity_Warning: return "Warning"; - case CSMDoc::Message::Severity_Error: return "Error"; - case CSMDoc::Message::Severity_SeriousError: return "Serious Error"; - case CSMDoc::Message::Severity_Default: break; + case CSMDoc::Message::Severity_Info: + return "Information"; + case CSMDoc::Message::Severity_Warning: + return "Warning"; + case CSMDoc::Message::Severity_Error: + return "Error"; + case CSMDoc::Message::Severity_SeriousError: + return "Serious Error"; + case CSMDoc::Message::Severity_Default: + break; } return ""; } +CSMDoc::Messages::Messages(Message::Severity default_) + : mDefault(default_) +{ +} -CSMDoc::Messages::Messages (Message::Severity default_) -: mDefault (default_) -{} - -void CSMDoc::Messages::add (const CSMWorld::UniversalId& id, const std::string& message, - const std::string& hint, Message::Severity severity) +void CSMDoc::Messages::add( + const CSMWorld::UniversalId& id, const std::string& message, const std::string& hint, Message::Severity severity) { - if (severity==Message::Severity_Default) + if (severity == Message::Severity_Default) severity = mDefault; - mMessages.push_back (Message (id, message, hint, severity)); + mMessages.push_back(Message(id, message, hint, severity)); } CSMDoc::Messages::Iterator CSMDoc::Messages::begin() const diff --git a/apps/opencs/model/doc/messages.hpp b/apps/opencs/model/doc/messages.hpp index 355493b79b..3186107914 100644 --- a/apps/opencs/model/doc/messages.hpp +++ b/apps/opencs/model/doc/messages.hpp @@ -12,9 +12,9 @@ namespace CSMDoc { enum Severity { - Severity_Info = 0, // no problem - Severity_Warning = 1, // a potential problem, but we are probably fine - Severity_Error = 2, // an error; we are not fine + Severity_Info = 0, // no problem + Severity_Warning = 1, // a potential problem, but we are probably fine + Severity_Error = 2, // an error; we are not fine Severity_SeriousError = 3, // an error so bad we can't even be sure if we are // reporting it correctly Severity_Default = 4 @@ -27,39 +27,35 @@ namespace CSMDoc Message(); - Message (const CSMWorld::UniversalId& id, const std::string& message, - const std::string& hint, Severity severity); + Message( + const CSMWorld::UniversalId& id, const std::string& message, const std::string& hint, Severity severity); - static std::string toString (Severity severity); + static std::string toString(Severity severity); }; class Messages { - public: + public: + typedef std::vector Collection; - typedef std::vector Collection; + typedef Collection::const_iterator Iterator; - typedef Collection::const_iterator Iterator; + private: + Collection mMessages; + Message::Severity mDefault; - private: + public: + Messages(Message::Severity default_); - Collection mMessages; - Message::Severity mDefault; + void add(const CSMWorld::UniversalId& id, const std::string& message, const std::string& hint = "", + Message::Severity severity = Message::Severity_Default); - public: + Iterator begin() const; - Messages (Message::Severity default_); - - void add (const CSMWorld::UniversalId& id, const std::string& message, - const std::string& hint = "", - Message::Severity severity = Message::Severity_Default); - - Iterator begin() const; - - Iterator end() const; + Iterator end() const; }; } -Q_DECLARE_METATYPE (CSMDoc::Message) +Q_DECLARE_METATYPE(CSMDoc::Message) #endif diff --git a/apps/opencs/model/doc/operation.cpp b/apps/opencs/model/doc/operation.cpp index 21db0e04b9..396eb17962 100644 --- a/apps/opencs/model/doc/operation.cpp +++ b/apps/opencs/model/doc/operation.cpp @@ -17,25 +17,33 @@ void CSMDoc::Operation::prepareStages() mTotalSteps = 0; mError = false; - for (std::vector >::iterator iter (mStages.begin()); iter!=mStages.end(); ++iter) + for (std::vector>::iterator iter(mStages.begin()); iter != mStages.end(); ++iter) { iter->second = iter->first->setup(); mTotalSteps += iter->second; } } -CSMDoc::Operation::Operation (int type, bool ordered, bool finalAlways) -: mType (type), mStages(std::vector >()), mCurrentStage(mStages.begin()), - mCurrentStep(0), mCurrentStepTotal(0), mTotalSteps(0), mOrdered (ordered), - mFinalAlways (finalAlways), mError(false), mConnected (false), mPrepared (false), - mDefaultSeverity (Message::Severity_Error) +CSMDoc::Operation::Operation(int type, bool ordered, bool finalAlways) + : mType(type) + , mStages(std::vector>()) + , mCurrentStage(mStages.begin()) + , mCurrentStep(0) + , mCurrentStepTotal(0) + , mTotalSteps(0) + , mOrdered(ordered) + , mFinalAlways(finalAlways) + , mError(false) + , mConnected(false) + , mPrepared(false) + , mDefaultSeverity(Message::Severity_Error) { - mTimer = new QTimer (this); + mTimer = new QTimer(this); } CSMDoc::Operation::~Operation() { - for (std::vector >::iterator iter (mStages.begin()); iter!=mStages.end(); ++iter) + for (std::vector>::iterator iter(mStages.begin()); iter != mStages.end(); ++iter) delete iter->first; } @@ -45,21 +53,21 @@ void CSMDoc::Operation::run() if (!mConnected) { - connect (mTimer, &QTimer::timeout, this, &Operation::executeStage); + connect(mTimer, &QTimer::timeout, this, &Operation::executeStage); mConnected = true; } mPrepared = false; - mTimer->start (0); + mTimer->start(0); } -void CSMDoc::Operation::appendStage (Stage *stage) +void CSMDoc::Operation::appendStage(Stage* stage) { - mStages.emplace_back (stage, 0); + mStages.emplace_back(stage, 0); } -void CSMDoc::Operation::setDefaultSeverity (Message::Severity severity) +void CSMDoc::Operation::setDefaultSeverity(Message::Severity severity) { mDefaultSeverity = severity; } @@ -78,7 +86,7 @@ void CSMDoc::Operation::abort() if (mFinalAlways) { - if (mStages.begin()!=mStages.end() && mCurrentStage!=--mStages.end()) + if (mStages.begin() != mStages.end() && mCurrentStage != --mStages.end()) { mCurrentStep = 0; mCurrentStage = --mStages.end(); @@ -96,11 +104,11 @@ void CSMDoc::Operation::executeStage() mPrepared = true; } - Messages messages (mDefaultSeverity); + Messages messages(mDefaultSeverity); - while (mCurrentStage!=mStages.end()) + while (mCurrentStage != mStages.end()) { - if (mCurrentStep>=mCurrentStage->second) + if (mCurrentStep >= mCurrentStage->second) { mCurrentStep = 0; ++mCurrentStage; @@ -109,11 +117,12 @@ void CSMDoc::Operation::executeStage() { try { - mCurrentStage->first->perform (mCurrentStep++, messages); + mCurrentStage->first->perform(mCurrentStep++, messages); } catch (const std::exception& e) { - emit reportMessage (Message (CSMWorld::UniversalId(), e.what(), "", Message::Severity_SeriousError), mType); + emit reportMessage( + Message(CSMWorld::UniversalId(), e.what(), "", Message::Severity_SeriousError), mType); abort(); } @@ -122,17 +131,17 @@ void CSMDoc::Operation::executeStage() } } - emit progress (mCurrentStepTotal, mTotalSteps ? mTotalSteps : 1, mType); + emit progress(mCurrentStepTotal, mTotalSteps ? mTotalSteps : 1, mType); - for (Messages::Iterator iter (messages.begin()); iter!=messages.end(); ++iter) - emit reportMessage (*iter, mType); + for (Messages::Iterator iter(messages.begin()); iter != messages.end(); ++iter) + emit reportMessage(*iter, mType); - if (mCurrentStage==mStages.end()) + if (mCurrentStage == mStages.end()) operationDone(); } void CSMDoc::Operation::operationDone() { mTimer->stop(); - emit done (mType, mError); + emit done(mType, mError); } diff --git a/apps/opencs/model/doc/operation.hpp b/apps/opencs/model/doc/operation.hpp index b094c08b4c..5ac89ff6b0 100644 --- a/apps/opencs/model/doc/operation.hpp +++ b/apps/opencs/model/doc/operation.hpp @@ -1,8 +1,8 @@ #ifndef CSM_DOC_OPERATION_H #define CSM_DOC_OPERATION_H -#include #include +#include #include #include @@ -20,63 +20,62 @@ namespace CSMDoc class Operation : public QObject { - Q_OBJECT - - int mType; - std::vector > mStages; // stage, number of steps - std::vector >::iterator mCurrentStage; - int mCurrentStep; - int mCurrentStepTotal; - int mTotalSteps; - int mOrdered; - bool mFinalAlways; - bool mError; - bool mConnected; - QTimer *mTimer; - bool mPrepared; - Message::Severity mDefaultSeverity; + Q_OBJECT - void prepareStages(); + int mType; + std::vector> mStages; // stage, number of steps + std::vector>::iterator mCurrentStage; + int mCurrentStep; + int mCurrentStepTotal; + int mTotalSteps; + int mOrdered; + bool mFinalAlways; + bool mError; + bool mConnected; + QTimer* mTimer; + bool mPrepared; + Message::Severity mDefaultSeverity; - public: + void prepareStages(); - Operation (int type, bool ordered, bool finalAlways = false); - ///< \param ordered Stages must be executed in the given order. - /// \param finalAlways Execute last stage even if an error occurred during earlier stages. + public: + Operation(int type, bool ordered, bool finalAlways = false); + ///< \param ordered Stages must be executed in the given order. + /// \param finalAlways Execute last stage even if an error occurred during earlier stages. - virtual ~Operation(); + virtual ~Operation(); - void appendStage (Stage *stage); - ///< The ownership of \a stage is transferred to *this. - /// - /// \attention Do no call this function while this Operation is running. + void appendStage(Stage* stage); + ///< The ownership of \a stage is transferred to *this. + /// + /// \attention Do no call this function while this Operation is running. - /// \attention Do no call this function while this Operation is running. - void setDefaultSeverity (Message::Severity severity); + /// \attention Do no call this function while this Operation is running. + void setDefaultSeverity(Message::Severity severity); - bool hasError() const; + bool hasError() const; - signals: + signals: - void progress (int current, int max, int type); + void progress(int current, int max, int type); - void reportMessage (const CSMDoc::Message& message, int type); + void reportMessage(const CSMDoc::Message& message, int type); - void done (int type, bool failed); + void done(int type, bool failed); - public slots: + public slots: - void abort(); + void abort(); - void run(); + void run(); - private slots: + private slots: - void executeStage(); + void executeStage(); - protected slots: + protected slots: - virtual void operationDone(); + virtual void operationDone(); }; } diff --git a/apps/opencs/model/doc/operationholder.cpp b/apps/opencs/model/doc/operationholder.cpp index a392a6d73c..6beab1fd99 100644 --- a/apps/opencs/model/doc/operationholder.cpp +++ b/apps/opencs/model/doc/operationholder.cpp @@ -2,31 +2,28 @@ #include "operation.hpp" -CSMDoc::OperationHolder::OperationHolder (Operation *operation) +CSMDoc::OperationHolder::OperationHolder(Operation* operation) : mOperation(nullptr) - , mRunning (false) + , mRunning(false) { if (operation) - setOperation (operation); + setOperation(operation); } -void CSMDoc::OperationHolder::setOperation (Operation *operation) +void CSMDoc::OperationHolder::setOperation(Operation* operation) { mOperation = operation; - mOperation->moveToThread (&mThread); + mOperation->moveToThread(&mThread); - connect (mOperation, &Operation::progress, - this, &OperationHolder::progress); + connect(mOperation, &Operation::progress, this, &OperationHolder::progress); - connect (mOperation, &Operation::reportMessage, - this, &OperationHolder::reportMessage); + connect(mOperation, &Operation::reportMessage, this, &OperationHolder::reportMessage); - connect (mOperation, &Operation::done, - this, &OperationHolder::doneSlot); + connect(mOperation, &Operation::done, this, &OperationHolder::doneSlot); - connect (this, &OperationHolder::abortSignal, mOperation, &Operation::abort); + connect(this, &OperationHolder::abortSignal, mOperation, &Operation::abort); - connect (&mThread, &QThread::started, mOperation, &Operation::run); + connect(&mThread, &QThread::started, mOperation, &Operation::run); } bool CSMDoc::OperationHolder::isRunning() const @@ -55,9 +52,9 @@ void CSMDoc::OperationHolder::abortAndWait() } } -void CSMDoc::OperationHolder::doneSlot (int type, bool failed) +void CSMDoc::OperationHolder::doneSlot(int type, bool failed) { mRunning = false; mThread.quit(); - emit done (type, failed); + emit done(type, failed); } diff --git a/apps/opencs/model/doc/operationholder.hpp b/apps/opencs/model/doc/operationholder.hpp index 69af6ed66c..c5b4d23b9a 100644 --- a/apps/opencs/model/doc/operationholder.hpp +++ b/apps/opencs/model/doc/operationholder.hpp @@ -17,40 +17,39 @@ namespace CSMDoc class OperationHolder : public QObject { - Q_OBJECT - - QThread mThread; - Operation *mOperation; - bool mRunning; + Q_OBJECT - public: + QThread mThread; + Operation* mOperation; + bool mRunning; - OperationHolder (Operation *operation = nullptr); + public: + OperationHolder(Operation* operation = nullptr); - void setOperation (Operation *operation); + void setOperation(Operation* operation); - bool isRunning() const; + bool isRunning() const; - void start(); + void start(); - void abort(); + void abort(); - // Abort and wait until thread has finished. - void abortAndWait(); + // Abort and wait until thread has finished. + void abortAndWait(); - private slots: + private slots: - void doneSlot (int type, bool failed); - - signals: + void doneSlot(int type, bool failed); - void progress (int current, int max, int type); + signals: - void reportMessage (const CSMDoc::Message& message, int type); + void progress(int current, int max, int type); - void done (int type, bool failed); + void reportMessage(const CSMDoc::Message& message, int type); - void abortSignal(); + void done(int type, bool failed); + + void abortSignal(); }; } diff --git a/apps/opencs/model/doc/runner.cpp b/apps/opencs/model/doc/runner.cpp index 435a32d920..8590939d97 100644 --- a/apps/opencs/model/doc/runner.cpp +++ b/apps/opencs/model/doc/runner.cpp @@ -2,26 +2,26 @@ #include +#include #include #include #include -#include #include #include #include "operationholder.hpp" -CSMDoc::Runner::Runner (std::filesystem::path projectPath) -: mRunning (false), mStartup (nullptr), mProjectPath (std::move(projectPath)) +CSMDoc::Runner::Runner(std::filesystem::path projectPath) + : mRunning(false) + , mStartup(nullptr) + , mProjectPath(std::move(projectPath)) { - connect (&mProcess, qOverload(&QProcess::finished), - this, &Runner::finished); + connect(&mProcess, qOverload(&QProcess::finished), this, &Runner::finished); - connect (&mProcess, &QProcess::readyReadStandardOutput, - this, &Runner::readyReadStandardOutput); + connect(&mProcess, &QProcess::readyReadStandardOutput, this, &Runner::readyReadStandardOutput); - mProcess.setProcessChannelMode (QProcess::MergedChannels); + mProcess.setProcessChannelMode(QProcess::MergedChannels); mProfile.blank(); } @@ -30,13 +30,13 @@ CSMDoc::Runner::~Runner() { if (mRunning) { - disconnect (&mProcess, nullptr, this, nullptr); + disconnect(&mProcess, nullptr, this, nullptr); mProcess.kill(); mProcess.waitForFinished(); } } -void CSMDoc::Runner::start (bool delayed) +void CSMDoc::Runner::start(bool delayed) { if (mStartup) { @@ -61,16 +61,16 @@ void CSMDoc::Runner::start (bool delayed) path.prepend(QString("./")); #endif - mStartup = new QTemporaryFile (this); + mStartup = new QTemporaryFile(this); mStartup->open(); { - QTextStream stream (mStartup); + QTextStream stream(mStartup); if (!mStartupInstruction.empty()) - stream << QString::fromUtf8 (mStartupInstruction.c_str()) << '\n'; + stream << QString::fromUtf8(mStartupInstruction.c_str()) << '\n'; - stream << QString::fromUtf8 (mProfile.mScriptText.c_str()); + stream << QString::fromUtf8(mProfile.mScriptText.c_str()); } mStartup->close(); @@ -94,8 +94,7 @@ void CSMDoc::Runner::start (bool delayed) arguments << "--content=" + Files::pathToQString(mContentFile); } - arguments - << "--content=" + Files::pathToQString(mProjectPath.filename()); + arguments << "--content=" + Files::pathToQString(mProjectPath.filename()); mProcess.start(path, arguments); } @@ -109,7 +108,7 @@ void CSMDoc::Runner::stop() delete mStartup; mStartup = nullptr; - if (mProcess.state()==QProcess::NotRunning) + if (mProcess.state() == QProcess::NotRunning) { mRunning = false; emit runStateChanged(); @@ -123,39 +122,38 @@ bool CSMDoc::Runner::isRunning() const return mRunning; } -void CSMDoc::Runner::configure (const ESM::DebugProfile& profile, - const std::vector &contentFiles, const std::string& startupInstruction) +void CSMDoc::Runner::configure(const ESM::DebugProfile& profile, const std::vector& contentFiles, + const std::string& startupInstruction) { mProfile = profile; mContentFiles = contentFiles; mStartupInstruction = startupInstruction; } -void CSMDoc::Runner::finished (int exitCode, QProcess::ExitStatus exitStatus) +void CSMDoc::Runner::finished(int exitCode, QProcess::ExitStatus exitStatus) { mRunning = false; emit runStateChanged(); } -QTextDocument *CSMDoc::Runner::getLog() +QTextDocument* CSMDoc::Runner::getLog() { return &mLog; } void CSMDoc::Runner::readyReadStandardOutput() { - mLog.setPlainText ( - mLog.toPlainText() + QString::fromUtf8 (mProcess.readAllStandardOutput())); + mLog.setPlainText(mLog.toPlainText() + QString::fromUtf8(mProcess.readAllStandardOutput())); } - -CSMDoc::SaveWatcher::SaveWatcher (Runner *runner, OperationHolder *operation) -: QObject (runner), mRunner (runner) +CSMDoc::SaveWatcher::SaveWatcher(Runner* runner, OperationHolder* operation) + : QObject(runner) + , mRunner(runner) { - connect (operation, &OperationHolder::done, this, &SaveWatcher::saveDone); + connect(operation, &OperationHolder::done, this, &SaveWatcher::saveDone); } -void CSMDoc::SaveWatcher::saveDone (int type, bool failed) +void CSMDoc::SaveWatcher::saveDone(int type, bool failed) { if (failed) mRunner->stop(); diff --git a/apps/opencs/model/doc/runner.hpp b/apps/opencs/model/doc/runner.hpp index c3ef4477c3..170779772b 100644 --- a/apps/opencs/model/doc/runner.hpp +++ b/apps/opencs/model/doc/runner.hpp @@ -1,8 +1,8 @@ #ifndef CSM_DOC_RUNNER_H #define CSM_DOC_RUNNER_H -#include #include +#include #include #include @@ -17,51 +17,49 @@ class QTemporaryFile; namespace CSMDoc { class OperationHolder; - + class Runner : public QObject { - Q_OBJECT + Q_OBJECT - QProcess mProcess; - bool mRunning; - ESM::DebugProfile mProfile; - std::vector mContentFiles; - std::string mStartupInstruction; - QTemporaryFile *mStartup; - QTextDocument mLog; - std::filesystem::path mProjectPath; + QProcess mProcess; + bool mRunning; + ESM::DebugProfile mProfile; + std::vector mContentFiles; + std::string mStartupInstruction; + QTemporaryFile* mStartup; + QTextDocument mLog; + std::filesystem::path mProjectPath; - public: + public: + Runner(std::filesystem::path projectPath); - Runner (std::filesystem::path projectPath); + ~Runner(); - ~Runner(); + /// \param delayed Flag as running but do not start the OpenMW process yet (the + /// process must be started by another call of start with delayed==false) + void start(bool delayed = false); - /// \param delayed Flag as running but do not start the OpenMW process yet (the - /// process must be started by another call of start with delayed==false) - void start (bool delayed = false); + void stop(); - void stop(); + /// \note Running state is entered when the start function is called. This + /// is not necessarily identical to the moment the child process is started. + bool isRunning() const; - /// \note Running state is entered when the start function is called. This - /// is not necessarily identical to the moment the child process is started. - bool isRunning() const; + void configure(const ESM::DebugProfile& profile, const std::vector& contentFiles, + const std::string& startupInstruction); - void configure (const ESM::DebugProfile& profile, - const std::vector &contentFiles, - const std::string& startupInstruction); + QTextDocument* getLog(); - QTextDocument *getLog(); + signals: - signals: + void runStateChanged(); - void runStateChanged(); + private slots: - private slots: + void finished(int exitCode, QProcess::ExitStatus exitStatus); - void finished (int exitCode, QProcess::ExitStatus exitStatus); - - void readyReadStandardOutput(); + void readyReadStandardOutput(); }; class Operation; @@ -69,18 +67,17 @@ namespace CSMDoc /// \brief Watch for end of save operation and restart or stop runner class SaveWatcher : public QObject { - Q_OBJECT - - Runner *mRunner; + Q_OBJECT - public: + Runner* mRunner; - /// *this attaches itself to runner - SaveWatcher (Runner *runner, OperationHolder *operation); + public: + /// *this attaches itself to runner + SaveWatcher(Runner* runner, OperationHolder* operation); - private slots: + private slots: - void saveDone (int type, bool failed); + void saveDone(int type, bool failed); }; } diff --git a/apps/opencs/model/doc/saving.cpp b/apps/opencs/model/doc/saving.cpp index ec9589ceb4..fb5aaca48d 100644 --- a/apps/opencs/model/doc/saving.cpp +++ b/apps/opencs/model/doc/saving.cpp @@ -3,104 +3,100 @@ #include "../world/data.hpp" #include "../world/idcollection.hpp" -#include "state.hpp" -#include "savingstages.hpp" #include "document.hpp" +#include "savingstages.hpp" +#include "state.hpp" -CSMDoc::Saving::Saving (Document& document, const std::filesystem::path& projectPath, - ToUTF8::FromType encoding) -: Operation (State_Saving, true, true), mDocument (document), mState (*this, projectPath, encoding) +CSMDoc::Saving::Saving(Document& document, const std::filesystem::path& projectPath, ToUTF8::FromType encoding) + : Operation(State_Saving, true, true) + , mDocument(document) + , mState(*this, projectPath, encoding) { // save project file - appendStage (new OpenSaveStage (mDocument, mState, true)); + appendStage(new OpenSaveStage(mDocument, mState, true)); - appendStage (new WriteHeaderStage (mDocument, mState, true)); + appendStage(new WriteHeaderStage(mDocument, mState, true)); - appendStage (new WriteCollectionStage > ( + appendStage(new WriteCollectionStage>( mDocument.getData().getFilters(), mState, CSMWorld::Scope_Project)); - appendStage (new WriteCollectionStage > ( + appendStage(new WriteCollectionStage>( mDocument.getData().getDebugProfiles(), mState, CSMWorld::Scope_Project)); - appendStage (new WriteCollectionStage > ( + appendStage(new WriteCollectionStage>( mDocument.getData().getScripts(), mState, CSMWorld::Scope_Project)); - appendStage (new CloseSaveStage (mState)); + appendStage(new CloseSaveStage(mState)); // save content file - appendStage (new OpenSaveStage (mDocument, mState, false)); + appendStage(new OpenSaveStage(mDocument, mState, false)); - appendStage (new WriteHeaderStage (mDocument, mState, false)); + appendStage(new WriteHeaderStage(mDocument, mState, false)); - appendStage (new WriteCollectionStage > - (mDocument.getData().getGlobals(), mState)); + appendStage( + new WriteCollectionStage>(mDocument.getData().getGlobals(), mState)); - appendStage (new WriteCollectionStage > - (mDocument.getData().getGmsts(), mState)); + appendStage( + new WriteCollectionStage>(mDocument.getData().getGmsts(), mState)); - appendStage (new WriteCollectionStage > - (mDocument.getData().getSkills(), mState)); + appendStage(new WriteCollectionStage>(mDocument.getData().getSkills(), mState)); - appendStage (new WriteCollectionStage > - (mDocument.getData().getClasses(), mState)); + appendStage(new WriteCollectionStage>(mDocument.getData().getClasses(), mState)); - appendStage (new WriteCollectionStage > - (mDocument.getData().getFactions(), mState)); + appendStage( + new WriteCollectionStage>(mDocument.getData().getFactions(), mState)); - appendStage (new WriteCollectionStage > - (mDocument.getData().getRaces(), mState)); + appendStage(new WriteCollectionStage>(mDocument.getData().getRaces(), mState)); - appendStage (new WriteCollectionStage > - (mDocument.getData().getSounds(), mState)); + appendStage(new WriteCollectionStage>(mDocument.getData().getSounds(), mState)); - appendStage (new WriteCollectionStage > - (mDocument.getData().getScripts(), mState)); + appendStage( + new WriteCollectionStage>(mDocument.getData().getScripts(), mState)); - appendStage (new WriteCollectionStage > - (mDocument.getData().getRegions(), mState)); + appendStage( + new WriteCollectionStage>(mDocument.getData().getRegions(), mState)); - appendStage (new WriteCollectionStage > - (mDocument.getData().getBirthsigns(), mState)); + appendStage( + new WriteCollectionStage>(mDocument.getData().getBirthsigns(), mState)); - appendStage (new WriteCollectionStage > - (mDocument.getData().getSpells(), mState)); + appendStage(new WriteCollectionStage>(mDocument.getData().getSpells(), mState)); - appendStage (new WriteCollectionStage > - (mDocument.getData().getEnchantments(), mState)); + appendStage(new WriteCollectionStage>( + mDocument.getData().getEnchantments(), mState)); - appendStage (new WriteCollectionStage > - (mDocument.getData().getBodyParts(), mState)); + appendStage( + new WriteCollectionStage>(mDocument.getData().getBodyParts(), mState)); - appendStage (new WriteCollectionStage > - (mDocument.getData().getSoundGens(), mState)); + appendStage(new WriteCollectionStage>( + mDocument.getData().getSoundGens(), mState)); - appendStage (new WriteCollectionStage > - (mDocument.getData().getMagicEffects(), mState)); + appendStage(new WriteCollectionStage>( + mDocument.getData().getMagicEffects(), mState)); - appendStage (new WriteCollectionStage > - (mDocument.getData().getStartScripts(), mState)); + appendStage(new WriteCollectionStage>( + mDocument.getData().getStartScripts(), mState)); - appendStage (new WriteRefIdCollectionStage (mDocument, mState)); + appendStage(new WriteRefIdCollectionStage(mDocument, mState)); - appendStage (new CollectionReferencesStage (mDocument, mState)); + appendStage(new CollectionReferencesStage(mDocument, mState)); - appendStage (new WriteCellCollectionStage (mDocument, mState)); + appendStage(new WriteCellCollectionStage(mDocument, mState)); // Dialogue can reference objects and cells so must be written after these records for vanilla-compatible files - appendStage (new WriteDialogueCollectionStage (mDocument, mState, false)); + appendStage(new WriteDialogueCollectionStage(mDocument, mState, false)); - appendStage (new WriteDialogueCollectionStage (mDocument, mState, true)); + appendStage(new WriteDialogueCollectionStage(mDocument, mState, true)); - appendStage (new WritePathgridCollectionStage (mDocument, mState)); + appendStage(new WritePathgridCollectionStage(mDocument, mState)); - appendStage (new WriteLandTextureCollectionStage (mDocument, mState)); + appendStage(new WriteLandTextureCollectionStage(mDocument, mState)); // references Land Textures - appendStage (new WriteLandCollectionStage (mDocument, mState)); + appendStage(new WriteLandCollectionStage(mDocument, mState)); // close file and clean up - appendStage (new CloseSaveStage (mState)); + appendStage(new CloseSaveStage(mState)); - appendStage (new FinalSavingStage (mDocument, mState)); + appendStage(new FinalSavingStage(mDocument, mState)); } diff --git a/apps/opencs/model/doc/saving.hpp b/apps/opencs/model/doc/saving.hpp index 0ec68dd942..cb22c4a62a 100644 --- a/apps/opencs/model/doc/saving.hpp +++ b/apps/opencs/model/doc/saving.hpp @@ -12,16 +12,13 @@ namespace CSMDoc class Saving : public Operation { - Q_OBJECT + Q_OBJECT - Document& mDocument; - SavingState mState; - - public: - - Saving (Document& document, const std::filesystem::path& projectPath, - ToUTF8::FromType encoding); + Document& mDocument; + SavingState mState; + public: + Saving(Document& document, const std::filesystem::path& projectPath, ToUTF8::FromType encoding); }; } diff --git a/apps/opencs/model/doc/savingstages.cpp b/apps/opencs/model/doc/savingstages.cpp index 841c930cf0..6f040b0ca3 100644 --- a/apps/opencs/model/doc/savingstages.cpp +++ b/apps/opencs/model/doc/savingstages.cpp @@ -1,48 +1,51 @@ #include "savingstages.hpp" -#include #include +#include #include #include -#include "../world/infocollection.hpp" #include "../world/cellcoordinates.hpp" +#include "../world/infocollection.hpp" #include "document.hpp" -CSMDoc::OpenSaveStage::OpenSaveStage (Document& document, SavingState& state, bool projectFile) -: mDocument (document), mState (state), mProjectFile (projectFile) -{} +CSMDoc::OpenSaveStage::OpenSaveStage(Document& document, SavingState& state, bool projectFile) + : mDocument(document) + , mState(state) + , mProjectFile(projectFile) +{ +} int CSMDoc::OpenSaveStage::setup() { return 1; } -void CSMDoc::OpenSaveStage::perform (int stage, Messages& messages) +void CSMDoc::OpenSaveStage::perform(int stage, Messages& messages) { - mState.start (mDocument, mProjectFile); + mState.start(mDocument, mProjectFile); - mState.getStream().open ( - mProjectFile ? mState.getPath() : mState.getTmpPath(), - std::ios::binary); + mState.getStream().open(mProjectFile ? mState.getPath() : mState.getTmpPath(), std::ios::binary); if (!mState.getStream().is_open()) - throw std::runtime_error ("failed to open stream for saving"); + throw std::runtime_error("failed to open stream for saving"); } - -CSMDoc::WriteHeaderStage::WriteHeaderStage (Document& document, SavingState& state, bool simple) -: mDocument (document), mState (state), mSimple (simple) -{} +CSMDoc::WriteHeaderStage::WriteHeaderStage(Document& document, SavingState& state, bool simple) + : mDocument(document) + , mState(state) + , mSimple(simple) +{ +} int CSMDoc::WriteHeaderStage::setup() { return 1; } -void CSMDoc::WriteHeaderStage::perform (int stage, Messages& messages) +void CSMDoc::WriteHeaderStage::perform(int stage, Messages& messages) { mState.getWriter().setVersion(); @@ -50,9 +53,9 @@ void CSMDoc::WriteHeaderStage::perform (int stage, Messages& messages) if (mSimple) { - mState.getWriter().setAuthor (""); - mState.getWriter().setDescription (""); - mState.getWriter().setRecordCount (0); + mState.getWriter().setAuthor(""); + mState.getWriter().setDescription(""); + mState.getWriter().setRecordCount(0); // ESM::Header::CurrentFormat is `1` but since new records are not yet used in opencs // we use the format `0` for compatibility with old versions. @@ -60,46 +63,43 @@ void CSMDoc::WriteHeaderStage::perform (int stage, Messages& messages) } else { - mDocument.getData().getMetaData().save (mState.getWriter()); - mState.getWriter().setRecordCount ( - mDocument.getData().count (CSMWorld::RecordBase::State_Modified) + - mDocument.getData().count (CSMWorld::RecordBase::State_ModifiedOnly) + - mDocument.getData().count (CSMWorld::RecordBase::State_Deleted)); + mDocument.getData().getMetaData().save(mState.getWriter()); + mState.getWriter().setRecordCount(mDocument.getData().count(CSMWorld::RecordBase::State_Modified) + + mDocument.getData().count(CSMWorld::RecordBase::State_ModifiedOnly) + + mDocument.getData().count(CSMWorld::RecordBase::State_Deleted)); /// \todo refine dependency list (at least remove redundant dependencies) std::vector dependencies = mDocument.getContentFiles(); - std::vector::const_iterator end (--dependencies.end()); + std::vector::const_iterator end(--dependencies.end()); - for (std::vector::const_iterator iter (dependencies.begin()); - iter!=end; ++iter) + for (std::vector::const_iterator iter(dependencies.begin()); iter != end; ++iter) { auto name = Files::pathToUnicodeString(iter->filename()); - auto size = std::filesystem::file_size (*iter); + auto size = std::filesystem::file_size(*iter); - mState.getWriter().addMaster (name, size); + mState.getWriter().addMaster(name, size); } } - mState.getWriter().save (mState.getStream()); + mState.getWriter().save(mState.getStream()); } - -CSMDoc::WriteDialogueCollectionStage::WriteDialogueCollectionStage (Document& document, - SavingState& state, bool journal) -: mState (state), - mTopics (journal ? document.getData().getJournals() : document.getData().getTopics()), - mInfos (journal ? document.getData().getJournalInfos() : document.getData().getTopicInfos()) -{} +CSMDoc::WriteDialogueCollectionStage::WriteDialogueCollectionStage(Document& document, SavingState& state, bool journal) + : mState(state) + , mTopics(journal ? document.getData().getJournals() : document.getData().getTopics()) + , mInfos(journal ? document.getData().getJournalInfos() : document.getData().getTopicInfos()) +{ +} int CSMDoc::WriteDialogueCollectionStage::setup() { return mTopics.getSize(); } -void CSMDoc::WriteDialogueCollectionStage::perform (int stage, Messages& messages) +void CSMDoc::WriteDialogueCollectionStage::perform(int stage, Messages& messages) { ESM::ESMWriter& writer = mState.getWriter(); - const CSMWorld::Record& topic = mTopics.getRecord (stage); + const CSMWorld::Record& topic = mTopics.getRecord(stage); if (topic.mState == CSMWorld::RecordBase::State_Deleted) { @@ -113,9 +113,9 @@ void CSMDoc::WriteDialogueCollectionStage::perform (int stage, Messages& message // Test, if we need to save anything associated info records. bool infoModified = false; - CSMWorld::InfoCollection::Range range = mInfos.getTopicRange (topic.get().mId); + CSMWorld::InfoCollection::Range range = mInfos.getTopicRange(topic.get().mId); - for (CSMWorld::InfoCollection::RecordConstIterator iter (range.first); iter!=range.second; ++iter) + for (CSMWorld::InfoCollection::RecordConstIterator iter(range.first); iter != range.second; ++iter) { if ((*iter)->isModified() || (*iter)->mState == CSMWorld::RecordBase::State_Deleted) { @@ -127,73 +127,74 @@ void CSMDoc::WriteDialogueCollectionStage::perform (int stage, Messages& message if (topic.isModified() || infoModified) { if (infoModified && topic.mState != CSMWorld::RecordBase::State_Modified - && topic.mState != CSMWorld::RecordBase::State_ModifiedOnly) + && topic.mState != CSMWorld::RecordBase::State_ModifiedOnly) { - mState.getWriter().startRecord (topic.mBase.sRecordId); - topic.mBase.save (mState.getWriter(), topic.mState == CSMWorld::RecordBase::State_Deleted); - mState.getWriter().endRecord (topic.mBase.sRecordId); + mState.getWriter().startRecord(topic.mBase.sRecordId); + topic.mBase.save(mState.getWriter(), topic.mState == CSMWorld::RecordBase::State_Deleted); + mState.getWriter().endRecord(topic.mBase.sRecordId); } else { - mState.getWriter().startRecord (topic.mModified.sRecordId); - topic.mModified.save (mState.getWriter(), topic.mState == CSMWorld::RecordBase::State_Deleted); - mState.getWriter().endRecord (topic.mModified.sRecordId); + mState.getWriter().startRecord(topic.mModified.sRecordId); + topic.mModified.save(mState.getWriter(), topic.mState == CSMWorld::RecordBase::State_Deleted); + mState.getWriter().endRecord(topic.mModified.sRecordId); } // write modified selected info records - for (CSMWorld::InfoCollection::RecordConstIterator iter (range.first); iter!=range.second; ++iter) + for (CSMWorld::InfoCollection::RecordConstIterator iter(range.first); iter != range.second; ++iter) { if ((*iter)->isModified() || (*iter)->mState == CSMWorld::RecordBase::State_Deleted) { ESM::DialInfo info = (*iter)->get(); - info.mId = info.mId.substr (info.mId.find_last_of ('#')+1); + info.mId = info.mId.substr(info.mId.find_last_of('#') + 1); info.mPrev.clear(); - if (iter!=range.first) + if (iter != range.first) { CSMWorld::InfoCollection::RecordConstIterator prev = iter; --prev; - info.mPrev = (*prev)->get().mId.substr ((*prev)->get().mId.find_last_of ('#')+1); + info.mPrev = (*prev)->get().mId.substr((*prev)->get().mId.find_last_of('#') + 1); } CSMWorld::InfoCollection::RecordConstIterator next = iter; ++next; info.mNext.clear(); - if (next!=range.second) + if (next != range.second) { - info.mNext = (*next)->get().mId.substr ((*next)->get().mId.find_last_of ('#')+1); + info.mNext = (*next)->get().mId.substr((*next)->get().mId.find_last_of('#') + 1); } - writer.startRecord (info.sRecordId); - info.save (writer, (*iter)->mState == CSMWorld::RecordBase::State_Deleted); - writer.endRecord (info.sRecordId); + writer.startRecord(info.sRecordId); + info.save(writer, (*iter)->mState == CSMWorld::RecordBase::State_Deleted); + writer.endRecord(info.sRecordId); } } } } - -CSMDoc::WriteRefIdCollectionStage::WriteRefIdCollectionStage (Document& document, SavingState& state) -: mDocument (document), mState (state) -{} +CSMDoc::WriteRefIdCollectionStage::WriteRefIdCollectionStage(Document& document, SavingState& state) + : mDocument(document) + , mState(state) +{ +} int CSMDoc::WriteRefIdCollectionStage::setup() { return mDocument.getData().getReferenceables().getSize(); } -void CSMDoc::WriteRefIdCollectionStage::perform (int stage, Messages& messages) +void CSMDoc::WriteRefIdCollectionStage::perform(int stage, Messages& messages) { - mDocument.getData().getReferenceables().save (stage, mState.getWriter()); + mDocument.getData().getReferenceables().save(stage, mState.getWriter()); } - -CSMDoc::CollectionReferencesStage::CollectionReferencesStage (Document& document, - SavingState& state) -: mDocument (document), mState (state) -{} +CSMDoc::CollectionReferencesStage::CollectionReferencesStage(Document& document, SavingState& state) + : mDocument(document) + , mState(state) +{ +} int CSMDoc::CollectionReferencesStage::setup() { @@ -201,31 +202,29 @@ int CSMDoc::CollectionReferencesStage::setup() int size = mDocument.getData().getReferences().getSize(); - int steps = size/100; - if (size%100) ++steps; + int steps = size / 100; + if (size % 100) + ++steps; return steps; } -void CSMDoc::CollectionReferencesStage::perform (int stage, Messages& messages) +void CSMDoc::CollectionReferencesStage::perform(int stage, Messages& messages) { int size = mDocument.getData().getReferences().getSize(); - for (int i=stage*100; i& record = - mDocument.getData().getReferences().getRecord (i); + const CSMWorld::Record& record = mDocument.getData().getReferences().getRecord(i); if (record.isModified() || record.mState == CSMWorld::RecordBase::State_Deleted) { - std::string cellId = record.get().mOriginalCell.empty() ? - record.get().mCell : record.get().mOriginalCell; + std::string cellId = record.get().mOriginalCell.empty() ? record.get().mCell : record.get().mOriginalCell; - std::deque& indices = - mState.getSubRecords()[Misc::StringUtils::lowerCase (cellId)]; + std::deque& indices = mState.getSubRecords()[Misc::StringUtils::lowerCase(cellId)]; // collect moved references at the end of the container - bool interior = cellId.substr (0, 1)!="#"; + bool interior = cellId.substr(0, 1) != "#"; std::ostringstream stream; if (!interior) { @@ -236,35 +235,34 @@ void CSMDoc::CollectionReferencesStage::perform (int stage, Messages& messages) // An empty mOriginalCell is meant to indicate that it is the same as // the current cell. It is possible that a moved ref is moved again. - if ((record.get().mOriginalCell.empty() ? - record.get().mCell : record.get().mOriginalCell) != stream.str() && !interior && record.mState!=CSMWorld::RecordBase::State_ModifiedOnly && !record.get().mNew) - indices.push_back (i); + if ((record.get().mOriginalCell.empty() ? record.get().mCell : record.get().mOriginalCell) != stream.str() + && !interior && record.mState != CSMWorld::RecordBase::State_ModifiedOnly && !record.get().mNew) + indices.push_back(i); else - indices.push_front (i); + indices.push_front(i); } } } - -CSMDoc::WriteCellCollectionStage::WriteCellCollectionStage (Document& document, - SavingState& state) -: mDocument (document), mState (state) -{} +CSMDoc::WriteCellCollectionStage::WriteCellCollectionStage(Document& document, SavingState& state) + : mDocument(document) + , mState(state) +{ +} int CSMDoc::WriteCellCollectionStage::setup() { return mDocument.getData().getCells().getSize(); } -void CSMDoc::WriteCellCollectionStage::writeReferences (const std::deque& references, bool interior, unsigned int& newRefNum) +void CSMDoc::WriteCellCollectionStage::writeReferences( + const std::deque& references, bool interior, unsigned int& newRefNum) { ESM::ESMWriter& writer = mState.getWriter(); - for (std::deque::const_iterator iter (references.begin()); - iter!=references.end(); ++iter) + for (std::deque::const_iterator iter(references.begin()); iter != references.end(); ++iter) { - const CSMWorld::Record& ref = - mDocument.getData().getReferences().getRecord (*iter); + const CSMWorld::Record& ref = mDocument.getData().getReferences().getRecord(*iter); if (ref.isModified() || ref.mState == CSMWorld::RecordBase::State_Deleted) { @@ -282,14 +280,14 @@ void CSMDoc::WriteCellCollectionStage::writeReferences (const std::deque& r stream << "#" << index.first << " " << index.second; } - if (refRecord.mNew || refRecord.mRefNum.mIndex == 0 || - (!interior && ref.mState==CSMWorld::RecordBase::State_ModifiedOnly && - refRecord.mCell!=stream.str())) + if (refRecord.mNew || refRecord.mRefNum.mIndex == 0 + || (!interior && ref.mState == CSMWorld::RecordBase::State_ModifiedOnly + && refRecord.mCell != stream.str())) { refRecord.mRefNum.mIndex = newRefNum++; } - else if ((refRecord.mOriginalCell.empty() ? refRecord.mCell : refRecord.mOriginalCell) - != stream.str() && !interior) + else if ((refRecord.mOriginalCell.empty() ? refRecord.mCell : refRecord.mOriginalCell) != stream.str() + && !interior) { // An empty mOriginalCell is meant to indicate that it is the same as // the current cell. It is possible that a moved ref is moved again. @@ -298,57 +296,54 @@ void CSMDoc::WriteCellCollectionStage::writeReferences (const std::deque& r moved.mRefNum = refRecord.mRefNum; // Need to fill mTarget with the ref's new position. - std::istringstream istream (stream.str().c_str()); + std::istringstream istream(stream.str().c_str()); char ignore; istream >> ignore >> moved.mTarget[0] >> moved.mTarget[1]; - refRecord.mRefNum.save (writer, false, "MVRF"); - writer.writeHNT ("CNDT", moved.mTarget); + refRecord.mRefNum.save(writer, false, "MVRF"); + writer.writeHNT("CNDT", moved.mTarget); } - refRecord.save (writer, false, false, ref.mState == CSMWorld::RecordBase::State_Deleted); + refRecord.save(writer, false, false, ref.mState == CSMWorld::RecordBase::State_Deleted); } } } -void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages) +void CSMDoc::WriteCellCollectionStage::perform(int stage, Messages& messages) { ESM::ESMWriter& writer = mState.getWriter(); - const CSMWorld::Record& cell = mDocument.getData().getCells().getRecord (stage); + const CSMWorld::Record& cell = mDocument.getData().getCells().getRecord(stage); const CSMWorld::RefIdCollection& referenceables = mDocument.getData().getReferenceables(); const CSMWorld::RefIdData& refIdData = referenceables.getDataSet(); std::deque tempRefs; std::deque persistentRefs; - std::map >::const_iterator references = - mState.getSubRecords().find (Misc::StringUtils::lowerCase (cell.get().mId)); + std::map>::const_iterator references + = mState.getSubRecords().find(Misc::StringUtils::lowerCase(cell.get().mId)); - if (cell.isModified() || - cell.mState == CSMWorld::RecordBase::State_Deleted || - references!=mState.getSubRecords().end()) + if (cell.isModified() || cell.mState == CSMWorld::RecordBase::State_Deleted + || references != mState.getSubRecords().end()) { CSMWorld::Cell cellRecord = cell.get(); - bool interior = cellRecord.mId.substr (0, 1)!="#"; + bool interior = cellRecord.mId.substr(0, 1) != "#"; // count new references and adjust RefNumCount accordingsly unsigned int newRefNum = cellRecord.mRefNumCounter; - if (references!=mState.getSubRecords().end()) + if (references != mState.getSubRecords().end()) { - for (std::deque::const_iterator iter (references->second.begin()); - iter!=references->second.end(); ++iter) + for (std::deque::const_iterator iter(references->second.begin()); iter != references->second.end(); + ++iter) { - const CSMWorld::Record& ref = - mDocument.getData().getReferences().getRecord (*iter); + const CSMWorld::Record& ref = mDocument.getData().getReferences().getRecord(*iter); CSMWorld::CellRef refRecord = ref.get(); CSMWorld::RefIdData::LocalIndex localIndex = refIdData.searchId(refRecord.mRefID); unsigned int recordFlags = refIdData.getRecordFlags(refRecord.mRefID); - bool isPersistent = ((recordFlags & ESM::FLAG_Persistent) != 0) - || refRecord.mTeleport + bool isPersistent = ((recordFlags & ESM::FLAG_Persistent) != 0) || refRecord.mTeleport || localIndex.second == CSMWorld::UniversalId::Type_Creature || localIndex.second == CSMWorld::UniversalId::Type_Npc; @@ -357,10 +352,10 @@ void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages) else tempRefs.push_back(*iter); - if (refRecord.mNew || - (!interior && ref.mState==CSMWorld::RecordBase::State_ModifiedOnly && - /// \todo consider worldspace - CSMWorld::CellCoordinates (refRecord.getCellIndex()).getId("") != refRecord.mCell)) + if (refRecord.mNew + || (!interior && ref.mState == CSMWorld::RecordBase::State_ModifiedOnly && + /// \todo consider worldspace + CSMWorld::CellCoordinates(refRecord.getCellIndex()).getId("") != refRecord.mCell)) ++cellRecord.mRefNumCounter; if (refRecord.mRefNum.mIndex >= newRefNum) @@ -369,7 +364,7 @@ void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages) } // write cell data - writer.startRecord (cellRecord.sRecordId); + writer.startRecord(cellRecord.sRecordId); if (interior) cellRecord.mData.mFlags |= ESM::Cell::Interior; @@ -377,157 +372,155 @@ void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages) { cellRecord.mData.mFlags &= ~ESM::Cell::Interior; - std::istringstream stream (cellRecord.mId.c_str()); + std::istringstream stream(cellRecord.mId.c_str()); char ignore; stream >> ignore >> cellRecord.mData.mX >> cellRecord.mData.mY; } - cellRecord.save (writer, cell.mState == CSMWorld::RecordBase::State_Deleted); + cellRecord.save(writer, cell.mState == CSMWorld::RecordBase::State_Deleted); // write references - if (references!=mState.getSubRecords().end()) + if (references != mState.getSubRecords().end()) { writeReferences(persistentRefs, interior, newRefNum); cellRecord.saveTempMarker(writer, int(references->second.size()) - persistentRefs.size()); writeReferences(tempRefs, interior, newRefNum); } - writer.endRecord (cellRecord.sRecordId); + writer.endRecord(cellRecord.sRecordId); } } - -CSMDoc::WritePathgridCollectionStage::WritePathgridCollectionStage (Document& document, - SavingState& state) -: mDocument (document), mState (state) -{} +CSMDoc::WritePathgridCollectionStage::WritePathgridCollectionStage(Document& document, SavingState& state) + : mDocument(document) + , mState(state) +{ +} int CSMDoc::WritePathgridCollectionStage::setup() { return mDocument.getData().getPathgrids().getSize(); } -void CSMDoc::WritePathgridCollectionStage::perform (int stage, Messages& messages) +void CSMDoc::WritePathgridCollectionStage::perform(int stage, Messages& messages) { ESM::ESMWriter& writer = mState.getWriter(); - const CSMWorld::Record& pathgrid = - mDocument.getData().getPathgrids().getRecord (stage); + const CSMWorld::Record& pathgrid = mDocument.getData().getPathgrids().getRecord(stage); if (pathgrid.isModified() || pathgrid.mState == CSMWorld::RecordBase::State_Deleted) { CSMWorld::Pathgrid record = pathgrid.get(); - if (record.mId.substr (0, 1)=="#") + if (record.mId.substr(0, 1) == "#") { - std::istringstream stream (record.mId.c_str()); + std::istringstream stream(record.mId.c_str()); char ignore; stream >> ignore >> record.mData.mX >> record.mData.mY; } else record.mCell = record.mId; - writer.startRecord (record.sRecordId); - record.save (writer, pathgrid.mState == CSMWorld::RecordBase::State_Deleted); - writer.endRecord (record.sRecordId); + writer.startRecord(record.sRecordId); + record.save(writer, pathgrid.mState == CSMWorld::RecordBase::State_Deleted); + writer.endRecord(record.sRecordId); } } - -CSMDoc::WriteLandCollectionStage::WriteLandCollectionStage (Document& document, - SavingState& state) -: mDocument (document), mState (state) -{} +CSMDoc::WriteLandCollectionStage::WriteLandCollectionStage(Document& document, SavingState& state) + : mDocument(document) + , mState(state) +{ +} int CSMDoc::WriteLandCollectionStage::setup() { return mDocument.getData().getLand().getSize(); } -void CSMDoc::WriteLandCollectionStage::perform (int stage, Messages& messages) +void CSMDoc::WriteLandCollectionStage::perform(int stage, Messages& messages) { ESM::ESMWriter& writer = mState.getWriter(); - const CSMWorld::Record& land = - mDocument.getData().getLand().getRecord (stage); + const CSMWorld::Record& land = mDocument.getData().getLand().getRecord(stage); if (land.isModified() || land.mState == CSMWorld::RecordBase::State_Deleted) { CSMWorld::Land record = land.get(); - writer.startRecord (record.sRecordId); - record.save (writer, land.mState == CSMWorld::RecordBase::State_Deleted); - writer.endRecord (record.sRecordId); + writer.startRecord(record.sRecordId); + record.save(writer, land.mState == CSMWorld::RecordBase::State_Deleted); + writer.endRecord(record.sRecordId); } } - -CSMDoc::WriteLandTextureCollectionStage::WriteLandTextureCollectionStage (Document& document, - SavingState& state) -: mDocument (document), mState (state) -{} +CSMDoc::WriteLandTextureCollectionStage::WriteLandTextureCollectionStage(Document& document, SavingState& state) + : mDocument(document) + , mState(state) +{ +} int CSMDoc::WriteLandTextureCollectionStage::setup() { return mDocument.getData().getLandTextures().getSize(); } -void CSMDoc::WriteLandTextureCollectionStage::perform (int stage, Messages& messages) +void CSMDoc::WriteLandTextureCollectionStage::perform(int stage, Messages& messages) { ESM::ESMWriter& writer = mState.getWriter(); - const CSMWorld::Record& landTexture = - mDocument.getData().getLandTextures().getRecord (stage); + const CSMWorld::Record& landTexture = mDocument.getData().getLandTextures().getRecord(stage); if (landTexture.isModified() || landTexture.mState == CSMWorld::RecordBase::State_Deleted) { CSMWorld::LandTexture record = landTexture.get(); - writer.startRecord (record.sRecordId); - record.save (writer, landTexture.mState == CSMWorld::RecordBase::State_Deleted); - writer.endRecord (record.sRecordId); + writer.startRecord(record.sRecordId); + record.save(writer, landTexture.mState == CSMWorld::RecordBase::State_Deleted); + writer.endRecord(record.sRecordId); } } - -CSMDoc::CloseSaveStage::CloseSaveStage (SavingState& state) -: mState (state) -{} +CSMDoc::CloseSaveStage::CloseSaveStage(SavingState& state) + : mState(state) +{ +} int CSMDoc::CloseSaveStage::setup() { return 1; } -void CSMDoc::CloseSaveStage::perform (int stage, Messages& messages) +void CSMDoc::CloseSaveStage::perform(int stage, Messages& messages) { mState.getStream().close(); if (!mState.getStream()) - throw std::runtime_error ("saving failed"); + throw std::runtime_error("saving failed"); } - -CSMDoc::FinalSavingStage::FinalSavingStage (Document& document, SavingState& state) -: mDocument (document), mState (state) -{} +CSMDoc::FinalSavingStage::FinalSavingStage(Document& document, SavingState& state) + : mDocument(document) + , mState(state) +{ +} int CSMDoc::FinalSavingStage::setup() { return 1; } -void CSMDoc::FinalSavingStage::perform (int stage, Messages& messages) +void CSMDoc::FinalSavingStage::perform(int stage, Messages& messages) { if (mState.hasError()) { mState.getWriter().close(); mState.getStream().close(); - if (std::filesystem::exists (mState.getTmpPath())) - std::filesystem::remove (mState.getTmpPath()); + if (std::filesystem::exists(mState.getTmpPath())) + std::filesystem::remove(mState.getTmpPath()); } else if (!mState.isProjectFile()) { - if (std::filesystem::exists (mState.getPath())) - std::filesystem::remove (mState.getPath()); + if (std::filesystem::exists(mState.getPath())) + std::filesystem::remove(mState.getPath()); - std::filesystem::rename (mState.getTmpPath(), mState.getPath()); + std::filesystem::rename(mState.getTmpPath(), mState.getPath()); mDocument.getUndoStack().setClean(); } diff --git a/apps/opencs/model/doc/savingstages.hpp b/apps/opencs/model/doc/savingstages.hpp index 9ccd1772e1..90ada3d502 100644 --- a/apps/opencs/model/doc/savingstages.hpp +++ b/apps/opencs/model/doc/savingstages.hpp @@ -3,8 +3,8 @@ #include "stage.hpp" -#include "../world/record.hpp" #include "../world/idcollection.hpp" +#include "../world/record.hpp" #include "../world/scope.hpp" #include @@ -28,242 +28,225 @@ namespace CSMDoc class OpenSaveStage : public Stage { - Document& mDocument; - SavingState& mState; - bool mProjectFile; - - public: + Document& mDocument; + SavingState& mState; + bool mProjectFile; - OpenSaveStage (Document& document, SavingState& state, bool projectFile); - ///< \param projectFile Saving the project file instead of the content file. + public: + OpenSaveStage(Document& document, SavingState& state, bool projectFile); + ///< \param projectFile Saving the project file instead of the content file. - int setup() override; - ///< \return number of steps + int setup() override; + ///< \return number of steps - void perform (int stage, Messages& messages) override; - ///< Messages resulting from this stage will be appended to \a messages. + void perform(int stage, Messages& messages) override; + ///< Messages resulting from this stage will be appended to \a messages. }; class WriteHeaderStage : public Stage { - Document& mDocument; - SavingState& mState; - bool mSimple; + Document& mDocument; + SavingState& mState; + bool mSimple; - public: + public: + WriteHeaderStage(Document& document, SavingState& state, bool simple); + ///< \param simple Simplified header (used for project files). - WriteHeaderStage (Document& document, SavingState& state, bool simple); - ///< \param simple Simplified header (used for project files). + int setup() override; + ///< \return number of steps - int setup() override; - ///< \return number of steps - - void perform (int stage, Messages& messages) override; - ///< Messages resulting from this stage will be appended to \a messages. + void perform(int stage, Messages& messages) override; + ///< Messages resulting from this stage will be appended to \a messages. }; - - template + template class WriteCollectionStage : public Stage { - const CollectionT& mCollection; - SavingState& mState; - CSMWorld::Scope mScope; - - public: + const CollectionT& mCollection; + SavingState& mState; + CSMWorld::Scope mScope; - WriteCollectionStage (const CollectionT& collection, SavingState& state, - CSMWorld::Scope scope = CSMWorld::Scope_Content); + public: + WriteCollectionStage( + const CollectionT& collection, SavingState& state, CSMWorld::Scope scope = CSMWorld::Scope_Content); - int setup() override; - ///< \return number of steps + int setup() override; + ///< \return number of steps - void perform (int stage, Messages& messages) override; - ///< Messages resulting from this stage will be appended to \a messages. + void perform(int stage, Messages& messages) override; + ///< Messages resulting from this stage will be appended to \a messages. }; - template - WriteCollectionStage::WriteCollectionStage (const CollectionT& collection, - SavingState& state, CSMWorld::Scope scope) - : mCollection (collection), mState (state), mScope (scope) - {} + template + WriteCollectionStage::WriteCollectionStage( + const CollectionT& collection, SavingState& state, CSMWorld::Scope scope) + : mCollection(collection) + , mState(state) + , mScope(scope) + { + } - template + template int WriteCollectionStage::setup() { return mCollection.getSize(); } - template - void WriteCollectionStage::perform (int stage, Messages& messages) + template + void WriteCollectionStage::perform(int stage, Messages& messages) { - if (CSMWorld::getScopeFromId (mCollection.getRecord (stage).get().mId)!=mScope) + if (CSMWorld::getScopeFromId(mCollection.getRecord(stage).get().mId) != mScope) return; ESM::ESMWriter& writer = mState.getWriter(); - CSMWorld::RecordBase::State state = mCollection.getRecord (stage).mState; - typename CollectionT::ESXRecord record = mCollection.getRecord (stage).get(); + CSMWorld::RecordBase::State state = mCollection.getRecord(stage).mState; + typename CollectionT::ESXRecord record = mCollection.getRecord(stage).get(); - if (state == CSMWorld::RecordBase::State_Modified || - state == CSMWorld::RecordBase::State_ModifiedOnly || - state == CSMWorld::RecordBase::State_Deleted) + if (state == CSMWorld::RecordBase::State_Modified || state == CSMWorld::RecordBase::State_ModifiedOnly + || state == CSMWorld::RecordBase::State_Deleted) { - writer.startRecord (record.sRecordId, record.mRecordFlags); - record.save (writer, state == CSMWorld::RecordBase::State_Deleted); - writer.endRecord (record.sRecordId); + writer.startRecord(record.sRecordId, record.mRecordFlags); + record.save(writer, state == CSMWorld::RecordBase::State_Deleted); + writer.endRecord(record.sRecordId); } } - class WriteDialogueCollectionStage : public Stage { - SavingState& mState; - const CSMWorld::IdCollection& mTopics; - CSMWorld::InfoCollection& mInfos; + SavingState& mState; + const CSMWorld::IdCollection& mTopics; + CSMWorld::InfoCollection& mInfos; - public: + public: + WriteDialogueCollectionStage(Document& document, SavingState& state, bool journal); - WriteDialogueCollectionStage (Document& document, SavingState& state, bool journal); + int setup() override; + ///< \return number of steps - int setup() override; - ///< \return number of steps - - void perform (int stage, Messages& messages) override; - ///< Messages resulting from this stage will be appended to \a messages. + void perform(int stage, Messages& messages) override; + ///< Messages resulting from this stage will be appended to \a messages. }; - class WriteRefIdCollectionStage : public Stage { - Document& mDocument; - SavingState& mState; - - public: + Document& mDocument; + SavingState& mState; - WriteRefIdCollectionStage (Document& document, SavingState& state); + public: + WriteRefIdCollectionStage(Document& document, SavingState& state); - int setup() override; - ///< \return number of steps + int setup() override; + ///< \return number of steps - void perform (int stage, Messages& messages) override; - ///< Messages resulting from this stage will be appended to \a messages. + void perform(int stage, Messages& messages) override; + ///< Messages resulting from this stage will be appended to \a messages. }; - class CollectionReferencesStage : public Stage { - Document& mDocument; - SavingState& mState; - - public: + Document& mDocument; + SavingState& mState; - CollectionReferencesStage (Document& document, SavingState& state); + public: + CollectionReferencesStage(Document& document, SavingState& state); - int setup() override; - ///< \return number of steps + int setup() override; + ///< \return number of steps - void perform (int stage, Messages& messages) override; - ///< Messages resulting from this stage will be appended to \a messages. + void perform(int stage, Messages& messages) override; + ///< Messages resulting from this stage will be appended to \a messages. }; class WriteCellCollectionStage : public Stage { - Document& mDocument; - SavingState& mState; - - void writeReferences (const std::deque& references, bool interior, unsigned int& newRefNum); + Document& mDocument; + SavingState& mState; - public: + void writeReferences(const std::deque& references, bool interior, unsigned int& newRefNum); - WriteCellCollectionStage (Document& document, SavingState& state); + public: + WriteCellCollectionStage(Document& document, SavingState& state); - int setup() override; - ///< \return number of steps + int setup() override; + ///< \return number of steps - void perform (int stage, Messages& messages) override; - ///< Messages resulting from this stage will be appended to \a messages. + void perform(int stage, Messages& messages) override; + ///< Messages resulting from this stage will be appended to \a messages. }; - class WritePathgridCollectionStage : public Stage { - Document& mDocument; - SavingState& mState; - - public: + Document& mDocument; + SavingState& mState; - WritePathgridCollectionStage (Document& document, SavingState& state); + public: + WritePathgridCollectionStage(Document& document, SavingState& state); - int setup() override; - ///< \return number of steps + int setup() override; + ///< \return number of steps - void perform (int stage, Messages& messages) override; - ///< Messages resulting from this stage will be appended to \a messages. + void perform(int stage, Messages& messages) override; + ///< Messages resulting from this stage will be appended to \a messages. }; - class WriteLandCollectionStage : public Stage { - Document& mDocument; - SavingState& mState; + Document& mDocument; + SavingState& mState; - public: + public: + WriteLandCollectionStage(Document& document, SavingState& state); - WriteLandCollectionStage (Document& document, SavingState& state); + int setup() override; + ///< \return number of steps - int setup() override; - ///< \return number of steps - - void perform (int stage, Messages& messages) override; - ///< Messages resulting from this stage will be appended to \a messages. + void perform(int stage, Messages& messages) override; + ///< Messages resulting from this stage will be appended to \a messages. }; - class WriteLandTextureCollectionStage : public Stage { - Document& mDocument; - SavingState& mState; - - public: + Document& mDocument; + SavingState& mState; - WriteLandTextureCollectionStage (Document& document, SavingState& state); + public: + WriteLandTextureCollectionStage(Document& document, SavingState& state); - int setup() override; - ///< \return number of steps + int setup() override; + ///< \return number of steps - void perform (int stage, Messages& messages) override; - ///< Messages resulting from this stage will be appended to \a messages. + void perform(int stage, Messages& messages) override; + ///< Messages resulting from this stage will be appended to \a messages. }; class CloseSaveStage : public Stage { - SavingState& mState; + SavingState& mState; - public: + public: + CloseSaveStage(SavingState& state); - CloseSaveStage (SavingState& state); + int setup() override; + ///< \return number of steps - int setup() override; - ///< \return number of steps - - void perform (int stage, Messages& messages) override; - ///< Messages resulting from this stage will be appended to \a messages. + void perform(int stage, Messages& messages) override; + ///< Messages resulting from this stage will be appended to \a messages. }; class FinalSavingStage : public Stage { - Document& mDocument; - SavingState& mState; - - public: + Document& mDocument; + SavingState& mState; - FinalSavingStage (Document& document, SavingState& state); + public: + FinalSavingStage(Document& document, SavingState& state); - int setup() override; - ///< \return number of steps + int setup() override; + ///< \return number of steps - void perform (int stage, Messages& messages) override; - ///< Messages resulting from this stage will be appended to \a messages. + void perform(int stage, Messages& messages) override; + ///< Messages resulting from this stage will be appended to \a messages. }; } diff --git a/apps/opencs/model/doc/savingstate.cpp b/apps/opencs/model/doc/savingstate.cpp index e9a2b55385..283f624242 100644 --- a/apps/opencs/model/doc/savingstate.cpp +++ b/apps/opencs/model/doc/savingstate.cpp @@ -3,14 +3,16 @@ #include #include -#include "operation.hpp" #include "document.hpp" +#include "operation.hpp" -CSMDoc::SavingState::SavingState (Operation& operation, std::filesystem::path projectPath, - ToUTF8::FromType encoding) -: mOperation (operation), mEncoder (encoding), mProjectPath (std::move(projectPath)), mProjectFile (false) +CSMDoc::SavingState::SavingState(Operation& operation, std::filesystem::path projectPath, ToUTF8::FromType encoding) + : mOperation(operation) + , mEncoder(encoding) + , mProjectPath(std::move(projectPath)) + , mProjectFile(false) { - mWriter.setEncoder (&mEncoder); + mWriter.setEncoder(&mEncoder); } bool CSMDoc::SavingState::hasError() const @@ -18,7 +20,7 @@ bool CSMDoc::SavingState::hasError() const return mOperation.hasError(); } -void CSMDoc::SavingState::start (Document& document, bool project) +void CSMDoc::SavingState::start(Document& document, bool project) { mProjectFile = project; @@ -34,7 +36,7 @@ void CSMDoc::SavingState::start (Document& document, bool project) else mPath = document.getSavePath(); - std::filesystem::path file (mPath.filename().u8string() + u8".tmp"); + std::filesystem::path file(mPath.filename().u8string() + u8".tmp"); mTmpPath = mPath.parent_path(); @@ -66,7 +68,7 @@ bool CSMDoc::SavingState::isProjectFile() const return mProjectFile; } -std::map >& CSMDoc::SavingState::getSubRecords() +std::map>& CSMDoc::SavingState::getSubRecords() { return mSubRecords; } diff --git a/apps/opencs/model/doc/savingstate.hpp b/apps/opencs/model/doc/savingstate.hpp index d05c6d504c..2ddc782a4b 100644 --- a/apps/opencs/model/doc/savingstate.hpp +++ b/apps/opencs/model/doc/savingstate.hpp @@ -1,10 +1,10 @@ #ifndef CSM_DOC_SAVINGSTATE_H #define CSM_DOC_SAVINGSTATE_H -#include -#include #include #include +#include +#include #include @@ -17,41 +17,38 @@ namespace CSMDoc class SavingState { - Operation& mOperation; - std::filesystem::path mPath; - std::filesystem::path mTmpPath; - ToUTF8::Utf8Encoder mEncoder; - std::ofstream mStream; - ESM::ESMWriter mWriter; - std::filesystem::path mProjectPath; - bool mProjectFile; - std::map > mSubRecords; // record ID, list of subrecords - - public: + Operation& mOperation; + std::filesystem::path mPath; + std::filesystem::path mTmpPath; + ToUTF8::Utf8Encoder mEncoder; + std::ofstream mStream; + ESM::ESMWriter mWriter; + std::filesystem::path mProjectPath; + bool mProjectFile; + std::map> mSubRecords; // record ID, list of subrecords - SavingState (Operation& operation, std::filesystem::path projectPath, - ToUTF8::FromType encoding); + public: + SavingState(Operation& operation, std::filesystem::path projectPath, ToUTF8::FromType encoding); - bool hasError() const; + bool hasError() const; - void start (Document& document, bool project); - ///< \param project Save project file instead of content file. + void start(Document& document, bool project); + ///< \param project Save project file instead of content file. - const std::filesystem::path& getPath() const; + const std::filesystem::path& getPath() const; - const std::filesystem::path& getTmpPath() const; + const std::filesystem::path& getTmpPath() const; - std::ofstream& getStream(); + std::ofstream& getStream(); - ESM::ESMWriter& getWriter(); + ESM::ESMWriter& getWriter(); - bool isProjectFile() const; - ///< Currently saving project file? (instead of content file) + bool isProjectFile() const; + ///< Currently saving project file? (instead of content file) - std::map >& getSubRecords(); + std::map>& getSubRecords(); }; - } #endif diff --git a/apps/opencs/model/doc/stage.hpp b/apps/opencs/model/doc/stage.hpp index 950019ce9a..d8f8a77c43 100644 --- a/apps/opencs/model/doc/stage.hpp +++ b/apps/opencs/model/doc/stage.hpp @@ -1,8 +1,8 @@ #ifndef CSM_DOC_STAGE_H #define CSM_DOC_STAGE_H -#include #include +#include #include "messages.hpp" @@ -12,15 +12,14 @@ namespace CSMDoc { class Stage { - public: - - virtual ~Stage(); + public: + virtual ~Stage(); - virtual int setup() = 0; - ///< \return number of steps + virtual int setup() = 0; + ///< \return number of steps - virtual void perform (int stage, Messages& messages) = 0; - ///< Messages resulting from this stage will be appended to \a messages. + virtual void perform(int stage, Messages& messages) = 0; + ///< Messages resulting from this stage will be appended to \a messages. }; } diff --git a/apps/opencs/model/doc/state.hpp b/apps/opencs/model/doc/state.hpp index 7352b4b999..9d53fa816b 100644 --- a/apps/opencs/model/doc/state.hpp +++ b/apps/opencs/model/doc/state.hpp @@ -14,7 +14,7 @@ namespace CSMDoc State_Verifying = 32, State_Merging = 64, State_Searching = 128, - State_Loading = 256 // pseudo-state; can not be encountered in a loaded document + State_Loading = 256 // pseudo-state; can not be encountered in a loaded document }; } diff --git a/apps/opencs/model/filter/andnode.cpp b/apps/opencs/model/filter/andnode.cpp index 508202edfc..c2fd79a7bd 100644 --- a/apps/opencs/model/filter/andnode.cpp +++ b/apps/opencs/model/filter/andnode.cpp @@ -1,16 +1,16 @@ #include "andnode.hpp" -CSMFilter::AndNode::AndNode (const std::vector >& nodes) -: NAryNode (nodes, "and") -{} +CSMFilter::AndNode::AndNode(const std::vector>& nodes) + : NAryNode(nodes, "and") +{ +} -bool CSMFilter::AndNode::test (const CSMWorld::IdTableBase& table, int row, - const std::map& columns) const +bool CSMFilter::AndNode::test(const CSMWorld::IdTableBase& table, int row, const std::map& columns) const { int size = getSize(); - for (int i=0; i>& nodes); - AndNode (const std::vector >& nodes); - - bool test (const CSMWorld::IdTableBase& table, int row, - const std::map& columns) const override; - ///< \return Can the specified table row pass through to filter? - /// \param columns column ID to column index mapping + bool test(const CSMWorld::IdTableBase& table, int row, const std::map& columns) const override; + ///< \return Can the specified table row pass through to filter? + /// \param columns column ID to column index mapping }; } diff --git a/apps/opencs/model/filter/booleannode.cpp b/apps/opencs/model/filter/booleannode.cpp index ee7ddc1c05..da8470ee7e 100644 --- a/apps/opencs/model/filter/booleannode.cpp +++ b/apps/opencs/model/filter/booleannode.cpp @@ -1,14 +1,16 @@ #include "booleannode.hpp" -CSMFilter::BooleanNode::BooleanNode (bool true_) : mTrue (true_) {} +CSMFilter::BooleanNode::BooleanNode(bool true_) + : mTrue(true_) +{ +} -bool CSMFilter::BooleanNode::test (const CSMWorld::IdTableBase& table, int row, - const std::map& columns) const +bool CSMFilter::BooleanNode::test(const CSMWorld::IdTableBase& table, int row, const std::map& columns) const { return mTrue; } -std::string CSMFilter::BooleanNode::toString (bool numericColumns) const +std::string CSMFilter::BooleanNode::toString(bool numericColumns) const { return mTrue ? "true" : "false"; } diff --git a/apps/opencs/model/filter/booleannode.hpp b/apps/opencs/model/filter/booleannode.hpp index bed6cbeb0c..c1bf3bd644 100644 --- a/apps/opencs/model/filter/booleannode.hpp +++ b/apps/opencs/model/filter/booleannode.hpp @@ -7,22 +7,19 @@ namespace CSMFilter { class BooleanNode : public LeafNode { - bool mTrue; + bool mTrue; - public: + public: + BooleanNode(bool true_); - BooleanNode (bool true_); - - bool test (const CSMWorld::IdTableBase& table, int row, - const std::map& columns) const override; - ///< \return Can the specified table row pass through to filter? - /// \param columns column ID to column index mapping - - std::string toString (bool numericColumns) const override; - ///< Return a string that represents this node. - /// - /// \param numericColumns Use numeric IDs instead of string to represent columns. + bool test(const CSMWorld::IdTableBase& table, int row, const std::map& columns) const override; + ///< \return Can the specified table row pass through to filter? + /// \param columns column ID to column index mapping + std::string toString(bool numericColumns) const override; + ///< Return a string that represents this node. + /// + /// \param numericColumns Use numeric IDs instead of string to represent columns. }; } diff --git a/apps/opencs/model/filter/leafnode.cpp b/apps/opencs/model/filter/leafnode.cpp index 6745e165ec..fd37c6cb64 100644 --- a/apps/opencs/model/filter/leafnode.cpp +++ b/apps/opencs/model/filter/leafnode.cpp @@ -4,4 +4,3 @@ std::vector CSMFilter::LeafNode::getReferencedColumns() const { return std::vector(); } - diff --git a/apps/opencs/model/filter/leafnode.hpp b/apps/opencs/model/filter/leafnode.hpp index d27bdcfe84..afaad32a70 100644 --- a/apps/opencs/model/filter/leafnode.hpp +++ b/apps/opencs/model/filter/leafnode.hpp @@ -9,11 +9,10 @@ namespace CSMFilter { class LeafNode : public Node { - public: - - std::vector getReferencedColumns() const override; - ///< Return a list of the IDs of the columns referenced by this node. The column mapping - /// passed into test as columns must contain all columns listed here. + public: + std::vector getReferencedColumns() const override; + ///< Return a list of the IDs of the columns referenced by this node. The column mapping + /// passed into test as columns must contain all columns listed here. }; } diff --git a/apps/opencs/model/filter/narynode.cpp b/apps/opencs/model/filter/narynode.cpp index 9415f1daff..622e57182b 100644 --- a/apps/opencs/model/filter/narynode.cpp +++ b/apps/opencs/model/filter/narynode.cpp @@ -2,37 +2,37 @@ #include -CSMFilter::NAryNode::NAryNode (const std::vector >& nodes, - const std::string& name) -: mNodes (nodes), mName (name) -{} +CSMFilter::NAryNode::NAryNode(const std::vector>& nodes, const std::string& name) + : mNodes(nodes) + , mName(name) +{ +} int CSMFilter::NAryNode::getSize() const { return static_cast(mNodes.size()); } -const CSMFilter::Node& CSMFilter::NAryNode::operator[] (int index) const +const CSMFilter::Node& CSMFilter::NAryNode::operator[](int index) const { - return *mNodes.at (index); + return *mNodes.at(index); } std::vector CSMFilter::NAryNode::getReferencedColumns() const { std::vector columns; - for (std::vector >::const_iterator iter (mNodes.begin()); - iter!=mNodes.end(); ++iter) + for (std::vector>::const_iterator iter(mNodes.begin()); iter != mNodes.end(); ++iter) { std::vector columns2 = (*iter)->getReferencedColumns(); - columns.insert (columns.end(), columns2.begin(), columns2.end()); + columns.insert(columns.end(), columns2.begin(), columns2.end()); } return columns; } -std::string CSMFilter::NAryNode::toString (bool numericColumns) const +std::string CSMFilter::NAryNode::toString(bool numericColumns) const { std::ostringstream stream; @@ -41,19 +41,17 @@ std::string CSMFilter::NAryNode::toString (bool numericColumns) const bool first = true; int size = getSize(); - for (int i=0; i #include +#include #include "node.hpp" @@ -10,25 +10,24 @@ namespace CSMFilter { class NAryNode : public Node { - std::vector > mNodes; - std::string mName; - - public: + std::vector> mNodes; + std::string mName; - NAryNode (const std::vector >& nodes, const std::string& name); + public: + NAryNode(const std::vector>& nodes, const std::string& name); - int getSize() const; + int getSize() const; - const Node& operator[] (int index) const; + const Node& operator[](int index) const; - std::vector getReferencedColumns() const override; - ///< Return a list of the IDs of the columns referenced by this node. The column mapping - /// passed into test as columns must contain all columns listed here. + std::vector getReferencedColumns() const override; + ///< Return a list of the IDs of the columns referenced by this node. The column mapping + /// passed into test as columns must contain all columns listed here. - std::string toString (bool numericColumns) const override; - ///< Return a string that represents this node. - /// - /// \param numericColumns Use numeric IDs instead of string to represent columns. + std::string toString(bool numericColumns) const override; + ///< Return a string that represents this node. + /// + /// \param numericColumns Use numeric IDs instead of string to represent columns. }; } diff --git a/apps/opencs/model/filter/node.hpp b/apps/opencs/model/filter/node.hpp index 7295b9018a..c0ef855360 100644 --- a/apps/opencs/model/filter/node.hpp +++ b/apps/opencs/model/filter/node.hpp @@ -1,9 +1,9 @@ #ifndef CSM_FILTER_NODE_H #define CSM_FILTER_NODE_H -#include #include #include +#include #include #include @@ -21,32 +21,30 @@ namespace CSMFilter /// interpreted as "the node and all its children". class Node { - // not implemented - Node (const Node&); - Node& operator= (const Node&); - - public: + // not implemented + Node(const Node&); + Node& operator=(const Node&); - Node(); + public: + Node(); - virtual ~Node(); + virtual ~Node(); - virtual bool test (const CSMWorld::IdTableBase& table, int row, - const std::map& columns) const = 0; - ///< \return Can the specified table row pass through to filter? - /// \param columns column ID to column index mapping + virtual bool test(const CSMWorld::IdTableBase& table, int row, const std::map& columns) const = 0; + ///< \return Can the specified table row pass through to filter? + /// \param columns column ID to column index mapping - virtual std::vector getReferencedColumns() const = 0; - ///< Return a list of the IDs of the columns referenced by this node. The column mapping - /// passed into test as columns must contain all columns listed here. + virtual std::vector getReferencedColumns() const = 0; + ///< Return a list of the IDs of the columns referenced by this node. The column mapping + /// passed into test as columns must contain all columns listed here. - virtual std::string toString (bool numericColumns) const = 0; - ///< Return a string that represents this node. - /// - /// \param numericColumns Use numeric IDs instead of string to represent columns. + virtual std::string toString(bool numericColumns) const = 0; + ///< Return a string that represents this node. + /// + /// \param numericColumns Use numeric IDs instead of string to represent columns. }; } -Q_DECLARE_METATYPE (std::shared_ptr) +Q_DECLARE_METATYPE(std::shared_ptr) #endif diff --git a/apps/opencs/model/filter/notnode.cpp b/apps/opencs/model/filter/notnode.cpp index 81588c7547..c9074843b8 100644 --- a/apps/opencs/model/filter/notnode.cpp +++ b/apps/opencs/model/filter/notnode.cpp @@ -1,9 +1,11 @@ #include "notnode.hpp" -CSMFilter::NotNode::NotNode (std::shared_ptr child) : UnaryNode (child, "not") {} +CSMFilter::NotNode::NotNode(std::shared_ptr child) + : UnaryNode(child, "not") +{ +} -bool CSMFilter::NotNode::test (const CSMWorld::IdTableBase& table, int row, - const std::map& columns) const +bool CSMFilter::NotNode::test(const CSMWorld::IdTableBase& table, int row, const std::map& columns) const { - return !getChild().test (table, row, columns); + return !getChild().test(table, row, columns); } diff --git a/apps/opencs/model/filter/notnode.hpp b/apps/opencs/model/filter/notnode.hpp index 5b15163d97..34a277d5a0 100644 --- a/apps/opencs/model/filter/notnode.hpp +++ b/apps/opencs/model/filter/notnode.hpp @@ -7,14 +7,12 @@ namespace CSMFilter { class NotNode : public UnaryNode { - public: + public: + NotNode(std::shared_ptr child); - NotNode (std::shared_ptr child); - - bool test (const CSMWorld::IdTableBase& table, int row, - const std::map& columns) const override; - ///< \return Can the specified table row pass through to filter? - /// \param columns column ID to column index mapping + bool test(const CSMWorld::IdTableBase& table, int row, const std::map& columns) const override; + ///< \return Can the specified table row pass through to filter? + /// \param columns column ID to column index mapping }; } diff --git a/apps/opencs/model/filter/ornode.cpp b/apps/opencs/model/filter/ornode.cpp index d6abaca40b..19e06f1aed 100644 --- a/apps/opencs/model/filter/ornode.cpp +++ b/apps/opencs/model/filter/ornode.cpp @@ -1,16 +1,16 @@ #include "ornode.hpp" -CSMFilter::OrNode::OrNode (const std::vector >& nodes) -: NAryNode (nodes, "or") -{} +CSMFilter::OrNode::OrNode(const std::vector>& nodes) + : NAryNode(nodes, "or") +{ +} -bool CSMFilter::OrNode::test (const CSMWorld::IdTableBase& table, int row, - const std::map& columns) const +bool CSMFilter::OrNode::test(const CSMWorld::IdTableBase& table, int row, const std::map& columns) const { int size = getSize(); - for (int i=0; i>& nodes); - OrNode (const std::vector >& nodes); - - bool test (const CSMWorld::IdTableBase& table, int row, - const std::map& columns) const override; - ///< \return Can the specified table row pass through to filter? - /// \param columns column ID to column index mapping + bool test(const CSMWorld::IdTableBase& table, int row, const std::map& columns) const override; + ///< \return Can the specified table row pass through to filter? + /// \param columns column ID to column index mapping }; } diff --git a/apps/opencs/model/filter/parser.cpp b/apps/opencs/model/filter/parser.cpp index d8b8a441c3..dc7a359680 100644 --- a/apps/opencs/model/filter/parser.cpp +++ b/apps/opencs/model/filter/parser.cpp @@ -1,8 +1,8 @@ #include "parser.hpp" #include -#include #include +#include #include @@ -10,10 +10,10 @@ #include "../world/data.hpp" #include "../world/idcollection.hpp" -#include "booleannode.hpp" -#include "ornode.hpp" #include "andnode.hpp" +#include "booleannode.hpp" #include "notnode.hpp" +#include "ornode.hpp" #include "textnode.hpp" #include "valuenode.hpp" @@ -59,49 +59,70 @@ namespace CSMFilter std::string mString; double mNumber; - Token (Type type = Type_None); + Token(Type type = Type_None); - Token (Type type, const std::string& string); + Token(Type type, const std::string& string); ///< Non-string type that can also be interpreted as a string. - Token (const std::string& string); + Token(const std::string& string); - Token (double number); + Token(double number); operator bool() const; bool isString() const; }; - Token::Token (Type type) : mType (type), mNumber(0.0) {} + Token::Token(Type type) + : mType(type) + , mNumber(0.0) + { + } - Token::Token (Type type, const std::string& string) : mType (type), mString (string), mNumber(0.0) {} + Token::Token(Type type, const std::string& string) + : mType(type) + , mString(string) + , mNumber(0.0) + { + } - Token::Token (const std::string& string) : mType (Type_String), mString (string), mNumber(0.0) {} + Token::Token(const std::string& string) + : mType(Type_String) + , mString(string) + , mNumber(0.0) + { + } - Token::Token (double number) : mType (Type_Number), mNumber (number) {} + Token::Token(double number) + : mType(Type_Number) + , mNumber(number) + { + } bool Token::isString() const { - return mType==Type_String || mType>=Type_Keyword_True; + return mType == Type_String || mType >= Type_Keyword_True; } Token::operator bool() const { - return mType!=Type_None; + return mType != Type_None; } - bool operator== (const Token& left, const Token& right) + bool operator==(const Token& left, const Token& right) { - if (left.mType!=right.mType) + if (left.mType != right.mType) return false; switch (left.mType) { - case Token::Type_String: return left.mString==right.mString; - case Token::Type_Number: return left.mNumber==right.mNumber; + case Token::Type_String: + return left.mString == right.mString; + case Token::Type_Number: + return left.mNumber == right.mNumber; - default: return true; + default: + return true; } } } @@ -110,19 +131,19 @@ CSMFilter::Token CSMFilter::Parser::getStringToken() { std::string string; - int size = static_cast (mInput.size()); + int size = static_cast(mInput.size()); - for (; mIndex1) + if (c == '"' && string.size() > 1) { ++mIndex; break; @@ -131,35 +152,35 @@ CSMFilter::Token CSMFilter::Parser::getStringToken() if (!string.empty()) { - if (string[0]=='"' && (string[string.size()-1]!='"' || string.size()<2) ) + if (string[0] == '"' && (string[string.size() - 1] != '"' || string.size() < 2)) { error(); - return Token (Token::Type_None); + return Token(Token::Type_None); } - if (string[0]!='"' && string[string.size()-1]=='"') + if (string[0] != '"' && string[string.size() - 1] == '"') { error(); - return Token (Token::Type_None); + return Token(Token::Type_None); } - if (string[0]=='"') - return string.substr (1, string.size()-2); + if (string[0] == '"') + return string.substr(1, string.size() - 2); } - return checkKeywords (string); + return checkKeywords(string); } CSMFilter::Token CSMFilter::Parser::getNumberToken() { std::string string; - int size = static_cast (mInput.size()); + int size = static_cast(mInput.size()); bool hasDecimalPoint = false; bool hasDigit = false; - for (; mIndex> value; return value; } -CSMFilter::Token CSMFilter::Parser::checkKeywords (const Token& token) +CSMFilter::Token CSMFilter::Parser::checkKeywords(const Token& token) { - static const char *sKeywords[] = - { - "true", "false", - "and", "or", "not", - "string", "value", + static const char* sKeywords[] = { + "true", + "false", + "and", + "or", + "not", + "string", + "value", nullptr, }; - std::string string = Misc::StringUtils::lowerCase (token.mString); + std::string string = Misc::StringUtils::lowerCase(token.mString); - for (int i=0; sKeywords[i]; ++i) - if (sKeywords[i]==string || (string.size()==1 && sKeywords[i][0]==string[0])) - return Token (static_cast (i+Token::Type_Keyword_True), token.mString); + for (int i = 0; sKeywords[i]; ++i) + if (sKeywords[i] == string || (string.size() == 1 && sKeywords[i][0] == string[0])) + return Token(static_cast(i + Token::Type_Keyword_True), token.mString); return token; } CSMFilter::Token CSMFilter::Parser::getNextToken() { - int size = static_cast (mInput.size()); + int size = static_cast(mInput.size()); char c = 0; - for (; mIndex=size) - return Token (Token::Type_EOS); + if (mIndex >= size) + return Token(Token::Type_EOS); switch (c) { - case '(': ++mIndex; return Token (Token::Type_Open); - case ')': ++mIndex; return Token (Token::Type_Close); - case '[': ++mIndex; return Token (Token::Type_OpenSquare); - case ']': ++mIndex; return Token (Token::Type_CloseSquare); - case ',': ++mIndex; return Token (Token::Type_Comma); - case '!': ++mIndex; return Token (Token::Type_OneShot); + case '(': + ++mIndex; + return Token(Token::Type_Open); + case ')': + ++mIndex; + return Token(Token::Type_Close); + case '[': + ++mIndex; + return Token(Token::Type_OpenSquare); + case ']': + ++mIndex; + return Token(Token::Type_CloseSquare); + case ',': + ++mIndex; + return Token(Token::Type_Comma); + case '!': + ++mIndex; + return Token(Token::Type_OneShot); } - if (c=='"' || c=='_' || isAlpha(c) || c==':') + if (c == '"' || c == '_' || isAlpha(c) || c == ':') return getStringToken(); - if (c=='-' || c=='.' || isDigit(c)) + if (c == '-' || c == '.' || isDigit(c)) return getNumberToken(); error(); - return Token (Token::Type_None); + return Token(Token::Type_None); } -std::shared_ptr CSMFilter::Parser::parseImp (bool allowEmpty, bool ignoreOneShot) +std::shared_ptr CSMFilter::Parser::parseImp(bool allowEmpty, bool ignoreOneShot) { if (Token token = getNextToken()) { - if (token==Token (Token::Type_OneShot)) + if (token == Token(Token::Type_OneShot)) token = getNextToken(); if (token) @@ -269,7 +305,7 @@ std::shared_ptr CSMFilter::Parser::parseImp (bool allowEmpty, b case Token::Type_Keyword_And: case Token::Type_Keyword_Or: - return parseNAry (token); + return parseNAry(token); case Token::Type_Keyword_Not: { @@ -305,13 +341,13 @@ std::shared_ptr CSMFilter::Parser::parseImp (bool allowEmpty, b return std::shared_ptr(); } -std::shared_ptr CSMFilter::Parser::parseNAry (const Token& keyword) +std::shared_ptr CSMFilter::Parser::parseNAry(const Token& keyword) { - std::vector > nodes; + std::vector> nodes; Token token = getNextToken(); - if (token.mType!=Token::Type_Open) + if (token.mType != Token::Type_Open) { error(); return std::shared_ptr(); @@ -324,25 +360,29 @@ std::shared_ptr CSMFilter::Parser::parseNAry (const Token& keyw if (mError) return std::shared_ptr(); - nodes.push_back (node); + nodes.push_back(node); token = getNextToken(); - if (!token || (token.mType!=Token::Type_Close && token.mType!=Token::Type_Comma)) + if (!token || (token.mType != Token::Type_Close && token.mType != Token::Type_Comma)) { error(); return std::shared_ptr(); } - if (token.mType==Token::Type_Close) + if (token.mType == Token::Type_Close) break; } switch (keyword.mType) { - case Token::Type_Keyword_And: return std::make_shared(nodes); - case Token::Type_Keyword_Or: return std::make_shared(nodes); - default: error(); return std::shared_ptr(); + case Token::Type_Keyword_And: + return std::make_shared(nodes); + case Token::Type_Keyword_Or: + return std::make_shared(nodes); + default: + error(); + return std::shared_ptr(); } } @@ -350,7 +390,7 @@ std::shared_ptr CSMFilter::Parser::parseText() { Token token = getNextToken(); - if (token.mType!=Token::Type_Open) + if (token.mType != Token::Type_Open) { error(); return std::shared_ptr(); @@ -364,17 +404,17 @@ std::shared_ptr CSMFilter::Parser::parseText() // parse column ID int columnId = -1; - if (token.mType==Token::Type_Number) + if (token.mType == Token::Type_Number) { - if (static_cast (token.mNumber)==token.mNumber) - columnId = static_cast (token.mNumber); + if (static_cast(token.mNumber) == token.mNumber) + columnId = static_cast(token.mNumber); } else if (token.isString()) { - columnId = CSMWorld::Columns::getId (token.mString); + columnId = CSMWorld::Columns::getId(token.mString); } - if (columnId<0) + if (columnId < 0) { error(); return std::shared_ptr(); @@ -382,7 +422,7 @@ std::shared_ptr CSMFilter::Parser::parseText() token = getNextToken(); - if (token.mType!=Token::Type_Comma) + if (token.mType != Token::Type_Comma) { error(); return std::shared_ptr(); @@ -401,7 +441,7 @@ std::shared_ptr CSMFilter::Parser::parseText() token = getNextToken(); - if (token.mType!=Token::Type_Close) + if (token.mType != Token::Type_Close) { error(); return std::shared_ptr(); @@ -414,7 +454,7 @@ std::shared_ptr CSMFilter::Parser::parseValue() { Token token = getNextToken(); - if (token.mType!=Token::Type_Open) + if (token.mType != Token::Type_Open) { error(); return std::shared_ptr(); @@ -428,17 +468,17 @@ std::shared_ptr CSMFilter::Parser::parseValue() // parse column ID int columnId = -1; - if (token.mType==Token::Type_Number) + if (token.mType == Token::Type_Number) { - if (static_cast (token.mNumber)==token.mNumber) - columnId = static_cast (token.mNumber); + if (static_cast(token.mNumber) == token.mNumber) + columnId = static_cast(token.mNumber); } else if (token.isString()) { - columnId = CSMWorld::Columns::getId (token.mString); + columnId = CSMWorld::Columns::getId(token.mString); } - if (columnId<0) + if (columnId < 0) { error(); return std::shared_ptr(); @@ -446,7 +486,7 @@ std::shared_ptr CSMFilter::Parser::parseValue() token = getNextToken(); - if (token.mType!=Token::Type_Comma) + if (token.mType != Token::Type_Comma) { error(); return std::shared_ptr(); @@ -460,7 +500,7 @@ std::shared_ptr CSMFilter::Parser::parseValue() token = getNextToken(); - if (token.mType==Token::Type_Number) + if (token.mType == Token::Type_Number) { // single value lower = upper = token.mNumber; @@ -469,9 +509,9 @@ std::shared_ptr CSMFilter::Parser::parseValue() else { // interval - if (token.mType==Token::Type_OpenSquare) + if (token.mType == Token::Type_OpenSquare) lowerType = ValueNode::Type_Closed; - else if (token.mType!=Token::Type_CloseSquare && token.mType!=Token::Type_Open) + else if (token.mType != Token::Type_CloseSquare && token.mType != Token::Type_Open) { error(); return std::shared_ptr(); @@ -479,19 +519,19 @@ std::shared_ptr CSMFilter::Parser::parseValue() token = getNextToken(); - if (token.mType==Token::Type_Number) + if (token.mType == Token::Type_Number) { lower = token.mNumber; token = getNextToken(); - if (token.mType!=Token::Type_Comma) + if (token.mType != Token::Type_Comma) { error(); return std::shared_ptr(); } } - else if (token.mType==Token::Type_Comma) + else if (token.mType == Token::Type_Comma) { lowerType = ValueNode::Type_Infinite; } @@ -503,7 +543,7 @@ std::shared_ptr CSMFilter::Parser::parseValue() token = getNextToken(); - if (token.mType==Token::Type_Number) + if (token.mType == Token::Type_Number) { upper = token.mNumber; @@ -512,12 +552,12 @@ std::shared_ptr CSMFilter::Parser::parseValue() else upperType = ValueNode::Type_Infinite; - if (token.mType==Token::Type_CloseSquare) + if (token.mType == Token::Type_CloseSquare) { - if (upperType!=ValueNode::Type_Infinite) + if (upperType != ValueNode::Type_Infinite) upperType = ValueNode::Type_Closed; } - else if (token.mType!=Token::Type_OpenSquare && token.mType!=Token::Type_Close) + else if (token.mType != Token::Type_OpenSquare && token.mType != Token::Type_Close) { error(); return std::shared_ptr(); @@ -526,7 +566,7 @@ std::shared_ptr CSMFilter::Parser::parseValue() token = getNextToken(); - if (token.mType!=Token::Type_Close) + if (token.mType != Token::Type_Close) { error(); return std::shared_ptr(); @@ -540,10 +580,14 @@ void CSMFilter::Parser::error() mError = true; } -CSMFilter::Parser::Parser (const CSMWorld::Data& data) -: mIndex (0), mError (false), mData (data) {} +CSMFilter::Parser::Parser(const CSMWorld::Data& data) + : mIndex(0) + , mError(false) + , mData(data) +{ +} -bool CSMFilter::Parser::parse (const std::string& filter, bool allowPredefined) +bool CSMFilter::Parser::parse(const std::string& filter, bool allowPredefined) { // reset mFilter.reset(); @@ -556,19 +600,19 @@ bool CSMFilter::Parser::parse (const std::string& filter, bool allowPredefined) if (allowPredefined) token = getNextToken(); - if (allowPredefined && token==Token (Token::Type_EOS)) + if (allowPredefined && token == Token(Token::Type_EOS)) { mFilter.reset(); return true; } - else if (!allowPredefined || token==Token (Token::Type_OneShot)) + else if (!allowPredefined || token == Token(Token::Type_OneShot)) { - std::shared_ptr node = parseImp (true, token!=Token (Token::Type_OneShot)); + std::shared_ptr node = parseImp(true, token != Token(Token::Type_OneShot)); if (mError) return false; - if (getNextToken()!=Token (Token::Type_EOS)) + if (getNextToken() != Token(Token::Type_EOS)) { error(); return false; @@ -586,23 +630,23 @@ bool CSMFilter::Parser::parse (const std::string& filter, bool allowPredefined) } // We do not use isString() here, because there could be a pre-defined filter with an ID that is // equal a filter keyword. - else if (token.mType==Token::Type_String) + else if (token.mType == Token::Type_String) { - if (getNextToken()!=Token (Token::Type_EOS)) + if (getNextToken() != Token(Token::Type_EOS)) { error(); return false; } - int index = mData.getFilters().searchId (token.mString); + int index = mData.getFilters().searchId(token.mString); - if (index==-1) + if (index == -1) { error(); return false; } - const CSMWorld::Record& record = mData.getFilters().getRecord (index); + const CSMWorld::Record& record = mData.getFilters().getRecord(index); if (record.isDeleted()) { @@ -610,7 +654,7 @@ bool CSMFilter::Parser::parse (const std::string& filter, bool allowPredefined) return false; } - return parse (record.get().mFilter, false); + return parse(record.get().mFilter, false); } else { @@ -622,7 +666,7 @@ bool CSMFilter::Parser::parse (const std::string& filter, bool allowPredefined) std::shared_ptr CSMFilter::Parser::getFilter() const { if (mError) - throw std::logic_error ("No filter available"); + throw std::logic_error("No filter available"); return mFilter; } diff --git a/apps/opencs/model/filter/parser.hpp b/apps/opencs/model/filter/parser.hpp index 344c552eff..660fd7d4fd 100644 --- a/apps/opencs/model/filter/parser.hpp +++ b/apps/opencs/model/filter/parser.hpp @@ -14,43 +14,42 @@ namespace CSMFilter class Parser { - std::shared_ptr mFilter; - std::string mInput; - int mIndex; - bool mError; - const CSMWorld::Data& mData; + std::shared_ptr mFilter; + std::string mInput; + int mIndex; + bool mError; + const CSMWorld::Data& mData; - Token getStringToken(); + Token getStringToken(); - Token getNumberToken(); + Token getNumberToken(); - Token getNextToken(); + Token getNextToken(); - Token checkKeywords (const Token& token); - ///< Turn string token into keyword token, if possible. + Token checkKeywords(const Token& token); + ///< Turn string token into keyword token, if possible. - std::shared_ptr parseImp (bool allowEmpty = false, bool ignoreOneShot = false); - ///< Will return a null-pointer, if there is nothing more to parse. + std::shared_ptr parseImp(bool allowEmpty = false, bool ignoreOneShot = false); + ///< Will return a null-pointer, if there is nothing more to parse. - std::shared_ptr parseNAry (const Token& keyword); + std::shared_ptr parseNAry(const Token& keyword); - std::shared_ptr parseText(); + std::shared_ptr parseText(); - std::shared_ptr parseValue(); + std::shared_ptr parseValue(); - void error(); + void error(); - public: + public: + Parser(const CSMWorld::Data& data); - Parser (const CSMWorld::Data& data); + bool parse(const std::string& filter, bool allowPredefined = true); + ///< Discards any previous calls to parse + /// + /// \return Success? - bool parse (const std::string& filter, bool allowPredefined = true); - ///< Discards any previous calls to parse - /// - /// \return Success? - - std::shared_ptr getFilter() const; - ///< Throws an exception if the last call to parse did not return true. + std::shared_ptr getFilter() const; + ///< Throws an exception if the last call to parse did not return true. }; } diff --git a/apps/opencs/model/filter/textnode.cpp b/apps/opencs/model/filter/textnode.cpp index 808090dc37..9bef2c2745 100644 --- a/apps/opencs/model/filter/textnode.cpp +++ b/apps/opencs/model/filter/textnode.cpp @@ -8,43 +8,44 @@ #include "../world/columns.hpp" #include "../world/idtablebase.hpp" -CSMFilter::TextNode::TextNode (int columnId, const std::string& text) -: mColumnId (columnId), mText (text) -{} +CSMFilter::TextNode::TextNode(int columnId, const std::string& text) + : mColumnId(columnId) + , mText(text) +{ +} -bool CSMFilter::TextNode::test (const CSMWorld::IdTableBase& table, int row, - const std::map& columns) const +bool CSMFilter::TextNode::test(const CSMWorld::IdTableBase& table, int row, const std::map& columns) const { - const std::map::const_iterator iter = columns.find (mColumnId); + const std::map::const_iterator iter = columns.find(mColumnId); - if (iter==columns.end()) - throw std::logic_error ("invalid column in text node test"); + if (iter == columns.end()) + throw std::logic_error("invalid column in text node test"); - if (iter->second==-1) + if (iter->second == -1) return true; - QModelIndex index = table.index (row, iter->second); + QModelIndex index = table.index(row, iter->second); - QVariant data = table.data (index); + QVariant data = table.data(index); QString string; - if (data.type()==QVariant::String) + if (data.type() == QVariant::String) { string = data.toString(); } - else if ((data.type()==QVariant::Int || data.type()==QVariant::UInt) && - CSMWorld::Columns::hasEnums (static_cast (mColumnId))) + else if ((data.type() == QVariant::Int || data.type() == QVariant::UInt) + && CSMWorld::Columns::hasEnums(static_cast(mColumnId))) { int value = data.toInt(); - std::vector> enums = - CSMWorld::Columns::getEnums (static_cast (mColumnId)); + std::vector> enums + = CSMWorld::Columns::getEnums(static_cast(mColumnId)); - if (value>=0 && value (enums.size())) - string = QString::fromUtf8 (enums[value].second.c_str()); + if (value >= 0 && value < static_cast(enums.size())) + string = QString::fromUtf8(enums[value].second.c_str()); } - else if (data.type()==QVariant::Bool) + else if (data.type() == QVariant::Bool) { string = data.toBool() ? "true" : "false"; } @@ -54,17 +55,17 @@ bool CSMFilter::TextNode::test (const CSMWorld::IdTableBase& table, int row, return false; /// \todo make pattern syntax configurable - QRegExp regExp (QString::fromUtf8 (mText.c_str()), Qt::CaseInsensitive); + QRegExp regExp(QString::fromUtf8(mText.c_str()), Qt::CaseInsensitive); - return regExp.exactMatch (string); + return regExp.exactMatch(string); } std::vector CSMFilter::TextNode::getReferencedColumns() const { - return std::vector (1, mColumnId); + return std::vector(1, mColumnId); } -std::string CSMFilter::TextNode::toString (bool numericColumns) const +std::string CSMFilter::TextNode::toString(bool numericColumns) const { std::ostringstream stream; @@ -73,10 +74,7 @@ std::string CSMFilter::TextNode::toString (bool numericColumns) const if (numericColumns) stream << mColumnId; else - stream - << "\"" - << CSMWorld::Columns::getName (static_cast (mColumnId)) - << "\""; + stream << "\"" << CSMWorld::Columns::getName(static_cast(mColumnId)) << "\""; stream << ", \"" << mText << "\")"; diff --git a/apps/opencs/model/filter/textnode.hpp b/apps/opencs/model/filter/textnode.hpp index 0e7a0e4f5e..03b2a473d3 100644 --- a/apps/opencs/model/filter/textnode.hpp +++ b/apps/opencs/model/filter/textnode.hpp @@ -7,26 +7,24 @@ namespace CSMFilter { class TextNode : public LeafNode { - int mColumnId; - std::string mText; + int mColumnId; + std::string mText; - public: + public: + TextNode(int columnId, const std::string& text); - TextNode (int columnId, const std::string& text); + bool test(const CSMWorld::IdTableBase& table, int row, const std::map& columns) const override; + ///< \return Can the specified table row pass through to filter? + /// \param columns column ID to column index mapping - bool test (const CSMWorld::IdTableBase& table, int row, - const std::map& columns) const override; - ///< \return Can the specified table row pass through to filter? - /// \param columns column ID to column index mapping + std::vector getReferencedColumns() const override; + ///< Return a list of the IDs of the columns referenced by this node. The column mapping + /// passed into test as columns must contain all columns listed here. - std::vector getReferencedColumns() const override; - ///< Return a list of the IDs of the columns referenced by this node. The column mapping - /// passed into test as columns must contain all columns listed here. - - std::string toString (bool numericColumns) const override; - ///< Return a string that represents this node. - /// - /// \param numericColumns Use numeric IDs instead of string to represent columns. + std::string toString(bool numericColumns) const override; + ///< Return a string that represents this node. + /// + /// \param numericColumns Use numeric IDs instead of string to represent columns. }; } diff --git a/apps/opencs/model/filter/unarynode.cpp b/apps/opencs/model/filter/unarynode.cpp index 7211f78b0a..9581361f46 100644 --- a/apps/opencs/model/filter/unarynode.cpp +++ b/apps/opencs/model/filter/unarynode.cpp @@ -1,8 +1,10 @@ #include "unarynode.hpp" -CSMFilter::UnaryNode::UnaryNode (std::shared_ptr child, const std::string& name) -: mChild (child), mName (name) -{} +CSMFilter::UnaryNode::UnaryNode(std::shared_ptr child, const std::string& name) + : mChild(child) + , mName(name) +{ +} const CSMFilter::Node& CSMFilter::UnaryNode::getChild() const { @@ -19,7 +21,7 @@ std::vector CSMFilter::UnaryNode::getReferencedColumns() const return mChild->getReferencedColumns(); } -std::string CSMFilter::UnaryNode::toString (bool numericColumns) const +std::string CSMFilter::UnaryNode::toString(bool numericColumns) const { - return mName + " " + mChild->toString (numericColumns); + return mName + " " + mChild->toString(numericColumns); } diff --git a/apps/opencs/model/filter/unarynode.hpp b/apps/opencs/model/filter/unarynode.hpp index 39326d1672..cb3fbdd925 100644 --- a/apps/opencs/model/filter/unarynode.hpp +++ b/apps/opencs/model/filter/unarynode.hpp @@ -7,25 +7,24 @@ namespace CSMFilter { class UnaryNode : public Node { - std::shared_ptr mChild; - std::string mName; + std::shared_ptr mChild; + std::string mName; - public: + public: + UnaryNode(std::shared_ptr child, const std::string& name); - UnaryNode (std::shared_ptr child, const std::string& name); + const Node& getChild() const; - const Node& getChild() const; + Node& getChild(); - Node& getChild(); + std::vector getReferencedColumns() const override; + ///< Return a list of the IDs of the columns referenced by this node. The column mapping + /// passed into test as columns must contain all columns listed here. - std::vector getReferencedColumns() const override; - ///< Return a list of the IDs of the columns referenced by this node. The column mapping - /// passed into test as columns must contain all columns listed here. - - std::string toString (bool numericColumns) const override; - ///< Return a string that represents this node. - /// - /// \param numericColumns Use numeric IDs instead of string to represent columns. + std::string toString(bool numericColumns) const override; + ///< Return a string that represents this node. + /// + /// \param numericColumns Use numeric IDs instead of string to represent columns. }; } diff --git a/apps/opencs/model/filter/valuenode.cpp b/apps/opencs/model/filter/valuenode.cpp index 85c5a8e27f..eb3d03f00a 100644 --- a/apps/opencs/model/filter/valuenode.cpp +++ b/apps/opencs/model/filter/valuenode.cpp @@ -6,43 +6,61 @@ #include "../world/columns.hpp" #include "../world/idtablebase.hpp" -CSMFilter::ValueNode::ValueNode (int columnId, Type lowerType, Type upperType, - double lower, double upper) -: mColumnId (columnId), mLower (lower), mUpper (upper), mLowerType (lowerType), mUpperType (upperType){} +CSMFilter::ValueNode::ValueNode(int columnId, Type lowerType, Type upperType, double lower, double upper) + : mColumnId(columnId) + , mLower(lower) + , mUpper(upper) + , mLowerType(lowerType) + , mUpperType(upperType) +{ +} -bool CSMFilter::ValueNode::test (const CSMWorld::IdTableBase& table, int row, - const std::map& columns) const +bool CSMFilter::ValueNode::test(const CSMWorld::IdTableBase& table, int row, const std::map& columns) const { - const std::map::const_iterator iter = columns.find (mColumnId); + const std::map::const_iterator iter = columns.find(mColumnId); - if (iter==columns.end()) - throw std::logic_error ("invalid column in value node test"); + if (iter == columns.end()) + throw std::logic_error("invalid column in value node test"); - if (iter->second==-1) + if (iter->second == -1) return true; - QModelIndex index = table.index (row, iter->second); + QModelIndex index = table.index(row, iter->second); - QVariant data = table.data (index); + QVariant data = table.data(index); - if (data.type()!=QVariant::Double && data.type()!=QVariant::Bool && data.type()!=QVariant::Int && - data.type()!=QVariant::UInt && data.type()!=static_cast (QMetaType::Float)) + if (data.type() != QVariant::Double && data.type() != QVariant::Bool && data.type() != QVariant::Int + && data.type() != QVariant::UInt && data.type() != static_cast(QMetaType::Float)) return false; double value = data.toDouble(); switch (mLowerType) { - case Type_Closed: if (valuemUpper) return false; break; - case Type_Open: if (value>=mUpper) return false; break; - case Type_Infinite: break; + case Type_Closed: + if (value > mUpper) + return false; + break; + case Type_Open: + if (value >= mUpper) + return false; + break; + case Type_Infinite: + break; } return true; @@ -50,10 +68,10 @@ bool CSMFilter::ValueNode::test (const CSMWorld::IdTableBase& table, int row, std::vector CSMFilter::ValueNode::getReferencedColumns() const { - return std::vector (1, mColumnId); + return std::vector(1, mColumnId); } -std::string CSMFilter::ValueNode::toString (bool numericColumns) const +std::string CSMFilter::ValueNode::toString(bool numericColumns) const { std::ostringstream stream; @@ -62,31 +80,40 @@ std::string CSMFilter::ValueNode::toString (bool numericColumns) const if (numericColumns) stream << mColumnId; else - stream - << "\"" - << CSMWorld::Columns::getName (static_cast (mColumnId)) - << "\""; + stream << "\"" << CSMWorld::Columns::getName(static_cast(mColumnId)) << "\""; stream << ", "; - if (mLower==mUpper && mLowerType!=Type_Infinite && mUpperType!=Type_Infinite) + if (mLower == mUpper && mLowerType != Type_Infinite && mUpperType != Type_Infinite) stream << mLower; else { switch (mLowerType) { - case Type_Closed: stream << "[" << mLower; break; - case Type_Open: stream << "(" << mLower; break; - case Type_Infinite: stream << "("; break; + case Type_Closed: + stream << "[" << mLower; + break; + case Type_Open: + stream << "(" << mLower; + break; + case Type_Infinite: + stream << "("; + break; } stream << ", "; switch (mUpperType) { - case Type_Closed: stream << mUpper << "]"; break; - case Type_Open: stream << mUpper << ")"; break; - case Type_Infinite: stream << ")"; break; + case Type_Closed: + stream << mUpper << "]"; + break; + case Type_Open: + stream << mUpper << ")"; + break; + case Type_Infinite: + stream << ")"; + break; } } diff --git a/apps/opencs/model/filter/valuenode.hpp b/apps/opencs/model/filter/valuenode.hpp index 339e4948a6..ffdf85a05f 100644 --- a/apps/opencs/model/filter/valuenode.hpp +++ b/apps/opencs/model/filter/valuenode.hpp @@ -7,39 +7,37 @@ namespace CSMFilter { class ValueNode : public LeafNode { - public: - - enum Type - { - Type_Closed, Type_Open, Type_Infinite - }; - - private: - - int mColumnId; - std::string mText; - double mLower; - double mUpper; - Type mLowerType; - Type mUpperType; - - public: - - ValueNode (int columnId, Type lowerType, Type upperType, double lower, double upper); - - bool test (const CSMWorld::IdTableBase& table, int row, - const std::map& columns) const override; - ///< \return Can the specified table row pass through to filter? - /// \param columns column ID to column index mapping - - std::vector getReferencedColumns() const override; - ///< Return a list of the IDs of the columns referenced by this node. The column mapping - /// passed into test as columns must contain all columns listed here. - - std::string toString (bool numericColumns) const override; - ///< Return a string that represents this node. - /// - /// \param numericColumns Use numeric IDs instead of string to represent columns. + public: + enum Type + { + Type_Closed, + Type_Open, + Type_Infinite + }; + + private: + int mColumnId; + std::string mText; + double mLower; + double mUpper; + Type mLowerType; + Type mUpperType; + + public: + ValueNode(int columnId, Type lowerType, Type upperType, double lower, double upper); + + bool test(const CSMWorld::IdTableBase& table, int row, const std::map& columns) const override; + ///< \return Can the specified table row pass through to filter? + /// \param columns column ID to column index mapping + + std::vector getReferencedColumns() const override; + ///< Return a list of the IDs of the columns referenced by this node. The column mapping + /// passed into test as columns must contain all columns listed here. + + std::string toString(bool numericColumns) const override; + ///< Return a string that represents this node. + /// + /// \param numericColumns Use numeric IDs instead of string to represent columns. }; } diff --git a/apps/opencs/model/prefs/boolsetting.cpp b/apps/opencs/model/prefs/boolsetting.cpp index afd80be99d..9b557406a5 100644 --- a/apps/opencs/model/prefs/boolsetting.cpp +++ b/apps/opencs/model/prefs/boolsetting.cpp @@ -8,49 +8,51 @@ #include "category.hpp" #include "state.hpp" -CSMPrefs::BoolSetting::BoolSetting (Category *parent, - QMutex *mutex, const std::string& key, const std::string& label, bool default_) -: Setting (parent, mutex, key, label), mDefault (default_), mWidget(nullptr) -{} +CSMPrefs::BoolSetting::BoolSetting( + Category* parent, QMutex* mutex, const std::string& key, const std::string& label, bool default_) + : Setting(parent, mutex, key, label) + , mDefault(default_) + , mWidget(nullptr) +{ +} -CSMPrefs::BoolSetting& CSMPrefs::BoolSetting::setTooltip (const std::string& tooltip) +CSMPrefs::BoolSetting& CSMPrefs::BoolSetting::setTooltip(const std::string& tooltip) { mTooltip = tooltip; return *this; } -std::pair CSMPrefs::BoolSetting::makeWidgets (QWidget *parent) +std::pair CSMPrefs::BoolSetting::makeWidgets(QWidget* parent) { - mWidget = new QCheckBox (QString::fromUtf8 (getLabel().c_str()), parent); - mWidget->setCheckState (mDefault ? Qt::Checked : Qt::Unchecked); + mWidget = new QCheckBox(QString::fromUtf8(getLabel().c_str()), parent); + mWidget->setCheckState(mDefault ? Qt::Checked : Qt::Unchecked); if (!mTooltip.empty()) { - QString tooltip = QString::fromUtf8 (mTooltip.c_str()); - mWidget->setToolTip (tooltip); + QString tooltip = QString::fromUtf8(mTooltip.c_str()); + mWidget->setToolTip(tooltip); } - connect (mWidget, &QCheckBox::stateChanged, this, &BoolSetting::valueChanged); + connect(mWidget, &QCheckBox::stateChanged, this, &BoolSetting::valueChanged); - return std::make_pair (static_cast (nullptr), mWidget); + return std::make_pair(static_cast(nullptr), mWidget); } void CSMPrefs::BoolSetting::updateWidget() { if (mWidget) { - mWidget->setCheckState(Settings::Manager::getBool(getKey(), getParent()->getKey()) - ? Qt::Checked - : Qt::Unchecked); + mWidget->setCheckState( + Settings::Manager::getBool(getKey(), getParent()->getKey()) ? Qt::Checked : Qt::Unchecked); } } -void CSMPrefs::BoolSetting::valueChanged (int value) +void CSMPrefs::BoolSetting::valueChanged(int value) { { - QMutexLocker lock (getMutex()); - Settings::Manager::setBool (getKey(), getParent()->getKey(), value); + QMutexLocker lock(getMutex()); + Settings::Manager::setBool(getKey(), getParent()->getKey(), value); } - getParent()->getState()->update (*this); + getParent()->getState()->update(*this); } diff --git a/apps/opencs/model/prefs/boolsetting.hpp b/apps/opencs/model/prefs/boolsetting.hpp index 4bfd7df47a..a7fdf5c8ef 100644 --- a/apps/opencs/model/prefs/boolsetting.hpp +++ b/apps/opencs/model/prefs/boolsetting.hpp @@ -9,27 +9,25 @@ namespace CSMPrefs { class BoolSetting : public Setting { - Q_OBJECT + Q_OBJECT - std::string mTooltip; - bool mDefault; - QCheckBox* mWidget; + std::string mTooltip; + bool mDefault; + QCheckBox* mWidget; - public: + public: + BoolSetting(Category* parent, QMutex* mutex, const std::string& key, const std::string& label, bool default_); - BoolSetting (Category *parent, - QMutex *mutex, const std::string& key, const std::string& label, bool default_); + BoolSetting& setTooltip(const std::string& tooltip); - BoolSetting& setTooltip (const std::string& tooltip); + /// Return label, input widget. + std::pair makeWidgets(QWidget* parent) override; - /// Return label, input widget. - std::pair makeWidgets (QWidget *parent) override; + void updateWidget() override; - void updateWidget() override; + private slots: - private slots: - - void valueChanged (int value); + void valueChanged(int value); }; } diff --git a/apps/opencs/model/prefs/category.cpp b/apps/opencs/model/prefs/category.cpp index 6af0ac645b..5a82be08fc 100644 --- a/apps/opencs/model/prefs/category.cpp +++ b/apps/opencs/model/prefs/category.cpp @@ -6,23 +6,25 @@ #include "setting.hpp" #include "state.hpp" -CSMPrefs::Category::Category (State *parent, const std::string& key) -: mParent (parent), mKey (key) -{} +CSMPrefs::Category::Category(State* parent, const std::string& key) + : mParent(parent) + , mKey(key) +{ +} const std::string& CSMPrefs::Category::getKey() const { return mKey; } -CSMPrefs::State *CSMPrefs::Category::getState() const +CSMPrefs::State* CSMPrefs::Category::getState() const { return mParent; } -void CSMPrefs::Category::addSetting (Setting *setting) +void CSMPrefs::Category::addSetting(Setting* setting) { - mSettings.push_back (setting); + mSettings.push_back(setting); } CSMPrefs::Category::Iterator CSMPrefs::Category::begin() @@ -35,17 +37,17 @@ CSMPrefs::Category::Iterator CSMPrefs::Category::end() return mSettings.end(); } -CSMPrefs::Setting& CSMPrefs::Category::operator[] (const std::string& key) +CSMPrefs::Setting& CSMPrefs::Category::operator[](const std::string& key) { - for (Iterator iter = mSettings.begin(); iter!=mSettings.end(); ++iter) - if ((*iter)->getKey()==key) + for (Iterator iter = mSettings.begin(); iter != mSettings.end(); ++iter) + if ((*iter)->getKey() == key) return **iter; - throw std::logic_error ("Invalid user setting: " + key); + throw std::logic_error("Invalid user setting: " + key); } void CSMPrefs::Category::update() { - for (Iterator iter = mSettings.begin(); iter!=mSettings.end(); ++iter) - mParent->update (**iter); + for (Iterator iter = mSettings.begin(); iter != mSettings.end(); ++iter) + mParent->update(**iter); } diff --git a/apps/opencs/model/prefs/category.hpp b/apps/opencs/model/prefs/category.hpp index b70716aa0e..3f98e9fbb3 100644 --- a/apps/opencs/model/prefs/category.hpp +++ b/apps/opencs/model/prefs/category.hpp @@ -11,34 +11,31 @@ namespace CSMPrefs class Category { - public: + public: + typedef std::vector Container; + typedef Container::iterator Iterator; - typedef std::vector Container; - typedef Container::iterator Iterator; + private: + State* mParent; + std::string mKey; + Container mSettings; - private: + public: + Category(State* parent, const std::string& key); - State *mParent; - std::string mKey; - Container mSettings; + const std::string& getKey() const; - public: + State* getState() const; - Category (State *parent, const std::string& key); + void addSetting(Setting* setting); - const std::string& getKey() const; + Iterator begin(); - State *getState() const; + Iterator end(); - void addSetting (Setting *setting); + Setting& operator[](const std::string& key); - Iterator begin(); - - Iterator end(); - - Setting& operator[] (const std::string& key); - - void update(); + void update(); }; } diff --git a/apps/opencs/model/prefs/coloursetting.cpp b/apps/opencs/model/prefs/coloursetting.cpp index 6849d51aad..b8df0e459e 100644 --- a/apps/opencs/model/prefs/coloursetting.cpp +++ b/apps/opencs/model/prefs/coloursetting.cpp @@ -11,51 +11,53 @@ #include "category.hpp" #include "state.hpp" -CSMPrefs::ColourSetting::ColourSetting (Category *parent, - QMutex *mutex, const std::string& key, const std::string& label, QColor default_) -: Setting (parent, mutex, key, label), mDefault (default_), mWidget(nullptr) -{} +CSMPrefs::ColourSetting::ColourSetting( + Category* parent, QMutex* mutex, const std::string& key, const std::string& label, QColor default_) + : Setting(parent, mutex, key, label) + , mDefault(default_) + , mWidget(nullptr) +{ +} -CSMPrefs::ColourSetting& CSMPrefs::ColourSetting::setTooltip (const std::string& tooltip) +CSMPrefs::ColourSetting& CSMPrefs::ColourSetting::setTooltip(const std::string& tooltip) { mTooltip = tooltip; return *this; } -std::pair CSMPrefs::ColourSetting::makeWidgets (QWidget *parent) +std::pair CSMPrefs::ColourSetting::makeWidgets(QWidget* parent) { - QLabel *label = new QLabel (QString::fromUtf8 (getLabel().c_str()), parent); + QLabel* label = new QLabel(QString::fromUtf8(getLabel().c_str()), parent); - mWidget = new CSVWidget::ColorEditor (mDefault, parent); + mWidget = new CSVWidget::ColorEditor(mDefault, parent); if (!mTooltip.empty()) { - QString tooltip = QString::fromUtf8 (mTooltip.c_str()); - label->setToolTip (tooltip); - mWidget->setToolTip (tooltip); + QString tooltip = QString::fromUtf8(mTooltip.c_str()); + label->setToolTip(tooltip); + mWidget->setToolTip(tooltip); } - connect (mWidget, &CSVWidget::ColorEditor::pickingFinished, this, &ColourSetting::valueChanged); + connect(mWidget, &CSVWidget::ColorEditor::pickingFinished, this, &ColourSetting::valueChanged); - return std::make_pair (label, mWidget); + return std::make_pair(label, mWidget); } void CSMPrefs::ColourSetting::updateWidget() { if (mWidget) { - mWidget->setColor(QString::fromStdString - (Settings::Manager::getString(getKey(), getParent()->getKey()))); + mWidget->setColor(QString::fromStdString(Settings::Manager::getString(getKey(), getParent()->getKey()))); } } void CSMPrefs::ColourSetting::valueChanged() { - CSVWidget::ColorEditor& widget = dynamic_cast (*sender()); + CSVWidget::ColorEditor& widget = dynamic_cast(*sender()); { - QMutexLocker lock (getMutex()); - Settings::Manager::setString (getKey(), getParent()->getKey(), widget.color().name().toUtf8().data()); + QMutexLocker lock(getMutex()); + Settings::Manager::setString(getKey(), getParent()->getKey(), widget.color().name().toUtf8().data()); } - getParent()->getState()->update (*this); + getParent()->getState()->update(*this); } diff --git a/apps/opencs/model/prefs/coloursetting.hpp b/apps/opencs/model/prefs/coloursetting.hpp index 097eec4313..7365dd51b1 100644 --- a/apps/opencs/model/prefs/coloursetting.hpp +++ b/apps/opencs/model/prefs/coloursetting.hpp @@ -14,28 +14,26 @@ namespace CSMPrefs { class ColourSetting : public Setting { - Q_OBJECT + Q_OBJECT - std::string mTooltip; - QColor mDefault; - CSVWidget::ColorEditor* mWidget; + std::string mTooltip; + QColor mDefault; + CSVWidget::ColorEditor* mWidget; - public: + public: + ColourSetting( + Category* parent, QMutex* mutex, const std::string& key, const std::string& label, QColor default_); - ColourSetting (Category *parent, - QMutex *mutex, const std::string& key, const std::string& label, - QColor default_); + ColourSetting& setTooltip(const std::string& tooltip); - ColourSetting& setTooltip (const std::string& tooltip); + /// Return label, input widget. + std::pair makeWidgets(QWidget* parent) override; - /// Return label, input widget. - std::pair makeWidgets (QWidget *parent) override; + void updateWidget() override; - void updateWidget() override; + private slots: - private slots: - - void valueChanged(); + void valueChanged(); }; } diff --git a/apps/opencs/model/prefs/doublesetting.cpp b/apps/opencs/model/prefs/doublesetting.cpp index 64e961eb9b..43f7963429 100644 --- a/apps/opencs/model/prefs/doublesetting.cpp +++ b/apps/opencs/model/prefs/doublesetting.cpp @@ -3,8 +3,8 @@ #include -#include #include +#include #include #include @@ -12,12 +12,16 @@ #include "category.hpp" #include "state.hpp" -CSMPrefs::DoubleSetting::DoubleSetting (Category *parent, - QMutex *mutex, const std::string& key, const std::string& label, double default_) -: Setting (parent, mutex, key, label), - mPrecision(2), mMin (0), mMax (std::numeric_limits::max()), - mDefault (default_), mWidget(nullptr) -{} +CSMPrefs::DoubleSetting::DoubleSetting( + Category* parent, QMutex* mutex, const std::string& key, const std::string& label, double default_) + : Setting(parent, mutex, key, label) + , mPrecision(2) + , mMin(0) + , mMax(std::numeric_limits::max()) + , mDefault(default_) + , mWidget(nullptr) +{ +} CSMPrefs::DoubleSetting& CSMPrefs::DoubleSetting::setPrecision(int precision) { @@ -25,50 +29,50 @@ CSMPrefs::DoubleSetting& CSMPrefs::DoubleSetting::setPrecision(int precision) return *this; } -CSMPrefs::DoubleSetting& CSMPrefs::DoubleSetting::setRange (double min, double max) +CSMPrefs::DoubleSetting& CSMPrefs::DoubleSetting::setRange(double min, double max) { mMin = min; mMax = max; return *this; } -CSMPrefs::DoubleSetting& CSMPrefs::DoubleSetting::setMin (double min) +CSMPrefs::DoubleSetting& CSMPrefs::DoubleSetting::setMin(double min) { mMin = min; return *this; } -CSMPrefs::DoubleSetting& CSMPrefs::DoubleSetting::setMax (double max) +CSMPrefs::DoubleSetting& CSMPrefs::DoubleSetting::setMax(double max) { mMax = max; return *this; } -CSMPrefs::DoubleSetting& CSMPrefs::DoubleSetting::setTooltip (const std::string& tooltip) +CSMPrefs::DoubleSetting& CSMPrefs::DoubleSetting::setTooltip(const std::string& tooltip) { mTooltip = tooltip; return *this; } -std::pair CSMPrefs::DoubleSetting::makeWidgets (QWidget *parent) +std::pair CSMPrefs::DoubleSetting::makeWidgets(QWidget* parent) { - QLabel *label = new QLabel (QString::fromUtf8 (getLabel().c_str()), parent); + QLabel* label = new QLabel(QString::fromUtf8(getLabel().c_str()), parent); - mWidget = new QDoubleSpinBox (parent); + mWidget = new QDoubleSpinBox(parent); mWidget->setDecimals(mPrecision); - mWidget->setRange (mMin, mMax); - mWidget->setValue (mDefault); + mWidget->setRange(mMin, mMax); + mWidget->setValue(mDefault); if (!mTooltip.empty()) { - QString tooltip = QString::fromUtf8 (mTooltip.c_str()); - label->setToolTip (tooltip); - mWidget->setToolTip (tooltip); + QString tooltip = QString::fromUtf8(mTooltip.c_str()); + label->setToolTip(tooltip); + mWidget->setToolTip(tooltip); } - connect (mWidget, qOverload(&QDoubleSpinBox::valueChanged), this, &DoubleSetting::valueChanged); + connect(mWidget, qOverload(&QDoubleSpinBox::valueChanged), this, &DoubleSetting::valueChanged); - return std::make_pair (label, mWidget); + return std::make_pair(label, mWidget); } void CSMPrefs::DoubleSetting::updateWidget() @@ -79,12 +83,12 @@ void CSMPrefs::DoubleSetting::updateWidget() } } -void CSMPrefs::DoubleSetting::valueChanged (double value) +void CSMPrefs::DoubleSetting::valueChanged(double value) { { - QMutexLocker lock (getMutex()); - Settings::Manager::setFloat (getKey(), getParent()->getKey(), value); + QMutexLocker lock(getMutex()); + Settings::Manager::setFloat(getKey(), getParent()->getKey(), value); } - getParent()->getState()->update (*this); + getParent()->getState()->update(*this); } diff --git a/apps/opencs/model/prefs/doublesetting.hpp b/apps/opencs/model/prefs/doublesetting.hpp index f65a776351..433d7ac8ca 100644 --- a/apps/opencs/model/prefs/doublesetting.hpp +++ b/apps/opencs/model/prefs/doublesetting.hpp @@ -9,40 +9,38 @@ namespace CSMPrefs { class DoubleSetting : public Setting { - Q_OBJECT + Q_OBJECT - int mPrecision; - double mMin; - double mMax; - std::string mTooltip; - double mDefault; - QDoubleSpinBox* mWidget; + int mPrecision; + double mMin; + double mMax; + std::string mTooltip; + double mDefault; + QDoubleSpinBox* mWidget; - public: + public: + DoubleSetting( + Category* parent, QMutex* mutex, const std::string& key, const std::string& label, double default_); - DoubleSetting (Category *parent, - QMutex *mutex, const std::string& key, const std::string& label, - double default_); + DoubleSetting& setPrecision(int precision); - DoubleSetting& setPrecision (int precision); + // defaults to [0, std::numeric_limits::max()] + DoubleSetting& setRange(double min, double max); - // defaults to [0, std::numeric_limits::max()] - DoubleSetting& setRange (double min, double max); + DoubleSetting& setMin(double min); - DoubleSetting& setMin (double min); + DoubleSetting& setMax(double max); - DoubleSetting& setMax (double max); + DoubleSetting& setTooltip(const std::string& tooltip); - DoubleSetting& setTooltip (const std::string& tooltip); + /// Return label, input widget. + std::pair makeWidgets(QWidget* parent) override; - /// Return label, input widget. - std::pair makeWidgets (QWidget *parent) override; + void updateWidget() override; - void updateWidget() override; + private slots: - private slots: - - void valueChanged (double value); + void valueChanged(double value); }; } diff --git a/apps/opencs/model/prefs/enumsetting.cpp b/apps/opencs/model/prefs/enumsetting.cpp index a11f84a993..7d64e31112 100644 --- a/apps/opencs/model/prefs/enumsetting.cpp +++ b/apps/opencs/model/prefs/enumsetting.cpp @@ -1,8 +1,8 @@ #include "enumsetting.hpp" -#include #include +#include #include #include @@ -11,114 +11,116 @@ #include "category.hpp" #include "state.hpp" +CSMPrefs::EnumValue::EnumValue(const std::string& value, const std::string& tooltip) + : mValue(value) + , mTooltip(tooltip) +{ +} -CSMPrefs::EnumValue::EnumValue (const std::string& value, const std::string& tooltip) -: mValue (value), mTooltip (tooltip) -{} - -CSMPrefs::EnumValue::EnumValue (const char *value) -: mValue (value) -{} - +CSMPrefs::EnumValue::EnumValue(const char* value) + : mValue(value) +{ +} -CSMPrefs::EnumValues& CSMPrefs::EnumValues::add (const EnumValues& values) +CSMPrefs::EnumValues& CSMPrefs::EnumValues::add(const EnumValues& values) { - mValues.insert (mValues.end(), values.mValues.begin(), values.mValues.end()); + mValues.insert(mValues.end(), values.mValues.begin(), values.mValues.end()); return *this; } -CSMPrefs::EnumValues& CSMPrefs::EnumValues::add (const EnumValue& value) +CSMPrefs::EnumValues& CSMPrefs::EnumValues::add(const EnumValue& value) { - mValues.push_back (value); + mValues.push_back(value); return *this; } -CSMPrefs::EnumValues& CSMPrefs::EnumValues::add (const std::string& value, const std::string& tooltip) +CSMPrefs::EnumValues& CSMPrefs::EnumValues::add(const std::string& value, const std::string& tooltip) { mValues.emplace_back(value, tooltip); return *this; } +CSMPrefs::EnumSetting::EnumSetting( + Category* parent, QMutex* mutex, const std::string& key, const std::string& label, const EnumValue& default_) + : Setting(parent, mutex, key, label) + , mDefault(default_) + , mWidget(nullptr) +{ +} -CSMPrefs::EnumSetting::EnumSetting (Category *parent, - QMutex *mutex, const std::string& key, const std::string& label, const EnumValue& default_) -: Setting (parent, mutex, key, label), mDefault (default_), mWidget(nullptr) -{} - -CSMPrefs::EnumSetting& CSMPrefs::EnumSetting::setTooltip (const std::string& tooltip) +CSMPrefs::EnumSetting& CSMPrefs::EnumSetting::setTooltip(const std::string& tooltip) { mTooltip = tooltip; return *this; } -CSMPrefs::EnumSetting& CSMPrefs::EnumSetting::addValues (const EnumValues& values) +CSMPrefs::EnumSetting& CSMPrefs::EnumSetting::addValues(const EnumValues& values) { - mValues.add (values); + mValues.add(values); return *this; } -CSMPrefs::EnumSetting& CSMPrefs::EnumSetting::addValue (const EnumValue& value) +CSMPrefs::EnumSetting& CSMPrefs::EnumSetting::addValue(const EnumValue& value) { - mValues.add (value); + mValues.add(value); return *this; } -CSMPrefs::EnumSetting& CSMPrefs::EnumSetting::addValue (const std::string& value, const std::string& tooltip) +CSMPrefs::EnumSetting& CSMPrefs::EnumSetting::addValue(const std::string& value, const std::string& tooltip) { - mValues.add (value, tooltip); + mValues.add(value, tooltip); return *this; } -std::pair CSMPrefs::EnumSetting::makeWidgets (QWidget *parent) +std::pair CSMPrefs::EnumSetting::makeWidgets(QWidget* parent) { - QLabel *label = new QLabel (QString::fromUtf8 (getLabel().c_str()), parent); + QLabel* label = new QLabel(QString::fromUtf8(getLabel().c_str()), parent); - mWidget = new QComboBox (parent); + mWidget = new QComboBox(parent); int index = 0; - for (int i=0; i (mValues.mValues.size()); ++i) + for (int i = 0; i < static_cast(mValues.mValues.size()); ++i) { - if (mDefault.mValue==mValues.mValues[i].mValue) + if (mDefault.mValue == mValues.mValues[i].mValue) index = i; - mWidget->addItem (QString::fromUtf8 (mValues.mValues[i].mValue.c_str())); + mWidget->addItem(QString::fromUtf8(mValues.mValues[i].mValue.c_str())); if (!mValues.mValues[i].mTooltip.empty()) - mWidget->setItemData (i, QString::fromUtf8 (mValues.mValues[i].mTooltip.c_str()), - Qt::ToolTipRole); + mWidget->setItemData(i, QString::fromUtf8(mValues.mValues[i].mTooltip.c_str()), Qt::ToolTipRole); } - mWidget->setCurrentIndex (index); + mWidget->setCurrentIndex(index); if (!mTooltip.empty()) { - QString tooltip = QString::fromUtf8 (mTooltip.c_str()); - label->setToolTip (tooltip); + QString tooltip = QString::fromUtf8(mTooltip.c_str()); + label->setToolTip(tooltip); } - connect (mWidget, qOverload(&QComboBox::currentIndexChanged), this, &EnumSetting::valueChanged); + connect(mWidget, qOverload(&QComboBox::currentIndexChanged), this, &EnumSetting::valueChanged); - return std::make_pair (label, mWidget); + return std::make_pair(label, mWidget); } void CSMPrefs::EnumSetting::updateWidget() { if (mWidget) { - int index = mWidget->findText(QString::fromStdString - (Settings::Manager::getString(getKey(), getParent()->getKey()))); + int index + = mWidget->findText(QString::fromStdString(Settings::Manager::getString(getKey(), getParent()->getKey()))); mWidget->setCurrentIndex(index); } } -void CSMPrefs::EnumSetting::valueChanged (int value) +void CSMPrefs::EnumSetting::valueChanged(int value) { { - QMutexLocker lock (getMutex()); - Settings::Manager::setString (getKey(), getParent()->getKey(), mValues.mValues.at (value).mValue); + QMutexLocker lock(getMutex()); + Settings::Manager::setString(getKey(), getParent()->getKey(), mValues.mValues.at(value).mValue); } - getParent()->getState()->update (*this); + getParent()->getState()->update(*this); } diff --git a/apps/opencs/model/prefs/enumsetting.hpp b/apps/opencs/model/prefs/enumsetting.hpp index d0467b0639..9acece98e8 100644 --- a/apps/opencs/model/prefs/enumsetting.hpp +++ b/apps/opencs/model/prefs/enumsetting.hpp @@ -14,53 +14,51 @@ namespace CSMPrefs std::string mValue; std::string mTooltip; - EnumValue (const std::string& value, const std::string& tooltip = ""); + EnumValue(const std::string& value, const std::string& tooltip = ""); - EnumValue (const char *value); + EnumValue(const char* value); }; struct EnumValues { std::vector mValues; - EnumValues& add (const EnumValues& values); + EnumValues& add(const EnumValues& values); - EnumValues& add (const EnumValue& value); + EnumValues& add(const EnumValue& value); - EnumValues& add (const std::string& value, const std::string& tooltip); + EnumValues& add(const std::string& value, const std::string& tooltip); }; class EnumSetting : public Setting { - Q_OBJECT + Q_OBJECT - std::string mTooltip; - EnumValue mDefault; - EnumValues mValues; - QComboBox* mWidget; - - public: + std::string mTooltip; + EnumValue mDefault; + EnumValues mValues; + QComboBox* mWidget; - EnumSetting (Category *parent, - QMutex *mutex, const std::string& key, const std::string& label, - const EnumValue& default_); + public: + EnumSetting(Category* parent, QMutex* mutex, const std::string& key, const std::string& label, + const EnumValue& default_); - EnumSetting& setTooltip (const std::string& tooltip); + EnumSetting& setTooltip(const std::string& tooltip); - EnumSetting& addValues (const EnumValues& values); + EnumSetting& addValues(const EnumValues& values); - EnumSetting& addValue (const EnumValue& value); + EnumSetting& addValue(const EnumValue& value); - EnumSetting& addValue (const std::string& value, const std::string& tooltip); + EnumSetting& addValue(const std::string& value, const std::string& tooltip); - /// Return label, input widget. - std::pair makeWidgets (QWidget *parent) override; + /// Return label, input widget. + std::pair makeWidgets(QWidget* parent) override; - void updateWidget() override; + void updateWidget() override; - private slots: + private slots: - void valueChanged (int value); + void valueChanged(int value); }; } diff --git a/apps/opencs/model/prefs/intsetting.cpp b/apps/opencs/model/prefs/intsetting.cpp index efc1d954ef..36a45bf04e 100644 --- a/apps/opencs/model/prefs/intsetting.cpp +++ b/apps/opencs/model/prefs/intsetting.cpp @@ -4,63 +4,67 @@ #include #include -#include #include +#include #include #include "category.hpp" #include "state.hpp" -CSMPrefs::IntSetting::IntSetting (Category *parent, - QMutex *mutex, const std::string& key, const std::string& label, int default_) -: Setting (parent, mutex, key, label), mMin (0), mMax (std::numeric_limits::max()), - mDefault (default_), mWidget(nullptr) -{} +CSMPrefs::IntSetting::IntSetting( + Category* parent, QMutex* mutex, const std::string& key, const std::string& label, int default_) + : Setting(parent, mutex, key, label) + , mMin(0) + , mMax(std::numeric_limits::max()) + , mDefault(default_) + , mWidget(nullptr) +{ +} -CSMPrefs::IntSetting& CSMPrefs::IntSetting::setRange (int min, int max) +CSMPrefs::IntSetting& CSMPrefs::IntSetting::setRange(int min, int max) { mMin = min; mMax = max; return *this; } -CSMPrefs::IntSetting& CSMPrefs::IntSetting::setMin (int min) +CSMPrefs::IntSetting& CSMPrefs::IntSetting::setMin(int min) { mMin = min; return *this; } -CSMPrefs::IntSetting& CSMPrefs::IntSetting::setMax (int max) +CSMPrefs::IntSetting& CSMPrefs::IntSetting::setMax(int max) { mMax = max; return *this; } -CSMPrefs::IntSetting& CSMPrefs::IntSetting::setTooltip (const std::string& tooltip) +CSMPrefs::IntSetting& CSMPrefs::IntSetting::setTooltip(const std::string& tooltip) { mTooltip = tooltip; return *this; } -std::pair CSMPrefs::IntSetting::makeWidgets (QWidget *parent) +std::pair CSMPrefs::IntSetting::makeWidgets(QWidget* parent) { - QLabel *label = new QLabel (QString::fromUtf8 (getLabel().c_str()), parent); + QLabel* label = new QLabel(QString::fromUtf8(getLabel().c_str()), parent); - mWidget = new QSpinBox (parent); - mWidget->setRange (mMin, mMax); - mWidget->setValue (mDefault); + mWidget = new QSpinBox(parent); + mWidget->setRange(mMin, mMax); + mWidget->setValue(mDefault); if (!mTooltip.empty()) { - QString tooltip = QString::fromUtf8 (mTooltip.c_str()); - label->setToolTip (tooltip); - mWidget->setToolTip (tooltip); + QString tooltip = QString::fromUtf8(mTooltip.c_str()); + label->setToolTip(tooltip); + mWidget->setToolTip(tooltip); } - connect (mWidget, qOverload(&QSpinBox::valueChanged), this, &IntSetting::valueChanged); + connect(mWidget, qOverload(&QSpinBox::valueChanged), this, &IntSetting::valueChanged); - return std::make_pair (label, mWidget); + return std::make_pair(label, mWidget); } void CSMPrefs::IntSetting::updateWidget() @@ -71,12 +75,12 @@ void CSMPrefs::IntSetting::updateWidget() } } -void CSMPrefs::IntSetting::valueChanged (int value) +void CSMPrefs::IntSetting::valueChanged(int value) { { - QMutexLocker lock (getMutex()); - Settings::Manager::setInt (getKey(), getParent()->getKey(), value); + QMutexLocker lock(getMutex()); + Settings::Manager::setInt(getKey(), getParent()->getKey(), value); } - getParent()->getState()->update (*this); + getParent()->getState()->update(*this); } diff --git a/apps/opencs/model/prefs/intsetting.hpp b/apps/opencs/model/prefs/intsetting.hpp index c03e010ad7..8ef811c8fc 100644 --- a/apps/opencs/model/prefs/intsetting.hpp +++ b/apps/opencs/model/prefs/intsetting.hpp @@ -9,36 +9,34 @@ namespace CSMPrefs { class IntSetting : public Setting { - Q_OBJECT + Q_OBJECT - int mMin; - int mMax; - std::string mTooltip; - int mDefault; - QSpinBox* mWidget; + int mMin; + int mMax; + std::string mTooltip; + int mDefault; + QSpinBox* mWidget; - public: + public: + IntSetting(Category* parent, QMutex* mutex, const std::string& key, const std::string& label, int default_); - IntSetting (Category *parent, - QMutex *mutex, const std::string& key, const std::string& label, int default_); + // defaults to [0, std::numeric_limits::max()] + IntSetting& setRange(int min, int max); - // defaults to [0, std::numeric_limits::max()] - IntSetting& setRange (int min, int max); + IntSetting& setMin(int min); - IntSetting& setMin (int min); + IntSetting& setMax(int max); - IntSetting& setMax (int max); + IntSetting& setTooltip(const std::string& tooltip); - IntSetting& setTooltip (const std::string& tooltip); + /// Return label, input widget. + std::pair makeWidgets(QWidget* parent) override; - /// Return label, input widget. - std::pair makeWidgets (QWidget *parent) override; + void updateWidget() override; - void updateWidget() override; + private slots: - private slots: - - void valueChanged (int value); + void valueChanged(int value); }; } diff --git a/apps/opencs/model/prefs/modifiersetting.cpp b/apps/opencs/model/prefs/modifiersetting.cpp index 1e4d29f1b6..d65367abaf 100644 --- a/apps/opencs/model/prefs/modifiersetting.cpp +++ b/apps/opencs/model/prefs/modifiersetting.cpp @@ -9,13 +9,12 @@ #include -#include "state.hpp" #include "shortcutmanager.hpp" +#include "state.hpp" namespace CSMPrefs { - ModifierSetting::ModifierSetting(Category* parent, QMutex* mutex, const std::string& key, - const std::string& label) + ModifierSetting::ModifierSetting(Category* parent, QMutex* mutex, const std::string& key, const std::string& label) : Setting(parent, mutex, key, label) , mButton(nullptr) , mEditorActive(false) @@ -40,7 +39,7 @@ namespace CSMPrefs mButton = widget; - connect (widget, &QPushButton::toggled, this, &ModifierSetting::buttonToggled); + connect(widget, &QPushButton::toggled, this, &ModifierSetting::buttonToggled); return std::make_pair(label, widget); } @@ -90,10 +89,7 @@ namespace CSMPrefs bool ModifierSetting::handleEvent(QObject* target, int mod, int value) { // For potential future exceptions - const int Blacklist[] = - { - 0 - }; + const int Blacklist[] = { 0 }; const size_t BlacklistSize = sizeof(Blacklist) / sizeof(int); @@ -118,7 +114,6 @@ namespace CSMPrefs return true; } - // Update modifier int modifier = value; storeValue(modifier); diff --git a/apps/opencs/model/prefs/modifiersetting.hpp b/apps/opencs/model/prefs/modifiersetting.hpp index d1af9d25c6..4aa8848759 100644 --- a/apps/opencs/model/prefs/modifiersetting.hpp +++ b/apps/opencs/model/prefs/modifiersetting.hpp @@ -12,33 +12,30 @@ namespace CSMPrefs { class ModifierSetting : public Setting { - Q_OBJECT + Q_OBJECT - public: + public: + ModifierSetting(Category* parent, QMutex* mutex, const std::string& key, const std::string& label); - ModifierSetting(Category* parent, QMutex* mutex, const std::string& key, const std::string& label); + std::pair makeWidgets(QWidget* parent) override; - std::pair makeWidgets(QWidget* parent) override; + void updateWidget() override; - void updateWidget() override; + protected: + bool eventFilter(QObject* target, QEvent* event) override; - protected: + private: + bool handleEvent(QObject* target, int mod, int value); - bool eventFilter(QObject* target, QEvent* event) override; + void storeValue(int modifier); + void resetState(); - private: + QPushButton* mButton; + bool mEditorActive; - bool handleEvent(QObject* target, int mod, int value); + private slots: - void storeValue(int modifier); - void resetState(); - - QPushButton* mButton; - bool mEditorActive; - - private slots: - - void buttonToggled(bool checked); + void buttonToggled(bool checked); }; } diff --git a/apps/opencs/model/prefs/setting.cpp b/apps/opencs/model/prefs/setting.cpp index 524938bcc7..4468fffaf3 100644 --- a/apps/opencs/model/prefs/setting.cpp +++ b/apps/opencs/model/prefs/setting.cpp @@ -9,28 +9,30 @@ #include "category.hpp" #include "state.hpp" -QMutex *CSMPrefs::Setting::getMutex() +QMutex* CSMPrefs::Setting::getMutex() { return mMutex; } -CSMPrefs::Setting::Setting (Category *parent, QMutex *mutex, - const std::string& key, const std::string& label) -: QObject (parent->getState()), mParent (parent), mMutex (mutex), mKey (key), mLabel (label) -{} - -CSMPrefs::Setting:: ~Setting() {} - -std::pair CSMPrefs::Setting::makeWidgets (QWidget *parent) +CSMPrefs::Setting::Setting(Category* parent, QMutex* mutex, const std::string& key, const std::string& label) + : QObject(parent->getState()) + , mParent(parent) + , mMutex(mutex) + , mKey(key) + , mLabel(label) { - return std::pair (0, 0); } -void CSMPrefs::Setting::updateWidget() +CSMPrefs::Setting::~Setting() {} + +std::pair CSMPrefs::Setting::makeWidgets(QWidget* parent) { + return std::pair(0, 0); } -const CSMPrefs::Category *CSMPrefs::Setting::getParent() const +void CSMPrefs::Setting::updateWidget() {} + +const CSMPrefs::Category* CSMPrefs::Setting::getParent() const { return mParent; } @@ -47,51 +49,51 @@ const std::string& CSMPrefs::Setting::getLabel() const int CSMPrefs::Setting::toInt() const { - QMutexLocker lock (mMutex); - return Settings::Manager::getInt (mKey, mParent->getKey()); + QMutexLocker lock(mMutex); + return Settings::Manager::getInt(mKey, mParent->getKey()); } double CSMPrefs::Setting::toDouble() const { - QMutexLocker lock (mMutex); - return Settings::Manager::getFloat (mKey, mParent->getKey()); + QMutexLocker lock(mMutex); + return Settings::Manager::getFloat(mKey, mParent->getKey()); } std::string CSMPrefs::Setting::toString() const { - QMutexLocker lock (mMutex); - return Settings::Manager::getString (mKey, mParent->getKey()); + QMutexLocker lock(mMutex); + return Settings::Manager::getString(mKey, mParent->getKey()); } bool CSMPrefs::Setting::isTrue() const { - QMutexLocker lock (mMutex); - return Settings::Manager::getBool (mKey, mParent->getKey()); + QMutexLocker lock(mMutex); + return Settings::Manager::getBool(mKey, mParent->getKey()); } QColor CSMPrefs::Setting::toColor() const { // toString() handles lock - return QColor (QString::fromUtf8 (toString().c_str())); + return QColor(QString::fromUtf8(toString().c_str())); } -bool CSMPrefs::operator== (const Setting& setting, const std::string& key) +bool CSMPrefs::operator==(const Setting& setting, const std::string& key) { std::string fullKey = setting.getParent()->getKey() + "/" + setting.getKey(); - return fullKey==key; + return fullKey == key; } -bool CSMPrefs::operator== (const std::string& key, const Setting& setting) +bool CSMPrefs::operator==(const std::string& key, const Setting& setting) { - return setting==key; + return setting == key; } -bool CSMPrefs::operator!= (const Setting& setting, const std::string& key) +bool CSMPrefs::operator!=(const Setting& setting, const std::string& key) { - return !(setting==key); + return !(setting == key); } -bool CSMPrefs::operator!= (const std::string& key, const Setting& setting) +bool CSMPrefs::operator!=(const std::string& key, const Setting& setting) { - return !(key==setting); + return !(key == setting); } diff --git a/apps/opencs/model/prefs/setting.hpp b/apps/opencs/model/prefs/setting.hpp index fcf70c26cd..86e80fb107 100644 --- a/apps/opencs/model/prefs/setting.hpp +++ b/apps/opencs/model/prefs/setting.hpp @@ -16,56 +16,54 @@ namespace CSMPrefs class Setting : public QObject { - Q_OBJECT + Q_OBJECT - Category *mParent; - QMutex *mMutex; - std::string mKey; - std::string mLabel; + Category* mParent; + QMutex* mMutex; + std::string mKey; + std::string mLabel; - protected: + protected: + QMutex* getMutex(); - QMutex *getMutex(); + public: + Setting(Category* parent, QMutex* mutex, const std::string& key, const std::string& label); - public: + virtual ~Setting(); - Setting (Category *parent, QMutex *mutex, const std::string& key, const std::string& label); + /// Return label, input widget. + /// + /// \note first can be a 0-pointer, which means that the label is part of the input + /// widget. + virtual std::pair makeWidgets(QWidget* parent); - virtual ~Setting(); + /// Updates the widget returned by makeWidgets() to the current setting. + /// + /// \note If make_widgets() has not been called yet then nothing happens. + virtual void updateWidget(); - /// Return label, input widget. - /// - /// \note first can be a 0-pointer, which means that the label is part of the input - /// widget. - virtual std::pair makeWidgets (QWidget *parent); + const Category* getParent() const; - /// Updates the widget returned by makeWidgets() to the current setting. - /// - /// \note If make_widgets() has not been called yet then nothing happens. - virtual void updateWidget(); + const std::string& getKey() const; - const Category *getParent() const; + const std::string& getLabel() const; - const std::string& getKey() const; + int toInt() const; - const std::string& getLabel() const; + double toDouble() const; - int toInt() const; + std::string toString() const; - double toDouble() const; + bool isTrue() const; - std::string toString() const; - - bool isTrue() const; - - QColor toColor() const; + QColor toColor() const; }; // note: fullKeys have the format categoryKey/settingKey - bool operator== (const Setting& setting, const std::string& fullKey); - bool operator== (const std::string& fullKey, const Setting& setting); - bool operator!= (const Setting& setting, const std::string& fullKey); - bool operator!= (const std::string& fullKey, const Setting& setting); + bool operator==(const Setting& setting, const std::string& fullKey); + bool operator==(const std::string& fullKey, const Setting& setting); + bool operator!=(const Setting& setting, const std::string& fullKey); + bool operator!=(const std::string& fullKey, const Setting& setting); } #endif diff --git a/apps/opencs/model/prefs/shortcut.cpp b/apps/opencs/model/prefs/shortcut.cpp index 130553a0f2..ae52df5912 100644 --- a/apps/opencs/model/prefs/shortcut.cpp +++ b/apps/opencs/model/prefs/shortcut.cpp @@ -7,8 +7,8 @@ #include -#include "state.hpp" #include "shortcutmanager.hpp" +#include "state.hpp" namespace CSMPrefs { @@ -25,7 +25,7 @@ namespace CSMPrefs , mModifierStatus(false) , mAction(nullptr) { - assert (parent); + assert(parent); State::get().getShortcutManager().addShortcut(this); State::get().getShortcutManager().getSequence(name, mSequence); @@ -44,7 +44,7 @@ namespace CSMPrefs , mModifierStatus(false) , mAction(nullptr) { - assert (parent); + assert(parent); State::get().getShortcutManager().addShortcut(this); State::get().getShortcutManager().getSequence(name, mSequence); @@ -64,7 +64,7 @@ namespace CSMPrefs , mModifierStatus(false) , mAction(nullptr) { - assert (parent); + assert(parent); State::get().getShortcutManager().addShortcut(this); State::get().getShortcutManager().getSequence(name, mSequence); @@ -77,7 +77,7 @@ namespace CSMPrefs { State::get().getShortcutManager().removeShortcut(this); } - catch(const std::exception& e) + catch (const std::exception& e) { Log(Debug::Error) << "Error in the destructor: " << e.what(); } diff --git a/apps/opencs/model/prefs/shortcut.hpp b/apps/opencs/model/prefs/shortcut.hpp index 4fa6f8a1a1..b2a17b8cb2 100644 --- a/apps/opencs/model/prefs/shortcut.hpp +++ b/apps/opencs/model/prefs/shortcut.hpp @@ -15,107 +15,105 @@ namespace CSMPrefs /// A class similar in purpose to QShortcut, but with the ability to use mouse buttons class Shortcut : public QObject { - Q_OBJECT + Q_OBJECT - public: + public: + enum ActivationStatus + { + AS_Regular, + AS_Secondary, + AS_Inactive + }; - enum ActivationStatus - { - AS_Regular, - AS_Secondary, - AS_Inactive - }; + enum SecondaryMode + { + SM_Replace, ///< The secondary signal replaces the regular signal when the modifier is active + SM_Detach, ///< The secondary signal is emitted independent of the regular signal, even if not active + SM_Ignore ///< The secondary signal will not ever be emitted + }; - enum SecondaryMode - { - SM_Replace, ///< The secondary signal replaces the regular signal when the modifier is active - SM_Detach, ///< The secondary signal is emitted independent of the regular signal, even if not active - SM_Ignore ///< The secondary signal will not ever be emitted - }; + Shortcut(const std::string& name, QWidget* parent); + Shortcut(const std::string& name, const std::string& modName, QWidget* parent); + Shortcut(const std::string& name, const std::string& modName, SecondaryMode secMode, QWidget* parent); - Shortcut(const std::string& name, QWidget* parent); - Shortcut(const std::string& name, const std::string& modName, QWidget* parent); - Shortcut(const std::string& name, const std::string& modName, SecondaryMode secMode, QWidget* parent); + ~Shortcut(); - ~Shortcut(); + bool isEnabled() const; - bool isEnabled() const; + const std::string& getName() const; + const std::string& getModifierName() const; - const std::string& getName() const; - const std::string& getModifierName() const; + SecondaryMode getSecondaryMode() const; - SecondaryMode getSecondaryMode() const; + const QKeySequence& getSequence() const; + int getModifier() const; - const QKeySequence& getSequence() const; - int getModifier() const; + /// The position in the sequence + int getPosition() const; + /// The position in the sequence + int getLastPosition() const; - /// The position in the sequence - int getPosition() const; - /// The position in the sequence - int getLastPosition() const; + ActivationStatus getActivationStatus() const; + bool getModifierStatus() const; - ActivationStatus getActivationStatus() const; - bool getModifierStatus() const; + void enable(bool state); - void enable(bool state); + void setSequence(const QKeySequence& sequence); + void setModifier(int modifier); - void setSequence(const QKeySequence& sequence); - void setModifier(int modifier); + /// The position in the sequence + void setPosition(int pos); - /// The position in the sequence - void setPosition(int pos); + void setActivationStatus(ActivationStatus status); + void setModifierStatus(bool status); - void setActivationStatus(ActivationStatus status); - void setModifierStatus(bool status); + /// Appends the sequence to the QAction text, also keeps it up to date + void associateAction(QAction* action); - /// Appends the sequence to the QAction text, also keeps it up to date - void associateAction(QAction* action); + // Workaround for Qt4 signals being "protected" + void signalActivated(bool state); + void signalActivated(); - // Workaround for Qt4 signals being "protected" - void signalActivated(bool state); - void signalActivated(); + void signalSecondary(bool state); + void signalSecondary(); - void signalSecondary(bool state); - void signalSecondary(); + QString toString() const; - QString toString() const; + private: + bool mEnabled; - private: + std::string mName; + std::string mModName; + SecondaryMode mSecondaryMode; + QKeySequence mSequence; + int mModifier; - bool mEnabled; + int mCurrentPos; + int mLastPos; - std::string mName; - std::string mModName; - SecondaryMode mSecondaryMode; - QKeySequence mSequence; - int mModifier; + ActivationStatus mActivationStatus; + bool mModifierStatus; - int mCurrentPos; - int mLastPos; + QAction* mAction; + QString mActionText; - ActivationStatus mActivationStatus; - bool mModifierStatus; + private slots: - QAction* mAction; - QString mActionText; + void actionDeleted(); - private slots: + signals: - void actionDeleted(); + /// Triggered when the shortcut is activated or deactivated; can be determined from \p state + void activated(bool state); - signals: + /// Convenience signal. + void activated(); - /// Triggered when the shortcut is activated or deactivated; can be determined from \p state - void activated(bool state); + /// Triggered depending on SecondaryMode + void secondary(bool state); - /// Convenience signal. - void activated(); - - /// Triggered depending on SecondaryMode - void secondary(bool state); - - /// Convenience signal. - void secondary(); + /// Convenience signal. + void secondary(); }; } diff --git a/apps/opencs/model/prefs/shortcuteventhandler.cpp b/apps/opencs/model/prefs/shortcuteventhandler.cpp index 50fd336e8a..aedd9b52ee 100644 --- a/apps/opencs/model/prefs/shortcuteventhandler.cpp +++ b/apps/opencs/model/prefs/shortcuteventhandler.cpp @@ -49,7 +49,9 @@ namespace CSMPrefs ShortcutMap::iterator shortcutListIt = mWidgetShortcuts.find(widget); if (shortcutListIt != mWidgetShortcuts.end()) { - shortcutListIt->second.erase(std::remove(shortcutListIt->second.begin(), shortcutListIt->second.end(), shortcut), shortcutListIt->second.end()); + shortcutListIt->second.erase( + std::remove(shortcutListIt->second.begin(), shortcutListIt->second.end(), shortcut), + shortcutListIt->second.end()); } } @@ -60,8 +62,8 @@ namespace CSMPrefs { QWidget* widget = static_cast(watched); QKeyEvent* keyEvent = static_cast(event); - unsigned int mod = (unsigned int) keyEvent->modifiers(); - unsigned int key = (unsigned int) keyEvent->key(); + unsigned int mod = (unsigned int)keyEvent->modifiers(); + unsigned int key = (unsigned int)keyEvent->key(); if (!keyEvent->isAutoRepeat()) return activate(widget, mod, key); @@ -70,8 +72,8 @@ namespace CSMPrefs { QWidget* widget = static_cast(watched); QKeyEvent* keyEvent = static_cast(event); - unsigned int mod = (unsigned int) keyEvent->modifiers(); - unsigned int key = (unsigned int) keyEvent->key(); + unsigned int mod = (unsigned int)keyEvent->modifiers(); + unsigned int key = (unsigned int)keyEvent->key(); if (!keyEvent->isAutoRepeat()) return deactivate(widget, mod, key); @@ -80,8 +82,8 @@ namespace CSMPrefs { QWidget* widget = static_cast(watched); QMouseEvent* mouseEvent = static_cast(event); - unsigned int mod = (unsigned int) mouseEvent->modifiers(); - unsigned int button = (unsigned int) mouseEvent->button(); + unsigned int mod = (unsigned int)mouseEvent->modifiers(); + unsigned int button = (unsigned int)mouseEvent->button(); return activate(widget, mod, button); } @@ -89,8 +91,8 @@ namespace CSMPrefs { QWidget* widget = static_cast(watched); QMouseEvent* mouseEvent = static_cast(event); - unsigned int mod = (unsigned int) mouseEvent->modifiers(); - unsigned int button = (unsigned int) mouseEvent->button(); + unsigned int mod = (unsigned int)mouseEvent->modifiers(); + unsigned int button = (unsigned int)mouseEvent->button(); return deactivate(widget, mod, button); } @@ -148,7 +150,7 @@ namespace CSMPrefs bool ShortcutEventHandler::activate(QWidget* widget, unsigned int mod, unsigned int button) { - std::vector > potentials; + std::vector> potentials; bool used = false; while (widget) @@ -178,7 +180,7 @@ namespace CSMPrefs { if (pos < lastPos && (result == Matches_WithMod || pos > 0)) { - shortcut->setPosition(pos+1); + shortcut->setPosition(pos + 1); } else if (pos == lastPos) { @@ -267,8 +269,8 @@ namespace CSMPrefs bool ShortcutEventHandler::checkModifier(unsigned int mod, unsigned int button, Shortcut* shortcut, bool activate) { - if (!shortcut->isEnabled() || !shortcut->getModifier() || shortcut->getSecondaryMode() == Shortcut::SM_Ignore || - shortcut->getModifierStatus() == activate) + if (!shortcut->isEnabled() || !shortcut->getModifier() || shortcut->getSecondaryMode() == Shortcut::SM_Ignore + || shortcut->getModifierStatus() == activate) return false; MatchResult result = match(mod, button, shortcut->getModifier()); @@ -302,8 +304,8 @@ namespace CSMPrefs return used; } - ShortcutEventHandler::MatchResult ShortcutEventHandler::match(unsigned int mod, unsigned int button, - unsigned int value) + ShortcutEventHandler::MatchResult ShortcutEventHandler::match( + unsigned int mod, unsigned int button, unsigned int value) { if ((mod | button) == value) { @@ -319,8 +321,8 @@ namespace CSMPrefs } } - bool ShortcutEventHandler::sort(const std::pair& left, - const std::pair& right) + bool ShortcutEventHandler::sort( + const std::pair& left, const std::pair& right) { if (left.first == Matches_WithMod && right.first == Matches_NoMod) return true; diff --git a/apps/opencs/model/prefs/shortcuteventhandler.hpp b/apps/opencs/model/prefs/shortcuteventhandler.hpp index 700b977fd3..2093e259e9 100644 --- a/apps/opencs/model/prefs/shortcuteventhandler.hpp +++ b/apps/opencs/model/prefs/shortcuteventhandler.hpp @@ -16,53 +16,49 @@ namespace CSMPrefs /// Users of this class should install it as an event handler class ShortcutEventHandler : public QObject { - Q_OBJECT + Q_OBJECT - public: + public: + ShortcutEventHandler(QObject* parent); - ShortcutEventHandler(QObject* parent); + void addShortcut(Shortcut* shortcut); + void removeShortcut(Shortcut* shortcut); - void addShortcut(Shortcut* shortcut); - void removeShortcut(Shortcut* shortcut); + protected: + bool eventFilter(QObject* watched, QEvent* event) override; - protected: + private: + typedef std::vector ShortcutList; + // Child, Parent + typedef std::map WidgetMap; + typedef std::map ShortcutMap; - bool eventFilter(QObject* watched, QEvent* event) override; + enum MatchResult + { + Matches_WithMod, + Matches_NoMod, + Matches_Not + }; - private: + void updateParent(QWidget* widget); - typedef std::vector ShortcutList; - // Child, Parent - typedef std::map WidgetMap; - typedef std::map ShortcutMap; + bool activate(QWidget* widget, unsigned int mod, unsigned int button); - enum MatchResult - { - Matches_WithMod, - Matches_NoMod, - Matches_Not - }; + bool deactivate(QWidget* widget, unsigned int mod, unsigned int button); - void updateParent(QWidget* widget); + bool checkModifier(unsigned int mod, unsigned int button, Shortcut* shortcut, bool activate); - bool activate(QWidget* widget, unsigned int mod, unsigned int button); + MatchResult match(unsigned int mod, unsigned int button, unsigned int value); - bool deactivate(QWidget* widget, unsigned int mod, unsigned int button); + // Prefers Matches_WithMod and a larger number of buttons + static bool sort(const std::pair& left, const std::pair& right); - bool checkModifier(unsigned int mod, unsigned int button, Shortcut* shortcut, bool activate); + WidgetMap mChildParentRelations; + ShortcutMap mWidgetShortcuts; - MatchResult match(unsigned int mod, unsigned int button, unsigned int value); + private slots: - // Prefers Matches_WithMod and a larger number of buttons - static bool sort(const std::pair& left, - const std::pair& right); - - WidgetMap mChildParentRelations; - ShortcutMap mWidgetShortcuts; - - private slots: - - void widgetDestroyed(); + void widgetDestroyed(); }; } diff --git a/apps/opencs/model/prefs/shortcutmanager.cpp b/apps/opencs/model/prefs/shortcutmanager.cpp index 25f295cd37..dfba28bd70 100644 --- a/apps/opencs/model/prefs/shortcutmanager.cpp +++ b/apps/opencs/model/prefs/shortcutmanager.cpp @@ -341,446 +341,445 @@ namespace CSMPrefs return substrings.join(""); } - const std::pair ShortcutManager::QtKeys[] = - { - std::make_pair((int)Qt::Key_Space , "Space"), - std::make_pair((int)Qt::Key_Exclam , "Exclam"), - std::make_pair((int)Qt::Key_QuoteDbl , "QuoteDbl"), - std::make_pair((int)Qt::Key_NumberSign , "NumberSign"), - std::make_pair((int)Qt::Key_Dollar , "Dollar"), - std::make_pair((int)Qt::Key_Percent , "Percent"), - std::make_pair((int)Qt::Key_Ampersand , "Ampersand"), - std::make_pair((int)Qt::Key_Apostrophe , "Apostrophe"), - std::make_pair((int)Qt::Key_ParenLeft , "ParenLeft"), - std::make_pair((int)Qt::Key_ParenRight , "ParenRight"), - std::make_pair((int)Qt::Key_Asterisk , "Asterisk"), - std::make_pair((int)Qt::Key_Plus , "Plus"), - std::make_pair((int)Qt::Key_Comma , "Comma"), - std::make_pair((int)Qt::Key_Minus , "Minus"), - std::make_pair((int)Qt::Key_Period , "Period"), - std::make_pair((int)Qt::Key_Slash , "Slash"), - std::make_pair((int)Qt::Key_0 , "0"), - std::make_pair((int)Qt::Key_1 , "1"), - std::make_pair((int)Qt::Key_2 , "2"), - std::make_pair((int)Qt::Key_3 , "3"), - std::make_pair((int)Qt::Key_4 , "4"), - std::make_pair((int)Qt::Key_5 , "5"), - std::make_pair((int)Qt::Key_6 , "6"), - std::make_pair((int)Qt::Key_7 , "7"), - std::make_pair((int)Qt::Key_8 , "8"), - std::make_pair((int)Qt::Key_9 , "9"), - std::make_pair((int)Qt::Key_Colon , "Colon"), - std::make_pair((int)Qt::Key_Semicolon , "Semicolon"), - std::make_pair((int)Qt::Key_Less , "Less"), - std::make_pair((int)Qt::Key_Equal , "Equal"), - std::make_pair((int)Qt::Key_Greater , "Greater"), - std::make_pair((int)Qt::Key_Question , "Question"), - std::make_pair((int)Qt::Key_At , "At"), - std::make_pair((int)Qt::Key_A , "A"), - std::make_pair((int)Qt::Key_B , "B"), - std::make_pair((int)Qt::Key_C , "C"), - std::make_pair((int)Qt::Key_D , "D"), - std::make_pair((int)Qt::Key_E , "E"), - std::make_pair((int)Qt::Key_F , "F"), - std::make_pair((int)Qt::Key_G , "G"), - std::make_pair((int)Qt::Key_H , "H"), - std::make_pair((int)Qt::Key_I , "I"), - std::make_pair((int)Qt::Key_J , "J"), - std::make_pair((int)Qt::Key_K , "K"), - std::make_pair((int)Qt::Key_L , "L"), - std::make_pair((int)Qt::Key_M , "M"), - std::make_pair((int)Qt::Key_N , "N"), - std::make_pair((int)Qt::Key_O , "O"), - std::make_pair((int)Qt::Key_P , "P"), - std::make_pair((int)Qt::Key_Q , "Q"), - std::make_pair((int)Qt::Key_R , "R"), - std::make_pair((int)Qt::Key_S , "S"), - std::make_pair((int)Qt::Key_T , "T"), - std::make_pair((int)Qt::Key_U , "U"), - std::make_pair((int)Qt::Key_V , "V"), - std::make_pair((int)Qt::Key_W , "W"), - std::make_pair((int)Qt::Key_X , "X"), - std::make_pair((int)Qt::Key_Y , "Y"), - std::make_pair((int)Qt::Key_Z , "Z"), - std::make_pair((int)Qt::Key_BracketLeft , "BracketLeft"), - std::make_pair((int)Qt::Key_Backslash , "Backslash"), - std::make_pair((int)Qt::Key_BracketRight , "BracketRight"), - std::make_pair((int)Qt::Key_AsciiCircum , "AsciiCircum"), - std::make_pair((int)Qt::Key_Underscore , "Underscore"), - std::make_pair((int)Qt::Key_QuoteLeft , "QuoteLeft"), - std::make_pair((int)Qt::Key_BraceLeft , "BraceLeft"), - std::make_pair((int)Qt::Key_Bar , "Bar"), - std::make_pair((int)Qt::Key_BraceRight , "BraceRight"), - std::make_pair((int)Qt::Key_AsciiTilde , "AsciiTilde"), - std::make_pair((int)Qt::Key_nobreakspace , "nobreakspace"), - std::make_pair((int)Qt::Key_exclamdown , "exclamdown"), - std::make_pair((int)Qt::Key_cent , "cent"), - std::make_pair((int)Qt::Key_sterling , "sterling"), - std::make_pair((int)Qt::Key_currency , "currency"), - std::make_pair((int)Qt::Key_yen , "yen"), - std::make_pair((int)Qt::Key_brokenbar , "brokenbar"), - std::make_pair((int)Qt::Key_section , "section"), - std::make_pair((int)Qt::Key_diaeresis , "diaeresis"), - std::make_pair((int)Qt::Key_copyright , "copyright"), - std::make_pair((int)Qt::Key_ordfeminine , "ordfeminine"), - std::make_pair((int)Qt::Key_guillemotleft , "guillemotleft"), - std::make_pair((int)Qt::Key_notsign , "notsign"), - std::make_pair((int)Qt::Key_hyphen , "hyphen"), - std::make_pair((int)Qt::Key_registered , "registered"), - std::make_pair((int)Qt::Key_macron , "macron"), - std::make_pair((int)Qt::Key_degree , "degree"), - std::make_pair((int)Qt::Key_plusminus , "plusminus"), - std::make_pair((int)Qt::Key_twosuperior , "twosuperior"), - std::make_pair((int)Qt::Key_threesuperior , "threesuperior"), - std::make_pair((int)Qt::Key_acute , "acute"), - std::make_pair((int)Qt::Key_mu , "mu"), - std::make_pair((int)Qt::Key_paragraph , "paragraph"), - std::make_pair((int)Qt::Key_periodcentered , "periodcentered"), - std::make_pair((int)Qt::Key_cedilla , "cedilla"), - std::make_pair((int)Qt::Key_onesuperior , "onesuperior"), - std::make_pair((int)Qt::Key_masculine , "masculine"), - std::make_pair((int)Qt::Key_guillemotright , "guillemotright"), - std::make_pair((int)Qt::Key_onequarter , "onequarter"), - std::make_pair((int)Qt::Key_onehalf , "onehalf"), - std::make_pair((int)Qt::Key_threequarters , "threequarters"), - std::make_pair((int)Qt::Key_questiondown , "questiondown"), - std::make_pair((int)Qt::Key_Agrave , "Agrave"), - std::make_pair((int)Qt::Key_Aacute , "Aacute"), - std::make_pair((int)Qt::Key_Acircumflex , "Acircumflex"), - std::make_pair((int)Qt::Key_Atilde , "Atilde"), - std::make_pair((int)Qt::Key_Adiaeresis , "Adiaeresis"), - std::make_pair((int)Qt::Key_Aring , "Aring"), - std::make_pair((int)Qt::Key_AE , "AE"), - std::make_pair((int)Qt::Key_Ccedilla , "Ccedilla"), - std::make_pair((int)Qt::Key_Egrave , "Egrave"), - std::make_pair((int)Qt::Key_Eacute , "Eacute"), - std::make_pair((int)Qt::Key_Ecircumflex , "Ecircumflex"), - std::make_pair((int)Qt::Key_Ediaeresis , "Ediaeresis"), - std::make_pair((int)Qt::Key_Igrave , "Igrave"), - std::make_pair((int)Qt::Key_Iacute , "Iacute"), - std::make_pair((int)Qt::Key_Icircumflex , "Icircumflex"), - std::make_pair((int)Qt::Key_Idiaeresis , "Idiaeresis"), - std::make_pair((int)Qt::Key_ETH , "ETH"), - std::make_pair((int)Qt::Key_Ntilde , "Ntilde"), - std::make_pair((int)Qt::Key_Ograve , "Ograve"), - std::make_pair((int)Qt::Key_Oacute , "Oacute"), - std::make_pair((int)Qt::Key_Ocircumflex , "Ocircumflex"), - std::make_pair((int)Qt::Key_Otilde , "Otilde"), - std::make_pair((int)Qt::Key_Odiaeresis , "Odiaeresis"), - std::make_pair((int)Qt::Key_multiply , "multiply"), - std::make_pair((int)Qt::Key_Ooblique , "Ooblique"), - std::make_pair((int)Qt::Key_Ugrave , "Ugrave"), - std::make_pair((int)Qt::Key_Uacute , "Uacute"), - std::make_pair((int)Qt::Key_Ucircumflex , "Ucircumflex"), - std::make_pair((int)Qt::Key_Udiaeresis , "Udiaeresis"), - std::make_pair((int)Qt::Key_Yacute , "Yacute"), - std::make_pair((int)Qt::Key_THORN , "THORN"), - std::make_pair((int)Qt::Key_ssharp , "ssharp"), - std::make_pair((int)Qt::Key_division , "division"), - std::make_pair((int)Qt::Key_ydiaeresis , "ydiaeresis"), - std::make_pair((int)Qt::Key_Escape , "Escape"), - std::make_pair((int)Qt::Key_Tab , "Tab"), - std::make_pair((int)Qt::Key_Backtab , "Backtab"), - std::make_pair((int)Qt::Key_Backspace , "Backspace"), - std::make_pair((int)Qt::Key_Return , "Return"), - std::make_pair((int)Qt::Key_Enter , "Enter"), - std::make_pair((int)Qt::Key_Insert , "Insert"), - std::make_pair((int)Qt::Key_Delete , "Delete"), - std::make_pair((int)Qt::Key_Pause , "Pause"), - std::make_pair((int)Qt::Key_Print , "Print"), - std::make_pair((int)Qt::Key_SysReq , "SysReq"), - std::make_pair((int)Qt::Key_Clear , "Clear"), - std::make_pair((int)Qt::Key_Home , "Home"), - std::make_pair((int)Qt::Key_End , "End"), - std::make_pair((int)Qt::Key_Left , "Left"), - std::make_pair((int)Qt::Key_Up , "Up"), - std::make_pair((int)Qt::Key_Right , "Right"), - std::make_pair((int)Qt::Key_Down , "Down"), - std::make_pair((int)Qt::Key_PageUp , "PageUp"), - std::make_pair((int)Qt::Key_PageDown , "PageDown"), - std::make_pair((int)Qt::Key_Shift , "Shift"), - std::make_pair((int)Qt::Key_Control , "Control"), - std::make_pair((int)Qt::Key_Meta , "Meta"), - std::make_pair((int)Qt::Key_Alt , "Alt"), - std::make_pair((int)Qt::Key_CapsLock , "CapsLock"), - std::make_pair((int)Qt::Key_NumLock , "NumLock"), - std::make_pair((int)Qt::Key_ScrollLock , "ScrollLock"), - std::make_pair((int)Qt::Key_F1 , "F1"), - std::make_pair((int)Qt::Key_F2 , "F2"), - std::make_pair((int)Qt::Key_F3 , "F3"), - std::make_pair((int)Qt::Key_F4 , "F4"), - std::make_pair((int)Qt::Key_F5 , "F5"), - std::make_pair((int)Qt::Key_F6 , "F6"), - std::make_pair((int)Qt::Key_F7 , "F7"), - std::make_pair((int)Qt::Key_F8 , "F8"), - std::make_pair((int)Qt::Key_F9 , "F9"), - std::make_pair((int)Qt::Key_F10 , "F10"), - std::make_pair((int)Qt::Key_F11 , "F11"), - std::make_pair((int)Qt::Key_F12 , "F12"), - std::make_pair((int)Qt::Key_F13 , "F13"), - std::make_pair((int)Qt::Key_F14 , "F14"), - std::make_pair((int)Qt::Key_F15 , "F15"), - std::make_pair((int)Qt::Key_F16 , "F16"), - std::make_pair((int)Qt::Key_F17 , "F17"), - std::make_pair((int)Qt::Key_F18 , "F18"), - std::make_pair((int)Qt::Key_F19 , "F19"), - std::make_pair((int)Qt::Key_F20 , "F20"), - std::make_pair((int)Qt::Key_F21 , "F21"), - std::make_pair((int)Qt::Key_F22 , "F22"), - std::make_pair((int)Qt::Key_F23 , "F23"), - std::make_pair((int)Qt::Key_F24 , "F24"), - std::make_pair((int)Qt::Key_F25 , "F25"), - std::make_pair((int)Qt::Key_F26 , "F26"), - std::make_pair((int)Qt::Key_F27 , "F27"), - std::make_pair((int)Qt::Key_F28 , "F28"), - std::make_pair((int)Qt::Key_F29 , "F29"), - std::make_pair((int)Qt::Key_F30 , "F30"), - std::make_pair((int)Qt::Key_F31 , "F31"), - std::make_pair((int)Qt::Key_F32 , "F32"), - std::make_pair((int)Qt::Key_F33 , "F33"), - std::make_pair((int)Qt::Key_F34 , "F34"), - std::make_pair((int)Qt::Key_F35 , "F35"), - std::make_pair((int)Qt::Key_Super_L , "Super_L"), - std::make_pair((int)Qt::Key_Super_R , "Super_R"), - std::make_pair((int)Qt::Key_Menu , "Menu"), - std::make_pair((int)Qt::Key_Hyper_L , "Hyper_L"), - std::make_pair((int)Qt::Key_Hyper_R , "Hyper_R"), - std::make_pair((int)Qt::Key_Help , "Help"), - std::make_pair((int)Qt::Key_Direction_L , "Direction_L"), - std::make_pair((int)Qt::Key_Direction_R , "Direction_R"), - std::make_pair((int)Qt::Key_Back , "Back"), - std::make_pair((int)Qt::Key_Forward , "Forward"), - std::make_pair((int)Qt::Key_Stop , "Stop"), - std::make_pair((int)Qt::Key_Refresh , "Refresh"), - std::make_pair((int)Qt::Key_VolumeDown , "VolumeDown"), - std::make_pair((int)Qt::Key_VolumeMute , "VolumeMute"), - std::make_pair((int)Qt::Key_VolumeUp , "VolumeUp"), - std::make_pair((int)Qt::Key_BassBoost , "BassBoost"), - std::make_pair((int)Qt::Key_BassUp , "BassUp"), - std::make_pair((int)Qt::Key_BassDown , "BassDown"), - std::make_pair((int)Qt::Key_TrebleUp , "TrebleUp"), - std::make_pair((int)Qt::Key_TrebleDown , "TrebleDown"), - std::make_pair((int)Qt::Key_MediaPlay , "MediaPlay"), - std::make_pair((int)Qt::Key_MediaStop , "MediaStop"), - std::make_pair((int)Qt::Key_MediaPrevious , "MediaPrevious"), - std::make_pair((int)Qt::Key_MediaNext , "MediaNext"), - std::make_pair((int)Qt::Key_MediaRecord , "MediaRecord"), - std::make_pair((int)Qt::Key_MediaPause , "MediaPause"), - std::make_pair((int)Qt::Key_MediaTogglePlayPause , "MediaTogglePlayPause"), - std::make_pair((int)Qt::Key_HomePage , "HomePage"), - std::make_pair((int)Qt::Key_Favorites , "Favorites"), - std::make_pair((int)Qt::Key_Search , "Search"), - std::make_pair((int)Qt::Key_Standby , "Standby"), - std::make_pair((int)Qt::Key_OpenUrl , "OpenUrl"), - std::make_pair((int)Qt::Key_LaunchMail , "LaunchMail"), - std::make_pair((int)Qt::Key_LaunchMedia , "LaunchMedia"), - std::make_pair((int)Qt::Key_Launch0 , "Launch0"), - std::make_pair((int)Qt::Key_Launch1 , "Launch1"), - std::make_pair((int)Qt::Key_Launch2 , "Launch2"), - std::make_pair((int)Qt::Key_Launch3 , "Launch3"), - std::make_pair((int)Qt::Key_Launch4 , "Launch4"), - std::make_pair((int)Qt::Key_Launch5 , "Launch5"), - std::make_pair((int)Qt::Key_Launch6 , "Launch6"), - std::make_pair((int)Qt::Key_Launch7 , "Launch7"), - std::make_pair((int)Qt::Key_Launch8 , "Launch8"), - std::make_pair((int)Qt::Key_Launch9 , "Launch9"), - std::make_pair((int)Qt::Key_LaunchA , "LaunchA"), - std::make_pair((int)Qt::Key_LaunchB , "LaunchB"), - std::make_pair((int)Qt::Key_LaunchC , "LaunchC"), - std::make_pair((int)Qt::Key_LaunchD , "LaunchD"), - std::make_pair((int)Qt::Key_LaunchE , "LaunchE"), - std::make_pair((int)Qt::Key_LaunchF , "LaunchF"), - std::make_pair((int)Qt::Key_MonBrightnessUp , "MonBrightnessUp"), - std::make_pair((int)Qt::Key_MonBrightnessDown , "MonBrightnessDown"), - std::make_pair((int)Qt::Key_KeyboardLightOnOff , "KeyboardLightOnOff"), - std::make_pair((int)Qt::Key_KeyboardBrightnessUp , "KeyboardBrightnessUp"), - std::make_pair((int)Qt::Key_KeyboardBrightnessDown , "KeyboardBrightnessDown"), - std::make_pair((int)Qt::Key_PowerOff , "PowerOff"), - std::make_pair((int)Qt::Key_WakeUp , "WakeUp"), - std::make_pair((int)Qt::Key_Eject , "Eject"), - std::make_pair((int)Qt::Key_ScreenSaver , "ScreenSaver"), - std::make_pair((int)Qt::Key_WWW , "WWW"), - std::make_pair((int)Qt::Key_Memo , "Memo"), - std::make_pair((int)Qt::Key_LightBulb , "LightBulb"), - std::make_pair((int)Qt::Key_Shop , "Shop"), - std::make_pair((int)Qt::Key_History , "History"), - std::make_pair((int)Qt::Key_AddFavorite , "AddFavorite"), - std::make_pair((int)Qt::Key_HotLinks , "HotLinks"), - std::make_pair((int)Qt::Key_BrightnessAdjust , "BrightnessAdjust"), - std::make_pair((int)Qt::Key_Finance , "Finance"), - std::make_pair((int)Qt::Key_Community , "Community"), - std::make_pair((int)Qt::Key_AudioRewind , "AudioRewind"), - std::make_pair((int)Qt::Key_BackForward , "BackForward"), - std::make_pair((int)Qt::Key_ApplicationLeft , "ApplicationLeft"), - std::make_pair((int)Qt::Key_ApplicationRight , "ApplicationRight"), - std::make_pair((int)Qt::Key_Book , "Book"), - std::make_pair((int)Qt::Key_CD , "CD"), - std::make_pair((int)Qt::Key_Calculator , "Calculator"), - std::make_pair((int)Qt::Key_ToDoList , "ToDoList"), - std::make_pair((int)Qt::Key_ClearGrab , "ClearGrab"), - std::make_pair((int)Qt::Key_Close , "Close"), - std::make_pair((int)Qt::Key_Copy , "Copy"), - std::make_pair((int)Qt::Key_Cut , "Cut"), - std::make_pair((int)Qt::Key_Display , "Display"), - std::make_pair((int)Qt::Key_DOS , "DOS"), - std::make_pair((int)Qt::Key_Documents , "Documents"), - std::make_pair((int)Qt::Key_Excel , "Excel"), - std::make_pair((int)Qt::Key_Explorer , "Explorer"), - std::make_pair((int)Qt::Key_Game , "Game"), - std::make_pair((int)Qt::Key_Go , "Go"), - std::make_pair((int)Qt::Key_iTouch , "iTouch"), - std::make_pair((int)Qt::Key_LogOff , "LogOff"), - std::make_pair((int)Qt::Key_Market , "Market"), - std::make_pair((int)Qt::Key_Meeting , "Meeting"), - std::make_pair((int)Qt::Key_MenuKB , "MenuKB"), - std::make_pair((int)Qt::Key_MenuPB , "MenuPB"), - std::make_pair((int)Qt::Key_MySites , "MySites"), - std::make_pair((int)Qt::Key_News , "News"), - std::make_pair((int)Qt::Key_OfficeHome , "OfficeHome"), - std::make_pair((int)Qt::Key_Option , "Option"), - std::make_pair((int)Qt::Key_Paste , "Paste"), - std::make_pair((int)Qt::Key_Phone , "Phone"), - std::make_pair((int)Qt::Key_Calendar , "Calendar"), - std::make_pair((int)Qt::Key_Reply , "Reply"), - std::make_pair((int)Qt::Key_Reload , "Reload"), - std::make_pair((int)Qt::Key_RotateWindows , "RotateWindows"), - std::make_pair((int)Qt::Key_RotationPB , "RotationPB"), - std::make_pair((int)Qt::Key_RotationKB , "RotationKB"), - std::make_pair((int)Qt::Key_Save , "Save"), - std::make_pair((int)Qt::Key_Send , "Send"), - std::make_pair((int)Qt::Key_Spell , "Spell"), - std::make_pair((int)Qt::Key_SplitScreen , "SplitScreen"), - std::make_pair((int)Qt::Key_Support , "Support"), - std::make_pair((int)Qt::Key_TaskPane , "TaskPane"), - std::make_pair((int)Qt::Key_Terminal , "Terminal"), - std::make_pair((int)Qt::Key_Tools , "Tools"), - std::make_pair((int)Qt::Key_Travel , "Travel"), - std::make_pair((int)Qt::Key_Video , "Video"), - std::make_pair((int)Qt::Key_Word , "Word"), - std::make_pair((int)Qt::Key_Xfer , "Xfer"), - std::make_pair((int)Qt::Key_ZoomIn , "ZoomIn"), - std::make_pair((int)Qt::Key_ZoomOut , "ZoomOut"), - std::make_pair((int)Qt::Key_Away , "Away"), - std::make_pair((int)Qt::Key_Messenger , "Messenger"), - std::make_pair((int)Qt::Key_WebCam , "WebCam"), - std::make_pair((int)Qt::Key_MailForward , "MailForward"), - std::make_pair((int)Qt::Key_Pictures , "Pictures"), - std::make_pair((int)Qt::Key_Music , "Music"), - std::make_pair((int)Qt::Key_Battery , "Battery"), - std::make_pair((int)Qt::Key_Bluetooth , "Bluetooth"), - std::make_pair((int)Qt::Key_WLAN , "WLAN"), - std::make_pair((int)Qt::Key_UWB , "UWB"), - std::make_pair((int)Qt::Key_AudioForward , "AudioForward"), - std::make_pair((int)Qt::Key_AudioRepeat , "AudioRepeat"), - std::make_pair((int)Qt::Key_AudioRandomPlay , "AudioRandomPlay"), - std::make_pair((int)Qt::Key_Subtitle , "Subtitle"), - std::make_pair((int)Qt::Key_AudioCycleTrack , "AudioCycleTrack"), - std::make_pair((int)Qt::Key_Time , "Time"), - std::make_pair((int)Qt::Key_Hibernate , "Hibernate"), - std::make_pair((int)Qt::Key_View , "View"), - std::make_pair((int)Qt::Key_TopMenu , "TopMenu"), - std::make_pair((int)Qt::Key_PowerDown , "PowerDown"), - std::make_pair((int)Qt::Key_Suspend , "Suspend"), - std::make_pair((int)Qt::Key_ContrastAdjust , "ContrastAdjust"), - std::make_pair((int)Qt::Key_LaunchG , "LaunchG"), - std::make_pair((int)Qt::Key_LaunchH , "LaunchH"), - std::make_pair((int)Qt::Key_TouchpadToggle , "TouchpadToggle"), - std::make_pair((int)Qt::Key_TouchpadOn , "TouchpadOn"), - std::make_pair((int)Qt::Key_TouchpadOff , "TouchpadOff"), - std::make_pair((int)Qt::Key_MicMute , "MicMute"), - std::make_pair((int)Qt::Key_Red , "Red"), - std::make_pair((int)Qt::Key_Green , "Green"), - std::make_pair((int)Qt::Key_Yellow , "Yellow"), - std::make_pair((int)Qt::Key_Blue , "Blue"), - std::make_pair((int)Qt::Key_ChannelUp , "ChannelUp"), - std::make_pair((int)Qt::Key_ChannelDown , "ChannelDown"), - std::make_pair((int)Qt::Key_Guide , "Guide"), - std::make_pair((int)Qt::Key_Info , "Info"), - std::make_pair((int)Qt::Key_Settings , "Settings"), - std::make_pair((int)Qt::Key_MicVolumeUp , "MicVolumeUp"), - std::make_pair((int)Qt::Key_MicVolumeDown , "MicVolumeDown"), - std::make_pair((int)Qt::Key_New , "New"), - std::make_pair((int)Qt::Key_Open , "Open"), - std::make_pair((int)Qt::Key_Find , "Find"), - std::make_pair((int)Qt::Key_Undo , "Undo"), - std::make_pair((int)Qt::Key_Redo , "Redo"), - std::make_pair((int)Qt::Key_AltGr , "AltGr"), - std::make_pair((int)Qt::Key_Multi_key , "Multi_key"), - std::make_pair((int)Qt::Key_Kanji , "Kanji"), - std::make_pair((int)Qt::Key_Muhenkan , "Muhenkan"), - std::make_pair((int)Qt::Key_Henkan , "Henkan"), - std::make_pair((int)Qt::Key_Romaji , "Romaji"), - std::make_pair((int)Qt::Key_Hiragana , "Hiragana"), - std::make_pair((int)Qt::Key_Katakana , "Katakana"), - std::make_pair((int)Qt::Key_Hiragana_Katakana , "Hiragana_Katakana"), - std::make_pair((int)Qt::Key_Zenkaku , "Zenkaku"), - std::make_pair((int)Qt::Key_Hankaku , "Hankaku"), - std::make_pair((int)Qt::Key_Zenkaku_Hankaku , "Zenkaku_Hankaku"), - std::make_pair((int)Qt::Key_Touroku , "Touroku"), - std::make_pair((int)Qt::Key_Massyo , "Massyo"), - std::make_pair((int)Qt::Key_Kana_Lock , "Kana_Lock"), - std::make_pair((int)Qt::Key_Kana_Shift , "Kana_Shift"), - std::make_pair((int)Qt::Key_Eisu_Shift , "Eisu_Shift"), - std::make_pair((int)Qt::Key_Eisu_toggle , "Eisu_toggle"), - std::make_pair((int)Qt::Key_Hangul , "Hangul"), - std::make_pair((int)Qt::Key_Hangul_Start , "Hangul_Start"), - std::make_pair((int)Qt::Key_Hangul_End , "Hangul_End"), - std::make_pair((int)Qt::Key_Hangul_Hanja , "Hangul_Hanja"), - std::make_pair((int)Qt::Key_Hangul_Jamo , "Hangul_Jamo"), - std::make_pair((int)Qt::Key_Hangul_Romaja , "Hangul_Romaja"), - std::make_pair((int)Qt::Key_Codeinput , "Codeinput"), - std::make_pair((int)Qt::Key_Hangul_Jeonja , "Hangul_Jeonja"), - std::make_pair((int)Qt::Key_Hangul_Banja , "Hangul_Banja"), - std::make_pair((int)Qt::Key_Hangul_PreHanja , "Hangul_PreHanja"), - std::make_pair((int)Qt::Key_Hangul_PostHanja , "Hangul_PostHanja"), - std::make_pair((int)Qt::Key_SingleCandidate , "SingleCandidate"), - std::make_pair((int)Qt::Key_MultipleCandidate , "MultipleCandidate"), - std::make_pair((int)Qt::Key_PreviousCandidate , "PreviousCandidate"), - std::make_pair((int)Qt::Key_Hangul_Special , "Hangul_Special"), - std::make_pair((int)Qt::Key_Mode_switch , "Mode_switch"), - std::make_pair((int)Qt::Key_Dead_Grave , "Dead_Grave"), - std::make_pair((int)Qt::Key_Dead_Acute , "Dead_Acute"), - std::make_pair((int)Qt::Key_Dead_Circumflex , "Dead_Circumflex"), - std::make_pair((int)Qt::Key_Dead_Tilde , "Dead_Tilde"), - std::make_pair((int)Qt::Key_Dead_Macron , "Dead_Macron"), - std::make_pair((int)Qt::Key_Dead_Breve , "Dead_Breve"), - std::make_pair((int)Qt::Key_Dead_Abovedot , "Dead_Abovedot"), - std::make_pair((int)Qt::Key_Dead_Diaeresis , "Dead_Diaeresis"), - std::make_pair((int)Qt::Key_Dead_Abovering , "Dead_Abovering"), - std::make_pair((int)Qt::Key_Dead_Doubleacute , "Dead_Doubleacute"), - std::make_pair((int)Qt::Key_Dead_Caron , "Dead_Caron"), - std::make_pair((int)Qt::Key_Dead_Cedilla , "Dead_Cedilla"), - std::make_pair((int)Qt::Key_Dead_Ogonek , "Dead_Ogonek"), - std::make_pair((int)Qt::Key_Dead_Iota , "Dead_Iota"), - std::make_pair((int)Qt::Key_Dead_Voiced_Sound , "Dead_Voiced_Sound"), - std::make_pair((int)Qt::Key_Dead_Semivoiced_Sound , "Dead_Semivoiced_Sound"), - std::make_pair((int)Qt::Key_Dead_Belowdot , "Dead_Belowdot"), - std::make_pair((int)Qt::Key_Dead_Hook , "Dead_Hook"), - std::make_pair((int)Qt::Key_Dead_Horn , "Dead_Horn"), - std::make_pair((int)Qt::Key_MediaLast , "MediaLast"), - std::make_pair((int)Qt::Key_Select , "Select"), - std::make_pair((int)Qt::Key_Yes , "Yes"), - std::make_pair((int)Qt::Key_No , "No"), - std::make_pair((int)Qt::Key_Cancel , "Cancel"), - std::make_pair((int)Qt::Key_Printer , "Printer"), - std::make_pair((int)Qt::Key_Execute , "Execute"), - std::make_pair((int)Qt::Key_Sleep , "Sleep"), - std::make_pair((int)Qt::Key_Play , "Play"), - std::make_pair((int)Qt::Key_Zoom , "Zoom"), - std::make_pair((int)Qt::Key_Exit , "Exit"), - std::make_pair((int)Qt::Key_Context1 , "Context1"), - std::make_pair((int)Qt::Key_Context2 , "Context2"), - std::make_pair((int)Qt::Key_Context3 , "Context3"), - std::make_pair((int)Qt::Key_Context4 , "Context4"), - std::make_pair((int)Qt::Key_Call , "Call"), - std::make_pair((int)Qt::Key_Hangup , "Hangup"), - std::make_pair((int)Qt::Key_Flip , "Flip"), - std::make_pair((int)Qt::Key_ToggleCallHangup , "ToggleCallHangup"), - std::make_pair((int)Qt::Key_VoiceDial , "VoiceDial"), - std::make_pair((int)Qt::Key_LastNumberRedial , "LastNumberRedial"), - std::make_pair((int)Qt::Key_Camera , "Camera"), - std::make_pair((int)Qt::Key_CameraFocus , "CameraFocus"), - std::make_pair(0 , static_cast(nullptr)), + const std::pair ShortcutManager::QtKeys[] = { + std::make_pair((int)Qt::Key_Space, "Space"), + std::make_pair((int)Qt::Key_Exclam, "Exclam"), + std::make_pair((int)Qt::Key_QuoteDbl, "QuoteDbl"), + std::make_pair((int)Qt::Key_NumberSign, "NumberSign"), + std::make_pair((int)Qt::Key_Dollar, "Dollar"), + std::make_pair((int)Qt::Key_Percent, "Percent"), + std::make_pair((int)Qt::Key_Ampersand, "Ampersand"), + std::make_pair((int)Qt::Key_Apostrophe, "Apostrophe"), + std::make_pair((int)Qt::Key_ParenLeft, "ParenLeft"), + std::make_pair((int)Qt::Key_ParenRight, "ParenRight"), + std::make_pair((int)Qt::Key_Asterisk, "Asterisk"), + std::make_pair((int)Qt::Key_Plus, "Plus"), + std::make_pair((int)Qt::Key_Comma, "Comma"), + std::make_pair((int)Qt::Key_Minus, "Minus"), + std::make_pair((int)Qt::Key_Period, "Period"), + std::make_pair((int)Qt::Key_Slash, "Slash"), + std::make_pair((int)Qt::Key_0, "0"), + std::make_pair((int)Qt::Key_1, "1"), + std::make_pair((int)Qt::Key_2, "2"), + std::make_pair((int)Qt::Key_3, "3"), + std::make_pair((int)Qt::Key_4, "4"), + std::make_pair((int)Qt::Key_5, "5"), + std::make_pair((int)Qt::Key_6, "6"), + std::make_pair((int)Qt::Key_7, "7"), + std::make_pair((int)Qt::Key_8, "8"), + std::make_pair((int)Qt::Key_9, "9"), + std::make_pair((int)Qt::Key_Colon, "Colon"), + std::make_pair((int)Qt::Key_Semicolon, "Semicolon"), + std::make_pair((int)Qt::Key_Less, "Less"), + std::make_pair((int)Qt::Key_Equal, "Equal"), + std::make_pair((int)Qt::Key_Greater, "Greater"), + std::make_pair((int)Qt::Key_Question, "Question"), + std::make_pair((int)Qt::Key_At, "At"), + std::make_pair((int)Qt::Key_A, "A"), + std::make_pair((int)Qt::Key_B, "B"), + std::make_pair((int)Qt::Key_C, "C"), + std::make_pair((int)Qt::Key_D, "D"), + std::make_pair((int)Qt::Key_E, "E"), + std::make_pair((int)Qt::Key_F, "F"), + std::make_pair((int)Qt::Key_G, "G"), + std::make_pair((int)Qt::Key_H, "H"), + std::make_pair((int)Qt::Key_I, "I"), + std::make_pair((int)Qt::Key_J, "J"), + std::make_pair((int)Qt::Key_K, "K"), + std::make_pair((int)Qt::Key_L, "L"), + std::make_pair((int)Qt::Key_M, "M"), + std::make_pair((int)Qt::Key_N, "N"), + std::make_pair((int)Qt::Key_O, "O"), + std::make_pair((int)Qt::Key_P, "P"), + std::make_pair((int)Qt::Key_Q, "Q"), + std::make_pair((int)Qt::Key_R, "R"), + std::make_pair((int)Qt::Key_S, "S"), + std::make_pair((int)Qt::Key_T, "T"), + std::make_pair((int)Qt::Key_U, "U"), + std::make_pair((int)Qt::Key_V, "V"), + std::make_pair((int)Qt::Key_W, "W"), + std::make_pair((int)Qt::Key_X, "X"), + std::make_pair((int)Qt::Key_Y, "Y"), + std::make_pair((int)Qt::Key_Z, "Z"), + std::make_pair((int)Qt::Key_BracketLeft, "BracketLeft"), + std::make_pair((int)Qt::Key_Backslash, "Backslash"), + std::make_pair((int)Qt::Key_BracketRight, "BracketRight"), + std::make_pair((int)Qt::Key_AsciiCircum, "AsciiCircum"), + std::make_pair((int)Qt::Key_Underscore, "Underscore"), + std::make_pair((int)Qt::Key_QuoteLeft, "QuoteLeft"), + std::make_pair((int)Qt::Key_BraceLeft, "BraceLeft"), + std::make_pair((int)Qt::Key_Bar, "Bar"), + std::make_pair((int)Qt::Key_BraceRight, "BraceRight"), + std::make_pair((int)Qt::Key_AsciiTilde, "AsciiTilde"), + std::make_pair((int)Qt::Key_nobreakspace, "nobreakspace"), + std::make_pair((int)Qt::Key_exclamdown, "exclamdown"), + std::make_pair((int)Qt::Key_cent, "cent"), + std::make_pair((int)Qt::Key_sterling, "sterling"), + std::make_pair((int)Qt::Key_currency, "currency"), + std::make_pair((int)Qt::Key_yen, "yen"), + std::make_pair((int)Qt::Key_brokenbar, "brokenbar"), + std::make_pair((int)Qt::Key_section, "section"), + std::make_pair((int)Qt::Key_diaeresis, "diaeresis"), + std::make_pair((int)Qt::Key_copyright, "copyright"), + std::make_pair((int)Qt::Key_ordfeminine, "ordfeminine"), + std::make_pair((int)Qt::Key_guillemotleft, "guillemotleft"), + std::make_pair((int)Qt::Key_notsign, "notsign"), + std::make_pair((int)Qt::Key_hyphen, "hyphen"), + std::make_pair((int)Qt::Key_registered, "registered"), + std::make_pair((int)Qt::Key_macron, "macron"), + std::make_pair((int)Qt::Key_degree, "degree"), + std::make_pair((int)Qt::Key_plusminus, "plusminus"), + std::make_pair((int)Qt::Key_twosuperior, "twosuperior"), + std::make_pair((int)Qt::Key_threesuperior, "threesuperior"), + std::make_pair((int)Qt::Key_acute, "acute"), + std::make_pair((int)Qt::Key_mu, "mu"), + std::make_pair((int)Qt::Key_paragraph, "paragraph"), + std::make_pair((int)Qt::Key_periodcentered, "periodcentered"), + std::make_pair((int)Qt::Key_cedilla, "cedilla"), + std::make_pair((int)Qt::Key_onesuperior, "onesuperior"), + std::make_pair((int)Qt::Key_masculine, "masculine"), + std::make_pair((int)Qt::Key_guillemotright, "guillemotright"), + std::make_pair((int)Qt::Key_onequarter, "onequarter"), + std::make_pair((int)Qt::Key_onehalf, "onehalf"), + std::make_pair((int)Qt::Key_threequarters, "threequarters"), + std::make_pair((int)Qt::Key_questiondown, "questiondown"), + std::make_pair((int)Qt::Key_Agrave, "Agrave"), + std::make_pair((int)Qt::Key_Aacute, "Aacute"), + std::make_pair((int)Qt::Key_Acircumflex, "Acircumflex"), + std::make_pair((int)Qt::Key_Atilde, "Atilde"), + std::make_pair((int)Qt::Key_Adiaeresis, "Adiaeresis"), + std::make_pair((int)Qt::Key_Aring, "Aring"), + std::make_pair((int)Qt::Key_AE, "AE"), + std::make_pair((int)Qt::Key_Ccedilla, "Ccedilla"), + std::make_pair((int)Qt::Key_Egrave, "Egrave"), + std::make_pair((int)Qt::Key_Eacute, "Eacute"), + std::make_pair((int)Qt::Key_Ecircumflex, "Ecircumflex"), + std::make_pair((int)Qt::Key_Ediaeresis, "Ediaeresis"), + std::make_pair((int)Qt::Key_Igrave, "Igrave"), + std::make_pair((int)Qt::Key_Iacute, "Iacute"), + std::make_pair((int)Qt::Key_Icircumflex, "Icircumflex"), + std::make_pair((int)Qt::Key_Idiaeresis, "Idiaeresis"), + std::make_pair((int)Qt::Key_ETH, "ETH"), + std::make_pair((int)Qt::Key_Ntilde, "Ntilde"), + std::make_pair((int)Qt::Key_Ograve, "Ograve"), + std::make_pair((int)Qt::Key_Oacute, "Oacute"), + std::make_pair((int)Qt::Key_Ocircumflex, "Ocircumflex"), + std::make_pair((int)Qt::Key_Otilde, "Otilde"), + std::make_pair((int)Qt::Key_Odiaeresis, "Odiaeresis"), + std::make_pair((int)Qt::Key_multiply, "multiply"), + std::make_pair((int)Qt::Key_Ooblique, "Ooblique"), + std::make_pair((int)Qt::Key_Ugrave, "Ugrave"), + std::make_pair((int)Qt::Key_Uacute, "Uacute"), + std::make_pair((int)Qt::Key_Ucircumflex, "Ucircumflex"), + std::make_pair((int)Qt::Key_Udiaeresis, "Udiaeresis"), + std::make_pair((int)Qt::Key_Yacute, "Yacute"), + std::make_pair((int)Qt::Key_THORN, "THORN"), + std::make_pair((int)Qt::Key_ssharp, "ssharp"), + std::make_pair((int)Qt::Key_division, "division"), + std::make_pair((int)Qt::Key_ydiaeresis, "ydiaeresis"), + std::make_pair((int)Qt::Key_Escape, "Escape"), + std::make_pair((int)Qt::Key_Tab, "Tab"), + std::make_pair((int)Qt::Key_Backtab, "Backtab"), + std::make_pair((int)Qt::Key_Backspace, "Backspace"), + std::make_pair((int)Qt::Key_Return, "Return"), + std::make_pair((int)Qt::Key_Enter, "Enter"), + std::make_pair((int)Qt::Key_Insert, "Insert"), + std::make_pair((int)Qt::Key_Delete, "Delete"), + std::make_pair((int)Qt::Key_Pause, "Pause"), + std::make_pair((int)Qt::Key_Print, "Print"), + std::make_pair((int)Qt::Key_SysReq, "SysReq"), + std::make_pair((int)Qt::Key_Clear, "Clear"), + std::make_pair((int)Qt::Key_Home, "Home"), + std::make_pair((int)Qt::Key_End, "End"), + std::make_pair((int)Qt::Key_Left, "Left"), + std::make_pair((int)Qt::Key_Up, "Up"), + std::make_pair((int)Qt::Key_Right, "Right"), + std::make_pair((int)Qt::Key_Down, "Down"), + std::make_pair((int)Qt::Key_PageUp, "PageUp"), + std::make_pair((int)Qt::Key_PageDown, "PageDown"), + std::make_pair((int)Qt::Key_Shift, "Shift"), + std::make_pair((int)Qt::Key_Control, "Control"), + std::make_pair((int)Qt::Key_Meta, "Meta"), + std::make_pair((int)Qt::Key_Alt, "Alt"), + std::make_pair((int)Qt::Key_CapsLock, "CapsLock"), + std::make_pair((int)Qt::Key_NumLock, "NumLock"), + std::make_pair((int)Qt::Key_ScrollLock, "ScrollLock"), + std::make_pair((int)Qt::Key_F1, "F1"), + std::make_pair((int)Qt::Key_F2, "F2"), + std::make_pair((int)Qt::Key_F3, "F3"), + std::make_pair((int)Qt::Key_F4, "F4"), + std::make_pair((int)Qt::Key_F5, "F5"), + std::make_pair((int)Qt::Key_F6, "F6"), + std::make_pair((int)Qt::Key_F7, "F7"), + std::make_pair((int)Qt::Key_F8, "F8"), + std::make_pair((int)Qt::Key_F9, "F9"), + std::make_pair((int)Qt::Key_F10, "F10"), + std::make_pair((int)Qt::Key_F11, "F11"), + std::make_pair((int)Qt::Key_F12, "F12"), + std::make_pair((int)Qt::Key_F13, "F13"), + std::make_pair((int)Qt::Key_F14, "F14"), + std::make_pair((int)Qt::Key_F15, "F15"), + std::make_pair((int)Qt::Key_F16, "F16"), + std::make_pair((int)Qt::Key_F17, "F17"), + std::make_pair((int)Qt::Key_F18, "F18"), + std::make_pair((int)Qt::Key_F19, "F19"), + std::make_pair((int)Qt::Key_F20, "F20"), + std::make_pair((int)Qt::Key_F21, "F21"), + std::make_pair((int)Qt::Key_F22, "F22"), + std::make_pair((int)Qt::Key_F23, "F23"), + std::make_pair((int)Qt::Key_F24, "F24"), + std::make_pair((int)Qt::Key_F25, "F25"), + std::make_pair((int)Qt::Key_F26, "F26"), + std::make_pair((int)Qt::Key_F27, "F27"), + std::make_pair((int)Qt::Key_F28, "F28"), + std::make_pair((int)Qt::Key_F29, "F29"), + std::make_pair((int)Qt::Key_F30, "F30"), + std::make_pair((int)Qt::Key_F31, "F31"), + std::make_pair((int)Qt::Key_F32, "F32"), + std::make_pair((int)Qt::Key_F33, "F33"), + std::make_pair((int)Qt::Key_F34, "F34"), + std::make_pair((int)Qt::Key_F35, "F35"), + std::make_pair((int)Qt::Key_Super_L, "Super_L"), + std::make_pair((int)Qt::Key_Super_R, "Super_R"), + std::make_pair((int)Qt::Key_Menu, "Menu"), + std::make_pair((int)Qt::Key_Hyper_L, "Hyper_L"), + std::make_pair((int)Qt::Key_Hyper_R, "Hyper_R"), + std::make_pair((int)Qt::Key_Help, "Help"), + std::make_pair((int)Qt::Key_Direction_L, "Direction_L"), + std::make_pair((int)Qt::Key_Direction_R, "Direction_R"), + std::make_pair((int)Qt::Key_Back, "Back"), + std::make_pair((int)Qt::Key_Forward, "Forward"), + std::make_pair((int)Qt::Key_Stop, "Stop"), + std::make_pair((int)Qt::Key_Refresh, "Refresh"), + std::make_pair((int)Qt::Key_VolumeDown, "VolumeDown"), + std::make_pair((int)Qt::Key_VolumeMute, "VolumeMute"), + std::make_pair((int)Qt::Key_VolumeUp, "VolumeUp"), + std::make_pair((int)Qt::Key_BassBoost, "BassBoost"), + std::make_pair((int)Qt::Key_BassUp, "BassUp"), + std::make_pair((int)Qt::Key_BassDown, "BassDown"), + std::make_pair((int)Qt::Key_TrebleUp, "TrebleUp"), + std::make_pair((int)Qt::Key_TrebleDown, "TrebleDown"), + std::make_pair((int)Qt::Key_MediaPlay, "MediaPlay"), + std::make_pair((int)Qt::Key_MediaStop, "MediaStop"), + std::make_pair((int)Qt::Key_MediaPrevious, "MediaPrevious"), + std::make_pair((int)Qt::Key_MediaNext, "MediaNext"), + std::make_pair((int)Qt::Key_MediaRecord, "MediaRecord"), + std::make_pair((int)Qt::Key_MediaPause, "MediaPause"), + std::make_pair((int)Qt::Key_MediaTogglePlayPause, "MediaTogglePlayPause"), + std::make_pair((int)Qt::Key_HomePage, "HomePage"), + std::make_pair((int)Qt::Key_Favorites, "Favorites"), + std::make_pair((int)Qt::Key_Search, "Search"), + std::make_pair((int)Qt::Key_Standby, "Standby"), + std::make_pair((int)Qt::Key_OpenUrl, "OpenUrl"), + std::make_pair((int)Qt::Key_LaunchMail, "LaunchMail"), + std::make_pair((int)Qt::Key_LaunchMedia, "LaunchMedia"), + std::make_pair((int)Qt::Key_Launch0, "Launch0"), + std::make_pair((int)Qt::Key_Launch1, "Launch1"), + std::make_pair((int)Qt::Key_Launch2, "Launch2"), + std::make_pair((int)Qt::Key_Launch3, "Launch3"), + std::make_pair((int)Qt::Key_Launch4, "Launch4"), + std::make_pair((int)Qt::Key_Launch5, "Launch5"), + std::make_pair((int)Qt::Key_Launch6, "Launch6"), + std::make_pair((int)Qt::Key_Launch7, "Launch7"), + std::make_pair((int)Qt::Key_Launch8, "Launch8"), + std::make_pair((int)Qt::Key_Launch9, "Launch9"), + std::make_pair((int)Qt::Key_LaunchA, "LaunchA"), + std::make_pair((int)Qt::Key_LaunchB, "LaunchB"), + std::make_pair((int)Qt::Key_LaunchC, "LaunchC"), + std::make_pair((int)Qt::Key_LaunchD, "LaunchD"), + std::make_pair((int)Qt::Key_LaunchE, "LaunchE"), + std::make_pair((int)Qt::Key_LaunchF, "LaunchF"), + std::make_pair((int)Qt::Key_MonBrightnessUp, "MonBrightnessUp"), + std::make_pair((int)Qt::Key_MonBrightnessDown, "MonBrightnessDown"), + std::make_pair((int)Qt::Key_KeyboardLightOnOff, "KeyboardLightOnOff"), + std::make_pair((int)Qt::Key_KeyboardBrightnessUp, "KeyboardBrightnessUp"), + std::make_pair((int)Qt::Key_KeyboardBrightnessDown, "KeyboardBrightnessDown"), + std::make_pair((int)Qt::Key_PowerOff, "PowerOff"), + std::make_pair((int)Qt::Key_WakeUp, "WakeUp"), + std::make_pair((int)Qt::Key_Eject, "Eject"), + std::make_pair((int)Qt::Key_ScreenSaver, "ScreenSaver"), + std::make_pair((int)Qt::Key_WWW, "WWW"), + std::make_pair((int)Qt::Key_Memo, "Memo"), + std::make_pair((int)Qt::Key_LightBulb, "LightBulb"), + std::make_pair((int)Qt::Key_Shop, "Shop"), + std::make_pair((int)Qt::Key_History, "History"), + std::make_pair((int)Qt::Key_AddFavorite, "AddFavorite"), + std::make_pair((int)Qt::Key_HotLinks, "HotLinks"), + std::make_pair((int)Qt::Key_BrightnessAdjust, "BrightnessAdjust"), + std::make_pair((int)Qt::Key_Finance, "Finance"), + std::make_pair((int)Qt::Key_Community, "Community"), + std::make_pair((int)Qt::Key_AudioRewind, "AudioRewind"), + std::make_pair((int)Qt::Key_BackForward, "BackForward"), + std::make_pair((int)Qt::Key_ApplicationLeft, "ApplicationLeft"), + std::make_pair((int)Qt::Key_ApplicationRight, "ApplicationRight"), + std::make_pair((int)Qt::Key_Book, "Book"), + std::make_pair((int)Qt::Key_CD, "CD"), + std::make_pair((int)Qt::Key_Calculator, "Calculator"), + std::make_pair((int)Qt::Key_ToDoList, "ToDoList"), + std::make_pair((int)Qt::Key_ClearGrab, "ClearGrab"), + std::make_pair((int)Qt::Key_Close, "Close"), + std::make_pair((int)Qt::Key_Copy, "Copy"), + std::make_pair((int)Qt::Key_Cut, "Cut"), + std::make_pair((int)Qt::Key_Display, "Display"), + std::make_pair((int)Qt::Key_DOS, "DOS"), + std::make_pair((int)Qt::Key_Documents, "Documents"), + std::make_pair((int)Qt::Key_Excel, "Excel"), + std::make_pair((int)Qt::Key_Explorer, "Explorer"), + std::make_pair((int)Qt::Key_Game, "Game"), + std::make_pair((int)Qt::Key_Go, "Go"), + std::make_pair((int)Qt::Key_iTouch, "iTouch"), + std::make_pair((int)Qt::Key_LogOff, "LogOff"), + std::make_pair((int)Qt::Key_Market, "Market"), + std::make_pair((int)Qt::Key_Meeting, "Meeting"), + std::make_pair((int)Qt::Key_MenuKB, "MenuKB"), + std::make_pair((int)Qt::Key_MenuPB, "MenuPB"), + std::make_pair((int)Qt::Key_MySites, "MySites"), + std::make_pair((int)Qt::Key_News, "News"), + std::make_pair((int)Qt::Key_OfficeHome, "OfficeHome"), + std::make_pair((int)Qt::Key_Option, "Option"), + std::make_pair((int)Qt::Key_Paste, "Paste"), + std::make_pair((int)Qt::Key_Phone, "Phone"), + std::make_pair((int)Qt::Key_Calendar, "Calendar"), + std::make_pair((int)Qt::Key_Reply, "Reply"), + std::make_pair((int)Qt::Key_Reload, "Reload"), + std::make_pair((int)Qt::Key_RotateWindows, "RotateWindows"), + std::make_pair((int)Qt::Key_RotationPB, "RotationPB"), + std::make_pair((int)Qt::Key_RotationKB, "RotationKB"), + std::make_pair((int)Qt::Key_Save, "Save"), + std::make_pair((int)Qt::Key_Send, "Send"), + std::make_pair((int)Qt::Key_Spell, "Spell"), + std::make_pair((int)Qt::Key_SplitScreen, "SplitScreen"), + std::make_pair((int)Qt::Key_Support, "Support"), + std::make_pair((int)Qt::Key_TaskPane, "TaskPane"), + std::make_pair((int)Qt::Key_Terminal, "Terminal"), + std::make_pair((int)Qt::Key_Tools, "Tools"), + std::make_pair((int)Qt::Key_Travel, "Travel"), + std::make_pair((int)Qt::Key_Video, "Video"), + std::make_pair((int)Qt::Key_Word, "Word"), + std::make_pair((int)Qt::Key_Xfer, "Xfer"), + std::make_pair((int)Qt::Key_ZoomIn, "ZoomIn"), + std::make_pair((int)Qt::Key_ZoomOut, "ZoomOut"), + std::make_pair((int)Qt::Key_Away, "Away"), + std::make_pair((int)Qt::Key_Messenger, "Messenger"), + std::make_pair((int)Qt::Key_WebCam, "WebCam"), + std::make_pair((int)Qt::Key_MailForward, "MailForward"), + std::make_pair((int)Qt::Key_Pictures, "Pictures"), + std::make_pair((int)Qt::Key_Music, "Music"), + std::make_pair((int)Qt::Key_Battery, "Battery"), + std::make_pair((int)Qt::Key_Bluetooth, "Bluetooth"), + std::make_pair((int)Qt::Key_WLAN, "WLAN"), + std::make_pair((int)Qt::Key_UWB, "UWB"), + std::make_pair((int)Qt::Key_AudioForward, "AudioForward"), + std::make_pair((int)Qt::Key_AudioRepeat, "AudioRepeat"), + std::make_pair((int)Qt::Key_AudioRandomPlay, "AudioRandomPlay"), + std::make_pair((int)Qt::Key_Subtitle, "Subtitle"), + std::make_pair((int)Qt::Key_AudioCycleTrack, "AudioCycleTrack"), + std::make_pair((int)Qt::Key_Time, "Time"), + std::make_pair((int)Qt::Key_Hibernate, "Hibernate"), + std::make_pair((int)Qt::Key_View, "View"), + std::make_pair((int)Qt::Key_TopMenu, "TopMenu"), + std::make_pair((int)Qt::Key_PowerDown, "PowerDown"), + std::make_pair((int)Qt::Key_Suspend, "Suspend"), + std::make_pair((int)Qt::Key_ContrastAdjust, "ContrastAdjust"), + std::make_pair((int)Qt::Key_LaunchG, "LaunchG"), + std::make_pair((int)Qt::Key_LaunchH, "LaunchH"), + std::make_pair((int)Qt::Key_TouchpadToggle, "TouchpadToggle"), + std::make_pair((int)Qt::Key_TouchpadOn, "TouchpadOn"), + std::make_pair((int)Qt::Key_TouchpadOff, "TouchpadOff"), + std::make_pair((int)Qt::Key_MicMute, "MicMute"), + std::make_pair((int)Qt::Key_Red, "Red"), + std::make_pair((int)Qt::Key_Green, "Green"), + std::make_pair((int)Qt::Key_Yellow, "Yellow"), + std::make_pair((int)Qt::Key_Blue, "Blue"), + std::make_pair((int)Qt::Key_ChannelUp, "ChannelUp"), + std::make_pair((int)Qt::Key_ChannelDown, "ChannelDown"), + std::make_pair((int)Qt::Key_Guide, "Guide"), + std::make_pair((int)Qt::Key_Info, "Info"), + std::make_pair((int)Qt::Key_Settings, "Settings"), + std::make_pair((int)Qt::Key_MicVolumeUp, "MicVolumeUp"), + std::make_pair((int)Qt::Key_MicVolumeDown, "MicVolumeDown"), + std::make_pair((int)Qt::Key_New, "New"), + std::make_pair((int)Qt::Key_Open, "Open"), + std::make_pair((int)Qt::Key_Find, "Find"), + std::make_pair((int)Qt::Key_Undo, "Undo"), + std::make_pair((int)Qt::Key_Redo, "Redo"), + std::make_pair((int)Qt::Key_AltGr, "AltGr"), + std::make_pair((int)Qt::Key_Multi_key, "Multi_key"), + std::make_pair((int)Qt::Key_Kanji, "Kanji"), + std::make_pair((int)Qt::Key_Muhenkan, "Muhenkan"), + std::make_pair((int)Qt::Key_Henkan, "Henkan"), + std::make_pair((int)Qt::Key_Romaji, "Romaji"), + std::make_pair((int)Qt::Key_Hiragana, "Hiragana"), + std::make_pair((int)Qt::Key_Katakana, "Katakana"), + std::make_pair((int)Qt::Key_Hiragana_Katakana, "Hiragana_Katakana"), + std::make_pair((int)Qt::Key_Zenkaku, "Zenkaku"), + std::make_pair((int)Qt::Key_Hankaku, "Hankaku"), + std::make_pair((int)Qt::Key_Zenkaku_Hankaku, "Zenkaku_Hankaku"), + std::make_pair((int)Qt::Key_Touroku, "Touroku"), + std::make_pair((int)Qt::Key_Massyo, "Massyo"), + std::make_pair((int)Qt::Key_Kana_Lock, "Kana_Lock"), + std::make_pair((int)Qt::Key_Kana_Shift, "Kana_Shift"), + std::make_pair((int)Qt::Key_Eisu_Shift, "Eisu_Shift"), + std::make_pair((int)Qt::Key_Eisu_toggle, "Eisu_toggle"), + std::make_pair((int)Qt::Key_Hangul, "Hangul"), + std::make_pair((int)Qt::Key_Hangul_Start, "Hangul_Start"), + std::make_pair((int)Qt::Key_Hangul_End, "Hangul_End"), + std::make_pair((int)Qt::Key_Hangul_Hanja, "Hangul_Hanja"), + std::make_pair((int)Qt::Key_Hangul_Jamo, "Hangul_Jamo"), + std::make_pair((int)Qt::Key_Hangul_Romaja, "Hangul_Romaja"), + std::make_pair((int)Qt::Key_Codeinput, "Codeinput"), + std::make_pair((int)Qt::Key_Hangul_Jeonja, "Hangul_Jeonja"), + std::make_pair((int)Qt::Key_Hangul_Banja, "Hangul_Banja"), + std::make_pair((int)Qt::Key_Hangul_PreHanja, "Hangul_PreHanja"), + std::make_pair((int)Qt::Key_Hangul_PostHanja, "Hangul_PostHanja"), + std::make_pair((int)Qt::Key_SingleCandidate, "SingleCandidate"), + std::make_pair((int)Qt::Key_MultipleCandidate, "MultipleCandidate"), + std::make_pair((int)Qt::Key_PreviousCandidate, "PreviousCandidate"), + std::make_pair((int)Qt::Key_Hangul_Special, "Hangul_Special"), + std::make_pair((int)Qt::Key_Mode_switch, "Mode_switch"), + std::make_pair((int)Qt::Key_Dead_Grave, "Dead_Grave"), + std::make_pair((int)Qt::Key_Dead_Acute, "Dead_Acute"), + std::make_pair((int)Qt::Key_Dead_Circumflex, "Dead_Circumflex"), + std::make_pair((int)Qt::Key_Dead_Tilde, "Dead_Tilde"), + std::make_pair((int)Qt::Key_Dead_Macron, "Dead_Macron"), + std::make_pair((int)Qt::Key_Dead_Breve, "Dead_Breve"), + std::make_pair((int)Qt::Key_Dead_Abovedot, "Dead_Abovedot"), + std::make_pair((int)Qt::Key_Dead_Diaeresis, "Dead_Diaeresis"), + std::make_pair((int)Qt::Key_Dead_Abovering, "Dead_Abovering"), + std::make_pair((int)Qt::Key_Dead_Doubleacute, "Dead_Doubleacute"), + std::make_pair((int)Qt::Key_Dead_Caron, "Dead_Caron"), + std::make_pair((int)Qt::Key_Dead_Cedilla, "Dead_Cedilla"), + std::make_pair((int)Qt::Key_Dead_Ogonek, "Dead_Ogonek"), + std::make_pair((int)Qt::Key_Dead_Iota, "Dead_Iota"), + std::make_pair((int)Qt::Key_Dead_Voiced_Sound, "Dead_Voiced_Sound"), + std::make_pair((int)Qt::Key_Dead_Semivoiced_Sound, "Dead_Semivoiced_Sound"), + std::make_pair((int)Qt::Key_Dead_Belowdot, "Dead_Belowdot"), + std::make_pair((int)Qt::Key_Dead_Hook, "Dead_Hook"), + std::make_pair((int)Qt::Key_Dead_Horn, "Dead_Horn"), + std::make_pair((int)Qt::Key_MediaLast, "MediaLast"), + std::make_pair((int)Qt::Key_Select, "Select"), + std::make_pair((int)Qt::Key_Yes, "Yes"), + std::make_pair((int)Qt::Key_No, "No"), + std::make_pair((int)Qt::Key_Cancel, "Cancel"), + std::make_pair((int)Qt::Key_Printer, "Printer"), + std::make_pair((int)Qt::Key_Execute, "Execute"), + std::make_pair((int)Qt::Key_Sleep, "Sleep"), + std::make_pair((int)Qt::Key_Play, "Play"), + std::make_pair((int)Qt::Key_Zoom, "Zoom"), + std::make_pair((int)Qt::Key_Exit, "Exit"), + std::make_pair((int)Qt::Key_Context1, "Context1"), + std::make_pair((int)Qt::Key_Context2, "Context2"), + std::make_pair((int)Qt::Key_Context3, "Context3"), + std::make_pair((int)Qt::Key_Context4, "Context4"), + std::make_pair((int)Qt::Key_Call, "Call"), + std::make_pair((int)Qt::Key_Hangup, "Hangup"), + std::make_pair((int)Qt::Key_Flip, "Flip"), + std::make_pair((int)Qt::Key_ToggleCallHangup, "ToggleCallHangup"), + std::make_pair((int)Qt::Key_VoiceDial, "VoiceDial"), + std::make_pair((int)Qt::Key_LastNumberRedial, "LastNumberRedial"), + std::make_pair((int)Qt::Key_Camera, "Camera"), + std::make_pair((int)Qt::Key_CameraFocus, "CameraFocus"), + std::make_pair(0, static_cast(nullptr)), }; } diff --git a/apps/opencs/model/prefs/shortcutmanager.hpp b/apps/opencs/model/prefs/shortcutmanager.hpp index 99f01a5dff..3fe3853f03 100644 --- a/apps/opencs/model/prefs/shortcutmanager.hpp +++ b/apps/opencs/model/prefs/shortcutmanager.hpp @@ -15,58 +15,56 @@ namespace CSMPrefs /// Class used to track and update shortcuts/sequences class ShortcutManager : public QObject { - Q_OBJECT + Q_OBJECT - public: + public: + ShortcutManager(); - ShortcutManager(); + /// The shortcut class will do this automatically + void addShortcut(Shortcut* shortcut); - /// The shortcut class will do this automatically - void addShortcut(Shortcut* shortcut); + /// The shortcut class will do this automatically + void removeShortcut(Shortcut* shortcut); - /// The shortcut class will do this automatically - void removeShortcut(Shortcut* shortcut); + bool getSequence(const std::string& name, QKeySequence& sequence) const; + void setSequence(const std::string& name, const QKeySequence& sequence); - bool getSequence(const std::string& name, QKeySequence& sequence) const; - void setSequence(const std::string& name, const QKeySequence& sequence); + bool getModifier(const std::string& name, int& modifier) const; + void setModifier(const std::string& name, int modifier); - bool getModifier(const std::string& name, int& modifier) const; - void setModifier(const std::string& name, int modifier); + std::string convertToString(const QKeySequence& sequence) const; + std::string convertToString(int modifier) const; - std::string convertToString(const QKeySequence& sequence) const; - std::string convertToString(int modifier) const; + std::string convertToString(const QKeySequence& sequence, int modifier) const; - std::string convertToString(const QKeySequence& sequence, int modifier) const; + void convertFromString(const std::string& data, QKeySequence& sequence) const; + void convertFromString(const std::string& data, int& modifier) const; - void convertFromString(const std::string& data, QKeySequence& sequence) const; - void convertFromString(const std::string& data, int& modifier) const; + void convertFromString(const std::string& data, QKeySequence& sequence, int& modifier) const; - void convertFromString(const std::string& data, QKeySequence& sequence, int& modifier) const; + /// Replaces "{sequence-name}" or "{modifier-name}" with the appropriate text + QString processToolTip(const QString& toolTip) const; - /// Replaces "{sequence-name}" or "{modifier-name}" with the appropriate text - QString processToolTip(const QString& toolTip) const; + private: + // Need a multimap in case multiple shortcuts share the same name + typedef std::multimap ShortcutMap; + typedef std::map SequenceMap; + typedef std::map ModifierMap; + typedef std::map NameMap; + typedef std::map KeyMap; - private: + ShortcutMap mShortcuts; + SequenceMap mSequences; + ModifierMap mModifiers; - // Need a multimap in case multiple shortcuts share the same name - typedef std::multimap ShortcutMap; - typedef std::map SequenceMap; - typedef std::map ModifierMap; - typedef std::map NameMap; - typedef std::map KeyMap; + NameMap mNames; + KeyMap mKeys; - ShortcutMap mShortcuts; - SequenceMap mSequences; - ModifierMap mModifiers; + ShortcutEventHandler* mEventHandler; - NameMap mNames; - KeyMap mKeys; + void createLookupTables(); - ShortcutEventHandler* mEventHandler; - - void createLookupTables(); - - static const std::pair QtKeys[]; + static const std::pair QtKeys[]; }; } diff --git a/apps/opencs/model/prefs/shortcutsetting.cpp b/apps/opencs/model/prefs/shortcutsetting.cpp index 44260b8cb0..eb1e398ecd 100644 --- a/apps/opencs/model/prefs/shortcutsetting.cpp +++ b/apps/opencs/model/prefs/shortcutsetting.cpp @@ -5,18 +5,17 @@ #include #include #include -#include #include +#include #include -#include "state.hpp" #include "shortcutmanager.hpp" +#include "state.hpp" namespace CSMPrefs { - ShortcutSetting::ShortcutSetting(Category* parent, QMutex* mutex, const std::string& key, - const std::string& label) + ShortcutSetting::ShortcutSetting(Category* parent, QMutex* mutex, const std::string& key, const std::string& label) : Setting(parent, mutex, key, label) , mButton(nullptr) , mEditorActive(false) @@ -115,14 +114,7 @@ namespace CSMPrefs bool ShortcutSetting::handleEvent(QObject* target, int mod, int value, bool active) { // Modifiers are handled differently - const int Blacklist[] = - { - Qt::Key_Shift, - Qt::Key_Control, - Qt::Key_Meta, - Qt::Key_Alt, - Qt::Key_AltGr - }; + const int Blacklist[] = { Qt::Key_Shift, Qt::Key_Control, Qt::Key_Meta, Qt::Key_Alt, Qt::Key_AltGr }; const size_t BlacklistSize = sizeof(Blacklist) / sizeof(int); diff --git a/apps/opencs/model/prefs/shortcutsetting.hpp b/apps/opencs/model/prefs/shortcutsetting.hpp index cc1394b47e..f620ae3556 100644 --- a/apps/opencs/model/prefs/shortcutsetting.hpp +++ b/apps/opencs/model/prefs/shortcutsetting.hpp @@ -12,39 +12,35 @@ namespace CSMPrefs { class ShortcutSetting : public Setting { - Q_OBJECT + Q_OBJECT - public: + public: + ShortcutSetting(Category* parent, QMutex* mutex, const std::string& key, const std::string& label); - ShortcutSetting(Category* parent, QMutex* mutex, const std::string& key, - const std::string& label); + std::pair makeWidgets(QWidget* parent) override; - std::pair makeWidgets(QWidget* parent) override; + void updateWidget() override; - void updateWidget() override; + protected: + bool eventFilter(QObject* target, QEvent* event) override; - protected: + private: + bool handleEvent(QObject* target, int mod, int value, bool active); - bool eventFilter(QObject* target, QEvent* event) override; + void storeValue(const QKeySequence& sequence); + void resetState(); - private: + static constexpr int MaxKeys = 4; - bool handleEvent(QObject* target, int mod, int value, bool active); + QPushButton* mButton; - void storeValue(const QKeySequence& sequence); - void resetState(); + bool mEditorActive; + int mEditorPos; + int mEditorKeys[MaxKeys]; - static constexpr int MaxKeys = 4; + private slots: - QPushButton* mButton; - - bool mEditorActive; - int mEditorPos; - int mEditorKeys[MaxKeys]; - - private slots: - - void buttonToggled(bool checked); + void buttonToggled(bool checked); }; } diff --git a/apps/opencs/model/prefs/state.cpp b/apps/opencs/model/prefs/state.cpp index bce4130c94..b3805670c3 100644 --- a/apps/opencs/model/prefs/state.cpp +++ b/apps/opencs/model/prefs/state.cpp @@ -1,640 +1,643 @@ #include "state.hpp" -#include #include #include +#include #include -#include "intsetting.hpp" -#include "doublesetting.hpp" #include "boolsetting.hpp" #include "coloursetting.hpp" -#include "shortcutsetting.hpp" +#include "doublesetting.hpp" +#include "intsetting.hpp" #include "modifiersetting.hpp" +#include "shortcutsetting.hpp" -CSMPrefs::State *CSMPrefs::State::sThis = nullptr; +CSMPrefs::State* CSMPrefs::State::sThis = nullptr; void CSMPrefs::State::declare() { - declareCategory ("Windows"); - declareInt ("default-width", "Default window width", 800). - setTooltip ("Newly opened top-level windows will open with this width."). - setMin (80); - declareInt ("default-height", "Default window height", 600). - setTooltip ("Newly opened top-level windows will open with this height."). - setMin (80); - declareBool ("show-statusbar", "Show Status Bar", true). - setTooltip ("If a newly open top level window is showing status bars or not. " - " Note that this does not affect existing windows."); + declareCategory("Windows"); + declareInt("default-width", "Default window width", 800) + .setTooltip("Newly opened top-level windows will open with this width.") + .setMin(80); + declareInt("default-height", "Default window height", 600) + .setTooltip("Newly opened top-level windows will open with this height.") + .setMin(80); + declareBool("show-statusbar", "Show Status Bar", true) + .setTooltip( + "If a newly open top level window is showing status bars or not. " + " Note that this does not affect existing windows."); declareSeparator(); - declareBool ("reuse", "Reuse Subviews", true). - setTooltip ("When a new subview is requested and a matching subview already " - " exist, do not open a new subview and use the existing one instead."); - declareInt ("max-subviews", "Maximum number of subviews per top-level window", 256). - setTooltip ("If the maximum number is reached and a new subview is opened " - "it will be placed into a new top-level window."). - setRange (1, 256); - declareBool ("hide-subview", "Hide single subview", false). - setTooltip ("When a view contains only a single subview, hide the subview title " - "bar and if this subview is closed also close the view (unless it is the last " - "view for this document)"); - declareInt ("minimum-width", "Minimum subview width", 325). - setTooltip ("Minimum width of subviews."). - setRange (50, 10000); + declareBool("reuse", "Reuse Subviews", true) + .setTooltip( + "When a new subview is requested and a matching subview already " + " exist, do not open a new subview and use the existing one instead."); + declareInt("max-subviews", "Maximum number of subviews per top-level window", 256) + .setTooltip( + "If the maximum number is reached and a new subview is opened " + "it will be placed into a new top-level window.") + .setRange(1, 256); + declareBool("hide-subview", "Hide single subview", false) + .setTooltip( + "When a view contains only a single subview, hide the subview title " + "bar and if this subview is closed also close the view (unless it is the last " + "view for this document)"); + declareInt("minimum-width", "Minimum subview width", 325) + .setTooltip("Minimum width of subviews.") + .setRange(50, 10000); declareSeparator(); - EnumValue scrollbarOnly ("Scrollbar Only", "Simple addition of scrollbars, the view window " + EnumValue scrollbarOnly("Scrollbar Only", + "Simple addition of scrollbars, the view window " "does not grow automatically."); - declareEnum ("mainwindow-scrollbar", "Horizontal scrollbar mode for main window.", scrollbarOnly). - addValue (scrollbarOnly). - addValue ("Grow Only", "The view window grows as subviews are added. No scrollbars."). - addValue ("Grow then Scroll", "The view window grows. The scrollbar appears once it cannot grow any further."); - declareBool ("grow-limit", "Grow Limit Screen", false). - setTooltip ("When \"Grow then Scroll\" option is selected, the window size grows to" - " the width of the virtual desktop. \nIf this option is selected the the window growth" - "is limited to the current screen."); - - declareCategory ("Records"); - EnumValue iconAndText ("Icon and Text"); + declareEnum("mainwindow-scrollbar", "Horizontal scrollbar mode for main window.", scrollbarOnly) + .addValue(scrollbarOnly) + .addValue("Grow Only", "The view window grows as subviews are added. No scrollbars.") + .addValue("Grow then Scroll", "The view window grows. The scrollbar appears once it cannot grow any further."); + declareBool("grow-limit", "Grow Limit Screen", false) + .setTooltip( + "When \"Grow then Scroll\" option is selected, the window size grows to" + " the width of the virtual desktop. \nIf this option is selected the the window growth" + "is limited to the current screen."); + + declareCategory("Records"); + EnumValue iconAndText("Icon and Text"); EnumValues recordValues; - recordValues.add (iconAndText).add ("Icon Only").add ("Text Only"); - declareEnum ("status-format", "Modification status display format", iconAndText). - addValues (recordValues); - declareEnum ("type-format", "ID type display format", iconAndText). - addValues (recordValues); - - declareCategory ("ID Tables"); - EnumValue inPlaceEdit ("Edit in Place", "Edit the clicked cell"); - EnumValue editRecord ("Edit Record", "Open a dialogue subview for the clicked record"); - EnumValue view ("View", "Open a scene subview for the clicked record (not available everywhere)"); - EnumValue editRecordAndClose ("Edit Record and Close"); + recordValues.add(iconAndText).add("Icon Only").add("Text Only"); + declareEnum("status-format", "Modification status display format", iconAndText).addValues(recordValues); + declareEnum("type-format", "ID type display format", iconAndText).addValues(recordValues); + + declareCategory("ID Tables"); + EnumValue inPlaceEdit("Edit in Place", "Edit the clicked cell"); + EnumValue editRecord("Edit Record", "Open a dialogue subview for the clicked record"); + EnumValue view("View", "Open a scene subview for the clicked record (not available everywhere)"); + EnumValue editRecordAndClose("Edit Record and Close"); EnumValues doubleClickValues; - doubleClickValues.add (inPlaceEdit).add (editRecord).add (view).add ("Revert"). - add ("Delete").add (editRecordAndClose). - add ("View and Close", "Open a scene subview for the clicked record and close the table subview"); - declareEnum ("double", "Double Click", inPlaceEdit).addValues (doubleClickValues); - declareEnum ("double-s", "Shift Double Click", editRecord).addValues (doubleClickValues); - declareEnum ("double-c", "Control Double Click", view).addValues (doubleClickValues); - declareEnum ("double-sc", "Shift Control Double Click", editRecordAndClose).addValues (doubleClickValues); + doubleClickValues.add(inPlaceEdit) + .add(editRecord) + .add(view) + .add("Revert") + .add("Delete") + .add(editRecordAndClose) + .add("View and Close", "Open a scene subview for the clicked record and close the table subview"); + declareEnum("double", "Double Click", inPlaceEdit).addValues(doubleClickValues); + declareEnum("double-s", "Shift Double Click", editRecord).addValues(doubleClickValues); + declareEnum("double-c", "Control Double Click", view).addValues(doubleClickValues); + declareEnum("double-sc", "Shift Control Double Click", editRecordAndClose).addValues(doubleClickValues); declareSeparator(); - EnumValue jumpAndSelect ("Jump and Select", "Scroll new record into view and make it the selection"); - declareEnum ("jump-to-added", "Action on adding or cloning a record", jumpAndSelect). - addValue (jumpAndSelect). - addValue ("Jump Only", "Scroll new record into view"). - addValue ("No Jump", "No special action"); - declareBool ("extended-config", - "Manually specify affected record types for an extended delete/revert", false). - setTooltip ("Delete and revert commands have an extended form that also affects " - "associated records.\n\n" - "If this option is enabled, types of affected records are selected " - "manually before a command execution.\nOtherwise, all associated " - "records are deleted/reverted immediately."); - declareBool ("subview-new-window", "Open Record in new window", false) - .setTooltip("When editing a record, open the view in a new window," - " rather than docked in the main view."); - - declareCategory ("ID Dialogues"); - declareBool ("toolbar", "Show toolbar", true); - - declareCategory ("Reports"); - EnumValue actionNone ("None"); - EnumValue actionEdit ("Edit", "Open a table or dialogue suitable for addressing the listed report"); - EnumValue actionRemove ("Remove", "Remove the report from the report table"); - EnumValue actionEditAndRemove ("Edit And Remove", "Open a table or dialogue suitable for addressing the listed report, then remove the report from the report table"); + EnumValue jumpAndSelect("Jump and Select", "Scroll new record into view and make it the selection"); + declareEnum("jump-to-added", "Action on adding or cloning a record", jumpAndSelect) + .addValue(jumpAndSelect) + .addValue("Jump Only", "Scroll new record into view") + .addValue("No Jump", "No special action"); + declareBool("extended-config", "Manually specify affected record types for an extended delete/revert", false) + .setTooltip( + "Delete and revert commands have an extended form that also affects " + "associated records.\n\n" + "If this option is enabled, types of affected records are selected " + "manually before a command execution.\nOtherwise, all associated " + "records are deleted/reverted immediately."); + declareBool("subview-new-window", "Open Record in new window", false) + .setTooltip( + "When editing a record, open the view in a new window," + " rather than docked in the main view."); + + declareCategory("ID Dialogues"); + declareBool("toolbar", "Show toolbar", true); + + declareCategory("Reports"); + EnumValue actionNone("None"); + EnumValue actionEdit("Edit", "Open a table or dialogue suitable for addressing the listed report"); + EnumValue actionRemove("Remove", "Remove the report from the report table"); + EnumValue actionEditAndRemove("Edit And Remove", + "Open a table or dialogue suitable for addressing the listed report, then remove the report from the report " + "table"); EnumValues reportValues; - reportValues.add (actionNone).add (actionEdit).add (actionRemove).add (actionEditAndRemove); - declareEnum ("double", "Double Click", actionEdit).addValues (reportValues); - declareEnum ("double-s", "Shift Double Click", actionRemove).addValues (reportValues); - declareEnum ("double-c", "Control Double Click", actionEditAndRemove).addValues (reportValues); - declareEnum ("double-sc", "Shift Control Double Click", actionNone).addValues (reportValues); + reportValues.add(actionNone).add(actionEdit).add(actionRemove).add(actionEditAndRemove); + declareEnum("double", "Double Click", actionEdit).addValues(reportValues); + declareEnum("double-s", "Shift Double Click", actionRemove).addValues(reportValues); + declareEnum("double-c", "Control Double Click", actionEditAndRemove).addValues(reportValues); + declareEnum("double-sc", "Shift Control Double Click", actionNone).addValues(reportValues); declareBool("ignore-base-records", "Ignore base records in verifier", false); - declareCategory ("Search & Replace"); - declareInt ("char-before", "Characters before search string", 10). - setTooltip ("Maximum number of character to display in search result before the searched text"); - declareInt ("char-after", "Characters after search string", 10). - setTooltip ("Maximum number of character to display in search result after the searched text"); - declareBool ("auto-delete", "Delete row from result table after a successful replace", true); - - declareCategory ("Scripts"); - declareBool ("show-linenum", "Show Line Numbers", true). - setTooltip ("Show line numbers to the left of the script editor window." - "The current row and column numbers of the text cursor are shown at the bottom."); - declareBool ("wrap-lines", "Wrap Lines", false). - setTooltip ("Wrap lines longer than width of script editor."); - declareBool ("mono-font", "Use monospace font", true); - declareInt ("tab-width", "Tab Width", 4). - setTooltip ("Number of characters for tab width"). - setRange (1, 10); - EnumValue warningsNormal ("Normal", "Report warnings as warning"); - declareEnum ("warnings", "Warning Mode", warningsNormal). - addValue ("Ignore", "Do not report warning"). - addValue (warningsNormal). - addValue ("Strict", "Promote warning to an error"); - declareBool ("toolbar", "Show toolbar", true); - declareInt ("compile-delay", "Delay between updating of source errors", 100). - setTooltip ("Delay in milliseconds"). - setRange (0, 10000); - declareInt ("error-height", "Initial height of the error panel", 100). - setRange (100, 10000); - declareBool ("highlight-occurrences", "Highlight other occurrences of selected names", true); - declareColour ("colour-highlight", "Colour of highlighted occurrences", QColor("lightcyan")); + declareCategory("Search & Replace"); + declareInt("char-before", "Characters before search string", 10) + .setTooltip("Maximum number of character to display in search result before the searched text"); + declareInt("char-after", "Characters after search string", 10) + .setTooltip("Maximum number of character to display in search result after the searched text"); + declareBool("auto-delete", "Delete row from result table after a successful replace", true); + + declareCategory("Scripts"); + declareBool("show-linenum", "Show Line Numbers", true) + .setTooltip( + "Show line numbers to the left of the script editor window." + "The current row and column numbers of the text cursor are shown at the bottom."); + declareBool("wrap-lines", "Wrap Lines", false).setTooltip("Wrap lines longer than width of script editor."); + declareBool("mono-font", "Use monospace font", true); + declareInt("tab-width", "Tab Width", 4).setTooltip("Number of characters for tab width").setRange(1, 10); + EnumValue warningsNormal("Normal", "Report warnings as warning"); + declareEnum("warnings", "Warning Mode", warningsNormal) + .addValue("Ignore", "Do not report warning") + .addValue(warningsNormal) + .addValue("Strict", "Promote warning to an error"); + declareBool("toolbar", "Show toolbar", true); + declareInt("compile-delay", "Delay between updating of source errors", 100) + .setTooltip("Delay in milliseconds") + .setRange(0, 10000); + declareInt("error-height", "Initial height of the error panel", 100).setRange(100, 10000); + declareBool("highlight-occurrences", "Highlight other occurrences of selected names", true); + declareColour("colour-highlight", "Colour of highlighted occurrences", QColor("lightcyan")); declareSeparator(); - declareColour ("colour-int", "Highlight Colour: Integer Literals", QColor ("darkmagenta")); - declareColour ("colour-float", "Highlight Colour: Float Literals", QColor ("magenta")); - declareColour ("colour-name", "Highlight Colour: Names", QColor ("grey")); - declareColour ("colour-keyword", "Highlight Colour: Keywords", QColor ("red")); - declareColour ("colour-special", "Highlight Colour: Special Characters", QColor ("darkorange")); - declareColour ("colour-comment", "Highlight Colour: Comments", QColor ("green")); - declareColour ("colour-id", "Highlight Colour: IDs", QColor ("blue")); - - declareCategory ("General Input"); - declareBool ("cycle", "Cyclic next/previous", false). - setTooltip ("When using next/previous functions at the last/first item of a " - "list go to the first/last item"); - - declareCategory ("3D Scene Input"); - - declareDouble ("navi-wheel-factor", "Camera Zoom Sensitivity", 8).setRange(-100.0, 100.0); - declareDouble ("s-navi-sensitivity", "Secondary Camera Movement Sensitivity", 50.0).setRange(-1000.0, 1000.0); + declareColour("colour-int", "Highlight Colour: Integer Literals", QColor("darkmagenta")); + declareColour("colour-float", "Highlight Colour: Float Literals", QColor("magenta")); + declareColour("colour-name", "Highlight Colour: Names", QColor("grey")); + declareColour("colour-keyword", "Highlight Colour: Keywords", QColor("red")); + declareColour("colour-special", "Highlight Colour: Special Characters", QColor("darkorange")); + declareColour("colour-comment", "Highlight Colour: Comments", QColor("green")); + declareColour("colour-id", "Highlight Colour: IDs", QColor("blue")); + + declareCategory("General Input"); + declareBool("cycle", "Cyclic next/previous", false) + .setTooltip( + "When using next/previous functions at the last/first item of a " + "list go to the first/last item"); + + declareCategory("3D Scene Input"); + + declareDouble("navi-wheel-factor", "Camera Zoom Sensitivity", 8).setRange(-100.0, 100.0); + declareDouble("s-navi-sensitivity", "Secondary Camera Movement Sensitivity", 50.0).setRange(-1000.0, 1000.0); declareSeparator(); - declareDouble ("p-navi-free-sensitivity", "Free Camera Sensitivity", 1/650.).setPrecision(5).setRange(0.0, 1.0); - declareBool ("p-navi-free-invert", "Invert Free Camera Mouse Input", false); - declareDouble ("navi-free-lin-speed", "Free Camera Linear Speed", 1000.0).setRange(1.0, 10000.0); - declareDouble ("navi-free-rot-speed", "Free Camera Rotational Speed", 3.14 / 2).setRange(0.001, 6.28); - declareDouble ("navi-free-speed-mult", "Free Camera Speed Multiplier (from Modifier)", 8).setRange(0.001, 1000.0); + declareDouble("p-navi-free-sensitivity", "Free Camera Sensitivity", 1 / 650.).setPrecision(5).setRange(0.0, 1.0); + declareBool("p-navi-free-invert", "Invert Free Camera Mouse Input", false); + declareDouble("navi-free-lin-speed", "Free Camera Linear Speed", 1000.0).setRange(1.0, 10000.0); + declareDouble("navi-free-rot-speed", "Free Camera Rotational Speed", 3.14 / 2).setRange(0.001, 6.28); + declareDouble("navi-free-speed-mult", "Free Camera Speed Multiplier (from Modifier)", 8).setRange(0.001, 1000.0); declareSeparator(); - declareDouble ("p-navi-orbit-sensitivity", "Orbit Camera Sensitivity", 1/650.).setPrecision(5).setRange(0.0, 1.0); - declareBool ("p-navi-orbit-invert", "Invert Orbit Camera Mouse Input", false); - declareDouble ("navi-orbit-rot-speed", "Orbital Camera Rotational Speed", 3.14 / 4).setRange(0.001, 6.28); - declareDouble ("navi-orbit-speed-mult", "Orbital Camera Speed Multiplier (from Modifier)", 4).setRange(0.001, 1000.0); - declareBool ("navi-orbit-const-roll", "Keep camera roll constant for orbital camera", true); + declareDouble("p-navi-orbit-sensitivity", "Orbit Camera Sensitivity", 1 / 650.).setPrecision(5).setRange(0.0, 1.0); + declareBool("p-navi-orbit-invert", "Invert Orbit Camera Mouse Input", false); + declareDouble("navi-orbit-rot-speed", "Orbital Camera Rotational Speed", 3.14 / 4).setRange(0.001, 6.28); + declareDouble("navi-orbit-speed-mult", "Orbital Camera Speed Multiplier (from Modifier)", 4) + .setRange(0.001, 1000.0); + declareBool("navi-orbit-const-roll", "Keep camera roll constant for orbital camera", true); declareSeparator(); - declareBool ("context-select", "Context Sensitive Selection", false); - declareDouble ("drag-factor", "Mouse sensitivity during drag operations", 1.0). - setRange (0.001, 100.0); - declareDouble ("drag-wheel-factor", "Mouse wheel sensitivity during drag operations", 1.0). - setRange (0.001, 100.0); - declareDouble ("drag-shift-factor", - "Shift-acceleration factor during drag operations", 4.0). - setTooltip ("Acceleration factor during drag operations while holding down shift"). - setRange (0.001, 100.0); - declareDouble ("rotate-factor", "Free rotation factor", 0.007).setPrecision(4).setRange(0.0001, 0.1); - - declareCategory ("Rendering"); - declareInt ("framerate-limit", "FPS limit", 60). - setTooltip("Framerate limit in 3D preview windows. Zero value means \"unlimited\"."). - setRange(0, 10000); - declareInt ("camera-fov", "Camera FOV", 90).setRange(10, 170); - declareBool ("camera-ortho", "Orthographic projection for camera", false); - declareInt ("camera-ortho-size", "Orthographic projection size parameter", 100). - setTooltip("Size of the orthographic frustum, greater value will allow the camera to see more of the world."). - setRange(10, 10000); - declareDouble ("object-marker-alpha", "Object Marker Transparency", 0.5).setPrecision(2).setRange(0,1); + declareBool("context-select", "Context Sensitive Selection", false); + declareDouble("drag-factor", "Mouse sensitivity during drag operations", 1.0).setRange(0.001, 100.0); + declareDouble("drag-wheel-factor", "Mouse wheel sensitivity during drag operations", 1.0).setRange(0.001, 100.0); + declareDouble("drag-shift-factor", "Shift-acceleration factor during drag operations", 4.0) + .setTooltip("Acceleration factor during drag operations while holding down shift") + .setRange(0.001, 100.0); + declareDouble("rotate-factor", "Free rotation factor", 0.007).setPrecision(4).setRange(0.0001, 0.1); + + declareCategory("Rendering"); + declareInt("framerate-limit", "FPS limit", 60) + .setTooltip("Framerate limit in 3D preview windows. Zero value means \"unlimited\".") + .setRange(0, 10000); + declareInt("camera-fov", "Camera FOV", 90).setRange(10, 170); + declareBool("camera-ortho", "Orthographic projection for camera", false); + declareInt("camera-ortho-size", "Orthographic projection size parameter", 100) + .setTooltip("Size of the orthographic frustum, greater value will allow the camera to see more of the world.") + .setRange(10, 10000); + declareDouble("object-marker-alpha", "Object Marker Transparency", 0.5).setPrecision(2).setRange(0, 1); declareBool("scene-use-gradient", "Use Gradient Background", true); - declareColour ("scene-day-background-colour", "Day Background Colour", QColor (110, 120, 128, 255)); - declareColour ("scene-day-gradient-colour", "Day Gradient Colour", QColor (47, 51, 51, 255)). - setTooltip("Sets the gradient color to use in conjunction with the day background color. Ignored if " - "the gradient option is disabled."); - declareColour ("scene-bright-background-colour", "Scene Bright Background Colour", QColor (79, 87, 92, 255)); - declareColour ("scene-bright-gradient-colour", "Scene Bright Gradient Colour", QColor (47, 51, 51, 255)). - setTooltip("Sets the gradient color to use in conjunction with the bright background color. Ignored if " + declareColour("scene-day-background-colour", "Day Background Colour", QColor(110, 120, 128, 255)); + declareColour("scene-day-gradient-colour", "Day Gradient Colour", QColor(47, 51, 51, 255)) + .setTooltip( + "Sets the gradient color to use in conjunction with the day background color. Ignored if " "the gradient option is disabled."); - declareColour ("scene-night-background-colour", "Scene Night Background Colour", QColor (64, 77, 79, 255)); - declareColour ("scene-night-gradient-colour", "Scene Night Gradient Colour", QColor (47, 51, 51, 255)). - setTooltip("Sets the gradient color to use in conjunction with the night background color. Ignored if " + declareColour("scene-bright-background-colour", "Scene Bright Background Colour", QColor(79, 87, 92, 255)); + declareColour("scene-bright-gradient-colour", "Scene Bright Gradient Colour", QColor(47, 51, 51, 255)) + .setTooltip( + "Sets the gradient color to use in conjunction with the bright background color. Ignored if " + "the gradient option is disabled."); + declareColour("scene-night-background-colour", "Scene Night Background Colour", QColor(64, 77, 79, 255)); + declareColour("scene-night-gradient-colour", "Scene Night Gradient Colour", QColor(47, 51, 51, 255)) + .setTooltip( + "Sets the gradient color to use in conjunction with the night background color. Ignored if " "the gradient option is disabled."); declareBool("scene-day-night-switch-nodes", "Use Day/Night Switch Nodes", true); - declareCategory ("Tooltips"); - declareBool ("scene", "Show Tooltips in 3D scenes", true); - declareBool ("scene-hide-basic", "Hide basic 3D scenes tooltips", false); - declareInt ("scene-delay", "Tooltip delay in milliseconds", 500). - setMin (1); + declareCategory("Tooltips"); + declareBool("scene", "Show Tooltips in 3D scenes", true); + declareBool("scene-hide-basic", "Hide basic 3D scenes tooltips", false); + declareInt("scene-delay", "Tooltip delay in milliseconds", 500).setMin(1); - EnumValue createAndInsert ("Create cell and insert"); - EnumValue showAndInsert ("Show cell and insert"); - EnumValue dontInsert ("Discard"); - EnumValue insertAnyway ("Insert anyway"); + EnumValue createAndInsert("Create cell and insert"); + EnumValue showAndInsert("Show cell and insert"); + EnumValue dontInsert("Discard"); + EnumValue insertAnyway("Insert anyway"); EnumValues insertOutsideCell; - insertOutsideCell.add (createAndInsert).add (dontInsert).add (insertAnyway); + insertOutsideCell.add(createAndInsert).add(dontInsert).add(insertAnyway); EnumValues insertOutsideVisibleCell; - insertOutsideVisibleCell.add (showAndInsert).add (dontInsert).add (insertAnyway); + insertOutsideVisibleCell.add(showAndInsert).add(dontInsert).add(insertAnyway); - EnumValue createAndLandEdit ("Create cell and land, then edit"); - EnumValue showAndLandEdit ("Show cell and edit"); - EnumValue dontLandEdit ("Discard"); + EnumValue createAndLandEdit("Create cell and land, then edit"); + EnumValue showAndLandEdit("Show cell and edit"); + EnumValue dontLandEdit("Discard"); EnumValues landeditOutsideCell; - landeditOutsideCell.add (createAndLandEdit).add (dontLandEdit); + landeditOutsideCell.add(createAndLandEdit).add(dontLandEdit); EnumValues landeditOutsideVisibleCell; - landeditOutsideVisibleCell.add (showAndLandEdit).add (dontLandEdit); + landeditOutsideVisibleCell.add(showAndLandEdit).add(dontLandEdit); - EnumValue SelectOnly ("Select only"); - EnumValue SelectAdd ("Add to selection"); - EnumValue SelectRemove ("Remove from selection"); - EnumValue selectInvert ("Invert selection"); + EnumValue SelectOnly("Select only"); + EnumValue SelectAdd("Add to selection"); + EnumValue SelectRemove("Remove from selection"); + EnumValue selectInvert("Invert selection"); EnumValues primarySelectAction; - primarySelectAction.add (SelectOnly).add (SelectAdd).add (SelectRemove).add (selectInvert); + primarySelectAction.add(SelectOnly).add(SelectAdd).add(SelectRemove).add(selectInvert); EnumValues secondarySelectAction; - secondarySelectAction.add (SelectOnly).add (SelectAdd).add (SelectRemove).add (selectInvert); + secondarySelectAction.add(SelectOnly).add(SelectAdd).add(SelectRemove).add(selectInvert); - declareCategory ("3D Scene Editing"); + declareCategory("3D Scene Editing"); declareDouble("gridsnap-movement", "Grid snap size", 16); declareDouble("gridsnap-rotation", "Angle snap size", 15); declareDouble("gridsnap-scale", "Scale snap size", 0.25); - declareInt ("distance", "Drop Distance", 50). - setTooltip ("If an instance drop can not be placed against another object at the " + declareInt("distance", "Drop Distance", 50) + .setTooltip( + "If an instance drop can not be placed against another object at the " "insert point, it will be placed by this distance from the insert point instead"); - declareEnum ("outside-drop", "Handling drops outside of cells", createAndInsert). - addValues (insertOutsideCell); - declareEnum ("outside-visible-drop", "Handling drops outside of visible cells", showAndInsert). - addValues (insertOutsideVisibleCell); - declareEnum ("outside-landedit", "Handling terrain edit outside of cells", createAndLandEdit). - setTooltip("Behavior of terrain editing, if land editing brush reaches an area without cell record."). - addValues (landeditOutsideCell); - declareEnum ("outside-visible-landedit", "Handling terrain edit outside of visible cells", showAndLandEdit). - setTooltip("Behavior of terrain editing, if land editing brush reaches an area that is not currently visible."). - addValues (landeditOutsideVisibleCell); - declareInt ("texturebrush-maximumsize", "Maximum texture brush size", 50). - setMin (1); - declareInt ("shapebrush-maximumsize", "Maximum height edit brush size", 100). - setTooltip("Setting for the slider range of brush size in terrain height editing."). - setMin (1); - declareBool ("landedit-post-smoothpainting", "Smooth land after painting height", false). - setTooltip("Raise and lower tools will leave bumpy finish without this option"); - declareDouble ("landedit-post-smoothstrength", "Smoothing strength (post-edit)", 0.25). - setTooltip("If smoothing land after painting height is used, this is the percentage of smooth applied afterwards. " - "Negative values may be used to roughen instead of smooth."). - setMin (-1). - setMax (1); - declareBool ("open-list-view", "Open displays list view", false). - setTooltip ("When opening a reference from the scene view, it will open the" - " instance list view instead of the individual instance record view."); - declareEnum ("primary-select-action", "Action for primary select", SelectOnly). - setTooltip("Selection can be chosen between select only, add to selection, remove from selection and invert selection."). - addValues (primarySelectAction); - declareEnum ("secondary-select-action", "Action for secondary select", SelectAdd). - setTooltip("Selection can be chosen between select only, add to selection, remove from selection and invert selection."). - addValues (secondarySelectAction); - - declareCategory ("Key Bindings"); - - declareSubcategory ("Document"); - declareShortcut ("document-file-newgame", "New Game", QKeySequence(Qt::ControlModifier | Qt::Key_N)); - declareShortcut ("document-file-newaddon", "New Addon", QKeySequence()); - declareShortcut ("document-file-open", "Open", QKeySequence(Qt::ControlModifier | Qt::Key_O)); - declareShortcut ("document-file-save", "Save", QKeySequence(Qt::ControlModifier | Qt::Key_S)); - declareShortcut ("document-help-help", "Help", QKeySequence(Qt::Key_F1)); - declareShortcut ("document-help-tutorial", "Tutorial", QKeySequence()); - declareShortcut ("document-file-verify", "Verify", QKeySequence()); - declareShortcut ("document-file-merge", "Merge", QKeySequence()); - declareShortcut ("document-file-errorlog", "Open Load Error Log", QKeySequence()); - declareShortcut ("document-file-metadata", "Meta Data", QKeySequence()); - declareShortcut ("document-file-close", "Close Document", QKeySequence(Qt::ControlModifier | Qt::Key_W)); - declareShortcut ("document-file-exit", "Exit Application", QKeySequence(Qt::ControlModifier | Qt::Key_Q)); - declareShortcut ("document-edit-undo", "Undo", QKeySequence(Qt::ControlModifier | Qt::Key_Z)); - declareShortcut ("document-edit-redo", "Redo", QKeySequence(Qt::ControlModifier | Qt::ShiftModifier | Qt::Key_Z)); - declareShortcut ("document-edit-preferences", "Open Preferences", QKeySequence()); - declareShortcut ("document-edit-search", "Search", QKeySequence(Qt::ControlModifier | Qt::Key_F)); - declareShortcut ("document-view-newview", "New View", QKeySequence()); - declareShortcut ("document-view-statusbar", "Toggle Status Bar", QKeySequence()); - declareShortcut ("document-view-filters", "Open Filter List", QKeySequence()); - declareShortcut ("document-world-regions", "Open Region List", QKeySequence()); - declareShortcut ("document-world-cells", "Open Cell List", QKeySequence()); - declareShortcut ("document-world-referencables", "Open Object List", QKeySequence()); - declareShortcut ("document-world-references", "Open Instance List", QKeySequence()); - declareShortcut ("document-world-lands", "Open Lands List", QKeySequence()); - declareShortcut ("document-world-landtextures", "Open Land Textures List", QKeySequence()); - declareShortcut ("document-world-pathgrid", "Open Pathgrid List", QKeySequence()); - declareShortcut ("document-world-regionmap", "Open Region Map", QKeySequence()); - declareShortcut ("document-mechanics-globals", "Open Global List", QKeySequence()); - declareShortcut ("document-mechanics-gamesettings", "Open Game Settings", QKeySequence()); - declareShortcut ("document-mechanics-scripts", "Open Script List", QKeySequence()); - declareShortcut ("document-mechanics-spells", "Open Spell List", QKeySequence()); - declareShortcut ("document-mechanics-enchantments", "Open Enchantment List", QKeySequence()); - declareShortcut ("document-mechanics-magiceffects", "Open Magic Effect List", QKeySequence()); - declareShortcut ("document-mechanics-startscripts", "Open Start Script List", QKeySequence()); - declareShortcut ("document-character-skills", "Open Skill List", QKeySequence()); - declareShortcut ("document-character-classes", "Open Class List", QKeySequence()); - declareShortcut ("document-character-factions", "Open Faction List", QKeySequence()); - declareShortcut ("document-character-races", "Open Race List", QKeySequence()); - declareShortcut ("document-character-birthsigns", "Open Birthsign List", QKeySequence()); - declareShortcut ("document-character-topics", "Open Topic List", QKeySequence()); - declareShortcut ("document-character-journals", "Open Journal List", QKeySequence()); - declareShortcut ("document-character-topicinfos", "Open Topic Info List", QKeySequence()); - declareShortcut ("document-character-journalinfos", "Open Journal Info List", QKeySequence()); - declareShortcut ("document-character-bodyparts", "Open Body Part List", QKeySequence()); - declareShortcut ("document-assets-reload", "Reload Assets", QKeySequence(Qt::Key_F5)); - declareShortcut ("document-assets-sounds", "Open Sound Asset List", QKeySequence()); - declareShortcut ("document-assets-soundgens", "Open Sound Generator List", QKeySequence()); - declareShortcut ("document-assets-meshes", "Open Mesh Asset List", QKeySequence()); - declareShortcut ("document-assets-icons", "Open Icon Asset List", QKeySequence()); - declareShortcut ("document-assets-music", "Open Music Asset List", QKeySequence()); - declareShortcut ("document-assets-soundres", "Open Sound File List", QKeySequence()); - declareShortcut ("document-assets-textures", "Open Texture Asset List", QKeySequence()); - declareShortcut ("document-assets-videos", "Open Video Asset List", QKeySequence()); - declareShortcut ("document-debug-run", "Run Debug", QKeySequence()); - declareShortcut ("document-debug-shutdown", "Stop Debug", QKeySequence()); - declareShortcut ("document-debug-profiles", "Debug Profiles", QKeySequence()); - declareShortcut ("document-debug-runlog", "Open Run Log", QKeySequence()); - - declareSubcategory ("Table"); - declareShortcut ("table-edit", "Edit Record", QKeySequence()); - declareShortcut ("table-add", "Add Row/Record", QKeySequence(Qt::ShiftModifier | Qt::Key_A)); - declareShortcut ("table-clone", "Clone Record", QKeySequence(Qt::ShiftModifier | Qt::Key_D)); - declareShortcut ("touch-record", "Touch Record", QKeySequence()); - declareShortcut ("table-revert", "Revert Record", QKeySequence()); - declareShortcut ("table-remove", "Remove Row/Record", QKeySequence(Qt::Key_Delete)); - declareShortcut ("table-moveup", "Move Record Up", QKeySequence()); - declareShortcut ("table-movedown", "Move Record Down", QKeySequence()); - declareShortcut ("table-view", "View Record", QKeySequence(Qt::ShiftModifier | Qt::Key_C)); - declareShortcut ("table-preview", "Preview Record", QKeySequence(Qt::ShiftModifier | Qt::Key_V)); - declareShortcut ("table-extendeddelete", "Extended Record Deletion", QKeySequence()); - declareShortcut ("table-extendedrevert", "Extended Record Revertion", QKeySequence()); - - declareSubcategory ("Report Table"); - declareShortcut ("reporttable-show", "Show Report", QKeySequence()); - declareShortcut ("reporttable-remove", "Remove Report", QKeySequence(Qt::Key_Delete)); - declareShortcut ("reporttable-replace", "Replace Report", QKeySequence()); - declareShortcut ("reporttable-refresh", "Refresh Report", QKeySequence()); - - declareSubcategory ("Scene"); - declareShortcut ("scene-navi-primary", "Camera Rotation From Mouse Movement", QKeySequence(Qt::LeftButton)); - declareShortcut ("scene-navi-secondary", "Camera Translation From Mouse Movement", + declareEnum("outside-drop", "Handling drops outside of cells", createAndInsert).addValues(insertOutsideCell); + declareEnum("outside-visible-drop", "Handling drops outside of visible cells", showAndInsert) + .addValues(insertOutsideVisibleCell); + declareEnum("outside-landedit", "Handling terrain edit outside of cells", createAndLandEdit) + .setTooltip("Behavior of terrain editing, if land editing brush reaches an area without cell record.") + .addValues(landeditOutsideCell); + declareEnum("outside-visible-landedit", "Handling terrain edit outside of visible cells", showAndLandEdit) + .setTooltip("Behavior of terrain editing, if land editing brush reaches an area that is not currently visible.") + .addValues(landeditOutsideVisibleCell); + declareInt("texturebrush-maximumsize", "Maximum texture brush size", 50).setMin(1); + declareInt("shapebrush-maximumsize", "Maximum height edit brush size", 100) + .setTooltip("Setting for the slider range of brush size in terrain height editing.") + .setMin(1); + declareBool("landedit-post-smoothpainting", "Smooth land after painting height", false) + .setTooltip("Raise and lower tools will leave bumpy finish without this option"); + declareDouble("landedit-post-smoothstrength", "Smoothing strength (post-edit)", 0.25) + .setTooltip( + "If smoothing land after painting height is used, this is the percentage of smooth applied afterwards. " + "Negative values may be used to roughen instead of smooth.") + .setMin(-1) + .setMax(1); + declareBool("open-list-view", "Open displays list view", false) + .setTooltip( + "When opening a reference from the scene view, it will open the" + " instance list view instead of the individual instance record view."); + declareEnum("primary-select-action", "Action for primary select", SelectOnly) + .setTooltip( + "Selection can be chosen between select only, add to selection, remove from selection and invert " + "selection.") + .addValues(primarySelectAction); + declareEnum("secondary-select-action", "Action for secondary select", SelectAdd) + .setTooltip( + "Selection can be chosen between select only, add to selection, remove from selection and invert " + "selection.") + .addValues(secondarySelectAction); + + declareCategory("Key Bindings"); + + declareSubcategory("Document"); + declareShortcut("document-file-newgame", "New Game", QKeySequence(Qt::ControlModifier | Qt::Key_N)); + declareShortcut("document-file-newaddon", "New Addon", QKeySequence()); + declareShortcut("document-file-open", "Open", QKeySequence(Qt::ControlModifier | Qt::Key_O)); + declareShortcut("document-file-save", "Save", QKeySequence(Qt::ControlModifier | Qt::Key_S)); + declareShortcut("document-help-help", "Help", QKeySequence(Qt::Key_F1)); + declareShortcut("document-help-tutorial", "Tutorial", QKeySequence()); + declareShortcut("document-file-verify", "Verify", QKeySequence()); + declareShortcut("document-file-merge", "Merge", QKeySequence()); + declareShortcut("document-file-errorlog", "Open Load Error Log", QKeySequence()); + declareShortcut("document-file-metadata", "Meta Data", QKeySequence()); + declareShortcut("document-file-close", "Close Document", QKeySequence(Qt::ControlModifier | Qt::Key_W)); + declareShortcut("document-file-exit", "Exit Application", QKeySequence(Qt::ControlModifier | Qt::Key_Q)); + declareShortcut("document-edit-undo", "Undo", QKeySequence(Qt::ControlModifier | Qt::Key_Z)); + declareShortcut("document-edit-redo", "Redo", QKeySequence(Qt::ControlModifier | Qt::ShiftModifier | Qt::Key_Z)); + declareShortcut("document-edit-preferences", "Open Preferences", QKeySequence()); + declareShortcut("document-edit-search", "Search", QKeySequence(Qt::ControlModifier | Qt::Key_F)); + declareShortcut("document-view-newview", "New View", QKeySequence()); + declareShortcut("document-view-statusbar", "Toggle Status Bar", QKeySequence()); + declareShortcut("document-view-filters", "Open Filter List", QKeySequence()); + declareShortcut("document-world-regions", "Open Region List", QKeySequence()); + declareShortcut("document-world-cells", "Open Cell List", QKeySequence()); + declareShortcut("document-world-referencables", "Open Object List", QKeySequence()); + declareShortcut("document-world-references", "Open Instance List", QKeySequence()); + declareShortcut("document-world-lands", "Open Lands List", QKeySequence()); + declareShortcut("document-world-landtextures", "Open Land Textures List", QKeySequence()); + declareShortcut("document-world-pathgrid", "Open Pathgrid List", QKeySequence()); + declareShortcut("document-world-regionmap", "Open Region Map", QKeySequence()); + declareShortcut("document-mechanics-globals", "Open Global List", QKeySequence()); + declareShortcut("document-mechanics-gamesettings", "Open Game Settings", QKeySequence()); + declareShortcut("document-mechanics-scripts", "Open Script List", QKeySequence()); + declareShortcut("document-mechanics-spells", "Open Spell List", QKeySequence()); + declareShortcut("document-mechanics-enchantments", "Open Enchantment List", QKeySequence()); + declareShortcut("document-mechanics-magiceffects", "Open Magic Effect List", QKeySequence()); + declareShortcut("document-mechanics-startscripts", "Open Start Script List", QKeySequence()); + declareShortcut("document-character-skills", "Open Skill List", QKeySequence()); + declareShortcut("document-character-classes", "Open Class List", QKeySequence()); + declareShortcut("document-character-factions", "Open Faction List", QKeySequence()); + declareShortcut("document-character-races", "Open Race List", QKeySequence()); + declareShortcut("document-character-birthsigns", "Open Birthsign List", QKeySequence()); + declareShortcut("document-character-topics", "Open Topic List", QKeySequence()); + declareShortcut("document-character-journals", "Open Journal List", QKeySequence()); + declareShortcut("document-character-topicinfos", "Open Topic Info List", QKeySequence()); + declareShortcut("document-character-journalinfos", "Open Journal Info List", QKeySequence()); + declareShortcut("document-character-bodyparts", "Open Body Part List", QKeySequence()); + declareShortcut("document-assets-reload", "Reload Assets", QKeySequence(Qt::Key_F5)); + declareShortcut("document-assets-sounds", "Open Sound Asset List", QKeySequence()); + declareShortcut("document-assets-soundgens", "Open Sound Generator List", QKeySequence()); + declareShortcut("document-assets-meshes", "Open Mesh Asset List", QKeySequence()); + declareShortcut("document-assets-icons", "Open Icon Asset List", QKeySequence()); + declareShortcut("document-assets-music", "Open Music Asset List", QKeySequence()); + declareShortcut("document-assets-soundres", "Open Sound File List", QKeySequence()); + declareShortcut("document-assets-textures", "Open Texture Asset List", QKeySequence()); + declareShortcut("document-assets-videos", "Open Video Asset List", QKeySequence()); + declareShortcut("document-debug-run", "Run Debug", QKeySequence()); + declareShortcut("document-debug-shutdown", "Stop Debug", QKeySequence()); + declareShortcut("document-debug-profiles", "Debug Profiles", QKeySequence()); + declareShortcut("document-debug-runlog", "Open Run Log", QKeySequence()); + + declareSubcategory("Table"); + declareShortcut("table-edit", "Edit Record", QKeySequence()); + declareShortcut("table-add", "Add Row/Record", QKeySequence(Qt::ShiftModifier | Qt::Key_A)); + declareShortcut("table-clone", "Clone Record", QKeySequence(Qt::ShiftModifier | Qt::Key_D)); + declareShortcut("touch-record", "Touch Record", QKeySequence()); + declareShortcut("table-revert", "Revert Record", QKeySequence()); + declareShortcut("table-remove", "Remove Row/Record", QKeySequence(Qt::Key_Delete)); + declareShortcut("table-moveup", "Move Record Up", QKeySequence()); + declareShortcut("table-movedown", "Move Record Down", QKeySequence()); + declareShortcut("table-view", "View Record", QKeySequence(Qt::ShiftModifier | Qt::Key_C)); + declareShortcut("table-preview", "Preview Record", QKeySequence(Qt::ShiftModifier | Qt::Key_V)); + declareShortcut("table-extendeddelete", "Extended Record Deletion", QKeySequence()); + declareShortcut("table-extendedrevert", "Extended Record Revertion", QKeySequence()); + + declareSubcategory("Report Table"); + declareShortcut("reporttable-show", "Show Report", QKeySequence()); + declareShortcut("reporttable-remove", "Remove Report", QKeySequence(Qt::Key_Delete)); + declareShortcut("reporttable-replace", "Replace Report", QKeySequence()); + declareShortcut("reporttable-refresh", "Refresh Report", QKeySequence()); + + declareSubcategory("Scene"); + declareShortcut("scene-navi-primary", "Camera Rotation From Mouse Movement", QKeySequence(Qt::LeftButton)); + declareShortcut("scene-navi-secondary", "Camera Translation From Mouse Movement", QKeySequence(Qt::ControlModifier | (int)Qt::LeftButton)); - declareShortcut ("scene-open-primary", "Primary Open", QKeySequence(Qt::ShiftModifier | (int)Qt::LeftButton)); - declareShortcut ("scene-edit-primary", "Primary Edit", QKeySequence(Qt::RightButton)); - declareShortcut ("scene-edit-secondary", "Secondary Edit", - QKeySequence(Qt::ControlModifier | (int)Qt::RightButton)); - declareShortcut ("scene-select-primary", "Primary Select", QKeySequence(Qt::MiddleButton)); - declareShortcut ("scene-select-secondary", "Secondary Select", - QKeySequence(Qt::ControlModifier | (int)Qt::MiddleButton)); - declareModifier ("scene-speed-modifier", "Speed Modifier", Qt::Key_Shift); - declareShortcut ("scene-delete", "Delete Instance", QKeySequence(Qt::Key_Delete)); - declareShortcut ("scene-instance-drop-terrain", "Drop to terrain level", QKeySequence(Qt::Key_G)); - declareShortcut ("scene-instance-drop-collision", "Drop to collision", QKeySequence(Qt::Key_H)); - declareShortcut ("scene-instance-drop-terrain-separately", "Drop to terrain level separately", QKeySequence()); - declareShortcut ("scene-instance-drop-collision-separately", "Drop to collision separately", QKeySequence()); - declareShortcut ("scene-load-cam-cell", "Load Camera Cell", QKeySequence(Qt::KeypadModifier | Qt::Key_5)); - declareShortcut ("scene-load-cam-eastcell", "Load East Cell", QKeySequence(Qt::KeypadModifier | Qt::Key_6)); - declareShortcut ("scene-load-cam-northcell", "Load North Cell", QKeySequence(Qt::KeypadModifier | Qt::Key_8)); - declareShortcut ("scene-load-cam-westcell", "Load West Cell", QKeySequence(Qt::KeypadModifier | Qt::Key_4)); - declareShortcut ("scene-load-cam-southcell", "Load South Cell", QKeySequence(Qt::KeypadModifier | Qt::Key_2)); - declareShortcut ("scene-edit-abort", "Abort", QKeySequence(Qt::Key_Escape)); - declareShortcut ("scene-focus-toolbar", "Toggle Toolbar Focus", QKeySequence(Qt::Key_T)); - declareShortcut ("scene-render-stats", "Debug Rendering Stats", QKeySequence(Qt::Key_F3)); - - declareSubcategory ("1st/Free Camera"); - declareShortcut ("free-forward", "Forward", QKeySequence(Qt::Key_W)); - declareShortcut ("free-backward", "Backward", QKeySequence(Qt::Key_S)); - declareShortcut ("free-left", "Left", QKeySequence(Qt::Key_A)); - declareShortcut ("free-right", "Right", QKeySequence(Qt::Key_D)); - declareShortcut ("free-roll-left", "Roll Left", QKeySequence(Qt::Key_Q)); - declareShortcut ("free-roll-right", "Roll Right", QKeySequence(Qt::Key_E)); - declareShortcut ("free-speed-mode", "Toggle Speed Mode", QKeySequence(Qt::Key_F)); - - declareSubcategory ("Orbit Camera"); - declareShortcut ("orbit-up", "Up", QKeySequence(Qt::Key_W)); - declareShortcut ("orbit-down", "Down", QKeySequence(Qt::Key_S)); - declareShortcut ("orbit-left", "Left", QKeySequence(Qt::Key_A)); - declareShortcut ("orbit-right", "Right", QKeySequence(Qt::Key_D)); - declareShortcut ("orbit-roll-left", "Roll Left", QKeySequence(Qt::Key_Q)); - declareShortcut ("orbit-roll-right", "Roll Right", QKeySequence(Qt::Key_E)); - declareShortcut ("orbit-speed-mode", "Toggle Speed Mode", QKeySequence(Qt::Key_F)); - declareShortcut ("orbit-center-selection", "Center On Selected", QKeySequence(Qt::Key_C)); - - declareSubcategory ("Script Editor"); - declareShortcut ("script-editor-comment", "Comment Selection", QKeySequence()); - declareShortcut ("script-editor-uncomment", "Uncomment Selection", QKeySequence()); - - declareCategory ("Models"); - declareString ("baseanim", "base animations", "meshes/base_anim.nif"). - setTooltip("3rd person base model with textkeys-data"); - declareString ("baseanimkna", "base animations, kna", "meshes/base_animkna.nif"). - setTooltip("3rd person beast race base model with textkeys-data"); - declareString ("baseanimfemale", "base animations, female", "meshes/base_anim_female.nif"). - setTooltip("3rd person female base model with textkeys-data"); - declareString ("wolfskin", "base animations, wolf", "meshes/wolf/skin.nif"). - setTooltip("3rd person werewolf skin"); + declareShortcut("scene-open-primary", "Primary Open", QKeySequence(Qt::ShiftModifier | (int)Qt::LeftButton)); + declareShortcut("scene-edit-primary", "Primary Edit", QKeySequence(Qt::RightButton)); + declareShortcut("scene-edit-secondary", "Secondary Edit", QKeySequence(Qt::ControlModifier | (int)Qt::RightButton)); + declareShortcut("scene-select-primary", "Primary Select", QKeySequence(Qt::MiddleButton)); + declareShortcut( + "scene-select-secondary", "Secondary Select", QKeySequence(Qt::ControlModifier | (int)Qt::MiddleButton)); + declareModifier("scene-speed-modifier", "Speed Modifier", Qt::Key_Shift); + declareShortcut("scene-delete", "Delete Instance", QKeySequence(Qt::Key_Delete)); + declareShortcut("scene-instance-drop-terrain", "Drop to terrain level", QKeySequence(Qt::Key_G)); + declareShortcut("scene-instance-drop-collision", "Drop to collision", QKeySequence(Qt::Key_H)); + declareShortcut("scene-instance-drop-terrain-separately", "Drop to terrain level separately", QKeySequence()); + declareShortcut("scene-instance-drop-collision-separately", "Drop to collision separately", QKeySequence()); + declareShortcut("scene-load-cam-cell", "Load Camera Cell", QKeySequence(Qt::KeypadModifier | Qt::Key_5)); + declareShortcut("scene-load-cam-eastcell", "Load East Cell", QKeySequence(Qt::KeypadModifier | Qt::Key_6)); + declareShortcut("scene-load-cam-northcell", "Load North Cell", QKeySequence(Qt::KeypadModifier | Qt::Key_8)); + declareShortcut("scene-load-cam-westcell", "Load West Cell", QKeySequence(Qt::KeypadModifier | Qt::Key_4)); + declareShortcut("scene-load-cam-southcell", "Load South Cell", QKeySequence(Qt::KeypadModifier | Qt::Key_2)); + declareShortcut("scene-edit-abort", "Abort", QKeySequence(Qt::Key_Escape)); + declareShortcut("scene-focus-toolbar", "Toggle Toolbar Focus", QKeySequence(Qt::Key_T)); + declareShortcut("scene-render-stats", "Debug Rendering Stats", QKeySequence(Qt::Key_F3)); + + declareSubcategory("1st/Free Camera"); + declareShortcut("free-forward", "Forward", QKeySequence(Qt::Key_W)); + declareShortcut("free-backward", "Backward", QKeySequence(Qt::Key_S)); + declareShortcut("free-left", "Left", QKeySequence(Qt::Key_A)); + declareShortcut("free-right", "Right", QKeySequence(Qt::Key_D)); + declareShortcut("free-roll-left", "Roll Left", QKeySequence(Qt::Key_Q)); + declareShortcut("free-roll-right", "Roll Right", QKeySequence(Qt::Key_E)); + declareShortcut("free-speed-mode", "Toggle Speed Mode", QKeySequence(Qt::Key_F)); + + declareSubcategory("Orbit Camera"); + declareShortcut("orbit-up", "Up", QKeySequence(Qt::Key_W)); + declareShortcut("orbit-down", "Down", QKeySequence(Qt::Key_S)); + declareShortcut("orbit-left", "Left", QKeySequence(Qt::Key_A)); + declareShortcut("orbit-right", "Right", QKeySequence(Qt::Key_D)); + declareShortcut("orbit-roll-left", "Roll Left", QKeySequence(Qt::Key_Q)); + declareShortcut("orbit-roll-right", "Roll Right", QKeySequence(Qt::Key_E)); + declareShortcut("orbit-speed-mode", "Toggle Speed Mode", QKeySequence(Qt::Key_F)); + declareShortcut("orbit-center-selection", "Center On Selected", QKeySequence(Qt::Key_C)); + + declareSubcategory("Script Editor"); + declareShortcut("script-editor-comment", "Comment Selection", QKeySequence()); + declareShortcut("script-editor-uncomment", "Uncomment Selection", QKeySequence()); + + declareCategory("Models"); + declareString("baseanim", "base animations", "meshes/base_anim.nif") + .setTooltip("3rd person base model with textkeys-data"); + declareString("baseanimkna", "base animations, kna", "meshes/base_animkna.nif") + .setTooltip("3rd person beast race base model with textkeys-data"); + declareString("baseanimfemale", "base animations, female", "meshes/base_anim_female.nif") + .setTooltip("3rd person female base model with textkeys-data"); + declareString("wolfskin", "base animations, wolf", "meshes/wolf/skin.nif").setTooltip("3rd person werewolf skin"); } -void CSMPrefs::State::declareCategory (const std::string& key) +void CSMPrefs::State::declareCategory(const std::string& key) { - std::map::iterator iter = mCategories.find (key); + std::map::iterator iter = mCategories.find(key); - if (iter!=mCategories.end()) + if (iter != mCategories.end()) { mCurrentCategory = iter; } else { - mCurrentCategory = - mCategories.insert (std::make_pair (key, Category (this, key))).first; + mCurrentCategory = mCategories.insert(std::make_pair(key, Category(this, key))).first; } } -CSMPrefs::IntSetting& CSMPrefs::State::declareInt (const std::string& key, - const std::string& label, int default_) +CSMPrefs::IntSetting& CSMPrefs::State::declareInt(const std::string& key, const std::string& label, int default_) { - if (mCurrentCategory==mCategories.end()) - throw std::logic_error ("no category for setting"); + if (mCurrentCategory == mCategories.end()) + throw std::logic_error("no category for setting"); setDefault(key, std::to_string(default_)); - default_ = Settings::Manager::getInt (key, mCurrentCategory->second.getKey()); + default_ = Settings::Manager::getInt(key, mCurrentCategory->second.getKey()); - CSMPrefs::IntSetting *setting = - new CSMPrefs::IntSetting (&mCurrentCategory->second, &mMutex, key, label, - default_); + CSMPrefs::IntSetting* setting = new CSMPrefs::IntSetting(&mCurrentCategory->second, &mMutex, key, label, default_); - mCurrentCategory->second.addSetting (setting); + mCurrentCategory->second.addSetting(setting); return *setting; } -CSMPrefs::DoubleSetting& CSMPrefs::State::declareDouble (const std::string& key, - const std::string& label, double default_) +CSMPrefs::DoubleSetting& CSMPrefs::State::declareDouble( + const std::string& key, const std::string& label, double default_) { - if (mCurrentCategory==mCategories.end()) - throw std::logic_error ("no category for setting"); + if (mCurrentCategory == mCategories.end()) + throw std::logic_error("no category for setting"); std::ostringstream stream; stream << default_; setDefault(key, stream.str()); - default_ = Settings::Manager::getFloat (key, mCurrentCategory->second.getKey()); + default_ = Settings::Manager::getFloat(key, mCurrentCategory->second.getKey()); - CSMPrefs::DoubleSetting *setting = - new CSMPrefs::DoubleSetting (&mCurrentCategory->second, &mMutex, - key, label, default_); + CSMPrefs::DoubleSetting* setting + = new CSMPrefs::DoubleSetting(&mCurrentCategory->second, &mMutex, key, label, default_); - mCurrentCategory->second.addSetting (setting); + mCurrentCategory->second.addSetting(setting); return *setting; } -CSMPrefs::BoolSetting& CSMPrefs::State::declareBool (const std::string& key, - const std::string& label, bool default_) +CSMPrefs::BoolSetting& CSMPrefs::State::declareBool(const std::string& key, const std::string& label, bool default_) { - if (mCurrentCategory==mCategories.end()) - throw std::logic_error ("no category for setting"); + if (mCurrentCategory == mCategories.end()) + throw std::logic_error("no category for setting"); - setDefault (key, default_ ? "true" : "false"); + setDefault(key, default_ ? "true" : "false"); - default_ = Settings::Manager::getBool (key, mCurrentCategory->second.getKey()); + default_ = Settings::Manager::getBool(key, mCurrentCategory->second.getKey()); - CSMPrefs::BoolSetting *setting = - new CSMPrefs::BoolSetting (&mCurrentCategory->second, &mMutex, key, label, - default_); + CSMPrefs::BoolSetting* setting + = new CSMPrefs::BoolSetting(&mCurrentCategory->second, &mMutex, key, label, default_); - mCurrentCategory->second.addSetting (setting); + mCurrentCategory->second.addSetting(setting); return *setting; } -CSMPrefs::EnumSetting& CSMPrefs::State::declareEnum (const std::string& key, - const std::string& label, EnumValue default_) +CSMPrefs::EnumSetting& CSMPrefs::State::declareEnum( + const std::string& key, const std::string& label, EnumValue default_) { - if (mCurrentCategory==mCategories.end()) - throw std::logic_error ("no category for setting"); + if (mCurrentCategory == mCategories.end()) + throw std::logic_error("no category for setting"); - setDefault (key, default_.mValue); + setDefault(key, default_.mValue); - default_.mValue = Settings::Manager::getString (key, mCurrentCategory->second.getKey()); + default_.mValue = Settings::Manager::getString(key, mCurrentCategory->second.getKey()); - CSMPrefs::EnumSetting *setting = - new CSMPrefs::EnumSetting (&mCurrentCategory->second, &mMutex, key, label, - default_); + CSMPrefs::EnumSetting* setting + = new CSMPrefs::EnumSetting(&mCurrentCategory->second, &mMutex, key, label, default_); - mCurrentCategory->second.addSetting (setting); + mCurrentCategory->second.addSetting(setting); return *setting; } -CSMPrefs::ColourSetting& CSMPrefs::State::declareColour (const std::string& key, - const std::string& label, QColor default_) +CSMPrefs::ColourSetting& CSMPrefs::State::declareColour( + const std::string& key, const std::string& label, QColor default_) { - if (mCurrentCategory==mCategories.end()) - throw std::logic_error ("no category for setting"); + if (mCurrentCategory == mCategories.end()) + throw std::logic_error("no category for setting"); - setDefault (key, default_.name().toUtf8().data()); + setDefault(key, default_.name().toUtf8().data()); - default_.setNamedColor (QString::fromUtf8 (Settings::Manager::getString (key, mCurrentCategory->second.getKey()).c_str())); + default_.setNamedColor( + QString::fromUtf8(Settings::Manager::getString(key, mCurrentCategory->second.getKey()).c_str())); - CSMPrefs::ColourSetting *setting = - new CSMPrefs::ColourSetting (&mCurrentCategory->second, &mMutex, key, label, - default_); + CSMPrefs::ColourSetting* setting + = new CSMPrefs::ColourSetting(&mCurrentCategory->second, &mMutex, key, label, default_); - mCurrentCategory->second.addSetting (setting); + mCurrentCategory->second.addSetting(setting); return *setting; } -CSMPrefs::ShortcutSetting& CSMPrefs::State::declareShortcut (const std::string& key, const std::string& label, - const QKeySequence& default_) +CSMPrefs::ShortcutSetting& CSMPrefs::State::declareShortcut( + const std::string& key, const std::string& label, const QKeySequence& default_) { - if (mCurrentCategory==mCategories.end()) - throw std::logic_error ("no category for setting"); + if (mCurrentCategory == mCategories.end()) + throw std::logic_error("no category for setting"); std::string seqStr = getShortcutManager().convertToString(default_); - setDefault (key, seqStr); + setDefault(key, seqStr); // Setup with actual data QKeySequence sequence; - getShortcutManager().convertFromString(Settings::Manager::getString(key, mCurrentCategory->second.getKey()), sequence); + getShortcutManager().convertFromString( + Settings::Manager::getString(key, mCurrentCategory->second.getKey()), sequence); getShortcutManager().setSequence(key, sequence); - CSMPrefs::ShortcutSetting *setting = new CSMPrefs::ShortcutSetting (&mCurrentCategory->second, &mMutex, - key, label); - mCurrentCategory->second.addSetting (setting); + CSMPrefs::ShortcutSetting* setting = new CSMPrefs::ShortcutSetting(&mCurrentCategory->second, &mMutex, key, label); + mCurrentCategory->second.addSetting(setting); return *setting; } -CSMPrefs::StringSetting& CSMPrefs::State::declareString (const std::string& key, const std::string& label, std::string default_) +CSMPrefs::StringSetting& CSMPrefs::State::declareString( + const std::string& key, const std::string& label, std::string default_) { - if (mCurrentCategory==mCategories.end()) - throw std::logic_error ("no category for setting"); + if (mCurrentCategory == mCategories.end()) + throw std::logic_error("no category for setting"); - setDefault (key, default_); + setDefault(key, default_); - default_ = Settings::Manager::getString (key, mCurrentCategory->second.getKey()); + default_ = Settings::Manager::getString(key, mCurrentCategory->second.getKey()); - CSMPrefs::StringSetting *setting = - new CSMPrefs::StringSetting (&mCurrentCategory->second, &mMutex, key, label, - default_); + CSMPrefs::StringSetting* setting + = new CSMPrefs::StringSetting(&mCurrentCategory->second, &mMutex, key, label, default_); - mCurrentCategory->second.addSetting (setting); + mCurrentCategory->second.addSetting(setting); return *setting; } -CSMPrefs::ModifierSetting& CSMPrefs::State::declareModifier(const std::string& key, const std::string& label, - int default_) +CSMPrefs::ModifierSetting& CSMPrefs::State::declareModifier( + const std::string& key, const std::string& label, int default_) { - if (mCurrentCategory==mCategories.end()) - throw std::logic_error ("no category for setting"); + if (mCurrentCategory == mCategories.end()) + throw std::logic_error("no category for setting"); std::string modStr = getShortcutManager().convertToString(default_); - setDefault (key, modStr); + setDefault(key, modStr); // Setup with actual data int modifier; - getShortcutManager().convertFromString(Settings::Manager::getString(key, mCurrentCategory->second.getKey()), modifier); + getShortcutManager().convertFromString( + Settings::Manager::getString(key, mCurrentCategory->second.getKey()), modifier); getShortcutManager().setModifier(key, modifier); - CSMPrefs::ModifierSetting *setting = new CSMPrefs::ModifierSetting (&mCurrentCategory->second, &mMutex, - key, label); - mCurrentCategory->second.addSetting (setting); + CSMPrefs::ModifierSetting* setting = new CSMPrefs::ModifierSetting(&mCurrentCategory->second, &mMutex, key, label); + mCurrentCategory->second.addSetting(setting); return *setting; } void CSMPrefs::State::declareSeparator() { - if (mCurrentCategory==mCategories.end()) - throw std::logic_error ("no category for setting"); + if (mCurrentCategory == mCategories.end()) + throw std::logic_error("no category for setting"); - CSMPrefs::Setting *setting = - new CSMPrefs::Setting (&mCurrentCategory->second, &mMutex, "", ""); + CSMPrefs::Setting* setting = new CSMPrefs::Setting(&mCurrentCategory->second, &mMutex, "", ""); - mCurrentCategory->second.addSetting (setting); + mCurrentCategory->second.addSetting(setting); } void CSMPrefs::State::declareSubcategory(const std::string& label) { - if (mCurrentCategory==mCategories.end()) - throw std::logic_error ("no category for setting"); + if (mCurrentCategory == mCategories.end()) + throw std::logic_error("no category for setting"); - CSMPrefs::Setting *setting = - new CSMPrefs::Setting (&mCurrentCategory->second, &mMutex, "", label); + CSMPrefs::Setting* setting = new CSMPrefs::Setting(&mCurrentCategory->second, &mMutex, "", label); - mCurrentCategory->second.addSetting (setting); + mCurrentCategory->second.addSetting(setting); } -void CSMPrefs::State::setDefault (const std::string& key, const std::string& default_) +void CSMPrefs::State::setDefault(const std::string& key, const std::string& default_) { - Settings::CategorySetting fullKey (mCurrentCategory->second.getKey(), key); + Settings::CategorySetting fullKey(mCurrentCategory->second.getKey(), key); - Settings::CategorySettingValueMap::iterator iter = - Settings::Manager::mDefaultSettings.find (fullKey); + Settings::CategorySettingValueMap::iterator iter = Settings::Manager::mDefaultSettings.find(fullKey); - if (iter==Settings::Manager::mDefaultSettings.end()) - Settings::Manager::mDefaultSettings.insert (std::make_pair (fullKey, default_)); + if (iter == Settings::Manager::mDefaultSettings.end()) + Settings::Manager::mDefaultSettings.insert(std::make_pair(fullKey, default_)); } -CSMPrefs::State::State (const Files::ConfigurationManager& configurationManager) -: mConfigFile ("openmw-cs.cfg"), mDefaultConfigFile("defaults-cs.bin"), mConfigurationManager (configurationManager), - mCurrentCategory (mCategories.end()) +CSMPrefs::State::State(const Files::ConfigurationManager& configurationManager) + : mConfigFile("openmw-cs.cfg") + , mDefaultConfigFile("defaults-cs.bin") + , mConfigurationManager(configurationManager) + , mCurrentCategory(mCategories.end()) { if (sThis) - throw std::logic_error ("An instance of CSMPRefs::State already exists"); + throw std::logic_error("An instance of CSMPRefs::State already exists"); sThis = this; @@ -648,7 +651,7 @@ CSMPrefs::State::~State() void CSMPrefs::State::save() { - Settings::Manager::saveUser (mConfigurationManager.getUserConfigPath() / mConfigFile); + Settings::Manager::saveUser(mConfigurationManager.getUserConfigPath() / mConfigFile); } CSMPrefs::State::Iterator CSMPrefs::State::begin() @@ -666,17 +669,17 @@ CSMPrefs::ShortcutManager& CSMPrefs::State::getShortcutManager() return mShortcutManager; } -CSMPrefs::Category& CSMPrefs::State::operator[] (const std::string& key) +CSMPrefs::Category& CSMPrefs::State::operator[](const std::string& key) { - Iterator iter = mCategories.find (key); + Iterator iter = mCategories.find(key); - if (iter==mCategories.end()) - throw std::logic_error ("Invalid user settings category: " + key); + if (iter == mCategories.end()) + throw std::logic_error("Invalid user settings category: " + key); return iter->second; } -void CSMPrefs::State::update (const Setting& setting) +void CSMPrefs::State::update(const Setting& setting) { emit settingChanged(&setting); } @@ -684,7 +687,7 @@ void CSMPrefs::State::update (const Setting& setting) CSMPrefs::State& CSMPrefs::State::get() { if (!sThis) - throw std::logic_error ("No instance of CSMPrefs::State"); + throw std::logic_error("No instance of CSMPrefs::State"); return *sThis; } @@ -724,7 +727,6 @@ void CSMPrefs::State::resetAll() } } - CSMPrefs::State& CSMPrefs::get() { return State::get(); diff --git a/apps/opencs/model/prefs/state.hpp b/apps/opencs/model/prefs/state.hpp index f464013644..5f330b7651 100644 --- a/apps/opencs/model/prefs/state.hpp +++ b/apps/opencs/model/prefs/state.hpp @@ -4,18 +4,18 @@ #include #include -#include #include +#include #ifndef Q_MOC_RUN #include #endif #include "category.hpp" -#include "setting.hpp" #include "enumsetting.hpp" -#include "stringsetting.hpp" +#include "setting.hpp" #include "shortcutmanager.hpp" +#include "stringsetting.hpp" class QColor; @@ -34,84 +34,80 @@ namespace CSMPrefs /// been completed. class State : public QObject { - Q_OBJECT - - static State *sThis; - - public: - - typedef std::map Collection; - typedef Collection::iterator Iterator; - - private: + Q_OBJECT - const std::string mConfigFile; - const std::string mDefaultConfigFile; - const Files::ConfigurationManager& mConfigurationManager; - ShortcutManager mShortcutManager; - Collection mCategories; - Iterator mCurrentCategory; - QMutex mMutex; + static State* sThis; - // not implemented - State (const State&); - State& operator= (const State&); + public: + typedef std::map Collection; + typedef Collection::iterator Iterator; - private: + private: + const std::string mConfigFile; + const std::string mDefaultConfigFile; + const Files::ConfigurationManager& mConfigurationManager; + ShortcutManager mShortcutManager; + Collection mCategories; + Iterator mCurrentCategory; + QMutex mMutex; - void declare(); + // not implemented + State(const State&); + State& operator=(const State&); - void declareCategory (const std::string& key); + private: + void declare(); - IntSetting& declareInt (const std::string& key, const std::string& label, int default_); - DoubleSetting& declareDouble (const std::string& key, const std::string& label, double default_); + void declareCategory(const std::string& key); - BoolSetting& declareBool (const std::string& key, const std::string& label, bool default_); + IntSetting& declareInt(const std::string& key, const std::string& label, int default_); + DoubleSetting& declareDouble(const std::string& key, const std::string& label, double default_); - EnumSetting& declareEnum (const std::string& key, const std::string& label, EnumValue default_); + BoolSetting& declareBool(const std::string& key, const std::string& label, bool default_); - ColourSetting& declareColour (const std::string& key, const std::string& label, QColor default_); + EnumSetting& declareEnum(const std::string& key, const std::string& label, EnumValue default_); - ShortcutSetting& declareShortcut (const std::string& key, const std::string& label, - const QKeySequence& default_); + ColourSetting& declareColour(const std::string& key, const std::string& label, QColor default_); - StringSetting& declareString (const std::string& key, const std::string& label, std::string default_); + ShortcutSetting& declareShortcut( + const std::string& key, const std::string& label, const QKeySequence& default_); - ModifierSetting& declareModifier(const std::string& key, const std::string& label, int modifier_); + StringSetting& declareString(const std::string& key, const std::string& label, std::string default_); - void declareSeparator(); + ModifierSetting& declareModifier(const std::string& key, const std::string& label, int modifier_); - void declareSubcategory(const std::string& label); + void declareSeparator(); - void setDefault (const std::string& key, const std::string& default_); + void declareSubcategory(const std::string& label); - public: + void setDefault(const std::string& key, const std::string& default_); - State (const Files::ConfigurationManager& configurationManager); + public: + State(const Files::ConfigurationManager& configurationManager); - ~State(); + ~State(); - void save(); + void save(); - Iterator begin(); + Iterator begin(); - Iterator end(); + Iterator end(); - ShortcutManager& getShortcutManager(); + ShortcutManager& getShortcutManager(); - Category& operator[](const std::string& key); + Category& operator[](const std::string& key); - void update (const Setting& setting); + void update(const Setting& setting); - static State& get(); + static State& get(); - void resetCategory(const std::string& category); + void resetCategory(const std::string& category); - void resetAll(); + void resetAll(); - signals: + signals: - void settingChanged (const CSMPrefs::Setting *setting); + void settingChanged(const CSMPrefs::Setting* setting); }; // convenience function diff --git a/apps/opencs/model/prefs/stringsetting.cpp b/apps/opencs/model/prefs/stringsetting.cpp index 4b3b943904..2f8bf089cd 100644 --- a/apps/opencs/model/prefs/stringsetting.cpp +++ b/apps/opencs/model/prefs/stringsetting.cpp @@ -9,30 +9,33 @@ #include "category.hpp" #include "state.hpp" -CSMPrefs::StringSetting::StringSetting (Category *parent, - QMutex *mutex, const std::string& key, const std::string& label, std::string default_) -: Setting (parent, mutex, key, label), mDefault (default_), mWidget(nullptr) -{} +CSMPrefs::StringSetting::StringSetting( + Category* parent, QMutex* mutex, const std::string& key, const std::string& label, std::string default_) + : Setting(parent, mutex, key, label) + , mDefault(default_) + , mWidget(nullptr) +{ +} -CSMPrefs::StringSetting& CSMPrefs::StringSetting::setTooltip (const std::string& tooltip) +CSMPrefs::StringSetting& CSMPrefs::StringSetting::setTooltip(const std::string& tooltip) { mTooltip = tooltip; return *this; } -std::pair CSMPrefs::StringSetting::makeWidgets (QWidget *parent) +std::pair CSMPrefs::StringSetting::makeWidgets(QWidget* parent) { - mWidget = new QLineEdit (QString::fromUtf8 (mDefault.c_str()), parent); + mWidget = new QLineEdit(QString::fromUtf8(mDefault.c_str()), parent); if (!mTooltip.empty()) { - QString tooltip = QString::fromUtf8 (mTooltip.c_str()); - mWidget->setToolTip (tooltip); + QString tooltip = QString::fromUtf8(mTooltip.c_str()); + mWidget->setToolTip(tooltip); } - connect (mWidget, &QLineEdit::textChanged, this, &StringSetting::textChanged); + connect(mWidget, &QLineEdit::textChanged, this, &StringSetting::textChanged); - return std::make_pair (static_cast (nullptr), mWidget); + return std::make_pair(static_cast(nullptr), mWidget); } void CSMPrefs::StringSetting::updateWidget() @@ -43,12 +46,12 @@ void CSMPrefs::StringSetting::updateWidget() } } -void CSMPrefs::StringSetting::textChanged (const QString& text) +void CSMPrefs::StringSetting::textChanged(const QString& text) { { - QMutexLocker lock (getMutex()); - Settings::Manager::setString (getKey(), getParent()->getKey(), text.toStdString()); + QMutexLocker lock(getMutex()); + Settings::Manager::setString(getKey(), getParent()->getKey(), text.toStdString()); } - getParent()->getState()->update (*this); + getParent()->getState()->update(*this); } diff --git a/apps/opencs/model/prefs/stringsetting.hpp b/apps/opencs/model/prefs/stringsetting.hpp index d4203bce8f..275dfde3c6 100644 --- a/apps/opencs/model/prefs/stringsetting.hpp +++ b/apps/opencs/model/prefs/stringsetting.hpp @@ -9,27 +9,26 @@ namespace CSMPrefs { class StringSetting : public Setting { - Q_OBJECT + Q_OBJECT - std::string mTooltip; - std::string mDefault; - QLineEdit* mWidget; + std::string mTooltip; + std::string mDefault; + QLineEdit* mWidget; - public: + public: + StringSetting( + Category* parent, QMutex* mutex, const std::string& key, const std::string& label, std::string default_); - StringSetting (Category *parent, - QMutex *mutex, const std::string& key, const std::string& label, std::string default_); + StringSetting& setTooltip(const std::string& tooltip); - StringSetting& setTooltip (const std::string& tooltip); + /// Return label, input widget. + std::pair makeWidgets(QWidget* parent) override; - /// Return label, input widget. - std::pair makeWidgets (QWidget *parent) override; + void updateWidget() override; - void updateWidget() override; + private slots: - private slots: - - void textChanged (const QString& text); + void textChanged(const QString& text); }; } diff --git a/apps/opencs/model/tools/birthsigncheck.cpp b/apps/opencs/model/tools/birthsigncheck.cpp index f91fc22f60..e7408ab2f8 100644 --- a/apps/opencs/model/tools/birthsigncheck.cpp +++ b/apps/opencs/model/tools/birthsigncheck.cpp @@ -6,10 +6,10 @@ #include "../world/universalid.hpp" -CSMTools::BirthsignCheckStage::BirthsignCheckStage (const CSMWorld::IdCollection& birthsigns, - const CSMWorld::Resources &textures) -: mBirthsigns(birthsigns), - mTextures(textures) +CSMTools::BirthsignCheckStage::BirthsignCheckStage( + const CSMWorld::IdCollection& birthsigns, const CSMWorld::Resources& textures) + : mBirthsigns(birthsigns) + , mTextures(textures) { mIgnoreBaseRecords = false; } @@ -21,9 +21,9 @@ int CSMTools::BirthsignCheckStage::setup() return mBirthsigns.getSize(); } -void CSMTools::BirthsignCheckStage::perform (int stage, CSMDoc::Messages& messages) +void CSMTools::BirthsignCheckStage::perform(int stage, CSMDoc::Messages& messages) { - const CSMWorld::Record& record = mBirthsigns.getRecord (stage); + const CSMWorld::Record& record = mBirthsigns.getRecord(stage); // Skip "Base" records (setting!) and "Deleted" records if ((mIgnoreBaseRecords && record.mState == CSMWorld::RecordBase::State_BaseOnly) || record.isDeleted()) @@ -31,7 +31,7 @@ void CSMTools::BirthsignCheckStage::perform (int stage, CSMDoc::Messages& messag const ESM::BirthSign& birthsign = record.get(); - CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Birthsign, birthsign.mId); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Birthsign, birthsign.mId); if (birthsign.mName.empty()) messages.add(id, "Name is missing", "", CSMDoc::Message::Severity_Error); @@ -45,7 +45,7 @@ void CSMTools::BirthsignCheckStage::perform (int stage, CSMDoc::Messages& messag { std::string ddsTexture = birthsign.mTexture; if (!(Misc::ResourceHelpers::changeExtensionToDds(ddsTexture) && mTextures.searchId(ddsTexture) != -1)) - messages.add(id, "Image '" + birthsign.mTexture + "' does not exist", "", CSMDoc::Message::Severity_Error); + messages.add(id, "Image '" + birthsign.mTexture + "' does not exist", "", CSMDoc::Message::Severity_Error); } /// \todo check data members that can't be edited in the table view diff --git a/apps/opencs/model/tools/birthsigncheck.hpp b/apps/opencs/model/tools/birthsigncheck.hpp index 1d88673adc..01f12cb5f1 100644 --- a/apps/opencs/model/tools/birthsigncheck.hpp +++ b/apps/opencs/model/tools/birthsigncheck.hpp @@ -13,20 +13,19 @@ namespace CSMTools /// \brief VerifyStage: make sure that birthsign records are internally consistent class BirthsignCheckStage : public CSMDoc::Stage { - const CSMWorld::IdCollection &mBirthsigns; - const CSMWorld::Resources &mTextures; - bool mIgnoreBaseRecords; + const CSMWorld::IdCollection& mBirthsigns; + const CSMWorld::Resources& mTextures; + bool mIgnoreBaseRecords; - public: + public: + BirthsignCheckStage( + const CSMWorld::IdCollection& birthsigns, const CSMWorld::Resources& textures); - BirthsignCheckStage (const CSMWorld::IdCollection &birthsigns, - const CSMWorld::Resources &textures); + int setup() override; + ///< \return number of steps - int setup() override; - ///< \return number of steps - - void perform (int stage, CSMDoc::Messages& messages) override; - ///< Messages resulting from this tage will be appended to \a messages. + void perform(int stage, CSMDoc::Messages& messages) override; + ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/bodypartcheck.cpp b/apps/opencs/model/tools/bodypartcheck.cpp index 1490a81039..b441f5c544 100644 --- a/apps/opencs/model/tools/bodypartcheck.cpp +++ b/apps/opencs/model/tools/bodypartcheck.cpp @@ -2,13 +2,11 @@ #include "../prefs/state.hpp" -CSMTools::BodyPartCheckStage::BodyPartCheckStage( - const CSMWorld::IdCollection &bodyParts, - const CSMWorld::Resources &meshes, - const CSMWorld::IdCollection &races ) : - mBodyParts(bodyParts), - mMeshes(meshes), - mRaces(races) +CSMTools::BodyPartCheckStage::BodyPartCheckStage(const CSMWorld::IdCollection& bodyParts, + const CSMWorld::Resources& meshes, const CSMWorld::IdCollection& races) + : mBodyParts(bodyParts) + , mMeshes(meshes) + , mRaces(races) { mIgnoreBaseRecords = false; } @@ -20,37 +18,37 @@ int CSMTools::BodyPartCheckStage::setup() return mBodyParts.getSize(); } -void CSMTools::BodyPartCheckStage::perform (int stage, CSMDoc::Messages &messages) +void CSMTools::BodyPartCheckStage::perform(int stage, CSMDoc::Messages& messages) { - const CSMWorld::Record &record = mBodyParts.getRecord(stage); + const CSMWorld::Record& record = mBodyParts.getRecord(stage); // Skip "Base" records (setting!) and "Deleted" records if ((mIgnoreBaseRecords && record.mState == CSMWorld::RecordBase::State_BaseOnly) || record.isDeleted()) return; - const ESM::BodyPart &bodyPart = record.get(); + const ESM::BodyPart& bodyPart = record.get(); - CSMWorld::UniversalId id( CSMWorld::UniversalId::Type_BodyPart, bodyPart.mId ); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_BodyPart, bodyPart.mId); // Check BYDT - if (bodyPart.mData.mPart >= ESM::BodyPart::MP_Count ) + if (bodyPart.mData.mPart >= ESM::BodyPart::MP_Count) messages.add(id, "Invalid part", "", CSMDoc::Message::Severity_Error); - if (bodyPart.mData.mType > ESM::BodyPart::MT_Armor ) + if (bodyPart.mData.mType > ESM::BodyPart::MT_Armor) messages.add(id, "Invalid type", "", CSMDoc::Message::Severity_Error); // Check MODL - if ( bodyPart.mModel.empty() ) + if (bodyPart.mModel.empty()) messages.add(id, "Model is missing", "", CSMDoc::Message::Severity_Error); - else if ( mMeshes.searchId( bodyPart.mModel ) == -1 ) + else if (mMeshes.searchId(bodyPart.mModel) == -1) messages.add(id, "Model '" + bodyPart.mModel + "' does not exist", "", CSMDoc::Message::Severity_Error); // Check FNAM for skin body parts (for non-skin body parts it's meaningless) - if ( bodyPart.mData.mType == ESM::BodyPart::MT_Skin ) + if (bodyPart.mData.mType == ESM::BodyPart::MT_Skin) { - if ( bodyPart.mRace.empty() ) + if (bodyPart.mRace.empty()) messages.add(id, "Race is missing", "", CSMDoc::Message::Severity_Error); - else if ( mRaces.searchId( bodyPart.mRace ) == -1 ) + else if (mRaces.searchId(bodyPart.mRace) == -1) messages.add(id, "Race '" + bodyPart.mRace + "' does not exist", "", CSMDoc::Message::Severity_Error); } } diff --git a/apps/opencs/model/tools/bodypartcheck.hpp b/apps/opencs/model/tools/bodypartcheck.hpp index 2eba75c495..7829fd0e6c 100644 --- a/apps/opencs/model/tools/bodypartcheck.hpp +++ b/apps/opencs/model/tools/bodypartcheck.hpp @@ -4,8 +4,8 @@ #include #include -#include "../world/resources.hpp" #include "../world/idcollection.hpp" +#include "../world/resources.hpp" #include "../doc/stage.hpp" @@ -14,21 +14,19 @@ namespace CSMTools /// \brief VerifyStage: make sure that body part records are internally consistent class BodyPartCheckStage : public CSMDoc::Stage { - const CSMWorld::IdCollection &mBodyParts; - const CSMWorld::Resources &mMeshes; - const CSMWorld::IdCollection &mRaces; - bool mIgnoreBaseRecords; + const CSMWorld::IdCollection& mBodyParts; + const CSMWorld::Resources& mMeshes; + const CSMWorld::IdCollection& mRaces; + bool mIgnoreBaseRecords; public: - BodyPartCheckStage( - const CSMWorld::IdCollection &bodyParts, - const CSMWorld::Resources &meshes, - const CSMWorld::IdCollection &races ); + BodyPartCheckStage(const CSMWorld::IdCollection& bodyParts, const CSMWorld::Resources& meshes, + const CSMWorld::IdCollection& races); int setup() override; ///< \return number of steps - void perform(int stage, CSMDoc::Messages &messages) override; + void perform(int stage, CSMDoc::Messages& messages) override; ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/classcheck.cpp b/apps/opencs/model/tools/classcheck.cpp index aa64805e5d..d650e0b192 100644 --- a/apps/opencs/model/tools/classcheck.cpp +++ b/apps/opencs/model/tools/classcheck.cpp @@ -7,9 +7,8 @@ #include "../prefs/state.hpp" - -CSMTools::ClassCheckStage::ClassCheckStage (const CSMWorld::IdCollection& classes) -: mClasses (classes) +CSMTools::ClassCheckStage::ClassCheckStage(const CSMWorld::IdCollection& classes) + : mClasses(classes) { mIgnoreBaseRecords = false; } @@ -21,9 +20,9 @@ int CSMTools::ClassCheckStage::setup() return mClasses.getSize(); } -void CSMTools::ClassCheckStage::perform (int stage, CSMDoc::Messages& messages) +void CSMTools::ClassCheckStage::perform(int stage, CSMDoc::Messages& messages) { - const CSMWorld::Record& record = mClasses.getRecord (stage); + const CSMWorld::Record& record = mClasses.getRecord(stage); // Skip "Base" records (setting!) and "Deleted" records if ((mIgnoreBaseRecords && record.mState == CSMWorld::RecordBase::State_BaseOnly) || record.isDeleted()) @@ -31,7 +30,7 @@ void CSMTools::ClassCheckStage::perform (int stage, CSMDoc::Messages& messages) const ESM::Class& class_ = record.get(); - CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Class, class_.mId); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Class, class_.mId); // A class should have a name if (class_.mName.empty()) @@ -42,13 +41,13 @@ void CSMTools::ClassCheckStage::perform (int stage, CSMDoc::Messages& messages) messages.add(id, "Description of a playable class is missing", "", CSMDoc::Message::Severity_Warning); // test for invalid attributes - for (int i=0; i<2; ++i) - if (class_.mData.mAttribute[i]==-1) + for (int i = 0; i < 2; ++i) + if (class_.mData.mAttribute[i] == -1) { messages.add(id, "Attribute #" + std::to_string(i) + " is not set", "", CSMDoc::Message::Severity_Error); } - if (class_.mData.mAttribute[0]==class_.mData.mAttribute[1] && class_.mData.mAttribute[0]!=-1) + if (class_.mData.mAttribute[0] == class_.mData.mAttribute[1] && class_.mData.mAttribute[0] != -1) { messages.add(id, "Same attribute is listed twice", "", CSMDoc::Message::Severity_Error); } @@ -56,13 +55,14 @@ void CSMTools::ClassCheckStage::perform (int stage, CSMDoc::Messages& messages) // test for non-unique skill std::map skills; // ID, number of occurrences - for (int i=0; i<5; ++i) - for (int i2=0; i2<2; ++i2) + for (int i = 0; i < 5; ++i) + for (int i2 = 0; i2 < 2; ++i2) ++skills[class_.mData.mSkills[i][i2]]; - for (auto &skill : skills) - if (skill.second>1) + for (auto& skill : skills) + if (skill.second > 1) { - messages.add(id, "Skill " + ESM::Skill::indexToId (skill.first) + " is listed more than once", "", CSMDoc::Message::Severity_Error); + messages.add(id, "Skill " + ESM::Skill::indexToId(skill.first) + " is listed more than once", "", + CSMDoc::Message::Severity_Error); } } diff --git a/apps/opencs/model/tools/classcheck.hpp b/apps/opencs/model/tools/classcheck.hpp index 9d66336d43..1947fa3072 100644 --- a/apps/opencs/model/tools/classcheck.hpp +++ b/apps/opencs/model/tools/classcheck.hpp @@ -12,18 +12,17 @@ namespace CSMTools /// \brief VerifyStage: make sure that class records are internally consistent class ClassCheckStage : public CSMDoc::Stage { - const CSMWorld::IdCollection& mClasses; - bool mIgnoreBaseRecords; + const CSMWorld::IdCollection& mClasses; + bool mIgnoreBaseRecords; - public: + public: + ClassCheckStage(const CSMWorld::IdCollection& classes); - ClassCheckStage (const CSMWorld::IdCollection& classes); + int setup() override; + ///< \return number of steps - int setup() override; - ///< \return number of steps - - void perform (int stage, CSMDoc::Messages& messages) override; - ///< Messages resulting from this tage will be appended to \a messages. + void perform(int stage, CSMDoc::Messages& messages) override; + ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/enchantmentcheck.cpp b/apps/opencs/model/tools/enchantmentcheck.cpp index 28f2b32cb9..6dc82ef9aa 100644 --- a/apps/opencs/model/tools/enchantmentcheck.cpp +++ b/apps/opencs/model/tools/enchantmentcheck.cpp @@ -4,8 +4,8 @@ #include "../world/universalid.hpp" -CSMTools::EnchantmentCheckStage::EnchantmentCheckStage (const CSMWorld::IdCollection& enchantments) - : mEnchantments (enchantments) +CSMTools::EnchantmentCheckStage::EnchantmentCheckStage(const CSMWorld::IdCollection& enchantments) + : mEnchantments(enchantments) { mIgnoreBaseRecords = false; } @@ -17,9 +17,9 @@ int CSMTools::EnchantmentCheckStage::setup() return mEnchantments.getSize(); } -void CSMTools::EnchantmentCheckStage::perform (int stage, CSMDoc::Messages& messages) +void CSMTools::EnchantmentCheckStage::perform(int stage, CSMDoc::Messages& messages) { - const CSMWorld::Record& record = mEnchantments.getRecord (stage); + const CSMWorld::Record& record = mEnchantments.getRecord(stage); // Skip "Base" records (setting!) and "Deleted" records if ((mIgnoreBaseRecords && record.mState == CSMWorld::RecordBase::State_BaseOnly) || record.isDeleted()) @@ -27,7 +27,7 @@ void CSMTools::EnchantmentCheckStage::perform (int stage, CSMDoc::Messages& mess const ESM::Enchantment& enchantment = record.get(); - CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Enchantment, enchantment.mId); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Enchantment, enchantment.mId); if (enchantment.mData.mType < 0 || enchantment.mData.mType > 3) messages.add(id, "Invalid type", "", CSMDoc::Message::Severity_Error); @@ -61,9 +61,11 @@ void CSMTools::EnchantmentCheckStage::perform (int stage, CSMDoc::Messages& mess } if (effect->mSkill < -1 || effect->mSkill > 26) - messages.add(id, "Effect #" + number + " affected skill is invalid", "", CSMDoc::Message::Severity_Error); + messages.add( + id, "Effect #" + number + " affected skill is invalid", "", CSMDoc::Message::Severity_Error); if (effect->mAttribute < -1 || effect->mAttribute > 7) - messages.add(id, "Effect #" + number + " affected attribute is invalid", "", CSMDoc::Message::Severity_Error); + messages.add( + id, "Effect #" + number + " affected attribute is invalid", "", CSMDoc::Message::Severity_Error); if (effect->mRange < 0 || effect->mRange > 2) messages.add(id, "Effect #" + number + " range is invalid", "", CSMDoc::Message::Severity_Error); if (effect->mArea < 0) @@ -71,11 +73,14 @@ void CSMTools::EnchantmentCheckStage::perform (int stage, CSMDoc::Messages& mess if (effect->mDuration < 0) messages.add(id, "Effect #" + number + " duration is negative", "", CSMDoc::Message::Severity_Error); if (effect->mMagnMin < 0) - messages.add(id, "Effect #" + number + " minimum magnitude is negative", "", CSMDoc::Message::Severity_Error); + messages.add( + id, "Effect #" + number + " minimum magnitude is negative", "", CSMDoc::Message::Severity_Error); if (effect->mMagnMax < 0) - messages.add(id, "Effect #" + number + " maximum magnitude is negative", "", CSMDoc::Message::Severity_Error); + messages.add( + id, "Effect #" + number + " maximum magnitude is negative", "", CSMDoc::Message::Severity_Error); if (effect->mMagnMin > effect->mMagnMax) - messages.add(id, "Effect #" + number + " minimum magnitude is higher than maximum magnitude", "", CSMDoc::Message::Severity_Error); + messages.add(id, "Effect #" + number + " minimum magnitude is higher than maximum magnitude", "", + CSMDoc::Message::Severity_Error); ++effect; } } diff --git a/apps/opencs/model/tools/enchantmentcheck.hpp b/apps/opencs/model/tools/enchantmentcheck.hpp index 8ee71ad7cb..0d5e31f0b1 100644 --- a/apps/opencs/model/tools/enchantmentcheck.hpp +++ b/apps/opencs/model/tools/enchantmentcheck.hpp @@ -12,19 +12,17 @@ namespace CSMTools /// \brief Make sure that enchantment records are correct class EnchantmentCheckStage : public CSMDoc::Stage { - const CSMWorld::IdCollection& mEnchantments; - bool mIgnoreBaseRecords; + const CSMWorld::IdCollection& mEnchantments; + bool mIgnoreBaseRecords; - public: + public: + EnchantmentCheckStage(const CSMWorld::IdCollection& enchantments); - EnchantmentCheckStage (const CSMWorld::IdCollection& enchantments); - - int setup() override; - ///< \return number of steps - - void perform (int stage, CSMDoc::Messages& messages) override; - ///< Messages resulting from this tage will be appended to \a messages. + int setup() override; + ///< \return number of steps + void perform(int stage, CSMDoc::Messages& messages) override; + ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/factioncheck.cpp b/apps/opencs/model/tools/factioncheck.cpp index 2be59c2f9d..35fe3bd4a4 100644 --- a/apps/opencs/model/tools/factioncheck.cpp +++ b/apps/opencs/model/tools/factioncheck.cpp @@ -6,9 +6,8 @@ #include "../prefs/state.hpp" - -CSMTools::FactionCheckStage::FactionCheckStage (const CSMWorld::IdCollection& factions) -: mFactions (factions) +CSMTools::FactionCheckStage::FactionCheckStage(const CSMWorld::IdCollection& factions) + : mFactions(factions) { mIgnoreBaseRecords = false; } @@ -20,9 +19,9 @@ int CSMTools::FactionCheckStage::setup() return mFactions.getSize(); } -void CSMTools::FactionCheckStage::perform (int stage, CSMDoc::Messages& messages) +void CSMTools::FactionCheckStage::perform(int stage, CSMDoc::Messages& messages) { - const CSMWorld::Record& record = mFactions.getRecord (stage); + const CSMWorld::Record& record = mFactions.getRecord(stage); // Skip "Base" records (setting!) and "Deleted" records if ((mIgnoreBaseRecords && record.mState == CSMWorld::RecordBase::State_BaseOnly) || record.isDeleted()) @@ -30,14 +29,14 @@ void CSMTools::FactionCheckStage::perform (int stage, CSMDoc::Messages& messages const ESM::Faction& faction = record.get(); - CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Faction, faction.mId); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Faction, faction.mId); // test for empty name if (faction.mName.empty()) messages.add(id, "Name is missing", "", CSMDoc::Message::Severity_Error); // test for invalid attributes - if (faction.mData.mAttribute[0]==faction.mData.mAttribute[1] && faction.mData.mAttribute[0]!=-1) + if (faction.mData.mAttribute[0] == faction.mData.mAttribute[1] && faction.mData.mAttribute[0] != -1) { messages.add(id, "Same attribute is listed twice", "", CSMDoc::Message::Severity_Error); } @@ -45,14 +44,15 @@ void CSMTools::FactionCheckStage::perform (int stage, CSMDoc::Messages& messages // test for non-unique skill std::map skills; // ID, number of occurrences - for (int i=0; i<7; ++i) - if (faction.mData.mSkills[i]!=-1) + for (int i = 0; i < 7; ++i) + if (faction.mData.mSkills[i] != -1) ++skills[faction.mData.mSkills[i]]; - for (auto &skill : skills) - if (skill.second>1) + for (auto& skill : skills) + if (skill.second > 1) { - messages.add(id, "Skill " + ESM::Skill::indexToId (skill.first) + " is listed more than once", "", CSMDoc::Message::Severity_Error); + messages.add(id, "Skill " + ESM::Skill::indexToId(skill.first) + " is listed more than once", "", + CSMDoc::Message::Severity_Error); } /// \todo check data members that can't be edited in the table view diff --git a/apps/opencs/model/tools/factioncheck.hpp b/apps/opencs/model/tools/factioncheck.hpp index a6a6815976..bc324fc4c2 100644 --- a/apps/opencs/model/tools/factioncheck.hpp +++ b/apps/opencs/model/tools/factioncheck.hpp @@ -12,18 +12,17 @@ namespace CSMTools /// \brief VerifyStage: make sure that faction records are internally consistent class FactionCheckStage : public CSMDoc::Stage { - const CSMWorld::IdCollection& mFactions; - bool mIgnoreBaseRecords; + const CSMWorld::IdCollection& mFactions; + bool mIgnoreBaseRecords; - public: + public: + FactionCheckStage(const CSMWorld::IdCollection& factions); - FactionCheckStage (const CSMWorld::IdCollection& factions); + int setup() override; + ///< \return number of steps - int setup() override; - ///< \return number of steps - - void perform (int stage, CSMDoc::Messages& messages) override; - ///< Messages resulting from this tage will be appended to \a messages. + void perform(int stage, CSMDoc::Messages& messages) override; + ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/gmstcheck.cpp b/apps/opencs/model/tools/gmstcheck.cpp index 7cd13e5c23..cbce4f35b1 100644 --- a/apps/opencs/model/tools/gmstcheck.cpp +++ b/apps/opencs/model/tools/gmstcheck.cpp @@ -21,20 +21,20 @@ int CSMTools::GmstCheckStage::setup() void CSMTools::GmstCheckStage::perform(int stage, CSMDoc::Messages& messages) { - const CSMWorld::Record& record = mGameSettings.getRecord (stage); - + const CSMWorld::Record& record = mGameSettings.getRecord(stage); + // Skip "Base" records (setting!) and "Deleted" records if ((mIgnoreBaseRecords && record.mState == CSMWorld::RecordBase::State_BaseOnly) || record.isDeleted()) return; - + const ESM::GameSetting& gmst = record.get(); - - CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Gmst, gmst.mId); - + + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Gmst, gmst.mId); + // Test for empty string if (gmst.mValue.getType() == ESM::VT_String && gmst.mValue.getString().empty()) messages.add(id, gmst.mId + " is an empty string", "", CSMDoc::Message::Severity_Warning); - + // Checking type and limits // optimization - compare it to lists based on naming convention (f-float,i-int,s-string) if (gmst.mId[0] == 'f') @@ -47,19 +47,19 @@ void CSMTools::GmstCheckStage::perform(int stage, CSMDoc::Messages& messages) { std::ostringstream stream; stream << "Expected float type for " << gmst.mId << " but found " - << varTypeToString(gmst.mValue.getType()) << " type"; - + << varTypeToString(gmst.mValue.getType()) << " type"; + messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error); } - - if (gmst.mValue.getFloat() < CSMWorld::DefaultGmsts::FloatLimits[i*2]) - messages.add(id, gmst.mId + " is less than the suggested range", "", - CSMDoc::Message::Severity_Warning); - - if (gmst.mValue.getFloat() > CSMWorld::DefaultGmsts::FloatLimits[i*2+1]) - messages.add(id, gmst.mId + " is more than the suggested range", "", - CSMDoc::Message::Severity_Warning); - + + if (gmst.mValue.getFloat() < CSMWorld::DefaultGmsts::FloatLimits[i * 2]) + messages.add( + id, gmst.mId + " is less than the suggested range", "", CSMDoc::Message::Severity_Warning); + + if (gmst.mValue.getFloat() > CSMWorld::DefaultGmsts::FloatLimits[i * 2 + 1]) + messages.add( + id, gmst.mId + " is more than the suggested range", "", CSMDoc::Message::Severity_Warning); + break; // for loop } } @@ -67,26 +67,26 @@ void CSMTools::GmstCheckStage::perform(int stage, CSMDoc::Messages& messages) else if (gmst.mId[0] == 'i') { for (size_t i = 0; i < CSMWorld::DefaultGmsts::IntCount; ++i) - { + { if (gmst.mId == CSMWorld::DefaultGmsts::Ints[i]) { if (gmst.mValue.getType() != ESM::VT_Int) { std::ostringstream stream; stream << "Expected int type for " << gmst.mId << " but found " - << varTypeToString(gmst.mValue.getType()) << " type"; - + << varTypeToString(gmst.mValue.getType()) << " type"; + messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error); } - - if (gmst.mValue.getInteger() < CSMWorld::DefaultGmsts::IntLimits[i*2]) - messages.add(id, gmst.mId + " is less than the suggested range", "", - CSMDoc::Message::Severity_Warning); - - if (gmst.mValue.getInteger() > CSMWorld::DefaultGmsts::IntLimits[i*2+1]) - messages.add(id, gmst.mId + " is more than the suggested range", "", - CSMDoc::Message::Severity_Warning); - + + if (gmst.mValue.getInteger() < CSMWorld::DefaultGmsts::IntLimits[i * 2]) + messages.add( + id, gmst.mId + " is less than the suggested range", "", CSMDoc::Message::Severity_Warning); + + if (gmst.mValue.getInteger() > CSMWorld::DefaultGmsts::IntLimits[i * 2 + 1]) + messages.add( + id, gmst.mId + " is more than the suggested range", "", CSMDoc::Message::Severity_Warning); + break; // for loop } } @@ -98,16 +98,16 @@ void CSMTools::GmstCheckStage::perform(int stage, CSMDoc::Messages& messages) if (gmst.mId == CSMWorld::DefaultGmsts::Strings[i]) { ESM::VarType type = gmst.mValue.getType(); - + if (type != ESM::VT_String && type != ESM::VT_None) { std::ostringstream stream; stream << "Expected string or none type for " << gmst.mId << " but found " - << varTypeToString(gmst.mValue.getType()) << " type"; - + << varTypeToString(gmst.mValue.getType()) << " type"; + messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error); } - + break; // for loop } } @@ -118,13 +118,21 @@ std::string CSMTools::GmstCheckStage::varTypeToString(ESM::VarType type) { switch (type) { - case ESM::VT_Unknown: return "unknown"; - case ESM::VT_None: return "none"; - case ESM::VT_Short: return "short"; - case ESM::VT_Int: return "int"; - case ESM::VT_Long: return "long"; - case ESM::VT_Float: return "float"; - case ESM::VT_String: return "string"; - default: return "unhandled"; + case ESM::VT_Unknown: + return "unknown"; + case ESM::VT_None: + return "none"; + case ESM::VT_Short: + return "short"; + case ESM::VT_Int: + return "int"; + case ESM::VT_Long: + return "long"; + case ESM::VT_Float: + return "float"; + case ESM::VT_String: + return "string"; + default: + return "unhandled"; } } diff --git a/apps/opencs/model/tools/gmstcheck.hpp b/apps/opencs/model/tools/gmstcheck.hpp index c57f6a088b..45e8d0e0d3 100644 --- a/apps/opencs/model/tools/gmstcheck.hpp +++ b/apps/opencs/model/tools/gmstcheck.hpp @@ -13,22 +13,19 @@ namespace CSMTools class GmstCheckStage : public CSMDoc::Stage { public: - GmstCheckStage(const CSMWorld::IdCollection& gameSettings); - + int setup() override; ///< \return number of steps void perform(int stage, CSMDoc::Messages& messages) override; ///< Messages resulting from this stage will be appended to \a messages - + private: - const CSMWorld::IdCollection& mGameSettings; bool mIgnoreBaseRecords; - + std::string varTypeToString(ESM::VarType); - }; } diff --git a/apps/opencs/model/tools/journalcheck.cpp b/apps/opencs/model/tools/journalcheck.cpp index 5959cdf54b..c7f0c0df6f 100644 --- a/apps/opencs/model/tools/journalcheck.cpp +++ b/apps/opencs/model/tools/journalcheck.cpp @@ -4,9 +4,10 @@ #include "../prefs/state.hpp" -CSMTools::JournalCheckStage::JournalCheckStage(const CSMWorld::IdCollection &journals, - const CSMWorld::InfoCollection& journalInfos) - : mJournals(journals), mJournalInfos(journalInfos) +CSMTools::JournalCheckStage::JournalCheckStage( + const CSMWorld::IdCollection& journals, const CSMWorld::InfoCollection& journalInfos) + : mJournals(journals) + , mJournalInfos(journalInfos) { mIgnoreBaseRecords = false; } @@ -20,13 +21,14 @@ int CSMTools::JournalCheckStage::setup() void CSMTools::JournalCheckStage::perform(int stage, CSMDoc::Messages& messages) { - const CSMWorld::Record &journalRecord = mJournals.getRecord(stage); + const CSMWorld::Record& journalRecord = mJournals.getRecord(stage); // Skip "Base" records (setting!) and "Deleted" records - if ((mIgnoreBaseRecords && journalRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || journalRecord.isDeleted()) + if ((mIgnoreBaseRecords && journalRecord.mState == CSMWorld::RecordBase::State_BaseOnly) + || journalRecord.isDeleted()) return; - const ESM::Dialogue &journal = journalRecord.get(); + const ESM::Dialogue& journal = journalRecord.get(); int statusNamedCount = 0; int totalInfoCount = 0; std::set questIndices; @@ -65,7 +67,8 @@ void CSMTools::JournalCheckStage::perform(int stage, CSMDoc::Messages& messages) if (!result.second) { CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_JournalInfo, journalInfo.mId); - messages.add(id, "Duplicated quest index " + std::to_string(journalInfo.mData.mJournalIndex), "", CSMDoc::Message::Severity_Error); + messages.add(id, "Duplicated quest index " + std::to_string(journalInfo.mData.mJournalIndex), "", + CSMDoc::Message::Severity_Error); } } diff --git a/apps/opencs/model/tools/journalcheck.hpp b/apps/opencs/model/tools/journalcheck.hpp index 65ce8b85df..855d23092d 100644 --- a/apps/opencs/model/tools/journalcheck.hpp +++ b/apps/opencs/model/tools/journalcheck.hpp @@ -14,9 +14,8 @@ namespace CSMTools class JournalCheckStage : public CSMDoc::Stage { public: - - JournalCheckStage(const CSMWorld::IdCollection& journals, - const CSMWorld::InfoCollection& journalInfos); + JournalCheckStage( + const CSMWorld::IdCollection& journals, const CSMWorld::InfoCollection& journalInfos); int setup() override; ///< \return number of steps @@ -25,11 +24,9 @@ namespace CSMTools ///< Messages resulting from this stage will be appended to \a messages private: - const CSMWorld::IdCollection& mJournals; const CSMWorld::InfoCollection& mJournalInfos; bool mIgnoreBaseRecords; - }; } diff --git a/apps/opencs/model/tools/magiceffectcheck.cpp b/apps/opencs/model/tools/magiceffectcheck.cpp index f55fb14eea..4af4636073 100644 --- a/apps/opencs/model/tools/magiceffectcheck.cpp +++ b/apps/opencs/model/tools/magiceffectcheck.cpp @@ -4,28 +4,25 @@ #include "../prefs/state.hpp" -std::string CSMTools::MagicEffectCheckStage::checkObject(const std::string &id, - const CSMWorld::UniversalId &type, - const std::string &column) const +std::string CSMTools::MagicEffectCheckStage::checkObject( + const std::string& id, const CSMWorld::UniversalId& type, const std::string& column) const { CSMWorld::RefIdData::LocalIndex index = mObjects.getDataSet().searchId(id); - if (index.first == -1) + if (index.first == -1) return (column + " '" + id + "' does not exist"); - else if (index.second != type.getType()) + else if (index.second != type.getType()) return (column + " '" + id + "' does not have " + type.getTypeName() + " type"); return std::string(); } -CSMTools::MagicEffectCheckStage::MagicEffectCheckStage(const CSMWorld::IdCollection &effects, - const CSMWorld::IdCollection &sounds, - const CSMWorld::RefIdCollection &objects, - const CSMWorld::Resources &icons, - const CSMWorld::Resources &textures) - : mMagicEffects(effects), - mSounds(sounds), - mObjects(objects), - mIcons(icons), - mTextures(textures) +CSMTools::MagicEffectCheckStage::MagicEffectCheckStage(const CSMWorld::IdCollection& effects, + const CSMWorld::IdCollection& sounds, const CSMWorld::RefIdCollection& objects, + const CSMWorld::Resources& icons, const CSMWorld::Resources& textures) + : mMagicEffects(effects) + , mSounds(sounds) + , mObjects(objects) + , mIcons(icons) + , mTextures(textures) { mIgnoreBaseRecords = false; } @@ -37,9 +34,9 @@ int CSMTools::MagicEffectCheckStage::setup() return mMagicEffects.getSize(); } -void CSMTools::MagicEffectCheckStage::perform(int stage, CSMDoc::Messages &messages) +void CSMTools::MagicEffectCheckStage::perform(int stage, CSMDoc::Messages& messages) { - const CSMWorld::Record &record = mMagicEffects.getRecord(stage); + const CSMWorld::Record& record = mMagicEffects.getRecord(stage); // Skip "Base" records (setting!) and "Deleted" records if ((mIgnoreBaseRecords && record.mState == CSMWorld::RecordBase::State_BaseOnly) || record.isDeleted()) @@ -78,7 +75,8 @@ void CSMTools::MagicEffectCheckStage::perform(int stage, CSMDoc::Messages &messa { std::string ddsParticle = effect.mParticle; if (!(Misc::ResourceHelpers::changeExtensionToDds(ddsParticle) && mTextures.searchId(ddsParticle) != -1)) - messages.add(id, "Particle texture '" + effect.mParticle + "' does not exist", "", CSMDoc::Message::Severity_Error); + messages.add(id, "Particle texture '" + effect.mParticle + "' does not exist", "", + CSMDoc::Message::Severity_Error); } } @@ -111,7 +109,8 @@ void CSMTools::MagicEffectCheckStage::perform(int stage, CSMDoc::Messages &messa } if (!effect.mCastSound.empty() && mSounds.searchId(effect.mCastSound) == -1) - messages.add(id, "Casting sound '" + effect.mCastSound + "' does not exist", "", CSMDoc::Message::Severity_Error); + messages.add( + id, "Casting sound '" + effect.mCastSound + "' does not exist", "", CSMDoc::Message::Severity_Error); if (!effect.mHitSound.empty() && mSounds.searchId(effect.mHitSound) == -1) messages.add(id, "Hit sound '" + effect.mHitSound + "' does not exist", "", CSMDoc::Message::Severity_Error); if (!effect.mAreaSound.empty() && mSounds.searchId(effect.mAreaSound) == -1) diff --git a/apps/opencs/model/tools/magiceffectcheck.hpp b/apps/opencs/model/tools/magiceffectcheck.hpp index e264683d04..154a15dc62 100644 --- a/apps/opencs/model/tools/magiceffectcheck.hpp +++ b/apps/opencs/model/tools/magiceffectcheck.hpp @@ -15,27 +15,26 @@ namespace CSMTools /// \brief VerifyStage: make sure that magic effect records are internally consistent class MagicEffectCheckStage : public CSMDoc::Stage { - const CSMWorld::IdCollection &mMagicEffects; - const CSMWorld::IdCollection &mSounds; - const CSMWorld::RefIdCollection &mObjects; - const CSMWorld::Resources &mIcons; - const CSMWorld::Resources &mTextures; - bool mIgnoreBaseRecords; - - private: - std::string checkObject(const std::string &id, const CSMWorld::UniversalId &type, const std::string &column) const; - - public: - MagicEffectCheckStage(const CSMWorld::IdCollection &effects, - const CSMWorld::IdCollection &sounds, - const CSMWorld::RefIdCollection &objects, - const CSMWorld::Resources &icons, - const CSMWorld::Resources &textures); - - int setup() override; - ///< \return number of steps - void perform (int stage, CSMDoc::Messages &messages) override; - ///< Messages resulting from this tage will be appended to \a messages. + const CSMWorld::IdCollection& mMagicEffects; + const CSMWorld::IdCollection& mSounds; + const CSMWorld::RefIdCollection& mObjects; + const CSMWorld::Resources& mIcons; + const CSMWorld::Resources& mTextures; + bool mIgnoreBaseRecords; + + private: + std::string checkObject( + const std::string& id, const CSMWorld::UniversalId& type, const std::string& column) const; + + public: + MagicEffectCheckStage(const CSMWorld::IdCollection& effects, + const CSMWorld::IdCollection& sounds, const CSMWorld::RefIdCollection& objects, + const CSMWorld::Resources& icons, const CSMWorld::Resources& textures); + + int setup() override; + ///< \return number of steps + void perform(int stage, CSMDoc::Messages& messages) override; + ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/mandatoryid.cpp b/apps/opencs/model/tools/mandatoryid.cpp index d0d9cc0b9d..75bea2014d 100644 --- a/apps/opencs/model/tools/mandatoryid.cpp +++ b/apps/opencs/model/tools/mandatoryid.cpp @@ -4,19 +4,21 @@ #include "../world/record.hpp" -CSMTools::MandatoryIdStage::MandatoryIdStage (const CSMWorld::CollectionBase& idCollection, +CSMTools::MandatoryIdStage::MandatoryIdStage(const CSMWorld::CollectionBase& idCollection, const CSMWorld::UniversalId& collectionId, const std::vector& ids) -: mIdCollection (idCollection), mCollectionId (collectionId), mIds (ids) -{} + : mIdCollection(idCollection) + , mCollectionId(collectionId) + , mIds(ids) +{ +} int CSMTools::MandatoryIdStage::setup() { return static_cast(mIds.size()); } -void CSMTools::MandatoryIdStage::perform (int stage, CSMDoc::Messages& messages) +void CSMTools::MandatoryIdStage::perform(int stage, CSMDoc::Messages& messages) { - if (mIdCollection.searchId (mIds.at (stage))==-1 || - mIdCollection.getRecord (mIds.at (stage)).isDeleted()) - messages.add (mCollectionId, "Missing mandatory record: " + mIds.at (stage)); + if (mIdCollection.searchId(mIds.at(stage)) == -1 || mIdCollection.getRecord(mIds.at(stage)).isDeleted()) + messages.add(mCollectionId, "Missing mandatory record: " + mIds.at(stage)); } diff --git a/apps/opencs/model/tools/mandatoryid.hpp b/apps/opencs/model/tools/mandatoryid.hpp index 9d069a2da8..77de77626c 100644 --- a/apps/opencs/model/tools/mandatoryid.hpp +++ b/apps/opencs/model/tools/mandatoryid.hpp @@ -18,20 +18,19 @@ namespace CSMTools /// \brief Verify stage: make sure that records with specific IDs exist. class MandatoryIdStage : public CSMDoc::Stage { - const CSMWorld::CollectionBase& mIdCollection; - CSMWorld::UniversalId mCollectionId; - std::vector mIds; + const CSMWorld::CollectionBase& mIdCollection; + CSMWorld::UniversalId mCollectionId; + std::vector mIds; - public: + public: + MandatoryIdStage(const CSMWorld::CollectionBase& idCollection, const CSMWorld::UniversalId& collectionId, + const std::vector& ids); - MandatoryIdStage (const CSMWorld::CollectionBase& idCollection, const CSMWorld::UniversalId& collectionId, - const std::vector& ids); + int setup() override; + ///< \return number of steps - int setup() override; - ///< \return number of steps - - void perform (int stage, CSMDoc::Messages& messages) override; - ///< Messages resulting from this tage will be appended to \a messages. + void perform(int stage, CSMDoc::Messages& messages) override; + ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/mergeoperation.cpp b/apps/opencs/model/tools/mergeoperation.cpp index b15b4b83f1..8fd1232edf 100644 --- a/apps/opencs/model/tools/mergeoperation.cpp +++ b/apps/opencs/model/tools/mergeoperation.cpp @@ -1,52 +1,56 @@ #include "mergeoperation.hpp" -#include "../doc/state.hpp" #include "../doc/document.hpp" +#include "../doc/state.hpp" #include "mergestages.hpp" -CSMTools::MergeOperation::MergeOperation (CSMDoc::Document& document, ToUTF8::FromType encoding) -: CSMDoc::Operation (CSMDoc::State_Merging, true), mState (document) +CSMTools::MergeOperation::MergeOperation(CSMDoc::Document& document, ToUTF8::FromType encoding) + : CSMDoc::Operation(CSMDoc::State_Merging, true) + , mState(document) { - appendStage (new StartMergeStage (mState)); - - appendStage (new MergeIdCollectionStage (mState, &CSMWorld::Data::getGlobals)); - appendStage (new MergeIdCollectionStage (mState, &CSMWorld::Data::getGmsts)); - appendStage (new MergeIdCollectionStage (mState, &CSMWorld::Data::getSkills)); - appendStage (new MergeIdCollectionStage (mState, &CSMWorld::Data::getClasses)); - appendStage (new MergeIdCollectionStage (mState, &CSMWorld::Data::getFactions)); - appendStage (new MergeIdCollectionStage (mState, &CSMWorld::Data::getRaces)); - appendStage (new MergeIdCollectionStage (mState, &CSMWorld::Data::getSounds)); - appendStage (new MergeIdCollectionStage (mState, &CSMWorld::Data::getScripts)); - appendStage (new MergeIdCollectionStage (mState, &CSMWorld::Data::getRegions)); - appendStage (new MergeIdCollectionStage (mState, &CSMWorld::Data::getBirthsigns)); - appendStage (new MergeIdCollectionStage (mState, &CSMWorld::Data::getSpells)); - appendStage (new MergeIdCollectionStage (mState, &CSMWorld::Data::getTopics)); - appendStage (new MergeIdCollectionStage (mState, &CSMWorld::Data::getJournals)); - appendStage (new MergeIdCollectionStage (mState, &CSMWorld::Data::getCells)); - appendStage (new MergeIdCollectionStage (mState, &CSMWorld::Data::getFilters)); - appendStage (new MergeIdCollectionStage (mState, &CSMWorld::Data::getEnchantments)); - appendStage (new MergeIdCollectionStage (mState, &CSMWorld::Data::getBodyParts)); - appendStage (new MergeIdCollectionStage (mState, &CSMWorld::Data::getDebugProfiles)); - appendStage (new MergeIdCollectionStage (mState, &CSMWorld::Data::getSoundGens)); - appendStage (new MergeIdCollectionStage (mState, &CSMWorld::Data::getMagicEffects)); - appendStage (new MergeIdCollectionStage (mState, &CSMWorld::Data::getStartScripts)); - appendStage (new MergeIdCollectionStage > (mState, &CSMWorld::Data::getPathgrids)); - appendStage (new MergeIdCollectionStage (mState, &CSMWorld::Data::getTopicInfos)); - appendStage (new MergeIdCollectionStage (mState, &CSMWorld::Data::getJournalInfos)); - appendStage (new MergeRefIdsStage (mState)); - appendStage (new MergeReferencesStage (mState)); - appendStage (new MergeReferencesStage (mState)); - appendStage (new PopulateLandTexturesMergeStage (mState)); - appendStage (new MergeLandStage (mState)); - appendStage (new FixLandsAndLandTexturesMergeStage (mState)); - appendStage (new CleanupLandTexturesMergeStage (mState)); - - appendStage (new FinishMergedDocumentStage (mState, encoding)); + appendStage(new StartMergeStage(mState)); + + appendStage(new MergeIdCollectionStage(mState, &CSMWorld::Data::getGlobals)); + appendStage(new MergeIdCollectionStage(mState, &CSMWorld::Data::getGmsts)); + appendStage(new MergeIdCollectionStage(mState, &CSMWorld::Data::getSkills)); + appendStage(new MergeIdCollectionStage(mState, &CSMWorld::Data::getClasses)); + appendStage(new MergeIdCollectionStage(mState, &CSMWorld::Data::getFactions)); + appendStage(new MergeIdCollectionStage(mState, &CSMWorld::Data::getRaces)); + appendStage(new MergeIdCollectionStage(mState, &CSMWorld::Data::getSounds)); + appendStage(new MergeIdCollectionStage(mState, &CSMWorld::Data::getScripts)); + appendStage(new MergeIdCollectionStage(mState, &CSMWorld::Data::getRegions)); + appendStage(new MergeIdCollectionStage(mState, &CSMWorld::Data::getBirthsigns)); + appendStage(new MergeIdCollectionStage(mState, &CSMWorld::Data::getSpells)); + appendStage(new MergeIdCollectionStage(mState, &CSMWorld::Data::getTopics)); + appendStage(new MergeIdCollectionStage(mState, &CSMWorld::Data::getJournals)); + appendStage(new MergeIdCollectionStage(mState, &CSMWorld::Data::getCells)); + appendStage(new MergeIdCollectionStage(mState, &CSMWorld::Data::getFilters)); + appendStage(new MergeIdCollectionStage(mState, &CSMWorld::Data::getEnchantments)); + appendStage(new MergeIdCollectionStage(mState, &CSMWorld::Data::getBodyParts)); + appendStage(new MergeIdCollectionStage(mState, &CSMWorld::Data::getDebugProfiles)); + appendStage(new MergeIdCollectionStage(mState, &CSMWorld::Data::getSoundGens)); + appendStage(new MergeIdCollectionStage(mState, &CSMWorld::Data::getMagicEffects)); + appendStage(new MergeIdCollectionStage(mState, &CSMWorld::Data::getStartScripts)); + appendStage(new MergeIdCollectionStage>( + mState, &CSMWorld::Data::getPathgrids)); + appendStage( + new MergeIdCollectionStage(mState, &CSMWorld::Data::getTopicInfos)); + appendStage( + new MergeIdCollectionStage(mState, &CSMWorld::Data::getJournalInfos)); + appendStage(new MergeRefIdsStage(mState)); + appendStage(new MergeReferencesStage(mState)); + appendStage(new MergeReferencesStage(mState)); + appendStage(new PopulateLandTexturesMergeStage(mState)); + appendStage(new MergeLandStage(mState)); + appendStage(new FixLandsAndLandTexturesMergeStage(mState)); + appendStage(new CleanupLandTexturesMergeStage(mState)); + + appendStage(new FinishMergedDocumentStage(mState, encoding)); } -void CSMTools::MergeOperation::setTarget (std::unique_ptr document) +void CSMTools::MergeOperation::setTarget(std::unique_ptr document) { mState.mTarget = std::move(document); } @@ -56,5 +60,5 @@ void CSMTools::MergeOperation::operationDone() CSMDoc::Operation::operationDone(); if (mState.mCompleted) - emit mergeDone (mState.mTarget.release()); + emit mergeDone(mState.mTarget.release()); } diff --git a/apps/opencs/model/tools/mergeoperation.hpp b/apps/opencs/model/tools/mergeoperation.hpp index 427967190c..be06de47fa 100644 --- a/apps/opencs/model/tools/mergeoperation.hpp +++ b/apps/opencs/model/tools/mergeoperation.hpp @@ -18,27 +18,25 @@ namespace CSMTools { class MergeOperation : public CSMDoc::Operation { - Q_OBJECT + Q_OBJECT - MergeState mState; + MergeState mState; - public: + public: + MergeOperation(CSMDoc::Document& document, ToUTF8::FromType encoding); - MergeOperation (CSMDoc::Document& document, ToUTF8::FromType encoding); + /// \attention Do not call this function while a merge is running. + void setTarget(std::unique_ptr document); - /// \attention Do not call this function while a merge is running. - void setTarget (std::unique_ptr document); + protected slots: - protected slots: + void operationDone() override; - void operationDone() override; - - signals: - - /// \attention When this signal is emitted, *this hands over the ownership of the - /// document. This signal must be handled to avoid a leak. - void mergeDone (CSMDoc::Document *document); + signals: + /// \attention When this signal is emitted, *this hands over the ownership of the + /// document. This signal must be handled to avoid a leak. + void mergeDone(CSMDoc::Document* document); }; } diff --git a/apps/opencs/model/tools/mergestages.cpp b/apps/opencs/model/tools/mergestages.cpp index 09a0db4078..ce52ab9608 100644 --- a/apps/opencs/model/tools/mergestages.cpp +++ b/apps/opencs/model/tools/mergestages.cpp @@ -9,33 +9,34 @@ #include "../world/data.hpp" #include "../world/idtable.hpp" - -CSMTools::StartMergeStage::StartMergeStage (MergeState& state) -: mState (state) -{} +CSMTools::StartMergeStage::StartMergeStage(MergeState& state) + : mState(state) +{ +} int CSMTools::StartMergeStage::setup() { return 1; } -void CSMTools::StartMergeStage::perform (int stage, CSMDoc::Messages& messages) +void CSMTools::StartMergeStage::perform(int stage, CSMDoc::Messages& messages) { mState.mCompleted = false; mState.mTextureIndices.clear(); } - -CSMTools::FinishMergedDocumentStage::FinishMergedDocumentStage (MergeState& state, ToUTF8::FromType encoding) -: mState (state), mEncoder (encoding) -{} +CSMTools::FinishMergedDocumentStage::FinishMergedDocumentStage(MergeState& state, ToUTF8::FromType encoding) + : mState(state) + , mEncoder(encoding) +{ +} int CSMTools::FinishMergedDocumentStage::setup() { return 1; } -void CSMTools::FinishMergedDocumentStage::perform (int stage, CSMDoc::Messages& messages) +void CSMTools::FinishMergedDocumentStage::perform(int stage, CSMDoc::Messages& messages) { // We know that the content file list contains at least two entries and that the first one // does exist on disc (otherwise it would have been impossible to initiate a merge on that @@ -43,41 +44,42 @@ void CSMTools::FinishMergedDocumentStage::perform (int stage, CSMDoc::Messages& std::filesystem::path path = mState.mSource.getContentFiles()[0]; ESM::ESMReader reader; - reader.setEncoder (&mEncoder); - reader.open (path); + reader.setEncoder(&mEncoder); + reader.open(path); CSMWorld::MetaData source; source.mId = "sys::meta"; - source.load (reader); + source.load(reader); CSMWorld::MetaData target = mState.mTarget->getData().getMetaData(); target.mAuthor = source.mAuthor; target.mDescription = source.mDescription; - mState.mTarget->getData().setMetaData (target); + mState.mTarget->getData().setMetaData(target); mState.mCompleted = true; } - -CSMTools::MergeRefIdsStage::MergeRefIdsStage (MergeState& state) : mState (state) {} +CSMTools::MergeRefIdsStage::MergeRefIdsStage(MergeState& state) + : mState(state) +{ +} int CSMTools::MergeRefIdsStage::setup() { return mState.mSource.getData().getReferenceables().getSize(); } -void CSMTools::MergeRefIdsStage::perform (int stage, CSMDoc::Messages& messages) +void CSMTools::MergeRefIdsStage::perform(int stage, CSMDoc::Messages& messages) { - mState.mSource.getData().getReferenceables().copyTo ( - stage, mState.mTarget->getData().getReferenceables()); + mState.mSource.getData().getReferenceables().copyTo(stage, mState.mTarget->getData().getReferenceables()); } - -CSMTools::MergeReferencesStage::MergeReferencesStage (MergeState& state) -: mState (state) -{} +CSMTools::MergeReferencesStage::MergeReferencesStage(MergeState& state) + : mState(state) +{ +} int CSMTools::MergeReferencesStage::setup() { @@ -85,10 +87,9 @@ int CSMTools::MergeReferencesStage::setup() return mState.mSource.getData().getReferences().getSize(); } -void CSMTools::MergeReferencesStage::perform (int stage, CSMDoc::Messages& messages) +void CSMTools::MergeReferencesStage::perform(int stage, CSMDoc::Messages& messages) { - const CSMWorld::Record& record = - mState.mSource.getData().getReferences().getRecord (stage); + const CSMWorld::Record& record = mState.mSource.getData().getReferences().getRecord(stage); if (!record.isDeleted()) { @@ -96,19 +97,17 @@ void CSMTools::MergeReferencesStage::perform (int stage, CSMDoc::Messages& messa ref.mOriginalCell = ref.mCell; - ref.mRefNum.mIndex = mIndex[Misc::StringUtils::lowerCase (ref.mCell)]++; + ref.mRefNum.mIndex = mIndex[Misc::StringUtils::lowerCase(ref.mCell)]++; ref.mRefNum.mContentFile = 0; ref.mNew = false; - mState.mTarget->getData().getReferences().appendRecord ( - std::make_unique >( - CSMWorld::Record(CSMWorld::RecordBase::State_ModifiedOnly, nullptr, &ref))); + mState.mTarget->getData().getReferences().appendRecord(std::make_unique>( + CSMWorld::Record(CSMWorld::RecordBase::State_ModifiedOnly, nullptr, &ref))); } } - -CSMTools::PopulateLandTexturesMergeStage::PopulateLandTexturesMergeStage (MergeState& state) - : mState (state) +CSMTools::PopulateLandTexturesMergeStage::PopulateLandTexturesMergeStage(MergeState& state) + : mState(state) { } @@ -117,22 +116,20 @@ int CSMTools::PopulateLandTexturesMergeStage::setup() return mState.mSource.getData().getLandTextures().getSize(); } -void CSMTools::PopulateLandTexturesMergeStage::perform (int stage, CSMDoc::Messages& messages) +void CSMTools::PopulateLandTexturesMergeStage::perform(int stage, CSMDoc::Messages& messages) { - const CSMWorld::Record& record = - mState.mSource.getData().getLandTextures().getRecord (stage); + const CSMWorld::Record& record = mState.mSource.getData().getLandTextures().getRecord(stage); if (!record.isDeleted()) { mState.mTarget->getData().getLandTextures().appendRecord( - std::make_unique >( - CSMWorld::Record(CSMWorld::RecordBase::State_ModifiedOnly, nullptr, &record.get()))); + std::make_unique>(CSMWorld::Record( + CSMWorld::RecordBase::State_ModifiedOnly, nullptr, &record.get()))); } } - -CSMTools::MergeLandStage::MergeLandStage (MergeState& state) - : mState (state) +CSMTools::MergeLandStage::MergeLandStage(MergeState& state) + : mState(state) { } @@ -141,22 +138,19 @@ int CSMTools::MergeLandStage::setup() return mState.mSource.getData().getLand().getSize(); } -void CSMTools::MergeLandStage::perform (int stage, CSMDoc::Messages& messages) +void CSMTools::MergeLandStage::perform(int stage, CSMDoc::Messages& messages) { - const CSMWorld::Record& record = - mState.mSource.getData().getLand().getRecord (stage); + const CSMWorld::Record& record = mState.mSource.getData().getLand().getRecord(stage); if (!record.isDeleted()) { - mState.mTarget->getData().getLand().appendRecord ( - std::make_unique >( - CSMWorld::Record(CSMWorld::RecordBase::State_ModifiedOnly, nullptr, &record.get()))); + mState.mTarget->getData().getLand().appendRecord(std::make_unique>( + CSMWorld::Record(CSMWorld::RecordBase::State_ModifiedOnly, nullptr, &record.get()))); } } - -CSMTools::FixLandsAndLandTexturesMergeStage::FixLandsAndLandTexturesMergeStage (MergeState& state) - : mState (state) +CSMTools::FixLandsAndLandTexturesMergeStage::FixLandsAndLandTexturesMergeStage(MergeState& state) + : mState(state) { } @@ -166,7 +160,7 @@ int CSMTools::FixLandsAndLandTexturesMergeStage::setup() return mState.mSource.getData().getLand().getSize(); } -void CSMTools::FixLandsAndLandTexturesMergeStage::perform (int stage, CSMDoc::Messages& messages) +void CSMTools::FixLandsAndLandTexturesMergeStage::perform(int stage, CSMDoc::Messages& messages) { if (stage < mState.mTarget->getData().getLand().getSize()) { @@ -182,17 +176,16 @@ void CSMTools::FixLandsAndLandTexturesMergeStage::perform (int stage, CSMDoc::Me cmd.redo(); // Get rid of base data - const CSMWorld::Record& oldRecord = - mState.mTarget->getData().getLand().getRecord (stage); + const CSMWorld::Record& oldRecord = mState.mTarget->getData().getLand().getRecord(stage); - mState.mTarget->getData().getLand().setRecord (stage, - std::make_unique >( - CSMWorld::Record(CSMWorld::RecordBase::State_ModifiedOnly, nullptr, &oldRecord.get()))); + mState.mTarget->getData().getLand().setRecord(stage, + std::make_unique>( + CSMWorld::Record(CSMWorld::RecordBase::State_ModifiedOnly, nullptr, &oldRecord.get()))); } } -CSMTools::CleanupLandTexturesMergeStage::CleanupLandTexturesMergeStage (MergeState& state) - : mState (state) +CSMTools::CleanupLandTexturesMergeStage::CleanupLandTexturesMergeStage(MergeState& state) + : mState(state) { } @@ -201,10 +194,10 @@ int CSMTools::CleanupLandTexturesMergeStage::setup() return 1; } -void CSMTools::CleanupLandTexturesMergeStage::perform (int stage, CSMDoc::Messages& messages) +void CSMTools::CleanupLandTexturesMergeStage::perform(int stage, CSMDoc::Messages& messages) { auto& landTextures = mState.mTarget->getData().getLandTextures(); - for (int i = 0; i < landTextures.getSize(); ) + for (int i = 0; i < landTextures.getSize();) { if (!landTextures.getRecord(i).isModified()) landTextures.removeRows(i, 1); diff --git a/apps/opencs/model/tools/mergestages.hpp b/apps/opencs/model/tools/mergestages.hpp index 778bea7c68..13a9de2bfe 100644 --- a/apps/opencs/model/tools/mergestages.hpp +++ b/apps/opencs/model/tools/mergestages.hpp @@ -17,170 +17,164 @@ namespace CSMTools { class StartMergeStage : public CSMDoc::Stage { - MergeState& mState; + MergeState& mState; - public: + public: + StartMergeStage(MergeState& state); - StartMergeStage (MergeState& state); + int setup() override; + ///< \return number of steps - int setup() override; - ///< \return number of steps - - void perform (int stage, CSMDoc::Messages& messages) override; - ///< Messages resulting from this stage will be appended to \a messages. + void perform(int stage, CSMDoc::Messages& messages) override; + ///< Messages resulting from this stage will be appended to \a messages. }; class FinishMergedDocumentStage : public CSMDoc::Stage { - MergeState& mState; - ToUTF8::Utf8Encoder mEncoder; - - public: + MergeState& mState; + ToUTF8::Utf8Encoder mEncoder; - FinishMergedDocumentStage (MergeState& state, ToUTF8::FromType encoding); + public: + FinishMergedDocumentStage(MergeState& state, ToUTF8::FromType encoding); - int setup() override; - ///< \return number of steps + int setup() override; + ///< \return number of steps - void perform (int stage, CSMDoc::Messages& messages) override; - ///< Messages resulting from this stage will be appended to \a messages. + void perform(int stage, CSMDoc::Messages& messages) override; + ///< Messages resulting from this stage will be appended to \a messages. }; - template > + template > class MergeIdCollectionStage : public CSMDoc::Stage { - MergeState& mState; - Collection& (CSMWorld::Data::*mAccessor)(); - - public: + MergeState& mState; + Collection& (CSMWorld::Data::*mAccessor)(); - MergeIdCollectionStage (MergeState& state, Collection& (CSMWorld::Data::*accessor)()); + public: + MergeIdCollectionStage(MergeState& state, Collection& (CSMWorld::Data::*accessor)()); - int setup() override; - ///< \return number of steps + int setup() override; + ///< \return number of steps - void perform (int stage, CSMDoc::Messages& messages) override; - ///< Messages resulting from this stage will be appended to \a messages. + void perform(int stage, CSMDoc::Messages& messages) override; + ///< Messages resulting from this stage will be appended to \a messages. }; - template - MergeIdCollectionStage::MergeIdCollectionStage (MergeState& state, Collection& (CSMWorld::Data::*accessor)()) - : mState (state), mAccessor (accessor) - {} + template + MergeIdCollectionStage::MergeIdCollectionStage( + MergeState& state, Collection& (CSMWorld::Data::*accessor)()) + : mState(state) + , mAccessor(accessor) + { + } - template + template int MergeIdCollectionStage::setup() { return (mState.mSource.getData().*mAccessor)().getSize(); } - template - void MergeIdCollectionStage::perform (int stage, CSMDoc::Messages& messages) + template + void MergeIdCollectionStage::perform(int stage, CSMDoc::Messages& messages) { const Collection& source = (mState.mSource.getData().*mAccessor)(); Collection& target = (mState.mTarget->getData().*mAccessor)(); - const CSMWorld::Record& record = source.getRecord (stage); + const CSMWorld::Record& record = source.getRecord(stage); if (!record.isDeleted()) - target.appendRecord (std::make_unique >( - CSMWorld::Record(CSMWorld::RecordBase::State_ModifiedOnly, nullptr, &record.get()))); + target.appendRecord(std::make_unique>( + CSMWorld::Record(CSMWorld::RecordBase::State_ModifiedOnly, nullptr, &record.get()))); } class MergeRefIdsStage : public CSMDoc::Stage { - MergeState& mState; - - public: + MergeState& mState; - MergeRefIdsStage (MergeState& state); + public: + MergeRefIdsStage(MergeState& state); - int setup() override; - ///< \return number of steps + int setup() override; + ///< \return number of steps - void perform (int stage, CSMDoc::Messages& messages) override; - ///< Messages resulting from this stage will be appended to \a messages. + void perform(int stage, CSMDoc::Messages& messages) override; + ///< Messages resulting from this stage will be appended to \a messages. }; class MergeReferencesStage : public CSMDoc::Stage { - MergeState& mState; - std::map mIndex; + MergeState& mState; + std::map mIndex; - public: + public: + MergeReferencesStage(MergeState& state); - MergeReferencesStage (MergeState& state); + int setup() override; + ///< \return number of steps - int setup() override; - ///< \return number of steps - - void perform (int stage, CSMDoc::Messages& messages) override; - ///< Messages resulting from this stage will be appended to \a messages. + void perform(int stage, CSMDoc::Messages& messages) override; + ///< Messages resulting from this stage will be appended to \a messages. }; /// Adds all land texture records that could potentially be referenced when merging class PopulateLandTexturesMergeStage : public CSMDoc::Stage { - MergeState& mState; - - public: + MergeState& mState; - PopulateLandTexturesMergeStage (MergeState& state); + public: + PopulateLandTexturesMergeStage(MergeState& state); - int setup() override; - ///< \return number of steps + int setup() override; + ///< \return number of steps - void perform (int stage, CSMDoc::Messages& messages) override; - ///< Messages resulting from this stage will be appended to \a messages. + void perform(int stage, CSMDoc::Messages& messages) override; + ///< Messages resulting from this stage will be appended to \a messages. }; class MergeLandStage : public CSMDoc::Stage { - MergeState& mState; - - public: + MergeState& mState; - MergeLandStage (MergeState& state); + public: + MergeLandStage(MergeState& state); - int setup() override; - ///< \return number of steps + int setup() override; + ///< \return number of steps - void perform (int stage, CSMDoc::Messages& messages) override; - ///< Messages resulting from this stage will be appended to \a messages. + void perform(int stage, CSMDoc::Messages& messages) override; + ///< Messages resulting from this stage will be appended to \a messages. }; /// During this stage, the complex process of combining LandTextures from /// potentially multiple plugins is undertaken. class FixLandsAndLandTexturesMergeStage : public CSMDoc::Stage { - MergeState& mState; + MergeState& mState; - public: + public: + FixLandsAndLandTexturesMergeStage(MergeState& state); - FixLandsAndLandTexturesMergeStage (MergeState& state); + int setup() override; + ///< \return number of steps - int setup() override; - ///< \return number of steps - - void perform (int stage, CSMDoc::Messages& messages) override; - ///< Messages resulting from this stage will be appended to \a messages. + void perform(int stage, CSMDoc::Messages& messages) override; + ///< Messages resulting from this stage will be appended to \a messages. }; /// Removes base LandTexture records. This gets rid of the base records previously /// needed in FixLandsAndLandTexturesMergeStage. class CleanupLandTexturesMergeStage : public CSMDoc::Stage { - MergeState& mState; - - public: + MergeState& mState; - CleanupLandTexturesMergeStage (MergeState& state); + public: + CleanupLandTexturesMergeStage(MergeState& state); - int setup() override; - ///< \return number of steps + int setup() override; + ///< \return number of steps - void perform (int stage, CSMDoc::Messages& messages) override; - ///< Messages resulting from this stage will be appended to \a messages. + void perform(int stage, CSMDoc::Messages& messages) override; + ///< Messages resulting from this stage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/mergestate.hpp b/apps/opencs/model/tools/mergestate.hpp index a100d7a2e0..9174854be0 100644 --- a/apps/opencs/model/tools/mergestate.hpp +++ b/apps/opencs/model/tools/mergestate.hpp @@ -3,8 +3,8 @@ #include -#include #include +#include #include "../doc/document.hpp" @@ -17,7 +17,11 @@ namespace CSMTools bool mCompleted; std::map, int> mTextureIndices; // (texture, content file) -> new texture - MergeState (CSMDoc::Document& source) : mSource (source), mCompleted (false) {} + MergeState(CSMDoc::Document& source) + : mSource(source) + , mCompleted(false) + { + } }; } diff --git a/apps/opencs/model/tools/pathgridcheck.cpp b/apps/opencs/model/tools/pathgridcheck.cpp index febb79c641..fa5af03d21 100644 --- a/apps/opencs/model/tools/pathgridcheck.cpp +++ b/apps/opencs/model/tools/pathgridcheck.cpp @@ -1,17 +1,17 @@ #include "pathgridcheck.hpp" -#include #include +#include #include "../prefs/state.hpp" -#include "../world/universalid.hpp" #include "../world/idcollection.hpp" -#include "../world/subcellcollection.hpp" #include "../world/pathgrid.hpp" +#include "../world/subcellcollection.hpp" +#include "../world/universalid.hpp" -CSMTools::PathgridCheckStage::PathgridCheckStage (const CSMWorld::SubCellCollection& pathgrids) -: mPathgrids (pathgrids) +CSMTools::PathgridCheckStage::PathgridCheckStage(const CSMWorld::SubCellCollection& pathgrids) + : mPathgrids(pathgrids) { mIgnoreBaseRecords = false; } @@ -23,9 +23,9 @@ int CSMTools::PathgridCheckStage::setup() return mPathgrids.getSize(); } -void CSMTools::PathgridCheckStage::perform (int stage, CSMDoc::Messages& messages) +void CSMTools::PathgridCheckStage::perform(int stage, CSMDoc::Messages& messages) { - const CSMWorld::Record& record = mPathgrids.getRecord (stage); + const CSMWorld::Record& record = mPathgrids.getRecord(stage); // Skip "Base" records (setting!) and "Deleted" records if ((mIgnoreBaseRecords && record.mState == CSMWorld::RecordBase::State_BaseOnly) || record.isDeleted()) @@ -33,13 +33,13 @@ void CSMTools::PathgridCheckStage::perform (int stage, CSMDoc::Messages& message const CSMWorld::Pathgrid& pathgrid = record.get(); - CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Pathgrid, pathgrid.mId); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Pathgrid, pathgrid.mId); // check the number of pathgrid points if (pathgrid.mData.mS2 < static_cast(pathgrid.mPoints.size())) - messages.add (id, "Less points than expected", "", CSMDoc::Message::Severity_Error); + messages.add(id, "Less points than expected", "", CSMDoc::Message::Severity_Error); else if (pathgrid.mData.mS2 > static_cast(pathgrid.mPoints.size())) - messages.add (id, "More points than expected", "", CSMDoc::Message::Severity_Error); + messages.add(id, "More points than expected", "", CSMDoc::Message::Severity_Error); std::vector pointList(pathgrid.mPoints.size()); std::vector duplList; @@ -56,8 +56,9 @@ void CSMTools::PathgridCheckStage::perform (int stage, CSMDoc::Messages& message if (pointList[pathgrid.mEdges[i].mV0].mOtherIndex[j] == pathgrid.mEdges[i].mV1) { std::ostringstream ss; - ss << "Duplicate edge between points #" << pathgrid.mEdges[i].mV0 << " and #" << pathgrid.mEdges[i].mV1; - messages.add (id, ss.str(), "", CSMDoc::Message::Severity_Error); + ss << "Duplicate edge between points #" << pathgrid.mEdges[i].mV0 << " and #" + << pathgrid.mEdges[i].mV1; + messages.add(id, ss.str(), "", CSMDoc::Message::Severity_Error); break; } } @@ -70,7 +71,7 @@ void CSMTools::PathgridCheckStage::perform (int stage, CSMDoc::Messages& message { std::ostringstream ss; ss << "An edge is connected to a non-existent point #" << pathgrid.mEdges[i].mV0; - messages.add (id, ss.str(), "", CSMDoc::Message::Severity_Error); + messages.add(id, ss.str(), "", CSMDoc::Message::Severity_Error); } } @@ -93,7 +94,7 @@ void CSMTools::PathgridCheckStage::perform (int stage, CSMDoc::Messages& message { std::ostringstream ss; ss << "Missing edge between points #" << i << " and #" << pointList[i].mOtherIndex[j]; - messages.add (id, ss.str(), "", CSMDoc::Message::Severity_Error); + messages.add(id, ss.str(), "", CSMDoc::Message::Severity_Error); } } @@ -101,17 +102,16 @@ void CSMTools::PathgridCheckStage::perform (int stage, CSMDoc::Messages& message // FIXME: how to do this efficiently? for (unsigned int j = 0; j != i; ++j) { - if (pathgrid.mPoints[i].mX == pathgrid.mPoints[j].mX && - pathgrid.mPoints[i].mY == pathgrid.mPoints[j].mY && - pathgrid.mPoints[i].mZ == pathgrid.mPoints[j].mZ) + if (pathgrid.mPoints[i].mX == pathgrid.mPoints[j].mX && pathgrid.mPoints[i].mY == pathgrid.mPoints[j].mY + && pathgrid.mPoints[i].mZ == pathgrid.mPoints[j].mZ) { std::vector::const_iterator it = find(duplList.begin(), duplList.end(), static_cast(i)); if (it == duplList.end()) { std::ostringstream ss; - ss << "Point #" << i << " duplicates point #" << j - << " (" << pathgrid.mPoints[i].mX << ", " << pathgrid.mPoints[i].mY << ", " << pathgrid.mPoints[i].mZ << ")"; - messages.add (id, ss.str(), "", CSMDoc::Message::Severity_Warning); + ss << "Point #" << i << " duplicates point #" << j << " (" << pathgrid.mPoints[i].mX << ", " + << pathgrid.mPoints[i].mY << ", " << pathgrid.mPoints[i].mZ << ")"; + messages.add(id, ss.str(), "", CSMDoc::Message::Severity_Warning); duplList.push_back(i); break; @@ -126,11 +126,9 @@ void CSMTools::PathgridCheckStage::perform (int stage, CSMDoc::Messages& message if (pointList[i].mConnectionNum == 0) { std::ostringstream ss; - ss << "Point #" << i << " (" - << pathgrid.mPoints[i].mX << ", " - << pathgrid.mPoints[i].mY << ", " - << pathgrid.mPoints[i].mZ << ") is disconnected from other points"; - messages.add (id, ss.str(), "", CSMDoc::Message::Severity_Warning); + ss << "Point #" << i << " (" << pathgrid.mPoints[i].mX << ", " << pathgrid.mPoints[i].mY << ", " + << pathgrid.mPoints[i].mZ << ") is disconnected from other points"; + messages.add(id, ss.str(), "", CSMDoc::Message::Severity_Warning); } } diff --git a/apps/opencs/model/tools/pathgridcheck.hpp b/apps/opencs/model/tools/pathgridcheck.hpp index 212637fd42..f7b280fe5b 100644 --- a/apps/opencs/model/tools/pathgridcheck.hpp +++ b/apps/opencs/model/tools/pathgridcheck.hpp @@ -8,7 +8,7 @@ namespace CSMWorld { struct Pathgrid; - template + template class SubCellCollection; } @@ -18,23 +18,25 @@ namespace CSMTools { unsigned char mConnectionNum; std::vector mOtherIndex; - Point() : mConnectionNum(0), mOtherIndex(0) {} + Point() + : mConnectionNum(0) + , mOtherIndex(0) + { + } }; class PathgridCheckStage : public CSMDoc::Stage { - const CSMWorld::SubCellCollection >& mPathgrids; + const CSMWorld::SubCellCollection>& mPathgrids; bool mIgnoreBaseRecords; public: - - PathgridCheckStage (const CSMWorld::SubCellCollection >& pathgrids); + PathgridCheckStage( + const CSMWorld::SubCellCollection>& pathgrids); int setup() override; - void perform (int stage, CSMDoc::Messages& messages) override; + void perform(int stage, CSMDoc::Messages& messages) override; }; } diff --git a/apps/opencs/model/tools/racecheck.cpp b/apps/opencs/model/tools/racecheck.cpp index 6585a31ccb..5fceeaa2e4 100644 --- a/apps/opencs/model/tools/racecheck.cpp +++ b/apps/opencs/model/tools/racecheck.cpp @@ -4,9 +4,9 @@ #include "../world/universalid.hpp" -void CSMTools::RaceCheckStage::performPerRecord (int stage, CSMDoc::Messages& messages) +void CSMTools::RaceCheckStage::performPerRecord(int stage, CSMDoc::Messages& messages) { - const CSMWorld::Record& record = mRaces.getRecord (stage); + const CSMWorld::Record& record = mRaces.getRecord(stage); if (record.isDeleted()) return; @@ -21,42 +21,44 @@ void CSMTools::RaceCheckStage::performPerRecord (int stage, CSMDoc::Messages& me if (mIgnoreBaseRecords && record.mState == CSMWorld::RecordBase::State_BaseOnly) return; - CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Race, race.mId); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Race, race.mId); // test for empty name and description if (race.mName.empty()) - messages.add(id, "Name is missing", "", (race.mData.mFlags & 0x1) ? CSMDoc::Message::Severity_Error : CSMDoc::Message::Severity_Warning); + messages.add(id, "Name is missing", "", + (race.mData.mFlags & 0x1) ? CSMDoc::Message::Severity_Error : CSMDoc::Message::Severity_Warning); if (race.mDescription.empty()) messages.add(id, "Description is missing", "", CSMDoc::Message::Severity_Warning); // test for positive height - if (race.mData.mHeight.mMale<=0) + if (race.mData.mHeight.mMale <= 0) messages.add(id, "Male height is non-positive", "", CSMDoc::Message::Severity_Error); - if (race.mData.mHeight.mFemale<=0) + if (race.mData.mHeight.mFemale <= 0) messages.add(id, "Female height is non-positive", "", CSMDoc::Message::Severity_Error); // test for non-negative weight - if (race.mData.mWeight.mMale<0) + if (race.mData.mWeight.mMale < 0) messages.add(id, "Male weight is negative", "", CSMDoc::Message::Severity_Error); - if (race.mData.mWeight.mFemale<0) + if (race.mData.mWeight.mFemale < 0) messages.add(id, "Female weight is negative", "", CSMDoc::Message::Severity_Error); /// \todo check data members that can't be edited in the table view } -void CSMTools::RaceCheckStage::performFinal (CSMDoc::Messages& messages) +void CSMTools::RaceCheckStage::performFinal(CSMDoc::Messages& messages) { - CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Races); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Races); if (!mPlayable) messages.add(id, "No playable race", "", CSMDoc::Message::Severity_SeriousError); } -CSMTools::RaceCheckStage::RaceCheckStage (const CSMWorld::IdCollection& races) -: mRaces (races), mPlayable (false) +CSMTools::RaceCheckStage::RaceCheckStage(const CSMWorld::IdCollection& races) + : mRaces(races) + , mPlayable(false) { mIgnoreBaseRecords = false; } @@ -66,13 +68,13 @@ int CSMTools::RaceCheckStage::setup() mPlayable = false; mIgnoreBaseRecords = CSMPrefs::get()["Reports"]["ignore-base-records"].isTrue(); - return mRaces.getSize()+1; + return mRaces.getSize() + 1; } -void CSMTools::RaceCheckStage::perform (int stage, CSMDoc::Messages& messages) +void CSMTools::RaceCheckStage::perform(int stage, CSMDoc::Messages& messages) { - if (stage==mRaces.getSize()) - performFinal (messages); + if (stage == mRaces.getSize()) + performFinal(messages); else - performPerRecord (stage, messages); + performPerRecord(stage, messages); } diff --git a/apps/opencs/model/tools/racecheck.hpp b/apps/opencs/model/tools/racecheck.hpp index fe08f4bb67..e80f7c12d5 100644 --- a/apps/opencs/model/tools/racecheck.hpp +++ b/apps/opencs/model/tools/racecheck.hpp @@ -12,23 +12,22 @@ namespace CSMTools /// \brief VerifyStage: make sure that race records are internally consistent class RaceCheckStage : public CSMDoc::Stage { - const CSMWorld::IdCollection& mRaces; - bool mPlayable; - bool mIgnoreBaseRecords; + const CSMWorld::IdCollection& mRaces; + bool mPlayable; + bool mIgnoreBaseRecords; - void performPerRecord (int stage, CSMDoc::Messages& messages); + void performPerRecord(int stage, CSMDoc::Messages& messages); - void performFinal (CSMDoc::Messages& messages); + void performFinal(CSMDoc::Messages& messages); - public: + public: + RaceCheckStage(const CSMWorld::IdCollection& races); - RaceCheckStage (const CSMWorld::IdCollection& races); + int setup() override; + ///< \return number of steps - int setup() override; - ///< \return number of steps - - void perform (int stage, CSMDoc::Messages& messages) override; - ///< Messages resulting from this tage will be appended to \a messages. + void perform(int stage, CSMDoc::Messages& messages) override; + ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 3816d1a0a4..d95357bc5a 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -1,37 +1,34 @@ #include "referenceablecheck.hpp" -#include #include +#include #include "../prefs/state.hpp" #include "../world/record.hpp" #include "../world/universalid.hpp" -CSMTools::ReferenceableCheckStage::ReferenceableCheckStage( - const CSMWorld::RefIdData& referenceable, const CSMWorld::IdCollection& races, - const CSMWorld::IdCollection& classes, - const CSMWorld::IdCollection& faction, - const CSMWorld::IdCollection& scripts, - const CSMWorld::Resources& models, - const CSMWorld::Resources& icons, +CSMTools::ReferenceableCheckStage::ReferenceableCheckStage(const CSMWorld::RefIdData& referenceable, + const CSMWorld::IdCollection& races, const CSMWorld::IdCollection& classes, + const CSMWorld::IdCollection& faction, const CSMWorld::IdCollection& scripts, + const CSMWorld::Resources& models, const CSMWorld::Resources& icons, const CSMWorld::IdCollection& bodyparts) - :mReferencables(referenceable), - mRaces(races), - mClasses(classes), - mFactions(faction), - mScripts(scripts), - mModels(models), - mIcons(icons), - mBodyParts(bodyparts), - mPlayerPresent(false) + : mReferencables(referenceable) + , mRaces(races) + , mClasses(classes) + , mFactions(faction) + , mScripts(scripts) + , mModels(models) + , mIcons(icons) + , mBodyParts(bodyparts) + , mPlayerPresent(false) { mIgnoreBaseRecords = false; } -void CSMTools::ReferenceableCheckStage::perform (int stage, CSMDoc::Messages& messages) +void CSMTools::ReferenceableCheckStage::perform(int stage, CSMDoc::Messages& messages) { - //Checks for books, than, when stage is above mBooksSize goes to other checks, with (stage - PrevSum) as stage. + // Checks for books, than, when stage is above mBooksSize goes to other checks, with (stage - PrevSum) as stage. const int bookSize(mReferencables.getBooks().getSize()); if (stage < bookSize) @@ -229,7 +226,7 @@ void CSMTools::ReferenceableCheckStage::perform (int stage, CSMDoc::Messages& me creatureCheck(stage, mReferencables.getCreatures(), messages); return; } -// if we come that far, we are about to perform our last, final check. + // if we come that far, we are about to perform our last, final check. finalCheck(messages); return; } @@ -243,9 +240,7 @@ int CSMTools::ReferenceableCheckStage::setup() } void CSMTools::ReferenceableCheckStage::bookCheck( - int stage, - const CSMWorld::RefIdDataContainer< ESM::Book >& records, - CSMDoc::Messages& messages) + int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages) { const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); @@ -253,7 +248,7 @@ void CSMTools::ReferenceableCheckStage::bookCheck( if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted()) return; - const ESM::Book& book = (dynamic_cast& >(baseRecord)).get(); + const ESM::Book& book = (dynamic_cast&>(baseRecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Book, book.mId); inventoryItemCheck(book, messages, id.toString(), true); @@ -263,9 +258,7 @@ void CSMTools::ReferenceableCheckStage::bookCheck( } void CSMTools::ReferenceableCheckStage::activatorCheck( - int stage, - const CSMWorld::RefIdDataContainer< ESM::Activator >& records, - CSMDoc::Messages& messages) + int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages) { const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); @@ -273,7 +266,7 @@ void CSMTools::ReferenceableCheckStage::activatorCheck( if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted()) return; - const ESM::Activator& activator = (dynamic_cast& >(baseRecord)).get(); + const ESM::Activator& activator = (dynamic_cast&>(baseRecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Activator, activator.mId); if (activator.mModel.empty()) @@ -286,9 +279,7 @@ void CSMTools::ReferenceableCheckStage::activatorCheck( } void CSMTools::ReferenceableCheckStage::potionCheck( - int stage, - const CSMWorld::RefIdDataContainer< ESM::Potion >& records, - CSMDoc::Messages& messages) + int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages) { const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); @@ -296,7 +287,7 @@ void CSMTools::ReferenceableCheckStage::potionCheck( if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted()) return; - const ESM::Potion& potion = (dynamic_cast& >(baseRecord)).get(); + const ESM::Potion& potion = (dynamic_cast&>(baseRecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Potion, potion.mId); inventoryItemCheck(potion, messages, id.toString()); @@ -306,11 +297,8 @@ void CSMTools::ReferenceableCheckStage::potionCheck( scriptCheck(potion, messages, id.toString()); } - void CSMTools::ReferenceableCheckStage::apparatusCheck( - int stage, - const CSMWorld::RefIdDataContainer< ESM::Apparatus >& records, - CSMDoc::Messages& messages) + int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages) { const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); @@ -318,7 +306,7 @@ void CSMTools::ReferenceableCheckStage::apparatusCheck( if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted()) return; - const ESM::Apparatus& apparatus = (dynamic_cast& >(baseRecord)).get(); + const ESM::Apparatus& apparatus = (dynamic_cast&>(baseRecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Apparatus, apparatus.mId); inventoryItemCheck(apparatus, messages, id.toString()); @@ -330,9 +318,7 @@ void CSMTools::ReferenceableCheckStage::apparatusCheck( } void CSMTools::ReferenceableCheckStage::armorCheck( - int stage, - const CSMWorld::RefIdDataContainer< ESM::Armor >& records, - CSMDoc::Messages& messages) + int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages) { const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); @@ -340,7 +326,7 @@ void CSMTools::ReferenceableCheckStage::armorCheck( if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted()) return; - const ESM::Armor& armor = (dynamic_cast& >(baseRecord)).get(); + const ESM::Armor& armor = (dynamic_cast&>(baseRecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Armor, armor.mId); inventoryItemCheck(armor, messages, id.toString(), true); @@ -358,9 +344,7 @@ void CSMTools::ReferenceableCheckStage::armorCheck( } void CSMTools::ReferenceableCheckStage::clothingCheck( - int stage, - const CSMWorld::RefIdDataContainer< ESM::Clothing >& records, - CSMDoc::Messages& messages) + int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages) { const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); @@ -368,7 +352,7 @@ void CSMTools::ReferenceableCheckStage::clothingCheck( if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted()) return; - const ESM::Clothing& clothing = (dynamic_cast& >(baseRecord)).get(); + const ESM::Clothing& clothing = (dynamic_cast&>(baseRecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Clothing, clothing.mId); inventoryItemCheck(clothing, messages, id.toString(), true); @@ -377,9 +361,7 @@ void CSMTools::ReferenceableCheckStage::clothingCheck( } void CSMTools::ReferenceableCheckStage::containerCheck( - int stage, - const CSMWorld::RefIdDataContainer< ESM::Container >& records, - CSMDoc::Messages& messages) + int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages) { const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); @@ -387,33 +369,32 @@ void CSMTools::ReferenceableCheckStage::containerCheck( if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted()) return; - const ESM::Container& container = (dynamic_cast& >(baseRecord)).get(); + const ESM::Container& container = (dynamic_cast&>(baseRecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Container, container.mId); - //checking for name + // checking for name if (container.mName.empty()) messages.add(id, "Name is missing", "", CSMDoc::Message::Severity_Error); - //Checking for model + // Checking for model if (container.mModel.empty()) messages.add(id, "Model is missing", "", CSMDoc::Message::Severity_Error); else if (mModels.searchId(container.mModel) == -1) messages.add(id, "Model '" + container.mModel + "' does not exist", "", CSMDoc::Message::Severity_Error); - //Checking for capacity (weight) - if (container.mWeight < 0) //0 is allowed + // Checking for capacity (weight) + if (container.mWeight < 0) // 0 is allowed messages.add(id, "Capacity is negative", "", CSMDoc::Message::Severity_Error); - - //checking contained items + + // checking contained items inventoryListCheck(container.mInventory.mList, messages, id.toString()); // Check that mentioned scripts exist scriptCheck(container, messages, id.toString()); } -void CSMTools::ReferenceableCheckStage::creatureCheck ( - int stage, const CSMWorld::RefIdDataContainer< ESM::Creature >& records, - CSMDoc::Messages& messages) +void CSMTools::ReferenceableCheckStage::creatureCheck( + int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages) { const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); @@ -432,7 +413,7 @@ void CSMTools::ReferenceableCheckStage::creatureCheck ( else if (mModels.searchId(creature.mModel) == -1) messages.add(id, "Model '" + creature.mModel + "' does not exist", "", CSMDoc::Message::Severity_Error); - //stats checks + // stats checks if (creature.mData.mLevel <= 0) messages.add(id, "Level is non-positive", "", CSMDoc::Message::Severity_Warning); @@ -480,9 +461,13 @@ void CSMTools::ReferenceableCheckStage::creatureCheck ( for (int i = 0; i < 6; ++i) { if (creature.mData.mAttack[i] < 0) - messages.add(id, "Attack " + std::to_string(i/2 + 1) + " has negative" + (i % 2 == 0 ? " minimum " : " maximum ") + "damage", "", CSMDoc::Message::Severity_Error); - if (i % 2 == 0 && creature.mData.mAttack[i] > creature.mData.mAttack[i+1]) - messages.add(id, "Attack " + std::to_string(i/2 + 1) + " has minimum damage higher than maximum damage", "", CSMDoc::Message::Severity_Error); + messages.add(id, + "Attack " + std::to_string(i / 2 + 1) + " has negative" + (i % 2 == 0 ? " minimum " : " maximum ") + + "damage", + "", CSMDoc::Message::Severity_Error); + if (i % 2 == 0 && creature.mData.mAttack[i] > creature.mData.mAttack[i + 1]) + messages.add(id, "Attack " + std::to_string(i / 2 + 1) + " has minimum damage higher than maximum damage", + "", CSMDoc::Message::Severity_Error); } if (creature.mData.mGold < 0) @@ -495,22 +480,22 @@ void CSMTools::ReferenceableCheckStage::creatureCheck ( { CSMWorld::RefIdData::LocalIndex index = mReferencables.searchId(creature.mOriginal); if (index.first == -1) - messages.add(id, "Parent creature '" + creature.mOriginal + "' does not exist", "", CSMDoc::Message::Severity_Error); + messages.add( + id, "Parent creature '" + creature.mOriginal + "' does not exist", "", CSMDoc::Message::Severity_Error); else if (index.second != CSMWorld::UniversalId::Type_Creature) messages.add(id, "'" + creature.mOriginal + "' is not a creature", "", CSMDoc::Message::Severity_Error); } // Check inventory inventoryListCheck(creature.mInventory.mList, messages, id.toString()); - + // Check that mentioned scripts exist scriptCheck(creature, messages, id.toString()); /// \todo Check spells, teleport table, AI data and AI packages for validity } void CSMTools::ReferenceableCheckStage::doorCheck( - int stage, const CSMWorld::RefIdDataContainer< ESM::Door >& records, - CSMDoc::Messages& messages) + int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages) { const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); @@ -521,7 +506,7 @@ void CSMTools::ReferenceableCheckStage::doorCheck( const ESM::Door& door = (dynamic_cast&>(baseRecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Door, door.mId); - //usual, name or model + // usual, name or model if (door.mName.empty()) messages.add(id, "Name is missing", "", CSMDoc::Message::Severity_Error); @@ -535,9 +520,7 @@ void CSMTools::ReferenceableCheckStage::doorCheck( } void CSMTools::ReferenceableCheckStage::ingredientCheck( - int stage, - const CSMWorld::RefIdDataContainer< ESM::Ingredient >& records, - CSMDoc::Messages& messages) + int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages) { const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); @@ -545,7 +528,7 @@ void CSMTools::ReferenceableCheckStage::ingredientCheck( if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted()) return; - const ESM::Ingredient& ingredient = (dynamic_cast& >(baseRecord)).get(); + const ESM::Ingredient& ingredient = (dynamic_cast&>(baseRecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Ingredient, ingredient.mId); inventoryItemCheck(ingredient, messages, id.toString()); @@ -555,9 +538,7 @@ void CSMTools::ReferenceableCheckStage::ingredientCheck( } void CSMTools::ReferenceableCheckStage::creaturesLevListCheck( - int stage, - const CSMWorld::RefIdDataContainer< ESM::CreatureLevList >& records, - CSMDoc::Messages& messages) + int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages) { const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); @@ -565,16 +546,16 @@ void CSMTools::ReferenceableCheckStage::creaturesLevListCheck( if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted()) return; - const ESM::CreatureLevList& CreatureLevList = (dynamic_cast& >(baseRecord)).get(); - CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_CreatureLevelledList, CreatureLevList.mId); //CreatureLevList but Type_CreatureLevelledList :/ + const ESM::CreatureLevList& CreatureLevList + = (dynamic_cast&>(baseRecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_CreatureLevelledList, + CreatureLevList.mId); // CreatureLevList but Type_CreatureLevelledList :/ listCheck(CreatureLevList, messages, id.toString()); } void CSMTools::ReferenceableCheckStage::itemLevelledListCheck( - int stage, - const CSMWorld::RefIdDataContainer< ESM::ItemLevList >& records, - CSMDoc::Messages& messages) + int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages) { const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); @@ -582,15 +563,14 @@ void CSMTools::ReferenceableCheckStage::itemLevelledListCheck( if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted()) return; - const ESM::ItemLevList& ItemLevList = (dynamic_cast& >(baseRecord)).get(); + const ESM::ItemLevList& ItemLevList = (dynamic_cast&>(baseRecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_ItemLevelledList, ItemLevList.mId); listCheck(ItemLevList, messages, id.toString()); } void CSMTools::ReferenceableCheckStage::lightCheck( - int stage, const CSMWorld::RefIdDataContainer< ESM::Light >& records, - CSMDoc::Messages& messages) + int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages) { const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); @@ -598,7 +578,7 @@ void CSMTools::ReferenceableCheckStage::lightCheck( if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted()) return; - const ESM::Light& light = (dynamic_cast& >(baseRecord)).get(); + const ESM::Light& light = (dynamic_cast&>(baseRecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Light, light.mId); if (light.mData.mRadius < 0) @@ -612,9 +592,7 @@ void CSMTools::ReferenceableCheckStage::lightCheck( } void CSMTools::ReferenceableCheckStage::lockpickCheck( - int stage, - const CSMWorld::RefIdDataContainer< ESM::Lockpick >& records, - CSMDoc::Messages& messages) + int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages) { const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); @@ -622,7 +600,7 @@ void CSMTools::ReferenceableCheckStage::lockpickCheck( if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted()) return; - const ESM::Lockpick& lockpick = (dynamic_cast& >(baseRecord)).get(); + const ESM::Lockpick& lockpick = (dynamic_cast&>(baseRecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Lockpick, lockpick.mId); inventoryItemCheck(lockpick, messages, id.toString()); @@ -634,9 +612,7 @@ void CSMTools::ReferenceableCheckStage::lockpickCheck( } void CSMTools::ReferenceableCheckStage::miscCheck( - int stage, - const CSMWorld::RefIdDataContainer< ESM::Miscellaneous >& records, - CSMDoc::Messages& messages) + int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages) { const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); @@ -644,7 +620,8 @@ void CSMTools::ReferenceableCheckStage::miscCheck( if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted()) return; - const ESM::Miscellaneous& miscellaneous = (dynamic_cast& >(baseRecord)).get(); + const ESM::Miscellaneous& miscellaneous + = (dynamic_cast&>(baseRecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Miscellaneous, miscellaneous.mId); inventoryItemCheck(miscellaneous, messages, id.toString()); @@ -653,20 +630,19 @@ void CSMTools::ReferenceableCheckStage::miscCheck( scriptCheck(miscellaneous, messages, id.toString()); } -void CSMTools::ReferenceableCheckStage::npcCheck ( - int stage, const CSMWorld::RefIdDataContainer< ESM::NPC >& records, - CSMDoc::Messages& messages) +void CSMTools::ReferenceableCheckStage::npcCheck( + int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages) { const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); if (baseRecord.isDeleted()) return; - const ESM::NPC& npc = (dynamic_cast& >(baseRecord)).get(); - CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Npc, npc.mId); + const ESM::NPC& npc = (dynamic_cast&>(baseRecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Npc, npc.mId); - //Detect if player is present - if (Misc::StringUtils::ciEqual(npc.mId, "player")) //Happy now, scrawl? + // Detect if player is present + if (Misc::StringUtils::ciEqual(npc.mId, "player")) // Happy now, scrawl? mPlayerPresent = true; // Skip "Base" records (setting!) @@ -676,11 +652,12 @@ void CSMTools::ReferenceableCheckStage::npcCheck ( short level(npc.mNpdt.mLevel); int gold(npc.mNpdt.mGold); - 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) //0x0010 = autocalculated flag + if ((npc.mFlags & ESM::NPC::Autocalc) == 0) // 0x0010 = autocalculated flag { - messages.add(id, "NPC with autocalculated stats doesn't have autocalc flag turned on", "", CSMDoc::Message::Severity_Error); //should not happen? + messages.add(id, "NPC with autocalculated stats doesn't have autocalc flag turned on", "", + CSMDoc::Message::Severity_Error); // should not happen? return; } } @@ -722,12 +699,12 @@ void CSMTools::ReferenceableCheckStage::npcCheck ( if (npc.mClass.empty()) messages.add(id, "Class is missing", "", CSMDoc::Message::Severity_Error); - else if (mClasses.searchId (npc.mClass) == -1) + else if (mClasses.searchId(npc.mClass) == -1) messages.add(id, "Class '" + npc.mClass + "' does not exist", "", CSMDoc::Message::Severity_Error); if (npc.mRace.empty()) messages.add(id, "Race is missing", "", CSMDoc::Message::Severity_Error); - else if (mRaces.searchId (npc.mRace) == -1) + else if (mRaces.searchId(npc.mRace) == -1) messages.add(id, "Race '" + npc.mRace + "' does not exist", "", CSMDoc::Message::Severity_Error); if (!npc.mFaction.empty() && mFactions.searchId(npc.mFaction) == -1) @@ -753,60 +730,43 @@ void CSMTools::ReferenceableCheckStage::npcCheck ( // Check inventory inventoryListCheck(npc.mInventory.mList, messages, id.toString()); - + // Check that mentioned scripts exist scriptCheck(npc, messages, id.toString()); } void CSMTools::ReferenceableCheckStage::weaponCheck( - int stage, const CSMWorld::RefIdDataContainer< ESM::Weapon >& records, - CSMDoc::Messages& messages) + int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages) { - const CSMWorld::RecordBase& baseRecord = records.getRecord (stage); + const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); // Skip "Base" records (setting!) and "Deleted" records if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted()) return; - const ESM::Weapon& weapon = (dynamic_cast& >(baseRecord)).get(); - CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Weapon, weapon.mId); - - //TODO, It seems that this stuff for spellcasting is obligatory and In fact We should check if records are present - if - ( //THOSE ARE HARDCODED! - !(weapon.mId == "VFX_Hands" || - weapon.mId == "VFX_Absorb" || - weapon.mId == "VFX_Reflect" || - weapon.mId == "VFX_DefaultBolt" || - //TODO I don't know how to get full list of effects :/ - //DANGER!, ACHTUNG! FIXME! The following is the list of the magical bolts, valid for Morrowind.esm. However those are not hardcoded. - weapon.mId == "magic_bolt" || - weapon.mId == "shock_bolt" || - weapon.mId == "shield_bolt" || - weapon.mId == "VFX_DestructBolt" || - weapon.mId == "VFX_PoisonBolt" || - weapon.mId == "VFX_RestoreBolt" || - weapon.mId == "VFX_AlterationBolt" || - weapon.mId == "VFX_ConjureBolt" || - weapon.mId == "VFX_FrostBolt" || - weapon.mId == "VFX_MysticismBolt" || - weapon.mId == "VFX_IllusionBolt" || - weapon.mId == "VFX_Multiple2" || - weapon.mId == "VFX_Multiple3" || - weapon.mId == "VFX_Multiple4" || - weapon.mId == "VFX_Multiple5" || - weapon.mId == "VFX_Multiple6" || - weapon.mId == "VFX_Multiple7" || - weapon.mId == "VFX_Multiple8" || - weapon.mId == "VFX_Multiple9")) + const ESM::Weapon& weapon = (dynamic_cast&>(baseRecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Weapon, weapon.mId); + + // TODO, It seems that this stuff for spellcasting is obligatory and In fact We should check if records are present + if ( // THOSE ARE HARDCODED! + !(weapon.mId == "VFX_Hands" || weapon.mId == "VFX_Absorb" || weapon.mId == "VFX_Reflect" + || weapon.mId == "VFX_DefaultBolt" || + // TODO I don't know how to get full list of effects :/ + // DANGER!, ACHTUNG! FIXME! The following is the list of the magical bolts, valid for Morrowind.esm. However + // those are not hardcoded. + weapon.mId == "magic_bolt" || weapon.mId == "shock_bolt" || weapon.mId == "shield_bolt" + || weapon.mId == "VFX_DestructBolt" || weapon.mId == "VFX_PoisonBolt" || weapon.mId == "VFX_RestoreBolt" + || weapon.mId == "VFX_AlterationBolt" || weapon.mId == "VFX_ConjureBolt" || weapon.mId == "VFX_FrostBolt" + || weapon.mId == "VFX_MysticismBolt" || weapon.mId == "VFX_IllusionBolt" || weapon.mId == "VFX_Multiple2" + || weapon.mId == "VFX_Multiple3" || weapon.mId == "VFX_Multiple4" || weapon.mId == "VFX_Multiple5" + || weapon.mId == "VFX_Multiple6" || weapon.mId == "VFX_Multiple7" || weapon.mId == "VFX_Multiple8" + || weapon.mId == "VFX_Multiple9")) { inventoryItemCheck(weapon, messages, id.toString(), true); - if (!(weapon.mData.mType == ESM::Weapon::MarksmanBow || - weapon.mData.mType == ESM::Weapon::MarksmanCrossbow || - weapon.mData.mType == ESM::Weapon::MarksmanThrown || - weapon.mData.mType == ESM::Weapon::Arrow || - weapon.mData.mType == ESM::Weapon::Bolt)) + if (!(weapon.mData.mType == ESM::Weapon::MarksmanBow || weapon.mData.mType == ESM::Weapon::MarksmanCrossbow + || weapon.mData.mType == ESM::Weapon::MarksmanThrown || weapon.mData.mType == ESM::Weapon::Arrow + || weapon.mData.mType == ESM::Weapon::Bolt)) { if (weapon.mData.mSlash[0] > weapon.mData.mSlash[1]) messages.add(id, "Minimum slash damage higher than maximum", "", CSMDoc::Message::Severity_Warning); @@ -818,11 +778,10 @@ void CSMTools::ReferenceableCheckStage::weaponCheck( if (weapon.mData.mChop[0] > weapon.mData.mChop[1]) messages.add(id, "Minimum chop damage higher than maximum", "", CSMDoc::Message::Severity_Warning); - if (!(weapon.mData.mType == ESM::Weapon::Arrow || - weapon.mData.mType == ESM::Weapon::Bolt || - weapon.mData.mType == ESM::Weapon::MarksmanThrown)) + if (!(weapon.mData.mType == ESM::Weapon::Arrow || weapon.mData.mType == ESM::Weapon::Bolt + || weapon.mData.mType == ESM::Weapon::MarksmanThrown)) { - //checking of health + // checking of health if (weapon.mData.mHealth == 0) messages.add(id, "Durability is equal to zero", "", CSMDoc::Message::Severity_Warning); @@ -836,9 +795,7 @@ void CSMTools::ReferenceableCheckStage::weaponCheck( } void CSMTools::ReferenceableCheckStage::probeCheck( - int stage, - const CSMWorld::RefIdDataContainer< ESM::Probe >& records, - CSMDoc::Messages& messages) + int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages) { const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); @@ -846,7 +803,7 @@ void CSMTools::ReferenceableCheckStage::probeCheck( if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted()) return; - const ESM::Probe& probe = (dynamic_cast& >(baseRecord)).get(); + const ESM::Probe& probe = (dynamic_cast&>(baseRecord)).get(); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Probe, probe.mId); inventoryItemCheck(probe, messages, id.toString()); @@ -856,38 +813,36 @@ void CSMTools::ReferenceableCheckStage::probeCheck( scriptCheck(probe, messages, id.toString()); } -void CSMTools::ReferenceableCheckStage::repairCheck ( - int stage, const CSMWorld::RefIdDataContainer< ESM::Repair >& records, - CSMDoc::Messages& messages) +void CSMTools::ReferenceableCheckStage::repairCheck( + int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages) { - const CSMWorld::RecordBase& baseRecord = records.getRecord (stage); + const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); // Skip "Base" records (setting!) and "Deleted" records if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted()) return; - const ESM::Repair& repair = (dynamic_cast& >(baseRecord)).get(); - CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Repair, repair.mId); + const ESM::Repair& repair = (dynamic_cast&>(baseRecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Repair, repair.mId); - inventoryItemCheck (repair, messages, id.toString()); - toolCheck (repair, messages, id.toString(), true); + inventoryItemCheck(repair, messages, id.toString()); + toolCheck(repair, messages, id.toString(), true); // Check that mentioned scripts exist scriptCheck(repair, messages, id.toString()); } -void CSMTools::ReferenceableCheckStage::staticCheck ( - int stage, const CSMWorld::RefIdDataContainer< ESM::Static >& records, - CSMDoc::Messages& messages) +void CSMTools::ReferenceableCheckStage::staticCheck( + int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages) { - const CSMWorld::RecordBase& baseRecord = records.getRecord (stage); + const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); // Skip "Base" records (setting!) and "Deleted" records if ((mIgnoreBaseRecords && baseRecord.mState == CSMWorld::RecordBase::State_BaseOnly) || baseRecord.isDeleted()) return; - const ESM::Static& staticElement = (dynamic_cast& >(baseRecord)).get(); - CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Static, staticElement.mId); + const ESM::Static& staticElement = (dynamic_cast&>(baseRecord)).get(); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Static, staticElement.mId); if (staticElement.mModel.empty()) messages.add(id, "Model is missing", "", CSMDoc::Message::Severity_Error); @@ -895,18 +850,17 @@ void CSMTools::ReferenceableCheckStage::staticCheck ( messages.add(id, "Model '" + staticElement.mModel + "' does not exist", "", CSMDoc::Message::Severity_Error); } -//final check +// final check -void CSMTools::ReferenceableCheckStage::finalCheck (CSMDoc::Messages& messages) +void CSMTools::ReferenceableCheckStage::finalCheck(CSMDoc::Messages& messages) { if (!mPlayerPresent) - messages.add(CSMWorld::UniversalId::Type_Referenceables, "Player record is missing", "", CSMDoc::Message::Severity_SeriousError); + messages.add(CSMWorld::UniversalId::Type_Referenceables, "Player record is missing", "", + CSMDoc::Message::Severity_SeriousError); } void CSMTools::ReferenceableCheckStage::inventoryListCheck( - const std::vector& itemList, - CSMDoc::Messages& messages, - const std::string& id) + const std::vector& itemList, CSMDoc::Messages& messages, const std::string& id) { for (size_t i = 0; i < itemList.size(); ++i) { @@ -920,50 +874,51 @@ void CSMTools::ReferenceableCheckStage::inventoryListCheck( // Needs to accommodate containers, creatures, and NPCs switch (localIndex.second) { - case CSMWorld::UniversalId::Type_Potion: - case CSMWorld::UniversalId::Type_Apparatus: - case CSMWorld::UniversalId::Type_Armor: - case CSMWorld::UniversalId::Type_Book: - case CSMWorld::UniversalId::Type_Clothing: - case CSMWorld::UniversalId::Type_Ingredient: - case CSMWorld::UniversalId::Type_Light: - case CSMWorld::UniversalId::Type_Lockpick: - case CSMWorld::UniversalId::Type_Miscellaneous: - case CSMWorld::UniversalId::Type_Probe: - case CSMWorld::UniversalId::Type_Repair: - case CSMWorld::UniversalId::Type_Weapon: - case CSMWorld::UniversalId::Type_ItemLevelledList: - break; - default: - messages.add(id, "'" + itemName + "' is not an item", "", CSMDoc::Message::Severity_Error); + case CSMWorld::UniversalId::Type_Potion: + case CSMWorld::UniversalId::Type_Apparatus: + case CSMWorld::UniversalId::Type_Armor: + case CSMWorld::UniversalId::Type_Book: + case CSMWorld::UniversalId::Type_Clothing: + case CSMWorld::UniversalId::Type_Ingredient: + case CSMWorld::UniversalId::Type_Light: + case CSMWorld::UniversalId::Type_Lockpick: + case CSMWorld::UniversalId::Type_Miscellaneous: + case CSMWorld::UniversalId::Type_Probe: + case CSMWorld::UniversalId::Type_Repair: + case CSMWorld::UniversalId::Type_Weapon: + case CSMWorld::UniversalId::Type_ItemLevelledList: + break; + default: + messages.add(id, "'" + itemName + "' is not an item", "", CSMDoc::Message::Severity_Error); } } } } -//Templates begins here +// Templates begins here -template void CSMTools::ReferenceableCheckStage::inventoryItemCheck ( +template +void CSMTools::ReferenceableCheckStage::inventoryItemCheck( const Item& someItem, CSMDoc::Messages& messages, const std::string& someID, bool enchantable) { if (someItem.mName.empty()) messages.add(someID, "Name is missing", "", CSMDoc::Message::Severity_Error); - //Checking for weight + // Checking for weight if (someItem.mData.mWeight < 0) messages.add(someID, "Weight is negative", "", CSMDoc::Message::Severity_Error); - //Checking for value + // Checking for value if (someItem.mData.mValue < 0) messages.add(someID, "Value is negative", "", CSMDoc::Message::Severity_Error); - //checking for model + // checking for model if (someItem.mModel.empty()) messages.add(someID, "Model is missing", "", CSMDoc::Message::Severity_Error); else if (mModels.searchId(someItem.mModel) == -1) messages.add(someID, "Model '" + someItem.mModel + "' does not exist", "", CSMDoc::Message::Severity_Error); - //checking for icon + // checking for icon if (someItem.mIcon.empty()) messages.add(someID, "Icon is missing", "", CSMDoc::Message::Severity_Error); else if (mIcons.searchId(someItem.mIcon) == -1) @@ -977,27 +932,28 @@ template void CSMTools::ReferenceableCheckStage::inventoryItemChe messages.add(someID, "Enchantment points number is negative", "", CSMDoc::Message::Severity_Error); } -template void CSMTools::ReferenceableCheckStage::inventoryItemCheck ( +template +void CSMTools::ReferenceableCheckStage::inventoryItemCheck( const Item& someItem, CSMDoc::Messages& messages, const std::string& someID) { if (someItem.mName.empty()) messages.add(someID, "Name is missing", "", CSMDoc::Message::Severity_Error); - //Checking for weight + // Checking for weight if (someItem.mData.mWeight < 0) messages.add(someID, "Weight is negative", "", CSMDoc::Message::Severity_Error); - //Checking for value + // Checking for value if (someItem.mData.mValue < 0) messages.add(someID, "Value is negative", "", CSMDoc::Message::Severity_Error); - //checking for model + // checking for model if (someItem.mModel.empty()) messages.add(someID, "Model is missing", "", CSMDoc::Message::Severity_Error); else if (mModels.searchId(someItem.mModel) == -1) messages.add(someID, "Model '" + someItem.mModel + "' does not exist", "", CSMDoc::Message::Severity_Error); - //checking for icon + // checking for icon if (someItem.mIcon.empty()) messages.add(someID, "Icon is missing", "", CSMDoc::Message::Severity_Error); else if (mIcons.searchId(someItem.mIcon) == -1) @@ -1008,47 +964,55 @@ template void CSMTools::ReferenceableCheckStage::inventoryItemChe } } -template void CSMTools::ReferenceableCheckStage::toolCheck ( +template +void CSMTools::ReferenceableCheckStage::toolCheck( const Tool& someTool, CSMDoc::Messages& messages, const std::string& someID, bool canBeBroken) { if (someTool.mData.mQuality <= 0) messages.add(someID, "Quality is non-positive", "", CSMDoc::Message::Severity_Error); - if (canBeBroken && someTool.mData.mUses<=0) + if (canBeBroken && someTool.mData.mUses <= 0) messages.add(someID, "Number of uses is non-positive", "", CSMDoc::Message::Severity_Error); } -template void CSMTools::ReferenceableCheckStage::toolCheck ( +template +void CSMTools::ReferenceableCheckStage::toolCheck( const Tool& someTool, CSMDoc::Messages& messages, const std::string& someID) { if (someTool.mData.mQuality <= 0) messages.add(someID, "Quality is non-positive", "", CSMDoc::Message::Severity_Error); } -template void CSMTools::ReferenceableCheckStage::listCheck ( +template +void CSMTools::ReferenceableCheckStage::listCheck( const List& someList, CSMDoc::Messages& messages, const std::string& someID) { if (someList.mChanceNone > 100) { - messages.add(someID, "Chance that no object is used is over 100 percent", "", CSMDoc::Message::Severity_Warning); + messages.add( + someID, "Chance that no object is used is over 100 percent", "", CSMDoc::Message::Severity_Warning); } for (unsigned i = 0; i < someList.mList.size(); ++i) { if (mReferencables.searchId(someList.mList[i].mId).first == -1) - messages.add(someID, "Object '" + someList.mList[i].mId + "' does not exist", "", CSMDoc::Message::Severity_Error); + messages.add( + someID, "Object '" + someList.mList[i].mId + "' does not exist", "", CSMDoc::Message::Severity_Error); if (someList.mList[i].mLevel < 1) - messages.add(someID, "Level of item '" + someList.mList[i].mId + "' is non-positive", "", CSMDoc::Message::Severity_Error); + messages.add(someID, "Level of item '" + someList.mList[i].mId + "' is non-positive", "", + CSMDoc::Message::Severity_Error); } } -template void CSMTools::ReferenceableCheckStage::scriptCheck ( +template +void CSMTools::ReferenceableCheckStage::scriptCheck( const Tool& someTool, CSMDoc::Messages& messages, const std::string& someID) { if (!someTool.mScript.empty()) { if (mScripts.searchId(someTool.mScript) == -1) - messages.add(someID, "Script '" + someTool.mScript + "' does not exist", "", CSMDoc::Message::Severity_Error); + messages.add( + someID, "Script '" + someTool.mScript + "' does not exist", "", CSMDoc::Message::Severity_Error); } } diff --git a/apps/opencs/model/tools/referenceablecheck.hpp b/apps/opencs/model/tools/referenceablecheck.hpp index c927087721..2be0070648 100644 --- a/apps/opencs/model/tools/referenceablecheck.hpp +++ b/apps/opencs/model/tools/referenceablecheck.hpp @@ -3,97 +3,108 @@ #include "../doc/stage.hpp" +#include "../world/idcollection.hpp" #include "../world/refiddata.hpp" #include "../world/resources.hpp" -#include "../world/idcollection.hpp" -#include +#include #include +#include #include -#include #include namespace CSMTools { class ReferenceableCheckStage : public CSMDoc::Stage { - public: - - ReferenceableCheckStage (const CSMWorld::RefIdData& referenceable, - const CSMWorld::IdCollection& races, - const CSMWorld::IdCollection& classes, - const CSMWorld::IdCollection& factions, - const CSMWorld::IdCollection& scripts, - const CSMWorld::Resources& models, - const CSMWorld::Resources& icons, - const CSMWorld::IdCollection& bodyparts); - - void perform(int stage, CSMDoc::Messages& messages) override; - int setup() override; - - private: - //CONCRETE CHECKS - void bookCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Book >& records, CSMDoc::Messages& messages); - void activatorCheck(int stage, const CSMWorld::RefIdDataContainer< ESM::Activator >& records, CSMDoc::Messages& messages); - void potionCheck(int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); - void apparatusCheck(int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); - void armorCheck(int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); - void clothingCheck(int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); - void containerCheck(int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); - void creatureCheck(int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); - void doorCheck(int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); - void ingredientCheck(int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); - void creaturesLevListCheck(int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); - void itemLevelledListCheck(int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); - void lightCheck(int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); - void lockpickCheck(int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); - void miscCheck(int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); - void npcCheck(int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); - void weaponCheck(int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); - void probeCheck(int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); - void repairCheck(int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); - void staticCheck(int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); - - //FINAL CHECK - void finalCheck (CSMDoc::Messages& messages); - - //Convenience functions - void inventoryListCheck(const std::vector& itemList, CSMDoc::Messages& messages, const std::string& id); - - /// for all enchantable items. - template - inline void inventoryItemCheck(const Item& someItem, CSMDoc::Messages& messages, const std::string& someID, - bool enchantable); - - /// for non-enchantable items. - template - inline void inventoryItemCheck(const Item& someItem, CSMDoc::Messages& messages, const std::string& someID); - - /// for tools with uses. - template - inline void toolCheck(const Tool& someTool, CSMDoc::Messages& messages, const std::string& someID, - bool canbebroken); - - /// for tools without uses. - template - inline void toolCheck(const Tool& someTool, CSMDoc::Messages& messages, const std::string& someID); - - template - inline void listCheck(const List& someList, CSMDoc::Messages& messages, const std::string& someID); - - template - inline void scriptCheck(const Tool& someTool, CSMDoc::Messages& messages, const std::string& someID); - - const CSMWorld::RefIdData& mReferencables; - const CSMWorld::IdCollection& mRaces; - const CSMWorld::IdCollection& mClasses; - const CSMWorld::IdCollection& mFactions; - const CSMWorld::IdCollection& mScripts; - const CSMWorld::Resources& mModels; - const CSMWorld::Resources& mIcons; - const CSMWorld::IdCollection& mBodyParts; - bool mPlayerPresent; - bool mIgnoreBaseRecords; + public: + ReferenceableCheckStage(const CSMWorld::RefIdData& referenceable, + const CSMWorld::IdCollection& races, const CSMWorld::IdCollection& classes, + const CSMWorld::IdCollection& factions, const CSMWorld::IdCollection& scripts, + const CSMWorld::Resources& models, const CSMWorld::Resources& icons, + const CSMWorld::IdCollection& bodyparts); + + void perform(int stage, CSMDoc::Messages& messages) override; + int setup() override; + + private: + // CONCRETE CHECKS + void bookCheck(int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); + void activatorCheck( + int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); + void potionCheck( + int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); + void apparatusCheck( + int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); + void armorCheck(int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); + void clothingCheck( + int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); + void containerCheck( + int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); + void creatureCheck( + int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); + void doorCheck(int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); + void ingredientCheck( + int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); + void creaturesLevListCheck( + int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); + void itemLevelledListCheck( + int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); + void lightCheck(int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); + void lockpickCheck( + int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); + void miscCheck( + int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); + void npcCheck(int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); + void weaponCheck( + int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); + void probeCheck(int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); + void repairCheck( + int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); + void staticCheck( + int stage, const CSMWorld::RefIdDataContainer& records, CSMDoc::Messages& messages); + + // FINAL CHECK + void finalCheck(CSMDoc::Messages& messages); + + // Convenience functions + void inventoryListCheck( + const std::vector& itemList, CSMDoc::Messages& messages, const std::string& id); + + /// for all enchantable items. + template + inline void inventoryItemCheck( + const Item& someItem, CSMDoc::Messages& messages, const std::string& someID, bool enchantable); + + /// for non-enchantable items. + template + inline void inventoryItemCheck(const Item& someItem, CSMDoc::Messages& messages, const std::string& someID); + + /// for tools with uses. + template + inline void toolCheck( + const Tool& someTool, CSMDoc::Messages& messages, const std::string& someID, bool canbebroken); + + /// for tools without uses. + template + inline void toolCheck(const Tool& someTool, CSMDoc::Messages& messages, const std::string& someID); + + template + inline void listCheck(const List& someList, CSMDoc::Messages& messages, const std::string& someID); + + template + inline void scriptCheck(const Tool& someTool, CSMDoc::Messages& messages, const std::string& someID); + + const CSMWorld::RefIdData& mReferencables; + const CSMWorld::IdCollection& mRaces; + const CSMWorld::IdCollection& mClasses; + const CSMWorld::IdCollection& mFactions; + const CSMWorld::IdCollection& mScripts; + const CSMWorld::Resources& mModels; + const CSMWorld::Resources& mIcons; + const CSMWorld::IdCollection& mBodyParts; + bool mPlayerPresent; + bool mIgnoreBaseRecords; }; } #endif // REFERENCEABLECHECKSTAGE_H diff --git a/apps/opencs/model/tools/referencecheck.cpp b/apps/opencs/model/tools/referencecheck.cpp index 8baf47c6c5..b1ae8441bd 100644 --- a/apps/opencs/model/tools/referencecheck.cpp +++ b/apps/opencs/model/tools/referencecheck.cpp @@ -6,22 +6,19 @@ #include -CSMTools::ReferenceCheckStage::ReferenceCheckStage( - const CSMWorld::RefCollection& references, - const CSMWorld::RefIdCollection& referencables, - const CSMWorld::IdCollection& cells, +CSMTools::ReferenceCheckStage::ReferenceCheckStage(const CSMWorld::RefCollection& references, + const CSMWorld::RefIdCollection& referencables, const CSMWorld::IdCollection& cells, const CSMWorld::IdCollection& factions) - : - mReferences(references), - mObjects(referencables), - mDataSet(referencables.getDataSet()), - mCells(cells), - mFactions(factions) + : mReferences(references) + , mObjects(referencables) + , mDataSet(referencables.getDataSet()) + , mCells(cells) + , mFactions(factions) { mIgnoreBaseRecords = false; } -void CSMTools::ReferenceCheckStage::perform(int stage, CSMDoc::Messages &messages) +void CSMTools::ReferenceCheckStage::perform(int stage, CSMDoc::Messages& messages) { const CSMWorld::Record& record = mReferences.getRecord(stage); @@ -35,12 +32,13 @@ void CSMTools::ReferenceCheckStage::perform(int stage, CSMDoc::Messages &message // Check reference id if (cellRef.mRefID.empty()) messages.add(id, "Instance is not based on an object", "", CSMDoc::Message::Severity_Error); - else + else { // Check for non existing referenced object if (mObjects.searchId(cellRef.mRefID) == -1) - messages.add(id, "Instance of a non-existent object '" + cellRef.mRefID + "'", "", CSMDoc::Message::Severity_Error); - else + messages.add( + id, "Instance of a non-existent object '" + cellRef.mRefID + "'", "", CSMDoc::Message::Severity_Error); + else { // Check if reference charge is valid for it's proper referenced type CSMWorld::RefIdData::LocalIndex localIndex = mDataSet.searchId(cellRef.mRefID); @@ -57,7 +55,8 @@ void CSMTools::ReferenceCheckStage::perform(int stage, CSMDoc::Messages &message // If object have creature soul trapped, check if that creature reference is valid if (!cellRef.mSoul.empty()) if (mObjects.searchId(cellRef.mSoul) == -1) - messages.add(id, "Trapped soul object '" + cellRef.mSoul + "' does not exist", "", CSMDoc::Message::Severity_Error); + messages.add( + id, "Trapped soul object '" + cellRef.mSoul + "' does not exist", "", CSMDoc::Message::Severity_Error); if (cellRef.mFaction.empty()) { @@ -73,7 +72,8 @@ void CSMTools::ReferenceCheckStage::perform(int stage, CSMDoc::Messages &message } if (!cellRef.mDestCell.empty() && mCells.searchId(cellRef.mDestCell) == -1) - messages.add(id, "Destination cell '" + cellRef.mDestCell + "' does not exist", "", CSMDoc::Message::Severity_Error); + messages.add( + id, "Destination cell '" + cellRef.mDestCell + "' does not exist", "", CSMDoc::Message::Severity_Error); if (cellRef.mScale < 0) messages.add(id, "Negative scale", "", CSMDoc::Message::Severity_Error); diff --git a/apps/opencs/model/tools/referencecheck.hpp b/apps/opencs/model/tools/referencecheck.hpp index a1e024dda3..e09df29434 100644 --- a/apps/opencs/model/tools/referencecheck.hpp +++ b/apps/opencs/model/tools/referencecheck.hpp @@ -2,9 +2,9 @@ #define CSM_TOOLS_REFERENCECHECK_H #include "../world/idcollection.hpp" -#include "../world/refiddata.hpp" -#include "../world/refidcollection.hpp" #include "../world/refcollection.hpp" +#include "../world/refidcollection.hpp" +#include "../world/refiddata.hpp" #include "../doc/stage.hpp" @@ -17,22 +17,20 @@ namespace CSMTools { class ReferenceCheckStage : public CSMDoc::Stage { - public: - ReferenceCheckStage (const CSMWorld::RefCollection& references, - const CSMWorld::RefIdCollection& referencables, - const CSMWorld::IdCollection& cells, - const CSMWorld::IdCollection& factions); + public: + ReferenceCheckStage(const CSMWorld::RefCollection& references, const CSMWorld::RefIdCollection& referencables, + const CSMWorld::IdCollection& cells, const CSMWorld::IdCollection& factions); - void perform(int stage, CSMDoc::Messages& messages) override; - int setup() override; + void perform(int stage, CSMDoc::Messages& messages) override; + int setup() override; - private: - const CSMWorld::RefCollection& mReferences; - const CSMWorld::RefIdCollection& mObjects; - const CSMWorld::RefIdData& mDataSet; - const CSMWorld::IdCollection& mCells; - const CSMWorld::IdCollection& mFactions; - bool mIgnoreBaseRecords; + private: + const CSMWorld::RefCollection& mReferences; + const CSMWorld::RefIdCollection& mObjects; + const CSMWorld::RefIdData& mDataSet; + const CSMWorld::IdCollection& mCells; + const CSMWorld::IdCollection& mFactions; + bool mIgnoreBaseRecords; }; } diff --git a/apps/opencs/model/tools/regioncheck.cpp b/apps/opencs/model/tools/regioncheck.cpp index 127281f5d9..754905c677 100644 --- a/apps/opencs/model/tools/regioncheck.cpp +++ b/apps/opencs/model/tools/regioncheck.cpp @@ -4,8 +4,8 @@ #include "../world/universalid.hpp" -CSMTools::RegionCheckStage::RegionCheckStage (const CSMWorld::IdCollection& regions) -: mRegions (regions) +CSMTools::RegionCheckStage::RegionCheckStage(const CSMWorld::IdCollection& regions) + : mRegions(regions) { mIgnoreBaseRecords = false; } @@ -17,9 +17,9 @@ int CSMTools::RegionCheckStage::setup() return mRegions.getSize(); } -void CSMTools::RegionCheckStage::perform (int stage, CSMDoc::Messages& messages) +void CSMTools::RegionCheckStage::perform(int stage, CSMDoc::Messages& messages) { - const CSMWorld::Record& record = mRegions.getRecord (stage); + const CSMWorld::Record& record = mRegions.getRecord(stage); // Skip "Base" records (setting!) and "Deleted" records if ((mIgnoreBaseRecords && record.mState == CSMWorld::RecordBase::State_BaseOnly) || record.isDeleted()) @@ -27,7 +27,7 @@ void CSMTools::RegionCheckStage::perform (int stage, CSMDoc::Messages& messages) const ESM::Region& region = record.get(); - CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Region, region.mId); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Region, region.mId); // test for empty name if (region.mName.empty()) @@ -36,16 +36,17 @@ void CSMTools::RegionCheckStage::perform (int stage, CSMDoc::Messages& messages) /// \todo test that the ID in mSleeplist exists // test that chances add up to 100 - int chances = region.mData.mClear + region.mData.mCloudy + region.mData.mFoggy + region.mData.mOvercast + - region.mData.mRain + region.mData.mThunder + region.mData.mAsh + region.mData.mBlight + - region.mData.mSnow + region.mData.mBlizzard; + int chances = region.mData.mClear + region.mData.mCloudy + region.mData.mFoggy + region.mData.mOvercast + + region.mData.mRain + region.mData.mThunder + region.mData.mAsh + region.mData.mBlight + region.mData.mSnow + + region.mData.mBlizzard; if (chances != 100) messages.add(id, "Weather chances do not add up to 100", "", CSMDoc::Message::Severity_Error); for (const ESM::Region::SoundRef& sound : region.mSoundList) { if (sound.mChance > 100) - messages.add(id, "Chance of '" + sound.mSound + "' sound to play is over 100 percent", "", CSMDoc::Message::Severity_Warning); + messages.add(id, "Chance of '" + sound.mSound + "' sound to play is over 100 percent", "", + CSMDoc::Message::Severity_Warning); } /// \todo check data members that can't be edited in the table view diff --git a/apps/opencs/model/tools/regioncheck.hpp b/apps/opencs/model/tools/regioncheck.hpp index 71893c6c5d..b9e0fb04f6 100644 --- a/apps/opencs/model/tools/regioncheck.hpp +++ b/apps/opencs/model/tools/regioncheck.hpp @@ -12,18 +12,17 @@ namespace CSMTools /// \brief VerifyStage: make sure that region records are internally consistent class RegionCheckStage : public CSMDoc::Stage { - const CSMWorld::IdCollection& mRegions; - bool mIgnoreBaseRecords; + const CSMWorld::IdCollection& mRegions; + bool mIgnoreBaseRecords; - public: + public: + RegionCheckStage(const CSMWorld::IdCollection& regions); - RegionCheckStage (const CSMWorld::IdCollection& regions); + int setup() override; + ///< \return number of steps - int setup() override; - ///< \return number of steps - - void perform (int stage, CSMDoc::Messages& messages) override; - ///< Messages resulting from this tage will be appended to \a messages. + void perform(int stage, CSMDoc::Messages& messages) override; + ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/reportmodel.cpp b/apps/opencs/model/tools/reportmodel.cpp index a2901a6630..e6afbe486b 100644 --- a/apps/opencs/model/tools/reportmodel.cpp +++ b/apps/opencs/model/tools/reportmodel.cpp @@ -1,12 +1,13 @@ #include "reportmodel.hpp" -#include #include +#include #include "../world/columns.hpp" -CSMTools::ReportModel::ReportModel (bool fieldColumn, bool severityColumn) -: mColumnField (-1), mColumnSeverity (-1) +CSMTools::ReportModel::ReportModel(bool fieldColumn, bool severityColumn) + : mColumnField(-1) + , mColumnSeverity(-1) { int index = 3; @@ -19,7 +20,7 @@ CSMTools::ReportModel::ReportModel (bool fieldColumn, bool severityColumn) mColumnDescription = index; } -int CSMTools::ReportModel::rowCount (const QModelIndex & parent) const +int CSMTools::ReportModel::rowCount(const QModelIndex& parent) const { if (parent.isValid()) return 0; @@ -27,110 +28,109 @@ int CSMTools::ReportModel::rowCount (const QModelIndex & parent) const return static_cast(mRows.size()); } -int CSMTools::ReportModel::columnCount (const QModelIndex & parent) const +int CSMTools::ReportModel::columnCount(const QModelIndex& parent) const { if (parent.isValid()) return 0; - return mColumnDescription+1; + return mColumnDescription + 1; } -QVariant CSMTools::ReportModel::data (const QModelIndex & index, int role) const +QVariant CSMTools::ReportModel::data(const QModelIndex& index, int role) const { - if (role!=Qt::DisplayRole && role!=Qt::UserRole) + if (role != Qt::DisplayRole && role != Qt::UserRole) return QVariant(); switch (index.column()) { case Column_Type: - if(role == Qt::UserRole) - return QString::fromUtf8 ( - mRows.at (index.row()).mId.getTypeName().c_str()); + if (role == Qt::UserRole) + return QString::fromUtf8(mRows.at(index.row()).mId.getTypeName().c_str()); else - return static_cast (mRows.at (index.row()).mId.getType()); + return static_cast(mRows.at(index.row()).mId.getType()); case Column_Id: { - CSMWorld::UniversalId id = mRows.at (index.row()).mId; + CSMWorld::UniversalId id = mRows.at(index.row()).mId; - if (id.getArgumentType()==CSMWorld::UniversalId::ArgumentType_Id) - return QString::fromUtf8 (id.getId().c_str()); + if (id.getArgumentType() == CSMWorld::UniversalId::ArgumentType_Id) + return QString::fromUtf8(id.getId().c_str()); - return QString ("-"); + return QString("-"); } case Column_Hint: - return QString::fromUtf8 (mRows.at (index.row()).mHint.c_str()); + return QString::fromUtf8(mRows.at(index.row()).mHint.c_str()); } - if (index.column()==mColumnDescription) - return QString::fromUtf8 (mRows.at (index.row()).mMessage.c_str()); + if (index.column() == mColumnDescription) + return QString::fromUtf8(mRows.at(index.row()).mMessage.c_str()); - if (index.column()==mColumnField) + if (index.column() == mColumnField) { std::string field; - std::istringstream stream (mRows.at (index.row()).mHint); + std::istringstream stream(mRows.at(index.row()).mHint); char type, ignore; int fieldIndex; - if ((stream >> type >> ignore >> fieldIndex) && (type=='r' || type=='R')) + if ((stream >> type >> ignore >> fieldIndex) && (type == 'r' || type == 'R')) { - field = CSMWorld::Columns::getName ( - static_cast (fieldIndex)); + field = CSMWorld::Columns::getName(static_cast(fieldIndex)); } - return QString::fromUtf8 (field.c_str()); + return QString::fromUtf8(field.c_str()); } - if (index.column()==mColumnSeverity) + if (index.column() == mColumnSeverity) { - return QString::fromUtf8 ( - CSMDoc::Message::toString (mRows.at (index.row()).mSeverity).c_str()); + return QString::fromUtf8(CSMDoc::Message::toString(mRows.at(index.row()).mSeverity).c_str()); } return QVariant(); } -QVariant CSMTools::ReportModel::headerData (int section, Qt::Orientation orientation, int role) const +QVariant CSMTools::ReportModel::headerData(int section, Qt::Orientation orientation, int role) const { - if (role!=Qt::DisplayRole) + if (role != Qt::DisplayRole) return QVariant(); - if (orientation==Qt::Vertical) + if (orientation == Qt::Vertical) return QVariant(); switch (section) { - case Column_Type: return "Type"; - case Column_Id: return "ID"; + case Column_Type: + return "Type"; + case Column_Id: + return "ID"; } - if (section==mColumnDescription) + if (section == mColumnDescription) return "Description"; - if (section==mColumnField) + if (section == mColumnField) return "Field"; - if (section==mColumnSeverity) + if (section == mColumnSeverity) return "Severity"; return "-"; } -bool CSMTools::ReportModel::removeRows (int row, int count, const QModelIndex& parent) +bool CSMTools::ReportModel::removeRows(int row, int count, const QModelIndex& parent) { if (parent.isValid()) return false; - if (count>0) + if (count > 0) { - beginRemoveRows (parent, row, row+count-1); + beginRemoveRows(parent, row, row + count - 1); - mRows.erase (mRows.begin()+row, mRows.begin()+row+count); + mRows.erase(mRows.begin() + row, mRows.begin() + row + count); endRemoveRows(); } @@ -138,45 +138,45 @@ bool CSMTools::ReportModel::removeRows (int row, int count, const QModelIndex& p return true; } -void CSMTools::ReportModel::add (const CSMDoc::Message& message) +void CSMTools::ReportModel::add(const CSMDoc::Message& message) { - beginInsertRows (QModelIndex(), static_cast(mRows.size()), static_cast(mRows.size())); + beginInsertRows(QModelIndex(), static_cast(mRows.size()), static_cast(mRows.size())); - mRows.push_back (message); + mRows.push_back(message); endInsertRows(); } -void CSMTools::ReportModel::flagAsReplaced (int index) +void CSMTools::ReportModel::flagAsReplaced(int index) { - CSMDoc::Message& line = mRows.at (index); + CSMDoc::Message& line = mRows.at(index); std::string hint = line.mHint; - if (hint.empty() || hint[0]!='R') - throw std::logic_error ("trying to flag message as replaced that is not replaceable"); + if (hint.empty() || hint[0] != 'R') + throw std::logic_error("trying to flag message as replaced that is not replaceable"); hint[0] = 'r'; line.mHint = hint; - emit dataChanged (this->index (index, 0), this->index (index, columnCount())); + emit dataChanged(this->index(index, 0), this->index(index, columnCount())); } -const CSMWorld::UniversalId& CSMTools::ReportModel::getUniversalId (int row) const +const CSMWorld::UniversalId& CSMTools::ReportModel::getUniversalId(int row) const { - return mRows.at (row).mId; + return mRows.at(row).mId; } -std::string CSMTools::ReportModel::getHint (int row) const +std::string CSMTools::ReportModel::getHint(int row) const { - return mRows.at (row).mHint; + return mRows.at(row).mHint; } void CSMTools::ReportModel::clear() { if (!mRows.empty()) { - beginRemoveRows (QModelIndex(), 0, static_cast(mRows.size())-1); + beginRemoveRows(QModelIndex(), 0, static_cast(mRows.size()) - 1); mRows.clear(); endRemoveRows(); } @@ -186,10 +186,9 @@ int CSMTools::ReportModel::countErrors() const { int count = 0; - for (std::vector::const_iterator iter (mRows.begin()); - iter!=mRows.end(); ++iter) - if (iter->mSeverity==CSMDoc::Message::Severity_Error || - iter->mSeverity==CSMDoc::Message::Severity_SeriousError) + for (std::vector::const_iterator iter(mRows.begin()); iter != mRows.end(); ++iter) + if (iter->mSeverity == CSMDoc::Message::Severity_Error + || iter->mSeverity == CSMDoc::Message::Severity_SeriousError) ++count; return count; diff --git a/apps/opencs/model/tools/reportmodel.hpp b/apps/opencs/model/tools/reportmodel.hpp index 809dfcc3e8..b862e5c647 100644 --- a/apps/opencs/model/tools/reportmodel.hpp +++ b/apps/opencs/model/tools/reportmodel.hpp @@ -1,8 +1,8 @@ #ifndef CSM_TOOLS_REPORTMODEL_H #define CSM_TOOLS_REPORTMODEL_H -#include #include +#include #include @@ -14,47 +14,48 @@ namespace CSMTools { class ReportModel : public QAbstractTableModel { - Q_OBJECT + Q_OBJECT + + std::vector mRows; + + // Fixed columns + enum Columns + { + Column_Type = 0, + Column_Id = 1, + Column_Hint = 2 + }; - std::vector mRows; + // Configurable columns + int mColumnDescription; + int mColumnField; + int mColumnSeverity; - // Fixed columns - enum Columns - { - Column_Type = 0, Column_Id = 1, Column_Hint = 2 - }; + public: + ReportModel(bool fieldColumn = false, bool severityColumn = true); - // Configurable columns - int mColumnDescription; - int mColumnField; - int mColumnSeverity; + int rowCount(const QModelIndex& parent = QModelIndex()) const override; - public: + int columnCount(const QModelIndex& parent = QModelIndex()) const override; - ReportModel (bool fieldColumn = false, bool severityColumn = true); - - int rowCount (const QModelIndex & parent = QModelIndex()) const override; + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; - int columnCount (const QModelIndex & parent = QModelIndex()) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const override; + bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex()) override; - QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + void add(const CSMDoc::Message& message); - bool removeRows (int row, int count, const QModelIndex& parent = QModelIndex()) override; - - void add (const CSMDoc::Message& message); + void flagAsReplaced(int index); - void flagAsReplaced (int index); - - const CSMWorld::UniversalId& getUniversalId (int row) const; + const CSMWorld::UniversalId& getUniversalId(int row) const; - std::string getHint (int row) const; + std::string getHint(int row) const; - void clear(); + void clear(); - // Return number of messages with Error or SeriousError severity. - int countErrors() const; + // Return number of messages with Error or SeriousError severity. + int countErrors() const; }; } diff --git a/apps/opencs/model/tools/scriptcheck.cpp b/apps/opencs/model/tools/scriptcheck.cpp index 6fa2dfcfc9..9a78db03c0 100644 --- a/apps/opencs/model/tools/scriptcheck.cpp +++ b/apps/opencs/model/tools/scriptcheck.cpp @@ -2,11 +2,11 @@ #include -#include -#include -#include #include #include +#include +#include +#include #include "../doc/document.hpp" @@ -14,51 +14,56 @@ #include "../prefs/state.hpp" -CSMDoc::Message::Severity CSMTools::ScriptCheckStage::getSeverity (Type type) +CSMDoc::Message::Severity CSMTools::ScriptCheckStage::getSeverity(Type type) { switch (type) { - case WarningMessage: return CSMDoc::Message::Severity_Warning; - case ErrorMessage: return CSMDoc::Message::Severity_Error; + case WarningMessage: + return CSMDoc::Message::Severity_Warning; + case ErrorMessage: + return CSMDoc::Message::Severity_Error; } return CSMDoc::Message::Severity_SeriousError; } -void CSMTools::ScriptCheckStage::report (const std::string& message, const Compiler::TokenLoc& loc, - Type type) +void CSMTools::ScriptCheckStage::report(const std::string& message, const Compiler::TokenLoc& loc, Type type) { std::ostringstream stream; - CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Script, mId); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Script, mId); - stream << message << " (" << loc.mLiteral << ")" << " @ line " << loc.mLine+1 << ", column " << loc.mColumn; + stream << message << " (" << loc.mLiteral << ")" + << " @ line " << loc.mLine + 1 << ", column " << loc.mColumn; std::ostringstream hintStream; - hintStream << "l:" << loc.mLine+1 << " " << loc.mColumn; + hintStream << "l:" << loc.mLine + 1 << " " << loc.mColumn; - mMessages->add (id, stream.str(), hintStream.str(), getSeverity (type)); + mMessages->add(id, stream.str(), hintStream.str(), getSeverity(type)); } -void CSMTools::ScriptCheckStage::report (const std::string& message, Type type) +void CSMTools::ScriptCheckStage::report(const std::string& message, Type type) { - CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Script, mId); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Script, mId); std::ostringstream stream; stream << message; - mMessages->add (id, stream.str(), "", getSeverity (type)); + mMessages->add(id, stream.str(), "", getSeverity(type)); } -CSMTools::ScriptCheckStage::ScriptCheckStage (const CSMDoc::Document& document) -: mDocument (document), mContext (document.getData()), mMessages (nullptr), mWarningMode (Mode_Ignore) +CSMTools::ScriptCheckStage::ScriptCheckStage(const CSMDoc::Document& document) + : mDocument(document) + , mContext(document.getData()) + , mMessages(nullptr) + , mWarningMode(Mode_Ignore) { /// \todo add an option to configure warning mode - setWarningsMode (0); + setWarningsMode(0); - Compiler::registerExtensions (mExtensions); - mContext.setExtensions (&mExtensions); + Compiler::registerExtensions(mExtensions); + mContext.setExtensions(&mExtensions); mIgnoreBaseRecords = false; } @@ -67,11 +72,11 @@ int CSMTools::ScriptCheckStage::setup() { std::string warnings = CSMPrefs::get()["Scripts"]["warnings"].toString(); - if (warnings=="Ignore") + if (warnings == "Ignore") mWarningMode = Mode_Ignore; - else if (warnings=="Normal") + else if (warnings == "Normal") mWarningMode = Mode_Normal; - else if (warnings=="Strict") + else if (warnings == "Strict") mWarningMode = Mode_Strict; mContext.clear(); @@ -84,14 +89,13 @@ int CSMTools::ScriptCheckStage::setup() return mDocument.getData().getScripts().getSize(); } -void CSMTools::ScriptCheckStage::perform (int stage, CSMDoc::Messages& messages) +void CSMTools::ScriptCheckStage::perform(int stage, CSMDoc::Messages& messages) { - const CSMWorld::Record &record = mDocument.getData().getScripts().getRecord(stage); + const CSMWorld::Record& record = mDocument.getData().getScripts().getRecord(stage); - mId = mDocument.getData().getScripts().getId (stage); + mId = mDocument.getData().getScripts().getId(stage); - if (mDocument.isBlacklisted ( - CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Script, mId))) + if (mDocument.isBlacklisted(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Script, mId))) return; // Skip "Base" records (setting!) and "Deleted" records @@ -102,21 +106,27 @@ void CSMTools::ScriptCheckStage::perform (int stage, CSMDoc::Messages& messages) switch (mWarningMode) { - case Mode_Ignore: setWarningsMode (0); break; - case Mode_Normal: setWarningsMode (1); break; - case Mode_Strict: setWarningsMode (2); break; + case Mode_Ignore: + setWarningsMode(0); + break; + case Mode_Normal: + setWarningsMode(1); + break; + case Mode_Strict: + setWarningsMode(2); + break; } try { mFile = record.get().mId; - std::istringstream input (record.get().mScriptText); + std::istringstream input(record.get().mScriptText); - Compiler::Scanner scanner (*this, input, mContext.getExtensions()); + Compiler::Scanner scanner(*this, input, mContext.getExtensions()); - Compiler::FileParser parser (*this, mContext); + Compiler::FileParser parser(*this, mContext); - scanner.scan (parser); + scanner.scan(parser); } catch (const Compiler::SourceException&) { @@ -124,12 +134,12 @@ void CSMTools::ScriptCheckStage::perform (int stage, CSMDoc::Messages& messages) } catch (const std::exception& error) { - CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Script, mId); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Script, mId); std::ostringstream stream; stream << error.what(); - messages.add (id, stream.str(), "", CSMDoc::Message::Severity_SeriousError); + messages.add(id, stream.str(), "", CSMDoc::Message::Severity_SeriousError); } mMessages = nullptr; diff --git a/apps/opencs/model/tools/scriptcheck.hpp b/apps/opencs/model/tools/scriptcheck.hpp index d975e02da5..d8d4d45d3a 100644 --- a/apps/opencs/model/tools/scriptcheck.hpp +++ b/apps/opencs/model/tools/scriptcheck.hpp @@ -18,39 +18,38 @@ namespace CSMTools /// \brief VerifyStage: make sure that scripts compile class ScriptCheckStage : public CSMDoc::Stage, private Compiler::ErrorHandler { - enum WarningMode - { - Mode_Ignore, - Mode_Normal, - Mode_Strict - }; - - const CSMDoc::Document& mDocument; - Compiler::Extensions mExtensions; - CSMWorld::ScriptContext mContext; - std::string mId; - std::string mFile; - CSMDoc::Messages *mMessages; - WarningMode mWarningMode; - bool mIgnoreBaseRecords; - - CSMDoc::Message::Severity getSeverity (Type type); - - void report (const std::string& message, const Compiler::TokenLoc& loc, Type type) override; - ///< Report error to the user. - - void report (const std::string& message, Type type) override; - ///< Report a file related error - - public: - - ScriptCheckStage (const CSMDoc::Document& document); - - int setup() override; - ///< \return number of steps - - void perform (int stage, CSMDoc::Messages& messages) override; - ///< Messages resulting from this tage will be appended to \a messages. + enum WarningMode + { + Mode_Ignore, + Mode_Normal, + Mode_Strict + }; + + const CSMDoc::Document& mDocument; + Compiler::Extensions mExtensions; + CSMWorld::ScriptContext mContext; + std::string mId; + std::string mFile; + CSMDoc::Messages* mMessages; + WarningMode mWarningMode; + bool mIgnoreBaseRecords; + + CSMDoc::Message::Severity getSeverity(Type type); + + void report(const std::string& message, const Compiler::TokenLoc& loc, Type type) override; + ///< Report error to the user. + + void report(const std::string& message, Type type) override; + ///< Report a file related error + + public: + ScriptCheckStage(const CSMDoc::Document& document); + + int setup() override; + ///< \return number of steps + + void perform(int stage, CSMDoc::Messages& messages) override; + ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/search.cpp b/apps/opencs/model/tools/search.cpp index 7005480d11..f7f5ff56e9 100644 --- a/apps/opencs/model/tools/search.cpp +++ b/apps/opencs/model/tools/search.cpp @@ -1,157 +1,172 @@ #include "search.hpp" -#include #include +#include -#include "../doc/messages.hpp" #include "../doc/document.hpp" +#include "../doc/messages.hpp" -#include "../world/idtablebase.hpp" #include "../world/columnbase.hpp" -#include "../world/universalid.hpp" #include "../world/commands.hpp" +#include "../world/idtablebase.hpp" +#include "../world/universalid.hpp" -void CSMTools::Search::searchTextCell (const CSMWorld::IdTableBase *model, - const QModelIndex& index, const CSMWorld::UniversalId& id, bool writable, - CSMDoc::Messages& messages) const +void CSMTools::Search::searchTextCell(const CSMWorld::IdTableBase* model, const QModelIndex& index, + const CSMWorld::UniversalId& id, bool writable, CSMDoc::Messages& messages) const { // using QString here for easier handling of case folding. - - QString search = QString::fromUtf8 (mText.c_str()); - QString text = model->data (index).toString(); + + QString search = QString::fromUtf8(mText.c_str()); + QString text = model->data(index).toString(); int pos = 0; Qt::CaseSensitivity caseSensitivity = mCase ? Qt::CaseSensitive : Qt::CaseInsensitive; - while ((pos = text.indexOf (search, pos, caseSensitivity))!=-1) + while ((pos = text.indexOf(search, pos, caseSensitivity)) != -1) { std::ostringstream hint; - hint - << (writable ? 'R' : 'r') - <<": " - << model->getColumnId (index.column()) - << " " << pos - << " " << search.length(); - - messages.add (id, formatDescription (text, pos, search.length()).toUtf8().data(), hint.str()); + hint << (writable ? 'R' : 'r') << ": " << model->getColumnId(index.column()) << " " << pos << " " + << search.length(); + + messages.add(id, formatDescription(text, pos, search.length()).toUtf8().data(), hint.str()); pos += search.length(); } } -void CSMTools::Search::searchRegExCell (const CSMWorld::IdTableBase *model, - const QModelIndex& index, const CSMWorld::UniversalId& id, bool writable, - CSMDoc::Messages& messages) const +void CSMTools::Search::searchRegExCell(const CSMWorld::IdTableBase* model, const QModelIndex& index, + const CSMWorld::UniversalId& id, bool writable, CSMDoc::Messages& messages) const { - QString text = model->data (index).toString(); + QString text = model->data(index).toString(); int pos = 0; - while ((pos = mRegExp.indexIn (text, pos))!=-1) + while ((pos = mRegExp.indexIn(text, pos)) != -1) { int length = mRegExp.matchedLength(); - + std::ostringstream hint; - hint - << (writable ? 'R' : 'r') - <<": " - << model->getColumnId (index.column()) - << " " << pos - << " " << length; - - messages.add (id, formatDescription (text, pos, length).toUtf8().data(), hint.str()); + hint << (writable ? 'R' : 'r') << ": " << model->getColumnId(index.column()) << " " << pos << " " << length; + + messages.add(id, formatDescription(text, pos, length).toUtf8().data(), hint.str()); pos += length; } } -void CSMTools::Search::searchRecordStateCell (const CSMWorld::IdTableBase *model, - const QModelIndex& index, const CSMWorld::UniversalId& id, bool writable, CSMDoc::Messages& messages) const +void CSMTools::Search::searchRecordStateCell(const CSMWorld::IdTableBase* model, const QModelIndex& index, + const CSMWorld::UniversalId& id, bool writable, CSMDoc::Messages& messages) const { if (writable) - throw std::logic_error ("Record state can not be modified by search and replace"); - - int data = model->data (index).toInt(); + throw std::logic_error("Record state can not be modified by search and replace"); + + int data = model->data(index).toInt(); - if (data==mValue) + if (data == mValue) { - std::vector> states = - CSMWorld::Columns::getEnums (CSMWorld::Columns::ColumnId_Modification); + std::vector> states + = CSMWorld::Columns::getEnums(CSMWorld::Columns::ColumnId_Modification); const std::string hint = "r: " + std::to_string(model->getColumnId(index.column())); - messages.add (id, states.at(data).second, hint); + messages.add(id, states.at(data).second, hint); } } -QString CSMTools::Search::formatDescription (const QString& description, int pos, int length) const +QString CSMTools::Search::formatDescription(const QString& description, int pos, int length) const { - QString text (description); + QString text(description); // split - QString highlight = flatten (text.mid (pos, length)); - QString before = flatten (mPaddingBefore>=pos ? - text.mid (0, pos) : text.mid (pos-mPaddingBefore, mPaddingBefore)); - QString after = flatten (text.mid (pos+length, mPaddingAfter)); + QString highlight = flatten(text.mid(pos, length)); + QString before = flatten(mPaddingBefore >= pos ? text.mid(0, pos) : text.mid(pos - mPaddingBefore, mPaddingBefore)); + QString after = flatten(text.mid(pos + length, mPaddingAfter)); // compensate for Windows nonsense - text.remove ('\r'); + text.remove('\r'); // join text = before + "" + highlight + "" + after; // improve layout for single line display - text.replace ("\n", "<CR>"); - text.replace ('\t', ' '); - - return text; + text.replace("\n", "<CR>"); + text.replace('\t', ' '); + + return text; } -QString CSMTools::Search::flatten (const QString& text) const +QString CSMTools::Search::flatten(const QString& text) const { - QString flat (text); + QString flat(text); - flat.replace ("&", "&"); - flat.replace ("<", "<"); + flat.replace("&", "&"); + flat.replace("<", "<"); return flat; } -CSMTools::Search::Search() : mType (Type_None), mValue (0), mCase (false), mIdColumn (0), mTypeColumn (0), - mPaddingBefore (10), mPaddingAfter (10) {} +CSMTools::Search::Search() + : mType(Type_None) + , mValue(0) + , mCase(false) + , mIdColumn(0) + , mTypeColumn(0) + , mPaddingBefore(10) + , mPaddingAfter(10) +{ +} -CSMTools::Search::Search (Type type, bool caseSensitive, const std::string& value) -: mType (type), mText (value), mValue (0), mCase (caseSensitive), mIdColumn (0), mTypeColumn (0), mPaddingBefore (10), mPaddingAfter (10) +CSMTools::Search::Search(Type type, bool caseSensitive, const std::string& value) + : mType(type) + , mText(value) + , mValue(0) + , mCase(caseSensitive) + , mIdColumn(0) + , mTypeColumn(0) + , mPaddingBefore(10) + , mPaddingAfter(10) { - if (type!=Type_Text && type!=Type_Id) - throw std::logic_error ("Invalid search parameter (string)"); + if (type != Type_Text && type != Type_Id) + throw std::logic_error("Invalid search parameter (string)"); } -CSMTools::Search::Search (Type type, bool caseSensitive, const QRegExp& value) -: mType (type), mRegExp (value), mValue (0), mCase (caseSensitive), mIdColumn (0), mTypeColumn (0), mPaddingBefore (10), mPaddingAfter (10) +CSMTools::Search::Search(Type type, bool caseSensitive, const QRegExp& value) + : mType(type) + , mRegExp(value) + , mValue(0) + , mCase(caseSensitive) + , mIdColumn(0) + , mTypeColumn(0) + , mPaddingBefore(10) + , mPaddingAfter(10) { mRegExp.setCaseSensitivity(mCase ? Qt::CaseSensitive : Qt::CaseInsensitive); - if (type!=Type_TextRegEx && type!=Type_IdRegEx) - throw std::logic_error ("Invalid search parameter (RegExp)"); + if (type != Type_TextRegEx && type != Type_IdRegEx) + throw std::logic_error("Invalid search parameter (RegExp)"); } -CSMTools::Search::Search (Type type, bool caseSensitive, int value) -: mType (type), mValue (value), mCase (caseSensitive), mIdColumn (0), mTypeColumn (0), mPaddingBefore (10), mPaddingAfter (10) +CSMTools::Search::Search(Type type, bool caseSensitive, int value) + : mType(type) + , mValue(value) + , mCase(caseSensitive) + , mIdColumn(0) + , mTypeColumn(0) + , mPaddingBefore(10) + , mPaddingAfter(10) { - if (type!=Type_RecordState) - throw std::logic_error ("invalid search parameter (int)"); + if (type != Type_RecordState) + throw std::logic_error("invalid search parameter (int)"); } -void CSMTools::Search::configure (const CSMWorld::IdTableBase *model) +void CSMTools::Search::configure(const CSMWorld::IdTableBase* model) { mColumns.clear(); int columns = model->columnCount(); - for (int i=0; i ( - model->headerData ( - i, Qt::Horizontal, static_cast (CSMWorld::ColumnBase::Role_Display)).toInt()); + CSMWorld::ColumnBase::Display display = static_cast( + model->headerData(i, Qt::Horizontal, static_cast(CSMWorld::ColumnBase::Role_Display)).toInt()); bool consider = false; @@ -160,28 +175,26 @@ void CSMTools::Search::configure (const CSMWorld::IdTableBase *model) case Type_Text: case Type_TextRegEx: - if (CSMWorld::ColumnBase::isText (display) || - CSMWorld::ColumnBase::isScript (display)) + if (CSMWorld::ColumnBase::isText(display) || CSMWorld::ColumnBase::isScript(display)) { consider = true; } break; - + case Type_Id: case Type_IdRegEx: - if (CSMWorld::ColumnBase::isId (display) || - CSMWorld::ColumnBase::isScript (display)) + if (CSMWorld::ColumnBase::isId(display) || CSMWorld::ColumnBase::isScript(display)) { consider = true; } break; - + case Type_RecordState: - if (display==CSMWorld::ColumnBase::Display_RecordState) + if (display == CSMWorld::ColumnBase::Display_RecordState) consider = true; break; @@ -192,45 +205,43 @@ void CSMTools::Search::configure (const CSMWorld::IdTableBase *model) } if (consider) - mColumns.insert (i); + mColumns.insert(i); } - mIdColumn = model->findColumnIndex (CSMWorld::Columns::ColumnId_Id); - mTypeColumn = model->findColumnIndex (CSMWorld::Columns::ColumnId_RecordType); + mIdColumn = model->findColumnIndex(CSMWorld::Columns::ColumnId_Id); + mTypeColumn = model->findColumnIndex(CSMWorld::Columns::ColumnId_RecordType); } -void CSMTools::Search::searchRow (const CSMWorld::IdTableBase *model, int row, - CSMDoc::Messages& messages) const +void CSMTools::Search::searchRow(const CSMWorld::IdTableBase* model, int row, CSMDoc::Messages& messages) const { - for (std::set::const_iterator iter (mColumns.begin()); iter!=mColumns.end(); ++iter) + for (std::set::const_iterator iter(mColumns.begin()); iter != mColumns.end(); ++iter) { - QModelIndex index = model->index (row, *iter); + QModelIndex index = model->index(row, *iter); + + CSMWorld::UniversalId::Type type + = static_cast(model->data(model->index(row, mTypeColumn)).toInt()); - CSMWorld::UniversalId::Type type = static_cast ( - model->data (model->index (row, mTypeColumn)).toInt()); - - CSMWorld::UniversalId id ( - type, model->data (model->index (row, mIdColumn)).toString().toUtf8().data()); + CSMWorld::UniversalId id(type, model->data(model->index(row, mIdColumn)).toString().toUtf8().data()); + + bool writable = model->flags(index) & Qt::ItemIsEditable; - bool writable = model->flags (index) & Qt::ItemIsEditable; - switch (mType) { case Type_Text: case Type_Id: - searchTextCell (model, index, id, writable, messages); + searchTextCell(model, index, id, writable, messages); break; - + case Type_TextRegEx: case Type_IdRegEx: - searchRegExCell (model, index, id, writable, messages); + searchRegExCell(model, index, id, writable, messages); break; - + case Type_RecordState: - searchRecordStateCell (model, index, id, writable, messages); + searchRecordStateCell(model, index, id, writable, messages); break; case Type_None: @@ -240,54 +251,49 @@ void CSMTools::Search::searchRow (const CSMWorld::IdTableBase *model, int row, } } -void CSMTools::Search::setPadding (int before, int after) +void CSMTools::Search::setPadding(int before, int after) { mPaddingBefore = before; mPaddingAfter = after; } -void CSMTools::Search::replace (CSMDoc::Document& document, CSMWorld::IdTableBase *model, - const CSMWorld::UniversalId& id, const std::string& messageHint, - const std::string& replaceText) const +void CSMTools::Search::replace(CSMDoc::Document& document, CSMWorld::IdTableBase* model, + const CSMWorld::UniversalId& id, const std::string& messageHint, const std::string& replaceText) const { - std::istringstream stream (messageHint.c_str()); + std::istringstream stream(messageHint.c_str()); char hint, ignore; int columnId, pos, length; if (stream >> hint >> ignore >> columnId >> pos >> length) { - int column = - model->findColumnIndex (static_cast (columnId)); - - QModelIndex index = model->getModelIndex (id.getId(), column); + int column = model->findColumnIndex(static_cast(columnId)); - std::string text = model->data (index).toString().toUtf8().constData(); + QModelIndex index = model->getModelIndex(id.getId(), column); - std::string before = text.substr (0, pos); - std::string after = text.substr (pos+length); + std::string text = model->data(index).toString().toUtf8().constData(); + + std::string before = text.substr(0, pos); + std::string after = text.substr(pos + length); std::string newText = before + replaceText + after; - - document.getUndoStack().push ( - new CSMWorld::ModifyCommand (*model, index, QString::fromUtf8 (newText.c_str()))); + + document.getUndoStack().push(new CSMWorld::ModifyCommand(*model, index, QString::fromUtf8(newText.c_str()))); } } -bool CSMTools::Search::verify (CSMDoc::Document& document, CSMWorld::IdTableBase *model, - const CSMWorld::UniversalId& id, const std::string& messageHint) const +bool CSMTools::Search::verify(CSMDoc::Document& document, CSMWorld::IdTableBase* model, const CSMWorld::UniversalId& id, + const std::string& messageHint) const { - CSMDoc::Messages messages (CSMDoc::Message::Severity_Info); + CSMDoc::Messages messages(CSMDoc::Message::Severity_Info); + + int row = model->getModelIndex(id.getId(), model->findColumnIndex(CSMWorld::Columns::ColumnId_Id)).row(); - int row = model->getModelIndex (id.getId(), - model->findColumnIndex (CSMWorld::Columns::ColumnId_Id)).row(); - - searchRow (model, row, messages); + searchRow(model, row, messages); - for (CSMDoc::Messages::Iterator iter (messages.begin()); iter!=messages.end(); ++iter) - if (iter->mHint==messageHint) + for (CSMDoc::Messages::Iterator iter(messages.begin()); iter != messages.end(); ++iter) + if (iter->mHint == messageHint) return true; return false; } - diff --git a/apps/opencs/model/tools/search.hpp b/apps/opencs/model/tools/search.hpp index 35cfa64025..70f27cad1d 100644 --- a/apps/opencs/model/tools/search.hpp +++ b/apps/opencs/model/tools/search.hpp @@ -1,11 +1,11 @@ #ifndef CSM_TOOLS_SEARCH_H #define CSM_TOOLS_SEARCH_H -#include #include +#include -#include #include +#include class QModelIndex; @@ -25,77 +25,71 @@ namespace CSMTools { class Search { - public: - - enum Type - { - Type_Text = 0, - Type_TextRegEx = 1, - Type_Id = 2, - Type_IdRegEx = 3, - Type_RecordState = 4, - Type_None - }; - - private: - - Type mType; - std::string mText; - QRegExp mRegExp; - int mValue; - bool mCase; - std::set mColumns; - int mIdColumn; - int mTypeColumn; - int mPaddingBefore; - int mPaddingAfter; - - void searchTextCell (const CSMWorld::IdTableBase *model, const QModelIndex& index, - const CSMWorld::UniversalId& id, bool writable, CSMDoc::Messages& messages) const; - - void searchRegExCell (const CSMWorld::IdTableBase *model, const QModelIndex& index, - const CSMWorld::UniversalId& id, bool writable, CSMDoc::Messages& messages) const; - - void searchRecordStateCell (const CSMWorld::IdTableBase *model, - const QModelIndex& index, const CSMWorld::UniversalId& id, bool writable, - CSMDoc::Messages& messages) const; - - QString formatDescription (const QString& description, int pos, int length) const; - - QString flatten (const QString& text) const; - - public: - - Search(); - - Search (Type type, bool caseSensitive, const std::string& value); - - Search (Type type, bool caseSensitive, const QRegExp& value); - - Search (Type type, bool caseSensitive, int value); - - // Configure search for the specified model. - void configure (const CSMWorld::IdTableBase *model); - - // Search row in \a model and store results in \a messages. - // - // \attention *this needs to be configured for \a model. - void searchRow (const CSMWorld::IdTableBase *model, int row, - CSMDoc::Messages& messages) const; - - void setPadding (int before, int after); - - // Configuring *this for the model is not necessary when calling this function. - void replace (CSMDoc::Document& document, CSMWorld::IdTableBase *model, - const CSMWorld::UniversalId& id, const std::string& messageHint, - const std::string& replaceText) const; - - // Check if model still matches search results. - bool verify (CSMDoc::Document& document, CSMWorld::IdTableBase *model, - const CSMWorld::UniversalId& id, const std::string& messageHint) const; + public: + enum Type + { + Type_Text = 0, + Type_TextRegEx = 1, + Type_Id = 2, + Type_IdRegEx = 3, + Type_RecordState = 4, + Type_None + }; + + private: + Type mType; + std::string mText; + QRegExp mRegExp; + int mValue; + bool mCase; + std::set mColumns; + int mIdColumn; + int mTypeColumn; + int mPaddingBefore; + int mPaddingAfter; + + void searchTextCell(const CSMWorld::IdTableBase* model, const QModelIndex& index, + const CSMWorld::UniversalId& id, bool writable, CSMDoc::Messages& messages) const; + + void searchRegExCell(const CSMWorld::IdTableBase* model, const QModelIndex& index, + const CSMWorld::UniversalId& id, bool writable, CSMDoc::Messages& messages) const; + + void searchRecordStateCell(const CSMWorld::IdTableBase* model, const QModelIndex& index, + const CSMWorld::UniversalId& id, bool writable, CSMDoc::Messages& messages) const; + + QString formatDescription(const QString& description, int pos, int length) const; + + QString flatten(const QString& text) const; + + public: + Search(); + + Search(Type type, bool caseSensitive, const std::string& value); + + Search(Type type, bool caseSensitive, const QRegExp& value); + + Search(Type type, bool caseSensitive, int value); + + // Configure search for the specified model. + void configure(const CSMWorld::IdTableBase* model); + + // Search row in \a model and store results in \a messages. + // + // \attention *this needs to be configured for \a model. + void searchRow(const CSMWorld::IdTableBase* model, int row, CSMDoc::Messages& messages) const; + + void setPadding(int before, int after); + + // Configuring *this for the model is not necessary when calling this function. + void replace(CSMDoc::Document& document, CSMWorld::IdTableBase* model, const CSMWorld::UniversalId& id, + const std::string& messageHint, const std::string& replaceText) const; + + // Check if model still matches search results. + bool verify(CSMDoc::Document& document, CSMWorld::IdTableBase* model, const CSMWorld::UniversalId& id, + const std::string& messageHint) const; }; } -Q_DECLARE_METATYPE (CSMTools::Search) +Q_DECLARE_METATYPE(CSMTools::Search) #endif diff --git a/apps/opencs/model/tools/searchoperation.cpp b/apps/opencs/model/tools/searchoperation.cpp index 8fba1cc1ef..48247481d6 100644 --- a/apps/opencs/model/tools/searchoperation.cpp +++ b/apps/opencs/model/tools/searchoperation.cpp @@ -1,38 +1,34 @@ #include "searchoperation.hpp" -#include "../doc/state.hpp" #include "../doc/document.hpp" +#include "../doc/state.hpp" #include "../world/data.hpp" #include "../world/idtablebase.hpp" #include "searchstage.hpp" -CSMTools::SearchOperation::SearchOperation (CSMDoc::Document& document) -: CSMDoc::Operation (CSMDoc::State_Searching, false) +CSMTools::SearchOperation::SearchOperation(CSMDoc::Document& document) + : CSMDoc::Operation(CSMDoc::State_Searching, false) { - std::vector types = CSMWorld::UniversalId::listTypes ( - CSMWorld::UniversalId::Class_RecordList | - CSMWorld::UniversalId::Class_ResourceList - ); + std::vector types = CSMWorld::UniversalId::listTypes( + CSMWorld::UniversalId::Class_RecordList | CSMWorld::UniversalId::Class_ResourceList); - for (std::vector::const_iterator iter (types.begin()); - iter!=types.end(); ++iter) - appendStage (new SearchStage (&dynamic_cast ( - *document.getData().getTableModel (*iter)))); + for (std::vector::const_iterator iter(types.begin()); iter != types.end(); ++iter) + appendStage(new SearchStage(&dynamic_cast(*document.getData().getTableModel(*iter)))); - setDefaultSeverity (CSMDoc::Message::Severity_Info); + setDefaultSeverity(CSMDoc::Message::Severity_Info); } -void CSMTools::SearchOperation::configure (const Search& search) +void CSMTools::SearchOperation::configure(const Search& search) { mSearch = search; } -void CSMTools::SearchOperation::appendStage (SearchStage *stage) +void CSMTools::SearchOperation::appendStage(SearchStage* stage) { - CSMDoc::Operation::appendStage (stage); - stage->setOperation (this); + CSMDoc::Operation::appendStage(stage); + stage->setOperation(this); } const CSMTools::Search& CSMTools::SearchOperation::getSearch() const diff --git a/apps/opencs/model/tools/searchoperation.hpp b/apps/opencs/model/tools/searchoperation.hpp index fbbb388981..87a046d09e 100644 --- a/apps/opencs/model/tools/searchoperation.hpp +++ b/apps/opencs/model/tools/searchoperation.hpp @@ -13,25 +13,23 @@ namespace CSMDoc namespace CSMTools { class SearchStage; - + class SearchOperation : public CSMDoc::Operation { - Search mSearch; - - public: + Search mSearch; - SearchOperation (CSMDoc::Document& document); + public: + SearchOperation(CSMDoc::Document& document); - /// \attention Do not call this function while a search is running. - void configure (const Search& search); + /// \attention Do not call this function while a search is running. + void configure(const Search& search); - void appendStage (SearchStage *stage); - ///< The ownership of \a stage is transferred to *this. - /// - /// \attention Do no call this function while this Operation is running. + void appendStage(SearchStage* stage); + ///< The ownership of \a stage is transferred to *this. + /// + /// \attention Do no call this function while this Operation is running. - const Search& getSearch() const; - + const Search& getSearch() const; }; } diff --git a/apps/opencs/model/tools/searchstage.cpp b/apps/opencs/model/tools/searchstage.cpp index 7cd3f49243..074a846871 100644 --- a/apps/opencs/model/tools/searchstage.cpp +++ b/apps/opencs/model/tools/searchstage.cpp @@ -4,26 +4,28 @@ #include "searchoperation.hpp" -CSMTools::SearchStage::SearchStage (const CSMWorld::IdTableBase *model) -: mModel (model), mOperation (nullptr) -{} +CSMTools::SearchStage::SearchStage(const CSMWorld::IdTableBase* model) + : mModel(model) + , mOperation(nullptr) +{ +} int CSMTools::SearchStage::setup() { if (mOperation) mSearch = mOperation->getSearch(); - mSearch.configure (mModel); - + mSearch.configure(mModel); + return mModel->rowCount(); } -void CSMTools::SearchStage::perform (int stage, CSMDoc::Messages& messages) +void CSMTools::SearchStage::perform(int stage, CSMDoc::Messages& messages) { - mSearch.searchRow (mModel, stage, messages); + mSearch.searchRow(mModel, stage, messages); } -void CSMTools::SearchStage::setOperation (const SearchOperation *operation) +void CSMTools::SearchStage::setOperation(const SearchOperation* operation) { mOperation = operation; } diff --git a/apps/opencs/model/tools/searchstage.hpp b/apps/opencs/model/tools/searchstage.hpp index 86abf31a34..6ce98c84f2 100644 --- a/apps/opencs/model/tools/searchstage.hpp +++ b/apps/opencs/model/tools/searchstage.hpp @@ -13,24 +13,23 @@ namespace CSMWorld namespace CSMTools { class SearchOperation; - + class SearchStage : public CSMDoc::Stage { - const CSMWorld::IdTableBase *mModel; - Search mSearch; - const SearchOperation *mOperation; - - public: + const CSMWorld::IdTableBase* mModel; + Search mSearch; + const SearchOperation* mOperation; - SearchStage (const CSMWorld::IdTableBase *model); + public: + SearchStage(const CSMWorld::IdTableBase* model); - int setup() override; - ///< \return number of steps + int setup() override; + ///< \return number of steps - void perform (int stage, CSMDoc::Messages& messages) override; - ///< Messages resulting from this stage will be appended to \a messages. + void perform(int stage, CSMDoc::Messages& messages) override; + ///< Messages resulting from this stage will be appended to \a messages. - void setOperation (const SearchOperation *operation); + void setOperation(const SearchOperation* operation); }; } diff --git a/apps/opencs/model/tools/skillcheck.cpp b/apps/opencs/model/tools/skillcheck.cpp index c5b38dc1e0..8fd1f5f664 100644 --- a/apps/opencs/model/tools/skillcheck.cpp +++ b/apps/opencs/model/tools/skillcheck.cpp @@ -4,8 +4,8 @@ #include "../world/universalid.hpp" -CSMTools::SkillCheckStage::SkillCheckStage (const CSMWorld::IdCollection& skills) -: mSkills (skills) +CSMTools::SkillCheckStage::SkillCheckStage(const CSMWorld::IdCollection& skills) + : mSkills(skills) { mIgnoreBaseRecords = false; } @@ -17,9 +17,9 @@ int CSMTools::SkillCheckStage::setup() return mSkills.getSize(); } -void CSMTools::SkillCheckStage::perform (int stage, CSMDoc::Messages& messages) +void CSMTools::SkillCheckStage::perform(int stage, CSMDoc::Messages& messages) { - const CSMWorld::Record& record = mSkills.getRecord (stage); + const CSMWorld::Record& record = mSkills.getRecord(stage); // Skip "Base" records (setting!) and "Deleted" records if ((mIgnoreBaseRecords && record.mState == CSMWorld::RecordBase::State_BaseOnly) || record.isDeleted()) @@ -27,13 +27,13 @@ void CSMTools::SkillCheckStage::perform (int stage, CSMDoc::Messages& messages) const ESM::Skill& skill = record.get(); - CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Skill, skill.mId); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Skill, skill.mId); if (skill.mDescription.empty()) messages.add(id, "Description is missing", "", CSMDoc::Message::Severity_Warning); - for (int i=0; i<4; ++i) - if (skill.mData.mUseValue[i]<0) + for (int i = 0; i < 4; ++i) + if (skill.mData.mUseValue[i] < 0) { messages.add(id, "Use value #" + std::to_string(i) + " is negative", "", CSMDoc::Message::Severity_Error); } diff --git a/apps/opencs/model/tools/skillcheck.hpp b/apps/opencs/model/tools/skillcheck.hpp index f13a5b7a29..c88f7e3715 100644 --- a/apps/opencs/model/tools/skillcheck.hpp +++ b/apps/opencs/model/tools/skillcheck.hpp @@ -12,18 +12,17 @@ namespace CSMTools /// \brief VerifyStage: make sure that skill records are internally consistent class SkillCheckStage : public CSMDoc::Stage { - const CSMWorld::IdCollection& mSkills; - bool mIgnoreBaseRecords; + const CSMWorld::IdCollection& mSkills; + bool mIgnoreBaseRecords; - public: + public: + SkillCheckStage(const CSMWorld::IdCollection& skills); - SkillCheckStage (const CSMWorld::IdCollection& skills); + int setup() override; + ///< \return number of steps - int setup() override; - ///< \return number of steps - - void perform (int stage, CSMDoc::Messages& messages) override; - ///< Messages resulting from this tage will be appended to \a messages. + void perform(int stage, CSMDoc::Messages& messages) override; + ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/soundcheck.cpp b/apps/opencs/model/tools/soundcheck.cpp index c0d893f1a1..cc57eb6017 100644 --- a/apps/opencs/model/tools/soundcheck.cpp +++ b/apps/opencs/model/tools/soundcheck.cpp @@ -4,10 +4,10 @@ #include "../world/universalid.hpp" -CSMTools::SoundCheckStage::SoundCheckStage (const CSMWorld::IdCollection &sounds, - const CSMWorld::Resources &soundfiles) - : mSounds (sounds), - mSoundFiles (soundfiles) +CSMTools::SoundCheckStage::SoundCheckStage( + const CSMWorld::IdCollection& sounds, const CSMWorld::Resources& soundfiles) + : mSounds(sounds) + , mSoundFiles(soundfiles) { mIgnoreBaseRecords = false; } @@ -19,9 +19,9 @@ int CSMTools::SoundCheckStage::setup() return mSounds.getSize(); } -void CSMTools::SoundCheckStage::perform (int stage, CSMDoc::Messages& messages) +void CSMTools::SoundCheckStage::perform(int stage, CSMDoc::Messages& messages) { - const CSMWorld::Record& record = mSounds.getRecord (stage); + const CSMWorld::Record& record = mSounds.getRecord(stage); // Skip "Base" records (setting!) and "Deleted" records if ((mIgnoreBaseRecords && record.mState == CSMWorld::RecordBase::State_BaseOnly) || record.isDeleted()) @@ -29,9 +29,9 @@ void CSMTools::SoundCheckStage::perform (int stage, CSMDoc::Messages& messages) const ESM::Sound& sound = record.get(); - CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Sound, sound.mId); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Sound, sound.mId); - if (sound.mData.mMinRange>sound.mData.mMaxRange) + if (sound.mData.mMinRange > sound.mData.mMaxRange) { messages.add(id, "Minimum range is larger than maximum range", "", CSMDoc::Message::Severity_Warning); } diff --git a/apps/opencs/model/tools/soundcheck.hpp b/apps/opencs/model/tools/soundcheck.hpp index fc3255c538..d97ffe9ab4 100644 --- a/apps/opencs/model/tools/soundcheck.hpp +++ b/apps/opencs/model/tools/soundcheck.hpp @@ -3,8 +3,8 @@ #include -#include "../world/resources.hpp" #include "../world/idcollection.hpp" +#include "../world/resources.hpp" #include "../doc/stage.hpp" @@ -13,20 +13,18 @@ namespace CSMTools /// \brief VerifyStage: make sure that sound records are internally consistent class SoundCheckStage : public CSMDoc::Stage { - const CSMWorld::IdCollection& mSounds; - const CSMWorld::Resources &mSoundFiles; - bool mIgnoreBaseRecords; - - public: + const CSMWorld::IdCollection& mSounds; + const CSMWorld::Resources& mSoundFiles; + bool mIgnoreBaseRecords; - SoundCheckStage (const CSMWorld::IdCollection& sounds, - const CSMWorld::Resources &soundfiles); + public: + SoundCheckStage(const CSMWorld::IdCollection& sounds, const CSMWorld::Resources& soundfiles); - int setup() override; - ///< \return number of steps + int setup() override; + ///< \return number of steps - void perform (int stage, CSMDoc::Messages& messages) override; - ///< Messages resulting from this tage will be appended to \a messages. + void perform(int stage, CSMDoc::Messages& messages) override; + ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/soundgencheck.cpp b/apps/opencs/model/tools/soundgencheck.cpp index ef6c211fb3..5168931fc1 100644 --- a/apps/opencs/model/tools/soundgencheck.cpp +++ b/apps/opencs/model/tools/soundgencheck.cpp @@ -5,15 +5,14 @@ #include "../world/refiddata.hpp" #include "../world/universalid.hpp" -#include #include +#include -CSMTools::SoundGenCheckStage::SoundGenCheckStage(const CSMWorld::IdCollection &soundGens, - const CSMWorld::IdCollection &sounds, - const CSMWorld::RefIdCollection &objects) - : mSoundGens(soundGens), - mSounds(sounds), - mObjects(objects) +CSMTools::SoundGenCheckStage::SoundGenCheckStage(const CSMWorld::IdCollection& soundGens, + const CSMWorld::IdCollection& sounds, const CSMWorld::RefIdCollection& objects) + : mSoundGens(soundGens) + , mSounds(sounds) + , mObjects(objects) { mIgnoreBaseRecords = false; } @@ -25,10 +24,10 @@ int CSMTools::SoundGenCheckStage::setup() return mSoundGens.getSize(); } -void CSMTools::SoundGenCheckStage::perform(int stage, CSMDoc::Messages &messages) +void CSMTools::SoundGenCheckStage::perform(int stage, CSMDoc::Messages& messages) { - const CSMWorld::Record &record = mSoundGens.getRecord(stage); - + const CSMWorld::Record& record = mSoundGens.getRecord(stage); + // Skip "Base" records (setting!) and "Deleted" records if ((mIgnoreBaseRecords && record.mState == CSMWorld::RecordBase::State_BaseOnly) || record.isDeleted()) return; @@ -41,7 +40,8 @@ void CSMTools::SoundGenCheckStage::perform(int stage, CSMDoc::Messages &messages CSMWorld::RefIdData::LocalIndex creatureIndex = mObjects.getDataSet().searchId(soundGen.mCreature); if (creatureIndex.first == -1) { - messages.add(id, "Creature '" + soundGen.mCreature + "' doesn't exist", "", CSMDoc::Message::Severity_Error); + messages.add( + id, "Creature '" + soundGen.mCreature + "' doesn't exist", "", CSMDoc::Message::Severity_Error); } else if (creatureIndex.second != CSMWorld::UniversalId::Type_Creature) { diff --git a/apps/opencs/model/tools/soundgencheck.hpp b/apps/opencs/model/tools/soundgencheck.hpp index 1a34db5694..a557f0b7d2 100644 --- a/apps/opencs/model/tools/soundgencheck.hpp +++ b/apps/opencs/model/tools/soundgencheck.hpp @@ -17,21 +17,20 @@ namespace CSMTools /// \brief VerifyStage: make sure that sound gen records are internally consistent class SoundGenCheckStage : public CSMDoc::Stage { - const CSMWorld::IdCollection &mSoundGens; - const CSMWorld::IdCollection &mSounds; - const CSMWorld::RefIdCollection &mObjects; - bool mIgnoreBaseRecords; + const CSMWorld::IdCollection& mSoundGens; + const CSMWorld::IdCollection& mSounds; + const CSMWorld::RefIdCollection& mObjects; + bool mIgnoreBaseRecords; - public: - SoundGenCheckStage(const CSMWorld::IdCollection &soundGens, - const CSMWorld::IdCollection &sounds, - const CSMWorld::RefIdCollection &objects); + public: + SoundGenCheckStage(const CSMWorld::IdCollection& soundGens, + const CSMWorld::IdCollection& sounds, const CSMWorld::RefIdCollection& objects); - int setup() override; - ///< \return number of steps + int setup() override; + ///< \return number of steps - void perform(int stage, CSMDoc::Messages &messages) override; - ///< Messages resulting from this stage will be appended to \a messages. + void perform(int stage, CSMDoc::Messages& messages) override; + ///< Messages resulting from this stage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/spellcheck.cpp b/apps/opencs/model/tools/spellcheck.cpp index eb2302aa70..066b50b744 100644 --- a/apps/opencs/model/tools/spellcheck.cpp +++ b/apps/opencs/model/tools/spellcheck.cpp @@ -4,9 +4,8 @@ #include "../prefs/state.hpp" - -CSMTools::SpellCheckStage::SpellCheckStage (const CSMWorld::IdCollection& spells) -: mSpells (spells) +CSMTools::SpellCheckStage::SpellCheckStage(const CSMWorld::IdCollection& spells) + : mSpells(spells) { mIgnoreBaseRecords = false; } @@ -18,9 +17,9 @@ int CSMTools::SpellCheckStage::setup() return mSpells.getSize(); } -void CSMTools::SpellCheckStage::perform (int stage, CSMDoc::Messages& messages) +void CSMTools::SpellCheckStage::perform(int stage, CSMDoc::Messages& messages) { - const CSMWorld::Record& record = mSpells.getRecord (stage); + const CSMWorld::Record& record = mSpells.getRecord(stage); // Skip "Base" records (setting!) and "Deleted" records if ((mIgnoreBaseRecords && record.mState == CSMWorld::RecordBase::State_BaseOnly) || record.isDeleted()) @@ -28,14 +27,14 @@ void CSMTools::SpellCheckStage::perform (int stage, CSMDoc::Messages& messages) const ESM::Spell& spell = record.get(); - CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Spell, spell.mId); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Spell, spell.mId); // test for empty name if (spell.mName.empty()) messages.add(id, "Name is missing", "", CSMDoc::Message::Severity_Error); // test for invalid cost values - if (spell.mData.mCost<0) + if (spell.mData.mCost < 0) messages.add(id, "Spell cost is negative", "", CSMDoc::Message::Severity_Error); /// \todo check data members that can't be edited in the table view diff --git a/apps/opencs/model/tools/spellcheck.hpp b/apps/opencs/model/tools/spellcheck.hpp index 1a8d3d0237..02eabe6f9f 100644 --- a/apps/opencs/model/tools/spellcheck.hpp +++ b/apps/opencs/model/tools/spellcheck.hpp @@ -12,18 +12,17 @@ namespace CSMTools /// \brief VerifyStage: make sure that spell records are internally consistent class SpellCheckStage : public CSMDoc::Stage { - const CSMWorld::IdCollection& mSpells; - bool mIgnoreBaseRecords; + const CSMWorld::IdCollection& mSpells; + bool mIgnoreBaseRecords; - public: + public: + SpellCheckStage(const CSMWorld::IdCollection& spells); - SpellCheckStage (const CSMWorld::IdCollection& spells); + int setup() override; + ///< \return number of steps - int setup() override; - ///< \return number of steps - - void perform (int stage, CSMDoc::Messages& messages) override; - ///< Messages resulting from this tage will be appended to \a messages. + void perform(int stage, CSMDoc::Messages& messages) override; + ///< Messages resulting from this tage will be appended to \a messages. }; } diff --git a/apps/opencs/model/tools/startscriptcheck.cpp b/apps/opencs/model/tools/startscriptcheck.cpp index 0dc8f9771d..f41598c43f 100644 --- a/apps/opencs/model/tools/startscriptcheck.cpp +++ b/apps/opencs/model/tools/startscriptcheck.cpp @@ -4,17 +4,17 @@ #include -CSMTools::StartScriptCheckStage::StartScriptCheckStage ( - const CSMWorld::IdCollection& startScripts, - const CSMWorld::IdCollection& scripts) -: mStartScripts (startScripts), mScripts (scripts) +CSMTools::StartScriptCheckStage::StartScriptCheckStage( + const CSMWorld::IdCollection& startScripts, const CSMWorld::IdCollection& scripts) + : mStartScripts(startScripts) + , mScripts(scripts) { mIgnoreBaseRecords = false; } void CSMTools::StartScriptCheckStage::perform(int stage, CSMDoc::Messages& messages) { - const CSMWorld::Record& record = mStartScripts.getRecord (stage); + const CSMWorld::Record& record = mStartScripts.getRecord(stage); // Skip "Base" records (setting!) and "Deleted" records if ((mIgnoreBaseRecords && record.mState == CSMWorld::RecordBase::State_BaseOnly) || record.isDeleted()) @@ -22,9 +22,9 @@ void CSMTools::StartScriptCheckStage::perform(int stage, CSMDoc::Messages& messa std::string scriptId = record.get().mId; - CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_StartScript, scriptId); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_StartScript, scriptId); - if (mScripts.searchId (Misc::StringUtils::lowerCase (scriptId))==-1) + if (mScripts.searchId(Misc::StringUtils::lowerCase(scriptId)) == -1) messages.add(id, "Start script " + scriptId + " does not exist", "", CSMDoc::Message::Severity_Error); } diff --git a/apps/opencs/model/tools/startscriptcheck.hpp b/apps/opencs/model/tools/startscriptcheck.hpp index 4113090793..6283ecfeff 100644 --- a/apps/opencs/model/tools/startscriptcheck.hpp +++ b/apps/opencs/model/tools/startscriptcheck.hpp @@ -1,8 +1,8 @@ #ifndef CSM_TOOLS_STARTSCRIPTCHECK_H #define CSM_TOOLS_STARTSCRIPTCHECK_H -#include #include +#include #include "../doc/stage.hpp" @@ -12,17 +12,16 @@ namespace CSMTools { class StartScriptCheckStage : public CSMDoc::Stage { - const CSMWorld::IdCollection& mStartScripts; - const CSMWorld::IdCollection& mScripts; - bool mIgnoreBaseRecords; - - public: + const CSMWorld::IdCollection& mStartScripts; + const CSMWorld::IdCollection& mScripts; + bool mIgnoreBaseRecords; - StartScriptCheckStage (const CSMWorld::IdCollection& startScripts, - const CSMWorld::IdCollection& scripts); + public: + StartScriptCheckStage(const CSMWorld::IdCollection& startScripts, + const CSMWorld::IdCollection& scripts); - void perform(int stage, CSMDoc::Messages& messages) override; - int setup() override; + void perform(int stage, CSMDoc::Messages& messages) override; + int setup() override; }; } diff --git a/apps/opencs/model/tools/tools.cpp b/apps/opencs/model/tools/tools.cpp index 5c2b822f3b..e7fc1bf2e1 100644 --- a/apps/opencs/model/tools/tools.cpp +++ b/apps/opencs/model/tools/tools.cpp @@ -1,155 +1,150 @@ #include "tools.hpp" -#include "../doc/state.hpp" -#include "../doc/operation.hpp" #include "../doc/document.hpp" +#include "../doc/operation.hpp" +#include "../doc/state.hpp" #include "../world/data.hpp" #include "../world/universalid.hpp" -#include "reportmodel.hpp" -#include "mandatoryid.hpp" -#include "skillcheck.hpp" +#include "birthsigncheck.hpp" +#include "bodypartcheck.hpp" #include "classcheck.hpp" +#include "enchantmentcheck.hpp" #include "factioncheck.hpp" +#include "gmstcheck.hpp" +#include "journalcheck.hpp" +#include "magiceffectcheck.hpp" +#include "mandatoryid.hpp" +#include "mergeoperation.hpp" +#include "pathgridcheck.hpp" #include "racecheck.hpp" -#include "soundcheck.hpp" -#include "regioncheck.hpp" -#include "birthsigncheck.hpp" -#include "spellcheck.hpp" #include "referenceablecheck.hpp" -#include "scriptcheck.hpp" -#include "bodypartcheck.hpp" #include "referencecheck.hpp" -#include "startscriptcheck.hpp" +#include "regioncheck.hpp" +#include "reportmodel.hpp" +#include "scriptcheck.hpp" #include "searchoperation.hpp" -#include "pathgridcheck.hpp" +#include "skillcheck.hpp" +#include "soundcheck.hpp" #include "soundgencheck.hpp" -#include "magiceffectcheck.hpp" -#include "mergeoperation.hpp" -#include "gmstcheck.hpp" +#include "spellcheck.hpp" +#include "startscriptcheck.hpp" #include "topicinfocheck.hpp" -#include "journalcheck.hpp" -#include "enchantmentcheck.hpp" -CSMDoc::OperationHolder *CSMTools::Tools::get (int type) +CSMDoc::OperationHolder* CSMTools::Tools::get(int type) { switch (type) { - case CSMDoc::State_Verifying: return &mVerifier; - case CSMDoc::State_Searching: return &mSearch; - case CSMDoc::State_Merging: return &mMerge; + case CSMDoc::State_Verifying: + return &mVerifier; + case CSMDoc::State_Searching: + return &mSearch; + case CSMDoc::State_Merging: + return &mMerge; } return nullptr; } -const CSMDoc::OperationHolder *CSMTools::Tools::get (int type) const +const CSMDoc::OperationHolder* CSMTools::Tools::get(int type) const { - return const_cast (this)->get (type); + return const_cast(this)->get(type); } -CSMDoc::OperationHolder *CSMTools::Tools::getVerifier() +CSMDoc::OperationHolder* CSMTools::Tools::getVerifier() { if (!mVerifierOperation) { - mVerifierOperation = new CSMDoc::Operation (CSMDoc::State_Verifying, false); + mVerifierOperation = new CSMDoc::Operation(CSMDoc::State_Verifying, false); - connect (&mVerifier, &CSMDoc::OperationHolder::progress, this, &Tools::progress); - connect (&mVerifier, &CSMDoc::OperationHolder::done, this, &Tools::done); - connect (&mVerifier, &CSMDoc::OperationHolder::reportMessage, - this, &Tools::verifierMessage); + connect(&mVerifier, &CSMDoc::OperationHolder::progress, this, &Tools::progress); + connect(&mVerifier, &CSMDoc::OperationHolder::done, this, &Tools::done); + connect(&mVerifier, &CSMDoc::OperationHolder::reportMessage, this, &Tools::verifierMessage); - std::vector mandatoryIds {"Day", "DaysPassed", "GameHour", "Month", "PCRace"}; + std::vector mandatoryIds{ "Day", "DaysPassed", "GameHour", "Month", "PCRace" }; - mVerifierOperation->appendStage (new MandatoryIdStage (mData.getGlobals(), - CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Globals), mandatoryIds)); + mVerifierOperation->appendStage(new MandatoryIdStage( + mData.getGlobals(), CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Globals), mandatoryIds)); - mVerifierOperation->appendStage (new SkillCheckStage (mData.getSkills())); + mVerifierOperation->appendStage(new SkillCheckStage(mData.getSkills())); - mVerifierOperation->appendStage (new ClassCheckStage (mData.getClasses())); + mVerifierOperation->appendStage(new ClassCheckStage(mData.getClasses())); - mVerifierOperation->appendStage (new FactionCheckStage (mData.getFactions())); + mVerifierOperation->appendStage(new FactionCheckStage(mData.getFactions())); - mVerifierOperation->appendStage (new RaceCheckStage (mData.getRaces())); + mVerifierOperation->appendStage(new RaceCheckStage(mData.getRaces())); - mVerifierOperation->appendStage (new SoundCheckStage (mData.getSounds(), mData.getResources (CSMWorld::UniversalId::Type_SoundsRes))); + mVerifierOperation->appendStage( + new SoundCheckStage(mData.getSounds(), mData.getResources(CSMWorld::UniversalId::Type_SoundsRes))); + + mVerifierOperation->appendStage(new RegionCheckStage(mData.getRegions())); + + mVerifierOperation->appendStage( + new BirthsignCheckStage(mData.getBirthsigns(), mData.getResources(CSMWorld::UniversalId::Type_Textures))); - mVerifierOperation->appendStage (new RegionCheckStage (mData.getRegions())); + mVerifierOperation->appendStage(new SpellCheckStage(mData.getSpells())); - mVerifierOperation->appendStage (new BirthsignCheckStage (mData.getBirthsigns(), mData.getResources (CSMWorld::UniversalId::Type_Textures))); + mVerifierOperation->appendStage( + new ReferenceableCheckStage(mData.getReferenceables().getDataSet(), mData.getRaces(), mData.getClasses(), + mData.getFactions(), mData.getScripts(), mData.getResources(CSMWorld::UniversalId::Type_Meshes), + mData.getResources(CSMWorld::UniversalId::Type_Icons), mData.getBodyParts())); - mVerifierOperation->appendStage (new SpellCheckStage (mData.getSpells())); + mVerifierOperation->appendStage(new ReferenceCheckStage( + mData.getReferences(), mData.getReferenceables(), mData.getCells(), mData.getFactions())); - mVerifierOperation->appendStage (new ReferenceableCheckStage (mData.getReferenceables().getDataSet(), mData.getRaces(), mData.getClasses(), mData.getFactions(), mData.getScripts(), - mData.getResources (CSMWorld::UniversalId::Type_Meshes), mData.getResources (CSMWorld::UniversalId::Type_Icons), - mData.getBodyParts())); + mVerifierOperation->appendStage(new ScriptCheckStage(mDocument)); - mVerifierOperation->appendStage (new ReferenceCheckStage(mData.getReferences(), mData.getReferenceables(), mData.getCells(), mData.getFactions())); + mVerifierOperation->appendStage(new StartScriptCheckStage(mData.getStartScripts(), mData.getScripts())); - mVerifierOperation->appendStage (new ScriptCheckStage (mDocument)); + mVerifierOperation->appendStage(new BodyPartCheckStage(mData.getBodyParts(), + mData.getResources(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Meshes)), mData.getRaces())); - mVerifierOperation->appendStage (new StartScriptCheckStage (mData.getStartScripts(), mData.getScripts())); + mVerifierOperation->appendStage(new PathgridCheckStage(mData.getPathgrids())); mVerifierOperation->appendStage( - new BodyPartCheckStage( - mData.getBodyParts(), - mData.getResources( - CSMWorld::UniversalId( CSMWorld::UniversalId::Type_Meshes )), - mData.getRaces() )); - - mVerifierOperation->appendStage (new PathgridCheckStage (mData.getPathgrids())); - - mVerifierOperation->appendStage (new SoundGenCheckStage (mData.getSoundGens(), - mData.getSounds(), - mData.getReferenceables())); - - mVerifierOperation->appendStage (new MagicEffectCheckStage (mData.getMagicEffects(), - mData.getSounds(), - mData.getReferenceables(), - mData.getResources (CSMWorld::UniversalId::Type_Icons), - mData.getResources (CSMWorld::UniversalId::Type_Textures))); - - mVerifierOperation->appendStage (new GmstCheckStage (mData.getGmsts())); - - mVerifierOperation->appendStage (new TopicInfoCheckStage (mData.getTopicInfos(), - mData.getCells(), - mData.getClasses(), - mData.getFactions(), - mData.getGmsts(), - mData.getGlobals(), - mData.getJournals(), - mData.getRaces(), - mData.getRegions(), - mData.getTopics(), - mData.getReferenceables().getDataSet(), - mData.getResources (CSMWorld::UniversalId::Type_SoundsRes))); - - mVerifierOperation->appendStage (new JournalCheckStage(mData.getJournals(), mData.getJournalInfos())); - - mVerifierOperation->appendStage (new EnchantmentCheckStage(mData.getEnchantments())); - - mVerifier.setOperation (mVerifierOperation); + new SoundGenCheckStage(mData.getSoundGens(), mData.getSounds(), mData.getReferenceables())); + + mVerifierOperation->appendStage(new MagicEffectCheckStage(mData.getMagicEffects(), mData.getSounds(), + mData.getReferenceables(), mData.getResources(CSMWorld::UniversalId::Type_Icons), + mData.getResources(CSMWorld::UniversalId::Type_Textures))); + + mVerifierOperation->appendStage(new GmstCheckStage(mData.getGmsts())); + + mVerifierOperation->appendStage(new TopicInfoCheckStage(mData.getTopicInfos(), mData.getCells(), + mData.getClasses(), mData.getFactions(), mData.getGmsts(), mData.getGlobals(), mData.getJournals(), + mData.getRaces(), mData.getRegions(), mData.getTopics(), mData.getReferenceables().getDataSet(), + mData.getResources(CSMWorld::UniversalId::Type_SoundsRes))); + + mVerifierOperation->appendStage(new JournalCheckStage(mData.getJournals(), mData.getJournalInfos())); + + mVerifierOperation->appendStage(new EnchantmentCheckStage(mData.getEnchantments())); + + mVerifier.setOperation(mVerifierOperation); } return &mVerifier; } -CSMTools::Tools::Tools (CSMDoc::Document& document, ToUTF8::FromType encoding) -: mDocument (document), mData (document.getData()), mVerifierOperation (nullptr), - mSearchOperation (nullptr), mMergeOperation (nullptr), mNextReportNumber (0), mEncoding (encoding) +CSMTools::Tools::Tools(CSMDoc::Document& document, ToUTF8::FromType encoding) + : mDocument(document) + , mData(document.getData()) + , mVerifierOperation(nullptr) + , mSearchOperation(nullptr) + , mMergeOperation(nullptr) + , mNextReportNumber(0) + , mEncoding(encoding) { // index 0: load error log - mReports.insert (std::make_pair (mNextReportNumber++, new ReportModel)); - mActiveReports.insert (std::make_pair (CSMDoc::State_Loading, 0)); + mReports.insert(std::make_pair(mNextReportNumber++, new ReportModel)); + mActiveReports.insert(std::make_pair(CSMDoc::State_Loading, 0)); - connect (&mSearch, &CSMDoc::OperationHolder::progress, this, &Tools::progress); - connect (&mSearch, &CSMDoc::OperationHolder::done, this, &Tools::done); - connect (&mSearch, &CSMDoc::OperationHolder::reportMessage, - this, &Tools::verifierMessage); + connect(&mSearch, &CSMDoc::OperationHolder::progress, this, &Tools::progress); + connect(&mSearch, &CSMDoc::OperationHolder::done, this, &Tools::done); + connect(&mSearch, &CSMDoc::OperationHolder::reportMessage, this, &Tools::verifierMessage); - connect (&mMerge, &CSMDoc::OperationHolder::progress, this, &Tools::progress); - connect (&mMerge, &CSMDoc::OperationHolder::done, this, &Tools::done); + connect(&mMerge, &CSMDoc::OperationHolder::progress, this, &Tools::progress); + connect(&mMerge, &CSMDoc::OperationHolder::done, this, &Tools::done); // don't need to connect report message, since there are no messages for merge } @@ -173,105 +168,104 @@ CSMTools::Tools::~Tools() delete mMergeOperation; } - for (std::map::iterator iter (mReports.begin()); iter!=mReports.end(); ++iter) + for (std::map::iterator iter(mReports.begin()); iter != mReports.end(); ++iter) delete iter->second; } -CSMWorld::UniversalId CSMTools::Tools::runVerifier (const CSMWorld::UniversalId& reportId) +CSMWorld::UniversalId CSMTools::Tools::runVerifier(const CSMWorld::UniversalId& reportId) { - int reportNumber = reportId.getType()==CSMWorld::UniversalId::Type_VerificationResults ? - reportId.getIndex() : mNextReportNumber++; + int reportNumber = reportId.getType() == CSMWorld::UniversalId::Type_VerificationResults ? reportId.getIndex() + : mNextReportNumber++; - if (mReports.find (reportNumber)==mReports.end()) - mReports.insert (std::make_pair (reportNumber, new ReportModel)); + if (mReports.find(reportNumber) == mReports.end()) + mReports.insert(std::make_pair(reportNumber, new ReportModel)); mActiveReports[CSMDoc::State_Verifying] = reportNumber; getVerifier()->start(); - return CSMWorld::UniversalId (CSMWorld::UniversalId::Type_VerificationResults, reportNumber); + return CSMWorld::UniversalId(CSMWorld::UniversalId::Type_VerificationResults, reportNumber); } CSMWorld::UniversalId CSMTools::Tools::newSearch() { - mReports.insert (std::make_pair (mNextReportNumber++, new ReportModel (true, false))); + mReports.insert(std::make_pair(mNextReportNumber++, new ReportModel(true, false))); - return CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Search, mNextReportNumber-1); + return CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Search, mNextReportNumber - 1); } -void CSMTools::Tools::runSearch (const CSMWorld::UniversalId& searchId, const Search& search) +void CSMTools::Tools::runSearch(const CSMWorld::UniversalId& searchId, const Search& search) { mActiveReports[CSMDoc::State_Searching] = searchId.getIndex(); if (!mSearchOperation) { - mSearchOperation = new SearchOperation (mDocument); - mSearch.setOperation (mSearchOperation); + mSearchOperation = new SearchOperation(mDocument); + mSearch.setOperation(mSearchOperation); } - mSearchOperation->configure (search); + mSearchOperation->configure(search); mSearch.start(); } -void CSMTools::Tools::runMerge (std::unique_ptr target) +void CSMTools::Tools::runMerge(std::unique_ptr target) { // not setting an active report, because merge does not produce messages if (!mMergeOperation) { - mMergeOperation = new MergeOperation (mDocument, mEncoding); - mMerge.setOperation (mMergeOperation); - connect (mMergeOperation, &MergeOperation::mergeDone, this, &Tools::mergeDone); + mMergeOperation = new MergeOperation(mDocument, mEncoding); + mMerge.setOperation(mMergeOperation); + connect(mMergeOperation, &MergeOperation::mergeDone, this, &Tools::mergeDone); } target->flagAsDirty(); - mMergeOperation->setTarget (std::move(target)); + mMergeOperation->setTarget(std::move(target)); mMerge.start(); } -void CSMTools::Tools::abortOperation (int type) +void CSMTools::Tools::abortOperation(int type) { - if (CSMDoc::OperationHolder *operation = get (type)) + if (CSMDoc::OperationHolder* operation = get(type)) operation->abort(); } int CSMTools::Tools::getRunningOperations() const { - static const int sOperations[] = - { - CSMDoc::State_Verifying, - CSMDoc::State_Searching, - CSMDoc::State_Merging, + static const int sOperations[] = { + CSMDoc::State_Verifying, + CSMDoc::State_Searching, + CSMDoc::State_Merging, -1, }; int result = 0; - for (int i=0; sOperations[i]!=-1; ++i) - if (const CSMDoc::OperationHolder *operation = get (sOperations[i])) + for (int i = 0; sOperations[i] != -1; ++i) + if (const CSMDoc::OperationHolder* operation = get(sOperations[i])) if (operation->isRunning()) result |= sOperations[i]; return result; } -CSMTools::ReportModel *CSMTools::Tools::getReport (const CSMWorld::UniversalId& id) +CSMTools::ReportModel* CSMTools::Tools::getReport(const CSMWorld::UniversalId& id) { - if (id.getType()!=CSMWorld::UniversalId::Type_VerificationResults && - id.getType()!=CSMWorld::UniversalId::Type_LoadErrorLog && - id.getType()!=CSMWorld::UniversalId::Type_Search) - throw std::logic_error ("invalid request for report model: " + id.toString()); + if (id.getType() != CSMWorld::UniversalId::Type_VerificationResults + && id.getType() != CSMWorld::UniversalId::Type_LoadErrorLog + && id.getType() != CSMWorld::UniversalId::Type_Search) + throw std::logic_error("invalid request for report model: " + id.toString()); - return mReports.at (id.getIndex()); + return mReports.at(id.getIndex()); } -void CSMTools::Tools::verifierMessage (const CSMDoc::Message& message, int type) +void CSMTools::Tools::verifierMessage(const CSMDoc::Message& message, int type) { - std::map::iterator iter = mActiveReports.find (type); + std::map::iterator iter = mActiveReports.find(type); - if (iter!=mActiveReports.end()) - mReports[iter->second]->add (message); + if (iter != mActiveReports.end()) + mReports[iter->second]->add(message); } diff --git a/apps/opencs/model/tools/tools.hpp b/apps/opencs/model/tools/tools.hpp index 93ab9b174d..8481b58735 100644 --- a/apps/opencs/model/tools/tools.hpp +++ b/apps/opencs/model/tools/tools.hpp @@ -1,8 +1,8 @@ #ifndef CSM_TOOLS_TOOLS_H #define CSM_TOOLS_TOOLS_H -#include #include +#include #include @@ -31,73 +31,72 @@ namespace CSMTools class Tools : public QObject { - Q_OBJECT - - CSMDoc::Document& mDocument; - CSMWorld::Data& mData; - CSMDoc::Operation *mVerifierOperation; - CSMDoc::OperationHolder mVerifier; - SearchOperation *mSearchOperation; - CSMDoc::OperationHolder mSearch; - MergeOperation *mMergeOperation; - CSMDoc::OperationHolder mMerge; - std::map mReports; - int mNextReportNumber; - std::map mActiveReports; // type, report number - ToUTF8::FromType mEncoding; + Q_OBJECT - // not implemented - Tools (const Tools&); - Tools& operator= (const Tools&); + CSMDoc::Document& mDocument; + CSMWorld::Data& mData; + CSMDoc::Operation* mVerifierOperation; + CSMDoc::OperationHolder mVerifier; + SearchOperation* mSearchOperation; + CSMDoc::OperationHolder mSearch; + MergeOperation* mMergeOperation; + CSMDoc::OperationHolder mMerge; + std::map mReports; + int mNextReportNumber; + std::map mActiveReports; // type, report number + ToUTF8::FromType mEncoding; - CSMDoc::OperationHolder *getVerifier(); + // not implemented + Tools(const Tools&); + Tools& operator=(const Tools&); - CSMDoc::OperationHolder *get (int type); - ///< Returns a 0-pointer, if operation hasn't been used yet. + CSMDoc::OperationHolder* getVerifier(); - const CSMDoc::OperationHolder *get (int type) const; - ///< Returns a 0-pointer, if operation hasn't been used yet. + CSMDoc::OperationHolder* get(int type); + ///< Returns a 0-pointer, if operation hasn't been used yet. - public: + const CSMDoc::OperationHolder* get(int type) const; + ///< Returns a 0-pointer, if operation hasn't been used yet. - Tools (CSMDoc::Document& document, ToUTF8::FromType encoding); + public: + Tools(CSMDoc::Document& document, ToUTF8::FromType encoding); - virtual ~Tools(); + virtual ~Tools(); - /// \param reportId If a valid VerificationResults ID, run verifier for the - /// specified report instead of creating a new one. - /// - /// \return ID of the report for this verification run - CSMWorld::UniversalId runVerifier (const CSMWorld::UniversalId& reportId = CSMWorld::UniversalId()); + /// \param reportId If a valid VerificationResults ID, run verifier for the + /// specified report instead of creating a new one. + /// + /// \return ID of the report for this verification run + CSMWorld::UniversalId runVerifier(const CSMWorld::UniversalId& reportId = CSMWorld::UniversalId()); - /// Return ID of the report for this search. - CSMWorld::UniversalId newSearch(); + /// Return ID of the report for this search. + CSMWorld::UniversalId newSearch(); - void runSearch (const CSMWorld::UniversalId& searchId, const Search& search); + void runSearch(const CSMWorld::UniversalId& searchId, const Search& search); - void runMerge (std::unique_ptr target); + void runMerge(std::unique_ptr target); - void abortOperation (int type); - ///< \attention The operation is not aborted immediately. + void abortOperation(int type); + ///< \attention The operation is not aborted immediately. - int getRunningOperations() const; + int getRunningOperations() const; - ReportModel *getReport (const CSMWorld::UniversalId& id); - ///< The ownership of the returned report is not transferred. + ReportModel* getReport(const CSMWorld::UniversalId& id); + ///< The ownership of the returned report is not transferred. - private slots: + private slots: - void verifierMessage (const CSMDoc::Message& message, int type); + void verifierMessage(const CSMDoc::Message& message, int type); - signals: + signals: - void progress (int current, int max, int type); + void progress(int current, int max, int type); - void done (int type, bool failed); + void done(int type, bool failed); - /// \attention When this signal is emitted, *this hands over the ownership of the - /// document. This signal must be handled to avoid a leak. - void mergeDone (CSMDoc::Document *document); + /// \attention When this signal is emitted, *this hands over the ownership of the + /// document. This signal must be handled to avoid a leak. + void mergeDone(CSMDoc::Document* document); }; } diff --git a/apps/opencs/model/tools/topicinfocheck.cpp b/apps/opencs/model/tools/topicinfocheck.cpp index 74643a46ee..2577ba1baf 100644 --- a/apps/opencs/model/tools/topicinfocheck.cpp +++ b/apps/opencs/model/tools/topicinfocheck.cpp @@ -6,31 +6,25 @@ #include "../world/infoselectwrapper.hpp" -CSMTools::TopicInfoCheckStage::TopicInfoCheckStage( - const CSMWorld::InfoCollection& topicInfos, - const CSMWorld::IdCollection& cells, - const CSMWorld::IdCollection& classes, - const CSMWorld::IdCollection& factions, - const CSMWorld::IdCollection& gmsts, - const CSMWorld::IdCollection& globals, - const CSMWorld::IdCollection& journals, - const CSMWorld::IdCollection& races, - const CSMWorld::IdCollection& regions, - const CSMWorld::IdCollection &topics, - const CSMWorld::RefIdData& referencables, +CSMTools::TopicInfoCheckStage::TopicInfoCheckStage(const CSMWorld::InfoCollection& topicInfos, + const CSMWorld::IdCollection& cells, const CSMWorld::IdCollection& classes, + const CSMWorld::IdCollection& factions, const CSMWorld::IdCollection& gmsts, + const CSMWorld::IdCollection& globals, const CSMWorld::IdCollection& journals, + const CSMWorld::IdCollection& races, const CSMWorld::IdCollection& regions, + const CSMWorld::IdCollection& topics, const CSMWorld::RefIdData& referencables, const CSMWorld::Resources& soundFiles) - : mTopicInfos(topicInfos), - mCells(cells), - mClasses(classes), - mFactions(factions), - mGameSettings(gmsts), - mGlobals(globals), - mJournals(journals), - mRaces(races), - mRegions(regions), - mTopics(topics), - mReferencables(referencables), - mSoundFiles(soundFiles) + : mTopicInfos(topicInfos) + , mCells(cells) + , mClasses(classes) + , mFactions(factions) + , mGameSettings(gmsts) + , mGlobals(globals) + , mJournals(journals) + , mRaces(races) + , mRegions(regions) + , mTopics(topics) + , mReferencables(referencables) + , mSoundFiles(soundFiles) { mIgnoreBaseRecords = false; } @@ -162,8 +156,8 @@ void CSMTools::TopicInfoCheckStage::perform(int stage, CSMDoc::Messages& message // Verification functions -bool CSMTools::TopicInfoCheckStage::verifyActor(const std::string& actor, const CSMWorld::UniversalId& id, - CSMDoc::Messages& messages) +bool CSMTools::TopicInfoCheckStage::verifyActor( + const std::string& actor, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages) { CSMWorld::RefIdData::LocalIndex index = mReferencables.searchId(actor); @@ -181,7 +175,8 @@ bool CSMTools::TopicInfoCheckStage::verifyActor(const std::string& actor, const { CSMWorld::UniversalId tempId(index.second, actor); std::ostringstream stream; - stream << "Object '" << actor << "' has invalid type " << tempId.getTypeName() << " (an actor must be an NPC or a creature)"; + stream << "Object '" << actor << "' has invalid type " << tempId.getTypeName() + << " (an actor must be an NPC or a creature)"; messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error); return false; } @@ -189,8 +184,8 @@ bool CSMTools::TopicInfoCheckStage::verifyActor(const std::string& actor, const return true; } -bool CSMTools::TopicInfoCheckStage::verifyCell(const std::string& cell, const CSMWorld::UniversalId& id, - CSMDoc::Messages& messages) +bool CSMTools::TopicInfoCheckStage::verifyCell( + const std::string& cell, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages) { if (mCellNames.find(cell) == mCellNames.end()) { @@ -201,8 +196,8 @@ bool CSMTools::TopicInfoCheckStage::verifyCell(const std::string& cell, const CS return true; } -bool CSMTools::TopicInfoCheckStage::verifyFactionRank(const std::string& factionName, int rank, const CSMWorld::UniversalId& id, - CSMDoc::Messages& messages) +bool CSMTools::TopicInfoCheckStage::verifyFactionRank( + const std::string& factionName, int rank, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages) { if (rank < -1) { @@ -214,7 +209,7 @@ bool CSMTools::TopicInfoCheckStage::verifyFactionRank(const std::string& faction int index = mFactions.searchId(factionName); - const ESM::Faction &faction = mFactions.getRecord(index).get(); + const ESM::Faction& faction = mFactions.getRecord(index).get(); int limit = 0; for (; limit < 10; ++limit) @@ -236,8 +231,8 @@ bool CSMTools::TopicInfoCheckStage::verifyFactionRank(const std::string& faction return true; } -bool CSMTools::TopicInfoCheckStage::verifyItem(const std::string& item, const CSMWorld::UniversalId& id, - CSMDoc::Messages& messages) +bool CSMTools::TopicInfoCheckStage::verifyItem( + const std::string& item, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages) { CSMWorld::RefIdData::LocalIndex index = mReferencables.searchId(item); @@ -274,7 +269,8 @@ bool CSMTools::TopicInfoCheckStage::verifyItem(const std::string& item, const CS { CSMWorld::UniversalId tempId(index.second, item); std::ostringstream stream; - stream << "Object '" << item << "' has invalid type " << tempId.getTypeName() << " (an item can be a potion, an armor piece, a book and so on)"; + stream << "Object '" << item << "' has invalid type " << tempId.getTypeName() + << " (an item can be a potion, an armor piece, a book and so on)"; messages.add(id, stream.str(), "", CSMDoc::Message::Severity_Error); return false; } @@ -284,8 +280,8 @@ bool CSMTools::TopicInfoCheckStage::verifyItem(const std::string& item, const CS return true; } -bool CSMTools::TopicInfoCheckStage::verifySelectStruct(const ESM::DialInfo::SelectStruct& select, - const CSMWorld::UniversalId& id, CSMDoc::Messages& messages) +bool CSMTools::TopicInfoCheckStage::verifySelectStruct( + const ESM::DialInfo::SelectStruct& select, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages) { CSMWorld::ConstInfoSelectWrapper infoCondition(select); @@ -301,13 +297,27 @@ bool CSMTools::TopicInfoCheckStage::verifySelectStruct(const ESM::DialInfo::Sele switch (select.mValue.getType()) { - case ESM::VT_None: stream << "None"; break; - case ESM::VT_Short: stream << "Short"; break; - case ESM::VT_Int: stream << "Int"; break; - case ESM::VT_Long: stream << "Long"; break; - case ESM::VT_Float: stream << "Float"; break; - case ESM::VT_String: stream << "String"; break; - default: stream << "unknown"; break; + case ESM::VT_None: + stream << "None"; + break; + case ESM::VT_Short: + stream << "Short"; + break; + case ESM::VT_Int: + stream << "Int"; + break; + case ESM::VT_Long: + stream << "Long"; + break; + case ESM::VT_Float: + stream << "Float"; + break; + case ESM::VT_String: + stream << "String"; + break; + default: + stream << "unknown"; + break; } stream << " type"; @@ -316,58 +326,60 @@ bool CSMTools::TopicInfoCheckStage::verifySelectStruct(const ESM::DialInfo::Sele } else if (infoCondition.conditionIsAlwaysTrue()) { - messages.add(id, "Condition '" + infoCondition.toString() + "' is always true", "", CSMDoc::Message::Severity_Warning); + messages.add( + id, "Condition '" + infoCondition.toString() + "' is always true", "", CSMDoc::Message::Severity_Warning); return false; } else if (infoCondition.conditionIsNeverTrue()) { - messages.add(id, "Condition '" + infoCondition.toString() + "' is never true", "", CSMDoc::Message::Severity_Warning); + messages.add( + id, "Condition '" + infoCondition.toString() + "' is never true", "", CSMDoc::Message::Severity_Warning); return false; } // Id checks - if (infoCondition.getFunctionName() == CSMWorld::ConstInfoSelectWrapper::Function_Global && - !verifyId(infoCondition.getVariableName(), mGlobals, id, messages)) + if (infoCondition.getFunctionName() == CSMWorld::ConstInfoSelectWrapper::Function_Global + && !verifyId(infoCondition.getVariableName(), mGlobals, id, messages)) { return false; } - else if (infoCondition.getFunctionName() == CSMWorld::ConstInfoSelectWrapper::Function_Journal && - !verifyId(infoCondition.getVariableName(), mJournals, id, messages)) + else if (infoCondition.getFunctionName() == CSMWorld::ConstInfoSelectWrapper::Function_Journal + && !verifyId(infoCondition.getVariableName(), mJournals, id, messages)) { return false; } - else if (infoCondition.getFunctionName() == CSMWorld::ConstInfoSelectWrapper::Function_Item && - !verifyItem(infoCondition.getVariableName(), id, messages)) + else if (infoCondition.getFunctionName() == CSMWorld::ConstInfoSelectWrapper::Function_Item + && !verifyItem(infoCondition.getVariableName(), id, messages)) { return false; } - else if (infoCondition.getFunctionName() == CSMWorld::ConstInfoSelectWrapper::Function_Dead && - !verifyActor(infoCondition.getVariableName(), id, messages)) + else if (infoCondition.getFunctionName() == CSMWorld::ConstInfoSelectWrapper::Function_Dead + && !verifyActor(infoCondition.getVariableName(), id, messages)) { return false; } - else if (infoCondition.getFunctionName() == CSMWorld::ConstInfoSelectWrapper::Function_NotId && - !verifyActor(infoCondition.getVariableName(), id, messages)) + else if (infoCondition.getFunctionName() == CSMWorld::ConstInfoSelectWrapper::Function_NotId + && !verifyActor(infoCondition.getVariableName(), id, messages)) { return false; } - else if (infoCondition.getFunctionName() == CSMWorld::ConstInfoSelectWrapper::Function_NotFaction && - !verifyId(infoCondition.getVariableName(), mFactions, id, messages)) + else if (infoCondition.getFunctionName() == CSMWorld::ConstInfoSelectWrapper::Function_NotFaction + && !verifyId(infoCondition.getVariableName(), mFactions, id, messages)) { return false; } - else if (infoCondition.getFunctionName() == CSMWorld::ConstInfoSelectWrapper::Function_NotClass && - !verifyId(infoCondition.getVariableName(), mClasses, id, messages)) + else if (infoCondition.getFunctionName() == CSMWorld::ConstInfoSelectWrapper::Function_NotClass + && !verifyId(infoCondition.getVariableName(), mClasses, id, messages)) { return false; } - else if (infoCondition.getFunctionName() == CSMWorld::ConstInfoSelectWrapper::Function_NotRace && - !verifyId(infoCondition.getVariableName(), mRaces, id, messages)) + else if (infoCondition.getFunctionName() == CSMWorld::ConstInfoSelectWrapper::Function_NotRace + && !verifyId(infoCondition.getVariableName(), mRaces, id, messages)) { return false; } - else if (infoCondition.getFunctionName() == CSMWorld::ConstInfoSelectWrapper::Function_NotCell && - !verifyCell(infoCondition.getVariableName(), id, messages)) + else if (infoCondition.getFunctionName() == CSMWorld::ConstInfoSelectWrapper::Function_NotCell + && !verifyCell(infoCondition.getVariableName(), id, messages)) { return false; } @@ -375,8 +387,8 @@ bool CSMTools::TopicInfoCheckStage::verifySelectStruct(const ESM::DialInfo::Sele return true; } -bool CSMTools::TopicInfoCheckStage::verifySound(const std::string& sound, const CSMWorld::UniversalId& id, - CSMDoc::Messages& messages) +bool CSMTools::TopicInfoCheckStage::verifySound( + const std::string& sound, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages) { if (mSoundFiles.searchId(sound) == -1) { @@ -395,12 +407,14 @@ bool CSMTools::TopicInfoCheckStage::verifyId(const std::string& name, const CSMW if (index == -1) { - messages.add(id, std::string(T::getRecordType()) + " '" + name + "' does not exist", "", CSMDoc::Message::Severity_Error); + messages.add(id, std::string(T::getRecordType()) + " '" + name + "' does not exist", "", + CSMDoc::Message::Severity_Error); return false; } else if (collection.getRecord(index).isDeleted()) { - messages.add(id, "Deleted " + std::string(T::getRecordType()) + " record '" + name + "' is being referenced", "", CSMDoc::Message::Severity_Error); + messages.add(id, "Deleted " + std::string(T::getRecordType()) + " record '" + name + "' is being referenced", + "", CSMDoc::Message::Severity_Error); return false; } diff --git a/apps/opencs/model/tools/topicinfocheck.hpp b/apps/opencs/model/tools/topicinfocheck.hpp index de3fa82ae3..864bca61d2 100644 --- a/apps/opencs/model/tools/topicinfocheck.hpp +++ b/apps/opencs/model/tools/topicinfocheck.hpp @@ -25,19 +25,12 @@ namespace CSMTools class TopicInfoCheckStage : public CSMDoc::Stage { public: - - TopicInfoCheckStage( - const CSMWorld::InfoCollection& topicInfos, - const CSMWorld::IdCollection& cells, - const CSMWorld::IdCollection& classes, - const CSMWorld::IdCollection& factions, - const CSMWorld::IdCollection& gmsts, - const CSMWorld::IdCollection& globals, - const CSMWorld::IdCollection& journals, - const CSMWorld::IdCollection& races, - const CSMWorld::IdCollection& regions, - const CSMWorld::IdCollection& topics, - const CSMWorld::RefIdData& referencables, + TopicInfoCheckStage(const CSMWorld::InfoCollection& topicInfos, + const CSMWorld::IdCollection& cells, const CSMWorld::IdCollection& classes, + const CSMWorld::IdCollection& factions, const CSMWorld::IdCollection& gmsts, + const CSMWorld::IdCollection& globals, const CSMWorld::IdCollection& journals, + const CSMWorld::IdCollection& races, const CSMWorld::IdCollection& regions, + const CSMWorld::IdCollection& topics, const CSMWorld::RefIdData& referencables, const CSMWorld::Resources& soundFiles); int setup() override; @@ -47,7 +40,6 @@ namespace CSMTools ///< Messages resulting from this stage will be appended to \a messages private: - const CSMWorld::InfoCollection& mTopicInfos; const CSMWorld::IdCollection& mCells; @@ -70,11 +62,11 @@ namespace CSMTools // These return false when not successful and write an error bool verifyActor(const std::string& name, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages); bool verifyCell(const std::string& name, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages); - bool verifyFactionRank(const std::string& name, int rank, const CSMWorld::UniversalId& id, - CSMDoc::Messages& messages); + bool verifyFactionRank( + const std::string& name, int rank, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages); bool verifyItem(const std::string& name, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages); - bool verifySelectStruct(const ESM::DialInfo::SelectStruct& select, const CSMWorld::UniversalId& id, - CSMDoc::Messages& messages); + bool verifySelectStruct( + const ESM::DialInfo::SelectStruct& select, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages); bool verifySound(const std::string& name, const CSMWorld::UniversalId& id, CSMDoc::Messages& messages); template diff --git a/apps/opencs/model/world/actoradapter.cpp b/apps/opencs/model/world/actoradapter.cpp index e1c457943d..2e40aa1607 100644 --- a/apps/opencs/model/world/actoradapter.cpp +++ b/apps/opencs/model/world/actoradapter.cpp @@ -73,7 +73,8 @@ namespace CSMWorld void ActorAdapter::RaceData::addOtherDependency(const std::string& id) { - if (!id.empty()) mDependencies.emplace(id); + if (!id.empty()) + mDependencies.emplace(id); } void ActorAdapter::RaceData::reset_data(const std::string& id, bool isBeast) @@ -90,7 +91,6 @@ namespace CSMWorld addOtherDependency(id); } - ActorAdapter::ActorData::ActorData() { mCreature = false; @@ -168,10 +168,12 @@ namespace CSMWorld void ActorAdapter::ActorData::addOtherDependency(const std::string& id) { - if (!id.empty()) mDependencies.emplace(id); + if (!id.empty()) + mDependencies.emplace(id); } - void ActorAdapter::ActorData::reset_data(const std::string& id, const std::string& skeleton, bool isCreature, bool isFemale, RaceDataPtr raceData) + void ActorAdapter::ActorData::reset_data( + const std::string& id, const std::string& skeleton, bool isCreature, bool isFemale, RaceDataPtr raceData) { mId = id; mCreature = isCreature; @@ -183,10 +185,10 @@ namespace CSMWorld // Mark self and race as a dependency addOtherDependency(id); - if (raceData) addOtherDependency(raceData->getId()); + if (raceData) + addOtherDependency(raceData->getId()); } - ActorAdapter::ActorAdapter(Data& data) : mReferenceables(data.getReferenceables()) , mRaces(data.getRaces()) @@ -194,28 +196,21 @@ namespace CSMWorld { // Setup qt slots and signals QAbstractItemModel* refModel = data.getTableModel(UniversalId::Type_Referenceable); - connect(refModel, &QAbstractItemModel::rowsInserted, - this, &ActorAdapter::handleReferenceablesInserted); - connect(refModel, &QAbstractItemModel::dataChanged, - this, &ActorAdapter::handleReferenceableChanged); - connect(refModel, &QAbstractItemModel::rowsAboutToBeRemoved, - this, &ActorAdapter::handleReferenceablesAboutToBeRemoved); + connect(refModel, &QAbstractItemModel::rowsInserted, this, &ActorAdapter::handleReferenceablesInserted); + connect(refModel, &QAbstractItemModel::dataChanged, this, &ActorAdapter::handleReferenceableChanged); + connect(refModel, &QAbstractItemModel::rowsAboutToBeRemoved, this, + &ActorAdapter::handleReferenceablesAboutToBeRemoved); QAbstractItemModel* raceModel = data.getTableModel(UniversalId::Type_Race); - connect(raceModel, &QAbstractItemModel::rowsInserted, - this, &ActorAdapter::handleRacesAboutToBeRemoved); - connect(raceModel, &QAbstractItemModel::dataChanged, - this, &ActorAdapter::handleRaceChanged); - connect(raceModel, &QAbstractItemModel::rowsAboutToBeRemoved, - this, &ActorAdapter::handleRacesAboutToBeRemoved); + connect(raceModel, &QAbstractItemModel::rowsInserted, this, &ActorAdapter::handleRacesAboutToBeRemoved); + connect(raceModel, &QAbstractItemModel::dataChanged, this, &ActorAdapter::handleRaceChanged); + connect(raceModel, &QAbstractItemModel::rowsAboutToBeRemoved, this, &ActorAdapter::handleRacesAboutToBeRemoved); QAbstractItemModel* partModel = data.getTableModel(UniversalId::Type_BodyPart); - connect(partModel, &QAbstractItemModel::rowsInserted, - this, &ActorAdapter::handleBodyPartsInserted); - connect(partModel, &QAbstractItemModel::dataChanged, - this, &ActorAdapter::handleBodyPartChanged); - connect(partModel, &QAbstractItemModel::rowsAboutToBeRemoved, - this, &ActorAdapter::handleBodyPartsAboutToBeRemoved); + connect(partModel, &QAbstractItemModel::rowsInserted, this, &ActorAdapter::handleBodyPartsInserted); + connect(partModel, &QAbstractItemModel::dataChanged, this, &ActorAdapter::handleBodyPartChanged); + connect( + partModel, &QAbstractItemModel::rowsAboutToBeRemoved, this, &ActorAdapter::handleBodyPartsAboutToBeRemoved); } ActorAdapter::ActorDataPtr ActorAdapter::getActorData(const std::string& id) @@ -428,7 +423,8 @@ namespace CSMWorld { // Return cached race data if it exists RaceDataPtr data = mCachedRaces.get(id); - if (data) return data; + if (data) + return data; // Create the race data data = std::make_shared(); @@ -515,10 +511,12 @@ namespace CSMWorld auto& part = partRecord.get(); if (part.mRace == id && part.mData.mType == ESM::BodyPart::MT_Skin && !is1stPersonPart(part.mId)) { - auto type = (ESM::BodyPart::MeshPart) part.mData.mPart; + auto type = (ESM::BodyPart::MeshPart)part.mData.mPart; bool female = part.mData.mFlags & ESM::BodyPart::BPF_Female; - if (female) data->setFemalePart(type, part.mId); - else data->setMalePart(type, part.mId); + if (female) + data->setFemalePart(type, part.mId); + else + data->setMalePart(type, part.mId); } } } @@ -539,7 +537,8 @@ namespace CSMWorld // Add inventory items for (auto& item : npc.mInventory.mList) { - if (item.mCount <= 0) continue; + if (item.mCount <= 0) + continue; std::string itemId = item.mItem; addNpcItem(itemId, data); } @@ -568,7 +567,7 @@ namespace CSMWorld for (auto& part : list) { std::string partId; - auto partType = (ESM::PartReferenceType) part.mPart; + auto partType = (ESM::PartReferenceType)part.mPart; if (data->isFemale()) partId = part.mFemale; @@ -600,15 +599,13 @@ namespace CSMWorld std::vector parts; if (clothing.mData.mType == ESM::Clothing::Robe) { - parts = { - ESM::PRT_Groin, ESM::PRT_Skirt, ESM::PRT_RLeg, ESM::PRT_LLeg, - ESM::PRT_RUpperarm, ESM::PRT_LUpperarm, ESM::PRT_RKnee, ESM::PRT_LKnee, - ESM::PRT_RForearm, ESM::PRT_LForearm, ESM::PRT_Cuirass - }; + parts = { ESM::PRT_Groin, ESM::PRT_Skirt, ESM::PRT_RLeg, ESM::PRT_LLeg, ESM::PRT_RUpperarm, + ESM::PRT_LUpperarm, ESM::PRT_RKnee, ESM::PRT_LKnee, ESM::PRT_RForearm, ESM::PRT_LForearm, + ESM::PRT_Cuirass }; } else if (clothing.mData.mType == ESM::Clothing::Skirt) { - parts = {ESM::PRT_Groin, ESM::PRT_RLeg, ESM::PRT_LLeg}; + parts = { ESM::PRT_Groin, ESM::PRT_RLeg, ESM::PRT_LLeg }; } std::vector reservedList; diff --git a/apps/opencs/model/world/actoradapter.hpp b/apps/opencs/model/world/actoradapter.hpp index d50eacaba0..c144eb7ff4 100644 --- a/apps/opencs/model/world/actoradapter.hpp +++ b/apps/opencs/model/world/actoradapter.hpp @@ -3,12 +3,12 @@ #include #include -#include #include #include +#include -#include #include +#include #include #include @@ -32,7 +32,6 @@ namespace CSMWorld { Q_OBJECT public: - /// A list indexed by ESM::PartReferenceType using ActorPartList = std::map>; /// A list indexed by ESM::BodyPart::MeshPart @@ -40,7 +39,6 @@ namespace CSMWorld /// Tracks unique strings using StringSet = std::unordered_set; - /// Contains base race data shared between actors class RaceData { @@ -67,7 +65,7 @@ namespace CSMWorld /// Marks an additional dependency void addOtherDependency(const std::string& id); /// Clears parts and dependencies - void reset_data(const std::string& raceId, bool isBeast=false); + void reset_data(const std::string& raceId, bool isBeast = false); private: bool handles(ESM::PartReferenceType type) const; @@ -104,7 +102,8 @@ namespace CSMWorld /// Marks an additional dependency for the actor void addOtherDependency(const std::string& id); /// Clears race, parts, and dependencies - void reset_data(const std::string& actorId, const std::string& skeleton="", bool isCreature=false, bool female=true, RaceDataPtr raceData=nullptr); + void reset_data(const std::string& actorId, const std::string& skeleton = "", bool isCreature = false, + bool female = true, RaceDataPtr raceData = nullptr); private: std::string mId; @@ -117,7 +116,6 @@ namespace CSMWorld }; using ActorDataPtr = std::shared_ptr; - ActorAdapter(Data& data); /// Obtains the shared data for a given actor @@ -145,7 +143,6 @@ namespace CSMWorld void handleBodyPartsRemoved(const QModelIndex&, int, int); private: - ActorAdapter(const ActorAdapter&) = delete; ActorAdapter& operator=(const ActorAdapter&) = delete; diff --git a/apps/opencs/model/world/cell.cpp b/apps/opencs/model/world/cell.cpp index 93f3c500d7..dff09aac61 100644 --- a/apps/opencs/model/world/cell.cpp +++ b/apps/opencs/model/world/cell.cpp @@ -2,9 +2,9 @@ #include -void CSMWorld::Cell::load (ESM::ESMReader &esm, bool &isDeleted) +void CSMWorld::Cell::load(ESM::ESMReader& esm, bool& isDeleted) { - ESM::Cell::load (esm, isDeleted, false); + ESM::Cell::load(esm, isDeleted, false); mId = mName; if (isExterior()) diff --git a/apps/opencs/model/world/cell.hpp b/apps/opencs/model/world/cell.hpp index 9f87451a46..c68a701e1a 100644 --- a/apps/opencs/model/world/cell.hpp +++ b/apps/opencs/model/world/cell.hpp @@ -15,8 +15,7 @@ namespace CSMWorld { std::string mId; - void load (ESM::ESMReader &esm, bool &isDeleted); - + void load(ESM::ESMReader& esm, bool& isDeleted); }; } diff --git a/apps/opencs/model/world/cellcoordinates.cpp b/apps/opencs/model/world/cellcoordinates.cpp index d1ac528fa7..14dcadddda 100644 --- a/apps/opencs/model/world/cellcoordinates.cpp +++ b/apps/opencs/model/world/cellcoordinates.cpp @@ -10,12 +10,23 @@ #include #include -CSMWorld::CellCoordinates::CellCoordinates() : mX (0), mY (0) {} +CSMWorld::CellCoordinates::CellCoordinates() + : mX(0) + , mY(0) +{ +} -CSMWorld::CellCoordinates::CellCoordinates (int x, int y) : mX (x), mY (y) {} +CSMWorld::CellCoordinates::CellCoordinates(int x, int y) + : mX(x) + , mY(y) +{ +} -CSMWorld::CellCoordinates::CellCoordinates (const std::pair& coordinates) -: mX (coordinates.first), mY (coordinates.second) {} +CSMWorld::CellCoordinates::CellCoordinates(const std::pair& coordinates) + : mX(coordinates.first) + , mY(coordinates.second) +{ +} int CSMWorld::CellCoordinates::getX() const { @@ -27,30 +38,29 @@ int CSMWorld::CellCoordinates::getY() const return mY; } -CSMWorld::CellCoordinates CSMWorld::CellCoordinates::move (int x, int y) const +CSMWorld::CellCoordinates CSMWorld::CellCoordinates::move(int x, int y) const { - return CellCoordinates (mX + x, mY + y); + return CellCoordinates(mX + x, mY + y); } -std::string CSMWorld::CellCoordinates::getId (const std::string& worldspace) const +std::string CSMWorld::CellCoordinates::getId(const std::string& worldspace) const { // we ignore the worldspace for now, since there is only one (will change in 1.1) return generateId(mX, mY); } -std::string CSMWorld::CellCoordinates::generateId (int x, int y) +std::string CSMWorld::CellCoordinates::generateId(int x, int y) { std::string cellId = "#" + std::to_string(x) + " " + std::to_string(y); return cellId; } -bool CSMWorld::CellCoordinates::isExteriorCell (const std::string& id) +bool CSMWorld::CellCoordinates::isExteriorCell(const std::string& id) { - return (!id.empty() && id[0]=='#'); + return (!id.empty() && id[0] == '#'); } -std::pair CSMWorld::CellCoordinates::fromId ( - const std::string& id) +std::pair CSMWorld::CellCoordinates::fromId(const std::string& id) { // no worldspace for now, needs to be changed for 1.1 if (isExteriorCell(id)) @@ -58,17 +68,17 @@ std::pair CSMWorld::CellCoordinates::fromId ( int x, y; char ignore; - std::istringstream stream (id); + std::istringstream stream(id); if (stream >> ignore >> x >> y) - return std::make_pair (CellCoordinates (x, y), true); + return std::make_pair(CellCoordinates(x, y), true); } - return std::make_pair (CellCoordinates(), false); + return std::make_pair(CellCoordinates(), false); } -std::pair CSMWorld::CellCoordinates::coordinatesToCellIndex (float x, float y) +std::pair CSMWorld::CellCoordinates::coordinatesToCellIndex(float x, float y) { - return std::make_pair (std::floor (x / Constants::CellSizeInUnits), std::floor (y / Constants::CellSizeInUnits)); + return std::make_pair(std::floor(x / Constants::CellSizeInUnits), std::floor(y / Constants::CellSizeInUnits)); } std::pair CSMWorld::CellCoordinates::toTextureCoords(const osg::Vec3d& worldPos) @@ -110,7 +120,8 @@ float CSMWorld::CellCoordinates::vertexGlobalToWorldCoords(int vertexGlobal) int CSMWorld::CellCoordinates::vertexGlobalToInCellCoords(int vertexGlobal) { - return static_cast(vertexGlobal - std::floor(static_cast(vertexGlobal) / (ESM::Land::LAND_SIZE - 1)) * (ESM::Land::LAND_SIZE - 1)); + return static_cast(vertexGlobal + - std::floor(static_cast(vertexGlobal) / (ESM::Land::LAND_SIZE - 1)) * (ESM::Land::LAND_SIZE - 1)); } std::string CSMWorld::CellCoordinates::textureGlobalToCellId(const std::pair& textureGlobal) @@ -127,28 +138,28 @@ std::string CSMWorld::CellCoordinates::vertexGlobalToCellId(const std::pairright.getX()) + if (left.getX() > right.getX()) return false; - return left.getY()& coordinates); - CellCoordinates (const std::pair& coordinates); + int getX() const; - int getX() const; + int getY() const; - int getY() const; + CellCoordinates move(int x, int y) const; + ///< Return a copy of *this, moved by the given offset. - CellCoordinates move (int x, int y) const; - ///< Return a copy of *this, moved by the given offset. + /// Generate cell id string from x and y coordinates + static std::string generateId(int x, int y); - ///Generate cell id string from x and y coordinates - static std::string generateId (int x, int y); + std::string getId(const std::string& worldspace) const; + ///< Return the ID for the cell at these coordinates. - std::string getId (const std::string& worldspace) const; - ///< Return the ID for the cell at these coordinates. + static bool isExteriorCell(const std::string& id); - static bool isExteriorCell (const std::string& id); + /// \return first: CellCoordinates (or 0, 0 if cell does not have coordinates), + /// second: is cell paged? + /// + /// \note The worldspace part of \a id is ignored + static std::pair fromId(const std::string& id); - /// \return first: CellCoordinates (or 0, 0 if cell does not have coordinates), - /// second: is cell paged? - /// - /// \note The worldspace part of \a id is ignored - static std::pair fromId (const std::string& id); + /// \return cell coordinates such that given world coordinates are in it. + static std::pair coordinatesToCellIndex(float x, float y); - /// \return cell coordinates such that given world coordinates are in it. - static std::pair coordinatesToCellIndex (float x, float y); + /// Converts worldspace coordinates to global texture selection, taking in account the texture offset. + static std::pair toTextureCoords(const osg::Vec3d& worldPos); - ///Converts worldspace coordinates to global texture selection, taking in account the texture offset. - static std::pair toTextureCoords(const osg::Vec3d& worldPos); + /// Converts worldspace coordinates to global vertex selection. + static std::pair toVertexCoords(const osg::Vec3d& worldPos); - ///Converts worldspace coordinates to global vertex selection. - static std::pair toVertexCoords(const osg::Vec3d& worldPos); + /// Converts global texture coordinate X to worldspace coordinate, offset by 0.25f. + static float textureGlobalXToWorldCoords(int textureGlobal); - ///Converts global texture coordinate X to worldspace coordinate, offset by 0.25f. - static float textureGlobalXToWorldCoords(int textureGlobal); + /// Converts global texture coordinate Y to worldspace coordinate, offset by 0.25f. + static float textureGlobalYToWorldCoords(int textureGlobal); - ///Converts global texture coordinate Y to worldspace coordinate, offset by 0.25f. - static float textureGlobalYToWorldCoords(int textureGlobal); + /// Converts global vertex coordinate to worldspace coordinate + static float vertexGlobalToWorldCoords(int vertexGlobal); - ///Converts global vertex coordinate to worldspace coordinate - static float vertexGlobalToWorldCoords(int vertexGlobal); + /// Converts global vertex coordinate to local cell's heightmap coordinates + static int vertexGlobalToInCellCoords(int vertexGlobal); - ///Converts global vertex coordinate to local cell's heightmap coordinates - static int vertexGlobalToInCellCoords(int vertexGlobal); + /// Converts global texture coordinates to cell id + static std::string textureGlobalToCellId(const std::pair& textureGlobal); - ///Converts global texture coordinates to cell id - static std::string textureGlobalToCellId(const std::pair& textureGlobal); - - ///Converts global vertex coordinates to cell id - static std::string vertexGlobalToCellId(const std::pair& vertexGlobal); + /// Converts global vertex coordinates to cell id + static std::string vertexGlobalToCellId(const std::pair& vertexGlobal); }; - bool operator== (const CellCoordinates& left, const CellCoordinates& right); - bool operator!= (const CellCoordinates& left, const CellCoordinates& right); - bool operator< (const CellCoordinates& left, const CellCoordinates& right); + bool operator==(const CellCoordinates& left, const CellCoordinates& right); + bool operator!=(const CellCoordinates& left, const CellCoordinates& right); + bool operator<(const CellCoordinates& left, const CellCoordinates& right); - std::ostream& operator<< (std::ostream& stream, const CellCoordinates& coordiantes); + std::ostream& operator<<(std::ostream& stream, const CellCoordinates& coordiantes); } -Q_DECLARE_METATYPE (CSMWorld::CellCoordinates) +Q_DECLARE_METATYPE(CSMWorld::CellCoordinates) #endif diff --git a/apps/opencs/model/world/cellselection.cpp b/apps/opencs/model/world/cellselection.cpp index 2e12a728b8..7ba2aa3129 100644 --- a/apps/opencs/model/world/cellselection.cpp +++ b/apps/opencs/model/world/cellselection.cpp @@ -3,8 +3,8 @@ #include "cellcoordinates.hpp" #include -#include #include +#include CSMWorld::CellSelection::Iterator CSMWorld::CellSelection::begin() const { @@ -16,19 +16,19 @@ CSMWorld::CellSelection::Iterator CSMWorld::CellSelection::end() const return mCells.end(); } -bool CSMWorld::CellSelection::add (const CellCoordinates& coordinates) +bool CSMWorld::CellSelection::add(const CellCoordinates& coordinates) { - return mCells.insert (coordinates).second; + return mCells.insert(coordinates).second; } -void CSMWorld::CellSelection::remove (const CellCoordinates& coordinates) +void CSMWorld::CellSelection::remove(const CellCoordinates& coordinates) { - mCells.erase (coordinates); + mCells.erase(coordinates); } -bool CSMWorld::CellSelection::has (const CellCoordinates& coordinates) const +bool CSMWorld::CellSelection::has(const CellCoordinates& coordinates) const { - return mCells.find (coordinates)!=end(); + return mCells.find(coordinates) != end(); } int CSMWorld::CellSelection::getSize() const @@ -39,12 +39,12 @@ int CSMWorld::CellSelection::getSize() const CSMWorld::CellCoordinates CSMWorld::CellSelection::getCentre() const { if (mCells.empty()) - throw std::logic_error ("call of getCentre on empty cell selection"); + throw std::logic_error("call of getCentre on empty cell selection"); double x = 0; double y = 0; - for (Iterator iter = begin(); iter!=end(); ++iter) + for (Iterator iter = begin(); iter != end(); ++iter) { x += iter->getX(); y += iter->getY(); @@ -56,14 +56,14 @@ CSMWorld::CellCoordinates CSMWorld::CellSelection::getCentre() const Iterator closest = begin(); double distance = std::numeric_limits::max(); - for (Iterator iter (begin()); iter!=end(); ++iter) + for (Iterator iter(begin()); iter != end(); ++iter) { double deltaX = x - iter->getX(); double deltaY = y - iter->getY(); - double delta = std::sqrt (deltaX * deltaX + deltaY * deltaY); + double delta = std::sqrt(deltaX * deltaX + deltaY * deltaY); - if (deltamove (x, y)); + for (Iterator iter = begin(); iter != end(); ++iter) + moved.insert(iter->move(x, y)); - mCells.swap (moved); + mCells.swap(moved); } diff --git a/apps/opencs/model/world/cellselection.hpp b/apps/opencs/model/world/cellselection.hpp index b4616bfb34..3119886bd9 100644 --- a/apps/opencs/model/world/cellselection.hpp +++ b/apps/opencs/model/world/cellselection.hpp @@ -14,44 +14,41 @@ namespace CSMWorld /// \note The CellSelection does not specify the worldspace it applies to. class CellSelection { - public: + public: + typedef std::set Container; + typedef Container::const_iterator Iterator; - typedef std::set Container; - typedef Container::const_iterator Iterator; + private: + Container mCells; - private: + public: + Iterator begin() const; - Container mCells; + Iterator end() const; - public: + bool add(const CellCoordinates& coordinates); + ///< Ignored if the cell specified by \a coordinates is already part of the selection. + /// + /// \return Was a cell added to the collection? - Iterator begin() const; + void remove(const CellCoordinates& coordinates); + ///< ignored if the cell specified by \a coordinates is not part of the selection. - Iterator end() const; + bool has(const CellCoordinates& coordinates) const; + ///< \return Is the cell specified by \a coordinates part of the selection? - bool add (const CellCoordinates& coordinates); - ///< Ignored if the cell specified by \a coordinates is already part of the selection. - /// - /// \return Was a cell added to the collection? + int getSize() const; + ///< Return number of cells. - void remove (const CellCoordinates& coordinates); - ///< ignored if the cell specified by \a coordinates is not part of the selection. + CellCoordinates getCentre() const; + ///< Return the selected cell that is closest to the geometric centre of the selection. + /// + /// \attention This function must not be called on selections that are empty. - bool has (const CellCoordinates& coordinates) const; - ///< \return Is the cell specified by \a coordinates part of the selection? - - int getSize() const; - ///< Return number of cells. - - CellCoordinates getCentre() const; - ///< Return the selected cell that is closest to the geometric centre of the selection. - /// - /// \attention This function must not be called on selections that are empty. - - void move (int x, int y); + void move(int x, int y); }; } -Q_DECLARE_METATYPE (CSMWorld::CellSelection) +Q_DECLARE_METATYPE(CSMWorld::CellSelection) #endif diff --git a/apps/opencs/model/world/collection.hpp b/apps/opencs/model/world/collection.hpp index 7901655245..8a8cb48dfa 100644 --- a/apps/opencs/model/world/collection.hpp +++ b/apps/opencs/model/world/collection.hpp @@ -1,22 +1,22 @@ #ifndef CSM_WOLRD_COLLECTION_H #define CSM_WOLRD_COLLECTION_H -#include -#include #include #include -#include -#include #include +#include #include +#include +#include #include +#include #include #include -#include "columnbase.hpp" #include "collectionbase.hpp" +#include "columnbase.hpp" #include "land.hpp" #include "landtexture.hpp" #include "ref.hpp" @@ -24,37 +24,37 @@ namespace CSMWorld { /// \brief Access to ID field in records - template + template struct IdAccessor { void setId(ESXRecordT& record, const std::string& id) const; - const std::string getId (const ESXRecordT& record) const; + const std::string getId(const ESXRecordT& record) const; }; - template + template void IdAccessor::setId(ESXRecordT& record, const std::string& id) const { record.mId = id; } - template - const std::string IdAccessor::getId (const ESXRecordT& record) const + template + const std::string IdAccessor::getId(const ESXRecordT& record) const { return record.mId; } - template<> - inline void IdAccessor::setId (Land& record, const std::string& id) const + template <> + inline void IdAccessor::setId(Land& record, const std::string& id) const { - int x=0, y=0; + int x = 0, y = 0; Land::parseUniqueRecordId(id, x, y); record.mX = x; record.mY = y; } - template<> - inline void IdAccessor::setId (LandTexture& record, const std::string& id) const + template <> + inline void IdAccessor::setId(LandTexture& record, const std::string& id) const { int plugin = 0; int index = 0; @@ -64,191 +64,180 @@ namespace CSMWorld record.mIndex = index; } - template<> - inline const std::string IdAccessor::getId (const Land& record) const + template <> + inline const std::string IdAccessor::getId(const Land& record) const { return Land::createUniqueRecordId(record.mX, record.mY); } - template<> - inline const std::string IdAccessor::getId (const LandTexture& record) const + template <> + inline const std::string IdAccessor::getId(const LandTexture& record) const { return LandTexture::createUniqueRecordId(record.mPluginIndex, record.mIndex); } /// \brief Single-type record collection - template > + template > class Collection : public CollectionBase { - public: - - typedef ESXRecordT ESXRecord; - - private: - - std::vector > > mRecords; - std::map mIndex; - std::vector *> mColumns; + public: + typedef ESXRecordT ESXRecord; - // not implemented - Collection (const Collection&); - Collection& operator= (const Collection&); + private: + std::vector>> mRecords; + std::map mIndex; + std::vector*> mColumns; - protected: + // not implemented + Collection(const Collection&); + Collection& operator=(const Collection&); - const std::vector > >& getRecords() const; + protected: + const std::vector>>& getRecords() const; - bool reorderRowsImp (int baseIndex, const std::vector& newOrder); - ///< Reorder the rows [baseIndex, baseIndex+newOrder.size()) according to the indices - /// given in \a newOrder (baseIndex+newOrder[0] specifies the new index of row baseIndex). - /// - /// \return Success? + bool reorderRowsImp(int baseIndex, const std::vector& newOrder); + ///< Reorder the rows [baseIndex, baseIndex+newOrder.size()) according to the indices + /// given in \a newOrder (baseIndex+newOrder[0] specifies the new index of row baseIndex). + /// + /// \return Success? - int cloneRecordImp (const std::string& origin, const std::string& dest, - UniversalId::Type type); - ///< Returns the index of the clone. + int cloneRecordImp(const std::string& origin, const std::string& dest, UniversalId::Type type); + ///< Returns the index of the clone. - int touchRecordImp (const std::string& id); - ///< Returns the index of the record on success, -1 on failure. + int touchRecordImp(const std::string& id); + ///< Returns the index of the record on success, -1 on failure. - public: + public: + Collection(); - Collection(); + virtual ~Collection(); - virtual ~Collection(); + void add(const ESXRecordT& record); + ///< Add a new record (modified) - void add (const ESXRecordT& record); - ///< Add a new record (modified) + int getSize() const override; - int getSize() const override; + std::string getId(int index) const override; - std::string getId (int index) const override; + int getIndex(const std::string& id) const override; - int getIndex (const std::string& id) const override; + int getColumns() const override; - int getColumns() const override; + QVariant getData(int index, int column) const override; - QVariant getData (int index, int column) const override; + void setData(int index, int column, const QVariant& data) override; - void setData (int index, int column, const QVariant& data) override; + const ColumnBase& getColumn(int column) const override; - const ColumnBase& getColumn (int column) const override; + virtual void merge(); + ///< Merge modified into base. - virtual void merge(); - ///< Merge modified into base. + virtual void purge(); + ///< Remove records that are flagged as erased. - virtual void purge(); - ///< Remove records that are flagged as erased. + void removeRows(int index, int count) override; - void removeRows (int index, int count) override; + void appendBlankRecord(const std::string& id, UniversalId::Type type = UniversalId::Type_None) override; + ///< \param type Will be ignored, unless the collection supports multiple record types - void appendBlankRecord (const std::string& id, - UniversalId::Type type = UniversalId::Type_None) override; - ///< \param type Will be ignored, unless the collection supports multiple record types + void cloneRecord( + const std::string& origin, const std::string& destination, const UniversalId::Type type) override; - void cloneRecord(const std::string& origin, - const std::string& destination, - const UniversalId::Type type) override; + bool touchRecord(const std::string& id) override; + ///< Change the state of a record from base to modified, if it is not already. + /// \return True if the record was changed. - bool touchRecord(const std::string& id) override; - ///< Change the state of a record from base to modified, if it is not already. - /// \return True if the record was changed. + int searchId(std::string_view id) const override; + ////< Search record with \a id. + /// \return index of record (if found) or -1 (not found) - int searchId(std::string_view id) const override; - ////< Search record with \a id. - /// \return index of record (if found) or -1 (not found) + void replace(int index, std::unique_ptr record) override; + ///< If the record type does not match, an exception is thrown. + /// + /// \attention \a record must not change the ID. - void replace (int index, std::unique_ptr record) override; - ///< If the record type does not match, an exception is thrown. - /// - /// \attention \a record must not change the ID. + void appendRecord(std::unique_ptr record, UniversalId::Type type = UniversalId::Type_None) override; + ///< If the record type does not match, an exception is thrown. + ///< \param type Will be ignored, unless the collection supports multiple record types - void appendRecord (std::unique_ptr record, - UniversalId::Type type = UniversalId::Type_None) override; - ///< If the record type does not match, an exception is thrown. - ///< \param type Will be ignored, unless the collection supports multiple record types + const Record& getRecord(const std::string& id) const override; - const Record& getRecord (const std::string& id) const override; + const Record& getRecord(int index) const override; - const Record& getRecord (int index) const override; + int getAppendIndex(const std::string& id, UniversalId::Type type = UniversalId::Type_None) const override; + ///< \param type Will be ignored, unless the collection supports multiple record types - int getAppendIndex (const std::string& id, - UniversalId::Type type = UniversalId::Type_None) const override; - ///< \param type Will be ignored, unless the collection supports multiple record types + std::vector getIds(bool listDeleted = true) const override; + ///< Return a sorted collection of all IDs + /// + /// \param listDeleted include deleted record in the list - std::vector getIds (bool listDeleted = true) const override; - ///< Return a sorted collection of all IDs - /// - /// \param listDeleted include deleted record in the list + virtual void insertRecord( + std::unique_ptr record, int index, UniversalId::Type type = UniversalId::Type_None); + ///< Insert record before index. + /// + /// If the record type does not match, an exception is thrown. + /// + /// If the index is invalid either generally (by being out of range) or for the particular + /// record, an exception is thrown. - virtual void insertRecord (std::unique_ptr record, int index, - UniversalId::Type type = UniversalId::Type_None); - ///< Insert record before index. - /// - /// If the record type does not match, an exception is thrown. - /// - /// If the index is invalid either generally (by being out of range) or for the particular - /// record, an exception is thrown. + bool reorderRows(int baseIndex, const std::vector& newOrder) override; + ///< Reorder the rows [baseIndex, baseIndex+newOrder.size()) according to the indices + /// given in \a newOrder (baseIndex+newOrder[0] specifies the new index of row baseIndex). + /// + /// \return Success? - bool reorderRows (int baseIndex, const std::vector& newOrder) override; - ///< Reorder the rows [baseIndex, baseIndex+newOrder.size()) according to the indices - /// given in \a newOrder (baseIndex+newOrder[0] specifies the new index of row baseIndex). - /// - /// \return Success? + void addColumn(Column* column); - void addColumn (Column *column); + void setRecord(int index, std::unique_ptr> record); + ///< \attention This function must not change the ID. - void setRecord (int index, std::unique_ptr > record); - ///< \attention This function must not change the ID. - - NestableColumn *getNestableColumn (int column) const; + NestableColumn* getNestableColumn(int column) const; }; - template - const std::vector > >& Collection::getRecords() const + template + const std::vector>>& Collection::getRecords() const { return mRecords; } - template - bool Collection::reorderRowsImp (int baseIndex, - const std::vector& newOrder) + template + bool Collection::reorderRowsImp(int baseIndex, const std::vector& newOrder) { if (!newOrder.empty()) { - int size = static_cast (newOrder.size()); + int size = static_cast(newOrder.size()); // check that all indices are present - std::vector test (newOrder); - std::sort (test.begin(), test.end()); - if (*test.begin()!=0 || *--test.end()!=size-1) + std::vector test(newOrder); + std::sort(test.begin(), test.end()); + if (*test.begin() != 0 || *--test.end() != size - 1) return false; // reorder records - std::vector > > buffer (size); + std::vector>> buffer(size); - for (int i=0; isetModified (buffer[newOrder[i]]->get()); + buffer[newOrder[i]]->setModified(buffer[newOrder[i]]->get()); } - std::move (buffer.begin(), buffer.end(), mRecords.begin()+baseIndex); + std::move(buffer.begin(), buffer.end(), mRecords.begin() + baseIndex); // adjust index - for (std::map::iterator iter (mIndex.begin()); iter!=mIndex.end(); - ++iter) - if (iter->second>=baseIndex && iter->secondsecond = newOrder.at (iter->second-baseIndex)+baseIndex; + for (std::map::iterator iter(mIndex.begin()); iter != mIndex.end(); ++iter) + if (iter->second >= baseIndex && iter->second < baseIndex + size) + iter->second = newOrder.at(iter->second - baseIndex) + baseIndex; } return true; } - template - int Collection::cloneRecordImp(const std::string& origin, - const std::string& destination, UniversalId::Type type) + template + int Collection::cloneRecordImp( + const std::string& origin, const std::string& destination, UniversalId::Type type) { auto copy = std::make_unique>(); copy->mModified = getRecord(origin).get(); @@ -257,7 +246,7 @@ namespace CSMWorld if (type == UniversalId::Type_Reference) { - CSMWorld::CellRef* ptr = (CSMWorld::CellRef*) ©->mModified; + CSMWorld::CellRef* ptr = (CSMWorld::CellRef*)©->mModified; ptr->mRefNum.mIndex = 0; } @@ -267,7 +256,7 @@ namespace CSMWorld return index; } - template + template int Collection::touchRecordImp(const std::string& id) { int index = getIndex(id); @@ -286,29 +275,29 @@ namespace CSMWorld return -1; } - template - void Collection::cloneRecord(const std::string& origin, - const std::string& destination, const UniversalId::Type type) + template + void Collection::cloneRecord( + const std::string& origin, const std::string& destination, const UniversalId::Type type) { cloneRecordImp(origin, destination, type); } - template<> - inline void Collection >::cloneRecord(const std::string& origin, - const std::string& destination, const UniversalId::Type type) + template <> + inline void Collection>::cloneRecord( + const std::string& origin, const std::string& destination, const UniversalId::Type type) { int index = cloneRecordImp(origin, destination, type); mRecords.at(index)->get().setPlugin(0); } - template + template bool Collection::touchRecord(const std::string& id) { return touchRecordImp(id) != -1; } - template<> - inline bool Collection >::touchRecord(const std::string& id) + template <> + inline bool Collection>::touchRecord(const std::string& id) { int index = touchRecordImp(id); if (index >= 0) @@ -320,142 +309,144 @@ namespace CSMWorld return false; } - template + template Collection::Collection() - {} + { + } - template + template Collection::~Collection() { - for (typename std::vector *>::iterator iter (mColumns.begin()); iter!=mColumns.end(); ++iter) + for (typename std::vector*>::iterator iter(mColumns.begin()); iter != mColumns.end(); ++iter) delete *iter; } - template - void Collection::add (const ESXRecordT& record) + template + void Collection::add(const ESXRecordT& record) { - std::string id = Misc::StringUtils::lowerCase (IdAccessorT().getId (record)); + std::string id = Misc::StringUtils::lowerCase(IdAccessorT().getId(record)); - std::map::iterator iter = mIndex.find (id); + std::map::iterator iter = mIndex.find(id); - if (iter==mIndex.end()) + if (iter == mIndex.end()) { auto record2 = std::make_unique>(); record2->mState = Record::State_ModifiedOnly; record2->mModified = record; - insertRecord (std::move(record2), getAppendIndex (id)); + insertRecord(std::move(record2), getAppendIndex(id)); } else { - mRecords[iter->second]->setModified (record); + mRecords[iter->second]->setModified(record); } } - template + template int Collection::getSize() const { return mRecords.size(); } - template - std::string Collection::getId (int index) const + template + std::string Collection::getId(int index) const { - return IdAccessorT().getId (mRecords.at (index)->get()); + return IdAccessorT().getId(mRecords.at(index)->get()); } - template - int Collection::getIndex (const std::string& id) const + template + int Collection::getIndex(const std::string& id) const { - int index = searchId (id); + int index = searchId(id); - if (index==-1) - throw std::runtime_error ("invalid ID: " + id); + if (index == -1) + throw std::runtime_error("invalid ID: " + id); return index; } - template + template int Collection::getColumns() const { return mColumns.size(); } - template - QVariant Collection::getData (int index, int column) const + template + QVariant Collection::getData(int index, int column) const { - return mColumns.at (column)->get (*mRecords.at (index)); + return mColumns.at(column)->get(*mRecords.at(index)); } - template - void Collection::setData (int index, int column, const QVariant& data) + template + void Collection::setData(int index, int column, const QVariant& data) { - return mColumns.at (column)->set (*mRecords.at (index), data); + return mColumns.at(column)->set(*mRecords.at(index), data); } - template - const ColumnBase& Collection::getColumn (int column) const + template + const ColumnBase& Collection::getColumn(int column) const { - return *mColumns.at (column); + return *mColumns.at(column); } - template - NestableColumn *Collection::getNestableColumn (int column) const + template + NestableColumn* Collection::getNestableColumn(int column) const { if (column < 0 || column >= static_cast(mColumns.size())) throw std::runtime_error("column index out of range"); - return mColumns.at (column); + return mColumns.at(column); } - template - void Collection::addColumn (Column *column) + template + void Collection::addColumn(Column* column) { - mColumns.push_back (column); + mColumns.push_back(column); } - template + template void Collection::merge() { - for (typename std::vector > >::iterator iter (mRecords.begin()); iter!=mRecords.end(); ++iter) + for (typename std::vector>>::iterator iter(mRecords.begin()); + iter != mRecords.end(); ++iter) (*iter)->merge(); purge(); } - template - void Collection::purge() + template + void Collection::purge() { int i = 0; - while (i (mRecords.size())) + while (i < static_cast(mRecords.size())) { if (mRecords[i]->isErased()) - removeRows (i, 1); + removeRows(i, 1); else ++i; } } - template - void Collection::removeRows (int index, int count) + template + void Collection::removeRows(int index, int count) { - mRecords.erase (mRecords.begin()+index, mRecords.begin()+index+count); + mRecords.erase(mRecords.begin() + index, mRecords.begin() + index + count); typename std::map::iterator iter = mIndex.begin(); - while (iter!=mIndex.end()) + while (iter != mIndex.end()) { - if (iter->second>=index) + if (iter->second >= index) { - if (iter->second>=index+count) + if (iter->second >= index + count) { iter->second -= count; ++iter; } else { - mIndex.erase (iter++); + mIndex.erase(iter++); } } else @@ -463,9 +454,8 @@ namespace CSMWorld } } - template - void Collection::appendBlankRecord (const std::string& id, - UniversalId::Type type) + template + void Collection::appendBlankRecord(const std::string& id, UniversalId::Type type) { ESXRecordT record; IdAccessorT().setId(record, id); @@ -475,114 +465,109 @@ namespace CSMWorld record2->mState = Record::State_ModifiedOnly; record2->mModified = record; - insertRecord (std::move(record2), getAppendIndex (id, type), type); + insertRecord(std::move(record2), getAppendIndex(id, type), type); } - template + template int Collection::searchId(std::string_view id) const { std::string id2 = Misc::StringUtils::lowerCase(id); - std::map::const_iterator iter = mIndex.find (id2); + std::map::const_iterator iter = mIndex.find(id2); - if (iter==mIndex.end()) + if (iter == mIndex.end()) return -1; return iter->second; } - template - void Collection::replace (int index, std::unique_ptr record) + template + void Collection::replace(int index, std::unique_ptr record) { - std::unique_ptr > tmp(static_cast*>(record.release())); - mRecords.at (index) = std::move(tmp); + std::unique_ptr> tmp(static_cast*>(record.release())); + mRecords.at(index) = std::move(tmp); } - template - void Collection::appendRecord (std::unique_ptr record, - UniversalId::Type type) + template + void Collection::appendRecord(std::unique_ptr record, UniversalId::Type type) { - int index = - getAppendIndex(IdAccessorT().getId(static_cast*>(record.get())->get()), type); - insertRecord (std::move(record), index, type); + int index = getAppendIndex(IdAccessorT().getId(static_cast*>(record.get())->get()), type); + insertRecord(std::move(record), index, type); } - template - int Collection::getAppendIndex (const std::string& id, - UniversalId::Type type) const + template + int Collection::getAppendIndex(const std::string& id, UniversalId::Type type) const { - return static_cast (mRecords.size()); + return static_cast(mRecords.size()); } - template - std::vector Collection::getIds (bool listDeleted) const + template + std::vector Collection::getIds(bool listDeleted) const { std::vector ids; - for (typename std::map::const_iterator iter = mIndex.begin(); - iter!=mIndex.end(); ++iter) + for (typename std::map::const_iterator iter = mIndex.begin(); iter != mIndex.end(); ++iter) { if (listDeleted || !mRecords[iter->second]->isDeleted()) - ids.push_back (IdAccessorT().getId (mRecords[iter->second]->get())); + ids.push_back(IdAccessorT().getId(mRecords[iter->second]->get())); } return ids; } - template - const Record& Collection::getRecord (const std::string& id) const + template + const Record& Collection::getRecord(const std::string& id) const { - int index = getIndex (id); - return *mRecords.at (index); + int index = getIndex(id); + return *mRecords.at(index); } - template - const Record& Collection::getRecord (int index) const + template + const Record& Collection::getRecord(int index) const { - return *mRecords.at (index); + return *mRecords.at(index); } - template - void Collection::insertRecord (std::unique_ptr record, int index, - UniversalId::Type type) + template + void Collection::insertRecord( + std::unique_ptr record, int index, UniversalId::Type type) { int size = static_cast(mRecords.size()); if (index < 0 || index > size) - throw std::runtime_error ("index out of range"); + throw std::runtime_error("index out of range"); - std::unique_ptr > record2(static_cast*>(record.release())); + std::unique_ptr> record2(static_cast*>(record.release())); std::string lowerId = Misc::StringUtils::lowerCase(IdAccessorT().getId(record2->get())); if (index == size) - mRecords.push_back (std::move(record2)); + mRecords.push_back(std::move(record2)); else - mRecords.insert (mRecords.begin()+index, std::move(record2)); + mRecords.insert(mRecords.begin() + index, std::move(record2)); - if (index < size-1) + if (index < size - 1) { - for (std::map::iterator iter (mIndex.begin()); iter!=mIndex.end(); ++iter) + for (std::map::iterator iter(mIndex.begin()); iter != mIndex.end(); ++iter) { if (iter->second >= index) ++(iter->second); } } - mIndex.insert (std::make_pair (lowerId, index)); + mIndex.insert(std::make_pair(lowerId, index)); } - template - void Collection::setRecord (int index, - std::unique_ptr > record) + template + void Collection::setRecord(int index, std::unique_ptr> record) { - if (Misc::StringUtils::lowerCase (IdAccessorT().getId (mRecords.at (index)->get())) != - Misc::StringUtils::lowerCase (IdAccessorT().getId (record->get()))) - throw std::runtime_error ("attempt to change the ID of a record"); + if (Misc::StringUtils::lowerCase(IdAccessorT().getId(mRecords.at(index)->get())) + != Misc::StringUtils::lowerCase(IdAccessorT().getId(record->get()))) + throw std::runtime_error("attempt to change the ID of a record"); - mRecords.at (index) = std::move(record); + mRecords.at(index) = std::move(record); } - template - bool Collection::reorderRows (int baseIndex, const std::vector& newOrder) + template + bool Collection::reorderRows(int baseIndex, const std::vector& newOrder) { return false; } diff --git a/apps/opencs/model/world/collectionbase.cpp b/apps/opencs/model/world/collectionbase.cpp index f20fc643e2..394400e6ed 100644 --- a/apps/opencs/model/world/collectionbase.cpp +++ b/apps/opencs/model/world/collectionbase.cpp @@ -8,28 +8,28 @@ CSMWorld::CollectionBase::CollectionBase() {} CSMWorld::CollectionBase::~CollectionBase() {} -int CSMWorld::CollectionBase::getInsertIndex (const std::string& id, UniversalId::Type type, RecordBase *record) const +int CSMWorld::CollectionBase::getInsertIndex(const std::string& id, UniversalId::Type type, RecordBase* record) const { return getAppendIndex(id, type); } -int CSMWorld::CollectionBase::searchColumnIndex (Columns::ColumnId id) const +int CSMWorld::CollectionBase::searchColumnIndex(Columns::ColumnId id) const { int columns = getColumns(); - for (int i=0; i -#include #include +#include #include +#include -#include "universalid.hpp" #include "columns.hpp" +#include "universalid.hpp" class QVariant; @@ -24,95 +24,91 @@ namespace CSMWorld /// manually. class CollectionBase { - // not implemented - CollectionBase (const CollectionBase&); - CollectionBase& operator= (const CollectionBase&); - - public: + // not implemented + CollectionBase(const CollectionBase&); + CollectionBase& operator=(const CollectionBase&); - CollectionBase(); + public: + CollectionBase(); - virtual ~CollectionBase(); + virtual ~CollectionBase(); - virtual int getSize() const = 0; + virtual int getSize() const = 0; - virtual std::string getId (int index) const = 0; + virtual std::string getId(int index) const = 0; - virtual int getIndex (const std::string& id) const = 0; + virtual int getIndex(const std::string& id) const = 0; - virtual int getColumns() const = 0; + virtual int getColumns() const = 0; - virtual const ColumnBase& getColumn (int column) const = 0; + virtual const ColumnBase& getColumn(int column) const = 0; - virtual QVariant getData (int index, int column) const = 0; + virtual QVariant getData(int index, int column) const = 0; - virtual void setData (int index, int column, const QVariant& data) = 0; + virtual void setData(int index, int column, const QVariant& data) = 0; -// Not in use. Temporarily removed so that the implementation of RefIdCollection can continue without -// these functions for now. -// virtual void merge() = 0; - ///< Merge modified into base. + // Not in use. Temporarily removed so that the implementation of RefIdCollection can continue without + // these functions for now. + // virtual void merge() = 0; + ///< Merge modified into base. -// virtual void purge() = 0; - ///< Remove records that are flagged as erased. + // virtual void purge() = 0; + ///< Remove records that are flagged as erased. - virtual void removeRows (int index, int count) = 0; + virtual void removeRows(int index, int count) = 0; - virtual void appendBlankRecord (const std::string& id, - UniversalId::Type type = UniversalId::Type_None) = 0; - ///< \param type Will be ignored, unless the collection supports multiple record types + virtual void appendBlankRecord(const std::string& id, UniversalId::Type type = UniversalId::Type_None) = 0; + ///< \param type Will be ignored, unless the collection supports multiple record types - virtual int searchId(std::string_view id) const = 0; - ////< Search record with \a id. - /// \return index of record (if found) or -1 (not found) + virtual int searchId(std::string_view id) const = 0; + ////< Search record with \a id. + /// \return index of record (if found) or -1 (not found) - virtual void replace (int index, std::unique_ptr record) = 0; - ///< If the record type does not match, an exception is thrown. - /// - /// \attention \a record must not change the ID. - ///< \param type Will be ignored, unless the collection supports multiple record types + virtual void replace(int index, std::unique_ptr record) = 0; + ///< If the record type does not match, an exception is thrown. + /// + /// \attention \a record must not change the ID. + ///< \param type Will be ignored, unless the collection supports multiple record types - virtual void appendRecord (std::unique_ptr record, - UniversalId::Type type = UniversalId::Type_None) = 0; - ///< If the record type does not match, an exception is thrown. + virtual void appendRecord(std::unique_ptr record, UniversalId::Type type = UniversalId::Type_None) + = 0; + ///< If the record type does not match, an exception is thrown. - virtual void cloneRecord(const std::string& origin, - const std::string& destination, - const UniversalId::Type type) = 0; + virtual void cloneRecord( + const std::string& origin, const std::string& destination, const UniversalId::Type type) + = 0; - virtual bool touchRecord(const std::string& id) = 0; + virtual bool touchRecord(const std::string& id) = 0; - virtual const RecordBase& getRecord (const std::string& id) const = 0; + virtual const RecordBase& getRecord(const std::string& id) const = 0; - virtual const RecordBase& getRecord (int index) const = 0; + virtual const RecordBase& getRecord(int index) const = 0; - virtual int getAppendIndex (const std::string& id, - UniversalId::Type type = UniversalId::Type_None) const = 0; - ///< \param type Will be ignored, unless the collection supports multiple record types + virtual int getAppendIndex(const std::string& id, UniversalId::Type type = UniversalId::Type_None) const = 0; + ///< \param type Will be ignored, unless the collection supports multiple record types - virtual std::vector getIds (bool listDeleted = true) const = 0; - ///< Return a sorted collection of all IDs - /// - /// \param listDeleted include deleted record in the list + virtual std::vector getIds(bool listDeleted = true) const = 0; + ///< Return a sorted collection of all IDs + /// + /// \param listDeleted include deleted record in the list - virtual bool reorderRows (int baseIndex, const std::vector& newOrder) = 0; - ///< Reorder the rows [baseIndex, baseIndex+newOrder.size()) according to the indices - /// given in \a newOrder (baseIndex+newOrder[0] specifies the new index of row baseIndex). - /// - /// \return Success? + virtual bool reorderRows(int baseIndex, const std::vector& newOrder) = 0; + ///< Reorder the rows [baseIndex, baseIndex+newOrder.size()) according to the indices + /// given in \a newOrder (baseIndex+newOrder[0] specifies the new index of row baseIndex). + /// + /// \return Success? - virtual int getInsertIndex (const std::string& id, - UniversalId::Type type = UniversalId::Type_None, - RecordBase *record = nullptr) const; - ///< Works like getAppendIndex unless an overloaded method uses the record pointer - /// to get additional info about the record that results in an alternative index. + virtual int getInsertIndex( + const std::string& id, UniversalId::Type type = UniversalId::Type_None, RecordBase* record = nullptr) const; + ///< Works like getAppendIndex unless an overloaded method uses the record pointer + /// to get additional info about the record that results in an alternative index. - int searchColumnIndex (Columns::ColumnId id) const; - ///< Return index of column with the given \a id. If no such column exists, -1 is returned. + int searchColumnIndex(Columns::ColumnId id) const; + ///< Return index of column with the given \a id. If no such column exists, -1 is returned. - int findColumnIndex (Columns::ColumnId id) const; - ///< Return index of column with the given \a id. If no such column exists, an exception is - /// thrown. + int findColumnIndex(Columns::ColumnId id) const; + ///< Return index of column with the given \a id. If no such column exists, an exception is + /// thrown. }; } diff --git a/apps/opencs/model/world/columnbase.cpp b/apps/opencs/model/world/columnbase.cpp index eed4202bd6..f9ad35dc3d 100644 --- a/apps/opencs/model/world/columnbase.cpp +++ b/apps/opencs/model/world/columnbase.cpp @@ -2,9 +2,12 @@ #include "columns.hpp" -CSMWorld::ColumnBase::ColumnBase (int columnId, Display displayType, int flags) - : mColumnId (columnId), mFlags (flags), mDisplayType (displayType) -{} +CSMWorld::ColumnBase::ColumnBase(int columnId, Display displayType, int flags) + : mColumnId(columnId) + , mFlags(flags) + , mDisplayType(displayType) +{ +} CSMWorld::ColumnBase::~ColumnBase() {} @@ -15,18 +18,17 @@ bool CSMWorld::ColumnBase::isUserEditable() const std::string CSMWorld::ColumnBase::getTitle() const { - return Columns::getName (static_cast (mColumnId)); + return Columns::getName(static_cast(mColumnId)); } -int CSMWorld::ColumnBase::getId() const +int CSMWorld::ColumnBase::getId() const { return mColumnId; } -bool CSMWorld::ColumnBase::isId (Display display) +bool CSMWorld::ColumnBase::isId(Display display) { - static const Display ids[] = - { + static const Display ids[] = { Display_Skill, Display_Class, Display_Faction, @@ -94,26 +96,25 @@ bool CSMWorld::ColumnBase::isId (Display display) Display_None, }; - for (int i=0; ids[i]!=Display_None; ++i) - if (ids[i]==display) + for (int i = 0; ids[i] != Display_None; ++i) + if (ids[i] == display) return true; return false; } -bool CSMWorld::ColumnBase::isText (Display display) +bool CSMWorld::ColumnBase::isText(Display display) { - return display==Display_String || display==Display_LongString || - display==Display_String32 || display==Display_String64 || - display==Display_LongString256; + return display == Display_String || display == Display_LongString || display == Display_String32 + || display == Display_String64 || display == Display_LongString256; } -bool CSMWorld::ColumnBase::isScript (Display display) +bool CSMWorld::ColumnBase::isScript(Display display) { - return display==Display_ScriptFile || display==Display_ScriptLines; + return display == Display_ScriptFile || display == Display_ScriptLines; } -void CSMWorld::NestableColumn::addColumn(CSMWorld::NestableColumn *column) +void CSMWorld::NestableColumn::addColumn(CSMWorld::NestableColumn* column) { mNestedColumns.push_back(column); } @@ -126,10 +127,10 @@ const CSMWorld::ColumnBase& CSMWorld::NestableColumn::nestedColumn(int subColumn return *mNestedColumns.at(subColumn); } -CSMWorld::NestableColumn::NestableColumn(int columnId, CSMWorld::ColumnBase::Display displayType, - int flag) +CSMWorld::NestableColumn::NestableColumn(int columnId, CSMWorld::ColumnBase::Display displayType, int flag) : CSMWorld::ColumnBase(columnId, displayType, flag) -{} +{ +} CSMWorld::NestableColumn::~NestableColumn() { @@ -144,12 +145,14 @@ bool CSMWorld::NestableColumn::hasChildren() const return !mNestedColumns.empty(); } -CSMWorld::NestedChildColumn::NestedChildColumn (int id, - CSMWorld::ColumnBase::Display display, int flags, bool isEditable) - : NestableColumn (id, display, flags) , mIsEditable(isEditable) -{} +CSMWorld::NestedChildColumn::NestedChildColumn( + int id, CSMWorld::ColumnBase::Display display, int flags, bool isEditable) + : NestableColumn(id, display, flags) + , mIsEditable(isEditable) +{ +} -bool CSMWorld::NestedChildColumn::isEditable () const +bool CSMWorld::NestedChildColumn::isEditable() const { return mIsEditable; } diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index 688cdffb74..4f0b25c14a 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -1,9 +1,9 @@ #ifndef CSM_WOLRD_COLUMNBASE_H #define CSM_WOLRD_COLUMNBASE_H +#include #include #include -#include #include @@ -15,16 +15,16 @@ namespace CSMWorld { enum TableEditModes { - TableEdit_None, // no editing - TableEdit_Full, // edit cells and add/remove rows - TableEdit_FixedRows // edit cells only + TableEdit_None, // no editing + TableEdit_Full, // edit cells and add/remove rows + TableEdit_FixedRows // edit cells only }; enum Roles { Role_Flags = Qt::UserRole, - Role_Display = Qt::UserRole+1, - Role_ColumnId = Qt::UserRole+2 + Role_Display = Qt::UserRole + 1, + Role_ColumnId = Qt::UserRole + 2 }; enum Flags @@ -37,11 +37,11 @@ namespace CSMWorld enum Display { - Display_None, //Do not use + Display_None, // Do not use Display_String, Display_LongString, - //CONCRETE TYPES STARTS HERE (for drag and drop) + // CONCRETE TYPES STARTS HERE (for drag and drop) Display_Skill, Display_Class, Display_Faction, @@ -83,7 +83,7 @@ namespace CSMWorld Display_GlobalVariable, Display_BodyPart, Display_Enchantment, - //CONCRETE TYPES ENDS HERE + // CONCRETE TYPES ENDS HERE Display_SignedInteger8, Display_SignedInteger16, @@ -140,12 +140,12 @@ namespace CSMWorld Display_BloodType, Display_EmitterType, - Display_EffectSkill, // must display at least one, unlike Display_Skill + Display_EffectSkill, // must display at least one, unlike Display_Skill Display_EffectAttribute, // must display at least one, unlike Display_Attribute - Display_IngredEffectId, // display none allowed, unlike Display_EffectId - Display_GenderNpc, // must display at least one, unlike Display_Gender + Display_IngredEffectId, // display none allowed, unlike Display_EffectId + Display_GenderNpc, // must display at least one, unlike Display_Gender - //top level columns that nest other columns + // top level columns that nest other columns Display_NestedHeader }; @@ -153,7 +153,7 @@ namespace CSMWorld int mFlags; Display mDisplayType; - ColumnBase (int columnId, Display displayType, int flag); + ColumnBase(int columnId, Display displayType, int flag); virtual ~ColumnBase(); @@ -166,58 +166,61 @@ namespace CSMWorld virtual int getId() const; - static bool isId (Display display); + static bool isId(Display display); - static bool isText (Display display); + static bool isText(Display display); - static bool isScript (Display display); + static bool isScript(Display display); }; class NestableColumn : public ColumnBase { - std::vector mNestedColumns; + std::vector mNestedColumns; public: - NestableColumn(int columnId, Display displayType, int flag); ~NestableColumn(); - void addColumn(CSMWorld::NestableColumn *column); + void addColumn(CSMWorld::NestableColumn* column); const ColumnBase& nestedColumn(int subColumn) const; bool hasChildren() const; }; - template + template struct Column : public NestableColumn { - Column (int columnId, Display displayType, int flags = Flag_Table | Flag_Dialogue) - : NestableColumn (columnId, displayType, flags) {} + Column(int columnId, Display displayType, int flags = Flag_Table | Flag_Dialogue) + : NestableColumn(columnId, displayType, flags) + { + } - virtual QVariant get (const Record& record) const = 0; + virtual QVariant get(const Record& record) const = 0; - virtual void set (Record& record, const QVariant& data) + virtual void set(Record& record, const QVariant& data) { - throw std::logic_error ("Column " + getTitle() + " is not editable"); + throw std::logic_error("Column " + getTitle() + " is not editable"); } }; - template + template struct NestedParentColumn : public Column { - NestedParentColumn (int id, int flags = ColumnBase::Flag_Dialogue, bool fixedRows = false) - : Column (id, ColumnBase::Display_NestedHeader, flags), mFixedRows(fixedRows) - {} + NestedParentColumn(int id, int flags = ColumnBase::Flag_Dialogue, bool fixedRows = false) + : Column(id, ColumnBase::Display_NestedHeader, flags) + , mFixedRows(fixedRows) + { + } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { // There is nothing to do here. // This prevents exceptions from parent's implementation } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { // by default editable; also see IdTree::hasChildren() if (mFixedRows) @@ -226,10 +229,7 @@ namespace CSMWorld return QVariant::fromValue(ColumnBase::TableEdit_Full); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } private: bool mFixedRows; @@ -237,8 +237,7 @@ namespace CSMWorld struct NestedChildColumn : public NestableColumn { - NestedChildColumn (int id, - Display display, int flags = ColumnBase::Flag_Dialogue, bool isEditable = true); + NestedChildColumn(int id, Display display, int flags = ColumnBase::Flag_Dialogue, bool isEditable = true); bool isEditable() const override; diff --git a/apps/opencs/model/world/columnimp.cpp b/apps/opencs/model/world/columnimp.cpp index 78c7bc02d5..090c19b679 100644 --- a/apps/opencs/model/world/columnimp.cpp +++ b/apps/opencs/model/world/columnimp.cpp @@ -264,11 +264,12 @@ namespace CSMWorld } /* BodyPartRaceColumn */ - BodyPartRaceColumn::BodyPartRaceColumn(const MeshTypeColumn *meshType) + BodyPartRaceColumn::BodyPartRaceColumn(const MeshTypeColumn* meshType) : mMeshType(meshType) - {} + { + } - QVariant BodyPartRaceColumn::get(const Record &record) const + QVariant BodyPartRaceColumn::get(const Record& record) const { if (mMeshType != nullptr && mMeshType->get(record) == ESM::BodyPart::MT_Skin) { @@ -277,7 +278,7 @@ namespace CSMWorld return QVariant(QVariant::UserType); } - void BodyPartRaceColumn::set(Record &record, const QVariant &data) + void BodyPartRaceColumn::set(Record& record, const QVariant& data) { ESM::BodyPart record2 = record.get(); diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index 2d69c664d4..436b379b52 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -9,8 +9,8 @@ #include #include -#include #include +#include #include "columnbase.hpp" #include "columns.hpp" @@ -22,153 +22,141 @@ namespace CSMWorld { /// \note Shares ID with VarValueColumn. A table can not have both. - template + template struct FloatValueColumn : public Column { - FloatValueColumn() : Column (Columns::ColumnId_Value, ColumnBase::Display_Float) {} - - QVariant get (const Record& record) const override + FloatValueColumn() + : Column(Columns::ColumnId_Value, ColumnBase::Display_Float) { - return record.get().mValue.getFloat(); } - void set (Record& record, const QVariant& data) override + QVariant get(const Record& record) const override { return record.get().mValue.getFloat(); } + + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); - record2.mValue.setFloat (data.toFloat()); - record.setModified (record2); + record2.mValue.setFloat(data.toFloat()); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct StringIdColumn : public Column { - StringIdColumn (bool hidden = false) - : Column (Columns::ColumnId_Id, ColumnBase::Display_Id, - hidden ? 0 : ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue) - {} - - QVariant get (const Record& record) const override + StringIdColumn(bool hidden = false) + : Column(Columns::ColumnId_Id, ColumnBase::Display_Id, + hidden ? 0 : ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue) { - return QString::fromUtf8 (record.get().mId.c_str()); } - bool isEditable() const override + QVariant get(const Record& record) const override { - return false; + return QString::fromUtf8(record.get().mId.c_str()); } + + bool isEditable() const override { return false; } }; - template<> + template <> inline QVariant StringIdColumn::get(const Record& record) const { const Land& land = record.get(); return QString::fromUtf8(Land::createUniqueRecordId(land.mX, land.mY).c_str()); } - template<> + template <> inline QVariant StringIdColumn::get(const Record& record) const { const LandTexture& ltex = record.get(); return QString::fromUtf8(LandTexture::createUniqueRecordId(ltex.mPluginIndex, ltex.mIndex).c_str()); } - template + template struct RecordStateColumn : public Column { RecordStateColumn() - : Column (Columns::ColumnId_Modification, ColumnBase::Display_RecordState) - {} - - QVariant get (const Record& record) const override + : Column(Columns::ColumnId_Modification, ColumnBase::Display_RecordState) { - if (record.mState==Record::State_Erased) - return static_cast (Record::State_Deleted); - - return static_cast (record.mState); } - void set (Record& record, const QVariant& data) override + QVariant get(const Record& record) const override { - record.mState = static_cast (data.toInt()); - } + if (record.mState == Record::State_Erased) + return static_cast(Record::State_Deleted); - bool isEditable() const override - { - return true; + return static_cast(record.mState); } - bool isUserEditable() const override + void set(Record& record, const QVariant& data) override { - return false; + record.mState = static_cast(data.toInt()); } + + bool isEditable() const override { return true; } + + bool isUserEditable() const override { return false; } }; - template + template struct FixedRecordTypeColumn : public Column { int mType; - FixedRecordTypeColumn (int type) - : Column (Columns::ColumnId_RecordType, ColumnBase::Display_Integer, 0), - mType (type) - {} - - QVariant get (const Record& record) const override + FixedRecordTypeColumn(int type) + : Column(Columns::ColumnId_RecordType, ColumnBase::Display_Integer, 0) + , mType(type) { - return mType; } - bool isEditable() const override - { - return false; - } + QVariant get(const Record& record) const override { return mType; } + + bool isEditable() const override { return false; } }; /// \attention A var type column must be immediately followed by a suitable value column. - template + template struct VarTypeColumn : public Column { - VarTypeColumn (ColumnBase::Display display) - : Column (Columns::ColumnId_ValueType, display, ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh) - {} - - QVariant get (const Record& record) const override + VarTypeColumn(ColumnBase::Display display) + : Column(Columns::ColumnId_ValueType, display, + ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh) { - return static_cast (record.get().mValue.getType()); } - void set (Record& record, const QVariant& data) override + QVariant get(const Record& record) const override { - ESXRecordT record2 = record.get(); - record2.mValue.setType (static_cast (data.toInt())); - record.setModified (record2); + return static_cast(record.get().mValue.getType()); } - bool isEditable() const override + void set(Record& record, const QVariant& data) override { - return true; + ESXRecordT record2 = record.get(); + record2.mValue.setType(static_cast(data.toInt())); + record.setModified(record2); } + + bool isEditable() const override { return true; } }; /// \note Shares ID with FloatValueColumn. A table can not have both. - template + template struct VarValueColumn : public Column { - VarValueColumn() : Column (Columns::ColumnId_Value, ColumnBase::Display_Var, ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh) {} + VarValueColumn() + : Column(Columns::ColumnId_Value, ColumnBase::Display_Var, + ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { switch (record.get().mValue.getType()) { case ESM::VT_String: - return QString::fromUtf8 (record.get().mValue.getString().c_str()); + return QString::fromUtf8(record.get().mValue.getString().c_str()); case ESM::VT_Int: case ESM::VT_Short: @@ -180,11 +168,12 @@ namespace CSMWorld return record.get().mValue.getFloat(); - default: return QVariant(); + default: + return QVariant(); } } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -192,311 +181,281 @@ namespace CSMWorld { case ESM::VT_String: - record2.mValue.setString (data.toString().toUtf8().constData()); + record2.mValue.setString(data.toString().toUtf8().constData()); break; case ESM::VT_Int: case ESM::VT_Short: case ESM::VT_Long: - record2.mValue.setInteger (data.toInt()); + record2.mValue.setInteger(data.toInt()); break; case ESM::VT_Float: - record2.mValue.setFloat (data.toFloat()); + record2.mValue.setFloat(data.toFloat()); break; - default: break; + default: + break; } - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct DescriptionColumn : public Column { DescriptionColumn() - : Column (Columns::ColumnId_Description, ColumnBase::Display_LongString) - {} + : Column(Columns::ColumnId_Description, ColumnBase::Display_LongString) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return QString::fromUtf8 (record.get().mDescription.c_str()); + return QString::fromUtf8(record.get().mDescription.c_str()); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mDescription = data.toString().toUtf8().constData(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct SpecialisationColumn : public Column { SpecialisationColumn() - : Column (Columns::ColumnId_Specialisation, ColumnBase::Display_Specialisation) - {} - - QVariant get (const Record& record) const override + : Column(Columns::ColumnId_Specialisation, ColumnBase::Display_Specialisation) { - return record.get().mData.mSpecialization; } - void set (Record& record, const QVariant& data) override + QVariant get(const Record& record) const override { return record.get().mData.mSpecialization; } + + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mSpecialization = data.toInt(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct UseValueColumn : public Column { int mIndex; - UseValueColumn (int index) - : Column (Columns::ColumnId_UseValue1 + index, ColumnBase::Display_Float), - mIndex (index) - {} - - QVariant get (const Record& record) const override + UseValueColumn(int index) + : Column(Columns::ColumnId_UseValue1 + index, ColumnBase::Display_Float) + , mIndex(index) { - return record.get().mData.mUseValue[mIndex]; } - void set (Record& record, const QVariant& data) override + QVariant get(const Record& record) const override { return record.get().mData.mUseValue[mIndex]; } + + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mUseValue[mIndex] = data.toFloat(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct AttributeColumn : public Column { AttributeColumn() - : Column (Columns::ColumnId_Attribute, ColumnBase::Display_Attribute) - {} - - QVariant get (const Record& record) const override + : Column(Columns::ColumnId_Attribute, ColumnBase::Display_Attribute) { - return record.get().mData.mAttribute; } - void set (Record& record, const QVariant& data) override + QVariant get(const Record& record) const override { return record.get().mData.mAttribute; } + + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mAttribute = data.toInt(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct NameColumn : public Column { NameColumn(ColumnBase::Display display = ColumnBase::Display_String) - : Column (Columns::ColumnId_Name, display) {} + : Column(Columns::ColumnId_Name, display) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return QString::fromUtf8 (record.get().mName.c_str()); + return QString::fromUtf8(record.get().mName.c_str()); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mName = data.toString().toUtf8().constData(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct AttributesColumn : public Column { int mIndex; - AttributesColumn (int index) - : Column (Columns::ColumnId_Attribute1 + index, ColumnBase::Display_Attribute), - mIndex (index) - {} - - QVariant get (const Record& record) const override + AttributesColumn(int index) + : Column(Columns::ColumnId_Attribute1 + index, ColumnBase::Display_Attribute) + , mIndex(index) { - return record.get().mData.mAttribute[mIndex]; } - void set (Record& record, const QVariant& data) override + QVariant get(const Record& record) const override { return record.get().mData.mAttribute[mIndex]; } + + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mAttribute[mIndex] = data.toInt(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct SkillsColumn : public Column { int mIndex; bool mMajor; - SkillsColumn (int index, bool typePrefix = false, bool major = false) - : Column ((typePrefix ? ( - major ? Columns::ColumnId_MajorSkill1 : Columns::ColumnId_MinorSkill1) : - Columns::ColumnId_Skill1) + index, ColumnBase::Display_Skill), - mIndex (index), mMajor (major) - {} + SkillsColumn(int index, bool typePrefix = false, bool major = false) + : Column((typePrefix ? (major ? Columns::ColumnId_MajorSkill1 : Columns::ColumnId_MinorSkill1) + : Columns::ColumnId_Skill1) + + index, + ColumnBase::Display_Skill) + , mIndex(index) + , mMajor(major) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - int skill = record.get().mData.getSkill (mIndex, mMajor); + int skill = record.get().mData.getSkill(mIndex, mMajor); - return QString::fromUtf8 (ESM::Skill::indexToId (skill).c_str()); + return QString::fromUtf8(ESM::Skill::indexToId(skill).c_str()); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { - std::istringstream stream (data.toString().toUtf8().constData()); + std::istringstream stream(data.toString().toUtf8().constData()); int index = -1; char c; stream >> c >> index; - if (index!=-1) + if (index != -1) { ESXRecordT record2 = record.get(); - record2.mData.getSkill (mIndex, mMajor) = index; + record2.mData.getSkill(mIndex, mMajor) = index; - record.setModified (record2); + record.setModified(record2); } } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct PlayableColumn : public Column { - PlayableColumn() : Column (Columns::ColumnId_Playable, ColumnBase::Display_Boolean) - {} - - QVariant get (const Record& record) const override + PlayableColumn() + : Column(Columns::ColumnId_Playable, ColumnBase::Display_Boolean) { - return record.get().mData.mIsPlayable!=0; } - void set (Record& record, const QVariant& data) override + QVariant get(const Record& record) const override { return record.get().mData.mIsPlayable != 0; } + + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mIsPlayable = data.toInt(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct HiddenColumn : public Column { - HiddenColumn() : Column (Columns::ColumnId_Hidden, ColumnBase::Display_Boolean) {} - - QVariant get (const Record& record) const override + HiddenColumn() + : Column(Columns::ColumnId_Hidden, ColumnBase::Display_Boolean) { - return record.get().mData.mIsHidden!=0; } - void set (Record& record, const QVariant& data) override + QVariant get(const Record& record) const override { return record.get().mData.mIsHidden != 0; } + + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mIsHidden = data.toInt(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct FlagColumn : public Column { int mMask; bool mInverted; - FlagColumn (int columnId, int mask, - int flags = ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, bool inverted = false) - : Column (columnId, ColumnBase::Display_Boolean, flags), mMask (mask), - mInverted (inverted) - {} + FlagColumn(int columnId, int mask, int flags = ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, + bool inverted = false) + : Column(columnId, ColumnBase::Display_Boolean, flags) + , mMask(mask) + , mInverted(inverted) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - bool flag = (record.get().mData.mFlags & mMask)!=0; + bool flag = (record.get().mData.mFlags & mMask) != 0; if (mInverted) flag = !flag; @@ -504,40 +463,39 @@ namespace CSMWorld return flag; } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); int flags = record2.mData.mFlags & ~mMask; - if ((data.toInt()!=0)!=mInverted) + if ((data.toInt() != 0) != mInverted) flags |= mMask; record2.mData.mFlags = flags; - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct FlagColumn2 : public Column { int mMask; bool mInverted; - FlagColumn2 (int columnId, int mask, bool inverted = false) - : Column (columnId, ColumnBase::Display_Boolean), mMask (mask), - mInverted (inverted) - {} + FlagColumn2(int columnId, int mask, bool inverted = false) + : Column(columnId, ColumnBase::Display_Boolean) + , mMask(mask) + , mInverted(inverted) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - bool flag = (record.get().mFlags & mMask)!=0; + bool flag = (record.get().mFlags & mMask) != 0; if (mInverted) flag = !flag; @@ -545,67 +503,60 @@ namespace CSMWorld return flag; } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); int flags = record2.mFlags & ~mMask; - if ((data.toInt()!=0)!=mInverted) + if ((data.toInt() != 0) != mInverted) flags |= mMask; record2.mFlags = flags; - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct WeightHeightColumn : public Column { bool mMale; bool mWeight; - WeightHeightColumn (bool male, bool weight) - : Column (male ? - (weight ? Columns::ColumnId_MaleWeight : Columns::ColumnId_MaleHeight) : - (weight ? Columns::ColumnId_FemaleWeight : Columns::ColumnId_FemaleHeight), - ColumnBase::Display_Float), - mMale (male), mWeight (weight) - {} + WeightHeightColumn(bool male, bool weight) + : Column(male ? (weight ? Columns::ColumnId_MaleWeight : Columns::ColumnId_MaleHeight) + : (weight ? Columns::ColumnId_FemaleWeight : Columns::ColumnId_FemaleHeight), + ColumnBase::Display_Float) + , mMale(male) + , mWeight(weight) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - const ESM::Race::MaleFemaleF& value = - mWeight ? record.get().mData.mWeight : record.get().mData.mHeight; + const ESM::Race::MaleFemaleF& value = mWeight ? record.get().mData.mWeight : record.get().mData.mHeight; return mMale ? value.mMale : value.mFemale; } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); - ESM::Race::MaleFemaleF& value = - mWeight ? record2.mData.mWeight : record2.mData.mHeight; + ESM::Race::MaleFemaleF& value = mWeight ? record2.mData.mWeight : record2.mData.mHeight; (mMale ? value.mMale : value.mFemale) = data.toFloat(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct SoundParamColumn : public Column { enum Type @@ -617,209 +568,203 @@ namespace CSMWorld Type mType; - SoundParamColumn (Type type) - : Column (type==Type_Volume ? Columns::ColumnId_Volume : - (type==Type_MinRange ? Columns::ColumnId_MinRange : Columns::ColumnId_MaxRange), - ColumnBase::Display_Integer), - mType (type) - {} + SoundParamColumn(Type type) + : Column(type == Type_Volume + ? Columns::ColumnId_Volume + : (type == Type_MinRange ? Columns::ColumnId_MinRange : Columns::ColumnId_MaxRange), + ColumnBase::Display_Integer) + , mType(type) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { int value = 0; switch (mType) { - case Type_Volume: value = record.get().mData.mVolume; break; - case Type_MinRange: value = record.get().mData.mMinRange; break; - case Type_MaxRange: value = record.get().mData.mMaxRange; break; + case Type_Volume: + value = record.get().mData.mVolume; + break; + case Type_MinRange: + value = record.get().mData.mMinRange; + break; + case Type_MaxRange: + value = record.get().mData.mMaxRange; + break; } return value; } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { int value = data.toInt(); - if (value<0) + if (value < 0) value = 0; - else if (value>255) + else if (value > 255) value = 255; ESXRecordT record2 = record.get(); switch (mType) { - case Type_Volume: record2.mData.mVolume = static_cast (value); break; - case Type_MinRange: record2.mData.mMinRange = static_cast (value); break; - case Type_MaxRange: record2.mData.mMaxRange = static_cast (value); break; + case Type_Volume: + record2.mData.mVolume = static_cast(value); + break; + case Type_MinRange: + record2.mData.mMinRange = static_cast(value); + break; + case Type_MaxRange: + record2.mData.mMaxRange = static_cast(value); + break; } - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct SoundFileColumn : public Column { SoundFileColumn() - : Column (Columns::ColumnId_SoundFile, ColumnBase::Display_SoundRes) - {} + : Column(Columns::ColumnId_SoundFile, ColumnBase::Display_SoundRes) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return QString::fromUtf8 (record.get().mSound.c_str()); + return QString::fromUtf8(record.get().mSound.c_str()); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mSound = data.toString().toUtf8().constData(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct MapColourColumn : public Column { MapColourColumn() - : Column (Columns::ColumnId_MapColour, ColumnBase::Display_Colour) - {} - - QVariant get (const Record& record) const override + : Column(Columns::ColumnId_MapColour, ColumnBase::Display_Colour) { - return record.get().mMapColor; } - void set (Record& record, const QVariant& data) override + QVariant get(const Record& record) const override { return record.get().mMapColor; } + + void set(Record& record, const QVariant& data) override { ESXRecordT copy = record.get(); copy.mMapColor = data.toInt(); - record.setModified (copy); + record.setModified(copy); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct SleepListColumn : public Column { SleepListColumn() - : Column (Columns::ColumnId_SleepEncounter, ColumnBase::Display_CreatureLevelledList) - {} + : Column(Columns::ColumnId_SleepEncounter, ColumnBase::Display_CreatureLevelledList) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return QString::fromUtf8 (record.get().mSleepList.c_str()); + return QString::fromUtf8(record.get().mSleepList.c_str()); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mSleepList = data.toString().toUtf8().constData(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct TextureColumn : public Column { - TextureColumn() : Column (Columns::ColumnId_Texture, ColumnBase::Display_Texture) {} + TextureColumn() + : Column(Columns::ColumnId_Texture, ColumnBase::Display_Texture) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return QString::fromUtf8 (record.get().mTexture.c_str()); + return QString::fromUtf8(record.get().mTexture.c_str()); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mTexture = data.toString().toUtf8().constData(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct SpellTypeColumn : public Column { SpellTypeColumn() - : Column (Columns::ColumnId_SpellType, ColumnBase::Display_SpellType) - {} - - QVariant get (const Record& record) const override + : Column(Columns::ColumnId_SpellType, ColumnBase::Display_SpellType) { - return record.get().mData.mType; } - void set (Record& record, const QVariant& data) override + QVariant get(const Record& record) const override { return record.get().mData.mType; } + + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mType = data.toInt(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct CostColumn : public Column { - CostColumn() : Column (Columns::ColumnId_Cost, ColumnBase::Display_Integer) {} - - QVariant get (const Record& record) const override + CostColumn() + : Column(Columns::ColumnId_Cost, ColumnBase::Display_Integer) { - return record.get().mData.mCost; } - void set (Record& record, const QVariant& data) override + QVariant get(const Record& record) const override { return record.get().mData.mCost; } + + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mCost = data.toInt(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct ScriptColumn : public Column { enum Type @@ -829,523 +774,478 @@ namespace CSMWorld Type_Info // dialogue context (not implemented yet) }; - ScriptColumn (Type type) - : Column (Columns::ColumnId_ScriptText, - type==Type_File ? ColumnBase::Display_ScriptFile : ColumnBase::Display_ScriptLines, - type==Type_File ? 0 : ColumnBase::Flag_Dialogue) - {} + ScriptColumn(Type type) + : Column(Columns::ColumnId_ScriptText, + type == Type_File ? ColumnBase::Display_ScriptFile : ColumnBase::Display_ScriptLines, + type == Type_File ? 0 : ColumnBase::Flag_Dialogue) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return QString::fromUtf8 (record.get().mScriptText.c_str()); + return QString::fromUtf8(record.get().mScriptText.c_str()); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mScriptText = data.toString().toUtf8().constData(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct RegionColumn : public Column { - RegionColumn() : Column (Columns::ColumnId_Region, ColumnBase::Display_Region) {} + RegionColumn() + : Column(Columns::ColumnId_Region, ColumnBase::Display_Region) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return QString::fromUtf8 (record.get().mRegion.c_str()); + return QString::fromUtf8(record.get().mRegion.c_str()); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mRegion = data.toString().toUtf8().constData(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct CellColumn : public Column { bool mBlocked; /// \param blocked Do not allow user-modification - CellColumn (bool blocked = false) - : Column (Columns::ColumnId_Cell, ColumnBase::Display_Cell), - mBlocked (blocked) - {} + CellColumn(bool blocked = false) + : Column(Columns::ColumnId_Cell, ColumnBase::Display_Cell) + , mBlocked(blocked) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return QString::fromUtf8 (record.get().mCell.c_str()); + return QString::fromUtf8(record.get().mCell.c_str()); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mCell = data.toString().toUtf8().constData(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } - bool isUserEditable() const override - { - return !mBlocked; - } + bool isUserEditable() const override { return !mBlocked; } }; - template + template struct OriginalCellColumn : public Column { OriginalCellColumn() - : Column (Columns::ColumnId_OriginalCell, ColumnBase::Display_Cell) - {} + : Column(Columns::ColumnId_OriginalCell, ColumnBase::Display_Cell) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return QString::fromUtf8 (record.get().mOriginalCell.c_str()); + return QString::fromUtf8(record.get().mOriginalCell.c_str()); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mOriginalCell = data.toString().toUtf8().constData(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } - bool isUserEditable() const override - { - return false; - } + bool isUserEditable() const override { return false; } }; - template + template struct IdColumn : public Column { - IdColumn() : Column (Columns::ColumnId_ReferenceableId, - ColumnBase::Display_Referenceable) {} + IdColumn() + : Column(Columns::ColumnId_ReferenceableId, ColumnBase::Display_Referenceable) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return QString::fromUtf8 (record.get().mRefID.c_str()); + return QString::fromUtf8(record.get().mRefID.c_str()); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mRefID = data.toString().toUtf8().constData(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct ScaleColumn : public Column { - ScaleColumn() : Column (Columns::ColumnId_Scale, ColumnBase::Display_Float) {} - - QVariant get (const Record& record) const override + ScaleColumn() + : Column(Columns::ColumnId_Scale, ColumnBase::Display_Float) { - return record.get().mScale; } - void set (Record& record, const QVariant& data) override + QVariant get(const Record& record) const override { return record.get().mScale; } + + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mScale = data.toFloat(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct OwnerColumn : public Column { - OwnerColumn() : Column (Columns::ColumnId_Owner, ColumnBase::Display_Npc) {} + OwnerColumn() + : Column(Columns::ColumnId_Owner, ColumnBase::Display_Npc) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return QString::fromUtf8 (record.get().mOwner.c_str()); + return QString::fromUtf8(record.get().mOwner.c_str()); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mOwner = data.toString().toUtf8().constData(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct SoulColumn : public Column { - SoulColumn() : Column (Columns::ColumnId_Soul, ColumnBase::Display_Creature) {} + SoulColumn() + : Column(Columns::ColumnId_Soul, ColumnBase::Display_Creature) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return QString::fromUtf8 (record.get().mSoul.c_str()); + return QString::fromUtf8(record.get().mSoul.c_str()); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mSoul = data.toString().toUtf8().constData(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct FactionColumn : public Column { - FactionColumn() : Column (Columns::ColumnId_Faction, ColumnBase::Display_Faction) {} + FactionColumn() + : Column(Columns::ColumnId_Faction, ColumnBase::Display_Faction) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return QString::fromUtf8 (record.get().mFaction.c_str()); + return QString::fromUtf8(record.get().mFaction.c_str()); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mFaction = data.toString().toUtf8().constData(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct FactionIndexColumn : public Column { FactionIndexColumn() - : Column (Columns::ColumnId_FactionIndex, ColumnBase::Display_Integer) - {} - - QVariant get (const Record& record) const override + : Column(Columns::ColumnId_FactionIndex, ColumnBase::Display_Integer) { - return record.get().mFactionRank; } - void set (Record& record, const QVariant& data) override + QVariant get(const Record& record) const override { return record.get().mFactionRank; } + + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mFactionRank = data.toInt(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct ChargesColumn : public Column { - ChargesColumn() : Column (Columns::ColumnId_Charges, ColumnBase::Display_Integer) {} - - QVariant get (const Record& record) const override + ChargesColumn() + : Column(Columns::ColumnId_Charges, ColumnBase::Display_Integer) { - return record.get().mChargeInt; } - void set (Record& record, const QVariant& data) override + QVariant get(const Record& record) const override { return record.get().mChargeInt; } + + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mChargeInt = data.toInt(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct EnchantmentChargesColumn : public Column { EnchantmentChargesColumn() - : Column (Columns::ColumnId_Enchantment, ColumnBase::Display_Float) - {} - - QVariant get (const Record& record) const override + : Column(Columns::ColumnId_Enchantment, ColumnBase::Display_Float) { - return record.get().mEnchantmentCharge; } - void set (Record& record, const QVariant& data) override + QVariant get(const Record& record) const override { return record.get().mEnchantmentCharge; } + + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mEnchantmentCharge = data.toFloat(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct GoldValueColumn : public Column { GoldValueColumn() - : Column (Columns::ColumnId_CoinValue, ColumnBase::Display_Integer) {} - - QVariant get (const Record& record) const override + : Column(Columns::ColumnId_CoinValue, ColumnBase::Display_Integer) { - return record.get().mGoldValue; } - void set (Record& record, const QVariant& data) override + QVariant get(const Record& record) const override { return record.get().mGoldValue; } + + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mGoldValue = data.toInt(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct TeleportColumn : public Column { TeleportColumn() - : Column (Columns::ColumnId_Teleport, ColumnBase::Display_Boolean) - {} - - QVariant get (const Record& record) const override + : Column(Columns::ColumnId_Teleport, ColumnBase::Display_Boolean) { - return record.get().mTeleport; } - void set (Record& record, const QVariant& data) override + QVariant get(const Record& record) const override { return record.get().mTeleport; } + + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mTeleport = data.toInt(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct TeleportCellColumn : public Column { TeleportCellColumn() - : Column (Columns::ColumnId_TeleportCell, ColumnBase::Display_Cell) - {} + : Column(Columns::ColumnId_TeleportCell, ColumnBase::Display_Cell) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return QString::fromUtf8 (record.get().mDestCell.c_str()); + return QString::fromUtf8(record.get().mDestCell.c_str()); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mDestCell = data.toString().toUtf8().constData(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } - bool isUserEditable() const override - { - return true; - } + bool isUserEditable() const override { return true; } }; - template + template struct LockLevelColumn : public Column { LockLevelColumn() - : Column (Columns::ColumnId_LockLevel, ColumnBase::Display_Integer) - {} - - QVariant get (const Record& record) const override + : Column(Columns::ColumnId_LockLevel, ColumnBase::Display_Integer) { - return record.get().mLockLevel; } - void set (Record& record, const QVariant& data) override + QVariant get(const Record& record) const override { return record.get().mLockLevel; } + + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mLockLevel = data.toInt(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct KeyColumn : public Column { - KeyColumn() : Column (Columns::ColumnId_Key, ColumnBase::Display_Miscellaneous) {} + KeyColumn() + : Column(Columns::ColumnId_Key, ColumnBase::Display_Miscellaneous) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return QString::fromUtf8 (record.get().mKey.c_str()); + return QString::fromUtf8(record.get().mKey.c_str()); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mKey = data.toString().toUtf8().constData(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct TrapColumn : public Column { - TrapColumn() : Column (Columns::ColumnId_Trap, ColumnBase::Display_Spell) {} + TrapColumn() + : Column(Columns::ColumnId_Trap, ColumnBase::Display_Spell) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return QString::fromUtf8 (record.get().mTrap.c_str()); + return QString::fromUtf8(record.get().mTrap.c_str()); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mTrap = data.toString().toUtf8().constData(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct FilterColumn : public Column { - FilterColumn() : Column (Columns::ColumnId_Filter, ColumnBase::Display_Filter) {} + FilterColumn() + : Column(Columns::ColumnId_Filter, ColumnBase::Display_Filter) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return QString::fromUtf8 (record.get().mFilter.c_str()); + return QString::fromUtf8(record.get().mFilter.c_str()); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mFilter = data.toString().toUtf8().constData(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct PosColumn : public Column { - ESM::Position ESXRecordT::* mPosition; + ESM::Position ESXRecordT::*mPosition; int mIndex; - PosColumn (ESM::Position ESXRecordT::* position, int index, bool door) - : Column ( - (door ? Columns::ColumnId_DoorPositionXPos : Columns::ColumnId_PositionXPos)+index, - ColumnBase::Display_Float), mPosition (position), mIndex (index) {} + PosColumn(ESM::Position ESXRecordT::*position, int index, bool door) + : Column((door ? Columns::ColumnId_DoorPositionXPos : Columns::ColumnId_PositionXPos) + index, + ColumnBase::Display_Float) + , mPosition(position) + , mIndex(index) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { const ESM::Position& position = record.get().*mPosition; return position.pos[mIndex]; } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -1353,33 +1253,33 @@ namespace CSMWorld position.pos[mIndex] = data.toFloat(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct RotColumn : public Column { - ESM::Position ESXRecordT::* mPosition; + ESM::Position ESXRecordT::*mPosition; int mIndex; - RotColumn (ESM::Position ESXRecordT::* position, int index, bool door) - : Column ( - (door ? Columns::ColumnId_DoorPositionXRot : Columns::ColumnId_PositionXRot)+index, - ColumnBase::Display_Double), mPosition (position), mIndex (index) {} + RotColumn(ESM::Position ESXRecordT::*position, int index, bool door) + : Column((door ? Columns::ColumnId_DoorPositionXRot : Columns::ColumnId_PositionXRot) + index, + ColumnBase::Display_Double) + , mPosition(position) + , mIndex(index) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { const ESM::Position& position = record.get().*mPosition; return osg::RadiansToDegrees(position.rot[mIndex]); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); @@ -1387,391 +1287,358 @@ namespace CSMWorld position.rot[mIndex] = osg::DegreesToRadians(data.toFloat()); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct DialogueTypeColumn : public Column { - DialogueTypeColumn (bool hidden = false) - : Column (Columns::ColumnId_DialogueType, ColumnBase::Display_DialogueType, - hidden ? 0 : ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue) - {} - - QVariant get (const Record& record) const override + DialogueTypeColumn(bool hidden = false) + : Column(Columns::ColumnId_DialogueType, ColumnBase::Display_DialogueType, + hidden ? 0 : ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue) { - return static_cast (record.get().mType); } - void set (Record& record, const QVariant& data) override + QVariant get(const Record& record) const override { return static_cast(record.get().mType); } + + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mType = data.toInt(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } - bool isUserEditable() const override - { - return false; - } + bool isUserEditable() const override { return false; } }; - template + template struct QuestStatusTypeColumn : public Column { QuestStatusTypeColumn() - : Column (Columns::ColumnId_QuestStatusType, ColumnBase::Display_QuestStatusType) - {} + : Column(Columns::ColumnId_QuestStatusType, ColumnBase::Display_QuestStatusType) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return static_cast (record.get().mQuestStatus); + return static_cast(record.get().mQuestStatus); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); - record2.mQuestStatus = static_cast (data.toInt()); + record2.mQuestStatus = static_cast(data.toInt()); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct QuestDescriptionColumn : public Column { - QuestDescriptionColumn() : Column (Columns::ColumnId_QuestDescription, ColumnBase::Display_LongString) {} + QuestDescriptionColumn() + : Column(Columns::ColumnId_QuestDescription, ColumnBase::Display_LongString) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return QString::fromUtf8 (record.get().mResponse.c_str()); + return QString::fromUtf8(record.get().mResponse.c_str()); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mResponse = data.toString().toUtf8().constData(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct QuestIndexColumn : public Column { QuestIndexColumn() - : Column (Columns::ColumnId_QuestIndex, ColumnBase::Display_Integer) - {} - - QVariant get (const Record& record) const override + : Column(Columns::ColumnId_QuestIndex, ColumnBase::Display_Integer) { - return record.get().mData.mDisposition; } - void set (Record& record, const QVariant& data) override + QVariant get(const Record& record) const override { return record.get().mData.mDisposition; } + + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mDisposition = data.toInt(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct TopicColumn : public Column { - TopicColumn (bool journal) - : Column (journal ? Columns::ColumnId_Journal : Columns::ColumnId_Topic, - journal ? ColumnBase::Display_Journal : ColumnBase::Display_Topic) - {} + TopicColumn(bool journal) + : Column(journal ? Columns::ColumnId_Journal : Columns::ColumnId_Topic, + journal ? ColumnBase::Display_Journal : ColumnBase::Display_Topic) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return QString::fromUtf8 (record.get().mTopicId.c_str()); + return QString::fromUtf8(record.get().mTopicId.c_str()); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mTopicId = data.toString().toUtf8().constData(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } - bool isUserEditable() const override - { - return false; - } + bool isUserEditable() const override { return false; } }; - template + template struct ActorColumn : public Column { - ActorColumn() : Column (Columns::ColumnId_Actor, ColumnBase::Display_Npc) {} + ActorColumn() + : Column(Columns::ColumnId_Actor, ColumnBase::Display_Npc) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return QString::fromUtf8 (record.get().mActor.c_str()); + return QString::fromUtf8(record.get().mActor.c_str()); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mActor = data.toString().toUtf8().constData(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct RaceColumn : public Column { - RaceColumn() : Column (Columns::ColumnId_Race, ColumnBase::Display_Race) {} + RaceColumn() + : Column(Columns::ColumnId_Race, ColumnBase::Display_Race) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return QString::fromUtf8 (record.get().mRace.c_str()); + return QString::fromUtf8(record.get().mRace.c_str()); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mRace = data.toString().toUtf8().constData(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct ClassColumn : public Column { - ClassColumn() : Column (Columns::ColumnId_Class, ColumnBase::Display_Class) {} + ClassColumn() + : Column(Columns::ColumnId_Class, ColumnBase::Display_Class) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return QString::fromUtf8 (record.get().mClass.c_str()); + return QString::fromUtf8(record.get().mClass.c_str()); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mClass = data.toString().toUtf8().constData(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct PcFactionColumn : public Column { - PcFactionColumn() : Column (Columns::ColumnId_PcFaction, ColumnBase::Display_Faction) {} + PcFactionColumn() + : Column(Columns::ColumnId_PcFaction, ColumnBase::Display_Faction) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return QString::fromUtf8 (record.get().mPcFaction.c_str()); + return QString::fromUtf8(record.get().mPcFaction.c_str()); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mPcFaction = data.toString().toUtf8().constData(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct ResponseColumn : public Column { - ResponseColumn() : Column (Columns::ColumnId_Response, ColumnBase::Display_LongString) {} + ResponseColumn() + : Column(Columns::ColumnId_Response, ColumnBase::Display_LongString) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return QString::fromUtf8 (record.get().mResponse.c_str()); + return QString::fromUtf8(record.get().mResponse.c_str()); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mResponse = data.toString().toUtf8().constData(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct DispositionColumn : public Column { DispositionColumn() - : Column (Columns::ColumnId_Disposition, ColumnBase::Display_Integer) - {} - - QVariant get (const Record& record) const override + : Column(Columns::ColumnId_Disposition, ColumnBase::Display_Integer) { - return record.get().mData.mDisposition; } - void set (Record& record, const QVariant& data) override + QVariant get(const Record& record) const override { return record.get().mData.mDisposition; } + + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mDisposition = data.toInt(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct RankColumn : public Column { RankColumn() - : Column (Columns::ColumnId_Rank, ColumnBase::Display_Integer) - {} - - QVariant get (const Record& record) const override + : Column(Columns::ColumnId_Rank, ColumnBase::Display_Integer) { - return static_cast (record.get().mData.mRank); } - void set (Record& record, const QVariant& data) override + QVariant get(const Record& record) const override { - ESXRecordT record2 = record.get(); - record2.mData.mRank = static_cast (data.toInt()); - record.setModified (record2); + return static_cast(record.get().mData.mRank); } - bool isEditable() const override + void set(Record& record, const QVariant& data) override { - return true; + ESXRecordT record2 = record.get(); + record2.mData.mRank = static_cast(data.toInt()); + record.setModified(record2); } + + bool isEditable() const override { return true; } }; - template + template struct PcRankColumn : public Column { PcRankColumn() - : Column (Columns::ColumnId_PcRank, ColumnBase::Display_Integer) - {} - - QVariant get (const Record& record) const override + : Column(Columns::ColumnId_PcRank, ColumnBase::Display_Integer) { - return static_cast (record.get().mData.mPCrank); } - void set (Record& record, const QVariant& data) override + QVariant get(const Record& record) const override { - ESXRecordT record2 = record.get(); - record2.mData.mPCrank = static_cast (data.toInt()); - record.setModified (record2); + return static_cast(record.get().mData.mPCrank); } - bool isEditable() const override + void set(Record& record, const QVariant& data) override { - return true; + ESXRecordT record2 = record.get(); + record2.mData.mPCrank = static_cast(data.toInt()); + record.setModified(record2); } + + bool isEditable() const override { return true; } }; - template + template struct GenderColumn : public Column { GenderColumn() - : Column (Columns::ColumnId_Gender, ColumnBase::Display_Gender) - {} + : Column(Columns::ColumnId_Gender, ColumnBase::Display_Gender) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return static_cast (record.get().mData.mGender); + return static_cast(record.get().mData.mGender); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mGender = data.toInt(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct GenderNpcColumn : public Column { GenderNpcColumn() : Column(Columns::ColumnId_Gender, ColumnBase::Display_GenderNpc) - {} + { + } QVariant get(const Record& record) const override { @@ -1795,637 +1662,595 @@ namespace CSMWorld record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct EnchantmentTypeColumn : public Column { EnchantmentTypeColumn() - : Column (Columns::ColumnId_EnchantmentType, ColumnBase::Display_EnchantmentType) - {} + : Column(Columns::ColumnId_EnchantmentType, ColumnBase::Display_EnchantmentType) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return static_cast (record.get().mData.mType); + return static_cast(record.get().mData.mType); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mType = data.toInt(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct ChargesColumn2 : public Column { - ChargesColumn2() : Column (Columns::ColumnId_Charges, ColumnBase::Display_Integer) {} - - QVariant get (const Record& record) const override + ChargesColumn2() + : Column(Columns::ColumnId_Charges, ColumnBase::Display_Integer) { - return record.get().mData.mCharge; } - void set (Record& record, const QVariant& data) override + QVariant get(const Record& record) const override { return record.get().mData.mCharge; } + + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mCharge = data.toInt(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct AutoCalcColumn : public Column { - AutoCalcColumn() : Column (Columns::ColumnId_AutoCalc, ColumnBase::Display_Boolean) - {} - - QVariant get (const Record& record) const override + AutoCalcColumn() + : Column(Columns::ColumnId_AutoCalc, ColumnBase::Display_Boolean) { - return record.get().mData.mAutocalc!=0; } - void set (Record& record, const QVariant& data) override + QVariant get(const Record& record) const override { return record.get().mData.mAutocalc != 0; } + + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mAutocalc = data.toInt(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct ModelColumn : public Column { - ModelColumn() : Column (Columns::ColumnId_Model, ColumnBase::Display_Mesh) {} + ModelColumn() + : Column(Columns::ColumnId_Model, ColumnBase::Display_Mesh) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return QString::fromUtf8 (record.get().mModel.c_str()); + return QString::fromUtf8(record.get().mModel.c_str()); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mModel = data.toString().toUtf8().constData(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct VampireColumn : public Column { - VampireColumn() : Column (Columns::ColumnId_Vampire, ColumnBase::Display_Boolean) - {} - - QVariant get (const Record& record) const override + VampireColumn() + : Column(Columns::ColumnId_Vampire, ColumnBase::Display_Boolean) { - return record.get().mData.mVampire!=0; } - void set (Record& record, const QVariant& data) override + QVariant get(const Record& record) const override { return record.get().mData.mVampire != 0; } + + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mVampire = data.toInt(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct BodyPartTypeColumn : public Column { BodyPartTypeColumn() - : Column (Columns::ColumnId_BodyPartType, ColumnBase::Display_BodyPartType) - {} + : Column(Columns::ColumnId_BodyPartType, ColumnBase::Display_BodyPartType) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return static_cast (record.get().mData.mPart); + return static_cast(record.get().mData.mPart); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mPart = data.toInt(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct MeshTypeColumn : public Column { MeshTypeColumn(int flags = ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue) - : Column (Columns::ColumnId_MeshType, ColumnBase::Display_MeshType, flags) - {} + : Column(Columns::ColumnId_MeshType, ColumnBase::Display_MeshType, flags) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return static_cast (record.get().mData.mType); + return static_cast(record.get().mData.mType); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mType = data.toInt(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct OwnerGlobalColumn : public Column { OwnerGlobalColumn() - : Column (Columns::ColumnId_OwnerGlobal, ColumnBase::Display_GlobalVariable) - {} + : Column(Columns::ColumnId_OwnerGlobal, ColumnBase::Display_GlobalVariable) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return QString::fromUtf8 (record.get().mGlobalVariable.c_str()); + return QString::fromUtf8(record.get().mGlobalVariable.c_str()); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mGlobalVariable = data.toString().toUtf8().constData(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct RefNumCounterColumn : public Column { RefNumCounterColumn() - : Column (Columns::ColumnId_RefNumCounter, ColumnBase::Display_Integer, 0) - {} + : Column(Columns::ColumnId_RefNumCounter, ColumnBase::Display_Integer, 0) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return static_cast (record.get().mRefNumCounter); + return static_cast(record.get().mRefNumCounter); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mRefNumCounter = data.toInt(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } - bool isUserEditable() const override - { - return false; - } + bool isUserEditable() const override { return false; } }; - template + template struct RefNumColumn : public Column { RefNumColumn() - : Column (Columns::ColumnId_RefNum, ColumnBase::Display_Integer, 0) - {} + : Column(Columns::ColumnId_RefNum, ColumnBase::Display_Integer, 0) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return static_cast (record.get().mRefNum.mIndex); + return static_cast(record.get().mRefNum.mIndex); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mRefNum.mIndex = data.toInt(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } - bool isUserEditable() const override - { - return false; - } + bool isUserEditable() const override { return false; } }; - template + template struct SoundColumn : public Column { SoundColumn() - : Column (Columns::ColumnId_Sound, ColumnBase::Display_Sound) - {} + : Column(Columns::ColumnId_Sound, ColumnBase::Display_Sound) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return QString::fromUtf8 (record.get().mSound.c_str()); + return QString::fromUtf8(record.get().mSound.c_str()); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mSound = data.toString().toUtf8().constData(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct CreatureColumn : public Column { CreatureColumn() - : Column (Columns::ColumnId_Creature, ColumnBase::Display_Creature) - {} + : Column(Columns::ColumnId_Creature, ColumnBase::Display_Creature) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return QString::fromUtf8 (record.get().mCreature.c_str()); + return QString::fromUtf8(record.get().mCreature.c_str()); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mCreature = data.toString().toUtf8().constData(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct SoundGeneratorTypeColumn : public Column { SoundGeneratorTypeColumn() - : Column (Columns::ColumnId_SoundGeneratorType, ColumnBase::Display_SoundGeneratorType) - {} - - QVariant get (const Record& record) const override + : Column(Columns::ColumnId_SoundGeneratorType, ColumnBase::Display_SoundGeneratorType) { - return static_cast (record.get().mType); } - void set (Record& record, const QVariant& data) override + QVariant get(const Record& record) const override { return static_cast(record.get().mType); } + + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mType = data.toInt(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct BaseCostColumn : public Column { - BaseCostColumn() : Column (Columns::ColumnId_BaseCost, ColumnBase::Display_Float) {} - - QVariant get (const Record& record) const override + BaseCostColumn() + : Column(Columns::ColumnId_BaseCost, ColumnBase::Display_Float) { - return record.get().mData.mBaseCost; } - void set (Record& record, const QVariant& data) override + QVariant get(const Record& record) const override { return record.get().mData.mBaseCost; } + + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mBaseCost = data.toFloat(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct SchoolColumn : public Column { SchoolColumn() - : Column (Columns::ColumnId_School, ColumnBase::Display_School) - {} - - QVariant get (const Record& record) const override + : Column(Columns::ColumnId_School, ColumnBase::Display_School) { - return record.get().mData.mSchool; } - void set (Record& record, const QVariant& data) override + QVariant get(const Record& record) const override { return record.get().mData.mSchool; } + + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mData.mSchool = data.toInt(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct EffectTextureColumn : public Column { - EffectTextureColumn (Columns::ColumnId columnId) - : Column (columnId, - columnId == Columns::ColumnId_Particle ? ColumnBase::Display_Texture - : ColumnBase::Display_Icon) + EffectTextureColumn(Columns::ColumnId columnId) + : Column(columnId, + columnId == Columns::ColumnId_Particle ? ColumnBase::Display_Texture : ColumnBase::Display_Icon) { - assert (this->mColumnId==Columns::ColumnId_Icon || - this->mColumnId==Columns::ColumnId_Particle); + assert(this->mColumnId == Columns::ColumnId_Icon || this->mColumnId == Columns::ColumnId_Particle); } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return QString::fromUtf8 ( - (this->mColumnId==Columns::ColumnId_Icon ? - record.get().mIcon : record.get().mParticle).c_str()); + return QString::fromUtf8( + (this->mColumnId == Columns::ColumnId_Icon ? record.get().mIcon : record.get().mParticle).c_str()); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); - (this->mColumnId==Columns::ColumnId_Icon ? - record2.mIcon : record2.mParticle) + (this->mColumnId == Columns::ColumnId_Icon ? record2.mIcon : record2.mParticle) = data.toString().toUtf8().constData(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct EffectObjectColumn : public Column { - EffectObjectColumn (Columns::ColumnId columnId) - : Column (columnId, columnId==Columns::ColumnId_BoltObject ? ColumnBase::Display_Weapon : ColumnBase::Display_Static) + EffectObjectColumn(Columns::ColumnId columnId) + : Column(columnId, + columnId == Columns::ColumnId_BoltObject ? ColumnBase::Display_Weapon : ColumnBase::Display_Static) { - assert (this->mColumnId==Columns::ColumnId_CastingObject || - this->mColumnId==Columns::ColumnId_HitObject || - this->mColumnId==Columns::ColumnId_AreaObject || - this->mColumnId==Columns::ColumnId_BoltObject); + assert(this->mColumnId == Columns::ColumnId_CastingObject || this->mColumnId == Columns::ColumnId_HitObject + || this->mColumnId == Columns::ColumnId_AreaObject || this->mColumnId == Columns::ColumnId_BoltObject); } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - const std::string *string = nullptr; + const std::string* string = nullptr; switch (this->mColumnId) { - case Columns::ColumnId_CastingObject: string = &record.get().mCasting; break; - case Columns::ColumnId_HitObject: string = &record.get().mHit; break; - case Columns::ColumnId_AreaObject: string = &record.get().mArea; break; - case Columns::ColumnId_BoltObject: string = &record.get().mBolt; break; + case Columns::ColumnId_CastingObject: + string = &record.get().mCasting; + break; + case Columns::ColumnId_HitObject: + string = &record.get().mHit; + break; + case Columns::ColumnId_AreaObject: + string = &record.get().mArea; + break; + case Columns::ColumnId_BoltObject: + string = &record.get().mBolt; + break; } if (!string) - throw std::logic_error ("Unsupported column ID"); + throw std::logic_error("Unsupported column ID"); - return QString::fromUtf8 (string->c_str()); + return QString::fromUtf8(string->c_str()); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { - std::string *string = nullptr; + std::string* string = nullptr; ESXRecordT record2 = record.get(); switch (this->mColumnId) { - case Columns::ColumnId_CastingObject: string = &record2.mCasting; break; - case Columns::ColumnId_HitObject: string = &record2.mHit; break; - case Columns::ColumnId_AreaObject: string = &record2.mArea; break; - case Columns::ColumnId_BoltObject: string = &record2.mBolt; break; + case Columns::ColumnId_CastingObject: + string = &record2.mCasting; + break; + case Columns::ColumnId_HitObject: + string = &record2.mHit; + break; + case Columns::ColumnId_AreaObject: + string = &record2.mArea; + break; + case Columns::ColumnId_BoltObject: + string = &record2.mBolt; + break; } if (!string) - throw std::logic_error ("Unsupported column ID"); + throw std::logic_error("Unsupported column ID"); *string = data.toString().toUtf8().constData(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct EffectSoundColumn : public Column { - EffectSoundColumn (Columns::ColumnId columnId) - : Column (columnId, ColumnBase::Display_Sound) + EffectSoundColumn(Columns::ColumnId columnId) + : Column(columnId, ColumnBase::Display_Sound) { - assert (this->mColumnId==Columns::ColumnId_CastingSound || - this->mColumnId==Columns::ColumnId_HitSound || - this->mColumnId==Columns::ColumnId_AreaSound || - this->mColumnId==Columns::ColumnId_BoltSound); + assert(this->mColumnId == Columns::ColumnId_CastingSound || this->mColumnId == Columns::ColumnId_HitSound + || this->mColumnId == Columns::ColumnId_AreaSound || this->mColumnId == Columns::ColumnId_BoltSound); } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - const std::string *string = nullptr; + const std::string* string = nullptr; switch (this->mColumnId) { - case Columns::ColumnId_CastingSound: string = &record.get().mCastSound; break; - case Columns::ColumnId_HitSound: string = &record.get().mHitSound; break; - case Columns::ColumnId_AreaSound: string = &record.get().mAreaSound; break; - case Columns::ColumnId_BoltSound: string = &record.get().mBoltSound; break; + case Columns::ColumnId_CastingSound: + string = &record.get().mCastSound; + break; + case Columns::ColumnId_HitSound: + string = &record.get().mHitSound; + break; + case Columns::ColumnId_AreaSound: + string = &record.get().mAreaSound; + break; + case Columns::ColumnId_BoltSound: + string = &record.get().mBoltSound; + break; } if (!string) - throw std::logic_error ("Unsupported column ID"); + throw std::logic_error("Unsupported column ID"); - return QString::fromUtf8 (string->c_str()); + return QString::fromUtf8(string->c_str()); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { - std::string *string = nullptr; + std::string* string = nullptr; ESXRecordT record2 = record.get(); switch (this->mColumnId) { - case Columns::ColumnId_CastingSound: string = &record2.mCastSound; break; - case Columns::ColumnId_HitSound: string = &record2.mHitSound; break; - case Columns::ColumnId_AreaSound: string = &record2.mAreaSound; break; - case Columns::ColumnId_BoltSound: string = &record2.mBoltSound; break; + case Columns::ColumnId_CastingSound: + string = &record2.mCastSound; + break; + case Columns::ColumnId_HitSound: + string = &record2.mHitSound; + break; + case Columns::ColumnId_AreaSound: + string = &record2.mAreaSound; + break; + case Columns::ColumnId_BoltSound: + string = &record2.mBoltSound; + break; } if (!string) - throw std::logic_error ("Unsupported column ID"); + throw std::logic_error("Unsupported column ID"); *string = data.toString().toUtf8().constData(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct FormatColumn : public Column { FormatColumn() - : Column (Columns::ColumnId_FileFormat, ColumnBase::Display_Integer) - {} - - QVariant get (const Record& record) const override + : Column(Columns::ColumnId_FileFormat, ColumnBase::Display_Integer) { - return record.get().mFormat; } - bool isEditable() const override - { - return false; - } + QVariant get(const Record& record) const override { return record.get().mFormat; } + + bool isEditable() const override { return false; } }; - template + template struct AuthorColumn : public Column { AuthorColumn() - : Column (Columns::ColumnId_Author, ColumnBase::Display_String32) - {} + : Column(Columns::ColumnId_Author, ColumnBase::Display_String32) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return QString::fromUtf8 (record.get().mAuthor.c_str()); + return QString::fromUtf8(record.get().mAuthor.c_str()); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mAuthor = data.toString().toUtf8().constData(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; - template + template struct FileDescriptionColumn : public Column { FileDescriptionColumn() - : Column (Columns::ColumnId_FileDescription, ColumnBase::Display_LongString256) - {} + : Column(Columns::ColumnId_FileDescription, ColumnBase::Display_LongString256) + { + } - QVariant get (const Record& record) const override + QVariant get(const Record& record) const override { - return QString::fromUtf8 (record.get().mDescription.c_str()); + return QString::fromUtf8(record.get().mDescription.c_str()); } - void set (Record& record, const QVariant& data) override + void set(Record& record, const QVariant& data) override { ESXRecordT record2 = record.get(); record2.mDescription = data.toString().toUtf8().constData(); - record.setModified (record2); + record.setModified(record2); } - bool isEditable() const override - { - return true; - } + bool isEditable() const override { return true; } }; struct LandTextureNicknameColumn : public Column @@ -2507,12 +2332,12 @@ namespace CSMWorld struct BodyPartRaceColumn : public RaceColumn { - const MeshTypeColumn *mMeshType; + const MeshTypeColumn* mMeshType; - BodyPartRaceColumn(const MeshTypeColumn *meshType); + BodyPartRaceColumn(const MeshTypeColumn* meshType); - QVariant get(const Record &record) const override; - void set(Record &record, const QVariant &data) override; + QVariant get(const Record& record) const override; + void set(Record& record, const QVariant& data) override; bool isEditable() const override; }; } diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index 83d8f05959..517080ce68 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -3,8 +3,8 @@ #include #include -#include "universalid.hpp" #include "infoselectwrapper.hpp" +#include "universalid.hpp" namespace CSMWorld { @@ -13,11 +13,10 @@ namespace CSMWorld struct ColumnDesc { int mId; - const char *mName; + const char* mName; }; - const ColumnDesc sNames[] = - { + const ColumnDesc sNames[] = { { ColumnId_Value, "Value" }, { ColumnId_Id, "ID" }, { ColumnId_Modification, "Modified" }, @@ -175,7 +174,7 @@ namespace CSMWorld { ColumnId_ContainerContent, "Content" }, { ColumnId_ItemCount, "Count" }, - { ColumnId_InventoryItemId, "Item ID"}, + { ColumnId_InventoryItemId, "Item ID" }, { ColumnId_CombatState, "Combat" }, { ColumnId_MagicState, "Magic" }, @@ -187,16 +186,16 @@ namespace CSMWorld { ColumnId_ActorInventory, "Inventory" }, { ColumnId_SpellList, "Spells" }, - { ColumnId_SpellId, "Spell ID"}, + { ColumnId_SpellId, "Spell ID" }, { ColumnId_NpcDestinations, "Destinations" }, - { ColumnId_DestinationCell, "Dest Cell"}, - { ColumnId_PosX, "Dest X"}, - { ColumnId_PosY, "Dest Y"}, - { ColumnId_PosZ, "Dest Z"}, - { ColumnId_RotX, "Rotation X"}, - { ColumnId_RotY, "Rotation Y"}, - { ColumnId_RotZ, "Rotation Z"}, + { ColumnId_DestinationCell, "Dest Cell" }, + { ColumnId_PosX, "Dest X" }, + { ColumnId_PosY, "Dest Y" }, + { ColumnId_PosZ, "Dest Z" }, + { ColumnId_RotX, "Rotation X" }, + { ColumnId_RotY, "Rotation Y" }, + { ColumnId_RotZ, "Rotation Z" }, { ColumnId_OwnerGlobal, "Owner Global" }, { ColumnId_DefaultProfile, "Default Profile" }, @@ -265,9 +264,9 @@ namespace CSMWorld { ColumnId_PartRefMale, "Male Part" }, { ColumnId_PartRefFemale, "Female Part" }, - { ColumnId_LevelledList,"Levelled List" }, - { ColumnId_LevelledItemId,"Levelled Item" }, - { ColumnId_LevelledItemLevel,"PC Level" }, + { ColumnId_LevelledList, "Levelled List" }, + { ColumnId_LevelledItemId, "Levelled Item" }, + { ColumnId_LevelledItemLevel, "PC Level" }, { ColumnId_LevelledItemType, "Calculate all levels <= player" }, { ColumnId_LevelledItemTypeEach, "Select a new item for each instance" }, { ColumnId_LevelledItemChanceNone, "Chance None" }, @@ -373,7 +372,7 @@ namespace CSMWorld { ColumnId_Persistent, "Persistent" }, { ColumnId_Blocked, "Blocked" }, - { ColumnId_LevelledCreatureId,"Levelled Creature" }, + { ColumnId_LevelledCreatureId, "Levelled Creature" }, // end marker { -1, 0 }, @@ -381,18 +380,18 @@ namespace CSMWorld } } -std::string CSMWorld::Columns::getName (ColumnId column) +std::string CSMWorld::Columns::getName(ColumnId column) { - for (int i=0; sNames[i].mName; ++i) - if (column==sNames[i].mId) + for (int i = 0; sNames[i].mName; ++i) + if (column == sNames[i].mId) return sNames[i].mName; return ""; } -int CSMWorld::Columns::getId (const std::string& name) +int CSMWorld::Columns::getId(const std::string& name) { - for (int i=0; sNames[i].mName; ++i) + for (int i = 0; sNames[i].mName; ++i) if (Misc::StringUtils::ciEqual(std::string_view(sNames[i].mName), name)) return sNames[i].mId; @@ -401,246 +400,191 @@ int CSMWorld::Columns::getId (const std::string& name) namespace { - static const char *sSpecialisations[] = - { - "Combat", "Magic", "Stealth", 0 - }; + static const char* sSpecialisations[] = { "Combat", "Magic", "Stealth", 0 }; // see ESM::Attribute::AttributeID in - static const char *sAttributes[] = - { - "Strength", "Intelligence", "Willpower", "Agility", "Speed", "Endurance", "Personality", - "Luck", 0 - }; + static const char* sAttributes[] + = { "Strength", "Intelligence", "Willpower", "Agility", "Speed", "Endurance", "Personality", "Luck", 0 }; - static const char *sSpellTypes[] = - { - "Spell", "Ability", "Blight", "Disease", "Curse", "Power", 0 - }; + static const char* sSpellTypes[] = { "Spell", "Ability", "Blight", "Disease", "Curse", "Power", 0 }; - static const char *sApparatusTypes[] = - { - "Mortar & Pestle", "Alembic", "Calcinator", "Retort", 0 - }; + static const char* sApparatusTypes[] = { "Mortar & Pestle", "Alembic", "Calcinator", "Retort", 0 }; - static const char *sArmorTypes[] = - { - "Helmet", "Cuirass", "Left Pauldron", "Right Pauldron", "Greaves", "Boots", "Left Gauntlet", - "Right Gauntlet", "Shield", "Left Bracer", "Right Bracer", 0 - }; + static const char* sArmorTypes[] = { "Helmet", "Cuirass", "Left Pauldron", "Right Pauldron", "Greaves", "Boots", + "Left Gauntlet", "Right Gauntlet", "Shield", "Left Bracer", "Right Bracer", 0 }; - static const char *sClothingTypes[] = - { - "Pants", "Shoes", "Shirt", "Belt", "Robe", "Right Glove", "Left Glove", "Skirt", "Ring", - "Amulet", 0 - }; + static const char* sClothingTypes[] + = { "Pants", "Shoes", "Shirt", "Belt", "Robe", "Right Glove", "Left Glove", "Skirt", "Ring", "Amulet", 0 }; - static const char *sCreatureTypes[] = - { - "Creature", "Daedra", "Undead", "Humanoid", 0 - }; + static const char* sCreatureTypes[] = { "Creature", "Daedra", "Undead", "Humanoid", 0 }; - static const char *sWeaponTypes[] = - { - "Short Blade 1H", "Long Blade 1H", "Long Blade 2H", "Blunt 1H", "Blunt 2H Close", - "Blunt 2H Wide", "Spear 2H", "Axe 1H", "Axe 2H", "Bow", "Crossbow", "Thrown", "Arrow", - "Bolt", 0 - }; + static const char* sWeaponTypes[] + = { "Short Blade 1H", "Long Blade 1H", "Long Blade 2H", "Blunt 1H", "Blunt 2H Close", "Blunt 2H Wide", + "Spear 2H", "Axe 1H", "Axe 2H", "Bow", "Crossbow", "Thrown", "Arrow", "Bolt", 0 }; - static const char *sModificationEnums[] = - { - "Base", "Modified", "Added", "Deleted", "Deleted", 0 - }; + static const char* sModificationEnums[] = { "Base", "Modified", "Added", "Deleted", "Deleted", 0 }; - static const char *sVarTypeEnums[] = - { - "unknown", "none", "short", "integer", "long", "float", "string", 0 - }; + static const char* sVarTypeEnums[] = { "unknown", "none", "short", "integer", "long", "float", "string", 0 }; - static const char *sDialogueTypeEnums[] = - { - "Topic", "Voice", "Greeting", "Persuasion", 0 - }; + static const char* sDialogueTypeEnums[] = { "Topic", "Voice", "Greeting", "Persuasion", 0 }; - static const char *sQuestStatusTypes[] = - { - "None", "Name", "Finished", "Restart", 0 - }; + static const char* sQuestStatusTypes[] = { "None", "Name", "Finished", "Restart", 0 }; - static const char *sGenderEnums[] = - { - "Male", "Female", 0 - }; + static const char* sGenderEnums[] = { "Male", "Female", 0 }; - static const char *sEnchantmentTypes[] = - { - "Cast Once", "When Strikes", "When Used", "Constant Effect", 0 - }; + static const char* sEnchantmentTypes[] = { "Cast Once", "When Strikes", "When Used", "Constant Effect", 0 }; - static const char *sBodyPartTypes[] = - { - "Head", "Hair", "Neck", "Chest", "Groin", "Hand", "Wrist", "Forearm", "Upper Arm", - "Foot", "Ankle", "Knee", "Upper Leg", "Clavicle", "Tail", 0 - }; + static const char* sBodyPartTypes[] = { "Head", "Hair", "Neck", "Chest", "Groin", "Hand", "Wrist", "Forearm", + "Upper Arm", "Foot", "Ankle", "Knee", "Upper Leg", "Clavicle", "Tail", 0 }; - static const char *sMeshTypes[] = - { - "Skin", "Clothing", "Armour", 0 - }; + static const char* sMeshTypes[] = { "Skin", "Clothing", "Armour", 0 }; - static const char *sSoundGeneratorType[] = - { - "Left Foot", "Right Foot", "Swim Left", "Swim Right", "Moan", "Roar", "Scream", - "Land", 0 - }; + static const char* sSoundGeneratorType[] + = { "Left Foot", "Right Foot", "Swim Left", "Swim Right", "Moan", "Roar", "Scream", "Land", 0 }; - static const char *sSchools[] = - { - "Alteration", "Conjuration", "Destruction", "Illusion", "Mysticism", "Restoration", 0 - }; + static const char* sSchools[] + = { "Alteration", "Conjuration", "Destruction", "Illusion", "Mysticism", "Restoration", 0 }; // impact from magic effects, see ESM::Skill::SkillEnum in - static const char *sSkills[] = - { - "Block", "Armorer", "MediumArmor", "HeavyArmor", "BluntWeapon", - "LongBlade", "Axe", "Spear", "Athletics", "Enchant", - "Destruction", "Alteration", "Illusion", "Conjuration", "Mysticism", - "Restoration", "Alchemy", "Unarmored", "Security", "Sneak", - "Acrobatics", "LightArmor", "ShortBlade", "Marksman", "Mercantile", - "Speechcraft", "HandToHand", 0 - }; + static const char* sSkills[] = { "Block", "Armorer", "MediumArmor", "HeavyArmor", "BluntWeapon", "LongBlade", "Axe", + "Spear", "Athletics", "Enchant", "Destruction", "Alteration", "Illusion", "Conjuration", "Mysticism", + "Restoration", "Alchemy", "Unarmored", "Security", "Sneak", "Acrobatics", "LightArmor", "ShortBlade", + "Marksman", "Mercantile", "Speechcraft", "HandToHand", 0 }; // range of magic effects, see ESM::RangeType in - static const char *sEffectRange[] = - { - "Self", "Touch", "Target", 0 - }; + static const char* sEffectRange[] = { "Self", "Touch", "Target", 0 }; // magic effect names, see ESM::MagicEffect::Effects in - static const char *sEffectId[] = - { - "WaterBreathing", "SwiftSwim", "WaterWalking", "Shield", "FireShield", - "LightningShield", "FrostShield", "Burden", "Feather", "Jump", - "Levitate", "SlowFall", "Lock", "Open", "FireDamage", - "ShockDamage", "FrostDamage", "DrainAttribute", "DrainHealth", "DrainMagicka", - "DrainFatigue", "DrainSkill", "DamageAttribute", "DamageHealth", "DamageMagicka", - "DamageFatigue", "DamageSkill", "Poison", "WeaknessToFire", "WeaknessToFrost", - "WeaknessToShock", "WeaknessToMagicka", "WeaknessToCommonDisease", "WeaknessToBlightDisease", "WeaknessToCorprusDisease", - "WeaknessToPoison", "WeaknessToNormalWeapons", "DisintegrateWeapon", "DisintegrateArmor", "Invisibility", - "Chameleon", "Light", "Sanctuary", "NightEye", "Charm", - "Paralyze", "Silence", "Blind", "Sound", "CalmHumanoid", - "CalmCreature", "FrenzyHumanoid", "FrenzyCreature", "DemoralizeHumanoid", "DemoralizeCreature", - "RallyHumanoid", "RallyCreature", "Dispel", "Soultrap", "Telekinesis", - "Mark", "Recall", "DivineIntervention", "AlmsiviIntervention", "DetectAnimal", - "DetectEnchantment", "DetectKey", "SpellAbsorption", "Reflect", "CureCommonDisease", - "CureBlightDisease", "CureCorprusDisease", "CurePoison", "CureParalyzation", "RestoreAttribute", - "RestoreHealth", "RestoreMagicka", "RestoreFatigue", "RestoreSkill", "FortifyAttribute", - "FortifyHealth", "FortifyMagicka", "FortifyFatigue", "FortifySkill", "FortifyMaximumMagicka", - "AbsorbAttribute", "AbsorbHealth", "AbsorbMagicka", "AbsorbFatigue", "AbsorbSkill", - "ResistFire", "ResistFrost", "ResistShock", "ResistMagicka", "ResistCommonDisease", + static const char* sEffectId[] = { "WaterBreathing", "SwiftSwim", "WaterWalking", "Shield", "FireShield", + "LightningShield", "FrostShield", "Burden", "Feather", "Jump", "Levitate", "SlowFall", "Lock", "Open", + "FireDamage", "ShockDamage", "FrostDamage", "DrainAttribute", "DrainHealth", "DrainMagicka", "DrainFatigue", + "DrainSkill", "DamageAttribute", "DamageHealth", "DamageMagicka", "DamageFatigue", "DamageSkill", "Poison", + "WeaknessToFire", "WeaknessToFrost", "WeaknessToShock", "WeaknessToMagicka", "WeaknessToCommonDisease", + "WeaknessToBlightDisease", "WeaknessToCorprusDisease", "WeaknessToPoison", "WeaknessToNormalWeapons", + "DisintegrateWeapon", "DisintegrateArmor", "Invisibility", "Chameleon", "Light", "Sanctuary", "NightEye", + "Charm", "Paralyze", "Silence", "Blind", "Sound", "CalmHumanoid", "CalmCreature", "FrenzyHumanoid", + "FrenzyCreature", "DemoralizeHumanoid", "DemoralizeCreature", "RallyHumanoid", "RallyCreature", "Dispel", + "Soultrap", "Telekinesis", "Mark", "Recall", "DivineIntervention", "AlmsiviIntervention", "DetectAnimal", + "DetectEnchantment", "DetectKey", "SpellAbsorption", "Reflect", "CureCommonDisease", "CureBlightDisease", + "CureCorprusDisease", "CurePoison", "CureParalyzation", "RestoreAttribute", "RestoreHealth", "RestoreMagicka", + "RestoreFatigue", "RestoreSkill", "FortifyAttribute", "FortifyHealth", "FortifyMagicka", "FortifyFatigue", + "FortifySkill", "FortifyMaximumMagicka", "AbsorbAttribute", "AbsorbHealth", "AbsorbMagicka", "AbsorbFatigue", + "AbsorbSkill", "ResistFire", "ResistFrost", "ResistShock", "ResistMagicka", "ResistCommonDisease", "ResistBlightDisease", "ResistCorprusDisease", "ResistPoison", "ResistNormalWeapons", "ResistParalysis", - "RemoveCurse", "TurnUndead", "SummonScamp", "SummonClannfear", "SummonDaedroth", - "SummonDremora", "SummonAncestralGhost", "SummonSkeletalMinion", "SummonBonewalker", "SummonGreaterBonewalker", - "SummonBonelord", "SummonWingedTwilight", "SummonHunger", "SummonGoldenSaint", "SummonFlameAtronach", - "SummonFrostAtronach", "SummonStormAtronach", "FortifyAttack", "CommandCreature", "CommandHumanoid", - "BoundDagger", "BoundLongsword", "BoundMace", "BoundBattleAxe", "BoundSpear", - "BoundLongbow", "ExtraSpell", "BoundCuirass", "BoundHelm", "BoundBoots", - "BoundShield", "BoundGloves", "Corprus", "Vampirism", "SummonCenturionSphere", - "SunDamage", "StuntedMagicka", "SummonFabricant", "SummonWolf", "SummonBear", - "SummonBonewolf", "SummonCreature04", "SummonCreature05", 0 - }; + "RemoveCurse", "TurnUndead", "SummonScamp", "SummonClannfear", "SummonDaedroth", "SummonDremora", + "SummonAncestralGhost", "SummonSkeletalMinion", "SummonBonewalker", "SummonGreaterBonewalker", "SummonBonelord", + "SummonWingedTwilight", "SummonHunger", "SummonGoldenSaint", "SummonFlameAtronach", "SummonFrostAtronach", + "SummonStormAtronach", "FortifyAttack", "CommandCreature", "CommandHumanoid", "BoundDagger", "BoundLongsword", + "BoundMace", "BoundBattleAxe", "BoundSpear", "BoundLongbow", "ExtraSpell", "BoundCuirass", "BoundHelm", + "BoundBoots", "BoundShield", "BoundGloves", "Corprus", "Vampirism", "SummonCenturionSphere", "SunDamage", + "StuntedMagicka", "SummonFabricant", "SummonWolf", "SummonBear", "SummonBonewolf", "SummonCreature04", + "SummonCreature05", 0 }; // see ESM::PartReferenceType in - static const char *sPartRefType[] = - { - "Head", "Hair", "Neck", "Cuirass", "Groin", - "Skirt", "Right Hand", "Left Hand", "Right Wrist", "Left Wrist", - "Shield", "Right Forearm", "Left Forearm", "Right Upperarm", "Left Upperarm", - "Right Foot", "Left Foot", "Right Ankle", "Left Ankle", "Right Knee", - "Left Knee", "Right Leg", "Left Leg", "Right Pauldron", "Left Pauldron", - "Weapon", "Tail", 0 - }; + static const char* sPartRefType[] = { "Head", "Hair", "Neck", "Cuirass", "Groin", "Skirt", "Right Hand", + "Left Hand", "Right Wrist", "Left Wrist", "Shield", "Right Forearm", "Left Forearm", "Right Upperarm", + "Left Upperarm", "Right Foot", "Left Foot", "Right Ankle", "Left Ankle", "Right Knee", "Left Knee", "Right Leg", + "Left Leg", "Right Pauldron", "Left Pauldron", "Weapon", "Tail", 0 }; // see the enums in - static const char *sAiPackageType[] = - { - "AI Wander", "AI Travel", "AI Follow", "AI Escort", "AI Activate", 0 - }; + static const char* sAiPackageType[] = { "AI Wander", "AI Travel", "AI Follow", "AI Escort", "AI Activate", 0 }; - static const char *sBookType[] = - { - "Book", "Scroll", 0 - }; + static const char* sBookType[] = { "Book", "Scroll", 0 }; - static const char *sEmitterType[] = - { - "", "Flickering", "Flickering (Slow)", "Pulsing", "Pulsing (Slow)", 0 - }; + static const char* sEmitterType[] = { "", "Flickering", "Flickering (Slow)", "Pulsing", "Pulsing (Slow)", 0 }; - const char **getEnumNames (CSMWorld::Columns::ColumnId column) + const char** getEnumNames(CSMWorld::Columns::ColumnId column) { switch (column) { - case CSMWorld::Columns::ColumnId_Specialisation: return sSpecialisations; - case CSMWorld::Columns::ColumnId_Attribute: return sAttributes; - case CSMWorld::Columns::ColumnId_SpellType: return sSpellTypes; - case CSMWorld::Columns::ColumnId_ApparatusType: return sApparatusTypes; - case CSMWorld::Columns::ColumnId_ArmorType: return sArmorTypes; - case CSMWorld::Columns::ColumnId_ClothingType: return sClothingTypes; - case CSMWorld::Columns::ColumnId_CreatureType: return sCreatureTypes; - case CSMWorld::Columns::ColumnId_WeaponType: return sWeaponTypes; - case CSMWorld::Columns::ColumnId_Modification: return sModificationEnums; - case CSMWorld::Columns::ColumnId_ValueType: return sVarTypeEnums; - case CSMWorld::Columns::ColumnId_DialogueType: return sDialogueTypeEnums; - case CSMWorld::Columns::ColumnId_QuestStatusType: return sQuestStatusTypes; - case CSMWorld::Columns::ColumnId_Gender: return sGenderEnums; - case CSMWorld::Columns::ColumnId_EnchantmentType: return sEnchantmentTypes; - case CSMWorld::Columns::ColumnId_BodyPartType: return sBodyPartTypes; - case CSMWorld::Columns::ColumnId_MeshType: return sMeshTypes; - case CSMWorld::Columns::ColumnId_SoundGeneratorType: return sSoundGeneratorType; - case CSMWorld::Columns::ColumnId_School: return sSchools; - case CSMWorld::Columns::ColumnId_Skill: return sSkills; - case CSMWorld::Columns::ColumnId_EffectRange: return sEffectRange; - case CSMWorld::Columns::ColumnId_EffectId: return sEffectId; - case CSMWorld::Columns::ColumnId_PartRefType: return sPartRefType; - case CSMWorld::Columns::ColumnId_AiPackageType: return sAiPackageType; - case CSMWorld::Columns::ColumnId_InfoCondFunc: return CSMWorld::ConstInfoSelectWrapper::FunctionEnumStrings; - case CSMWorld::Columns::ColumnId_InfoCondComp: return CSMWorld::ConstInfoSelectWrapper::RelationEnumStrings; - case CSMWorld::Columns::ColumnId_BookType: return sBookType; - case CSMWorld::Columns::ColumnId_EmitterType: return sEmitterType; - - default: return 0; + case CSMWorld::Columns::ColumnId_Specialisation: + return sSpecialisations; + case CSMWorld::Columns::ColumnId_Attribute: + return sAttributes; + case CSMWorld::Columns::ColumnId_SpellType: + return sSpellTypes; + case CSMWorld::Columns::ColumnId_ApparatusType: + return sApparatusTypes; + case CSMWorld::Columns::ColumnId_ArmorType: + return sArmorTypes; + case CSMWorld::Columns::ColumnId_ClothingType: + return sClothingTypes; + case CSMWorld::Columns::ColumnId_CreatureType: + return sCreatureTypes; + case CSMWorld::Columns::ColumnId_WeaponType: + return sWeaponTypes; + case CSMWorld::Columns::ColumnId_Modification: + return sModificationEnums; + case CSMWorld::Columns::ColumnId_ValueType: + return sVarTypeEnums; + case CSMWorld::Columns::ColumnId_DialogueType: + return sDialogueTypeEnums; + case CSMWorld::Columns::ColumnId_QuestStatusType: + return sQuestStatusTypes; + case CSMWorld::Columns::ColumnId_Gender: + return sGenderEnums; + case CSMWorld::Columns::ColumnId_EnchantmentType: + return sEnchantmentTypes; + case CSMWorld::Columns::ColumnId_BodyPartType: + return sBodyPartTypes; + case CSMWorld::Columns::ColumnId_MeshType: + return sMeshTypes; + case CSMWorld::Columns::ColumnId_SoundGeneratorType: + return sSoundGeneratorType; + case CSMWorld::Columns::ColumnId_School: + return sSchools; + case CSMWorld::Columns::ColumnId_Skill: + return sSkills; + case CSMWorld::Columns::ColumnId_EffectRange: + return sEffectRange; + case CSMWorld::Columns::ColumnId_EffectId: + return sEffectId; + case CSMWorld::Columns::ColumnId_PartRefType: + return sPartRefType; + case CSMWorld::Columns::ColumnId_AiPackageType: + return sAiPackageType; + case CSMWorld::Columns::ColumnId_InfoCondFunc: + return CSMWorld::ConstInfoSelectWrapper::FunctionEnumStrings; + case CSMWorld::Columns::ColumnId_InfoCondComp: + return CSMWorld::ConstInfoSelectWrapper::RelationEnumStrings; + case CSMWorld::Columns::ColumnId_BookType: + return sBookType; + case CSMWorld::Columns::ColumnId_EmitterType: + return sEmitterType; + + default: + return 0; } } } -bool CSMWorld::Columns::hasEnums (ColumnId column) +bool CSMWorld::Columns::hasEnums(ColumnId column) { - return getEnumNames (column)!=0 || column==ColumnId_RecordType; + return getEnumNames(column) != 0 || column == ColumnId_RecordType; } -std::vector>CSMWorld::Columns::getEnums (ColumnId column) +std::vector> CSMWorld::Columns::getEnums(ColumnId column) { - std::vector> enums; + std::vector> enums; - if (const char **table = getEnumNames (column)) - for (int i=0; table[i]; ++i) + if (const char** table = getEnumNames(column)) + for (int i = 0; table[i]; ++i) enums.emplace_back(i, table[i]); - else if (column==ColumnId_BloodType) + else if (column == ColumnId_BloodType) { - for (int i=0; i<8; i++) + for (int i = 0; i < 8; i++) { std::string_view bloodName = Fallback::Map::getString("Blood_Texture_Name_" + std::to_string(i)); if (!bloodName.empty()) enums.emplace_back(i, bloodName); } } - else if (column==ColumnId_RecordType) + else if (column == ColumnId_RecordType) { enums.emplace_back(UniversalId::Type_None, ""); // none - for (int i=UniversalId::Type_None+1; i (i)).getTypeName()); + for (int i = UniversalId::Type_None + 1; i < UniversalId::NumberOfTypes; ++i) + enums.emplace_back(i, UniversalId(static_cast(i)).getTypeName()); } return enums; diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 5e43a4d561..acb7c9b2b7 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -383,14 +383,14 @@ namespace CSMWorld ColumnId_Skill7 = 0x50006 }; - std::string getName (ColumnId column); + std::string getName(ColumnId column); - int getId (const std::string& name); + int getId(const std::string& name); ///< Will return -1 for an invalid name. - bool hasEnums (ColumnId column); + bool hasEnums(ColumnId column); - std::vector> getEnums (ColumnId column); + std::vector> getEnums(ColumnId column); ///< Returns an empty vector, if \a column isn't an enum type column. } } diff --git a/apps/opencs/model/world/commanddispatcher.cpp b/apps/opencs/model/world/commanddispatcher.cpp index 00d949f450..e8adb5f3a7 100644 --- a/apps/opencs/model/world/commanddispatcher.cpp +++ b/apps/opencs/model/world/commanddispatcher.cpp @@ -3,49 +3,48 @@ #include #include -#include #include +#include #include "../doc/document.hpp" -#include "idtable.hpp" -#include "record.hpp" +#include "commandmacro.hpp" #include "commands.hpp" +#include "idtable.hpp" #include "idtableproxymodel.hpp" -#include "commandmacro.hpp" +#include "record.hpp" std::vector CSMWorld::CommandDispatcher::getDeletableRecords() const { std::vector result; - IdTable& model = dynamic_cast (*mDocument.getData().getTableModel (mId)); + IdTable& model = dynamic_cast(*mDocument.getData().getTableModel(mId)); - int stateColumnIndex = model.findColumnIndex (Columns::ColumnId_Modification); + int stateColumnIndex = model.findColumnIndex(Columns::ColumnId_Modification); - for (std::vector::const_iterator iter (mSelection.begin()); - iter!=mSelection.end(); ++iter) + for (std::vector::const_iterator iter(mSelection.begin()); iter != mSelection.end(); ++iter) { - int row = model.getModelIndex (*iter, 0).row(); + int row = model.getModelIndex(*iter, 0).row(); // check record state - RecordBase::State state = static_cast ( - model.data (model.index (row, stateColumnIndex)).toInt()); + RecordBase::State state + = static_cast(model.data(model.index(row, stateColumnIndex)).toInt()); - if (state==RecordBase::State_Deleted) + if (state == RecordBase::State_Deleted) continue; // check other columns (only relevant for a subset of the tables) - int dialogueTypeIndex = model.searchColumnIndex (Columns::ColumnId_DialogueType); + int dialogueTypeIndex = model.searchColumnIndex(Columns::ColumnId_DialogueType); - if (dialogueTypeIndex!=-1) + if (dialogueTypeIndex != -1) { - int type = model.data (model.index (row, dialogueTypeIndex)).toInt(); + int type = model.data(model.index(row, dialogueTypeIndex)).toInt(); - if (type!=ESM::Dialogue::Topic && type!=ESM::Dialogue::Journal) + if (type != ESM::Dialogue::Topic && type != ESM::Dialogue::Journal) continue; } - result.push_back (*iter); + result.push_back(*iter); } return result; @@ -55,53 +54,57 @@ std::vector CSMWorld::CommandDispatcher::getRevertableRecords() con { std::vector result; - IdTable& model = dynamic_cast (*mDocument.getData().getTableModel (mId)); + IdTable& model = dynamic_cast(*mDocument.getData().getTableModel(mId)); /// \todo Reverting temporarily disabled on tables that support reordering, because /// revert logic currently can not handle reordering. if (model.getFeatures() & IdTable::Feature_ReorderWithinTopic) return result; - int stateColumnIndex = model.findColumnIndex (Columns::ColumnId_Modification); + int stateColumnIndex = model.findColumnIndex(Columns::ColumnId_Modification); - for (std::vector::const_iterator iter (mSelection.begin()); - iter!=mSelection.end(); ++iter) + for (std::vector::const_iterator iter(mSelection.begin()); iter != mSelection.end(); ++iter) { - int row = model.getModelIndex (*iter, 0).row(); + int row = model.getModelIndex(*iter, 0).row(); // check record state - RecordBase::State state = static_cast ( - model.data (model.index (row, stateColumnIndex)).toInt()); + RecordBase::State state + = static_cast(model.data(model.index(row, stateColumnIndex)).toInt()); - if (state==RecordBase::State_BaseOnly) + if (state == RecordBase::State_BaseOnly) continue; - result.push_back (*iter); + result.push_back(*iter); } return result; } -CSMWorld::CommandDispatcher::CommandDispatcher (CSMDoc::Document& document, - const CSMWorld::UniversalId& id, QObject *parent) -: QObject (parent), mLocked (false), mDocument (document), mId (id) -{} +CSMWorld::CommandDispatcher::CommandDispatcher( + CSMDoc::Document& document, const CSMWorld::UniversalId& id, QObject* parent) + : QObject(parent) + , mLocked(false) + , mDocument(document) + , mId(id) +{ +} -void CSMWorld::CommandDispatcher::setEditLock (bool locked) +void CSMWorld::CommandDispatcher::setEditLock(bool locked) { mLocked = locked; } -void CSMWorld::CommandDispatcher::setSelection (const std::vector& selection) +void CSMWorld::CommandDispatcher::setSelection(const std::vector& selection) { mSelection = selection; - for (auto& sel : mSelection) { + for (auto& sel : mSelection) + { Misc::StringUtils::lowerCaseInPlace(sel); } - std::sort (mSelection.begin(), mSelection.end()); + std::sort(mSelection.begin(), mSelection.end()); } -void CSMWorld::CommandDispatcher::setExtendedTypes (const std::vector& types) +void CSMWorld::CommandDispatcher::setExtendedTypes(const std::vector& types) { mExtendedTypes = types; } @@ -111,7 +114,7 @@ bool CSMWorld::CommandDispatcher::canDelete() const if (mLocked) return false; - return getDeletableRecords().size()!=0; + return getDeletableRecords().size() != 0; } bool CSMWorld::CommandDispatcher::canRevert() const @@ -119,16 +122,16 @@ bool CSMWorld::CommandDispatcher::canRevert() const if (mLocked) return false; - return getRevertableRecords().size()!=0; + return getRevertableRecords().size() != 0; } std::vector CSMWorld::CommandDispatcher::getExtendedTypes() const { std::vector tables; - if (mId==UniversalId::Type_Cells) + if (mId == UniversalId::Type_Cells) { - tables.push_back (mId); + tables.push_back(mId); tables.emplace_back(UniversalId::Type_References); /// \todo add other cell-specific types } @@ -136,40 +139,41 @@ std::vector CSMWorld::CommandDispatcher::getExtendedTypes return tables; } -void CSMWorld::CommandDispatcher::executeModify (QAbstractItemModel *model, const QModelIndex& index, const QVariant& new_) +void CSMWorld::CommandDispatcher::executeModify( + QAbstractItemModel* model, const QModelIndex& index, const QVariant& new_) { if (mLocked) return; std::unique_ptr modifyCell; + int columnId = model->data(index, ColumnBase::Role_ColumnId).toInt(); - int columnId = model->data (index, ColumnBase::Role_ColumnId).toInt(); - - if (columnId==Columns::ColumnId_PositionXPos || columnId==Columns::ColumnId_PositionYPos) + if (columnId == Columns::ColumnId_PositionXPos || columnId == Columns::ColumnId_PositionYPos) { - const float oldPosition = model->data (index).toFloat(); + const float oldPosition = model->data(index).toFloat(); // Modulate by cell size, update cell id if reference has been moved to a new cell if (std::abs(std::fmod(oldPosition, Constants::CellSizeInUnits)) - - std::abs(std::fmod(new_.toFloat(), Constants::CellSizeInUnits)) >= 0.5f) + - std::abs(std::fmod(new_.toFloat(), Constants::CellSizeInUnits)) + >= 0.5f) { - IdTableProxyModel *proxy = dynamic_cast (model); + IdTableProxyModel* proxy = dynamic_cast(model); - int row = proxy ? proxy->mapToSource (index).row() : index.row(); + int row = proxy ? proxy->mapToSource(index).row() : index.row(); // This is not guaranteed to be the same as \a model, since a proxy could be used. - IdTable& model2 = dynamic_cast (*mDocument.getData().getTableModel (mId)); + IdTable& model2 = dynamic_cast(*mDocument.getData().getTableModel(mId)); - int cellColumn = model2.searchColumnIndex (Columns::ColumnId_Cell); + int cellColumn = model2.searchColumnIndex(Columns::ColumnId_Cell); - if (cellColumn!=-1) + if (cellColumn != -1) { - QModelIndex cellIndex = model2.index (row, cellColumn); + QModelIndex cellIndex = model2.index(row, cellColumn); - std::string cellId = model2.data (cellIndex).toString().toUtf8().data(); + std::string cellId = model2.data(cellIndex).toString().toUtf8().data(); - if (cellId.find ('#')!=std::string::npos) + if (cellId.find('#') != std::string::npos) { // Need to recalculate the cell modifyCell = std::make_unique(model2, row); @@ -182,12 +186,12 @@ void CSMWorld::CommandDispatcher::executeModify (QAbstractItemModel *model, cons if (modifyCell.get()) { - CommandMacro macro (mDocument.getUndoStack()); - macro.push (modifyData.release()); - macro.push (modifyCell.release()); + CommandMacro macro(mDocument.getUndoStack()); + macro.push(modifyData.release()); + macro.push(modifyCell.release()); } else - mDocument.getUndoStack().push (modifyData.release()); + mDocument.getUndoStack().push(modifyData.release()); } void CSMWorld::CommandDispatcher::executeDelete() @@ -200,25 +204,26 @@ void CSMWorld::CommandDispatcher::executeDelete() if (rows.empty()) return; - IdTable& model = dynamic_cast (*mDocument.getData().getTableModel (mId)); + IdTable& model = dynamic_cast(*mDocument.getData().getTableModel(mId)); - int columnIndex = model.findColumnIndex (Columns::ColumnId_Id); + int columnIndex = model.findColumnIndex(Columns::ColumnId_Id); - CommandMacro macro (mDocument.getUndoStack(), rows.size()>1 ? "Delete multiple records" : ""); - for (std::vector::const_iterator iter (rows.begin()); iter!=rows.end(); ++iter) + CommandMacro macro(mDocument.getUndoStack(), rows.size() > 1 ? "Delete multiple records" : ""); + for (std::vector::const_iterator iter(rows.begin()); iter != rows.end(); ++iter) { - std::string id = model.data (model.getModelIndex (*iter, columnIndex)). - toString().toUtf8().constData(); + std::string id = model.data(model.getModelIndex(*iter, columnIndex)).toString().toUtf8().constData(); if (mId.getType() == UniversalId::Type_Referenceables) { - macro.push (new CSMWorld::DeleteCommand (model, id, - static_cast(model.data (model.index ( - model.getModelIndex (id, columnIndex).row(), - model.findColumnIndex (CSMWorld::Columns::ColumnId_RecordType))).toInt()))); + macro.push(new CSMWorld::DeleteCommand(model, id, + static_cast( + model + .data(model.index(model.getModelIndex(id, columnIndex).row(), + model.findColumnIndex(CSMWorld::Columns::ColumnId_RecordType))) + .toInt()))); } else - mDocument.getUndoStack().push (new CSMWorld::DeleteCommand (model, id)); + mDocument.getUndoStack().push(new CSMWorld::DeleteCommand(model, id)); } } @@ -232,50 +237,48 @@ void CSMWorld::CommandDispatcher::executeRevert() if (rows.empty()) return; - IdTable& model = dynamic_cast (*mDocument.getData().getTableModel (mId)); + IdTable& model = dynamic_cast(*mDocument.getData().getTableModel(mId)); - int columnIndex = model.findColumnIndex (Columns::ColumnId_Id); + int columnIndex = model.findColumnIndex(Columns::ColumnId_Id); - CommandMacro macro (mDocument.getUndoStack(), rows.size()>1 ? "Revert multiple records" : ""); - for (std::vector::const_iterator iter (rows.begin()); iter!=rows.end(); ++iter) + CommandMacro macro(mDocument.getUndoStack(), rows.size() > 1 ? "Revert multiple records" : ""); + for (std::vector::const_iterator iter(rows.begin()); iter != rows.end(); ++iter) { - std::string id = model.data (model.getModelIndex (*iter, columnIndex)). - toString().toUtf8().constData(); + std::string id = model.data(model.getModelIndex(*iter, columnIndex)).toString().toUtf8().constData(); - macro.push (new CSMWorld::RevertCommand (model, id)); + macro.push(new CSMWorld::RevertCommand(model, id)); } } void CSMWorld::CommandDispatcher::executeExtendedDelete() { - CommandMacro macro (mDocument.getUndoStack(), mExtendedTypes.size()>1 ? tr ("Extended delete of multiple records") : ""); + CommandMacro macro( + mDocument.getUndoStack(), mExtendedTypes.size() > 1 ? tr("Extended delete of multiple records") : ""); - for (std::vector::const_iterator iter (mExtendedTypes.begin()); - iter!=mExtendedTypes.end(); ++iter) + for (std::vector::const_iterator iter(mExtendedTypes.begin()); iter != mExtendedTypes.end(); ++iter) { - if (*iter==mId) + if (*iter == mId) executeDelete(); - else if (*iter==UniversalId::Type_References) + else if (*iter == UniversalId::Type_References) { - IdTable& model = dynamic_cast ( - *mDocument.getData().getTableModel (*iter)); + IdTable& model = dynamic_cast(*mDocument.getData().getTableModel(*iter)); const RefCollection& collection = mDocument.getData().getReferences(); int size = collection.getSize(); - for (int i=size-1; i>=0; --i) + for (int i = size - 1; i >= 0; --i) { - const Record& record = collection.getRecord (i); + const Record& record = collection.getRecord(i); - if (record.mState==RecordBase::State_Deleted) + if (record.mState == RecordBase::State_Deleted) continue; - if (!std::binary_search (mSelection.begin(), mSelection.end(), - Misc::StringUtils::lowerCase (record.get().mCell))) + if (!std::binary_search( + mSelection.begin(), mSelection.end(), Misc::StringUtils::lowerCase(record.get().mCell))) continue; - macro.push (new CSMWorld::DeleteCommand (model, record.get().mId)); + macro.push(new CSMWorld::DeleteCommand(model, record.get().mId)); } } } @@ -283,31 +286,30 @@ void CSMWorld::CommandDispatcher::executeExtendedDelete() void CSMWorld::CommandDispatcher::executeExtendedRevert() { - CommandMacro macro (mDocument.getUndoStack(), mExtendedTypes.size()>1 ? tr ("Extended revert of multiple records") : ""); + CommandMacro macro( + mDocument.getUndoStack(), mExtendedTypes.size() > 1 ? tr("Extended revert of multiple records") : ""); - for (std::vector::const_iterator iter (mExtendedTypes.begin()); - iter!=mExtendedTypes.end(); ++iter) + for (std::vector::const_iterator iter(mExtendedTypes.begin()); iter != mExtendedTypes.end(); ++iter) { - if (*iter==mId) + if (*iter == mId) executeRevert(); - else if (*iter==UniversalId::Type_References) + else if (*iter == UniversalId::Type_References) { - IdTable& model = dynamic_cast ( - *mDocument.getData().getTableModel (*iter)); + IdTable& model = dynamic_cast(*mDocument.getData().getTableModel(*iter)); const RefCollection& collection = mDocument.getData().getReferences(); int size = collection.getSize(); - for (int i=size-1; i>=0; --i) + for (int i = size - 1; i >= 0; --i) { - const Record& record = collection.getRecord (i); + const Record& record = collection.getRecord(i); - if (!std::binary_search (mSelection.begin(), mSelection.end(), - Misc::StringUtils::lowerCase (record.get().mCell))) + if (!std::binary_search( + mSelection.begin(), mSelection.end(), Misc::StringUtils::lowerCase(record.get().mCell))) continue; - macro.push (new CSMWorld::RevertCommand (model, record.get().mId)); + macro.push(new CSMWorld::RevertCommand(model, record.get().mId)); } } } diff --git a/apps/opencs/model/world/commanddispatcher.hpp b/apps/opencs/model/world/commanddispatcher.hpp index 538fd7f188..7d931acbca 100644 --- a/apps/opencs/model/world/commanddispatcher.hpp +++ b/apps/opencs/model/world/commanddispatcher.hpp @@ -19,59 +19,56 @@ namespace CSMWorld { class CommandDispatcher : public QObject { - Q_OBJECT + Q_OBJECT - bool mLocked; - CSMDoc::Document& mDocument; - UniversalId mId; - std::vector mSelection; - std::vector mExtendedTypes; + bool mLocked; + CSMDoc::Document& mDocument; + UniversalId mId; + std::vector mSelection; + std::vector mExtendedTypes; - std::vector getDeletableRecords() const; + std::vector getDeletableRecords() const; - std::vector getRevertableRecords() const; + std::vector getRevertableRecords() const; - public: + public: + CommandDispatcher(CSMDoc::Document& document, const CSMWorld::UniversalId& id, QObject* parent = nullptr); + ///< \param id ID of the table the commands should operate on primarily. - CommandDispatcher (CSMDoc::Document& document, const CSMWorld::UniversalId& id, - QObject *parent = nullptr); - ///< \param id ID of the table the commands should operate on primarily. + void setEditLock(bool locked); - void setEditLock (bool locked); + void setSelection(const std::vector& selection); - void setSelection (const std::vector& selection); + void setExtendedTypes(const std::vector& types); + ///< Set record lists selected by the user for extended operations. - void setExtendedTypes (const std::vector& types); - ///< Set record lists selected by the user for extended operations. + bool canDelete() const; - bool canDelete() const; + bool canRevert() const; - bool canRevert() const; + /// Return IDs of the record collection that can also be affected when + /// operating on the record collection this dispatcher is used for. + /// + /// \note The returned collection contains the ID of the record collection this + /// dispatcher is used for. However if that record collection does not support + /// the extended mode, the returned vector will be empty instead. + std::vector getExtendedTypes() const; - /// Return IDs of the record collection that can also be affected when - /// operating on the record collection this dispatcher is used for. - /// - /// \note The returned collection contains the ID of the record collection this - /// dispatcher is used for. However if that record collection does not support - /// the extended mode, the returned vector will be empty instead. - std::vector getExtendedTypes() const; + /// Add a modify command to the undo stack. + /// + /// \attention model must either be a model for the table operated on by this + /// dispatcher or a proxy of it. + void executeModify(QAbstractItemModel* model, const QModelIndex& index, const QVariant& new_); - /// Add a modify command to the undo stack. - /// - /// \attention model must either be a model for the table operated on by this - /// dispatcher or a proxy of it. - void executeModify (QAbstractItemModel *model, const QModelIndex& index, const QVariant& new_); + public slots: - public slots: + void executeDelete(); - void executeDelete(); + void executeRevert(); - void executeRevert(); - - void executeExtendedDelete(); - - void executeExtendedRevert(); + void executeExtendedDelete(); + void executeExtendedRevert(); }; } diff --git a/apps/opencs/model/world/commandmacro.cpp b/apps/opencs/model/world/commandmacro.cpp index 0bd74cbe21..2c3b7e1726 100644 --- a/apps/opencs/model/world/commandmacro.cpp +++ b/apps/opencs/model/world/commandmacro.cpp @@ -1,12 +1,15 @@ #include "commandmacro.hpp" -#include #include +#include -CSMWorld::CommandMacro::CommandMacro (QUndoStack& undoStack, const QString& description) -: mUndoStack (undoStack), mDescription (description), mStarted (false) -{} +CSMWorld::CommandMacro::CommandMacro(QUndoStack& undoStack, const QString& description) + : mUndoStack(undoStack) + , mDescription(description) + , mStarted(false) +{ +} CSMWorld::CommandMacro::~CommandMacro() { @@ -14,13 +17,13 @@ CSMWorld::CommandMacro::~CommandMacro() mUndoStack.endMacro(); } -void CSMWorld::CommandMacro::push (QUndoCommand *command) +void CSMWorld::CommandMacro::push(QUndoCommand* command) { if (!mStarted) { - mUndoStack.beginMacro (mDescription.isEmpty() ? command->text() : mDescription); + mUndoStack.beginMacro(mDescription.isEmpty() ? command->text() : mDescription); mStarted = true; } - mUndoStack.push (command); + mUndoStack.push(command); } diff --git a/apps/opencs/model/world/commandmacro.hpp b/apps/opencs/model/world/commandmacro.hpp index b1f6301d9a..bc21e935c0 100644 --- a/apps/opencs/model/world/commandmacro.hpp +++ b/apps/opencs/model/world/commandmacro.hpp @@ -10,24 +10,23 @@ namespace CSMWorld { class CommandMacro { - QUndoStack& mUndoStack; - QString mDescription; - bool mStarted; + QUndoStack& mUndoStack; + QString mDescription; + bool mStarted; - /// not implemented - CommandMacro (const CommandMacro&); + /// not implemented + CommandMacro(const CommandMacro&); - /// not implemented - CommandMacro& operator= (const CommandMacro&); + /// not implemented + CommandMacro& operator=(const CommandMacro&); - public: + public: + /// If \a description is empty, the description of the first command is used. + CommandMacro(QUndoStack& undoStack, const QString& description = ""); - /// If \a description is empty, the description of the first command is used. - CommandMacro (QUndoStack& undoStack, const QString& description = ""); + ~CommandMacro(); - ~CommandMacro(); - - void push (QUndoCommand *command); + void push(QUndoCommand* command); }; } diff --git a/apps/opencs/model/world/commands.cpp b/apps/opencs/model/world/commands.cpp index cbb637e8cb..52e746cd23 100644 --- a/apps/opencs/model/world/commands.cpp +++ b/apps/opencs/model/world/commands.cpp @@ -39,8 +39,8 @@ void CSMWorld::TouchCommand::undo() } } -CSMWorld::ImportLandTexturesCommand::ImportLandTexturesCommand(IdTable& landTable, - IdTable& ltexTable, QUndoCommand* parent) +CSMWorld::ImportLandTexturesCommand::ImportLandTexturesCommand( + IdTable& landTable, IdTable& ltexTable, QUndoCommand* parent) : QUndoCommand(parent) , mLands(landTable) , mLtexs(ltexTable) @@ -131,8 +131,8 @@ void CSMWorld::ImportLandTexturesCommand::undo() mCreatedTextures.clear(); } -CSMWorld::CopyLandTexturesCommand::CopyLandTexturesCommand(IdTable& landTable, IdTable& ltexTable, - const std::string& origin, const std::string& dest, QUndoCommand* parent) +CSMWorld::CopyLandTexturesCommand::CopyLandTexturesCommand( + IdTable& landTable, IdTable& ltexTable, const std::string& origin, const std::string& dest, QUndoCommand* parent) : ImportLandTexturesCommand(landTable, ltexTable, parent) , mOriginId(origin) , mDestId(dest) @@ -149,8 +149,8 @@ const std::string& CSMWorld::CopyLandTexturesCommand::getDestinationId() const return mDestId; } -CSMWorld::TouchLandCommand::TouchLandCommand(IdTable& landTable, IdTable& ltexTable, - const std::string& id, QUndoCommand* parent) +CSMWorld::TouchLandCommand::TouchLandCommand( + IdTable& landTable, IdTable& ltexTable, const std::string& id, QUndoCommand* parent) : ImportLandTexturesCommand(landTable, ltexTable, parent) , mId(id) , mOld(nullptr) @@ -172,7 +172,8 @@ const std::string& CSMWorld::TouchLandCommand::getDestinationId() const void CSMWorld::TouchLandCommand::onRedo() { mChanged = mLands.touchRecord(mId); - if (mChanged) mOld.reset(mLands.getRecord(mId).clone().get()); + if (mChanged) + mOld.reset(mLands.getRecord(mId).clone().get()); } void CSMWorld::TouchLandCommand::onUndo() @@ -184,14 +185,19 @@ void CSMWorld::TouchLandCommand::onUndo() } } -CSMWorld::ModifyCommand::ModifyCommand (QAbstractItemModel& model, const QModelIndex& index, - const QVariant& new_, QUndoCommand* parent) - : QUndoCommand (parent), mModel (&model), mIndex (index), mNew (new_), mHasRecordState(false), mOldRecordState(CSMWorld::RecordBase::State_BaseOnly) +CSMWorld::ModifyCommand::ModifyCommand( + QAbstractItemModel& model, const QModelIndex& index, const QVariant& new_, QUndoCommand* parent) + : QUndoCommand(parent) + , mModel(&model) + , mIndex(index) + , mNew(new_) + , mHasRecordState(false) + , mOldRecordState(CSMWorld::RecordBase::State_BaseOnly) { - if (QAbstractProxyModel *proxy = dynamic_cast (mModel)) + if (QAbstractProxyModel* proxy = dynamic_cast(mModel)) { // Replace proxy with actual model - mIndex = proxy->mapToSource (mIndex); + mIndex = proxy->mapToSource(mIndex); mModel = proxy->sourceModel(); } } @@ -201,16 +207,17 @@ void CSMWorld::ModifyCommand::redo() if (mIndex.parent().isValid()) { CSMWorld::IdTree* tree = &dynamic_cast(*mModel); - setText ("Modify " + tree->nestedHeaderData ( - mIndex.parent().column(), mIndex.column(), Qt::Horizontal, Qt::DisplayRole).toString()); + setText("Modify " + + tree->nestedHeaderData(mIndex.parent().column(), mIndex.column(), Qt::Horizontal, Qt::DisplayRole) + .toString()); } else { - setText ("Modify " + mModel->headerData (mIndex.column(), Qt::Horizontal, Qt::DisplayRole).toString()); + setText("Modify " + mModel->headerData(mIndex.column(), Qt::Horizontal, Qt::DisplayRole).toString()); } // Remember record state before the modification - if (CSMWorld::IdTable *table = dynamic_cast(mModel)) + if (CSMWorld::IdTable* table = dynamic_cast(mModel)) { mHasRecordState = true; int stateColumnIndex = table->findColumnIndex(Columns::ColumnId_Modification); @@ -225,184 +232,186 @@ void CSMWorld::ModifyCommand::redo() mOldRecordState = static_cast(table->data(mRecordStateIndex).toInt()); } - mOld = mModel->data (mIndex, Qt::EditRole); - mModel->setData (mIndex, mNew); + mOld = mModel->data(mIndex, Qt::EditRole); + mModel->setData(mIndex, mNew); } void CSMWorld::ModifyCommand::undo() { - mModel->setData (mIndex, mOld); + mModel->setData(mIndex, mOld); if (mHasRecordState) { mModel->setData(mRecordStateIndex, mOldRecordState); } } - void CSMWorld::CreateCommand::applyModifications() { if (!mNestedValues.empty()) { CSMWorld::IdTree* tree = &dynamic_cast(mModel); - std::map >::const_iterator current = mNestedValues.begin(); - std::map >::const_iterator end = mNestedValues.end(); + std::map>::const_iterator current = mNestedValues.begin(); + std::map>::const_iterator end = mNestedValues.end(); for (; current != end; ++current) { - QModelIndex index = tree->index(0, - current->second.first, - tree->getNestedModelIndex(mId, current->first)); + QModelIndex index = tree->index(0, current->second.first, tree->getNestedModelIndex(mId, current->first)); tree->setData(index, current->second.second); } } } -CSMWorld::CreateCommand::CreateCommand (IdTable& model, const std::string& id, QUndoCommand* parent) -: QUndoCommand (parent), mModel (model), mId (id), mType (UniversalId::Type_None) +CSMWorld::CreateCommand::CreateCommand(IdTable& model, const std::string& id, QUndoCommand* parent) + : QUndoCommand(parent) + , mModel(model) + , mId(id) + , mType(UniversalId::Type_None) { - setText (("Create record " + id).c_str()); + setText(("Create record " + id).c_str()); } -void CSMWorld::CreateCommand::addValue (int column, const QVariant& value) +void CSMWorld::CreateCommand::addValue(int column, const QVariant& value) { mValues[column] = value; } -void CSMWorld::CreateCommand::addNestedValue(int parentColumn, int nestedColumn, const QVariant &value) +void CSMWorld::CreateCommand::addNestedValue(int parentColumn, int nestedColumn, const QVariant& value) { mNestedValues[parentColumn] = std::make_pair(nestedColumn, value); } -void CSMWorld::CreateCommand::setType (UniversalId::Type type) +void CSMWorld::CreateCommand::setType(UniversalId::Type type) { mType = type; } void CSMWorld::CreateCommand::redo() { - mModel.addRecordWithData (mId, mValues, mType); + mModel.addRecordWithData(mId, mValues, mType); applyModifications(); } void CSMWorld::CreateCommand::undo() { - mModel.removeRow (mModel.getModelIndex (mId, 0).row()); + mModel.removeRow(mModel.getModelIndex(mId, 0).row()); } -CSMWorld::RevertCommand::RevertCommand (IdTable& model, const std::string& id, QUndoCommand* parent) -: QUndoCommand (parent), mModel (model), mId (id), mOld(nullptr) +CSMWorld::RevertCommand::RevertCommand(IdTable& model, const std::string& id, QUndoCommand* parent) + : QUndoCommand(parent) + , mModel(model) + , mId(id) + , mOld(nullptr) { - setText (("Revert record " + id).c_str()); + setText(("Revert record " + id).c_str()); } -CSMWorld::RevertCommand::~RevertCommand() -{ -} +CSMWorld::RevertCommand::~RevertCommand() {} void CSMWorld::RevertCommand::redo() { - mOld = mModel.getRecord (mId).clone(); + mOld = mModel.getRecord(mId).clone(); - int column = mModel.findColumnIndex (Columns::ColumnId_Modification); + int column = mModel.findColumnIndex(Columns::ColumnId_Modification); - QModelIndex index = mModel.getModelIndex (mId, column); - RecordBase::State state = static_cast (mModel.data (index).toInt()); + QModelIndex index = mModel.getModelIndex(mId, column); + RecordBase::State state = static_cast(mModel.data(index).toInt()); - if (state==RecordBase::State_ModifiedOnly) + if (state == RecordBase::State_ModifiedOnly) { - mModel.removeRows (index.row(), 1); + mModel.removeRows(index.row(), 1); } else { - mModel.setData (index, static_cast (RecordBase::State_BaseOnly)); + mModel.setData(index, static_cast(RecordBase::State_BaseOnly)); } } void CSMWorld::RevertCommand::undo() { - mModel.setRecord (mId, std::move(mOld)); + mModel.setRecord(mId, std::move(mOld)); } -CSMWorld::DeleteCommand::DeleteCommand (IdTable& model, - const std::string& id, CSMWorld::UniversalId::Type type, QUndoCommand* parent) -: QUndoCommand (parent), mModel (model), mId (id), mOld(nullptr), mType(type) +CSMWorld::DeleteCommand::DeleteCommand( + IdTable& model, const std::string& id, CSMWorld::UniversalId::Type type, QUndoCommand* parent) + : QUndoCommand(parent) + , mModel(model) + , mId(id) + , mOld(nullptr) + , mType(type) { - setText (("Delete record " + id).c_str()); + setText(("Delete record " + id).c_str()); } -CSMWorld::DeleteCommand::~DeleteCommand() -{ -} +CSMWorld::DeleteCommand::~DeleteCommand() {} void CSMWorld::DeleteCommand::redo() { - mOld = mModel.getRecord (mId).clone(); + mOld = mModel.getRecord(mId).clone(); - int column = mModel.findColumnIndex (Columns::ColumnId_Modification); + int column = mModel.findColumnIndex(Columns::ColumnId_Modification); - QModelIndex index = mModel.getModelIndex (mId, column); - RecordBase::State state = static_cast (mModel.data (index).toInt()); + QModelIndex index = mModel.getModelIndex(mId, column); + RecordBase::State state = static_cast(mModel.data(index).toInt()); - if (state==RecordBase::State_ModifiedOnly) + if (state == RecordBase::State_ModifiedOnly) { - mModel.removeRows (index.row(), 1); + mModel.removeRows(index.row(), 1); } else { - mModel.setData (index, static_cast (RecordBase::State_Deleted)); + mModel.setData(index, static_cast(RecordBase::State_Deleted)); } } void CSMWorld::DeleteCommand::undo() { - mModel.setRecord (mId, std::move(mOld), mType); + mModel.setRecord(mId, std::move(mOld), mType); } - -CSMWorld::ReorderRowsCommand::ReorderRowsCommand (IdTable& model, int baseIndex, - const std::vector& newOrder) -: mModel (model), mBaseIndex (baseIndex), mNewOrder (newOrder) -{} +CSMWorld::ReorderRowsCommand::ReorderRowsCommand(IdTable& model, int baseIndex, const std::vector& newOrder) + : mModel(model) + , mBaseIndex(baseIndex) + , mNewOrder(newOrder) +{ +} void CSMWorld::ReorderRowsCommand::redo() { - mModel.reorderRows (mBaseIndex, mNewOrder); + mModel.reorderRows(mBaseIndex, mNewOrder); } void CSMWorld::ReorderRowsCommand::undo() { - int size = static_cast (mNewOrder.size()); - std::vector reverse (size); + int size = static_cast(mNewOrder.size()); + std::vector reverse(size); - for (int i=0; i< size; ++i) - reverse.at (mNewOrder[i]) = i; + for (int i = 0; i < size; ++i) + reverse.at(mNewOrder[i]) = i; - mModel.reorderRows (mBaseIndex, reverse); + mModel.reorderRows(mBaseIndex, reverse); } -CSMWorld::CloneCommand::CloneCommand (CSMWorld::IdTable& model, - const std::string& idOrigin, - const std::string& idDestination, - const CSMWorld::UniversalId::Type type, - QUndoCommand* parent) -: CreateCommand (model, idDestination, parent), mIdOrigin (idOrigin) +CSMWorld::CloneCommand::CloneCommand(CSMWorld::IdTable& model, const std::string& idOrigin, + const std::string& idDestination, const CSMWorld::UniversalId::Type type, QUndoCommand* parent) + : CreateCommand(model, idDestination, parent) + , mIdOrigin(idOrigin) { - setType (type); - setText ( ("Clone record " + idOrigin + " to the " + idDestination).c_str()); + setType(type); + setText(("Clone record " + idOrigin + " to the " + idDestination).c_str()); } void CSMWorld::CloneCommand::redo() { - mModel.cloneRecord (mIdOrigin, mId, mType); + mModel.cloneRecord(mIdOrigin, mId, mType); applyModifications(); for (auto& value : mOverrideValues) { - mModel.setData(mModel.getModelIndex (mId, value.first), value.second); + mModel.setData(mModel.getModelIndex(mId, value.first), value.second); } } void CSMWorld::CloneCommand::undo() { - mModel.removeRow (mModel.getModelIndex (mId, 0).row()); + mModel.removeRow(mModel.getModelIndex(mId, 0).row()); } void CSMWorld::CloneCommand::setOverrideValue(int column, QVariant value) @@ -410,7 +419,7 @@ void CSMWorld::CloneCommand::setOverrideValue(int column, QVariant value) mOverrideValues.emplace_back(std::make_pair(column, value)); } -CSMWorld::CreatePathgridCommand::CreatePathgridCommand(IdTable& model, const std::string& id, QUndoCommand *parent) +CSMWorld::CreatePathgridCommand::CreatePathgridCommand(IdTable& model, const std::string& id, QUndoCommand* parent) : CreateCommand(model, id, parent) { setType(UniversalId::Type_Pathgrid); @@ -420,8 +429,8 @@ void CSMWorld::CreatePathgridCommand::redo() { CreateCommand::redo(); - std::unique_ptr > record - = std::make_unique >(static_cast& >(mModel.getRecord(mId))); + std::unique_ptr> record + = std::make_unique>(static_cast&>(mModel.getRecord(mId))); record->get().blank(); record->get().mCell = mId; @@ -435,59 +444,54 @@ void CSMWorld::CreatePathgridCommand::redo() mModel.setRecord(mId, std::move(record), mType); } -CSMWorld::UpdateCellCommand::UpdateCellCommand (IdTable& model, int row, QUndoCommand *parent) -: QUndoCommand (parent), mModel (model), mRow (row) +CSMWorld::UpdateCellCommand::UpdateCellCommand(IdTable& model, int row, QUndoCommand* parent) + : QUndoCommand(parent) + , mModel(model) + , mRow(row) { - setText ("Update cell ID"); + setText("Update cell ID"); } void CSMWorld::UpdateCellCommand::redo() { if (!mNew.isValid()) { - int cellColumn = mModel.searchColumnIndex (Columns::ColumnId_Cell); - mIndex = mModel.index (mRow, cellColumn); + int cellColumn = mModel.searchColumnIndex(Columns::ColumnId_Cell); + mIndex = mModel.index(mRow, cellColumn); - QModelIndex xIndex = mModel.index ( - mRow, mModel.findColumnIndex (Columns::ColumnId_PositionXPos)); + QModelIndex xIndex = mModel.index(mRow, mModel.findColumnIndex(Columns::ColumnId_PositionXPos)); - QModelIndex yIndex = mModel.index ( - mRow, mModel.findColumnIndex (Columns::ColumnId_PositionYPos)); + QModelIndex yIndex = mModel.index(mRow, mModel.findColumnIndex(Columns::ColumnId_PositionYPos)); - int x = std::floor (mModel.data (xIndex).toFloat() / Constants::CellSizeInUnits); - int y = std::floor (mModel.data (yIndex).toFloat() / Constants::CellSizeInUnits); + int x = std::floor(mModel.data(xIndex).toFloat() / Constants::CellSizeInUnits); + int y = std::floor(mModel.data(yIndex).toFloat() / Constants::CellSizeInUnits); std::ostringstream stream; stream << "#" << x << " " << y; - mNew = QString::fromUtf8 (stream.str().c_str()); + mNew = QString::fromUtf8(stream.str().c_str()); } - mModel.setData (mIndex, mNew); + mModel.setData(mIndex, mNew); } void CSMWorld::UpdateCellCommand::undo() { - mModel.setData (mIndex, mOld); + mModel.setData(mIndex, mOld); } - -CSMWorld::DeleteNestedCommand::DeleteNestedCommand (IdTree& model, - const std::string& id, - int nestedRow, - int parentColumn, - QUndoCommand* parent) : - QUndoCommand(parent), - NestedTableStoring(model, id, parentColumn), - mModel(model), - mId(id), - mParentColumn(parentColumn), - mNestedRow(nestedRow) +CSMWorld::DeleteNestedCommand::DeleteNestedCommand( + IdTree& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent) + : QUndoCommand(parent) + , NestedTableStoring(model, id, parentColumn) + , mModel(model) + , mId(id) + , mParentColumn(parentColumn) + , mNestedRow(nestedRow) { - std::string title = - model.headerData(parentColumn, Qt::Horizontal, Qt::DisplayRole).toString().toUtf8().constData(); - setText (("Delete row in " + title + " sub-table of " + mId).c_str()); + std::string title = model.headerData(parentColumn, Qt::Horizontal, Qt::DisplayRole).toString().toUtf8().constData(); + setText(("Delete row in " + title + " sub-table of " + mId).c_str()); QModelIndex parentIndex = mModel.getModelIndex(mId, mParentColumn); mModifyParentCommand = new ModifyCommand(mModel, parentIndex, parentIndex.data(Qt::EditRole), this); @@ -497,10 +501,9 @@ void CSMWorld::DeleteNestedCommand::redo() { QModelIndex parentIndex = mModel.getModelIndex(mId, mParentColumn); mModifyParentCommand->redo(); - mModel.removeRows (mNestedRow, 1, parentIndex); + mModel.removeRows(mNestedRow, 1, parentIndex); } - void CSMWorld::DeleteNestedCommand::undo() { QModelIndex parentIndex = mModel.getModelIndex(mId, mParentColumn); @@ -508,17 +511,17 @@ void CSMWorld::DeleteNestedCommand::undo() mModifyParentCommand->undo(); } -CSMWorld::AddNestedCommand::AddNestedCommand(IdTree& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent) - : QUndoCommand(parent), - NestedTableStoring(model, id, parentColumn), - mModel(model), - mId(id), - mNewRow(nestedRow), - mParentColumn(parentColumn) +CSMWorld::AddNestedCommand::AddNestedCommand( + IdTree& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent) + : QUndoCommand(parent) + , NestedTableStoring(model, id, parentColumn) + , mModel(model) + , mId(id) + , mNewRow(nestedRow) + , mParentColumn(parentColumn) { - std::string title = - model.headerData(parentColumn, Qt::Horizontal, Qt::DisplayRole).toString().toUtf8().constData(); - setText (("Add row in " + title + " sub-table of " + mId).c_str()); + std::string title = model.headerData(parentColumn, Qt::Horizontal, Qt::DisplayRole).toString().toUtf8().constData(); + setText(("Add row in " + title + " sub-table of " + mId).c_str()); QModelIndex parentIndex = mModel.getModelIndex(mId, mParentColumn); mModifyParentCommand = new ModifyCommand(mModel, parentIndex, parentIndex.data(Qt::EditRole), this); @@ -528,7 +531,7 @@ void CSMWorld::AddNestedCommand::redo() { QModelIndex parentIndex = mModel.getModelIndex(mId, mParentColumn); mModifyParentCommand->redo(); - mModel.addNestedRow (parentIndex, mNewRow); + mModel.addNestedRow(parentIndex, mNewRow); } void CSMWorld::AddNestedCommand::undo() @@ -539,7 +542,9 @@ void CSMWorld::AddNestedCommand::undo() } CSMWorld::NestedTableStoring::NestedTableStoring(const IdTree& model, const std::string& id, int parentColumn) - : mOld(model.nestedTable(model.getModelIndex(id, parentColumn))) {} + : mOld(model.nestedTable(model.getModelIndex(id, parentColumn))) +{ +} CSMWorld::NestedTableStoring::~NestedTableStoring() { diff --git a/apps/opencs/model/world/commands.hpp b/apps/opencs/model/world/commands.hpp index 4b619d11ed..2a22252514 100644 --- a/apps/opencs/model/world/commands.hpp +++ b/apps/opencs/model/world/commands.hpp @@ -3,18 +3,18 @@ #include "record.hpp" -#include #include #include +#include #include -#include -#include #include +#include +#include #include "columnimp.hpp" -#include "universalid.hpp" #include "nestedtablewrapper.hpp" +#include "universalid.hpp" class QAbstractItemModel; @@ -27,20 +27,18 @@ namespace CSMWorld class TouchCommand : public QUndoCommand { - public: - - TouchCommand(IdTable& model, const std::string& id, QUndoCommand* parent=nullptr); - - void redo() override; - void undo() override; + public: + TouchCommand(IdTable& model, const std::string& id, QUndoCommand* parent = nullptr); - private: + void redo() override; + void undo() override; - IdTable& mTable; - std::string mId; - std::unique_ptr mOld; + private: + IdTable& mTable; + std::string mId; + std::unique_ptr mOld; - bool mChanged; + bool mChanged; }; /// \brief Adds LandTexture records and modifies texture indices as needed. @@ -54,29 +52,26 @@ namespace CSMWorld /// LandRecord and within the Land record. class ImportLandTexturesCommand : public QUndoCommand { - public: - - ImportLandTexturesCommand(IdTable& landTable, IdTable& ltexTable, - QUndoCommand* parent); - - void redo() override; - void undo() override; + public: + ImportLandTexturesCommand(IdTable& landTable, IdTable& ltexTable, QUndoCommand* parent); - protected: + void redo() override; + void undo() override; - using DataType = LandTexturesColumn::DataType; + protected: + using DataType = LandTexturesColumn::DataType; - virtual const std::string& getOriginId() const = 0; - virtual const std::string& getDestinationId() const = 0; + virtual const std::string& getOriginId() const = 0; + virtual const std::string& getDestinationId() const = 0; - virtual void onRedo() = 0; - virtual void onUndo() = 0; + virtual void onRedo() = 0; + virtual void onUndo() = 0; - IdTable& mLands; - IdTable& mLtexs; - DataType mOld; - int mOldState; - std::vector mCreatedTextures; + IdTable& mLands; + IdTable& mLtexs; + DataType mOld; + int mOldState; + std::vector mCreatedTextures; }; /// \brief This command is used to fix LandTexture records and texture @@ -84,21 +79,19 @@ namespace CSMWorld /// details. class CopyLandTexturesCommand : public ImportLandTexturesCommand { - public: - - CopyLandTexturesCommand(IdTable& landTable, IdTable& ltexTable, const std::string& origin, - const std::string& dest, QUndoCommand* parent = nullptr); - - private: + public: + CopyLandTexturesCommand(IdTable& landTable, IdTable& ltexTable, const std::string& origin, + const std::string& dest, QUndoCommand* parent = nullptr); - const std::string& getOriginId() const override; - const std::string& getDestinationId() const override; + private: + const std::string& getOriginId() const override; + const std::string& getDestinationId() const override; - void onRedo() override {} - void onUndo() override {} + void onRedo() override {} + void onUndo() override {} - std::string mOriginId; - std::string mDestId; + std::string mOriginId; + std::string mDestId; }; /// \brief This command brings a land record into the current plugin, adding @@ -106,164 +99,150 @@ namespace CSMWorld /// \note See ImportLandTextures for more details. class TouchLandCommand : public ImportLandTexturesCommand { - public: - - TouchLandCommand(IdTable& landTable, IdTable& ltexTable, - const std::string& id, QUndoCommand* parent = nullptr); - - private: + public: + TouchLandCommand(IdTable& landTable, IdTable& ltexTable, const std::string& id, QUndoCommand* parent = nullptr); - const std::string& getOriginId() const override; - const std::string& getDestinationId() const override; + private: + const std::string& getOriginId() const override; + const std::string& getDestinationId() const override; - void onRedo() override; - void onUndo() override; + void onRedo() override; + void onUndo() override; - std::string mId; - std::unique_ptr mOld; + std::string mId; + std::unique_ptr mOld; - bool mChanged; + bool mChanged; }; class ModifyCommand : public QUndoCommand { - QAbstractItemModel *mModel; - QModelIndex mIndex; - QVariant mNew; - QVariant mOld; + QAbstractItemModel* mModel; + QModelIndex mIndex; + QVariant mNew; + QVariant mOld; - bool mHasRecordState; - QModelIndex mRecordStateIndex; - CSMWorld::RecordBase::State mOldRecordState; + bool mHasRecordState; + QModelIndex mRecordStateIndex; + CSMWorld::RecordBase::State mOldRecordState; - public: - - ModifyCommand (QAbstractItemModel& model, const QModelIndex& index, const QVariant& new_, - QUndoCommand *parent = nullptr); + public: + ModifyCommand( + QAbstractItemModel& model, const QModelIndex& index, const QVariant& new_, QUndoCommand* parent = nullptr); - void redo() override; + void redo() override; - void undo() override; + void undo() override; }; class CreateCommand : public QUndoCommand { - std::map mValues; - std::map > mNestedValues; - ///< Parameter order: a parent column, a nested column, a data. - ///< A nested row has index of 0. - - protected: + std::map mValues; + std::map> mNestedValues; + ///< Parameter order: a parent column, a nested column, a data. + ///< A nested row has index of 0. - IdTable& mModel; - std::string mId; - UniversalId::Type mType; - - protected: - - /// Apply modifications set via addValue. - void applyModifications(); + protected: + IdTable& mModel; + std::string mId; + UniversalId::Type mType; - public: + protected: + /// Apply modifications set via addValue. + void applyModifications(); - CreateCommand (IdTable& model, const std::string& id, QUndoCommand *parent = nullptr); + public: + CreateCommand(IdTable& model, const std::string& id, QUndoCommand* parent = nullptr); - void setType (UniversalId::Type type); + void setType(UniversalId::Type type); - void addValue (int column, const QVariant& value); + void addValue(int column, const QVariant& value); - void addNestedValue(int parentColumn, int nestedColumn, const QVariant &value); + void addNestedValue(int parentColumn, int nestedColumn, const QVariant& value); - void redo() override; + void redo() override; - void undo() override; + void undo() override; }; class CloneCommand : public CreateCommand { - std::string mIdOrigin; - std::vector> mOverrideValues; - - public: + std::string mIdOrigin; + std::vector> mOverrideValues; - CloneCommand (IdTable& model, const std::string& idOrigin, - const std::string& IdDestination, - const UniversalId::Type type, - QUndoCommand* parent = nullptr); + public: + CloneCommand(IdTable& model, const std::string& idOrigin, const std::string& IdDestination, + const UniversalId::Type type, QUndoCommand* parent = nullptr); - void redo() override; + void redo() override; - void undo() override; + void undo() override; - void setOverrideValue(int column, QVariant value); + void setOverrideValue(int column, QVariant value); }; class RevertCommand : public QUndoCommand { - IdTable& mModel; - std::string mId; - std::unique_ptr mOld; - - // not implemented - RevertCommand (const RevertCommand&); - RevertCommand& operator= (const RevertCommand&); + IdTable& mModel; + std::string mId; + std::unique_ptr mOld; - public: + // not implemented + RevertCommand(const RevertCommand&); + RevertCommand& operator=(const RevertCommand&); - RevertCommand (IdTable& model, const std::string& id, QUndoCommand *parent = nullptr); + public: + RevertCommand(IdTable& model, const std::string& id, QUndoCommand* parent = nullptr); - virtual ~RevertCommand(); + virtual ~RevertCommand(); - void redo() override; + void redo() override; - void undo() override; + void undo() override; }; class DeleteCommand : public QUndoCommand { - IdTable& mModel; - std::string mId; - std::unique_ptr mOld; - UniversalId::Type mType; + IdTable& mModel; + std::string mId; + std::unique_ptr mOld; + UniversalId::Type mType; - // not implemented - DeleteCommand (const DeleteCommand&); - DeleteCommand& operator= (const DeleteCommand&); + // not implemented + DeleteCommand(const DeleteCommand&); + DeleteCommand& operator=(const DeleteCommand&); - public: - - DeleteCommand (IdTable& model, const std::string& id, - UniversalId::Type type = UniversalId::Type_None, QUndoCommand *parent = nullptr); + public: + DeleteCommand(IdTable& model, const std::string& id, UniversalId::Type type = UniversalId::Type_None, + QUndoCommand* parent = nullptr); - virtual ~DeleteCommand(); + virtual ~DeleteCommand(); - void redo() override; + void redo() override; - void undo() override; + void undo() override; }; class ReorderRowsCommand : public QUndoCommand { - IdTable& mModel; - int mBaseIndex; - std::vector mNewOrder; - - public: + IdTable& mModel; + int mBaseIndex; + std::vector mNewOrder; - ReorderRowsCommand (IdTable& model, int baseIndex, const std::vector& newOrder); + public: + ReorderRowsCommand(IdTable& model, int baseIndex, const std::vector& newOrder); - void redo() override; + void redo() override; - void undo() override; + void undo() override; }; class CreatePathgridCommand : public CreateCommand { - public: - - CreatePathgridCommand(IdTable& model, const std::string& id, QUndoCommand *parent = nullptr); + public: + CreatePathgridCommand(IdTable& model, const std::string& id, QUndoCommand* parent = nullptr); - void redo() override; + void redo() override; }; /// \brief Update cell ID according to x/y-coordinates @@ -273,22 +252,20 @@ namespace CSMWorld /// in a macro. class UpdateCellCommand : public QUndoCommand { - IdTable& mModel; - int mRow; - QModelIndex mIndex; - QVariant mNew; // invalid, if new cell ID has not been calculated yet - QVariant mOld; + IdTable& mModel; + int mRow; + QModelIndex mIndex; + QVariant mNew; // invalid, if new cell ID has not been calculated yet + QVariant mOld; - public: - - UpdateCellCommand (IdTable& model, int row, QUndoCommand *parent = nullptr); + public: + UpdateCellCommand(IdTable& model, int row, QUndoCommand* parent = nullptr); - void redo() override; + void redo() override; - void undo() override; + void undo() override; }; - class NestedTableStoring { NestedTableWrapperBase* mOld; @@ -299,52 +276,51 @@ namespace CSMWorld ~NestedTableStoring(); protected: - const NestedTableWrapperBase& getOld() const; }; class DeleteNestedCommand : public QUndoCommand, private NestedTableStoring { - IdTree& mModel; - - std::string mId; + IdTree& mModel; - int mParentColumn; + std::string mId; - int mNestedRow; + int mParentColumn; - // The command to redo/undo the Modified status of a record - ModifyCommand *mModifyParentCommand; + int mNestedRow; - public: + // The command to redo/undo the Modified status of a record + ModifyCommand* mModifyParentCommand; - DeleteNestedCommand (IdTree& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent = nullptr); + public: + DeleteNestedCommand( + IdTree& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent = nullptr); - void redo() override; + void redo() override; - void undo() override; + void undo() override; }; class AddNestedCommand : public QUndoCommand, private NestedTableStoring { - IdTree& mModel; + IdTree& mModel; - std::string mId; + std::string mId; - int mNewRow; + int mNewRow; - int mParentColumn; + int mParentColumn; - // The command to redo/undo the Modified status of a record - ModifyCommand *mModifyParentCommand; + // The command to redo/undo the Modified status of a record + ModifyCommand* mModifyParentCommand; - public: - - AddNestedCommand(IdTree& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent = nullptr); + public: + AddNestedCommand( + IdTree& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent = nullptr); - void redo() override; + void redo() override; - void undo() override; + void undo() override; }; } diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 3ac499b4f4..bc1d7abe8a 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -1,12 +1,12 @@ #include "data.hpp" -#include #include +#include #include -#include #include +#include #include #include @@ -17,57 +17,62 @@ #include "../doc/messages.hpp" +#include "columnimp.hpp" +#include "columns.hpp" #include "idtable.hpp" #include "idtree.hpp" -#include "columnimp.hpp" +#include "nestedcoladapterimp.hpp" #include "regionmap.hpp" -#include "columns.hpp" #include "resourcesmanager.hpp" #include "resourcetable.hpp" -#include "nestedcoladapterimp.hpp" -void CSMWorld::Data::addModel (QAbstractItemModel *model, UniversalId::Type type, bool update) +void CSMWorld::Data::addModel(QAbstractItemModel* model, UniversalId::Type type, bool update) { - mModels.push_back (model); - mModelIndex.insert (std::make_pair (type, model)); + mModels.push_back(model); + mModelIndex.insert(std::make_pair(type, model)); - UniversalId::Type type2 = UniversalId::getParentType (type); + UniversalId::Type type2 = UniversalId::getParentType(type); - if (type2!=UniversalId::Type_None) - mModelIndex.insert (std::make_pair (type2, model)); + if (type2 != UniversalId::Type_None) + mModelIndex.insert(std::make_pair(type2, model)); if (update) { - connect (model, &QAbstractItemModel::dataChanged, this, &Data::dataChanged); - connect (model, &QAbstractItemModel::rowsInserted, this, &Data::rowsChanged); - connect (model, &QAbstractItemModel::rowsRemoved, this, &Data::rowsChanged); + connect(model, &QAbstractItemModel::dataChanged, this, &Data::dataChanged); + connect(model, &QAbstractItemModel::rowsInserted, this, &Data::rowsChanged); + connect(model, &QAbstractItemModel::rowsRemoved, this, &Data::rowsChanged); } } -void CSMWorld::Data::appendIds (std::vector& ids, const CollectionBase& collection, - bool listDeleted) +void CSMWorld::Data::appendIds(std::vector& ids, const CollectionBase& collection, bool listDeleted) { - std::vector ids2 = collection.getIds (listDeleted); + std::vector ids2 = collection.getIds(listDeleted); - ids.insert (ids.end(), ids2.begin(), ids2.end()); + ids.insert(ids.end(), ids2.begin(), ids2.end()); } -int CSMWorld::Data::count (RecordBase::State state, const CollectionBase& collection) +int CSMWorld::Data::count(RecordBase::State state, const CollectionBase& collection) { int number = 0; - for (int i=0; i& archives, const std::filesystem::path& resDir) -: mEncoder (encoding), mPathgrids (mCells), mRefs (mCells), - mReader (nullptr), mDialogue (nullptr), mReaderIndex(1), - mFsStrict(fsStrict), mDataPaths(dataPaths), mArchives(archives) + : mEncoder(encoding) + , mPathgrids(mCells) + , mRefs(mCells) + , mReader(nullptr) + , mDialogue(nullptr) + , mReaderIndex(1) + , mFsStrict(fsStrict) + , mDataPaths(dataPaths) + , mArchives(archives) { mVFS = std::make_unique(mFsStrict); VFS::registerArchives(mVFS.get(), Files::Collections(mDataPaths, !mFsStrict), mArchives, true); @@ -75,7 +80,8 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, bool fsStrict, const Files::Pat mResourcesManager.setVFS(mVFS.get()); mResourceSystem = std::make_unique(mVFS.get()); - Shader::ShaderManager::DefineMap defines = mResourceSystem->getSceneManager()->getShaderManager().getGlobalDefines(); + Shader::ShaderManager::DefineMap defines + = mResourceSystem->getSceneManager()->getShaderManager().getGlobalDefines(); Shader::ShaderManager::DefineMap shadowDefines = SceneUtil::ShadowManager::getShadowsDisabledDefines(); defines["forcePPL"] = "0"; // Don't force per-pixel lighting defines["clamp"] = "1"; // Clamp lighting @@ -92,514 +98,501 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, bool fsStrict, const Files::Pat int index = 0; - mGlobals.addColumn (new StringIdColumn); - mGlobals.addColumn (new RecordStateColumn); - mGlobals.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Global)); - mGlobals.addColumn (new VarTypeColumn (ColumnBase::Display_GlobalVarType)); - mGlobals.addColumn (new VarValueColumn); - - mGmsts.addColumn (new StringIdColumn); - mGmsts.addColumn (new RecordStateColumn); - mGmsts.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Gmst)); - mGmsts.addColumn (new VarTypeColumn (ColumnBase::Display_GmstVarType)); - mGmsts.addColumn (new VarValueColumn); - - mSkills.addColumn (new StringIdColumn); - mSkills.addColumn (new RecordStateColumn); - mSkills.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Skill)); - mSkills.addColumn (new AttributeColumn); - mSkills.addColumn (new SpecialisationColumn); - for (int i=0; i<4; ++i) - mSkills.addColumn (new UseValueColumn (i)); - mSkills.addColumn (new DescriptionColumn); - - mClasses.addColumn (new StringIdColumn); - mClasses.addColumn (new RecordStateColumn); - mClasses.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Class)); - mClasses.addColumn (new NameColumn); - mClasses.addColumn (new AttributesColumn (0)); - mClasses.addColumn (new AttributesColumn (1)); - mClasses.addColumn (new SpecialisationColumn); - for (int i=0; i<5; ++i) - mClasses.addColumn (new SkillsColumn (i, true, true)); - for (int i=0; i<5; ++i) - mClasses.addColumn (new SkillsColumn (i, true, false)); - mClasses.addColumn (new PlayableColumn); - mClasses.addColumn (new DescriptionColumn); - - mFactions.addColumn (new StringIdColumn); - mFactions.addColumn (new RecordStateColumn); - mFactions.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Faction)); - mFactions.addColumn (new NameColumn(ColumnBase::Display_String32)); - mFactions.addColumn (new AttributesColumn (0)); - mFactions.addColumn (new AttributesColumn (1)); - mFactions.addColumn (new HiddenColumn); - for (int i=0; i<7; ++i) - mFactions.addColumn (new SkillsColumn (i)); + mGlobals.addColumn(new StringIdColumn); + mGlobals.addColumn(new RecordStateColumn); + mGlobals.addColumn(new FixedRecordTypeColumn(UniversalId::Type_Global)); + mGlobals.addColumn(new VarTypeColumn(ColumnBase::Display_GlobalVarType)); + mGlobals.addColumn(new VarValueColumn); + + mGmsts.addColumn(new StringIdColumn); + mGmsts.addColumn(new RecordStateColumn); + mGmsts.addColumn(new FixedRecordTypeColumn(UniversalId::Type_Gmst)); + mGmsts.addColumn(new VarTypeColumn(ColumnBase::Display_GmstVarType)); + mGmsts.addColumn(new VarValueColumn); + + mSkills.addColumn(new StringIdColumn); + mSkills.addColumn(new RecordStateColumn); + mSkills.addColumn(new FixedRecordTypeColumn(UniversalId::Type_Skill)); + mSkills.addColumn(new AttributeColumn); + mSkills.addColumn(new SpecialisationColumn); + for (int i = 0; i < 4; ++i) + mSkills.addColumn(new UseValueColumn(i)); + mSkills.addColumn(new DescriptionColumn); + + mClasses.addColumn(new StringIdColumn); + mClasses.addColumn(new RecordStateColumn); + mClasses.addColumn(new FixedRecordTypeColumn(UniversalId::Type_Class)); + mClasses.addColumn(new NameColumn); + mClasses.addColumn(new AttributesColumn(0)); + mClasses.addColumn(new AttributesColumn(1)); + mClasses.addColumn(new SpecialisationColumn); + for (int i = 0; i < 5; ++i) + mClasses.addColumn(new SkillsColumn(i, true, true)); + for (int i = 0; i < 5; ++i) + mClasses.addColumn(new SkillsColumn(i, true, false)); + mClasses.addColumn(new PlayableColumn); + mClasses.addColumn(new DescriptionColumn); + + mFactions.addColumn(new StringIdColumn); + mFactions.addColumn(new RecordStateColumn); + mFactions.addColumn(new FixedRecordTypeColumn(UniversalId::Type_Faction)); + mFactions.addColumn(new NameColumn(ColumnBase::Display_String32)); + mFactions.addColumn(new AttributesColumn(0)); + mFactions.addColumn(new AttributesColumn(1)); + mFactions.addColumn(new HiddenColumn); + for (int i = 0; i < 7; ++i) + mFactions.addColumn(new SkillsColumn(i)); // Faction Reactions - mFactions.addColumn (new NestedParentColumn (Columns::ColumnId_FactionReactions)); - index = mFactions.getColumns()-1; - mFactions.addAdapter (std::make_pair(&mFactions.getColumn(index), new FactionReactionsAdapter ())); + mFactions.addColumn(new NestedParentColumn(Columns::ColumnId_FactionReactions)); + index = mFactions.getColumns() - 1; + mFactions.addAdapter(std::make_pair(&mFactions.getColumn(index), new FactionReactionsAdapter())); mFactions.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_Faction, ColumnBase::Display_Faction)); + new NestedChildColumn(Columns::ColumnId_Faction, ColumnBase::Display_Faction)); mFactions.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_FactionReaction, ColumnBase::Display_Integer)); + new NestedChildColumn(Columns::ColumnId_FactionReaction, ColumnBase::Display_Integer)); // Faction Ranks - mFactions.addColumn (new NestedParentColumn (Columns::ColumnId_FactionRanks)); - index = mFactions.getColumns()-1; - mFactions.addAdapter (std::make_pair(&mFactions.getColumn(index), new FactionRanksAdapter ())); + mFactions.addColumn(new NestedParentColumn(Columns::ColumnId_FactionRanks)); + index = mFactions.getColumns() - 1; + mFactions.addAdapter(std::make_pair(&mFactions.getColumn(index), new FactionRanksAdapter())); mFactions.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_RankName, ColumnBase::Display_Rank)); + new NestedChildColumn(Columns::ColumnId_RankName, ColumnBase::Display_Rank)); mFactions.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_FactionAttrib1, ColumnBase::Display_Integer)); + new NestedChildColumn(Columns::ColumnId_FactionAttrib1, ColumnBase::Display_Integer)); mFactions.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_FactionAttrib2, ColumnBase::Display_Integer)); + new NestedChildColumn(Columns::ColumnId_FactionAttrib2, ColumnBase::Display_Integer)); mFactions.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_FactionPrimSkill, ColumnBase::Display_Integer)); + new NestedChildColumn(Columns::ColumnId_FactionPrimSkill, ColumnBase::Display_Integer)); mFactions.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_FactionFavSkill, ColumnBase::Display_Integer)); + new NestedChildColumn(Columns::ColumnId_FactionFavSkill, ColumnBase::Display_Integer)); mFactions.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_FactionRep, ColumnBase::Display_Integer)); - - mRaces.addColumn (new StringIdColumn); - mRaces.addColumn (new RecordStateColumn); - mRaces.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Race)); - mRaces.addColumn (new NameColumn); - mRaces.addColumn (new DescriptionColumn); - mRaces.addColumn (new FlagColumn (Columns::ColumnId_Playable, 0x1)); - mRaces.addColumn (new FlagColumn (Columns::ColumnId_BeastRace, 0x2)); - mRaces.addColumn (new WeightHeightColumn (true, true)); - mRaces.addColumn (new WeightHeightColumn (true, false)); - mRaces.addColumn (new WeightHeightColumn (false, true)); - mRaces.addColumn (new WeightHeightColumn (false, false)); + new NestedChildColumn(Columns::ColumnId_FactionRep, ColumnBase::Display_Integer)); + + mRaces.addColumn(new StringIdColumn); + mRaces.addColumn(new RecordStateColumn); + mRaces.addColumn(new FixedRecordTypeColumn(UniversalId::Type_Race)); + mRaces.addColumn(new NameColumn); + mRaces.addColumn(new DescriptionColumn); + mRaces.addColumn(new FlagColumn(Columns::ColumnId_Playable, 0x1)); + mRaces.addColumn(new FlagColumn(Columns::ColumnId_BeastRace, 0x2)); + mRaces.addColumn(new WeightHeightColumn(true, true)); + mRaces.addColumn(new WeightHeightColumn(true, false)); + mRaces.addColumn(new WeightHeightColumn(false, true)); + mRaces.addColumn(new WeightHeightColumn(false, false)); // Race spells - mRaces.addColumn (new NestedParentColumn (Columns::ColumnId_PowerList)); - index = mRaces.getColumns()-1; - mRaces.addAdapter (std::make_pair(&mRaces.getColumn(index), new SpellListAdapter ())); + mRaces.addColumn(new NestedParentColumn(Columns::ColumnId_PowerList)); + index = mRaces.getColumns() - 1; + mRaces.addAdapter(std::make_pair(&mRaces.getColumn(index), new SpellListAdapter())); mRaces.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_SpellId, ColumnBase::Display_Spell)); + new NestedChildColumn(Columns::ColumnId_SpellId, ColumnBase::Display_Spell)); // Race attributes - mRaces.addColumn (new NestedParentColumn (Columns::ColumnId_RaceAttributes, - ColumnBase::Flag_Dialogue, true)); // fixed rows table - index = mRaces.getColumns()-1; - mRaces.addAdapter (std::make_pair(&mRaces.getColumn(index), new RaceAttributeAdapter())); + mRaces.addColumn(new NestedParentColumn( + Columns::ColumnId_RaceAttributes, ColumnBase::Flag_Dialogue, true)); // fixed rows table + index = mRaces.getColumns() - 1; + mRaces.addAdapter(std::make_pair(&mRaces.getColumn(index), new RaceAttributeAdapter())); + mRaces.getNestableColumn(index)->addColumn(new NestedChildColumn( + Columns::ColumnId_Attribute, ColumnBase::Display_Attribute, ColumnBase::Flag_Dialogue, false)); mRaces.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_Attribute, - ColumnBase::Flag_Dialogue, false)); + new NestedChildColumn(Columns::ColumnId_Male, ColumnBase::Display_Integer)); mRaces.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_Male, ColumnBase::Display_Integer)); - mRaces.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_Female, ColumnBase::Display_Integer)); + new NestedChildColumn(Columns::ColumnId_Female, ColumnBase::Display_Integer)); // Race skill bonus - mRaces.addColumn (new NestedParentColumn (Columns::ColumnId_RaceSkillBonus, - ColumnBase::Flag_Dialogue, true)); // fixed rows table - index = mRaces.getColumns()-1; - mRaces.addAdapter (std::make_pair(&mRaces.getColumn(index), new RaceSkillsBonusAdapter())); + mRaces.addColumn(new NestedParentColumn( + Columns::ColumnId_RaceSkillBonus, ColumnBase::Flag_Dialogue, true)); // fixed rows table + index = mRaces.getColumns() - 1; + mRaces.addAdapter(std::make_pair(&mRaces.getColumn(index), new RaceSkillsBonusAdapter())); mRaces.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_Skill, ColumnBase::Display_SkillId)); + new NestedChildColumn(Columns::ColumnId_Skill, ColumnBase::Display_SkillId)); mRaces.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_RaceBonus, ColumnBase::Display_Integer)); - - mSounds.addColumn (new StringIdColumn); - mSounds.addColumn (new RecordStateColumn); - mSounds.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Sound)); - mSounds.addColumn (new SoundParamColumn (SoundParamColumn::Type_Volume)); - mSounds.addColumn (new SoundParamColumn (SoundParamColumn::Type_MinRange)); - mSounds.addColumn (new SoundParamColumn (SoundParamColumn::Type_MaxRange)); - mSounds.addColumn (new SoundFileColumn); - - mScripts.addColumn (new StringIdColumn); - mScripts.addColumn (new RecordStateColumn); - mScripts.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Script)); - mScripts.addColumn (new ScriptColumn (ScriptColumn::Type_File)); - - mRegions.addColumn (new StringIdColumn); - mRegions.addColumn (new RecordStateColumn); - mRegions.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Region)); - mRegions.addColumn (new NameColumn); - mRegions.addColumn (new MapColourColumn); - mRegions.addColumn (new SleepListColumn); + new NestedChildColumn(Columns::ColumnId_RaceBonus, ColumnBase::Display_Integer)); + + mSounds.addColumn(new StringIdColumn); + mSounds.addColumn(new RecordStateColumn); + mSounds.addColumn(new FixedRecordTypeColumn(UniversalId::Type_Sound)); + mSounds.addColumn(new SoundParamColumn(SoundParamColumn::Type_Volume)); + mSounds.addColumn(new SoundParamColumn(SoundParamColumn::Type_MinRange)); + mSounds.addColumn(new SoundParamColumn(SoundParamColumn::Type_MaxRange)); + mSounds.addColumn(new SoundFileColumn); + + mScripts.addColumn(new StringIdColumn); + mScripts.addColumn(new RecordStateColumn); + mScripts.addColumn(new FixedRecordTypeColumn(UniversalId::Type_Script)); + mScripts.addColumn(new ScriptColumn(ScriptColumn::Type_File)); + + mRegions.addColumn(new StringIdColumn); + mRegions.addColumn(new RecordStateColumn); + mRegions.addColumn(new FixedRecordTypeColumn(UniversalId::Type_Region)); + mRegions.addColumn(new NameColumn); + mRegions.addColumn(new MapColourColumn); + mRegions.addColumn(new SleepListColumn); // Region Weather - mRegions.addColumn (new NestedParentColumn (Columns::ColumnId_RegionWeather)); - index = mRegions.getColumns()-1; - mRegions.addAdapter (std::make_pair(&mRegions.getColumn(index), new RegionWeatherAdapter ())); + mRegions.addColumn(new NestedParentColumn(Columns::ColumnId_RegionWeather)); + index = mRegions.getColumns() - 1; + mRegions.addAdapter(std::make_pair(&mRegions.getColumn(index), new RegionWeatherAdapter())); mRegions.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_WeatherName, ColumnBase::Display_String, false)); + new NestedChildColumn(Columns::ColumnId_WeatherName, ColumnBase::Display_String, false)); mRegions.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_WeatherChance, ColumnBase::Display_UnsignedInteger8)); + new NestedChildColumn(Columns::ColumnId_WeatherChance, ColumnBase::Display_UnsignedInteger8)); // Region Sounds - mRegions.addColumn (new NestedParentColumn (Columns::ColumnId_RegionSounds)); - index = mRegions.getColumns()-1; - mRegions.addAdapter (std::make_pair(&mRegions.getColumn(index), new RegionSoundListAdapter ())); + mRegions.addColumn(new NestedParentColumn(Columns::ColumnId_RegionSounds)); + index = mRegions.getColumns() - 1; + mRegions.addAdapter(std::make_pair(&mRegions.getColumn(index), new RegionSoundListAdapter())); mRegions.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_SoundName, ColumnBase::Display_Sound)); + new NestedChildColumn(Columns::ColumnId_SoundName, ColumnBase::Display_Sound)); mRegions.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_SoundChance, ColumnBase::Display_UnsignedInteger8)); - - mBirthsigns.addColumn (new StringIdColumn); - mBirthsigns.addColumn (new RecordStateColumn); - mBirthsigns.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Birthsign)); - mBirthsigns.addColumn (new NameColumn); - mBirthsigns.addColumn (new TextureColumn); - mBirthsigns.addColumn (new DescriptionColumn); + new NestedChildColumn(Columns::ColumnId_SoundChance, ColumnBase::Display_UnsignedInteger8)); + + mBirthsigns.addColumn(new StringIdColumn); + mBirthsigns.addColumn(new RecordStateColumn); + mBirthsigns.addColumn(new FixedRecordTypeColumn(UniversalId::Type_Birthsign)); + mBirthsigns.addColumn(new NameColumn); + mBirthsigns.addColumn(new TextureColumn); + mBirthsigns.addColumn(new DescriptionColumn); // Birthsign spells - mBirthsigns.addColumn (new NestedParentColumn (Columns::ColumnId_PowerList)); - index = mBirthsigns.getColumns()-1; - mBirthsigns.addAdapter (std::make_pair(&mBirthsigns.getColumn(index), - new SpellListAdapter ())); + mBirthsigns.addColumn(new NestedParentColumn(Columns::ColumnId_PowerList)); + index = mBirthsigns.getColumns() - 1; + mBirthsigns.addAdapter(std::make_pair(&mBirthsigns.getColumn(index), new SpellListAdapter())); mBirthsigns.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_SpellId, ColumnBase::Display_Spell)); - - mSpells.addColumn (new StringIdColumn); - mSpells.addColumn (new RecordStateColumn); - mSpells.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Spell)); - mSpells.addColumn (new NameColumn); - mSpells.addColumn (new SpellTypeColumn); - mSpells.addColumn (new CostColumn); - mSpells.addColumn (new FlagColumn (Columns::ColumnId_AutoCalc, 0x1)); - mSpells.addColumn (new FlagColumn (Columns::ColumnId_StarterSpell, 0x2)); - mSpells.addColumn (new FlagColumn (Columns::ColumnId_AlwaysSucceeds, 0x4)); + new NestedChildColumn(Columns::ColumnId_SpellId, ColumnBase::Display_Spell)); + + mSpells.addColumn(new StringIdColumn); + mSpells.addColumn(new RecordStateColumn); + mSpells.addColumn(new FixedRecordTypeColumn(UniversalId::Type_Spell)); + mSpells.addColumn(new NameColumn); + mSpells.addColumn(new SpellTypeColumn); + mSpells.addColumn(new CostColumn); + mSpells.addColumn(new FlagColumn(Columns::ColumnId_AutoCalc, 0x1)); + mSpells.addColumn(new FlagColumn(Columns::ColumnId_StarterSpell, 0x2)); + mSpells.addColumn(new FlagColumn(Columns::ColumnId_AlwaysSucceeds, 0x4)); // Spell effects - mSpells.addColumn (new NestedParentColumn (Columns::ColumnId_EffectList)); - index = mSpells.getColumns()-1; - mSpells.addAdapter (std::make_pair(&mSpells.getColumn(index), new EffectsListAdapter ())); + mSpells.addColumn(new NestedParentColumn(Columns::ColumnId_EffectList)); + index = mSpells.getColumns() - 1; + mSpells.addAdapter(std::make_pair(&mSpells.getColumn(index), new EffectsListAdapter())); mSpells.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_EffectId)); + new NestedChildColumn(Columns::ColumnId_EffectId, ColumnBase::Display_EffectId)); mSpells.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_Skill, ColumnBase::Display_EffectSkill)); + new NestedChildColumn(Columns::ColumnId_Skill, ColumnBase::Display_EffectSkill)); mSpells.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_EffectAttribute)); + new NestedChildColumn(Columns::ColumnId_Attribute, ColumnBase::Display_EffectAttribute)); mSpells.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_EffectRange, ColumnBase::Display_EffectRange)); + new NestedChildColumn(Columns::ColumnId_EffectRange, ColumnBase::Display_EffectRange)); mSpells.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_EffectArea, ColumnBase::Display_String)); + new NestedChildColumn(Columns::ColumnId_EffectArea, ColumnBase::Display_String)); mSpells.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_Duration, ColumnBase::Display_Integer)); // reuse from light + new NestedChildColumn(Columns::ColumnId_Duration, ColumnBase::Display_Integer)); // reuse from light mSpells.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_MinMagnitude, ColumnBase::Display_Integer)); + new NestedChildColumn(Columns::ColumnId_MinMagnitude, ColumnBase::Display_Integer)); mSpells.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_MaxMagnitude, ColumnBase::Display_Integer)); - - mTopics.addColumn (new StringIdColumn); - mTopics.addColumn (new RecordStateColumn); - mTopics.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Topic)); - mTopics.addColumn (new DialogueTypeColumn); - - mJournals.addColumn (new StringIdColumn); - mJournals.addColumn (new RecordStateColumn); - mJournals.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Journal)); - mJournals.addColumn (new DialogueTypeColumn (true)); - - mTopicInfos.addColumn (new StringIdColumn (true)); - mTopicInfos.addColumn (new RecordStateColumn); - mTopicInfos.addColumn (new FixedRecordTypeColumn (UniversalId::Type_TopicInfo)); - mTopicInfos.addColumn (new TopicColumn (false)); - mTopicInfos.addColumn (new ActorColumn); - mTopicInfos.addColumn (new RaceColumn); - mTopicInfos.addColumn (new ClassColumn); - mTopicInfos.addColumn (new FactionColumn); - mTopicInfos.addColumn (new CellColumn); - mTopicInfos.addColumn (new DispositionColumn); - mTopicInfos.addColumn (new RankColumn); - mTopicInfos.addColumn (new GenderColumn); - mTopicInfos.addColumn (new PcFactionColumn); - mTopicInfos.addColumn (new PcRankColumn); - mTopicInfos.addColumn (new SoundFileColumn); - mTopicInfos.addColumn (new ResponseColumn); + new NestedChildColumn(Columns::ColumnId_MaxMagnitude, ColumnBase::Display_Integer)); + + mTopics.addColumn(new StringIdColumn); + mTopics.addColumn(new RecordStateColumn); + mTopics.addColumn(new FixedRecordTypeColumn(UniversalId::Type_Topic)); + mTopics.addColumn(new DialogueTypeColumn); + + mJournals.addColumn(new StringIdColumn); + mJournals.addColumn(new RecordStateColumn); + mJournals.addColumn(new FixedRecordTypeColumn(UniversalId::Type_Journal)); + mJournals.addColumn(new DialogueTypeColumn(true)); + + mTopicInfos.addColumn(new StringIdColumn(true)); + mTopicInfos.addColumn(new RecordStateColumn); + mTopicInfos.addColumn(new FixedRecordTypeColumn(UniversalId::Type_TopicInfo)); + mTopicInfos.addColumn(new TopicColumn(false)); + mTopicInfos.addColumn(new ActorColumn); + mTopicInfos.addColumn(new RaceColumn); + mTopicInfos.addColumn(new ClassColumn); + mTopicInfos.addColumn(new FactionColumn); + mTopicInfos.addColumn(new CellColumn); + mTopicInfos.addColumn(new DispositionColumn); + mTopicInfos.addColumn(new RankColumn); + mTopicInfos.addColumn(new GenderColumn); + mTopicInfos.addColumn(new PcFactionColumn); + mTopicInfos.addColumn(new PcRankColumn); + mTopicInfos.addColumn(new SoundFileColumn); + mTopicInfos.addColumn(new ResponseColumn); // Result script - mTopicInfos.addColumn (new NestedParentColumn (Columns::ColumnId_InfoList, - ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_List)); - index = mTopicInfos.getColumns()-1; - mTopicInfos.addAdapter (std::make_pair(&mTopicInfos.getColumn(index), new InfoListAdapter ())); + mTopicInfos.addColumn(new NestedParentColumn( + Columns::ColumnId_InfoList, ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_List)); + index = mTopicInfos.getColumns() - 1; + mTopicInfos.addAdapter(std::make_pair(&mTopicInfos.getColumn(index), new InfoListAdapter())); mTopicInfos.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_ScriptText, ColumnBase::Display_ScriptLines)); + new NestedChildColumn(Columns::ColumnId_ScriptText, ColumnBase::Display_ScriptLines)); // Special conditions - mTopicInfos.addColumn (new NestedParentColumn (Columns::ColumnId_InfoCondition)); - index = mTopicInfos.getColumns()-1; - mTopicInfos.addAdapter (std::make_pair(&mTopicInfos.getColumn(index), new InfoConditionAdapter ())); + mTopicInfos.addColumn(new NestedParentColumn(Columns::ColumnId_InfoCondition)); + index = mTopicInfos.getColumns() - 1; + mTopicInfos.addAdapter(std::make_pair(&mTopicInfos.getColumn(index), new InfoConditionAdapter())); mTopicInfos.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_InfoCondFunc, ColumnBase::Display_InfoCondFunc)); + new NestedChildColumn(Columns::ColumnId_InfoCondFunc, ColumnBase::Display_InfoCondFunc)); // FIXME: don't have dynamic value enum delegate, use Display_String for now mTopicInfos.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_InfoCondVar, ColumnBase::Display_InfoCondVar)); + new NestedChildColumn(Columns::ColumnId_InfoCondVar, ColumnBase::Display_InfoCondVar)); mTopicInfos.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_InfoCondComp, ColumnBase::Display_InfoCondComp)); + new NestedChildColumn(Columns::ColumnId_InfoCondComp, ColumnBase::Display_InfoCondComp)); mTopicInfos.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_Value, ColumnBase::Display_Var)); - - mJournalInfos.addColumn (new StringIdColumn (true)); - mJournalInfos.addColumn (new RecordStateColumn); - mJournalInfos.addColumn (new FixedRecordTypeColumn (UniversalId::Type_JournalInfo)); - mJournalInfos.addColumn (new TopicColumn (true)); - mJournalInfos.addColumn (new QuestStatusTypeColumn); - mJournalInfos.addColumn (new QuestIndexColumn); - mJournalInfos.addColumn (new QuestDescriptionColumn); - - mCells.addColumn (new StringIdColumn); - mCells.addColumn (new RecordStateColumn); - mCells.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Cell)); - mCells.addColumn (new NameColumn(ColumnBase::Display_String64)); - mCells.addColumn (new FlagColumn (Columns::ColumnId_SleepForbidden, ESM::Cell::NoSleep)); - mCells.addColumn (new FlagColumn (Columns::ColumnId_InteriorWater, ESM::Cell::HasWater, + new NestedChildColumn(Columns::ColumnId_Value, ColumnBase::Display_Var)); + + mJournalInfos.addColumn(new StringIdColumn(true)); + mJournalInfos.addColumn(new RecordStateColumn); + mJournalInfos.addColumn(new FixedRecordTypeColumn(UniversalId::Type_JournalInfo)); + mJournalInfos.addColumn(new TopicColumn(true)); + mJournalInfos.addColumn(new QuestStatusTypeColumn); + mJournalInfos.addColumn(new QuestIndexColumn); + mJournalInfos.addColumn(new QuestDescriptionColumn); + + mCells.addColumn(new StringIdColumn); + mCells.addColumn(new RecordStateColumn); + mCells.addColumn(new FixedRecordTypeColumn(UniversalId::Type_Cell)); + mCells.addColumn(new NameColumn(ColumnBase::Display_String64)); + mCells.addColumn(new FlagColumn(Columns::ColumnId_SleepForbidden, ESM::Cell::NoSleep)); + mCells.addColumn(new FlagColumn(Columns::ColumnId_InteriorWater, ESM::Cell::HasWater, ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh)); - mCells.addColumn (new FlagColumn (Columns::ColumnId_InteriorSky, ESM::Cell::QuasiEx, + mCells.addColumn(new FlagColumn(Columns::ColumnId_InteriorSky, ESM::Cell::QuasiEx, ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh)); - mCells.addColumn (new RegionColumn); - mCells.addColumn (new RefNumCounterColumn); + mCells.addColumn(new RegionColumn); + mCells.addColumn(new RefNumCounterColumn); // Misc Cell data - mCells.addColumn (new NestedParentColumn (Columns::ColumnId_Cell, - ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_List)); - index = mCells.getColumns()-1; - mCells.addAdapter (std::make_pair(&mCells.getColumn(index), new CellListAdapter ())); + mCells.addColumn(new NestedParentColumn( + Columns::ColumnId_Cell, ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_List)); + index = mCells.getColumns() - 1; + mCells.addAdapter(std::make_pair(&mCells.getColumn(index), new CellListAdapter())); mCells.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_Interior, ColumnBase::Display_Boolean, - ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh)); + new NestedChildColumn(Columns::ColumnId_Interior, ColumnBase::Display_Boolean, + ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh)); mCells.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_Ambient, ColumnBase::Display_Colour)); + new NestedChildColumn(Columns::ColumnId_Ambient, ColumnBase::Display_Colour)); mCells.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_Sunlight, ColumnBase::Display_Colour)); + new NestedChildColumn(Columns::ColumnId_Sunlight, ColumnBase::Display_Colour)); mCells.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_Fog, ColumnBase::Display_Colour)); + new NestedChildColumn(Columns::ColumnId_Fog, ColumnBase::Display_Colour)); mCells.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_FogDensity, ColumnBase::Display_Float)); + new NestedChildColumn(Columns::ColumnId_FogDensity, ColumnBase::Display_Float)); mCells.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_WaterLevel, ColumnBase::Display_Float)); + new NestedChildColumn(Columns::ColumnId_WaterLevel, ColumnBase::Display_Float)); mCells.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_MapColor, ColumnBase::Display_Colour)); - - mEnchantments.addColumn (new StringIdColumn); - mEnchantments.addColumn (new RecordStateColumn); - mEnchantments.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Enchantment)); - mEnchantments.addColumn (new EnchantmentTypeColumn); - mEnchantments.addColumn (new CostColumn); - mEnchantments.addColumn (new ChargesColumn2); - mEnchantments.addColumn (new FlagColumn (Columns::ColumnId_AutoCalc, ESM::Enchantment::Autocalc)); + new NestedChildColumn(Columns::ColumnId_MapColor, ColumnBase::Display_Colour)); + + mEnchantments.addColumn(new StringIdColumn); + mEnchantments.addColumn(new RecordStateColumn); + mEnchantments.addColumn(new FixedRecordTypeColumn(UniversalId::Type_Enchantment)); + mEnchantments.addColumn(new EnchantmentTypeColumn); + mEnchantments.addColumn(new CostColumn); + mEnchantments.addColumn(new ChargesColumn2); + mEnchantments.addColumn(new FlagColumn(Columns::ColumnId_AutoCalc, ESM::Enchantment::Autocalc)); // Enchantment effects - mEnchantments.addColumn (new NestedParentColumn (Columns::ColumnId_EffectList)); - index = mEnchantments.getColumns()-1; - mEnchantments.addAdapter (std::make_pair(&mEnchantments.getColumn(index), - new EffectsListAdapter ())); + mEnchantments.addColumn(new NestedParentColumn(Columns::ColumnId_EffectList)); + index = mEnchantments.getColumns() - 1; + mEnchantments.addAdapter( + std::make_pair(&mEnchantments.getColumn(index), new EffectsListAdapter())); mEnchantments.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_EffectId)); + new NestedChildColumn(Columns::ColumnId_EffectId, ColumnBase::Display_EffectId)); mEnchantments.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_Skill, ColumnBase::Display_EffectSkill)); + new NestedChildColumn(Columns::ColumnId_Skill, ColumnBase::Display_EffectSkill)); mEnchantments.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_EffectAttribute)); + new NestedChildColumn(Columns::ColumnId_Attribute, ColumnBase::Display_EffectAttribute)); mEnchantments.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_EffectRange, ColumnBase::Display_EffectRange)); + new NestedChildColumn(Columns::ColumnId_EffectRange, ColumnBase::Display_EffectRange)); mEnchantments.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_EffectArea, ColumnBase::Display_String)); + new NestedChildColumn(Columns::ColumnId_EffectArea, ColumnBase::Display_String)); mEnchantments.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_Duration, ColumnBase::Display_Integer)); // reuse from light + new NestedChildColumn(Columns::ColumnId_Duration, ColumnBase::Display_Integer)); // reuse from light mEnchantments.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_MinMagnitude, ColumnBase::Display_Integer)); + new NestedChildColumn(Columns::ColumnId_MinMagnitude, ColumnBase::Display_Integer)); mEnchantments.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_MaxMagnitude, ColumnBase::Display_Integer)); + new NestedChildColumn(Columns::ColumnId_MaxMagnitude, ColumnBase::Display_Integer)); - mBodyParts.addColumn (new StringIdColumn); - mBodyParts.addColumn (new RecordStateColumn); - mBodyParts.addColumn (new FixedRecordTypeColumn (UniversalId::Type_BodyPart)); - mBodyParts.addColumn (new BodyPartTypeColumn); - mBodyParts.addColumn (new VampireColumn); + mBodyParts.addColumn(new StringIdColumn); + mBodyParts.addColumn(new RecordStateColumn); + mBodyParts.addColumn(new FixedRecordTypeColumn(UniversalId::Type_BodyPart)); + mBodyParts.addColumn(new BodyPartTypeColumn); + mBodyParts.addColumn(new VampireColumn); mBodyParts.addColumn(new GenderNpcColumn); - mBodyParts.addColumn (new FlagColumn (Columns::ColumnId_Playable, - ESM::BodyPart::BPF_NotPlayable, ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, true)); + mBodyParts.addColumn(new FlagColumn(Columns::ColumnId_Playable, ESM::BodyPart::BPF_NotPlayable, + ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, true)); int meshTypeFlags = ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh; - MeshTypeColumn *meshTypeColumn = new MeshTypeColumn(meshTypeFlags); - mBodyParts.addColumn (meshTypeColumn); - mBodyParts.addColumn (new ModelColumn); - mBodyParts.addColumn (new BodyPartRaceColumn(meshTypeColumn)); - - mSoundGens.addColumn (new StringIdColumn); - mSoundGens.addColumn (new RecordStateColumn); - mSoundGens.addColumn (new FixedRecordTypeColumn (UniversalId::Type_SoundGen)); - mSoundGens.addColumn (new CreatureColumn); - mSoundGens.addColumn (new SoundColumn); - mSoundGens.addColumn (new SoundGeneratorTypeColumn); - - mMagicEffects.addColumn (new StringIdColumn); - mMagicEffects.addColumn (new RecordStateColumn); - mMagicEffects.addColumn (new FixedRecordTypeColumn (UniversalId::Type_MagicEffect)); - mMagicEffects.addColumn (new SchoolColumn); - mMagicEffects.addColumn (new BaseCostColumn); - mMagicEffects.addColumn (new EffectTextureColumn (Columns::ColumnId_Icon)); - mMagicEffects.addColumn (new EffectTextureColumn (Columns::ColumnId_Particle)); - mMagicEffects.addColumn (new EffectObjectColumn (Columns::ColumnId_CastingObject)); - mMagicEffects.addColumn (new EffectObjectColumn (Columns::ColumnId_HitObject)); - mMagicEffects.addColumn (new EffectObjectColumn (Columns::ColumnId_AreaObject)); - mMagicEffects.addColumn (new EffectObjectColumn (Columns::ColumnId_BoltObject)); - mMagicEffects.addColumn (new EffectSoundColumn (Columns::ColumnId_CastingSound)); - mMagicEffects.addColumn (new EffectSoundColumn (Columns::ColumnId_HitSound)); - mMagicEffects.addColumn (new EffectSoundColumn (Columns::ColumnId_AreaSound)); - mMagicEffects.addColumn (new EffectSoundColumn (Columns::ColumnId_BoltSound)); - mMagicEffects.addColumn (new FlagColumn ( - Columns::ColumnId_AllowSpellmaking, ESM::MagicEffect::AllowSpellmaking)); - mMagicEffects.addColumn (new FlagColumn ( - Columns::ColumnId_AllowEnchanting, ESM::MagicEffect::AllowEnchanting)); - mMagicEffects.addColumn (new FlagColumn ( - Columns::ColumnId_NegativeLight, ESM::MagicEffect::NegativeLight)); - mMagicEffects.addColumn (new DescriptionColumn); - - mLand.addColumn (new StringIdColumn); - mLand.addColumn (new RecordStateColumn); - mLand.addColumn (new FixedRecordTypeColumn(UniversalId::Type_Land)); - mLand.addColumn (new LandPluginIndexColumn); - mLand.addColumn (new LandNormalsColumn); - mLand.addColumn (new LandHeightsColumn); - mLand.addColumn (new LandColoursColumn); - mLand.addColumn (new LandTexturesColumn); - - mLandTextures.addColumn (new StringIdColumn(true)); - mLandTextures.addColumn (new RecordStateColumn); - mLandTextures.addColumn (new FixedRecordTypeColumn(UniversalId::Type_LandTexture)); - mLandTextures.addColumn (new LandTextureNicknameColumn); - mLandTextures.addColumn (new LandTexturePluginIndexColumn); - mLandTextures.addColumn (new LandTextureIndexColumn); - mLandTextures.addColumn (new TextureColumn); - - mPathgrids.addColumn (new StringIdColumn); - mPathgrids.addColumn (new RecordStateColumn); - mPathgrids.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Pathgrid)); + MeshTypeColumn* meshTypeColumn = new MeshTypeColumn(meshTypeFlags); + mBodyParts.addColumn(meshTypeColumn); + mBodyParts.addColumn(new ModelColumn); + mBodyParts.addColumn(new BodyPartRaceColumn(meshTypeColumn)); + + mSoundGens.addColumn(new StringIdColumn); + mSoundGens.addColumn(new RecordStateColumn); + mSoundGens.addColumn(new FixedRecordTypeColumn(UniversalId::Type_SoundGen)); + mSoundGens.addColumn(new CreatureColumn); + mSoundGens.addColumn(new SoundColumn); + mSoundGens.addColumn(new SoundGeneratorTypeColumn); + + mMagicEffects.addColumn(new StringIdColumn); + mMagicEffects.addColumn(new RecordStateColumn); + mMagicEffects.addColumn(new FixedRecordTypeColumn(UniversalId::Type_MagicEffect)); + mMagicEffects.addColumn(new SchoolColumn); + mMagicEffects.addColumn(new BaseCostColumn); + mMagicEffects.addColumn(new EffectTextureColumn(Columns::ColumnId_Icon)); + mMagicEffects.addColumn(new EffectTextureColumn(Columns::ColumnId_Particle)); + mMagicEffects.addColumn(new EffectObjectColumn(Columns::ColumnId_CastingObject)); + mMagicEffects.addColumn(new EffectObjectColumn(Columns::ColumnId_HitObject)); + mMagicEffects.addColumn(new EffectObjectColumn(Columns::ColumnId_AreaObject)); + mMagicEffects.addColumn(new EffectObjectColumn(Columns::ColumnId_BoltObject)); + mMagicEffects.addColumn(new EffectSoundColumn(Columns::ColumnId_CastingSound)); + mMagicEffects.addColumn(new EffectSoundColumn(Columns::ColumnId_HitSound)); + mMagicEffects.addColumn(new EffectSoundColumn(Columns::ColumnId_AreaSound)); + mMagicEffects.addColumn(new EffectSoundColumn(Columns::ColumnId_BoltSound)); + mMagicEffects.addColumn( + new FlagColumn(Columns::ColumnId_AllowSpellmaking, ESM::MagicEffect::AllowSpellmaking)); + mMagicEffects.addColumn( + new FlagColumn(Columns::ColumnId_AllowEnchanting, ESM::MagicEffect::AllowEnchanting)); + mMagicEffects.addColumn( + new FlagColumn(Columns::ColumnId_NegativeLight, ESM::MagicEffect::NegativeLight)); + mMagicEffects.addColumn(new DescriptionColumn); + + mLand.addColumn(new StringIdColumn); + mLand.addColumn(new RecordStateColumn); + mLand.addColumn(new FixedRecordTypeColumn(UniversalId::Type_Land)); + mLand.addColumn(new LandPluginIndexColumn); + mLand.addColumn(new LandNormalsColumn); + mLand.addColumn(new LandHeightsColumn); + mLand.addColumn(new LandColoursColumn); + mLand.addColumn(new LandTexturesColumn); + + mLandTextures.addColumn(new StringIdColumn(true)); + mLandTextures.addColumn(new RecordStateColumn); + mLandTextures.addColumn(new FixedRecordTypeColumn(UniversalId::Type_LandTexture)); + mLandTextures.addColumn(new LandTextureNicknameColumn); + mLandTextures.addColumn(new LandTexturePluginIndexColumn); + mLandTextures.addColumn(new LandTextureIndexColumn); + mLandTextures.addColumn(new TextureColumn); + + mPathgrids.addColumn(new StringIdColumn); + mPathgrids.addColumn(new RecordStateColumn); + mPathgrids.addColumn(new FixedRecordTypeColumn(UniversalId::Type_Pathgrid)); // new object deleted in dtor of Collection - mPathgrids.addColumn (new NestedParentColumn (Columns::ColumnId_PathgridPoints)); - index = mPathgrids.getColumns()-1; + mPathgrids.addColumn(new NestedParentColumn(Columns::ColumnId_PathgridPoints)); + index = mPathgrids.getColumns() - 1; // new object deleted in dtor of NestedCollection - mPathgrids.addAdapter (std::make_pair(&mPathgrids.getColumn(index), new PathgridPointListAdapter ())); + mPathgrids.addAdapter(std::make_pair(&mPathgrids.getColumn(index), new PathgridPointListAdapter())); // new objects deleted in dtor of NestableColumn // WARNING: The order of the columns below are assumed in PathgridPointListAdapter + mPathgrids.getNestableColumn(index)->addColumn(new NestedChildColumn( + Columns::ColumnId_PathgridIndex, ColumnBase::Display_Integer, ColumnBase::Flag_Dialogue, false)); mPathgrids.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_PathgridIndex, ColumnBase::Display_Integer, - ColumnBase::Flag_Dialogue, false)); + new NestedChildColumn(Columns::ColumnId_PathgridPosX, ColumnBase::Display_Integer)); mPathgrids.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_PathgridPosX, ColumnBase::Display_Integer)); + new NestedChildColumn(Columns::ColumnId_PathgridPosY, ColumnBase::Display_Integer)); mPathgrids.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_PathgridPosY, ColumnBase::Display_Integer)); - mPathgrids.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_PathgridPosZ, ColumnBase::Display_Integer)); + new NestedChildColumn(Columns::ColumnId_PathgridPosZ, ColumnBase::Display_Integer)); - mPathgrids.addColumn (new NestedParentColumn (Columns::ColumnId_PathgridEdges)); - index = mPathgrids.getColumns()-1; - mPathgrids.addAdapter (std::make_pair(&mPathgrids.getColumn(index), new PathgridEdgeListAdapter ())); - mPathgrids.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_PathgridEdgeIndex, ColumnBase::Display_Integer, - ColumnBase::Flag_Dialogue, false)); + mPathgrids.addColumn(new NestedParentColumn(Columns::ColumnId_PathgridEdges)); + index = mPathgrids.getColumns() - 1; + mPathgrids.addAdapter(std::make_pair(&mPathgrids.getColumn(index), new PathgridEdgeListAdapter())); + mPathgrids.getNestableColumn(index)->addColumn(new NestedChildColumn( + Columns::ColumnId_PathgridEdgeIndex, ColumnBase::Display_Integer, ColumnBase::Flag_Dialogue, false)); mPathgrids.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_PathgridEdge0, ColumnBase::Display_Integer)); + new NestedChildColumn(Columns::ColumnId_PathgridEdge0, ColumnBase::Display_Integer)); mPathgrids.getNestableColumn(index)->addColumn( - new NestedChildColumn (Columns::ColumnId_PathgridEdge1, ColumnBase::Display_Integer)); - - mStartScripts.addColumn (new StringIdColumn); - mStartScripts.addColumn (new RecordStateColumn); - mStartScripts.addColumn (new FixedRecordTypeColumn (UniversalId::Type_StartScript)); - - mRefs.addColumn (new StringIdColumn (true)); - mRefs.addColumn (new RecordStateColumn); - mRefs.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Reference)); - mRefs.addColumn (new CellColumn (true)); - mRefs.addColumn (new OriginalCellColumn); - mRefs.addColumn (new IdColumn); - mRefs.addColumn (new PosColumn (&CellRef::mPos, 0, false)); - mRefs.addColumn (new PosColumn (&CellRef::mPos, 1, false)); - mRefs.addColumn (new PosColumn (&CellRef::mPos, 2, false)); - mRefs.addColumn (new RotColumn (&CellRef::mPos, 0, false)); - mRefs.addColumn (new RotColumn (&CellRef::mPos, 1, false)); - mRefs.addColumn (new RotColumn (&CellRef::mPos, 2, false)); - mRefs.addColumn (new ScaleColumn); - mRefs.addColumn (new OwnerColumn); - mRefs.addColumn (new SoulColumn); - mRefs.addColumn (new FactionColumn); - mRefs.addColumn (new FactionIndexColumn); - mRefs.addColumn (new ChargesColumn); - mRefs.addColumn (new EnchantmentChargesColumn); - mRefs.addColumn (new GoldValueColumn); - mRefs.addColumn (new TeleportColumn); - mRefs.addColumn (new TeleportCellColumn); - mRefs.addColumn (new PosColumn (&CellRef::mDoorDest, 0, true)); - mRefs.addColumn (new PosColumn (&CellRef::mDoorDest, 1, true)); - mRefs.addColumn (new PosColumn (&CellRef::mDoorDest, 2, true)); - mRefs.addColumn (new RotColumn (&CellRef::mDoorDest, 0, true)); - mRefs.addColumn (new RotColumn (&CellRef::mDoorDest, 1, true)); - mRefs.addColumn (new RotColumn (&CellRef::mDoorDest, 2, true)); - mRefs.addColumn (new LockLevelColumn); - mRefs.addColumn (new KeyColumn); - mRefs.addColumn (new TrapColumn); - mRefs.addColumn (new OwnerGlobalColumn); - mRefs.addColumn (new RefNumColumn); - - mFilters.addColumn (new StringIdColumn); - mFilters.addColumn (new RecordStateColumn); - mFilters.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Filter)); - mFilters.addColumn (new FilterColumn); - mFilters.addColumn (new DescriptionColumn); - - mDebugProfiles.addColumn (new StringIdColumn); - mDebugProfiles.addColumn (new RecordStateColumn); - mDebugProfiles.addColumn (new FixedRecordTypeColumn (UniversalId::Type_DebugProfile)); - mDebugProfiles.addColumn (new FlagColumn2 ( - Columns::ColumnId_DefaultProfile, ESM::DebugProfile::Flag_Default)); - mDebugProfiles.addColumn (new FlagColumn2 ( - Columns::ColumnId_BypassNewGame, ESM::DebugProfile::Flag_BypassNewGame)); - mDebugProfiles.addColumn (new FlagColumn2 ( - Columns::ColumnId_GlobalProfile, ESM::DebugProfile::Flag_Global)); - mDebugProfiles.addColumn (new DescriptionColumn); - mDebugProfiles.addColumn (new ScriptColumn ( - ScriptColumn::Type_Lines)); - - mMetaData.appendBlankRecord ("sys::meta"); - - mMetaData.addColumn (new StringIdColumn (true)); - mMetaData.addColumn (new RecordStateColumn); - mMetaData.addColumn (new FixedRecordTypeColumn (UniversalId::Type_MetaData)); - mMetaData.addColumn (new FormatColumn); - mMetaData.addColumn (new AuthorColumn); - mMetaData.addColumn (new FileDescriptionColumn); - - addModel (new IdTable (&mGlobals), UniversalId::Type_Global); - addModel (new IdTable (&mGmsts), UniversalId::Type_Gmst); - addModel (new IdTable (&mSkills), UniversalId::Type_Skill); - addModel (new IdTable (&mClasses), UniversalId::Type_Class); - addModel (new IdTree (&mFactions, &mFactions), UniversalId::Type_Faction); - addModel (new IdTree (&mRaces, &mRaces), UniversalId::Type_Race); - addModel (new IdTable (&mSounds), UniversalId::Type_Sound); - addModel (new IdTable (&mScripts), UniversalId::Type_Script); - addModel (new IdTree (&mRegions, &mRegions), UniversalId::Type_Region); - addModel (new IdTree (&mBirthsigns, &mBirthsigns), UniversalId::Type_Birthsign); - addModel (new IdTree (&mSpells, &mSpells), UniversalId::Type_Spell); - addModel (new IdTable (&mTopics), UniversalId::Type_Topic); - addModel (new IdTable (&mJournals), UniversalId::Type_Journal); - addModel (new IdTree (&mTopicInfos, &mTopicInfos, IdTable::Feature_ReorderWithinTopic), - UniversalId::Type_TopicInfo); - addModel (new IdTable (&mJournalInfos, IdTable::Feature_ReorderWithinTopic), UniversalId::Type_JournalInfo); - addModel (new IdTree (&mCells, &mCells, IdTable::Feature_ViewId), UniversalId::Type_Cell); - addModel (new IdTree (&mEnchantments, &mEnchantments), UniversalId::Type_Enchantment); - addModel (new IdTable (&mBodyParts), UniversalId::Type_BodyPart); - addModel (new IdTable (&mSoundGens), UniversalId::Type_SoundGen); - addModel (new IdTable (&mMagicEffects), UniversalId::Type_MagicEffect); - addModel (new IdTable (&mLand, IdTable::Feature_AllowTouch), UniversalId::Type_Land); - addModel (new LandTextureIdTable (&mLandTextures), UniversalId::Type_LandTexture); - addModel (new IdTree (&mPathgrids, &mPathgrids), UniversalId::Type_Pathgrid); - addModel (new IdTable (&mStartScripts), UniversalId::Type_StartScript); - addModel (new IdTree (&mReferenceables, &mReferenceables, IdTable::Feature_Preview), - UniversalId::Type_Referenceable); - addModel (new IdTable (&mRefs, IdTable::Feature_ViewCell | IdTable::Feature_Preview), UniversalId::Type_Reference); - addModel (new IdTable (&mFilters), UniversalId::Type_Filter); - addModel (new IdTable (&mDebugProfiles), UniversalId::Type_DebugProfile); - addModel (new ResourceTable (&mResourcesManager.get (UniversalId::Type_Meshes)), - UniversalId::Type_Mesh); - addModel (new ResourceTable (&mResourcesManager.get (UniversalId::Type_Icons)), - UniversalId::Type_Icon); - addModel (new ResourceTable (&mResourcesManager.get (UniversalId::Type_Musics)), - UniversalId::Type_Music); - addModel (new ResourceTable (&mResourcesManager.get (UniversalId::Type_SoundsRes)), - UniversalId::Type_SoundRes); - addModel (new ResourceTable (&mResourcesManager.get (UniversalId::Type_Textures)), - UniversalId::Type_Texture); - addModel (new ResourceTable (&mResourcesManager.get (UniversalId::Type_Videos)), - UniversalId::Type_Video); - addModel (new IdTable (&mMetaData), UniversalId::Type_MetaData); + new NestedChildColumn(Columns::ColumnId_PathgridEdge1, ColumnBase::Display_Integer)); + + mStartScripts.addColumn(new StringIdColumn); + mStartScripts.addColumn(new RecordStateColumn); + mStartScripts.addColumn(new FixedRecordTypeColumn(UniversalId::Type_StartScript)); + + mRefs.addColumn(new StringIdColumn(true)); + mRefs.addColumn(new RecordStateColumn); + mRefs.addColumn(new FixedRecordTypeColumn(UniversalId::Type_Reference)); + mRefs.addColumn(new CellColumn(true)); + mRefs.addColumn(new OriginalCellColumn); + mRefs.addColumn(new IdColumn); + mRefs.addColumn(new PosColumn(&CellRef::mPos, 0, false)); + mRefs.addColumn(new PosColumn(&CellRef::mPos, 1, false)); + mRefs.addColumn(new PosColumn(&CellRef::mPos, 2, false)); + mRefs.addColumn(new RotColumn(&CellRef::mPos, 0, false)); + mRefs.addColumn(new RotColumn(&CellRef::mPos, 1, false)); + mRefs.addColumn(new RotColumn(&CellRef::mPos, 2, false)); + mRefs.addColumn(new ScaleColumn); + mRefs.addColumn(new OwnerColumn); + mRefs.addColumn(new SoulColumn); + mRefs.addColumn(new FactionColumn); + mRefs.addColumn(new FactionIndexColumn); + mRefs.addColumn(new ChargesColumn); + mRefs.addColumn(new EnchantmentChargesColumn); + mRefs.addColumn(new GoldValueColumn); + mRefs.addColumn(new TeleportColumn); + mRefs.addColumn(new TeleportCellColumn); + mRefs.addColumn(new PosColumn(&CellRef::mDoorDest, 0, true)); + mRefs.addColumn(new PosColumn(&CellRef::mDoorDest, 1, true)); + mRefs.addColumn(new PosColumn(&CellRef::mDoorDest, 2, true)); + mRefs.addColumn(new RotColumn(&CellRef::mDoorDest, 0, true)); + mRefs.addColumn(new RotColumn(&CellRef::mDoorDest, 1, true)); + mRefs.addColumn(new RotColumn(&CellRef::mDoorDest, 2, true)); + mRefs.addColumn(new LockLevelColumn); + mRefs.addColumn(new KeyColumn); + mRefs.addColumn(new TrapColumn); + mRefs.addColumn(new OwnerGlobalColumn); + mRefs.addColumn(new RefNumColumn); + + mFilters.addColumn(new StringIdColumn); + mFilters.addColumn(new RecordStateColumn); + mFilters.addColumn(new FixedRecordTypeColumn(UniversalId::Type_Filter)); + mFilters.addColumn(new FilterColumn); + mFilters.addColumn(new DescriptionColumn); + + mDebugProfiles.addColumn(new StringIdColumn); + mDebugProfiles.addColumn(new RecordStateColumn); + mDebugProfiles.addColumn(new FixedRecordTypeColumn(UniversalId::Type_DebugProfile)); + mDebugProfiles.addColumn( + new FlagColumn2(Columns::ColumnId_DefaultProfile, ESM::DebugProfile::Flag_Default)); + mDebugProfiles.addColumn( + new FlagColumn2(Columns::ColumnId_BypassNewGame, ESM::DebugProfile::Flag_BypassNewGame)); + mDebugProfiles.addColumn( + new FlagColumn2(Columns::ColumnId_GlobalProfile, ESM::DebugProfile::Flag_Global)); + mDebugProfiles.addColumn(new DescriptionColumn); + mDebugProfiles.addColumn(new ScriptColumn(ScriptColumn::Type_Lines)); + + mMetaData.appendBlankRecord("sys::meta"); + + mMetaData.addColumn(new StringIdColumn(true)); + mMetaData.addColumn(new RecordStateColumn); + mMetaData.addColumn(new FixedRecordTypeColumn(UniversalId::Type_MetaData)); + mMetaData.addColumn(new FormatColumn); + mMetaData.addColumn(new AuthorColumn); + mMetaData.addColumn(new FileDescriptionColumn); + + addModel(new IdTable(&mGlobals), UniversalId::Type_Global); + addModel(new IdTable(&mGmsts), UniversalId::Type_Gmst); + addModel(new IdTable(&mSkills), UniversalId::Type_Skill); + addModel(new IdTable(&mClasses), UniversalId::Type_Class); + addModel(new IdTree(&mFactions, &mFactions), UniversalId::Type_Faction); + addModel(new IdTree(&mRaces, &mRaces), UniversalId::Type_Race); + addModel(new IdTable(&mSounds), UniversalId::Type_Sound); + addModel(new IdTable(&mScripts), UniversalId::Type_Script); + addModel(new IdTree(&mRegions, &mRegions), UniversalId::Type_Region); + addModel(new IdTree(&mBirthsigns, &mBirthsigns), UniversalId::Type_Birthsign); + addModel(new IdTree(&mSpells, &mSpells), UniversalId::Type_Spell); + addModel(new IdTable(&mTopics), UniversalId::Type_Topic); + addModel(new IdTable(&mJournals), UniversalId::Type_Journal); + addModel(new IdTree(&mTopicInfos, &mTopicInfos, IdTable::Feature_ReorderWithinTopic), UniversalId::Type_TopicInfo); + addModel(new IdTable(&mJournalInfos, IdTable::Feature_ReorderWithinTopic), UniversalId::Type_JournalInfo); + addModel(new IdTree(&mCells, &mCells, IdTable::Feature_ViewId), UniversalId::Type_Cell); + addModel(new IdTree(&mEnchantments, &mEnchantments), UniversalId::Type_Enchantment); + addModel(new IdTable(&mBodyParts), UniversalId::Type_BodyPart); + addModel(new IdTable(&mSoundGens), UniversalId::Type_SoundGen); + addModel(new IdTable(&mMagicEffects), UniversalId::Type_MagicEffect); + addModel(new IdTable(&mLand, IdTable::Feature_AllowTouch), UniversalId::Type_Land); + addModel(new LandTextureIdTable(&mLandTextures), UniversalId::Type_LandTexture); + addModel(new IdTree(&mPathgrids, &mPathgrids), UniversalId::Type_Pathgrid); + addModel(new IdTable(&mStartScripts), UniversalId::Type_StartScript); + addModel(new IdTree(&mReferenceables, &mReferenceables, IdTable::Feature_Preview), UniversalId::Type_Referenceable); + addModel(new IdTable(&mRefs, IdTable::Feature_ViewCell | IdTable::Feature_Preview), UniversalId::Type_Reference); + addModel(new IdTable(&mFilters), UniversalId::Type_Filter); + addModel(new IdTable(&mDebugProfiles), UniversalId::Type_DebugProfile); + addModel(new ResourceTable(&mResourcesManager.get(UniversalId::Type_Meshes)), UniversalId::Type_Mesh); + addModel(new ResourceTable(&mResourcesManager.get(UniversalId::Type_Icons)), UniversalId::Type_Icon); + addModel(new ResourceTable(&mResourcesManager.get(UniversalId::Type_Musics)), UniversalId::Type_Music); + addModel(new ResourceTable(&mResourcesManager.get(UniversalId::Type_SoundsRes)), UniversalId::Type_SoundRes); + addModel(new ResourceTable(&mResourcesManager.get(UniversalId::Type_Textures)), UniversalId::Type_Texture); + addModel(new ResourceTable(&mResourcesManager.get(UniversalId::Type_Videos)), UniversalId::Type_Video); + addModel(new IdTable(&mMetaData), UniversalId::Type_MetaData); mActorAdapter = std::make_unique(*this); @@ -608,7 +601,7 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, bool fsStrict, const Files::Pat CSMWorld::Data::~Data() { - for (std::vector::iterator iter (mModels.begin()); iter!=mModels.end(); ++iter) + for (std::vector::iterator iter(mModels.begin()); iter != mModels.end(); ++iter) delete *iter; delete mReader; @@ -734,7 +727,6 @@ CSMWorld::IdCollection& CSMWorld::Data::getSpells() return mSpells; } - const CSMWorld::IdCollection& CSMWorld::Data::getTopics() const { return mTopics; @@ -905,39 +897,39 @@ CSMWorld::IdCollection& CSMWorld::Data::getStartScripts() return mStartScripts; } -const CSMWorld::Resources& CSMWorld::Data::getResources (const UniversalId& id) const +const CSMWorld::Resources& CSMWorld::Data::getResources(const UniversalId& id) const { - return mResourcesManager.get (id.getType()); + return mResourcesManager.get(id.getType()); } const CSMWorld::MetaData& CSMWorld::Data::getMetaData() const { - return mMetaData.getRecord (0).get(); + return mMetaData.getRecord(0).get(); } -void CSMWorld::Data::setMetaData (const MetaData& metaData) +void CSMWorld::Data::setMetaData(const MetaData& metaData) { - mMetaData.setRecord (0, std::make_unique >( - Record(RecordBase::State_ModifiedOnly, nullptr, &metaData))); + mMetaData.setRecord( + 0, std::make_unique>(Record(RecordBase::State_ModifiedOnly, nullptr, &metaData))); } -QAbstractItemModel *CSMWorld::Data::getTableModel (const CSMWorld::UniversalId& id) +QAbstractItemModel* CSMWorld::Data::getTableModel(const CSMWorld::UniversalId& id) { - std::map::iterator iter = mModelIndex.find (id.getType()); + std::map::iterator iter = mModelIndex.find(id.getType()); - if (iter==mModelIndex.end()) + if (iter == mModelIndex.end()) { // try creating missing (secondary) tables on the fly // // Note: We create these tables here so we don't have to deal with them during load/initial // construction of the ESX data where no update signals are available. - if (id.getType()==UniversalId::Type_RegionMap) + if (id.getType() == UniversalId::Type_RegionMap) { - RegionMap *table = nullptr; - addModel (table = new RegionMap (*this), UniversalId::Type_RegionMap, false); + RegionMap* table = nullptr; + addModel(table = new RegionMap(*this), UniversalId::Type_RegionMap, false); return table; } - throw std::logic_error ("No table model available for " + id.toString()); + throw std::logic_error("No table model available for " + id.toString()); } return iter->second; @@ -958,7 +950,7 @@ void CSMWorld::Data::merge() mGlobals.merge(); } -int CSMWorld::Data::getTotalRecords (const std::vector& files) +int CSMWorld::Data::getTotalRecords(const std::vector& files) { int records = 0; @@ -977,7 +969,7 @@ int CSMWorld::Data::getTotalRecords (const std::vector& f return records; } -int CSMWorld::Data::startLoading (const std::filesystem::path& path, bool base, bool project) +int CSMWorld::Data::startLoading(const std::filesystem::path& path, bool base, bool project) { // Don't delete the Reader yet. Some record types store a reference to the Reader to handle on-demand loading std::shared_ptr ptr(mReader); @@ -987,9 +979,9 @@ int CSMWorld::Data::startLoading (const std::filesystem::path& path, bool base, mDialogue = nullptr; mReader = new ESM::ESMReader; - mReader->setEncoder (&mEncoder); + mReader->setEncoder(&mEncoder); mReader->setIndex((project || !base) ? 0 : mReaderIndex++); - mReader->open (path); + mReader->open(path); mBase = base; mProject = project; @@ -998,10 +990,10 @@ int CSMWorld::Data::startLoading (const std::filesystem::path& path, bool base, { MetaData metaData; metaData.mId = "sys::meta"; - metaData.load (*mReader); + metaData.load(*mReader); - mMetaData.setRecord (0, std::make_unique >( - Record (RecordBase::State_ModifiedOnly, nullptr, &metaData))); + mMetaData.setRecord(0, + std::make_unique>(Record(RecordBase::State_ModifiedOnly, nullptr, &metaData))); } return mReader->getRecordCount(); @@ -1010,21 +1002,15 @@ int CSMWorld::Data::startLoading (const std::filesystem::path& path, bool base, void CSMWorld::Data::loadFallbackEntries() { // Load default marker definitions, if game files do not have them for some reason - std::pair staticMarkers[] = { - std::make_pair("DivineMarker", "marker_divine.nif"), - std::make_pair("DoorMarker", "marker_arrow.nif"), - std::make_pair("NorthMarker", "marker_north.nif"), - std::make_pair("TempleMarker", "marker_temple.nif"), - std::make_pair("TravelMarker", "marker_travel.nif") - }; - - std::pair doorMarkers[] = { - std::make_pair("PrisonMarker", "marker_prison.nif") - }; - - for (const auto &marker : staticMarkers) + std::pair staticMarkers[] = { std::make_pair("DivineMarker", "marker_divine.nif"), + std::make_pair("DoorMarker", "marker_arrow.nif"), std::make_pair("NorthMarker", "marker_north.nif"), + std::make_pair("TempleMarker", "marker_temple.nif"), std::make_pair("TravelMarker", "marker_travel.nif") }; + + std::pair doorMarkers[] = { std::make_pair("PrisonMarker", "marker_prison.nif") }; + + for (const auto& marker : staticMarkers) { - if (mReferenceables.searchId (marker.first)==-1) + if (mReferenceables.searchId(marker.first) == -1) { ESM::Static newMarker; newMarker.mId = marker.first; @@ -1033,13 +1019,13 @@ void CSMWorld::Data::loadFallbackEntries() auto record = std::make_unique>(); record->mBase = newMarker; record->mState = CSMWorld::RecordBase::State_BaseOnly; - mReferenceables.appendRecord (std::move(record), CSMWorld::UniversalId::Type_Static); + mReferenceables.appendRecord(std::move(record), CSMWorld::UniversalId::Type_Static); } } - for (const auto &marker : doorMarkers) + for (const auto& marker : doorMarkers) { - if (mReferenceables.searchId (marker.first)==-1) + if (mReferenceables.searchId(marker.first) == -1) { ESM::Door newMarker; newMarker.mId = marker.first; @@ -1048,23 +1034,23 @@ void CSMWorld::Data::loadFallbackEntries() auto record = std::make_unique>(); record->mBase = newMarker; record->mState = CSMWorld::RecordBase::State_BaseOnly; - mReferenceables.appendRecord (std::move(record), CSMWorld::UniversalId::Type_Door); + mReferenceables.appendRecord(std::move(record), CSMWorld::UniversalId::Type_Door); } } } -bool CSMWorld::Data::continueLoading (CSMDoc::Messages& messages) +bool CSMWorld::Data::continueLoading(CSMDoc::Messages& messages) { if (!mReader) - throw std::logic_error ("can't continue loading, because no load has been started"); + throw std::logic_error("can't continue loading, because no load has been started"); if (!mReader->hasMoreRecs()) { if (mBase) { - // Don't delete the Reader yet. Some record types store a reference to the Reader to handle on-demand loading. - // We don't store non-base reader, because everything going into modified will be - // fully loaded during the initial loading process. + // Don't delete the Reader yet. Some record types store a reference to the Reader to handle on-demand + // loading. We don't store non-base reader, because everything going into modified will be fully loaded + // during the initial loading process. std::shared_ptr ptr(mReader); mReaders.push_back(ptr); } @@ -1087,105 +1073,180 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Messages& messages) switch (n.toInt()) { - case ESM::REC_GLOB: mGlobals.load (*mReader, mBase); break; - case ESM::REC_GMST: mGmsts.load (*mReader, mBase); break; - case ESM::REC_SKIL: mSkills.load (*mReader, mBase); break; - case ESM::REC_CLAS: mClasses.load (*mReader, mBase); break; - case ESM::REC_FACT: mFactions.load (*mReader, mBase); break; - case ESM::REC_RACE: mRaces.load (*mReader, mBase); break; - case ESM::REC_SOUN: mSounds.load (*mReader, mBase); break; - case ESM::REC_SCPT: mScripts.load (*mReader, mBase); break; - case ESM::REC_REGN: mRegions.load (*mReader, mBase); break; - case ESM::REC_BSGN: mBirthsigns.load (*mReader, mBase); break; - case ESM::REC_SPEL: mSpells.load (*mReader, mBase); break; - case ESM::REC_ENCH: mEnchantments.load (*mReader, mBase); break; - case ESM::REC_BODY: mBodyParts.load (*mReader, mBase); break; - case ESM::REC_SNDG: mSoundGens.load (*mReader, mBase); break; - case ESM::REC_MGEF: mMagicEffects.load (*mReader, mBase); break; - case ESM::REC_PGRD: mPathgrids.load (*mReader, mBase); break; - case ESM::REC_SSCR: mStartScripts.load (*mReader, mBase); break; - - case ESM::REC_LTEX: mLandTextures.load (*mReader, mBase); break; - - case ESM::REC_LAND: mLand.load(*mReader, mBase); break; + case ESM::REC_GLOB: + mGlobals.load(*mReader, mBase); + break; + case ESM::REC_GMST: + mGmsts.load(*mReader, mBase); + break; + case ESM::REC_SKIL: + mSkills.load(*mReader, mBase); + break; + case ESM::REC_CLAS: + mClasses.load(*mReader, mBase); + break; + case ESM::REC_FACT: + mFactions.load(*mReader, mBase); + break; + case ESM::REC_RACE: + mRaces.load(*mReader, mBase); + break; + case ESM::REC_SOUN: + mSounds.load(*mReader, mBase); + break; + case ESM::REC_SCPT: + mScripts.load(*mReader, mBase); + break; + case ESM::REC_REGN: + mRegions.load(*mReader, mBase); + break; + case ESM::REC_BSGN: + mBirthsigns.load(*mReader, mBase); + break; + case ESM::REC_SPEL: + mSpells.load(*mReader, mBase); + break; + case ESM::REC_ENCH: + mEnchantments.load(*mReader, mBase); + break; + case ESM::REC_BODY: + mBodyParts.load(*mReader, mBase); + break; + case ESM::REC_SNDG: + mSoundGens.load(*mReader, mBase); + break; + case ESM::REC_MGEF: + mMagicEffects.load(*mReader, mBase); + break; + case ESM::REC_PGRD: + mPathgrids.load(*mReader, mBase); + break; + case ESM::REC_SSCR: + mStartScripts.load(*mReader, mBase); + break; + + case ESM::REC_LTEX: + mLandTextures.load(*mReader, mBase); + break; + + case ESM::REC_LAND: + mLand.load(*mReader, mBase); + break; case ESM::REC_CELL: { - int index = mCells.load (*mReader, mBase); + int index = mCells.load(*mReader, mBase); if (index < 0 || index >= mCells.getSize()) { // log an error and continue loading the refs to the last loaded cell - CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_None); - messages.add (id, "Logic error: cell index out of bounds", "", CSMDoc::Message::Severity_Error); - index = mCells.getSize()-1; + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_None); + messages.add(id, "Logic error: cell index out of bounds", "", CSMDoc::Message::Severity_Error); + index = mCells.getSize() - 1; } - std::string cellId = Misc::StringUtils::lowerCase (mCells.getId (index)); - mRefs.load (*mReader, index, mBase, mRefLoadCache[cellId], messages); + std::string cellId = Misc::StringUtils::lowerCase(mCells.getId(index)); + mRefs.load(*mReader, index, mBase, mRefLoadCache[cellId], messages); break; } - case ESM::REC_ACTI: mReferenceables.load (*mReader, mBase, UniversalId::Type_Activator); break; - case ESM::REC_ALCH: mReferenceables.load (*mReader, mBase, UniversalId::Type_Potion); break; - case ESM::REC_APPA: mReferenceables.load (*mReader, mBase, UniversalId::Type_Apparatus); break; - case ESM::REC_ARMO: mReferenceables.load (*mReader, mBase, UniversalId::Type_Armor); break; - case ESM::REC_BOOK: mReferenceables.load (*mReader, mBase, UniversalId::Type_Book); break; - case ESM::REC_CLOT: mReferenceables.load (*mReader, mBase, UniversalId::Type_Clothing); break; - case ESM::REC_CONT: mReferenceables.load (*mReader, mBase, UniversalId::Type_Container); break; - case ESM::REC_CREA: mReferenceables.load (*mReader, mBase, UniversalId::Type_Creature); break; - case ESM::REC_DOOR: mReferenceables.load (*mReader, mBase, UniversalId::Type_Door); break; - case ESM::REC_INGR: mReferenceables.load (*mReader, mBase, UniversalId::Type_Ingredient); break; + case ESM::REC_ACTI: + mReferenceables.load(*mReader, mBase, UniversalId::Type_Activator); + break; + case ESM::REC_ALCH: + mReferenceables.load(*mReader, mBase, UniversalId::Type_Potion); + break; + case ESM::REC_APPA: + mReferenceables.load(*mReader, mBase, UniversalId::Type_Apparatus); + break; + case ESM::REC_ARMO: + mReferenceables.load(*mReader, mBase, UniversalId::Type_Armor); + break; + case ESM::REC_BOOK: + mReferenceables.load(*mReader, mBase, UniversalId::Type_Book); + break; + case ESM::REC_CLOT: + mReferenceables.load(*mReader, mBase, UniversalId::Type_Clothing); + break; + case ESM::REC_CONT: + mReferenceables.load(*mReader, mBase, UniversalId::Type_Container); + break; + case ESM::REC_CREA: + mReferenceables.load(*mReader, mBase, UniversalId::Type_Creature); + break; + case ESM::REC_DOOR: + mReferenceables.load(*mReader, mBase, UniversalId::Type_Door); + break; + case ESM::REC_INGR: + mReferenceables.load(*mReader, mBase, UniversalId::Type_Ingredient); + break; case ESM::REC_LEVC: - mReferenceables.load (*mReader, mBase, UniversalId::Type_CreatureLevelledList); break; + mReferenceables.load(*mReader, mBase, UniversalId::Type_CreatureLevelledList); + break; case ESM::REC_LEVI: - mReferenceables.load (*mReader, mBase, UniversalId::Type_ItemLevelledList); break; - case ESM::REC_LIGH: mReferenceables.load (*mReader, mBase, UniversalId::Type_Light); break; - case ESM::REC_LOCK: mReferenceables.load (*mReader, mBase, UniversalId::Type_Lockpick); break; + mReferenceables.load(*mReader, mBase, UniversalId::Type_ItemLevelledList); + break; + case ESM::REC_LIGH: + mReferenceables.load(*mReader, mBase, UniversalId::Type_Light); + break; + case ESM::REC_LOCK: + mReferenceables.load(*mReader, mBase, UniversalId::Type_Lockpick); + break; case ESM::REC_MISC: - mReferenceables.load (*mReader, mBase, UniversalId::Type_Miscellaneous); break; - case ESM::REC_NPC_: mReferenceables.load (*mReader, mBase, UniversalId::Type_Npc); break; - case ESM::REC_PROB: mReferenceables.load (*mReader, mBase, UniversalId::Type_Probe); break; - case ESM::REC_REPA: mReferenceables.load (*mReader, mBase, UniversalId::Type_Repair); break; - case ESM::REC_STAT: mReferenceables.load (*mReader, mBase, UniversalId::Type_Static); break; - case ESM::REC_WEAP: mReferenceables.load (*mReader, mBase, UniversalId::Type_Weapon); break; + mReferenceables.load(*mReader, mBase, UniversalId::Type_Miscellaneous); + break; + case ESM::REC_NPC_: + mReferenceables.load(*mReader, mBase, UniversalId::Type_Npc); + break; + case ESM::REC_PROB: + mReferenceables.load(*mReader, mBase, UniversalId::Type_Probe); + break; + case ESM::REC_REPA: + mReferenceables.load(*mReader, mBase, UniversalId::Type_Repair); + break; + case ESM::REC_STAT: + mReferenceables.load(*mReader, mBase, UniversalId::Type_Static); + break; + case ESM::REC_WEAP: + mReferenceables.load(*mReader, mBase, UniversalId::Type_Weapon); + break; case ESM::REC_DIAL: { ESM::Dialogue record; bool isDeleted = false; - record.load (*mReader, isDeleted); + record.load(*mReader, isDeleted); if (isDeleted) { // record vector can be shuffled around which would make pointer to record invalid mDialogue = nullptr; - if (mJournals.tryDelete (record.mId)) + if (mJournals.tryDelete(record.mId)) { mJournalInfos.removeDialogueInfos(record.mId); } - else if (mTopics.tryDelete (record.mId)) + else if (mTopics.tryDelete(record.mId)) { mTopicInfos.removeDialogueInfos(record.mId); } else { - messages.add (UniversalId::Type_None, - "Trying to delete dialogue record " + record.mId + " which does not exist", - "", CSMDoc::Message::Severity_Warning); + messages.add(UniversalId::Type_None, + "Trying to delete dialogue record " + record.mId + " which does not exist", "", + CSMDoc::Message::Severity_Warning); } } else { if (record.mType == ESM::Dialogue::Journal) { - mJournals.load (record, mBase); - mDialogue = &mJournals.getRecord (record.mId).get(); + mJournals.load(record, mBase); + mDialogue = &mJournals.getRecord(record.mId).get(); } else { - mTopics.load (record, mBase); - mDialogue = &mTopics.getRecord (record.mId).get(); + mTopics.load(record, mBase); + mDialogue = &mTopics.getRecord(record.mId).get(); } } @@ -1196,17 +1257,17 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Messages& messages) { if (!mDialogue) { - messages.add (UniversalId::Type_None, - "Found info record not following a dialogue record", "", CSMDoc::Message::Severity_Error); + messages.add(UniversalId::Type_None, "Found info record not following a dialogue record", "", + CSMDoc::Message::Severity_Error); mReader->skipRecord(); break; } - if (mDialogue->mType==ESM::Dialogue::Journal) - mJournalInfos.load (*mReader, mBase, *mDialogue); + if (mDialogue->mType == ESM::Dialogue::Journal) + mJournalInfos.load(*mReader, mBase, *mDialogue); else - mTopicInfos.load (*mReader, mBase, *mDialogue); + mTopicInfos.load(*mReader, mBase, *mDialogue); break; } @@ -1219,7 +1280,7 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Messages& messages) break; } - mFilters.load (*mReader, mBase); + mFilters.load(*mReader, mBase); break; case ESM::REC_DBGP: @@ -1230,7 +1291,7 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Messages& messages) break; } - mDebugProfiles.load (*mReader, mBase); + mDebugProfiles.load(*mReader, mBase); break; default: @@ -1240,8 +1301,8 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Messages& messages) if (unhandledRecord) { - messages.add (UniversalId::Type_None, "Unsupported record type: " + n.toString(), "", - CSMDoc::Message::Severity_Error); + messages.add( + UniversalId::Type_None, "Unsupported record type: " + n.toString(), "", CSMDoc::Message::Severity_Error); mReader->skipRecord(); } @@ -1249,79 +1310,51 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Messages& messages) return false; } -bool CSMWorld::Data::hasId (const std::string& id) const -{ - return - getGlobals().searchId (id)!=-1 || - getGmsts().searchId (id)!=-1 || - getSkills().searchId (id)!=-1 || - getClasses().searchId (id)!=-1 || - getFactions().searchId (id)!=-1 || - getRaces().searchId (id)!=-1 || - getSounds().searchId (id)!=-1 || - getScripts().searchId (id)!=-1 || - getRegions().searchId (id)!=-1 || - getBirthsigns().searchId (id)!=-1 || - getSpells().searchId (id)!=-1 || - getTopics().searchId (id)!=-1 || - getJournals().searchId (id)!=-1 || - getCells().searchId (id)!=-1 || - getEnchantments().searchId (id)!=-1 || - getBodyParts().searchId (id)!=-1 || - getSoundGens().searchId (id)!=-1 || - getMagicEffects().searchId (id)!=-1 || - getReferenceables().searchId (id)!=-1; -} - -int CSMWorld::Data::count (RecordBase::State state) const -{ - return - count (state, mGlobals) + - count (state, mGmsts) + - count (state, mSkills) + - count (state, mClasses) + - count (state, mFactions) + - count (state, mRaces) + - count (state, mSounds) + - count (state, mScripts) + - count (state, mRegions) + - count (state, mBirthsigns) + - count (state, mSpells) + - count (state, mCells) + - count (state, mEnchantments) + - count (state, mBodyParts) + - count (state, mLand) + - count (state, mLandTextures) + - count (state, mSoundGens) + - count (state, mMagicEffects) + - count (state, mReferenceables) + - count (state, mPathgrids); -} - -std::vector CSMWorld::Data::getIds (bool listDeleted) const +bool CSMWorld::Data::hasId(const std::string& id) const +{ + return getGlobals().searchId(id) != -1 || getGmsts().searchId(id) != -1 || getSkills().searchId(id) != -1 + || getClasses().searchId(id) != -1 || getFactions().searchId(id) != -1 || getRaces().searchId(id) != -1 + || getSounds().searchId(id) != -1 || getScripts().searchId(id) != -1 || getRegions().searchId(id) != -1 + || getBirthsigns().searchId(id) != -1 || getSpells().searchId(id) != -1 || getTopics().searchId(id) != -1 + || getJournals().searchId(id) != -1 || getCells().searchId(id) != -1 || getEnchantments().searchId(id) != -1 + || getBodyParts().searchId(id) != -1 || getSoundGens().searchId(id) != -1 + || getMagicEffects().searchId(id) != -1 || getReferenceables().searchId(id) != -1; +} + +int CSMWorld::Data::count(RecordBase::State state) const +{ + return count(state, mGlobals) + count(state, mGmsts) + count(state, mSkills) + count(state, mClasses) + + count(state, mFactions) + count(state, mRaces) + count(state, mSounds) + count(state, mScripts) + + count(state, mRegions) + count(state, mBirthsigns) + count(state, mSpells) + count(state, mCells) + + count(state, mEnchantments) + count(state, mBodyParts) + count(state, mLand) + count(state, mLandTextures) + + count(state, mSoundGens) + count(state, mMagicEffects) + count(state, mReferenceables) + + count(state, mPathgrids); +} + +std::vector CSMWorld::Data::getIds(bool listDeleted) const { std::vector ids; - appendIds (ids, mGlobals, listDeleted); - appendIds (ids, mGmsts, listDeleted); - appendIds (ids, mClasses, listDeleted); - appendIds (ids, mFactions, listDeleted); - appendIds (ids, mRaces, listDeleted); - appendIds (ids, mSounds, listDeleted); - appendIds (ids, mScripts, listDeleted); - appendIds (ids, mRegions, listDeleted); - appendIds (ids, mBirthsigns, listDeleted); - appendIds (ids, mSpells, listDeleted); - appendIds (ids, mTopics, listDeleted); - appendIds (ids, mJournals, listDeleted); - appendIds (ids, mCells, listDeleted); - appendIds (ids, mEnchantments, listDeleted); - appendIds (ids, mBodyParts, listDeleted); - appendIds (ids, mSoundGens, listDeleted); - appendIds (ids, mMagicEffects, listDeleted); - appendIds (ids, mReferenceables, listDeleted); - - std::sort (ids.begin(), ids.end()); + appendIds(ids, mGlobals, listDeleted); + appendIds(ids, mGmsts, listDeleted); + appendIds(ids, mClasses, listDeleted); + appendIds(ids, mFactions, listDeleted); + appendIds(ids, mRaces, listDeleted); + appendIds(ids, mSounds, listDeleted); + appendIds(ids, mScripts, listDeleted); + appendIds(ids, mRegions, listDeleted); + appendIds(ids, mBirthsigns, listDeleted); + appendIds(ids, mSpells, listDeleted); + appendIds(ids, mTopics, listDeleted); + appendIds(ids, mJournals, listDeleted); + appendIds(ids, mCells, listDeleted); + appendIds(ids, mEnchantments, listDeleted); + appendIds(ids, mBodyParts, listDeleted); + appendIds(ids, mSoundGens, listDeleted); + appendIds(ids, mMagicEffects, listDeleted); + appendIds(ids, mReferenceables, listDeleted); + + std::sort(ids.begin(), ids.end()); return ids; } @@ -1331,14 +1364,8 @@ void CSMWorld::Data::assetsChanged() mVFS.get()->reset(); VFS::registerArchives(mVFS.get(), Files::Collections(mDataPaths, !mFsStrict), mArchives, true); - const UniversalId assetTableIds[] = { - UniversalId::Type_Meshes, - UniversalId::Type_Icons, - UniversalId::Type_Musics, - UniversalId::Type_SoundsRes, - UniversalId::Type_Textures, - UniversalId::Type_Videos - }; + const UniversalId assetTableIds[] = { UniversalId::Type_Meshes, UniversalId::Type_Icons, UniversalId::Type_Musics, + UniversalId::Type_SoundsRes, UniversalId::Type_Textures, UniversalId::Type_Videos }; size_t numAssetTables = sizeof(assetTableIds) / sizeof(UniversalId); @@ -1363,13 +1390,13 @@ void CSMWorld::Data::assetsChanged() emit assetTablesChanged(); } -void CSMWorld::Data::dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) +void CSMWorld::Data::dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) { - if (topLeft.column()<=0) + if (topLeft.column() <= 0) emit idListChanged(); } -void CSMWorld::Data::rowsChanged (const QModelIndex& parent, int start, int end) +void CSMWorld::Data::rowsChanged(const QModelIndex& parent, int start, int end) { emit idListChanged(); } diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index 112ac1b239..ce6b4df053 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -4,28 +4,28 @@ #include #include -#include #include +#include -#include -#include -#include +#include +#include +#include +#include #include +#include +#include #include +#include +#include +#include #include -#include -#include #include -#include -#include -#include -#include -#include +#include +#include #include -#include +#include +#include #include -#include -#include #include @@ -33,19 +33,19 @@ #include #include "actoradapter.hpp" -#include "idcollection.hpp" -#include "nestedidcollection.hpp" -#include "universalid.hpp" #include "cell.hpp" +#include "idcollection.hpp" +#include "infocollection.hpp" #include "land.hpp" #include "landtexture.hpp" -#include "refidcollection.hpp" -#include "refcollection.hpp" -#include "infocollection.hpp" +#include "metadata.hpp" +#include "nestedidcollection.hpp" #include "nestedinfocollection.hpp" #include "pathgrid.hpp" +#include "refcollection.hpp" +#include "refidcollection.hpp" #include "resourcesmanager.hpp" -#include "metadata.hpp" +#include "universalid.hpp" #ifndef Q_MOC_RUN #include "subcellcollection.hpp" #endif @@ -75,254 +75,251 @@ namespace CSMWorld class Data : public QObject { - Q_OBJECT - - ToUTF8::Utf8Encoder mEncoder; - IdCollection mGlobals; - IdCollection mGmsts; - IdCollection mSkills; - IdCollection mClasses; - NestedIdCollection mFactions; - NestedIdCollection mRaces; - IdCollection mSounds; - IdCollection mScripts; - NestedIdCollection mRegions; - NestedIdCollection mBirthsigns; - NestedIdCollection mSpells; - IdCollection mTopics; - IdCollection mJournals; - NestedIdCollection mEnchantments; - IdCollection mBodyParts; - IdCollection mMagicEffects; - IdCollection mDebugProfiles; - IdCollection mSoundGens; - IdCollection mStartScripts; - NestedInfoCollection mTopicInfos; - InfoCollection mJournalInfos; - NestedIdCollection mCells; - SubCellCollection mPathgrids; - IdCollection mLandTextures; - IdCollection mLand; - RefIdCollection mReferenceables; - RefCollection mRefs; - IdCollection mFilters; - Collection mMetaData; - std::unique_ptr mActorAdapter; - std::vector mModels; - std::map mModelIndex; - ESM::ESMReader *mReader; - const ESM::Dialogue *mDialogue; // last loaded dialogue - bool mBase; - bool mProject; - std::map > mRefLoadCache; - int mReaderIndex; + Q_OBJECT - bool mFsStrict; - Files::PathContainer mDataPaths; - std::vector mArchives; - std::unique_ptr mVFS; - ResourcesManager mResourcesManager; - std::shared_ptr mResourceSystem; + ToUTF8::Utf8Encoder mEncoder; + IdCollection mGlobals; + IdCollection mGmsts; + IdCollection mSkills; + IdCollection mClasses; + NestedIdCollection mFactions; + NestedIdCollection mRaces; + IdCollection mSounds; + IdCollection mScripts; + NestedIdCollection mRegions; + NestedIdCollection mBirthsigns; + NestedIdCollection mSpells; + IdCollection mTopics; + IdCollection mJournals; + NestedIdCollection mEnchantments; + IdCollection mBodyParts; + IdCollection mMagicEffects; + IdCollection mDebugProfiles; + IdCollection mSoundGens; + IdCollection mStartScripts; + NestedInfoCollection mTopicInfos; + InfoCollection mJournalInfos; + NestedIdCollection mCells; + SubCellCollection mPathgrids; + IdCollection mLandTextures; + IdCollection mLand; + RefIdCollection mReferenceables; + RefCollection mRefs; + IdCollection mFilters; + Collection mMetaData; + std::unique_ptr mActorAdapter; + std::vector mModels; + std::map mModelIndex; + ESM::ESMReader* mReader; + const ESM::Dialogue* mDialogue; // last loaded dialogue + bool mBase; + bool mProject; + std::map> mRefLoadCache; + int mReaderIndex; - std::vector > mReaders; + bool mFsStrict; + Files::PathContainer mDataPaths; + std::vector mArchives; + std::unique_ptr mVFS; + ResourcesManager mResourcesManager; + std::shared_ptr mResourceSystem; - // not implemented - Data (const Data&); - Data& operator= (const Data&); + std::vector> mReaders; - void addModel (QAbstractItemModel *model, UniversalId::Type type, - bool update = true); + // not implemented + Data(const Data&); + Data& operator=(const Data&); - static void appendIds (std::vector& ids, const CollectionBase& collection, - bool listDeleted); - ///< Append all IDs from collection to \a ids. + void addModel(QAbstractItemModel* model, UniversalId::Type type, bool update = true); - static int count (RecordBase::State state, const CollectionBase& collection); + static void appendIds(std::vector& ids, const CollectionBase& collection, bool listDeleted); + ///< Append all IDs from collection to \a ids. - void loadFallbackEntries(); + static int count(RecordBase::State state, const CollectionBase& collection); - public: + void loadFallbackEntries(); - Data (ToUTF8::FromType encoding, bool fsStrict, const Files::PathContainer& dataPaths, - const std::vector& archives, const std::filesystem::path& resDir); + public: + Data(ToUTF8::FromType encoding, bool fsStrict, const Files::PathContainer& dataPaths, + const std::vector& archives, const std::filesystem::path& resDir); - ~Data() override; + ~Data() override; - const VFS::Manager* getVFS() const; + const VFS::Manager* getVFS() const; - std::shared_ptr getResourceSystem(); + std::shared_ptr getResourceSystem(); - std::shared_ptr getResourceSystem() const; + std::shared_ptr getResourceSystem() const; - const IdCollection& getGlobals() const; + const IdCollection& getGlobals() const; - IdCollection& getGlobals(); + IdCollection& getGlobals(); - const IdCollection& getGmsts() const; + const IdCollection& getGmsts() const; - IdCollection& getGmsts(); + IdCollection& getGmsts(); - const IdCollection& getSkills() const; + const IdCollection& getSkills() const; - IdCollection& getSkills(); + IdCollection& getSkills(); - const IdCollection& getClasses() const; + const IdCollection& getClasses() const; - IdCollection& getClasses(); + IdCollection& getClasses(); - const IdCollection& getFactions() const; + const IdCollection& getFactions() const; - IdCollection& getFactions(); + IdCollection& getFactions(); - const IdCollection& getRaces() const; + const IdCollection& getRaces() const; - IdCollection& getRaces(); + IdCollection& getRaces(); - const IdCollection& getSounds() const; + const IdCollection& getSounds() const; - IdCollection& getSounds(); + IdCollection& getSounds(); - const IdCollection& getScripts() const; + const IdCollection& getScripts() const; - IdCollection& getScripts(); + IdCollection& getScripts(); - const IdCollection& getRegions() const; + const IdCollection& getRegions() const; - IdCollection& getRegions(); + IdCollection& getRegions(); - const IdCollection& getBirthsigns() const; + const IdCollection& getBirthsigns() const; - IdCollection& getBirthsigns(); + IdCollection& getBirthsigns(); - const IdCollection& getSpells() const; + const IdCollection& getSpells() const; - IdCollection& getSpells(); + IdCollection& getSpells(); - const IdCollection& getTopics() const; + const IdCollection& getTopics() const; - IdCollection& getTopics(); + IdCollection& getTopics(); - const IdCollection& getJournals() const; + const IdCollection& getJournals() const; - IdCollection& getJournals(); + IdCollection& getJournals(); - const InfoCollection& getTopicInfos() const; + const InfoCollection& getTopicInfos() const; - InfoCollection& getTopicInfos(); + InfoCollection& getTopicInfos(); - const InfoCollection& getJournalInfos() const; + const InfoCollection& getJournalInfos() const; - InfoCollection& getJournalInfos(); + InfoCollection& getJournalInfos(); - const IdCollection& getCells() const; + const IdCollection& getCells() const; - IdCollection& getCells(); + IdCollection& getCells(); - const RefIdCollection& getReferenceables() const; + const RefIdCollection& getReferenceables() const; - RefIdCollection& getReferenceables(); + RefIdCollection& getReferenceables(); - const RefCollection& getReferences() const; + const RefCollection& getReferences() const; - RefCollection& getReferences(); + RefCollection& getReferences(); - const IdCollection& getFilters() const; + const IdCollection& getFilters() const; - IdCollection& getFilters(); + IdCollection& getFilters(); - const IdCollection& getEnchantments() const; + const IdCollection& getEnchantments() const; - IdCollection& getEnchantments(); + IdCollection& getEnchantments(); - const IdCollection& getBodyParts() const; + const IdCollection& getBodyParts() const; - IdCollection& getBodyParts(); + IdCollection& getBodyParts(); - const IdCollection& getDebugProfiles() const; + const IdCollection& getDebugProfiles() const; - IdCollection& getDebugProfiles(); + IdCollection& getDebugProfiles(); - const IdCollection& getLand() const; + const IdCollection& getLand() const; - IdCollection& getLand(); + IdCollection& getLand(); - const IdCollection& getLandTextures() const; + const IdCollection& getLandTextures() const; - IdCollection& getLandTextures(); + IdCollection& getLandTextures(); - const IdCollection& getSoundGens() const; + const IdCollection& getSoundGens() const; - IdCollection& getSoundGens(); + IdCollection& getSoundGens(); - const IdCollection& getMagicEffects() const; + const IdCollection& getMagicEffects() const; - IdCollection& getMagicEffects(); + IdCollection& getMagicEffects(); - const SubCellCollection& getPathgrids() const; + const SubCellCollection& getPathgrids() const; - SubCellCollection& getPathgrids(); + SubCellCollection& getPathgrids(); - const IdCollection& getStartScripts() const; + const IdCollection& getStartScripts() const; - IdCollection& getStartScripts(); + IdCollection& getStartScripts(); - /// Throws an exception, if \a id does not match a resources list. - const Resources& getResources (const UniversalId& id) const; + /// Throws an exception, if \a id does not match a resources list. + const Resources& getResources(const UniversalId& id) const; - const MetaData& getMetaData() const; + const MetaData& getMetaData() const; - void setMetaData (const MetaData& metaData); + void setMetaData(const MetaData& metaData); - QAbstractItemModel *getTableModel (const UniversalId& id); - ///< If no table model is available for \a id, an exception is thrown. - /// - /// \note The returned table may either be the model for the ID itself or the model that - /// contains the record specified by the ID. + QAbstractItemModel* getTableModel(const UniversalId& id); + ///< If no table model is available for \a id, an exception is thrown. + /// + /// \note The returned table may either be the model for the ID itself or the model that + /// contains the record specified by the ID. - const ActorAdapter* getActorAdapter() const; + const ActorAdapter* getActorAdapter() const; - ActorAdapter* getActorAdapter(); + ActorAdapter* getActorAdapter(); - void merge(); - ///< Merge modified into base. + void merge(); + ///< Merge modified into base. - int getTotalRecords (const std::vector& files); // for better loading bar + int getTotalRecords(const std::vector& files); // for better loading bar - int startLoading (const std::filesystem::path& path, bool base, bool project); - ///< Begin merging content of a file into base or modified. - /// - /// \param project load project file instead of content file - /// - ///< \return estimated number of records + int startLoading(const std::filesystem::path& path, bool base, bool project); + ///< Begin merging content of a file into base or modified. + /// + /// \param project load project file instead of content file + /// + ///< \return estimated number of records - bool continueLoading (CSMDoc::Messages& messages); - ///< \return Finished? + bool continueLoading(CSMDoc::Messages& messages); + ///< \return Finished? - bool hasId (const std::string& id) const; + bool hasId(const std::string& id) const; - std::vector getIds (bool listDeleted = true) const; - ///< Return a sorted collection of all IDs that are not internal to the editor. - /// - /// \param listDeleted include deleted record in the list + std::vector getIds(bool listDeleted = true) const; + ///< Return a sorted collection of all IDs that are not internal to the editor. + /// + /// \param listDeleted include deleted record in the list - int count (RecordBase::State state) const; - ///< Return number of top-level records with the given \a state. + int count(RecordBase::State state) const; + ///< Return number of top-level records with the given \a state. - signals: + signals: - void idListChanged(); + void idListChanged(); - void assetTablesChanged(); + void assetTablesChanged(); - public slots: + public slots: - void assetsChanged(); + void assetsChanged(); - private slots: + private slots: - void dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); + void dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); - void rowsChanged (const QModelIndex& parent, int start, int end); + void rowsChanged(const QModelIndex& parent, int start, int end); }; } diff --git a/apps/opencs/model/world/defaultgmsts.cpp b/apps/opencs/model/world/defaultgmsts.cpp index 98ea9ebc1d..2c9a8a66e0 100644 --- a/apps/opencs/model/world/defaultgmsts.cpp +++ b/apps/opencs/model/world/defaultgmsts.cpp @@ -8,8 +8,7 @@ const float FEps = std::numeric_limits::epsilon(); const int IMax = std::numeric_limits::max(); const int IMin = std::numeric_limits::min(); -const char* CSMWorld::DefaultGmsts::Floats[CSMWorld::DefaultGmsts::FloatCount] = -{ +const char* CSMWorld::DefaultGmsts::Floats[CSMWorld::DefaultGmsts::FloatCount] = { "fAIFleeFleeMult", "fAIFleeHealthMult", "fAIMagicSpellMult", @@ -270,8 +269,7 @@ const char* CSMWorld::DefaultGmsts::Floats[CSMWorld::DefaultGmsts::FloatCount] = "fWortChanceValue", }; -const char * CSMWorld::DefaultGmsts::Ints[CSMWorld::DefaultGmsts::IntCount] = -{ +const char* CSMWorld::DefaultGmsts::Ints[CSMWorld::DefaultGmsts::IntCount] = { "i1stPersonSneakDelta", "iAlarmAttack", "iAlarmKilling", @@ -363,8 +361,7 @@ const char * CSMWorld::DefaultGmsts::Ints[CSMWorld::DefaultGmsts::IntCount] = "iWereWolfLevelToAttack", }; -const char * CSMWorld::DefaultGmsts::Strings[CSMWorld::DefaultGmsts::StringCount] = -{ +const char* CSMWorld::DefaultGmsts::Strings[CSMWorld::DefaultGmsts::StringCount] = { "s3dAudio", "s3dHardware", "s3dSoftware", @@ -1541,8 +1538,7 @@ const char * CSMWorld::DefaultGmsts::Strings[CSMWorld::DefaultGmsts::StringCount "sYourGold", }; -const char * CSMWorld::DefaultGmsts::OptionalFloats[CSMWorld::DefaultGmsts::OptionalFloatCount] = -{ +const char* CSMWorld::DefaultGmsts::OptionalFloats[CSMWorld::DefaultGmsts::OptionalFloatCount] = { "fCombatDistanceWerewolfMod", "fFleeDistance", "fWereWolfAcrobatics", @@ -1587,16 +1583,14 @@ const char * CSMWorld::DefaultGmsts::OptionalFloats[CSMWorld::DefaultGmsts::Opti "fWereWolfWillPower", }; -const char * CSMWorld::DefaultGmsts::OptionalInts[CSMWorld::DefaultGmsts::OptionalIntCount] = -{ +const char* CSMWorld::DefaultGmsts::OptionalInts[CSMWorld::DefaultGmsts::OptionalIntCount] = { "iWereWolfBounty", "iWereWolfFightMod", "iWereWolfFleeMod", "iWereWolfLevelToAttack", }; -const char * CSMWorld::DefaultGmsts::OptionalStrings[CSMWorld::DefaultGmsts::OptionalStringCount] = -{ +const char* CSMWorld::DefaultGmsts::OptionalStrings[CSMWorld::DefaultGmsts::OptionalStringCount] = { "sCompanionShare", "sCompanionWarningButtonOne", "sCompanionWarningButtonTwo", @@ -1625,712 +1619,708 @@ const char * CSMWorld::DefaultGmsts::OptionalStrings[CSMWorld::DefaultGmsts::Opt "sWerewolfRestMessage", }; -const float CSMWorld::DefaultGmsts::FloatsDefaultValues[CSMWorld::DefaultGmsts::FloatCount] = -{ - 0.3f, // fAIFleeFleeMult - 7.0f, // fAIFleeHealthMult - 3.0f, // fAIMagicSpellMult - 1.0f, // fAIMeleeArmorMult - 1.0f, // fAIMeleeSummWeaponMult - 2.0f, // fAIMeleeWeaponMult - 5.0f, // fAIRangeMagicSpellMult - 5.0f, // fAIRangeMeleeWeaponMult +const float CSMWorld::DefaultGmsts::FloatsDefaultValues[CSMWorld::DefaultGmsts::FloatCount] = { + 0.3f, // fAIFleeFleeMult + 7.0f, // fAIFleeHealthMult + 3.0f, // fAIMagicSpellMult + 1.0f, // fAIMeleeArmorMult + 1.0f, // fAIMeleeSummWeaponMult + 2.0f, // fAIMeleeWeaponMult + 5.0f, // fAIRangeMagicSpellMult + 5.0f, // fAIRangeMeleeWeaponMult 2000.0f, // fAlarmRadius - 1.0f, // fAthleticsRunBonus - 40.0f, // fAudioDefaultMaxDistance - 5.0f, // fAudioDefaultMinDistance - 50.0f, // fAudioMaxDistanceMult - 20.0f, // fAudioMinDistanceMult - 60.0f, // fAudioVoiceDefaultMaxDistance - 10.0f, // fAudioVoiceDefaultMinDistance - 50.0f, // fAutoPCSpellChance - 80.0f, // fAutoSpellChance - 50.0f, // fBargainOfferBase - -4.0f, // fBargainOfferMulti - 24.0f, // fBarterGoldResetDelay - 1.75f, // fBaseRunMultiplier - 1.25f, // fBlockStillBonus - 150.0f, // fBribe1000Mod - 75.0f, // fBribe100Mod - 35.0f, // fBribe10Mod - 60.0f, // fCombatAngleXY - 60.0f, // fCombatAngleZ - 0.25f, // fCombatArmorMinMult - -90.0f, // fCombatBlockLeftAngle - 30.0f, // fCombatBlockRightAngle - 4.0f, // fCombatCriticalStrikeMult - 0.1f, // fCombatDelayCreature - 0.1f, // fCombatDelayNPC - 128.0f, // fCombatDistance - 0.3f, // fCombatDistanceWerewolfMod - 30.0f, // fCombatForceSideAngle - 0.2f, // fCombatInvisoMult - 1.5f, // fCombatKODamageMult - 45.0f, // fCombatTorsoSideAngle - 0.3f, // fCombatTorsoStartPercent - 0.8f, // fCombatTorsoStopPercent - 15.0f, // fConstantEffectMult - 72.0f, // fCorpseClearDelay - 72.0f, // fCorpseRespawnDelay - 0.5f, // fCrimeGoldDiscountMult - 0.9f, // fCrimeGoldTurnInMult - 1.0f, // fCrimeStealing - 0.5f, // fDamageStrengthBase - 0.1f, // fDamageStrengthMult - 5.0f, // fDifficultyMult - 2.5f, // fDiseaseXferChance - -10.0f, // fDispAttacking - -1.0f, // fDispBargainFailMod - 1.0f, // fDispBargainSuccessMod - 0.0f, // fDispCrimeMod - -10.0f, // fDispDiseaseMod - 3.0f, // fDispFactionMod - 1.0f, // fDispFactionRankBase - 0.5f, // fDispFactionRankMult - 1.0f, // fDispositionMod - 50.0f, // fDispPersonalityBase - 0.5f, // fDispPersonalityMult - -25.0f, // fDispPickPocketMod - 5.0f, // fDispRaceMod - -0.5f, // fDispStealing - -5.0f, // fDispWeaponDrawn - 0.5f, // fEffectCostMult - 0.1f, // fElementalShieldMult - 3.0f, // fEnchantmentChanceMult - 0.5f, // fEnchantmentConstantChanceMult - 100.0f, // fEnchantmentConstantDurationMult - 0.1f, // fEnchantmentMult + 1.0f, // fAthleticsRunBonus + 40.0f, // fAudioDefaultMaxDistance + 5.0f, // fAudioDefaultMinDistance + 50.0f, // fAudioMaxDistanceMult + 20.0f, // fAudioMinDistanceMult + 60.0f, // fAudioVoiceDefaultMaxDistance + 10.0f, // fAudioVoiceDefaultMinDistance + 50.0f, // fAutoPCSpellChance + 80.0f, // fAutoSpellChance + 50.0f, // fBargainOfferBase + -4.0f, // fBargainOfferMulti + 24.0f, // fBarterGoldResetDelay + 1.75f, // fBaseRunMultiplier + 1.25f, // fBlockStillBonus + 150.0f, // fBribe1000Mod + 75.0f, // fBribe100Mod + 35.0f, // fBribe10Mod + 60.0f, // fCombatAngleXY + 60.0f, // fCombatAngleZ + 0.25f, // fCombatArmorMinMult + -90.0f, // fCombatBlockLeftAngle + 30.0f, // fCombatBlockRightAngle + 4.0f, // fCombatCriticalStrikeMult + 0.1f, // fCombatDelayCreature + 0.1f, // fCombatDelayNPC + 128.0f, // fCombatDistance + 0.3f, // fCombatDistanceWerewolfMod + 30.0f, // fCombatForceSideAngle + 0.2f, // fCombatInvisoMult + 1.5f, // fCombatKODamageMult + 45.0f, // fCombatTorsoSideAngle + 0.3f, // fCombatTorsoStartPercent + 0.8f, // fCombatTorsoStopPercent + 15.0f, // fConstantEffectMult + 72.0f, // fCorpseClearDelay + 72.0f, // fCorpseRespawnDelay + 0.5f, // fCrimeGoldDiscountMult + 0.9f, // fCrimeGoldTurnInMult + 1.0f, // fCrimeStealing + 0.5f, // fDamageStrengthBase + 0.1f, // fDamageStrengthMult + 5.0f, // fDifficultyMult + 2.5f, // fDiseaseXferChance + -10.0f, // fDispAttacking + -1.0f, // fDispBargainFailMod + 1.0f, // fDispBargainSuccessMod + 0.0f, // fDispCrimeMod + -10.0f, // fDispDiseaseMod + 3.0f, // fDispFactionMod + 1.0f, // fDispFactionRankBase + 0.5f, // fDispFactionRankMult + 1.0f, // fDispositionMod + 50.0f, // fDispPersonalityBase + 0.5f, // fDispPersonalityMult + -25.0f, // fDispPickPocketMod + 5.0f, // fDispRaceMod + -0.5f, // fDispStealing + -5.0f, // fDispWeaponDrawn + 0.5f, // fEffectCostMult + 0.1f, // fElementalShieldMult + 3.0f, // fEnchantmentChanceMult + 0.5f, // fEnchantmentConstantChanceMult + 100.0f, // fEnchantmentConstantDurationMult + 0.1f, // fEnchantmentMult 1000.0f, // fEnchantmentValueMult - 0.3f, // fEncumberedMoveEffect - 5.0f, // fEncumbranceStrMult - 0.04f, // fEndFatigueMult - 0.25f, // fFallAcroBase - 0.01f, // fFallAcroMult - 400.0f, // fFallDamageDistanceMin - 0.0f, // fFallDistanceBase - 0.07f, // fFallDistanceMult - 2.0f, // fFatigueAttackBase - 0.0f, // fFatigueAttackMult - 1.25f, // fFatigueBase - 4.0f, // fFatigueBlockBase - 0.0f, // fFatigueBlockMult - 5.0f, // fFatigueJumpBase - 0.0f, // fFatigueJumpMult - 0.5f, // fFatigueMult - 2.5f, // fFatigueReturnBase - 0.02f, // fFatigueReturnMult - 5.0f, // fFatigueRunBase - 2.0f, // fFatigueRunMult - 1.5f, // fFatigueSneakBase - 1.5f, // fFatigueSneakMult - 0.0f, // fFatigueSpellBase - 0.0f, // fFatigueSpellCostMult - 0.0f, // fFatigueSpellMult - 7.0f, // fFatigueSwimRunBase - 0.0f, // fFatigueSwimRunMult - 2.5f, // fFatigueSwimWalkBase - 0.0f, // fFatigueSwimWalkMult - 0.2f, // fFightDispMult - 0.005f, // fFightDistanceMultiplier - 50.0f, // fFightStealing + 0.3f, // fEncumberedMoveEffect + 5.0f, // fEncumbranceStrMult + 0.04f, // fEndFatigueMult + 0.25f, // fFallAcroBase + 0.01f, // fFallAcroMult + 400.0f, // fFallDamageDistanceMin + 0.0f, // fFallDistanceBase + 0.07f, // fFallDistanceMult + 2.0f, // fFatigueAttackBase + 0.0f, // fFatigueAttackMult + 1.25f, // fFatigueBase + 4.0f, // fFatigueBlockBase + 0.0f, // fFatigueBlockMult + 5.0f, // fFatigueJumpBase + 0.0f, // fFatigueJumpMult + 0.5f, // fFatigueMult + 2.5f, // fFatigueReturnBase + 0.02f, // fFatigueReturnMult + 5.0f, // fFatigueRunBase + 2.0f, // fFatigueRunMult + 1.5f, // fFatigueSneakBase + 1.5f, // fFatigueSneakMult + 0.0f, // fFatigueSpellBase + 0.0f, // fFatigueSpellCostMult + 0.0f, // fFatigueSpellMult + 7.0f, // fFatigueSwimRunBase + 0.0f, // fFatigueSwimRunMult + 2.5f, // fFatigueSwimWalkBase + 0.0f, // fFatigueSwimWalkMult + 0.2f, // fFightDispMult + 0.005f, // fFightDistanceMultiplier + 50.0f, // fFightStealing 3000.0f, // fFleeDistance - 512.0f, // fGreetDistanceReset - 0.1f, // fHandtoHandHealthPer - 1.0f, // fHandToHandReach - 0.5f, // fHoldBreathEndMult - 20.0f, // fHoldBreathTime - 0.75f, // fIdleChanceMultiplier - 1.0f, // fIngredientMult - 0.5f, // fInteriorHeadTrackMult - 128.0f, // fJumpAcrobaticsBase - 4.0f, // fJumpAcroMultiplier - 0.5f, // fJumpEncumbranceBase - 1.0f, // fJumpEncumbranceMultiplier - 0.5f, // fJumpMoveBase - 0.5f, // fJumpMoveMult - 1.0f, // fJumpRunMultiplier - 0.5f, // fKnockDownMult - 5.0f, // fLevelMod - 0.1f, // fLevelUpHealthEndMult - 0.6f, // fLightMaxMod - 10.0f, // fLuckMod - 10.0f, // fMagesGuildTravel - 1.5f, // fMagicCreatureCastDelay + 512.0f, // fGreetDistanceReset + 0.1f, // fHandtoHandHealthPer + 1.0f, // fHandToHandReach + 0.5f, // fHoldBreathEndMult + 20.0f, // fHoldBreathTime + 0.75f, // fIdleChanceMultiplier + 1.0f, // fIngredientMult + 0.5f, // fInteriorHeadTrackMult + 128.0f, // fJumpAcrobaticsBase + 4.0f, // fJumpAcroMultiplier + 0.5f, // fJumpEncumbranceBase + 1.0f, // fJumpEncumbranceMultiplier + 0.5f, // fJumpMoveBase + 0.5f, // fJumpMoveMult + 1.0f, // fJumpRunMultiplier + 0.5f, // fKnockDownMult + 5.0f, // fLevelMod + 0.1f, // fLevelUpHealthEndMult + 0.6f, // fLightMaxMod + 10.0f, // fLuckMod + 10.0f, // fMagesGuildTravel + 1.5f, // fMagicCreatureCastDelay 0.0167f, // fMagicDetectRefreshRate - 1.0f, // fMagicItemConstantMult - 1.0f, // fMagicItemCostMult - 1.0f, // fMagicItemOnceMult - 1.0f, // fMagicItemPriceMult - 0.05f, // fMagicItemRechargePerSecond - 1.0f, // fMagicItemStrikeMult - 1.0f, // fMagicItemUsedMult - 3.0f, // fMagicStartIconBlink - 0.5f, // fMagicSunBlockedMult - 0.75f, // fMajorSkillBonus - 300.0f, // fMaxFlySpeed - 0.5f, // fMaxHandToHandMult - 400.0f, // fMaxHeadTrackDistance - 200.0f, // fMaxWalkSpeed - 300.0f, // fMaxWalkSpeedCreature - 0.9f, // fMedMaxMod - 0.1f, // fMessageTimePerChar - 5.0f, // fMinFlySpeed - 0.1f, // fMinHandToHandMult - 1.0f, // fMinorSkillBonus - 100.0f, // fMinWalkSpeed - 5.0f, // fMinWalkSpeedCreature - 1.25f, // fMiscSkillBonus - 2.0f, // fNPCbaseMagickaMult - 0.5f, // fNPCHealthBarFade - 3.0f, // fNPCHealthBarTime - 1.0f, // fPCbaseMagickaMult - 0.3f, // fPerDieRollMult - 5.0f, // fPersonalityMod - 1.0f, // fPerTempMult - -1.0f, // fPickLockMult - 0.3f, // fPickPocketMod - 20.0f, // fPotionMinUsefulDuration - 0.5f, // fPotionStrengthMult - 0.5f, // fPotionT1DurMult - 1.5f, // fPotionT1MagMult - 20.0f, // fPotionT4BaseStrengthMult - 12.0f, // fPotionT4EquipStrengthMult + 1.0f, // fMagicItemConstantMult + 1.0f, // fMagicItemCostMult + 1.0f, // fMagicItemOnceMult + 1.0f, // fMagicItemPriceMult + 0.05f, // fMagicItemRechargePerSecond + 1.0f, // fMagicItemStrikeMult + 1.0f, // fMagicItemUsedMult + 3.0f, // fMagicStartIconBlink + 0.5f, // fMagicSunBlockedMult + 0.75f, // fMajorSkillBonus + 300.0f, // fMaxFlySpeed + 0.5f, // fMaxHandToHandMult + 400.0f, // fMaxHeadTrackDistance + 200.0f, // fMaxWalkSpeed + 300.0f, // fMaxWalkSpeedCreature + 0.9f, // fMedMaxMod + 0.1f, // fMessageTimePerChar + 5.0f, // fMinFlySpeed + 0.1f, // fMinHandToHandMult + 1.0f, // fMinorSkillBonus + 100.0f, // fMinWalkSpeed + 5.0f, // fMinWalkSpeedCreature + 1.25f, // fMiscSkillBonus + 2.0f, // fNPCbaseMagickaMult + 0.5f, // fNPCHealthBarFade + 3.0f, // fNPCHealthBarTime + 1.0f, // fPCbaseMagickaMult + 0.3f, // fPerDieRollMult + 5.0f, // fPersonalityMod + 1.0f, // fPerTempMult + -1.0f, // fPickLockMult + 0.3f, // fPickPocketMod + 20.0f, // fPotionMinUsefulDuration + 0.5f, // fPotionStrengthMult + 0.5f, // fPotionT1DurMult + 1.5f, // fPotionT1MagMult + 20.0f, // fPotionT4BaseStrengthMult + 12.0f, // fPotionT4EquipStrengthMult 3000.0f, // fProjectileMaxSpeed - 400.0f, // fProjectileMinSpeed - 25.0f, // fProjectileThrownStoreChance - 3.0f, // fRepairAmountMult - 1.0f, // fRepairMult - 1.0f, // fReputationMod - 0.15f, // fRestMagicMult - 0.0f, // fSeriousWoundMult - 0.25f, // fSleepRandMod - 0.3f, // fSleepRestMod - -1.0f, // fSneakBootMult - 0.5f, // fSneakDistanceBase - 0.002f, // fSneakDistanceMultiplier - 0.5f, // fSneakNoViewMult - 1.0f, // fSneakSkillMult - 0.75f, // fSneakSpeedMultiplier - 1.0f, // fSneakUseDelay - 500.0f, // fSneakUseDist - 1.5f, // fSneakViewMult - 3.0f, // fSoulGemMult - 0.8f, // fSpecialSkillBonus - 7.0f, // fSpellMakingValueMult - 2.0f, // fSpellPriceMult - 10.0f, // fSpellValueMult - 0.25f, // fStromWalkMult - 0.7f, // fStromWindSpeed - 3.0f, // fSuffocationDamage - 0.9f, // fSwimHeightScale - 0.1f, // fSwimRunAthleticsMult - 0.5f, // fSwimRunBase - 0.02f, // fSwimWalkAthleticsMult - 0.5f, // fSwimWalkBase - 1.0f, // fSwingBlockBase - 1.0f, // fSwingBlockMult + 400.0f, // fProjectileMinSpeed + 25.0f, // fProjectileThrownStoreChance + 3.0f, // fRepairAmountMult + 1.0f, // fRepairMult + 1.0f, // fReputationMod + 0.15f, // fRestMagicMult + 0.0f, // fSeriousWoundMult + 0.25f, // fSleepRandMod + 0.3f, // fSleepRestMod + -1.0f, // fSneakBootMult + 0.5f, // fSneakDistanceBase + 0.002f, // fSneakDistanceMultiplier + 0.5f, // fSneakNoViewMult + 1.0f, // fSneakSkillMult + 0.75f, // fSneakSpeedMultiplier + 1.0f, // fSneakUseDelay + 500.0f, // fSneakUseDist + 1.5f, // fSneakViewMult + 3.0f, // fSoulGemMult + 0.8f, // fSpecialSkillBonus + 7.0f, // fSpellMakingValueMult + 2.0f, // fSpellPriceMult + 10.0f, // fSpellValueMult + 0.25f, // fStromWalkMult + 0.7f, // fStromWindSpeed + 3.0f, // fSuffocationDamage + 0.9f, // fSwimHeightScale + 0.1f, // fSwimRunAthleticsMult + 0.5f, // fSwimRunBase + 0.02f, // fSwimWalkAthleticsMult + 0.5f, // fSwimWalkBase + 1.0f, // fSwingBlockBase + 1.0f, // fSwingBlockMult 1000.0f, // fTargetSpellMaxSpeed 1000.0f, // fThrownWeaponMaxSpeed - 300.0f, // fThrownWeaponMinSpeed - 0.0f, // fTrapCostMult + 300.0f, // fThrownWeaponMinSpeed + 0.0f, // fTrapCostMult 4000.0f, // fTravelMult - 16000.0f,// fTravelTimeMult - 0.1f, // fUnarmoredBase1 - 0.065f, // fUnarmoredBase2 - 30.0f, // fVanityDelay - 10.0f, // fVoiceIdleOdds - 0.0f, // fWaterReflectUpdateAlways - 10.0f, // fWaterReflectUpdateSeldom - 0.1f, // fWeaponDamageMult - 1.0f, // fWeaponFatigueBlockMult - 0.25f, // fWeaponFatigueMult - 150.0f, // fWereWolfAcrobatics - 150.0f, // fWereWolfAgility - 1.0f, // fWereWolfAlchemy - 1.0f, // fWereWolfAlteration - 1.0f, // fWereWolfArmorer - 150.0f, // fWereWolfAthletics - 1.0f, // fWereWolfAxe - 1.0f, // fWereWolfBlock - 1.0f, // fWereWolfBluntWeapon - 1.0f, // fWereWolfConjuration - 1.0f, // fWereWolfDestruction - 1.0f, // fWereWolfEnchant - 150.0f, // fWereWolfEndurance - 400.0f, // fWereWolfFatigue - 100.0f, // fWereWolfHandtoHand - 2.0f, // fWereWolfHealth - 1.0f, // fWereWolfHeavyArmor - 1.0f, // fWereWolfIllusion - 1.0f, // fWereWolfIntellegence - 1.0f, // fWereWolfLightArmor - 1.0f, // fWereWolfLongBlade - 1.0f, // fWereWolfLuck - 100.0f, // fWereWolfMagicka - 1.0f, // fWereWolfMarksman - 1.0f, // fWereWolfMediumArmor - 1.0f, // fWereWolfMerchantile - 1.0f, // fWereWolfMysticism - 1.0f, // fWereWolfPersonality - 1.0f, // fWereWolfRestoration - 1.5f, // fWereWolfRunMult - 1.0f, // fWereWolfSecurity - 1.0f, // fWereWolfShortBlade - 1.5f, // fWereWolfSilverWeaponDamageMult - 1.0f, // fWereWolfSneak - 1.0f, // fWereWolfSpear - 1.0f, // fWereWolfSpeechcraft - 150.0f, // fWereWolfSpeed - 150.0f, // fWereWolfStrength - 100.0f, // fWereWolfUnarmored - 1.0f, // fWereWolfWillPower - 15.0f, // fWortChanceValue + 16000.0f, // fTravelTimeMult + 0.1f, // fUnarmoredBase1 + 0.065f, // fUnarmoredBase2 + 30.0f, // fVanityDelay + 10.0f, // fVoiceIdleOdds + 0.0f, // fWaterReflectUpdateAlways + 10.0f, // fWaterReflectUpdateSeldom + 0.1f, // fWeaponDamageMult + 1.0f, // fWeaponFatigueBlockMult + 0.25f, // fWeaponFatigueMult + 150.0f, // fWereWolfAcrobatics + 150.0f, // fWereWolfAgility + 1.0f, // fWereWolfAlchemy + 1.0f, // fWereWolfAlteration + 1.0f, // fWereWolfArmorer + 150.0f, // fWereWolfAthletics + 1.0f, // fWereWolfAxe + 1.0f, // fWereWolfBlock + 1.0f, // fWereWolfBluntWeapon + 1.0f, // fWereWolfConjuration + 1.0f, // fWereWolfDestruction + 1.0f, // fWereWolfEnchant + 150.0f, // fWereWolfEndurance + 400.0f, // fWereWolfFatigue + 100.0f, // fWereWolfHandtoHand + 2.0f, // fWereWolfHealth + 1.0f, // fWereWolfHeavyArmor + 1.0f, // fWereWolfIllusion + 1.0f, // fWereWolfIntellegence + 1.0f, // fWereWolfLightArmor + 1.0f, // fWereWolfLongBlade + 1.0f, // fWereWolfLuck + 100.0f, // fWereWolfMagicka + 1.0f, // fWereWolfMarksman + 1.0f, // fWereWolfMediumArmor + 1.0f, // fWereWolfMerchantile + 1.0f, // fWereWolfMysticism + 1.0f, // fWereWolfPersonality + 1.0f, // fWereWolfRestoration + 1.5f, // fWereWolfRunMult + 1.0f, // fWereWolfSecurity + 1.0f, // fWereWolfShortBlade + 1.5f, // fWereWolfSilverWeaponDamageMult + 1.0f, // fWereWolfSneak + 1.0f, // fWereWolfSpear + 1.0f, // fWereWolfSpeechcraft + 150.0f, // fWereWolfSpeed + 150.0f, // fWereWolfStrength + 100.0f, // fWereWolfUnarmored + 1.0f, // fWereWolfWillPower + 15.0f, // fWortChanceValue }; -const int CSMWorld::DefaultGmsts::IntsDefaultValues[CSMWorld::DefaultGmsts::IntCount] = -{ - 10, // i1stPersonSneakDelta - 50, // iAlarmAttack - 90, // iAlarmKilling - 20, // iAlarmPickPocket - 1, // iAlarmStealing - 5, // iAlarmTresspass - 2, // iAlchemyMod - 100, // iAutoPCSpellMax - 2, // iAutoRepFacMod - 0, // iAutoRepLevMod - 5, // iAutoSpellAlterationMax - 70, // iAutoSpellAttSkillMin - 2, // iAutoSpellConjurationMax - 5, // iAutoSpellDestructionMax - 5, // iAutoSpellIllusionMax - 5, // iAutoSpellMysticismMax - 5, // iAutoSpellRestorationMax - 3, // iAutoSpellTimesCanCast - -1, // iBarterFailDisposition - 1, // iBarterSuccessDisposition - 30, // iBaseArmorSkill - 50, // iBlockMaxChance - 10, // iBlockMinChance - 20, // iBootsWeight - 40, // iCrimeAttack - 1000, // iCrimeKilling - 25, // iCrimePickPocket - 1000, // iCrimeThreshold - 10, // iCrimeThresholdMultiplier - 5, // iCrimeTresspass - 30, // iCuirassWeight - 100, // iDaysinPrisonMod - -50, // iDispAttackMod - -50, // iDispKilling - -20, // iDispTresspass - 1, // iFightAlarmMult - 100, // iFightAttack - 50, // iFightAttacking - 20, // iFightDistanceBase - 50, // iFightKilling - 25, // iFightPickpocket - 25, // iFightTrespass - 0, // iFlee - 5, // iGauntletWeight - 15, // iGreavesWeight - 6, // iGreetDistanceMultiplier - 4, // iGreetDuration - 5, // iHelmWeight - 50, // iKnockDownOddsBase - 50, // iKnockDownOddsMult - 2, // iLevelUp01Mult - 2, // iLevelUp02Mult - 2, // iLevelUp03Mult - 2, // iLevelUp04Mult - 3, // iLevelUp05Mult - 3, // iLevelUp06Mult - 3, // iLevelUp07Mult - 4, // iLevelUp08Mult - 4, // iLevelUp09Mult - 5, // iLevelUp10Mult - 1, // iLevelupMajorMult - 1, // iLevelupMajorMultAttribute - 1, // iLevelupMinorMult - 1, // iLevelupMinorMultAttribute - 1, // iLevelupMiscMultAttriubte - 1, // iLevelupSpecialization - 10, // iLevelupTotal - 10, // iMagicItemChargeConst - 1, // iMagicItemChargeOnce - 10, // iMagicItemChargeStrike - 5, // iMagicItemChargeUse - 192, // iMaxActivateDist - 192, // iMaxInfoDist - 4, // iMonthsToRespawn - 1, // iNumberCreatures - 10, // iPauldronWeight - 5, // iPerMinChance - 10, // iPerMinChange - 75, // iPickMaxChance - 5, // iPickMinChance - 15, // iShieldWeight - 400, // iSoulAmountForConstantEffect - 10, // iTrainingMod - 10, // iVoiceAttackOdds - 30, // iVoiceHitOdds - 10000, // iWereWolfBounty - 100, // iWereWolfFightMod - 100, // iWereWolfFleeMod - 20, // iWereWolfLevelToAttack +const int CSMWorld::DefaultGmsts::IntsDefaultValues[CSMWorld::DefaultGmsts::IntCount] = { + 10, // i1stPersonSneakDelta + 50, // iAlarmAttack + 90, // iAlarmKilling + 20, // iAlarmPickPocket + 1, // iAlarmStealing + 5, // iAlarmTresspass + 2, // iAlchemyMod + 100, // iAutoPCSpellMax + 2, // iAutoRepFacMod + 0, // iAutoRepLevMod + 5, // iAutoSpellAlterationMax + 70, // iAutoSpellAttSkillMin + 2, // iAutoSpellConjurationMax + 5, // iAutoSpellDestructionMax + 5, // iAutoSpellIllusionMax + 5, // iAutoSpellMysticismMax + 5, // iAutoSpellRestorationMax + 3, // iAutoSpellTimesCanCast + -1, // iBarterFailDisposition + 1, // iBarterSuccessDisposition + 30, // iBaseArmorSkill + 50, // iBlockMaxChance + 10, // iBlockMinChance + 20, // iBootsWeight + 40, // iCrimeAttack + 1000, // iCrimeKilling + 25, // iCrimePickPocket + 1000, // iCrimeThreshold + 10, // iCrimeThresholdMultiplier + 5, // iCrimeTresspass + 30, // iCuirassWeight + 100, // iDaysinPrisonMod + -50, // iDispAttackMod + -50, // iDispKilling + -20, // iDispTresspass + 1, // iFightAlarmMult + 100, // iFightAttack + 50, // iFightAttacking + 20, // iFightDistanceBase + 50, // iFightKilling + 25, // iFightPickpocket + 25, // iFightTrespass + 0, // iFlee + 5, // iGauntletWeight + 15, // iGreavesWeight + 6, // iGreetDistanceMultiplier + 4, // iGreetDuration + 5, // iHelmWeight + 50, // iKnockDownOddsBase + 50, // iKnockDownOddsMult + 2, // iLevelUp01Mult + 2, // iLevelUp02Mult + 2, // iLevelUp03Mult + 2, // iLevelUp04Mult + 3, // iLevelUp05Mult + 3, // iLevelUp06Mult + 3, // iLevelUp07Mult + 4, // iLevelUp08Mult + 4, // iLevelUp09Mult + 5, // iLevelUp10Mult + 1, // iLevelupMajorMult + 1, // iLevelupMajorMultAttribute + 1, // iLevelupMinorMult + 1, // iLevelupMinorMultAttribute + 1, // iLevelupMiscMultAttriubte + 1, // iLevelupSpecialization + 10, // iLevelupTotal + 10, // iMagicItemChargeConst + 1, // iMagicItemChargeOnce + 10, // iMagicItemChargeStrike + 5, // iMagicItemChargeUse + 192, // iMaxActivateDist + 192, // iMaxInfoDist + 4, // iMonthsToRespawn + 1, // iNumberCreatures + 10, // iPauldronWeight + 5, // iPerMinChance + 10, // iPerMinChange + 75, // iPickMaxChance + 5, // iPickMinChance + 15, // iShieldWeight + 400, // iSoulAmountForConstantEffect + 10, // iTrainingMod + 10, // iVoiceAttackOdds + 30, // iVoiceHitOdds + 10000, // iWereWolfBounty + 100, // iWereWolfFightMod + 100, // iWereWolfFleeMod + 20, // iWereWolfLevelToAttack }; -const float CSMWorld::DefaultGmsts::FloatLimits[CSMWorld::DefaultGmsts::FloatCount * 2] = -{ - -FInf, FInf, // fAIFleeFleeMult - -FInf, FInf, // fAIFleeHealthMult - -FInf, FInf, // fAIMagicSpellMult - -FInf, FInf, // fAIMeleeArmorMult - -FInf, FInf, // fAIMeleeSummWeaponMult - -FInf, FInf, // fAIMeleeWeaponMult - -FInf, FInf, // fAIRangeMagicSpellMult - -FInf, FInf, // fAIRangeMeleeWeaponMult - 0, FInf, // fAlarmRadius - -FInf, FInf, // fAthleticsRunBonus - 0, FInf, // fAudioDefaultMaxDistance - 0, FInf, // fAudioDefaultMinDistance - 0, FInf, // fAudioMaxDistanceMult - 0, FInf, // fAudioMinDistanceMult - 0, FInf, // fAudioVoiceDefaultMaxDistance - 0, FInf, // fAudioVoiceDefaultMinDistance - 0, FInf, // fAutoPCSpellChance - 0, FInf, // fAutoSpellChance - -FInf, FInf, // fBargainOfferBase - -FInf, 0, // fBargainOfferMulti - -FInf, FInf, // fBarterGoldResetDelay - 0, FInf, // fBaseRunMultiplier - -FInf, FInf, // fBlockStillBonus - 0, FInf, // fBribe1000Mod - 0, FInf, // fBribe100Mod - 0, FInf, // fBribe10Mod - 0, FInf, // fCombatAngleXY - 0, FInf, // fCombatAngleZ - 0, 1, // fCombatArmorMinMult - -180, 0, // fCombatBlockLeftAngle - 0, 180, // fCombatBlockRightAngle - 0, FInf, // fCombatCriticalStrikeMult - 0, FInf, // fCombatDelayCreature - 0, FInf, // fCombatDelayNPC - 0, FInf, // fCombatDistance - -FInf, FInf, // fCombatDistanceWerewolfMod - -FInf, FInf, // fCombatForceSideAngle - 0, FInf, // fCombatInvisoMult - 0, FInf, // fCombatKODamageMult - -FInf, FInf, // fCombatTorsoSideAngle - -FInf, FInf, // fCombatTorsoStartPercent - -FInf, FInf, // fCombatTorsoStopPercent - -FInf, FInf, // fConstantEffectMult - -FInf, FInf, // fCorpseClearDelay - -FInf, FInf, // fCorpseRespawnDelay - 0, 1, // fCrimeGoldDiscountMult - 0, FInf, // fCrimeGoldTurnInMult - 0, FInf, // fCrimeStealing - 0, FInf, // fDamageStrengthBase - 0, FInf, // fDamageStrengthMult - -FInf, FInf, // fDifficultyMult - 0, FInf, // fDiseaseXferChance - -FInf, 0, // fDispAttacking - -FInf, FInf, // fDispBargainFailMod - -FInf, FInf, // fDispBargainSuccessMod - -FInf, 0, // fDispCrimeMod - -FInf, 0, // fDispDiseaseMod - 0, FInf, // fDispFactionMod - 0, FInf, // fDispFactionRankBase - 0, FInf, // fDispFactionRankMult - 0, FInf, // fDispositionMod - 0, FInf, // fDispPersonalityBase - 0, FInf, // fDispPersonalityMult - -FInf, 0, // fDispPickPocketMod - 0, FInf, // fDispRaceMod - -FInf, 0, // fDispStealing - -FInf, 0, // fDispWeaponDrawn - 0, FInf, // fEffectCostMult - 0, FInf, // fElementalShieldMult - FEps, FInf, // fEnchantmentChanceMult - 0, FInf, // fEnchantmentConstantChanceMult - 0, FInf, // fEnchantmentConstantDurationMult - 0, FInf, // fEnchantmentMult - 0, FInf, // fEnchantmentValueMult - 0, FInf, // fEncumberedMoveEffect - 0, FInf, // fEncumbranceStrMult - 0, FInf, // fEndFatigueMult - -FInf, FInf, // fFallAcroBase - 0, FInf, // fFallAcroMult - 0, FInf, // fFallDamageDistanceMin - -FInf, FInf, // fFallDistanceBase - 0, FInf, // fFallDistanceMult - -FInf, FInf, // fFatigueAttackBase - 0, FInf, // fFatigueAttackMult - 0, FInf, // fFatigueBase - 0, FInf, // fFatigueBlockBase - 0, FInf, // fFatigueBlockMult - 0, FInf, // fFatigueJumpBase - 0, FInf, // fFatigueJumpMult - 0, FInf, // fFatigueMult - -FInf, FInf, // fFatigueReturnBase - 0, FInf, // fFatigueReturnMult - -FInf, FInf, // fFatigueRunBase - 0, FInf, // fFatigueRunMult - -FInf, FInf, // fFatigueSneakBase - 0, FInf, // fFatigueSneakMult - -FInf, FInf, // fFatigueSpellBase - -FInf, FInf, // fFatigueSpellCostMult - 0, FInf, // fFatigueSpellMult - -FInf, FInf, // fFatigueSwimRunBase - 0, FInf, // fFatigueSwimRunMult - -FInf, FInf, // fFatigueSwimWalkBase - 0, FInf, // fFatigueSwimWalkMult - -FInf, FInf, // fFightDispMult - -FInf, FInf, // fFightDistanceMultiplier - -FInf, FInf, // fFightStealing - -FInf, FInf, // fFleeDistance - -FInf, FInf, // fGreetDistanceReset - 0, FInf, // fHandtoHandHealthPer - 0, FInf, // fHandToHandReach - -FInf, FInf, // fHoldBreathEndMult - 0, FInf, // fHoldBreathTime - 0, FInf, // fIdleChanceMultiplier - -FInf, FInf, // fIngredientMult - 0, FInf, // fInteriorHeadTrackMult - -FInf, FInf, // fJumpAcrobaticsBase - 0, FInf, // fJumpAcroMultiplier - -FInf, FInf, // fJumpEncumbranceBase - 0, FInf, // fJumpEncumbranceMultiplier - -FInf, FInf, // fJumpMoveBase - 0, FInf, // fJumpMoveMult - 0, FInf, // fJumpRunMultiplier - -FInf, FInf, // fKnockDownMult - 0, FInf, // fLevelMod - 0, FInf, // fLevelUpHealthEndMult - 0, FInf, // fLightMaxMod - 0, FInf, // fLuckMod - 0, FInf, // fMagesGuildTravel - -FInf, FInf, // fMagicCreatureCastDelay - -FInf, FInf, // fMagicDetectRefreshRate - -FInf, FInf, // fMagicItemConstantMult - -FInf, FInf, // fMagicItemCostMult - -FInf, FInf, // fMagicItemOnceMult - -FInf, FInf, // fMagicItemPriceMult - 0, FInf, // fMagicItemRechargePerSecond - -FInf, FInf, // fMagicItemStrikeMult - -FInf, FInf, // fMagicItemUsedMult - 0, FInf, // fMagicStartIconBlink - 0, FInf, // fMagicSunBlockedMult - FEps, FInf, // fMajorSkillBonus - 0, FInf, // fMaxFlySpeed - 0, FInf, // fMaxHandToHandMult - 0, FInf, // fMaxHeadTrackDistance - 0, FInf, // fMaxWalkSpeed - 0, FInf, // fMaxWalkSpeedCreature - 0, FInf, // fMedMaxMod - 0, FInf, // fMessageTimePerChar - 0, FInf, // fMinFlySpeed - 0, FInf, // fMinHandToHandMult - FEps, FInf, // fMinorSkillBonus - 0, FInf, // fMinWalkSpeed - 0, FInf, // fMinWalkSpeedCreature - FEps, FInf, // fMiscSkillBonus - 0, FInf, // fNPCbaseMagickaMult - 0, FInf, // fNPCHealthBarFade - 0, FInf, // fNPCHealthBarTime - 0, FInf, // fPCbaseMagickaMult - 0, FInf, // fPerDieRollMult - 0, FInf, // fPersonalityMod - 0, FInf, // fPerTempMult - -FInf, 0, // fPickLockMult - 0, FInf, // fPickPocketMod - -FInf, FInf, // fPotionMinUsefulDuration - 0, FInf, // fPotionStrengthMult - FEps, FInf, // fPotionT1DurMult - FEps, FInf, // fPotionT1MagMult - -FInf, FInf, // fPotionT4BaseStrengthMult - -FInf, FInf, // fPotionT4EquipStrengthMult - 0, FInf, // fProjectileMaxSpeed - 0, FInf, // fProjectileMinSpeed - 0, FInf, // fProjectileThrownStoreChance - 0, FInf, // fRepairAmountMult - 0, FInf, // fRepairMult - 0, FInf, // fReputationMod - 0, FInf, // fRestMagicMult - -FInf, FInf, // fSeriousWoundMult - 0, FInf, // fSleepRandMod - 0, FInf, // fSleepRestMod - -FInf, 0, // fSneakBootMult - -FInf, FInf, // fSneakDistanceBase - 0, FInf, // fSneakDistanceMultiplier - 0, FInf, // fSneakNoViewMult - 0, FInf, // fSneakSkillMult - 0, FInf, // fSneakSpeedMultiplier - 0, FInf, // fSneakUseDelay - 0, FInf, // fSneakUseDist - 0, FInf, // fSneakViewMult - 0, FInf, // fSoulGemMult - 0, FInf, // fSpecialSkillBonus - 0, FInf, // fSpellMakingValueMult - -FInf, FInf, // fSpellPriceMult - 0, FInf, // fSpellValueMult - 0, FInf, // fStromWalkMult - 0, FInf, // fStromWindSpeed - 0, FInf, // fSuffocationDamage - 0, FInf, // fSwimHeightScale - 0, FInf, // fSwimRunAthleticsMult - 0, FInf, // fSwimRunBase - -FInf, FInf, // fSwimWalkAthleticsMult - -FInf, FInf, // fSwimWalkBase - 0, FInf, // fSwingBlockBase - 0, FInf, // fSwingBlockMult - 0, FInf, // fTargetSpellMaxSpeed - 0, FInf, // fThrownWeaponMaxSpeed - 0, FInf, // fThrownWeaponMinSpeed - 0, FInf, // fTrapCostMult - 0, FInf, // fTravelMult - 0, FInf, // fTravelTimeMult - 0, FInf, // fUnarmoredBase1 - 0, FInf, // fUnarmoredBase2 - 0, FInf, // fVanityDelay - 0, FInf, // fVoiceIdleOdds - -FInf, FInf, // fWaterReflectUpdateAlways - -FInf, FInf, // fWaterReflectUpdateSeldom - 0, FInf, // fWeaponDamageMult - 0, FInf, // fWeaponFatigueBlockMult - 0, FInf, // fWeaponFatigueMult - 0, FInf, // fWereWolfAcrobatics - -FInf, FInf, // fWereWolfAgility - -FInf, FInf, // fWereWolfAlchemy - -FInf, FInf, // fWereWolfAlteration - -FInf, FInf, // fWereWolfArmorer - -FInf, FInf, // fWereWolfAthletics - -FInf, FInf, // fWereWolfAxe - -FInf, FInf, // fWereWolfBlock - -FInf, FInf, // fWereWolfBluntWeapon - -FInf, FInf, // fWereWolfConjuration - -FInf, FInf, // fWereWolfDestruction - -FInf, FInf, // fWereWolfEnchant - -FInf, FInf, // fWereWolfEndurance - -FInf, FInf, // fWereWolfFatigue - -FInf, FInf, // fWereWolfHandtoHand - -FInf, FInf, // fWereWolfHealth - -FInf, FInf, // fWereWolfHeavyArmor - -FInf, FInf, // fWereWolfIllusion - -FInf, FInf, // fWereWolfIntellegence - -FInf, FInf, // fWereWolfLightArmor - -FInf, FInf, // fWereWolfLongBlade - -FInf, FInf, // fWereWolfLuck - -FInf, FInf, // fWereWolfMagicka - -FInf, FInf, // fWereWolfMarksman - -FInf, FInf, // fWereWolfMediumArmor - -FInf, FInf, // fWereWolfMerchantile - -FInf, FInf, // fWereWolfMysticism - -FInf, FInf, // fWereWolfPersonality - -FInf, FInf, // fWereWolfRestoration - 0, FInf, // fWereWolfRunMult - -FInf, FInf, // fWereWolfSecurity - -FInf, FInf, // fWereWolfShortBlade - -FInf, FInf, // fWereWolfSilverWeaponDamageMult - -FInf, FInf, // fWereWolfSneak - -FInf, FInf, // fWereWolfSpear - -FInf, FInf, // fWereWolfSpeechcraft - -FInf, FInf, // fWereWolfSpeed - -FInf, FInf, // fWereWolfStrength - -FInf, FInf, // fWereWolfUnarmored - -FInf, FInf, // fWereWolfWillPower - 0, FInf, // fWortChanceValue +const float CSMWorld::DefaultGmsts::FloatLimits[CSMWorld::DefaultGmsts::FloatCount * 2] = { + -FInf, FInf, // fAIFleeFleeMult + -FInf, FInf, // fAIFleeHealthMult + -FInf, FInf, // fAIMagicSpellMult + -FInf, FInf, // fAIMeleeArmorMult + -FInf, FInf, // fAIMeleeSummWeaponMult + -FInf, FInf, // fAIMeleeWeaponMult + -FInf, FInf, // fAIRangeMagicSpellMult + -FInf, FInf, // fAIRangeMeleeWeaponMult + 0, FInf, // fAlarmRadius + -FInf, FInf, // fAthleticsRunBonus + 0, FInf, // fAudioDefaultMaxDistance + 0, FInf, // fAudioDefaultMinDistance + 0, FInf, // fAudioMaxDistanceMult + 0, FInf, // fAudioMinDistanceMult + 0, FInf, // fAudioVoiceDefaultMaxDistance + 0, FInf, // fAudioVoiceDefaultMinDistance + 0, FInf, // fAutoPCSpellChance + 0, FInf, // fAutoSpellChance + -FInf, FInf, // fBargainOfferBase + -FInf, 0, // fBargainOfferMulti + -FInf, FInf, // fBarterGoldResetDelay + 0, FInf, // fBaseRunMultiplier + -FInf, FInf, // fBlockStillBonus + 0, FInf, // fBribe1000Mod + 0, FInf, // fBribe100Mod + 0, FInf, // fBribe10Mod + 0, FInf, // fCombatAngleXY + 0, FInf, // fCombatAngleZ + 0, 1, // fCombatArmorMinMult + -180, 0, // fCombatBlockLeftAngle + 0, 180, // fCombatBlockRightAngle + 0, FInf, // fCombatCriticalStrikeMult + 0, FInf, // fCombatDelayCreature + 0, FInf, // fCombatDelayNPC + 0, FInf, // fCombatDistance + -FInf, FInf, // fCombatDistanceWerewolfMod + -FInf, FInf, // fCombatForceSideAngle + 0, FInf, // fCombatInvisoMult + 0, FInf, // fCombatKODamageMult + -FInf, FInf, // fCombatTorsoSideAngle + -FInf, FInf, // fCombatTorsoStartPercent + -FInf, FInf, // fCombatTorsoStopPercent + -FInf, FInf, // fConstantEffectMult + -FInf, FInf, // fCorpseClearDelay + -FInf, FInf, // fCorpseRespawnDelay + 0, 1, // fCrimeGoldDiscountMult + 0, FInf, // fCrimeGoldTurnInMult + 0, FInf, // fCrimeStealing + 0, FInf, // fDamageStrengthBase + 0, FInf, // fDamageStrengthMult + -FInf, FInf, // fDifficultyMult + 0, FInf, // fDiseaseXferChance + -FInf, 0, // fDispAttacking + -FInf, FInf, // fDispBargainFailMod + -FInf, FInf, // fDispBargainSuccessMod + -FInf, 0, // fDispCrimeMod + -FInf, 0, // fDispDiseaseMod + 0, FInf, // fDispFactionMod + 0, FInf, // fDispFactionRankBase + 0, FInf, // fDispFactionRankMult + 0, FInf, // fDispositionMod + 0, FInf, // fDispPersonalityBase + 0, FInf, // fDispPersonalityMult + -FInf, 0, // fDispPickPocketMod + 0, FInf, // fDispRaceMod + -FInf, 0, // fDispStealing + -FInf, 0, // fDispWeaponDrawn + 0, FInf, // fEffectCostMult + 0, FInf, // fElementalShieldMult + FEps, FInf, // fEnchantmentChanceMult + 0, FInf, // fEnchantmentConstantChanceMult + 0, FInf, // fEnchantmentConstantDurationMult + 0, FInf, // fEnchantmentMult + 0, FInf, // fEnchantmentValueMult + 0, FInf, // fEncumberedMoveEffect + 0, FInf, // fEncumbranceStrMult + 0, FInf, // fEndFatigueMult + -FInf, FInf, // fFallAcroBase + 0, FInf, // fFallAcroMult + 0, FInf, // fFallDamageDistanceMin + -FInf, FInf, // fFallDistanceBase + 0, FInf, // fFallDistanceMult + -FInf, FInf, // fFatigueAttackBase + 0, FInf, // fFatigueAttackMult + 0, FInf, // fFatigueBase + 0, FInf, // fFatigueBlockBase + 0, FInf, // fFatigueBlockMult + 0, FInf, // fFatigueJumpBase + 0, FInf, // fFatigueJumpMult + 0, FInf, // fFatigueMult + -FInf, FInf, // fFatigueReturnBase + 0, FInf, // fFatigueReturnMult + -FInf, FInf, // fFatigueRunBase + 0, FInf, // fFatigueRunMult + -FInf, FInf, // fFatigueSneakBase + 0, FInf, // fFatigueSneakMult + -FInf, FInf, // fFatigueSpellBase + -FInf, FInf, // fFatigueSpellCostMult + 0, FInf, // fFatigueSpellMult + -FInf, FInf, // fFatigueSwimRunBase + 0, FInf, // fFatigueSwimRunMult + -FInf, FInf, // fFatigueSwimWalkBase + 0, FInf, // fFatigueSwimWalkMult + -FInf, FInf, // fFightDispMult + -FInf, FInf, // fFightDistanceMultiplier + -FInf, FInf, // fFightStealing + -FInf, FInf, // fFleeDistance + -FInf, FInf, // fGreetDistanceReset + 0, FInf, // fHandtoHandHealthPer + 0, FInf, // fHandToHandReach + -FInf, FInf, // fHoldBreathEndMult + 0, FInf, // fHoldBreathTime + 0, FInf, // fIdleChanceMultiplier + -FInf, FInf, // fIngredientMult + 0, FInf, // fInteriorHeadTrackMult + -FInf, FInf, // fJumpAcrobaticsBase + 0, FInf, // fJumpAcroMultiplier + -FInf, FInf, // fJumpEncumbranceBase + 0, FInf, // fJumpEncumbranceMultiplier + -FInf, FInf, // fJumpMoveBase + 0, FInf, // fJumpMoveMult + 0, FInf, // fJumpRunMultiplier + -FInf, FInf, // fKnockDownMult + 0, FInf, // fLevelMod + 0, FInf, // fLevelUpHealthEndMult + 0, FInf, // fLightMaxMod + 0, FInf, // fLuckMod + 0, FInf, // fMagesGuildTravel + -FInf, FInf, // fMagicCreatureCastDelay + -FInf, FInf, // fMagicDetectRefreshRate + -FInf, FInf, // fMagicItemConstantMult + -FInf, FInf, // fMagicItemCostMult + -FInf, FInf, // fMagicItemOnceMult + -FInf, FInf, // fMagicItemPriceMult + 0, FInf, // fMagicItemRechargePerSecond + -FInf, FInf, // fMagicItemStrikeMult + -FInf, FInf, // fMagicItemUsedMult + 0, FInf, // fMagicStartIconBlink + 0, FInf, // fMagicSunBlockedMult + FEps, FInf, // fMajorSkillBonus + 0, FInf, // fMaxFlySpeed + 0, FInf, // fMaxHandToHandMult + 0, FInf, // fMaxHeadTrackDistance + 0, FInf, // fMaxWalkSpeed + 0, FInf, // fMaxWalkSpeedCreature + 0, FInf, // fMedMaxMod + 0, FInf, // fMessageTimePerChar + 0, FInf, // fMinFlySpeed + 0, FInf, // fMinHandToHandMult + FEps, FInf, // fMinorSkillBonus + 0, FInf, // fMinWalkSpeed + 0, FInf, // fMinWalkSpeedCreature + FEps, FInf, // fMiscSkillBonus + 0, FInf, // fNPCbaseMagickaMult + 0, FInf, // fNPCHealthBarFade + 0, FInf, // fNPCHealthBarTime + 0, FInf, // fPCbaseMagickaMult + 0, FInf, // fPerDieRollMult + 0, FInf, // fPersonalityMod + 0, FInf, // fPerTempMult + -FInf, 0, // fPickLockMult + 0, FInf, // fPickPocketMod + -FInf, FInf, // fPotionMinUsefulDuration + 0, FInf, // fPotionStrengthMult + FEps, FInf, // fPotionT1DurMult + FEps, FInf, // fPotionT1MagMult + -FInf, FInf, // fPotionT4BaseStrengthMult + -FInf, FInf, // fPotionT4EquipStrengthMult + 0, FInf, // fProjectileMaxSpeed + 0, FInf, // fProjectileMinSpeed + 0, FInf, // fProjectileThrownStoreChance + 0, FInf, // fRepairAmountMult + 0, FInf, // fRepairMult + 0, FInf, // fReputationMod + 0, FInf, // fRestMagicMult + -FInf, FInf, // fSeriousWoundMult + 0, FInf, // fSleepRandMod + 0, FInf, // fSleepRestMod + -FInf, 0, // fSneakBootMult + -FInf, FInf, // fSneakDistanceBase + 0, FInf, // fSneakDistanceMultiplier + 0, FInf, // fSneakNoViewMult + 0, FInf, // fSneakSkillMult + 0, FInf, // fSneakSpeedMultiplier + 0, FInf, // fSneakUseDelay + 0, FInf, // fSneakUseDist + 0, FInf, // fSneakViewMult + 0, FInf, // fSoulGemMult + 0, FInf, // fSpecialSkillBonus + 0, FInf, // fSpellMakingValueMult + -FInf, FInf, // fSpellPriceMult + 0, FInf, // fSpellValueMult + 0, FInf, // fStromWalkMult + 0, FInf, // fStromWindSpeed + 0, FInf, // fSuffocationDamage + 0, FInf, // fSwimHeightScale + 0, FInf, // fSwimRunAthleticsMult + 0, FInf, // fSwimRunBase + -FInf, FInf, // fSwimWalkAthleticsMult + -FInf, FInf, // fSwimWalkBase + 0, FInf, // fSwingBlockBase + 0, FInf, // fSwingBlockMult + 0, FInf, // fTargetSpellMaxSpeed + 0, FInf, // fThrownWeaponMaxSpeed + 0, FInf, // fThrownWeaponMinSpeed + 0, FInf, // fTrapCostMult + 0, FInf, // fTravelMult + 0, FInf, // fTravelTimeMult + 0, FInf, // fUnarmoredBase1 + 0, FInf, // fUnarmoredBase2 + 0, FInf, // fVanityDelay + 0, FInf, // fVoiceIdleOdds + -FInf, FInf, // fWaterReflectUpdateAlways + -FInf, FInf, // fWaterReflectUpdateSeldom + 0, FInf, // fWeaponDamageMult + 0, FInf, // fWeaponFatigueBlockMult + 0, FInf, // fWeaponFatigueMult + 0, FInf, // fWereWolfAcrobatics + -FInf, FInf, // fWereWolfAgility + -FInf, FInf, // fWereWolfAlchemy + -FInf, FInf, // fWereWolfAlteration + -FInf, FInf, // fWereWolfArmorer + -FInf, FInf, // fWereWolfAthletics + -FInf, FInf, // fWereWolfAxe + -FInf, FInf, // fWereWolfBlock + -FInf, FInf, // fWereWolfBluntWeapon + -FInf, FInf, // fWereWolfConjuration + -FInf, FInf, // fWereWolfDestruction + -FInf, FInf, // fWereWolfEnchant + -FInf, FInf, // fWereWolfEndurance + -FInf, FInf, // fWereWolfFatigue + -FInf, FInf, // fWereWolfHandtoHand + -FInf, FInf, // fWereWolfHealth + -FInf, FInf, // fWereWolfHeavyArmor + -FInf, FInf, // fWereWolfIllusion + -FInf, FInf, // fWereWolfIntellegence + -FInf, FInf, // fWereWolfLightArmor + -FInf, FInf, // fWereWolfLongBlade + -FInf, FInf, // fWereWolfLuck + -FInf, FInf, // fWereWolfMagicka + -FInf, FInf, // fWereWolfMarksman + -FInf, FInf, // fWereWolfMediumArmor + -FInf, FInf, // fWereWolfMerchantile + -FInf, FInf, // fWereWolfMysticism + -FInf, FInf, // fWereWolfPersonality + -FInf, FInf, // fWereWolfRestoration + 0, FInf, // fWereWolfRunMult + -FInf, FInf, // fWereWolfSecurity + -FInf, FInf, // fWereWolfShortBlade + -FInf, FInf, // fWereWolfSilverWeaponDamageMult + -FInf, FInf, // fWereWolfSneak + -FInf, FInf, // fWereWolfSpear + -FInf, FInf, // fWereWolfSpeechcraft + -FInf, FInf, // fWereWolfSpeed + -FInf, FInf, // fWereWolfStrength + -FInf, FInf, // fWereWolfUnarmored + -FInf, FInf, // fWereWolfWillPower + 0, FInf, // fWortChanceValue }; -const int CSMWorld::DefaultGmsts::IntLimits[CSMWorld::DefaultGmsts::IntCount * 2] = -{ - IMin, IMax, // i1stPersonSneakDelta - IMin, IMax, // iAlarmAttack - IMin, IMax, // iAlarmKilling - IMin, IMax, // iAlarmPickPocket - IMin, IMax, // iAlarmStealing - IMin, IMax, // iAlarmTresspass - IMin, IMax, // iAlchemyMod - 0, IMax, // iAutoPCSpellMax - IMin, IMax, // iAutoRepFacMod - IMin, IMax, // iAutoRepLevMod - IMin, IMax, // iAutoSpellAlterationMax - 0, IMax, // iAutoSpellAttSkillMin - IMin, IMax, // iAutoSpellConjurationMax - IMin, IMax, // iAutoSpellDestructionMax - IMin, IMax, // iAutoSpellIllusionMax - IMin, IMax, // iAutoSpellMysticismMax - IMin, IMax, // iAutoSpellRestorationMax - 0, IMax, // iAutoSpellTimesCanCast - IMin, 0, // iBarterFailDisposition - 0, IMax, // iBarterSuccessDisposition - 1, IMax, // iBaseArmorSkill - 0, IMax, // iBlockMaxChance - 0, IMax, // iBlockMinChance - 0, IMax, // iBootsWeight - IMin, IMax, // iCrimeAttack - IMin, IMax, // iCrimeKilling - IMin, IMax, // iCrimePickPocket - 0, IMax, // iCrimeThreshold - 0, IMax, // iCrimeThresholdMultiplier - IMin, IMax, // iCrimeTresspass - 0, IMax, // iCuirassWeight - 1, IMax, // iDaysinPrisonMod - IMin, 0, // iDispAttackMod - IMin, 0, // iDispKilling - IMin, 0, // iDispTresspass - IMin, IMax, // iFightAlarmMult - IMin, IMax, // iFightAttack - IMin, IMax, // iFightAttacking - 0, IMax, // iFightDistanceBase - IMin, IMax, // iFightKilling - IMin, IMax, // iFightPickpocket - IMin, IMax, // iFightTrespass - IMin, IMax, // iFlee - 0, IMax, // iGauntletWeight - 0, IMax, // iGreavesWeight - 0, IMax, // iGreetDistanceMultiplier - 0, IMax, // iGreetDuration - 0, IMax, // iHelmWeight - IMin, IMax, // iKnockDownOddsBase - IMin, IMax, // iKnockDownOddsMult - IMin, IMax, // iLevelUp01Mult - IMin, IMax, // iLevelUp02Mult - IMin, IMax, // iLevelUp03Mult - IMin, IMax, // iLevelUp04Mult - IMin, IMax, // iLevelUp05Mult - IMin, IMax, // iLevelUp06Mult - IMin, IMax, // iLevelUp07Mult - IMin, IMax, // iLevelUp08Mult - IMin, IMax, // iLevelUp09Mult - IMin, IMax, // iLevelUp10Mult - IMin, IMax, // iLevelupMajorMult - IMin, IMax, // iLevelupMajorMultAttribute - IMin, IMax, // iLevelupMinorMult - IMin, IMax, // iLevelupMinorMultAttribute - IMin, IMax, // iLevelupMiscMultAttriubte - IMin, IMax, // iLevelupSpecialization - IMin, IMax, // iLevelupTotal - IMin, IMax, // iMagicItemChargeConst - IMin, IMax, // iMagicItemChargeOnce - IMin, IMax, // iMagicItemChargeStrike - IMin, IMax, // iMagicItemChargeUse - IMin, IMax, // iMaxActivateDist - IMin, IMax, // iMaxInfoDist - 0, IMax, // iMonthsToRespawn - 0, IMax, // iNumberCreatures - 0, IMax, // iPauldronWeight - 0, IMax, // iPerMinChance - 0, IMax, // iPerMinChange - 0, IMax, // iPickMaxChance - 0, IMax, // iPickMinChance - 0, IMax, // iShieldWeight - 0, IMax, // iSoulAmountForConstantEffect - 0, IMax, // iTrainingMod - 0, IMax, // iVoiceAttackOdds - 0, IMax, // iVoiceHitOdds - IMin, IMax, // iWereWolfBounty - IMin, IMax, // iWereWolfFightMod - IMin, IMax, // iWereWolfFleeMod - IMin, IMax, // iWereWolfLevelToAttack +const int CSMWorld::DefaultGmsts::IntLimits[CSMWorld::DefaultGmsts::IntCount * 2] = { + IMin, IMax, // i1stPersonSneakDelta + IMin, IMax, // iAlarmAttack + IMin, IMax, // iAlarmKilling + IMin, IMax, // iAlarmPickPocket + IMin, IMax, // iAlarmStealing + IMin, IMax, // iAlarmTresspass + IMin, IMax, // iAlchemyMod + 0, IMax, // iAutoPCSpellMax + IMin, IMax, // iAutoRepFacMod + IMin, IMax, // iAutoRepLevMod + IMin, IMax, // iAutoSpellAlterationMax + 0, IMax, // iAutoSpellAttSkillMin + IMin, IMax, // iAutoSpellConjurationMax + IMin, IMax, // iAutoSpellDestructionMax + IMin, IMax, // iAutoSpellIllusionMax + IMin, IMax, // iAutoSpellMysticismMax + IMin, IMax, // iAutoSpellRestorationMax + 0, IMax, // iAutoSpellTimesCanCast + IMin, 0, // iBarterFailDisposition + 0, IMax, // iBarterSuccessDisposition + 1, IMax, // iBaseArmorSkill + 0, IMax, // iBlockMaxChance + 0, IMax, // iBlockMinChance + 0, IMax, // iBootsWeight + IMin, IMax, // iCrimeAttack + IMin, IMax, // iCrimeKilling + IMin, IMax, // iCrimePickPocket + 0, IMax, // iCrimeThreshold + 0, IMax, // iCrimeThresholdMultiplier + IMin, IMax, // iCrimeTresspass + 0, IMax, // iCuirassWeight + 1, IMax, // iDaysinPrisonMod + IMin, 0, // iDispAttackMod + IMin, 0, // iDispKilling + IMin, 0, // iDispTresspass + IMin, IMax, // iFightAlarmMult + IMin, IMax, // iFightAttack + IMin, IMax, // iFightAttacking + 0, IMax, // iFightDistanceBase + IMin, IMax, // iFightKilling + IMin, IMax, // iFightPickpocket + IMin, IMax, // iFightTrespass + IMin, IMax, // iFlee + 0, IMax, // iGauntletWeight + 0, IMax, // iGreavesWeight + 0, IMax, // iGreetDistanceMultiplier + 0, IMax, // iGreetDuration + 0, IMax, // iHelmWeight + IMin, IMax, // iKnockDownOddsBase + IMin, IMax, // iKnockDownOddsMult + IMin, IMax, // iLevelUp01Mult + IMin, IMax, // iLevelUp02Mult + IMin, IMax, // iLevelUp03Mult + IMin, IMax, // iLevelUp04Mult + IMin, IMax, // iLevelUp05Mult + IMin, IMax, // iLevelUp06Mult + IMin, IMax, // iLevelUp07Mult + IMin, IMax, // iLevelUp08Mult + IMin, IMax, // iLevelUp09Mult + IMin, IMax, // iLevelUp10Mult + IMin, IMax, // iLevelupMajorMult + IMin, IMax, // iLevelupMajorMultAttribute + IMin, IMax, // iLevelupMinorMult + IMin, IMax, // iLevelupMinorMultAttribute + IMin, IMax, // iLevelupMiscMultAttriubte + IMin, IMax, // iLevelupSpecialization + IMin, IMax, // iLevelupTotal + IMin, IMax, // iMagicItemChargeConst + IMin, IMax, // iMagicItemChargeOnce + IMin, IMax, // iMagicItemChargeStrike + IMin, IMax, // iMagicItemChargeUse + IMin, IMax, // iMaxActivateDist + IMin, IMax, // iMaxInfoDist + 0, IMax, // iMonthsToRespawn + 0, IMax, // iNumberCreatures + 0, IMax, // iPauldronWeight + 0, IMax, // iPerMinChance + 0, IMax, // iPerMinChange + 0, IMax, // iPickMaxChance + 0, IMax, // iPickMinChance + 0, IMax, // iShieldWeight + 0, IMax, // iSoulAmountForConstantEffect + 0, IMax, // iTrainingMod + 0, IMax, // iVoiceAttackOdds + 0, IMax, // iVoiceHitOdds + IMin, IMax, // iWereWolfBounty + IMin, IMax, // iWereWolfFightMod + IMin, IMax, // iWereWolfFleeMod + IMin, IMax, // iWereWolfLevelToAttack }; diff --git a/apps/opencs/model/world/defaultgmsts.hpp b/apps/opencs/model/world/defaultgmsts.hpp index a2888ed6ac..baee7d66a9 100644 --- a/apps/opencs/model/world/defaultgmsts.hpp +++ b/apps/opencs/model/world/defaultgmsts.hpp @@ -3,24 +3,26 @@ #include -namespace CSMWorld { - namespace DefaultGmsts { - +namespace CSMWorld +{ + namespace DefaultGmsts + { + const size_t FloatCount = 258; const size_t IntCount = 89; const size_t StringCount = 1174; - + const size_t OptionalFloatCount = 42; const size_t OptionalIntCount = 4; const size_t OptionalStringCount = 26; - + extern const char* Floats[]; - extern const char * Ints[]; - extern const char * Strings[]; - - extern const char * OptionalFloats[]; - extern const char * OptionalInts[]; - extern const char * OptionalStrings[]; + extern const char* Ints[]; + extern const char* Strings[]; + + extern const char* OptionalFloats[]; + extern const char* OptionalInts[]; + extern const char* OptionalStrings[]; extern const float FloatsDefaultValues[]; extern const int IntsDefaultValues[]; diff --git a/apps/opencs/model/world/idcollection.cpp b/apps/opencs/model/world/idcollection.cpp index 802ffe2487..13877be3d1 100644 --- a/apps/opencs/model/world/idcollection.cpp +++ b/apps/opencs/model/world/idcollection.cpp @@ -2,23 +2,23 @@ namespace CSMWorld { - template<> - int IdCollection >::load (ESM::ESMReader& reader, bool base) + template <> + int IdCollection>::load(ESM::ESMReader& reader, bool base) { Pathgrid record; bool isDeleted = false; - loadRecord (record, reader, isDeleted); + loadRecord(record, reader, isDeleted); - std::string id = IdAccessor().getId (record); - int index = this->searchId (id); + std::string id = IdAccessor().getId(record); + int index = this->searchId(id); if (record.mPoints.empty() || record.mEdges.empty()) isDeleted = true; if (isDeleted) { - if (index==-1) + if (index == -1) { // deleting a record that does not exist // ignore it for now @@ -28,7 +28,7 @@ namespace CSMWorld if (base) { - this->removeRows (index, 1); + this->removeRows(index, 1); return -1; } @@ -38,6 +38,6 @@ namespace CSMWorld return index; } - return load (record, base, index); + return load(record, base, index); } } diff --git a/apps/opencs/model/world/idcollection.hpp b/apps/opencs/model/world/idcollection.hpp index d246dc6852..f40ead044b 100644 --- a/apps/opencs/model/world/idcollection.hpp +++ b/apps/opencs/model/world/idcollection.hpp @@ -10,67 +10,62 @@ namespace CSMWorld { /// \brief Single type collection of top level records - template > + template > class IdCollection : public Collection { - virtual void loadRecord (ESXRecordT& record, ESM::ESMReader& reader, bool& isDeleted); - - public: - - /// \return Index of loaded record (-1 if no record was loaded) - int load (ESM::ESMReader& reader, bool base); - - /// \param index Index at which the record can be found. - /// Special values: -2 index unknown, -1 record does not exist yet and therefore - /// does not have an index - /// - /// \return index - int load (const ESXRecordT& record, bool base, int index = -2); - - bool tryDelete (const std::string& id); - ///< Try deleting \a id. If the id does not exist or can't be deleted the call is ignored. - /// - /// \return Has the ID been deleted? + virtual void loadRecord(ESXRecordT& record, ESM::ESMReader& reader, bool& isDeleted); + + public: + /// \return Index of loaded record (-1 if no record was loaded) + int load(ESM::ESMReader& reader, bool base); + + /// \param index Index at which the record can be found. + /// Special values: -2 index unknown, -1 record does not exist yet and therefore + /// does not have an index + /// + /// \return index + int load(const ESXRecordT& record, bool base, int index = -2); + + bool tryDelete(const std::string& id); + ///< Try deleting \a id. If the id does not exist or can't be deleted the call is ignored. + /// + /// \return Has the ID been deleted? }; - template - void IdCollection::loadRecord (ESXRecordT& record, - ESM::ESMReader& reader, - bool& isDeleted) + template + void IdCollection::loadRecord(ESXRecordT& record, ESM::ESMReader& reader, bool& isDeleted) { - record.load (reader, isDeleted); + record.load(reader, isDeleted); } - template<> - inline void IdCollection >::loadRecord (Land& record, - ESM::ESMReader& reader, bool& isDeleted) + template <> + inline void IdCollection>::loadRecord(Land& record, ESM::ESMReader& reader, bool& isDeleted) { - record.load (reader, isDeleted); + record.load(reader, isDeleted); // Load all land data for now. A future optimisation may only load non-base data // if a suitable mechanism for avoiding race conditions can be established. - int flags = ESM::Land::DATA_VHGT | ESM::Land::DATA_VNML | - ESM::Land::DATA_VCLR | ESM::Land::DATA_VTEX; - record.loadData (flags); + int flags = ESM::Land::DATA_VHGT | ESM::Land::DATA_VNML | ESM::Land::DATA_VCLR | ESM::Land::DATA_VTEX; + record.loadData(flags); // Prevent data from being reloaded. record.mContext.filename.clear(); } - template - int IdCollection::load (ESM::ESMReader& reader, bool base) + template + int IdCollection::load(ESM::ESMReader& reader, bool base) { ESXRecordT record; bool isDeleted = false; - loadRecord (record, reader, isDeleted); + loadRecord(record, reader, isDeleted); - std::string id = IdAccessorT().getId (record); - int index = this->searchId (id); + std::string id = IdAccessorT().getId(record); + int index = this->searchId(id); if (isDeleted) { - if (index==-1) + if (index == -1) { // deleting a record that does not exist // ignore it for now @@ -80,7 +75,7 @@ namespace CSMWorld if (base) { - this->removeRows (index, 1); + this->removeRows(index, 1); return -1; } @@ -90,17 +85,16 @@ namespace CSMWorld return index; } - return load (record, base, index); + return load(record, base, index); } - template - int IdCollection::load (const ESXRecordT& record, bool base, - int index) + template + int IdCollection::load(const ESXRecordT& record, bool base, int index) { - if (index==-2) // index unknown - index = this->searchId (IdAccessorT().getId (record)); + if (index == -2) // index unknown + index = this->searchId(IdAccessorT().getId(record)); - if (index==-1) + if (index == -1) { // new record auto record2 = std::make_unique>(); @@ -126,22 +120,22 @@ namespace CSMWorld return index; } - template - bool IdCollection::tryDelete (const std::string& id) + template + bool IdCollection::tryDelete(const std::string& id) { - int index = this->searchId (id); + int index = this->searchId(id); - if (index==-1) + if (index == -1) return false; - const Record& record = Collection::getRecord (index); + const Record& record = Collection::getRecord(index); if (record.isDeleted()) return false; - if (record.mState==RecordBase::State_ModifiedOnly) + if (record.mState == RecordBase::State_ModifiedOnly) { - Collection::removeRows (index, 1); + Collection::removeRows(index, 1); } else { @@ -153,8 +147,8 @@ namespace CSMWorld return true; } - template<> - int IdCollection >::load(ESM::ESMReader& reader, bool base); + template <> + int IdCollection>::load(ESM::ESMReader& reader, bool base); } #endif diff --git a/apps/opencs/model/world/idcompletionmanager.cpp b/apps/opencs/model/world/idcompletionmanager.cpp index 649a960387..722463681a 100644 --- a/apps/opencs/model/world/idcompletionmanager.cpp +++ b/apps/opencs/model/world/idcompletionmanager.cpp @@ -13,37 +13,36 @@ namespace { std::map types; - types[CSMWorld::ColumnBase::Display_BodyPart ] = CSMWorld::UniversalId::Type_BodyPart; - types[CSMWorld::ColumnBase::Display_Cell ] = CSMWorld::UniversalId::Type_Cell; - types[CSMWorld::ColumnBase::Display_Class ] = CSMWorld::UniversalId::Type_Class; + types[CSMWorld::ColumnBase::Display_BodyPart] = CSMWorld::UniversalId::Type_BodyPart; + types[CSMWorld::ColumnBase::Display_Cell] = CSMWorld::UniversalId::Type_Cell; + types[CSMWorld::ColumnBase::Display_Class] = CSMWorld::UniversalId::Type_Class; types[CSMWorld::ColumnBase::Display_CreatureLevelledList] = CSMWorld::UniversalId::Type_Referenceable; - types[CSMWorld::ColumnBase::Display_Creature ] = CSMWorld::UniversalId::Type_Referenceable; - types[CSMWorld::ColumnBase::Display_Enchantment ] = CSMWorld::UniversalId::Type_Enchantment; - types[CSMWorld::ColumnBase::Display_Faction ] = CSMWorld::UniversalId::Type_Faction; - types[CSMWorld::ColumnBase::Display_GlobalVariable ] = CSMWorld::UniversalId::Type_Global; - types[CSMWorld::ColumnBase::Display_Icon ] = CSMWorld::UniversalId::Type_Icon; - types[CSMWorld::ColumnBase::Display_Journal ] = CSMWorld::UniversalId::Type_Journal; - types[CSMWorld::ColumnBase::Display_Mesh ] = CSMWorld::UniversalId::Type_Mesh; - types[CSMWorld::ColumnBase::Display_Miscellaneous ] = CSMWorld::UniversalId::Type_Referenceable; - types[CSMWorld::ColumnBase::Display_Npc ] = CSMWorld::UniversalId::Type_Referenceable; - types[CSMWorld::ColumnBase::Display_Race ] = CSMWorld::UniversalId::Type_Race; - types[CSMWorld::ColumnBase::Display_Region ] = CSMWorld::UniversalId::Type_Region; - types[CSMWorld::ColumnBase::Display_Referenceable ] = CSMWorld::UniversalId::Type_Referenceable; - types[CSMWorld::ColumnBase::Display_Script ] = CSMWorld::UniversalId::Type_Script; - types[CSMWorld::ColumnBase::Display_Skill ] = CSMWorld::UniversalId::Type_Skill; - types[CSMWorld::ColumnBase::Display_Sound ] = CSMWorld::UniversalId::Type_Sound; - types[CSMWorld::ColumnBase::Display_SoundRes ] = CSMWorld::UniversalId::Type_SoundRes; - types[CSMWorld::ColumnBase::Display_Spell ] = CSMWorld::UniversalId::Type_Spell; - types[CSMWorld::ColumnBase::Display_Static ] = CSMWorld::UniversalId::Type_Referenceable; - types[CSMWorld::ColumnBase::Display_Texture ] = CSMWorld::UniversalId::Type_Texture; - types[CSMWorld::ColumnBase::Display_Topic ] = CSMWorld::UniversalId::Type_Topic; - types[CSMWorld::ColumnBase::Display_Weapon ] = CSMWorld::UniversalId::Type_Referenceable; + types[CSMWorld::ColumnBase::Display_Creature] = CSMWorld::UniversalId::Type_Referenceable; + types[CSMWorld::ColumnBase::Display_Enchantment] = CSMWorld::UniversalId::Type_Enchantment; + types[CSMWorld::ColumnBase::Display_Faction] = CSMWorld::UniversalId::Type_Faction; + types[CSMWorld::ColumnBase::Display_GlobalVariable] = CSMWorld::UniversalId::Type_Global; + types[CSMWorld::ColumnBase::Display_Icon] = CSMWorld::UniversalId::Type_Icon; + types[CSMWorld::ColumnBase::Display_Journal] = CSMWorld::UniversalId::Type_Journal; + types[CSMWorld::ColumnBase::Display_Mesh] = CSMWorld::UniversalId::Type_Mesh; + types[CSMWorld::ColumnBase::Display_Miscellaneous] = CSMWorld::UniversalId::Type_Referenceable; + types[CSMWorld::ColumnBase::Display_Npc] = CSMWorld::UniversalId::Type_Referenceable; + types[CSMWorld::ColumnBase::Display_Race] = CSMWorld::UniversalId::Type_Race; + types[CSMWorld::ColumnBase::Display_Region] = CSMWorld::UniversalId::Type_Region; + types[CSMWorld::ColumnBase::Display_Referenceable] = CSMWorld::UniversalId::Type_Referenceable; + types[CSMWorld::ColumnBase::Display_Script] = CSMWorld::UniversalId::Type_Script; + types[CSMWorld::ColumnBase::Display_Skill] = CSMWorld::UniversalId::Type_Skill; + types[CSMWorld::ColumnBase::Display_Sound] = CSMWorld::UniversalId::Type_Sound; + types[CSMWorld::ColumnBase::Display_SoundRes] = CSMWorld::UniversalId::Type_SoundRes; + types[CSMWorld::ColumnBase::Display_Spell] = CSMWorld::UniversalId::Type_Spell; + types[CSMWorld::ColumnBase::Display_Static] = CSMWorld::UniversalId::Type_Referenceable; + types[CSMWorld::ColumnBase::Display_Texture] = CSMWorld::UniversalId::Type_Texture; + types[CSMWorld::ColumnBase::Display_Topic] = CSMWorld::UniversalId::Type_Topic; + types[CSMWorld::ColumnBase::Display_Weapon] = CSMWorld::UniversalId::Type_Referenceable; return types; } - typedef std::map::const_iterator ModelTypeConstIterator; + typedef std::map::const_iterator ModelTypeConstIterator; } const std::map @@ -65,7 +64,7 @@ std::vector CSMWorld::IdCompletionManager::getDis return types; } -CSMWorld::IdCompletionManager::IdCompletionManager(CSMWorld::Data &data) +CSMWorld::IdCompletionManager::IdCompletionManager(CSMWorld::Data& data) { generateCompleters(data); } @@ -84,14 +83,14 @@ std::shared_ptr CSMWorld::IdCompletionManager::getCompleter(CSMWorld return mCompleters[display]; } -void CSMWorld::IdCompletionManager::generateCompleters(CSMWorld::Data &data) +void CSMWorld::IdCompletionManager::generateCompleters(CSMWorld::Data& data) { ModelTypeConstIterator current = sCompleterModelTypes.begin(); ModelTypeConstIterator end = sCompleterModelTypes.end(); for (; current != end; ++current) { - QAbstractItemModel *model = data.getTableModel(current->second); - CSMWorld::IdTableBase *table = dynamic_cast(model); + QAbstractItemModel* model = data.getTableModel(current->second); + CSMWorld::IdTableBase* table = dynamic_cast(model); if (table != nullptr) { int idColumn = table->searchColumnIndex(CSMWorld::Columns::ColumnId_Id); @@ -103,7 +102,7 @@ void CSMWorld::IdCompletionManager::generateCompleters(CSMWorld::Data &data) completer->setCompletionRole(Qt::DisplayRole); completer->setCaseSensitivity(Qt::CaseInsensitive); - QAbstractItemView *popup = new CSVWidget::CompleterPopup(); + QAbstractItemView* popup = new CSVWidget::CompleterPopup(); completer->setPopup(popup); // The completer takes ownership of the popup completer->setMaxVisibleItems(10); diff --git a/apps/opencs/model/world/idcompletionmanager.hpp b/apps/opencs/model/world/idcompletionmanager.hpp index e48360432a..b1e9f732fd 100644 --- a/apps/opencs/model/world/idcompletionmanager.hpp +++ b/apps/opencs/model/world/idcompletionmanager.hpp @@ -1,9 +1,9 @@ #ifndef CSM_WORLD_IDCOMPLETIONMANAGER_HPP #define CSM_WORLD_IDCOMPLETIONMANAGER_HPP -#include #include #include +#include #include "columnbase.hpp" #include "universalid.hpp" @@ -17,23 +17,23 @@ namespace CSMWorld /// \brief Creates and stores all ID completers class IdCompletionManager { - static const std::map sCompleterModelTypes; + static const std::map sCompleterModelTypes; - std::map > mCompleters; + std::map> mCompleters; - // Don't allow copying - IdCompletionManager(const IdCompletionManager &); - IdCompletionManager &operator = (const IdCompletionManager &); + // Don't allow copying + IdCompletionManager(const IdCompletionManager&); + IdCompletionManager& operator=(const IdCompletionManager&); - void generateCompleters(Data &data); + void generateCompleters(Data& data); - public: - static std::vector getDisplayTypes(); + public: + static std::vector getDisplayTypes(); - IdCompletionManager(Data &data); + IdCompletionManager(Data& data); - bool hasCompleterFor(ColumnBase::Display display) const; - std::shared_ptr getCompleter(ColumnBase::Display display); + bool hasCompleterFor(ColumnBase::Display display) const; + std::shared_ptr getCompleter(ColumnBase::Display display); }; } diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index 61315459ac..531d3404bf 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -13,14 +13,15 @@ #include "columnbase.hpp" #include "landtexture.hpp" -CSMWorld::IdTable::IdTable (CollectionBase *idCollection, unsigned int features) -: IdTableBase (features), mIdCollection (idCollection) -{} +CSMWorld::IdTable::IdTable(CollectionBase* idCollection, unsigned int features) + : IdTableBase(features) + , mIdCollection(idCollection) +{ +} -CSMWorld::IdTable::~IdTable() -{} +CSMWorld::IdTable::~IdTable() {} -int CSMWorld::IdTable::rowCount (const QModelIndex & parent) const +int CSMWorld::IdTable::rowCount(const QModelIndex& parent) const { if (parent.isValid()) return 0; @@ -28,7 +29,7 @@ int CSMWorld::IdTable::rowCount (const QModelIndex & parent) const return mIdCollection->getSize(); } -int CSMWorld::IdTable::columnCount (const QModelIndex & parent) const +int CSMWorld::IdTable::columnCount(const QModelIndex& parent) const { if (parent.isValid()) return 0; @@ -36,54 +37,54 @@ int CSMWorld::IdTable::columnCount (const QModelIndex & parent) const return mIdCollection->getColumns(); } -QVariant CSMWorld::IdTable::data (const QModelIndex & index, int role) const +QVariant CSMWorld::IdTable::data(const QModelIndex& index, int role) const { if (index.row() < 0 || index.column() < 0) return QVariant(); - if (role==ColumnBase::Role_Display) + if (role == ColumnBase::Role_Display) return QVariant(mIdCollection->getColumn(index.column()).mDisplayType); - if (role==ColumnBase::Role_ColumnId) - return QVariant (getColumnId (index.column())); + if (role == ColumnBase::Role_ColumnId) + return QVariant(getColumnId(index.column())); - if ((role!=Qt::DisplayRole && role!=Qt::EditRole)) + if ((role != Qt::DisplayRole && role != Qt::EditRole)) return QVariant(); - if (role==Qt::EditRole && !mIdCollection->getColumn (index.column()).isEditable()) + if (role == Qt::EditRole && !mIdCollection->getColumn(index.column()).isEditable()) return QVariant(); - return mIdCollection->getData (index.row(), index.column()); + return mIdCollection->getData(index.row(), index.column()); } -QVariant CSMWorld::IdTable::headerData (int section, Qt::Orientation orientation, int role) const +QVariant CSMWorld::IdTable::headerData(int section, Qt::Orientation orientation, int role) const { - if (orientation==Qt::Vertical) + if (orientation == Qt::Vertical) return QVariant(); if (orientation != Qt::Horizontal) throw std::logic_error("Unknown header orientation specified"); - if (role==Qt::DisplayRole) - return tr (mIdCollection->getColumn (section).getTitle().c_str()); + if (role == Qt::DisplayRole) + return tr(mIdCollection->getColumn(section).getTitle().c_str()); - if (role==ColumnBase::Role_Flags) - return mIdCollection->getColumn (section).mFlags; + if (role == ColumnBase::Role_Flags) + return mIdCollection->getColumn(section).mFlags; - if (role==ColumnBase::Role_Display) - return mIdCollection->getColumn (section).mDisplayType; + if (role == ColumnBase::Role_Display) + return mIdCollection->getColumn(section).mDisplayType; - if (role==ColumnBase::Role_ColumnId) - return getColumnId (section); + if (role == ColumnBase::Role_ColumnId) + return getColumnId(section); return QVariant(); } -bool CSMWorld::IdTable::setData (const QModelIndex &index, const QVariant &value, int role) +bool CSMWorld::IdTable::setData(const QModelIndex& index, const QVariant& value, int role) { - if (mIdCollection->getColumn (index.column()).isEditable() && role==Qt::EditRole) + if (mIdCollection->getColumn(index.column()).isEditable() && role == Qt::EditRole) { - mIdCollection->setData (index.row(), index.column(), value); + mIdCollection->setData(index.row(), index.column(), value); int stateColumn = searchColumnIndex(Columns::ColumnId_Modification); if (stateColumn != -1) @@ -93,10 +94,10 @@ bool CSMWorld::IdTable::setData (const QModelIndex &index, const QVariant &value // modifying the state column can modify other values. we need to tell // views that the whole row has changed. - emit dataChanged(this->index(index.row(), 0), - this->index(index.row(), columnCount(index.parent()) - 1)); - - } else + emit dataChanged( + this->index(index.row(), 0), this->index(index.row(), columnCount(index.parent()) - 1)); + } + else { emit dataChanged(index, index); @@ -104,7 +105,8 @@ bool CSMWorld::IdTable::setData (const QModelIndex &index, const QVariant &value QModelIndex stateIndex = this->index(index.row(), stateColumn); emit dataChanged(stateIndex, stateIndex); } - } else + } + else emit dataChanged(index, index); return true; @@ -113,14 +115,14 @@ bool CSMWorld::IdTable::setData (const QModelIndex &index, const QVariant &value return false; } -Qt::ItemFlags CSMWorld::IdTable::flags (const QModelIndex & index) const +Qt::ItemFlags CSMWorld::IdTable::flags(const QModelIndex& index) const { if (!index.isValid()) return Qt::ItemFlags(); Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled; - if (mIdCollection->getColumn (index.column()).isUserEditable()) + if (mIdCollection->getColumn(index.column()).isUserEditable()) flags |= Qt::ItemIsEditable; int blockedColumn = searchColumnIndex(Columns::ColumnId_Blocked); @@ -134,60 +136,60 @@ Qt::ItemFlags CSMWorld::IdTable::flags (const QModelIndex & index) const return flags; } -bool CSMWorld::IdTable::removeRows (int row, int count, const QModelIndex& parent) +bool CSMWorld::IdTable::removeRows(int row, int count, const QModelIndex& parent) { if (parent.isValid()) return false; - beginRemoveRows (parent, row, row+count-1); + beginRemoveRows(parent, row, row + count - 1); - mIdCollection->removeRows (row, count); + mIdCollection->removeRows(row, count); endRemoveRows(); return true; } -QModelIndex CSMWorld::IdTable::index (int row, int column, const QModelIndex& parent) const +QModelIndex CSMWorld::IdTable::index(int row, int column, const QModelIndex& parent) const { if (parent.isValid()) return QModelIndex(); - if (row<0 || row>=mIdCollection->getSize()) + if (row < 0 || row >= mIdCollection->getSize()) return QModelIndex(); - if (column<0 || column>=mIdCollection->getColumns()) + if (column < 0 || column >= mIdCollection->getColumns()) return QModelIndex(); - return createIndex (row, column); + return createIndex(row, column); } -QModelIndex CSMWorld::IdTable::parent (const QModelIndex& index) const +QModelIndex CSMWorld::IdTable::parent(const QModelIndex& index) const { return QModelIndex(); } -void CSMWorld::IdTable::addRecord (const std::string& id, UniversalId::Type type) +void CSMWorld::IdTable::addRecord(const std::string& id, UniversalId::Type type) { - int index = mIdCollection->getAppendIndex (id, type); + int index = mIdCollection->getAppendIndex(id, type); - beginInsertRows (QModelIndex(), index, index); + beginInsertRows(QModelIndex(), index, index); - mIdCollection->appendBlankRecord (id, type); + mIdCollection->appendBlankRecord(id, type); endInsertRows(); } -void CSMWorld::IdTable::addRecordWithData (const std::string& id, - const std::map& data, UniversalId::Type type) +void CSMWorld::IdTable::addRecordWithData( + const std::string& id, const std::map& data, UniversalId::Type type) { - int index = mIdCollection->getAppendIndex (id, type); + int index = mIdCollection->getAppendIndex(id, type); - beginInsertRows (QModelIndex(), index, index); + beginInsertRows(QModelIndex(), index, index); - mIdCollection->appendBlankRecord (id, type); + mIdCollection->appendBlankRecord(id, type); - for (std::map::const_iterator iter (data.begin()); iter!=data.end(); ++iter) + for (std::map::const_iterator iter(data.begin()); iter != data.end(); ++iter) { mIdCollection->setData(index, iter->first, iter->second); } @@ -195,13 +197,12 @@ void CSMWorld::IdTable::addRecordWithData (const std::string& id, endInsertRows(); } -void CSMWorld::IdTable::cloneRecord(const std::string& origin, - const std::string& destination, - CSMWorld::UniversalId::Type type) +void CSMWorld::IdTable::cloneRecord( + const std::string& origin, const std::string& destination, CSMWorld::UniversalId::Type type) { - int index = mIdCollection->getAppendIndex (destination, type); + int index = mIdCollection->getAppendIndex(destination, type); - beginInsertRows (QModelIndex(), index, index); + beginInsertRows(QModelIndex(), index, index); mIdCollection->cloneRecord(origin, destination, type); endInsertRows(); } @@ -226,22 +227,22 @@ std::string CSMWorld::IdTable::getId(int row) const return mIdCollection->getId(row); } -///This method can return only indexes to the top level table cells -QModelIndex CSMWorld::IdTable::getModelIndex (const std::string& id, int column) const +/// This method can return only indexes to the top level table cells +QModelIndex CSMWorld::IdTable::getModelIndex(const std::string& id, int column) const { - int row = mIdCollection->searchId (id); + int row = mIdCollection->searchId(id); if (row != -1) return index(row, column); return QModelIndex(); } -void CSMWorld::IdTable::setRecord (const std::string& id, - std::unique_ptr record, CSMWorld::UniversalId::Type type) +void CSMWorld::IdTable::setRecord( + const std::string& id, std::unique_ptr record, CSMWorld::UniversalId::Type type) { - int index = mIdCollection->searchId (id); + int index = mIdCollection->searchId(id); - if (index==-1) + if (index == -1) { // For info records, appendRecord may use a different index than the one returned by // getAppendIndex (because of prev/next links). This can result in the display not @@ -249,85 +250,85 @@ void CSMWorld::IdTable::setRecord (const std::string& id, // // Use an alternative method to get the correct index. For non-Info records the // record pointer is ignored and internally calls getAppendIndex. - int index2 = mIdCollection->getInsertIndex (id, type, record.get()); + int index2 = mIdCollection->getInsertIndex(id, type, record.get()); - beginInsertRows (QModelIndex(), index2, index2); + beginInsertRows(QModelIndex(), index2, index2); - mIdCollection->appendRecord (std::move(record), type); + mIdCollection->appendRecord(std::move(record), type); endInsertRows(); } else { - mIdCollection->replace (index, std::move(record)); - emit dataChanged (CSMWorld::IdTable::index (index, 0), - CSMWorld::IdTable::index (index, mIdCollection->getColumns()-1)); + mIdCollection->replace(index, std::move(record)); + emit dataChanged( + CSMWorld::IdTable::index(index, 0), CSMWorld::IdTable::index(index, mIdCollection->getColumns() - 1)); } } -const CSMWorld::RecordBase& CSMWorld::IdTable::getRecord (const std::string& id) const +const CSMWorld::RecordBase& CSMWorld::IdTable::getRecord(const std::string& id) const { - return mIdCollection->getRecord (id); + return mIdCollection->getRecord(id); } -int CSMWorld::IdTable::searchColumnIndex (Columns::ColumnId id) const +int CSMWorld::IdTable::searchColumnIndex(Columns::ColumnId id) const { - return mIdCollection->searchColumnIndex (id); + return mIdCollection->searchColumnIndex(id); } -int CSMWorld::IdTable::findColumnIndex (Columns::ColumnId id) const +int CSMWorld::IdTable::findColumnIndex(Columns::ColumnId id) const { - return mIdCollection->findColumnIndex (id); + return mIdCollection->findColumnIndex(id); } -void CSMWorld::IdTable::reorderRows (int baseIndex, const std::vector& newOrder) +void CSMWorld::IdTable::reorderRows(int baseIndex, const std::vector& newOrder) { if (!newOrder.empty()) - if (mIdCollection->reorderRows (baseIndex, newOrder)) - emit dataChanged (index (baseIndex, 0), - index (baseIndex+static_cast(newOrder.size())-1, mIdCollection->getColumns()-1)); + if (mIdCollection->reorderRows(baseIndex, newOrder)) + emit dataChanged(index(baseIndex, 0), + index(baseIndex + static_cast(newOrder.size()) - 1, mIdCollection->getColumns() - 1)); } -std::pair CSMWorld::IdTable::view (int row) const +std::pair CSMWorld::IdTable::view(int row) const { std::string id; std::string hint; if (getFeatures() & Feature_ViewCell) { - int cellColumn = mIdCollection->searchColumnIndex (Columns::ColumnId_Cell); - int idColumn = mIdCollection->searchColumnIndex (Columns::ColumnId_Id); + int cellColumn = mIdCollection->searchColumnIndex(Columns::ColumnId_Cell); + int idColumn = mIdCollection->searchColumnIndex(Columns::ColumnId_Id); - if (cellColumn!=-1 && idColumn!=-1) + if (cellColumn != -1 && idColumn != -1) { - id = mIdCollection->getData (row, cellColumn).toString().toUtf8().constData(); - hint = "r:" + std::string (mIdCollection->getData (row, idColumn).toString().toUtf8().constData()); + id = mIdCollection->getData(row, cellColumn).toString().toUtf8().constData(); + hint = "r:" + std::string(mIdCollection->getData(row, idColumn).toString().toUtf8().constData()); } } else if (getFeatures() & Feature_ViewId) { - int column = mIdCollection->searchColumnIndex (Columns::ColumnId_Id); + int column = mIdCollection->searchColumnIndex(Columns::ColumnId_Id); - if (column!=-1) + if (column != -1) { - id = mIdCollection->getData (row, column).toString().toUtf8().constData(); + id = mIdCollection->getData(row, column).toString().toUtf8().constData(); hint = "c:" + id; } } if (id.empty()) - return std::make_pair (UniversalId::Type_None, ""); + return std::make_pair(UniversalId::Type_None, ""); - if (id[0]=='#') + if (id[0] == '#') id = ESM::CellId::sDefaultWorldspace; - return std::make_pair (UniversalId (UniversalId::Type_Scene, id), hint); + return std::make_pair(UniversalId(UniversalId::Type_Scene, id), hint); } -///For top level data/columns -bool CSMWorld::IdTable::isDeleted (const std::string& id) const +/// For top level data/columns +bool CSMWorld::IdTable::isDeleted(const std::string& id) const { - return getRecord (id).isDeleted(); + return getRecord(id).isDeleted(); } int CSMWorld::IdTable::getColumnId(int column) const @@ -335,7 +336,7 @@ int CSMWorld::IdTable::getColumnId(int column) const return mIdCollection->getColumn(column).getId(); } -CSMWorld::CollectionBase *CSMWorld::IdTable::idCollection() const +CSMWorld::CollectionBase* CSMWorld::IdTable::idCollection() const { return mIdCollection; } @@ -345,7 +346,8 @@ CSMWorld::LandTextureIdTable::LandTextureIdTable(CollectionBase* idCollection, u { } -CSMWorld::LandTextureIdTable::ImportResults CSMWorld::LandTextureIdTable::importTextures(const std::vector& ids) +CSMWorld::LandTextureIdTable::ImportResults CSMWorld::LandTextureIdTable::importTextures( + const std::vector& ids) { ImportResults results; @@ -384,7 +386,8 @@ CSMWorld::LandTextureIdTable::ImportResults CSMWorld::LandTextureIdTable::import // Iterate until an unused index or found, or the index has completely wrapped around. int startIndex = index; - do { + do + { std::string newId = LandTexture::createUniqueRecordId(0, index); int newRow = idCollection()->searchId(newId); diff --git a/apps/opencs/model/world/idtable.hpp b/apps/opencs/model/world/idtable.hpp index c38e1b5f9c..71cf42f605 100644 --- a/apps/opencs/model/world/idtable.hpp +++ b/apps/opencs/model/world/idtable.hpp @@ -1,12 +1,12 @@ #ifndef CSM_WOLRD_IDTABLE_H #define CSM_WOLRD_IDTABLE_H -#include #include +#include +#include "columns.hpp" #include "idtablebase.hpp" #include "universalid.hpp" -#include "columns.hpp" namespace CSMWorld { @@ -15,88 +15,84 @@ namespace CSMWorld class IdTable : public IdTableBase { - Q_OBJECT + Q_OBJECT - private: + private: + CollectionBase* mIdCollection; - CollectionBase *mIdCollection; + // not implemented + IdTable(const IdTable&); + IdTable& operator=(const IdTable&); - // not implemented - IdTable (const IdTable&); - IdTable& operator= (const IdTable&); + public: + IdTable(CollectionBase* idCollection, unsigned int features = 0); + ///< The ownership of \a idCollection is not transferred. - public: + virtual ~IdTable(); - IdTable (CollectionBase *idCollection, unsigned int features = 0); - ///< The ownership of \a idCollection is not transferred. + int rowCount(const QModelIndex& parent = QModelIndex()) const override; - virtual ~IdTable(); + int columnCount(const QModelIndex& parent = QModelIndex()) const override; - int rowCount (const QModelIndex & parent = QModelIndex()) const override; + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; - int columnCount (const QModelIndex & parent = QModelIndex()) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const override; + bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override; - QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + Qt::ItemFlags flags(const QModelIndex& index) const override; - bool setData ( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex()) override; - Qt::ItemFlags flags (const QModelIndex & index) const override; + QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override; - bool removeRows (int row, int count, const QModelIndex& parent = QModelIndex()) override; + QModelIndex parent(const QModelIndex& index) const override; - QModelIndex index (int row, int column, const QModelIndex& parent = QModelIndex()) const override; + void addRecord(const std::string& id, UniversalId::Type type = UniversalId::Type_None); + ///< \param type Will be ignored, unless the collection supports multiple record types - QModelIndex parent (const QModelIndex& index) const override; + void addRecordWithData(const std::string& id, const std::map& data, + UniversalId::Type type = UniversalId::Type_None); + ///< \param type Will be ignored, unless the collection supports multiple record types - void addRecord (const std::string& id, UniversalId::Type type = UniversalId::Type_None); - ///< \param type Will be ignored, unless the collection supports multiple record types + void cloneRecord( + const std::string& origin, const std::string& destination, UniversalId::Type type = UniversalId::Type_None); - void addRecordWithData (const std::string& id, const std::map& data, - UniversalId::Type type = UniversalId::Type_None); - ///< \param type Will be ignored, unless the collection supports multiple record types + bool touchRecord(const std::string& id); + ///< Will change the record state to modified, if it is not already. - void cloneRecord(const std::string& origin, - const std::string& destination, - UniversalId::Type type = UniversalId::Type_None); + std::string getId(int row) const; - bool touchRecord(const std::string& id); - ///< Will change the record state to modified, if it is not already. + QModelIndex getModelIndex(const std::string& id, int column) const override; - std::string getId(int row) const; + void setRecord( + const std::string& id, std::unique_ptr record, UniversalId::Type type = UniversalId::Type_None); + ///< Add record or overwrite existing record. - QModelIndex getModelIndex (const std::string& id, int column) const override; + const RecordBase& getRecord(const std::string& id) const; - void setRecord (const std::string& id, std::unique_ptr record, - UniversalId::Type type = UniversalId::Type_None); - ///< Add record or overwrite existing record. + int searchColumnIndex(Columns::ColumnId id) const override; + ///< Return index of column with the given \a id. If no such column exists, -1 is returned. - const RecordBase& getRecord (const std::string& id) const; + int findColumnIndex(Columns::ColumnId id) const override; + ///< Return index of column with the given \a id. If no such column exists, an exception is + /// thrown. - int searchColumnIndex (Columns::ColumnId id) const override; - ///< Return index of column with the given \a id. If no such column exists, -1 is returned. + void reorderRows(int baseIndex, const std::vector& newOrder); + ///< Reorder the rows [baseIndex, baseIndex+newOrder.size()) according to the indices + /// given in \a newOrder (baseIndex+newOrder[0] specifies the new index of row baseIndex). - int findColumnIndex (Columns::ColumnId id) const override; - ///< Return index of column with the given \a id. If no such column exists, an exception is - /// thrown. + std::pair view(int row) const override; + ///< Return the UniversalId and the hint for viewing \a row. If viewing is not + /// supported by this table, return (UniversalId::Type_None, ""). - void reorderRows (int baseIndex, const std::vector& newOrder); - ///< Reorder the rows [baseIndex, baseIndex+newOrder.size()) according to the indices - /// given in \a newOrder (baseIndex+newOrder[0] specifies the new index of row baseIndex). + /// Is \a id flagged as deleted? + bool isDeleted(const std::string& id) const override; - std::pair view (int row) const override; - ///< Return the UniversalId and the hint for viewing \a row. If viewing is not - /// supported by this table, return (UniversalId::Type_None, ""). + int getColumnId(int column) const override; - /// Is \a id flagged as deleted? - bool isDeleted (const std::string& id) const override; - - int getColumnId(int column) const override; - - protected: - - virtual CollectionBase *idCollection() const; + protected: + virtual CollectionBase* idCollection() const; }; /// An IdTable customized to handle the more unique needs of LandTextureId's which behave @@ -104,22 +100,21 @@ namespace CSMWorld /// modified. class LandTextureIdTable : public IdTable { - public: - - struct ImportResults - { - using StringPair = std::pair; + public: + struct ImportResults + { + using StringPair = std::pair; - /// The newly added records - std::vector createdRecords; - /// The 1st string is the original id, the 2nd is the mapped id - std::vector recordMapping; - }; + /// The newly added records + std::vector createdRecords; + /// The 1st string is the original id, the 2nd is the mapped id + std::vector recordMapping; + }; - LandTextureIdTable(CollectionBase* idCollection, unsigned int features=0); + LandTextureIdTable(CollectionBase* idCollection, unsigned int features = 0); - /// Finds and maps/recreates the specified ids. - ImportResults importTextures(const std::vector& ids); + /// Finds and maps/recreates the specified ids. + ImportResults importTextures(const std::vector& ids); }; } diff --git a/apps/opencs/model/world/idtablebase.cpp b/apps/opencs/model/world/idtablebase.cpp index 274446b796..fd523d1ec7 100644 --- a/apps/opencs/model/world/idtablebase.cpp +++ b/apps/opencs/model/world/idtablebase.cpp @@ -1,6 +1,9 @@ #include "idtablebase.hpp" -CSMWorld::IdTableBase::IdTableBase (unsigned int features) : mFeatures (features) {} +CSMWorld::IdTableBase::IdTableBase(unsigned int features) + : mFeatures(features) +{ +} unsigned int CSMWorld::IdTableBase::getFeatures() const { diff --git a/apps/opencs/model/world/idtablebase.hpp b/apps/opencs/model/world/idtablebase.hpp index 8b82f984b9..d4ef5d7770 100644 --- a/apps/opencs/model/world/idtablebase.hpp +++ b/apps/opencs/model/world/idtablebase.hpp @@ -11,60 +11,57 @@ namespace CSMWorld class IdTableBase : public QAbstractItemModel { - Q_OBJECT + Q_OBJECT - public: + public: + enum Features + { + Feature_ReorderWithinTopic = 1, - enum Features - { - Feature_ReorderWithinTopic = 1, + /// Use ID column to generate view request (ID is transformed into + /// worldspace and original ID is passed as hint with c: prefix). + Feature_ViewId = 2, - /// Use ID column to generate view request (ID is transformed into - /// worldspace and original ID is passed as hint with c: prefix). - Feature_ViewId = 2, + /// Use cell column to generate view request (cell ID is transformed + /// into worldspace and record ID is passed as hint with r: prefix). + Feature_ViewCell = 4, - /// Use cell column to generate view request (cell ID is transformed - /// into worldspace and record ID is passed as hint with r: prefix). - Feature_ViewCell = 4, + Feature_View = Feature_ViewId | Feature_ViewCell, - Feature_View = Feature_ViewId | Feature_ViewCell, + Feature_Preview = 8, - Feature_Preview = 8, + /// Table can not be modified through ordinary means. + Feature_Constant = 16, - /// Table can not be modified through ordinary means. - Feature_Constant = 16, + Feature_AllowTouch = 32 + }; - Feature_AllowTouch = 32 - }; + private: + unsigned int mFeatures; - private: + public: + IdTableBase(unsigned int features); - unsigned int mFeatures; + virtual QModelIndex getModelIndex(const std::string& id, int column) const = 0; - public: + /// Return index of column with the given \a id. If no such column exists, -1 is + /// returned. + virtual int searchColumnIndex(Columns::ColumnId id) const = 0; - IdTableBase (unsigned int features); + /// Return index of column with the given \a id. If no such column exists, an + /// exception is thrown. + virtual int findColumnIndex(Columns::ColumnId id) const = 0; - virtual QModelIndex getModelIndex (const std::string& id, int column) const = 0; + /// Return the UniversalId and the hint for viewing \a row. If viewing is not + /// supported by this table, return (UniversalId::Type_None, ""). + virtual std::pair view(int row) const = 0; - /// Return index of column with the given \a id. If no such column exists, -1 is - /// returned. - virtual int searchColumnIndex (Columns::ColumnId id) const = 0; + /// Is \a id flagged as deleted? + virtual bool isDeleted(const std::string& id) const = 0; - /// Return index of column with the given \a id. If no such column exists, an - /// exception is thrown. - virtual int findColumnIndex (Columns::ColumnId id) const = 0; + virtual int getColumnId(int column) const = 0; - /// Return the UniversalId and the hint for viewing \a row. If viewing is not - /// supported by this table, return (UniversalId::Type_None, ""). - virtual std::pair view (int row) const = 0; - - /// Is \a id flagged as deleted? - virtual bool isDeleted (const std::string& id) const = 0; - - virtual int getColumnId (int column) const = 0; - - unsigned int getFeatures() const; + unsigned int getFeatures() const; }; } diff --git a/apps/opencs/model/world/idtableproxymodel.cpp b/apps/opencs/model/world/idtableproxymodel.cpp index d0e7bd8a59..4d68c03ce2 100644 --- a/apps/opencs/model/world/idtableproxymodel.cpp +++ b/apps/opencs/model/world/idtableproxymodel.cpp @@ -2,12 +2,12 @@ #include -#include "idtablebase.hpp" #include "columnbase.hpp" +#include "idtablebase.hpp" namespace { - std::string getEnumValue(const std::vector> &values, int index) + std::string getEnumValue(const std::vector>& values, int index) { if (index < 0 || index >= static_cast(values.size())) { @@ -25,14 +25,13 @@ void CSMWorld::IdTableProxyModel::updateColumnMap() if (mFilter) { std::vector columns = mFilter->getReferencedColumns(); - for (std::vector::const_iterator iter (columns.begin()); iter!=columns.end(); ++iter) - mColumnMap.insert (std::make_pair (*iter, - mSourceModel->searchColumnIndex (static_cast (*iter)))); + for (std::vector::const_iterator iter(columns.begin()); iter != columns.end(); ++iter) + mColumnMap.insert(std::make_pair( + *iter, mSourceModel->searchColumnIndex(static_cast(*iter)))); } } -bool CSMWorld::IdTableProxyModel::filterAcceptsRow (int sourceRow, const QModelIndex& sourceParent) - const +bool CSMWorld::IdTableProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const { Q_ASSERT(mSourceModel != nullptr); @@ -47,37 +46,34 @@ bool CSMWorld::IdTableProxyModel::filterAcceptsRow (int sourceRow, const QModelI if (!mFilter) return true; - return mFilter->test (*mSourceModel, sourceRow, mColumnMap); + return mFilter->test(*mSourceModel, sourceRow, mColumnMap); } -CSMWorld::IdTableProxyModel::IdTableProxyModel (QObject *parent) - : QSortFilterProxyModel (parent), - mSourceModel(nullptr) +CSMWorld::IdTableProxyModel::IdTableProxyModel(QObject* parent) + : QSortFilterProxyModel(parent) + , mSourceModel(nullptr) { - setSortCaseSensitivity (Qt::CaseInsensitive); + setSortCaseSensitivity(Qt::CaseInsensitive); } -QModelIndex CSMWorld::IdTableProxyModel::getModelIndex (const std::string& id, int column) const +QModelIndex CSMWorld::IdTableProxyModel::getModelIndex(const std::string& id, int column) const { Q_ASSERT(mSourceModel != nullptr); - return mapFromSource(mSourceModel->getModelIndex (id, column)); + return mapFromSource(mSourceModel->getModelIndex(id, column)); } -void CSMWorld::IdTableProxyModel::setSourceModel(QAbstractItemModel *model) +void CSMWorld::IdTableProxyModel::setSourceModel(QAbstractItemModel* model) { QSortFilterProxyModel::setSourceModel(model); - mSourceModel = dynamic_cast(sourceModel()); - connect(mSourceModel, &IdTableBase::rowsInserted, - this, &IdTableProxyModel::sourceRowsInserted); - connect(mSourceModel, &IdTableBase::rowsRemoved, - this, &IdTableProxyModel::sourceRowsRemoved); - connect(mSourceModel, &IdTableBase::dataChanged, - this, &IdTableProxyModel::sourceDataChanged); + mSourceModel = dynamic_cast(sourceModel()); + connect(mSourceModel, &IdTableBase::rowsInserted, this, &IdTableProxyModel::sourceRowsInserted); + connect(mSourceModel, &IdTableBase::rowsRemoved, this, &IdTableProxyModel::sourceRowsRemoved); + connect(mSourceModel, &IdTableBase::dataChanged, this, &IdTableProxyModel::sourceDataChanged); } -void CSMWorld::IdTableProxyModel::setFilter (const std::shared_ptr& filter) +void CSMWorld::IdTableProxyModel::setFilter(const std::shared_ptr& filter) { beginResetModel(); mFilter = filter; @@ -85,7 +81,7 @@ void CSMWorld::IdTableProxyModel::setFilter (const std::shared_ptr(left.data(ColumnBase::Role_ColumnId).toInt()); EnumColumnCache::const_iterator valuesIt = mEnumColumnCache.find(id); @@ -123,7 +119,7 @@ void CSMWorld::IdTableProxyModel::refreshFilter() } } -void CSMWorld::IdTableProxyModel::sourceRowsInserted(const QModelIndex &parent, int /*start*/, int end) +void CSMWorld::IdTableProxyModel::sourceRowsInserted(const QModelIndex& parent, int /*start*/, int end) { refreshFilter(); if (!parent.isValid()) @@ -132,12 +128,12 @@ void CSMWorld::IdTableProxyModel::sourceRowsInserted(const QModelIndex &parent, } } -void CSMWorld::IdTableProxyModel::sourceRowsRemoved(const QModelIndex &/*parent*/, int /*start*/, int /*end*/) +void CSMWorld::IdTableProxyModel::sourceRowsRemoved(const QModelIndex& /*parent*/, int /*start*/, int /*end*/) { refreshFilter(); } -void CSMWorld::IdTableProxyModel::sourceDataChanged(const QModelIndex &/*topLeft*/, const QModelIndex &/*bottomRight*/) +void CSMWorld::IdTableProxyModel::sourceDataChanged(const QModelIndex& /*topLeft*/, const QModelIndex& /*bottomRight*/) { refreshFilter(); } diff --git a/apps/opencs/model/world/idtableproxymodel.hpp b/apps/opencs/model/world/idtableproxymodel.hpp index 7e0563834a..2af94f4ccf 100644 --- a/apps/opencs/model/world/idtableproxymodel.hpp +++ b/apps/opencs/model/world/idtableproxymodel.hpp @@ -15,55 +15,51 @@ namespace CSMWorld { class IdTableProxyModel : public QSortFilterProxyModel { - Q_OBJECT + Q_OBJECT - std::shared_ptr mFilter; - std::map mColumnMap; // column ID, column index in this model (or -1) + std::shared_ptr mFilter; + std::map mColumnMap; // column ID, column index in this model (or -1) - // Cache of enum values for enum columns (e.g. Modified, Record Type). - // Used to speed up comparisons during the sort by such columns. - typedef std::map> > EnumColumnCache; - mutable EnumColumnCache mEnumColumnCache; + // Cache of enum values for enum columns (e.g. Modified, Record Type). + // Used to speed up comparisons during the sort by such columns. + typedef std::map>> EnumColumnCache; + mutable EnumColumnCache mEnumColumnCache; - protected: + protected: + IdTableBase* mSourceModel; - IdTableBase *mSourceModel; + private: + void updateColumnMap(); - private: + public: + IdTableProxyModel(QObject* parent = nullptr); - void updateColumnMap(); + virtual QModelIndex getModelIndex(const std::string& id, int column) const; - public: + void setSourceModel(QAbstractItemModel* model) override; - IdTableProxyModel (QObject *parent = nullptr); + void setFilter(const std::shared_ptr& filter); - virtual QModelIndex getModelIndex (const std::string& id, int column) const; + void refreshFilter(); - void setSourceModel(QAbstractItemModel *model) override; + protected: + bool lessThan(const QModelIndex& left, const QModelIndex& right) const override; - void setFilter (const std::shared_ptr& filter); + bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const override; - void refreshFilter(); + QString getRecordId(int sourceRow) const; - protected: + protected slots: - bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; + virtual void sourceRowsInserted(const QModelIndex& parent, int start, int end); - bool filterAcceptsRow (int sourceRow, const QModelIndex& sourceParent) const override; + virtual void sourceRowsRemoved(const QModelIndex& parent, int start, int end); - QString getRecordId(int sourceRow) const; + virtual void sourceDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); - protected slots: + signals: - virtual void sourceRowsInserted(const QModelIndex &parent, int start, int end); - - virtual void sourceRowsRemoved(const QModelIndex &parent, int start, int end); - - virtual void sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); - - signals: - - void rowAdded(const std::string &id); + void rowAdded(const std::string& id); }; } diff --git a/apps/opencs/model/world/idtree.cpp b/apps/opencs/model/world/idtree.cpp index 1e3398bbb2..35792ad532 100644 --- a/apps/opencs/model/world/idtree.cpp +++ b/apps/opencs/model/world/idtree.cpp @@ -3,18 +3,19 @@ #include "nestedtablewrapper.hpp" #include "collectionbase.hpp" -#include "nestedcollection.hpp" #include "columnbase.hpp" +#include "nestedcollection.hpp" // NOTE: parent class still needs idCollection -CSMWorld::IdTree::IdTree (NestedCollection *nestedCollection, CollectionBase *idCollection, unsigned int features) -: IdTable (idCollection, features), mNestedCollection (nestedCollection) -{} +CSMWorld::IdTree::IdTree(NestedCollection* nestedCollection, CollectionBase* idCollection, unsigned int features) + : IdTable(idCollection, features) + , mNestedCollection(nestedCollection) +{ +} -CSMWorld::IdTree::~IdTree() -{} +CSMWorld::IdTree::~IdTree() {} -int CSMWorld::IdTree::rowCount (const QModelIndex & parent) const +int CSMWorld::IdTree::rowCount(const QModelIndex& parent) const { if (hasChildren(parent)) return mNestedCollection->getNestedRowsCount(parent.row(), parent.column()); @@ -22,7 +23,7 @@ int CSMWorld::IdTree::rowCount (const QModelIndex & parent) const return IdTable::rowCount(parent); } -int CSMWorld::IdTree::columnCount (const QModelIndex & parent) const +int CSMWorld::IdTree::columnCount(const QModelIndex& parent) const { if (hasChildren(parent)) return mNestedCollection->getNestedColumnsCount(parent.row(), parent.column()); @@ -30,15 +31,15 @@ int CSMWorld::IdTree::columnCount (const QModelIndex & parent) const return IdTable::columnCount(parent); } -QVariant CSMWorld::IdTree::data (const QModelIndex & index, int role) const +QVariant CSMWorld::IdTree::data(const QModelIndex& index, int role) const { - if (!index.isValid()) - return QVariant(); + if (!index.isValid()) + return QVariant(); if (index.internalId() != 0) { std::pair parentAddress(unfoldIndexAddress(index.internalId())); - const NestableColumn *parentColumn = mNestedCollection->getNestableColumn(parentAddress.second); + const NestableColumn* parentColumn = mNestedCollection->getNestableColumn(parentAddress.second); if (role == ColumnBase::Role_Display) return parentColumn->nestedColumn(index.column()).mDisplayType; @@ -52,8 +53,7 @@ QVariant CSMWorld::IdTree::data (const QModelIndex & index, int role) const if (role != Qt::DisplayRole && role != Qt::EditRole) return QVariant(); - return mNestedCollection->getNestedData(parentAddress.first, - parentAddress.second, index.row(), index.column()); + return mNestedCollection->getNestedData(parentAddress.first, parentAddress.second, index.row(), index.column()); } else { @@ -66,35 +66,36 @@ QVariant CSMWorld::IdTree::nestedHeaderData(int section, int subSection, Qt::Ori if (section < 0 || section >= idCollection()->getColumns()) return QVariant(); - const NestableColumn *parentColumn = mNestedCollection->getNestableColumn(section); + const NestableColumn* parentColumn = mNestedCollection->getNestableColumn(section); - if (orientation==Qt::Vertical) + if (orientation == Qt::Vertical) return QVariant(); - if (role==Qt::DisplayRole) + if (role == Qt::DisplayRole) return tr(parentColumn->nestedColumn(subSection).getTitle().c_str()); - if (role==ColumnBase::Role_Flags) + if (role == ColumnBase::Role_Flags) return parentColumn->nestedColumn(subSection).mFlags; - if (role==ColumnBase::Role_Display) + if (role == ColumnBase::Role_Display) return parentColumn->nestedColumn(subSection).mDisplayType; - if (role==ColumnBase::Role_ColumnId) + if (role == ColumnBase::Role_ColumnId) return parentColumn->nestedColumn(subSection).mColumnId; return QVariant(); } -bool CSMWorld::IdTree::setData (const QModelIndex &index, const QVariant &value, int role) +bool CSMWorld::IdTree::setData(const QModelIndex& index, const QVariant& value, int role) { if (index.internalId() != 0) { - if (idCollection()->getColumn(parent(index).column()).isEditable() && role==Qt::EditRole) + if (idCollection()->getColumn(parent(index).column()).isEditable() && role == Qt::EditRole) { const std::pair& parentAddress(unfoldIndexAddress(index.internalId())); - mNestedCollection->setNestedData(parentAddress.first, parentAddress.second, value, index.row(), index.column()); + mNestedCollection->setNestedData( + parentAddress.first, parentAddress.second, value, index.row(), index.column()); emit dataChanged(index, index); // Modifying a value can also change the Modified status of a record. @@ -113,7 +114,7 @@ bool CSMWorld::IdTree::setData (const QModelIndex &index, const QVariant &value, return IdTable::setData(index, value, role); } -Qt::ItemFlags CSMWorld::IdTree::flags (const QModelIndex & index) const +Qt::ItemFlags CSMWorld::IdTree::flags(const QModelIndex& index) const { if (!index.isValid()) return Qt::ItemFlags(); @@ -133,21 +134,21 @@ Qt::ItemFlags CSMWorld::IdTree::flags (const QModelIndex & index) const return IdTable::flags(index); } -bool CSMWorld::IdTree::removeRows (int row, int count, const QModelIndex& parent) +bool CSMWorld::IdTree::removeRows(int row, int count, const QModelIndex& parent) { if (parent.isValid()) { - beginRemoveRows (parent, row, row+count-1); + beginRemoveRows(parent, row, row + count - 1); for (int i = 0; i < count; ++i) { - mNestedCollection->removeNestedRows(parent.row(), parent.column(), row+i); + mNestedCollection->removeNestedRows(parent.row(), parent.column(), row + i); } endRemoveRows(); - emit dataChanged (CSMWorld::IdTree::index (parent.row(), 0), - CSMWorld::IdTree::index (parent.row(), idCollection()->getColumns()-1)); + emit dataChanged(CSMWorld::IdTree::index(parent.row(), 0), + CSMWorld::IdTree::index(parent.row(), idCollection()->getColumns() - 1)); return true; } @@ -166,11 +167,10 @@ void CSMWorld::IdTree::addNestedRow(const QModelIndex& parent, int position) mNestedCollection->addNestedRow(row, parent.column(), position); endInsertRows(); - emit dataChanged (CSMWorld::IdTree::index (row, 0), - CSMWorld::IdTree::index (row, idCollection()->getColumns()-1)); + emit dataChanged(CSMWorld::IdTree::index(row, 0), CSMWorld::IdTree::index(row, idCollection()->getColumns() - 1)); } -QModelIndex CSMWorld::IdTree::index (int row, int column, const QModelIndex& parent) const +QModelIndex CSMWorld::IdTree::index(int row, int column, const QModelIndex& parent) const { unsigned int encodedId = 0; if (parent.isValid()) @@ -187,12 +187,12 @@ QModelIndex CSMWorld::IdTree::index (int row, int column, const QModelIndex& par return createIndex(row, column, encodedId); // store internal id } -QModelIndex CSMWorld::IdTree::getNestedModelIndex (const std::string& id, int column) const +QModelIndex CSMWorld::IdTree::getNestedModelIndex(const std::string& id, int column) const { - return CSMWorld::IdTable::index(idCollection()->getIndex (id), column); + return CSMWorld::IdTable::index(idCollection()->getIndex(id), column); } -QModelIndex CSMWorld::IdTree::parent (const QModelIndex& index) const +QModelIndex CSMWorld::IdTree::parent(const QModelIndex& index) const { if (index.internalId() == 0) // 0 is used for indexs with invalid parent (top level data) return QModelIndex(); @@ -206,14 +206,14 @@ QModelIndex CSMWorld::IdTree::parent (const QModelIndex& index) const return createIndex(address.first, address.second); } -unsigned int CSMWorld::IdTree::foldIndexAddress (const QModelIndex& index) const +unsigned int CSMWorld::IdTree::foldIndexAddress(const QModelIndex& index) const { unsigned int out = index.row() * this->columnCount(); out += index.column(); return ++out; } -std::pair< int, int > CSMWorld::IdTree::unfoldIndexAddress (unsigned int id) const +std::pair CSMWorld::IdTree::unfoldIndexAddress(unsigned int id) const { if (id == 0) throw std::runtime_error("Attempt to unfold index id of the top level data cell"); @@ -221,7 +221,7 @@ std::pair< int, int > CSMWorld::IdTree::unfoldIndexAddress (unsigned int id) con --id; int row = id / this->columnCount(); int column = id - row * this->columnCount(); - return std::make_pair (row, column); + return std::make_pair(row, column); } // FIXME: Not sure why this check is also needed? @@ -232,10 +232,8 @@ std::pair< int, int > CSMWorld::IdTree::unfoldIndexAddress (unsigned int id) con // Also see comments in refidadapter.hpp and refidadapterimp.hpp. bool CSMWorld::IdTree::hasChildren(const QModelIndex& index) const { - return (index.isValid() && - index.internalId() == 0 && - mNestedCollection->getNestableColumn(index.column())->hasChildren() && - index.data().isValid()); + return (index.isValid() && index.internalId() == 0 + && mNestedCollection->getNestableColumn(index.column())->hasChildren() && index.data().isValid()); } void CSMWorld::IdTree::setNestedTable(const QModelIndex& index, const CSMWorld::NestedTableWrapperBase& nestedTable) @@ -252,8 +250,8 @@ void CSMWorld::IdTree::setNestedTable(const QModelIndex& index, const CSMWorld:: mNestedCollection->setNestedTable(index.row(), index.column(), nestedTable); - emit dataChanged (CSMWorld::IdTree::index (index.row(), 0), - CSMWorld::IdTree::index (index.row(), idCollection()->getColumns()-1)); + emit dataChanged(CSMWorld::IdTree::index(index.row(), 0), + CSMWorld::IdTree::index(index.row(), idCollection()->getColumns() - 1)); if (removeRowsMode) { diff --git a/apps/opencs/model/world/idtree.hpp b/apps/opencs/model/world/idtree.hpp index 2793aac62d..1da219ecdf 100644 --- a/apps/opencs/model/world/idtree.hpp +++ b/apps/opencs/model/world/idtree.hpp @@ -1,8 +1,8 @@ #ifndef CSM_WOLRD_IDTREE_H #define CSM_WOLRD_IDTREE_H -#include "idtable.hpp" #include "columns.hpp" +#include "idtable.hpp" /*! \brief * Class for holding the model. Uses typical qt table abstraction/interface for granting access @@ -23,59 +23,58 @@ namespace CSMWorld class IdTree : public IdTable { - Q_OBJECT - - private: - - NestedCollection *mNestedCollection; + Q_OBJECT - // not implemented - IdTree (const IdTree&); - IdTree& operator= (const IdTree&); + private: + NestedCollection* mNestedCollection; - unsigned int foldIndexAddress(const QModelIndex& index) const; - std::pair unfoldIndexAddress(unsigned int id) const; + // not implemented + IdTree(const IdTree&); + IdTree& operator=(const IdTree&); - public: + unsigned int foldIndexAddress(const QModelIndex& index) const; + std::pair unfoldIndexAddress(unsigned int id) const; - IdTree (NestedCollection *nestedCollection, CollectionBase *idCollection, unsigned int features = 0); - ///< The ownerships of \a nestedCollecton and \a idCollection are not transferred. + public: + IdTree(NestedCollection* nestedCollection, CollectionBase* idCollection, unsigned int features = 0); + ///< The ownerships of \a nestedCollecton and \a idCollection are not transferred. - ~IdTree() override; + ~IdTree() override; - int rowCount (const QModelIndex & parent = QModelIndex()) const override; + int rowCount(const QModelIndex& parent = QModelIndex()) const override; - int columnCount (const QModelIndex & parent = QModelIndex()) const override; + int columnCount(const QModelIndex& parent = QModelIndex()) const override; - QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const override; + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; - bool setData ( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override; - Qt::ItemFlags flags (const QModelIndex & index) const override; + Qt::ItemFlags flags(const QModelIndex& index) const override; - bool removeRows (int row, int count, const QModelIndex& parent = QModelIndex()) override; + bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex()) override; - QModelIndex index (int row, int column, const QModelIndex& parent = QModelIndex()) const override; + QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override; - QModelIndex parent (const QModelIndex& index) const override; + QModelIndex parent(const QModelIndex& index) const override; - QModelIndex getNestedModelIndex (const std::string& id, int column) const; + QModelIndex getNestedModelIndex(const std::string& id, int column) const; - QVariant nestedHeaderData(int section, int subSection, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + QVariant nestedHeaderData( + int section, int subSection, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - NestedTableWrapperBase* nestedTable(const QModelIndex &index) const; + NestedTableWrapperBase* nestedTable(const QModelIndex& index) const; - void setNestedTable(const QModelIndex &index, const NestedTableWrapperBase& nestedTable); + void setNestedTable(const QModelIndex& index, const NestedTableWrapperBase& nestedTable); - void addNestedRow (const QModelIndex& parent, int position); + void addNestedRow(const QModelIndex& parent, int position); - bool hasChildren (const QModelIndex& index) const override; + bool hasChildren(const QModelIndex& index) const override; - virtual int searchNestedColumnIndex(int parentColumn, Columns::ColumnId id); - ///< \return the column index or -1 if the requested column wasn't found. + virtual int searchNestedColumnIndex(int parentColumn, Columns::ColumnId id); + ///< \return the column index or -1 if the requested column wasn't found. - virtual int findNestedColumnIndex(int parentColumn, Columns::ColumnId id); - ///< \return the column index or throws an exception if the requested column wasn't found. + virtual int findNestedColumnIndex(int parentColumn, Columns::ColumnId id); + ///< \return the column index or throws an exception if the requested column wasn't found. signals: diff --git a/apps/opencs/model/world/infocollection.cpp b/apps/opencs/model/world/infocollection.cpp index 0fc572e46f..a136b7c402 100644 --- a/apps/opencs/model/world/infocollection.cpp +++ b/apps/opencs/model/world/infocollection.cpp @@ -1,8 +1,8 @@ #include "infocollection.hpp" -#include -#include #include +#include +#include #include #include @@ -11,35 +11,34 @@ namespace CSMWorld { - template<> - void Collection >::removeRows (int index, int count) + template <> + void Collection>::removeRows(int index, int count) { - mRecords.erase(mRecords.begin()+index, mRecords.begin()+index+count); + mRecords.erase(mRecords.begin() + index, mRecords.begin() + index + count); // index map is updated in InfoCollection::removeRows() } - template<> - void Collection >::insertRecord (std::unique_ptr record, - int index, UniversalId::Type type) + template <> + void Collection>::insertRecord( + std::unique_ptr record, int index, UniversalId::Type type) { int size = static_cast(mRecords.size()); if (index < 0 || index > size) throw std::runtime_error("index out of range"); - std::unique_ptr > record2(static_cast*>(record.release())); + std::unique_ptr> record2(static_cast*>(record.release())); if (index == size) mRecords.push_back(std::move(record2)); else - mRecords.insert(mRecords.begin()+index, std::move(record2)); + mRecords.insert(mRecords.begin() + index, std::move(record2)); // index map is updated in InfoCollection::insertRecord() } - template<> - bool Collection >::reorderRowsImp (int baseIndex, - const std::vector& newOrder) + template <> + bool Collection>::reorderRowsImp(int baseIndex, const std::vector& newOrder) { if (!newOrder.empty()) { @@ -48,21 +47,21 @@ namespace CSMWorld // check that all indices are present std::vector test(newOrder); std::sort(test.begin(), test.end()); - if (*test.begin() != 0 || *--test.end() != size-1) + if (*test.begin() != 0 || *--test.end() != size - 1) return false; // reorder records - std::vector > > buffer(size); + std::vector>> buffer(size); // FIXME: BUG: undo does not remove modified flag for (int i = 0; i < size; ++i) { - buffer[newOrder[i]] = std::move(mRecords[baseIndex+i]); + buffer[newOrder[i]] = std::move(mRecords[baseIndex + i]); if (buffer[newOrder[i]]) buffer[newOrder[i]]->setModified(buffer[newOrder[i]]->get()); } - std::move(buffer.begin(), buffer.end(), mRecords.begin()+baseIndex); + std::move(buffer.begin(), buffer.end(), mRecords.begin() + baseIndex); // index map is updated in InfoCollection::reorderRows() } @@ -71,11 +70,11 @@ namespace CSMWorld } } -void CSMWorld::InfoCollection::load (const Info& record, bool base) +void CSMWorld::InfoCollection::load(const Info& record, bool base) { - int index = searchId (record.mId); + int index = searchId(record.mId); - if (index==-1) + if (index == -1) { // new record auto record2 = std::make_unique>(); @@ -92,24 +91,24 @@ void CSMWorld::InfoCollection::load (const Info& record, bool base) if (base) record2->mBase = record; else - record2->setModified (record); + record2->setModified(record); - setRecord (index, std::move(record2)); + setRecord(index, std::move(record2)); } } int CSMWorld::InfoCollection::getInfoIndex(std::string_view id, std::string_view topic) const { // find the topic first - std::unordered_map > >::const_iterator iter + std::unordered_map>>::const_iterator iter = mInfoIndex.find(Misc::StringUtils::lowerCase(topic)); if (iter == mInfoIndex.end()) return -1; // brute force loop - for (std::vector >::const_iterator it = iter->second.begin(); - it != iter->second.end(); ++it) + for (std::vector>::const_iterator it = iter->second.begin(); it != iter->second.end(); + ++it) { if (Misc::StringUtils::ciEqual(it->first, id)) return it->second; @@ -120,8 +119,7 @@ int CSMWorld::InfoCollection::getInfoIndex(std::string_view id, std::string_view // Calling insertRecord() using index from getInsertIndex() needs to take into account of // prev/next records; an example is deleting a record then undo -int CSMWorld::InfoCollection::getInsertIndex (const std::string& id, - UniversalId::Type type, RecordBase *record) const +int CSMWorld::InfoCollection::getInsertIndex(const std::string& id, UniversalId::Type type, RecordBase* record) const { if (record == nullptr) { @@ -133,7 +131,7 @@ int CSMWorld::InfoCollection::getInsertIndex (const std::string& id, std::pair range = getTopicRange(id.substr(0, separator)); if (range.first == range.second) - return Collection >::getAppendIndex(id, type); + return Collection>::getAppendIndex(id, type); return std::distance(getRecords().begin(), range.second); } @@ -170,21 +168,20 @@ int CSMWorld::InfoCollection::getInsertIndex (const std::string& id, return index; } -bool CSMWorld::InfoCollection::reorderRows (int baseIndex, const std::vector& newOrder) +bool CSMWorld::InfoCollection::reorderRows(int baseIndex, const std::vector& newOrder) { // check if the range is valid - int lastIndex = baseIndex + newOrder.size() -1; + int lastIndex = baseIndex + newOrder.size() - 1; - if (lastIndex>=getSize()) + if (lastIndex >= getSize()) return false; // Check that topics match - if (!Misc::StringUtils::ciEqual(getRecord(baseIndex).get().mTopicId, - getRecord(lastIndex).get().mTopicId)) + if (!Misc::StringUtils::ciEqual(getRecord(baseIndex).get().mTopicId, getRecord(lastIndex).get().mTopicId)) return false; // reorder - if (!Collection >::reorderRowsImp(baseIndex, newOrder)) + if (!Collection>::reorderRowsImp(baseIndex, newOrder)) return false; // adjust index @@ -197,19 +194,19 @@ bool CSMWorld::InfoCollection::reorderRows (int baseIndex, const std::vector>(getRecord(index)); record->mState = RecordBase::State_Deleted; - setRecord (index, std::move(record)); + setRecord(index, std::move(record)); } } else { info.mTopicId = dialogue.mId; info.mId = id; - load (info, base); + load(info, base); } } -CSMWorld::InfoCollection::Range CSMWorld::InfoCollection::getTopicRange (const std::string& topic) - const +CSMWorld::InfoCollection::Range CSMWorld::InfoCollection::getTopicRange(const std::string& topic) const { - std::string lowerTopic = Misc::StringUtils::lowerCase (topic); + std::string lowerTopic = Misc::StringUtils::lowerCase(topic); // find the topic - std::unordered_map > >::const_iterator iter + std::unordered_map>>::const_iterator iter = mInfoIndex.find(lowerTopic); if (iter == mInfoIndex.end()) - return Range (getRecords().end(), getRecords().end()); + return Range(getRecords().end(), getRecords().end()); // topic found, find the starting index int low = INT_MAX; - for (std::vector >::const_iterator it = iter->second.begin(); - it != iter->second.end(); ++it) + for (std::vector>::const_iterator it = iter->second.begin(); it != iter->second.end(); + ++it) { low = std::min(low, it->second); } @@ -261,7 +257,7 @@ CSMWorld::InfoCollection::Range CSMWorld::InfoCollection::getTopicRange (const s assert(static_cast(std::distance(begin, end)) == iter->second.size()); - return Range (begin, end); + return Range(begin, end); } void CSMWorld::InfoCollection::removeDialogueInfos(const std::string& dialogueId) @@ -302,19 +298,18 @@ void CSMWorld::InfoCollection::removeDialogueInfos(const std::string& dialogueId // FIXME: removing a record should adjust prev/next and mark those records as modified // accordingly (also consider undo) -void CSMWorld::InfoCollection::removeRows (int index, int count) +void CSMWorld::InfoCollection::removeRows(int index, int count) { - Collection >::removeRows(index, count); // erase records only + Collection>::removeRows(index, count); // erase records only - for (std::unordered_map > >::iterator iter - = mInfoIndex.begin(); iter != mInfoIndex.end();) + for (std::unordered_map>>::iterator iter = mInfoIndex.begin(); + iter != mInfoIndex.end();) { - for (std::vector >::iterator it = iter->second.begin(); - it != iter->second.end();) + for (std::vector>::iterator it = iter->second.begin(); it != iter->second.end();) { if (it->second >= index) { - if (it->second >= index+count) + if (it->second >= index + count) { it->second -= count; ++it; @@ -334,7 +329,7 @@ void CSMWorld::InfoCollection::removeRows (int index, int count) } } -void CSMWorld::InfoCollection::appendBlankRecord (const std::string& id, UniversalId::Type type) +void CSMWorld::InfoCollection::appendBlankRecord(const std::string& id, UniversalId::Type type) { auto record2 = std::make_unique>(); @@ -353,18 +348,17 @@ int CSMWorld::InfoCollection::searchId(std::string_view id) const if (separator == std::string::npos) throw std::runtime_error("invalid info ID: " + std::string(id)); - return getInfoIndex(id.substr(separator+1), id.substr(0, separator)); + return getInfoIndex(id.substr(separator + 1), id.substr(0, separator)); } -void CSMWorld::InfoCollection::appendRecord (std::unique_ptr record, UniversalId::Type type) +void CSMWorld::InfoCollection::appendRecord(std::unique_ptr record, UniversalId::Type type) { int index = getInsertIndex(static_cast*>(record.get())->get().mId, type, record.get()); insertRecord(std::move(record), index, type); } -void CSMWorld::InfoCollection::insertRecord (std::unique_ptr record, int index, - UniversalId::Type type) +void CSMWorld::InfoCollection::insertRecord(std::unique_ptr record, int index, UniversalId::Type type) { int size = static_cast(getRecords().size()); @@ -374,16 +368,17 @@ void CSMWorld::InfoCollection::insertRecord (std::unique_ptr record, if (separator == std::string::npos) throw std::runtime_error("invalid info ID: " + id); - Collection >::insertRecord(std::move(record), index, type); // add records only + Collection>::insertRecord(std::move(record), index, type); // add records only // adjust index - if (index < size-1) + if (index < size - 1) { - for (std::unordered_map > >::iterator iter - = mInfoIndex.begin(); iter != mInfoIndex.end(); ++iter) + for (std::unordered_map>>::iterator iter + = mInfoIndex.begin(); + iter != mInfoIndex.end(); ++iter) { - for (std::vector >::iterator it = iter->second.begin(); - it != iter->second.end(); ++it) + for (std::vector>::iterator it = iter->second.begin(); it != iter->second.end(); + ++it) { if (it->second >= index) ++(it->second); @@ -393,11 +388,10 @@ void CSMWorld::InfoCollection::insertRecord (std::unique_ptr record, // get iterator for existing topic or a new topic std::string lowerId = Misc::StringUtils::lowerCase(id); - std::pair > >::iterator, bool> res + std::pair>>::iterator, bool> res = mInfoIndex.insert( - std::make_pair(lowerId.substr(0, separator), - std::vector >())); // empty vector + std::make_pair(lowerId.substr(0, separator), std::vector>())); // empty vector // insert info and index - res.first->second.push_back(std::make_pair(lowerId.substr(separator+1), index)); + res.first->second.push_back(std::make_pair(lowerId.substr(separator + 1), index)); } diff --git a/apps/opencs/model/world/infocollection.hpp b/apps/opencs/model/world/infocollection.hpp index 96061fb03c..cfd74afd10 100644 --- a/apps/opencs/model/world/infocollection.hpp +++ b/apps/opencs/model/world/infocollection.hpp @@ -1,8 +1,8 @@ #ifndef CSM_WOLRD_INFOCOLLECTION_H #define CSM_WOLRD_INFOCOLLECTION_H -#include #include +#include #include "collection.hpp" #include "info.hpp" @@ -14,80 +14,72 @@ namespace ESM namespace CSMWorld { - template<> - void Collection >::removeRows (int index, int count); + template <> + void Collection>::removeRows(int index, int count); - template<> - void Collection >::insertRecord (std::unique_ptr record, - int index, UniversalId::Type type); + template <> + void Collection>::insertRecord( + std::unique_ptr record, int index, UniversalId::Type type); - template<> - bool Collection >::reorderRowsImp (int baseIndex, - const std::vector& newOrder); + template <> + bool Collection>::reorderRowsImp(int baseIndex, const std::vector& newOrder); - class InfoCollection : public Collection > + class InfoCollection : public Collection> { - public: - - typedef std::vector > >::const_iterator RecordConstIterator; - typedef std::pair Range; - - private: - - // The general strategy is to keep the records in Collection kept in order (within - // a topic group) while the index lookup maps are not ordered. It is assumed that - // each topic has a small number of infos, which allows the use of vectors for - // iterating through them without too much penalty. - // - // NOTE: topic string as well as id string are stored in lower case. - std::unordered_map > > mInfoIndex; + public: + typedef std::vector>>::const_iterator RecordConstIterator; + typedef std::pair Range; - void load (const Info& record, bool base); + private: + // The general strategy is to keep the records in Collection kept in order (within + // a topic group) while the index lookup maps are not ordered. It is assumed that + // each topic has a small number of infos, which allows the use of vectors for + // iterating through them without too much penalty. + // + // NOTE: topic string as well as id string are stored in lower case. + std::unordered_map>> mInfoIndex; - int getInfoIndex(std::string_view id, std::string_view topic) const; - ///< Return index for record \a id or -1 (if not present; deleted records are considered) - /// - /// \param id info ID without topic prefix - // - /// \attention id and topic are assumed to be in lower case + void load(const Info& record, bool base); - public: + int getInfoIndex(std::string_view id, std::string_view topic) const; + ///< Return index for record \a id or -1 (if not present; deleted records are considered) + /// + /// \param id info ID without topic prefix + // + /// \attention id and topic are assumed to be in lower case - int getInsertIndex (const std::string& id, - UniversalId::Type type = UniversalId::Type_None, - RecordBase *record = nullptr) const override; - ///< \param type Will be ignored, unless the collection supports multiple record types - /// - /// Works like getAppendIndex unless an overloaded method uses the record pointer - /// to get additional info about the record that results in an alternative index. + public: + int getInsertIndex(const std::string& id, UniversalId::Type type = UniversalId::Type_None, + RecordBase* record = nullptr) const override; + ///< \param type Will be ignored, unless the collection supports multiple record types + /// + /// Works like getAppendIndex unless an overloaded method uses the record pointer + /// to get additional info about the record that results in an alternative index. - bool reorderRows (int baseIndex, const std::vector& newOrder) override; - ///< Reorder the rows [baseIndex, baseIndex+newOrder.size()) according to the indices - /// given in \a newOrder (baseIndex+newOrder[0] specifies the new index of row baseIndex). - /// - /// \return Success? + bool reorderRows(int baseIndex, const std::vector& newOrder) override; + ///< Reorder the rows [baseIndex, baseIndex+newOrder.size()) according to the indices + /// given in \a newOrder (baseIndex+newOrder[0] specifies the new index of row baseIndex). + /// + /// \return Success? - void load (ESM::ESMReader& reader, bool base, const ESM::Dialogue& dialogue); + void load(ESM::ESMReader& reader, bool base, const ESM::Dialogue& dialogue); - Range getTopicRange (const std::string& topic) const; - ///< Return iterators that point to the beginning and past the end of the range for - /// the given topic. + Range getTopicRange(const std::string& topic) const; + ///< Return iterators that point to the beginning and past the end of the range for + /// the given topic. - void removeDialogueInfos(const std::string& dialogueId); + void removeDialogueInfos(const std::string& dialogueId); - void removeRows (int index, int count) override; + void removeRows(int index, int count) override; - void appendBlankRecord (const std::string& id, - UniversalId::Type type = UniversalId::Type_None) override; + void appendBlankRecord(const std::string& id, UniversalId::Type type = UniversalId::Type_None) override; - int searchId(std::string_view id) const override; + int searchId(std::string_view id) const override; - void appendRecord (std::unique_ptr record, - UniversalId::Type type = UniversalId::Type_None) override; + void appendRecord(std::unique_ptr record, UniversalId::Type type = UniversalId::Type_None) override; - void insertRecord (std::unique_ptr record, - int index, - UniversalId::Type type = UniversalId::Type_None) override; + void insertRecord( + std::unique_ptr record, int index, UniversalId::Type type = UniversalId::Type_None) override; }; } diff --git a/apps/opencs/model/world/infoselectwrapper.cpp b/apps/opencs/model/world/infoselectwrapper.cpp index dc1b336f03..1fdff35dfe 100644 --- a/apps/opencs/model/world/infoselectwrapper.cpp +++ b/apps/opencs/model/world/infoselectwrapper.cpp @@ -11,8 +11,7 @@ const size_t CSMWorld::ConstInfoSelectWrapper::FunctionIndexOffset = 2; const size_t CSMWorld::ConstInfoSelectWrapper::RelationIndexOffset = 4; const size_t CSMWorld::ConstInfoSelectWrapper::VarNameOffset = 5; -const char* CSMWorld::ConstInfoSelectWrapper::FunctionEnumStrings[] = -{ +const char* CSMWorld::ConstInfoSelectWrapper::FunctionEnumStrings[] = { "Rank Low", "Rank High", "Rank Requirement", @@ -101,8 +100,7 @@ const char* CSMWorld::ConstInfoSelectWrapper::FunctionEnumStrings[] = nullptr, }; -const char* CSMWorld::ConstInfoSelectWrapper::RelationEnumStrings[] = -{ +const char* CSMWorld::ConstInfoSelectWrapper::RelationEnumStrings[] = { "=", "!=", ">", @@ -112,8 +110,7 @@ const char* CSMWorld::ConstInfoSelectWrapper::RelationEnumStrings[] = nullptr, }; -const char* CSMWorld::ConstInfoSelectWrapper::ComparisonEnumStrings[] = -{ +const char* CSMWorld::ConstInfoSelectWrapper::ComparisonEnumStrings[] = { "Boolean", "Integer", "Numeric", @@ -298,18 +295,42 @@ void CSMWorld::ConstInfoSelectWrapper::readFunctionName() mFunctionName = Function_None; break; - case '2': mFunctionName = Function_Global; break; - case '3': mFunctionName = Function_Local; break; - case '4': mFunctionName = Function_Journal; break; - case '5': mFunctionName = Function_Item; break; - case '6': mFunctionName = Function_Dead; break; - case '7': mFunctionName = Function_NotId; break; - case '8': mFunctionName = Function_NotFaction; break; - case '9': mFunctionName = Function_NotClass; break; - case 'A': mFunctionName = Function_NotRace; break; - case 'B': mFunctionName = Function_NotCell; break; - case 'C': mFunctionName = Function_NotLocal; break; - default: mFunctionName = Function_None; break; + case '2': + mFunctionName = Function_Global; + break; + case '3': + mFunctionName = Function_Local; + break; + case '4': + mFunctionName = Function_Journal; + break; + case '5': + mFunctionName = Function_Item; + break; + case '6': + mFunctionName = Function_Dead; + break; + case '7': + mFunctionName = Function_NotId; + break; + case '8': + mFunctionName = Function_NotFaction; + break; + case '9': + mFunctionName = Function_NotClass; + break; + case 'A': + mFunctionName = Function_NotRace; + break; + case 'B': + mFunctionName = Function_NotCell; + break; + case 'C': + mFunctionName = Function_NotLocal; + break; + default: + mFunctionName = Function_None; + break; } } @@ -319,13 +340,26 @@ void CSMWorld::ConstInfoSelectWrapper::readRelationType() switch (relationIndex) { - case '0': mRelationType = Relation_Equal; break; - case '1': mRelationType = Relation_NotEqual; break; - case '2': mRelationType = Relation_Greater; break; - case '3': mRelationType = Relation_GreaterOrEqual; break; - case '4': mRelationType = Relation_Less; break; - case '5': mRelationType = Relation_LessOrEqual; break; - default: mRelationType = Relation_None; + case '0': + mRelationType = Relation_Equal; + break; + case '1': + mRelationType = Relation_NotEqual; + break; + case '2': + mRelationType = Relation_Greater; + break; + case '3': + mRelationType = Relation_GreaterOrEqual; + break; + case '4': + mRelationType = Relation_Less; + break; + case '5': + mRelationType = Relation_LessOrEqual; + break; + default: + mRelationType = Relation_None; } } @@ -700,38 +734,37 @@ std::pair CSMWorld::ConstInfoSelectWrapper::getValidFloatRange() c } template -bool CSMWorld::ConstInfoSelectWrapper::rangeContains(T1 value, std::pair range) const +bool CSMWorld::ConstInfoSelectWrapper::rangeContains(T1 value, std::pair range) const { return (value >= range.first && value <= range.second); } template -bool CSMWorld::ConstInfoSelectWrapper::rangeFullyContains(std::pair containingRange, - std::pair testRange) const +bool CSMWorld::ConstInfoSelectWrapper::rangeFullyContains( + std::pair containingRange, std::pair testRange) const { return (containingRange.first <= testRange.first) && (testRange.second <= containingRange.second); } template -bool CSMWorld::ConstInfoSelectWrapper::rangesOverlap(std::pair range1, std::pair range2) const +bool CSMWorld::ConstInfoSelectWrapper::rangesOverlap(std::pair range1, std::pair range2) const { // One of the bounds of either range should fall within the other range - return - (range1.first <= range2.first && range2.first <= range1.second) || - (range1.first <= range2.second && range2.second <= range1.second) || - (range2.first <= range1.first && range1.first <= range2.second) || - (range2.first <= range1.second && range1.second <= range2.second); + return (range1.first <= range2.first && range2.first <= range1.second) + || (range1.first <= range2.second && range2.second <= range1.second) + || (range2.first <= range1.first && range1.first <= range2.second) + || (range2.first <= range1.second && range1.second <= range2.second); } template -bool CSMWorld::ConstInfoSelectWrapper::rangesMatch(std::pair range1, std::pair range2) const +bool CSMWorld::ConstInfoSelectWrapper::rangesMatch(std::pair range1, std::pair range2) const { - return (range1.first == range2.first && range1.second == range2.second); + return (range1.first == range2.first && range1.second == range2.second); } template -bool CSMWorld::ConstInfoSelectWrapper::conditionIsAlwaysTrue(std::pair conditionRange, - std::pair validRange) const +bool CSMWorld::ConstInfoSelectWrapper::conditionIsAlwaysTrue( + std::pair conditionRange, std::pair validRange) const { switch (mRelationType) { @@ -757,8 +790,8 @@ bool CSMWorld::ConstInfoSelectWrapper::conditionIsAlwaysTrue(std::pair co } template -bool CSMWorld::ConstInfoSelectWrapper::conditionIsNeverTrue(std::pair conditionRange, - std::pair validRange) const +bool CSMWorld::ConstInfoSelectWrapper::conditionIsNeverTrue( + std::pair conditionRange, std::pair validRange) const { switch (mRelationType) { @@ -785,7 +818,8 @@ bool CSMWorld::ConstInfoSelectWrapper::conditionIsNeverTrue(std::pair con // InfoSelectWrapper CSMWorld::InfoSelectWrapper::InfoSelectWrapper(ESM::DialInfo::SelectStruct& select) - : CSMWorld::ConstInfoSelectWrapper(select), mSelect(select) + : CSMWorld::ConstInfoSelectWrapper(select) + , mSelect(select) { } @@ -846,19 +880,46 @@ void CSMWorld::InfoSelectWrapper::update() switch (mFunctionName) { - case Function_None: stream << '0'; break; - case Function_Global: stream << '2'; break; - case Function_Local: stream << '3'; break; - case Function_Journal: stream << '4'; break; - case Function_Item: stream << '5'; break; - case Function_Dead: stream << '6'; break; - case Function_NotId: stream << '7'; break; - case Function_NotFaction: stream << '8'; break; - case Function_NotClass: stream << '9'; break; - case Function_NotRace: stream << 'A'; break; - case Function_NotCell: stream << 'B'; break; - case Function_NotLocal: stream << 'C'; break; - default: stream << '1'; writeIndex = true; break; + case Function_None: + stream << '0'; + break; + case Function_Global: + stream << '2'; + break; + case Function_Local: + stream << '3'; + break; + case Function_Journal: + stream << '4'; + break; + case Function_Item: + stream << '5'; + break; + case Function_Dead: + stream << '6'; + break; + case Function_NotId: + stream << '7'; + break; + case Function_NotFaction: + stream << '8'; + break; + case Function_NotClass: + stream << '9'; + break; + case Function_NotRace: + stream << 'A'; + break; + case Function_NotCell: + stream << 'B'; + break; + case Function_NotLocal: + stream << 'C'; + break; + default: + stream << '1'; + writeIndex = true; + break; } if (writeIndex && functionIndex < 10) // leading 0 @@ -871,13 +932,27 @@ void CSMWorld::InfoSelectWrapper::update() // Write Relation switch (mRelationType) { - case Relation_Equal: stream << '0'; break; - case Relation_NotEqual: stream << '1'; break; - case Relation_Greater: stream << '2'; break; - case Relation_GreaterOrEqual: stream << '3'; break; - case Relation_Less: stream << '4'; break; - case Relation_LessOrEqual: stream << '5'; break; - default: stream << '0'; break; + case Relation_Equal: + stream << '0'; + break; + case Relation_NotEqual: + stream << '1'; + break; + case Relation_Greater: + stream << '2'; + break; + case Relation_GreaterOrEqual: + stream << '3'; + break; + case Relation_Less: + stream << '4'; + break; + case Relation_LessOrEqual: + stream << '5'; + break; + default: + stream << '0'; + break; } if (mHasVariable) diff --git a/apps/opencs/model/world/infoselectwrapper.hpp b/apps/opencs/model/world/infoselectwrapper.hpp index 7c7a839fa6..6df763c345 100644 --- a/apps/opencs/model/world/infoselectwrapper.hpp +++ b/apps/opencs/model/world/infoselectwrapper.hpp @@ -20,11 +20,10 @@ namespace CSMWorld class ConstInfoSelectWrapper { public: - // Order matters enum FunctionName { - Function_RankLow=0, + Function_RankLow = 0, Function_RankHigh, Function_RankRequirement, Function_Reputation, @@ -97,7 +96,7 @@ namespace CSMWorld Function_Flee, Function_ShouldAttack, Function_Werewolf, - Function_PcWerewolfKills=73, + Function_PcWerewolfKills = 73, Function_Global, Function_Local, @@ -168,7 +167,6 @@ namespace CSMWorld std::string toString() const; protected: - void readRule(); void readFunctionName(); void readRelationType(); @@ -183,22 +181,22 @@ namespace CSMWorld std::pair getValidFloatRange() const; template - bool rangeContains(Type1 value, std::pair range) const; + bool rangeContains(Type1 value, std::pair range) const; template - bool rangesOverlap(std::pair range1, std::pair range2) const; + bool rangesOverlap(std::pair range1, std::pair range2) const; template - bool rangeFullyContains(std::pair containing, std::pair test) const; + bool rangeFullyContains(std::pair containing, std::pair test) const; template - bool rangesMatch(std::pair range1, std::pair range2) const; + bool rangesMatch(std::pair range1, std::pair range2) const; template - bool conditionIsAlwaysTrue(std::pair conditionRange, std::pair validRange) const; + bool conditionIsAlwaysTrue(std::pair conditionRange, std::pair validRange) const; template - bool conditionIsNeverTrue(std::pair conditionRange, std::pair validRange) const; + bool conditionIsNeverTrue(std::pair conditionRange, std::pair validRange) const; FunctionName mFunctionName; RelationType mRelationType; @@ -208,7 +206,6 @@ namespace CSMWorld std::string mVariableName; private: - const ESM::DialInfo::SelectStruct& mConstSelect; }; @@ -216,7 +213,6 @@ namespace CSMWorld class InfoSelectWrapper : public ConstInfoSelectWrapper { public: - InfoSelectWrapper(ESM::DialInfo::SelectStruct& select); // Wrapped SelectStruct will not be modified until update() is called @@ -233,7 +229,6 @@ namespace CSMWorld ESM::Variant& getVariant(); private: - ESM::DialInfo::SelectStruct& mSelect; void writeRule(); diff --git a/apps/opencs/model/world/infotableproxymodel.cpp b/apps/opencs/model/world/infotableproxymodel.cpp index e6d024311e..9446ba6b86 100644 --- a/apps/opencs/model/world/infotableproxymodel.cpp +++ b/apps/opencs/model/world/infotableproxymodel.cpp @@ -2,29 +2,28 @@ #include -#include "idtablebase.hpp" #include "columns.hpp" +#include "idtablebase.hpp" namespace { - QString toLower(const QString &str) + QString toLower(const QString& str) { return QString::fromUtf8(Misc::StringUtils::lowerCase(str.toUtf8().constData()).c_str()); } } -CSMWorld::InfoTableProxyModel::InfoTableProxyModel(CSMWorld::UniversalId::Type type, QObject *parent) - : IdTableProxyModel(parent), - mType(type), - mInfoColumnId(type == UniversalId::Type_TopicInfos ? Columns::ColumnId_Topic : - Columns::ColumnId_Journal), - mInfoColumnIndex(-1), - mLastAddedSourceRow(-1) +CSMWorld::InfoTableProxyModel::InfoTableProxyModel(CSMWorld::UniversalId::Type type, QObject* parent) + : IdTableProxyModel(parent) + , mType(type) + , mInfoColumnId(type == UniversalId::Type_TopicInfos ? Columns::ColumnId_Topic : Columns::ColumnId_Journal) + , mInfoColumnIndex(-1) + , mLastAddedSourceRow(-1) { Q_ASSERT(type == UniversalId::Type_TopicInfos || type == UniversalId::Type_JournalInfos); } -void CSMWorld::InfoTableProxyModel::setSourceModel(QAbstractItemModel *sourceModel) +void CSMWorld::InfoTableProxyModel::setSourceModel(QAbstractItemModel* sourceModel) { IdTableProxyModel::setSourceModel(sourceModel); @@ -35,7 +34,7 @@ void CSMWorld::InfoTableProxyModel::setSourceModel(QAbstractItemModel *sourceMod } } -bool CSMWorld::InfoTableProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const +bool CSMWorld::InfoTableProxyModel::lessThan(const QModelIndex& left, const QModelIndex& right) const { Q_ASSERT(mSourceModel != nullptr); @@ -63,21 +62,21 @@ int CSMWorld::InfoTableProxyModel::getFirstInfoRow(int currentRow) const return mFirstRowCache[info]; } - while (--row >= 0 && - toLower(mSourceModel->data(mSourceModel->index(row, column)).toString()) == info); + while (--row >= 0 && toLower(mSourceModel->data(mSourceModel->index(row, column)).toString()) == info) + ; ++row; mFirstRowCache[info] = row; return row; } -void CSMWorld::InfoTableProxyModel::sourceRowsRemoved(const QModelIndex &/*parent*/, int /*start*/, int /*end*/) +void CSMWorld::InfoTableProxyModel::sourceRowsRemoved(const QModelIndex& /*parent*/, int /*start*/, int /*end*/) { refreshFilter(); mFirstRowCache.clear(); } -void CSMWorld::InfoTableProxyModel::sourceRowsInserted(const QModelIndex &parent, int /*start*/, int end) +void CSMWorld::InfoTableProxyModel::sourceRowsInserted(const QModelIndex& parent, int /*start*/, int end) { refreshFilter(); @@ -90,19 +89,18 @@ void CSMWorld::InfoTableProxyModel::sourceRowsInserted(const QModelIndex &parent } } -void CSMWorld::InfoTableProxyModel::sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) +void CSMWorld::InfoTableProxyModel::sourceDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) { refreshFilter(); - if (mLastAddedSourceRow != -1 && - topLeft.row() <= mLastAddedSourceRow && bottomRight.row() >= mLastAddedSourceRow) + if (mLastAddedSourceRow != -1 && topLeft.row() <= mLastAddedSourceRow && bottomRight.row() >= mLastAddedSourceRow) { - // Now the topic of the last added row is set, + // Now the topic of the last added row is set, // so we can re-sort the model to ensure the corrent position of this row int column = sortColumn(); Qt::SortOrder order = sortOrder(); sort(mInfoColumnIndex); // Restore the correct position of an added row - sort(column, order); // Restore the original sort order + sort(column, order); // Restore the original sort order emit rowAdded(getRecordId(mLastAddedSourceRow).toUtf8().constData()); // Make sure that we perform a re-sorting only in the first dataChanged() after a row insertion diff --git a/apps/opencs/model/world/infotableproxymodel.hpp b/apps/opencs/model/world/infotableproxymodel.hpp index 92afdabdc5..5bf0c86039 100644 --- a/apps/opencs/model/world/infotableproxymodel.hpp +++ b/apps/opencs/model/world/infotableproxymodel.hpp @@ -3,8 +3,8 @@ #include -#include "idtableproxymodel.hpp" #include "columns.hpp" +#include "idtableproxymodel.hpp" #include "universalid.hpp" namespace CSMWorld @@ -13,32 +13,32 @@ namespace CSMWorld class InfoTableProxyModel : public IdTableProxyModel { - Q_OBJECT + Q_OBJECT - UniversalId::Type mType; - Columns::ColumnId mInfoColumnId; - ///< Contains ID for Topic or Journal ID - int mInfoColumnIndex; - int mLastAddedSourceRow; + UniversalId::Type mType; + Columns::ColumnId mInfoColumnId; + ///< Contains ID for Topic or Journal ID + int mInfoColumnIndex; + int mLastAddedSourceRow; - mutable QHash mFirstRowCache; + mutable QHash mFirstRowCache; - int getFirstInfoRow(int currentRow) const; - ///< Finds the first row with the same topic (journal entry) as in \a currentRow - ///< \a currentRow is a row of the source model. + int getFirstInfoRow(int currentRow) const; + ///< Finds the first row with the same topic (journal entry) as in \a currentRow + ///< \a currentRow is a row of the source model. - public: - InfoTableProxyModel(UniversalId::Type type, QObject *parent = nullptr); + public: + InfoTableProxyModel(UniversalId::Type type, QObject* parent = nullptr); - void setSourceModel(QAbstractItemModel *sourceModel) override; + void setSourceModel(QAbstractItemModel* sourceModel) override; - protected: - bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; + protected: + bool lessThan(const QModelIndex& left, const QModelIndex& right) const override; - protected slots: - void sourceRowsInserted(const QModelIndex &parent, int start, int end) override; - void sourceRowsRemoved(const QModelIndex &parent, int start, int end) override; - void sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) override; + protected slots: + void sourceRowsInserted(const QModelIndex& parent, int start, int end) override; + void sourceRowsRemoved(const QModelIndex& parent, int start, int end) override; + void sourceDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) override; }; } diff --git a/apps/opencs/model/world/land.cpp b/apps/opencs/model/world/land.cpp index bfa927444e..e5264039e7 100644 --- a/apps/opencs/model/world/land.cpp +++ b/apps/opencs/model/world/land.cpp @@ -5,7 +5,7 @@ namespace CSMWorld { - void Land::load(ESM::ESMReader &esm, bool &isDeleted) + void Land::load(ESM::ESMReader& esm, bool& isDeleted) { ESM::Land::load(esm, isDeleted); } diff --git a/apps/opencs/model/world/land.hpp b/apps/opencs/model/world/land.hpp index 99da5cfac0..67261066f4 100644 --- a/apps/opencs/model/world/land.hpp +++ b/apps/opencs/model/world/land.hpp @@ -13,7 +13,7 @@ namespace CSMWorld struct Land : public ESM::Land { /// Loads the metadata and ID - void load (ESM::ESMReader &esm, bool &isDeleted); + void load(ESM::ESMReader& esm, bool& isDeleted); static std::string createUniqueRecordId(int x, int y); static void parseUniqueRecordId(const std::string& id, int& x, int& y); diff --git a/apps/opencs/model/world/landtexture.cpp b/apps/opencs/model/world/landtexture.cpp index c8ac8369ed..9b11b348fc 100644 --- a/apps/opencs/model/world/landtexture.cpp +++ b/apps/opencs/model/world/landtexture.cpp @@ -7,7 +7,7 @@ namespace CSMWorld { - void LandTexture::load(ESM::ESMReader &esm, bool &isDeleted) + void LandTexture::load(ESM::ESMReader& esm, bool& isDeleted) { ESM::LandTexture::load(esm, isDeleted); @@ -28,7 +28,7 @@ namespace CSMWorld if (middle == std::string::npos || id[0] != 'L') throw std::runtime_error("Invalid LandTexture ID"); - plugin = std::stoi(id.substr(1,middle-1)); - index = std::stoi(id.substr(middle+1)); + plugin = std::stoi(id.substr(1, middle - 1)); + index = std::stoi(id.substr(middle + 1)); } } diff --git a/apps/opencs/model/world/landtexture.hpp b/apps/opencs/model/world/landtexture.hpp index 601d4b79c9..27e9d0d4f1 100644 --- a/apps/opencs/model/world/landtexture.hpp +++ b/apps/opencs/model/world/landtexture.hpp @@ -12,7 +12,7 @@ namespace CSMWorld { int mPluginIndex; - void load (ESM::ESMReader &esm, bool &isDeleted); + void load(ESM::ESMReader& esm, bool& isDeleted); /// Returns a string identifier that will be unique to any LandTexture. static std::string createUniqueRecordId(int plugin, int index); diff --git a/apps/opencs/model/world/landtexturetableproxymodel.cpp b/apps/opencs/model/world/landtexturetableproxymodel.cpp index e064bbe8aa..b1249c5580 100644 --- a/apps/opencs/model/world/landtexturetableproxymodel.cpp +++ b/apps/opencs/model/world/landtexturetableproxymodel.cpp @@ -9,7 +9,7 @@ namespace CSMWorld { } - bool LandTextureTableProxyModel::filterAcceptsRow (int sourceRow, const QModelIndex& sourceParent) const + bool LandTextureTableProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const { return IdTableProxyModel::filterAcceptsRow(sourceRow, sourceParent); } diff --git a/apps/opencs/model/world/landtexturetableproxymodel.hpp b/apps/opencs/model/world/landtexturetableproxymodel.hpp index bbedecb538..8609381585 100644 --- a/apps/opencs/model/world/landtexturetableproxymodel.hpp +++ b/apps/opencs/model/world/landtexturetableproxymodel.hpp @@ -8,14 +8,12 @@ namespace CSMWorld /// \brief Removes base records from filtered results. class LandTextureTableProxyModel : public IdTableProxyModel { - Q_OBJECT - public: + Q_OBJECT + public: + LandTextureTableProxyModel(QObject* parent = nullptr); - LandTextureTableProxyModel(QObject* parent = nullptr); - - protected: - - bool filterAcceptsRow (int sourceRow, const QModelIndex& sourceParent) const override; + protected: + bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const override; }; } diff --git a/apps/opencs/model/world/metadata.cpp b/apps/opencs/model/world/metadata.cpp index e7d6c8900c..d747515c86 100644 --- a/apps/opencs/model/world/metadata.cpp +++ b/apps/opencs/model/world/metadata.cpp @@ -1,8 +1,8 @@ #include "metadata.hpp" -#include #include #include +#include void CSMWorld::MetaData::blank() { @@ -13,16 +13,16 @@ void CSMWorld::MetaData::blank() mDescription.clear(); } -void CSMWorld::MetaData::load (ESM::ESMReader& esm) +void CSMWorld::MetaData::load(ESM::ESMReader& esm) { mFormat = esm.getHeader().mFormat; mAuthor = esm.getHeader().mData.author; mDescription = esm.getHeader().mData.desc; } -void CSMWorld::MetaData::save (ESM::ESMWriter& esm) const +void CSMWorld::MetaData::save(ESM::ESMWriter& esm) const { - esm.setFormat (mFormat); - esm.setAuthor (mAuthor); - esm.setDescription (mDescription); + esm.setFormat(mFormat); + esm.setAuthor(mAuthor); + esm.setDescription(mDescription); } diff --git a/apps/opencs/model/world/metadata.hpp b/apps/opencs/model/world/metadata.hpp index f8df2690ec..330551b1e2 100644 --- a/apps/opencs/model/world/metadata.hpp +++ b/apps/opencs/model/world/metadata.hpp @@ -21,8 +21,8 @@ namespace CSMWorld void blank(); - void load (ESM::ESMReader& esm); - void save (ESM::ESMWriter& esm) const; + void load(ESM::ESMReader& esm); + void save(ESM::ESMWriter& esm) const; }; } diff --git a/apps/opencs/model/world/nestedcoladapterimp.cpp b/apps/opencs/model/world/nestedcoladapterimp.cpp index 131c71d5a0..8951a97c1e 100644 --- a/apps/opencs/model/world/nestedcoladapterimp.cpp +++ b/apps/opencs/model/world/nestedcoladapterimp.cpp @@ -1,16 +1,16 @@ #include "nestedcoladapterimp.hpp" -#include #include +#include #include "idcollection.hpp" -#include "pathgrid.hpp" #include "info.hpp" #include "infoselectwrapper.hpp" +#include "pathgrid.hpp" namespace CSMWorld { - PathgridPointListAdapter::PathgridPointListAdapter () {} + PathgridPointListAdapter::PathgridPointListAdapter() {} void PathgridPointListAdapter::addRow(Record& record, int position) const { @@ -27,10 +27,10 @@ namespace CSMWorld point.mConnectionNum = 0; point.mUnknown = 0; - points.insert(points.begin()+position, point); + points.insert(points.begin() + position, point); pathgrid.mData.mS2 = pathgrid.mPoints.size(); - record.setModified (pathgrid); + record.setModified(pathgrid); } void PathgridPointListAdapter::removeRow(Record& record, int rowToRemove) const @@ -39,25 +39,24 @@ namespace CSMWorld ESM::Pathgrid::PointList& points = pathgrid.mPoints; - if (rowToRemove < 0 || rowToRemove >= static_cast (points.size())) - throw std::runtime_error ("index out of range"); + if (rowToRemove < 0 || rowToRemove >= static_cast(points.size())) + throw std::runtime_error("index out of range"); // Do not remove dangling edges, does not work with current undo mechanism // Do not automatically adjust indices, what would be done with dangling edges? - points.erase(points.begin()+rowToRemove); + points.erase(points.begin() + rowToRemove); pathgrid.mData.mS2 = pathgrid.mPoints.size(); - record.setModified (pathgrid); + record.setModified(pathgrid); } - void PathgridPointListAdapter::setTable(Record& record, - const NestedTableWrapperBase& nestedTable) const + void PathgridPointListAdapter::setTable(Record& record, const NestedTableWrapperBase& nestedTable) const { Pathgrid pathgrid = record.get(); - pathgrid.mPoints = static_cast &>(nestedTable).mNestedTable; + pathgrid.mPoints = static_cast&>(nestedTable).mNestedTable; pathgrid.mData.mS2 = pathgrid.mPoints.size(); - record.setModified (pathgrid); + record.setModified(pathgrid); } NestedTableWrapperBase* PathgridPointListAdapter::table(const Record& record) const @@ -66,37 +65,49 @@ namespace CSMWorld return new NestedTableWrapper(record.get().mPoints); } - QVariant PathgridPointListAdapter::getData(const Record& record, - int subRowIndex, int subColIndex) const + QVariant PathgridPointListAdapter::getData(const Record& record, int subRowIndex, int subColIndex) const { ESM::Pathgrid::Point point = record.get().mPoints[subRowIndex]; switch (subColIndex) { - case 0: return subRowIndex; - case 1: return point.mX; - case 2: return point.mY; - case 3: return point.mZ; - default: throw std::runtime_error("Pathgrid point subcolumn index out of range"); + case 0: + return subRowIndex; + case 1: + return point.mX; + case 2: + return point.mY; + case 3: + return point.mZ; + default: + throw std::runtime_error("Pathgrid point subcolumn index out of range"); } } - void PathgridPointListAdapter::setData(Record& record, - const QVariant& value, int subRowIndex, int subColIndex) const + void PathgridPointListAdapter::setData( + Record& record, const QVariant& value, int subRowIndex, int subColIndex) const { Pathgrid pathgrid = record.get(); ESM::Pathgrid::Point point = pathgrid.mPoints[subRowIndex]; switch (subColIndex) { - case 0: return; // return without saving - case 1: point.mX = value.toInt(); break; - case 2: point.mY = value.toInt(); break; - case 3: point.mZ = value.toInt(); break; - default: throw std::runtime_error("Pathgrid point subcolumn index out of range"); + case 0: + return; // return without saving + case 1: + point.mX = value.toInt(); + break; + case 2: + point.mY = value.toInt(); + break; + case 3: + point.mZ = value.toInt(); + break; + default: + throw std::runtime_error("Pathgrid point subcolumn index out of range"); } pathgrid.mPoints[subRowIndex] = point; - record.setModified (pathgrid); + record.setModified(pathgrid); } int PathgridPointListAdapter::getColumnsCount(const Record& record) const @@ -109,7 +120,7 @@ namespace CSMWorld return static_cast(record.get().mPoints.size()); } - PathgridEdgeListAdapter::PathgridEdgeListAdapter () {} + PathgridEdgeListAdapter::PathgridEdgeListAdapter() {} void PathgridEdgeListAdapter::addRow(Record& record, int position) const { @@ -127,9 +138,9 @@ namespace CSMWorld // // Currently the code assumes that the end user to know what he/she is doing. // e.g. Edges come in pairs, from points a->b and b->a - edges.insert(edges.begin()+position, edge); + edges.insert(edges.begin() + position, edge); - record.setModified (pathgrid); + record.setModified(pathgrid); } void PathgridEdgeListAdapter::removeRow(Record& record, int rowToRemove) const @@ -138,23 +149,21 @@ namespace CSMWorld ESM::Pathgrid::EdgeList& edges = pathgrid.mEdges; - if (rowToRemove < 0 || rowToRemove >= static_cast (edges.size())) - throw std::runtime_error ("index out of range"); + if (rowToRemove < 0 || rowToRemove >= static_cast(edges.size())) + throw std::runtime_error("index out of range"); - edges.erase(edges.begin()+rowToRemove); + edges.erase(edges.begin() + rowToRemove); - record.setModified (pathgrid); + record.setModified(pathgrid); } - void PathgridEdgeListAdapter::setTable(Record& record, - const NestedTableWrapperBase& nestedTable) const + void PathgridEdgeListAdapter::setTable(Record& record, const NestedTableWrapperBase& nestedTable) const { Pathgrid pathgrid = record.get(); - pathgrid.mEdges = - static_cast &>(nestedTable).mNestedTable; + pathgrid.mEdges = static_cast&>(nestedTable).mNestedTable; - record.setModified (pathgrid); + record.setModified(pathgrid); } NestedTableWrapperBase* PathgridEdgeListAdapter::table(const Record& record) const @@ -163,44 +172,53 @@ namespace CSMWorld return new NestedTableWrapper(record.get().mEdges); } - QVariant PathgridEdgeListAdapter::getData(const Record& record, - int subRowIndex, int subColIndex) const + QVariant PathgridEdgeListAdapter::getData(const Record& record, int subRowIndex, int subColIndex) const { Pathgrid pathgrid = record.get(); - if (subRowIndex < 0 || subRowIndex >= static_cast (pathgrid.mEdges.size())) - throw std::runtime_error ("index out of range"); + if (subRowIndex < 0 || subRowIndex >= static_cast(pathgrid.mEdges.size())) + throw std::runtime_error("index out of range"); ESM::Pathgrid::Edge edge = pathgrid.mEdges[subRowIndex]; switch (subColIndex) { - case 0: return subRowIndex; - case 1: return edge.mV0; - case 2: return edge.mV1; - default: throw std::runtime_error("Pathgrid edge subcolumn index out of range"); + case 0: + return subRowIndex; + case 1: + return edge.mV0; + case 2: + return edge.mV1; + default: + throw std::runtime_error("Pathgrid edge subcolumn index out of range"); } } - void PathgridEdgeListAdapter::setData(Record& record, - const QVariant& value, int subRowIndex, int subColIndex) const + void PathgridEdgeListAdapter::setData( + Record& record, const QVariant& value, int subRowIndex, int subColIndex) const { Pathgrid pathgrid = record.get(); - if (subRowIndex < 0 || subRowIndex >= static_cast (pathgrid.mEdges.size())) - throw std::runtime_error ("index out of range"); + if (subRowIndex < 0 || subRowIndex >= static_cast(pathgrid.mEdges.size())) + throw std::runtime_error("index out of range"); ESM::Pathgrid::Edge edge = pathgrid.mEdges[subRowIndex]; switch (subColIndex) { - case 0: return; // return without saving - case 1: edge.mV0 = value.toInt(); break; - case 2: edge.mV1 = value.toInt(); break; - default: throw std::runtime_error("Pathgrid edge subcolumn index out of range"); + case 0: + return; // return without saving + case 1: + edge.mV0 = value.toInt(); + break; + case 2: + edge.mV1 = value.toInt(); + break; + default: + throw std::runtime_error("Pathgrid edge subcolumn index out of range"); } pathgrid.mEdges[subRowIndex] = edge; - record.setModified (pathgrid); + record.setModified(pathgrid); } int PathgridEdgeListAdapter::getColumnsCount(const Record& record) const @@ -213,7 +231,7 @@ namespace CSMWorld return static_cast(record.get().mEdges.size()); } - FactionReactionsAdapter::FactionReactionsAdapter () {} + FactionReactionsAdapter::FactionReactionsAdapter() {} void FactionReactionsAdapter::addRow(Record& record, int position) const { @@ -224,7 +242,7 @@ namespace CSMWorld // blank row reactions.insert(std::make_pair("", 0)); - record.setModified (faction); + record.setModified(faction); } void FactionReactionsAdapter::removeRow(Record& record, int rowToRemove) const @@ -233,73 +251,76 @@ namespace CSMWorld std::map& reactions = faction.mReactions; - if (rowToRemove < 0 || rowToRemove >= static_cast (reactions.size())) - throw std::runtime_error ("index out of range"); + if (rowToRemove < 0 || rowToRemove >= static_cast(reactions.size())) + throw std::runtime_error("index out of range"); // FIXME: how to ensure that the map entries correspond to table indicies? // WARNING: Assumed that the table view has the same order as std::map std::map::iterator iter = reactions.begin(); - for(int i = 0; i < rowToRemove; ++i) + for (int i = 0; i < rowToRemove; ++i) ++iter; reactions.erase(iter); - record.setModified (faction); + record.setModified(faction); } - void FactionReactionsAdapter::setTable(Record& record, - const NestedTableWrapperBase& nestedTable) const + void FactionReactionsAdapter::setTable( + Record& record, const NestedTableWrapperBase& nestedTable) const { ESM::Faction faction = record.get(); - faction.mReactions = - static_cast >&>(nestedTable).mNestedTable; + faction.mReactions + = static_cast>&>(nestedTable).mNestedTable; - record.setModified (faction); + record.setModified(faction); } NestedTableWrapperBase* FactionReactionsAdapter::table(const Record& record) const { // deleted by dtor of NestedTableStoring - return new NestedTableWrapper >(record.get().mReactions); + return new NestedTableWrapper>(record.get().mReactions); } - QVariant FactionReactionsAdapter::getData(const Record& record, - int subRowIndex, int subColIndex) const + QVariant FactionReactionsAdapter::getData( + const Record& record, int subRowIndex, int subColIndex) const { ESM::Faction faction = record.get(); std::map& reactions = faction.mReactions; - if (subRowIndex < 0 || subRowIndex >= static_cast (reactions.size())) - throw std::runtime_error ("index out of range"); + if (subRowIndex < 0 || subRowIndex >= static_cast(reactions.size())) + throw std::runtime_error("index out of range"); // FIXME: how to ensure that the map entries correspond to table indicies? // WARNING: Assumed that the table view has the same order as std::map std::map::const_iterator iter = reactions.begin(); - for(int i = 0; i < subRowIndex; ++i) + for (int i = 0; i < subRowIndex; ++i) ++iter; switch (subColIndex) { - case 0: return QString((*iter).first.c_str()); - case 1: return (*iter).second; - default: throw std::runtime_error("Faction reactions subcolumn index out of range"); + case 0: + return QString((*iter).first.c_str()); + case 1: + return (*iter).second; + default: + throw std::runtime_error("Faction reactions subcolumn index out of range"); } } - void FactionReactionsAdapter::setData(Record& record, - const QVariant& value, int subRowIndex, int subColIndex) const + void FactionReactionsAdapter::setData( + Record& record, const QVariant& value, int subRowIndex, int subColIndex) const { ESM::Faction faction = record.get(); std::map& reactions = faction.mReactions; - if (subRowIndex < 0 || subRowIndex >= static_cast (reactions.size())) - throw std::runtime_error ("index out of range"); + if (subRowIndex < 0 || subRowIndex >= static_cast(reactions.size())) + throw std::runtime_error("index out of range"); // FIXME: how to ensure that the map entries correspond to table indicies? // WARNING: Assumed that the table view has the same order as std::map std::map::iterator iter = reactions.begin(); - for(int i = 0; i < subRowIndex; ++i) + for (int i = 0; i < subRowIndex; ++i) ++iter; std::string factionId = (*iter).first; @@ -318,10 +339,11 @@ namespace CSMWorld reactions[factionId] = value.toInt(); break; } - default: throw std::runtime_error("Faction reactions subcolumn index out of range"); + default: + throw std::runtime_error("Faction reactions subcolumn index out of range"); } - record.setModified (faction); + record.setModified(faction); } int FactionReactionsAdapter::getColumnsCount(const Record& record) const @@ -334,7 +356,7 @@ namespace CSMWorld return static_cast(record.get().mReactions.size()); } - RegionSoundListAdapter::RegionSoundListAdapter () {} + RegionSoundListAdapter::RegionSoundListAdapter() {} void RegionSoundListAdapter::addRow(Record& record, int position) const { @@ -347,9 +369,9 @@ namespace CSMWorld soundRef.mSound.assign(""); soundRef.mChance = 0; - soundList.insert(soundList.begin()+position, soundRef); + soundList.insert(soundList.begin() + position, soundRef); - record.setModified (region); + record.setModified(region); } void RegionSoundListAdapter::removeRow(Record& record, int rowToRemove) const @@ -358,71 +380,77 @@ namespace CSMWorld std::vector& soundList = region.mSoundList; - if (rowToRemove < 0 || rowToRemove >= static_cast (soundList.size())) - throw std::runtime_error ("index out of range"); + if (rowToRemove < 0 || rowToRemove >= static_cast(soundList.size())) + throw std::runtime_error("index out of range"); - soundList.erase(soundList.begin()+rowToRemove); + soundList.erase(soundList.begin() + rowToRemove); - record.setModified (region); + record.setModified(region); } - void RegionSoundListAdapter::setTable(Record& record, - const NestedTableWrapperBase& nestedTable) const + void RegionSoundListAdapter::setTable(Record& record, const NestedTableWrapperBase& nestedTable) const { ESM::Region region = record.get(); - region.mSoundList = - static_cast >&>(nestedTable).mNestedTable; + region.mSoundList + = static_cast>&>(nestedTable).mNestedTable; - record.setModified (region); + record.setModified(region); } NestedTableWrapperBase* RegionSoundListAdapter::table(const Record& record) const { // deleted by dtor of NestedTableStoring - return new NestedTableWrapper >(record.get().mSoundList); + return new NestedTableWrapper>(record.get().mSoundList); } - QVariant RegionSoundListAdapter::getData(const Record& record, - int subRowIndex, int subColIndex) const + QVariant RegionSoundListAdapter::getData(const Record& record, int subRowIndex, int subColIndex) const { ESM::Region region = record.get(); std::vector& soundList = region.mSoundList; - if (subRowIndex < 0 || subRowIndex >= static_cast (soundList.size())) - throw std::runtime_error ("index out of range"); + if (subRowIndex < 0 || subRowIndex >= static_cast(soundList.size())) + throw std::runtime_error("index out of range"); ESM::Region::SoundRef soundRef = soundList[subRowIndex]; switch (subColIndex) { - case 0: return QString(soundRef.mSound.c_str()); - case 1: return soundRef.mChance; - default: throw std::runtime_error("Region sounds subcolumn index out of range"); + case 0: + return QString(soundRef.mSound.c_str()); + case 1: + return soundRef.mChance; + default: + throw std::runtime_error("Region sounds subcolumn index out of range"); } } - void RegionSoundListAdapter::setData(Record& record, - const QVariant& value, int subRowIndex, int subColIndex) const + void RegionSoundListAdapter::setData( + Record& record, const QVariant& value, int subRowIndex, int subColIndex) const { ESM::Region region = record.get(); std::vector& soundList = region.mSoundList; - if (subRowIndex < 0 || subRowIndex >= static_cast (soundList.size())) - throw std::runtime_error ("index out of range"); + if (subRowIndex < 0 || subRowIndex >= static_cast(soundList.size())) + throw std::runtime_error("index out of range"); ESM::Region::SoundRef soundRef = soundList[subRowIndex]; switch (subColIndex) { - case 0: soundRef.mSound.assign(value.toString().toUtf8().constData()); break; - case 1: soundRef.mChance = static_cast(value.toInt()); break; - default: throw std::runtime_error("Region sounds subcolumn index out of range"); + case 0: + soundRef.mSound.assign(value.toString().toUtf8().constData()); + break; + case 1: + soundRef.mChance = static_cast(value.toInt()); + break; + default: + throw std::runtime_error("Region sounds subcolumn index out of range"); } region.mSoundList[subRowIndex] = soundRef; - record.setModified (region); + record.setModified(region); } int RegionSoundListAdapter::getColumnsCount(const Record& record) const @@ -435,31 +463,29 @@ namespace CSMWorld return static_cast(record.get().mSoundList.size()); } - InfoListAdapter::InfoListAdapter () {} + InfoListAdapter::InfoListAdapter() {} void InfoListAdapter::addRow(Record& record, int position) const { - throw std::logic_error ("cannot add a row to a fixed table"); + throw std::logic_error("cannot add a row to a fixed table"); } void InfoListAdapter::removeRow(Record& record, int rowToRemove) const { - throw std::logic_error ("cannot remove a row to a fixed table"); + throw std::logic_error("cannot remove a row to a fixed table"); } - void InfoListAdapter::setTable(Record& record, - const NestedTableWrapperBase& nestedTable) const + void InfoListAdapter::setTable(Record& record, const NestedTableWrapperBase& nestedTable) const { - throw std::logic_error ("table operation not supported"); + throw std::logic_error("table operation not supported"); } NestedTableWrapperBase* InfoListAdapter::table(const Record& record) const { - throw std::logic_error ("table operation not supported"); + throw std::logic_error("table operation not supported"); } - QVariant InfoListAdapter::getData(const Record& record, - int subRowIndex, int subColIndex) const + QVariant InfoListAdapter::getData(const Record& record, int subRowIndex, int subColIndex) const { Info info = record.get(); @@ -469,8 +495,7 @@ namespace CSMWorld throw std::runtime_error("Trying to access non-existing column in the nested table!"); } - void InfoListAdapter::setData(Record& record, - const QVariant& value, int subRowIndex, int subColIndex) const + void InfoListAdapter::setData(Record& record, const QVariant& value, int subRowIndex, int subColIndex) const { Info info = record.get(); @@ -479,7 +504,7 @@ namespace CSMWorld else throw std::runtime_error("Trying to access non-existing column in the nested table!"); - record.setModified (info); + record.setModified(info); } int InfoListAdapter::getColumnsCount(const Record& record) const @@ -492,7 +517,7 @@ namespace CSMWorld return 1; // fixed at size 1 } - InfoConditionAdapter::InfoConditionAdapter () {} + InfoConditionAdapter::InfoConditionAdapter() {} void InfoConditionAdapter::addRow(Record& record, int position) const { @@ -506,9 +531,9 @@ namespace CSMWorld condStruct.mValue = ESM::Variant(); condStruct.mValue.setType(ESM::VT_Int); - conditions.insert(conditions.begin()+position, condStruct); + conditions.insert(conditions.begin() + position, condStruct); - record.setModified (info); + record.setModified(info); } void InfoConditionAdapter::removeRow(Record& record, int rowToRemove) const @@ -517,40 +542,38 @@ namespace CSMWorld std::vector& conditions = info.mSelects; - if (rowToRemove < 0 || rowToRemove >= static_cast (conditions.size())) - throw std::runtime_error ("index out of range"); + if (rowToRemove < 0 || rowToRemove >= static_cast(conditions.size())) + throw std::runtime_error("index out of range"); - conditions.erase(conditions.begin()+rowToRemove); + conditions.erase(conditions.begin() + rowToRemove); - record.setModified (info); + record.setModified(info); } - void InfoConditionAdapter::setTable(Record& record, - const NestedTableWrapperBase& nestedTable) const + void InfoConditionAdapter::setTable(Record& record, const NestedTableWrapperBase& nestedTable) const { Info info = record.get(); - info.mSelects = - static_cast >&>(nestedTable).mNestedTable; + info.mSelects = static_cast>&>(nestedTable) + .mNestedTable; - record.setModified (info); + record.setModified(info); } NestedTableWrapperBase* InfoConditionAdapter::table(const Record& record) const { // deleted by dtor of NestedTableStoring - return new NestedTableWrapper >(record.get().mSelects); + return new NestedTableWrapper>(record.get().mSelects); } - QVariant InfoConditionAdapter::getData(const Record& record, - int subRowIndex, int subColIndex) const + QVariant InfoConditionAdapter::getData(const Record& record, int subRowIndex, int subColIndex) const { Info info = record.get(); std::vector& conditions = info.mSelects; - if (subRowIndex < 0 || subRowIndex >= static_cast (conditions.size())) - throw std::runtime_error ("index out of range"); + if (subRowIndex < 0 || subRowIndex >= static_cast(conditions.size())) + throw std::runtime_error("index out of range"); ConstInfoSelectWrapper infoSelectWrapper(conditions[subRowIndex]); @@ -583,22 +606,24 @@ namespace CSMWorld { return infoSelectWrapper.getVariant().getFloat(); } - default: return QVariant(); + default: + return QVariant(); } } - default: throw std::runtime_error("Info condition subcolumn index out of range"); + default: + throw std::runtime_error("Info condition subcolumn index out of range"); } } - void InfoConditionAdapter::setData(Record& record, - const QVariant& value, int subRowIndex, int subColIndex) const + void InfoConditionAdapter::setData( + Record& record, const QVariant& value, int subRowIndex, int subColIndex) const { Info info = record.get(); std::vector& conditions = info.mSelects; - if (subRowIndex < 0 || subRowIndex >= static_cast (conditions.size())) - throw std::runtime_error ("index out of range"); + if (subRowIndex < 0 || subRowIndex >= static_cast(conditions.size())) + throw std::runtime_error("index out of range"); InfoSelectWrapper infoSelectWrapper(conditions[subRowIndex]); bool conversionResult = false; @@ -609,8 +634,8 @@ namespace CSMWorld { infoSelectWrapper.setFunctionName(static_cast(value.toInt())); - if (infoSelectWrapper.getComparisonType() != ConstInfoSelectWrapper::Comparison_Numeric && - infoSelectWrapper.getVariant().getType() != ESM::VT_Int) + if (infoSelectWrapper.getComparisonType() != ConstInfoSelectWrapper::Comparison_Numeric + && infoSelectWrapper.getVariant().getType() != ESM::VT_Int) { infoSelectWrapper.getVariant().setType(ESM::VT_Int); } @@ -659,14 +684,16 @@ namespace CSMWorld } break; } - default: break; + default: + break; } break; } - default: throw std::runtime_error("Info condition subcolumn index out of range"); + default: + throw std::runtime_error("Info condition subcolumn index out of range"); } - record.setModified (info); + record.setModified(info); } int InfoConditionAdapter::getColumnsCount(const Record& record) const @@ -679,7 +706,7 @@ namespace CSMWorld return static_cast(record.get().mSelects.size()); } - RaceAttributeAdapter::RaceAttributeAdapter () {} + RaceAttributeAdapter::RaceAttributeAdapter() {} void RaceAttributeAdapter::addRow(Record& record, int position) const { @@ -691,15 +718,14 @@ namespace CSMWorld // Do nothing, this table cannot be changed by the user } - void RaceAttributeAdapter::setTable(Record& record, - const NestedTableWrapperBase& nestedTable) const + void RaceAttributeAdapter::setTable(Record& record, const NestedTableWrapperBase& nestedTable) const { ESM::Race race = record.get(); - race.mData = - static_cast >&>(nestedTable).mNestedTable.at(0); + race.mData = static_cast>&>(nestedTable) + .mNestedTable.at(0); - record.setModified (race); + record.setModified(race); } NestedTableWrapperBase* RaceAttributeAdapter::table(const Record& record) const @@ -707,43 +733,52 @@ namespace CSMWorld std::vector wrap; wrap.push_back(record.get().mData); // deleted by dtor of NestedTableStoring - return new NestedTableWrapper >(wrap); + return new NestedTableWrapper>(wrap); } - QVariant RaceAttributeAdapter::getData(const Record& record, - int subRowIndex, int subColIndex) const + QVariant RaceAttributeAdapter::getData(const Record& record, int subRowIndex, int subColIndex) const { ESM::Race race = record.get(); if (subRowIndex < 0 || subRowIndex >= ESM::Attribute::Length) - throw std::runtime_error ("index out of range"); + throw std::runtime_error("index out of range"); switch (subColIndex) { - case 0: return subRowIndex; - case 1: return race.mData.mAttributeValues[subRowIndex].mMale; - case 2: return race.mData.mAttributeValues[subRowIndex].mFemale; - default: throw std::runtime_error("Race Attribute subcolumn index out of range"); + case 0: + return subRowIndex; + case 1: + return race.mData.mAttributeValues[subRowIndex].mMale; + case 2: + return race.mData.mAttributeValues[subRowIndex].mFemale; + default: + throw std::runtime_error("Race Attribute subcolumn index out of range"); } } - void RaceAttributeAdapter::setData(Record& record, - const QVariant& value, int subRowIndex, int subColIndex) const + void RaceAttributeAdapter::setData( + Record& record, const QVariant& value, int subRowIndex, int subColIndex) const { ESM::Race race = record.get(); if (subRowIndex < 0 || subRowIndex >= ESM::Attribute::Length) - throw std::runtime_error ("index out of range"); + throw std::runtime_error("index out of range"); switch (subColIndex) { - case 0: return; // throw an exception here? - case 1: race.mData.mAttributeValues[subRowIndex].mMale = value.toInt(); break; - case 2: race.mData.mAttributeValues[subRowIndex].mFemale = value.toInt(); break; - default: throw std::runtime_error("Race Attribute subcolumn index out of range"); + case 0: + return; // throw an exception here? + case 1: + race.mData.mAttributeValues[subRowIndex].mMale = value.toInt(); + break; + case 2: + race.mData.mAttributeValues[subRowIndex].mFemale = value.toInt(); + break; + default: + throw std::runtime_error("Race Attribute subcolumn index out of range"); } - record.setModified (race); + record.setModified(race); } int RaceAttributeAdapter::getColumnsCount(const Record& record) const @@ -756,7 +791,7 @@ namespace CSMWorld return ESM::Attribute::Length; // there are 8 attributes } - RaceSkillsBonusAdapter::RaceSkillsBonusAdapter () {} + RaceSkillsBonusAdapter::RaceSkillsBonusAdapter() {} void RaceSkillsBonusAdapter::addRow(Record& record, int position) const { @@ -768,15 +803,14 @@ namespace CSMWorld // Do nothing, this table cannot be changed by the user } - void RaceSkillsBonusAdapter::setTable(Record& record, - const NestedTableWrapperBase& nestedTable) const + void RaceSkillsBonusAdapter::setTable(Record& record, const NestedTableWrapperBase& nestedTable) const { ESM::Race race = record.get(); - race.mData = - static_cast >&>(nestedTable).mNestedTable.at(0); + race.mData = static_cast>&>(nestedTable) + .mNestedTable.at(0); - record.setModified (race); + record.setModified(race); } NestedTableWrapperBase* RaceSkillsBonusAdapter::table(const Record& record) const @@ -784,41 +818,50 @@ namespace CSMWorld std::vector wrap; wrap.push_back(record.get().mData); // deleted by dtor of NestedTableStoring - return new NestedTableWrapper >(wrap); + return new NestedTableWrapper>(wrap); } - QVariant RaceSkillsBonusAdapter::getData(const Record& record, - int subRowIndex, int subColIndex) const + QVariant RaceSkillsBonusAdapter::getData(const Record& record, int subRowIndex, int subColIndex) const { ESM::Race race = record.get(); - if (subRowIndex < 0 || subRowIndex >= static_cast(sizeof(race.mData.mBonus)/sizeof(race.mData.mBonus[0]))) - throw std::runtime_error ("index out of range"); + if (subRowIndex < 0 + || subRowIndex >= static_cast(sizeof(race.mData.mBonus) / sizeof(race.mData.mBonus[0]))) + throw std::runtime_error("index out of range"); switch (subColIndex) { - case 0: return race.mData.mBonus[subRowIndex].mSkill; // can be -1 - case 1: return race.mData.mBonus[subRowIndex].mBonus; - default: throw std::runtime_error("Race skill bonus subcolumn index out of range"); + case 0: + return race.mData.mBonus[subRowIndex].mSkill; // can be -1 + case 1: + return race.mData.mBonus[subRowIndex].mBonus; + default: + throw std::runtime_error("Race skill bonus subcolumn index out of range"); } } - void RaceSkillsBonusAdapter::setData(Record& record, - const QVariant& value, int subRowIndex, int subColIndex) const + void RaceSkillsBonusAdapter::setData( + Record& record, const QVariant& value, int subRowIndex, int subColIndex) const { ESM::Race race = record.get(); - if (subRowIndex < 0 || subRowIndex >= static_cast(sizeof(race.mData.mBonus)/sizeof(race.mData.mBonus[0]))) - throw std::runtime_error ("index out of range"); + if (subRowIndex < 0 + || subRowIndex >= static_cast(sizeof(race.mData.mBonus) / sizeof(race.mData.mBonus[0]))) + throw std::runtime_error("index out of range"); switch (subColIndex) { - case 0: race.mData.mBonus[subRowIndex].mSkill = value.toInt(); break; // can be -1 - case 1: race.mData.mBonus[subRowIndex].mBonus = value.toInt(); break; - default: throw std::runtime_error("Race skill bonus subcolumn index out of range"); + case 0: + race.mData.mBonus[subRowIndex].mSkill = value.toInt(); + break; // can be -1 + case 1: + race.mData.mBonus[subRowIndex].mBonus = value.toInt(); + break; + default: + throw std::runtime_error("Race skill bonus subcolumn index out of range"); } - record.setModified (race); + record.setModified(race); } int RaceSkillsBonusAdapter::getColumnsCount(const Record& record) const @@ -829,34 +872,32 @@ namespace CSMWorld int RaceSkillsBonusAdapter::getRowsCount(const Record& record) const { // there are 7 skill bonuses - return static_cast(sizeof(record.get().mData.mBonus)/sizeof(record.get().mData.mBonus[0])); + return static_cast(sizeof(record.get().mData.mBonus) / sizeof(record.get().mData.mBonus[0])); } - CellListAdapter::CellListAdapter () {} + CellListAdapter::CellListAdapter() {} void CellListAdapter::addRow(Record& record, int position) const { - throw std::logic_error ("cannot add a row to a fixed table"); + throw std::logic_error("cannot add a row to a fixed table"); } void CellListAdapter::removeRow(Record& record, int rowToRemove) const { - throw std::logic_error ("cannot remove a row to a fixed table"); + throw std::logic_error("cannot remove a row to a fixed table"); } - void CellListAdapter::setTable(Record& record, - const NestedTableWrapperBase& nestedTable) const + void CellListAdapter::setTable(Record& record, const NestedTableWrapperBase& nestedTable) const { - throw std::logic_error ("table operation not supported"); + throw std::logic_error("table operation not supported"); } NestedTableWrapperBase* CellListAdapter::table(const Record& record) const { - throw std::logic_error ("table operation not supported"); + throw std::logic_error("table operation not supported"); } - QVariant CellListAdapter::getData(const Record& record, - int subRowIndex, int subColIndex) const + QVariant CellListAdapter::getData(const Record& record, int subRowIndex, int subColIndex) const { CSMWorld::Cell cell = record.get(); @@ -866,17 +907,18 @@ namespace CSMWorld switch (subColIndex) { - case 0: return isInterior; + case 0: + return isInterior; // While the ambient information is not necessarily valid if the subrecord wasn't loaded, // the user should still be allowed to edit it - case 1: return (isInterior && !behaveLikeExterior) ? - cell.mAmbi.mAmbient : QVariant(QVariant::UserType); - case 2: return (isInterior && !behaveLikeExterior) ? - cell.mAmbi.mSunlight : QVariant(QVariant::UserType); - case 3: return (isInterior && !behaveLikeExterior) ? - cell.mAmbi.mFog : QVariant(QVariant::UserType); - case 4: return (isInterior && !behaveLikeExterior) ? - cell.mAmbi.mFogDensity : QVariant(QVariant::UserType); + case 1: + return (isInterior && !behaveLikeExterior) ? cell.mAmbi.mAmbient : QVariant(QVariant::UserType); + case 2: + return (isInterior && !behaveLikeExterior) ? cell.mAmbi.mSunlight : QVariant(QVariant::UserType); + case 3: + return (isInterior && !behaveLikeExterior) ? cell.mAmbi.mFog : QVariant(QVariant::UserType); + case 4: + return (isInterior && !behaveLikeExterior) ? cell.mAmbi.mFogDensity : QVariant(QVariant::UserType); case 5: { if (isInterior && interiorWater) @@ -884,16 +926,17 @@ namespace CSMWorld else return QVariant(QVariant::UserType); } - case 6: return isInterior ? - QVariant(QVariant::UserType) : cell.mMapColor; // TODO: how to select? - //case 7: return isInterior ? - //behaveLikeExterior : QVariant(QVariant::UserType); - default: throw std::runtime_error("Cell subcolumn index out of range"); + case 6: + return isInterior ? QVariant(QVariant::UserType) : cell.mMapColor; // TODO: how to select? + // case 7: return isInterior ? + // behaveLikeExterior : QVariant(QVariant::UserType); + default: + throw std::runtime_error("Cell subcolumn index out of range"); } } - void CellListAdapter::setData(Record& record, - const QVariant& value, int subRowIndex, int subColIndex) const + void CellListAdapter::setData( + Record& record, const QVariant& value, int subRowIndex, int subColIndex) const { CSMWorld::Cell cell = record.get(); @@ -988,10 +1031,11 @@ namespace CSMWorld break; } #endif - default: throw std::runtime_error("Cell subcolumn index out of range"); + default: + throw std::runtime_error("Cell subcolumn index out of range"); } - record.setModified (cell); + record.setModified(cell); } int CellListAdapter::getColumnsCount(const Record& record) const @@ -1004,42 +1048,32 @@ namespace CSMWorld return 1; // fixed at size 1 } - RegionWeatherAdapter::RegionWeatherAdapter () {} + RegionWeatherAdapter::RegionWeatherAdapter() {} void RegionWeatherAdapter::addRow(Record& record, int position) const { - throw std::logic_error ("cannot add a row to a fixed table"); + throw std::logic_error("cannot add a row to a fixed table"); } void RegionWeatherAdapter::removeRow(Record& record, int rowToRemove) const { - throw std::logic_error ("cannot remove a row from a fixed table"); + throw std::logic_error("cannot remove a row from a fixed table"); } void RegionWeatherAdapter::setTable(Record& record, const NestedTableWrapperBase& nestedTable) const { - throw std::logic_error ("table operation not supported"); + throw std::logic_error("table operation not supported"); } NestedTableWrapperBase* RegionWeatherAdapter::table(const Record& record) const { - throw std::logic_error ("table operation not supported"); + throw std::logic_error("table operation not supported"); } QVariant RegionWeatherAdapter::getData(const Record& record, int subRowIndex, int subColIndex) const { - const char* WeatherNames[] = { - "Clear", - "Cloudy", - "Fog", - "Overcast", - "Rain", - "Thunder", - "Ash", - "Blight", - "Snow", - "Blizzard" - }; + const char* WeatherNames[] + = { "Clear", "Cloudy", "Fog", "Overcast", "Rain", "Thunder", "Ash", "Blight", "Snow", "Blizzard" }; const ESM::Region& region = record.get(); @@ -1051,25 +1085,36 @@ namespace CSMWorld { switch (subRowIndex) { - case 0: return region.mData.mClear; - case 1: return region.mData.mCloudy; - case 2: return region.mData.mFoggy; - case 3: return region.mData.mOvercast; - case 4: return region.mData.mRain; - case 5: return region.mData.mThunder; - case 6: return region.mData.mAsh; - case 7: return region.mData.mBlight; - case 8: return region.mData.mSnow; - case 9: return region.mData.mBlizzard; - default: break; + case 0: + return region.mData.mClear; + case 1: + return region.mData.mCloudy; + case 2: + return region.mData.mFoggy; + case 3: + return region.mData.mOvercast; + case 4: + return region.mData.mRain; + case 5: + return region.mData.mThunder; + case 6: + return region.mData.mAsh; + case 7: + return region.mData.mBlight; + case 8: + return region.mData.mSnow; + case 9: + return region.mData.mBlizzard; + default: + break; } } throw std::runtime_error("index out of range"); } - void RegionWeatherAdapter::setData(Record& record, const QVariant& value, int subRowIndex, - int subColIndex) const + void RegionWeatherAdapter::setData( + Record& record, const QVariant& value, int subRowIndex, int subColIndex) const { ESM::Region region = record.get(); unsigned char chance = static_cast(value.toInt()); @@ -1078,20 +1123,41 @@ namespace CSMWorld { switch (subRowIndex) { - case 0: region.mData.mClear = chance; break; - case 1: region.mData.mCloudy = chance; break; - case 2: region.mData.mFoggy = chance; break; - case 3: region.mData.mOvercast = chance; break; - case 4: region.mData.mRain = chance; break; - case 5: region.mData.mThunder = chance; break; - case 6: region.mData.mAsh = chance; break; - case 7: region.mData.mBlight = chance; break; - case 8: region.mData.mSnow = chance; break; - case 9: region.mData.mBlizzard = chance; break; - default: throw std::runtime_error("index out of range"); + case 0: + region.mData.mClear = chance; + break; + case 1: + region.mData.mCloudy = chance; + break; + case 2: + region.mData.mFoggy = chance; + break; + case 3: + region.mData.mOvercast = chance; + break; + case 4: + region.mData.mRain = chance; + break; + case 5: + region.mData.mThunder = chance; + break; + case 6: + region.mData.mAsh = chance; + break; + case 7: + region.mData.mBlight = chance; + break; + case 8: + region.mData.mSnow = chance; + break; + case 9: + region.mData.mBlizzard = chance; + break; + default: + throw std::runtime_error("index out of range"); } - record.setModified (region); + record.setModified(region); } } @@ -1105,73 +1171,93 @@ namespace CSMWorld return 10; } - FactionRanksAdapter::FactionRanksAdapter () {} + FactionRanksAdapter::FactionRanksAdapter() {} void FactionRanksAdapter::addRow(Record& record, int position) const { - throw std::logic_error ("cannot add a row to a fixed table"); + throw std::logic_error("cannot add a row to a fixed table"); } void FactionRanksAdapter::removeRow(Record& record, int rowToRemove) const { - throw std::logic_error ("cannot remove a row from a fixed table"); + throw std::logic_error("cannot remove a row from a fixed table"); } - void FactionRanksAdapter::setTable(Record& record, - const NestedTableWrapperBase& nestedTable) const + void FactionRanksAdapter::setTable(Record& record, const NestedTableWrapperBase& nestedTable) const { - throw std::logic_error ("table operation not supported"); + throw std::logic_error("table operation not supported"); } NestedTableWrapperBase* FactionRanksAdapter::table(const Record& record) const { - throw std::logic_error ("table operation not supported"); + throw std::logic_error("table operation not supported"); } - QVariant FactionRanksAdapter::getData(const Record& record, - int subRowIndex, int subColIndex) const + QVariant FactionRanksAdapter::getData(const Record& record, int subRowIndex, int subColIndex) const { ESM::Faction faction = record.get(); - if (subRowIndex < 0 || subRowIndex >= static_cast(sizeof(faction.mData.mRankData)/sizeof(faction.mData.mRankData[0]))) - throw std::runtime_error ("index out of range"); + if (subRowIndex < 0 + || subRowIndex >= static_cast(sizeof(faction.mData.mRankData) / sizeof(faction.mData.mRankData[0]))) + throw std::runtime_error("index out of range"); auto& rankData = faction.mData.mRankData[subRowIndex]; switch (subColIndex) { - case 0: return QString(faction.mRanks[subRowIndex].c_str()); - case 1: return rankData.mAttribute1; - case 2: return rankData.mAttribute2; - case 3: return rankData.mPrimarySkill; - case 4: return rankData.mFavouredSkill; - case 5: return rankData.mFactReaction; - default: throw std::runtime_error("Rank subcolumn index out of range"); + case 0: + return QString(faction.mRanks[subRowIndex].c_str()); + case 1: + return rankData.mAttribute1; + case 2: + return rankData.mAttribute2; + case 3: + return rankData.mPrimarySkill; + case 4: + return rankData.mFavouredSkill; + case 5: + return rankData.mFactReaction; + default: + throw std::runtime_error("Rank subcolumn index out of range"); } } - void FactionRanksAdapter::setData(Record& record, - const QVariant& value, int subRowIndex, int subColIndex) const + void FactionRanksAdapter::setData( + Record& record, const QVariant& value, int subRowIndex, int subColIndex) const { ESM::Faction faction = record.get(); - if (subRowIndex < 0 || subRowIndex >= static_cast(sizeof(faction.mData.mRankData)/sizeof(faction.mData.mRankData[0]))) - throw std::runtime_error ("index out of range"); + if (subRowIndex < 0 + || subRowIndex >= static_cast(sizeof(faction.mData.mRankData) / sizeof(faction.mData.mRankData[0]))) + throw std::runtime_error("index out of range"); auto& rankData = faction.mData.mRankData[subRowIndex]; switch (subColIndex) { - case 0: faction.mRanks[subRowIndex] = value.toString().toUtf8().constData(); break; - case 1: rankData.mAttribute1 = value.toInt(); break; - case 2: rankData.mAttribute2 = value.toInt(); break; - case 3: rankData.mPrimarySkill = value.toInt(); break; - case 4: rankData.mFavouredSkill = value.toInt(); break; - case 5: rankData.mFactReaction = value.toInt(); break; - default: throw std::runtime_error("Rank index out of range"); + case 0: + faction.mRanks[subRowIndex] = value.toString().toUtf8().constData(); + break; + case 1: + rankData.mAttribute1 = value.toInt(); + break; + case 2: + rankData.mAttribute2 = value.toInt(); + break; + case 3: + rankData.mPrimarySkill = value.toInt(); + break; + case 4: + rankData.mFavouredSkill = value.toInt(); + break; + case 5: + rankData.mFactReaction = value.toInt(); + break; + default: + throw std::runtime_error("Rank index out of range"); } - record.setModified (faction); + record.setModified(faction); } int FactionRanksAdapter::getColumnsCount(const Record& record) const diff --git a/apps/opencs/model/world/nestedcoladapterimp.hpp b/apps/opencs/model/world/nestedcoladapterimp.hpp index b1785cc919..a5d2d34eb4 100644 --- a/apps/opencs/model/world/nestedcoladapterimp.hpp +++ b/apps/opencs/model/world/nestedcoladapterimp.hpp @@ -3,16 +3,16 @@ #include -#include +#include // for converting attributes #include #include // for converting magic effect id to string & back -#include // for converting skill names -#include // for converting attributes +#include #include +#include // for converting skill names +#include "cell.hpp" #include "nestedcolumnadapter.hpp" #include "nestedtablewrapper.hpp" -#include "cell.hpp" namespace ESM { @@ -28,22 +28,19 @@ namespace CSMWorld class PathgridPointListAdapter : public NestedColumnAdapter { public: - PathgridPointListAdapter (); + PathgridPointListAdapter(); void addRow(Record& record, int position) const override; void removeRow(Record& record, int rowToRemove) const override; - void setTable(Record& record, - const NestedTableWrapperBase& nestedTable) const override; + void setTable(Record& record, const NestedTableWrapperBase& nestedTable) const override; NestedTableWrapperBase* table(const Record& record) const override; - QVariant getData(const Record& record, - int subRowIndex, int subColIndex) const override; + QVariant getData(const Record& record, int subRowIndex, int subColIndex) const override; - void setData(Record& record, - const QVariant& value, int subRowIndex, int subColIndex) const override; + void setData(Record& record, const QVariant& value, int subRowIndex, int subColIndex) const override; int getColumnsCount(const Record& record) const override; @@ -53,22 +50,19 @@ namespace CSMWorld class PathgridEdgeListAdapter : public NestedColumnAdapter { public: - PathgridEdgeListAdapter (); + PathgridEdgeListAdapter(); void addRow(Record& record, int position) const override; void removeRow(Record& record, int rowToRemove) const override; - void setTable(Record& record, - const NestedTableWrapperBase& nestedTable) const override; + void setTable(Record& record, const NestedTableWrapperBase& nestedTable) const override; NestedTableWrapperBase* table(const Record& record) const override; - QVariant getData(const Record& record, - int subRowIndex, int subColIndex) const override; + QVariant getData(const Record& record, int subRowIndex, int subColIndex) const override; - void setData(Record& record, - const QVariant& value, int subRowIndex, int subColIndex) const override; + void setData(Record& record, const QVariant& value, int subRowIndex, int subColIndex) const override; int getColumnsCount(const Record& record) const override; @@ -78,22 +72,20 @@ namespace CSMWorld class FactionReactionsAdapter : public NestedColumnAdapter { public: - FactionReactionsAdapter (); + FactionReactionsAdapter(); void addRow(Record& record, int position) const override; void removeRow(Record& record, int rowToRemove) const override; - void setTable(Record& record, - const NestedTableWrapperBase& nestedTable) const override; + void setTable(Record& record, const NestedTableWrapperBase& nestedTable) const override; NestedTableWrapperBase* table(const Record& record) const override; - QVariant getData(const Record& record, - int subRowIndex, int subColIndex) const override; + QVariant getData(const Record& record, int subRowIndex, int subColIndex) const override; - void setData(Record& record, - const QVariant& value, int subRowIndex, int subColIndex) const override; + void setData( + Record& record, const QVariant& value, int subRowIndex, int subColIndex) const override; int getColumnsCount(const Record& record) const override; @@ -103,22 +95,20 @@ namespace CSMWorld class FactionRanksAdapter : public NestedColumnAdapter { public: - FactionRanksAdapter (); + FactionRanksAdapter(); void addRow(Record& record, int position) const override; void removeRow(Record& record, int rowToRemove) const override; - void setTable(Record& record, - const NestedTableWrapperBase& nestedTable) const override; + void setTable(Record& record, const NestedTableWrapperBase& nestedTable) const override; NestedTableWrapperBase* table(const Record& record) const override; - QVariant getData(const Record& record, - int subRowIndex, int subColIndex) const override; + QVariant getData(const Record& record, int subRowIndex, int subColIndex) const override; - void setData(Record& record, - const QVariant& value, int subRowIndex, int subColIndex) const override; + void setData( + Record& record, const QVariant& value, int subRowIndex, int subColIndex) const override; int getColumnsCount(const Record& record) const override; @@ -128,33 +118,31 @@ namespace CSMWorld class RegionSoundListAdapter : public NestedColumnAdapter { public: - RegionSoundListAdapter (); + RegionSoundListAdapter(); void addRow(Record& record, int position) const override; void removeRow(Record& record, int rowToRemove) const override; - void setTable(Record& record, - const NestedTableWrapperBase& nestedTable) const override; + void setTable(Record& record, const NestedTableWrapperBase& nestedTable) const override; NestedTableWrapperBase* table(const Record& record) const override; - QVariant getData(const Record& record, - int subRowIndex, int subColIndex) const override; + QVariant getData(const Record& record, int subRowIndex, int subColIndex) const override; - void setData(Record& record, - const QVariant& value, int subRowIndex, int subColIndex) const override; + void setData( + Record& record, const QVariant& value, int subRowIndex, int subColIndex) const override; int getColumnsCount(const Record& record) const override; int getRowsCount(const Record& record) const override; }; - template + template class SpellListAdapter : public NestedColumnAdapter { public: - SpellListAdapter () {} + SpellListAdapter() {} void addRow(Record& record, int position) const override { @@ -165,9 +153,9 @@ namespace CSMWorld // blank row std::string spell; - spells.insert(spells.begin()+position, spell); + spells.insert(spells.begin() + position, spell); - record.setModified (raceOrBthSgn); + record.setModified(raceOrBthSgn); } void removeRow(Record& record, int rowToRemove) const override @@ -176,28 +164,28 @@ namespace CSMWorld std::vector& spells = raceOrBthSgn.mPowers.mList; - if (rowToRemove < 0 || rowToRemove >= static_cast (spells.size())) - throw std::runtime_error ("index out of range"); + if (rowToRemove < 0 || rowToRemove >= static_cast(spells.size())) + throw std::runtime_error("index out of range"); - spells.erase(spells.begin()+rowToRemove); + spells.erase(spells.begin() + rowToRemove); - record.setModified (raceOrBthSgn); + record.setModified(raceOrBthSgn); } void setTable(Record& record, const NestedTableWrapperBase& nestedTable) const override { ESXRecordT raceOrBthSgn = record.get(); - raceOrBthSgn.mPowers.mList = - static_cast >&>(nestedTable).mNestedTable; + raceOrBthSgn.mPowers.mList + = static_cast>&>(nestedTable).mNestedTable; - record.setModified (raceOrBthSgn); + record.setModified(raceOrBthSgn); } NestedTableWrapperBase* table(const Record& record) const override { // deleted by dtor of NestedTableStoring - return new NestedTableWrapper >(record.get().mPowers.mList); + return new NestedTableWrapper>(record.get().mPowers.mList); } QVariant getData(const Record& record, int subRowIndex, int subColIndex) const override @@ -206,43 +194,44 @@ namespace CSMWorld std::vector& spells = raceOrBthSgn.mPowers.mList; - if (subRowIndex < 0 || subRowIndex >= static_cast (spells.size())) - throw std::runtime_error ("index out of range"); + if (subRowIndex < 0 || subRowIndex >= static_cast(spells.size())) + throw std::runtime_error("index out of range"); std::string spell = spells[subRowIndex]; switch (subColIndex) { - case 0: return QString(spell.c_str()); - default: throw std::runtime_error("Spells subcolumn index out of range"); + case 0: + return QString(spell.c_str()); + default: + throw std::runtime_error("Spells subcolumn index out of range"); } } - void setData(Record& record, const QVariant& value, - int subRowIndex, int subColIndex) const override + void setData(Record& record, const QVariant& value, int subRowIndex, int subColIndex) const override { ESXRecordT raceOrBthSgn = record.get(); std::vector& spells = raceOrBthSgn.mPowers.mList; - if (subRowIndex < 0 || subRowIndex >= static_cast (spells.size())) - throw std::runtime_error ("index out of range"); + if (subRowIndex < 0 || subRowIndex >= static_cast(spells.size())) + throw std::runtime_error("index out of range"); std::string spell = spells[subRowIndex]; switch (subColIndex) { - case 0: spell = value.toString().toUtf8().constData(); break; - default: throw std::runtime_error("Spells subcolumn index out of range"); + case 0: + spell = value.toString().toUtf8().constData(); + break; + default: + throw std::runtime_error("Spells subcolumn index out of range"); } raceOrBthSgn.mPowers.mList[subRowIndex] = spell; - record.setModified (raceOrBthSgn); + record.setModified(raceOrBthSgn); } - int getColumnsCount(const Record& record) const override - { - return 1; - } + int getColumnsCount(const Record& record) const override { return 1; } int getRowsCount(const Record& record) const override { @@ -250,11 +239,11 @@ namespace CSMWorld } }; - template + template class EffectsListAdapter : public NestedColumnAdapter { public: - EffectsListAdapter () {} + EffectsListAdapter() {} void addRow(Record& record, int position) const override { @@ -273,9 +262,9 @@ namespace CSMWorld effect.mMagnMin = 0; effect.mMagnMax = 0; - effectsList.insert(effectsList.begin()+position, effect); + effectsList.insert(effectsList.begin() + position, effect); - record.setModified (magic); + record.setModified(magic); } void removeRow(Record& record, int rowToRemove) const override @@ -284,28 +273,28 @@ namespace CSMWorld std::vector& effectsList = magic.mEffects.mList; - if (rowToRemove < 0 || rowToRemove >= static_cast (effectsList.size())) - throw std::runtime_error ("index out of range"); + if (rowToRemove < 0 || rowToRemove >= static_cast(effectsList.size())) + throw std::runtime_error("index out of range"); - effectsList.erase(effectsList.begin()+rowToRemove); + effectsList.erase(effectsList.begin() + rowToRemove); - record.setModified (magic); + record.setModified(magic); } void setTable(Record& record, const NestedTableWrapperBase& nestedTable) const override { ESXRecordT magic = record.get(); - magic.mEffects.mList = - static_cast >&>(nestedTable).mNestedTable; + magic.mEffects.mList + = static_cast>&>(nestedTable).mNestedTable; - record.setModified (magic); + record.setModified(magic); } NestedTableWrapperBase* table(const Record& record) const override { // deleted by dtor of NestedTableStoring - return new NestedTableWrapper >(record.get().mEffects.mList); + return new NestedTableWrapper>(record.get().mEffects.mList); } QVariant getData(const Record& record, int subRowIndex, int subColIndex) const override @@ -314,15 +303,15 @@ namespace CSMWorld std::vector& effectsList = magic.mEffects.mList; - if (subRowIndex < 0 || subRowIndex >= static_cast (effectsList.size())) - throw std::runtime_error ("index out of range"); + if (subRowIndex < 0 || subRowIndex >= static_cast(effectsList.size())) + throw std::runtime_error("index out of range"); ESM::ENAMstruct effect = effectsList[subRowIndex]; switch (subColIndex) { case 0: { - if (effect.mEffectID >=0 && effect.mEffectID < ESM::MagicEffect::Length) + if (effect.mEffectID >= 0 && effect.mEffectID < ESM::MagicEffect::Length) return effect.mEffectID; else throw std::runtime_error("Magic effects ID unexpected value"); @@ -336,7 +325,7 @@ namespace CSMWorld case ESM::MagicEffect::RestoreSkill: case ESM::MagicEffect::FortifySkill: case ESM::MagicEffect::AbsorbSkill: - return effect.mSkill; + return effect.mSkill; default: return QVariant(); } @@ -350,35 +339,39 @@ namespace CSMWorld case ESM::MagicEffect::RestoreAttribute: case ESM::MagicEffect::FortifyAttribute: case ESM::MagicEffect::AbsorbAttribute: - return effect.mAttribute; + return effect.mAttribute; default: return QVariant(); } } case 3: { - if (effect.mRange >=0 && effect.mRange <=2) + if (effect.mRange >= 0 && effect.mRange <= 2) return effect.mRange; else throw std::runtime_error("Magic effects range unexpected value"); } - case 4: return effect.mArea; - case 5: return effect.mDuration; - case 6: return effect.mMagnMin; - case 7: return effect.mMagnMax; - default: throw std::runtime_error("Magic Effects subcolumn index out of range"); + case 4: + return effect.mArea; + case 5: + return effect.mDuration; + case 6: + return effect.mMagnMin; + case 7: + return effect.mMagnMax; + default: + throw std::runtime_error("Magic Effects subcolumn index out of range"); } } - void setData(Record& record, const QVariant& value, - int subRowIndex, int subColIndex) const override + void setData(Record& record, const QVariant& value, int subRowIndex, int subColIndex) const override { ESXRecordT magic = record.get(); std::vector& effectsList = magic.mEffects.mList; - if (subRowIndex < 0 || subRowIndex >= static_cast (effectsList.size())) - throw std::runtime_error ("index out of range"); + if (subRowIndex < 0 || subRowIndex >= static_cast(effectsList.size())) + throw std::runtime_error("index out of range"); ESM::ENAMstruct effect = effectsList[subRowIndex]; switch (subColIndex) @@ -403,22 +396,28 @@ namespace CSMWorld effect.mRange = value.toInt(); break; } - case 4: effect.mArea = value.toInt(); break; - case 5: effect.mDuration = value.toInt(); break; - case 6: effect.mMagnMin = value.toInt(); break; - case 7: effect.mMagnMax = value.toInt(); break; - default: throw std::runtime_error("Magic Effects subcolumn index out of range"); + case 4: + effect.mArea = value.toInt(); + break; + case 5: + effect.mDuration = value.toInt(); + break; + case 6: + effect.mMagnMin = value.toInt(); + break; + case 7: + effect.mMagnMax = value.toInt(); + break; + default: + throw std::runtime_error("Magic Effects subcolumn index out of range"); } magic.mEffects.mList[subRowIndex] = effect; - record.setModified (magic); + record.setModified(magic); } - int getColumnsCount(const Record& record) const override - { - return 8; - } + int getColumnsCount(const Record& record) const override { return 8; } int getRowsCount(const Record& record) const override { @@ -429,22 +428,19 @@ namespace CSMWorld class InfoListAdapter : public NestedColumnAdapter { public: - InfoListAdapter (); + InfoListAdapter(); void addRow(Record& record, int position) const override; void removeRow(Record& record, int rowToRemove) const override; - void setTable(Record& record, - const NestedTableWrapperBase& nestedTable) const override; + void setTable(Record& record, const NestedTableWrapperBase& nestedTable) const override; NestedTableWrapperBase* table(const Record& record) const override; - QVariant getData(const Record& record, - int subRowIndex, int subColIndex) const override; + QVariant getData(const Record& record, int subRowIndex, int subColIndex) const override; - void setData(Record& record, - const QVariant& value, int subRowIndex, int subColIndex) const override; + void setData(Record& record, const QVariant& value, int subRowIndex, int subColIndex) const override; int getColumnsCount(const Record& record) const override; @@ -454,22 +450,19 @@ namespace CSMWorld class InfoConditionAdapter : public NestedColumnAdapter { public: - InfoConditionAdapter (); + InfoConditionAdapter(); void addRow(Record& record, int position) const override; void removeRow(Record& record, int rowToRemove) const override; - void setTable(Record& record, - const NestedTableWrapperBase& nestedTable) const override; + void setTable(Record& record, const NestedTableWrapperBase& nestedTable) const override; NestedTableWrapperBase* table(const Record& record) const override; - QVariant getData(const Record& record, - int subRowIndex, int subColIndex) const override; + QVariant getData(const Record& record, int subRowIndex, int subColIndex) const override; - void setData(Record& record, - const QVariant& value, int subRowIndex, int subColIndex) const override; + void setData(Record& record, const QVariant& value, int subRowIndex, int subColIndex) const override; int getColumnsCount(const Record& record) const override; @@ -479,22 +472,19 @@ namespace CSMWorld class RaceAttributeAdapter : public NestedColumnAdapter { public: - RaceAttributeAdapter (); + RaceAttributeAdapter(); void addRow(Record& record, int position) const override; void removeRow(Record& record, int rowToRemove) const override; - void setTable(Record& record, - const NestedTableWrapperBase& nestedTable) const override; + void setTable(Record& record, const NestedTableWrapperBase& nestedTable) const override; NestedTableWrapperBase* table(const Record& record) const override; - QVariant getData(const Record& record, - int subRowIndex, int subColIndex) const override; + QVariant getData(const Record& record, int subRowIndex, int subColIndex) const override; - void setData(Record& record, - const QVariant& value, int subRowIndex, int subColIndex) const override; + void setData(Record& record, const QVariant& value, int subRowIndex, int subColIndex) const override; int getColumnsCount(const Record& record) const override; @@ -504,22 +494,19 @@ namespace CSMWorld class RaceSkillsBonusAdapter : public NestedColumnAdapter { public: - RaceSkillsBonusAdapter (); + RaceSkillsBonusAdapter(); void addRow(Record& record, int position) const override; void removeRow(Record& record, int rowToRemove) const override; - void setTable(Record& record, - const NestedTableWrapperBase& nestedTable) const override; + void setTable(Record& record, const NestedTableWrapperBase& nestedTable) const override; NestedTableWrapperBase* table(const Record& record) const override; - QVariant getData(const Record& record, - int subRowIndex, int subColIndex) const override; + QVariant getData(const Record& record, int subRowIndex, int subColIndex) const override; - void setData(Record& record, - const QVariant& value, int subRowIndex, int subColIndex) const override; + void setData(Record& record, const QVariant& value, int subRowIndex, int subColIndex) const override; int getColumnsCount(const Record& record) const override; @@ -529,22 +516,20 @@ namespace CSMWorld class CellListAdapter : public NestedColumnAdapter { public: - CellListAdapter (); + CellListAdapter(); void addRow(Record& record, int position) const override; void removeRow(Record& record, int rowToRemove) const override; - void setTable(Record& record, - const NestedTableWrapperBase& nestedTable) const override; + void setTable(Record& record, const NestedTableWrapperBase& nestedTable) const override; NestedTableWrapperBase* table(const Record& record) const override; - QVariant getData(const Record& record, - int subRowIndex, int subColIndex) const override; + QVariant getData(const Record& record, int subRowIndex, int subColIndex) const override; - void setData(Record& record, - const QVariant& value, int subRowIndex, int subColIndex) const override; + void setData( + Record& record, const QVariant& value, int subRowIndex, int subColIndex) const override; int getColumnsCount(const Record& record) const override; @@ -554,22 +539,20 @@ namespace CSMWorld class RegionWeatherAdapter : public NestedColumnAdapter { public: - RegionWeatherAdapter (); + RegionWeatherAdapter(); void addRow(Record& record, int position) const override; void removeRow(Record& record, int rowToRemove) const override; - void setTable(Record& record, - const NestedTableWrapperBase& nestedTable) const override; + void setTable(Record& record, const NestedTableWrapperBase& nestedTable) const override; NestedTableWrapperBase* table(const Record& record) const override; - QVariant getData(const Record& record, - int subRowIndex, int subColIndex) const override; + QVariant getData(const Record& record, int subRowIndex, int subColIndex) const override; - void setData(Record& record, - const QVariant& value, int subRowIndex, int subColIndex) const override; + void setData( + Record& record, const QVariant& value, int subRowIndex, int subColIndex) const override; int getColumnsCount(const Record& record) const override; diff --git a/apps/opencs/model/world/nestedcollection.cpp b/apps/opencs/model/world/nestedcollection.cpp index 6d4a2579c7..c114dacaa3 100644 --- a/apps/opencs/model/world/nestedcollection.cpp +++ b/apps/opencs/model/world/nestedcollection.cpp @@ -2,11 +2,9 @@ #include "columnbase.hpp" -CSMWorld::NestedCollection::NestedCollection() -{} +CSMWorld::NestedCollection::NestedCollection() {} -CSMWorld::NestedCollection::~NestedCollection() -{} +CSMWorld::NestedCollection::~NestedCollection() {} int CSMWorld::NestedCollection::getNestedRowsCount(int row, int column) const { @@ -21,7 +19,7 @@ int CSMWorld::NestedCollection::getNestedColumnsCount(int row, int column) const int CSMWorld::NestedCollection::searchNestedColumnIndex(int parentColumn, Columns::ColumnId id) { // Assumed that the parentColumn is always a valid index - const NestableColumn *parent = getNestableColumn(parentColumn); + const NestableColumn* parent = getNestableColumn(parentColumn); int nestedColumnCount = getNestedColumnsCount(0, parentColumn); for (int i = 0; i < nestedColumnCount; ++i) { diff --git a/apps/opencs/model/world/nestedcollection.hpp b/apps/opencs/model/world/nestedcollection.hpp index 4548cfb2b9..3e90bde9cc 100644 --- a/apps/opencs/model/world/nestedcollection.hpp +++ b/apps/opencs/model/world/nestedcollection.hpp @@ -14,7 +14,6 @@ namespace CSMWorld { public: - NestedCollection(); virtual ~NestedCollection(); @@ -34,7 +33,7 @@ namespace CSMWorld virtual int getNestedColumnsCount(int row, int column) const; - virtual NestableColumn *getNestableColumn(int column) = 0; + virtual NestableColumn* getNestableColumn(int column) = 0; virtual int searchNestedColumnIndex(int parentColumn, Columns::ColumnId id); ///< \return the column index or -1 if the requested column wasn't found. diff --git a/apps/opencs/model/world/nestedcolumnadapter.hpp b/apps/opencs/model/world/nestedcolumnadapter.hpp index 462b5a5ab1..198cc9b18e 100644 --- a/apps/opencs/model/world/nestedcolumnadapter.hpp +++ b/apps/opencs/model/world/nestedcolumnadapter.hpp @@ -10,11 +10,10 @@ namespace CSMWorld template struct Record; - template + template class NestedColumnAdapter { public: - NestedColumnAdapter() {} virtual ~NestedColumnAdapter() {} @@ -29,7 +28,8 @@ namespace CSMWorld virtual QVariant getData(const Record& record, int subRowIndex, int subColIndex) const = 0; - virtual void setData(Record& record, const QVariant& value, int subRowIndex, int subColIndex) const = 0; + virtual void setData( + Record& record, const QVariant& value, int subRowIndex, int subColIndex) const = 0; virtual int getColumnsCount(const Record& record) const = 0; diff --git a/apps/opencs/model/world/nestedidcollection.hpp b/apps/opencs/model/world/nestedidcollection.hpp index 76402821f5..0f334a3015 100644 --- a/apps/opencs/model/world/nestedidcollection.hpp +++ b/apps/opencs/model/world/nestedidcollection.hpp @@ -2,11 +2,11 @@ #define CSM_WOLRD_NESTEDIDCOLLECTION_H #include -#include #include +#include -#include "nestedcollection.hpp" #include "collection.hpp" +#include "nestedcollection.hpp" #include "nestedcolumnadapter.hpp" namespace ESM @@ -29,74 +29,75 @@ namespace CSMWorld template class NestedColumnAdapter; - template > + template > class NestedIdCollection : public IdCollection, public NestedCollection { - std::map* > mAdapters; - - const NestedColumnAdapter& getAdapter(const ColumnBase &column) const; + std::map*> mAdapters; - public: + const NestedColumnAdapter& getAdapter(const ColumnBase& column) const; - NestedIdCollection (); - ~NestedIdCollection() override; + public: + NestedIdCollection(); + ~NestedIdCollection() override; - void addNestedRow(int row, int column, int position) override; + void addNestedRow(int row, int column, int position) override; - void removeNestedRows(int row, int column, int subRow) override; + void removeNestedRows(int row, int column, int subRow) override; - QVariant getNestedData(int row, int column, int subRow, int subColumn) const override; + QVariant getNestedData(int row, int column, int subRow, int subColumn) const override; - void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn) override; + void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn) override; - NestedTableWrapperBase* nestedTable(int row, int column) const override; + NestedTableWrapperBase* nestedTable(int row, int column) const override; - void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable) override; + void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable) override; - int getNestedRowsCount(int row, int column) const override; + int getNestedRowsCount(int row, int column) const override; - int getNestedColumnsCount(int row, int column) const override; + int getNestedColumnsCount(int row, int column) const override; - // this method is inherited from NestedCollection, not from Collection - NestableColumn *getNestableColumn(int column) override; + // this method is inherited from NestedCollection, not from Collection + NestableColumn* getNestableColumn(int column) override; - void addAdapter(std::pair* > adapter); + void addAdapter(std::pair*> adapter); }; - template - NestedIdCollection::NestedIdCollection () - {} + template + NestedIdCollection::NestedIdCollection() + { + } - template + template NestedIdCollection::~NestedIdCollection() { - for (typename std::map* >::iterator - iter (mAdapters.begin()); iter!=mAdapters.end(); ++iter) + for (typename std::map*>::iterator iter(mAdapters.begin()); + iter != mAdapters.end(); ++iter) { delete (*iter).second; } } - template - void NestedIdCollection::addAdapter(std::pair* > adapter) + template + void NestedIdCollection::addAdapter( + std::pair*> adapter) { mAdapters.insert(adapter); } - template - const NestedColumnAdapter& NestedIdCollection::getAdapter(const ColumnBase &column) const + template + const NestedColumnAdapter& NestedIdCollection::getAdapter( + const ColumnBase& column) const { - typename std::map* >::const_iterator iter = - mAdapters.find (&column); + typename std::map*>::const_iterator iter + = mAdapters.find(&column); - if (iter==mAdapters.end()) + if (iter == mAdapters.end()) throw std::logic_error("No such column in the nestedidadapter"); return *iter->second; } - template + template void NestedIdCollection::addNestedRow(int row, int column, int position) { auto record = std::make_unique>(); @@ -107,7 +108,7 @@ namespace CSMWorld Collection::setRecord(row, std::move(record)); } - template + template void NestedIdCollection::removeNestedRows(int row, int column, int subRow) { auto record = std::make_unique>(); @@ -118,59 +119,57 @@ namespace CSMWorld Collection::setRecord(row, std::move(record)); } - template - QVariant NestedIdCollection::getNestedData (int row, - int column, int subRow, int subColumn) const + template + QVariant NestedIdCollection::getNestedData( + int row, int column, int subRow, int subColumn) const { - return getAdapter(Collection::getColumn(column)).getData( - Collection::getRecord(row), subRow, subColumn); + return getAdapter(Collection::getColumn(column)) + .getData(Collection::getRecord(row), subRow, subColumn); } - template - void NestedIdCollection::setNestedData(int row, - int column, const QVariant& data, int subRow, int subColumn) + template + void NestedIdCollection::setNestedData( + int row, int column, const QVariant& data, int subRow, int subColumn) { auto record = std::make_unique>(); record->assign(Collection::getRecord(row)); - getAdapter(Collection::getColumn(column)).setData( - *record, data, subRow, subColumn); + getAdapter(Collection::getColumn(column)).setData(*record, data, subRow, subColumn); Collection::setRecord(row, std::move(record)); } - template - CSMWorld::NestedTableWrapperBase* NestedIdCollection::nestedTable(int row, - int column) const + template + CSMWorld::NestedTableWrapperBase* NestedIdCollection::nestedTable( + int row, int column) const { - return getAdapter(Collection::getColumn(column)).table( - Collection::getRecord(row)); + return getAdapter(Collection::getColumn(column)) + .table(Collection::getRecord(row)); } - template - void NestedIdCollection::setNestedTable(int row, - int column, const CSMWorld::NestedTableWrapperBase& nestedTable) + template + void NestedIdCollection::setNestedTable( + int row, int column, const CSMWorld::NestedTableWrapperBase& nestedTable) { auto record = std::make_unique>(); record->assign(Collection::getRecord(row)); - getAdapter(Collection::getColumn(column)).setTable( - *record, nestedTable); + getAdapter(Collection::getColumn(column)).setTable(*record, nestedTable); Collection::setRecord(row, std::move(record)); } - template + template int NestedIdCollection::getNestedRowsCount(int row, int column) const { - return getAdapter(Collection::getColumn(column)).getRowsCount( - Collection::getRecord(row)); + return getAdapter(Collection::getColumn(column)) + .getRowsCount(Collection::getRecord(row)); } - template + template int NestedIdCollection::getNestedColumnsCount(int row, int column) const { - const ColumnBase &nestedColumn = Collection::getColumn(column); + const ColumnBase& nestedColumn = Collection::getColumn(column); int numRecords = Collection::getSize(); if (row >= 0 && row < numRecords) { @@ -185,8 +184,8 @@ namespace CSMWorld } } - template - CSMWorld::NestableColumn *NestedIdCollection::getNestableColumn(int column) + template + CSMWorld::NestableColumn* NestedIdCollection::getNestableColumn(int column) { return Collection::getNestableColumn(column); } diff --git a/apps/opencs/model/world/nestedinfocollection.cpp b/apps/opencs/model/world/nestedinfocollection.cpp index e2e90c49d1..e8fe5da1c1 100644 --- a/apps/opencs/model/world/nestedinfocollection.cpp +++ b/apps/opencs/model/world/nestedinfocollection.cpp @@ -4,30 +4,27 @@ namespace CSMWorld { - NestedInfoCollection::NestedInfoCollection () - {} + NestedInfoCollection::NestedInfoCollection() {} NestedInfoCollection::~NestedInfoCollection() { - for (std::map* >::iterator - iter (mAdapters.begin()); iter!=mAdapters.end(); ++iter) + for (std::map*>::iterator iter(mAdapters.begin()); + iter != mAdapters.end(); ++iter) { delete (*iter).second; } } - void NestedInfoCollection::addAdapter(std::pair* > adapter) + void NestedInfoCollection::addAdapter(std::pair*> adapter) { mAdapters.insert(adapter); } - const NestedColumnAdapter& NestedInfoCollection::getAdapter(const ColumnBase &column) const + const NestedColumnAdapter& NestedInfoCollection::getAdapter(const ColumnBase& column) const { - std::map* >::const_iterator iter = - mAdapters.find (&column); + std::map*>::const_iterator iter = mAdapters.find(&column); - if (iter==mAdapters.end()) + if (iter == mAdapters.end()) throw std::logic_error("No such column in the nestedidadapter"); return *iter->second; @@ -36,75 +33,69 @@ namespace CSMWorld void NestedInfoCollection::addNestedRow(int row, int column, int position) { auto record = std::make_unique>(); - record->assign(Collection >::getRecord(row)); + record->assign(Collection>::getRecord(row)); - getAdapter(Collection >::getColumn(column)).addRow(*record, position); + getAdapter(Collection>::getColumn(column)).addRow(*record, position); - Collection >::setRecord(row, std::move(record)); + Collection>::setRecord(row, std::move(record)); } void NestedInfoCollection::removeNestedRows(int row, int column, int subRow) { auto record = std::make_unique>(); - record->assign(Collection >::getRecord(row)); + record->assign(Collection>::getRecord(row)); - getAdapter(Collection >::getColumn(column)).removeRow(*record, subRow); + getAdapter(Collection>::getColumn(column)).removeRow(*record, subRow); - Collection >::setRecord(row, std::move(record)); + Collection>::setRecord(row, std::move(record)); } - QVariant NestedInfoCollection::getNestedData (int row, - int column, int subRow, int subColumn) const + QVariant NestedInfoCollection::getNestedData(int row, int column, int subRow, int subColumn) const { - return getAdapter(Collection >::getColumn(column)).getData( - Collection >::getRecord(row), subRow, subColumn); + return getAdapter(Collection>::getColumn(column)) + .getData(Collection>::getRecord(row), subRow, subColumn); } - void NestedInfoCollection::setNestedData(int row, - int column, const QVariant& data, int subRow, int subColumn) + void NestedInfoCollection::setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn) { auto record = std::make_unique>(); - record->assign(Collection >::getRecord(row)); + record->assign(Collection>::getRecord(row)); - getAdapter(Collection >::getColumn(column)).setData( - *record, data, subRow, subColumn); + getAdapter(Collection>::getColumn(column)).setData(*record, data, subRow, subColumn); - Collection >::setRecord(row, std::move(record)); + Collection>::setRecord(row, std::move(record)); } - CSMWorld::NestedTableWrapperBase* NestedInfoCollection::nestedTable(int row, - int column) const + CSMWorld::NestedTableWrapperBase* NestedInfoCollection::nestedTable(int row, int column) const { - return getAdapter(Collection >::getColumn(column)).table( - Collection >::getRecord(row)); + return getAdapter(Collection>::getColumn(column)) + .table(Collection>::getRecord(row)); } - void NestedInfoCollection::setNestedTable(int row, - int column, const CSMWorld::NestedTableWrapperBase& nestedTable) + void NestedInfoCollection::setNestedTable(int row, int column, const CSMWorld::NestedTableWrapperBase& nestedTable) { auto record = std::make_unique>(); - record->assign(Collection >::getRecord(row)); + record->assign(Collection>::getRecord(row)); - getAdapter(Collection >::getColumn(column)).setTable( - *record, nestedTable); + getAdapter(Collection>::getColumn(column)).setTable(*record, nestedTable); - Collection >::setRecord(row, std::move(record)); + Collection>::setRecord(row, std::move(record)); } int NestedInfoCollection::getNestedRowsCount(int row, int column) const { - return getAdapter(Collection >::getColumn(column)).getRowsCount( - Collection >::getRecord(row)); + return getAdapter(Collection>::getColumn(column)) + .getRowsCount(Collection>::getRecord(row)); } int NestedInfoCollection::getNestedColumnsCount(int row, int column) const { - return getAdapter(Collection >::getColumn(column)).getColumnsCount( - Collection >::getRecord(row)); + return getAdapter(Collection>::getColumn(column)) + .getColumnsCount(Collection>::getRecord(row)); } - CSMWorld::NestableColumn *NestedInfoCollection::getNestableColumn(int column) + CSMWorld::NestableColumn* NestedInfoCollection::getNestableColumn(int column) { - return Collection >::getNestableColumn(column); + return Collection>::getNestableColumn(column); } } diff --git a/apps/opencs/model/world/nestedinfocollection.hpp b/apps/opencs/model/world/nestedinfocollection.hpp index bb747efadf..76db3a1186 100644 --- a/apps/opencs/model/world/nestedinfocollection.hpp +++ b/apps/opencs/model/world/nestedinfocollection.hpp @@ -10,40 +10,39 @@ namespace CSMWorld { struct NestedTableWrapperBase; - template + template class NestedColumnAdapter; class NestedInfoCollection : public InfoCollection, public NestedCollection { - std::map* > mAdapters; + std::map*> mAdapters; - const NestedColumnAdapter& getAdapter(const ColumnBase &column) const; + const NestedColumnAdapter& getAdapter(const ColumnBase& column) const; - public: + public: + NestedInfoCollection(); + ~NestedInfoCollection() override; - NestedInfoCollection (); - ~NestedInfoCollection() override; + void addNestedRow(int row, int column, int position) override; - void addNestedRow(int row, int column, int position) override; + void removeNestedRows(int row, int column, int subRow) override; - void removeNestedRows(int row, int column, int subRow) override; + QVariant getNestedData(int row, int column, int subRow, int subColumn) const override; - QVariant getNestedData(int row, int column, int subRow, int subColumn) const override; + void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn) override; - void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn) override; + NestedTableWrapperBase* nestedTable(int row, int column) const override; - NestedTableWrapperBase* nestedTable(int row, int column) const override; + void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable) override; - void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable) override; + int getNestedRowsCount(int row, int column) const override; - int getNestedRowsCount(int row, int column) const override; + int getNestedColumnsCount(int row, int column) const override; - int getNestedColumnsCount(int row, int column) const override; + // this method is inherited from NestedCollection, not from Collection > + NestableColumn* getNestableColumn(int column) override; - // this method is inherited from NestedCollection, not from Collection > - NestableColumn *getNestableColumn(int column) override; - - void addAdapter(std::pair* > adapter); + void addAdapter(std::pair*> adapter); }; } diff --git a/apps/opencs/model/world/nestedtableproxymodel.cpp b/apps/opencs/model/world/nestedtableproxymodel.cpp index bb918ee685..ef89a13af7 100644 --- a/apps/opencs/model/world/nestedtableproxymodel.cpp +++ b/apps/opencs/model/world/nestedtableproxymodel.cpp @@ -1,13 +1,12 @@ #include "nestedtableproxymodel.hpp" -#include #include "idtree.hpp" +#include -CSMWorld::NestedTableProxyModel::NestedTableProxyModel(const QModelIndex& parent, - ColumnBase::Display columnId, - CSMWorld::IdTree* parentModel) - : mParentColumn(parent.column()), - mMainModel(parentModel) +CSMWorld::NestedTableProxyModel::NestedTableProxyModel( + const QModelIndex& parent, ColumnBase::Display columnId, CSMWorld::IdTree* parentModel) + : mParentColumn(parent.column()) + , mMainModel(parentModel) { const int parentRow = parent.row(); @@ -15,32 +14,25 @@ CSMWorld::NestedTableProxyModel::NestedTableProxyModel(const QModelIndex& parent QAbstractProxyModel::setSourceModel(parentModel); - connect(mMainModel, &IdTree::rowsAboutToBeInserted, - this, &NestedTableProxyModel::forwardRowsAboutToInserted); + connect(mMainModel, &IdTree::rowsAboutToBeInserted, this, &NestedTableProxyModel::forwardRowsAboutToInserted); - connect(mMainModel, &IdTree::rowsInserted, - this, &NestedTableProxyModel::forwardRowsInserted); + connect(mMainModel, &IdTree::rowsInserted, this, &NestedTableProxyModel::forwardRowsInserted); - connect(mMainModel, &IdTree::rowsAboutToBeRemoved, - this, &NestedTableProxyModel::forwardRowsAboutToRemoved); + connect(mMainModel, &IdTree::rowsAboutToBeRemoved, this, &NestedTableProxyModel::forwardRowsAboutToRemoved); - connect(mMainModel, &IdTree::rowsRemoved, - this, &NestedTableProxyModel::forwardRowsRemoved); + connect(mMainModel, &IdTree::rowsRemoved, this, &NestedTableProxyModel::forwardRowsRemoved); - connect(mMainModel, &IdTree::resetStart, - this, &NestedTableProxyModel::forwardResetStart); + connect(mMainModel, &IdTree::resetStart, this, &NestedTableProxyModel::forwardResetStart); - connect(mMainModel, &IdTree::resetEnd, - this, &NestedTableProxyModel::forwardResetEnd); + connect(mMainModel, &IdTree::resetEnd, this, &NestedTableProxyModel::forwardResetEnd); - connect(mMainModel, &IdTree::dataChanged, - this, &NestedTableProxyModel::forwardDataChanged); + connect(mMainModel, &IdTree::dataChanged, this, &NestedTableProxyModel::forwardDataChanged); } QModelIndex CSMWorld::NestedTableProxyModel::mapFromSource(const QModelIndex& sourceIndex) const { const QModelIndex& testedParent = mMainModel->parent(sourceIndex); - const QModelIndex& parent = mMainModel->getNestedModelIndex (mId, mParentColumn); + const QModelIndex& parent = mMainModel->getNestedModelIndex(mId, mParentColumn); if (testedParent == parent) { return createIndex(sourceIndex.row(), sourceIndex.column()); @@ -53,27 +45,27 @@ QModelIndex CSMWorld::NestedTableProxyModel::mapFromSource(const QModelIndex& so QModelIndex CSMWorld::NestedTableProxyModel::mapToSource(const QModelIndex& proxyIndex) const { - const QModelIndex& parent = mMainModel->getNestedModelIndex (mId, mParentColumn); + const QModelIndex& parent = mMainModel->getNestedModelIndex(mId, mParentColumn); return mMainModel->index(proxyIndex.row(), proxyIndex.column(), parent); } int CSMWorld::NestedTableProxyModel::rowCount(const QModelIndex& index) const { - assert (!index.isValid()); + assert(!index.isValid()); return mMainModel->rowCount(mMainModel->getModelIndex(mId, mParentColumn)); } int CSMWorld::NestedTableProxyModel::columnCount(const QModelIndex& parent) const { - assert (!parent.isValid()); + assert(!parent.isValid()); return mMainModel->columnCount(mMainModel->getModelIndex(mId, mParentColumn)); } QModelIndex CSMWorld::NestedTableProxyModel::index(int row, int column, const QModelIndex& parent) const { - assert (!parent.isValid()); + assert(!parent.isValid()); int numRows = rowCount(parent); int numColumns = columnCount(parent); @@ -89,9 +81,7 @@ QModelIndex CSMWorld::NestedTableProxyModel::parent(const QModelIndex& index) co return QModelIndex(); } -QVariant CSMWorld::NestedTableProxyModel::headerData(int section, - Qt::Orientation orientation, - int role) const +QVariant CSMWorld::NestedTableProxyModel::headerData(int section, Qt::Orientation orientation, int role) const { return mMainModel->nestedHeaderData(mParentColumn, section, orientation, role); } @@ -104,7 +94,7 @@ QVariant CSMWorld::NestedTableProxyModel::data(const QModelIndex& index, int rol // NOTE: Due to mapToSouce(index) the dataChanged() signal resulting from setData() will have the // source model's index values. The indicies need to be converted to the proxy space values. // See forwardDataChanged() -bool CSMWorld::NestedTableProxyModel::setData (const QModelIndex & index, const QVariant & value, int role) +bool CSMWorld::NestedTableProxyModel::setData(const QModelIndex& index, const QVariant& value, int role) { return mMainModel->setData(mapToSource(index), value, role); } @@ -129,8 +119,7 @@ CSMWorld::IdTree* CSMWorld::NestedTableProxyModel::model() const return mMainModel; } -void CSMWorld::NestedTableProxyModel::forwardRowsAboutToInserted(const QModelIndex& parent, - int first, int last) +void CSMWorld::NestedTableProxyModel::forwardRowsAboutToInserted(const QModelIndex& parent, int first, int last) { if (indexIsParent(parent)) { @@ -148,13 +137,11 @@ void CSMWorld::NestedTableProxyModel::forwardRowsInserted(const QModelIndex& par bool CSMWorld::NestedTableProxyModel::indexIsParent(const QModelIndex& index) { - return (index.isValid() && - index.column() == mParentColumn && - mMainModel->data(mMainModel->index(index.row(), 0)).toString().toUtf8().constData() == mId); + return (index.isValid() && index.column() == mParentColumn + && mMainModel->data(mMainModel->index(index.row(), 0)).toString().toUtf8().constData() == mId); } -void CSMWorld::NestedTableProxyModel::forwardRowsAboutToRemoved(const QModelIndex& parent, - int first, int last) +void CSMWorld::NestedTableProxyModel::forwardRowsAboutToRemoved(const QModelIndex& parent, int first, int last) { if (indexIsParent(parent)) { @@ -182,15 +169,13 @@ void CSMWorld::NestedTableProxyModel::forwardResetEnd(const QString& id) endResetModel(); } -void CSMWorld::NestedTableProxyModel::forwardDataChanged (const QModelIndex& topLeft, - const QModelIndex& bottomRight) +void CSMWorld::NestedTableProxyModel::forwardDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) { - const QModelIndex& parent = mMainModel->getNestedModelIndex (mId, mParentColumn); + const QModelIndex& parent = mMainModel->getNestedModelIndex(mId, mParentColumn); if (topLeft.column() <= parent.column() && bottomRight.column() >= parent.column()) { - emit dataChanged(index(0,0), - index(mMainModel->rowCount(parent)-1, mMainModel->columnCount(parent)-1)); + emit dataChanged(index(0, 0), index(mMainModel->rowCount(parent) - 1, mMainModel->columnCount(parent) - 1)); } else if (topLeft.parent() == parent && bottomRight.parent() == parent) { diff --git a/apps/opencs/model/world/nestedtableproxymodel.hpp b/apps/opencs/model/world/nestedtableproxymodel.hpp index 4f44cd7df6..bac6b7ebdc 100644 --- a/apps/opencs/model/world/nestedtableproxymodel.hpp +++ b/apps/opencs/model/world/nestedtableproxymodel.hpp @@ -26,10 +26,8 @@ namespace CSMWorld std::string mId; public: - NestedTableProxyModel(const QModelIndex& parent, - ColumnBase::Display displayType, - IdTree* parentModel); - //parent is the parent of columns to work with. Columnid provides information about the column + NestedTableProxyModel(const QModelIndex& parent, ColumnBase::Display displayType, IdTree* parentModel); + // parent is the parent of columns to work with. Columnid provides information about the column std::string getParentId() const; @@ -49,11 +47,11 @@ namespace CSMWorld QModelIndex parent(const QModelIndex& index) const override; - QVariant headerData (int section, Qt::Orientation orientation, int role) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role) const override; - QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override; + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; - bool setData (const QModelIndex & index, const QVariant & value, int role = Qt::EditRole) override; + bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override; Qt::ItemFlags flags(const QModelIndex& index) const override; @@ -63,19 +61,19 @@ namespace CSMWorld bool indexIsParent(const QModelIndex& index); private slots: - void forwardRowsAboutToInserted(const QModelIndex & parent, int first, int last); + void forwardRowsAboutToInserted(const QModelIndex& parent, int first, int last); - void forwardRowsInserted(const QModelIndex & parent, int first, int last); + void forwardRowsInserted(const QModelIndex& parent, int first, int last); - void forwardRowsAboutToRemoved(const QModelIndex & parent, int first, int last); + void forwardRowsAboutToRemoved(const QModelIndex& parent, int first, int last); - void forwardRowsRemoved(const QModelIndex & parent, int first, int last); + void forwardRowsRemoved(const QModelIndex& parent, int first, int last); void forwardResetStart(const QString& id); void forwardResetEnd(const QString& id); - void forwardDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); + void forwardDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); }; } diff --git a/apps/opencs/model/world/nestedtablewrapper.cpp b/apps/opencs/model/world/nestedtablewrapper.cpp index 3966dbc575..480f6aab3e 100644 --- a/apps/opencs/model/world/nestedtablewrapper.cpp +++ b/apps/opencs/model/world/nestedtablewrapper.cpp @@ -1,10 +1,8 @@ #include "nestedtablewrapper.hpp" -CSMWorld::NestedTableWrapperBase::NestedTableWrapperBase() -{} +CSMWorld::NestedTableWrapperBase::NestedTableWrapperBase() {} -CSMWorld::NestedTableWrapperBase::~NestedTableWrapperBase() -{} +CSMWorld::NestedTableWrapperBase::~NestedTableWrapperBase() {} int CSMWorld::NestedTableWrapperBase::size() const { diff --git a/apps/opencs/model/world/nestedtablewrapper.hpp b/apps/opencs/model/world/nestedtablewrapper.hpp index 1b652683a4..0779988c1d 100644 --- a/apps/opencs/model/world/nestedtablewrapper.hpp +++ b/apps/opencs/model/world/nestedtablewrapper.hpp @@ -6,25 +6,27 @@ namespace CSMWorld struct NestedTableWrapperBase { virtual ~NestedTableWrapperBase(); - + virtual int size() const; - + NestedTableWrapperBase(); }; - - template + + template struct NestedTableWrapper : public NestedTableWrapperBase { NestedTable mNestedTable; NestedTableWrapper(const NestedTable& nestedTable) - : mNestedTable(nestedTable) {} + : mNestedTable(nestedTable) + { + } ~NestedTableWrapper() override {} int size() const override { - return mNestedTable.size(); //i hope that this will be enough + return mNestedTable.size(); // i hope that this will be enough } }; } diff --git a/apps/opencs/model/world/pathgrid.cpp b/apps/opencs/model/world/pathgrid.cpp index c995bd8f09..0852ad46fa 100644 --- a/apps/opencs/model/world/pathgrid.cpp +++ b/apps/opencs/model/world/pathgrid.cpp @@ -1,15 +1,15 @@ +#include "pathgrid.hpp" #include "cell.hpp" #include "idcollection.hpp" -#include "pathgrid.hpp" #include -void CSMWorld::Pathgrid::load (ESM::ESMReader &esm, bool &isDeleted, const IdCollection& cells) +void CSMWorld::Pathgrid::load(ESM::ESMReader& esm, bool& isDeleted, const IdCollection& cells) { - load (esm, isDeleted); + load(esm, isDeleted); // correct ID - if (!mId.empty() && mId[0]!='#' && cells.searchId (mId)==-1) + if (!mId.empty() && mId[0] != '#' && cells.searchId(mId) == -1) { std::ostringstream stream; stream << "#" << mData.mX << " " << mData.mY; @@ -17,9 +17,9 @@ void CSMWorld::Pathgrid::load (ESM::ESMReader &esm, bool &isDeleted, const IdCol } } -void CSMWorld::Pathgrid::load (ESM::ESMReader &esm, bool &isDeleted) +void CSMWorld::Pathgrid::load(ESM::ESMReader& esm, bool& isDeleted) { - ESM::Pathgrid::load (esm, isDeleted); + ESM::Pathgrid::load(esm, isDeleted); mId = mCell; if (mCell.empty()) diff --git a/apps/opencs/model/world/pathgrid.hpp b/apps/opencs/model/world/pathgrid.hpp index ad89918fbf..6317e2fd9e 100644 --- a/apps/opencs/model/world/pathgrid.hpp +++ b/apps/opencs/model/world/pathgrid.hpp @@ -1,18 +1,18 @@ #ifndef CSM_WOLRD_PATHGRID_H #define CSM_WOLRD_PATHGRID_H -#include #include +#include #include namespace CSMWorld { struct Cell; - template + template class IdCollection; - template + template struct IdAccessor; /// \brief Wrapper for Pathgrid record @@ -23,8 +23,8 @@ namespace CSMWorld { std::string mId; - void load (ESM::ESMReader &esm, bool &isDeleted, const IdCollection >& cells); - void load (ESM::ESMReader &esm, bool &isDeleted); + void load(ESM::ESMReader& esm, bool& isDeleted, const IdCollection>& cells); + void load(ESM::ESMReader& esm, bool& isDeleted); }; } diff --git a/apps/opencs/model/world/record.cpp b/apps/opencs/model/world/record.cpp index da1651f2b5..27f52c73a1 100644 --- a/apps/opencs/model/world/record.cpp +++ b/apps/opencs/model/world/record.cpp @@ -4,17 +4,15 @@ CSMWorld::RecordBase::~RecordBase() {} bool CSMWorld::RecordBase::isDeleted() const { - return mState==State_Deleted || mState==State_Erased; + return mState == State_Deleted || mState == State_Erased; } - bool CSMWorld::RecordBase::isErased() const { - return mState==State_Erased; + return mState == State_Erased; } - bool CSMWorld::RecordBase::isModified() const { - return mState==State_Modified || mState==State_ModifiedOnly; + return mState == State_Modified || mState == State_ModifiedOnly; } \ No newline at end of file diff --git a/apps/opencs/model/world/record.hpp b/apps/opencs/model/world/record.hpp index bb43612e5e..8fc69cfdae 100644 --- a/apps/opencs/model/world/record.hpp +++ b/apps/opencs/model/world/record.hpp @@ -25,7 +25,7 @@ namespace CSMWorld virtual std::unique_ptr modifiedCopy() const = 0; - virtual void assign (const RecordBase& record) = 0; + virtual void assign(const RecordBase& record) = 0; ///< Will throw an exception if the types don't match. bool isDeleted() const; @@ -43,14 +43,13 @@ namespace CSMWorld Record(); - Record(State state, - const ESXRecordT *base = 0, const ESXRecordT *modified = 0); + Record(State state, const ESXRecordT* base = 0, const ESXRecordT* modified = 0); std::unique_ptr clone() const override; std::unique_ptr modifiedCopy() const override; - void assign (const RecordBase& record) override; + void assign(const RecordBase& record) override; const ESXRecordT& get() const; ///< Throws an exception, if the record is deleted. @@ -61,7 +60,7 @@ namespace CSMWorld const ESXRecordT& getBase() const; ///< Throws an exception, if the record is deleted. Returns modified, if there is no base. - void setModified (const ESXRecordT& modified); + void setModified(const ESXRecordT& modified); ///< Throws an exception, if the record is deleted. void merge(); @@ -70,16 +69,18 @@ namespace CSMWorld template Record::Record() - : mBase(), mModified() - { } + : mBase() + , mModified() + { + } template - Record::Record(State state, const ESXRecordT *base, const ESXRecordT *modified) + Record::Record(State state, const ESXRecordT* base, const ESXRecordT* modified) { - if(base) + if (base) mBase = *base; - if(modified) + if (modified) mModified = *modified; this->mState = state; @@ -88,58 +89,57 @@ namespace CSMWorld template std::unique_ptr Record::modifiedCopy() const { - return std::make_unique >( - Record(State_ModifiedOnly, nullptr, &(this->get()))); + return std::make_unique>(Record(State_ModifiedOnly, nullptr, &(this->get()))); } template std::unique_ptr Record::clone() const { - return std::make_unique >(Record(*this)); + return std::make_unique>(Record(*this)); } template - void Record::assign (const RecordBase& record) + void Record::assign(const RecordBase& record) { - *this = dynamic_cast& > (record); + *this = dynamic_cast&>(record); } template const ESXRecordT& Record::get() const { - if (mState==State_Erased) - throw std::logic_error ("attempt to access a deleted record"); + if (mState == State_Erased) + throw std::logic_error("attempt to access a deleted record"); - return mState==State_BaseOnly || mState==State_Deleted ? mBase : mModified; + return mState == State_BaseOnly || mState == State_Deleted ? mBase : mModified; } template ESXRecordT& Record::get() { - if (mState==State_Erased) - throw std::logic_error ("attempt to access a deleted record"); + if (mState == State_Erased) + throw std::logic_error("attempt to access a deleted record"); - return mState==State_BaseOnly || mState==State_Deleted ? mBase : mModified; + return mState == State_BaseOnly || mState == State_Deleted ? mBase : mModified; } template const ESXRecordT& Record::getBase() const { - if (mState==State_Erased) - throw std::logic_error ("attempt to access a deleted record"); + if (mState == State_Erased) + throw std::logic_error("attempt to access a deleted record"); - return mState==State_ModifiedOnly ? mModified : mBase; + return mState == State_ModifiedOnly ? mModified : mBase; } template - void Record::setModified (const ESXRecordT& modified) + void Record::setModified(const ESXRecordT& modified) { - if (mState==State_Erased) - throw std::logic_error ("attempt to modify a deleted record"); + if (mState == State_Erased) + throw std::logic_error("attempt to modify a deleted record"); mModified = modified; - if (mState!=State_ModifiedOnly) + if (mState != State_ModifiedOnly) mState = State_Modified; } @@ -151,7 +151,7 @@ namespace CSMWorld mBase = mModified; mState = State_BaseOnly; } - else if (mState==State_Deleted) + else if (mState == State_Deleted) { mState = State_Erased; } diff --git a/apps/opencs/model/world/ref.cpp b/apps/opencs/model/world/ref.cpp index 0b07b484ca..00957bb3ed 100644 --- a/apps/opencs/model/world/ref.cpp +++ b/apps/opencs/model/world/ref.cpp @@ -2,7 +2,9 @@ #include "cellcoordinates.hpp" -CSMWorld::CellRef::CellRef() : mNew (true), mIdNum(0) +CSMWorld::CellRef::CellRef() + : mNew(true) + , mIdNum(0) { mRefNum.mIndex = 0; mRefNum.mContentFile = 0; @@ -10,5 +12,5 @@ CSMWorld::CellRef::CellRef() : mNew (true), mIdNum(0) std::pair CSMWorld::CellRef::getCellIndex() const { - return CellCoordinates::coordinatesToCellIndex (mPos.pos[0], mPos.pos[1]); + return CellCoordinates::coordinatesToCellIndex(mPos.pos[0], mPos.pos[1]); } diff --git a/apps/opencs/model/world/refcollection.cpp b/apps/opencs/model/world/refcollection.cpp index 49abbbbf16..0fb199b68f 100644 --- a/apps/opencs/model/world/refcollection.cpp +++ b/apps/opencs/model/world/refcollection.cpp @@ -2,10 +2,10 @@ #include -#include "ref.hpp" #include "cell.hpp" -#include "universalid.hpp" #include "record.hpp" +#include "ref.hpp" +#include "universalid.hpp" #include "../doc/messages.hpp" @@ -13,37 +13,37 @@ namespace CSMWorld { - template<> - void Collection >::removeRows (int index, int count) + template <> + void Collection>::removeRows(int index, int count) { - mRecords.erase(mRecords.begin()+index, mRecords.begin()+index+count); + mRecords.erase(mRecords.begin() + index, mRecords.begin() + index + count); // index map is updated in RefCollection::removeRows() } - template<> - void Collection >::insertRecord (std::unique_ptr record, int index, - UniversalId::Type type) + template <> + void Collection>::insertRecord( + std::unique_ptr record, int index, UniversalId::Type type) { int size = static_cast(mRecords.size()); if (index < 0 || index > size) throw std::runtime_error("index out of range"); - std::unique_ptr > record2(static_cast*>(record.release())); + std::unique_ptr> record2(static_cast*>(record.release())); if (index == size) mRecords.push_back(std::move(record2)); else - mRecords.insert(mRecords.begin()+index, std::move(record2)); + mRecords.insert(mRecords.begin() + index, std::move(record2)); // index map is updated in RefCollection::insertRecord() } } -void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool base, +void CSMWorld::RefCollection::load(ESM::ESMReader& reader, int cellIndex, bool base, std::map& cache, CSMDoc::Messages& messages) { - Record cell = mCells.getRecord (cellIndex); + Record cell = mCells.getRecord(cellIndex); Cell& cell2 = base ? cell.mBase : cell.mModified; @@ -83,7 +83,7 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool std::string indexCell = ref.mCell; ref.mCell = "#" + std::to_string(mref.mTarget[0]) + " " + std::to_string(mref.mTarget[1]); - CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Cell, mCells.getId (cellIndex)); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Cell, mCells.getId(cellIndex)); messages.add(id, "The position of the moved reference " + ref.mRefID + " (cell " + indexCell + ")" " does not match the target cell (" + ref.mCell + ")", std::string(), CSMDoc::Message::Severity_Warning); @@ -99,8 +99,8 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool ref.mRefNum.mIndex &= 0x00ffffff; } - unsigned int refNum = (ref.mRefNum.mIndex & 0x00ffffff) | - (ref.mRefNum.hasContentFile() ? ref.mRefNum.mContentFile : 0xff) << 24; + unsigned int refNum = (ref.mRefNum.mIndex & 0x00ffffff) + | (ref.mRefNum.hasContentFile() ? ref.mRefNum.mContentFile : 0xff) << 24; std::map::iterator iter = cache.find(refNum); @@ -108,14 +108,12 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool { if (iter == cache.end()) { - CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Cell, - mCells.getId(cellIndex)); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Cell, mCells.getId(cellIndex)); - messages.add(id, "Attempt to move a non-existent reference - RefNum index " - + std::to_string(ref.mRefNum.mIndex) + ", refID " + ref.mRefID + ", content file index " - + std::to_string(ref.mRefNum.mContentFile), - /*hint*/"", - CSMDoc::Message::Severity_Warning); + messages.add(id, + "Attempt to move a non-existent reference - RefNum index " + std::to_string(ref.mRefNum.mIndex) + + ", refID " + ref.mRefID + ", content file index " + std::to_string(ref.mRefNum.mContentFile), + /*hint*/ "", CSMDoc::Message::Severity_Warning); continue; } @@ -138,25 +136,23 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool if (isDeleted) { - if (iter==cache.end()) + if (iter == cache.end()) { - CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Cell, - mCells.getId (cellIndex)); - - messages.add (id, "Attempt to delete a non-existent reference - RefNum index " - + std::to_string(ref.mRefNum.mIndex) + ", refID " + ref.mRefID + ", content file index " - + std::to_string(ref.mRefNum.mContentFile), - /*hint*/"", - CSMDoc::Message::Severity_Warning); + CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Cell, mCells.getId(cellIndex)); + + messages.add(id, + "Attempt to delete a non-existent reference - RefNum index " + std::to_string(ref.mRefNum.mIndex) + + ", refID " + ref.mRefID + ", content file index " + std::to_string(ref.mRefNum.mContentFile), + /*hint*/ "", CSMDoc::Message::Severity_Warning); continue; } - int index = getIntIndex (iter->second); + int index = getIntIndex(iter->second); if (base) { - removeRows (index, 1); - cache.erase (iter); + removeRows(index, 1); + cache.erase(iter); } else { @@ -168,7 +164,7 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool continue; } - if (iter==cache.end()) + if (iter == cache.end()) { // new reference ref.mIdNum = mNextId; // FIXME: fragile @@ -228,10 +224,10 @@ unsigned int CSMWorld::RefCollection::extractIdNum(std::string_view id) const if (separator == std::string::npos) throw std::runtime_error("invalid ref ID: " + std::string(id)); - return static_cast(std::stoi(std::string(id.substr(separator+1)))); + return static_cast(std::stoi(std::string(id.substr(separator + 1)))); } -int CSMWorld::RefCollection::getIntIndex (unsigned int id) const +int CSMWorld::RefCollection::getIntIndex(unsigned int id) const { int index = searchId(id); @@ -241,7 +237,7 @@ int CSMWorld::RefCollection::getIntIndex (unsigned int id) const return index; } -int CSMWorld::RefCollection::searchId (unsigned int id) const +int CSMWorld::RefCollection::searchId(unsigned int id) const { std::map::const_iterator iter = mRefIndex.find(id); @@ -251,16 +247,16 @@ int CSMWorld::RefCollection::searchId (unsigned int id) const return iter->second; } -void CSMWorld::RefCollection::removeRows (int index, int count) +void CSMWorld::RefCollection::removeRows(int index, int count) { - Collection >::removeRows(index, count); // erase records only + Collection>::removeRows(index, count); // erase records only std::map::iterator iter = mRefIndex.begin(); while (iter != mRefIndex.end()) { - if (iter->second>=index) + if (iter->second >= index) { - if (iter->second >= index+count) + if (iter->second >= index + count) { iter->second -= count; ++iter; @@ -273,7 +269,7 @@ void CSMWorld::RefCollection::removeRows (int index, int count) } } -void CSMWorld::RefCollection::appendBlankRecord (const std::string& id, UniversalId::Type type) +void CSMWorld::RefCollection::appendBlankRecord(const std::string& id, UniversalId::Type type) { auto record = std::make_unique>(); @@ -283,12 +279,11 @@ void CSMWorld::RefCollection::appendBlankRecord (const std::string& id, Univers record->get().mId = id; record->get().mIdNum = extractIdNum(id); - Collection >::appendRecord(std::move(record)); + Collection>::appendRecord(std::move(record)); } -void CSMWorld::RefCollection::cloneRecord (const std::string& origin, - const std::string& destination, - const UniversalId::Type type) +void CSMWorld::RefCollection::cloneRecord( + const std::string& origin, const std::string& destination, const UniversalId::Type type) { auto copy = std::make_unique>(); @@ -306,24 +301,23 @@ int CSMWorld::RefCollection::searchId(std::string_view id) const return searchId(extractIdNum(id)); } -void CSMWorld::RefCollection::appendRecord (std::unique_ptr record, UniversalId::Type type) +void CSMWorld::RefCollection::appendRecord(std::unique_ptr record, UniversalId::Type type) { - int index = getAppendIndex(/*id*/"", type); // for CellRef records id is ignored + int index = getAppendIndex(/*id*/ "", type); // for CellRef records id is ignored mRefIndex.insert(std::make_pair(static_cast*>(record.get())->get().mIdNum, index)); - Collection >::insertRecord(std::move(record), index, type); // add records only + Collection>::insertRecord(std::move(record), index, type); // add records only } -void CSMWorld::RefCollection::insertRecord (std::unique_ptr record, int index, - UniversalId::Type type) +void CSMWorld::RefCollection::insertRecord(std::unique_ptr record, int index, UniversalId::Type type) { - int size = getAppendIndex(/*id*/"", type); // for CellRef records id is ignored + int size = getAppendIndex(/*id*/ "", type); // for CellRef records id is ignored unsigned int idNum = static_cast*>(record.get())->get().mIdNum; - Collection >::insertRecord(std::move(record), index, type); // add records only + Collection>::insertRecord(std::move(record), index, type); // add records only - if (index < size-1) + if (index < size - 1) { for (std::map::iterator iter(mRefIndex.begin()); iter != mRefIndex.end(); ++iter) { diff --git a/apps/opencs/model/world/refcollection.hpp b/apps/opencs/model/world/refcollection.hpp index 87688c162a..749b5167f6 100644 --- a/apps/opencs/model/world/refcollection.hpp +++ b/apps/opencs/model/world/refcollection.hpp @@ -5,8 +5,8 @@ #include #include "collection.hpp" -#include "ref.hpp" #include "record.hpp" +#include "ref.hpp" namespace CSMDoc { @@ -18,56 +18,54 @@ namespace CSMWorld struct Cell; class UniversalId; - template<> - void Collection >::removeRows (int index, int count); + template <> + void Collection>::removeRows(int index, int count); - template<> - void Collection >::insertRecord (std::unique_ptr record, int index, - UniversalId::Type type); + template <> + void Collection>::insertRecord( + std::unique_ptr record, int index, UniversalId::Type type); /// \brief References in cells class RefCollection : public Collection { - Collection& mCells; - std::map mRefIndex; // CellRef index keyed by CSMWorld::CellRef::mIdNum + Collection& mCells; + std::map mRefIndex; // CellRef index keyed by CSMWorld::CellRef::mIdNum - int mNextId; + int mNextId; - unsigned int extractIdNum(std::string_view id) const; + unsigned int extractIdNum(std::string_view id) const; - int getIntIndex (unsigned int id) const; + int getIntIndex(unsigned int id) const; - int searchId (unsigned int id) const; + int searchId(unsigned int id) const; - public: - // MSVC needs the constructor for a class inheriting a template to be defined in header - RefCollection (Collection& cells) - : mCells (cells), mNextId (0) - {} + public: + // MSVC needs the constructor for a class inheriting a template to be defined in header + RefCollection(Collection& cells) + : mCells(cells) + , mNextId(0) + { + } - void load (ESM::ESMReader& reader, int cellIndex, bool base, - std::map& cache, CSMDoc::Messages& messages); - ///< Load a sequence of references. + void load(ESM::ESMReader& reader, int cellIndex, bool base, std::map& cache, + CSMDoc::Messages& messages); + ///< Load a sequence of references. - std::string getNewId(); + std::string getNewId(); - virtual void removeRows (int index, int count); + virtual void removeRows(int index, int count); - virtual void appendBlankRecord (const std::string& id, - UniversalId::Type type = UniversalId::Type_None); + virtual void appendBlankRecord(const std::string& id, UniversalId::Type type = UniversalId::Type_None); - virtual void cloneRecord (const std::string& origin, - const std::string& destination, - const UniversalId::Type type); + virtual void cloneRecord( + const std::string& origin, const std::string& destination, const UniversalId::Type type); - virtual int searchId(std::string_view id) const; + virtual int searchId(std::string_view id) const; - virtual void appendRecord (std::unique_ptr record, - UniversalId::Type type = UniversalId::Type_None); + virtual void appendRecord(std::unique_ptr record, UniversalId::Type type = UniversalId::Type_None); - virtual void insertRecord (std::unique_ptr record, - int index, - UniversalId::Type type = UniversalId::Type_None); + virtual void insertRecord( + std::unique_ptr record, int index, UniversalId::Type type = UniversalId::Type_None); }; } diff --git a/apps/opencs/model/world/refidadapter.hpp b/apps/opencs/model/world/refidadapter.hpp index 116adb69a7..c98090e7ee 100644 --- a/apps/opencs/model/world/refidadapter.hpp +++ b/apps/opencs/model/world/refidadapter.hpp @@ -5,10 +5,12 @@ #include /*! \brief - * Adapters acts as indirection layer, abstracting details of the record types (in the wrappers) from the higher levels of model. - * Please notice that nested adaptor uses helper classes for actually performing any actions. Different record types require different helpers (needs to be created in the subclass and then fetched via member function). + * Adapters acts as indirection layer, abstracting details of the record types (in the wrappers) from the higher levels + * of model. Please notice that nested adaptor uses helper classes for actually performing any actions. Different record + * types require different helpers (needs to be created in the subclass and then fetched via member function). * - * Important point: don't forget to make sure that getData on the nestedColumn returns true (otherwise code will not treat the index pointing to the column as having children! + * Important point: don't forget to make sure that getData on the nestedColumn returns true (otherwise code will not + * treat the index pointing to the column as having children! */ class QVariant; @@ -23,57 +25,52 @@ namespace CSMWorld class RefIdAdapter { - // not implemented - RefIdAdapter (const RefIdAdapter&); - RefIdAdapter& operator= (const RefIdAdapter&); + // not implemented + RefIdAdapter(const RefIdAdapter&); + RefIdAdapter& operator=(const RefIdAdapter&); - public: + public: + RefIdAdapter(); - RefIdAdapter(); + virtual ~RefIdAdapter(); - virtual ~RefIdAdapter(); + virtual QVariant getData(const RefIdColumn* column, const RefIdData& data, int idnex) const = 0; + ///< If called on the nest column, should return QVariant(true). - virtual QVariant getData (const RefIdColumn *column, const RefIdData& data, int idnex) - const = 0; - ///< If called on the nest column, should return QVariant(true). + virtual void setData(const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const = 0; + ///< If the data type does not match an exception is thrown. - virtual void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const = 0; - ///< If the data type does not match an exception is thrown. + virtual std::string getId(const RecordBase& record) const = 0; - virtual std::string getId (const RecordBase& record) const = 0; - - virtual void setId(RecordBase& record, const std::string& id) = 0; // used by RefIdCollection::cloneRecord() + virtual void setId(RecordBase& record, const std::string& id) = 0; // used by RefIdCollection::cloneRecord() }; class NestedRefIdAdapterBase { - public: - NestedRefIdAdapterBase(); + public: + NestedRefIdAdapterBase(); - virtual ~NestedRefIdAdapterBase(); + virtual ~NestedRefIdAdapterBase(); - virtual void setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const = 0; + virtual void setNestedData(const RefIdColumn* column, RefIdData& data, int row, const QVariant& value, + int subRowIndex, int subColIndex) const = 0; - virtual QVariant getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const = 0; + virtual QVariant getNestedData( + const RefIdColumn* column, const RefIdData& data, int index, int subRowIndex, int subColIndex) const = 0; - virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const = 0; + virtual int getNestedColumnsCount(const RefIdColumn* column, const RefIdData& data) const = 0; - virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const = 0; + virtual int getNestedRowsCount(const RefIdColumn* column, const RefIdData& data, int index) const = 0; - virtual void removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const = 0; + virtual void removeNestedRow(const RefIdColumn* column, RefIdData& data, int index, int rowToRemove) const = 0; - virtual void addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const = 0; + virtual void addNestedRow(const RefIdColumn* column, RefIdData& data, int index, int position) const = 0; - virtual void setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const = 0; + virtual void setNestedTable( + const RefIdColumn* column, RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const = 0; - virtual NestedTableWrapperBase* nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const = 0; + virtual NestedTableWrapperBase* nestedTable( + const RefIdColumn* column, const RefIdData& data, int index) const = 0; }; } diff --git a/apps/opencs/model/world/refidadapterimp.cpp b/apps/opencs/model/world/refidadapterimp.cpp index a30dcadd0b..54917fd0d9 100644 --- a/apps/opencs/model/world/refidadapterimp.cpp +++ b/apps/opencs/model/world/refidadapterimp.cpp @@ -7,44 +7,47 @@ #include "nestedtablewrapper.hpp" -CSMWorld::PotionColumns::PotionColumns (const InventoryColumns& columns) -: InventoryColumns (columns), mEffects(nullptr) {} +CSMWorld::PotionColumns::PotionColumns(const InventoryColumns& columns) + : InventoryColumns(columns) + , mEffects(nullptr) +{ +} -CSMWorld::PotionRefIdAdapter::PotionRefIdAdapter (const PotionColumns& columns, - const RefIdColumn *autoCalc) -: InventoryRefIdAdapter (UniversalId::Type_Potion, columns), - mColumns(columns), mAutoCalc (autoCalc) -{} +CSMWorld::PotionRefIdAdapter::PotionRefIdAdapter(const PotionColumns& columns, const RefIdColumn* autoCalc) + : InventoryRefIdAdapter(UniversalId::Type_Potion, columns) + , mColumns(columns) + , mAutoCalc(autoCalc) +{ +} -QVariant CSMWorld::PotionRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, - int index) const +QVariant CSMWorld::PotionRefIdAdapter::getData(const RefIdColumn* column, const RefIdData& data, int index) const { - const Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Potion))); + const Record& record = static_cast&>( + data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Potion))); - if (column==mAutoCalc) - return record.get().mData.mAutoCalc!=0; + if (column == mAutoCalc) + return record.get().mData.mAutoCalc != 0; // to show nested tables in dialogue subview, see IdTree::hasChildren() - if (column==mColumns.mEffects) + if (column == mColumns.mEffects) return QVariant::fromValue(ColumnBase::TableEdit_Full); - return InventoryRefIdAdapter::getData (column, data, index); + return InventoryRefIdAdapter::getData(column, data, index); } -void CSMWorld::PotionRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const +void CSMWorld::PotionRefIdAdapter::setData( + const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const { - Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Potion))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Potion))); ESM::Potion potion = record.get(); - if (column==mAutoCalc) + if (column == mAutoCalc) potion.mData.mAutoCalc = value.toInt(); else { - InventoryRefIdAdapter::setData (column, data, index, value); + InventoryRefIdAdapter::setData(column, data, index, value); return; } @@ -52,93 +55,93 @@ void CSMWorld::PotionRefIdAdapter::setData (const RefIdColumn *column, RefIdData record.setModified(potion); } +CSMWorld::IngredientColumns::IngredientColumns(const InventoryColumns& columns) + : InventoryColumns(columns) + , mEffects(nullptr) +{ +} -CSMWorld::IngredientColumns::IngredientColumns (const InventoryColumns& columns) -: InventoryColumns (columns) -, mEffects(nullptr) -{} - -CSMWorld::IngredientRefIdAdapter::IngredientRefIdAdapter (const IngredientColumns& columns) -: InventoryRefIdAdapter (UniversalId::Type_Ingredient, columns), - mColumns(columns) -{} +CSMWorld::IngredientRefIdAdapter::IngredientRefIdAdapter(const IngredientColumns& columns) + : InventoryRefIdAdapter(UniversalId::Type_Ingredient, columns) + , mColumns(columns) +{ +} -QVariant CSMWorld::IngredientRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, - int index) const +QVariant CSMWorld::IngredientRefIdAdapter::getData(const RefIdColumn* column, const RefIdData& data, int index) const { - if (column==mColumns.mEffects) + if (column == mColumns.mEffects) return QVariant::fromValue(ColumnBase::TableEdit_FixedRows); - return InventoryRefIdAdapter::getData (column, data, index); + return InventoryRefIdAdapter::getData(column, data, index); } -void CSMWorld::IngredientRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const +void CSMWorld::IngredientRefIdAdapter::setData( + const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const { - InventoryRefIdAdapter::setData (column, data, index, value); + InventoryRefIdAdapter::setData(column, data, index, value); return; } - CSMWorld::IngredEffectRefIdAdapter::IngredEffectRefIdAdapter() -: mType(UniversalId::Type_Ingredient) -{} + : mType(UniversalId::Type_Ingredient) +{ +} -CSMWorld::IngredEffectRefIdAdapter::~IngredEffectRefIdAdapter() -{} +CSMWorld::IngredEffectRefIdAdapter::~IngredEffectRefIdAdapter() {} -void CSMWorld::IngredEffectRefIdAdapter::addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const +void CSMWorld::IngredEffectRefIdAdapter::addNestedRow( + const RefIdColumn* column, RefIdData& data, int index, int position) const { // Do nothing, this table cannot be changed by the user } -void CSMWorld::IngredEffectRefIdAdapter::removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const +void CSMWorld::IngredEffectRefIdAdapter::removeNestedRow( + const RefIdColumn* column, RefIdData& data, int index, int rowToRemove) const { // Do nothing, this table cannot be changed by the user } -void CSMWorld::IngredEffectRefIdAdapter::setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const +void CSMWorld::IngredEffectRefIdAdapter::setNestedTable( + const RefIdColumn* column, RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); ESM::Ingredient ingredient = record.get(); - ingredient.mData = - static_cast >&>(nestedTable).mNestedTable.at(0); + ingredient.mData = static_cast>&>(nestedTable) + .mNestedTable.at(0); - record.setModified (ingredient); + record.setModified(ingredient); } -CSMWorld::NestedTableWrapperBase* CSMWorld::IngredEffectRefIdAdapter::nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const +CSMWorld::NestedTableWrapperBase* CSMWorld::IngredEffectRefIdAdapter::nestedTable( + const RefIdColumn* column, const RefIdData& data, int index) const { - const Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + const Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); // return the whole struct std::vector wrap; wrap.push_back(record.get().mData); // deleted by dtor of NestedTableStoring - return new NestedTableWrapper >(wrap); + return new NestedTableWrapper>(wrap); } -QVariant CSMWorld::IngredEffectRefIdAdapter::getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const +QVariant CSMWorld::IngredEffectRefIdAdapter::getNestedData( + const RefIdColumn* column, const RefIdData& data, int index, int subRowIndex, int subColIndex) const { - const Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + const Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); if (subRowIndex < 0 || subRowIndex >= 4) - throw std::runtime_error ("index out of range"); + throw std::runtime_error("index out of range"); switch (subColIndex) { - case 0: return record.get().mData.mEffectID[subRowIndex]; + case 0: + return record.get().mData.mEffectID[subRowIndex]; case 1: { switch (record.get().mData.mEffectID[subRowIndex]) @@ -172,127 +175,135 @@ QVariant CSMWorld::IngredEffectRefIdAdapter::getNestedData (const RefIdColumn *c } } -void CSMWorld::IngredEffectRefIdAdapter::setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const +void CSMWorld::IngredEffectRefIdAdapter::setNestedData( + const RefIdColumn* column, RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (row, mType))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(row, mType))); ESM::Ingredient ingredient = record.get(); if (subRowIndex < 0 || subRowIndex >= 4) - throw std::runtime_error ("index out of range"); + throw std::runtime_error("index out of range"); - switch(subColIndex) + switch (subColIndex) { - case 0: ingredient.mData.mEffectID[subRowIndex] = value.toInt(); break; - case 1: ingredient.mData.mSkills[subRowIndex] = value.toInt(); break; - case 2: ingredient.mData.mAttributes[subRowIndex] = value.toInt(); break; + case 0: + ingredient.mData.mEffectID[subRowIndex] = value.toInt(); + break; + case 1: + ingredient.mData.mSkills[subRowIndex] = value.toInt(); + break; + case 2: + ingredient.mData.mAttributes[subRowIndex] = value.toInt(); + break; default: throw std::runtime_error("Trying to access non-existing column in the nested table!"); } - record.setModified (ingredient); + record.setModified(ingredient); } -int CSMWorld::IngredEffectRefIdAdapter::getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const +int CSMWorld::IngredEffectRefIdAdapter::getNestedColumnsCount(const RefIdColumn* column, const RefIdData& data) const { return 3; // effect, skill, attribute } -int CSMWorld::IngredEffectRefIdAdapter::getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const +int CSMWorld::IngredEffectRefIdAdapter::getNestedRowsCount( + const RefIdColumn* column, const RefIdData& data, int index) const { return 4; // up to 4 effects } +CSMWorld::ApparatusRefIdAdapter::ApparatusRefIdAdapter( + const InventoryColumns& columns, const RefIdColumn* type, const RefIdColumn* quality) + : InventoryRefIdAdapter(UniversalId::Type_Apparatus, columns) + , mType(type) + , mQuality(quality) +{ +} -CSMWorld::ApparatusRefIdAdapter::ApparatusRefIdAdapter (const InventoryColumns& columns, - const RefIdColumn *type, const RefIdColumn *quality) -: InventoryRefIdAdapter (UniversalId::Type_Apparatus, columns), - mType (type), mQuality (quality) -{} - -QVariant CSMWorld::ApparatusRefIdAdapter::getData (const RefIdColumn *column, - const RefIdData& data, int index) const +QVariant CSMWorld::ApparatusRefIdAdapter::getData(const RefIdColumn* column, const RefIdData& data, int index) const { - const Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Apparatus))); + const Record& record = static_cast&>( + data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Apparatus))); - if (column==mType) + if (column == mType) return record.get().mData.mType; - if (column==mQuality) + if (column == mQuality) return record.get().mData.mQuality; - return InventoryRefIdAdapter::getData (column, data, index); + return InventoryRefIdAdapter::getData(column, data, index); } -void CSMWorld::ApparatusRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const +void CSMWorld::ApparatusRefIdAdapter::setData( + const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const { - Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Apparatus))); + Record& record = static_cast&>( + data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Apparatus))); ESM::Apparatus apparatus = record.get(); - if (column==mType) + if (column == mType) apparatus.mData.mType = value.toInt(); - else if (column==mQuality) + else if (column == mQuality) apparatus.mData.mQuality = value.toFloat(); else { - InventoryRefIdAdapter::setData (column, data, index, value); + InventoryRefIdAdapter::setData(column, data, index, value); return; } record.setModified(apparatus); } +CSMWorld::ArmorRefIdAdapter::ArmorRefIdAdapter(const EnchantableColumns& columns, const RefIdColumn* type, + const RefIdColumn* health, const RefIdColumn* armor, const RefIdColumn* partRef) + : EnchantableRefIdAdapter(UniversalId::Type_Armor, columns) + , mType(type) + , mHealth(health) + , mArmor(armor) + , mPartRef(partRef) +{ +} -CSMWorld::ArmorRefIdAdapter::ArmorRefIdAdapter (const EnchantableColumns& columns, - const RefIdColumn *type, const RefIdColumn *health, const RefIdColumn *armor, - const RefIdColumn *partRef) -: EnchantableRefIdAdapter (UniversalId::Type_Armor, columns), - mType (type), mHealth (health), mArmor (armor), mPartRef(partRef) -{} - -QVariant CSMWorld::ArmorRefIdAdapter::getData (const RefIdColumn *column, - const RefIdData& data, int index) const +QVariant CSMWorld::ArmorRefIdAdapter::getData(const RefIdColumn* column, const RefIdData& data, int index) const { - const Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Armor))); + const Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Armor))); - if (column==mType) + if (column == mType) return record.get().mData.mType; - if (column==mHealth) + if (column == mHealth) return record.get().mData.mHealth; - if (column==mArmor) + if (column == mArmor) return record.get().mData.mArmor; - if (column==mPartRef) + if (column == mPartRef) return QVariant::fromValue(ColumnBase::TableEdit_Full); - return EnchantableRefIdAdapter::getData (column, data, index); + return EnchantableRefIdAdapter::getData(column, data, index); } -void CSMWorld::ArmorRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const +void CSMWorld::ArmorRefIdAdapter::setData( + const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const { - Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Armor))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Armor))); ESM::Armor armor = record.get(); - if (column==mType) + if (column == mType) armor.mData.mType = value.toInt(); - else if (column==mHealth) + else if (column == mHealth) armor.mData.mHealth = value.toInt(); - else if (column==mArmor) + else if (column == mArmor) armor.mData.mArmor = value.toInt(); else { - EnchantableRefIdAdapter::setData (column, data, index, value); + EnchantableRefIdAdapter::setData(column, data, index, value); return; } @@ -300,47 +311,49 @@ void CSMWorld::ArmorRefIdAdapter::setData (const RefIdColumn *column, RefIdData& record.setModified(armor); } -CSMWorld::BookRefIdAdapter::BookRefIdAdapter (const EnchantableColumns& columns, - const RefIdColumn *bookType, const RefIdColumn *skill, const RefIdColumn *text) -: EnchantableRefIdAdapter (UniversalId::Type_Book, columns), - mBookType (bookType), mSkill (skill), mText (text) -{} +CSMWorld::BookRefIdAdapter::BookRefIdAdapter( + const EnchantableColumns& columns, const RefIdColumn* bookType, const RefIdColumn* skill, const RefIdColumn* text) + : EnchantableRefIdAdapter(UniversalId::Type_Book, columns) + , mBookType(bookType) + , mSkill(skill) + , mText(text) +{ +} -QVariant CSMWorld::BookRefIdAdapter::getData (const RefIdColumn *column, - const RefIdData& data, int index) const +QVariant CSMWorld::BookRefIdAdapter::getData(const RefIdColumn* column, const RefIdData& data, int index) const { - const Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Book))); + const Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Book))); - if (column==mBookType) + if (column == mBookType) return record.get().mData.mIsScroll; - if (column==mSkill) + if (column == mSkill) return record.get().mData.mSkillId; - if (column==mText) - return QString::fromUtf8 (record.get().mText.c_str()); + if (column == mText) + return QString::fromUtf8(record.get().mText.c_str()); - return EnchantableRefIdAdapter::getData (column, data, index); + return EnchantableRefIdAdapter::getData(column, data, index); } -void CSMWorld::BookRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const +void CSMWorld::BookRefIdAdapter::setData( + const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const { - Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Book))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Book))); ESM::Book book = record.get(); - if (column==mBookType) + if (column == mBookType) book.mData.mIsScroll = value.toInt(); - else if (column==mSkill) + else if (column == mSkill) book.mData.mSkillId = value.toInt(); - else if (column==mText) + else if (column == mText) book.mText = value.toString().toUtf8().data(); else { - EnchantableRefIdAdapter::setData (column, data, index, value); + EnchantableRefIdAdapter::setData(column, data, index, value); return; } @@ -348,40 +361,41 @@ void CSMWorld::BookRefIdAdapter::setData (const RefIdColumn *column, RefIdData& record.setModified(book); } -CSMWorld::ClothingRefIdAdapter::ClothingRefIdAdapter (const EnchantableColumns& columns, - const RefIdColumn *type, const RefIdColumn *partRef) -: EnchantableRefIdAdapter (UniversalId::Type_Clothing, columns), mType (type), - mPartRef(partRef) -{} +CSMWorld::ClothingRefIdAdapter::ClothingRefIdAdapter( + const EnchantableColumns& columns, const RefIdColumn* type, const RefIdColumn* partRef) + : EnchantableRefIdAdapter(UniversalId::Type_Clothing, columns) + , mType(type) + , mPartRef(partRef) +{ +} -QVariant CSMWorld::ClothingRefIdAdapter::getData (const RefIdColumn *column, - const RefIdData& data, int index) const +QVariant CSMWorld::ClothingRefIdAdapter::getData(const RefIdColumn* column, const RefIdData& data, int index) const { - const Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Clothing))); + const Record& record = static_cast&>( + data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Clothing))); - if (column==mType) + if (column == mType) return record.get().mData.mType; - if (column==mPartRef) + if (column == mPartRef) return QVariant::fromValue(ColumnBase::TableEdit_Full); - return EnchantableRefIdAdapter::getData (column, data, index); + return EnchantableRefIdAdapter::getData(column, data, index); } -void CSMWorld::ClothingRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const +void CSMWorld::ClothingRefIdAdapter::setData( + const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const { - Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Clothing))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Clothing))); ESM::Clothing clothing = record.get(); - if (column==mType) + if (column == mType) clothing.mData.mType = value.toInt(); else { - EnchantableRefIdAdapter::setData (column, data, index, value); + EnchantableRefIdAdapter::setData(column, data, index, value); return; } @@ -389,52 +403,54 @@ void CSMWorld::ClothingRefIdAdapter::setData (const RefIdColumn *column, RefIdDa record.setModified(clothing); } -CSMWorld::ContainerRefIdAdapter::ContainerRefIdAdapter (const NameColumns& columns, - const RefIdColumn *weight, const RefIdColumn *organic, const RefIdColumn *respawn, const RefIdColumn *content) -: NameRefIdAdapter (UniversalId::Type_Container, columns), mWeight (weight), - mOrganic (organic), mRespawn (respawn), mContent(content) -{} +CSMWorld::ContainerRefIdAdapter::ContainerRefIdAdapter(const NameColumns& columns, const RefIdColumn* weight, + const RefIdColumn* organic, const RefIdColumn* respawn, const RefIdColumn* content) + : NameRefIdAdapter(UniversalId::Type_Container, columns) + , mWeight(weight) + , mOrganic(organic) + , mRespawn(respawn) + , mContent(content) +{ +} -QVariant CSMWorld::ContainerRefIdAdapter::getData (const RefIdColumn *column, - const RefIdData& data, - int index) const +QVariant CSMWorld::ContainerRefIdAdapter::getData(const RefIdColumn* column, const RefIdData& data, int index) const { - const Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container))); + const Record& record = static_cast&>( + data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Container))); - if (column==mWeight) + if (column == mWeight) return record.get().mWeight; - if (column==mOrganic) - return (record.get().mFlags & ESM::Container::Organic)!=0; + if (column == mOrganic) + return (record.get().mFlags & ESM::Container::Organic) != 0; - if (column==mRespawn) - return (record.get().mFlags & ESM::Container::Respawn)!=0; + if (column == mRespawn) + return (record.get().mFlags & ESM::Container::Respawn) != 0; - if (column==mContent) + if (column == mContent) return QVariant::fromValue(ColumnBase::TableEdit_Full); - return NameRefIdAdapter::getData (column, data, index); + return NameRefIdAdapter::getData(column, data, index); } -void CSMWorld::ContainerRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const +void CSMWorld::ContainerRefIdAdapter::setData( + const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const { - Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Container))); + Record& record = static_cast&>( + data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Container))); ESM::Container container = record.get(); - if (column==mWeight) + if (column == mWeight) container.mWeight = value.toFloat(); - else if (column==mOrganic) + else if (column == mOrganic) { if (value.toInt()) container.mFlags |= ESM::Container::Organic; else container.mFlags &= ~ESM::Container::Organic; } - else if (column==mRespawn) + else if (column == mRespawn) { if (value.toInt()) container.mFlags |= ESM::Container::Respawn; @@ -443,7 +459,7 @@ void CSMWorld::ContainerRefIdAdapter::setData (const RefIdColumn *column, RefIdD } else { - NameRefIdAdapter::setData (column, data, index, value); + NameRefIdAdapter::setData(column, data, index, value); return; } @@ -451,88 +467,88 @@ void CSMWorld::ContainerRefIdAdapter::setData (const RefIdColumn *column, RefIdD record.setModified(container); } -CSMWorld::CreatureColumns::CreatureColumns (const ActorColumns& actorColumns) -: ActorColumns (actorColumns), - mType(nullptr), - mScale(nullptr), - mOriginal(nullptr), - mAttributes(nullptr), - mAttacks(nullptr), - mMisc(nullptr), - mBloodType(nullptr) -{} +CSMWorld::CreatureColumns::CreatureColumns(const ActorColumns& actorColumns) + : ActorColumns(actorColumns) + , mType(nullptr) + , mScale(nullptr) + , mOriginal(nullptr) + , mAttributes(nullptr) + , mAttacks(nullptr) + , mMisc(nullptr) + , mBloodType(nullptr) +{ +} -CSMWorld::CreatureRefIdAdapter::CreatureRefIdAdapter (const CreatureColumns& columns) -: ActorRefIdAdapter (UniversalId::Type_Creature, columns), mColumns (columns) -{} +CSMWorld::CreatureRefIdAdapter::CreatureRefIdAdapter(const CreatureColumns& columns) + : ActorRefIdAdapter(UniversalId::Type_Creature, columns) + , mColumns(columns) +{ +} -QVariant CSMWorld::CreatureRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, - int index) const +QVariant CSMWorld::CreatureRefIdAdapter::getData(const RefIdColumn* column, const RefIdData& data, int index) const { - const Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Creature))); + const Record& record = static_cast&>( + data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Creature))); - if (column==mColumns.mType) + if (column == mColumns.mType) return record.get().mData.mType; - if (column==mColumns.mScale) + if (column == mColumns.mScale) return record.get().mScale; - if (column==mColumns.mOriginal) - return QString::fromUtf8 (record.get().mOriginal.c_str()); + if (column == mColumns.mOriginal) + return QString::fromUtf8(record.get().mOriginal.c_str()); - if (column==mColumns.mAttributes) + if (column == mColumns.mAttributes) return QVariant::fromValue(ColumnBase::TableEdit_FixedRows); - if (column==mColumns.mAttacks) + if (column == mColumns.mAttacks) return QVariant::fromValue(ColumnBase::TableEdit_FixedRows); - if (column==mColumns.mMisc) + if (column == mColumns.mMisc) return QVariant::fromValue(ColumnBase::TableEdit_Full); if (column == mColumns.mBloodType) return record.get().mBloodType; - std::map::const_iterator iter = - mColumns.mFlags.find (column); + std::map::const_iterator iter = mColumns.mFlags.find(column); - if (iter!=mColumns.mFlags.end()) - return (record.get().mFlags & iter->second)!=0; + if (iter != mColumns.mFlags.end()) + return (record.get().mFlags & iter->second) != 0; - return ActorRefIdAdapter::getData (column, data, index); + return ActorRefIdAdapter::getData(column, data, index); } -void CSMWorld::CreatureRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const +void CSMWorld::CreatureRefIdAdapter::setData( + const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const { - Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Creature))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Creature))); ESM::Creature creature = record.get(); - if (column==mColumns.mType) + if (column == mColumns.mType) creature.mData.mType = value.toInt(); - else if (column==mColumns.mScale) + else if (column == mColumns.mScale) creature.mScale = value.toFloat(); - else if (column==mColumns.mOriginal) + else if (column == mColumns.mOriginal) creature.mOriginal = value.toString().toUtf8().constData(); else if (column == mColumns.mBloodType) creature.mBloodType = value.toInt(); else { - std::map::const_iterator iter = - mColumns.mFlags.find (column); + std::map::const_iterator iter = mColumns.mFlags.find(column); - if (iter!=mColumns.mFlags.end()) + if (iter != mColumns.mFlags.end()) { - if (value.toInt()!=0) + if (value.toInt() != 0) creature.mFlags |= iter->second; else creature.mFlags &= ~iter->second; } else { - ActorRefIdAdapter::setData (column, data, index, value); + ActorRefIdAdapter::setData(column, data, index, value); return; } @@ -541,42 +557,43 @@ void CSMWorld::CreatureRefIdAdapter::setData (const RefIdColumn *column, RefIdDa record.setModified(creature); } -CSMWorld::DoorRefIdAdapter::DoorRefIdAdapter (const NameColumns& columns, - const RefIdColumn *openSound, const RefIdColumn *closeSound) -: NameRefIdAdapter (UniversalId::Type_Door, columns), mOpenSound (openSound), - mCloseSound (closeSound) -{} +CSMWorld::DoorRefIdAdapter::DoorRefIdAdapter( + const NameColumns& columns, const RefIdColumn* openSound, const RefIdColumn* closeSound) + : NameRefIdAdapter(UniversalId::Type_Door, columns) + , mOpenSound(openSound) + , mCloseSound(closeSound) +{ +} -QVariant CSMWorld::DoorRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, - int index) const +QVariant CSMWorld::DoorRefIdAdapter::getData(const RefIdColumn* column, const RefIdData& data, int index) const { - const Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Door))); + const Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Door))); - if (column==mOpenSound) - return QString::fromUtf8 (record.get().mOpenSound.c_str()); + if (column == mOpenSound) + return QString::fromUtf8(record.get().mOpenSound.c_str()); - if (column==mCloseSound) - return QString::fromUtf8 (record.get().mCloseSound.c_str()); + if (column == mCloseSound) + return QString::fromUtf8(record.get().mCloseSound.c_str()); - return NameRefIdAdapter::getData (column, data, index); + return NameRefIdAdapter::getData(column, data, index); } -void CSMWorld::DoorRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const +void CSMWorld::DoorRefIdAdapter::setData( + const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const { - Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Door))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Door))); ESM::Door door = record.get(); - if (column==mOpenSound) + if (column == mOpenSound) door.mOpenSound = value.toString().toUtf8().constData(); - else if (column==mCloseSound) + else if (column == mCloseSound) door.mCloseSound = value.toString().toUtf8().constData(); else { - NameRefIdAdapter::setData (column, data, index, value); + NameRefIdAdapter::setData(column, data, index, value); return; } @@ -584,36 +601,38 @@ void CSMWorld::DoorRefIdAdapter::setData (const RefIdColumn *column, RefIdData& record.setModified(door); } -CSMWorld::LightColumns::LightColumns (const InventoryColumns& columns) -: InventoryColumns (columns) -, mTime(nullptr) -, mRadius(nullptr) -, mColor(nullptr) -, mSound(nullptr) -, mEmitterType(nullptr) -{} +CSMWorld::LightColumns::LightColumns(const InventoryColumns& columns) + : InventoryColumns(columns) + , mTime(nullptr) + , mRadius(nullptr) + , mColor(nullptr) + , mSound(nullptr) + , mEmitterType(nullptr) +{ +} -CSMWorld::LightRefIdAdapter::LightRefIdAdapter (const LightColumns& columns) -: InventoryRefIdAdapter (UniversalId::Type_Light, columns), mColumns (columns) -{} +CSMWorld::LightRefIdAdapter::LightRefIdAdapter(const LightColumns& columns) + : InventoryRefIdAdapter(UniversalId::Type_Light, columns) + , mColumns(columns) +{ +} -QVariant CSMWorld::LightRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, - int index) const +QVariant CSMWorld::LightRefIdAdapter::getData(const RefIdColumn* column, const RefIdData& data, int index) const { - const Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Light))); + const Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Light))); - if (column==mColumns.mTime) + if (column == mColumns.mTime) return record.get().mData.mTime; - if (column==mColumns.mRadius) + if (column == mColumns.mRadius) return record.get().mData.mRadius; - if (column==mColumns.mColor) + if (column == mColumns.mColor) return record.get().mData.mColor; - if (column==mColumns.mSound) - return QString::fromUtf8 (record.get().mSound.c_str()); + if (column == mColumns.mSound) + return QString::fromUtf8(record.get().mSound.c_str()); if (column == mColumns.mEmitterType) { @@ -634,30 +653,29 @@ QVariant CSMWorld::LightRefIdAdapter::getData (const RefIdColumn *column, const return 0; } - std::map::const_iterator iter = - mColumns.mFlags.find (column); + std::map::const_iterator iter = mColumns.mFlags.find(column); - if (iter!=mColumns.mFlags.end()) - return (record.get().mData.mFlags & iter->second)!=0; + if (iter != mColumns.mFlags.end()) + return (record.get().mData.mFlags & iter->second) != 0; - return InventoryRefIdAdapter::getData (column, data, index); + return InventoryRefIdAdapter::getData(column, data, index); } -void CSMWorld::LightRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const +void CSMWorld::LightRefIdAdapter::setData( + const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const { - Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Light))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Light))); ESM::Light light = record.get(); - if (column==mColumns.mTime) + if (column == mColumns.mTime) light.mData.mTime = value.toInt(); - else if (column==mColumns.mRadius) + else if (column == mColumns.mRadius) light.mData.mRadius = value.toInt(); - else if (column==mColumns.mColor) + else if (column == mColumns.mColor) light.mData.mColor = value.toInt(); - else if (column==mColumns.mSound) + else if (column == mColumns.mSound) light.mSound = value.toString().toUtf8().constData(); else if (column == mColumns.mEmitterType) { @@ -676,56 +694,56 @@ void CSMWorld::LightRefIdAdapter::setData (const RefIdColumn *column, RefIdData& } else { - std::map::const_iterator iter = - mColumns.mFlags.find (column); + std::map::const_iterator iter = mColumns.mFlags.find(column); - if (iter!=mColumns.mFlags.end()) + if (iter != mColumns.mFlags.end()) { - if (value.toInt()!=0) + if (value.toInt() != 0) light.mData.mFlags |= iter->second; else light.mData.mFlags &= ~iter->second; } else { - InventoryRefIdAdapter::setData (column, data, index, value); + InventoryRefIdAdapter::setData(column, data, index, value); return; } } - record.setModified (light); + record.setModified(light); } -CSMWorld::MiscRefIdAdapter::MiscRefIdAdapter (const InventoryColumns& columns, const RefIdColumn *key) -: InventoryRefIdAdapter (UniversalId::Type_Miscellaneous, columns), mKey (key) -{} +CSMWorld::MiscRefIdAdapter::MiscRefIdAdapter(const InventoryColumns& columns, const RefIdColumn* key) + : InventoryRefIdAdapter(UniversalId::Type_Miscellaneous, columns) + , mKey(key) +{ +} -QVariant CSMWorld::MiscRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, - int index) const +QVariant CSMWorld::MiscRefIdAdapter::getData(const RefIdColumn* column, const RefIdData& data, int index) const { - const Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Miscellaneous))); + const Record& record = static_cast&>( + data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Miscellaneous))); - if (column==mKey) - return record.get().mData.mIsKey!=0; + if (column == mKey) + return record.get().mData.mIsKey != 0; - return InventoryRefIdAdapter::getData (column, data, index); + return InventoryRefIdAdapter::getData(column, data, index); } -void CSMWorld::MiscRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const +void CSMWorld::MiscRefIdAdapter::setData( + const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const { - Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Miscellaneous))); + Record& record = static_cast&>( + data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Miscellaneous))); ESM::Miscellaneous misc = record.get(); - if (column==mKey) + if (column == mKey) misc.mData.mIsKey = value.toInt(); else { - InventoryRefIdAdapter::setData (column, data, index, value); + InventoryRefIdAdapter::setData(column, data, index, value); return; } @@ -733,46 +751,48 @@ void CSMWorld::MiscRefIdAdapter::setData (const RefIdColumn *column, RefIdData& record.setModified(misc); } -CSMWorld::NpcColumns::NpcColumns (const ActorColumns& actorColumns) -: ActorColumns (actorColumns), - mRace(nullptr), - mClass(nullptr), - mFaction(nullptr), - mHair(nullptr), - mHead(nullptr), - mAttributes(nullptr), - mSkills(nullptr), - mMisc(nullptr), - mBloodType(nullptr), - mGender(nullptr) -{} +CSMWorld::NpcColumns::NpcColumns(const ActorColumns& actorColumns) + : ActorColumns(actorColumns) + , mRace(nullptr) + , mClass(nullptr) + , mFaction(nullptr) + , mHair(nullptr) + , mHead(nullptr) + , mAttributes(nullptr) + , mSkills(nullptr) + , mMisc(nullptr) + , mBloodType(nullptr) + , mGender(nullptr) +{ +} -CSMWorld::NpcRefIdAdapter::NpcRefIdAdapter (const NpcColumns& columns) -: ActorRefIdAdapter (UniversalId::Type_Npc, columns), mColumns (columns) -{} +CSMWorld::NpcRefIdAdapter::NpcRefIdAdapter(const NpcColumns& columns) + : ActorRefIdAdapter(UniversalId::Type_Npc, columns) + , mColumns(columns) +{ +} -QVariant CSMWorld::NpcRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, int index) - const +QVariant CSMWorld::NpcRefIdAdapter::getData(const RefIdColumn* column, const RefIdData& data, int index) const { - const Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc))); + const Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Npc))); - if (column==mColumns.mRace) - return QString::fromUtf8 (record.get().mRace.c_str()); + if (column == mColumns.mRace) + return QString::fromUtf8(record.get().mRace.c_str()); - if (column==mColumns.mClass) - return QString::fromUtf8 (record.get().mClass.c_str()); + if (column == mColumns.mClass) + return QString::fromUtf8(record.get().mClass.c_str()); - if (column==mColumns.mFaction) - return QString::fromUtf8 (record.get().mFaction.c_str()); + if (column == mColumns.mFaction) + return QString::fromUtf8(record.get().mFaction.c_str()); - if (column==mColumns.mHair) - return QString::fromUtf8 (record.get().mHair.c_str()); + if (column == mColumns.mHair) + return QString::fromUtf8(record.get().mHair.c_str()); - if (column==mColumns.mHead) - return QString::fromUtf8 (record.get().mHead.c_str()); + if (column == mColumns.mHead) + return QString::fromUtf8(record.get().mHead.c_str()); - if (column==mColumns.mAttributes || column==mColumns.mSkills) + if (column == mColumns.mAttributes || column == mColumns.mSkills) { if ((record.get().mFlags & ESM::NPC::Autocalc) != 0) return QVariant::fromValue(ColumnBase::TableEdit_None); @@ -780,7 +800,7 @@ QVariant CSMWorld::NpcRefIdAdapter::getData (const RefIdColumn *column, const Re return QVariant::fromValue(ColumnBase::TableEdit_FixedRows); } - if (column==mColumns.mMisc) + if (column == mColumns.mMisc) return QVariant::fromValue(ColumnBase::TableEdit_Full); if (column == mColumns.mBloodType) @@ -795,32 +815,31 @@ QVariant CSMWorld::NpcRefIdAdapter::getData (const RefIdColumn *column, const Re return 0; } - std::map::const_iterator iter = - mColumns.mFlags.find (column); + std::map::const_iterator iter = mColumns.mFlags.find(column); - if (iter!=mColumns.mFlags.end()) - return (record.get().mFlags & iter->second)!=0; + if (iter != mColumns.mFlags.end()) + return (record.get().mFlags & iter->second) != 0; - return ActorRefIdAdapter::getData (column, data, index); + return ActorRefIdAdapter::getData(column, data, index); } -void CSMWorld::NpcRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const +void CSMWorld::NpcRefIdAdapter::setData( + const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const { - Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Npc))); ESM::NPC npc = record.get(); - if (column==mColumns.mRace) + if (column == mColumns.mRace) npc.mRace = value.toString().toUtf8().constData(); - else if (column==mColumns.mClass) + else if (column == mColumns.mClass) npc.mClass = value.toString().toUtf8().constData(); - else if (column==mColumns.mFaction) + else if (column == mColumns.mFaction) npc.mFaction = value.toString().toUtf8().constData(); - else if (column==mColumns.mHair) + else if (column == mColumns.mHair) npc.mHair = value.toString().toUtf8().constData(); - else if (column==mColumns.mHead) + else if (column == mColumns.mHead) npc.mHead = value.toString().toUtf8().constData(); else if (column == mColumns.mBloodType) npc.mBloodType = value.toInt(); @@ -834,78 +853,75 @@ void CSMWorld::NpcRefIdAdapter::setData (const RefIdColumn *column, RefIdData& d } else { - std::map::const_iterator iter = - mColumns.mFlags.find (column); + std::map::const_iterator iter = mColumns.mFlags.find(column); - if (iter!=mColumns.mFlags.end()) + if (iter != mColumns.mFlags.end()) { - if (value.toInt()!=0) + if (value.toInt() != 0) npc.mFlags |= iter->second; else 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; + npc.mNpdtType = (value.toInt() != 0) ? ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS : ESM::NPC::NPC_DEFAULT; } else { - ActorRefIdAdapter::setData (column, data, index, value); + ActorRefIdAdapter::setData(column, data, index, value); return; } } - record.setModified (npc); + record.setModified(npc); } -CSMWorld::NpcAttributesRefIdAdapter::NpcAttributesRefIdAdapter () -{} +CSMWorld::NpcAttributesRefIdAdapter::NpcAttributesRefIdAdapter() {} -void CSMWorld::NpcAttributesRefIdAdapter::addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const +void CSMWorld::NpcAttributesRefIdAdapter::addNestedRow( + const RefIdColumn* column, RefIdData& data, int index, int position) const { // Do nothing, this table cannot be changed by the user } -void CSMWorld::NpcAttributesRefIdAdapter::removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const +void CSMWorld::NpcAttributesRefIdAdapter::removeNestedRow( + const RefIdColumn* column, RefIdData& data, int index, int rowToRemove) const { // Do nothing, this table cannot be changed by the user } -void CSMWorld::NpcAttributesRefIdAdapter::setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const +void CSMWorld::NpcAttributesRefIdAdapter::setNestedTable( + const RefIdColumn* column, RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Npc))); ESM::NPC npc = record.get(); // store the whole struct - npc.mNpdt = - static_cast > &>(nestedTable).mNestedTable.at(0); + npc.mNpdt + = static_cast>&>(nestedTable).mNestedTable.at(0); - record.setModified (npc); + record.setModified(npc); } -CSMWorld::NestedTableWrapperBase* CSMWorld::NpcAttributesRefIdAdapter::nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const +CSMWorld::NestedTableWrapperBase* CSMWorld::NpcAttributesRefIdAdapter::nestedTable( + const RefIdColumn* column, const RefIdData& data, int index) const { - const Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc))); + const Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Npc))); // return the whole struct std::vector wrap; wrap.push_back(record.get().mNpdt); // deleted by dtor of NestedTableStoring - return new NestedTableWrapper >(wrap); + return new NestedTableWrapper>(wrap); } -QVariant CSMWorld::NpcAttributesRefIdAdapter::getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const +QVariant CSMWorld::NpcAttributesRefIdAdapter::getNestedData( + const RefIdColumn* column, const RefIdData& data, int index, int subRowIndex, int subColIndex) const { - const Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc))); + const Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Npc))); const ESM::NPC::NPDTstruct52& npcStruct = record.get().mNpdt; @@ -914,110 +930,136 @@ QVariant CSMWorld::NpcAttributesRefIdAdapter::getNestedData (const RefIdColumn * else if (subColIndex == 1) switch (subRowIndex) { - case 0: return static_cast(npcStruct.mStrength); - case 1: return static_cast(npcStruct.mIntelligence); - case 2: return static_cast(npcStruct.mWillpower); - case 3: return static_cast(npcStruct.mAgility); - case 4: return static_cast(npcStruct.mSpeed); - case 5: return static_cast(npcStruct.mEndurance); - case 6: return static_cast(npcStruct.mPersonality); - case 7: return static_cast(npcStruct.mLuck); - default: return QVariant(); // throw an exception here? + case 0: + return static_cast(npcStruct.mStrength); + case 1: + return static_cast(npcStruct.mIntelligence); + case 2: + return static_cast(npcStruct.mWillpower); + case 3: + return static_cast(npcStruct.mAgility); + case 4: + return static_cast(npcStruct.mSpeed); + case 5: + return static_cast(npcStruct.mEndurance); + case 6: + return static_cast(npcStruct.mPersonality); + case 7: + return static_cast(npcStruct.mLuck); + default: + return QVariant(); // throw an exception here? } else return QVariant(); // throw an exception here? } -void CSMWorld::NpcAttributesRefIdAdapter::setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const +void CSMWorld::NpcAttributesRefIdAdapter::setNestedData( + const RefIdColumn* column, RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (row, UniversalId::Type_Npc))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(row, UniversalId::Type_Npc))); ESM::NPC npc = record.get(); ESM::NPC::NPDTstruct52& npcStruct = npc.mNpdt; if (subColIndex == 1) - switch(subRowIndex) + switch (subRowIndex) { - case 0: npcStruct.mStrength = static_cast(value.toInt()); break; - case 1: npcStruct.mIntelligence = static_cast(value.toInt()); break; - case 2: npcStruct.mWillpower = static_cast(value.toInt()); break; - case 3: npcStruct.mAgility = static_cast(value.toInt()); break; - case 4: npcStruct.mSpeed = static_cast(value.toInt()); break; - case 5: npcStruct.mEndurance = static_cast(value.toInt()); break; - case 6: npcStruct.mPersonality = static_cast(value.toInt()); break; - case 7: npcStruct.mLuck = static_cast(value.toInt()); break; - default: return; // throw an exception here? + case 0: + npcStruct.mStrength = static_cast(value.toInt()); + break; + case 1: + npcStruct.mIntelligence = static_cast(value.toInt()); + break; + case 2: + npcStruct.mWillpower = static_cast(value.toInt()); + break; + case 3: + npcStruct.mAgility = static_cast(value.toInt()); + break; + case 4: + npcStruct.mSpeed = static_cast(value.toInt()); + break; + case 5: + npcStruct.mEndurance = static_cast(value.toInt()); + break; + case 6: + npcStruct.mPersonality = static_cast(value.toInt()); + break; + case 7: + npcStruct.mLuck = static_cast(value.toInt()); + break; + default: + return; // throw an exception here? } else return; // throw an exception here? - record.setModified (npc); + record.setModified(npc); } -int CSMWorld::NpcAttributesRefIdAdapter::getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const +int CSMWorld::NpcAttributesRefIdAdapter::getNestedColumnsCount(const RefIdColumn* column, const RefIdData& data) const { return 2; } -int CSMWorld::NpcAttributesRefIdAdapter::getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const +int CSMWorld::NpcAttributesRefIdAdapter::getNestedRowsCount( + const RefIdColumn* column, const RefIdData& data, int index) const { // There are 8 attributes return 8; } -CSMWorld::NpcSkillsRefIdAdapter::NpcSkillsRefIdAdapter () -{} +CSMWorld::NpcSkillsRefIdAdapter::NpcSkillsRefIdAdapter() {} -void CSMWorld::NpcSkillsRefIdAdapter::addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const +void CSMWorld::NpcSkillsRefIdAdapter::addNestedRow( + const RefIdColumn* column, RefIdData& data, int index, int position) const { // Do nothing, this table cannot be changed by the user } -void CSMWorld::NpcSkillsRefIdAdapter::removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const +void CSMWorld::NpcSkillsRefIdAdapter::removeNestedRow( + const RefIdColumn* column, RefIdData& data, int index, int rowToRemove) const { // Do nothing, this table cannot be changed by the user } -void CSMWorld::NpcSkillsRefIdAdapter::setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const +void CSMWorld::NpcSkillsRefIdAdapter::setNestedTable( + const RefIdColumn* column, RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Npc))); ESM::NPC npc = record.get(); // store the whole struct - npc.mNpdt = - static_cast > &>(nestedTable).mNestedTable.at(0); + npc.mNpdt + = static_cast>&>(nestedTable).mNestedTable.at(0); - record.setModified (npc); + record.setModified(npc); } -CSMWorld::NestedTableWrapperBase* CSMWorld::NpcSkillsRefIdAdapter::nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const +CSMWorld::NestedTableWrapperBase* CSMWorld::NpcSkillsRefIdAdapter::nestedTable( + const RefIdColumn* column, const RefIdData& data, int index) const { - const Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc))); + const Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Npc))); // return the whole struct std::vector wrap; wrap.push_back(record.get().mNpdt); // deleted by dtor of NestedTableStoring - return new NestedTableWrapper >(wrap); + return new NestedTableWrapper>(wrap); } -QVariant CSMWorld::NpcSkillsRefIdAdapter::getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const +QVariant CSMWorld::NpcSkillsRefIdAdapter::getNestedData( + const RefIdColumn* column, const RefIdData& data, int index, int subRowIndex, int subColIndex) const { - const Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc))); + const Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Npc))); const ESM::NPC::NPDTstruct52& npcStruct = record.get().mNpdt; if (subRowIndex < 0 || subRowIndex >= ESM::Skill::Length) - throw std::runtime_error ("index out of range"); + throw std::runtime_error("index out of range"); if (subColIndex == 0) return subRowIndex; @@ -1027,198 +1069,245 @@ QVariant CSMWorld::NpcSkillsRefIdAdapter::getNestedData (const RefIdColumn *colu return QVariant(); // throw an exception here? } -void CSMWorld::NpcSkillsRefIdAdapter::setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const +void CSMWorld::NpcSkillsRefIdAdapter::setNestedData( + const RefIdColumn* column, RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (row, UniversalId::Type_Npc))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(row, UniversalId::Type_Npc))); ESM::NPC npc = record.get(); ESM::NPC::NPDTstruct52& npcStruct = npc.mNpdt; if (subRowIndex < 0 || subRowIndex >= ESM::Skill::Length) - throw std::runtime_error ("index out of range"); + throw std::runtime_error("index out of range"); if (subColIndex == 1) npcStruct.mSkills[subRowIndex] = static_cast(value.toInt()); else return; // throw an exception here? - record.setModified (npc); + record.setModified(npc); } -int CSMWorld::NpcSkillsRefIdAdapter::getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const +int CSMWorld::NpcSkillsRefIdAdapter::getNestedColumnsCount(const RefIdColumn* column, const RefIdData& data) const { return 2; } -int CSMWorld::NpcSkillsRefIdAdapter::getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const +int CSMWorld::NpcSkillsRefIdAdapter::getNestedRowsCount( + const RefIdColumn* column, const RefIdData& data, int index) const { // There are 27 skills return ESM::Skill::Length; } -CSMWorld::NpcMiscRefIdAdapter::NpcMiscRefIdAdapter () -{} +CSMWorld::NpcMiscRefIdAdapter::NpcMiscRefIdAdapter() {} -CSMWorld::NpcMiscRefIdAdapter::~NpcMiscRefIdAdapter() -{} +CSMWorld::NpcMiscRefIdAdapter::~NpcMiscRefIdAdapter() {} -void CSMWorld::NpcMiscRefIdAdapter::addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const +void CSMWorld::NpcMiscRefIdAdapter::addNestedRow( + const RefIdColumn* column, RefIdData& data, int index, int position) const { - throw std::logic_error ("cannot add a row to a fixed table"); + throw std::logic_error("cannot add a row to a fixed table"); } -void CSMWorld::NpcMiscRefIdAdapter::removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const +void CSMWorld::NpcMiscRefIdAdapter::removeNestedRow( + const RefIdColumn* column, RefIdData& data, int index, int rowToRemove) const { - throw std::logic_error ("cannot remove a row to a fixed table"); + throw std::logic_error("cannot remove a row to a fixed table"); } -void CSMWorld::NpcMiscRefIdAdapter::setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const +void CSMWorld::NpcMiscRefIdAdapter::setNestedTable( + const RefIdColumn* column, RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const { - throw std::logic_error ("table operation not supported"); + throw std::logic_error("table operation not supported"); } -CSMWorld::NestedTableWrapperBase* CSMWorld::NpcMiscRefIdAdapter::nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const +CSMWorld::NestedTableWrapperBase* CSMWorld::NpcMiscRefIdAdapter::nestedTable( + const RefIdColumn* column, const RefIdData& data, int index) const { - throw std::logic_error ("table operation not supported"); + throw std::logic_error("table operation not supported"); } -QVariant CSMWorld::NpcMiscRefIdAdapter::getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const +QVariant CSMWorld::NpcMiscRefIdAdapter::getNestedData( + const RefIdColumn* column, const RefIdData& data, int index, int subRowIndex, int subColIndex) const { - const Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc))); + const Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Npc))); bool autoCalc = (record.get().mFlags & ESM::NPC::Autocalc) != 0; if (autoCalc) switch (subColIndex) { - case 0: return static_cast(record.get().mNpdt.mLevel); - case 1: return QVariant(QVariant::UserType); - case 2: return QVariant(QVariant::UserType); - case 3: return QVariant(QVariant::UserType); - case 4: return static_cast(record.get().mNpdt.mDisposition); - case 5: return static_cast(record.get().mNpdt.mReputation); - case 6: return static_cast(record.get().mNpdt.mRank); - case 7: return record.get().mNpdt.mGold; - default: return QVariant(); // throw an exception here? + case 0: + return static_cast(record.get().mNpdt.mLevel); + case 1: + return QVariant(QVariant::UserType); + case 2: + return QVariant(QVariant::UserType); + case 3: + return QVariant(QVariant::UserType); + case 4: + return static_cast(record.get().mNpdt.mDisposition); + case 5: + return static_cast(record.get().mNpdt.mReputation); + case 6: + return static_cast(record.get().mNpdt.mRank); + case 7: + return record.get().mNpdt.mGold; + default: + return QVariant(); // throw an exception here? } else switch (subColIndex) { - case 0: return static_cast(record.get().mNpdt.mLevel); - case 1: return static_cast(record.get().mNpdt.mHealth); - case 2: return static_cast(record.get().mNpdt.mMana); - case 3: return static_cast(record.get().mNpdt.mFatigue); - case 4: return static_cast(record.get().mNpdt.mDisposition); - case 5: return static_cast(record.get().mNpdt.mReputation); - case 6: return static_cast(record.get().mNpdt.mRank); - case 7: return record.get().mNpdt.mGold; - default: return QVariant(); // throw an exception here? + case 0: + return static_cast(record.get().mNpdt.mLevel); + case 1: + return static_cast(record.get().mNpdt.mHealth); + case 2: + return static_cast(record.get().mNpdt.mMana); + case 3: + return static_cast(record.get().mNpdt.mFatigue); + case 4: + return static_cast(record.get().mNpdt.mDisposition); + case 5: + return static_cast(record.get().mNpdt.mReputation); + case 6: + return static_cast(record.get().mNpdt.mRank); + case 7: + return record.get().mNpdt.mGold; + default: + return QVariant(); // throw an exception here? } } -void CSMWorld::NpcMiscRefIdAdapter::setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const +void CSMWorld::NpcMiscRefIdAdapter::setNestedData( + const RefIdColumn* column, RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (row, UniversalId::Type_Npc))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(row, UniversalId::Type_Npc))); ESM::NPC npc = record.get(); bool autoCalc = (record.get().mFlags & ESM::NPC::Autocalc) != 0; if (autoCalc) - switch(subColIndex) + switch (subColIndex) { - case 0: npc.mNpdt.mLevel = static_cast(value.toInt()); break; - case 1: return; - case 2: return; - case 3: return; - case 4: npc.mNpdt.mDisposition = static_cast(value.toInt()); break; - case 5: npc.mNpdt.mReputation = static_cast(value.toInt()); break; - case 6: npc.mNpdt.mRank = static_cast(value.toInt()); break; - case 7: npc.mNpdt.mGold = value.toInt(); break; - default: return; // throw an exception here? + case 0: + npc.mNpdt.mLevel = static_cast(value.toInt()); + break; + case 1: + return; + case 2: + return; + case 3: + return; + case 4: + npc.mNpdt.mDisposition = static_cast(value.toInt()); + break; + case 5: + npc.mNpdt.mReputation = static_cast(value.toInt()); + break; + case 6: + npc.mNpdt.mRank = static_cast(value.toInt()); + break; + case 7: + npc.mNpdt.mGold = value.toInt(); + break; + default: + return; // throw an exception here? } else - switch(subColIndex) + switch (subColIndex) { - case 0: npc.mNpdt.mLevel = static_cast(value.toInt()); break; - case 1: npc.mNpdt.mHealth = static_cast(value.toInt()); break; - case 2: npc.mNpdt.mMana = static_cast(value.toInt()); break; - case 3: npc.mNpdt.mFatigue = static_cast(value.toInt()); break; - case 4: npc.mNpdt.mDisposition = static_cast(value.toInt()); break; - case 5: npc.mNpdt.mReputation = static_cast(value.toInt()); break; - case 6: npc.mNpdt.mRank = static_cast(value.toInt()); break; - case 7: npc.mNpdt.mGold = value.toInt(); break; - default: return; // throw an exception here? + case 0: + npc.mNpdt.mLevel = static_cast(value.toInt()); + break; + case 1: + npc.mNpdt.mHealth = static_cast(value.toInt()); + break; + case 2: + npc.mNpdt.mMana = static_cast(value.toInt()); + break; + case 3: + npc.mNpdt.mFatigue = static_cast(value.toInt()); + break; + case 4: + npc.mNpdt.mDisposition = static_cast(value.toInt()); + break; + case 5: + npc.mNpdt.mReputation = static_cast(value.toInt()); + break; + case 6: + npc.mNpdt.mRank = static_cast(value.toInt()); + break; + case 7: + npc.mNpdt.mGold = value.toInt(); + break; + default: + return; // throw an exception here? } - record.setModified (npc); + record.setModified(npc); } -int CSMWorld::NpcMiscRefIdAdapter::getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const +int CSMWorld::NpcMiscRefIdAdapter::getNestedColumnsCount(const RefIdColumn* column, const RefIdData& data) const { return 8; // Level, Health, Mana, Fatigue, Disposition, Reputation, Rank, Gold } -int CSMWorld::NpcMiscRefIdAdapter::getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const +int CSMWorld::NpcMiscRefIdAdapter::getNestedRowsCount(const RefIdColumn* column, const RefIdData& data, int index) const { return 1; // fixed at size 1 } -CSMWorld::CreatureAttributesRefIdAdapter::CreatureAttributesRefIdAdapter() -{} +CSMWorld::CreatureAttributesRefIdAdapter::CreatureAttributesRefIdAdapter() {} -void CSMWorld::CreatureAttributesRefIdAdapter::addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const +void CSMWorld::CreatureAttributesRefIdAdapter::addNestedRow( + const RefIdColumn* column, RefIdData& data, int index, int position) const { // Do nothing, this table cannot be changed by the user } -void CSMWorld::CreatureAttributesRefIdAdapter::removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const +void CSMWorld::CreatureAttributesRefIdAdapter::removeNestedRow( + const RefIdColumn* column, RefIdData& data, int index, int rowToRemove) const { // Do nothing, this table cannot be changed by the user } -void CSMWorld::CreatureAttributesRefIdAdapter::setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const +void CSMWorld::CreatureAttributesRefIdAdapter::setNestedTable( + const RefIdColumn* column, RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Creature))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Creature))); ESM::Creature creature = record.get(); // store the whole struct - creature.mData = - static_cast > &>(nestedTable).mNestedTable.at(0); + creature.mData = static_cast>&>(nestedTable) + .mNestedTable.at(0); - record.setModified (creature); + record.setModified(creature); } -CSMWorld::NestedTableWrapperBase* CSMWorld::CreatureAttributesRefIdAdapter::nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const +CSMWorld::NestedTableWrapperBase* CSMWorld::CreatureAttributesRefIdAdapter::nestedTable( + const RefIdColumn* column, const RefIdData& data, int index) const { - const Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Creature))); + const Record& record = static_cast&>( + data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Creature))); // return the whole struct std::vector wrap; wrap.push_back(record.get().mData); // deleted by dtor of NestedTableStoring - return new NestedTableWrapper >(wrap); + return new NestedTableWrapper>(wrap); } -QVariant CSMWorld::CreatureAttributesRefIdAdapter::getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const +QVariant CSMWorld::CreatureAttributesRefIdAdapter::getNestedData( + const RefIdColumn* column, const RefIdData& data, int index, int subRowIndex, int subColIndex) const { - const Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Creature))); + const Record& record = static_cast&>( + data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Creature))); const ESM::Creature& creature = record.get(); @@ -1227,331 +1316,387 @@ QVariant CSMWorld::CreatureAttributesRefIdAdapter::getNestedData (const RefIdCol else if (subColIndex == 1) switch (subRowIndex) { - case 0: return creature.mData.mStrength; - case 1: return creature.mData.mIntelligence; - case 2: return creature.mData.mWillpower; - case 3: return creature.mData.mAgility; - case 4: return creature.mData.mSpeed; - case 5: return creature.mData.mEndurance; - case 6: return creature.mData.mPersonality; - case 7: return creature.mData.mLuck; - default: return QVariant(); // throw an exception here? + case 0: + return creature.mData.mStrength; + case 1: + return creature.mData.mIntelligence; + case 2: + return creature.mData.mWillpower; + case 3: + return creature.mData.mAgility; + case 4: + return creature.mData.mSpeed; + case 5: + return creature.mData.mEndurance; + case 6: + return creature.mData.mPersonality; + case 7: + return creature.mData.mLuck; + default: + return QVariant(); // throw an exception here? } else return QVariant(); // throw an exception here? } -void CSMWorld::CreatureAttributesRefIdAdapter::setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const +void CSMWorld::CreatureAttributesRefIdAdapter::setNestedData( + const RefIdColumn* column, RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (row, UniversalId::Type_Creature))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(row, UniversalId::Type_Creature))); ESM::Creature creature = record.get(); if (subColIndex == 1) - switch(subRowIndex) + switch (subRowIndex) { - case 0: creature.mData.mStrength = value.toInt(); break; - case 1: creature.mData.mIntelligence = value.toInt(); break; - case 2: creature.mData.mWillpower = value.toInt(); break; - case 3: creature.mData.mAgility = value.toInt(); break; - case 4: creature.mData.mSpeed = value.toInt(); break; - case 5: creature.mData.mEndurance = value.toInt(); break; - case 6: creature.mData.mPersonality = value.toInt(); break; - case 7: creature.mData.mLuck = value.toInt(); break; - default: return; // throw an exception here? + case 0: + creature.mData.mStrength = value.toInt(); + break; + case 1: + creature.mData.mIntelligence = value.toInt(); + break; + case 2: + creature.mData.mWillpower = value.toInt(); + break; + case 3: + creature.mData.mAgility = value.toInt(); + break; + case 4: + creature.mData.mSpeed = value.toInt(); + break; + case 5: + creature.mData.mEndurance = value.toInt(); + break; + case 6: + creature.mData.mPersonality = value.toInt(); + break; + case 7: + creature.mData.mLuck = value.toInt(); + break; + default: + return; // throw an exception here? } else return; // throw an exception here? - record.setModified (creature); + record.setModified(creature); } -int CSMWorld::CreatureAttributesRefIdAdapter::getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const +int CSMWorld::CreatureAttributesRefIdAdapter::getNestedColumnsCount( + const RefIdColumn* column, const RefIdData& data) const { return 2; } -int CSMWorld::CreatureAttributesRefIdAdapter::getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const +int CSMWorld::CreatureAttributesRefIdAdapter::getNestedRowsCount( + const RefIdColumn* column, const RefIdData& data, int index) const { // There are 8 attributes return 8; } -CSMWorld::CreatureAttackRefIdAdapter::CreatureAttackRefIdAdapter() -{} +CSMWorld::CreatureAttackRefIdAdapter::CreatureAttackRefIdAdapter() {} -void CSMWorld::CreatureAttackRefIdAdapter::addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const +void CSMWorld::CreatureAttackRefIdAdapter::addNestedRow( + const RefIdColumn* column, RefIdData& data, int index, int position) const { // Do nothing, this table cannot be changed by the user } -void CSMWorld::CreatureAttackRefIdAdapter::removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const +void CSMWorld::CreatureAttackRefIdAdapter::removeNestedRow( + const RefIdColumn* column, RefIdData& data, int index, int rowToRemove) const { // Do nothing, this table cannot be changed by the user } -void CSMWorld::CreatureAttackRefIdAdapter::setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const +void CSMWorld::CreatureAttackRefIdAdapter::setNestedTable( + const RefIdColumn* column, RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Creature))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Creature))); ESM::Creature creature = record.get(); // store the whole struct - creature.mData = - static_cast > &>(nestedTable).mNestedTable.at(0); + creature.mData = static_cast>&>(nestedTable) + .mNestedTable.at(0); - record.setModified (creature); + record.setModified(creature); } -CSMWorld::NestedTableWrapperBase* CSMWorld::CreatureAttackRefIdAdapter::nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const +CSMWorld::NestedTableWrapperBase* CSMWorld::CreatureAttackRefIdAdapter::nestedTable( + const RefIdColumn* column, const RefIdData& data, int index) const { - const Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Creature))); + const Record& record = static_cast&>( + data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Creature))); // return the whole struct std::vector wrap; wrap.push_back(record.get().mData); // deleted by dtor of NestedTableStoring - return new NestedTableWrapper >(wrap); + return new NestedTableWrapper>(wrap); } -QVariant CSMWorld::CreatureAttackRefIdAdapter::getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const +QVariant CSMWorld::CreatureAttackRefIdAdapter::getNestedData( + const RefIdColumn* column, const RefIdData& data, int index, int subRowIndex, int subColIndex) const { - const Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Creature))); + const Record& record = static_cast&>( + data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Creature))); const ESM::Creature& creature = record.get(); if (subRowIndex < 0 || subRowIndex > 2) - throw std::runtime_error ("index out of range"); + throw std::runtime_error("index out of range"); if (subColIndex == 0) return subRowIndex + 1; else if (subColIndex == 1 || subColIndex == 2) return creature.mData.mAttack[(subRowIndex * 2) + (subColIndex - 1)]; else - throw std::runtime_error ("index out of range"); + throw std::runtime_error("index out of range"); } -void CSMWorld::CreatureAttackRefIdAdapter::setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const +void CSMWorld::CreatureAttackRefIdAdapter::setNestedData( + const RefIdColumn* column, RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (row, UniversalId::Type_Creature))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(row, UniversalId::Type_Creature))); ESM::Creature creature = record.get(); if (subRowIndex < 0 || subRowIndex > 2) - throw std::runtime_error ("index out of range"); + throw std::runtime_error("index out of range"); if (subColIndex == 1 || subColIndex == 2) creature.mData.mAttack[(subRowIndex * 2) + (subColIndex - 1)] = value.toInt(); else return; // throw an exception here? - record.setModified (creature); + record.setModified(creature); } -int CSMWorld::CreatureAttackRefIdAdapter::getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const +int CSMWorld::CreatureAttackRefIdAdapter::getNestedColumnsCount(const RefIdColumn* column, const RefIdData& data) const { return 3; } -int CSMWorld::CreatureAttackRefIdAdapter::getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const +int CSMWorld::CreatureAttackRefIdAdapter::getNestedRowsCount( + const RefIdColumn* column, const RefIdData& data, int index) const { // There are 3 attacks return 3; } -CSMWorld::CreatureMiscRefIdAdapter::CreatureMiscRefIdAdapter() -{} +CSMWorld::CreatureMiscRefIdAdapter::CreatureMiscRefIdAdapter() {} -CSMWorld::CreatureMiscRefIdAdapter::~CreatureMiscRefIdAdapter() -{} +CSMWorld::CreatureMiscRefIdAdapter::~CreatureMiscRefIdAdapter() {} -void CSMWorld::CreatureMiscRefIdAdapter::addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const +void CSMWorld::CreatureMiscRefIdAdapter::addNestedRow( + const RefIdColumn* column, RefIdData& data, int index, int position) const { - throw std::logic_error ("cannot add a row to a fixed table"); + throw std::logic_error("cannot add a row to a fixed table"); } -void CSMWorld::CreatureMiscRefIdAdapter::removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const +void CSMWorld::CreatureMiscRefIdAdapter::removeNestedRow( + const RefIdColumn* column, RefIdData& data, int index, int rowToRemove) const { - throw std::logic_error ("cannot remove a row to a fixed table"); + throw std::logic_error("cannot remove a row to a fixed table"); } -void CSMWorld::CreatureMiscRefIdAdapter::setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const +void CSMWorld::CreatureMiscRefIdAdapter::setNestedTable( + const RefIdColumn* column, RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const { - throw std::logic_error ("table operation not supported"); + throw std::logic_error("table operation not supported"); } -CSMWorld::NestedTableWrapperBase* CSMWorld::CreatureMiscRefIdAdapter::nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const +CSMWorld::NestedTableWrapperBase* CSMWorld::CreatureMiscRefIdAdapter::nestedTable( + const RefIdColumn* column, const RefIdData& data, int index) const { - throw std::logic_error ("table operation not supported"); + throw std::logic_error("table operation not supported"); } -QVariant CSMWorld::CreatureMiscRefIdAdapter::getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const +QVariant CSMWorld::CreatureMiscRefIdAdapter::getNestedData( + const RefIdColumn* column, const RefIdData& data, int index, int subRowIndex, int subColIndex) const { - const Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Creature))); + const Record& record = static_cast&>( + data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Creature))); const ESM::Creature& creature = record.get(); switch (subColIndex) { - case 0: return creature.mData.mLevel; - case 1: return creature.mData.mHealth; - case 2: return creature.mData.mMana; - case 3: return creature.mData.mFatigue; - case 4: return creature.mData.mSoul; - case 5: return creature.mData.mCombat; - case 6: return creature.mData.mMagic; - case 7: return creature.mData.mStealth; - case 8: return creature.mData.mGold; - default: return QVariant(); // throw an exception here? + case 0: + return creature.mData.mLevel; + case 1: + return creature.mData.mHealth; + case 2: + return creature.mData.mMana; + case 3: + return creature.mData.mFatigue; + case 4: + return creature.mData.mSoul; + case 5: + return creature.mData.mCombat; + case 6: + return creature.mData.mMagic; + case 7: + return creature.mData.mStealth; + case 8: + return creature.mData.mGold; + default: + return QVariant(); // throw an exception here? } } -void CSMWorld::CreatureMiscRefIdAdapter::setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const +void CSMWorld::CreatureMiscRefIdAdapter::setNestedData( + const RefIdColumn* column, RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (row, UniversalId::Type_Creature))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(row, UniversalId::Type_Creature))); ESM::Creature creature = record.get(); - switch(subColIndex) + switch (subColIndex) { - case 0: creature.mData.mLevel = value.toInt(); break; - case 1: creature.mData.mHealth = value.toInt(); break; - case 2: creature.mData.mMana = value.toInt(); break; - case 3: creature.mData.mFatigue = value.toInt(); break; - case 4: creature.mData.mSoul = value.toInt(); break; - case 5: creature.mData.mCombat = value.toInt(); break; - case 6: creature.mData.mMagic = value.toInt(); break; - case 7: creature.mData.mStealth = value.toInt(); break; - case 8: creature.mData.mGold = value.toInt(); break; - default: return; // throw an exception here? + case 0: + creature.mData.mLevel = value.toInt(); + break; + case 1: + creature.mData.mHealth = value.toInt(); + break; + case 2: + creature.mData.mMana = value.toInt(); + break; + case 3: + creature.mData.mFatigue = value.toInt(); + break; + case 4: + creature.mData.mSoul = value.toInt(); + break; + case 5: + creature.mData.mCombat = value.toInt(); + break; + case 6: + creature.mData.mMagic = value.toInt(); + break; + case 7: + creature.mData.mStealth = value.toInt(); + break; + case 8: + creature.mData.mGold = value.toInt(); + break; + default: + return; // throw an exception here? } - record.setModified (creature); + record.setModified(creature); } -int CSMWorld::CreatureMiscRefIdAdapter::getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const +int CSMWorld::CreatureMiscRefIdAdapter::getNestedColumnsCount(const RefIdColumn* column, const RefIdData& data) const { return 9; // Level, Health, Mana, Fatigue, Soul, Combat, Magic, Steath, Gold } -int CSMWorld::CreatureMiscRefIdAdapter::getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const +int CSMWorld::CreatureMiscRefIdAdapter::getNestedRowsCount( + const RefIdColumn* column, const RefIdData& data, int index) const { return 1; // fixed at size 1 } -CSMWorld::WeaponColumns::WeaponColumns (const EnchantableColumns& columns) -: EnchantableColumns (columns) -, mType(nullptr) -, mHealth(nullptr) -, mSpeed(nullptr) -, mReach(nullptr) -, mChop{nullptr} -, mSlash{nullptr} -, mThrust{nullptr} -{} +CSMWorld::WeaponColumns::WeaponColumns(const EnchantableColumns& columns) + : EnchantableColumns(columns) + , mType(nullptr) + , mHealth(nullptr) + , mSpeed(nullptr) + , mReach(nullptr) + , mChop{ nullptr } + , mSlash{ nullptr } + , mThrust{ nullptr } +{ +} -CSMWorld::WeaponRefIdAdapter::WeaponRefIdAdapter (const WeaponColumns& columns) -: EnchantableRefIdAdapter (UniversalId::Type_Weapon, columns), mColumns (columns) -{} +CSMWorld::WeaponRefIdAdapter::WeaponRefIdAdapter(const WeaponColumns& columns) + : EnchantableRefIdAdapter(UniversalId::Type_Weapon, columns) + , mColumns(columns) +{ +} -QVariant CSMWorld::WeaponRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, - int index) const +QVariant CSMWorld::WeaponRefIdAdapter::getData(const RefIdColumn* column, const RefIdData& data, int index) const { - const Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Weapon))); + const Record& record = static_cast&>( + data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Weapon))); - if (column==mColumns.mType) + if (column == mColumns.mType) return record.get().mData.mType; - if (column==mColumns.mHealth) + if (column == mColumns.mHealth) return record.get().mData.mHealth; - if (column==mColumns.mSpeed) + if (column == mColumns.mSpeed) return record.get().mData.mSpeed; - if (column==mColumns.mReach) + if (column == mColumns.mReach) return record.get().mData.mReach; - for (int i=0; i<2; ++i) + for (int i = 0; i < 2; ++i) { - if (column==mColumns.mChop[i]) + if (column == mColumns.mChop[i]) return record.get().mData.mChop[i]; - if (column==mColumns.mSlash[i]) + if (column == mColumns.mSlash[i]) return record.get().mData.mSlash[i]; - if (column==mColumns.mThrust[i]) + if (column == mColumns.mThrust[i]) return record.get().mData.mThrust[i]; } - std::map::const_iterator iter = - mColumns.mFlags.find (column); + std::map::const_iterator iter = mColumns.mFlags.find(column); - if (iter!=mColumns.mFlags.end()) - return (record.get().mData.mFlags & iter->second)!=0; + if (iter != mColumns.mFlags.end()) + return (record.get().mData.mFlags & iter->second) != 0; - return EnchantableRefIdAdapter::getData (column, data, index); + return EnchantableRefIdAdapter::getData(column, data, index); } -void CSMWorld::WeaponRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const +void CSMWorld::WeaponRefIdAdapter::setData( + const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const { - Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Weapon))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, UniversalId::Type_Weapon))); ESM::Weapon weapon = record.get(); - if (column==mColumns.mType) + if (column == mColumns.mType) weapon.mData.mType = value.toInt(); - else if (column==mColumns.mHealth) + else if (column == mColumns.mHealth) weapon.mData.mHealth = value.toInt(); - else if (column==mColumns.mSpeed) + else if (column == mColumns.mSpeed) weapon.mData.mSpeed = value.toFloat(); - else if (column==mColumns.mReach) + else if (column == mColumns.mReach) weapon.mData.mReach = value.toFloat(); - else if (column==mColumns.mChop[0]) + else if (column == mColumns.mChop[0]) weapon.mData.mChop[0] = value.toInt(); - else if (column==mColumns.mChop[1]) + else if (column == mColumns.mChop[1]) weapon.mData.mChop[1] = value.toInt(); - else if (column==mColumns.mSlash[0]) + else if (column == mColumns.mSlash[0]) weapon.mData.mSlash[0] = value.toInt(); - else if (column==mColumns.mSlash[1]) + else if (column == mColumns.mSlash[1]) weapon.mData.mSlash[1] = value.toInt(); - else if (column==mColumns.mThrust[0]) + else if (column == mColumns.mThrust[0]) weapon.mData.mThrust[0] = value.toInt(); - else if (column==mColumns.mThrust[1]) + else if (column == mColumns.mThrust[1]) weapon.mData.mThrust[1] = value.toInt(); else { - std::map::const_iterator iter = - mColumns.mFlags.find (column); + std::map::const_iterator iter = mColumns.mFlags.find(column); - if (iter!=mColumns.mFlags.end()) + if (iter != mColumns.mFlags.end()) { - if (value.toInt()!=0) + if (value.toInt() != 0) weapon.mData.mFlags |= iter->second; else weapon.mData.mFlags &= ~iter->second; } else { - EnchantableRefIdAdapter::setData (column, data, index, value); + EnchantableRefIdAdapter::setData(column, data, index, value); return; // Don't overwrite changes made by base class } } diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index ab25c87607..6d154a0437 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -6,112 +6,113 @@ #include #include -#include #include -#include #include +#include +#include #include "columnbase.hpp" +#include "nestedtablewrapper.hpp" #include "record.hpp" +#include "refidadapter.hpp" #include "refiddata.hpp" #include "universalid.hpp" -#include "refidadapter.hpp" -#include "nestedtablewrapper.hpp" namespace CSMWorld { struct BaseColumns { - const RefIdColumn *mId; - const RefIdColumn *mModified; - const RefIdColumn *mType; - const RefIdColumn *mBlocked; + const RefIdColumn* mId; + const RefIdColumn* mModified; + const RefIdColumn* mType; + const RefIdColumn* mBlocked; - BaseColumns () : mId(nullptr) - , mModified(nullptr) - , mType(nullptr) - , mBlocked(nullptr) {} + BaseColumns() + : mId(nullptr) + , mModified(nullptr) + , mType(nullptr) + , mBlocked(nullptr) + { + } }; /// \brief Base adapter for all refereceable record types /// Adapters that can handle nested tables, needs to return valid qvariant for parent columns - template + template class BaseRefIdAdapter : public RefIdAdapter { - UniversalId::Type mType; - BaseColumns mBase; - - public: + UniversalId::Type mType; + BaseColumns mBase; - BaseRefIdAdapter (UniversalId::Type type, const BaseColumns& base); + public: + BaseRefIdAdapter(UniversalId::Type type, const BaseColumns& base); - std::string getId (const RecordBase& record) const override; + std::string getId(const RecordBase& record) const override; - void setId (RecordBase& record, const std::string& id) override; + void setId(RecordBase& record, const std::string& id) override; - QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) const override; + QVariant getData(const RefIdColumn* column, const RefIdData& data, int index) const override; - void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const override; - ///< If the data type does not match an exception is thrown. + void setData(const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const override; + ///< If the data type does not match an exception is thrown. - UniversalId::Type getType() const; + UniversalId::Type getType() const; }; - template - BaseRefIdAdapter::BaseRefIdAdapter (UniversalId::Type type, const BaseColumns& base) - : mType (type), mBase (base) - {} + template + BaseRefIdAdapter::BaseRefIdAdapter(UniversalId::Type type, const BaseColumns& base) + : mType(type) + , mBase(base) + { + } - template - void BaseRefIdAdapter::setId (RecordBase& record, const std::string& id) + template + void BaseRefIdAdapter::setId(RecordBase& record, const std::string& id) { - (dynamic_cast&> (record).get().mId) = id; + (dynamic_cast&>(record).get().mId) = id; } - template - std::string BaseRefIdAdapter::getId (const RecordBase& record) const + template + std::string BaseRefIdAdapter::getId(const RecordBase& record) const { - return dynamic_cast&> (record).get().mId; + return dynamic_cast&>(record).get().mId; } - template - QVariant BaseRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, - int index) const + template + QVariant BaseRefIdAdapter::getData(const RefIdColumn* column, const RefIdData& data, int index) const { - const Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, mType))); + const Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); - if (column==mBase.mId) - return QString::fromUtf8 (record.get().mId.c_str()); + if (column == mBase.mId) + return QString::fromUtf8(record.get().mId.c_str()); - if (column==mBase.mModified) + if (column == mBase.mModified) { - if (record.mState==Record::State_Erased) - return static_cast (Record::State_Deleted); + if (record.mState == Record::State_Erased) + return static_cast(Record::State_Deleted); - return static_cast (record.mState); + return static_cast(record.mState); } - if (column==mBase.mType) - return static_cast (mType); + if (column == mBase.mType) + return static_cast(mType); - if (column==mBase.mBlocked) + if (column == mBase.mBlocked) return (record.get().mRecordFlags & ESM::FLAG_Blocked) != 0; return QVariant(); } - template - void BaseRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const + template + void BaseRefIdAdapter::setData( + const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const { - Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, mType))); + Record& record = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); - if (column==mBase.mModified) - record.mState = static_cast (value.toInt()); - else if (column==mBase.mBlocked) + if (column == mBase.mModified) + record.mState = static_cast(value.toInt()); + else if (column == mBase.mBlocked) { RecordT record2 = record.get(); @@ -124,7 +125,7 @@ namespace CSMWorld } } - template + template UniversalId::Type BaseRefIdAdapter::getType() const { return mType; @@ -141,62 +142,65 @@ namespace CSMWorld struct ModelColumns : public BaseColumns { - const RefIdColumn *mModel; - const RefIdColumn *mPersistence; + const RefIdColumn* mModel; + const RefIdColumn* mPersistence; - ModelColumns (const BaseColumns& base) : BaseColumns (base), mModel(nullptr), mPersistence(nullptr) {} + ModelColumns(const BaseColumns& base) + : BaseColumns(base) + , mModel(nullptr) + , mPersistence(nullptr) + { + } }; /// \brief Adapter for IDs with models (all but levelled lists) - template + template class ModelRefIdAdapter : public BaseRefIdAdapter { - ModelColumns mModel; - - public: + ModelColumns mModel; - ModelRefIdAdapter (UniversalId::Type type, const ModelColumns& columns); + public: + ModelRefIdAdapter(UniversalId::Type type, const ModelColumns& columns); - QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const override; + QVariant getData(const RefIdColumn* column, const RefIdData& data, int index) const override; - void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const override; - ///< If the data type does not match an exception is thrown. + void setData(const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const override; + ///< If the data type does not match an exception is thrown. }; - template - ModelRefIdAdapter::ModelRefIdAdapter (UniversalId::Type type, const ModelColumns& columns) - : BaseRefIdAdapter (type, columns), mModel (columns) - {} + template + ModelRefIdAdapter::ModelRefIdAdapter(UniversalId::Type type, const ModelColumns& columns) + : BaseRefIdAdapter(type, columns) + , mModel(columns) + { + } - template - QVariant ModelRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, - int index) const + template + QVariant ModelRefIdAdapter::getData(const RefIdColumn* column, const RefIdData& data, int index) const { - const Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + const Record& record = static_cast&>( + data.getRecord(RefIdData::LocalIndex(index, BaseRefIdAdapter::getType()))); - if (column==mModel.mModel) - return QString::fromUtf8 (record.get().mModel.c_str()); + if (column == mModel.mModel) + return QString::fromUtf8(record.get().mModel.c_str()); - if (column==mModel.mPersistence) + if (column == mModel.mPersistence) return (record.get().mRecordFlags & ESM::FLAG_Persistent) != 0; - return BaseRefIdAdapter::getData (column, data, index); + return BaseRefIdAdapter::getData(column, data, index); } - template - void ModelRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const + template + void ModelRefIdAdapter::setData( + const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const { - Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + Record& record = static_cast&>( + data.getRecord(RefIdData::LocalIndex(index, BaseRefIdAdapter::getType()))); RecordT record2 = record.get(); - if (column==mModel.mModel) + if (column == mModel.mModel) record2.mModel = value.toString().toUtf8().constData(); - else if (column==mModel.mPersistence) + else if (column == mModel.mPersistence) { if (value.toInt() != 0) record2.mRecordFlags |= ESM::FLAG_Persistent; @@ -205,7 +209,7 @@ namespace CSMWorld } else { - BaseRefIdAdapter::setData (column, data, index, value); + BaseRefIdAdapter::setData(column, data, index, value); return; } @@ -214,70 +218,69 @@ namespace CSMWorld struct NameColumns : public ModelColumns { - const RefIdColumn *mName; - const RefIdColumn *mScript; + const RefIdColumn* mName; + const RefIdColumn* mScript; - NameColumns (const ModelColumns& base) - : ModelColumns (base) - , mName(nullptr) - , mScript(nullptr) - {} + NameColumns(const ModelColumns& base) + : ModelColumns(base) + , mName(nullptr) + , mScript(nullptr) + { + } }; /// \brief Adapter for IDs with names (all but levelled lists and statics) - template + template class NameRefIdAdapter : public ModelRefIdAdapter { - NameColumns mName; - - public: + NameColumns mName; - NameRefIdAdapter (UniversalId::Type type, const NameColumns& columns); + public: + NameRefIdAdapter(UniversalId::Type type, const NameColumns& columns); - QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const override; + QVariant getData(const RefIdColumn* column, const RefIdData& data, int index) const override; - void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const override; - ///< If the data type does not match an exception is thrown. + void setData(const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const override; + ///< If the data type does not match an exception is thrown. }; - template - NameRefIdAdapter::NameRefIdAdapter (UniversalId::Type type, const NameColumns& columns) - : ModelRefIdAdapter (type, columns), mName (columns) - {} + template + NameRefIdAdapter::NameRefIdAdapter(UniversalId::Type type, const NameColumns& columns) + : ModelRefIdAdapter(type, columns) + , mName(columns) + { + } - template - QVariant NameRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, - int index) const + template + QVariant NameRefIdAdapter::getData(const RefIdColumn* column, const RefIdData& data, int index) const { - const Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + const Record& record = static_cast&>( + data.getRecord(RefIdData::LocalIndex(index, BaseRefIdAdapter::getType()))); - if (column==mName.mName) - return QString::fromUtf8 (record.get().mName.c_str()); + if (column == mName.mName) + return QString::fromUtf8(record.get().mName.c_str()); - if (column==mName.mScript) - return QString::fromUtf8 (record.get().mScript.c_str()); + if (column == mName.mScript) + return QString::fromUtf8(record.get().mScript.c_str()); - return ModelRefIdAdapter::getData (column, data, index); + return ModelRefIdAdapter::getData(column, data, index); } - template - void NameRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const + template + void NameRefIdAdapter::setData( + const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const { - Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + Record& record = static_cast&>( + data.getRecord(RefIdData::LocalIndex(index, BaseRefIdAdapter::getType()))); RecordT record2 = record.get(); - if (column==mName.mName) + if (column == mName.mName) record2.mName = value.toString().toUtf8().constData(); - else if (column==mName.mScript) + else if (column == mName.mScript) record2.mScript = value.toString().toUtf8().constData(); else { - ModelRefIdAdapter::setData (column, data, index, value); + ModelRefIdAdapter::setData(column, data, index, value); return; } @@ -286,78 +289,76 @@ namespace CSMWorld struct InventoryColumns : public NameColumns { - const RefIdColumn *mIcon; - const RefIdColumn *mWeight; - const RefIdColumn *mValue; + const RefIdColumn* mIcon; + const RefIdColumn* mWeight; + const RefIdColumn* mValue; - InventoryColumns (const NameColumns& base) - : NameColumns (base) - , mIcon(nullptr) - , mWeight(nullptr) - , mValue(nullptr) - {} + InventoryColumns(const NameColumns& base) + : NameColumns(base) + , mIcon(nullptr) + , mWeight(nullptr) + , mValue(nullptr) + { + } }; /// \brief Adapter for IDs that can go into an inventory - template + template class InventoryRefIdAdapter : public NameRefIdAdapter { - InventoryColumns mInventory; - - public: + InventoryColumns mInventory; - InventoryRefIdAdapter (UniversalId::Type type, const InventoryColumns& columns); + public: + InventoryRefIdAdapter(UniversalId::Type type, const InventoryColumns& columns); - QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const override; + QVariant getData(const RefIdColumn* column, const RefIdData& data, int index) const override; - void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const override; - ///< If the data type does not match an exception is thrown. + void setData(const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const override; + ///< If the data type does not match an exception is thrown. }; - template - InventoryRefIdAdapter::InventoryRefIdAdapter (UniversalId::Type type, - const InventoryColumns& columns) - : NameRefIdAdapter (type, columns), mInventory (columns) - {} + template + InventoryRefIdAdapter::InventoryRefIdAdapter(UniversalId::Type type, const InventoryColumns& columns) + : NameRefIdAdapter(type, columns) + , mInventory(columns) + { + } - template - QVariant InventoryRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, - int index) const + template + QVariant InventoryRefIdAdapter::getData(const RefIdColumn* column, const RefIdData& data, int index) const { - const Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + const Record& record = static_cast&>( + data.getRecord(RefIdData::LocalIndex(index, BaseRefIdAdapter::getType()))); - if (column==mInventory.mIcon) - return QString::fromUtf8 (record.get().mIcon.c_str()); + if (column == mInventory.mIcon) + return QString::fromUtf8(record.get().mIcon.c_str()); - if (column==mInventory.mWeight) + if (column == mInventory.mWeight) return record.get().mData.mWeight; - if (column==mInventory.mValue) + if (column == mInventory.mValue) return record.get().mData.mValue; - return NameRefIdAdapter::getData (column, data, index); + return NameRefIdAdapter::getData(column, data, index); } - template - void InventoryRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const + template + void InventoryRefIdAdapter::setData( + const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const { - Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + Record& record = static_cast&>( + data.getRecord(RefIdData::LocalIndex(index, BaseRefIdAdapter::getType()))); RecordT record2 = record.get(); - if (column==mInventory.mIcon) + if (column == mInventory.mIcon) record2.mIcon = value.toString().toUtf8().constData(); - else if (column==mInventory.mWeight) + else if (column == mInventory.mWeight) record2.mData.mWeight = value.toFloat(); - else if (column==mInventory.mValue) + else if (column == mInventory.mValue) record2.mData.mValue = value.toInt(); else { - NameRefIdAdapter::setData (column, data, index, value); + NameRefIdAdapter::setData(column, data, index, value); return; } @@ -366,49 +367,43 @@ namespace CSMWorld struct PotionColumns : public InventoryColumns { - const RefIdColumn *mEffects; + const RefIdColumn* mEffects; - PotionColumns (const InventoryColumns& columns); + PotionColumns(const InventoryColumns& columns); }; class PotionRefIdAdapter : public InventoryRefIdAdapter { - PotionColumns mColumns; - const RefIdColumn *mAutoCalc; + PotionColumns mColumns; + const RefIdColumn* mAutoCalc; - public: - - PotionRefIdAdapter (const PotionColumns& columns, const RefIdColumn *autoCalc); + public: + PotionRefIdAdapter(const PotionColumns& columns, const RefIdColumn* autoCalc); - QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const override; + QVariant getData(const RefIdColumn* column, const RefIdData& data, int index) const override; - void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const override; - ///< If the data type does not match an exception is thrown. + void setData(const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const override; + ///< If the data type does not match an exception is thrown. }; struct IngredientColumns : public InventoryColumns { - const RefIdColumn *mEffects; + const RefIdColumn* mEffects; - IngredientColumns (const InventoryColumns& columns); + IngredientColumns(const InventoryColumns& columns); }; class IngredientRefIdAdapter : public InventoryRefIdAdapter { - IngredientColumns mColumns; - - public: + IngredientColumns mColumns; - IngredientRefIdAdapter (const IngredientColumns& columns); + public: + IngredientRefIdAdapter(const IngredientColumns& columns); - QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const override; + QVariant getData(const RefIdColumn* column, const RefIdData& data, int index) const override; - void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const override; - ///< If the data type does not match an exception is thrown. + void setData(const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const override; + ///< If the data type does not match an exception is thrown. }; class IngredEffectRefIdAdapter : public NestedRefIdAdapterBase @@ -416,105 +411,100 @@ namespace CSMWorld UniversalId::Type mType; // not implemented - IngredEffectRefIdAdapter (const IngredEffectRefIdAdapter&); - IngredEffectRefIdAdapter& operator= (const IngredEffectRefIdAdapter&); + IngredEffectRefIdAdapter(const IngredEffectRefIdAdapter&); + IngredEffectRefIdAdapter& operator=(const IngredEffectRefIdAdapter&); public: - IngredEffectRefIdAdapter(); ~IngredEffectRefIdAdapter() override; - void addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const override; + void addNestedRow(const RefIdColumn* column, RefIdData& data, int index, int position) const override; - void removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const override; + void removeNestedRow(const RefIdColumn* column, RefIdData& data, int index, int rowToRemove) const override; - void setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const override; + void setNestedTable(const RefIdColumn* column, RefIdData& data, int index, + const NestedTableWrapperBase& nestedTable) const override; - NestedTableWrapperBase* nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const override; + NestedTableWrapperBase* nestedTable(const RefIdColumn* column, const RefIdData& data, int index) const override; - QVariant getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const override; + QVariant getNestedData(const RefIdColumn* column, const RefIdData& data, int index, int subRowIndex, + int subColIndex) const override; - void setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const override; + void setNestedData(const RefIdColumn* column, RefIdData& data, int row, const QVariant& value, int subRowIndex, + int subColIndex) const override; - int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const override; + int getNestedColumnsCount(const RefIdColumn* column, const RefIdData& data) const override; - int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const override; + int getNestedRowsCount(const RefIdColumn* column, const RefIdData& data, int index) const override; }; struct EnchantableColumns : public InventoryColumns { - const RefIdColumn *mEnchantment; - const RefIdColumn *mEnchantmentPoints; + const RefIdColumn* mEnchantment; + const RefIdColumn* mEnchantmentPoints; - EnchantableColumns (const InventoryColumns& base) - : InventoryColumns (base) - , mEnchantment(nullptr) - , mEnchantmentPoints(nullptr) - {} + EnchantableColumns(const InventoryColumns& base) + : InventoryColumns(base) + , mEnchantment(nullptr) + , mEnchantmentPoints(nullptr) + { + } }; /// \brief Adapter for enchantable IDs - template + template class EnchantableRefIdAdapter : public InventoryRefIdAdapter { - EnchantableColumns mEnchantable; - - public: + EnchantableColumns mEnchantable; - EnchantableRefIdAdapter (UniversalId::Type type, const EnchantableColumns& columns); + public: + EnchantableRefIdAdapter(UniversalId::Type type, const EnchantableColumns& columns); - QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const override; + QVariant getData(const RefIdColumn* column, const RefIdData& data, int index) const override; - void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const override; - ///< If the data type does not match an exception is thrown. + void setData(const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const override; + ///< If the data type does not match an exception is thrown. }; - template - EnchantableRefIdAdapter::EnchantableRefIdAdapter (UniversalId::Type type, - const EnchantableColumns& columns) - : InventoryRefIdAdapter (type, columns), mEnchantable (columns) - {} + template + EnchantableRefIdAdapter::EnchantableRefIdAdapter(UniversalId::Type type, const EnchantableColumns& columns) + : InventoryRefIdAdapter(type, columns) + , mEnchantable(columns) + { + } - template - QVariant EnchantableRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, - int index) const + template + QVariant EnchantableRefIdAdapter::getData( + const RefIdColumn* column, const RefIdData& data, int index) const { - const Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + const Record& record = static_cast&>( + data.getRecord(RefIdData::LocalIndex(index, BaseRefIdAdapter::getType()))); - if (column==mEnchantable.mEnchantment) - return QString::fromUtf8 (record.get().mEnchant.c_str()); + if (column == mEnchantable.mEnchantment) + return QString::fromUtf8(record.get().mEnchant.c_str()); - if (column==mEnchantable.mEnchantmentPoints) - return static_cast (record.get().mData.mEnchant); + if (column == mEnchantable.mEnchantmentPoints) + return static_cast(record.get().mData.mEnchant); - return InventoryRefIdAdapter::getData (column, data, index); + return InventoryRefIdAdapter::getData(column, data, index); } - template - void EnchantableRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, - int index, const QVariant& value) const + template + void EnchantableRefIdAdapter::setData( + const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const { - Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + Record& record = static_cast&>( + data.getRecord(RefIdData::LocalIndex(index, BaseRefIdAdapter::getType()))); RecordT record2 = record.get(); - if (column==mEnchantable.mEnchantment) + if (column == mEnchantable.mEnchantment) record2.mEnchant = value.toString().toUtf8().constData(); - else if (column==mEnchantable.mEnchantmentPoints) + else if (column == mEnchantable.mEnchantmentPoints) record2.mData.mEnchant = value.toInt(); else { - InventoryRefIdAdapter::setData (column, data, index, value); + InventoryRefIdAdapter::setData(column, data, index, value); return; } @@ -523,70 +513,69 @@ namespace CSMWorld struct ToolColumns : public InventoryColumns { - const RefIdColumn *mQuality; - const RefIdColumn *mUses; + const RefIdColumn* mQuality; + const RefIdColumn* mUses; - ToolColumns (const InventoryColumns& base) - : InventoryColumns (base) - , mQuality(nullptr) - , mUses(nullptr) - {} + ToolColumns(const InventoryColumns& base) + : InventoryColumns(base) + , mQuality(nullptr) + , mUses(nullptr) + { + } }; /// \brief Adapter for tools with limited uses IDs (lockpick, repair, probes) - template + template class ToolRefIdAdapter : public InventoryRefIdAdapter { - ToolColumns mTools; - - public: + ToolColumns mTools; - ToolRefIdAdapter (UniversalId::Type type, const ToolColumns& columns); + public: + ToolRefIdAdapter(UniversalId::Type type, const ToolColumns& columns); - QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const override; + QVariant getData(const RefIdColumn* column, const RefIdData& data, int index) const override; - void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const override; - ///< If the data type does not match an exception is thrown. + void setData(const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const override; + ///< If the data type does not match an exception is thrown. }; - template - ToolRefIdAdapter::ToolRefIdAdapter (UniversalId::Type type, const ToolColumns& columns) - : InventoryRefIdAdapter (type, columns), mTools (columns) - {} + template + ToolRefIdAdapter::ToolRefIdAdapter(UniversalId::Type type, const ToolColumns& columns) + : InventoryRefIdAdapter(type, columns) + , mTools(columns) + { + } - template - QVariant ToolRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, - int index) const + template + QVariant ToolRefIdAdapter::getData(const RefIdColumn* column, const RefIdData& data, int index) const { - const Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + const Record& record = static_cast&>( + data.getRecord(RefIdData::LocalIndex(index, BaseRefIdAdapter::getType()))); - if (column==mTools.mQuality) + if (column == mTools.mQuality) return record.get().mData.mQuality; - if (column==mTools.mUses) + if (column == mTools.mUses) return record.get().mData.mUses; - return InventoryRefIdAdapter::getData (column, data, index); + return InventoryRefIdAdapter::getData(column, data, index); } - template - void ToolRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, - int index, const QVariant& value) const + template + void ToolRefIdAdapter::setData( + const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const { - Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + Record& record = static_cast&>( + data.getRecord(RefIdData::LocalIndex(index, BaseRefIdAdapter::getType()))); RecordT record2 = record.get(); - if (column==mTools.mQuality) + if (column == mTools.mQuality) record2.mData.mQuality = value.toFloat(); - else if (column==mTools.mUses) + else if (column == mTools.mUses) record2.mData.mUses = value.toInt(); else { - InventoryRefIdAdapter::setData (column, data, index, value); + InventoryRefIdAdapter::setData(column, data, index, value); return; } @@ -595,18 +584,18 @@ namespace CSMWorld struct ActorColumns : public NameColumns { - const RefIdColumn *mHello; - const RefIdColumn *mFlee; - const RefIdColumn *mFight; - const RefIdColumn *mAlarm; - const RefIdColumn *mInventory; - const RefIdColumn *mSpells; - const RefIdColumn *mDestinations; - const RefIdColumn *mAiPackages; - std::map mServices; - - ActorColumns (const NameColumns& base) - : NameColumns (base) + const RefIdColumn* mHello; + const RefIdColumn* mFlee; + const RefIdColumn* mFight; + const RefIdColumn* mAlarm; + const RefIdColumn* mInventory; + const RefIdColumn* mSpells; + const RefIdColumn* mDestinations; + const RefIdColumn* mAiPackages; + std::map mServices; + + ActorColumns(const NameColumns& base) + : NameColumns(base) , mHello(nullptr) , mFlee(nullptr) , mFight(nullptr) @@ -615,103 +604,99 @@ namespace CSMWorld , mSpells(nullptr) , mDestinations(nullptr) , mAiPackages(nullptr) - {} + { + } }; /// \brief Adapter for actor IDs (handles common AI functionality) - template + template class ActorRefIdAdapter : public NameRefIdAdapter { - ActorColumns mActors; - - public: + ActorColumns mActors; - ActorRefIdAdapter (UniversalId::Type type, const ActorColumns& columns); + public: + ActorRefIdAdapter(UniversalId::Type type, const ActorColumns& columns); - QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const override; + QVariant getData(const RefIdColumn* column, const RefIdData& data, int index) const override; - void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const override; - ///< If the data type does not match an exception is thrown. + void setData(const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const override; + ///< If the data type does not match an exception is thrown. }; - template - ActorRefIdAdapter::ActorRefIdAdapter (UniversalId::Type type, - const ActorColumns& columns) - : NameRefIdAdapter (type, columns), mActors (columns) - {} + template + ActorRefIdAdapter::ActorRefIdAdapter(UniversalId::Type type, const ActorColumns& columns) + : NameRefIdAdapter(type, columns) + , mActors(columns) + { + } - template - QVariant ActorRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, - int index) const + template + QVariant ActorRefIdAdapter::getData(const RefIdColumn* column, const RefIdData& data, int index) const { - const Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + const Record& record = static_cast&>( + data.getRecord(RefIdData::LocalIndex(index, BaseRefIdAdapter::getType()))); - if (column==mActors.mHello) + if (column == mActors.mHello) return record.get().mAiData.mHello; - if (column==mActors.mFlee) + if (column == mActors.mFlee) return record.get().mAiData.mFlee; - if (column==mActors.mFight) + if (column == mActors.mFight) return record.get().mAiData.mFight; - if (column==mActors.mAlarm) + if (column == mActors.mAlarm) return record.get().mAiData.mAlarm; - if (column==mActors.mInventory) + if (column == mActors.mInventory) return QVariant::fromValue(ColumnBase::TableEdit_Full); - if (column==mActors.mSpells) + if (column == mActors.mSpells) return QVariant::fromValue(ColumnBase::TableEdit_Full); - if (column==mActors.mDestinations) + if (column == mActors.mDestinations) return QVariant::fromValue(ColumnBase::TableEdit_Full); - if (column==mActors.mAiPackages) + if (column == mActors.mAiPackages) return QVariant::fromValue(ColumnBase::TableEdit_Full); - std::map::const_iterator iter = - mActors.mServices.find (column); + std::map::const_iterator iter = mActors.mServices.find(column); - if (iter!=mActors.mServices.end()) - return (record.get().mAiData.mServices & iter->second)!=0; + if (iter != mActors.mServices.end()) + return (record.get().mAiData.mServices & iter->second) != 0; - return NameRefIdAdapter::getData (column, data, index); + return NameRefIdAdapter::getData(column, data, index); } - template - void ActorRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const + template + void ActorRefIdAdapter::setData( + const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const { - Record& record = static_cast&> ( - data.getRecord (RefIdData::LocalIndex (index, BaseRefIdAdapter::getType()))); + Record& record = static_cast&>( + data.getRecord(RefIdData::LocalIndex(index, BaseRefIdAdapter::getType()))); RecordT record2 = record.get(); - if (column==mActors.mHello) + if (column == mActors.mHello) record2.mAiData.mHello = value.toInt(); - else if (column==mActors.mFlee) // Flee, Fight and Alarm ratings are probabilities. + else if (column == mActors.mFlee) // Flee, Fight and Alarm ratings are probabilities. record2.mAiData.mFlee = std::min(100, value.toInt()); - else if (column==mActors.mFight) + else if (column == mActors.mFight) record2.mAiData.mFight = std::min(100, value.toInt()); - else if (column==mActors.mAlarm) + else if (column == mActors.mAlarm) record2.mAiData.mAlarm = std::min(100, value.toInt()); else { - typename std::map::const_iterator iter = - mActors.mServices.find (column); - if (iter!=mActors.mServices.end()) + typename std::map::const_iterator iter = mActors.mServices.find(column); + if (iter != mActors.mServices.end()) { - if (value.toInt()!=0) + if (value.toInt() != 0) record2.mAiData.mServices |= iter->second; else record2.mAiData.mServices &= ~iter->second; } else { - NameRefIdAdapter::setData (column, data, index, value); + NameRefIdAdapter::setData(column, data, index, value); return; } } @@ -721,514 +706,453 @@ namespace CSMWorld class ApparatusRefIdAdapter : public InventoryRefIdAdapter { - const RefIdColumn *mType; - const RefIdColumn *mQuality; - - public: + const RefIdColumn* mType; + const RefIdColumn* mQuality; - ApparatusRefIdAdapter (const InventoryColumns& columns, const RefIdColumn *type, - const RefIdColumn *quality); + public: + ApparatusRefIdAdapter(const InventoryColumns& columns, const RefIdColumn* type, const RefIdColumn* quality); - QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const override; + QVariant getData(const RefIdColumn* column, const RefIdData& data, int index) const override; - void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const override; - ///< If the data type does not match an exception is thrown. + void setData(const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const override; + ///< If the data type does not match an exception is thrown. }; class ArmorRefIdAdapter : public EnchantableRefIdAdapter { - const RefIdColumn *mType; - const RefIdColumn *mHealth; - const RefIdColumn *mArmor; - const RefIdColumn *mPartRef; - - public: + const RefIdColumn* mType; + const RefIdColumn* mHealth; + const RefIdColumn* mArmor; + const RefIdColumn* mPartRef; - ArmorRefIdAdapter (const EnchantableColumns& columns, const RefIdColumn *type, - const RefIdColumn *health, const RefIdColumn *armor, const RefIdColumn *partRef); + public: + ArmorRefIdAdapter(const EnchantableColumns& columns, const RefIdColumn* type, const RefIdColumn* health, + const RefIdColumn* armor, const RefIdColumn* partRef); - QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const override; + QVariant getData(const RefIdColumn* column, const RefIdData& data, int index) const override; - void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const override; - ///< If the data type does not match an exception is thrown. + void setData(const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const override; + ///< If the data type does not match an exception is thrown. }; class BookRefIdAdapter : public EnchantableRefIdAdapter { - const RefIdColumn *mBookType; - const RefIdColumn *mSkill; - const RefIdColumn *mText; + const RefIdColumn* mBookType; + const RefIdColumn* mSkill; + const RefIdColumn* mText; - public: - - BookRefIdAdapter (const EnchantableColumns& columns, const RefIdColumn *bookType, - const RefIdColumn *skill, const RefIdColumn *text); + public: + BookRefIdAdapter(const EnchantableColumns& columns, const RefIdColumn* bookType, const RefIdColumn* skill, + const RefIdColumn* text); - QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const override; + QVariant getData(const RefIdColumn* column, const RefIdData& data, int index) const override; - void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const override; - ///< If the data type does not match an exception is thrown. + void setData(const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const override; + ///< If the data type does not match an exception is thrown. }; class ClothingRefIdAdapter : public EnchantableRefIdAdapter { - const RefIdColumn *mType; - const RefIdColumn *mPartRef; - - public: + const RefIdColumn* mType; + const RefIdColumn* mPartRef; - ClothingRefIdAdapter (const EnchantableColumns& columns, - const RefIdColumn *type, const RefIdColumn *partRef); + public: + ClothingRefIdAdapter(const EnchantableColumns& columns, const RefIdColumn* type, const RefIdColumn* partRef); - QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const override; + QVariant getData(const RefIdColumn* column, const RefIdData& data, int index) const override; - void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const override; - ///< If the data type does not match an exception is thrown. + void setData(const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const override; + ///< If the data type does not match an exception is thrown. }; class ContainerRefIdAdapter : public NameRefIdAdapter { - const RefIdColumn *mWeight; - const RefIdColumn *mOrganic; - const RefIdColumn *mRespawn; - const RefIdColumn *mContent; - - public: + const RefIdColumn* mWeight; + const RefIdColumn* mOrganic; + const RefIdColumn* mRespawn; + const RefIdColumn* mContent; - ContainerRefIdAdapter (const NameColumns& columns, const RefIdColumn *weight, - const RefIdColumn *organic, const RefIdColumn *respawn, const RefIdColumn *content); + public: + ContainerRefIdAdapter(const NameColumns& columns, const RefIdColumn* weight, const RefIdColumn* organic, + const RefIdColumn* respawn, const RefIdColumn* content); - QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) const override; + QVariant getData(const RefIdColumn* column, const RefIdData& data, int index) const override; - void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const override; - ///< If the data type does not match an exception is thrown. + void setData(const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const override; + ///< If the data type does not match an exception is thrown. }; struct CreatureColumns : public ActorColumns { - std::map mFlags; - const RefIdColumn *mType; - const RefIdColumn *mScale; - const RefIdColumn *mOriginal; - const RefIdColumn *mAttributes; - const RefIdColumn *mAttacks; - const RefIdColumn *mMisc; - const RefIdColumn *mBloodType; + std::map mFlags; + const RefIdColumn* mType; + const RefIdColumn* mScale; + const RefIdColumn* mOriginal; + const RefIdColumn* mAttributes; + const RefIdColumn* mAttacks; + const RefIdColumn* mMisc; + const RefIdColumn* mBloodType; - CreatureColumns (const ActorColumns& actorColumns); + CreatureColumns(const ActorColumns& actorColumns); }; class CreatureRefIdAdapter : public ActorRefIdAdapter { - CreatureColumns mColumns; + CreatureColumns mColumns; - public: - - CreatureRefIdAdapter (const CreatureColumns& columns); + public: + CreatureRefIdAdapter(const CreatureColumns& columns); - QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const override; + QVariant getData(const RefIdColumn* column, const RefIdData& data, int index) const override; - void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const override; - ///< If the data type does not match an exception is thrown. + void setData(const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const override; + ///< If the data type does not match an exception is thrown. }; class DoorRefIdAdapter : public NameRefIdAdapter { - const RefIdColumn *mOpenSound; - const RefIdColumn *mCloseSound; - - public: + const RefIdColumn* mOpenSound; + const RefIdColumn* mCloseSound; - DoorRefIdAdapter (const NameColumns& columns, const RefIdColumn *openSound, - const RefIdColumn *closeSound); + public: + DoorRefIdAdapter(const NameColumns& columns, const RefIdColumn* openSound, const RefIdColumn* closeSound); - QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const override; + QVariant getData(const RefIdColumn* column, const RefIdData& data, int index) const override; - void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const override; - ///< If the data type does not match an exception is thrown. + void setData(const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const override; + ///< If the data type does not match an exception is thrown. }; struct LightColumns : public InventoryColumns { - const RefIdColumn *mTime; - const RefIdColumn *mRadius; - const RefIdColumn *mColor; - const RefIdColumn *mSound; - const RefIdColumn *mEmitterType; - std::map mFlags; + const RefIdColumn* mTime; + const RefIdColumn* mRadius; + const RefIdColumn* mColor; + const RefIdColumn* mSound; + const RefIdColumn* mEmitterType; + std::map mFlags; - LightColumns (const InventoryColumns& columns); + LightColumns(const InventoryColumns& columns); }; class LightRefIdAdapter : public InventoryRefIdAdapter { - LightColumns mColumns; - - public: + LightColumns mColumns; - LightRefIdAdapter (const LightColumns& columns); + public: + LightRefIdAdapter(const LightColumns& columns); - QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const override; + QVariant getData(const RefIdColumn* column, const RefIdData& data, int index) const override; - void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const override; - ///< If the data type does not match an exception is thrown. + void setData(const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const override; + ///< If the data type does not match an exception is thrown. }; class MiscRefIdAdapter : public InventoryRefIdAdapter { - const RefIdColumn *mKey; + const RefIdColumn* mKey; - public: - - MiscRefIdAdapter (const InventoryColumns& columns, const RefIdColumn *key); + public: + MiscRefIdAdapter(const InventoryColumns& columns, const RefIdColumn* key); - QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const override; + QVariant getData(const RefIdColumn* column, const RefIdData& data, int index) const override; - void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const override; - ///< If the data type does not match an exception is thrown. + void setData(const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const override; + ///< If the data type does not match an exception is thrown. }; struct NpcColumns : public ActorColumns { - std::map mFlags; - const RefIdColumn *mRace; - const RefIdColumn *mClass; - const RefIdColumn *mFaction; - const RefIdColumn *mHair; - const RefIdColumn *mHead; - const RefIdColumn *mAttributes; // depends on npc type - const RefIdColumn *mSkills; // depends on npc type - const RefIdColumn *mMisc; // may depend on npc type, e.g. FactionID - const RefIdColumn *mBloodType; - const RefIdColumn *mGender; - - NpcColumns (const ActorColumns& actorColumns); + std::map mFlags; + const RefIdColumn* mRace; + const RefIdColumn* mClass; + const RefIdColumn* mFaction; + const RefIdColumn* mHair; + const RefIdColumn* mHead; + const RefIdColumn* mAttributes; // depends on npc type + const RefIdColumn* mSkills; // depends on npc type + const RefIdColumn* mMisc; // may depend on npc type, e.g. FactionID + const RefIdColumn* mBloodType; + const RefIdColumn* mGender; + + NpcColumns(const ActorColumns& actorColumns); }; class NpcRefIdAdapter : public ActorRefIdAdapter { - NpcColumns mColumns; - - public: + NpcColumns mColumns; - NpcRefIdAdapter (const NpcColumns& columns); + public: + NpcRefIdAdapter(const NpcColumns& columns); - QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const override; + QVariant getData(const RefIdColumn* column, const RefIdData& data, int index) const override; - void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const override; - ///< If the data type does not match an exception is thrown. + void setData(const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const override; + ///< If the data type does not match an exception is thrown. }; struct WeaponColumns : public EnchantableColumns { - const RefIdColumn *mType; - const RefIdColumn *mHealth; - const RefIdColumn *mSpeed; - const RefIdColumn *mReach; - const RefIdColumn *mChop[2]; - const RefIdColumn *mSlash[2]; - const RefIdColumn *mThrust[2]; - std::map mFlags; + const RefIdColumn* mType; + const RefIdColumn* mHealth; + const RefIdColumn* mSpeed; + const RefIdColumn* mReach; + const RefIdColumn* mChop[2]; + const RefIdColumn* mSlash[2]; + const RefIdColumn* mThrust[2]; + std::map mFlags; - WeaponColumns (const EnchantableColumns& columns); + WeaponColumns(const EnchantableColumns& columns); }; class WeaponRefIdAdapter : public EnchantableRefIdAdapter { - WeaponColumns mColumns; - - public: + WeaponColumns mColumns; - WeaponRefIdAdapter (const WeaponColumns& columns); + public: + WeaponRefIdAdapter(const WeaponColumns& columns); - QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const override; + QVariant getData(const RefIdColumn* column, const RefIdData& data, int index) const override; - void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const override; - ///< If the data type does not match an exception is thrown. + void setData(const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const override; + ///< If the data type does not match an exception is thrown. }; - class NestedRefIdAdapterBase; class NpcAttributesRefIdAdapter : public NestedRefIdAdapterBase { public: + NpcAttributesRefIdAdapter(); - NpcAttributesRefIdAdapter (); - - void addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const override; + void addNestedRow(const RefIdColumn* column, RefIdData& data, int index, int position) const override; - void removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const override; + void removeNestedRow(const RefIdColumn* column, RefIdData& data, int index, int rowToRemove) const override; - void setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const override; + void setNestedTable(const RefIdColumn* column, RefIdData& data, int index, + const NestedTableWrapperBase& nestedTable) const override; - NestedTableWrapperBase* nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const override; + NestedTableWrapperBase* nestedTable(const RefIdColumn* column, const RefIdData& data, int index) const override; - QVariant getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const override; + QVariant getNestedData(const RefIdColumn* column, const RefIdData& data, int index, int subRowIndex, + int subColIndex) const override; - void setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const override; + void setNestedData(const RefIdColumn* column, RefIdData& data, int row, const QVariant& value, int subRowIndex, + int subColIndex) const override; - int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const override; + int getNestedColumnsCount(const RefIdColumn* column, const RefIdData& data) const override; - int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const override; + int getNestedRowsCount(const RefIdColumn* column, const RefIdData& data, int index) const override; }; class NpcSkillsRefIdAdapter : public NestedRefIdAdapterBase { public: + NpcSkillsRefIdAdapter(); - NpcSkillsRefIdAdapter (); - - void addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const override; + void addNestedRow(const RefIdColumn* column, RefIdData& data, int index, int position) const override; - void removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const override; + void removeNestedRow(const RefIdColumn* column, RefIdData& data, int index, int rowToRemove) const override; - void setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const override; + void setNestedTable(const RefIdColumn* column, RefIdData& data, int index, + const NestedTableWrapperBase& nestedTable) const override; - NestedTableWrapperBase* nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const override; + NestedTableWrapperBase* nestedTable(const RefIdColumn* column, const RefIdData& data, int index) const override; - QVariant getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const override; + QVariant getNestedData(const RefIdColumn* column, const RefIdData& data, int index, int subRowIndex, + int subColIndex) const override; - void setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const override; + void setNestedData(const RefIdColumn* column, RefIdData& data, int row, const QVariant& value, int subRowIndex, + int subColIndex) const override; - int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const override; + int getNestedColumnsCount(const RefIdColumn* column, const RefIdData& data) const override; - int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const override; + int getNestedRowsCount(const RefIdColumn* column, const RefIdData& data, int index) const override; }; class NpcMiscRefIdAdapter : public NestedRefIdAdapterBase { - NpcMiscRefIdAdapter (const NpcMiscRefIdAdapter&); - NpcMiscRefIdAdapter& operator= (const NpcMiscRefIdAdapter&); + NpcMiscRefIdAdapter(const NpcMiscRefIdAdapter&); + NpcMiscRefIdAdapter& operator=(const NpcMiscRefIdAdapter&); public: - - NpcMiscRefIdAdapter (); + NpcMiscRefIdAdapter(); ~NpcMiscRefIdAdapter() override; - void addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const override; + void addNestedRow(const RefIdColumn* column, RefIdData& data, int index, int position) const override; - void removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const override; + void removeNestedRow(const RefIdColumn* column, RefIdData& data, int index, int rowToRemove) const override; - void setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const override; + void setNestedTable(const RefIdColumn* column, RefIdData& data, int index, + const NestedTableWrapperBase& nestedTable) const override; - NestedTableWrapperBase* nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const override; + NestedTableWrapperBase* nestedTable(const RefIdColumn* column, const RefIdData& data, int index) const override; - QVariant getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const override; + QVariant getNestedData(const RefIdColumn* column, const RefIdData& data, int index, int subRowIndex, + int subColIndex) const override; - void setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const override; + void setNestedData(const RefIdColumn* column, RefIdData& data, int row, const QVariant& value, int subRowIndex, + int subColIndex) const override; - int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const override; + int getNestedColumnsCount(const RefIdColumn* column, const RefIdData& data) const override; - int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const override; + int getNestedRowsCount(const RefIdColumn* column, const RefIdData& data, int index) const override; }; class CreatureAttributesRefIdAdapter : public NestedRefIdAdapterBase { public: + CreatureAttributesRefIdAdapter(); - CreatureAttributesRefIdAdapter (); - - void addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const override; + void addNestedRow(const RefIdColumn* column, RefIdData& data, int index, int position) const override; - void removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const override; + void removeNestedRow(const RefIdColumn* column, RefIdData& data, int index, int rowToRemove) const override; - void setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const override; + void setNestedTable(const RefIdColumn* column, RefIdData& data, int index, + const NestedTableWrapperBase& nestedTable) const override; - NestedTableWrapperBase* nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const override; + NestedTableWrapperBase* nestedTable(const RefIdColumn* column, const RefIdData& data, int index) const override; - QVariant getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const override; + QVariant getNestedData(const RefIdColumn* column, const RefIdData& data, int index, int subRowIndex, + int subColIndex) const override; - void setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const override; + void setNestedData(const RefIdColumn* column, RefIdData& data, int row, const QVariant& value, int subRowIndex, + int subColIndex) const override; - int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const override; + int getNestedColumnsCount(const RefIdColumn* column, const RefIdData& data) const override; - int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const override; + int getNestedRowsCount(const RefIdColumn* column, const RefIdData& data, int index) const override; }; class CreatureAttackRefIdAdapter : public NestedRefIdAdapterBase { public: + CreatureAttackRefIdAdapter(); - CreatureAttackRefIdAdapter (); - - void addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const override; + void addNestedRow(const RefIdColumn* column, RefIdData& data, int index, int position) const override; - void removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const override; + void removeNestedRow(const RefIdColumn* column, RefIdData& data, int index, int rowToRemove) const override; - void setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const override; + void setNestedTable(const RefIdColumn* column, RefIdData& data, int index, + const NestedTableWrapperBase& nestedTable) const override; - NestedTableWrapperBase* nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const override; + NestedTableWrapperBase* nestedTable(const RefIdColumn* column, const RefIdData& data, int index) const override; - QVariant getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const override; + QVariant getNestedData(const RefIdColumn* column, const RefIdData& data, int index, int subRowIndex, + int subColIndex) const override; - void setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const override; + void setNestedData(const RefIdColumn* column, RefIdData& data, int row, const QVariant& value, int subRowIndex, + int subColIndex) const override; - int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const override; + int getNestedColumnsCount(const RefIdColumn* column, const RefIdData& data) const override; - int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const override; + int getNestedRowsCount(const RefIdColumn* column, const RefIdData& data, int index) const override; }; class CreatureMiscRefIdAdapter : public NestedRefIdAdapterBase { - CreatureMiscRefIdAdapter (const CreatureMiscRefIdAdapter&); - CreatureMiscRefIdAdapter& operator= (const CreatureMiscRefIdAdapter&); + CreatureMiscRefIdAdapter(const CreatureMiscRefIdAdapter&); + CreatureMiscRefIdAdapter& operator=(const CreatureMiscRefIdAdapter&); public: - - CreatureMiscRefIdAdapter (); + CreatureMiscRefIdAdapter(); ~CreatureMiscRefIdAdapter() override; - void addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const override; + void addNestedRow(const RefIdColumn* column, RefIdData& data, int index, int position) const override; - void removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const override; + void removeNestedRow(const RefIdColumn* column, RefIdData& data, int index, int rowToRemove) const override; - void setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const override; + void setNestedTable(const RefIdColumn* column, RefIdData& data, int index, + const NestedTableWrapperBase& nestedTable) const override; - NestedTableWrapperBase* nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const override; + NestedTableWrapperBase* nestedTable(const RefIdColumn* column, const RefIdData& data, int index) const override; - QVariant getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const override; + QVariant getNestedData(const RefIdColumn* column, const RefIdData& data, int index, int subRowIndex, + int subColIndex) const override; - void setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const override; + void setNestedData(const RefIdColumn* column, RefIdData& data, int row, const QVariant& value, int subRowIndex, + int subColIndex) const override; - int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const override; + int getNestedColumnsCount(const RefIdColumn* column, const RefIdData& data) const override; - int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const override; + int getNestedRowsCount(const RefIdColumn* column, const RefIdData& data, int index) const override; }; - template + template class EffectsListAdapter; - template + template class EffectsRefIdAdapter : public EffectsListAdapter, public NestedRefIdAdapterBase { UniversalId::Type mType; // not implemented - EffectsRefIdAdapter (const EffectsRefIdAdapter&); - EffectsRefIdAdapter& operator= (const EffectsRefIdAdapter&); + EffectsRefIdAdapter(const EffectsRefIdAdapter&); + EffectsRefIdAdapter& operator=(const EffectsRefIdAdapter&); public: - - EffectsRefIdAdapter(UniversalId::Type type) :mType(type) {} + EffectsRefIdAdapter(UniversalId::Type type) + : mType(type) + { + } virtual ~EffectsRefIdAdapter() {} - void addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const override + void addNestedRow(const RefIdColumn* column, RefIdData& data, int index, int position) const override { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); EffectsListAdapter::addRow(record, position); } - void removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const override + void removeNestedRow(const RefIdColumn* column, RefIdData& data, int index, int rowToRemove) const override { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); EffectsListAdapter::removeRow(record, rowToRemove); } - void setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const override + void setNestedTable(const RefIdColumn* column, RefIdData& data, int index, + const NestedTableWrapperBase& nestedTable) const override { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); EffectsListAdapter::setTable(record, nestedTable); } - NestedTableWrapperBase* nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const override + NestedTableWrapperBase* nestedTable(const RefIdColumn* column, const RefIdData& data, int index) const override { - const Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + const Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); return EffectsListAdapter::table(record); } - QVariant getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const override + QVariant getNestedData(const RefIdColumn* column, const RefIdData& data, int index, int subRowIndex, + int subColIndex) const override { - const Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + const Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); return EffectsListAdapter::getData(record, subRowIndex, subColIndex); } - void setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const override + void setNestedData(const RefIdColumn* column, RefIdData& data, int row, const QVariant& value, int subRowIndex, + int subColIndex) const override { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (row, mType))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(row, mType))); EffectsListAdapter::setData(record, value, subRowIndex, subColIndex); } - int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const override + int getNestedColumnsCount(const RefIdColumn* column, const RefIdData& data) const override { const Record record; // not used, just a dummy return EffectsListAdapter::getColumnsCount(record); } - int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const override + int getNestedRowsCount(const RefIdColumn* column, const RefIdData& data, int index) const override { - const Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + const Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); return EffectsListAdapter::getRowsCount(record); } }; @@ -1239,20 +1163,21 @@ namespace CSMWorld UniversalId::Type mType; // not implemented - NestedInventoryRefIdAdapter (const NestedInventoryRefIdAdapter&); - NestedInventoryRefIdAdapter& operator= (const NestedInventoryRefIdAdapter&); + NestedInventoryRefIdAdapter(const NestedInventoryRefIdAdapter&); + NestedInventoryRefIdAdapter& operator=(const NestedInventoryRefIdAdapter&); public: - - NestedInventoryRefIdAdapter(UniversalId::Type type) :mType(type) {} + NestedInventoryRefIdAdapter(UniversalId::Type type) + : mType(type) + { + } virtual ~NestedInventoryRefIdAdapter() {} - void addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const override + void addNestedRow(const RefIdColumn* column, RefIdData& data, int index, int position) const override { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); ESXRecordT container = record.get(); std::vector& list = container.mInventory.mList; @@ -1262,85 +1187,85 @@ namespace CSMWorld if (position >= (int)list.size()) list.push_back(newRow); else - list.insert(list.begin()+position, newRow); + list.insert(list.begin() + position, newRow); - record.setModified (container); + record.setModified(container); } - void removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const override + void removeNestedRow(const RefIdColumn* column, RefIdData& data, int index, int rowToRemove) const override { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); ESXRecordT container = record.get(); std::vector& list = container.mInventory.mList; - if (rowToRemove < 0 || rowToRemove >= static_cast (list.size())) - throw std::runtime_error ("index out of range"); + if (rowToRemove < 0 || rowToRemove >= static_cast(list.size())) + throw std::runtime_error("index out of range"); - list.erase (list.begin () + rowToRemove); + list.erase(list.begin() + rowToRemove); - record.setModified (container); + record.setModified(container); } - void setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const override + void setNestedTable(const RefIdColumn* column, RefIdData& data, int index, + const NestedTableWrapperBase& nestedTable) const override { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); ESXRecordT container = record.get(); - container.mInventory.mList = - static_cast >&>(nestedTable).mNestedTable; + container.mInventory.mList + = static_cast>&>(nestedTable).mNestedTable; - record.setModified (container); + record.setModified(container); } - NestedTableWrapperBase* nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const override + NestedTableWrapperBase* nestedTable(const RefIdColumn* column, const RefIdData& data, int index) const override { - const Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + const Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); // deleted by dtor of NestedTableStoring - return new NestedTableWrapper >(record.get().mInventory.mList); + return new NestedTableWrapper>(record.get().mInventory.mList); } - QVariant getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const override + QVariant getNestedData(const RefIdColumn* column, const RefIdData& data, int index, int subRowIndex, + int subColIndex) const override { - const Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + const Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); const std::vector& list = record.get().mInventory.mList; - if (subRowIndex < 0 || subRowIndex >= static_cast (list.size())) - throw std::runtime_error ("index out of range"); + if (subRowIndex < 0 || subRowIndex >= static_cast(list.size())) + throw std::runtime_error("index out of range"); const ESM::ContItem& content = list.at(subRowIndex); switch (subColIndex) { - case 0: return QString::fromUtf8(content.mItem.c_str()); - case 1: return content.mCount; + case 0: + return QString::fromUtf8(content.mItem.c_str()); + case 1: + return content.mCount; default: throw std::runtime_error("Trying to access non-existing column in the nested table!"); } } - void setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const override + void setNestedData(const RefIdColumn* column, RefIdData& data, int row, const QVariant& value, int subRowIndex, + int subColIndex) const override { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (row, mType))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(row, mType))); ESXRecordT container = record.get(); std::vector& list = container.mInventory.mList; - if (subRowIndex < 0 || subRowIndex >= static_cast (list.size())) - throw std::runtime_error ("index out of range"); + if (subRowIndex < 0 || subRowIndex >= static_cast(list.size())) + throw std::runtime_error("index out of range"); - switch(subColIndex) + switch (subColIndex) { case 0: list.at(subRowIndex).mItem.assign(std::string(value.toString().toUtf8().constData())); @@ -1354,18 +1279,15 @@ namespace CSMWorld throw std::runtime_error("Trying to access non-existing column in the nested table!"); } - record.setModified (container); + record.setModified(container); } - int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const override - { - return 2; - } + int getNestedColumnsCount(const RefIdColumn* column, const RefIdData& data) const override { return 2; } - int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const override + int getNestedRowsCount(const RefIdColumn* column, const RefIdData& data, int index) const override { - const Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + const Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); return static_cast(record.get().mInventory.mList.size()); } @@ -1377,20 +1299,21 @@ namespace CSMWorld UniversalId::Type mType; // not implemented - NestedSpellRefIdAdapter (const NestedSpellRefIdAdapter&); - NestedSpellRefIdAdapter& operator= (const NestedSpellRefIdAdapter&); + NestedSpellRefIdAdapter(const NestedSpellRefIdAdapter&); + NestedSpellRefIdAdapter& operator=(const NestedSpellRefIdAdapter&); public: - - NestedSpellRefIdAdapter(UniversalId::Type type) :mType(type) {} + NestedSpellRefIdAdapter(UniversalId::Type type) + : mType(type) + { + } virtual ~NestedSpellRefIdAdapter() {} - void addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const override + void addNestedRow(const RefIdColumn* column, RefIdData& data, int index, int position) const override { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); ESXRecordT caster = record.get(); std::vector& list = caster.mSpells.mList; @@ -1400,61 +1323,59 @@ namespace CSMWorld if (position >= (int)list.size()) list.push_back(newString); else - list.insert(list.begin()+position, newString); + list.insert(list.begin() + position, newString); - record.setModified (caster); + record.setModified(caster); } - void removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const override + void removeNestedRow(const RefIdColumn* column, RefIdData& data, int index, int rowToRemove) const override { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); ESXRecordT caster = record.get(); std::vector& list = caster.mSpells.mList; - if (rowToRemove < 0 || rowToRemove >= static_cast (list.size())) - throw std::runtime_error ("index out of range"); + if (rowToRemove < 0 || rowToRemove >= static_cast(list.size())) + throw std::runtime_error("index out of range"); - list.erase (list.begin () + rowToRemove); + list.erase(list.begin() + rowToRemove); - record.setModified (caster); + record.setModified(caster); } - void setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const override + void setNestedTable(const RefIdColumn* column, RefIdData& data, int index, + const NestedTableWrapperBase& nestedTable) const override { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); ESXRecordT caster = record.get(); - caster.mSpells.mList = - static_cast >&>(nestedTable).mNestedTable; + caster.mSpells.mList + = static_cast>&>(nestedTable).mNestedTable; - record.setModified (caster); + record.setModified(caster); } - NestedTableWrapperBase* nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const override + NestedTableWrapperBase* nestedTable(const RefIdColumn* column, const RefIdData& data, int index) const override { - const Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + const Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); // deleted by dtor of NestedTableStoring - return new NestedTableWrapper >(record.get().mSpells.mList); + return new NestedTableWrapper>(record.get().mSpells.mList); } - QVariant getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const override + QVariant getNestedData(const RefIdColumn* column, const RefIdData& data, int index, int subRowIndex, + int subColIndex) const override { - const Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + const Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); const std::vector& list = record.get().mSpells.mList; - if (subRowIndex < 0 || subRowIndex >= static_cast (list.size())) - throw std::runtime_error ("index out of range"); + if (subRowIndex < 0 || subRowIndex >= static_cast(list.size())) + throw std::runtime_error("index out of range"); const std::string& content = list.at(subRowIndex); @@ -1464,34 +1385,31 @@ namespace CSMWorld throw std::runtime_error("Trying to access non-existing column in the nested table!"); } - void setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const override + void setNestedData(const RefIdColumn* column, RefIdData& data, int row, const QVariant& value, int subRowIndex, + int subColIndex) const override { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (row, mType))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(row, mType))); ESXRecordT caster = record.get(); std::vector& list = caster.mSpells.mList; - if (subRowIndex < 0 || subRowIndex >= static_cast (list.size())) - throw std::runtime_error ("index out of range"); + if (subRowIndex < 0 || subRowIndex >= static_cast(list.size())) + throw std::runtime_error("index out of range"); if (subColIndex == 0) list.at(subRowIndex) = std::string(value.toString().toUtf8()); else throw std::runtime_error("Trying to access non-existing column in the nested table!"); - record.setModified (caster); + record.setModified(caster); } - int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const override - { - return 1; - } + int getNestedColumnsCount(const RefIdColumn* column, const RefIdData& data) const override { return 1; } - int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const override + int getNestedRowsCount(const RefIdColumn* column, const RefIdData& data, int index) const override { - const Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + const Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); return static_cast(record.get().mSpells.mList.size()); } @@ -1503,20 +1421,21 @@ namespace CSMWorld UniversalId::Type mType; // not implemented - NestedTravelRefIdAdapter (const NestedTravelRefIdAdapter&); - NestedTravelRefIdAdapter& operator= (const NestedTravelRefIdAdapter&); + NestedTravelRefIdAdapter(const NestedTravelRefIdAdapter&); + NestedTravelRefIdAdapter& operator=(const NestedTravelRefIdAdapter&); public: - - NestedTravelRefIdAdapter(UniversalId::Type type) :mType(type) {} + NestedTravelRefIdAdapter(UniversalId::Type type) + : mType(type) + { + } virtual ~NestedTravelRefIdAdapter() {} - void addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const override + void addNestedRow(const RefIdColumn* column, RefIdData& data, int index, int position) const override { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); ESXRecordT traveller = record.get(); std::vector& list = traveller.mTransport.mList; @@ -1535,114 +1454,131 @@ namespace CSMWorld if (position >= (int)list.size()) list.push_back(newRow); else - list.insert(list.begin()+position, newRow); + list.insert(list.begin() + position, newRow); - record.setModified (traveller); + record.setModified(traveller); } - void removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const override + void removeNestedRow(const RefIdColumn* column, RefIdData& data, int index, int rowToRemove) const override { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); ESXRecordT traveller = record.get(); std::vector& list = traveller.mTransport.mList; - if (rowToRemove < 0 || rowToRemove >= static_cast (list.size())) - throw std::runtime_error ("index out of range"); + if (rowToRemove < 0 || rowToRemove >= static_cast(list.size())) + throw std::runtime_error("index out of range"); - list.erase (list.begin () + rowToRemove); + list.erase(list.begin() + rowToRemove); - record.setModified (traveller); + record.setModified(traveller); } - void setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const override + void setNestedTable(const RefIdColumn* column, RefIdData& data, int index, + const NestedTableWrapperBase& nestedTable) const override { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); ESXRecordT traveller = record.get(); - traveller.mTransport.mList = - static_cast >&>(nestedTable).mNestedTable; + traveller.mTransport.mList + = static_cast>&>(nestedTable) + .mNestedTable; - record.setModified (traveller); + record.setModified(traveller); } - NestedTableWrapperBase* nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const override + NestedTableWrapperBase* nestedTable(const RefIdColumn* column, const RefIdData& data, int index) const override { - const Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + const Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); // deleted by dtor of NestedTableStoring - return new NestedTableWrapper >(record.get().mTransport.mList); + return new NestedTableWrapper>(record.get().mTransport.mList); } - QVariant getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const override + QVariant getNestedData(const RefIdColumn* column, const RefIdData& data, int index, int subRowIndex, + int subColIndex) const override { - const Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + const Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); const std::vector& list = record.get().mTransport.mList; - if (subRowIndex < 0 || subRowIndex >= static_cast (list.size())) - throw std::runtime_error ("index out of range"); + if (subRowIndex < 0 || subRowIndex >= static_cast(list.size())) + throw std::runtime_error("index out of range"); const ESM::Transport::Dest& content = list.at(subRowIndex); switch (subColIndex) { - case 0: return QString::fromUtf8(content.mCellName.c_str()); - case 1: return content.mPos.pos[0]; - case 2: return content.mPos.pos[1]; - case 3: return content.mPos.pos[2]; - case 4: return content.mPos.rot[0]; - case 5: return content.mPos.rot[1]; - case 6: return content.mPos.rot[2]; + case 0: + return QString::fromUtf8(content.mCellName.c_str()); + case 1: + return content.mPos.pos[0]; + case 2: + return content.mPos.pos[1]; + case 3: + return content.mPos.pos[2]; + case 4: + return content.mPos.rot[0]; + case 5: + return content.mPos.rot[1]; + case 6: + return content.mPos.rot[2]; default: throw std::runtime_error("Trying to access non-existing column in the nested table!"); } } - void setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const override + void setNestedData(const RefIdColumn* column, RefIdData& data, int row, const QVariant& value, int subRowIndex, + int subColIndex) const override { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (row, mType))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(row, mType))); ESXRecordT traveller = record.get(); std::vector& list = traveller.mTransport.mList; - if (subRowIndex < 0 || subRowIndex >= static_cast (list.size())) - throw std::runtime_error ("index out of range"); + if (subRowIndex < 0 || subRowIndex >= static_cast(list.size())) + throw std::runtime_error("index out of range"); - switch(subColIndex) + switch (subColIndex) { - case 0: list.at(subRowIndex).mCellName = std::string(value.toString().toUtf8().constData()); break; - case 1: list.at(subRowIndex).mPos.pos[0] = value.toFloat(); break; - case 2: list.at(subRowIndex).mPos.pos[1] = value.toFloat(); break; - case 3: list.at(subRowIndex).mPos.pos[2] = value.toFloat(); break; - case 4: list.at(subRowIndex).mPos.rot[0] = value.toFloat(); break; - case 5: list.at(subRowIndex).mPos.rot[1] = value.toFloat(); break; - case 6: list.at(subRowIndex).mPos.rot[2] = value.toFloat(); break; + case 0: + list.at(subRowIndex).mCellName = std::string(value.toString().toUtf8().constData()); + break; + case 1: + list.at(subRowIndex).mPos.pos[0] = value.toFloat(); + break; + case 2: + list.at(subRowIndex).mPos.pos[1] = value.toFloat(); + break; + case 3: + list.at(subRowIndex).mPos.pos[2] = value.toFloat(); + break; + case 4: + list.at(subRowIndex).mPos.rot[0] = value.toFloat(); + break; + case 5: + list.at(subRowIndex).mPos.rot[1] = value.toFloat(); + break; + case 6: + list.at(subRowIndex).mPos.rot[2] = value.toFloat(); + break; default: throw std::runtime_error("Trying to access non-existing column in the nested table!"); } - record.setModified (traveller); + record.setModified(traveller); } - int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const override - { - return 7; - } + int getNestedColumnsCount(const RefIdColumn* column, const RefIdData& data) const override { return 7; } - int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const override + int getNestedRowsCount(const RefIdColumn* column, const RefIdData& data, int index) const override { - const Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + const Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); return static_cast(record.get().mTransport.mList.size()); } @@ -1654,22 +1590,23 @@ namespace CSMWorld UniversalId::Type mType; // not implemented - ActorAiRefIdAdapter (const ActorAiRefIdAdapter&); - ActorAiRefIdAdapter& operator= (const ActorAiRefIdAdapter&); + ActorAiRefIdAdapter(const ActorAiRefIdAdapter&); + ActorAiRefIdAdapter& operator=(const ActorAiRefIdAdapter&); public: - - ActorAiRefIdAdapter(UniversalId::Type type) :mType(type) {} + ActorAiRefIdAdapter(UniversalId::Type type) + : mType(type) + { + } virtual ~ActorAiRefIdAdapter() {} // FIXME: should check if the AI package type is already in the list and use a default // that wasn't used already (in extreme case do not add anything at all? - void addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const override + void addNestedRow(const RefIdColumn* column, RefIdData& data, int index, int position) const override { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); ESXRecordT actor = record.get(); std::vector& list = actor.mAiPackage.mList; @@ -1687,61 +1624,60 @@ namespace CSMWorld if (position >= (int)list.size()) list.push_back(newRow); else - list.insert(list.begin()+position, newRow); + list.insert(list.begin() + position, newRow); - record.setModified (actor); + record.setModified(actor); } - void removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const override + void removeNestedRow(const RefIdColumn* column, RefIdData& data, int index, int rowToRemove) const override { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); ESXRecordT actor = record.get(); std::vector& list = actor.mAiPackage.mList; - if (rowToRemove < 0 || rowToRemove >= static_cast (list.size())) - throw std::runtime_error ("index out of range"); + if (rowToRemove < 0 || rowToRemove >= static_cast(list.size())) + throw std::runtime_error("index out of range"); - list.erase (list.begin () + rowToRemove); + list.erase(list.begin() + rowToRemove); - record.setModified (actor); + record.setModified(actor); } - void setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const override + void setNestedTable(const RefIdColumn* column, RefIdData& data, int index, + const NestedTableWrapperBase& nestedTable) const override { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); ESXRecordT actor = record.get(); - actor.mAiPackage.mList = - static_cast >&>(nestedTable).mNestedTable; + actor.mAiPackage.mList + = static_cast>&>(nestedTable) + .mNestedTable; - record.setModified (actor); + record.setModified(actor); } - NestedTableWrapperBase* nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const override + NestedTableWrapperBase* nestedTable(const RefIdColumn* column, const RefIdData& data, int index) const override { - const Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + const Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); // deleted by dtor of NestedTableStoring - return new NestedTableWrapper >(record.get().mAiPackage.mList); + return new NestedTableWrapper>(record.get().mAiPackage.mList); } - QVariant getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const override + QVariant getNestedData(const RefIdColumn* column, const RefIdData& data, int index, int subRowIndex, + int subColIndex) const override { - const Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + const Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); const std::vector& list = record.get().mAiPackage.mList; - if (subRowIndex < 0 || subRowIndex >= static_cast (list.size())) - throw std::runtime_error ("index out of range"); + if (subRowIndex < 0 || subRowIndex >= static_cast(list.size())) + throw std::runtime_error("index out of range"); const ESM::AIPackage& content = list.at(subRowIndex); @@ -1751,12 +1687,18 @@ namespace CSMWorld // FIXME: should more than one AI package type be allowed? Check vanilla switch (content.mType) { - case ESM::AI_Wander: return 0; - case ESM::AI_Travel: return 1; - case ESM::AI_Follow: return 2; - case ESM::AI_Escort: return 3; - case ESM::AI_Activate: return 4; - default: return QVariant(); + case ESM::AI_Wander: + return 0; + case ESM::AI_Travel: + return 1; + case ESM::AI_Follow: + return 2; + case ESM::AI_Escort: + return 3; + case ESM::AI_Activate: + return 4; + default: + return QVariant(); } case 1: // wander dist if (content.mType == ESM::AI_Wander) @@ -1784,7 +1726,7 @@ namespace CSMWorld case 10: case 11: if (content.mType == ESM::AI_Wander) - return static_cast(content.mWander.mIdle[subColIndex-4]); + return static_cast(content.mWander.mIdle[subColIndex - 4]); else return QVariant(); case 12: // repeat @@ -1839,30 +1781,41 @@ namespace CSMWorld } } - void setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const override + void setNestedData(const RefIdColumn* column, RefIdData& data, int row, const QVariant& value, int subRowIndex, + int subColIndex) const override { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (row, mType))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(row, mType))); ESXRecordT actor = record.get(); std::vector& list = actor.mAiPackage.mList; - if (subRowIndex < 0 || subRowIndex >= static_cast (list.size())) - throw std::runtime_error ("index out of range"); + if (subRowIndex < 0 || subRowIndex >= static_cast(list.size())) + throw std::runtime_error("index out of range"); ESM::AIPackage& content = list.at(subRowIndex); - switch(subColIndex) + switch (subColIndex) { case 0: // ai package type switch (value.toInt()) { - case 0: content.mType = ESM::AI_Wander; break; - case 1: content.mType = ESM::AI_Travel; break; - case 2: content.mType = ESM::AI_Follow; break; - case 3: content.mType = ESM::AI_Escort; break; - case 4: content.mType = ESM::AI_Activate; break; - default: return; // return without saving + case 0: + content.mType = ESM::AI_Wander; + break; + case 1: + content.mType = ESM::AI_Travel; + break; + case 2: + content.mType = ESM::AI_Follow; + break; + case 3: + content.mType = ESM::AI_Escort; + break; + case 4: + content.mType = ESM::AI_Activate; + break; + default: + return; // return without saving } break; // always save @@ -1897,7 +1850,7 @@ namespace CSMWorld case 10: case 11: if (content.mType == ESM::AI_Wander) - content.mWander.mIdle[subColIndex-4] = static_cast(value.toInt()); + content.mWander.mIdle[subColIndex - 4] = static_cast(value.toInt()); else return; // return without saving @@ -1973,44 +1926,41 @@ namespace CSMWorld throw std::runtime_error("Trying to access non-existing column in the nested table!"); } - record.setModified (actor); + record.setModified(actor); } - int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const override - { - return 19; - } + int getNestedColumnsCount(const RefIdColumn* column, const RefIdData& data) const override { return 19; } - int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const override + int getNestedRowsCount(const RefIdColumn* column, const RefIdData& data, int index) const override { - const Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + const Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); return static_cast(record.get().mAiPackage.mList.size()); } }; - template class BodyPartRefIdAdapter : public NestedRefIdAdapterBase { UniversalId::Type mType; // not implemented - BodyPartRefIdAdapter (const BodyPartRefIdAdapter&); - BodyPartRefIdAdapter& operator= (const BodyPartRefIdAdapter&); + BodyPartRefIdAdapter(const BodyPartRefIdAdapter&); + BodyPartRefIdAdapter& operator=(const BodyPartRefIdAdapter&); public: - - BodyPartRefIdAdapter(UniversalId::Type type) :mType(type) {} + BodyPartRefIdAdapter(UniversalId::Type type) + : mType(type) + { + } virtual ~BodyPartRefIdAdapter() {} - void addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const override + void addNestedRow(const RefIdColumn* column, RefIdData& data, int index, int position) const override { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); ESXRecordT apparel = record.get(); std::vector& list = apparel.mParts.mParts; @@ -2023,61 +1973,60 @@ namespace CSMWorld if (position >= (int)list.size()) list.push_back(newPart); else - list.insert(list.begin()+position, newPart); + list.insert(list.begin() + position, newPart); - record.setModified (apparel); + record.setModified(apparel); } - void removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const override + void removeNestedRow(const RefIdColumn* column, RefIdData& data, int index, int rowToRemove) const override { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); ESXRecordT apparel = record.get(); std::vector& list = apparel.mParts.mParts; - if (rowToRemove < 0 || rowToRemove >= static_cast (list.size())) - throw std::runtime_error ("index out of range"); + if (rowToRemove < 0 || rowToRemove >= static_cast(list.size())) + throw std::runtime_error("index out of range"); - list.erase (list.begin () + rowToRemove); + list.erase(list.begin() + rowToRemove); - record.setModified (apparel); + record.setModified(apparel); } - void setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const override + void setNestedTable(const RefIdColumn* column, RefIdData& data, int index, + const NestedTableWrapperBase& nestedTable) const override { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); ESXRecordT apparel = record.get(); - apparel.mParts.mParts = - static_cast >&>(nestedTable).mNestedTable; + apparel.mParts.mParts + = static_cast>&>(nestedTable) + .mNestedTable; - record.setModified (apparel); + record.setModified(apparel); } - NestedTableWrapperBase* nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const override + NestedTableWrapperBase* nestedTable(const RefIdColumn* column, const RefIdData& data, int index) const override { - const Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + const Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); // deleted by dtor of NestedTableStoring - return new NestedTableWrapper >(record.get().mParts.mParts); + return new NestedTableWrapper>(record.get().mParts.mParts); } - QVariant getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const override + QVariant getNestedData(const RefIdColumn* column, const RefIdData& data, int index, int subRowIndex, + int subColIndex) const override { - const Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + const Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); const std::vector& list = record.get().mParts.mParts; - if (subRowIndex < 0 || subRowIndex >= static_cast (list.size())) - throw std::runtime_error ("index out of range"); + if (subRowIndex < 0 || subRowIndex >= static_cast(list.size())) + throw std::runtime_error("index out of range"); const ESM::PartReference& content = list.at(subRowIndex); @@ -2090,105 +2039,107 @@ namespace CSMWorld else throw std::runtime_error("Part Reference Type unexpected value"); } - case 1: return QString(content.mMale.c_str()); - case 2: return QString(content.mFemale.c_str()); + case 1: + return QString(content.mMale.c_str()); + case 2: + return QString(content.mFemale.c_str()); default: throw std::runtime_error("Trying to access non-existing column in the nested table!"); } } - void setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const override + void setNestedData(const RefIdColumn* column, RefIdData& data, int row, const QVariant& value, int subRowIndex, + int subColIndex) const override { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (row, mType))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(row, mType))); ESXRecordT apparel = record.get(); std::vector& list = apparel.mParts.mParts; - if (subRowIndex < 0 || subRowIndex >= static_cast (list.size())) - throw std::runtime_error ("index out of range"); + if (subRowIndex < 0 || subRowIndex >= static_cast(list.size())) + throw std::runtime_error("index out of range"); - switch(subColIndex) + switch (subColIndex) { - case 0: list.at(subRowIndex).mPart = static_cast(value.toInt()); break; - case 1: list.at(subRowIndex).mMale = value.toString().toStdString(); break; - case 2: list.at(subRowIndex).mFemale = value.toString().toStdString(); break; + case 0: + list.at(subRowIndex).mPart = static_cast(value.toInt()); + break; + case 1: + list.at(subRowIndex).mMale = value.toString().toStdString(); + break; + case 2: + list.at(subRowIndex).mFemale = value.toString().toStdString(); + break; default: throw std::runtime_error("Trying to access non-existing column in the nested table!"); } - record.setModified (apparel); + record.setModified(apparel); } - int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const override - { - return 3; - } + int getNestedColumnsCount(const RefIdColumn* column, const RefIdData& data) const override { return 3; } - int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const override + int getNestedRowsCount(const RefIdColumn* column, const RefIdData& data, int index) const override { - const Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + const Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); return static_cast(record.get().mParts.mParts.size()); } }; - struct LevListColumns : public BaseColumns { - const RefIdColumn *mLevList; - const RefIdColumn *mNestedListLevList; + const RefIdColumn* mLevList; + const RefIdColumn* mNestedListLevList; - LevListColumns (const BaseColumns& base) - : BaseColumns (base) - , mLevList(nullptr) - , mNestedListLevList(nullptr) - {} + LevListColumns(const BaseColumns& base) + : BaseColumns(base) + , mLevList(nullptr) + , mNestedListLevList(nullptr) + { + } }; - template + template class LevelledListRefIdAdapter : public BaseRefIdAdapter { - LevListColumns mLevList; - - public: + LevListColumns mLevList; - LevelledListRefIdAdapter (UniversalId::Type type, const LevListColumns &columns); + public: + LevelledListRefIdAdapter(UniversalId::Type type, const LevListColumns& columns); - QVariant getData (const RefIdColumn *column, const RefIdData& data, int index) - const override; + QVariant getData(const RefIdColumn* column, const RefIdData& data, int index) const override; - void setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const override; - ///< If the data type does not match an exception is thrown. + void setData(const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const override; + ///< If the data type does not match an exception is thrown. }; - template - LevelledListRefIdAdapter::LevelledListRefIdAdapter (UniversalId::Type type, - const LevListColumns &columns) - : BaseRefIdAdapter (type, columns), mLevList (columns) - {} + template + LevelledListRefIdAdapter::LevelledListRefIdAdapter(UniversalId::Type type, const LevListColumns& columns) + : BaseRefIdAdapter(type, columns) + , mLevList(columns) + { + } - template - QVariant LevelledListRefIdAdapter::getData (const RefIdColumn *column, const RefIdData& data, - int index) const + template + QVariant LevelledListRefIdAdapter::getData( + const RefIdColumn* column, const RefIdData& data, int index) const { - if (column==mLevList.mLevList || column == mLevList.mNestedListLevList) + if (column == mLevList.mLevList || column == mLevList.mNestedListLevList) return QVariant::fromValue(ColumnBase::TableEdit_Full); - return BaseRefIdAdapter::getData (column, data, index); + return BaseRefIdAdapter::getData(column, data, index); } - template - void LevelledListRefIdAdapter::setData (const RefIdColumn *column, RefIdData& data, int index, - const QVariant& value) const + template + void LevelledListRefIdAdapter::setData( + const RefIdColumn* column, RefIdData& data, int index, const QVariant& value) const { - BaseRefIdAdapter::setData (column, data, index, value); + BaseRefIdAdapter::setData(column, data, index, value); return; } - // for non-tables template class NestedListLevListRefIdAdapter : public NestedRefIdAdapterBase @@ -2196,53 +2147,54 @@ namespace CSMWorld UniversalId::Type mType; // not implemented - NestedListLevListRefIdAdapter (const NestedListLevListRefIdAdapter&); - NestedListLevListRefIdAdapter& operator= (const NestedListLevListRefIdAdapter&); + NestedListLevListRefIdAdapter(const NestedListLevListRefIdAdapter&); + NestedListLevListRefIdAdapter& operator=(const NestedListLevListRefIdAdapter&); public: - NestedListLevListRefIdAdapter(UniversalId::Type type) - :mType(type) {} + : mType(type) + { + } virtual ~NestedListLevListRefIdAdapter() {} - void addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const override + void addNestedRow(const RefIdColumn* column, RefIdData& data, int index, int position) const override { - throw std::logic_error ("cannot add a row to a fixed table"); + throw std::logic_error("cannot add a row to a fixed table"); } - void removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const override + void removeNestedRow(const RefIdColumn* column, RefIdData& data, int index, int rowToRemove) const override { - throw std::logic_error ("cannot remove a row to a fixed table"); + throw std::logic_error("cannot remove a row to a fixed table"); } - void setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const override + void setNestedTable(const RefIdColumn* column, RefIdData& data, int index, + const NestedTableWrapperBase& nestedTable) const override { - throw std::logic_error ("table operation not supported"); + throw std::logic_error("table operation not supported"); } - NestedTableWrapperBase* nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const override + NestedTableWrapperBase* nestedTable(const RefIdColumn* column, const RefIdData& data, int index) const override { - throw std::logic_error ("table operation not supported"); + throw std::logic_error("table operation not supported"); } - QVariant getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const override + QVariant getNestedData(const RefIdColumn* column, const RefIdData& data, int index, int subRowIndex, + int subColIndex) const override { - const Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + const Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); if (mType == UniversalId::Type_CreatureLevelledList) { switch (subColIndex) { - case 0: return QVariant(); // disable the checkbox editor - case 1: return record.get().mFlags & ESM::CreatureLevList::AllLevels; - case 2: return static_cast (record.get().mChanceNone); + case 0: + return QVariant(); // disable the checkbox editor + case 1: + return record.get().mFlags & ESM::CreatureLevList::AllLevels; + case 2: + return static_cast(record.get().mChanceNone); default: throw std::runtime_error("Trying to access non-existing column in levelled creatues!"); } @@ -2251,30 +2203,34 @@ namespace CSMWorld { switch (subColIndex) { - case 0: return record.get().mFlags & ESM::ItemLevList::Each; - case 1: return record.get().mFlags & ESM::ItemLevList::AllLevels; - case 2: return static_cast (record.get().mChanceNone); + case 0: + return record.get().mFlags & ESM::ItemLevList::Each; + case 1: + return record.get().mFlags & ESM::ItemLevList::AllLevels; + case 2: + return static_cast(record.get().mChanceNone); default: throw std::runtime_error("Trying to access non-existing column in levelled items!"); } } } - void setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const override + void setNestedData(const RefIdColumn* column, RefIdData& data, int row, const QVariant& value, int subRowIndex, + int subColIndex) const override { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (row, mType))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(row, mType))); ESXRecordT leveled = record.get(); if (mType == UniversalId::Type_CreatureLevelledList) { - switch(subColIndex) + switch (subColIndex) { - case 0: return; // return without saving + case 0: + return; // return without saving case 1: { - if(value.toBool()) + if (value.toBool()) { leveled.mFlags |= ESM::CreatureLevList::AllLevels; break; @@ -2285,18 +2241,20 @@ namespace CSMWorld break; } } - case 2: leveled.mChanceNone = static_cast(value.toInt()); break; + case 2: + leveled.mChanceNone = static_cast(value.toInt()); + break; default: throw std::runtime_error("Trying to set non-existing column in levelled creatures!"); } } else { - switch(subColIndex) + switch (subColIndex) { case 0: { - if(value.toBool()) + if (value.toBool()) { leveled.mFlags |= ESM::ItemLevList::Each; break; @@ -2309,7 +2267,7 @@ namespace CSMWorld } case 1: { - if(value.toBool()) + if (value.toBool()) { leveled.mFlags |= ESM::ItemLevList::AllLevels; break; @@ -2320,21 +2278,20 @@ namespace CSMWorld break; } } - case 2: leveled.mChanceNone = static_cast(value.toInt()); break; + case 2: + leveled.mChanceNone = static_cast(value.toInt()); + break; default: throw std::runtime_error("Trying to set non-existing column in levelled items!"); } } - record.setModified (leveled); + record.setModified(leveled); } - int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const override - { - return 3; - } + int getNestedColumnsCount(const RefIdColumn* column, const RefIdData& data) const override { return 3; } - int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const override + int getNestedRowsCount(const RefIdColumn* column, const RefIdData& data, int index) const override { return 1; // fixed at size 1 } @@ -2347,20 +2304,21 @@ namespace CSMWorld UniversalId::Type mType; // not implemented - NestedLevListRefIdAdapter (const NestedLevListRefIdAdapter&); - NestedLevListRefIdAdapter& operator= (const NestedLevListRefIdAdapter&); + NestedLevListRefIdAdapter(const NestedLevListRefIdAdapter&); + NestedLevListRefIdAdapter& operator=(const NestedLevListRefIdAdapter&); public: - - NestedLevListRefIdAdapter(UniversalId::Type type) :mType(type) {} + NestedLevListRefIdAdapter(UniversalId::Type type) + : mType(type) + { + } virtual ~NestedLevListRefIdAdapter() {} - void addNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int position) const override + void addNestedRow(const RefIdColumn* column, RefIdData& data, int index, int position) const override { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); ESXRecordT leveled = record.get(); std::vector& list = leveled.mList; @@ -2372,104 +2330,107 @@ namespace CSMWorld if (position >= (int)list.size()) list.push_back(newItem); else - list.insert(list.begin()+position, newItem); + list.insert(list.begin() + position, newItem); - record.setModified (leveled); + record.setModified(leveled); } - void removeNestedRow (const RefIdColumn *column, - RefIdData& data, int index, int rowToRemove) const override + void removeNestedRow(const RefIdColumn* column, RefIdData& data, int index, int rowToRemove) const override { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); ESXRecordT leveled = record.get(); std::vector& list = leveled.mList; - if (rowToRemove < 0 || rowToRemove >= static_cast (list.size())) - throw std::runtime_error ("index out of range"); + if (rowToRemove < 0 || rowToRemove >= static_cast(list.size())) + throw std::runtime_error("index out of range"); - list.erase (list.begin () + rowToRemove); + list.erase(list.begin() + rowToRemove); - record.setModified (leveled); + record.setModified(leveled); } - void setNestedTable (const RefIdColumn* column, - RefIdData& data, int index, const NestedTableWrapperBase& nestedTable) const override + void setNestedTable(const RefIdColumn* column, RefIdData& data, int index, + const NestedTableWrapperBase& nestedTable) const override { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); ESXRecordT leveled = record.get(); - leveled.mList = - static_cast >&>(nestedTable).mNestedTable; + leveled.mList + = static_cast>&>( + nestedTable) + .mNestedTable; - record.setModified (leveled); + record.setModified(leveled); } - NestedTableWrapperBase* nestedTable (const RefIdColumn* column, - const RefIdData& data, int index) const override + NestedTableWrapperBase* nestedTable(const RefIdColumn* column, const RefIdData& data, int index) const override { - const Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + const Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); // deleted by dtor of NestedTableStoring - return new NestedTableWrapper >(record.get().mList); + return new NestedTableWrapper>(record.get().mList); } - QVariant getNestedData (const RefIdColumn *column, - const RefIdData& data, int index, int subRowIndex, int subColIndex) const override + QVariant getNestedData(const RefIdColumn* column, const RefIdData& data, int index, int subRowIndex, + int subColIndex) const override { - const Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + const Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); const std::vector& list = record.get().mList; - if (subRowIndex < 0 || subRowIndex >= static_cast (list.size())) - throw std::runtime_error ("index out of range"); + if (subRowIndex < 0 || subRowIndex >= static_cast(list.size())) + throw std::runtime_error("index out of range"); const ESM::LevelledListBase::LevelItem& content = list.at(subRowIndex); switch (subColIndex) { - case 0: return QString(content.mId.c_str()); - case 1: return content.mLevel; + case 0: + return QString(content.mId.c_str()); + case 1: + return content.mLevel; default: throw std::runtime_error("Trying to access non-existing column in the nested table!"); } } - void setNestedData (const RefIdColumn *column, - RefIdData& data, int row, const QVariant& value, int subRowIndex, int subColIndex) const override + void setNestedData(const RefIdColumn* column, RefIdData& data, int row, const QVariant& value, int subRowIndex, + int subColIndex) const override { - Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (row, mType))); + Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(row, mType))); ESXRecordT leveled = record.get(); std::vector& list = leveled.mList; - if (subRowIndex < 0 || subRowIndex >= static_cast (list.size())) - throw std::runtime_error ("index out of range"); + if (subRowIndex < 0 || subRowIndex >= static_cast(list.size())) + throw std::runtime_error("index out of range"); - switch(subColIndex) + switch (subColIndex) { - case 0: list.at(subRowIndex).mId = value.toString().toStdString(); break; - case 1: list.at(subRowIndex).mLevel = static_cast(value.toInt()); break; + case 0: + list.at(subRowIndex).mId = value.toString().toStdString(); + break; + case 1: + list.at(subRowIndex).mLevel = static_cast(value.toInt()); + break; default: throw std::runtime_error("Trying to access non-existing column in the nested table!"); } - record.setModified (leveled); + record.setModified(leveled); } - int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const override - { - return 2; - } + int getNestedColumnsCount(const RefIdColumn* column, const RefIdData& data) const override { return 2; } - int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const override + int getNestedRowsCount(const RefIdColumn* column, const RefIdData& data, int index) const override { - const Record& record = - static_cast&> (data.getRecord (RefIdData::LocalIndex (index, mType))); + const Record& record + = static_cast&>(data.getRecord(RefIdData::LocalIndex(index, mType))); return static_cast(record.get().mList.size()); } diff --git a/apps/opencs/model/world/refidcollection.cpp b/apps/opencs/model/world/refidcollection.cpp index b5f887e3e6..818dc6a644 100644 --- a/apps/opencs/model/world/refidcollection.cpp +++ b/apps/opencs/model/world/refidcollection.cpp @@ -1,21 +1,23 @@ #include "refidcollection.hpp" -#include #include +#include #include #include -#include "refidadapter.hpp" -#include "refidadapterimp.hpp" #include "columns.hpp" -#include "nestedtablewrapper.hpp" #include "nestedcoladapterimp.hpp" +#include "nestedtablewrapper.hpp" +#include "refidadapter.hpp" +#include "refidadapterimp.hpp" -CSMWorld::RefIdColumn::RefIdColumn (int columnId, Display displayType, int flag, - bool editable, bool userEditable) - : NestableColumn (columnId, displayType, flag), mEditable (editable), mUserEditable (userEditable) -{} +CSMWorld::RefIdColumn::RefIdColumn(int columnId, Display displayType, int flag, bool editable, bool userEditable) + : NestableColumn(columnId, displayType, flag) + , mEditable(editable) + , mUserEditable(userEditable) +{ +} bool CSMWorld::RefIdColumn::isEditable() const { @@ -27,12 +29,12 @@ bool CSMWorld::RefIdColumn::isUserEditable() const return mUserEditable; } -const CSMWorld::RefIdAdapter& CSMWorld::RefIdCollection::findAdapter (UniversalId::Type type) const +const CSMWorld::RefIdAdapter& CSMWorld::RefIdCollection::findAdapter(UniversalId::Type type) const { - std::map::const_iterator iter = mAdapters.find (type); + std::map::const_iterator iter = mAdapters.find(type); - if (iter==mAdapters.end()) - throw std::logic_error ("unsupported type in RefIdCollection"); + if (iter == mAdapters.end()) + throw std::logic_error("unsupported type in RefIdCollection"); return *iter->second; } @@ -41,8 +43,8 @@ CSMWorld::RefIdCollection::RefIdCollection() { BaseColumns baseColumns; - mColumns.emplace_back(Columns::ColumnId_Id, ColumnBase::Display_Id, - ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false); + mColumns.emplace_back( + Columns::ColumnId_Id, ColumnBase::Display_Id, ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false); baseColumns.mId = &mColumns.back(); mColumns.emplace_back(Columns::ColumnId_Modification, ColumnBase::Display_RecordState, ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, true, false); @@ -51,17 +53,17 @@ CSMWorld::RefIdCollection::RefIdCollection() ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue, false, false); baseColumns.mType = &mColumns.back(); mColumns.emplace_back(Columns::ColumnId_Blocked, ColumnBase::Display_Boolean, - ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh); + ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh); baseColumns.mBlocked = &mColumns.back(); - ModelColumns modelColumns (baseColumns); + ModelColumns modelColumns(baseColumns); mColumns.emplace_back(Columns::ColumnId_Persistent, ColumnBase::Display_Boolean); modelColumns.mPersistence = &mColumns.back(); mColumns.emplace_back(Columns::ColumnId_Model, ColumnBase::Display_Mesh); modelColumns.mModel = &mColumns.back(); - NameColumns nameColumns (modelColumns); + NameColumns nameColumns(modelColumns); // Only items that can be placed in a container have the 32 character limit, but enforce // that for all referenceable types for now. @@ -70,7 +72,7 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.emplace_back(Columns::ColumnId_Script, ColumnBase::Display_Script); nameColumns.mScript = &mColumns.back(); - InventoryColumns inventoryColumns (nameColumns); + InventoryColumns inventoryColumns(nameColumns); mColumns.emplace_back(Columns::ColumnId_Icon, ColumnBase::Display_Icon); inventoryColumns.mIcon = &mColumns.back(); @@ -79,62 +81,49 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.emplace_back(Columns::ColumnId_CoinValue, ColumnBase::Display_Integer); inventoryColumns.mValue = &mColumns.back(); - IngredientColumns ingredientColumns (inventoryColumns); - mColumns.emplace_back(Columns::ColumnId_EffectList, - ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); + IngredientColumns ingredientColumns(inventoryColumns); + mColumns.emplace_back(Columns::ColumnId_EffectList, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); ingredientColumns.mEffects = &mColumns.back(); std::map ingredientEffectsMap; - ingredientEffectsMap.insert(std::make_pair(UniversalId::Type_Ingredient, - new IngredEffectRefIdAdapter ())); + ingredientEffectsMap.insert(std::make_pair(UniversalId::Type_Ingredient, new IngredEffectRefIdAdapter())); mNestedAdapters.emplace_back(&mColumns.back(), ingredientEffectsMap); - mColumns.back().addColumn( - new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_IngredEffectId)); - mColumns.back().addColumn( - new NestedChildColumn (Columns::ColumnId_Skill, ColumnBase::Display_EffectSkill)); - mColumns.back().addColumn( - new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_EffectAttribute)); + mColumns.back().addColumn(new NestedChildColumn(Columns::ColumnId_EffectId, ColumnBase::Display_IngredEffectId)); + mColumns.back().addColumn(new NestedChildColumn(Columns::ColumnId_Skill, ColumnBase::Display_EffectSkill)); + mColumns.back().addColumn(new NestedChildColumn(Columns::ColumnId_Attribute, ColumnBase::Display_EffectAttribute)); // nested table - PotionColumns potionColumns (inventoryColumns); - mColumns.emplace_back(Columns::ColumnId_EffectList, - ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); + PotionColumns potionColumns(inventoryColumns); + mColumns.emplace_back(Columns::ColumnId_EffectList, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); potionColumns.mEffects = &mColumns.back(); // see refidadapterimp.hpp std::map effectsMap; - effectsMap.insert(std::make_pair(UniversalId::Type_Potion, - new EffectsRefIdAdapter (UniversalId::Type_Potion))); + effectsMap.insert( + std::make_pair(UniversalId::Type_Potion, new EffectsRefIdAdapter(UniversalId::Type_Potion))); mNestedAdapters.emplace_back(&mColumns.back(), effectsMap); + mColumns.back().addColumn(new NestedChildColumn(Columns::ColumnId_EffectId, ColumnBase::Display_EffectId)); + mColumns.back().addColumn(new NestedChildColumn(Columns::ColumnId_Skill, ColumnBase::Display_EffectSkill)); + mColumns.back().addColumn(new NestedChildColumn(Columns::ColumnId_Attribute, ColumnBase::Display_EffectAttribute)); + mColumns.back().addColumn(new NestedChildColumn(Columns::ColumnId_EffectRange, ColumnBase::Display_EffectRange)); + mColumns.back().addColumn(new NestedChildColumn(Columns::ColumnId_EffectArea, ColumnBase::Display_String)); mColumns.back().addColumn( - new NestedChildColumn (Columns::ColumnId_EffectId, ColumnBase::Display_EffectId)); - mColumns.back().addColumn( - new NestedChildColumn (Columns::ColumnId_Skill, ColumnBase::Display_EffectSkill)); - mColumns.back().addColumn( - new NestedChildColumn (Columns::ColumnId_Attribute, ColumnBase::Display_EffectAttribute)); - mColumns.back().addColumn( - new NestedChildColumn (Columns::ColumnId_EffectRange, ColumnBase::Display_EffectRange)); - mColumns.back().addColumn( - new NestedChildColumn (Columns::ColumnId_EffectArea, ColumnBase::Display_String)); - mColumns.back().addColumn( - new NestedChildColumn (Columns::ColumnId_Duration, ColumnBase::Display_Integer)); // reuse from light - mColumns.back().addColumn( - new NestedChildColumn (Columns::ColumnId_MinMagnitude, ColumnBase::Display_Integer)); - mColumns.back().addColumn( - new NestedChildColumn (Columns::ColumnId_MaxMagnitude, ColumnBase::Display_Integer)); + new NestedChildColumn(Columns::ColumnId_Duration, ColumnBase::Display_Integer)); // reuse from light + mColumns.back().addColumn(new NestedChildColumn(Columns::ColumnId_MinMagnitude, ColumnBase::Display_Integer)); + mColumns.back().addColumn(new NestedChildColumn(Columns::ColumnId_MaxMagnitude, ColumnBase::Display_Integer)); - EnchantableColumns enchantableColumns (inventoryColumns); + EnchantableColumns enchantableColumns(inventoryColumns); mColumns.emplace_back(Columns::ColumnId_Enchantment, ColumnBase::Display_Enchantment); enchantableColumns.mEnchantment = &mColumns.back(); mColumns.emplace_back(Columns::ColumnId_EnchantmentPoints, ColumnBase::Display_Integer); enchantableColumns.mEnchantmentPoints = &mColumns.back(); - ToolColumns toolsColumns (inventoryColumns); + ToolColumns toolsColumns(inventoryColumns); mColumns.emplace_back(Columns::ColumnId_Quality, ColumnBase::Display_Float); toolsColumns.mQuality = &mColumns.back(); mColumns.emplace_back(Columns::ColumnId_Charges, ColumnBase::Display_Integer); toolsColumns.mUses = &mColumns.back(); - ActorColumns actorsColumns (nameColumns); + ActorColumns actorsColumns(nameColumns); mColumns.emplace_back(Columns::ColumnId_AiHello, ColumnBase::Display_UnsignedInteger16); actorsColumns.mHello = &mColumns.back(); @@ -146,194 +135,152 @@ CSMWorld::RefIdCollection::RefIdCollection() actorsColumns.mAlarm = &mColumns.back(); // Nested table - mColumns.emplace_back(Columns::ColumnId_ActorInventory, - ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); + mColumns.emplace_back( + Columns::ColumnId_ActorInventory, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); actorsColumns.mInventory = &mColumns.back(); std::map inventoryMap; - inventoryMap.insert(std::make_pair(UniversalId::Type_Npc, - new NestedInventoryRefIdAdapter (UniversalId::Type_Npc))); - inventoryMap.insert(std::make_pair(UniversalId::Type_Creature, - new NestedInventoryRefIdAdapter (UniversalId::Type_Creature))); + inventoryMap.insert( + std::make_pair(UniversalId::Type_Npc, new NestedInventoryRefIdAdapter(UniversalId::Type_Npc))); + inventoryMap.insert(std::make_pair( + UniversalId::Type_Creature, new NestedInventoryRefIdAdapter(UniversalId::Type_Creature))); mNestedAdapters.emplace_back(&mColumns.back(), inventoryMap); mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_Referenceable)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_ItemCount, CSMWorld::ColumnBase::Display_Integer)); + new RefIdColumn(Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_Referenceable)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_ItemCount, CSMWorld::ColumnBase::Display_Integer)); // Nested table - mColumns.emplace_back(Columns::ColumnId_SpellList, - ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); + mColumns.emplace_back(Columns::ColumnId_SpellList, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); actorsColumns.mSpells = &mColumns.back(); std::map spellsMap; - spellsMap.insert(std::make_pair(UniversalId::Type_Npc, - new NestedSpellRefIdAdapter (UniversalId::Type_Npc))); - spellsMap.insert(std::make_pair(UniversalId::Type_Creature, - new NestedSpellRefIdAdapter (UniversalId::Type_Creature))); + spellsMap.insert( + std::make_pair(UniversalId::Type_Npc, new NestedSpellRefIdAdapter(UniversalId::Type_Npc))); + spellsMap.insert(std::make_pair( + UniversalId::Type_Creature, new NestedSpellRefIdAdapter(UniversalId::Type_Creature))); mNestedAdapters.emplace_back(&mColumns.back(), spellsMap); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_SpellId, CSMWorld::ColumnBase::Display_Spell)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_SpellId, CSMWorld::ColumnBase::Display_Spell)); // Nested table - mColumns.emplace_back(Columns::ColumnId_NpcDestinations, - ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); + mColumns.emplace_back( + Columns::ColumnId_NpcDestinations, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); actorsColumns.mDestinations = &mColumns.back(); std::map destMap; - destMap.insert(std::make_pair(UniversalId::Type_Npc, - new NestedTravelRefIdAdapter (UniversalId::Type_Npc))); - destMap.insert(std::make_pair(UniversalId::Type_Creature, - new NestedTravelRefIdAdapter (UniversalId::Type_Creature))); + destMap.insert( + std::make_pair(UniversalId::Type_Npc, new NestedTravelRefIdAdapter(UniversalId::Type_Npc))); + destMap.insert(std::make_pair( + UniversalId::Type_Creature, new NestedTravelRefIdAdapter(UniversalId::Type_Creature))); mNestedAdapters.emplace_back(&mColumns.back(), destMap); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_DestinationCell, CSMWorld::ColumnBase::Display_Cell)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_PosX, CSMWorld::ColumnBase::Display_Float)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_PosY, CSMWorld::ColumnBase::Display_Float)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_PosZ, CSMWorld::ColumnBase::Display_Float)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_RotX, CSMWorld::ColumnBase::Display_Double)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_RotY, CSMWorld::ColumnBase::Display_Double)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_RotZ, CSMWorld::ColumnBase::Display_Double)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_DestinationCell, CSMWorld::ColumnBase::Display_Cell)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_PosX, CSMWorld::ColumnBase::Display_Float)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_PosY, CSMWorld::ColumnBase::Display_Float)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_PosZ, CSMWorld::ColumnBase::Display_Float)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_RotX, CSMWorld::ColumnBase::Display_Double)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_RotY, CSMWorld::ColumnBase::Display_Double)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_RotZ, CSMWorld::ColumnBase::Display_Double)); // Nested table - mColumns.emplace_back(Columns::ColumnId_AiPackageList, - ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); + mColumns.emplace_back(Columns::ColumnId_AiPackageList, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); actorsColumns.mAiPackages = &mColumns.back(); std::map aiMap; - aiMap.insert(std::make_pair(UniversalId::Type_Npc, - new ActorAiRefIdAdapter (UniversalId::Type_Npc))); - aiMap.insert(std::make_pair(UniversalId::Type_Creature, - new ActorAiRefIdAdapter (UniversalId::Type_Creature))); + aiMap.insert(std::make_pair(UniversalId::Type_Npc, new ActorAiRefIdAdapter(UniversalId::Type_Npc))); + aiMap.insert( + std::make_pair(UniversalId::Type_Creature, new ActorAiRefIdAdapter(UniversalId::Type_Creature))); mNestedAdapters.emplace_back(&mColumns.back(), aiMap); mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_AiPackageType, CSMWorld::ColumnBase::Display_AiPackageType)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_AiWanderDist, CSMWorld::ColumnBase::Display_Integer)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_AiDuration, CSMWorld::ColumnBase::Display_Integer)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_AiWanderToD, CSMWorld::ColumnBase::Display_Integer)); - - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_Idle1, CSMWorld::ColumnBase::Display_Integer)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_Idle2, CSMWorld::ColumnBase::Display_Integer)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_Idle3, CSMWorld::ColumnBase::Display_Integer)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_Idle4, CSMWorld::ColumnBase::Display_Integer)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_Idle5, CSMWorld::ColumnBase::Display_Integer)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_Idle6, CSMWorld::ColumnBase::Display_Integer)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_Idle7, CSMWorld::ColumnBase::Display_Integer)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_Idle8, CSMWorld::ColumnBase::Display_Integer)); - - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_AiWanderRepeat, CSMWorld::ColumnBase::Display_Boolean)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_AiActivateName, CSMWorld::ColumnBase::Display_String32)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_AiTargetId, CSMWorld::ColumnBase::Display_String32)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_AiTargetCell, CSMWorld::ColumnBase::Display_String)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_PosX, CSMWorld::ColumnBase::Display_Float)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_PosY, CSMWorld::ColumnBase::Display_Float)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_PosZ, CSMWorld::ColumnBase::Display_Float)); + new RefIdColumn(Columns::ColumnId_AiPackageType, CSMWorld::ColumnBase::Display_AiPackageType)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_AiWanderDist, CSMWorld::ColumnBase::Display_Integer)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_AiDuration, CSMWorld::ColumnBase::Display_Integer)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_AiWanderToD, CSMWorld::ColumnBase::Display_Integer)); + + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_Idle1, CSMWorld::ColumnBase::Display_Integer)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_Idle2, CSMWorld::ColumnBase::Display_Integer)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_Idle3, CSMWorld::ColumnBase::Display_Integer)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_Idle4, CSMWorld::ColumnBase::Display_Integer)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_Idle5, CSMWorld::ColumnBase::Display_Integer)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_Idle6, CSMWorld::ColumnBase::Display_Integer)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_Idle7, CSMWorld::ColumnBase::Display_Integer)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_Idle8, CSMWorld::ColumnBase::Display_Integer)); + + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_AiWanderRepeat, CSMWorld::ColumnBase::Display_Boolean)); + mColumns.back().addColumn( + new RefIdColumn(Columns::ColumnId_AiActivateName, CSMWorld::ColumnBase::Display_String32)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_AiTargetId, CSMWorld::ColumnBase::Display_String32)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_AiTargetCell, CSMWorld::ColumnBase::Display_String)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_PosX, CSMWorld::ColumnBase::Display_Float)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_PosY, CSMWorld::ColumnBase::Display_Float)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_PosZ, CSMWorld::ColumnBase::Display_Float)); static const struct { int mName; unsigned int mFlag; - } sServiceTable[] = - { - { Columns::ColumnId_BuysWeapons, ESM::NPC::Weapon}, - { Columns::ColumnId_BuysArmor, ESM::NPC::Armor}, - { Columns::ColumnId_BuysClothing, ESM::NPC::Clothing}, - { Columns::ColumnId_BuysBooks, ESM::NPC::Books}, - { Columns::ColumnId_BuysIngredients, ESM::NPC::Ingredients}, - { Columns::ColumnId_BuysLockpicks, ESM::NPC::Picks}, - { Columns::ColumnId_BuysProbes, ESM::NPC::Probes}, - { Columns::ColumnId_BuysLights, ESM::NPC::Lights}, - { Columns::ColumnId_BuysApparati, ESM::NPC::Apparatus}, - { Columns::ColumnId_BuysRepairItems, ESM::NPC::RepairItem}, - { Columns::ColumnId_BuysMiscItems, ESM::NPC::Misc}, - { Columns::ColumnId_BuysPotions, ESM::NPC::Potions}, - { Columns::ColumnId_BuysMagicItems, ESM::NPC::MagicItems}, - { Columns::ColumnId_SellsSpells, ESM::NPC::Spells}, - { Columns::ColumnId_Trainer, ESM::NPC::Training}, - { Columns::ColumnId_Spellmaking, ESM::NPC::Spellmaking}, - { Columns::ColumnId_EnchantingService, ESM::NPC::Enchanting}, - { Columns::ColumnId_RepairService, ESM::NPC::Repair}, - { -1, 0 } - }; - - for (int i=0; sServiceTable[i].mName!=-1; ++i) + } sServiceTable[] = { { Columns::ColumnId_BuysWeapons, ESM::NPC::Weapon }, + { Columns::ColumnId_BuysArmor, ESM::NPC::Armor }, { Columns::ColumnId_BuysClothing, ESM::NPC::Clothing }, + { Columns::ColumnId_BuysBooks, ESM::NPC::Books }, { Columns::ColumnId_BuysIngredients, ESM::NPC::Ingredients }, + { Columns::ColumnId_BuysLockpicks, ESM::NPC::Picks }, { Columns::ColumnId_BuysProbes, ESM::NPC::Probes }, + { Columns::ColumnId_BuysLights, ESM::NPC::Lights }, { Columns::ColumnId_BuysApparati, ESM::NPC::Apparatus }, + { Columns::ColumnId_BuysRepairItems, ESM::NPC::RepairItem }, + { Columns::ColumnId_BuysMiscItems, ESM::NPC::Misc }, { Columns::ColumnId_BuysPotions, ESM::NPC::Potions }, + { Columns::ColumnId_BuysMagicItems, ESM::NPC::MagicItems }, { Columns::ColumnId_SellsSpells, ESM::NPC::Spells }, + { Columns::ColumnId_Trainer, ESM::NPC::Training }, { Columns::ColumnId_Spellmaking, ESM::NPC::Spellmaking }, + { Columns::ColumnId_EnchantingService, ESM::NPC::Enchanting }, + { Columns::ColumnId_RepairService, ESM::NPC::Repair }, { -1, 0 } }; + + for (int i = 0; sServiceTable[i].mName != -1; ++i) { mColumns.emplace_back(sServiceTable[i].mName, ColumnBase::Display_Boolean); - actorsColumns.mServices.insert (std::make_pair (&mColumns.back(), sServiceTable[i].mFlag)); + actorsColumns.mServices.insert(std::make_pair(&mColumns.back(), sServiceTable[i].mFlag)); } mColumns.emplace_back(Columns::ColumnId_AutoCalc, ColumnBase::Display_Boolean, - ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh); - const RefIdColumn *autoCalc = &mColumns.back(); + ColumnBase::Flag_Table | ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh); + const RefIdColumn* autoCalc = &mColumns.back(); - mColumns.emplace_back(Columns::ColumnId_ApparatusType, - ColumnBase::Display_ApparatusType); - const RefIdColumn *apparatusType = &mColumns.back(); + mColumns.emplace_back(Columns::ColumnId_ApparatusType, ColumnBase::Display_ApparatusType); + const RefIdColumn* apparatusType = &mColumns.back(); mColumns.emplace_back(Columns::ColumnId_ArmorType, ColumnBase::Display_ArmorType); - const RefIdColumn *armorType = &mColumns.back(); + const RefIdColumn* armorType = &mColumns.back(); mColumns.emplace_back(Columns::ColumnId_Health, ColumnBase::Display_Integer); - const RefIdColumn *health = &mColumns.back(); + const RefIdColumn* health = &mColumns.back(); mColumns.emplace_back(Columns::ColumnId_ArmorValue, ColumnBase::Display_Integer); - const RefIdColumn *armor = &mColumns.back(); + const RefIdColumn* armor = &mColumns.back(); mColumns.emplace_back(Columns::ColumnId_BookType, ColumnBase::Display_BookType); - const RefIdColumn *bookType = &mColumns.back(); + const RefIdColumn* bookType = &mColumns.back(); mColumns.emplace_back(Columns::ColumnId_Skill, ColumnBase::Display_SkillId); - const RefIdColumn *skill = &mColumns.back(); + const RefIdColumn* skill = &mColumns.back(); mColumns.emplace_back(Columns::ColumnId_Text, ColumnBase::Display_LongString); - const RefIdColumn *text = &mColumns.back(); + const RefIdColumn* text = &mColumns.back(); mColumns.emplace_back(Columns::ColumnId_ClothingType, ColumnBase::Display_ClothingType); - const RefIdColumn *clothingType = &mColumns.back(); + const RefIdColumn* clothingType = &mColumns.back(); mColumns.emplace_back(Columns::ColumnId_WeightCapacity, ColumnBase::Display_Float); - const RefIdColumn *weightCapacity = &mColumns.back(); + const RefIdColumn* weightCapacity = &mColumns.back(); mColumns.emplace_back(Columns::ColumnId_OrganicContainer, ColumnBase::Display_Boolean); - const RefIdColumn *organic = &mColumns.back(); + const RefIdColumn* organic = &mColumns.back(); mColumns.emplace_back(Columns::ColumnId_Respawn, ColumnBase::Display_Boolean); - const RefIdColumn *respawn = &mColumns.back(); + const RefIdColumn* respawn = &mColumns.back(); // Nested table - mColumns.emplace_back(Columns::ColumnId_ContainerContent, - ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); - const RefIdColumn *content = &mColumns.back(); + mColumns.emplace_back( + Columns::ColumnId_ContainerContent, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); + const RefIdColumn* content = &mColumns.back(); std::map contMap; - contMap.insert(std::make_pair(UniversalId::Type_Container, - new NestedInventoryRefIdAdapter (UniversalId::Type_Container))); + contMap.insert(std::make_pair( + UniversalId::Type_Container, new NestedInventoryRefIdAdapter(UniversalId::Type_Container))); mNestedAdapters.emplace_back(&mColumns.back(), contMap); mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_Referenceable)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_ItemCount, CSMWorld::ColumnBase::Display_Integer)); + new RefIdColumn(Columns::ColumnId_InventoryItemId, CSMWorld::ColumnBase::Display_Referenceable)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_ItemCount, CSMWorld::ColumnBase::Display_Integer)); - CreatureColumns creatureColumns (actorsColumns); + CreatureColumns creatureColumns(actorsColumns); mColumns.emplace_back(Columns::ColumnId_CreatureType, ColumnBase::Display_CreatureType); creatureColumns.mType = &mColumns.back(); @@ -346,98 +293,82 @@ CSMWorld::RefIdCollection::RefIdCollection() { int mName; unsigned int mFlag; - } sCreatureFlagTable[] = - { - { Columns::ColumnId_Biped, ESM::Creature::Bipedal }, - { Columns::ColumnId_HasWeapon, ESM::Creature::Weapon }, - { Columns::ColumnId_Swims, ESM::Creature::Swims }, - { Columns::ColumnId_Flies, ESM::Creature::Flies }, - { Columns::ColumnId_Walks, ESM::Creature::Walks }, - { Columns::ColumnId_Essential, ESM::Creature::Essential }, - { -1, 0 } - }; + } sCreatureFlagTable[] = { { Columns::ColumnId_Biped, ESM::Creature::Bipedal }, + { Columns::ColumnId_HasWeapon, ESM::Creature::Weapon }, { Columns::ColumnId_Swims, ESM::Creature::Swims }, + { Columns::ColumnId_Flies, ESM::Creature::Flies }, { Columns::ColumnId_Walks, ESM::Creature::Walks }, + { Columns::ColumnId_Essential, ESM::Creature::Essential }, { -1, 0 } }; // for re-use in NPC records - const RefIdColumn *essential = nullptr; + const RefIdColumn* essential = nullptr; - for (int i=0; sCreatureFlagTable[i].mName!=-1; ++i) + for (int i = 0; sCreatureFlagTable[i].mName != -1; ++i) { mColumns.emplace_back(sCreatureFlagTable[i].mName, ColumnBase::Display_Boolean); - creatureColumns.mFlags.insert (std::make_pair (&mColumns.back(), sCreatureFlagTable[i].mFlag)); + creatureColumns.mFlags.insert(std::make_pair(&mColumns.back(), sCreatureFlagTable[i].mFlag)); switch (sCreatureFlagTable[i].mFlag) { - case ESM::Creature::Essential: essential = &mColumns.back(); break; + case ESM::Creature::Essential: + essential = &mColumns.back(); + break; } } mColumns.emplace_back(Columns::ColumnId_BloodType, ColumnBase::Display_BloodType); // For re-use in NPC records. - const RefIdColumn *bloodType = &mColumns.back(); + const RefIdColumn* bloodType = &mColumns.back(); creatureColumns.mBloodType = bloodType; - creatureColumns.mFlags.insert (std::make_pair (respawn, ESM::Creature::Respawn)); + creatureColumns.mFlags.insert(std::make_pair(respawn, ESM::Creature::Respawn)); // Nested table - mColumns.emplace_back(Columns::ColumnId_CreatureAttributes, - ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); + mColumns.emplace_back( + Columns::ColumnId_CreatureAttributes, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); creatureColumns.mAttributes = &mColumns.back(); std::map creaAttrMap; creaAttrMap.insert(std::make_pair(UniversalId::Type_Creature, new CreatureAttributesRefIdAdapter())); mNestedAdapters.emplace_back(&mColumns.back(), creaAttrMap); mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_Attribute, CSMWorld::ColumnBase::Display_Attribute, false, false)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_AttributeValue, CSMWorld::ColumnBase::Display_Integer)); + new RefIdColumn(Columns::ColumnId_Attribute, CSMWorld::ColumnBase::Display_Attribute, false, false)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_AttributeValue, CSMWorld::ColumnBase::Display_Integer)); // Nested table - mColumns.emplace_back(Columns::ColumnId_CreatureAttack, - ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); + mColumns.emplace_back( + Columns::ColumnId_CreatureAttack, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); creatureColumns.mAttacks = &mColumns.back(); std::map attackMap; attackMap.insert(std::make_pair(UniversalId::Type_Creature, new CreatureAttackRefIdAdapter())); mNestedAdapters.emplace_back(&mColumns.back(), attackMap); mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_CreatureAttack, CSMWorld::ColumnBase::Display_Integer, false, false)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_MinAttack, CSMWorld::ColumnBase::Display_Integer)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_MaxAttack, CSMWorld::ColumnBase::Display_Integer)); + new RefIdColumn(Columns::ColumnId_CreatureAttack, CSMWorld::ColumnBase::Display_Integer, false, false)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_MinAttack, CSMWorld::ColumnBase::Display_Integer)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_MaxAttack, CSMWorld::ColumnBase::Display_Integer)); // Nested list - mColumns.emplace_back(Columns::ColumnId_CreatureMisc, - ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_List); + mColumns.emplace_back(Columns::ColumnId_CreatureMisc, ColumnBase::Display_NestedHeader, + ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_List); creatureColumns.mMisc = &mColumns.back(); std::map creaMiscMap; creaMiscMap.insert(std::make_pair(UniversalId::Type_Creature, new CreatureMiscRefIdAdapter())); mNestedAdapters.emplace_back(&mColumns.back(), creaMiscMap); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_Level, CSMWorld::ColumnBase::Display_Integer, - ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_Health, CSMWorld::ColumnBase::Display_Integer)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_Mana, CSMWorld::ColumnBase::Display_Integer)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_Fatigue, CSMWorld::ColumnBase::Display_Integer)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_SoulPoints, CSMWorld::ColumnBase::Display_Integer)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_CombatState, CSMWorld::ColumnBase::Display_Integer)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_MagicState, CSMWorld::ColumnBase::Display_Integer)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_StealthState, CSMWorld::ColumnBase::Display_Integer)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_Gold, CSMWorld::ColumnBase::Display_Integer)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_Level, CSMWorld::ColumnBase::Display_Integer, + ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_Refresh)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_Health, CSMWorld::ColumnBase::Display_Integer)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_Mana, CSMWorld::ColumnBase::Display_Integer)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_Fatigue, CSMWorld::ColumnBase::Display_Integer)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_SoulPoints, CSMWorld::ColumnBase::Display_Integer)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_CombatState, CSMWorld::ColumnBase::Display_Integer)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_MagicState, CSMWorld::ColumnBase::Display_Integer)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_StealthState, CSMWorld::ColumnBase::Display_Integer)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_Gold, CSMWorld::ColumnBase::Display_Integer)); mColumns.emplace_back(Columns::ColumnId_OpenSound, ColumnBase::Display_Sound); - const RefIdColumn *openSound = &mColumns.back(); + const RefIdColumn* openSound = &mColumns.back(); mColumns.emplace_back(Columns::ColumnId_CloseSound, ColumnBase::Display_Sound); - const RefIdColumn *closeSound = &mColumns.back(); + const RefIdColumn* closeSound = &mColumns.back(); - LightColumns lightColumns (inventoryColumns); + LightColumns lightColumns(inventoryColumns); mColumns.emplace_back(Columns::ColumnId_Duration, ColumnBase::Display_Integer); lightColumns.mTime = &mColumns.back(); @@ -458,26 +389,21 @@ CSMWorld::RefIdCollection::RefIdCollection() { int mName; unsigned int mFlag; - } sLightFlagTable[] = - { - { Columns::ColumnId_Dynamic, ESM::Light::Dynamic }, - { Columns::ColumnId_Portable, ESM::Light::Carry }, - { Columns::ColumnId_NegativeLight, ESM::Light::Negative }, - { Columns::ColumnId_Fire, ESM::Light::Fire }, - { Columns::ColumnId_OffByDefault, ESM::Light::OffDefault }, - { -1, 0 } - }; - - for (int i=0; sLightFlagTable[i].mName!=-1; ++i) + } sLightFlagTable[] + = { { Columns::ColumnId_Dynamic, ESM::Light::Dynamic }, { Columns::ColumnId_Portable, ESM::Light::Carry }, + { Columns::ColumnId_NegativeLight, ESM::Light::Negative }, { Columns::ColumnId_Fire, ESM::Light::Fire }, + { Columns::ColumnId_OffByDefault, ESM::Light::OffDefault }, { -1, 0 } }; + + for (int i = 0; sLightFlagTable[i].mName != -1; ++i) { mColumns.emplace_back(sLightFlagTable[i].mName, ColumnBase::Display_Boolean); - lightColumns.mFlags.insert (std::make_pair (&mColumns.back(), sLightFlagTable[i].mFlag)); + lightColumns.mFlags.insert(std::make_pair(&mColumns.back(), sLightFlagTable[i].mFlag)); } mColumns.emplace_back(Columns::ColumnId_IsKey, ColumnBase::Display_Boolean); - const RefIdColumn *key = &mColumns.back(); + const RefIdColumn* key = &mColumns.back(); - NpcColumns npcColumns (actorsColumns); + NpcColumns npcColumns(actorsColumns); mColumns.emplace_back(Columns::ColumnId_Race, ColumnBase::Display_Race); npcColumns.mRace = &mColumns.back(); @@ -498,11 +424,11 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.emplace_back(Columns::ColumnId_Gender, ColumnBase::Display_GenderNpc); npcColumns.mGender = &mColumns.back(); - npcColumns.mFlags.insert (std::make_pair (essential, ESM::NPC::Essential)); + npcColumns.mFlags.insert(std::make_pair(essential, ESM::NPC::Essential)); - npcColumns.mFlags.insert (std::make_pair (respawn, ESM::NPC::Respawn)); + npcColumns.mFlags.insert(std::make_pair(respawn, ESM::NPC::Respawn)); - npcColumns.mFlags.insert (std::make_pair (autoCalc, ESM::NPC::Autocalc)); + npcColumns.mFlags.insert(std::make_pair(autoCalc, ESM::NPC::Autocalc)); // Re-used from Creature records. npcColumns.mBloodType = bloodType; @@ -512,54 +438,47 @@ CSMWorld::RefIdCollection::RefIdCollection() // These needs to be driven from the autocalculated setting. // Nested table - mColumns.emplace_back(Columns::ColumnId_NpcAttributes, - ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); + mColumns.emplace_back(Columns::ColumnId_NpcAttributes, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); npcColumns.mAttributes = &mColumns.back(); std::map attrMap; attrMap.insert(std::make_pair(UniversalId::Type_Npc, new NpcAttributesRefIdAdapter())); mNestedAdapters.emplace_back(&mColumns.back(), attrMap); mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_Attribute, CSMWorld::ColumnBase::Display_Attribute, false, false)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_UChar, CSMWorld::ColumnBase::Display_UnsignedInteger8)); + new RefIdColumn(Columns::ColumnId_Attribute, CSMWorld::ColumnBase::Display_Attribute, false, false)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_UChar, CSMWorld::ColumnBase::Display_UnsignedInteger8)); // Nested table - mColumns.emplace_back(Columns::ColumnId_NpcSkills, - ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); + mColumns.emplace_back(Columns::ColumnId_NpcSkills, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); npcColumns.mSkills = &mColumns.back(); std::map skillsMap; skillsMap.insert(std::make_pair(UniversalId::Type_Npc, new NpcSkillsRefIdAdapter())); mNestedAdapters.emplace_back(&mColumns.back(), skillsMap); mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_Skill, CSMWorld::ColumnBase::Display_SkillId, false, false)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_UChar, CSMWorld::ColumnBase::Display_UnsignedInteger8)); + new RefIdColumn(Columns::ColumnId_Skill, CSMWorld::ColumnBase::Display_SkillId, false, false)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_UChar, CSMWorld::ColumnBase::Display_UnsignedInteger8)); // Nested list - mColumns.emplace_back(Columns::ColumnId_NpcMisc, - ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_List); + mColumns.emplace_back(Columns::ColumnId_NpcMisc, ColumnBase::Display_NestedHeader, + ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_List); npcColumns.mMisc = &mColumns.back(); std::map miscMap; miscMap.insert(std::make_pair(UniversalId::Type_Npc, new NpcMiscRefIdAdapter())); mNestedAdapters.emplace_back(&mColumns.back(), miscMap); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_Level, CSMWorld::ColumnBase::Display_SignedInteger16)); mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_Level, CSMWorld::ColumnBase::Display_SignedInteger16)); + new RefIdColumn(Columns::ColumnId_Health, CSMWorld::ColumnBase::Display_UnsignedInteger16)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_Mana, CSMWorld::ColumnBase::Display_UnsignedInteger16)); mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_Health, CSMWorld::ColumnBase::Display_UnsignedInteger16)); + new RefIdColumn(Columns::ColumnId_Fatigue, CSMWorld::ColumnBase::Display_UnsignedInteger16)); mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_Mana, CSMWorld::ColumnBase::Display_UnsignedInteger16)); + new RefIdColumn(Columns::ColumnId_NpcDisposition, CSMWorld::ColumnBase::Display_UnsignedInteger8)); mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_Fatigue, CSMWorld::ColumnBase::Display_UnsignedInteger16)); + new RefIdColumn(Columns::ColumnId_NpcReputation, CSMWorld::ColumnBase::Display_UnsignedInteger8)); mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_NpcDisposition, CSMWorld::ColumnBase::Display_UnsignedInteger8)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_NpcReputation, CSMWorld::ColumnBase::Display_UnsignedInteger8)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_NpcRank, CSMWorld::ColumnBase::Display_UnsignedInteger8)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_Gold, CSMWorld::ColumnBase::Display_Integer)); + new RefIdColumn(Columns::ColumnId_NpcRank, CSMWorld::ColumnBase::Display_UnsignedInteger8)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_Gold, CSMWorld::ColumnBase::Display_Integer)); - WeaponColumns weaponColumns (enchantableColumns); + WeaponColumns weaponColumns(enchantableColumns); mColumns.emplace_back(Columns::ColumnId_WeaponType, ColumnBase::Display_WeaponType); weaponColumns.mType = &mColumns.back(); @@ -572,14 +491,14 @@ CSMWorld::RefIdCollection::RefIdCollection() mColumns.emplace_back(Columns::ColumnId_WeaponReach, ColumnBase::Display_Float); weaponColumns.mReach = &mColumns.back(); - for (int i=0; i<3; ++i) + for (int i = 0; i < 3; ++i) { - const RefIdColumn **column = - i==0 ? weaponColumns.mChop : (i==1 ? weaponColumns.mSlash : weaponColumns.mThrust); + const RefIdColumn** column + = i == 0 ? weaponColumns.mChop : (i == 1 ? weaponColumns.mSlash : weaponColumns.mThrust); - for (int j=0; j<2; ++j) + for (int j = 0; j < 2; ++j) { - mColumns.emplace_back(Columns::ColumnId_MinChop+i*2+j, ColumnBase::Display_Integer); + mColumns.emplace_back(Columns::ColumnId_MinChop + i * 2 + j, ColumnBase::Display_Integer); column[j] = &mColumns.back(); } } @@ -588,135 +507,119 @@ CSMWorld::RefIdCollection::RefIdCollection() { int mName; unsigned int mFlag; - } sWeaponFlagTable[] = - { - { Columns::ColumnId_Magical, ESM::Weapon::Magical }, - { Columns::ColumnId_Silver, ESM::Weapon::Silver }, - { -1, 0 } - }; + } sWeaponFlagTable[] = { { Columns::ColumnId_Magical, ESM::Weapon::Magical }, + { Columns::ColumnId_Silver, ESM::Weapon::Silver }, { -1, 0 } }; - for (int i=0; sWeaponFlagTable[i].mName!=-1; ++i) + for (int i = 0; sWeaponFlagTable[i].mName != -1; ++i) { mColumns.emplace_back(sWeaponFlagTable[i].mName, ColumnBase::Display_Boolean); - weaponColumns.mFlags.insert (std::make_pair (&mColumns.back(), sWeaponFlagTable[i].mFlag)); + weaponColumns.mFlags.insert(std::make_pair(&mColumns.back(), sWeaponFlagTable[i].mFlag)); } // Nested table mColumns.emplace_back(Columns::ColumnId_PartRefList, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); - const RefIdColumn *partRef = &mColumns.back(); + const RefIdColumn* partRef = &mColumns.back(); std::map partMap; - partMap.insert(std::make_pair(UniversalId::Type_Armor, - new BodyPartRefIdAdapter (UniversalId::Type_Armor))); - partMap.insert(std::make_pair(UniversalId::Type_Clothing, - new BodyPartRefIdAdapter (UniversalId::Type_Clothing))); + partMap.insert( + std::make_pair(UniversalId::Type_Armor, new BodyPartRefIdAdapter(UniversalId::Type_Armor))); + partMap.insert(std::make_pair( + UniversalId::Type_Clothing, new BodyPartRefIdAdapter(UniversalId::Type_Clothing))); mNestedAdapters.emplace_back(&mColumns.back(), partMap); mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_PartRefType, CSMWorld::ColumnBase::Display_PartRefType)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_PartRefMale, CSMWorld::ColumnBase::Display_BodyPart)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_PartRefFemale, CSMWorld::ColumnBase::Display_BodyPart)); + new RefIdColumn(Columns::ColumnId_PartRefType, CSMWorld::ColumnBase::Display_PartRefType)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_PartRefMale, CSMWorld::ColumnBase::Display_BodyPart)); + mColumns.back().addColumn(new RefIdColumn(Columns::ColumnId_PartRefFemale, CSMWorld::ColumnBase::Display_BodyPart)); - LevListColumns creatureLevListColumns (baseColumns); - LevListColumns itemLevListColumns (baseColumns); + LevListColumns creatureLevListColumns(baseColumns); + LevListColumns itemLevListColumns(baseColumns); std::map creatureLevListMap, itemLevListMap; creatureLevListMap.insert(std::make_pair(UniversalId::Type_CreatureLevelledList, - new NestedLevListRefIdAdapter (UniversalId::Type_CreatureLevelledList))); + new NestedLevListRefIdAdapter(UniversalId::Type_CreatureLevelledList))); itemLevListMap.insert(std::make_pair(UniversalId::Type_ItemLevelledList, - new NestedLevListRefIdAdapter (UniversalId::Type_ItemLevelledList))); + new NestedLevListRefIdAdapter(UniversalId::Type_ItemLevelledList))); // Levelled creature nested table - mColumns.emplace_back(Columns::ColumnId_LevelledList, - ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); + mColumns.emplace_back(Columns::ColumnId_LevelledList, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); creatureLevListColumns.mLevList = &mColumns.back(); mNestedAdapters.emplace_back(&mColumns.back(), creatureLevListMap); mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_LevelledCreatureId, CSMWorld::ColumnBase::Display_Referenceable)); + new RefIdColumn(Columns::ColumnId_LevelledCreatureId, CSMWorld::ColumnBase::Display_Referenceable)); mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_LevelledItemLevel, CSMWorld::ColumnBase::Display_Integer)); + new RefIdColumn(Columns::ColumnId_LevelledItemLevel, CSMWorld::ColumnBase::Display_Integer)); // Levelled item nested table - mColumns.emplace_back(Columns::ColumnId_LevelledList, - ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); + mColumns.emplace_back(Columns::ColumnId_LevelledList, ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue); itemLevListColumns.mLevList = &mColumns.back(); mNestedAdapters.emplace_back(&mColumns.back(), itemLevListMap); mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_LevelledItemId, CSMWorld::ColumnBase::Display_Referenceable)); + new RefIdColumn(Columns::ColumnId_LevelledItemId, CSMWorld::ColumnBase::Display_Referenceable)); mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_LevelledItemLevel, CSMWorld::ColumnBase::Display_Integer)); + new RefIdColumn(Columns::ColumnId_LevelledItemLevel, CSMWorld::ColumnBase::Display_Integer)); // Shared levelled list nested list - mColumns.emplace_back(Columns::ColumnId_LevelledList, - ColumnBase::Display_NestedHeader, ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_List); + mColumns.emplace_back(Columns::ColumnId_LevelledList, ColumnBase::Display_NestedHeader, + ColumnBase::Flag_Dialogue | ColumnBase::Flag_Dialogue_List); creatureLevListColumns.mNestedListLevList = &mColumns.back(); itemLevListColumns.mNestedListLevList = &mColumns.back(); std::map nestedListLevListMap; nestedListLevListMap.insert(std::make_pair(UniversalId::Type_CreatureLevelledList, - new NestedListLevListRefIdAdapter (UniversalId::Type_CreatureLevelledList))); + new NestedListLevListRefIdAdapter(UniversalId::Type_CreatureLevelledList))); nestedListLevListMap.insert(std::make_pair(UniversalId::Type_ItemLevelledList, - new NestedListLevListRefIdAdapter (UniversalId::Type_ItemLevelledList))); + new NestedListLevListRefIdAdapter(UniversalId::Type_ItemLevelledList))); mNestedAdapters.emplace_back(&mColumns.back(), nestedListLevListMap); mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_LevelledItemTypeEach, CSMWorld::ColumnBase::Display_Boolean)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_LevelledItemType, CSMWorld::ColumnBase::Display_Boolean)); - mColumns.back().addColumn( - new RefIdColumn (Columns::ColumnId_LevelledItemChanceNone, CSMWorld::ColumnBase::Display_UnsignedInteger8)); - - mAdapters.insert (std::make_pair (UniversalId::Type_Activator, - new NameRefIdAdapter (UniversalId::Type_Activator, nameColumns))); - mAdapters.insert (std::make_pair (UniversalId::Type_Potion, - new PotionRefIdAdapter (potionColumns, autoCalc))); - mAdapters.insert (std::make_pair (UniversalId::Type_Apparatus, - new ApparatusRefIdAdapter (inventoryColumns, apparatusType, toolsColumns.mQuality))); - mAdapters.insert (std::make_pair (UniversalId::Type_Armor, - new ArmorRefIdAdapter (enchantableColumns, armorType, health, armor, partRef))); - mAdapters.insert (std::make_pair (UniversalId::Type_Book, - new BookRefIdAdapter (enchantableColumns, bookType, skill, text))); - mAdapters.insert (std::make_pair (UniversalId::Type_Clothing, - new ClothingRefIdAdapter (enchantableColumns, clothingType, partRef))); - mAdapters.insert (std::make_pair (UniversalId::Type_Container, - new ContainerRefIdAdapter (nameColumns, weightCapacity, organic, respawn, content))); - mAdapters.insert (std::make_pair (UniversalId::Type_Creature, - new CreatureRefIdAdapter (creatureColumns))); - mAdapters.insert (std::make_pair (UniversalId::Type_Door, - new DoorRefIdAdapter (nameColumns, openSound, closeSound))); - mAdapters.insert (std::make_pair (UniversalId::Type_Ingredient, - new IngredientRefIdAdapter (ingredientColumns))); - mAdapters.insert (std::make_pair (UniversalId::Type_CreatureLevelledList, - new LevelledListRefIdAdapter ( - UniversalId::Type_CreatureLevelledList, creatureLevListColumns))); - mAdapters.insert (std::make_pair (UniversalId::Type_ItemLevelledList, - new LevelledListRefIdAdapter (UniversalId::Type_ItemLevelledList, itemLevListColumns))); - mAdapters.insert (std::make_pair (UniversalId::Type_Light, - new LightRefIdAdapter (lightColumns))); - mAdapters.insert (std::make_pair (UniversalId::Type_Lockpick, - new ToolRefIdAdapter (UniversalId::Type_Lockpick, toolsColumns))); - mAdapters.insert (std::make_pair (UniversalId::Type_Miscellaneous, - new MiscRefIdAdapter (inventoryColumns, key))); - mAdapters.insert (std::make_pair (UniversalId::Type_Npc, - new NpcRefIdAdapter (npcColumns))); - mAdapters.insert (std::make_pair (UniversalId::Type_Probe, - new ToolRefIdAdapter (UniversalId::Type_Probe, toolsColumns))); - mAdapters.insert (std::make_pair (UniversalId::Type_Repair, - new ToolRefIdAdapter (UniversalId::Type_Repair, toolsColumns))); - mAdapters.insert (std::make_pair (UniversalId::Type_Static, - new ModelRefIdAdapter (UniversalId::Type_Static, modelColumns))); - mAdapters.insert (std::make_pair (UniversalId::Type_Weapon, - new WeaponRefIdAdapter (weaponColumns))); + new RefIdColumn(Columns::ColumnId_LevelledItemTypeEach, CSMWorld::ColumnBase::Display_Boolean)); + mColumns.back().addColumn( + new RefIdColumn(Columns::ColumnId_LevelledItemType, CSMWorld::ColumnBase::Display_Boolean)); + mColumns.back().addColumn( + new RefIdColumn(Columns::ColumnId_LevelledItemChanceNone, CSMWorld::ColumnBase::Display_UnsignedInteger8)); + + mAdapters.insert(std::make_pair( + UniversalId::Type_Activator, new NameRefIdAdapter(UniversalId::Type_Activator, nameColumns))); + mAdapters.insert(std::make_pair(UniversalId::Type_Potion, new PotionRefIdAdapter(potionColumns, autoCalc))); + mAdapters.insert(std::make_pair(UniversalId::Type_Apparatus, + new ApparatusRefIdAdapter(inventoryColumns, apparatusType, toolsColumns.mQuality))); + mAdapters.insert(std::make_pair( + UniversalId::Type_Armor, new ArmorRefIdAdapter(enchantableColumns, armorType, health, armor, partRef))); + mAdapters.insert( + std::make_pair(UniversalId::Type_Book, new BookRefIdAdapter(enchantableColumns, bookType, skill, text))); + mAdapters.insert(std::make_pair( + UniversalId::Type_Clothing, new ClothingRefIdAdapter(enchantableColumns, clothingType, partRef))); + mAdapters.insert(std::make_pair(UniversalId::Type_Container, + new ContainerRefIdAdapter(nameColumns, weightCapacity, organic, respawn, content))); + mAdapters.insert(std::make_pair(UniversalId::Type_Creature, new CreatureRefIdAdapter(creatureColumns))); + mAdapters.insert(std::make_pair(UniversalId::Type_Door, new DoorRefIdAdapter(nameColumns, openSound, closeSound))); + mAdapters.insert(std::make_pair(UniversalId::Type_Ingredient, new IngredientRefIdAdapter(ingredientColumns))); + mAdapters.insert(std::make_pair(UniversalId::Type_CreatureLevelledList, + new LevelledListRefIdAdapter( + UniversalId::Type_CreatureLevelledList, creatureLevListColumns))); + mAdapters.insert(std::make_pair(UniversalId::Type_ItemLevelledList, + new LevelledListRefIdAdapter(UniversalId::Type_ItemLevelledList, itemLevListColumns))); + mAdapters.insert(std::make_pair(UniversalId::Type_Light, new LightRefIdAdapter(lightColumns))); + mAdapters.insert(std::make_pair( + UniversalId::Type_Lockpick, new ToolRefIdAdapter(UniversalId::Type_Lockpick, toolsColumns))); + mAdapters.insert(std::make_pair(UniversalId::Type_Miscellaneous, new MiscRefIdAdapter(inventoryColumns, key))); + mAdapters.insert(std::make_pair(UniversalId::Type_Npc, new NpcRefIdAdapter(npcColumns))); + mAdapters.insert(std::make_pair( + UniversalId::Type_Probe, new ToolRefIdAdapter(UniversalId::Type_Probe, toolsColumns))); + mAdapters.insert(std::make_pair( + UniversalId::Type_Repair, new ToolRefIdAdapter(UniversalId::Type_Repair, toolsColumns))); + mAdapters.insert(std::make_pair( + UniversalId::Type_Static, new ModelRefIdAdapter(UniversalId::Type_Static, modelColumns))); + mAdapters.insert(std::make_pair(UniversalId::Type_Weapon, new WeaponRefIdAdapter(weaponColumns))); } CSMWorld::RefIdCollection::~RefIdCollection() { - for (std::map::iterator iter (mAdapters.begin()); - iter!=mAdapters.end(); ++iter) - delete iter->second; + for (std::map::iterator iter(mAdapters.begin()); iter != mAdapters.end(); ++iter) + delete iter->second; - for (std::vector > >::iterator iter (mNestedAdapters.begin()); - iter!=mNestedAdapters.end(); ++iter) + for (std::vector>>::iterator iter( + mNestedAdapters.begin()); + iter != mNestedAdapters.end(); ++iter) { - for (std::map::iterator it ((iter->second).begin()); - it!=(iter->second).end(); ++it) + for (std::map::iterator it((iter->second).begin()); + it != (iter->second).end(); ++it) delete it->second; } } @@ -726,17 +629,17 @@ int CSMWorld::RefIdCollection::getSize() const return mData.getSize(); } -std::string CSMWorld::RefIdCollection::getId (int index) const +std::string CSMWorld::RefIdCollection::getId(int index) const { - return getData (index, 0).toString().toUtf8().constData(); + return getData(index, 0).toString().toUtf8().constData(); } -int CSMWorld::RefIdCollection::getIndex (const std::string& id) const +int CSMWorld::RefIdCollection::getIndex(const std::string& id) const { - int index = searchId (id); + int index = searchId(id); - if (index==-1) - throw std::runtime_error ("invalid ID: " + id); + if (index == -1) + throw std::runtime_error("invalid ID: " + id); return index; } @@ -746,85 +649,84 @@ int CSMWorld::RefIdCollection::getColumns() const return mColumns.size(); } -const CSMWorld::ColumnBase& CSMWorld::RefIdCollection::getColumn (int column) const +const CSMWorld::ColumnBase& CSMWorld::RefIdCollection::getColumn(int column) const { - return mColumns.at (column); + return mColumns.at(column); } -QVariant CSMWorld::RefIdCollection::getData (int index, int column) const +QVariant CSMWorld::RefIdCollection::getData(int index, int column) const { - RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (index); + RefIdData::LocalIndex localIndex = mData.globalToLocalIndex(index); - const RefIdAdapter& adaptor = findAdapter (localIndex.second); + const RefIdAdapter& adaptor = findAdapter(localIndex.second); - return adaptor.getData (&mColumns.at (column), mData, localIndex.first); + return adaptor.getData(&mColumns.at(column), mData, localIndex.first); } -QVariant CSMWorld::RefIdCollection::getNestedData (int row, int column, int subRow, int subColumn) const +QVariant CSMWorld::RefIdCollection::getNestedData(int row, int column, int subRow, int subColumn) const { RefIdData::LocalIndex localIndex = mData.globalToLocalIndex(row); const CSMWorld::NestedRefIdAdapterBase& nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second); - return nestedAdapter.getNestedData(&mColumns.at (column), mData, localIndex.first, subRow, subColumn); + return nestedAdapter.getNestedData(&mColumns.at(column), mData, localIndex.first, subRow, subColumn); } -void CSMWorld::RefIdCollection::setData (int index, int column, const QVariant& data) +void CSMWorld::RefIdCollection::setData(int index, int column, const QVariant& data) { - RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (index); + RefIdData::LocalIndex localIndex = mData.globalToLocalIndex(index); - const RefIdAdapter& adaptor = findAdapter (localIndex.second); + const RefIdAdapter& adaptor = findAdapter(localIndex.second); - adaptor.setData (&mColumns.at (column), mData, localIndex.first, data); + adaptor.setData(&mColumns.at(column), mData, localIndex.first, data); } void CSMWorld::RefIdCollection::setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn) { - RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); + RefIdData::LocalIndex localIndex = mData.globalToLocalIndex(row); const CSMWorld::NestedRefIdAdapterBase& nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second); - nestedAdapter.setNestedData(&mColumns.at (column), mData, localIndex.first, data, subRow, subColumn); + nestedAdapter.setNestedData(&mColumns.at(column), mData, localIndex.first, data, subRow, subColumn); } -void CSMWorld::RefIdCollection::removeRows (int index, int count) +void CSMWorld::RefIdCollection::removeRows(int index, int count) { - mData.erase (index, count); + mData.erase(index, count); } void CSMWorld::RefIdCollection::removeNestedRows(int row, int column, int subRow) { - RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); + RefIdData::LocalIndex localIndex = mData.globalToLocalIndex(row); const CSMWorld::NestedRefIdAdapterBase& nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second); - nestedAdapter.removeNestedRow(&mColumns.at (column), mData, localIndex.first, subRow); + nestedAdapter.removeNestedRow(&mColumns.at(column), mData, localIndex.first, subRow); } -void CSMWorld::RefIdCollection::appendBlankRecord (const std::string& id, UniversalId::Type type) +void CSMWorld::RefIdCollection::appendBlankRecord(const std::string& id, UniversalId::Type type) { - mData.appendRecord (type, id, false); + mData.appendRecord(type, id, false); } int CSMWorld::RefIdCollection::searchId(std::string_view id) const { - RefIdData::LocalIndex localIndex = mData.searchId (id); + RefIdData::LocalIndex localIndex = mData.searchId(id); - if (localIndex.first==-1) + if (localIndex.first == -1) return -1; - return mData.localToGlobalIndex (localIndex); + return mData.localToGlobalIndex(localIndex); } -void CSMWorld::RefIdCollection::replace (int index, std::unique_ptr record) +void CSMWorld::RefIdCollection::replace(int index, std::unique_ptr record) { - mData.getRecord (mData.globalToLocalIndex (index)).assign (*record.release()); + mData.getRecord(mData.globalToLocalIndex(index)).assign(*record.release()); } -void CSMWorld::RefIdCollection::cloneRecord(const std::string& origin, - const std::string& destination, - const CSMWorld::UniversalId::Type type) +void CSMWorld::RefIdCollection::cloneRecord( + const std::string& origin, const std::string& destination, const CSMWorld::UniversalId::Type type) { - std::unique_ptr newRecord = mData.getRecord(mData.searchId(origin)).modifiedCopy(); - mAdapters.find(type)->second->setId(*newRecord, destination); - mData.insertRecord(std::move(newRecord), type, destination); + std::unique_ptr newRecord = mData.getRecord(mData.searchId(origin)).modifiedCopy(); + mAdapters.find(type)->second->setId(*newRecord, destination); + mData.insertRecord(std::move(newRecord), type, destination); } bool CSMWorld::RefIdCollection::touchRecord(const std::string& id) @@ -833,51 +735,50 @@ bool CSMWorld::RefIdCollection::touchRecord(const std::string& id) return false; } -void CSMWorld::RefIdCollection::appendRecord (std::unique_ptr record, - UniversalId::Type type) +void CSMWorld::RefIdCollection::appendRecord(std::unique_ptr record, UniversalId::Type type) { - std::string id = findAdapter (type).getId (*record.get()); + std::string id = findAdapter(type).getId(*record.get()); - int index = mData.getAppendIndex (type); + int index = mData.getAppendIndex(type); - mData.appendRecord (type, id, false); + mData.appendRecord(type, id, false); - mData.getRecord (mData.globalToLocalIndex (index)).assign (*record.release()); + mData.getRecord(mData.globalToLocalIndex(index)).assign(*record.release()); } -const CSMWorld::RecordBase& CSMWorld::RefIdCollection::getRecord (const std::string& id) const +const CSMWorld::RecordBase& CSMWorld::RefIdCollection::getRecord(const std::string& id) const { - return mData.getRecord (mData.searchId (id)); + return mData.getRecord(mData.searchId(id)); } -const CSMWorld::RecordBase& CSMWorld::RefIdCollection::getRecord (int index) const +const CSMWorld::RecordBase& CSMWorld::RefIdCollection::getRecord(int index) const { - return mData.getRecord (mData.globalToLocalIndex (index)); + return mData.getRecord(mData.globalToLocalIndex(index)); } -void CSMWorld::RefIdCollection::load (ESM::ESMReader& reader, bool base, UniversalId::Type type) +void CSMWorld::RefIdCollection::load(ESM::ESMReader& reader, bool base, UniversalId::Type type) { mData.load(reader, base, type); } -int CSMWorld::RefIdCollection::getAppendIndex (const std::string& id, UniversalId::Type type) const +int CSMWorld::RefIdCollection::getAppendIndex(const std::string& id, UniversalId::Type type) const { - return mData.getAppendIndex (type); + return mData.getAppendIndex(type); } -std::vector CSMWorld::RefIdCollection::getIds (bool listDeleted) const +std::vector CSMWorld::RefIdCollection::getIds(bool listDeleted) const { - return mData.getIds (listDeleted); + return mData.getIds(listDeleted); } -bool CSMWorld::RefIdCollection::reorderRows (int baseIndex, const std::vector& newOrder) +bool CSMWorld::RefIdCollection::reorderRows(int baseIndex, const std::vector& newOrder) { return false; } -void CSMWorld::RefIdCollection::save (int index, ESM::ESMWriter& writer) const +void CSMWorld::RefIdCollection::save(int index, ESM::ESMWriter& writer) const { - mData.save (index, writer); + mData.save(index, writer); } const CSMWorld::RefIdData& CSMWorld::RefIdCollection::getDataSet() const @@ -887,7 +788,7 @@ const CSMWorld::RefIdData& CSMWorld::RefIdCollection::getDataSet() const int CSMWorld::RefIdCollection::getNestedRowsCount(int row, int column) const { - RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); + RefIdData::LocalIndex localIndex = mData.globalToLocalIndex(row); const CSMWorld::NestedRefIdAdapterBase& nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second); return nestedAdapter.getNestedRowsCount(&mColumns.at(column), mData, localIndex.first); @@ -895,20 +796,20 @@ int CSMWorld::RefIdCollection::getNestedRowsCount(int row, int column) const int CSMWorld::RefIdCollection::getNestedColumnsCount(int row, int column) const { - RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); + RefIdData::LocalIndex localIndex = mData.globalToLocalIndex(row); const CSMWorld::NestedRefIdAdapterBase& nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second); return nestedAdapter.getNestedColumnsCount(&mColumns.at(column), mData); } -CSMWorld::NestableColumn *CSMWorld::RefIdCollection::getNestableColumn(int column) +CSMWorld::NestableColumn* CSMWorld::RefIdCollection::getNestableColumn(int column) { return &mColumns.at(column); } void CSMWorld::RefIdCollection::addNestedRow(int row, int col, int position) { - RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); + RefIdData::LocalIndex localIndex = mData.globalToLocalIndex(row); const CSMWorld::NestedRefIdAdapterBase& nestedAdapter = getNestedAdapter(mColumns.at(col), localIndex.second); nestedAdapter.addNestedRow(&mColumns.at(col), mData, localIndex.first, position); @@ -916,7 +817,7 @@ void CSMWorld::RefIdCollection::addNestedRow(int row, int col, int position) void CSMWorld::RefIdCollection::setNestedTable(int row, int column, const CSMWorld::NestedTableWrapperBase& nestedTable) { - RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); + RefIdData::LocalIndex localIndex = mData.globalToLocalIndex(row); const CSMWorld::NestedRefIdAdapterBase& nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second); nestedAdapter.setNestedTable(&mColumns.at(column), mData, localIndex.first, nestedTable); @@ -924,21 +825,22 @@ void CSMWorld::RefIdCollection::setNestedTable(int row, int column, const CSMWor CSMWorld::NestedTableWrapperBase* CSMWorld::RefIdCollection::nestedTable(int row, int column) const { - RefIdData::LocalIndex localIndex = mData.globalToLocalIndex (row); + RefIdData::LocalIndex localIndex = mData.globalToLocalIndex(row); const CSMWorld::NestedRefIdAdapterBase& nestedAdapter = getNestedAdapter(mColumns.at(column), localIndex.second); return nestedAdapter.nestedTable(&mColumns.at(column), mData, localIndex.first); } -const CSMWorld::NestedRefIdAdapterBase& CSMWorld::RefIdCollection::getNestedAdapter(const CSMWorld::ColumnBase &column, UniversalId::Type type) const +const CSMWorld::NestedRefIdAdapterBase& CSMWorld::RefIdCollection::getNestedAdapter( + const CSMWorld::ColumnBase& column, UniversalId::Type type) const { - for (std::vector > >::const_iterator iter (mNestedAdapters.begin()); - iter!=mNestedAdapters.end(); ++iter) + for (std::vector>>::const_iterator + iter(mNestedAdapters.begin()); + iter != mNestedAdapters.end(); ++iter) { if ((iter->first) == &column) { - std::map::const_iterator it = - (iter->second).find(type); + std::map::const_iterator it = (iter->second).find(type); if (it == (iter->second).end()) throw std::runtime_error("No such type in the nestedadapters"); @@ -949,7 +851,7 @@ const CSMWorld::NestedRefIdAdapterBase& CSMWorld::RefIdCollection::getNestedAdap throw std::runtime_error("No such column in the nestedadapters"); } -void CSMWorld::RefIdCollection::copyTo (int index, RefIdCollection& target) const +void CSMWorld::RefIdCollection::copyTo(int index, RefIdCollection& target) const { - mData.copyTo (index, target.mData); + mData.copyTo(index, target.mData); } diff --git a/apps/opencs/model/world/refidcollection.hpp b/apps/opencs/model/world/refidcollection.hpp index ee17bb3214..63271db77f 100644 --- a/apps/opencs/model/world/refidcollection.hpp +++ b/apps/opencs/model/world/refidcollection.hpp @@ -1,13 +1,13 @@ #ifndef CSM_WOLRD_REFIDCOLLECTION_H #define CSM_WOLRD_REFIDCOLLECTION_H -#include -#include #include +#include #include +#include -#include "columnbase.hpp" #include "collectionbase.hpp" +#include "columnbase.hpp" #include "nestedcollection.hpp" #include "refiddata.hpp" @@ -24,124 +24,118 @@ namespace CSMWorld class RefIdColumn : public NestableColumn { - bool mEditable; - bool mUserEditable; - - public: + bool mEditable; + bool mUserEditable; - RefIdColumn (int columnId, Display displayType, - int flag = Flag_Table | Flag_Dialogue, bool editable = true, - bool userEditable = true); + public: + RefIdColumn(int columnId, Display displayType, int flag = Flag_Table | Flag_Dialogue, bool editable = true, + bool userEditable = true); - bool isEditable() const override; + bool isEditable() const override; - bool isUserEditable() const override; + bool isUserEditable() const override; }; class RefIdCollection : public CollectionBase, public NestedCollection { - private: - - RefIdData mData; - std::deque mColumns; - std::map mAdapters; - - std::vector > > mNestedAdapters; - - private: + private: + RefIdData mData; + std::deque mColumns; + std::map mAdapters; - const RefIdAdapter& findAdapter (UniversalId::Type) const; - ///< Throws an exception if no adaptor for \a Type can be found. + std::vector>> mNestedAdapters; - const NestedRefIdAdapterBase& getNestedAdapter(const ColumnBase &column, UniversalId::Type type) const; + private: + const RefIdAdapter& findAdapter(UniversalId::Type) const; + ///< Throws an exception if no adaptor for \a Type can be found. - public: + const NestedRefIdAdapterBase& getNestedAdapter(const ColumnBase& column, UniversalId::Type type) const; - RefIdCollection(); + public: + RefIdCollection(); - ~RefIdCollection() override; + ~RefIdCollection() override; - int getSize() const override; + int getSize() const override; - std::string getId (int index) const override; + std::string getId(int index) const override; - int getIndex (const std::string& id) const override; + int getIndex(const std::string& id) const override; - int getColumns() const override; + int getColumns() const override; - const ColumnBase& getColumn (int column) const override; + const ColumnBase& getColumn(int column) const override; - QVariant getData (int index, int column) const override; + QVariant getData(int index, int column) const override; - void setData (int index, int column, const QVariant& data) override; + void setData(int index, int column, const QVariant& data) override; - void removeRows (int index, int count) override; + void removeRows(int index, int count) override; - void cloneRecord(const std::string& origin, - const std::string& destination, - const UniversalId::Type type) override; + void cloneRecord( + const std::string& origin, const std::string& destination, const UniversalId::Type type) override; - bool touchRecord(const std::string& id) override; + bool touchRecord(const std::string& id) override; - void appendBlankRecord (const std::string& id, UniversalId::Type type) override; - ///< \param type Will be ignored, unless the collection supports multiple record types + void appendBlankRecord(const std::string& id, UniversalId::Type type) override; + ///< \param type Will be ignored, unless the collection supports multiple record types - int searchId(std::string_view id) const override; - ////< Search record with \a id. - /// \return index of record (if found) or -1 (not found) + int searchId(std::string_view id) const override; + ////< Search record with \a id. + /// \return index of record (if found) or -1 (not found) - void replace (int index, std::unique_ptr record) override; - ///< If the record type does not match, an exception is thrown. - /// - /// \attention \a record must not change the ID. + void replace(int index, std::unique_ptr record) override; + ///< If the record type does not match, an exception is thrown. + /// + /// \attention \a record must not change the ID. - void appendRecord (std::unique_ptr record, UniversalId::Type type) override; - ///< If the record type does not match, an exception is thrown. - /// - ///< \param type Will be ignored, unless the collection supports multiple record types + void appendRecord(std::unique_ptr record, UniversalId::Type type) override; + ///< If the record type does not match, an exception is thrown. + /// + ///< \param type Will be ignored, unless the collection supports multiple record types - const RecordBase& getRecord (const std::string& id) const override; + const RecordBase& getRecord(const std::string& id) const override; - const RecordBase& getRecord (int index) const override; + const RecordBase& getRecord(int index) const override; - void load (ESM::ESMReader& reader, bool base, UniversalId::Type type); + void load(ESM::ESMReader& reader, bool base, UniversalId::Type type); - int getAppendIndex (const std::string& id, UniversalId::Type type) const override; - ///< \param type Will be ignored, unless the collection supports multiple record types + int getAppendIndex(const std::string& id, UniversalId::Type type) const override; + ///< \param type Will be ignored, unless the collection supports multiple record types - std::vector getIds (bool listDeleted) const override; - ///< Return a sorted collection of all IDs - /// - /// \param listDeleted include deleted record in the list + std::vector getIds(bool listDeleted) const override; + ///< Return a sorted collection of all IDs + /// + /// \param listDeleted include deleted record in the list - bool reorderRows (int baseIndex, const std::vector& newOrder) override; - ///< Reorder the rows [baseIndex, baseIndex+newOrder.size()) according to the indices - /// given in \a newOrder (baseIndex+newOrder[0] specifies the new index of row baseIndex). - /// - /// \return Success? + bool reorderRows(int baseIndex, const std::vector& newOrder) override; + ///< Reorder the rows [baseIndex, baseIndex+newOrder.size()) according to the indices + /// given in \a newOrder (baseIndex+newOrder[0] specifies the new index of row baseIndex). + /// + /// \return Success? - QVariant getNestedData(int row, int column, int subRow, int subColumn) const override; + QVariant getNestedData(int row, int column, int subRow, int subColumn) const override; - NestedTableWrapperBase* nestedTable(int row, int column) const override; + NestedTableWrapperBase* nestedTable(int row, int column) const override; - void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable) override; + void setNestedTable(int row, int column, const NestedTableWrapperBase& nestedTable) override; - int getNestedRowsCount(int row, int column) const override; + int getNestedRowsCount(int row, int column) const override; - int getNestedColumnsCount(int row, int column) const override; + int getNestedColumnsCount(int row, int column) const override; - NestableColumn *getNestableColumn(int column) override; + NestableColumn* getNestableColumn(int column) override; - void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn) override; + void setNestedData(int row, int column, const QVariant& data, int subRow, int subColumn) override; - void removeNestedRows(int row, int column, int subRow) override; + void removeNestedRows(int row, int column, int subRow) override; - void addNestedRow(int row, int col, int position) override; + void addNestedRow(int row, int col, int position) override; - void save (int index, ESM::ESMWriter& writer) const; + void save(int index, ESM::ESMWriter& writer) const; - const RefIdData& getDataSet() const; //I can't figure out a better name for this one :( - void copyTo (int index, RefIdCollection& target) const; + const RefIdData& getDataSet() const; // I can't figure out a better name for this one :( + void copyTo(int index, RefIdCollection& target) const; }; } diff --git a/apps/opencs/model/world/refiddata.cpp b/apps/opencs/model/world/refiddata.cpp index 009e43706f..5f453ed1c6 100644 --- a/apps/opencs/model/world/refiddata.cpp +++ b/apps/opencs/model/world/refiddata.cpp @@ -8,70 +8,65 @@ CSMWorld::RefIdDataContainerBase::~RefIdDataContainerBase() {} - -std::string CSMWorld::RefIdData::getRecordId(const CSMWorld::RefIdData::LocalIndex &index) const +std::string CSMWorld::RefIdData::getRecordId(const CSMWorld::RefIdData::LocalIndex& index) const { - std::map::const_iterator found = - mRecordContainers.find (index.second); + std::map::const_iterator found = mRecordContainers.find(index.second); if (found == mRecordContainers.end()) - throw std::logic_error ("invalid local index type"); + throw std::logic_error("invalid local index type"); return found->second->getId(index.first); } CSMWorld::RefIdData::RefIdData() { - mRecordContainers.insert (std::make_pair (UniversalId::Type_Activator, &mActivators)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_Potion, &mPotions)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_Apparatus, &mApparati)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_Armor, &mArmors)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_Book, &mBooks)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_Clothing, &mClothing)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_Container, &mContainers)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_Creature, &mCreatures)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_Door, &mDoors)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_Ingredient, &mIngredients)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_CreatureLevelledList, - &mCreatureLevelledLists)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_ItemLevelledList, &mItemLevelledLists)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_Light, &mLights)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_Lockpick, &mLockpicks)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_Miscellaneous, &mMiscellaneous)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_Npc, &mNpcs)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_Probe, &mProbes)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_Repair, &mRepairs)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_Static, &mStatics)); - mRecordContainers.insert (std::make_pair (UniversalId::Type_Weapon, &mWeapons)); -} - -CSMWorld::RefIdData::LocalIndex CSMWorld::RefIdData::globalToLocalIndex (int index) const -{ - for (std::map::const_iterator iter ( - mRecordContainers.begin()); iter!=mRecordContainers.end(); ++iter) + mRecordContainers.insert(std::make_pair(UniversalId::Type_Activator, &mActivators)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_Potion, &mPotions)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_Apparatus, &mApparati)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_Armor, &mArmors)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_Book, &mBooks)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_Clothing, &mClothing)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_Container, &mContainers)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_Creature, &mCreatures)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_Door, &mDoors)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_Ingredient, &mIngredients)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_CreatureLevelledList, &mCreatureLevelledLists)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_ItemLevelledList, &mItemLevelledLists)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_Light, &mLights)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_Lockpick, &mLockpicks)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_Miscellaneous, &mMiscellaneous)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_Npc, &mNpcs)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_Probe, &mProbes)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_Repair, &mRepairs)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_Static, &mStatics)); + mRecordContainers.insert(std::make_pair(UniversalId::Type_Weapon, &mWeapons)); +} + +CSMWorld::RefIdData::LocalIndex CSMWorld::RefIdData::globalToLocalIndex(int index) const +{ + for (std::map::const_iterator iter(mRecordContainers.begin()); + iter != mRecordContainers.end(); ++iter) { - if (indexsecond->getSize()) - return LocalIndex (index, iter->first); + if (index < iter->second->getSize()) + return LocalIndex(index, iter->first); index -= iter->second->getSize(); } - throw std::runtime_error ("RefIdData index out of range"); + throw std::runtime_error("RefIdData index out of range"); } -int CSMWorld::RefIdData::localToGlobalIndex (const LocalIndex& index) - const +int CSMWorld::RefIdData::localToGlobalIndex(const LocalIndex& index) const { - std::map::const_iterator end = - mRecordContainers.find (index.second); + std::map::const_iterator end = mRecordContainers.find(index.second); - if (end==mRecordContainers.end()) - throw std::logic_error ("invalid local index type"); + if (end == mRecordContainers.end()) + throw std::logic_error("invalid local index type"); int globalIndex = index.first; - for (std::map::const_iterator iter ( - mRecordContainers.begin()); iter!=end; ++iter) + for (std::map::const_iterator iter(mRecordContainers.begin()); + iter != end; ++iter) globalIndex += iter->second->getSize(); return globalIndex; @@ -79,42 +74,62 @@ int CSMWorld::RefIdData::localToGlobalIndex (const LocalIndex& index) CSMWorld::RefIdData::LocalIndex CSMWorld::RefIdData::searchId(std::string_view id) const { - std::string id2 = Misc::StringUtils::lowerCase (id); + std::string id2 = Misc::StringUtils::lowerCase(id); - std::map >::const_iterator iter = mIndex.find (id2); + std::map>::const_iterator iter = mIndex.find(id2); - if (iter==mIndex.end()) - return std::make_pair (-1, CSMWorld::UniversalId::Type_None); + if (iter == mIndex.end()) + return std::make_pair(-1, CSMWorld::UniversalId::Type_None); return iter->second; } -unsigned int CSMWorld::RefIdData::getRecordFlags (const std::string& id) const +unsigned int CSMWorld::RefIdData::getRecordFlags(const std::string& id) const { - LocalIndex localIndex = searchId (id); + LocalIndex localIndex = searchId(id); switch (localIndex.second) { - case UniversalId::Type_Activator: return mActivators.getRecordFlags(localIndex.first); - case UniversalId::Type_Potion: return mPotions.getRecordFlags(localIndex.first); - case UniversalId::Type_Apparatus: return mApparati.getRecordFlags(localIndex.first); - case UniversalId::Type_Armor: return mArmors.getRecordFlags(localIndex.first); - case UniversalId::Type_Book: return mBooks.getRecordFlags(localIndex.first); - case UniversalId::Type_Clothing: return mClothing.getRecordFlags(localIndex.first); - case UniversalId::Type_Container: return mContainers.getRecordFlags(localIndex.first); - case UniversalId::Type_Creature: return mCreatures.getRecordFlags(localIndex.first); - case UniversalId::Type_Door: return mDoors.getRecordFlags(localIndex.first); - case UniversalId::Type_Ingredient: return mIngredients.getRecordFlags(localIndex.first); - case UniversalId::Type_CreatureLevelledList: return mCreatureLevelledLists.getRecordFlags(localIndex.first); - case UniversalId::Type_ItemLevelledList: return mItemLevelledLists.getRecordFlags(localIndex.first); - case UniversalId::Type_Light: return mLights.getRecordFlags(localIndex.first); - case UniversalId::Type_Lockpick: return mLockpicks.getRecordFlags(localIndex.first); - case UniversalId::Type_Miscellaneous: return mMiscellaneous.getRecordFlags(localIndex.first); - case UniversalId::Type_Npc: return mNpcs.getRecordFlags(localIndex.first); - case UniversalId::Type_Probe: return mProbes.getRecordFlags(localIndex.first); - case UniversalId::Type_Repair: return mRepairs.getRecordFlags(localIndex.first); - case UniversalId::Type_Static: return mStatics.getRecordFlags(localIndex.first); - case UniversalId::Type_Weapon: return mWeapons.getRecordFlags(localIndex.first); + case UniversalId::Type_Activator: + return mActivators.getRecordFlags(localIndex.first); + case UniversalId::Type_Potion: + return mPotions.getRecordFlags(localIndex.first); + case UniversalId::Type_Apparatus: + return mApparati.getRecordFlags(localIndex.first); + case UniversalId::Type_Armor: + return mArmors.getRecordFlags(localIndex.first); + case UniversalId::Type_Book: + return mBooks.getRecordFlags(localIndex.first); + case UniversalId::Type_Clothing: + return mClothing.getRecordFlags(localIndex.first); + case UniversalId::Type_Container: + return mContainers.getRecordFlags(localIndex.first); + case UniversalId::Type_Creature: + return mCreatures.getRecordFlags(localIndex.first); + case UniversalId::Type_Door: + return mDoors.getRecordFlags(localIndex.first); + case UniversalId::Type_Ingredient: + return mIngredients.getRecordFlags(localIndex.first); + case UniversalId::Type_CreatureLevelledList: + return mCreatureLevelledLists.getRecordFlags(localIndex.first); + case UniversalId::Type_ItemLevelledList: + return mItemLevelledLists.getRecordFlags(localIndex.first); + case UniversalId::Type_Light: + return mLights.getRecordFlags(localIndex.first); + case UniversalId::Type_Lockpick: + return mLockpicks.getRecordFlags(localIndex.first); + case UniversalId::Type_Miscellaneous: + return mMiscellaneous.getRecordFlags(localIndex.first); + case UniversalId::Type_Npc: + return mNpcs.getRecordFlags(localIndex.first); + case UniversalId::Type_Probe: + return mProbes.getRecordFlags(localIndex.first); + case UniversalId::Type_Repair: + return mRepairs.getRecordFlags(localIndex.first); + case UniversalId::Type_Static: + return mStatics.getRecordFlags(localIndex.first); + case UniversalId::Type_Weapon: + return mWeapons.getRecordFlags(localIndex.first); default: break; } @@ -122,97 +137,92 @@ unsigned int CSMWorld::RefIdData::getRecordFlags (const std::string& id) const return 0; } -void CSMWorld::RefIdData::erase (int index, int count) +void CSMWorld::RefIdData::erase(int index, int count) { - LocalIndex localIndex = globalToLocalIndex (index); + LocalIndex localIndex = globalToLocalIndex(index); - std::map::const_iterator iter = - mRecordContainers.find (localIndex.second); + std::map::const_iterator iter + = mRecordContainers.find(localIndex.second); - while (count>0 && iter!=mRecordContainers.end()) + while (count > 0 && iter != mRecordContainers.end()) { int size = iter->second->getSize(); - if (localIndex.first+count>size) + if (localIndex.first + count > size) { - erase (localIndex, size-localIndex.first); - count -= size-localIndex.first; + erase(localIndex, size - localIndex.first); + count -= size - localIndex.first; ++iter; - if (iter==mRecordContainers.end()) - throw std::runtime_error ("invalid count value for erase operation"); + if (iter == mRecordContainers.end()) + throw std::runtime_error("invalid count value for erase operation"); localIndex.first = 0; localIndex.second = iter->first; } else { - erase (localIndex, count); + erase(localIndex, count); count = 0; } } } -const CSMWorld::RecordBase& CSMWorld::RefIdData::getRecord (const LocalIndex& index) const +const CSMWorld::RecordBase& CSMWorld::RefIdData::getRecord(const LocalIndex& index) const { - std::map::const_iterator iter = - mRecordContainers.find (index.second); + std::map::const_iterator iter = mRecordContainers.find(index.second); - if (iter==mRecordContainers.end()) - throw std::logic_error ("invalid local index type"); + if (iter == mRecordContainers.end()) + throw std::logic_error("invalid local index type"); - return iter->second->getRecord (index.first); + return iter->second->getRecord(index.first); } -CSMWorld::RecordBase& CSMWorld::RefIdData::getRecord (const LocalIndex& index) +CSMWorld::RecordBase& CSMWorld::RefIdData::getRecord(const LocalIndex& index) { - std::map::iterator iter = - mRecordContainers.find (index.second); + std::map::iterator iter = mRecordContainers.find(index.second); - if (iter==mRecordContainers.end()) - throw std::logic_error ("invalid local index type"); + if (iter == mRecordContainers.end()) + throw std::logic_error("invalid local index type"); - return iter->second->getRecord (index.first); + return iter->second->getRecord(index.first); } -void CSMWorld::RefIdData::appendRecord (UniversalId::Type type, const std::string& id, bool base) +void CSMWorld::RefIdData::appendRecord(UniversalId::Type type, const std::string& id, bool base) { - std::map::iterator iter = - mRecordContainers.find (type); + std::map::iterator iter = mRecordContainers.find(type); - if (iter==mRecordContainers.end()) - throw std::logic_error ("invalid local index type"); + if (iter == mRecordContainers.end()) + throw std::logic_error("invalid local index type"); - iter->second->appendRecord (id, base); + iter->second->appendRecord(id, base); - mIndex.insert (std::make_pair (Misc::StringUtils::lowerCase (id), - LocalIndex (iter->second->getSize()-1, type))); + mIndex.insert(std::make_pair(Misc::StringUtils::lowerCase(id), LocalIndex(iter->second->getSize() - 1, type))); } -int CSMWorld::RefIdData::getAppendIndex (UniversalId::Type type) const +int CSMWorld::RefIdData::getAppendIndex(UniversalId::Type type) const { int index = 0; - for (std::map::const_iterator iter ( - mRecordContainers.begin()); iter!=mRecordContainers.end(); ++iter) + for (std::map::const_iterator iter(mRecordContainers.begin()); + iter != mRecordContainers.end(); ++iter) { index += iter->second->getSize(); - if (type==iter->first) + if (type == iter->first) break; } return index; } -void CSMWorld::RefIdData::load (ESM::ESMReader& reader, bool base, CSMWorld::UniversalId::Type type) +void CSMWorld::RefIdData::load(ESM::ESMReader& reader, bool base, CSMWorld::UniversalId::Type type) { - std::map::iterator found = - mRecordContainers.find (type); + std::map::iterator found = mRecordContainers.find(type); if (found == mRecordContainers.end()) - throw std::logic_error ("Invalid Referenceable ID type"); + throw std::logic_error("Invalid Referenceable ID type"); int index = found->second->load(reader, base); if (index != -1) @@ -229,20 +239,19 @@ void CSMWorld::RefIdData::load (ESM::ESMReader& reader, bool base, CSMWorld::Uni } } -void CSMWorld::RefIdData::erase (const LocalIndex& index, int count) +void CSMWorld::RefIdData::erase(const LocalIndex& index, int count) { - std::map::iterator iter = - mRecordContainers.find (index.second); - if (iter==mRecordContainers.end()) - throw std::logic_error ("invalid local index type"); + std::map::iterator iter = mRecordContainers.find(index.second); + if (iter == mRecordContainers.end()) + throw std::logic_error("invalid local index type"); - for (int i=index.first; i::iterator result = - mIndex.find (Misc::StringUtils::lowerCase (iter->second->getId (i))); + std::map::iterator result + = mIndex.find(Misc::StringUtils::lowerCase(iter->second->getId(i))); - if (result!=mIndex.end()) - mIndex.erase (result); + if (result != mIndex.end()) + mIndex.erase(result); } // Adjust the local indexes to avoid gaps between them after removal of records @@ -250,8 +259,8 @@ void CSMWorld::RefIdData::erase (const LocalIndex& index, int count) int recordCount = iter->second->getSize(); while (recordIndex < recordCount) { - std::map::iterator recordIndexFound = - mIndex.find(Misc::StringUtils::lowerCase(iter->second->getId(recordIndex))); + std::map::iterator recordIndexFound + = mIndex.find(Misc::StringUtils::lowerCase(iter->second->getId(recordIndex))); if (recordIndexFound != mIndex.end()) { recordIndexFound->second.first -= count; @@ -259,7 +268,7 @@ void CSMWorld::RefIdData::erase (const LocalIndex& index, int count) ++recordIndex; } - iter->second->erase (index.first, count); + iter->second->erase(index.first, count); } int CSMWorld::RefIdData::getSize() const @@ -267,162 +276,159 @@ int CSMWorld::RefIdData::getSize() const return mIndex.size(); } -std::vector CSMWorld::RefIdData::getIds (bool listDeleted) const +std::vector CSMWorld::RefIdData::getIds(bool listDeleted) const { std::vector ids; - for (std::map::const_iterator iter (mIndex.begin()); iter!=mIndex.end(); - ++iter) + for (std::map::const_iterator iter(mIndex.begin()); iter != mIndex.end(); ++iter) { - if (listDeleted || !getRecord (iter->second).isDeleted()) + if (listDeleted || !getRecord(iter->second).isDeleted()) { - std::map::const_iterator container = - mRecordContainers.find (iter->second.second); + std::map::const_iterator container + = mRecordContainers.find(iter->second.second); - if (container==mRecordContainers.end()) - throw std::logic_error ("Invalid referenceable ID type"); + if (container == mRecordContainers.end()) + throw std::logic_error("Invalid referenceable ID type"); - ids.push_back (container->second->getId (iter->second.first)); + ids.push_back(container->second->getId(iter->second.first)); } } return ids; } -void CSMWorld::RefIdData::save (int index, ESM::ESMWriter& writer) const +void CSMWorld::RefIdData::save(int index, ESM::ESMWriter& writer) const { - LocalIndex localIndex = globalToLocalIndex (index); + LocalIndex localIndex = globalToLocalIndex(index); - std::map::const_iterator iter = - mRecordContainers.find (localIndex.second); + std::map::const_iterator iter + = mRecordContainers.find(localIndex.second); - if (iter==mRecordContainers.end()) - throw std::logic_error ("invalid local index type"); + if (iter == mRecordContainers.end()) + throw std::logic_error("invalid local index type"); - iter->second->save (localIndex.first, writer); + iter->second->save(localIndex.first, writer); } -const CSMWorld::RefIdDataContainer< ESM::Book >& CSMWorld::RefIdData::getBooks() const +const CSMWorld::RefIdDataContainer& CSMWorld::RefIdData::getBooks() const { return mBooks; } -const CSMWorld::RefIdDataContainer< ESM::Activator >& CSMWorld::RefIdData::getActivators() const +const CSMWorld::RefIdDataContainer& CSMWorld::RefIdData::getActivators() const { return mActivators; } -const CSMWorld::RefIdDataContainer< ESM::Potion >& CSMWorld::RefIdData::getPotions() const +const CSMWorld::RefIdDataContainer& CSMWorld::RefIdData::getPotions() const { return mPotions; } -const CSMWorld::RefIdDataContainer< ESM::Apparatus >& CSMWorld::RefIdData::getApparati() const +const CSMWorld::RefIdDataContainer& CSMWorld::RefIdData::getApparati() const { return mApparati; } -const CSMWorld::RefIdDataContainer< ESM::Armor >& CSMWorld::RefIdData::getArmors() const +const CSMWorld::RefIdDataContainer& CSMWorld::RefIdData::getArmors() const { return mArmors; } -const CSMWorld::RefIdDataContainer< ESM::Clothing >& CSMWorld::RefIdData::getClothing() const +const CSMWorld::RefIdDataContainer& CSMWorld::RefIdData::getClothing() const { return mClothing; } -const CSMWorld::RefIdDataContainer< ESM::Container >& CSMWorld::RefIdData::getContainers() const +const CSMWorld::RefIdDataContainer& CSMWorld::RefIdData::getContainers() const { return mContainers; } -const CSMWorld::RefIdDataContainer< ESM::Creature >& CSMWorld::RefIdData::getCreatures() const +const CSMWorld::RefIdDataContainer& CSMWorld::RefIdData::getCreatures() const { return mCreatures; } -const CSMWorld::RefIdDataContainer< ESM::Door >& CSMWorld::RefIdData::getDoors() const +const CSMWorld::RefIdDataContainer& CSMWorld::RefIdData::getDoors() const { return mDoors; } -const CSMWorld::RefIdDataContainer< ESM::Ingredient >& CSMWorld::RefIdData::getIngredients() const +const CSMWorld::RefIdDataContainer& CSMWorld::RefIdData::getIngredients() const { return mIngredients; } -const CSMWorld::RefIdDataContainer< ESM::CreatureLevList >& CSMWorld::RefIdData::getCreatureLevelledLists() const +const CSMWorld::RefIdDataContainer& CSMWorld::RefIdData::getCreatureLevelledLists() const { return mCreatureLevelledLists; } -const CSMWorld::RefIdDataContainer< ESM::ItemLevList >& CSMWorld::RefIdData::getItemLevelledList() const +const CSMWorld::RefIdDataContainer& CSMWorld::RefIdData::getItemLevelledList() const { return mItemLevelledLists; } -const CSMWorld::RefIdDataContainer< ESM::Light >& CSMWorld::RefIdData::getLights() const +const CSMWorld::RefIdDataContainer& CSMWorld::RefIdData::getLights() const { return mLights; } -const CSMWorld::RefIdDataContainer< ESM::Lockpick >& CSMWorld::RefIdData::getLocpicks() const +const CSMWorld::RefIdDataContainer& CSMWorld::RefIdData::getLocpicks() const { return mLockpicks; } -const CSMWorld::RefIdDataContainer< ESM::Miscellaneous >& CSMWorld::RefIdData::getMiscellaneous() const +const CSMWorld::RefIdDataContainer& CSMWorld::RefIdData::getMiscellaneous() const { return mMiscellaneous; } -const CSMWorld::RefIdDataContainer< ESM::NPC >& CSMWorld::RefIdData::getNPCs() const +const CSMWorld::RefIdDataContainer& CSMWorld::RefIdData::getNPCs() const { return mNpcs; } -const CSMWorld::RefIdDataContainer< ESM::Weapon >& CSMWorld::RefIdData::getWeapons() const +const CSMWorld::RefIdDataContainer& CSMWorld::RefIdData::getWeapons() const { return mWeapons; } -const CSMWorld::RefIdDataContainer< ESM::Probe >& CSMWorld::RefIdData::getProbes() const +const CSMWorld::RefIdDataContainer& CSMWorld::RefIdData::getProbes() const { return mProbes; } -const CSMWorld::RefIdDataContainer< ESM::Repair >& CSMWorld::RefIdData::getRepairs() const +const CSMWorld::RefIdDataContainer& CSMWorld::RefIdData::getRepairs() const { return mRepairs; } -const CSMWorld::RefIdDataContainer< ESM::Static >& CSMWorld::RefIdData::getStatics() const +const CSMWorld::RefIdDataContainer& CSMWorld::RefIdData::getStatics() const { return mStatics; } -void CSMWorld::RefIdData::insertRecord (std::unique_ptr record, CSMWorld::UniversalId::Type type, const std::string& id) +void CSMWorld::RefIdData::insertRecord( + std::unique_ptr record, CSMWorld::UniversalId::Type type, const std::string& id) { - std::map::iterator iter = - mRecordContainers.find (type); + std::map::iterator iter = mRecordContainers.find(type); - if (iter==mRecordContainers.end()) - throw std::logic_error ("invalid local index type"); + if (iter == mRecordContainers.end()) + throw std::logic_error("invalid local index type"); iter->second->insertRecord(std::move(record)); - mIndex.insert (std::make_pair (Misc::StringUtils::lowerCase (id), - LocalIndex (iter->second->getSize()-1, type))); + mIndex.insert(std::make_pair(Misc::StringUtils::lowerCase(id), LocalIndex(iter->second->getSize() - 1, type))); } -void CSMWorld::RefIdData::copyTo (int index, RefIdData& target) const +void CSMWorld::RefIdData::copyTo(int index, RefIdData& target) const { - LocalIndex localIndex = globalToLocalIndex (index); + LocalIndex localIndex = globalToLocalIndex(index); - RefIdDataContainerBase *source = mRecordContainers.find (localIndex.second)->second; + RefIdDataContainerBase* source = mRecordContainers.find(localIndex.second)->second; - target.insertRecord(source->getRecord(localIndex.first).modifiedCopy(), - localIndex.second, - source->getId(localIndex.first)); + target.insertRecord( + source->getRecord(localIndex.first).modifiedCopy(), localIndex.second, source->getId(localIndex.first)); } diff --git a/apps/opencs/model/world/refiddata.hpp b/apps/opencs/model/world/refiddata.hpp index 85889f8d81..0df62a8041 100644 --- a/apps/opencs/model/world/refiddata.hpp +++ b/apps/opencs/model/world/refiddata.hpp @@ -1,12 +1,13 @@ #ifndef CSM_WOLRD_REFIDDATA_H #define CSM_WOLRD_REFIDDATA_H -#include +#include #include #include -#include #include +#include +#include #include #include #include @@ -20,13 +21,12 @@ #include #include #include +#include +#include #include #include #include #include -#include -#include -#include #include @@ -46,54 +46,54 @@ namespace CSMWorld virtual int getSize() const = 0; - virtual const RecordBase& getRecord (int index) const = 0; + virtual const RecordBase& getRecord(int index) const = 0; - virtual RecordBase& getRecord (int index)= 0; + virtual RecordBase& getRecord(int index) = 0; - virtual unsigned int getRecordFlags (int index) const = 0; + virtual unsigned int getRecordFlags(int index) const = 0; - virtual void appendRecord (const std::string& id, bool base) = 0; + virtual void appendRecord(const std::string& id, bool base) = 0; - virtual void insertRecord (std::unique_ptr record) = 0; + virtual void insertRecord(std::unique_ptr record) = 0; - virtual int load (ESM::ESMReader& reader, bool base) = 0; + virtual int load(ESM::ESMReader& reader, bool base) = 0; ///< \return index of a loaded record or -1 if no record was loaded - virtual void erase (int index, int count) = 0; + virtual void erase(int index, int count) = 0; - virtual std::string getId (int index) const = 0; + virtual std::string getId(int index) const = 0; - virtual void save (int index, ESM::ESMWriter& writer) const = 0; + virtual void save(int index, ESM::ESMWriter& writer) const = 0; }; - template + template struct RefIdDataContainer : public RefIdDataContainerBase { - std::vector > > mContainer; + std::vector>> mContainer; int getSize() const override; - const RecordBase& getRecord (int index) const override; + const RecordBase& getRecord(int index) const override; - RecordBase& getRecord (int index) override; + RecordBase& getRecord(int index) override; - unsigned int getRecordFlags (int index) const override; + unsigned int getRecordFlags(int index) const override; - void appendRecord (const std::string& id, bool base) override; + void appendRecord(const std::string& id, bool base) override; - void insertRecord (std::unique_ptr record) override; + void insertRecord(std::unique_ptr record) override; - int load (ESM::ESMReader& reader, bool base) override; + int load(ESM::ESMReader& reader, bool base) override; ///< \return index of a loaded record or -1 if no record was loaded - void erase (int index, int count) override; + void erase(int index, int count) override; - std::string getId (int index) const override; + std::string getId(int index) const override; - void save (int index, ESM::ESMWriter& writer) const override; + void save(int index, ESM::ESMWriter& writer) const override; }; - template + template void RefIdDataContainer::insertRecord(std::unique_ptr record) { assert(record != nullptr); @@ -103,32 +103,32 @@ namespace CSMWorld mContainer.push_back(std::move(typedRecord)); } - template + template int RefIdDataContainer::getSize() const { - return static_cast (mContainer.size()); + return static_cast(mContainer.size()); } - template - const RecordBase& RefIdDataContainer::getRecord (int index) const + template + const RecordBase& RefIdDataContainer::getRecord(int index) const { - return *mContainer.at (index); + return *mContainer.at(index); } - template - RecordBase& RefIdDataContainer::getRecord (int index) + template + RecordBase& RefIdDataContainer::getRecord(int index) { - return *mContainer.at (index); + return *mContainer.at(index); } - template - unsigned int RefIdDataContainer::getRecordFlags (int index) const + template + unsigned int RefIdDataContainer::getRecordFlags(int index) const { - return mContainer.at (index)->get().mRecordFlags; + return mContainer.at(index)->get().mRecordFlags; } - template - void RefIdDataContainer::appendRecord (const std::string& id, bool base) + template + void RefIdDataContainer::appendRecord(const std::string& id, bool base) { auto record = std::make_unique>(); @@ -138,11 +138,11 @@ namespace CSMWorld record->mModified.mId = id; (base ? record->mBase : record->mModified).blank(); - mContainer.push_back (std::move(record)); + mContainer.push_back(std::move(record)); } - template - int RefIdDataContainer::load (ESM::ESMReader& reader, bool base) + template + int RefIdDataContainer::load(ESM::ESMReader& reader, bool base) { RecordT record; bool isDeleted = false; @@ -202,23 +202,23 @@ namespace CSMWorld return index; } - template - void RefIdDataContainer::erase (int index, int count) + template + void RefIdDataContainer::erase(int index, int count) { - if (index<0 || index+count>getSize()) - throw std::runtime_error ("invalid RefIdDataContainer index"); + if (index < 0 || index + count > getSize()) + throw std::runtime_error("invalid RefIdDataContainer index"); - mContainer.erase (mContainer.begin()+index, mContainer.begin()+index+count); + mContainer.erase(mContainer.begin() + index, mContainer.begin() + index + count); } - template - std::string RefIdDataContainer::getId (int index) const + template + std::string RefIdDataContainer::getId(int index) const { - return mContainer.at (index)->get().mId; + return mContainer.at(index)->get().mId; } - template - void RefIdDataContainer::save (int index, ESM::ESMWriter& writer) const + template + void RefIdDataContainer::save(int index, ESM::ESMWriter& writer) const { const Record& record = *mContainer.at(index); @@ -231,104 +231,99 @@ namespace CSMWorld } } - class RefIdData { - public: - - typedef std::pair LocalIndex; - - private: - - RefIdDataContainer mActivators; - RefIdDataContainer mPotions; - RefIdDataContainer mApparati; - RefIdDataContainer mArmors; - RefIdDataContainer mBooks; - RefIdDataContainer mClothing; - RefIdDataContainer mContainers; - RefIdDataContainer mCreatures; - RefIdDataContainer mDoors; - RefIdDataContainer mIngredients; - RefIdDataContainer mCreatureLevelledLists; - RefIdDataContainer mItemLevelledLists; - RefIdDataContainer mLights; - RefIdDataContainer mLockpicks; - RefIdDataContainer mMiscellaneous; - RefIdDataContainer mNpcs; - RefIdDataContainer mProbes; - RefIdDataContainer mRepairs; - RefIdDataContainer mStatics; - RefIdDataContainer mWeapons; + public: + typedef std::pair LocalIndex; - std::map mIndex; + private: + RefIdDataContainer mActivators; + RefIdDataContainer mPotions; + RefIdDataContainer mApparati; + RefIdDataContainer mArmors; + RefIdDataContainer mBooks; + RefIdDataContainer mClothing; + RefIdDataContainer mContainers; + RefIdDataContainer mCreatures; + RefIdDataContainer mDoors; + RefIdDataContainer mIngredients; + RefIdDataContainer mCreatureLevelledLists; + RefIdDataContainer mItemLevelledLists; + RefIdDataContainer mLights; + RefIdDataContainer mLockpicks; + RefIdDataContainer mMiscellaneous; + RefIdDataContainer mNpcs; + RefIdDataContainer mProbes; + RefIdDataContainer mRepairs; + RefIdDataContainer mStatics; + RefIdDataContainer mWeapons; - std::map mRecordContainers; + std::map mIndex; - void erase (const LocalIndex& index, int count); - ///< Must not spill over into another type. + std::map mRecordContainers; - std::string getRecordId(const LocalIndex &index) const; + void erase(const LocalIndex& index, int count); + ///< Must not spill over into another type. - public: + std::string getRecordId(const LocalIndex& index) const; - RefIdData(); + public: + RefIdData(); - LocalIndex globalToLocalIndex (int index) const; + LocalIndex globalToLocalIndex(int index) const; - int localToGlobalIndex (const LocalIndex& index) const; + int localToGlobalIndex(const LocalIndex& index) const; - LocalIndex searchId(std::string_view id) const; + LocalIndex searchId(std::string_view id) const; - void erase (int index, int count); + void erase(int index, int count); - void insertRecord (std::unique_ptr record, CSMWorld::UniversalId::Type type, - const std::string& id); + void insertRecord(std::unique_ptr record, CSMWorld::UniversalId::Type type, const std::string& id); - const RecordBase& getRecord (const LocalIndex& index) const; + const RecordBase& getRecord(const LocalIndex& index) const; - RecordBase& getRecord (const LocalIndex& index); + RecordBase& getRecord(const LocalIndex& index); - unsigned int getRecordFlags(const std::string& id) const; + unsigned int getRecordFlags(const std::string& id) const; - void appendRecord (UniversalId::Type type, const std::string& id, bool base); + void appendRecord(UniversalId::Type type, const std::string& id, bool base); - int getAppendIndex (UniversalId::Type type) const; + int getAppendIndex(UniversalId::Type type) const; - void load (ESM::ESMReader& reader, bool base, UniversalId::Type type); + void load(ESM::ESMReader& reader, bool base, UniversalId::Type type); - int getSize() const; + int getSize() const; - std::vector getIds (bool listDeleted = true) const; - ///< Return a sorted collection of all IDs - /// - /// \param listDeleted include deleted record in the list + std::vector getIds(bool listDeleted = true) const; + ///< Return a sorted collection of all IDs + /// + /// \param listDeleted include deleted record in the list - void save (int index, ESM::ESMWriter& writer) const; + void save(int index, ESM::ESMWriter& writer) const; - //RECORD CONTAINERS ACCESS METHODS - const RefIdDataContainer& getBooks() const; - const RefIdDataContainer& getActivators() const; - const RefIdDataContainer& getPotions() const; - const RefIdDataContainer& getApparati() const; - const RefIdDataContainer& getArmors() const; - const RefIdDataContainer& getClothing() const; - const RefIdDataContainer& getContainers() const; - const RefIdDataContainer& getCreatures() const; - const RefIdDataContainer& getDoors() const; - const RefIdDataContainer& getIngredients() const; - const RefIdDataContainer& getCreatureLevelledLists() const; - const RefIdDataContainer& getItemLevelledList() const; - const RefIdDataContainer& getLights() const; - const RefIdDataContainer& getLocpicks() const; - const RefIdDataContainer& getMiscellaneous() const; - const RefIdDataContainer& getNPCs() const; - const RefIdDataContainer& getWeapons() const; - const RefIdDataContainer& getProbes() const; - const RefIdDataContainer& getRepairs() const; - const RefIdDataContainer& getStatics() const; + // RECORD CONTAINERS ACCESS METHODS + const RefIdDataContainer& getBooks() const; + const RefIdDataContainer& getActivators() const; + const RefIdDataContainer& getPotions() const; + const RefIdDataContainer& getApparati() const; + const RefIdDataContainer& getArmors() const; + const RefIdDataContainer& getClothing() const; + const RefIdDataContainer& getContainers() const; + const RefIdDataContainer& getCreatures() const; + const RefIdDataContainer& getDoors() const; + const RefIdDataContainer& getIngredients() const; + const RefIdDataContainer& getCreatureLevelledLists() const; + const RefIdDataContainer& getItemLevelledList() const; + const RefIdDataContainer& getLights() const; + const RefIdDataContainer& getLocpicks() const; + const RefIdDataContainer& getMiscellaneous() const; + const RefIdDataContainer& getNPCs() const; + const RefIdDataContainer& getWeapons() const; + const RefIdDataContainer& getProbes() const; + const RefIdDataContainer& getRepairs() const; + const RefIdDataContainer& getStatics() const; - void copyTo (int index, RefIdData& target) const; + void copyTo(int index, RefIdData& target) const; }; } diff --git a/apps/opencs/model/world/regionmap.cpp b/apps/opencs/model/world/regionmap.cpp index 910572af91..383394bece 100644 --- a/apps/opencs/model/world/regionmap.cpp +++ b/apps/opencs/model/world/regionmap.cpp @@ -1,7 +1,7 @@ #include "regionmap.hpp" -#include #include +#include #include #include @@ -11,14 +11,17 @@ #include "data.hpp" #include "universalid.hpp" -CSMWorld::RegionMap::CellDescription::CellDescription() : mDeleted (false) {} +CSMWorld::RegionMap::CellDescription::CellDescription() + : mDeleted(false) +{ +} -CSMWorld::RegionMap::CellDescription::CellDescription (const Record& cell) +CSMWorld::RegionMap::CellDescription::CellDescription(const Record& cell) { const Cell& cell2 = cell.get(); if (!cell2.isExterior()) - throw std::logic_error ("Interior cell in region map"); + throw std::logic_error("Interior cell in region map"); mDeleted = cell.isDeleted(); @@ -26,28 +29,28 @@ CSMWorld::RegionMap::CellDescription::CellDescription (const Record& cell) mName = cell2.mName; } -CSMWorld::CellCoordinates CSMWorld::RegionMap::getIndex (const QModelIndex& index) const +CSMWorld::CellCoordinates CSMWorld::RegionMap::getIndex(const QModelIndex& index) const { - return mMin.move (index.column(), mMax.getY()-mMin.getY() - index.row()-1); + return mMin.move(index.column(), mMax.getY() - mMin.getY() - index.row() - 1); } -QModelIndex CSMWorld::RegionMap::getIndex (const CellCoordinates& index) const +QModelIndex CSMWorld::RegionMap::getIndex(const CellCoordinates& index) const { // I hate you, Qt API naming scheme! - return QAbstractTableModel::index (mMax.getY()-mMin.getY() - (index.getY()-mMin.getY())-1, - index.getX()-mMin.getX()); + return QAbstractTableModel::index( + mMax.getY() - mMin.getY() - (index.getY() - mMin.getY()) - 1, index.getX() - mMin.getX()); } -CSMWorld::CellCoordinates CSMWorld::RegionMap::getIndex (const Cell& cell) const +CSMWorld::CellCoordinates CSMWorld::RegionMap::getIndex(const Cell& cell) const { - std::istringstream stream (cell.mId); + std::istringstream stream(cell.mId); char ignore; int x = 0; int y = 0; stream >> ignore >> x >> y; - return CellCoordinates (x, y); + return CellCoordinates(x, y); } void CSMWorld::RegionMap::buildRegions() @@ -56,13 +59,12 @@ void CSMWorld::RegionMap::buildRegions() int size = regions.getSize(); - for (int i=0; i& region = regions.getRecord (i); + const Record& region = regions.getRecord(i); if (!region.isDeleted()) - mColours.insert (std::make_pair (Misc::StringUtils::lowerCase (region.get().mId), - region.get().mMapColor)); + mColours.insert(std::make_pair(Misc::StringUtils::lowerCase(region.get().mId), region.get().mMapColor)); } } @@ -72,19 +74,19 @@ void CSMWorld::RegionMap::buildMap() int size = cells.getSize(); - for (int i=0; i& cell = cells.getRecord (i); + const Record& cell = cells.getRecord(i); const Cell& cell2 = cell.get(); if (cell2.isExterior()) { - CellDescription description (cell); + CellDescription description(cell); - CellCoordinates index = getIndex (cell2); + CellCoordinates index = getIndex(cell2); - mMap.insert (std::make_pair (index, description)); + mMap.insert(std::make_pair(index, description)); } } @@ -94,11 +96,11 @@ void CSMWorld::RegionMap::buildMap() mMax = mapSize.second; } -void CSMWorld::RegionMap::addCell (const CellCoordinates& index, const CellDescription& description) +void CSMWorld::RegionMap::addCell(const CellCoordinates& index, const CellDescription& description) { - std::map::iterator cell = mMap.find (index); + std::map::iterator cell = mMap.find(index); - if (cell!=mMap.end()) + if (cell != mMap.end()) { cell->second = description; } @@ -106,84 +108,83 @@ void CSMWorld::RegionMap::addCell (const CellCoordinates& index, const CellDescr { updateSize(); - mMap.insert (std::make_pair (index, description)); + mMap.insert(std::make_pair(index, description)); } - QModelIndex index2 = getIndex (index); + QModelIndex index2 = getIndex(index); - dataChanged (index2, index2); + dataChanged(index2, index2); } -void CSMWorld::RegionMap::addCells (int start, int end) +void CSMWorld::RegionMap::addCells(int start, int end) { const IdCollection& cells = mData.getCells(); - for (int i=start; i<=end; ++i) + for (int i = start; i <= end; ++i) { - const Record& cell = cells.getRecord (i); + const Record& cell = cells.getRecord(i); const Cell& cell2 = cell.get(); if (cell2.isExterior()) { - CellCoordinates index = getIndex (cell2); + CellCoordinates index = getIndex(cell2); - CellDescription description (cell); + CellDescription description(cell); - addCell (index, description); + addCell(index, description); } } } -void CSMWorld::RegionMap::removeCell (const CellCoordinates& index) +void CSMWorld::RegionMap::removeCell(const CellCoordinates& index) { - std::map::iterator cell = mMap.find (index); + std::map::iterator cell = mMap.find(index); - if (cell!=mMap.end()) + if (cell != mMap.end()) { - mMap.erase (cell); + mMap.erase(cell); - QModelIndex index2 = getIndex (index); + QModelIndex index2 = getIndex(index); - dataChanged (index2, index2); + dataChanged(index2, index2); updateSize(); } } -void CSMWorld::RegionMap::addRegion (const std::string& region, unsigned int colour) +void CSMWorld::RegionMap::addRegion(const std::string& region, unsigned int colour) { - mColours[Misc::StringUtils::lowerCase (region)] = colour; + mColours[Misc::StringUtils::lowerCase(region)] = colour; } -void CSMWorld::RegionMap::removeRegion (const std::string& region) +void CSMWorld::RegionMap::removeRegion(const std::string& region) { - std::map::iterator iter ( - mColours.find (Misc::StringUtils::lowerCase (region))); + std::map::iterator iter(mColours.find(Misc::StringUtils::lowerCase(region))); - if (iter!=mColours.end()) - mColours.erase (iter); + if (iter != mColours.end()) + mColours.erase(iter); } -void CSMWorld::RegionMap::updateRegions (const std::vector& regions) +void CSMWorld::RegionMap::updateRegions(const std::vector& regions) { - std::vector regions2 (regions); + std::vector regions2(regions); - for (auto& region2 : regions2) { + for (auto& region2 : regions2) + { Misc::StringUtils::lowerCaseInPlace(region2); } - std::sort (regions2.begin(), regions2.end()); + std::sort(regions2.begin(), regions2.end()); - for (std::map::const_iterator iter (mMap.begin()); - iter!=mMap.end(); ++iter) + for (std::map::const_iterator iter(mMap.begin()); iter != mMap.end(); ++iter) { - if (!iter->second.mRegion.empty() && - std::find (regions2.begin(), regions2.end(), - Misc::StringUtils::lowerCase (iter->second.mRegion))!=regions2.end()) + if (!iter->second.mRegion.empty() + && std::find(regions2.begin(), regions2.end(), Misc::StringUtils::lowerCase(iter->second.mRegion)) + != regions2.end()) { - QModelIndex index = getIndex (iter->first); + QModelIndex index = getIndex(iter->first); - dataChanged (index, index); + dataChanged(index, index); } } } @@ -194,15 +195,15 @@ void CSMWorld::RegionMap::updateSize() if (int diff = size.first.getX() - mMin.getX()) { - beginInsertColumns (QModelIndex(), 0, std::abs (diff)-1); - mMin = CellCoordinates (size.first.getX(), mMin.getY()); + beginInsertColumns(QModelIndex(), 0, std::abs(diff) - 1); + mMin = CellCoordinates(size.first.getX(), mMin.getY()); endInsertColumns(); } if (int diff = size.first.getY() - mMin.getY()) { - beginInsertRows (QModelIndex(), 0, std::abs (diff)-1); - mMin = CellCoordinates (mMin.getX(), size.first.getY()); + beginInsertRows(QModelIndex(), 0, std::abs(diff) - 1); + mMin = CellCoordinates(mMin.getX(), size.first.getY()); endInsertRows(); } @@ -210,12 +211,12 @@ void CSMWorld::RegionMap::updateSize() { int columns = columnCount(); - if (diff>0) - beginInsertColumns (QModelIndex(), columns, columns+diff-1); + if (diff > 0) + beginInsertColumns(QModelIndex(), columns, columns + diff - 1); else - beginRemoveColumns (QModelIndex(), columns+diff, columns-1); + beginRemoveColumns(QModelIndex(), columns + diff, columns - 1); - mMax = CellCoordinates (size.second.getX(), mMax.getY()); + mMax = CellCoordinates(size.second.getX(), mMax.getY()); endInsertColumns(); } @@ -223,12 +224,12 @@ void CSMWorld::RegionMap::updateSize() { int rows = rowCount(); - if (diff>0) - beginInsertRows (QModelIndex(), rows, rows+diff-1); + if (diff > 0) + beginInsertRows(QModelIndex(), rows, rows + diff - 1); else - beginRemoveRows (QModelIndex(), rows+diff, rows-1); + beginRemoveRows(QModelIndex(), rows + diff, rows - 1); - mMax = CellCoordinates (mMax.getX(), size.second.getY()); + mMax = CellCoordinates(mMax.getX(), size.second.getY()); endInsertRows(); } } @@ -239,128 +240,119 @@ std::pair CSMWorld::Region int size = cells.getSize(); - CellCoordinates min (0, 0); - CellCoordinates max (0, 0); + CellCoordinates min(0, 0); + CellCoordinates max(0, 0); - for (int i=0; i& cell = cells.getRecord (i); + const Record& cell = cells.getRecord(i); const Cell& cell2 = cell.get(); if (cell2.isExterior()) { - CellCoordinates index = getIndex (cell2); + CellCoordinates index = getIndex(cell2); - if (min==max) + if (min == max) { min = index; - max = min.move (1, 1); + max = min.move(1, 1); } else { - if (index.getX()=max.getX()) - max = CellCoordinates (index.getX()+1, max.getY()); - - if (index.getY()=max.getY()) - max = CellCoordinates (max.getX(), index.getY() + 1); + if (index.getX() < min.getX()) + min = CellCoordinates(index.getX(), min.getY()); + else if (index.getX() >= max.getX()) + max = CellCoordinates(index.getX() + 1, max.getY()); + + if (index.getY() < min.getY()) + min = CellCoordinates(min.getX(), index.getY()); + else if (index.getY() >= max.getY()) + max = CellCoordinates(max.getX(), index.getY() + 1); } } } - return std::make_pair (min, max); + return std::make_pair(min, max); } -CSMWorld::RegionMap::RegionMap (Data& data) : mData (data) +CSMWorld::RegionMap::RegionMap(Data& data) + : mData(data) { buildRegions(); buildMap(); - QAbstractItemModel *regions = data.getTableModel (UniversalId (UniversalId::Type_Regions)); + QAbstractItemModel* regions = data.getTableModel(UniversalId(UniversalId::Type_Regions)); - connect (regions, &QAbstractItemModel::rowsAboutToBeRemoved, - this, &RegionMap::regionsAboutToBeRemoved); - connect (regions, &QAbstractItemModel::rowsInserted, - this, &RegionMap::regionsInserted); - connect (regions, &QAbstractItemModel::dataChanged, - this, &RegionMap::regionsChanged); + connect(regions, &QAbstractItemModel::rowsAboutToBeRemoved, this, &RegionMap::regionsAboutToBeRemoved); + connect(regions, &QAbstractItemModel::rowsInserted, this, &RegionMap::regionsInserted); + connect(regions, &QAbstractItemModel::dataChanged, this, &RegionMap::regionsChanged); - QAbstractItemModel *cells = data.getTableModel (UniversalId (UniversalId::Type_Cells)); + QAbstractItemModel* cells = data.getTableModel(UniversalId(UniversalId::Type_Cells)); - connect (cells, &QAbstractItemModel::rowsAboutToBeRemoved, - this, &RegionMap::cellsAboutToBeRemoved); - connect (cells, &QAbstractItemModel::rowsInserted, - this, &RegionMap::cellsInserted); - connect (cells, &QAbstractItemModel::dataChanged, - this, &RegionMap::cellsChanged); + connect(cells, &QAbstractItemModel::rowsAboutToBeRemoved, this, &RegionMap::cellsAboutToBeRemoved); + connect(cells, &QAbstractItemModel::rowsInserted, this, &RegionMap::cellsInserted); + connect(cells, &QAbstractItemModel::dataChanged, this, &RegionMap::cellsChanged); } -int CSMWorld::RegionMap::rowCount (const QModelIndex& parent) const +int CSMWorld::RegionMap::rowCount(const QModelIndex& parent) const { if (parent.isValid()) return 0; - return mMax.getY()-mMin.getY(); + return mMax.getY() - mMin.getY(); } -int CSMWorld::RegionMap::columnCount (const QModelIndex& parent) const +int CSMWorld::RegionMap::columnCount(const QModelIndex& parent) const { if (parent.isValid()) return 0; - return mMax.getX()-mMin.getX(); + return mMax.getX() - mMin.getX(); } -QVariant CSMWorld::RegionMap::data (const QModelIndex& index, int role) const +QVariant CSMWorld::RegionMap::data(const QModelIndex& index, int role) const { - if (role==Qt::SizeHintRole) - return QSize (16, 16); + if (role == Qt::SizeHintRole) + return QSize(16, 16); - if (role==Qt::BackgroundRole) + if (role == Qt::BackgroundRole) { /// \todo GUI class in non-GUI code. Needs to be addressed eventually. - std::map::const_iterator cell = - mMap.find (getIndex (index)); + std::map::const_iterator cell = mMap.find(getIndex(index)); - if (cell!=mMap.end()) + if (cell != mMap.end()) { if (cell->second.mDeleted) - return QBrush (Qt::red, Qt::DiagCrossPattern); + return QBrush(Qt::red, Qt::DiagCrossPattern); - std::map::const_iterator iter = - mColours.find (Misc::StringUtils::lowerCase (cell->second.mRegion)); + std::map::const_iterator iter + = mColours.find(Misc::StringUtils::lowerCase(cell->second.mRegion)); - if (iter!=mColours.end()) - return QBrush (QColor (iter->second & 0xff, - (iter->second >> 8) & 0xff, - (iter->second >> 16) & 0xff)); + if (iter != mColours.end()) + 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 + return QBrush(Qt::Dense6Pattern); // no region - return QBrush (Qt::red, Qt::Dense6Pattern); // invalid region + return QBrush(Qt::red, Qt::Dense6Pattern); // invalid region } - return QBrush (Qt::DiagCrossPattern); + return QBrush(Qt::DiagCrossPattern); } - if (role==Qt::ToolTipRole) + if (role == Qt::ToolTipRole) { - CellCoordinates cellIndex = getIndex (index); + CellCoordinates cellIndex = getIndex(index); std::ostringstream stream; stream << cellIndex; - std::map::const_iterator cell = - mMap.find (cellIndex); + std::map::const_iterator cell = mMap.find(cellIndex); - if (cell!=mMap.end()) + if (cell != mMap.end()) { if (!cell->second.mName.empty()) stream << " " << cell->second.mName; @@ -372,10 +364,10 @@ QVariant CSMWorld::RegionMap::data (const QModelIndex& index, int role) const { stream << "
"; - std::map::const_iterator iter = - mColours.find (Misc::StringUtils::lowerCase (cell->second.mRegion)); + std::map::const_iterator iter + = mColours.find(Misc::StringUtils::lowerCase(cell->second.mRegion)); - if (iter!=mColours.end()) + if (iter != mColours.end()) stream << cell->second.mRegion; else stream << "" << cell->second.mRegion << ""; @@ -384,78 +376,77 @@ QVariant CSMWorld::RegionMap::data (const QModelIndex& index, int role) const else stream << " (no cell)"; - return QString::fromUtf8 (stream.str().c_str()); + return QString::fromUtf8(stream.str().c_str()); } - if (role==Role_Region) + if (role == Role_Region) { - CellCoordinates cellIndex = getIndex (index); + CellCoordinates cellIndex = getIndex(index); - std::map::const_iterator cell = - mMap.find (cellIndex); + std::map::const_iterator cell = mMap.find(cellIndex); - if (cell!=mMap.end() && !cell->second.mRegion.empty()) - return QString::fromUtf8 (Misc::StringUtils::lowerCase (cell->second.mRegion).c_str()); + if (cell != mMap.end() && !cell->second.mRegion.empty()) + return QString::fromUtf8(Misc::StringUtils::lowerCase(cell->second.mRegion).c_str()); } - if (role==Role_CellId) + if (role == Role_CellId) { - CellCoordinates cellIndex = getIndex (index); + CellCoordinates cellIndex = getIndex(index); std::ostringstream stream; stream << "#" << cellIndex.getX() << " " << cellIndex.getY(); - return QString::fromUtf8 (stream.str().c_str()); + return QString::fromUtf8(stream.str().c_str()); } return QVariant(); } -Qt::ItemFlags CSMWorld::RegionMap::flags (const QModelIndex& index) const +Qt::ItemFlags CSMWorld::RegionMap::flags(const QModelIndex& index) const { return Qt::ItemIsSelectable | Qt::ItemIsEnabled; } -void CSMWorld::RegionMap::regionsAboutToBeRemoved (const QModelIndex& parent, int start, int end) +void CSMWorld::RegionMap::regionsAboutToBeRemoved(const QModelIndex& parent, int start, int end) { std::vector update; const IdCollection& regions = mData.getRegions(); - for (int i=start; i<=end; ++i) + for (int i = start; i <= end; ++i) { - const Record& region = regions.getRecord (i); + const Record& region = regions.getRecord(i); - update.push_back (region.get().mId); + update.push_back(region.get().mId); - removeRegion (region.get().mId); + removeRegion(region.get().mId); } - updateRegions (update); + updateRegions(update); } -void CSMWorld::RegionMap::regionsInserted (const QModelIndex& parent, int start, int end) +void CSMWorld::RegionMap::regionsInserted(const QModelIndex& parent, int start, int end) { std::vector update; const IdCollection& regions = mData.getRegions(); - for (int i=start; i<=end; ++i) + for (int i = start; i <= end; ++i) { - const Record& region = regions.getRecord (i); + const Record& region = regions.getRecord(i); if (!region.isDeleted()) { - update.push_back (region.get().mId); + update.push_back(region.get().mId); - addRegion (region.get().mId, region.get().mMapColor); + addRegion(region.get().mId, region.get().mMapColor); } } - updateRegions (update); + updateRegions(update); } -void CSMWorld::RegionMap::regionsChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) +void CSMWorld::RegionMap::regionsChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) { // Note: At this point an additional check could be inserted to see if there is any change to the // columns we are interested in. If not we can exit the function here and avoid all updating. @@ -464,45 +455,45 @@ void CSMWorld::RegionMap::regionsChanged (const QModelIndex& topLeft, const QMod const IdCollection& regions = mData.getRegions(); - for (int i=topLeft.row(); i<=bottomRight.column(); ++i) + for (int i = topLeft.row(); i <= bottomRight.column(); ++i) { - const Record& region = regions.getRecord (i); + const Record& region = regions.getRecord(i); - update.push_back (region.get().mId); + update.push_back(region.get().mId); if (!region.isDeleted()) - addRegion (region.get().mId, region.get().mMapColor); + addRegion(region.get().mId, region.get().mMapColor); else - removeRegion (region.get().mId); + removeRegion(region.get().mId); } - updateRegions (update); + updateRegions(update); } -void CSMWorld::RegionMap::cellsAboutToBeRemoved (const QModelIndex& parent, int start, int end) +void CSMWorld::RegionMap::cellsAboutToBeRemoved(const QModelIndex& parent, int start, int end) { const IdCollection& cells = mData.getCells(); - for (int i=start; i<=end; ++i) + for (int i = start; i <= end; ++i) { - const Record& cell = cells.getRecord (i); + const Record& cell = cells.getRecord(i); const Cell& cell2 = cell.get(); if (cell2.isExterior()) - removeCell (getIndex (cell2)); + removeCell(getIndex(cell2)); } } -void CSMWorld::RegionMap::cellsInserted (const QModelIndex& parent, int start, int end) +void CSMWorld::RegionMap::cellsInserted(const QModelIndex& parent, int start, int end) { - addCells (start, end); + addCells(start, end); } -void CSMWorld::RegionMap::cellsChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) +void CSMWorld::RegionMap::cellsChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) { // Note: At this point an additional check could be inserted to see if there is any change to the // columns we are interested in. If not we can exit the function here and avoid all updating. - addCells (topLeft.row(), bottomRight.row()); + addCells(topLeft.row(), bottomRight.row()); } diff --git a/apps/opencs/model/world/regionmap.hpp b/apps/opencs/model/world/regionmap.hpp index 1de7f1cdb9..5ccda4956c 100644 --- a/apps/opencs/model/world/regionmap.hpp +++ b/apps/opencs/model/world/regionmap.hpp @@ -7,9 +7,9 @@ #include -#include "record.hpp" #include "cell.hpp" #include "cellcoordinates.hpp" +#include "record.hpp" namespace CSMWorld { @@ -20,100 +20,97 @@ namespace CSMWorld /// This class does not holds any record data (other than for the purpose of buffering). class RegionMap : public QAbstractTableModel { - Q_OBJECT - - public: - - enum Role - { - Role_Region = Qt::UserRole, - Role_CellId = Qt::UserRole+1 - }; - - private: + Q_OBJECT - struct CellDescription - { - bool mDeleted; - std::string mRegion; - std::string mName; + public: + enum Role + { + Role_Region = Qt::UserRole, + Role_CellId = Qt::UserRole + 1 + }; - CellDescription(); + private: + struct CellDescription + { + bool mDeleted; + std::string mRegion; + std::string mName; - CellDescription (const Record& cell); - }; + CellDescription(); - Data& mData; - std::map mMap; - CellCoordinates mMin; ///< inclusive - CellCoordinates mMax; ///< exclusive - std::map mColours; ///< region ID, colour (RGBA) + CellDescription(const Record& cell); + }; - CellCoordinates getIndex (const QModelIndex& index) const; - ///< Translates a Qt model index into a cell index (which can contain negative components) + Data& mData; + std::map mMap; + CellCoordinates mMin; ///< inclusive + CellCoordinates mMax; ///< exclusive + std::map mColours; ///< region ID, colour (RGBA) - QModelIndex getIndex (const CellCoordinates& index) const; + CellCoordinates getIndex(const QModelIndex& index) const; + ///< Translates a Qt model index into a cell index (which can contain negative components) - CellCoordinates getIndex (const Cell& cell) const; + QModelIndex getIndex(const CellCoordinates& index) const; - void buildRegions(); + CellCoordinates getIndex(const Cell& cell) const; - void buildMap(); + void buildRegions(); - void addCell (const CellCoordinates& index, const CellDescription& description); - ///< May be called on a cell that is already in the map (in which case an update is - // performed) + void buildMap(); - void addCells (int start, int end); + void addCell(const CellCoordinates& index, const CellDescription& description); + ///< May be called on a cell that is already in the map (in which case an update is + // performed) - void removeCell (const CellCoordinates& index); - ///< May be called on a cell that is not in the map (in which case the call is ignored) + void addCells(int start, int end); - void addRegion (const std::string& region, unsigned int colour); - ///< May be called on a region that is already listed (in which case an update is - /// performed) - /// - /// \note This function does not update the region map. + void removeCell(const CellCoordinates& index); + ///< May be called on a cell that is not in the map (in which case the call is ignored) - void removeRegion (const std::string& region); - ///< May be called on a region that is not listed (in which case the call is ignored) - /// - /// \note This function does not update the region map. + void addRegion(const std::string& region, unsigned int colour); + ///< May be called on a region that is already listed (in which case an update is + /// performed) + /// + /// \note This function does not update the region map. - void updateRegions (const std::vector& regions); - ///< Update cells affected by the listed regions + void removeRegion(const std::string& region); + ///< May be called on a region that is not listed (in which case the call is ignored) + /// + /// \note This function does not update the region map. - void updateSize(); + void updateRegions(const std::vector& regions); + ///< Update cells affected by the listed regions - std::pair getSize() const; + void updateSize(); - public: + std::pair getSize() const; - RegionMap (Data& data); + public: + RegionMap(Data& data); - int rowCount (const QModelIndex& parent = QModelIndex()) const override; + int rowCount(const QModelIndex& parent = QModelIndex()) const override; - int columnCount (const QModelIndex& parent = QModelIndex()) const override; + int columnCount(const QModelIndex& parent = QModelIndex()) const override; - QVariant data (const QModelIndex& index, int role = Qt::DisplayRole) const override; - ///< \note Calling this function with role==Role_CellId may return the ID of a cell - /// that does not exist. + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; + ///< \note Calling this function with role==Role_CellId may return the ID of a cell + /// that does not exist. - Qt::ItemFlags flags (const QModelIndex& index) const override; + Qt::ItemFlags flags(const QModelIndex& index) const override; - private slots: + private slots: - void regionsAboutToBeRemoved (const QModelIndex& parent, int start, int end); + void regionsAboutToBeRemoved(const QModelIndex& parent, int start, int end); - void regionsInserted (const QModelIndex& parent, int start, int end); + void regionsInserted(const QModelIndex& parent, int start, int end); - void regionsChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); + void regionsChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); - void cellsAboutToBeRemoved (const QModelIndex& parent, int start, int end); + void cellsAboutToBeRemoved(const QModelIndex& parent, int start, int end); - void cellsInserted (const QModelIndex& parent, int start, int end); + void cellsInserted(const QModelIndex& parent, int start, int end); - void cellsChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); + void cellsChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); }; } diff --git a/apps/opencs/model/world/resources.cpp b/apps/opencs/model/world/resources.cpp index 71ee997413..4a600f5d32 100644 --- a/apps/opencs/model/world/resources.cpp +++ b/apps/opencs/model/world/resources.cpp @@ -1,22 +1,23 @@ #include "resources.hpp" +#include #include #include -#include #include #include #include -CSMWorld::Resources::Resources (const VFS::Manager* vfs, const std::string& baseDirectory, UniversalId::Type type, - const char * const *extensions) -: mBaseDirectory (baseDirectory), mType (type) +CSMWorld::Resources::Resources( + const VFS::Manager* vfs, const std::string& baseDirectory, UniversalId::Type type, const char* const* extensions) + : mBaseDirectory(baseDirectory) + , mType(type) { recreate(vfs, extensions); } -void CSMWorld::Resources::recreate(const VFS::Manager* vfs, const char * const *extensions) +void CSMWorld::Resources::recreate(const VFS::Manager* vfs, const char* const* extensions) { mFiles.clear(); mIndex.clear(); @@ -25,35 +26,33 @@ void CSMWorld::Resources::recreate(const VFS::Manager* vfs, const char * const * for (const auto& filepath : vfs->getRecursiveDirectoryIterator("")) { - if (filepath.size() (mFiles.size())-1)); + std::string file = filepath.substr(baseSize + 1); + mFiles.push_back(file); + std::replace(file.begin(), file.end(), '\\', '/'); + mIndex.insert(std::make_pair(Misc::StringUtils::lowerCase(file), static_cast(mFiles.size()) - 1)); } } @@ -62,21 +61,21 @@ int CSMWorld::Resources::getSize() const return static_cast(mFiles.size()); } -std::string CSMWorld::Resources::getId (int index) const +std::string CSMWorld::Resources::getId(int index) const { - return mFiles.at (index); + return mFiles.at(index); } -int CSMWorld::Resources::getIndex (const std::string& id) const +int CSMWorld::Resources::getIndex(const std::string& id) const { - int index = searchId (id); + int index = searchId(id); - if (index==-1) + if (index == -1) { std::ostringstream stream; stream << "Invalid resource: " << mBaseDirectory << '/' << id; - throw std::runtime_error (stream.str()); + throw std::runtime_error(stream.str()); } return index; @@ -84,13 +83,13 @@ int CSMWorld::Resources::getIndex (const std::string& id) const int CSMWorld::Resources::searchId(std::string_view id) const { - std::string id2 = Misc::StringUtils::lowerCase (id); + std::string id2 = Misc::StringUtils::lowerCase(id); - std::replace (id2.begin(), id2.end(), '\\', '/'); + std::replace(id2.begin(), id2.end(), '\\', '/'); - std::map::const_iterator iter = mIndex.find (id2); + std::map::const_iterator iter = mIndex.find(id2); - if (iter==mIndex.end()) + if (iter == mIndex.end()) return -1; return iter->second; diff --git a/apps/opencs/model/world/resources.hpp b/apps/opencs/model/world/resources.hpp index 2de13a259e..9a3152daa1 100644 --- a/apps/opencs/model/world/resources.hpp +++ b/apps/opencs/model/world/resources.hpp @@ -1,10 +1,10 @@ #ifndef CSM_WOLRD_RESOURCES_H #define CSM_WOLRD_RESOURCES_H -#include #include -#include +#include #include +#include #include "universalid.hpp" @@ -17,28 +17,27 @@ namespace CSMWorld { class Resources { - std::map mIndex; - std::vector mFiles; - std::string mBaseDirectory; - UniversalId::Type mType; - - public: + std::map mIndex; + std::vector mFiles; + std::string mBaseDirectory; + UniversalId::Type mType; - /// \param type Type of resources in this table. - Resources (const VFS::Manager* vfs, const std::string& baseDirectory, UniversalId::Type type, - const char * const *extensions = nullptr); + public: + /// \param type Type of resources in this table. + Resources(const VFS::Manager* vfs, const std::string& baseDirectory, UniversalId::Type type, + const char* const* extensions = nullptr); - void recreate(const VFS::Manager* vfs, const char * const *extensions = nullptr); + void recreate(const VFS::Manager* vfs, const char* const* extensions = nullptr); - int getSize() const; + int getSize() const; - std::string getId (int index) const; + std::string getId(int index) const; - int getIndex (const std::string& id) const; + int getIndex(const std::string& id) const; - int searchId(std::string_view id) const; + int searchId(std::string_view id) const; - UniversalId::Type getType() const; + UniversalId::Type getType() const; }; } diff --git a/apps/opencs/model/world/resourcesmanager.cpp b/apps/opencs/model/world/resourcesmanager.cpp index 67774e79a3..f35557c995 100644 --- a/apps/opencs/model/world/resourcesmanager.cpp +++ b/apps/opencs/model/world/resourcesmanager.cpp @@ -11,31 +11,30 @@ CSMWorld::ResourcesManager::ResourcesManager() CSMWorld::ResourcesManager::~ResourcesManager() = default; -void CSMWorld::ResourcesManager::addResources (const Resources& resources) +void CSMWorld::ResourcesManager::addResources(const Resources& resources) { - mResources.insert (std::make_pair (resources.getType(), resources)); - mResources.insert (std::make_pair (UniversalId::getParentType (resources.getType()), - resources)); + mResources.insert(std::make_pair(resources.getType(), resources)); + mResources.insert(std::make_pair(UniversalId::getParentType(resources.getType()), resources)); } -const char * const * CSMWorld::ResourcesManager::getMeshExtensions() +const char* const* CSMWorld::ResourcesManager::getMeshExtensions() { // maybe we could go over the osgDB::Registry to list all supported node formats - static const char * const sMeshTypes[] = { "nif", "osg", "osgt", "osgb", "osgx", "osg2", "dae", 0 }; + static const char* const sMeshTypes[] = { "nif", "osg", "osgt", "osgb", "osgx", "osg2", "dae", 0 }; return sMeshTypes; } -void CSMWorld::ResourcesManager::setVFS(const VFS::Manager *vfs) +void CSMWorld::ResourcesManager::setVFS(const VFS::Manager* vfs) { mVFS = vfs; mResources.clear(); - addResources (Resources (vfs, "meshes", UniversalId::Type_Mesh, getMeshExtensions())); - addResources (Resources (vfs, "icons", UniversalId::Type_Icon)); - addResources (Resources (vfs, "music", UniversalId::Type_Music)); - addResources (Resources (vfs, "sound", UniversalId::Type_SoundRes)); - addResources (Resources (vfs, "textures", UniversalId::Type_Texture)); - addResources (Resources (vfs, "video", UniversalId::Type_Video)); + addResources(Resources(vfs, "meshes", UniversalId::Type_Mesh, getMeshExtensions())); + addResources(Resources(vfs, "icons", UniversalId::Type_Icon)); + addResources(Resources(vfs, "music", UniversalId::Type_Music)); + addResources(Resources(vfs, "sound", UniversalId::Type_SoundRes)); + addResources(Resources(vfs, "textures", UniversalId::Type_Texture)); + addResources(Resources(vfs, "video", UniversalId::Type_Video)); } const VFS::Manager* CSMWorld::ResourcesManager::getVFS() const @@ -46,7 +45,7 @@ const VFS::Manager* CSMWorld::ResourcesManager::getVFS() const void CSMWorld::ResourcesManager::recreateResources() { std::map::iterator it = mResources.begin(); - for ( ; it != mResources.end(); ++it) + for (; it != mResources.end(); ++it) { if (it->first == UniversalId::Type_Mesh) it->second.recreate(mVFS, getMeshExtensions()); @@ -55,12 +54,12 @@ void CSMWorld::ResourcesManager::recreateResources() } } -const CSMWorld::Resources& CSMWorld::ResourcesManager::get (UniversalId::Type type) const +const CSMWorld::Resources& CSMWorld::ResourcesManager::get(UniversalId::Type type) const { - std::map::const_iterator iter = mResources.find (type); + std::map::const_iterator iter = mResources.find(type); - if (iter==mResources.end()) - throw std::logic_error ("Unknown resource type"); + if (iter == mResources.end()) + throw std::logic_error("Unknown resource type"); return iter->second; } diff --git a/apps/opencs/model/world/resourcesmanager.hpp b/apps/opencs/model/world/resourcesmanager.hpp index 4b6857f63d..f6e04d4d03 100644 --- a/apps/opencs/model/world/resourcesmanager.hpp +++ b/apps/opencs/model/world/resourcesmanager.hpp @@ -16,27 +16,25 @@ namespace CSMWorld class ResourcesManager { - std::map mResources; - const VFS::Manager* mVFS; + std::map mResources; + const VFS::Manager* mVFS; - private: + private: + void addResources(const Resources& resources); - void addResources (const Resources& resources); + const char* const* getMeshExtensions(); - const char * const * getMeshExtensions(); + public: + ResourcesManager(); + ~ResourcesManager(); - public: + const VFS::Manager* getVFS() const; - ResourcesManager(); - ~ResourcesManager(); + void setVFS(const VFS::Manager* vfs); - const VFS::Manager* getVFS() const; + void recreateResources(); - void setVFS(const VFS::Manager* vfs); - - void recreateResources(); - - const Resources& get (UniversalId::Type type) const; + const Resources& get(UniversalId::Type type) const; }; } diff --git a/apps/opencs/model/world/resourcetable.cpp b/apps/opencs/model/world/resourcetable.cpp index 0e7864e48e..f6fae9275d 100644 --- a/apps/opencs/model/world/resourcetable.cpp +++ b/apps/opencs/model/world/resourcetable.cpp @@ -2,17 +2,19 @@ #include -#include "resources.hpp" #include "columnbase.hpp" +#include "resources.hpp" #include "universalid.hpp" -CSMWorld::ResourceTable::ResourceTable (const Resources *resources, unsigned int features) -: IdTableBase (features | Feature_Constant), mResources (resources) -{} +CSMWorld::ResourceTable::ResourceTable(const Resources* resources, unsigned int features) + : IdTableBase(features | Feature_Constant) + , mResources(resources) +{ +} CSMWorld::ResourceTable::~ResourceTable() {} -int CSMWorld::ResourceTable::rowCount (const QModelIndex & parent) const +int CSMWorld::ResourceTable::rowCount(const QModelIndex& parent) const { if (parent.isValid()) return 0; @@ -20,7 +22,7 @@ int CSMWorld::ResourceTable::rowCount (const QModelIndex & parent) const return mResources->getSize(); } -int CSMWorld::ResourceTable::columnCount (const QModelIndex & parent) const +int CSMWorld::ResourceTable::columnCount(const QModelIndex& parent) const { if (parent.isValid()) return 0; @@ -28,47 +30,46 @@ int CSMWorld::ResourceTable::columnCount (const QModelIndex & parent) const return 2; // ID, type } -QVariant CSMWorld::ResourceTable::data (const QModelIndex & index, int role) const +QVariant CSMWorld::ResourceTable::data(const QModelIndex& index, int role) const { - if (role!=Qt::DisplayRole) + if (role != Qt::DisplayRole) return QVariant(); - if (index.column()==0) - return QString::fromUtf8 (mResources->getId (index.row()).c_str()); + if (index.column() == 0) + return QString::fromUtf8(mResources->getId(index.row()).c_str()); - if (index.column()==1) - return static_cast (mResources->getType()); + if (index.column() == 1) + return static_cast(mResources->getType()); - throw std::logic_error ("Invalid column in resource table"); + throw std::logic_error("Invalid column in resource table"); } -QVariant CSMWorld::ResourceTable::headerData (int section, Qt::Orientation orientation, - int role ) const +QVariant CSMWorld::ResourceTable::headerData(int section, Qt::Orientation orientation, int role) const { - if (orientation==Qt::Vertical) + if (orientation == Qt::Vertical) return QVariant(); - if (role==ColumnBase::Role_Flags) - return section==0 ? ColumnBase::Flag_Table : 0; + if (role == ColumnBase::Role_Flags) + return section == 0 ? ColumnBase::Flag_Table : 0; switch (section) { case 0: - if (role==Qt::DisplayRole) - return Columns::getName (Columns::ColumnId_Id).c_str(); + if (role == Qt::DisplayRole) + return Columns::getName(Columns::ColumnId_Id).c_str(); - if (role==ColumnBase::Role_Display) + if (role == ColumnBase::Role_Display) return ColumnBase::Display_Id; break; case 1: - if (role==Qt::DisplayRole) - return Columns::getName (Columns::ColumnId_RecordType).c_str(); + if (role == Qt::DisplayRole) + return Columns::getName(Columns::ColumnId_RecordType).c_str(); - if (role==ColumnBase::Role_Display) + if (role == ColumnBase::Role_Display) return ColumnBase::Display_Integer; break; @@ -77,83 +78,83 @@ QVariant CSMWorld::ResourceTable::headerData (int section, Qt::Orientation orien return QVariant(); } -bool CSMWorld::ResourceTable::setData ( const QModelIndex &index, const QVariant &value, - int role) +bool CSMWorld::ResourceTable::setData(const QModelIndex& index, const QVariant& value, int role) { return false; } -Qt::ItemFlags CSMWorld::ResourceTable::flags (const QModelIndex & index) const +Qt::ItemFlags CSMWorld::ResourceTable::flags(const QModelIndex& index) const { return Qt::ItemIsSelectable | Qt::ItemIsEnabled; } -QModelIndex CSMWorld::ResourceTable::index (int row, int column, const QModelIndex& parent) - const +QModelIndex CSMWorld::ResourceTable::index(int row, int column, const QModelIndex& parent) const { if (parent.isValid()) return QModelIndex(); - if (row<0 || row>=mResources->getSize()) + if (row < 0 || row >= mResources->getSize()) return QModelIndex(); - if (column<0 || column>1) + if (column < 0 || column > 1) return QModelIndex(); - return createIndex (row, column); + return createIndex(row, column); } -QModelIndex CSMWorld::ResourceTable::parent (const QModelIndex& index) const +QModelIndex CSMWorld::ResourceTable::parent(const QModelIndex& index) const { return QModelIndex(); } -QModelIndex CSMWorld::ResourceTable::getModelIndex (const std::string& id, int column) const +QModelIndex CSMWorld::ResourceTable::getModelIndex(const std::string& id, int column) const { int row = mResources->searchId(id); if (row != -1) - return index (row, column); + return index(row, column); return QModelIndex(); } -int CSMWorld::ResourceTable::searchColumnIndex (Columns::ColumnId id) const +int CSMWorld::ResourceTable::searchColumnIndex(Columns::ColumnId id) const { - if (id==Columns::ColumnId_Id) + if (id == Columns::ColumnId_Id) return 0; - if (id==Columns::ColumnId_RecordType) + if (id == Columns::ColumnId_RecordType) return 1; return -1; } -int CSMWorld::ResourceTable::findColumnIndex (Columns::ColumnId id) const +int CSMWorld::ResourceTable::findColumnIndex(Columns::ColumnId id) const { - int index = searchColumnIndex (id); + int index = searchColumnIndex(id); - if (index==-1) - throw std::logic_error ("invalid column index"); + if (index == -1) + throw std::logic_error("invalid column index"); return index; } -std::pair CSMWorld::ResourceTable::view (int row) const +std::pair CSMWorld::ResourceTable::view(int row) const { - return std::make_pair (UniversalId::Type_None, ""); + return std::make_pair(UniversalId::Type_None, ""); } -bool CSMWorld::ResourceTable::isDeleted (const std::string& id) const +bool CSMWorld::ResourceTable::isDeleted(const std::string& id) const { return false; } -int CSMWorld::ResourceTable::getColumnId (int column) const +int CSMWorld::ResourceTable::getColumnId(int column) const { switch (column) { - case 0: return Columns::ColumnId_Id; - case 1: return Columns::ColumnId_RecordType; + case 0: + return Columns::ColumnId_Id; + case 1: + return Columns::ColumnId_RecordType; } return -1; diff --git a/apps/opencs/model/world/resourcetable.hpp b/apps/opencs/model/world/resourcetable.hpp index 34d8298d9a..eea3d5c711 100644 --- a/apps/opencs/model/world/resourcetable.hpp +++ b/apps/opencs/model/world/resourcetable.hpp @@ -9,54 +9,53 @@ namespace CSMWorld class ResourceTable : public IdTableBase { - const Resources *mResources; + const Resources* mResources; - public: + public: + /// \note The feature Feature_Constant will be added implicitly. + ResourceTable(const Resources* resources, unsigned int features = 0); - /// \note The feature Feature_Constant will be added implicitly. - ResourceTable (const Resources *resources, unsigned int features = 0); + ~ResourceTable() override; - ~ResourceTable() override; + int rowCount(const QModelIndex& parent = QModelIndex()) const override; - int rowCount (const QModelIndex & parent = QModelIndex()) const override; + int columnCount(const QModelIndex& parent = QModelIndex()) const override; - int columnCount (const QModelIndex & parent = QModelIndex()) const override; + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; - QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override; - bool setData ( const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + Qt::ItemFlags flags(const QModelIndex& index) const override; - Qt::ItemFlags flags (const QModelIndex & index) const override; + QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override; - QModelIndex index (int row, int column, const QModelIndex& parent = QModelIndex()) const override; + QModelIndex parent(const QModelIndex& index) const override; - QModelIndex parent (const QModelIndex& index) const override; + QModelIndex getModelIndex(const std::string& id, int column) const override; - QModelIndex getModelIndex (const std::string& id, int column) const override; + /// Return index of column with the given \a id. If no such column exists, -1 is + /// returned. + int searchColumnIndex(Columns::ColumnId id) const override; - /// Return index of column with the given \a id. If no such column exists, -1 is - /// returned. - int searchColumnIndex (Columns::ColumnId id) const override; + /// Return index of column with the given \a id. If no such column exists, an + /// exception is thrown. + int findColumnIndex(Columns::ColumnId id) const override; - /// Return index of column with the given \a id. If no such column exists, an - /// exception is thrown. - int findColumnIndex (Columns::ColumnId id) const override; + /// Return the UniversalId and the hint for viewing \a row. If viewing is not + /// supported by this table, return (UniversalId::Type_None, ""). + std::pair view(int row) const override; - /// Return the UniversalId and the hint for viewing \a row. If viewing is not - /// supported by this table, return (UniversalId::Type_None, ""). - std::pair view (int row) const override; + /// Is \a id flagged as deleted? + bool isDeleted(const std::string& id) const override; - /// Is \a id flagged as deleted? - bool isDeleted (const std::string& id) const override; + int getColumnId(int column) const override; - int getColumnId (int column) const override; - - /// Signal Qt that the data is about to change. - void beginReset(); - /// Signal Qt that the data has been changed. - void endReset(); + /// Signal Qt that the data is about to change. + void beginReset(); + /// Signal Qt that the data has been changed. + void endReset(); }; } diff --git a/apps/opencs/model/world/scope.cpp b/apps/opencs/model/world/scope.cpp index 136b85e6b3..0cf522a392 100644 --- a/apps/opencs/model/world/scope.cpp +++ b/apps/opencs/model/world/scope.cpp @@ -4,20 +4,20 @@ #include -CSMWorld::Scope CSMWorld::getScopeFromId (const std::string& id) +CSMWorld::Scope CSMWorld::getScopeFromId(const std::string& id) { // get root namespace std::string namespace_; - std::string::size_type i = id.find ("::"); + std::string::size_type i = id.find("::"); - if (i!=std::string::npos) + if (i != std::string::npos) namespace_ = Misc::StringUtils::lowerCase(std::string_view(id).substr(0, i)); - if (namespace_=="project") + if (namespace_ == "project") return Scope_Project; - if (namespace_=="session") + if (namespace_ == "session") return Scope_Session; return Scope_Content; diff --git a/apps/opencs/model/world/scope.hpp b/apps/opencs/model/world/scope.hpp index 3983d91f50..dc00987858 100644 --- a/apps/opencs/model/world/scope.hpp +++ b/apps/opencs/model/world/scope.hpp @@ -17,7 +17,7 @@ namespace CSMWorld Scope_Session = 4 }; - Scope getScopeFromId (const std::string& id); + Scope getScopeFromId(const std::string& id); } #endif diff --git a/apps/opencs/model/world/scriptcontext.cpp b/apps/opencs/model/world/scriptcontext.cpp index 1088a58a00..392052b051 100644 --- a/apps/opencs/model/world/scriptcontext.cpp +++ b/apps/opencs/model/world/scriptcontext.cpp @@ -5,104 +5,112 @@ #include -#include #include +#include #include #include "data.hpp" -CSMWorld::ScriptContext::ScriptContext (const Data& data) : mData (data), mIdsUpdated (false) {} +CSMWorld::ScriptContext::ScriptContext(const Data& data) + : mData(data) + , mIdsUpdated(false) +{ +} bool CSMWorld::ScriptContext::canDeclareLocals() const { return true; } -char CSMWorld::ScriptContext::getGlobalType (const std::string& name) const +char CSMWorld::ScriptContext::getGlobalType(const std::string& name) const { - int index = mData.getGlobals().searchId (name); + int index = mData.getGlobals().searchId(name); - if (index!=-1) + if (index != -1) { - switch (mData.getGlobals().getRecord (index).get().mValue.getType()) + switch (mData.getGlobals().getRecord(index).get().mValue.getType()) { - case ESM::VT_Short: return 's'; - case ESM::VT_Long: return 'l'; - case ESM::VT_Float: return 'f'; - - default: return ' '; + case ESM::VT_Short: + return 's'; + case ESM::VT_Long: + return 'l'; + case ESM::VT_Float: + return 'f'; + + default: + return ' '; } } return ' '; } -std::pair CSMWorld::ScriptContext::getMemberType (const std::string& name, - const std::string& id) const +std::pair CSMWorld::ScriptContext::getMemberType(const std::string& name, const std::string& id) const { - std::string id2 = Misc::StringUtils::lowerCase (id); + std::string id2 = Misc::StringUtils::lowerCase(id); - int index = mData.getScripts().searchId (id2); + int index = mData.getScripts().searchId(id2); bool reference = false; - if (index==-1) + if (index == -1) { // ID is not a script ID. Search for a matching referenceable instead. - index = mData.getReferenceables().searchId (id2); + index = mData.getReferenceables().searchId(id2); - if (index!=-1) + if (index != -1) { // Referenceable found. - int columnIndex = mData.getReferenceables().findColumnIndex (Columns::ColumnId_Script); + int columnIndex = mData.getReferenceables().findColumnIndex(Columns::ColumnId_Script); - id2 = Misc::StringUtils::lowerCase (mData.getReferenceables(). - getData (index, columnIndex).toString().toUtf8().constData()); + id2 = Misc::StringUtils::lowerCase( + mData.getReferenceables().getData(index, columnIndex).toString().toUtf8().constData()); if (!id2.empty()) { // Referenceable has a script -> use it. - index = mData.getScripts().searchId (id2); + index = mData.getScripts().searchId(id2); reference = true; } } } - if (index==-1) - return std::make_pair (' ', false); + if (index == -1) + return std::make_pair(' ', false); - std::map::iterator iter = mLocals.find (id2); + std::map::iterator iter = mLocals.find(id2); - if (iter==mLocals.end()) + if (iter == mLocals.end()) { Compiler::Locals locals; Compiler::NullErrorHandler errorHandler; - std::istringstream stream (mData.getScripts().getRecord (index).get().mScriptText); - Compiler::QuickFileParser parser (errorHandler, *this, locals); - Compiler::Scanner scanner (errorHandler, stream, getExtensions()); - scanner.scan (parser); + std::istringstream stream(mData.getScripts().getRecord(index).get().mScriptText); + Compiler::QuickFileParser parser(errorHandler, *this, locals); + Compiler::Scanner scanner(errorHandler, stream, getExtensions()); + scanner.scan(parser); - iter = mLocals.insert (std::make_pair (id2, locals)).first; + iter = mLocals.insert(std::make_pair(id2, locals)).first; } - return std::make_pair (iter->second.getType (Misc::StringUtils::lowerCase (name)), reference); + return std::make_pair(iter->second.getType(Misc::StringUtils::lowerCase(name)), reference); } -bool CSMWorld::ScriptContext::isId (const std::string& name) const +bool CSMWorld::ScriptContext::isId(const std::string& name) const { if (!mIdsUpdated) { mIds = mData.getIds(); - for (auto& id : mIds) { + for (auto& id : mIds) + { Misc::StringUtils::lowerCaseInPlace(id); } - std::sort (mIds.begin(), mIds.end()); + std::sort(mIds.begin(), mIds.end()); mIdsUpdated = true; } - return std::binary_search (mIds.begin(), mIds.end(), Misc::StringUtils::lowerCase (name)); + return std::binary_search(mIds.begin(), mIds.end(), Misc::StringUtils::lowerCase(name)); } void CSMWorld::ScriptContext::invalidateIds() @@ -117,14 +125,13 @@ void CSMWorld::ScriptContext::clear() mLocals.clear(); } -bool CSMWorld::ScriptContext::clearLocals (const std::string& script) +bool CSMWorld::ScriptContext::clearLocals(const std::string& script) { - std::map::iterator iter = - mLocals.find (Misc::StringUtils::lowerCase (script)); + std::map::iterator iter = mLocals.find(Misc::StringUtils::lowerCase(script)); - if (iter!=mLocals.end()) + if (iter != mLocals.end()) { - mLocals.erase (iter); + mLocals.erase(iter); mIdsUpdated = false; return true; } diff --git a/apps/opencs/model/world/scriptcontext.hpp b/apps/opencs/model/world/scriptcontext.hpp index cb08fc70bd..a1ad54882a 100644 --- a/apps/opencs/model/world/scriptcontext.hpp +++ b/apps/opencs/model/world/scriptcontext.hpp @@ -1,9 +1,9 @@ #ifndef CSM_WORLD_SCRIPTCONTEXT_H #define CSM_WORLD_SCRIPTCONTEXT_H +#include #include #include -#include #include #include @@ -14,38 +14,36 @@ namespace CSMWorld class ScriptContext : public Compiler::Context { - const Data& mData; - mutable std::vector mIds; - mutable bool mIdsUpdated; - mutable std::map mLocals; - - public: + const Data& mData; + mutable std::vector mIds; + mutable bool mIdsUpdated; + mutable std::map mLocals; - ScriptContext (const Data& data); + public: + ScriptContext(const Data& data); - bool canDeclareLocals() const override; - ///< Is the compiler allowed to declare local variables? + bool canDeclareLocals() const override; + ///< Is the compiler allowed to declare local variables? - char getGlobalType (const std::string& name) const override; - ///< 'l: long, 's': short, 'f': float, ' ': does not exist. + char getGlobalType(const std::string& name) const override; + ///< 'l: long, 's': short, 'f': float, ' ': does not exist. - std::pair getMemberType (const std::string& name, - const std::string& id) const override; - ///< Return type of member variable \a name in script \a id or in script of reference of - /// \a id - /// \return first: 'l: long, 's': short, 'f': float, ' ': does not exist. - /// second: true: script of reference + std::pair getMemberType(const std::string& name, const std::string& id) const override; + ///< Return type of member variable \a name in script \a id or in script of reference of + /// \a id + /// \return first: 'l: long, 's': short, 'f': float, ' ': does not exist. + /// second: true: script of reference - bool isId (const std::string& name) const override; - ///< Does \a name match an ID, that can be referenced? + bool isId(const std::string& name) const override; + ///< Does \a name match an ID, that can be referenced? - void invalidateIds(); + void invalidateIds(); - void clear(); - ///< Remove all cached data. + void clear(); + ///< Remove all cached data. - /// \return Were there any locals that needed clearing? - bool clearLocals (const std::string& script); + /// \return Were there any locals that needed clearing? + bool clearLocals(const std::string& script); }; } diff --git a/apps/opencs/model/world/subcellcollection.hpp b/apps/opencs/model/world/subcellcollection.hpp index a792e11457..6f9d1eda8f 100644 --- a/apps/opencs/model/world/subcellcollection.hpp +++ b/apps/opencs/model/world/subcellcollection.hpp @@ -13,30 +13,29 @@ namespace CSMWorld struct Cell; /// \brief Single type collection of top level records that are associated with cells - template > + template > class SubCellCollection : public NestedIdCollection { - const IdCollection>& mCells; + const IdCollection>& mCells; - void loadRecord (ESXRecordT& record, ESM::ESMReader& reader, bool& isDeleted) override; + void loadRecord(ESXRecordT& record, ESM::ESMReader& reader, bool& isDeleted) override; - public: - SubCellCollection(const IdCollection>& cells); + public: + SubCellCollection(const IdCollection>& cells); }; - template - void SubCellCollection::loadRecord (ESXRecordT& record, - ESM::ESMReader& reader, - bool& isDeleted) + template + void SubCellCollection::loadRecord( + ESXRecordT& record, ESM::ESMReader& reader, bool& isDeleted) { - record.load (reader, isDeleted, mCells); + record.load(reader, isDeleted, mCells); } - template - SubCellCollection::SubCellCollection ( - const IdCollection>& cells) - : mCells (cells) - {} + template + SubCellCollection::SubCellCollection(const IdCollection>& cells) + : mCells(cells) + { + } } #endif diff --git a/apps/opencs/model/world/tablemimedata.cpp b/apps/opencs/model/world/tablemimedata.cpp index 1268a7389d..bbede2175c 100644 --- a/apps/opencs/model/world/tablemimedata.cpp +++ b/apps/opencs/model/world/tablemimedata.cpp @@ -4,22 +4,23 @@ #include -#include "universalid.hpp" #include "columnbase.hpp" +#include "universalid.hpp" -CSMWorld::TableMimeData::TableMimeData (UniversalId id, const CSMDoc::Document& document) : -mDocument(document) +CSMWorld::TableMimeData::TableMimeData(UniversalId id, const CSMDoc::Document& document) + : mDocument(document) { - mUniversalId.push_back (id); - mObjectsFormats << QString::fromUtf8 (("tabledata/" + id.getTypeName()).c_str()); + mUniversalId.push_back(id); + mObjectsFormats << QString::fromUtf8(("tabledata/" + id.getTypeName()).c_str()); } -CSMWorld::TableMimeData::TableMimeData (const std::vector< CSMWorld::UniversalId >& id, const CSMDoc::Document& document) : - mUniversalId (id), mDocument(document) +CSMWorld::TableMimeData::TableMimeData(const std::vector& id, const CSMDoc::Document& document) + : mUniversalId(id) + , mDocument(document) { - for (std::vector::iterator it (mUniversalId.begin()); it != mUniversalId.end(); ++it) + for (std::vector::iterator it(mUniversalId.begin()); it != mUniversalId.end(); ++it) { - mObjectsFormats << QString::fromUtf8 (("tabledata/" + it->getTypeName()).c_str()); + mObjectsFormats << QString::fromUtf8(("tabledata/" + it->getTypeName()).c_str()); } } @@ -28,16 +29,15 @@ QStringList CSMWorld::TableMimeData::formats() const return mObjectsFormats; } -CSMWorld::TableMimeData::~TableMimeData() -{ -} +CSMWorld::TableMimeData::~TableMimeData() {} std::string CSMWorld::TableMimeData::getIcon() const { if (mUniversalId.empty()) { - qDebug()<<"TableMimeData object does not hold any records!"; //because throwing in the event loop tends to be problematic - throw std::runtime_error ("TableMimeData object does not hold any records!"); + qDebug() << "TableMimeData object does not hold any records!"; // because throwing in the event loop tends to be + // problematic + throw std::runtime_error("TableMimeData object does not hold any records!"); } std::string tmpIcon; @@ -54,68 +54,50 @@ std::string CSMWorld::TableMimeData::getIcon() const if (tmpIcon != mUniversalId[i].getIcon()) { - return ":/multitype.png"; //icon stolen from gnome TODO: get new icon + return ":/multitype.png"; // icon stolen from gnome TODO: get new icon } tmpIcon = mUniversalId[i].getIcon(); } - return mUniversalId.begin()->getIcon(); //All objects are of the same type; + return mUniversalId.begin()->getIcon(); // All objects are of the same type; } -std::vector< CSMWorld::UniversalId > CSMWorld::TableMimeData::getData() const +std::vector CSMWorld::TableMimeData::getData() const { return mUniversalId; } bool CSMWorld::TableMimeData::isReferencable(CSMWorld::ColumnBase::Display type) const { -return ( type == CSMWorld::ColumnBase::Display_Activator - || type == CSMWorld::ColumnBase::Display_Potion - || type == CSMWorld::ColumnBase::Display_Apparatus - || type == CSMWorld::ColumnBase::Display_Armor - || type == CSMWorld::ColumnBase::Display_Book - || type == CSMWorld::ColumnBase::Display_Clothing - || type == CSMWorld::ColumnBase::Display_Container - || type == CSMWorld::ColumnBase::Display_Creature - || type == CSMWorld::ColumnBase::Display_Door - || type == CSMWorld::ColumnBase::Display_Ingredient - || type == CSMWorld::ColumnBase::Display_CreatureLevelledList - || type == CSMWorld::ColumnBase::Display_ItemLevelledList - || type == CSMWorld::ColumnBase::Display_Light - || type == CSMWorld::ColumnBase::Display_Lockpick - || type == CSMWorld::ColumnBase::Display_Miscellaneous - || type == CSMWorld::ColumnBase::Display_Npc - || type == CSMWorld::ColumnBase::Display_Probe - || type == CSMWorld::ColumnBase::Display_Repair - || type == CSMWorld::ColumnBase::Display_Static - || type == CSMWorld::ColumnBase::Display_Weapon); + return (type == CSMWorld::ColumnBase::Display_Activator || type == CSMWorld::ColumnBase::Display_Potion + || type == CSMWorld::ColumnBase::Display_Apparatus || type == CSMWorld::ColumnBase::Display_Armor + || type == CSMWorld::ColumnBase::Display_Book || type == CSMWorld::ColumnBase::Display_Clothing + || type == CSMWorld::ColumnBase::Display_Container || type == CSMWorld::ColumnBase::Display_Creature + || type == CSMWorld::ColumnBase::Display_Door || type == CSMWorld::ColumnBase::Display_Ingredient + || type == CSMWorld::ColumnBase::Display_CreatureLevelledList + || type == CSMWorld::ColumnBase::Display_ItemLevelledList || type == CSMWorld::ColumnBase::Display_Light + || type == CSMWorld::ColumnBase::Display_Lockpick || type == CSMWorld::ColumnBase::Display_Miscellaneous + || type == CSMWorld::ColumnBase::Display_Npc || type == CSMWorld::ColumnBase::Display_Probe + || type == CSMWorld::ColumnBase::Display_Repair || type == CSMWorld::ColumnBase::Display_Static + || type == CSMWorld::ColumnBase::Display_Weapon); } bool CSMWorld::TableMimeData::isReferencable(CSMWorld::UniversalId::Type type) { - return ( type == CSMWorld::UniversalId::Type_Activator - || type == CSMWorld::UniversalId::Type_Potion - || type == CSMWorld::UniversalId::Type_Apparatus - || type == CSMWorld::UniversalId::Type_Armor - || type == CSMWorld::UniversalId::Type_Book - || type == CSMWorld::UniversalId::Type_Clothing - || type == CSMWorld::UniversalId::Type_Container - || type == CSMWorld::UniversalId::Type_Creature - || type == CSMWorld::UniversalId::Type_Door - || type == CSMWorld::UniversalId::Type_Ingredient - || type == CSMWorld::UniversalId::Type_CreatureLevelledList - || type == CSMWorld::UniversalId::Type_ItemLevelledList - || type == CSMWorld::UniversalId::Type_Light - || type == CSMWorld::UniversalId::Type_Lockpick - || type == CSMWorld::UniversalId::Type_Miscellaneous - || type == CSMWorld::UniversalId::Type_Npc - || type == CSMWorld::UniversalId::Type_Probe - || type == CSMWorld::UniversalId::Type_Repair - || type == CSMWorld::UniversalId::Type_Static - || type == CSMWorld::UniversalId::Type_Weapon); + return (type == CSMWorld::UniversalId::Type_Activator || type == CSMWorld::UniversalId::Type_Potion + || type == CSMWorld::UniversalId::Type_Apparatus || type == CSMWorld::UniversalId::Type_Armor + || type == CSMWorld::UniversalId::Type_Book || type == CSMWorld::UniversalId::Type_Clothing + || type == CSMWorld::UniversalId::Type_Container || type == CSMWorld::UniversalId::Type_Creature + || type == CSMWorld::UniversalId::Type_Door || type == CSMWorld::UniversalId::Type_Ingredient + || type == CSMWorld::UniversalId::Type_CreatureLevelledList + || type == CSMWorld::UniversalId::Type_ItemLevelledList || type == CSMWorld::UniversalId::Type_Light + || type == CSMWorld::UniversalId::Type_Lockpick || type == CSMWorld::UniversalId::Type_Miscellaneous + || type == CSMWorld::UniversalId::Type_Npc || type == CSMWorld::UniversalId::Type_Probe + || type == CSMWorld::UniversalId::Type_Repair || type == CSMWorld::UniversalId::Type_Static + || type == CSMWorld::UniversalId::Type_Weapon); } -bool CSMWorld::TableMimeData::holdsType (CSMWorld::UniversalId::Type type) const +bool CSMWorld::TableMimeData::holdsType(CSMWorld::UniversalId::Type type) const { bool referencable = (type == CSMWorld::UniversalId::Type_Referenceable); for (std::vector::const_iterator it = mUniversalId.begin(); it != mUniversalId.end(); ++it) @@ -126,8 +108,10 @@ bool CSMWorld::TableMimeData::holdsType (CSMWorld::UniversalId::Type type) const { return true; } - } else { - if (it->getType() == type) + } + else + { + if (it->getType() == type) { return true; } @@ -137,7 +121,7 @@ bool CSMWorld::TableMimeData::holdsType (CSMWorld::UniversalId::Type type) const return false; } -bool CSMWorld::TableMimeData::holdsType (CSMWorld::ColumnBase::Display type) const +bool CSMWorld::TableMimeData::holdsType(CSMWorld::ColumnBase::Display type) const { bool referencable = (type == CSMWorld::ColumnBase::Display_Referenceable); for (std::vector::const_iterator it = mUniversalId.begin(); it != mUniversalId.end(); ++it) @@ -148,8 +132,10 @@ bool CSMWorld::TableMimeData::holdsType (CSMWorld::ColumnBase::Display type) con { return true; } - } else { - if (it->getType() == convertEnums (type)) + } + else + { + if (it->getType() == convertEnums(type)) { return true; } @@ -159,7 +145,7 @@ bool CSMWorld::TableMimeData::holdsType (CSMWorld::ColumnBase::Display type) con return false; } -CSMWorld::UniversalId CSMWorld::TableMimeData::returnMatching (CSMWorld::UniversalId::Type type) const +CSMWorld::UniversalId CSMWorld::TableMimeData::returnMatching(CSMWorld::UniversalId::Type type) const { bool referencable = (type == CSMWorld::UniversalId::Type_Referenceable); for (std::vector::const_iterator it = mUniversalId.begin(); it != mUniversalId.end(); ++it) @@ -170,7 +156,8 @@ CSMWorld::UniversalId CSMWorld::TableMimeData::returnMatching (CSMWorld::Univers { return *it; } - } else + } + else { if (it->getType() == type) { @@ -179,10 +166,10 @@ CSMWorld::UniversalId CSMWorld::TableMimeData::returnMatching (CSMWorld::Univers } } - throw std::runtime_error ("TableMimeData object does not hold object of the sought type"); + throw std::runtime_error("TableMimeData object does not hold object of the sought type"); } -CSMWorld::UniversalId CSMWorld::TableMimeData::returnMatching (CSMWorld::ColumnBase::Display type) const +CSMWorld::UniversalId CSMWorld::TableMimeData::returnMatching(CSMWorld::ColumnBase::Display type) const { bool referencable = (type == CSMWorld::ColumnBase::Display_Referenceable); for (std::vector::const_iterator it = mUniversalId.begin(); it != mUniversalId.end(); ++it) @@ -193,18 +180,20 @@ CSMWorld::UniversalId CSMWorld::TableMimeData::returnMatching (CSMWorld::ColumnB { return *it; } - } else { - if (it->getType() == convertEnums (type)) + } + else + { + if (it->getType() == convertEnums(type)) { return *it; } } } - throw std::runtime_error ("TableMimeData object does not hold object of the sought type"); + throw std::runtime_error("TableMimeData object does not hold object of the sought type"); } -bool CSMWorld::TableMimeData::fromDocument (const CSMDoc::Document& document) const +bool CSMWorld::TableMimeData::fromDocument(const CSMDoc::Document& document) const { return &document == &mDocument; } @@ -217,8 +206,7 @@ namespace CSMWorld::ColumnBase::Display mDisplayType; }; - const Mapping mapping[] = - { + const Mapping mapping[] = { { CSMWorld::UniversalId::Type_Race, CSMWorld::ColumnBase::Display_Race }, { CSMWorld::UniversalId::Type_Skill, CSMWorld::ColumnBase::Display_Skill }, { CSMWorld::UniversalId::Type_Class, CSMWorld::ColumnBase::Display_Class }, @@ -271,19 +259,19 @@ namespace }; } -CSMWorld::UniversalId::Type CSMWorld::TableMimeData::convertEnums (ColumnBase::Display type) +CSMWorld::UniversalId::Type CSMWorld::TableMimeData::convertEnums(ColumnBase::Display type) { - for (int i=0; mapping[i].mUniversalIdType!=CSMWorld::UniversalId::Type_None; ++i) - if (mapping[i].mDisplayType==type) + for (int i = 0; mapping[i].mUniversalIdType != CSMWorld::UniversalId::Type_None; ++i) + if (mapping[i].mDisplayType == type) return mapping[i].mUniversalIdType; return CSMWorld::UniversalId::Type_None; } -CSMWorld::ColumnBase::Display CSMWorld::TableMimeData::convertEnums (UniversalId::Type type) +CSMWorld::ColumnBase::Display CSMWorld::TableMimeData::convertEnums(UniversalId::Type type) { - for (int i=0; mapping[i].mUniversalIdType!=CSMWorld::UniversalId::Type_None; ++i) - if (mapping[i].mUniversalIdType==type) + for (int i = 0; mapping[i].mUniversalIdType != CSMWorld::UniversalId::Type_None; ++i) + if (mapping[i].mUniversalIdType == type) return mapping[i].mDisplayType; return CSMWorld::ColumnBase::Display_None; diff --git a/apps/opencs/model/world/tablemimedata.hpp b/apps/opencs/model/world/tablemimedata.hpp index 2345249122..e76dd930d7 100644 --- a/apps/opencs/model/world/tablemimedata.hpp +++ b/apps/opencs/model/world/tablemimedata.hpp @@ -3,11 +3,11 @@ #include -#include #include +#include -#include "universalid.hpp" #include "columnbase.hpp" +#include "universalid.hpp" namespace CSMDoc { @@ -17,51 +17,52 @@ namespace CSMDoc namespace CSMWorld { -/// \brief Subclass of QmimeData, augmented to contain and transport UniversalIds. -/// -/// This class provides way to construct mimedata object holding the universalid copy -/// Universalid is used in the majority of the tables to store type, id, argument types. -/// This way universalid grants a way to retrieve record from the concrete table. -/// Please note, that tablemimedata object can hold multiple universalIds in the vector. + /// \brief Subclass of QmimeData, augmented to contain and transport UniversalIds. + /// + /// This class provides way to construct mimedata object holding the universalid copy + /// Universalid is used in the majority of the tables to store type, id, argument types. + /// This way universalid grants a way to retrieve record from the concrete table. + /// Please note, that tablemimedata object can hold multiple universalIds in the vector. class TableMimeData : public QMimeData { - std::vector mUniversalId; - QStringList mObjectsFormats; - const CSMDoc::Document& mDocument; - public: - TableMimeData(UniversalId id, const CSMDoc::Document& document); + std::vector mUniversalId; + QStringList mObjectsFormats; + const CSMDoc::Document& mDocument; + + public: + TableMimeData(UniversalId id, const CSMDoc::Document& document); - TableMimeData(const std::vector& id, const CSMDoc::Document& document); + TableMimeData(const std::vector& id, const CSMDoc::Document& document); - ~TableMimeData(); + ~TableMimeData(); - QStringList formats() const override; + QStringList formats() const override; - std::string getIcon() const; + std::string getIcon() const; - std::vector getData() const; + std::vector getData() const; - bool holdsType(UniversalId::Type type) const; + bool holdsType(UniversalId::Type type) const; - bool holdsType(CSMWorld::ColumnBase::Display type) const; + bool holdsType(CSMWorld::ColumnBase::Display type) const; - bool fromDocument(const CSMDoc::Document& document) const; + bool fromDocument(const CSMDoc::Document& document) const; - UniversalId returnMatching(UniversalId::Type type) const; + UniversalId returnMatching(UniversalId::Type type) const; - const CSMDoc::Document* getDocumentPtr() const; + const CSMDoc::Document* getDocumentPtr() const; - UniversalId returnMatching(CSMWorld::ColumnBase::Display type) const; + UniversalId returnMatching(CSMWorld::ColumnBase::Display type) const; - static CSMWorld::UniversalId::Type convertEnums(CSMWorld::ColumnBase::Display type); + static CSMWorld::UniversalId::Type convertEnums(CSMWorld::ColumnBase::Display type); - static CSMWorld::ColumnBase::Display convertEnums(CSMWorld::UniversalId::Type type); + static CSMWorld::ColumnBase::Display convertEnums(CSMWorld::UniversalId::Type type); - static bool isReferencable(CSMWorld::UniversalId::Type type); - private: - bool isReferencable(CSMWorld::ColumnBase::Display type) const; + static bool isReferencable(CSMWorld::UniversalId::Type type); + private: + bool isReferencable(CSMWorld::ColumnBase::Display type) const; }; } #endif // TABLEMIMEDATA_H diff --git a/apps/opencs/model/world/universalid.cpp b/apps/opencs/model/world/universalid.cpp index 0c2910ce53..95da6aaa38 100644 --- a/apps/opencs/model/world/universalid.cpp +++ b/apps/opencs/model/world/universalid.cpp @@ -1,23 +1,23 @@ #include "universalid.hpp" -#include -#include #include +#include +#include namespace { struct TypeData { - CSMWorld::UniversalId::Class mClass; - CSMWorld::UniversalId::Type mType; - const char *mName; - const char *mIcon; + CSMWorld::UniversalId::Class mClass; + CSMWorld::UniversalId::Type mType; + const char* mName; + const char* mIcon; }; - static const TypeData sNoArg[] = - { + static const TypeData sNoArg[] = { { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, "-", 0 }, - { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Globals, "Global Variables", ":./global-variable.png" }, + { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Globals, "Global Variables", + ":./global-variable.png" }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Gmsts, "Game Settings", ":./gmst.png" }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Skills, "Skills", ":./skill.png" }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Classes, "Classes", ":./class.png" }, @@ -26,41 +26,64 @@ namespace { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Sounds, "Sounds", ":./sound.png" }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Scripts, "Scripts", ":./script.png" }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Regions, "Regions", ":./region.png" }, - { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Birthsigns, "Birthsigns", ":./birthsign.png" }, + { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Birthsigns, "Birthsigns", + ":./birthsign.png" }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Spells, "Spells", ":./spell.png" }, - { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Topics, "Topics", ":./dialogue-topics.png" }, - { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Journals, "Journals", ":./journal-topics.png" }, - { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_TopicInfos, "Topic Infos", ":./dialogue-topic-infos.png" }, - { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_JournalInfos, "Journal Infos", ":./journal-topic-infos.png" }, + { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Topics, "Topics", + ":./dialogue-topics.png" }, + { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Journals, "Journals", + ":./journal-topics.png" }, + { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_TopicInfos, "Topic Infos", + ":./dialogue-topic-infos.png" }, + { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_JournalInfos, "Journal Infos", + ":./journal-topic-infos.png" }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Cells, "Cells", ":./cell.png" }, - { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Enchantments, "Enchantments", ":./enchantment.png" }, - { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_BodyParts, "Body Parts", ":./body-part.png" }, - { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Referenceables, "Objects", ":./object.png" }, - { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_References, "Instances", ":./instance.png" }, - { CSMWorld::UniversalId::Class_NonRecord, CSMWorld::UniversalId::Type_RegionMap, "Region Map", ":./region-map.png" }, + { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Enchantments, "Enchantments", + ":./enchantment.png" }, + { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_BodyParts, "Body Parts", + ":./body-part.png" }, + { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Referenceables, "Objects", + ":./object.png" }, + { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_References, "Instances", + ":./instance.png" }, + { CSMWorld::UniversalId::Class_NonRecord, CSMWorld::UniversalId::Type_RegionMap, "Region Map", + ":./region-map.png" }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Filters, "Filters", ":./filter.png" }, - { CSMWorld::UniversalId::Class_ResourceList, CSMWorld::UniversalId::Type_Meshes, "Meshes", ":./resources-mesh" }, + { CSMWorld::UniversalId::Class_ResourceList, CSMWorld::UniversalId::Type_Meshes, "Meshes", + ":./resources-mesh" }, { CSMWorld::UniversalId::Class_ResourceList, CSMWorld::UniversalId::Type_Icons, "Icons", ":./resources-icon" }, - { CSMWorld::UniversalId::Class_ResourceList, CSMWorld::UniversalId::Type_Musics, "Music Files", ":./resources-music" }, - { CSMWorld::UniversalId::Class_ResourceList, CSMWorld::UniversalId::Type_SoundsRes, "Sound Files", ":resources-sound" }, - { CSMWorld::UniversalId::Class_ResourceList, CSMWorld::UniversalId::Type_Textures, "Textures", ":./resources-texture" }, - { CSMWorld::UniversalId::Class_ResourceList, CSMWorld::UniversalId::Type_Videos, "Videos", ":./resources-video" }, - { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_DebugProfiles, "Debug Profiles", ":./debug-profile.png" }, + { CSMWorld::UniversalId::Class_ResourceList, CSMWorld::UniversalId::Type_Musics, "Music Files", + ":./resources-music" }, + { CSMWorld::UniversalId::Class_ResourceList, CSMWorld::UniversalId::Type_SoundsRes, "Sound Files", + ":resources-sound" }, + { CSMWorld::UniversalId::Class_ResourceList, CSMWorld::UniversalId::Type_Textures, "Textures", + ":./resources-texture" }, + { CSMWorld::UniversalId::Class_ResourceList, CSMWorld::UniversalId::Type_Videos, "Videos", + ":./resources-video" }, + { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_DebugProfiles, "Debug Profiles", + ":./debug-profile.png" }, { CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_RunLog, "Run Log", ":./run-log.png" }, - { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_SoundGens, "Sound Generators", ":./sound-generator.png" }, - { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_MagicEffects, "Magic Effects", ":./magic-effect.png" }, - { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Lands, "Lands", ":./land-heightmap.png" }, - { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_LandTextures, "Land Textures", ":./land-texture.png" }, - { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Pathgrids, "Pathgrids", ":./pathgrid.png" }, - { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_StartScripts, "Start Scripts", ":./start-script.png" }, - { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_MetaDatas, "Metadata", ":./metadata.png" }, + { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_SoundGens, "Sound Generators", + ":./sound-generator.png" }, + { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_MagicEffects, "Magic Effects", + ":./magic-effect.png" }, + { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Lands, "Lands", + ":./land-heightmap.png" }, + { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_LandTextures, "Land Textures", + ":./land-texture.png" }, + { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Pathgrids, "Pathgrids", + ":./pathgrid.png" }, + { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_StartScripts, "Start Scripts", + ":./start-script.png" }, + { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_MetaDatas, "Metadata", + ":./metadata.png" }, // end marker { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 }, }; - static const TypeData sIdArg[] = - { - { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Global, "Global Variable", ":./global-variable.png" }, + static const TypeData sIdArg[] = { + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Global, "Global Variable", + ":./global-variable.png" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Gmst, "Game Setting", ":./gmst.png" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Skill, "Skill", ":./skill.png" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Class, "Class", ":./class.png" }, @@ -72,96 +95,115 @@ namespace { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Birthsign, "Birthsign", ":./birthsign.png" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Spell, "Spell", ":./spell.png" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Topic, "Topic", ":./dialogue-topics.png" }, - { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Journal, "Journal", ":./journal-topics.png" }, - { CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_TopicInfo, "TopicInfo", ":./dialogue-topic-infos.png" }, - { CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_JournalInfo, "JournalInfo", ":./journal-topic-infos.png" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Journal, "Journal", + ":./journal-topics.png" }, + { CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_TopicInfo, "TopicInfo", + ":./dialogue-topic-infos.png" }, + { CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_JournalInfo, "JournalInfo", + ":./journal-topic-infos.png" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Cell, "Cell", ":./cell.png" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Cell_Missing, "Cell", ":./cell.png" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Referenceable, "Object", ":./object.png" }, - { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Activator, "Activator", ":./activator.png" }, + { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Activator, "Activator", + ":./activator.png" }, { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Potion, "Potion", ":./potion.png" }, - { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Apparatus, "Apparatus", ":./apparatus.png" }, + { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Apparatus, "Apparatus", + ":./apparatus.png" }, { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Armor, "Armor", ":./armor.png" }, { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Book, "Book", ":./book.png" }, { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Clothing, "Clothing", ":./clothing.png" }, - { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Container, "Container", ":./container.png" }, + { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Container, "Container", + ":./container.png" }, { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Creature, "Creature", ":./creature.png" }, { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Door, "Door", ":./door.png" }, - { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Ingredient, "Ingredient", ":./ingredient.png" }, + { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Ingredient, "Ingredient", + ":./ingredient.png" }, { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_CreatureLevelledList, "Creature Levelled List", ":./levelled-creature.png" }, - { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_ItemLevelledList, - "Item Levelled List", ":./levelled-item.png" }, + { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_ItemLevelledList, "Item Levelled List", + ":./levelled-item.png" }, { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Light, "Light", ":./light.png" }, { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Lockpick, "Lockpick", ":./lockpick.png" }, - { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Miscellaneous, - "Miscellaneous", ":./miscellaneous.png" }, + { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Miscellaneous, "Miscellaneous", + ":./miscellaneous.png" }, { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Npc, "NPC", ":./npc.png" }, { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Probe, "Probe", ":./probe.png" }, { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Repair, "Repair", ":./repair.png" }, { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Static, "Static", ":./static.png" }, { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Weapon, "Weapon", ":./weapon.png" }, - { CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_Reference, "Instance", ":./instance.png" }, + { CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_Reference, "Instance", + ":./instance.png" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Filter, "Filter", ":./filter.png" }, { CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Scene, "Scene", ":./scene.png" }, - { CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Preview, "Preview", ":./record-preview.png" }, - { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Enchantment, "Enchantment", ":./enchantment.png" }, + { CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Preview, "Preview", + ":./record-preview.png" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Enchantment, "Enchantment", + ":./enchantment.png" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_BodyPart, "Body Part", ":./body-part.png" }, - { CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Mesh, "Mesh", ":./resources-mesh"}, - { CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Icon, "Icon", ":./resources-icon"}, + { CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Mesh, "Mesh", ":./resources-mesh" }, + { CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Icon, "Icon", ":./resources-icon" }, { CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Music, "Music", ":./resources-music" }, - { CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_SoundRes, "Sound File", ":./resources-sound" }, - { CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Texture, "Texture", ":./resources-texture" }, + { CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_SoundRes, "Sound File", + ":./resources-sound" }, + { CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Texture, "Texture", + ":./resources-texture" }, { CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Video, "Video", ":./resources-video" }, - { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_DebugProfile, "Debug Profile", ":./debug-profile.png" }, - { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_SoundGen, "Sound Generator", ":./sound-generator.png" }, - { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_MagicEffect, "Magic Effect", ":./magic-effect.png" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_DebugProfile, "Debug Profile", + ":./debug-profile.png" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_SoundGen, "Sound Generator", + ":./sound-generator.png" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_MagicEffect, "Magic Effect", + ":./magic-effect.png" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Land, "Land", ":./land-heightmap.png" }, - { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_LandTexture, "Land Texture", ":./land-texture.png" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_LandTexture, "Land Texture", + ":./land-texture.png" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Pathgrid, "Pathgrid", ":./pathgrid.png" }, - { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_StartScript, "Start Script", ":./start-script.png" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_StartScript, "Start Script", + ":./start-script.png" }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_MetaData, "Metadata", ":./metadata.png" }, // end marker { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 }, }; - static const TypeData sIndexArg[] = - { - { CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_VerificationResults, "Verification Results", ":./menu-verify.png" }, - { CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_LoadErrorLog, "Load Error Log", ":./error-log.png" }, - { CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_Search, "Global Search", ":./menu-search.png" }, + static const TypeData sIndexArg[] = { + { CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_VerificationResults, + "Verification Results", ":./menu-verify.png" }, + { CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_LoadErrorLog, "Load Error Log", + ":./error-log.png" }, + { CSMWorld::UniversalId::Class_Transient, CSMWorld::UniversalId::Type_Search, "Global Search", + ":./menu-search.png" }, // end marker { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 }, }; } -CSMWorld::UniversalId::UniversalId (const std::string& universalId) -: mIndex(0) +CSMWorld::UniversalId::UniversalId(const std::string& universalId) + : mIndex(0) { - std::string::size_type index = universalId.find (':'); + std::string::size_type index = universalId.find(':'); - if (index!=std::string::npos) + if (index != std::string::npos) { - std::string type = universalId.substr (0, index); + std::string type = universalId.substr(0, index); - for (int i=0; sIdArg[i].mName; ++i) - if (type==sIdArg[i].mName) + for (int i = 0; sIdArg[i].mName; ++i) + if (type == sIdArg[i].mName) { mArgumentType = ArgumentType_Id; mType = sIdArg[i].mType; mClass = sIdArg[i].mClass; - mId = universalId.substr (index+2); + mId = universalId.substr(index + 2); return; } - for (int i=0; sIndexArg[i].mName; ++i) - if (type==sIndexArg[i].mName) + for (int i = 0; sIndexArg[i].mName; ++i) + if (type == sIndexArg[i].mName) { mArgumentType = ArgumentType_Index; mType = sIndexArg[i].mType; mClass = sIndexArg[i].mClass; - std::istringstream stream (universalId.substr (index+2)); + std::istringstream stream(universalId.substr(index + 2)); if (stream >> mIndex) return; @@ -171,8 +213,8 @@ CSMWorld::UniversalId::UniversalId (const std::string& universalId) } else { - for (int i=0; sNoArg[i].mName; ++i) - if (universalId==sNoArg[i].mName) + for (int i = 0; sNoArg[i].mName; ++i) + if (universalId == sNoArg[i].mName) { mArgumentType = ArgumentType_None; mType = sNoArg[i].mType; @@ -181,60 +223,68 @@ CSMWorld::UniversalId::UniversalId (const std::string& universalId) } } - throw std::runtime_error ("invalid UniversalId: " + universalId); + throw std::runtime_error("invalid UniversalId: " + universalId); } -CSMWorld::UniversalId::UniversalId (Type type) : mArgumentType (ArgumentType_None), mType (type), mIndex (0) +CSMWorld::UniversalId::UniversalId(Type type) + : mArgumentType(ArgumentType_None) + , mType(type) + , mIndex(0) { - for (int i=0; sNoArg[i].mName; ++i) - if (type==sNoArg[i].mType) + for (int i = 0; sNoArg[i].mName; ++i) + if (type == sNoArg[i].mType) { mClass = sNoArg[i].mClass; return; } - for (int i=0; sIdArg[i].mName; ++i) - if (type==sIdArg[i].mType) + for (int i = 0; sIdArg[i].mName; ++i) + if (type == sIdArg[i].mType) { mArgumentType = ArgumentType_Id; mClass = sIdArg[i].mClass; return; } - for (int i=0; sIndexArg[i].mName; ++i) - if (type==sIndexArg[i].mType) + for (int i = 0; sIndexArg[i].mName; ++i) + if (type == sIndexArg[i].mType) { mArgumentType = ArgumentType_Index; mClass = sIndexArg[i].mClass; return; } - throw std::logic_error ("invalid argument-less UniversalId type"); + throw std::logic_error("invalid argument-less UniversalId type"); } -CSMWorld::UniversalId::UniversalId (Type type, const std::string& id) -: mArgumentType (ArgumentType_Id), mType (type), mId (id), mIndex (0) +CSMWorld::UniversalId::UniversalId(Type type, const std::string& id) + : mArgumentType(ArgumentType_Id) + , mType(type) + , mId(id) + , mIndex(0) { - for (int i=0; sIdArg[i].mName; ++i) - if (type==sIdArg[i].mType) + for (int i = 0; sIdArg[i].mName; ++i) + if (type == sIdArg[i].mType) { mClass = sIdArg[i].mClass; return; } - throw std::logic_error ("invalid ID argument UniversalId type"); + throw std::logic_error("invalid ID argument UniversalId type"); } -CSMWorld::UniversalId::UniversalId (Type type, int index) -: mArgumentType (ArgumentType_Index), mType (type), mIndex (index) +CSMWorld::UniversalId::UniversalId(Type type, int index) + : mArgumentType(ArgumentType_Index) + , mType(type) + , mIndex(index) { - for (int i=0; sIndexArg[i].mName; ++i) - if (type==sIndexArg[i].mType) + for (int i = 0; sIndexArg[i].mName; ++i) + if (type == sIndexArg[i].mType) { mClass = sIndexArg[i].mClass; return; } - throw std::logic_error ("invalid index argument UniversalId type"); + throw std::logic_error("invalid index argument UniversalId type"); } CSMWorld::UniversalId::Class CSMWorld::UniversalId::getClass() const @@ -254,61 +304,67 @@ CSMWorld::UniversalId::Type CSMWorld::UniversalId::getType() const const std::string& CSMWorld::UniversalId::getId() const { - if (mArgumentType!=ArgumentType_Id) - throw std::logic_error ("invalid access to ID of non-ID UniversalId"); + if (mArgumentType != ArgumentType_Id) + throw std::logic_error("invalid access to ID of non-ID UniversalId"); return mId; } int CSMWorld::UniversalId::getIndex() const { - if (mArgumentType!=ArgumentType_Index) - throw std::logic_error ("invalid access to index of non-index UniversalId"); + if (mArgumentType != ArgumentType_Index) + throw std::logic_error("invalid access to index of non-index UniversalId"); return mIndex; } -bool CSMWorld::UniversalId::isEqual (const UniversalId& universalId) const +bool CSMWorld::UniversalId::isEqual(const UniversalId& universalId) const { - if (mClass!=universalId.mClass || mArgumentType!=universalId.mArgumentType || mType!=universalId.mType) - return false; + if (mClass != universalId.mClass || mArgumentType != universalId.mArgumentType || mType != universalId.mType) + return false; switch (mArgumentType) { - case ArgumentType_Id: return mId==universalId.mId; - case ArgumentType_Index: return mIndex==universalId.mIndex; + case ArgumentType_Id: + return mId == universalId.mId; + case ArgumentType_Index: + return mIndex == universalId.mIndex; - default: return true; + default: + return true; } } -bool CSMWorld::UniversalId::isLess (const UniversalId& universalId) const +bool CSMWorld::UniversalId::isLess(const UniversalId& universalId) const { - if (mTypeuniversalId.mType) + if (mType > universalId.mType) return false; switch (mArgumentType) { - case ArgumentType_Id: return mId CSMWorld::UniversalId::listReferenceableTypes() { std::vector list; - for (int i=0; sIdArg[i].mName; ++i) - if (sIdArg[i].mClass==Class_RefRecord) - list.push_back (sIdArg[i].mType); + for (int i = 0; sIdArg[i].mName; ++i) + if (sIdArg[i].mClass == Class_RefRecord) + list.push_back(sIdArg[i].mType); return list; } -std::vector CSMWorld::UniversalId::listTypes (int classes) +std::vector CSMWorld::UniversalId::listTypes(int classes) { std::vector list; - for (int i=0; sNoArg[i].mName; ++i) + for (int i = 0; sNoArg[i].mName; ++i) if (sNoArg[i].mClass & classes) - list.push_back (sNoArg[i].mType); + list.push_back(sNoArg[i].mType); - for (int i=0; sIdArg[i].mName; ++i) + for (int i = 0; sIdArg[i].mName; ++i) if (sIdArg[i].mClass & classes) - list.push_back (sIdArg[i].mType); + list.push_back(sIdArg[i].mType); - for (int i=0; sIndexArg[i].mName; ++i) + for (int i = 0; sIndexArg[i].mName; ++i) if (sIndexArg[i].mClass & classes) - list.push_back (sIndexArg[i].mType); + list.push_back(sIndexArg[i].mType); return list; } -CSMWorld::UniversalId::Type CSMWorld::UniversalId::getParentType (Type type) +CSMWorld::UniversalId::Type CSMWorld::UniversalId::getParentType(Type type) { - for (int i=0; sIdArg[i].mType; ++i) - if (type==sIdArg[i].mType) + for (int i = 0; sIdArg[i].mType; ++i) + if (type == sIdArg[i].mType) { - if (sIdArg[i].mClass==Class_RefRecord) + if (sIdArg[i].mClass == Class_RefRecord) return Type_Referenceables; - if (sIdArg[i].mClass==Class_SubRecord || sIdArg[i].mClass==Class_Record || - sIdArg[i].mClass==Class_Resource) + if (sIdArg[i].mClass == Class_SubRecord || sIdArg[i].mClass == Class_Record + || sIdArg[i].mClass == Class_Resource) { - if (type==Type_Cell_Missing) + if (type == Type_Cell_Missing) return Type_Cells; - return static_cast (type-1); + return static_cast(type - 1); } break; @@ -392,17 +453,17 @@ CSMWorld::UniversalId::Type CSMWorld::UniversalId::getParentType (Type type) return Type_None; } -bool CSMWorld::operator== (const CSMWorld::UniversalId& left, const CSMWorld::UniversalId& right) +bool CSMWorld::operator==(const CSMWorld::UniversalId& left, const CSMWorld::UniversalId& right) { - return left.isEqual (right); + return left.isEqual(right); } -bool CSMWorld::operator!= (const CSMWorld::UniversalId& left, const CSMWorld::UniversalId& right) +bool CSMWorld::operator!=(const CSMWorld::UniversalId& left, const CSMWorld::UniversalId& right) { - return !left.isEqual (right); + return !left.isEqual(right); } -bool CSMWorld::operator< (const UniversalId& left, const UniversalId& right) +bool CSMWorld::operator<(const UniversalId& left, const UniversalId& right) { - return left.isLess (right); + return left.isLess(right); } diff --git a/apps/opencs/model/world/universalid.hpp b/apps/opencs/model/world/universalid.hpp index 09fd8f3bb9..5db1f02f1e 100644 --- a/apps/opencs/model/world/universalid.hpp +++ b/apps/opencs/model/world/universalid.hpp @@ -10,196 +10,196 @@ namespace CSMWorld { class UniversalId { - public: - - enum Class - { - Class_None = 0, - Class_Record = 1, - Class_RefRecord = 2, // referenceable record - Class_SubRecord = 4, - Class_RecordList = 8, - Class_Collection = 16, // multiple types of records combined - Class_Transient = 32, // not part of the world data or the project data - Class_NonRecord = 64, // record like data that is not part of the world - Class_Resource = 128, ///< \attention Resource IDs are unique only within the - /// respective collection - Class_ResourceList = 256 - }; - - enum ArgumentType - { - ArgumentType_None, - ArgumentType_Id, - ArgumentType_Index - }; - - /// \note A record list type must always be immediately followed by the matching - /// record type, if this type is of class SubRecord or Record. - enum Type - { - Type_None = 0, - Type_Globals, - Type_Global, - Type_VerificationResults, - Type_Gmsts, - Type_Gmst, - Type_Skills, - Type_Skill, - Type_Classes, - Type_Class, - Type_Factions, - Type_Faction, - Type_Races, - Type_Race, - Type_Sounds, - Type_Sound, - Type_Scripts, - Type_Script, - Type_Regions, - Type_Region, - Type_Birthsigns, - Type_Birthsign, - Type_Spells, - Type_Spell, - Type_Cells, - Type_Cell, - Type_Cell_Missing, //For cells that does not exist yet. - Type_Referenceables, - Type_Referenceable, - Type_Activator, - Type_Potion, - Type_Apparatus, - Type_Armor, - Type_Book, - Type_Clothing, - Type_Container, - Type_Creature, - Type_Door, - Type_Ingredient, - Type_CreatureLevelledList, - Type_ItemLevelledList, - Type_Light, - Type_Lockpick, - Type_Miscellaneous, - Type_Npc, - Type_Probe, - Type_Repair, - Type_Static, - Type_Weapon, - Type_References, - Type_Reference, - Type_RegionMap, - Type_Filters, - Type_Filter, - Type_Topics, - Type_Topic, - Type_Journals, - Type_Journal, - Type_TopicInfos, - Type_TopicInfo, - Type_JournalInfos, - Type_JournalInfo, - Type_Scene, - Type_Preview, - Type_LoadErrorLog, - Type_Enchantments, - Type_Enchantment, - Type_BodyParts, - Type_BodyPart, - Type_Meshes, - Type_Mesh, - Type_Icons, - Type_Icon, - Type_Musics, - Type_Music, - Type_SoundsRes, - Type_SoundRes, - Type_Textures, - Type_Texture, - Type_Videos, - Type_Video, - Type_DebugProfiles, - Type_DebugProfile, - Type_SoundGens, - Type_SoundGen, - Type_MagicEffects, - Type_MagicEffect, - Type_Lands, - Type_Land, - Type_LandTextures, - Type_LandTexture, - Type_Pathgrids, - Type_Pathgrid, - Type_StartScripts, - Type_StartScript, - Type_Search, - Type_MetaDatas, - Type_MetaData, - Type_RunLog - }; - - enum { NumberOfTypes = Type_RunLog+1 }; - - private: - - Class mClass; - ArgumentType mArgumentType; - Type mType; - std::string mId; - int mIndex; - - public: - - UniversalId (const std::string& universalId); - - UniversalId (Type type = Type_None); - - UniversalId (Type type, const std::string& id); - ///< Using a type for a non-ID-argument UniversalId will throw an exception. - - UniversalId (Type type, int index); - ///< Using a type for a non-index-argument UniversalId will throw an exception. - - Class getClass() const; - - ArgumentType getArgumentType() const; - - Type getType() const; - - const std::string& getId() const; - ///< Calling this function for a non-ID type will throw an exception. - - int getIndex() const; - ///< Calling this function for a non-index type will throw an exception. - - bool isEqual (const UniversalId& universalId) const; - - bool isLess (const UniversalId& universalId) const; - - std::string getTypeName() const; - - std::string toString() const; - - std::string getIcon() const; - ///< Will return an empty string, if no icon is available. - - static std::vector listReferenceableTypes(); - - static std::vector listTypes (int classes); - - /// If \a type is a SubRecord, RefRecord or Record type return the type of the table - /// that contains records of type \a type. - /// Otherwise return Type_None. - static Type getParentType (Type type); + public: + enum Class + { + Class_None = 0, + Class_Record = 1, + Class_RefRecord = 2, // referenceable record + Class_SubRecord = 4, + Class_RecordList = 8, + Class_Collection = 16, // multiple types of records combined + Class_Transient = 32, // not part of the world data or the project data + Class_NonRecord = 64, // record like data that is not part of the world + Class_Resource = 128, ///< \attention Resource IDs are unique only within the + /// respective collection + Class_ResourceList = 256 + }; + + enum ArgumentType + { + ArgumentType_None, + ArgumentType_Id, + ArgumentType_Index + }; + + /// \note A record list type must always be immediately followed by the matching + /// record type, if this type is of class SubRecord or Record. + enum Type + { + Type_None = 0, + Type_Globals, + Type_Global, + Type_VerificationResults, + Type_Gmsts, + Type_Gmst, + Type_Skills, + Type_Skill, + Type_Classes, + Type_Class, + Type_Factions, + Type_Faction, + Type_Races, + Type_Race, + Type_Sounds, + Type_Sound, + Type_Scripts, + Type_Script, + Type_Regions, + Type_Region, + Type_Birthsigns, + Type_Birthsign, + Type_Spells, + Type_Spell, + Type_Cells, + Type_Cell, + Type_Cell_Missing, // For cells that does not exist yet. + Type_Referenceables, + Type_Referenceable, + Type_Activator, + Type_Potion, + Type_Apparatus, + Type_Armor, + Type_Book, + Type_Clothing, + Type_Container, + Type_Creature, + Type_Door, + Type_Ingredient, + Type_CreatureLevelledList, + Type_ItemLevelledList, + Type_Light, + Type_Lockpick, + Type_Miscellaneous, + Type_Npc, + Type_Probe, + Type_Repair, + Type_Static, + Type_Weapon, + Type_References, + Type_Reference, + Type_RegionMap, + Type_Filters, + Type_Filter, + Type_Topics, + Type_Topic, + Type_Journals, + Type_Journal, + Type_TopicInfos, + Type_TopicInfo, + Type_JournalInfos, + Type_JournalInfo, + Type_Scene, + Type_Preview, + Type_LoadErrorLog, + Type_Enchantments, + Type_Enchantment, + Type_BodyParts, + Type_BodyPart, + Type_Meshes, + Type_Mesh, + Type_Icons, + Type_Icon, + Type_Musics, + Type_Music, + Type_SoundsRes, + Type_SoundRes, + Type_Textures, + Type_Texture, + Type_Videos, + Type_Video, + Type_DebugProfiles, + Type_DebugProfile, + Type_SoundGens, + Type_SoundGen, + Type_MagicEffects, + Type_MagicEffect, + Type_Lands, + Type_Land, + Type_LandTextures, + Type_LandTexture, + Type_Pathgrids, + Type_Pathgrid, + Type_StartScripts, + Type_StartScript, + Type_Search, + Type_MetaDatas, + Type_MetaData, + Type_RunLog + }; + + enum + { + NumberOfTypes = Type_RunLog + 1 + }; + + private: + Class mClass; + ArgumentType mArgumentType; + Type mType; + std::string mId; + int mIndex; + + public: + UniversalId(const std::string& universalId); + + UniversalId(Type type = Type_None); + + UniversalId(Type type, const std::string& id); + ///< Using a type for a non-ID-argument UniversalId will throw an exception. + + UniversalId(Type type, int index); + ///< Using a type for a non-index-argument UniversalId will throw an exception. + + Class getClass() const; + + ArgumentType getArgumentType() const; + + Type getType() const; + + const std::string& getId() const; + ///< Calling this function for a non-ID type will throw an exception. + + int getIndex() const; + ///< Calling this function for a non-index type will throw an exception. + + bool isEqual(const UniversalId& universalId) const; + + bool isLess(const UniversalId& universalId) const; + + std::string getTypeName() const; + + std::string toString() const; + + std::string getIcon() const; + ///< Will return an empty string, if no icon is available. + + static std::vector listReferenceableTypes(); + + static std::vector listTypes(int classes); + + /// If \a type is a SubRecord, RefRecord or Record type return the type of the table + /// that contains records of type \a type. + /// Otherwise return Type_None. + static Type getParentType(Type type); }; - bool operator== (const UniversalId& left, const UniversalId& right); - bool operator!= (const UniversalId& left, const UniversalId& right); + bool operator==(const UniversalId& left, const UniversalId& right); + bool operator!=(const UniversalId& left, const UniversalId& right); - bool operator< (const UniversalId& left, const UniversalId& right); + bool operator<(const UniversalId& left, const UniversalId& right); } -Q_DECLARE_METATYPE (CSMWorld::UniversalId) +Q_DECLARE_METATYPE(CSMWorld::UniversalId) #endif diff --git a/apps/opencs/view/doc/adjusterwidget.cpp b/apps/opencs/view/doc/adjusterwidget.cpp index 6dfd6b9d3e..d3014c9f09 100644 --- a/apps/opencs/view/doc/adjusterwidget.cpp +++ b/apps/opencs/view/doc/adjusterwidget.cpp @@ -9,32 +9,34 @@ #include #include -CSVDoc::AdjusterWidget::AdjusterWidget (QWidget *parent) - : QWidget (parent), mValid (false), mAction (ContentAction_Undefined) +CSVDoc::AdjusterWidget::AdjusterWidget(QWidget* parent) + : QWidget(parent) + , mValid(false) + , mAction(ContentAction_Undefined) { - QHBoxLayout *layout = new QHBoxLayout (this); + QHBoxLayout* layout = new QHBoxLayout(this); - mIcon = new QLabel (this); + mIcon = new QLabel(this); - layout->addWidget (mIcon, 0); + layout->addWidget(mIcon, 0); - mMessage = new QLabel (this); - mMessage->setWordWrap (true); - mMessage->setSizePolicy (QSizePolicy (QSizePolicy::Minimum, QSizePolicy::Minimum)); + mMessage = new QLabel(this); + mMessage->setWordWrap(true); + mMessage->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum)); - layout->addWidget (mMessage, 1); + layout->addWidget(mMessage, 1); - setName ("", false); + setName("", false); - setLayout (layout); + setLayout(layout); } -void CSVDoc::AdjusterWidget::setAction (ContentAction action) +void CSVDoc::AdjusterWidget::setAction(ContentAction action) { mAction = action; } -void CSVDoc::AdjusterWidget::setLocalData (const std::filesystem::path& localData) +void CSVDoc::AdjusterWidget::setLocalData(const std::filesystem::path& localData) { mLocalData = localData; } @@ -42,7 +44,7 @@ void CSVDoc::AdjusterWidget::setLocalData (const std::filesystem::path& localDat std::filesystem::path CSVDoc::AdjusterWidget::getPath() const { if (!mValid) - throw std::logic_error ("invalid content file path"); + throw std::logic_error("invalid content file path"); return mResultPath; } @@ -52,12 +54,12 @@ bool CSVDoc::AdjusterWidget::isValid() const return mValid; } -void CSVDoc::AdjusterWidget::setFilenameCheck (bool doCheck) +void CSVDoc::AdjusterWidget::setFilenameCheck(bool doCheck) { mDoFilenameCheck = doCheck; } -void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon) +void CSVDoc::AdjusterWidget::setName(const QString& name, bool addon) { QString message; @@ -74,23 +76,22 @@ void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon) const auto extension = Misc::StringUtils::lowerCase(path.extension().u8string()); - bool isLegacyPath = (extension == u8".esm" || - extension == u8".esp"); + bool isLegacyPath = (extension == u8".esm" || extension == u8".esp"); bool isFilePathChanged = (path.parent_path() != mLocalData); if (isLegacyPath) - path.replace_extension (addon ? ".omwaddon" : ".omwgame"); + path.replace_extension(addon ? ".omwaddon" : ".omwgame"); - //if the file came from data-local and is not a legacy file to be converted, - //don't worry about doing a file check. + // if the file came from data-local and is not a legacy file to be converted, + // don't worry about doing a file check. if (!isFilePathChanged && !isLegacyPath) { // path already points to the local data directory message = "Will be saved as: " + Files::pathToQString(path); mResultPath = path; } - //in all other cases, ensure the path points to data-local and do an existing file check + // in all other cases, ensure the path points to data-local and do an existing file check else { // path points somewhere else or is a leaf name. @@ -100,7 +101,7 @@ void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon) message = "Will be saved as: " + Files::pathToQString(path); mResultPath = path; - if (std::filesystem::exists (path)) + if (std::filesystem::exists(path)) { /// \todo add an user setting to make this an error. message += "

A file with the same name already exists. If you continue, it will be overwritten."; @@ -109,10 +110,12 @@ void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon) } } - mMessage->setText (message); - mIcon->setPixmap (style()->standardIcon ( - mValid ? (warning ? QStyle::SP_MessageBoxWarning : QStyle::SP_MessageBoxInformation) : QStyle::SP_MessageBoxCritical). - pixmap (QSize (16, 16))); + mMessage->setText(message); + mIcon->setPixmap( + style() + ->standardIcon(mValid ? (warning ? QStyle::SP_MessageBoxWarning : QStyle::SP_MessageBoxInformation) + : QStyle::SP_MessageBoxCritical) + .pixmap(QSize(16, 16))); - emit stateChanged (mValid); + emit stateChanged(mValid); } diff --git a/apps/opencs/view/doc/adjusterwidget.hpp b/apps/opencs/view/doc/adjusterwidget.hpp index 7e6330a652..53192d8414 100644 --- a/apps/opencs/view/doc/adjusterwidget.hpp +++ b/apps/opencs/view/doc/adjusterwidget.hpp @@ -1,7 +1,6 @@ #ifndef CSV_DOC_ADJUSTERWIDGET_H #define CSV_DOC_ADJUSTERWIDGET_H - #include #include @@ -19,38 +18,36 @@ namespace CSVDoc class AdjusterWidget : public QWidget { - Q_OBJECT - - public: - - std::filesystem::path mLocalData; - QLabel *mMessage; - QLabel *mIcon; - bool mValid; - std::filesystem::path mResultPath; - ContentAction mAction; - bool mDoFilenameCheck; + Q_OBJECT - public: + public: + std::filesystem::path mLocalData; + QLabel* mMessage; + QLabel* mIcon; + bool mValid; + std::filesystem::path mResultPath; + ContentAction mAction; + bool mDoFilenameCheck; - AdjusterWidget (QWidget *parent = nullptr); + public: + AdjusterWidget(QWidget* parent = nullptr); - void setLocalData (const std::filesystem::path& localData); - void setAction (ContentAction action); + void setLocalData(const std::filesystem::path& localData); + void setAction(ContentAction action); - void setFilenameCheck (bool doCheck); - bool isValid() const; + void setFilenameCheck(bool doCheck); + bool isValid() const; - std::filesystem::path getPath() const; - ///< This function must not be called if there is no valid path. + std::filesystem::path getPath() const; + ///< This function must not be called if there is no valid path. - public slots: + public slots: - void setName (const QString& name, bool addon); + void setName(const QString& name, bool addon); - signals: + signals: - void stateChanged (bool valid); + void stateChanged(bool valid); }; } diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index 5a7852b4db..ee52f153c7 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -1,23 +1,28 @@ #include "filedialog.hpp" -#include #include +#include #include "components/contentselector/model/esmfile.hpp" #include "components/contentselector/view/contentselector.hpp" -#include "filewidget.hpp" #include "adjusterwidget.hpp" +#include "filewidget.hpp" -CSVDoc::FileDialog::FileDialog(QWidget *parent) : - QDialog(parent), mSelector (nullptr), mAction(ContentAction_Undefined), mFileWidget (nullptr), mAdjusterWidget (nullptr), mDialogBuilt(false) +CSVDoc::FileDialog::FileDialog(QWidget* parent) + : QDialog(parent) + , mSelector(nullptr) + , mAction(ContentAction_Undefined) + , mFileWidget(nullptr) + , mAdjusterWidget(nullptr) + , mDialogBuilt(false) { - ui.setupUi (this); + ui.setupUi(this); resize(400, 400); - setObjectName ("FileDialog"); - mSelector = new ContentSelectorView::ContentSelector (ui.contentSelectorWidget, /*showOMWScripts=*/false); - mAdjusterWidget = new AdjusterWidget (this); + setObjectName("FileDialog"); + mSelector = new ContentSelectorView::ContentSelector(ui.contentSelectorWidget, /*showOMWScripts=*/false); + mAdjusterWidget = new AdjusterWidget(this); } void CSVDoc::FileDialog::addFiles(const std::vector& dataDirs) @@ -30,7 +35,7 @@ void CSVDoc::FileDialog::addFiles(const std::vector& data mSelector->sortFiles(); } -void CSVDoc::FileDialog::setEncoding(const QString &encoding) +void CSVDoc::FileDialog::setEncoding(const QString& encoding) { mSelector->setEncoding(encoding); } @@ -44,46 +49,46 @@ QStringList CSVDoc::FileDialog::selectedFilePaths() { QStringList filePaths; - for (ContentSelectorModel::EsmFile *file : mSelector->selectedFiles() ) + for (ContentSelectorModel::EsmFile* file : mSelector->selectedFiles()) filePaths.append(file->filePath()); return filePaths; } -void CSVDoc::FileDialog::setLocalData (const std::filesystem::path& localData) +void CSVDoc::FileDialog::setLocalData(const std::filesystem::path& localData) { - mAdjusterWidget->setLocalData (localData); + mAdjusterWidget->setLocalData(localData); } -void CSVDoc::FileDialog::showDialog (ContentAction action) +void CSVDoc::FileDialog::showDialog(ContentAction action) { mAction = action; - ui.projectGroupBoxLayout->insertWidget (0, mAdjusterWidget); + ui.projectGroupBoxLayout->insertWidget(0, mAdjusterWidget); switch (mAction) { - case ContentAction_New: - buildNewFileView(); - break; + case ContentAction_New: + buildNewFileView(); + break; - case ContentAction_Edit: - buildOpenFileView(); - break; + case ContentAction_Edit: + buildOpenFileView(); + break; - default: - break; + default: + break; } - mAdjusterWidget->setFilenameCheck (mAction == ContentAction_New); + mAdjusterWidget->setFilenameCheck(mAction == ContentAction_New); - if(!mDialogBuilt) + if (!mDialogBuilt) { - //connections common to both dialog view flavors - connect (mSelector, &ContentSelectorView::ContentSelector::signalCurrentGamefileIndexChanged, - this, qOverload(&FileDialog::slotUpdateAcceptButton)); + // connections common to both dialog view flavors + connect(mSelector, &ContentSelectorView::ContentSelector::signalCurrentGamefileIndexChanged, this, + qOverload(&FileDialog::slotUpdateAcceptButton)); - connect (ui.projectButtonBox, &QDialogButtonBox::rejected, this, &FileDialog::slotRejected); + connect(ui.projectButtonBox, &QDialogButtonBox::rejected, this, &FileDialog::slotRejected); mDialogBuilt = true; } @@ -96,48 +101,47 @@ void CSVDoc::FileDialog::buildNewFileView() { setWindowTitle(tr("Create a new addon")); - QPushButton* createButton = ui.projectButtonBox->button (QDialogButtonBox::Ok); - createButton->setText ("Create"); - createButton->setEnabled (false); + QPushButton* createButton = ui.projectButtonBox->button(QDialogButtonBox::Ok); + createButton->setText("Create"); + createButton->setEnabled(false); - if(!mFileWidget) + if (!mFileWidget) { - mFileWidget = new FileWidget (this); + mFileWidget = new FileWidget(this); - mFileWidget->setType (true); + mFileWidget->setType(true); mFileWidget->extensionLabelIsVisible(true); - connect (mFileWidget, &FileWidget::nameChanged, - mAdjusterWidget, &AdjusterWidget::setName); + connect(mFileWidget, &FileWidget::nameChanged, mAdjusterWidget, &AdjusterWidget::setName); - connect (mFileWidget, &FileWidget::nameChanged, - this, qOverload(&FileDialog::slotUpdateAcceptButton)); + connect(mFileWidget, &FileWidget::nameChanged, this, + qOverload(&FileDialog::slotUpdateAcceptButton)); } - ui.projectGroupBoxLayout->insertWidget (0, mFileWidget); + ui.projectGroupBoxLayout->insertWidget(0, mFileWidget); - connect (ui.projectButtonBox, &QDialogButtonBox::accepted, this, &FileDialog::slotNewFile); + connect(ui.projectButtonBox, &QDialogButtonBox::accepted, this, &FileDialog::slotNewFile); } void CSVDoc::FileDialog::buildOpenFileView() { setWindowTitle(tr("Open")); - ui.projectGroupBox->setTitle (QString("")); - ui.projectButtonBox->button(QDialogButtonBox::Ok)->setText ("Open"); - if(mSelector->isGamefileSelected()) - ui.projectButtonBox->button(QDialogButtonBox::Ok)->setEnabled (true); + ui.projectGroupBox->setTitle(QString("")); + ui.projectButtonBox->button(QDialogButtonBox::Ok)->setText("Open"); + if (mSelector->isGamefileSelected()) + ui.projectButtonBox->button(QDialogButtonBox::Ok)->setEnabled(true); else - ui.projectButtonBox->button(QDialogButtonBox::Ok)->setEnabled (false); + ui.projectButtonBox->button(QDialogButtonBox::Ok)->setEnabled(false); - if(!mDialogBuilt) + if (!mDialogBuilt) { - connect (mSelector, &ContentSelectorView::ContentSelector::signalAddonDataChanged, - this, &FileDialog::slotAddonDataChanged); + connect(mSelector, &ContentSelectorView::ContentSelector::signalAddonDataChanged, this, + &FileDialog::slotAddonDataChanged); } - connect (ui.projectButtonBox, &QDialogButtonBox::accepted, this, &FileDialog::slotOpenFile); + connect(ui.projectButtonBox, &QDialogButtonBox::accepted, this, &FileDialog::slotOpenFile); } -void CSVDoc::FileDialog::slotAddonDataChanged(const QModelIndex &topleft, const QModelIndex &bottomright) +void CSVDoc::FileDialog::slotAddonDataChanged(const QModelIndex& topleft, const QModelIndex& bottomright) { slotUpdateAcceptButton(0); } @@ -149,10 +153,10 @@ void CSVDoc::FileDialog::slotUpdateAcceptButton(int) if (mFileWidget && mAction == ContentAction_New) name = mFileWidget->getName(); - slotUpdateAcceptButton (name, true); + slotUpdateAcceptButton(name, true); } -void CSVDoc::FileDialog::slotUpdateAcceptButton(const QString &name, bool) +void CSVDoc::FileDialog::slotUpdateAcceptButton(const QString& name, bool) { bool success = !mSelector->selectedFiles().empty(); @@ -162,13 +166,13 @@ void CSVDoc::FileDialog::slotUpdateAcceptButton(const QString &name, bool) success = !name.isEmpty(); else if (success) { - ContentSelectorModel::EsmFile *file = mSelector->selectedFiles().back(); - mAdjusterWidget->setName (file->filePath(), !file->isGameFile()); + ContentSelectorModel::EsmFile* file = mSelector->selectedFiles().back(); + mAdjusterWidget->setName(file->filePath(), !file->isGameFile()); } else - mAdjusterWidget->setName ("", true); + mAdjusterWidget->setName("", true); - ui.projectButtonBox->button (QDialogButtonBox::Ok)->setEnabled (success); + ui.projectButtonBox->button(QDialogButtonBox::Ok)->setEnabled(success); } QString CSVDoc::FileDialog::filename() const @@ -182,9 +186,9 @@ QString CSVDoc::FileDialog::filename() const void CSVDoc::FileDialog::slotRejected() { emit rejected(); - disconnect (ui.projectButtonBox, &QDialogButtonBox::accepted, this, &FileDialog::slotNewFile); - disconnect (ui.projectButtonBox, &QDialogButtonBox::accepted, this, &FileDialog::slotOpenFile); - if(mFileWidget) + disconnect(ui.projectButtonBox, &QDialogButtonBox::accepted, this, &FileDialog::slotNewFile); + disconnect(ui.projectButtonBox, &QDialogButtonBox::accepted, this, &FileDialog::slotOpenFile); + if (mFileWidget) { delete mFileWidget; mFileWidget = nullptr; @@ -194,23 +198,23 @@ void CSVDoc::FileDialog::slotRejected() void CSVDoc::FileDialog::slotNewFile() { - emit signalCreateNewFile (mAdjusterWidget->getPath()); - if(mFileWidget) + emit signalCreateNewFile(mAdjusterWidget->getPath()); + if (mFileWidget) { delete mFileWidget; mFileWidget = nullptr; } - disconnect (ui.projectButtonBox, &QDialogButtonBox::accepted, this, &FileDialog::slotNewFile); + disconnect(ui.projectButtonBox, &QDialogButtonBox::accepted, this, &FileDialog::slotNewFile); close(); } void CSVDoc::FileDialog::slotOpenFile() { - ContentSelectorModel::EsmFile *file = mSelector->selectedFiles().back(); + ContentSelectorModel::EsmFile* file = mSelector->selectedFiles().back(); - mAdjusterWidget->setName (file->filePath(), !file->isGameFile()); + mAdjusterWidget->setName(file->filePath(), !file->isGameFile()); - emit signalOpenFiles (mAdjusterWidget->getPath()); - disconnect (ui.projectButtonBox, &QDialogButtonBox::accepted, this, &FileDialog::slotOpenFile); + emit signalOpenFiles(mAdjusterWidget->getPath()); + disconnect(ui.projectButtonBox, &QDialogButtonBox::accepted, this, &FileDialog::slotOpenFile); close(); } diff --git a/apps/opencs/view/doc/filedialog.hpp b/apps/opencs/view/doc/filedialog.hpp index 154efc14ea..4855297bf5 100644 --- a/apps/opencs/view/doc/filedialog.hpp +++ b/apps/opencs/view/doc/filedialog.hpp @@ -10,7 +10,7 @@ #ifndef CS_QT_STD_FILESYSTEM_PATH_DECLARED #define CS_QT_STD_FILESYSTEM_PATH_DECLARED -Q_DECLARE_METATYPE (std::filesystem::path) +Q_DECLARE_METATYPE(std::filesystem::path) #endif #endif @@ -31,46 +31,43 @@ namespace CSVDoc Q_OBJECT private: - - ContentSelectorView::ContentSelector *mSelector; + ContentSelectorView::ContentSelector* mSelector; Ui::FileDialog ui; ContentAction mAction; - FileWidget *mFileWidget; - AdjusterWidget *mAdjusterWidget; + FileWidget* mFileWidget; + AdjusterWidget* mAdjusterWidget; bool mDialogBuilt; public: - - explicit FileDialog(QWidget *parent = nullptr); - void showDialog (ContentAction action); + explicit FileDialog(QWidget* parent = nullptr); + void showDialog(ContentAction action); void addFiles(const std::vector& dataDirs); - void setEncoding (const QString &encoding); - void clearFiles (); + void setEncoding(const QString& encoding); + void clearFiles(); QString filename() const; QStringList selectedFilePaths(); - void setLocalData (const std::filesystem::path& localData); + void setLocalData(const std::filesystem::path& localData); private: - void buildNewFileView(); void buildOpenFileView(); signals: - void signalOpenFiles (const std::filesystem::path &path); - void signalCreateNewFile (const std::filesystem::path &path); + void signalOpenFiles(const std::filesystem::path& path); + void signalCreateNewFile(const std::filesystem::path& path); - void signalUpdateAcceptButton (bool, int); + void signalUpdateAcceptButton(bool, int); private slots: void slotNewFile(); void slotOpenFile(); - void slotUpdateAcceptButton (int); - void slotUpdateAcceptButton (const QString &, bool); + void slotUpdateAcceptButton(int); + void slotUpdateAcceptButton(const QString&, bool); void slotRejected(); void slotAddonDataChanged(const QModelIndex& topleft, const QModelIndex& bottomright); }; diff --git a/apps/opencs/view/doc/filewidget.cpp b/apps/opencs/view/doc/filewidget.cpp index 45ce08daad..1048601790 100644 --- a/apps/opencs/view/doc/filewidget.cpp +++ b/apps/opencs/view/doc/filewidget.cpp @@ -1,38 +1,40 @@ #include "filewidget.hpp" #include -#include #include -#include +#include #include +#include QString CSVDoc::FileWidget::getExtension() const { return mAddon ? ".omwaddon" : ".omwgame"; } -CSVDoc::FileWidget::FileWidget (QWidget *parent) : QWidget (parent), mAddon (false) +CSVDoc::FileWidget::FileWidget(QWidget* parent) + : QWidget(parent) + , mAddon(false) { - QHBoxLayout *layout = new QHBoxLayout (this); + QHBoxLayout* layout = new QHBoxLayout(this); - mInput = new QLineEdit (this); + mInput = new QLineEdit(this); - layout->addWidget (mInput, 1); + layout->addWidget(mInput, 1); - mType = new QLabel (this); + mType = new QLabel(this); - layout ->addWidget (mType); + layout->addWidget(mType); - connect (mInput, &QLineEdit::textChanged, this, &FileWidget::textChanged); + connect(mInput, &QLineEdit::textChanged, this, &FileWidget::textChanged); - setLayout (layout); + setLayout(layout); } -void CSVDoc::FileWidget::setType (bool addon) +void CSVDoc::FileWidget::setType(bool addon) { mAddon = addon; - mType->setText (getExtension()); + mType->setText(getExtension()); } QString CSVDoc::FileWidget::getName() const @@ -45,9 +47,9 @@ QString CSVDoc::FileWidget::getName() const return text + getExtension(); } -void CSVDoc::FileWidget::textChanged (const QString& text) +void CSVDoc::FileWidget::textChanged(const QString& text) { - emit nameChanged (getName(), mAddon); + emit nameChanged(getName(), mAddon); } void CSVDoc::FileWidget::extensionLabelIsVisible(bool visible) @@ -55,10 +57,10 @@ void CSVDoc::FileWidget::extensionLabelIsVisible(bool visible) mType->setVisible(visible); } -void CSVDoc::FileWidget::setName (const std::string& text) +void CSVDoc::FileWidget::setName(const std::string& text) { - QString text2 = QString::fromUtf8 (text.c_str()); + QString text2 = QString::fromUtf8(text.c_str()); - mInput->setText (text2); - textChanged (text2); + mInput->setText(text2); + textChanged(text2); } diff --git a/apps/opencs/view/doc/filewidget.hpp b/apps/opencs/view/doc/filewidget.hpp index 626b8d77d8..e50d6f34e0 100644 --- a/apps/opencs/view/doc/filewidget.hpp +++ b/apps/opencs/view/doc/filewidget.hpp @@ -13,33 +13,32 @@ namespace CSVDoc { class FileWidget : public QWidget { - Q_OBJECT + Q_OBJECT - bool mAddon; - QLineEdit *mInput; - QLabel *mType; + bool mAddon; + QLineEdit* mInput; + QLabel* mType; - QString getExtension() const; + QString getExtension() const; - public: + public: + FileWidget(QWidget* parent = nullptr); - FileWidget (QWidget *parent = nullptr); + void setType(bool addon); - void setType (bool addon); + QString getName() const; - QString getName() const; + void extensionLabelIsVisible(bool visible); - void extensionLabelIsVisible(bool visible); + void setName(const std::string& text); - void setName (const std::string& text); + private slots: - private slots: + void textChanged(const QString& text); - void textChanged (const QString& text); + signals: - signals: - - void nameChanged (const QString& file, bool addon); + void nameChanged(const QString& file, bool addon); }; } diff --git a/apps/opencs/view/doc/globaldebugprofilemenu.cpp b/apps/opencs/view/doc/globaldebugprofilemenu.cpp index 5990c179f3..7a91000c10 100644 --- a/apps/opencs/view/doc/globaldebugprofilemenu.cpp +++ b/apps/opencs/view/doc/globaldebugprofilemenu.cpp @@ -1,7 +1,7 @@ #include "globaldebugprofilemenu.hpp" -#include #include +#include #include @@ -15,78 +15,72 @@ void CSVDoc::GlobalDebugProfileMenu::rebuild() delete mActions; mActions = nullptr; - int idColumn = mDebugProfiles->findColumnIndex (CSMWorld::Columns::ColumnId_Id); - int stateColumn = mDebugProfiles->findColumnIndex (CSMWorld::Columns::ColumnId_Modification); - int globalColumn = mDebugProfiles->findColumnIndex ( - CSMWorld::Columns::ColumnId_GlobalProfile); + int idColumn = mDebugProfiles->findColumnIndex(CSMWorld::Columns::ColumnId_Id); + int stateColumn = mDebugProfiles->findColumnIndex(CSMWorld::Columns::ColumnId_Modification); + int globalColumn = mDebugProfiles->findColumnIndex(CSMWorld::Columns::ColumnId_GlobalProfile); int size = mDebugProfiles->rowCount(); std::vector ids; - for (int i=0; idata (mDebugProfiles->index (i, stateColumn)).toInt(); + int state = mDebugProfiles->data(mDebugProfiles->index(i, stateColumn)).toInt(); - bool global = mDebugProfiles->data (mDebugProfiles->index (i, globalColumn)).toInt(); + bool global = mDebugProfiles->data(mDebugProfiles->index(i, globalColumn)).toInt(); - if (state!=CSMWorld::RecordBase::State_Deleted && global) - ids.push_back ( - mDebugProfiles->data (mDebugProfiles->index (i, idColumn)).toString()); + if (state != CSMWorld::RecordBase::State_Deleted && global) + ids.push_back(mDebugProfiles->data(mDebugProfiles->index(i, idColumn)).toString()); } - mActions = new QActionGroup (this); - connect (mActions, &QActionGroup::triggered, this, &GlobalDebugProfileMenu::actionTriggered); + mActions = new QActionGroup(this); + connect(mActions, &QActionGroup::triggered, this, &GlobalDebugProfileMenu::actionTriggered); - std::sort (ids.begin(), ids.end()); + std::sort(ids.begin(), ids.end()); - for (std::vector::const_iterator iter (ids.begin()); iter!=ids.end(); ++iter) + for (std::vector::const_iterator iter(ids.begin()); iter != ids.end(); ++iter) { - mActions->addAction (addAction (*iter)); + mActions->addAction(addAction(*iter)); } } -CSVDoc::GlobalDebugProfileMenu::GlobalDebugProfileMenu (CSMWorld::IdTable *debugProfiles, - QWidget *parent) -: QMenu (parent), mDebugProfiles (debugProfiles), mActions (nullptr) +CSVDoc::GlobalDebugProfileMenu::GlobalDebugProfileMenu(CSMWorld::IdTable* debugProfiles, QWidget* parent) + : QMenu(parent) + , mDebugProfiles(debugProfiles) + , mActions(nullptr) { rebuild(); - connect (mDebugProfiles, &CSMWorld::IdTable::rowsAboutToBeRemoved, - this, &GlobalDebugProfileMenu::profileAboutToBeRemoved); + connect(mDebugProfiles, &CSMWorld::IdTable::rowsAboutToBeRemoved, this, + &GlobalDebugProfileMenu::profileAboutToBeRemoved); - connect (mDebugProfiles, &CSMWorld::IdTable::rowsInserted, - this, &GlobalDebugProfileMenu::profileInserted); + connect(mDebugProfiles, &CSMWorld::IdTable::rowsInserted, this, &GlobalDebugProfileMenu::profileInserted); - connect (mDebugProfiles, &CSMWorld::IdTable::dataChanged, - this, &GlobalDebugProfileMenu::profileChanged); + connect(mDebugProfiles, &CSMWorld::IdTable::dataChanged, this, &GlobalDebugProfileMenu::profileChanged); } -void CSVDoc::GlobalDebugProfileMenu::updateActions (bool running) +void CSVDoc::GlobalDebugProfileMenu::updateActions(bool running) { if (mActions) - mActions->setEnabled (!running); + mActions->setEnabled(!running); } -void CSVDoc::GlobalDebugProfileMenu::profileAboutToBeRemoved (const QModelIndex& parent, - int start, int end) +void CSVDoc::GlobalDebugProfileMenu::profileAboutToBeRemoved(const QModelIndex& parent, int start, int end) { rebuild(); } -void CSVDoc::GlobalDebugProfileMenu::profileInserted (const QModelIndex& parent, int start, - int end) +void CSVDoc::GlobalDebugProfileMenu::profileInserted(const QModelIndex& parent, int start, int end) { rebuild(); } -void CSVDoc::GlobalDebugProfileMenu::profileChanged (const QModelIndex& topLeft, - const QModelIndex& bottomRight) +void CSVDoc::GlobalDebugProfileMenu::profileChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) { rebuild(); } -void CSVDoc::GlobalDebugProfileMenu::actionTriggered (QAction *action) +void CSVDoc::GlobalDebugProfileMenu::actionTriggered(QAction* action) { - emit triggered (std::string (action->text().toUtf8().constData())); + emit triggered(std::string(action->text().toUtf8().constData())); } diff --git a/apps/opencs/view/doc/globaldebugprofilemenu.hpp b/apps/opencs/view/doc/globaldebugprofilemenu.hpp index e12ee306a1..02b26712de 100644 --- a/apps/opencs/view/doc/globaldebugprofilemenu.hpp +++ b/apps/opencs/view/doc/globaldebugprofilemenu.hpp @@ -15,34 +15,32 @@ namespace CSVDoc { class GlobalDebugProfileMenu : public QMenu { - Q_OBJECT + Q_OBJECT - CSMWorld::IdTable *mDebugProfiles; - QActionGroup *mActions; + CSMWorld::IdTable* mDebugProfiles; + QActionGroup* mActions; - private: + private: + void rebuild(); - void rebuild(); + public: + GlobalDebugProfileMenu(CSMWorld::IdTable* debugProfiles, QWidget* parent = nullptr); - public: + void updateActions(bool running); - GlobalDebugProfileMenu (CSMWorld::IdTable *debugProfiles, QWidget *parent = nullptr); + private slots: - void updateActions (bool running); + void profileAboutToBeRemoved(const QModelIndex& parent, int start, int end); - private slots: + void profileInserted(const QModelIndex& parent, int start, int end); - void profileAboutToBeRemoved (const QModelIndex& parent, int start, int end); + void profileChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); - void profileInserted (const QModelIndex& parent, int start, int end); + void actionTriggered(QAction* action); - void profileChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); + signals: - void actionTriggered (QAction *action); - - signals: - - void triggered (const std::string& profile); + void triggered(const std::string& profile); }; } diff --git a/apps/opencs/view/doc/loader.cpp b/apps/opencs/view/doc/loader.cpp index dd37176d76..44e056a5bf 100644 --- a/apps/opencs/view/doc/loader.cpp +++ b/apps/opencs/view/doc/loader.cpp @@ -1,93 +1,99 @@ #include "loader.hpp" -#include -#include -#include +#include #include #include -#include +#include #include +#include +#include #include #include #include "../../model/doc/document.hpp" -void CSVDoc::LoadingDocument::closeEvent (QCloseEvent *event) +void CSVDoc::LoadingDocument::closeEvent(QCloseEvent* event) { event->ignore(); cancel(); } -CSVDoc::LoadingDocument::LoadingDocument (CSMDoc::Document *document) -: mDocument (document), mTotalRecordsLabel (0), mRecordsLabel (0), mAborted (false), mMessages (nullptr), mRecords(0) +CSVDoc::LoadingDocument::LoadingDocument(CSMDoc::Document* document) + : mDocument(document) + , mTotalRecordsLabel(0) + , mRecordsLabel(0) + , mAborted(false) + , mMessages(nullptr) + , mRecords(0) { - setWindowTitle ("Opening " + Files::pathToQString(document->getSavePath().filename())); + setWindowTitle("Opening " + Files::pathToQString(document->getSavePath().filename())); - setMinimumWidth (400); + setMinimumWidth(400); - mLayout = new QVBoxLayout (this); + mLayout = new QVBoxLayout(this); // total progress - mTotalRecordsLabel = new QLabel (this); + mTotalRecordsLabel = new QLabel(this); - mLayout->addWidget (mTotalRecordsLabel); + mLayout->addWidget(mTotalRecordsLabel); - mTotalProgress = new QProgressBar (this); + mTotalProgress = new QProgressBar(this); - mLayout->addWidget (mTotalProgress); + mLayout->addWidget(mTotalProgress); - mTotalProgress->setMinimum (0); - mTotalProgress->setMaximum (document->getData().getTotalRecords(document->getContentFiles())); - mTotalProgress->setTextVisible (true); - mTotalProgress->setValue (0); + mTotalProgress->setMinimum(0); + mTotalProgress->setMaximum(document->getData().getTotalRecords(document->getContentFiles())); + mTotalProgress->setTextVisible(true); + mTotalProgress->setValue(0); mTotalRecords = 0; mFilesLoaded = 0; // record progress - mLayout->addWidget (mRecordsLabel = new QLabel ("Records", this)); + mLayout->addWidget(mRecordsLabel = new QLabel("Records", this)); - mRecordProgress = new QProgressBar (this); + mRecordProgress = new QProgressBar(this); - mLayout->addWidget (mRecordProgress); + mLayout->addWidget(mRecordProgress); - mRecordProgress->setMinimum (0); - mRecordProgress->setTextVisible (true); - mRecordProgress->setValue (0); + mRecordProgress->setMinimum(0); + mRecordProgress->setTextVisible(true); + mRecordProgress->setValue(0); // error message - mError = new QLabel (this); - mError->setWordWrap (true); + mError = new QLabel(this); + mError->setWordWrap(true); - mLayout->addWidget (mError); + mLayout->addWidget(mError); // buttons - mButtons = new QDialogButtonBox (QDialogButtonBox::Cancel, Qt::Horizontal, this); + mButtons = new QDialogButtonBox(QDialogButtonBox::Cancel, Qt::Horizontal, this); - mLayout->addWidget (mButtons); + mLayout->addWidget(mButtons); - setLayout (mLayout); + setLayout(mLayout); - move (QCursor::pos()); + move(QCursor::pos()); show(); - connect (mButtons, &QDialogButtonBox::rejected, this, qOverload<>(&LoadingDocument::cancel)); + connect(mButtons, &QDialogButtonBox::rejected, this, qOverload<>(&LoadingDocument::cancel)); } -void CSVDoc::LoadingDocument::nextStage (const std::string& name, int fileRecords) +void CSVDoc::LoadingDocument::nextStage(const std::string& name, int fileRecords) { ++mFilesLoaded; size_t numFiles = mDocument->getContentFiles().size(); - mTotalRecordsLabel->setText (QString::fromUtf8 (("Loading: "+name - +" ("+std::to_string(mFilesLoaded)+" of "+std::to_string((numFiles))+")").c_str())); + mTotalRecordsLabel->setText(QString::fromUtf8( + ("Loading: " + name + " (" + std::to_string(mFilesLoaded) + " of " + std::to_string((numFiles)) + ")") + .c_str())); mTotalRecords = mTotalProgress->value(); - mRecordProgress->setValue (0); - mRecordProgress->setMaximum (fileRecords>0 ? fileRecords : 1); + mRecordProgress->setValue(0); + mRecordProgress->setMaximum(fileRecords > 0 ? fileRecords : 1); mRecords = fileRecords; } @@ -100,107 +106,101 @@ void CSVDoc::LoadingDocument::nextRecord(int records) mRecordProgress->setValue(records); - mRecordsLabel->setText( - "Records: " + QString::number(records) + " of " + QString::number(mRecords)); + mRecordsLabel->setText("Records: " + QString::number(records) + " of " + QString::number(mRecords)); } } -void CSVDoc::LoadingDocument::abort (const std::string& error) +void CSVDoc::LoadingDocument::abort(const std::string& error) { mAborted = true; - mError->setText (QString::fromUtf8 (("Loading failed: " + error + "").c_str())); - mButtons->setStandardButtons (QDialogButtonBox::Close); + mError->setText(QString::fromUtf8(("Loading failed: " + error + "").c_str())); + mButtons->setStandardButtons(QDialogButtonBox::Close); } -void CSVDoc::LoadingDocument::addMessage (const std::string& message) +void CSVDoc::LoadingDocument::addMessage(const std::string& message) { if (!mMessages) { - mMessages = new QListWidget (this); - mLayout->insertWidget (4, mMessages); + mMessages = new QListWidget(this); + mLayout->insertWidget(4, mMessages); } - new QListWidgetItem (QString::fromUtf8 (message.c_str()), mMessages); + new QListWidgetItem(QString::fromUtf8(message.c_str()), mMessages); } void CSVDoc::LoadingDocument::cancel() { if (!mAborted) - emit cancel (mDocument); + emit cancel(mDocument); else { - emit close (mDocument); + emit close(mDocument); deleteLater(); } } - CSVDoc::Loader::Loader() {} CSVDoc::Loader::~Loader() { - for (std::map::iterator iter (mDocuments.begin()); - iter!=mDocuments.end(); ++iter) + for (std::map::iterator iter(mDocuments.begin()); iter != mDocuments.end(); + ++iter) delete iter->second; } -void CSVDoc::Loader::add (CSMDoc::Document *document) +void CSVDoc::Loader::add(CSMDoc::Document* document) { - LoadingDocument *loading = new LoadingDocument (document); - mDocuments.insert (std::make_pair (document, loading)); + LoadingDocument* loading = new LoadingDocument(document); + mDocuments.insert(std::make_pair(document, loading)); - connect (loading, qOverload(&LoadingDocument::cancel), - this, &Loader::cancel); - connect (loading, &LoadingDocument::close, - this, &Loader::close); + connect(loading, qOverload(&LoadingDocument::cancel), this, &Loader::cancel); + connect(loading, &LoadingDocument::close, this, &Loader::close); } -void CSVDoc::Loader::loadingStopped (CSMDoc::Document *document, bool completed, - const std::string& error) +void CSVDoc::Loader::loadingStopped(CSMDoc::Document* document, bool completed, const std::string& error) { - std::map::iterator iter = mDocuments.begin(); + std::map::iterator iter = mDocuments.begin(); - for (; iter!=mDocuments.end(); ++iter) - if (iter->first==document) + for (; iter != mDocuments.end(); ++iter) + if (iter->first == document) break; - if (iter==mDocuments.end()) + if (iter == mDocuments.end()) return; if (completed || error.empty()) { delete iter->second; - mDocuments.erase (iter); + mDocuments.erase(iter); } else { - iter->second->abort (error); + iter->second->abort(error); // Leave the window open for now (wait for the user to close it) - mDocuments.erase (iter); + mDocuments.erase(iter); } } -void CSVDoc::Loader::nextStage (CSMDoc::Document *document, const std::string& name, - int fileRecords) +void CSVDoc::Loader::nextStage(CSMDoc::Document* document, const std::string& name, int fileRecords) { - std::map::iterator iter = mDocuments.find (document); + std::map::iterator iter = mDocuments.find(document); - if (iter!=mDocuments.end()) - iter->second->nextStage (name, fileRecords); + if (iter != mDocuments.end()) + iter->second->nextStage(name, fileRecords); } -void CSVDoc::Loader::nextRecord (CSMDoc::Document *document, int records) +void CSVDoc::Loader::nextRecord(CSMDoc::Document* document, int records) { - std::map::iterator iter = mDocuments.find (document); + std::map::iterator iter = mDocuments.find(document); - if (iter!=mDocuments.end()) - iter->second->nextRecord (records); + if (iter != mDocuments.end()) + iter->second->nextRecord(records); } -void CSVDoc::Loader::loadMessage (CSMDoc::Document *document, const std::string& message) +void CSVDoc::Loader::loadMessage(CSMDoc::Document* document, const std::string& message) { - std::map::iterator iter = mDocuments.find (document); + std::map::iterator iter = mDocuments.find(document); - if (iter!=mDocuments.end()) - iter->second->addMessage (message); + if (iter != mDocuments.end()) + iter->second->addMessage(message); } diff --git a/apps/opencs/view/doc/loader.hpp b/apps/opencs/view/doc/loader.hpp index 80d986283d..6cdac2be28 100644 --- a/apps/opencs/view/doc/loader.hpp +++ b/apps/opencs/view/doc/loader.hpp @@ -21,81 +21,77 @@ namespace CSVDoc { class LoadingDocument : public QWidget { - Q_OBJECT + Q_OBJECT - CSMDoc::Document *mDocument; - QLabel *mTotalRecordsLabel; - QLabel *mRecordsLabel; - QProgressBar *mTotalProgress; - QProgressBar *mRecordProgress; - bool mAborted; - QDialogButtonBox *mButtons; - QLabel *mError; - QListWidget *mMessages; - QVBoxLayout *mLayout; - int mRecords; - int mTotalRecords; - int mFilesLoaded; + CSMDoc::Document* mDocument; + QLabel* mTotalRecordsLabel; + QLabel* mRecordsLabel; + QProgressBar* mTotalProgress; + QProgressBar* mRecordProgress; + bool mAborted; + QDialogButtonBox* mButtons; + QLabel* mError; + QListWidget* mMessages; + QVBoxLayout* mLayout; + int mRecords; + int mTotalRecords; + int mFilesLoaded; - private: + private: + void closeEvent(QCloseEvent* event) override; - void closeEvent (QCloseEvent *event) override; + public: + LoadingDocument(CSMDoc::Document* document); - public: + void nextStage(const std::string& name, int totalRecords); - LoadingDocument (CSMDoc::Document *document); + void nextRecord(int records); - void nextStage (const std::string& name, int totalRecords); + void abort(const std::string& error); - void nextRecord (int records); + void addMessage(const std::string& message); - void abort (const std::string& error); + private slots: - void addMessage (const std::string& message); + void cancel(); - private slots: + signals: - void cancel(); + void cancel(CSMDoc::Document* document); + ///< Stop loading process. - signals: - - void cancel (CSMDoc::Document *document); - ///< Stop loading process. - - void close (CSMDoc::Document *document); - ///< Close stopped loading process. + void close(CSMDoc::Document* document); + ///< Close stopped loading process. }; class Loader : public QObject { - Q_OBJECT - - std::map mDocuments; + Q_OBJECT - public: + std::map mDocuments; - Loader(); + public: + Loader(); - ~Loader() override; + ~Loader() override; - signals: + signals: - void cancel (CSMDoc::Document *document); + void cancel(CSMDoc::Document* document); - void close (CSMDoc::Document *document); + void close(CSMDoc::Document* document); - public slots: + public slots: - void add (CSMDoc::Document *document); + void add(CSMDoc::Document* document); - void loadingStopped (CSMDoc::Document *document, bool completed, - const std::string& error); + void loadingStopped(CSMDoc::Document* document, bool completed, const std::string& error); - void nextStage (CSMDoc::Document *document, const std::string& name, int totalRecords); + void nextStage(CSMDoc::Document* document, const std::string& name, int totalRecords); - void nextRecord (CSMDoc::Document *document, int records); + void nextRecord(CSMDoc::Document* document, int records); - void loadMessage (CSMDoc::Document *document, const std::string& message); + void loadMessage(CSMDoc::Document* document, const std::string& message); }; } diff --git a/apps/opencs/view/doc/newgame.cpp b/apps/opencs/view/doc/newgame.cpp index 5fecf49134..99ee189e7d 100644 --- a/apps/opencs/view/doc/newgame.cpp +++ b/apps/opencs/view/doc/newgame.cpp @@ -1,72 +1,72 @@ #include "newgame.hpp" -#include -#include #include +#include #include #include +#include -#include "filewidget.hpp" #include "adjusterwidget.hpp" +#include "filewidget.hpp" CSVDoc::NewGameDialogue::NewGameDialogue() { - setWindowTitle ("Create New Game"); + setWindowTitle("Create New Game"); - QVBoxLayout *layout = new QVBoxLayout (this); + QVBoxLayout* layout = new QVBoxLayout(this); - mFileWidget = new FileWidget (this); - mFileWidget->setType (false); + mFileWidget = new FileWidget(this); + mFileWidget->setType(false); - layout->addWidget (mFileWidget, 1); + layout->addWidget(mFileWidget, 1); - mAdjusterWidget = new AdjusterWidget (this); + mAdjusterWidget = new AdjusterWidget(this); - layout->addWidget (mAdjusterWidget, 1); + layout->addWidget(mAdjusterWidget, 1); - QDialogButtonBox *buttons = new QDialogButtonBox (this); + QDialogButtonBox* buttons = new QDialogButtonBox(this); - mCreate = new QPushButton ("Create", this); - mCreate->setDefault (true); - mCreate->setEnabled (false); + mCreate = new QPushButton("Create", this); + mCreate->setDefault(true); + mCreate->setEnabled(false); - buttons->addButton (mCreate, QDialogButtonBox::AcceptRole); + buttons->addButton(mCreate, QDialogButtonBox::AcceptRole); - QPushButton *cancel = new QPushButton ("Cancel", this); + QPushButton* cancel = new QPushButton("Cancel", this); - buttons->addButton (cancel, QDialogButtonBox::RejectRole); + buttons->addButton(cancel, QDialogButtonBox::RejectRole); - layout->addWidget (buttons); + layout->addWidget(buttons); - setLayout (layout); + setLayout(layout); - connect (mAdjusterWidget, &AdjusterWidget::stateChanged, this, &NewGameDialogue::stateChanged); - connect (mCreate, &QPushButton::clicked, this, &NewGameDialogue::create); - connect (cancel, &QPushButton::clicked, this, &NewGameDialogue::reject); - connect (mFileWidget, &FileWidget::nameChanged, mAdjusterWidget, &AdjusterWidget::setName); + connect(mAdjusterWidget, &AdjusterWidget::stateChanged, this, &NewGameDialogue::stateChanged); + connect(mCreate, &QPushButton::clicked, this, &NewGameDialogue::create); + connect(cancel, &QPushButton::clicked, this, &NewGameDialogue::reject); + connect(mFileWidget, &FileWidget::nameChanged, mAdjusterWidget, &AdjusterWidget::setName); QRect scr = QGuiApplication::primaryScreen()->geometry(); QRect rect = geometry(); - move (scr.center().x() - rect.center().x(), scr.center().y() - rect.center().y()); + move(scr.center().x() - rect.center().x(), scr.center().y() - rect.center().y()); } -void CSVDoc::NewGameDialogue::setLocalData (const std::filesystem::path& localData) +void CSVDoc::NewGameDialogue::setLocalData(const std::filesystem::path& localData) { - mAdjusterWidget->setLocalData (localData); + mAdjusterWidget->setLocalData(localData); } -void CSVDoc::NewGameDialogue::stateChanged (bool valid) +void CSVDoc::NewGameDialogue::stateChanged(bool valid) { - mCreate->setEnabled (valid); + mCreate->setEnabled(valid); } void CSVDoc::NewGameDialogue::create() { - emit createRequest (mAdjusterWidget->getPath()); + emit createRequest(mAdjusterWidget->getPath()); } void CSVDoc::NewGameDialogue::reject() { - emit cancelCreateGame (); + emit cancelCreateGame(); QDialog::reject(); } diff --git a/apps/opencs/view/doc/newgame.hpp b/apps/opencs/view/doc/newgame.hpp index f5eace0671..4e8154e22b 100644 --- a/apps/opencs/view/doc/newgame.hpp +++ b/apps/opencs/view/doc/newgame.hpp @@ -8,7 +8,7 @@ #ifndef CS_QT_STD_FILESYSTEM_PATH_DECLARED #define CS_QT_STD_FILESYSTEM_PATH_DECLARED -Q_DECLARE_METATYPE (std::filesystem::path) +Q_DECLARE_METATYPE(std::filesystem::path) #endif class QPushButton; @@ -20,31 +20,30 @@ namespace CSVDoc class NewGameDialogue : public QDialog { - Q_OBJECT + Q_OBJECT - QPushButton *mCreate; - FileWidget *mFileWidget; - AdjusterWidget *mAdjusterWidget; + QPushButton* mCreate; + FileWidget* mFileWidget; + AdjusterWidget* mAdjusterWidget; - public: + public: + NewGameDialogue(); - NewGameDialogue(); + void setLocalData(const std::filesystem::path& localData); - void setLocalData (const std::filesystem::path& localData); + signals: - signals: + void createRequest(const std::filesystem::path& file); - void createRequest (const std::filesystem::path& file); + void cancelCreateGame(); - void cancelCreateGame (); + private slots: - private slots: + void stateChanged(bool valid); - void stateChanged (bool valid); + void create(); - void create(); - - void reject() override; + void reject() override; }; } diff --git a/apps/opencs/view/doc/operation.cpp b/apps/opencs/view/doc/operation.cpp index 6b0165b475..8d8a389f0d 100644 --- a/apps/opencs/view/doc/operation.cpp +++ b/apps/opencs/view/doc/operation.cpp @@ -2,29 +2,37 @@ #include +#include #include #include -#include #include "../../model/doc/state.hpp" -void CSVDoc::Operation::updateLabel (int threads) +void CSVDoc::Operation::updateLabel(int threads) { - if (threads==-1 || ((threads==0)!=mStalling)) + if (threads == -1 || ((threads == 0) != mStalling)) { - std::string name ("unknown operation"); + std::string name("unknown operation"); switch (mType) { - case CSMDoc::State_Saving: name = "saving"; break; - case CSMDoc::State_Verifying: name = "verifying"; break; - case CSMDoc::State_Searching: name = "searching"; break; - case CSMDoc::State_Merging: name = "merging"; break; + case CSMDoc::State_Saving: + name = "saving"; + break; + case CSMDoc::State_Verifying: + name = "verifying"; + break; + case CSMDoc::State_Searching: + name = "searching"; + break; + case CSMDoc::State_Merging: + name = "merging"; + break; } std::ostringstream stream; - if ((mStalling = (threads<=0))) + if ((mStalling = (threads <= 0))) { stream << name << " (waiting for a free worker thread)"; } @@ -33,15 +41,17 @@ void CSVDoc::Operation::updateLabel (int threads) stream << name << " (%p%)"; } - mProgressBar->setFormat (stream.str().c_str()); + mProgressBar->setFormat(stream.str().c_str()); } } -CSVDoc::Operation::Operation (int type, QWidget* parent) : mType (type), mStalling (false) +CSVDoc::Operation::Operation(int type, QWidget* parent) + : mType(type) + , mStalling(false) { /// \todo Add a cancel button or a pop up menu with a cancel item initWidgets(); - setBarColor( type); + setBarColor(type); updateLabel(); /// \todo assign different progress bar colours to allow the user to distinguish easily between operation types @@ -56,21 +66,21 @@ CSVDoc::Operation::~Operation() void CSVDoc::Operation::initWidgets() { - mProgressBar = new QProgressBar (); + mProgressBar = new QProgressBar(); mAbortButton = new QPushButton("Abort"); mLayout = new QHBoxLayout(); - mLayout->addWidget (mProgressBar); - mLayout->addWidget (mAbortButton); + mLayout->addWidget(mProgressBar); + mLayout->addWidget(mAbortButton); - connect (mAbortButton, &QPushButton::clicked, this, qOverload<>(&Operation::abortOperation)); + connect(mAbortButton, &QPushButton::clicked, this, qOverload<>(&Operation::abortOperation)); } -void CSVDoc::Operation::setProgress (int current, int max, int threads) +void CSVDoc::Operation::setProgress(int current, int max, int threads) { - updateLabel (threads); - mProgressBar->setRange (0, max); - mProgressBar->setValue (current); + updateLabel(threads); + mProgressBar->setRange(0, max); + mProgressBar->setValue(current); } int CSVDoc::Operation::getType() const @@ -78,76 +88,77 @@ int CSVDoc::Operation::getType() const return mType; } -void CSVDoc::Operation::setBarColor (int type) +void CSVDoc::Operation::setBarColor(int type) { - QString style ="QProgressBar {" - "text-align: center;" - "}" + QString style + = "QProgressBar {" + "text-align: center;" + "}" "QProgressBar::chunk {" - "background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 %1, stop:.50 %2 stop: .51 %3 stop:1 %4);" - "text-align: center;" - "margin: 2px 1px 1p 2px;" + "background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 %1, stop:.50 %2 stop: .51 %3 stop:1 %4);" + "text-align: center;" + "margin: 2px 1px 1p 2px;" "}"; QString topColor = "#F2F6F8"; QString bottomColor = "#E0EFF9"; QString midTopColor = "#D8E1E7"; - QString midBottomColor = "#B5C6D0"; // default gray gloss + QString midBottomColor = "#B5C6D0"; // default gray gloss // colors inspired by samples from: // http://www.colorzilla.com/gradient-editor/ switch (type) { - case CSMDoc::State_Saving: + case CSMDoc::State_Saving: - topColor = "#FECCB1"; - midTopColor = "#F17432"; - midBottomColor = "#EA5507"; - bottomColor = "#FB955E"; // red gloss #2 - break; + topColor = "#FECCB1"; + midTopColor = "#F17432"; + midBottomColor = "#EA5507"; + bottomColor = "#FB955E"; // red gloss #2 + break; - case CSMDoc::State_Searching: + case CSMDoc::State_Searching: - topColor = "#EBF1F6"; - midTopColor = "#ABD3EE"; - midBottomColor = "#89C3EB"; - bottomColor = "#D5EBFB"; //blue gloss #4 - break; + topColor = "#EBF1F6"; + midTopColor = "#ABD3EE"; + midBottomColor = "#89C3EB"; + bottomColor = "#D5EBFB"; // blue gloss #4 + break; - case CSMDoc::State_Verifying: + case CSMDoc::State_Verifying: - topColor = "#BFD255"; - midTopColor = "#8EB92A"; - midBottomColor = "#72AA00"; - bottomColor = "#9ECB2D"; //green gloss - break; + topColor = "#BFD255"; + midTopColor = "#8EB92A"; + midBottomColor = "#72AA00"; + bottomColor = "#9ECB2D"; // green gloss + break; - case CSMDoc::State_Merging: + case CSMDoc::State_Merging: - topColor = "#F3E2C7"; - midTopColor = "#C19E67"; - midBottomColor = "#B68D4C"; - bottomColor = "#E9D4B3"; //l Brown 3D - break; + topColor = "#F3E2C7"; + midTopColor = "#C19E67"; + midBottomColor = "#B68D4C"; + bottomColor = "#E9D4B3"; // l Brown 3D + break; - default: + default: - topColor = "#F2F6F8"; - bottomColor = "#E0EFF9"; - midTopColor = "#D8E1E7"; - midBottomColor = "#B5C6D0"; // gray gloss for undefined ops + topColor = "#F2F6F8"; + bottomColor = "#E0EFF9"; + midTopColor = "#D8E1E7"; + midBottomColor = "#B5C6D0"; // gray gloss for undefined ops } mProgressBar->setStyleSheet(style.arg(topColor).arg(midTopColor).arg(midBottomColor).arg(bottomColor)); } -QHBoxLayout *CSVDoc::Operation::getLayout() const +QHBoxLayout* CSVDoc::Operation::getLayout() const { return mLayout; } void CSVDoc::Operation::abortOperation() { - emit abortOperation (mType); + emit abortOperation(mType); } diff --git a/apps/opencs/view/doc/operation.hpp b/apps/opencs/view/doc/operation.hpp index 1d07464604..7f7f4f016e 100644 --- a/apps/opencs/view/doc/operation.hpp +++ b/apps/opencs/view/doc/operation.hpp @@ -11,42 +11,40 @@ namespace CSVDoc { class Operation : public QObject { - Q_OBJECT + Q_OBJECT - int mType; - bool mStalling; - QProgressBar *mProgressBar; - QPushButton *mAbortButton; - QHBoxLayout *mLayout; + int mType; + bool mStalling; + QProgressBar* mProgressBar; + QPushButton* mAbortButton; + QHBoxLayout* mLayout; - // not implemented - Operation (const Operation&); - Operation& operator= (const Operation&); + // not implemented + Operation(const Operation&); + Operation& operator=(const Operation&); - void updateLabel (int threads = -1); + void updateLabel(int threads = -1); - public: + public: + Operation(int type, QWidget* parent); + ~Operation() override; - Operation (int type, QWidget *parent); - ~Operation() override; + void setProgress(int current, int max, int threads); - void setProgress (int current, int max, int threads); + int getType() const; + QHBoxLayout* getLayout() const; - int getType() const; - QHBoxLayout *getLayout() const; + private: + void setBarColor(int type); + void initWidgets(); - private: + signals: - void setBarColor (int type); - void initWidgets(); + void abortOperation(int type); - signals: + private slots: - void abortOperation (int type); - - private slots: - - void abortOperation(); + void abortOperation(); }; } diff --git a/apps/opencs/view/doc/operations.cpp b/apps/opencs/view/doc/operations.cpp index 585184ae67..103acf5211 100644 --- a/apps/opencs/view/doc/operations.cpp +++ b/apps/opencs/view/doc/operations.cpp @@ -8,60 +8,60 @@ CSVDoc::Operations::Operations() { /// \todo make widget height fixed (exactly the height required to display all operations) - setFeatures (QDockWidget::NoDockWidgetFeatures); + setFeatures(QDockWidget::NoDockWidgetFeatures); - QWidget *widgetContainer = new QWidget (this); + QWidget* widgetContainer = new QWidget(this); mLayout = new QVBoxLayout; - widgetContainer->setLayout (mLayout); - setWidget (widgetContainer); - setVisible (false); - setFixedHeight (widgetContainer->height()); - setTitleBarWidget (new QWidget (this)); + widgetContainer->setLayout(mLayout); + setWidget(widgetContainer); + setVisible(false); + setFixedHeight(widgetContainer->height()); + setTitleBarWidget(new QWidget(this)); } -void CSVDoc::Operations::setProgress (int current, int max, int type, int threads) +void CSVDoc::Operations::setProgress(int current, int max, int type, int threads) { - for (std::vector::iterator iter (mOperations.begin()); iter!=mOperations.end(); ++iter) - if ((*iter)->getType()==type) + for (std::vector::iterator iter(mOperations.begin()); iter != mOperations.end(); ++iter) + if ((*iter)->getType() == type) { - (*iter)->setProgress (current, max, threads); + (*iter)->setProgress(current, max, threads); return; } int oldCount = static_cast(mOperations.size()); int newCount = oldCount + 1; - Operation *operation = new Operation (type, this); - connect (operation, qOverload(&Operation::abortOperation), this, &Operations::abortOperation); + Operation* operation = new Operation(type, this); + connect(operation, qOverload(&Operation::abortOperation), this, &Operations::abortOperation); - mLayout->addLayout (operation->getLayout()); - mOperations.push_back (operation); - operation->setProgress (current, max, threads); + mLayout->addLayout(operation->getLayout()); + mOperations.push_back(operation); + operation->setProgress(current, max, threads); - if ( oldCount > 0) - setFixedHeight (height()/oldCount * newCount); + if (oldCount > 0) + setFixedHeight(height() / oldCount * newCount); - setVisible (true); + setVisible(true); } -void CSVDoc::Operations::quitOperation (int type) +void CSVDoc::Operations::quitOperation(int type) { - for (std::vector::iterator iter (mOperations.begin()); iter!=mOperations.end(); ++iter) - if ((*iter)->getType()==type) + for (std::vector::iterator iter(mOperations.begin()); iter != mOperations.end(); ++iter) + if ((*iter)->getType() == type) { int oldCount = static_cast(mOperations.size()); int newCount = oldCount - 1; - mLayout->removeItem ((*iter)->getLayout()); + mLayout->removeItem((*iter)->getLayout()); (*iter)->deleteLater(); - mOperations.erase (iter); + mOperations.erase(iter); if (oldCount > 1) - setFixedHeight (height() / oldCount * newCount); + setFixedHeight(height() / oldCount * newCount); else - setVisible (false); + setVisible(false); break; } diff --git a/apps/opencs/view/doc/operations.hpp b/apps/opencs/view/doc/operations.hpp index 71c595f66b..110ed3f728 100644 --- a/apps/opencs/view/doc/operations.hpp +++ b/apps/opencs/view/doc/operations.hpp @@ -13,28 +13,27 @@ namespace CSVDoc class Operations : public QDockWidget { - Q_OBJECT + Q_OBJECT - QVBoxLayout *mLayout; - std::vector mOperations; + QVBoxLayout* mLayout; + std::vector mOperations; - // not implemented - Operations (const Operations&); - Operations& operator= (const Operations&); + // not implemented + Operations(const Operations&); + Operations& operator=(const Operations&); - public: + public: + Operations(); - Operations(); + void setProgress(int current, int max, int type, int threads); + ///< Implicitly starts the operation, if it is not running already. - void setProgress (int current, int max, int type, int threads); - ///< Implicitly starts the operation, if it is not running already. + void quitOperation(int type); + ///< Calling this function for an operation that is not running is a no-op. - void quitOperation (int type); - ///< Calling this function for an operation that is not running is a no-op. + signals: - signals: - - void abortOperation (int type); + void abortOperation(int type); }; } diff --git a/apps/opencs/view/doc/runlogsubview.cpp b/apps/opencs/view/doc/runlogsubview.cpp index 3a871ff103..ba7fa20a87 100644 --- a/apps/opencs/view/doc/runlogsubview.cpp +++ b/apps/opencs/view/doc/runlogsubview.cpp @@ -4,18 +4,17 @@ #include -CSVDoc::RunLogSubView::RunLogSubView (const CSMWorld::UniversalId& id, - CSMDoc::Document& document) -: SubView (id) +CSVDoc::RunLogSubView::RunLogSubView(const CSMWorld::UniversalId& id, CSMDoc::Document& document) + : SubView(id) { - QTextEdit *edit = new QTextEdit (this); - edit->setDocument (document.getRunLog()); - edit->setReadOnly (true); + QTextEdit* edit = new QTextEdit(this); + edit->setDocument(document.getRunLog()); + edit->setReadOnly(true); - setWidget (edit); + setWidget(edit); } -void CSVDoc::RunLogSubView::setEditLock (bool locked) +void CSVDoc::RunLogSubView::setEditLock(bool locked) { // ignored since this SubView does not have editing } diff --git a/apps/opencs/view/doc/runlogsubview.hpp b/apps/opencs/view/doc/runlogsubview.hpp index 31a390276c..3bc234a780 100644 --- a/apps/opencs/view/doc/runlogsubview.hpp +++ b/apps/opencs/view/doc/runlogsubview.hpp @@ -12,13 +12,12 @@ namespace CSVDoc { class RunLogSubView : public SubView { - Q_OBJECT + Q_OBJECT - public: + public: + RunLogSubView(const CSMWorld::UniversalId& id, CSMDoc::Document& document); - RunLogSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document); - - void setEditLock (bool locked) override; + void setEditLock(bool locked) override; }; } diff --git a/apps/opencs/view/doc/sizehint.cpp b/apps/opencs/view/doc/sizehint.cpp index 038bd9e4d1..4337835149 100644 --- a/apps/opencs/view/doc/sizehint.cpp +++ b/apps/opencs/view/doc/sizehint.cpp @@ -1,17 +1,18 @@ #include "sizehint.hpp" -CSVDoc::SizeHintWidget::SizeHintWidget(QWidget *parent) : QWidget(parent) -{} +CSVDoc::SizeHintWidget::SizeHintWidget(QWidget* parent) + : QWidget(parent) +{ +} -CSVDoc::SizeHintWidget::~SizeHintWidget() -{} +CSVDoc::SizeHintWidget::~SizeHintWidget() {} QSize CSVDoc::SizeHintWidget::sizeHint() const { return mSize; } -void CSVDoc::SizeHintWidget::setSizeHint(const QSize &size) +void CSVDoc::SizeHintWidget::setSizeHint(const QSize& size) { mSize = size; } diff --git a/apps/opencs/view/doc/sizehint.hpp b/apps/opencs/view/doc/sizehint.hpp index 949265e31a..7f43f28bb4 100644 --- a/apps/opencs/view/doc/sizehint.hpp +++ b/apps/opencs/view/doc/sizehint.hpp @@ -1,21 +1,21 @@ #ifndef CSV_DOC_SIZEHINT_H #define CSV_DOC_SIZEHINT_H -#include #include +#include namespace CSVDoc { class SizeHintWidget : public QWidget { - QSize mSize; + QSize mSize; - public: - SizeHintWidget(QWidget *parent = nullptr); - ~SizeHintWidget() override; + public: + SizeHintWidget(QWidget* parent = nullptr); + ~SizeHintWidget() override; - QSize sizeHint() const override; - void setSizeHint(const QSize &size); + QSize sizeHint() const override; + void setSizeHint(const QSize& size); }; } diff --git a/apps/opencs/view/doc/startup.cpp b/apps/opencs/view/doc/startup.cpp index 4676284a17..27463b0456 100644 --- a/apps/opencs/view/doc/startup.cpp +++ b/apps/opencs/view/doc/startup.cpp @@ -1,125 +1,129 @@ #include "startup.hpp" +#include #include -#include #include -#include -#include -#include #include +#include #include +#include #include +#include -QPushButton *CSVDoc::StartupDialogue::addButton (const QString& label, const QIcon& icon) +QPushButton* CSVDoc::StartupDialogue::addButton(const QString& label, const QIcon& icon) { int column = mColumn--; - QPushButton *button = new QPushButton (this); + QPushButton* button = new QPushButton(this); - button->setIcon (QIcon (icon)); + button->setIcon(QIcon(icon)); - button->setSizePolicy (QSizePolicy (QSizePolicy::Preferred, QSizePolicy::Preferred)); + button->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred)); - mLayout->addWidget (button, 0, column); + mLayout->addWidget(button, 0, column); - mLayout->addWidget (new QLabel (label, this), 1, column, Qt::AlignCenter); + mLayout->addWidget(new QLabel(label, this), 1, column, Qt::AlignCenter); - int width = mLayout->itemAtPosition (1, column)->widget()->sizeHint().width(); + int width = mLayout->itemAtPosition(1, column)->widget()->sizeHint().width(); - if (width>mWidth) + if (width > mWidth) mWidth = width; return button; } - -QWidget *CSVDoc::StartupDialogue::createButtons() +QWidget* CSVDoc::StartupDialogue::createButtons() { - QWidget *widget = new QWidget (this); + QWidget* widget = new QWidget(this); - mLayout = new QGridLayout (widget); + mLayout = new QGridLayout(widget); /// \todo add icons - QPushButton *loadDocument = addButton ("Edit A Content File", QIcon (":startup/edit-content")); - connect (loadDocument, &QPushButton::clicked, this, &StartupDialogue::loadDocument); + QPushButton* loadDocument = addButton("Edit A Content File", QIcon(":startup/edit-content")); + connect(loadDocument, &QPushButton::clicked, this, &StartupDialogue::loadDocument); - QPushButton *createAddon = addButton ("Create A New Addon", QIcon (":startup/create-addon")); - connect (createAddon, &QPushButton::clicked, this, &StartupDialogue::createAddon); + QPushButton* createAddon = addButton("Create A New Addon", QIcon(":startup/create-addon")); + connect(createAddon, &QPushButton::clicked, this, &StartupDialogue::createAddon); - QPushButton *createGame = addButton ("Create A New Game", QIcon (":startup/create-game")); - connect (createGame, &QPushButton::clicked, this, &StartupDialogue::createGame); + QPushButton* createGame = addButton("Create A New Game", QIcon(":startup/create-game")); + connect(createGame, &QPushButton::clicked, this, &StartupDialogue::createGame); - for (int i=0; i<3; ++i) - mLayout->setColumnMinimumWidth (i, mWidth); + for (int i = 0; i < 3; ++i) + mLayout->setColumnMinimumWidth(i, mWidth); - mLayout->setRowMinimumHeight (0, mWidth); + mLayout->setRowMinimumHeight(0, mWidth); - mLayout->setSizeConstraint (QLayout::SetMinimumSize); - mLayout->setHorizontalSpacing (32); + mLayout->setSizeConstraint(QLayout::SetMinimumSize); + mLayout->setHorizontalSpacing(32); - mLayout->setContentsMargins (16, 16, 16, 8); + mLayout->setContentsMargins(16, 16, 16, 8); - loadDocument->setIconSize (QSize (mWidth, mWidth)); - createGame->setIconSize (QSize (mWidth, mWidth)); - createAddon->setIconSize (QSize (mWidth, mWidth)); + loadDocument->setIconSize(QSize(mWidth, mWidth)); + createGame->setIconSize(QSize(mWidth, mWidth)); + createAddon->setIconSize(QSize(mWidth, mWidth)); - widget->setLayout (mLayout); + widget->setLayout(mLayout); return widget; } -QWidget *CSVDoc::StartupDialogue::createTools() +QWidget* CSVDoc::StartupDialogue::createTools() { - QWidget *widget = new QWidget (this); + QWidget* widget = new QWidget(this); - QHBoxLayout *layout = new QHBoxLayout (widget); - layout->setDirection (QBoxLayout::RightToLeft); - layout->setContentsMargins (4, 4, 4, 4); + QHBoxLayout* layout = new QHBoxLayout(widget); + layout->setDirection(QBoxLayout::RightToLeft); + layout->setContentsMargins(4, 4, 4, 4); - QPushButton *config = new QPushButton (widget); + QPushButton* config = new QPushButton(widget); - config->setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed)); - config->setIcon (QIcon (":startup/configure")); - config->setToolTip ("Open user settings"); + config->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); + config->setIcon(QIcon(":startup/configure")); + config->setToolTip("Open user settings"); - layout->addWidget (config); + layout->addWidget(config); - layout->addWidget (new QWidget, 1); // dummy widget; stops buttons from taking all the space + layout->addWidget(new QWidget, 1); // dummy widget; stops buttons from taking all the space - widget->setLayout (layout); + widget->setLayout(layout); - connect (config, &QPushButton::clicked, this, &StartupDialogue::editConfig); + connect(config, &QPushButton::clicked, this, &StartupDialogue::editConfig); return widget; } -CSVDoc::StartupDialogue::StartupDialogue() : mWidth (0), mColumn (2) +CSVDoc::StartupDialogue::StartupDialogue() + : mWidth(0) + , mColumn(2) { - setWindowTitle ("OpenMW-CS"); + setWindowTitle("OpenMW-CS"); - QVBoxLayout *layout = new QVBoxLayout (this); + QVBoxLayout* layout = new QVBoxLayout(this); - layout->setContentsMargins (0, 0, 0, 0); + layout->setContentsMargins(0, 0, 0, 0); - layout->addWidget (createButtons()); - layout->addWidget (createTools()); + layout->addWidget(createButtons()); + layout->addWidget(createTools()); /// \todo remove this label once we are feature complete and convinced that this thing is /// working properly. - QLabel *warning = new QLabel ("WARNING: OpenMW-CS is in alpha stage.

The editor is not feature complete and not sufficiently tested.
In theory your data should be safe. But we strongly advise to make backups regularly if you are working with live data.
"); + QLabel* warning = new QLabel( + "WARNING: OpenMW-CS is in alpha stage.

The editor is not feature complete and not " + "sufficiently tested.
In theory your data should be safe. But we strongly advise to make backups regularly " + "if you are working with live data.
"); QFont font; - font.setPointSize (12); - font.setBold (true); + font.setPointSize(12); + font.setBold(true); - warning->setFont (font); - warning->setWordWrap (true); + warning->setFont(font); + warning->setWordWrap(true); - layout->addWidget (warning, 1); + layout->addWidget(warning, 1); - setLayout (layout); + setLayout(layout); QRect scr = QGuiApplication::primaryScreen()->geometry(); QRect rect = geometry(); - move (scr.center().x() - rect.center().x(), scr.center().y() - rect.center().y()); + move(scr.center().x() - rect.center().x(), scr.center().y() - rect.center().y()); } diff --git a/apps/opencs/view/doc/startup.hpp b/apps/opencs/view/doc/startup.hpp index f059a44e5c..061b91b2d1 100644 --- a/apps/opencs/view/doc/startup.hpp +++ b/apps/opencs/view/doc/startup.hpp @@ -15,31 +15,29 @@ namespace CSVDoc { Q_OBJECT - private: + private: + int mWidth; + int mColumn; + QGridLayout* mLayout; - int mWidth; - int mColumn; - QGridLayout *mLayout; + QPushButton* addButton(const QString& label, const QIcon& icon); - QPushButton *addButton (const QString& label, const QIcon& icon); + QWidget* createButtons(); - QWidget *createButtons(); + QWidget* createTools(); - QWidget *createTools(); + public: + StartupDialogue(); - public: + signals: - StartupDialogue(); + void createGame(); - signals: + void createAddon(); - void createGame(); + void loadDocument(); - void createAddon(); - - void loadDocument(); - - void editConfig(); + void editConfig(); }; } diff --git a/apps/opencs/view/doc/subview.cpp b/apps/opencs/view/doc/subview.cpp index a566a6e26f..30d9661ff2 100644 --- a/apps/opencs/view/doc/subview.cpp +++ b/apps/opencs/view/doc/subview.cpp @@ -5,26 +5,26 @@ #include #include -bool CSVDoc::SubView::event (QEvent *event) +bool CSVDoc::SubView::event(QEvent* event) { - if (event->type()==QEvent::ShortcutOverride) + if (event->type() == QEvent::ShortcutOverride) { - QKeyEvent *keyEvent = static_cast (event); + QKeyEvent* keyEvent = static_cast(event); - if (keyEvent->key()==Qt::Key_W && keyEvent->modifiers()==(Qt::ShiftModifier | Qt::ControlModifier)) + if (keyEvent->key() == Qt::Key_W && keyEvent->modifiers() == (Qt::ShiftModifier | Qt::ControlModifier)) emit closeRequest(); - return true; + return true; } - return QDockWidget::event (event); + return QDockWidget::event(event); } -CSVDoc::SubView::SubView (const CSMWorld::UniversalId& id) - : mUniversalId (id) +CSVDoc::SubView::SubView(const CSMWorld::UniversalId& id) + : mUniversalId(id) { /// \todo add a button to the title bar that clones this sub view - setWindowTitle (QString::fromUtf8 (mUniversalId.toString().c_str())); + setWindowTitle(QString::fromUtf8(mUniversalId.toString().c_str())); setAttribute(Qt::WA_DeleteOnClose); } @@ -33,20 +33,20 @@ CSMWorld::UniversalId CSVDoc::SubView::getUniversalId() const return mUniversalId; } -void CSVDoc::SubView::setStatusBar (bool show) {} +void CSVDoc::SubView::setStatusBar(bool show) {} -void CSVDoc::SubView::useHint (const std::string& hint) {} +void CSVDoc::SubView::useHint(const std::string& hint) {} -void CSVDoc::SubView::setUniversalId (const CSMWorld::UniversalId& id) +void CSVDoc::SubView::setUniversalId(const CSMWorld::UniversalId& id) { mUniversalId = id; - setWindowTitle (QString::fromUtf8(mUniversalId.toString().c_str())); - emit universalIdChanged (mUniversalId); + setWindowTitle(QString::fromUtf8(mUniversalId.toString().c_str())); + emit universalIdChanged(mUniversalId); } -void CSVDoc::SubView::closeEvent (QCloseEvent *event) +void CSVDoc::SubView::closeEvent(QCloseEvent* event) { - emit updateSubViewIndices (this); + emit updateSubViewIndices(this); } std::string CSVDoc::SubView::getTitle() const @@ -56,5 +56,5 @@ std::string CSVDoc::SubView::getTitle() const void CSVDoc::SubView::closeRequest() { - emit closeRequest (this); + emit closeRequest(this); } diff --git a/apps/opencs/view/doc/subview.hpp b/apps/opencs/view/doc/subview.hpp index d61609da98..04950ab48a 100644 --- a/apps/opencs/view/doc/subview.hpp +++ b/apps/opencs/view/doc/subview.hpp @@ -18,55 +18,52 @@ namespace CSVDoc class SubView : public QDockWidget { - Q_OBJECT + Q_OBJECT - CSMWorld::UniversalId mUniversalId; + CSMWorld::UniversalId mUniversalId; - // not implemented - SubView (const SubView&); - SubView& operator= (SubView&); + // not implemented + SubView(const SubView&); + SubView& operator=(SubView&); - protected: + protected: + void setUniversalId(const CSMWorld::UniversalId& id); - void setUniversalId(const CSMWorld::UniversalId& id); + bool event(QEvent* event) override; - bool event (QEvent *event) override; + public: + SubView(const CSMWorld::UniversalId& id); - public: + CSMWorld::UniversalId getUniversalId() const; - SubView (const CSMWorld::UniversalId& id); + virtual void setEditLock(bool locked) = 0; - CSMWorld::UniversalId getUniversalId() const; + virtual void setStatusBar(bool show); + ///< Default implementation: ignored - virtual void setEditLock (bool locked) = 0; + virtual void useHint(const std::string& hint); + ///< Default implementation: ignored - virtual void setStatusBar (bool show); - ///< Default implementation: ignored + virtual std::string getTitle() const; - virtual void useHint (const std::string& hint); - ///< Default implementation: ignored + private: + void closeEvent(QCloseEvent* event) override; - virtual std::string getTitle() const; + signals: - private: + void focusId(const CSMWorld::UniversalId& universalId, const std::string& hint); - void closeEvent (QCloseEvent *event) override; + void closeRequest(SubView* subView); - signals: + void updateTitle(); - void focusId (const CSMWorld::UniversalId& universalId, const std::string& hint); + void updateSubViewIndices(SubView* view = nullptr); - void closeRequest (SubView *subView); + void universalIdChanged(const CSMWorld::UniversalId& universalId); - void updateTitle(); + protected slots: - void updateSubViewIndices (SubView *view = nullptr); - - void universalIdChanged (const CSMWorld::UniversalId& universalId); - - protected slots: - - void closeRequest(); + void closeRequest(); }; } diff --git a/apps/opencs/view/doc/subviewfactory.cpp b/apps/opencs/view/doc/subviewfactory.cpp index 82a8aeb054..7ab16df5c2 100644 --- a/apps/opencs/view/doc/subviewfactory.cpp +++ b/apps/opencs/view/doc/subviewfactory.cpp @@ -8,30 +8,28 @@ CSVDoc::SubViewFactoryBase::SubViewFactoryBase() {} CSVDoc::SubViewFactoryBase::~SubViewFactoryBase() {} - CSVDoc::SubViewFactoryManager::SubViewFactoryManager() {} CSVDoc::SubViewFactoryManager::~SubViewFactoryManager() { - for (std::map::iterator iter (mSubViewFactories.begin()); - iter!=mSubViewFactories.end(); ++iter) + for (std::map::iterator iter(mSubViewFactories.begin()); + iter != mSubViewFactories.end(); ++iter) delete iter->second; } -void CSVDoc::SubViewFactoryManager::add (const CSMWorld::UniversalId::Type& id, SubViewFactoryBase *factory) +void CSVDoc::SubViewFactoryManager::add(const CSMWorld::UniversalId::Type& id, SubViewFactoryBase* factory) { - assert (mSubViewFactories.find (id)==mSubViewFactories.end()); + assert(mSubViewFactories.find(id) == mSubViewFactories.end()); - mSubViewFactories.insert (std::make_pair (id, factory)); + mSubViewFactories.insert(std::make_pair(id, factory)); } -CSVDoc::SubView *CSVDoc::SubViewFactoryManager::makeSubView (const CSMWorld::UniversalId& id, - CSMDoc::Document& document) +CSVDoc::SubView* CSVDoc::SubViewFactoryManager::makeSubView(const CSMWorld::UniversalId& id, CSMDoc::Document& document) { - std::map::iterator iter = mSubViewFactories.find (id.getType()); + std::map::iterator iter = mSubViewFactories.find(id.getType()); - if (iter==mSubViewFactories.end()) - throw std::runtime_error ("Failed to create a sub view for: " + id.toString()); + if (iter == mSubViewFactories.end()) + throw std::runtime_error("Failed to create a sub view for: " + id.toString()); - return iter->second->makeSubView (id, document); + return iter->second->makeSubView(id, document); } diff --git a/apps/opencs/view/doc/subviewfactory.hpp b/apps/opencs/view/doc/subviewfactory.hpp index 1f7c154806..f4d95e7eaa 100644 --- a/apps/opencs/view/doc/subviewfactory.hpp +++ b/apps/opencs/view/doc/subviewfactory.hpp @@ -16,39 +16,37 @@ namespace CSVDoc class SubViewFactoryBase { - // not implemented - SubViewFactoryBase (const SubViewFactoryBase&); - SubViewFactoryBase& operator= (const SubViewFactoryBase&); + // not implemented + SubViewFactoryBase(const SubViewFactoryBase&); + SubViewFactoryBase& operator=(const SubViewFactoryBase&); - public: + public: + SubViewFactoryBase(); - SubViewFactoryBase(); + virtual ~SubViewFactoryBase(); - virtual ~SubViewFactoryBase(); - - virtual SubView *makeSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) = 0; - ///< The ownership of the returned sub view is not transferred. + virtual SubView* makeSubView(const CSMWorld::UniversalId& id, CSMDoc::Document& document) = 0; + ///< The ownership of the returned sub view is not transferred. }; class SubViewFactoryManager { - std::map mSubViewFactories; - - // not implemented - SubViewFactoryManager (const SubViewFactoryManager&); - SubViewFactoryManager& operator= (const SubViewFactoryManager&); + std::map mSubViewFactories; - public: + // not implemented + SubViewFactoryManager(const SubViewFactoryManager&); + SubViewFactoryManager& operator=(const SubViewFactoryManager&); - SubViewFactoryManager(); + public: + SubViewFactoryManager(); - ~SubViewFactoryManager(); + ~SubViewFactoryManager(); - void add (const CSMWorld::UniversalId::Type& id, SubViewFactoryBase *factory); - ///< The ownership of \a factory is transferred to this. + void add(const CSMWorld::UniversalId::Type& id, SubViewFactoryBase* factory); + ///< The ownership of \a factory is transferred to this. - SubView *makeSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document); - ///< The ownership of the returned sub view is not transferred. + SubView* makeSubView(const CSMWorld::UniversalId& id, CSMDoc::Document& document); + ///< The ownership of the returned sub view is not transferred. }; } diff --git a/apps/opencs/view/doc/subviewfactoryimp.hpp b/apps/opencs/view/doc/subviewfactoryimp.hpp index 152b443a34..40990779a4 100644 --- a/apps/opencs/view/doc/subviewfactoryimp.hpp +++ b/apps/opencs/view/doc/subviewfactoryimp.hpp @@ -7,44 +7,41 @@ namespace CSVDoc { - template + template class SubViewFactory : public SubViewFactoryBase { - public: - - CSVDoc::SubView *makeSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) override; + public: + CSVDoc::SubView* makeSubView(const CSMWorld::UniversalId& id, CSMDoc::Document& document) override; }; - template - CSVDoc::SubView *SubViewFactory::makeSubView (const CSMWorld::UniversalId& id, - CSMDoc::Document& document) + template + CSVDoc::SubView* SubViewFactory::makeSubView(const CSMWorld::UniversalId& id, CSMDoc::Document& document) { - return new SubViewT (id, document); + return new SubViewT(id, document); } - - template + template class SubViewFactoryWithCreator : public SubViewFactoryBase { - bool mSorting; - - public: + bool mSorting; - SubViewFactoryWithCreator (bool sorting = true); + public: + SubViewFactoryWithCreator(bool sorting = true); - CSVDoc::SubView *makeSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) override; + CSVDoc::SubView* makeSubView(const CSMWorld::UniversalId& id, CSMDoc::Document& document) override; }; - template - SubViewFactoryWithCreator::SubViewFactoryWithCreator (bool sorting) - : mSorting (sorting) - {} + template + SubViewFactoryWithCreator::SubViewFactoryWithCreator(bool sorting) + : mSorting(sorting) + { + } - template - CSVDoc::SubView *SubViewFactoryWithCreator::makeSubView ( + template + CSVDoc::SubView* SubViewFactoryWithCreator::makeSubView( const CSMWorld::UniversalId& id, CSMDoc::Document& document) { - return new SubViewT (id, document, CreatorFactoryT(), mSorting); + return new SubViewT(id, document, CreatorFactoryT(), mSorting); } } diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index 0d5dfd829b..8987112dfe 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -3,45 +3,45 @@ #include #include +#include #include +#include #include #include -#include -#include +#include #include #include -#include #include "../../model/doc/document.hpp" #include "../../model/doc/state.hpp" -#include "../../model/prefs/state.hpp" #include "../../model/prefs/shortcut.hpp" +#include "../../model/prefs/state.hpp" #include "../../model/world/idtable.hpp" -#include "../world/subviews.hpp" -#include "../world/scenesubview.hpp" -#include "../world/tablesubview.hpp" #include "../world/dialoguesubview.hpp" +#include "../world/scenesubview.hpp" #include "../world/scriptsubview.hpp" +#include "../world/subviews.hpp" +#include "../world/tablesubview.hpp" #include "../tools/subviews.hpp" +#include #include #include -#include -#include "viewmanager.hpp" -#include "operations.hpp" -#include "subview.hpp" #include "globaldebugprofilemenu.hpp" +#include "operations.hpp" #include "runlogsubview.hpp" +#include "subview.hpp" #include "subviewfactoryimp.hpp" +#include "viewmanager.hpp" -void CSVDoc::View::closeEvent (QCloseEvent *event) +void CSVDoc::View::closeEvent(QCloseEvent* event) { - if (!mViewManager.closeRequest (this)) + if (!mViewManager.closeRequest(this)) event->ignore(); else { @@ -52,52 +52,52 @@ void CSVDoc::View::closeEvent (QCloseEvent *event) void CSVDoc::View::setupFileMenu() { - QMenu *file = menuBar()->addMenu (tr ("File")); + QMenu* file = menuBar()->addMenu(tr("File")); QAction* newGame = createMenuEntry("New Game", ":./menu-new-game.png", file, "document-file-newgame"); - connect (newGame, &QAction::triggered, this, &View::newGameRequest); + connect(newGame, &QAction::triggered, this, &View::newGameRequest); QAction* newAddon = createMenuEntry("New Addon", ":./menu-new-addon.png", file, "document-file-newaddon"); - connect (newAddon, &QAction::triggered, this, &View::newAddonRequest); + connect(newAddon, &QAction::triggered, this, &View::newAddonRequest); QAction* open = createMenuEntry("Open", ":./menu-open.png", file, "document-file-open"); - connect (open, &QAction::triggered, this, &View::loadDocumentRequest); + connect(open, &QAction::triggered, this, &View::loadDocumentRequest); QAction* save = createMenuEntry("Save", ":./menu-save.png", file, "document-file-save"); - connect (save, &QAction::triggered, this, &View::save); + connect(save, &QAction::triggered, this, &View::save); mSave = save; file->addSeparator(); QAction* verify = createMenuEntry("Verify", ":./menu-verify.png", file, "document-file-verify"); - connect (verify, &QAction::triggered, this, &View::verify); + connect(verify, &QAction::triggered, this, &View::verify); mVerify = verify; QAction* merge = createMenuEntry("Merge", ":./menu-merge.png", file, "document-file-merge"); - connect (merge, &QAction::triggered, this, &View::merge); + connect(merge, &QAction::triggered, this, &View::merge); mMerge = merge; QAction* loadErrors = createMenuEntry("Error Log", ":./error-log.png", file, "document-file-errorlog"); - connect (loadErrors, &QAction::triggered, this, &View::loadErrorLog); + connect(loadErrors, &QAction::triggered, this, &View::loadErrorLog); QAction* meta = createMenuEntry(CSMWorld::UniversalId::Type_MetaDatas, file, "document-file-metadata"); - connect (meta, &QAction::triggered, this, &View::addMetaDataSubView); + connect(meta, &QAction::triggered, this, &View::addMetaDataSubView); file->addSeparator(); QAction* close = createMenuEntry("Close", ":./menu-close.png", file, "document-file-close"); - connect (close, &QAction::triggered, this, &View::close); + connect(close, &QAction::triggered, this, &View::close); QAction* exit = createMenuEntry("Exit", ":./menu-exit.png", file, "document-file-exit"); - connect (exit, &QAction::triggered, this, &View::exit); + connect(exit, &QAction::triggered, this, &View::exit); - connect (this, &View::exitApplicationRequest, &mViewManager, &ViewManager::exitApplication); + connect(this, &View::exitApplicationRequest, &mViewManager, &ViewManager::exitApplication); } namespace { - void updateUndoRedoAction(QAction *action, const std::string &settingsKey) + void updateUndoRedoAction(QAction* action, const std::string& settingsKey) { QKeySequence seq; CSMPrefs::State::get().getShortcutManager().getSequence(settingsKey, seq); @@ -118,249 +118,262 @@ void CSVDoc::View::redoActionChanged() void CSVDoc::View::setupEditMenu() { - QMenu *edit = menuBar()->addMenu (tr ("Edit")); + QMenu* edit = menuBar()->addMenu(tr("Edit")); - mUndo = mDocument->getUndoStack().createUndoAction (this, tr("Undo")); + mUndo = mDocument->getUndoStack().createUndoAction(this, tr("Undo")); setupShortcut("document-edit-undo", mUndo); connect(mUndo, &QAction::changed, this, &View::undoActionChanged); mUndo->setIcon(QIcon(QString::fromStdString(":./menu-undo.png"))); - edit->addAction (mUndo); + edit->addAction(mUndo); - mRedo = mDocument->getUndoStack().createRedoAction (this, tr("Redo")); + mRedo = mDocument->getUndoStack().createRedoAction(this, tr("Redo")); connect(mRedo, &QAction::changed, this, &View::redoActionChanged); setupShortcut("document-edit-redo", mRedo); mRedo->setIcon(QIcon(QString::fromStdString(":./menu-redo.png"))); - edit->addAction (mRedo); + edit->addAction(mRedo); - QAction* userSettings = createMenuEntry("Preferences", ":./menu-preferences.png", edit, "document-edit-preferences"); - connect (userSettings, &QAction::triggered, this, &View::editSettingsRequest); + QAction* userSettings + = createMenuEntry("Preferences", ":./menu-preferences.png", edit, "document-edit-preferences"); + connect(userSettings, &QAction::triggered, this, &View::editSettingsRequest); QAction* search = createMenuEntry(CSMWorld::UniversalId::Type_Search, edit, "document-edit-search"); - connect (search, &QAction::triggered, this, &View::addSearchSubView); + connect(search, &QAction::triggered, this, &View::addSearchSubView); } void CSVDoc::View::setupViewMenu() { - QMenu *view = menuBar()->addMenu (tr ("View")); + QMenu* view = menuBar()->addMenu(tr("View")); - QAction *newWindow = createMenuEntry("New View", ":./menu-new-window.png", view, "document-view-newview"); - connect (newWindow, &QAction::triggered, this, &View::newView); + QAction* newWindow = createMenuEntry("New View", ":./menu-new-window.png", view, "document-view-newview"); + connect(newWindow, &QAction::triggered, this, &View::newView); mShowStatusBar = createMenuEntry("Toggle Status Bar", ":./menu-status-bar.png", view, "document-view-statusbar"); - connect (mShowStatusBar, &QAction::toggled, this, &View::toggleShowStatusBar); - mShowStatusBar->setCheckable (true); - mShowStatusBar->setChecked (CSMPrefs::get()["Windows"]["show-statusbar"].isTrue()); + connect(mShowStatusBar, &QAction::toggled, this, &View::toggleShowStatusBar); + mShowStatusBar->setCheckable(true); + mShowStatusBar->setChecked(CSMPrefs::get()["Windows"]["show-statusbar"].isTrue()); - view->addAction (mShowStatusBar); + view->addAction(mShowStatusBar); - QAction *filters = createMenuEntry(CSMWorld::UniversalId::Type_Filters, view, "document-mechanics-filters"); - connect (filters, &QAction::triggered, this, &View::addFiltersSubView); + QAction* filters = createMenuEntry(CSMWorld::UniversalId::Type_Filters, view, "document-mechanics-filters"); + connect(filters, &QAction::triggered, this, &View::addFiltersSubView); } void CSVDoc::View::setupWorldMenu() { - QMenu *world = menuBar()->addMenu (tr ("World")); + QMenu* world = menuBar()->addMenu(tr("World")); - QAction* referenceables = createMenuEntry(CSMWorld::UniversalId::Type_Referenceables, world, "document-world-referencables"); - connect (referenceables, &QAction::triggered, this, &View::addReferenceablesSubView); + QAction* referenceables + = createMenuEntry(CSMWorld::UniversalId::Type_Referenceables, world, "document-world-referencables"); + connect(referenceables, &QAction::triggered, this, &View::addReferenceablesSubView); QAction* references = createMenuEntry(CSMWorld::UniversalId::Type_References, world, "document-world-references"); - connect (references, &QAction::triggered, this, &View::addReferencesSubView); + connect(references, &QAction::triggered, this, &View::addReferencesSubView); world->addSeparator(); QAction* cells = createMenuEntry(CSMWorld::UniversalId::Type_Cells, world, "document-world-cells"); - connect (cells, &QAction::triggered, this, &View::addCellsSubView); + connect(cells, &QAction::triggered, this, &View::addCellsSubView); - QAction *lands = createMenuEntry(CSMWorld::UniversalId::Type_Lands, world, "document-world-lands"); - connect (lands, &QAction::triggered, this, &View::addLandsSubView); + QAction* lands = createMenuEntry(CSMWorld::UniversalId::Type_Lands, world, "document-world-lands"); + connect(lands, &QAction::triggered, this, &View::addLandsSubView); - QAction *landTextures = createMenuEntry(CSMWorld::UniversalId::Type_LandTextures, world, "document-world-landtextures"); - connect (landTextures, &QAction::triggered, this, &View::addLandTexturesSubView); + QAction* landTextures + = createMenuEntry(CSMWorld::UniversalId::Type_LandTextures, world, "document-world-landtextures"); + connect(landTextures, &QAction::triggered, this, &View::addLandTexturesSubView); - QAction *grid = createMenuEntry(CSMWorld::UniversalId::Type_Pathgrids, world, "document-world-pathgrid"); - connect (grid, &QAction::triggered, this, &View::addPathgridSubView); + QAction* grid = createMenuEntry(CSMWorld::UniversalId::Type_Pathgrids, world, "document-world-pathgrid"); + connect(grid, &QAction::triggered, this, &View::addPathgridSubView); world->addSeparator(); QAction* regions = createMenuEntry(CSMWorld::UniversalId::Type_Regions, world, "document-world-regions"); - connect (regions, &QAction::triggered, this, &View::addRegionsSubView); + connect(regions, &QAction::triggered, this, &View::addRegionsSubView); - QAction *regionMap = createMenuEntry(CSMWorld::UniversalId::Type_RegionMap, world, "document-world-regionmap"); - connect (regionMap, &QAction::triggered, this, &View::addRegionMapSubView); + QAction* regionMap = createMenuEntry(CSMWorld::UniversalId::Type_RegionMap, world, "document-world-regionmap"); + connect(regionMap, &QAction::triggered, this, &View::addRegionMapSubView); } void CSVDoc::View::setupMechanicsMenu() { - QMenu *mechanics = menuBar()->addMenu (tr ("Mechanics")); + QMenu* mechanics = menuBar()->addMenu(tr("Mechanics")); QAction* scripts = createMenuEntry(CSMWorld::UniversalId::Type_Scripts, mechanics, "document-mechanics-scripts"); - connect (scripts, &QAction::triggered, this, &View::addScriptsSubView); + connect(scripts, &QAction::triggered, this, &View::addScriptsSubView); - QAction* startScripts = createMenuEntry(CSMWorld::UniversalId::Type_StartScripts, mechanics, "document-mechanics-startscripts"); - connect (startScripts, &QAction::triggered, this, &View::addStartScriptsSubView); + QAction* startScripts + = createMenuEntry(CSMWorld::UniversalId::Type_StartScripts, mechanics, "document-mechanics-startscripts"); + connect(startScripts, &QAction::triggered, this, &View::addStartScriptsSubView); QAction* globals = createMenuEntry(CSMWorld::UniversalId::Type_Globals, mechanics, "document-mechanics-globals"); - connect (globals, &QAction::triggered, this, &View::addGlobalsSubView); + connect(globals, &QAction::triggered, this, &View::addGlobalsSubView); QAction* gmsts = createMenuEntry(CSMWorld::UniversalId::Type_Gmsts, mechanics, "document-mechanics-gamesettings"); - connect (gmsts, &QAction::triggered, this, &View::addGmstsSubView); + connect(gmsts, &QAction::triggered, this, &View::addGmstsSubView); mechanics->addSeparator(); QAction* spells = createMenuEntry(CSMWorld::UniversalId::Type_Spells, mechanics, "document-mechanics-spells"); - connect (spells, &QAction::triggered, this, &View::addSpellsSubView); + connect(spells, &QAction::triggered, this, &View::addSpellsSubView); - QAction* enchantments = createMenuEntry(CSMWorld::UniversalId::Type_Enchantments, mechanics, "document-mechanics-enchantments"); - connect (enchantments, &QAction::triggered, this, &View::addEnchantmentsSubView); + QAction* enchantments + = createMenuEntry(CSMWorld::UniversalId::Type_Enchantments, mechanics, "document-mechanics-enchantments"); + connect(enchantments, &QAction::triggered, this, &View::addEnchantmentsSubView); - QAction* magicEffects = createMenuEntry(CSMWorld::UniversalId::Type_MagicEffects, mechanics, "document-mechanics-magiceffects"); - connect (magicEffects, &QAction::triggered, this, &View::addMagicEffectsSubView); + QAction* magicEffects + = createMenuEntry(CSMWorld::UniversalId::Type_MagicEffects, mechanics, "document-mechanics-magiceffects"); + connect(magicEffects, &QAction::triggered, this, &View::addMagicEffectsSubView); } void CSVDoc::View::setupCharacterMenu() { - QMenu *characters = menuBar()->addMenu (tr ("Characters")); + QMenu* characters = menuBar()->addMenu(tr("Characters")); QAction* skills = createMenuEntry(CSMWorld::UniversalId::Type_Skills, characters, "document-character-skills"); - connect (skills, &QAction::triggered, this, &View::addSkillsSubView); + connect(skills, &QAction::triggered, this, &View::addSkillsSubView); QAction* classes = createMenuEntry(CSMWorld::UniversalId::Type_Classes, characters, "document-character-classes"); - connect (classes, &QAction::triggered, this, &View::addClassesSubView); + connect(classes, &QAction::triggered, this, &View::addClassesSubView); QAction* factions = createMenuEntry(CSMWorld::UniversalId::Type_Faction, characters, "document-character-factions"); - connect (factions, &QAction::triggered, this, &View::addFactionsSubView); + connect(factions, &QAction::triggered, this, &View::addFactionsSubView); QAction* races = createMenuEntry(CSMWorld::UniversalId::Type_Races, characters, "document-character-races"); - connect (races, &QAction::triggered, this, &View::addRacesSubView); + connect(races, &QAction::triggered, this, &View::addRacesSubView); - QAction* birthsigns = createMenuEntry(CSMWorld::UniversalId::Type_Birthsigns, characters, "document-character-birthsigns"); - connect (birthsigns, &QAction::triggered, this, &View::addBirthsignsSubView); + QAction* birthsigns + = createMenuEntry(CSMWorld::UniversalId::Type_Birthsigns, characters, "document-character-birthsigns"); + connect(birthsigns, &QAction::triggered, this, &View::addBirthsignsSubView); - QAction* bodyParts = createMenuEntry(CSMWorld::UniversalId::Type_BodyParts, characters, "document-character-bodyparts"); - connect (bodyParts, &QAction::triggered, this, &View::addBodyPartsSubView); + QAction* bodyParts + = createMenuEntry(CSMWorld::UniversalId::Type_BodyParts, characters, "document-character-bodyparts"); + connect(bodyParts, &QAction::triggered, this, &View::addBodyPartsSubView); characters->addSeparator(); QAction* topics = createMenuEntry(CSMWorld::UniversalId::Type_Topics, characters, "document-character-topics"); - connect (topics, &QAction::triggered, this, &View::addTopicsSubView); + connect(topics, &QAction::triggered, this, &View::addTopicsSubView); - QAction* topicInfos = createMenuEntry(CSMWorld::UniversalId::Type_TopicInfos, characters, "document-character-topicinfos"); - connect (topicInfos, &QAction::triggered, this, &View::addTopicInfosSubView); + QAction* topicInfos + = createMenuEntry(CSMWorld::UniversalId::Type_TopicInfos, characters, "document-character-topicinfos"); + connect(topicInfos, &QAction::triggered, this, &View::addTopicInfosSubView); characters->addSeparator(); - QAction* journals = createMenuEntry(CSMWorld::UniversalId::Type_Journals, characters, "document-character-journals"); - connect (journals, &QAction::triggered, this, &View::addJournalsSubView); + QAction* journals + = createMenuEntry(CSMWorld::UniversalId::Type_Journals, characters, "document-character-journals"); + connect(journals, &QAction::triggered, this, &View::addJournalsSubView); - QAction* journalInfos = createMenuEntry(CSMWorld::UniversalId::Type_JournalInfos, characters, "document-character-journalinfos"); - connect (journalInfos, &QAction::triggered, this, &View::addJournalInfosSubView); + QAction* journalInfos + = createMenuEntry(CSMWorld::UniversalId::Type_JournalInfos, characters, "document-character-journalinfos"); + connect(journalInfos, &QAction::triggered, this, &View::addJournalInfosSubView); } void CSVDoc::View::setupAssetsMenu() { - QMenu *assets = menuBar()->addMenu (tr ("Assets")); + QMenu* assets = menuBar()->addMenu(tr("Assets")); QAction* reload = createMenuEntry("Reload", ":./menu-reload.png", assets, "document-assets-reload"); - connect (reload, &QAction::triggered, &mDocument->getData(), &CSMWorld::Data::assetsChanged); + connect(reload, &QAction::triggered, &mDocument->getData(), &CSMWorld::Data::assetsChanged); assets->addSeparator(); QAction* sounds = createMenuEntry(CSMWorld::UniversalId::Type_Sounds, assets, "document-assets-sounds"); - connect (sounds, &QAction::triggered, this, &View::addSoundsSubView); + connect(sounds, &QAction::triggered, this, &View::addSoundsSubView); QAction* soundGens = createMenuEntry(CSMWorld::UniversalId::Type_SoundGens, assets, "document-assets-soundgens"); - connect (soundGens, &QAction::triggered, this, &View::addSoundGensSubView); + connect(soundGens, &QAction::triggered, this, &View::addSoundGensSubView); assets->addSeparator(); // resources follow here QAction* meshes = createMenuEntry(CSMWorld::UniversalId::Type_Meshes, assets, "document-assets-meshes"); - connect (meshes, &QAction::triggered, this, &View::addMeshesSubView); + connect(meshes, &QAction::triggered, this, &View::addMeshesSubView); QAction* icons = createMenuEntry(CSMWorld::UniversalId::Type_Icons, assets, "document-assets-icons"); - connect (icons, &QAction::triggered, this, &View::addIconsSubView); + connect(icons, &QAction::triggered, this, &View::addIconsSubView); QAction* musics = createMenuEntry(CSMWorld::UniversalId::Type_Musics, assets, "document-assets-musics"); - connect (musics, &QAction::triggered, this, &View::addMusicsSubView); + connect(musics, &QAction::triggered, this, &View::addMusicsSubView); QAction* soundFiles = createMenuEntry(CSMWorld::UniversalId::Type_SoundsRes, assets, "document-assets-soundres"); - connect (soundFiles, &QAction::triggered, this, &View::addSoundsResSubView); + connect(soundFiles, &QAction::triggered, this, &View::addSoundsResSubView); QAction* textures = createMenuEntry(CSMWorld::UniversalId::Type_Textures, assets, "document-assets-textures"); - connect (textures, &QAction::triggered, this, &View::addTexturesSubView); + connect(textures, &QAction::triggered, this, &View::addTexturesSubView); QAction* videos = createMenuEntry(CSMWorld::UniversalId::Type_Videos, assets, "document-assets-videos"); - connect (videos, &QAction::triggered, this, &View::addVideosSubView); + connect(videos, &QAction::triggered, this, &View::addVideosSubView); } void CSVDoc::View::setupDebugMenu() { - QMenu *debug = menuBar()->addMenu (tr ("Debug")); + QMenu* debug = menuBar()->addMenu(tr("Debug")); QAction* profiles = createMenuEntry(CSMWorld::UniversalId::Type_DebugProfiles, debug, "document-debug-profiles"); - connect (profiles, &QAction::triggered, this, &View::addDebugProfilesSubView); + connect(profiles, &QAction::triggered, this, &View::addDebugProfilesSubView); debug->addSeparator(); - mGlobalDebugProfileMenu = new GlobalDebugProfileMenu ( - &dynamic_cast (*mDocument->getData().getTableModel ( - CSMWorld::UniversalId::Type_DebugProfiles)), this); + mGlobalDebugProfileMenu = new GlobalDebugProfileMenu( + &dynamic_cast( + *mDocument->getData().getTableModel(CSMWorld::UniversalId::Type_DebugProfiles)), + this); - connect (mGlobalDebugProfileMenu, &GlobalDebugProfileMenu::triggered, - this, [this](const std::string &profile){ this->run(profile, ""); }); + connect(mGlobalDebugProfileMenu, &GlobalDebugProfileMenu::triggered, this, + [this](const std::string& profile) { this->run(profile, ""); }); - QAction *runDebug = debug->addMenu (mGlobalDebugProfileMenu); - runDebug->setText (tr ("Run OpenMW")); + QAction* runDebug = debug->addMenu(mGlobalDebugProfileMenu); + runDebug->setText(tr("Run OpenMW")); setupShortcut("document-debug-run", runDebug); runDebug->setIcon(QIcon(QString::fromStdString(":./run-openmw.png"))); QAction* stopDebug = createMenuEntry("Stop OpenMW", ":./stop-openmw.png", debug, "document-debug-shutdown"); - connect (stopDebug, &QAction::triggered, this, &View::stop); + connect(stopDebug, &QAction::triggered, this, &View::stop); mStopDebug = stopDebug; QAction* runLog = createMenuEntry(CSMWorld::UniversalId::Type_RunLog, debug, "document-debug-runlog"); - connect (runLog, &QAction::triggered, this, &View::addRunLogSubView); + connect(runLog, &QAction::triggered, this, &View::addRunLogSubView); } void CSVDoc::View::setupHelpMenu() { - QMenu *help = menuBar()->addMenu (tr ("Help")); + QMenu* help = menuBar()->addMenu(tr("Help")); QAction* helpInfo = createMenuEntry("Help", ":/info.png", help, "document-help-help"); - connect (helpInfo, &QAction::triggered, this, &View::openHelp); + connect(helpInfo, &QAction::triggered, this, &View::openHelp); QAction* tutorial = createMenuEntry("Tutorial", ":/info.png", help, "document-help-tutorial"); - connect (tutorial, &QAction::triggered, this, &View::tutorial); + connect(tutorial, &QAction::triggered, this, &View::tutorial); QAction* about = createMenuEntry("About OpenMW-CS", ":./info.png", help, "document-help-about"); - connect (about, &QAction::triggered, this, &View::infoAbout); + connect(about, &QAction::triggered, this, &View::infoAbout); QAction* aboutQt = createMenuEntry("About Qt", ":./qt.png", help, "document-help-qt"); - connect (aboutQt, &QAction::triggered, this, &View::infoAboutQt); + connect(aboutQt, &QAction::triggered, this, &View::infoAboutQt); } QAction* CSVDoc::View::createMenuEntry(CSMWorld::UniversalId::Type type, QMenu* menu, const char* shortcutName) { - const std::string title = CSMWorld::UniversalId (type).getTypeName(); - QAction *entry = new QAction(QString::fromStdString(title), this); + const std::string title = CSMWorld::UniversalId(type).getTypeName(); + QAction* entry = new QAction(QString::fromStdString(title), this); setupShortcut(shortcutName, entry); - const std::string iconName = CSMWorld::UniversalId (type).getIcon(); + const std::string iconName = CSMWorld::UniversalId(type).getIcon(); if (!iconName.empty() && iconName != ":placeholder") entry->setIcon(QIcon(QString::fromStdString(iconName))); - menu->addAction (entry); + menu->addAction(entry); return entry; } -QAction* CSVDoc::View::createMenuEntry(const std::string& title, const std::string& iconName, QMenu* menu, const char* shortcutName) +QAction* CSVDoc::View::createMenuEntry( + const std::string& title, const std::string& iconName, QMenu* menu, const char* shortcutName) { - QAction *entry = new QAction(QString::fromStdString(title), this); + QAction* entry = new QAction(QString::fromStdString(title), this); setupShortcut(shortcutName, entry); if (!iconName.empty() && iconName != ":placeholder") entry->setIcon(QIcon(QString::fromStdString(iconName))); - menu->addAction (entry); + menu->addAction(entry); return entry; } @@ -391,27 +404,26 @@ void CSVDoc::View::updateTitle() stream << Files::pathToUnicodeString(mDocument->getSavePath().filename()); if (mDocument->getState() & CSMDoc::State_Modified) - stream << " *"; + stream << " *"; - if (mViewTotal>1) - stream << " [" << (mViewIndex+1) << "/" << mViewTotal << "]"; + if (mViewTotal > 1) + stream << " [" << (mViewIndex + 1) << "/" << mViewTotal << "]"; CSMPrefs::Category& windows = CSMPrefs::State::get()["Windows"]; - bool hideTitle = windows["hide-subview"].isTrue() && - mSubViews.size()==1 && !mSubViews.at (0)->isFloating(); + bool hideTitle = windows["hide-subview"].isTrue() && mSubViews.size() == 1 && !mSubViews.at(0)->isFloating(); if (hideTitle) - stream << " - " << mSubViews.at (0)->getTitle(); + stream << " - " << mSubViews.at(0)->getTitle(); - setWindowTitle (QString::fromUtf8(stream.str().c_str())); + setWindowTitle(QString::fromUtf8(stream.str().c_str())); } -void CSVDoc::View::updateSubViewIndices(SubView *view) +void CSVDoc::View::updateSubViewIndices(SubView* view) { CSMPrefs::Category& windows = CSMPrefs::State::get()["Windows"]; - if(view && mSubViews.contains(view)) + if (view && mSubViews.contains(view)) { mSubViews.removeOne(view); @@ -420,24 +432,23 @@ void CSVDoc::View::updateSubViewIndices(SubView *view) updateScrollbar(); } - bool hideTitle = windows["hide-subview"].isTrue() && - mSubViews.size()==1 && !mSubViews.at (0)->isFloating(); + bool hideTitle = windows["hide-subview"].isTrue() && mSubViews.size() == 1 && !mSubViews.at(0)->isFloating(); updateTitle(); - for (SubView *subView : mSubViews) + for (SubView* subView : mSubViews) { if (!subView->isFloating()) { if (hideTitle) { - subView->setTitleBarWidget (new QWidget (this)); - subView->setWindowTitle (QString::fromUtf8 (subView->getTitle().c_str())); + subView->setTitleBarWidget(new QWidget(this)); + subView->setWindowTitle(QString::fromUtf8(subView->getTitle().c_str())); } else { delete subView->titleBarWidget(); - subView->setTitleBarWidget (nullptr); + subView->setTitleBarWidget(nullptr); } } } @@ -448,38 +459,41 @@ void CSVDoc::View::updateActions() bool editing = !(mDocument->getState() & CSMDoc::State_Locked); bool running = mDocument->getState() & CSMDoc::State_Running; - for (std::vector::iterator iter (mEditingActions.begin()); iter!=mEditingActions.end(); ++iter) - (*iter)->setEnabled (editing); + for (std::vector::iterator iter(mEditingActions.begin()); iter != mEditingActions.end(); ++iter) + (*iter)->setEnabled(editing); - mUndo->setEnabled (editing && mDocument->getUndoStack().canUndo()); - mRedo->setEnabled (editing && mDocument->getUndoStack().canRedo()); + mUndo->setEnabled(editing && mDocument->getUndoStack().canUndo()); + mRedo->setEnabled(editing && mDocument->getUndoStack().canRedo()); - mSave->setEnabled (!(mDocument->getState() & CSMDoc::State_Saving) && !running); - mVerify->setEnabled (!(mDocument->getState() & CSMDoc::State_Verifying)); + mSave->setEnabled(!(mDocument->getState() & CSMDoc::State_Saving) && !running); + mVerify->setEnabled(!(mDocument->getState() & CSMDoc::State_Verifying)); - mGlobalDebugProfileMenu->updateActions (running); - mStopDebug->setEnabled (running); + mGlobalDebugProfileMenu->updateActions(running); + mStopDebug->setEnabled(running); - mMerge->setEnabled (mDocument->getContentFiles().size()>1 && - !(mDocument->getState() & CSMDoc::State_Merging)); + mMerge->setEnabled(mDocument->getContentFiles().size() > 1 && !(mDocument->getState() & CSMDoc::State_Merging)); } -CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews) - : mViewManager (viewManager), mDocument (document), mViewIndex (totalViews-1), - mViewTotal (totalViews), mScroll(nullptr), mScrollbarOnly(false) +CSVDoc::View::View(ViewManager& viewManager, CSMDoc::Document* document, int totalViews) + : mViewManager(viewManager) + , mDocument(document) + , mViewIndex(totalViews - 1) + , mViewTotal(totalViews) + , mScroll(nullptr) + , mScrollbarOnly(false) { CSMPrefs::Category& windows = CSMPrefs::State::get()["Windows"]; - int width = std::max (windows["default-width"].toInt(), 300); - int height = std::max (windows["default-height"].toInt(), 300); + int width = std::max(windows["default-width"].toInt(), 300); + int height = std::max(windows["default-height"].toInt(), 300); - resize (width, height); + resize(width, height); - mSubViewWindow.setDockOptions (QMainWindow::AllowNestedDocks); + mSubViewWindow.setDockOptions(QMainWindow::AllowNestedDocks); if (windows["mainwindow-scrollbar"].toString() == "Grow Only") { - setCentralWidget (&mSubViewWindow); + setCentralWidget(&mSubViewWindow); } else { @@ -487,7 +501,7 @@ CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int to } mOperations = new Operations; - addDockWidget (Qt::BottomDockWidgetArea, mOperations); + addDockWidget(Qt::BottomDockWidgetArea, mOperations); setContextMenuPolicy(Qt::NoContextMenu); @@ -497,32 +511,29 @@ CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int to updateActions(); - CSVWorld::addSubViewFactories (mSubViewFactory); - CSVTools::addSubViewFactories (mSubViewFactory); + CSVWorld::addSubViewFactories(mSubViewFactory); + CSVTools::addSubViewFactories(mSubViewFactory); - mSubViewFactory.add (CSMWorld::UniversalId::Type_RunLog, new SubViewFactory); + mSubViewFactory.add(CSMWorld::UniversalId::Type_RunLog, new SubViewFactory); - connect (mOperations, &Operations::abortOperation, this, &View::abortOperation); + connect(mOperations, &Operations::abortOperation, this, &View::abortOperation); - connect (&CSMPrefs::State::get(), &CSMPrefs::State::settingChanged, - this, &View::settingChanged); + connect(&CSMPrefs::State::get(), &CSMPrefs::State::settingChanged, this, &View::settingChanged); } -CSVDoc::View::~View() -{ -} +CSVDoc::View::~View() {} -const CSMDoc::Document *CSVDoc::View::getDocument() const +const CSMDoc::Document* CSVDoc::View::getDocument() const { - return mDocument; + return mDocument; } -CSMDoc::Document *CSVDoc::View::getDocument() +CSMDoc::Document* CSVDoc::View::getDocument() { - return mDocument; + return mDocument; } -void CSVDoc::View::setIndex (int viewIndex, int totalViews) +void CSVDoc::View::setIndex(int viewIndex, int totalViews) { mViewIndex = viewIndex; mViewTotal = totalViews; @@ -534,32 +545,33 @@ void CSVDoc::View::updateDocumentState() updateTitle(); updateActions(); - static const int operations[] = - { - CSMDoc::State_Saving, CSMDoc::State_Verifying, CSMDoc::State_Searching, + static const int operations[] = { + CSMDoc::State_Saving, + CSMDoc::State_Verifying, + CSMDoc::State_Searching, CSMDoc::State_Merging, // end marker -1, }; - int state = mDocument->getState() ; + int state = mDocument->getState(); - for (int i=0; operations[i]!=-1; ++i) + for (int i = 0; operations[i] != -1; ++i) if (!(state & operations[i])) - mOperations->quitOperation (operations[i]); + mOperations->quitOperation(operations[i]); - QList subViews = findChildren(); + QList subViews = findChildren(); - for (QList::iterator iter (subViews.begin()); iter!=subViews.end(); ++iter) - (*iter)->setEditLock (state & CSMDoc::State_Locked); + for (QList::iterator iter(subViews.begin()); iter != subViews.end(); ++iter) + (*iter)->setEditLock(state & CSMDoc::State_Locked); } -void CSVDoc::View::updateProgress (int current, int max, int type, int threads) +void CSVDoc::View::updateProgress(int current, int max, int type, int threads) { - mOperations->setProgress (current, max, type, threads); + mOperations->setProgress(current, max, type, threads); } -void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::string& hint) +void CSVDoc::View::addSubView(const CSMWorld::UniversalId& id, const std::string& hint) { CSMPrefs::Category& windows = CSMPrefs::State::get()["Windows"]; @@ -568,57 +580,55 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::strin // User setting to reuse sub views (on a per top level view basis) if (windows["reuse"].isTrue()) { - for (SubView *sb : mSubViews) + for (SubView* sb : mSubViews) { - bool isSubViewReferenceable = - sb->getUniversalId().getType() == CSMWorld::UniversalId::Type_Referenceable; + bool isSubViewReferenceable = sb->getUniversalId().getType() == CSMWorld::UniversalId::Type_Referenceable; - if((isReferenceable && isSubViewReferenceable && id.getId() == sb->getUniversalId().getId()) - || - (!isReferenceable && id == sb->getUniversalId())) + if ((isReferenceable && isSubViewReferenceable && id.getId() == sb->getUniversalId().getId()) + || (!isReferenceable && id == sb->getUniversalId())) { sb->setFocus(); if (!hint.empty()) - sb->useHint (hint); + sb->useHint(hint); return; } } } if (mScroll) - QObject::connect(mScroll->horizontalScrollBar(), &QScrollBar::rangeChanged, - this, &View::moveScrollBarToEnd); + QObject::connect(mScroll->horizontalScrollBar(), &QScrollBar::rangeChanged, this, &View::moveScrollBarToEnd); // 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 // // If the sub view limit setting is one, the sub view title bar is hidden and the // text in the main title bar is adjusted accordingly - if(mSubViews.size() >= windows["max-subviews"].toInt()) // create a new top level view + if (mSubViews.size() >= windows["max-subviews"].toInt()) // create a new top level view { mViewManager.addView(mDocument, id, hint); return; } - SubView *view = nullptr; - if(isReferenceable) + SubView* view = nullptr; + if (isReferenceable) { - view = mSubViewFactory.makeSubView (CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Referenceable, id.getId()), *mDocument); + view = mSubViewFactory.makeSubView( + CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Referenceable, id.getId()), *mDocument); } else { - view = mSubViewFactory.makeSubView (id, *mDocument); + view = mSubViewFactory.makeSubView(id, *mDocument); } assert(view); view->setParent(this); - view->setEditLock (mDocument->getState() & CSMDoc::State_Locked); + view->setEditLock(mDocument->getState() & CSMDoc::State_Locked); mSubViews.append(view); // only after assert int minWidth = windows["minimum-width"].toInt(); - view->setMinimumWidth (minWidth); + view->setMinimumWidth(minWidth); - view->setStatusBar (mShowStatusBar->isChecked()); + view->setStatusBar(mShowStatusBar->isChecked()); // Work out how to deal with additional subviews // @@ -635,31 +645,28 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::strin updateWidth(windows["grow-limit"].isTrue(), minWidth); - mSubViewWindow.addDockWidget (Qt::TopDockWidgetArea, view); + mSubViewWindow.addDockWidget(Qt::TopDockWidgetArea, view); updateSubViewIndices(); - connect (view, &SubView::focusId, this, &View::addSubView); + connect(view, &SubView::focusId, this, &View::addSubView); - connect (view, qOverload(&SubView::closeRequest), - this, &View::closeRequest); + connect(view, qOverload(&SubView::closeRequest), this, &View::closeRequest); - connect (view, &SubView::updateTitle, this, &View::updateTitle); + connect(view, &SubView::updateTitle, this, &View::updateTitle); - connect (view, &SubView::updateSubViewIndices, this, &View::updateSubViewIndices); + connect(view, &SubView::updateSubViewIndices, this, &View::updateSubViewIndices); CSVWorld::TableSubView* tableView = dynamic_cast(view); if (tableView) { - connect (this, &View::requestFocus, - tableView, &CSVWorld::TableSubView::requestFocus); + connect(this, &View::requestFocus, tableView, &CSVWorld::TableSubView::requestFocus); } CSVWorld::SceneSubView* sceneView = dynamic_cast(view); if (sceneView) { - connect(sceneView, &CSVWorld::SceneSubView::requestFocus, - this, &View::onRequestFocus); + connect(sceneView, &CSVWorld::SceneSubView::requestFocus, this, &View::onRequestFocus); } if (CSMPrefs::State::get()["ID Tables"]["subview-new-window"].isTrue()) @@ -676,7 +683,7 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::strin view->show(); if (!hint.empty()) - view->useHint (hint); + view->useHint(hint); } void CSVDoc::View::moveScrollBarToEnd(int min, int max) @@ -685,22 +692,21 @@ void CSVDoc::View::moveScrollBarToEnd(int min, int max) { mScroll->horizontalScrollBar()->setValue(max); - QObject::disconnect(mScroll->horizontalScrollBar(), &QScrollBar::rangeChanged, - this, &View::moveScrollBarToEnd); + QObject::disconnect(mScroll->horizontalScrollBar(), &QScrollBar::rangeChanged, this, &View::moveScrollBarToEnd); } } -void CSVDoc::View::settingChanged (const CSMPrefs::Setting *setting) +void CSVDoc::View::settingChanged(const CSMPrefs::Setting* setting) { - if (*setting=="Windows/hide-subview") - updateSubViewIndices (nullptr); - else if (*setting=="Windows/mainwindow-scrollbar") + if (*setting == "Windows/hide-subview") + updateSubViewIndices(nullptr); + else if (*setting == "Windows/mainwindow-scrollbar") { - if (setting->toString()!="Grow Only") + if (setting->toString() != "Grow Only") { if (mScroll) { - if (setting->toString()=="Scrollbar Only") + if (setting->toString() == "Scrollbar Only") { mScrollbarOnly = true; mSubViewWindow.setMinimumWidth(0); @@ -716,10 +722,10 @@ void CSVDoc::View::settingChanged (const CSMPrefs::Setting *setting) createScrollArea(); } } - else if (mScroll) + else if (mScroll) { mScroll->takeWidget(); - setCentralWidget (&mSubViewWindow); + setCentralWidget(&mSubViewWindow); mScroll->deleteLater(); mScroll = nullptr; } @@ -728,7 +734,7 @@ void CSVDoc::View::settingChanged (const CSMPrefs::Setting *setting) void CSVDoc::View::newView() { - mViewManager.addView (mDocument); + mViewManager.addView(mDocument); } void CSVDoc::View::save() @@ -749,11 +755,13 @@ void CSVDoc::View::tutorial() void CSVDoc::View::infoAbout() { // Get current OpenMW version - QString versionInfo = (Version::getOpenmwVersionDescription(mDocument->getResourceDir())+ + QString versionInfo = (Version::getOpenmwVersionDescription(mDocument->getResourceDir()) + #if defined(__x86_64__) || defined(_M_X64) - " (64-bit)").c_str(); + " (64-bit)") + .c_str(); #else - " (32-bit)").c_str(); + " (32-bit)") + .c_str(); #endif // Get current year @@ -764,25 +772,23 @@ void CSVDoc::View::infoAbout() strftime(copyrightInfo, sizeof(copyrightInfo), "Copyright © 2008-%Y OpenMW Team", &tstruct); QString aboutText = QString( - "

" - "

OpenMW Construction Set

" - "%1\n\n" - "%2\n\n" - "%3\n\n" - "" - "" - "" - "" - "" - "
%4https://openmw.org
%5https://forum.openmw.org
%6https://gitlab.com/OpenMW/openmw/issues
%7ircs://irc.libera.chat/#openmw
" - "

") - .arg(versionInfo - , tr("OpenMW-CS is a content file editor for OpenMW, a modern, free and open source game engine.") - , tr(copyrightInfo) - , tr("Home Page:") - , tr("Forum:") - , tr("Bug Tracker:") - , tr("IRC:")); + "

" + "

OpenMW Construction Set

" + "%1\n\n" + "%2\n\n" + "%3\n\n" + "" + "" + "" + "" + "" + "
%4https://openmw.org
%5https://forum.openmw.org
%6https://gitlab.com/OpenMW/openmw/issues
%7ircs://irc.libera.chat/#openmw
" + "

") + .arg(versionInfo, + tr("OpenMW-CS is a content file editor for OpenMW, a modern, free and open source game " + "engine."), + tr(copyrightInfo), tr("Home Page:"), tr("Forum:"), tr("Bug Tracker:"), tr("IRC:")); QMessageBox::about(this, "About OpenMW-CS", aboutText); } @@ -794,233 +800,233 @@ void CSVDoc::View::infoAboutQt() void CSVDoc::View::verify() { - addSubView (mDocument->verify()); + addSubView(mDocument->verify()); } void CSVDoc::View::addGlobalsSubView() { - addSubView (CSMWorld::UniversalId::Type_Globals); + addSubView(CSMWorld::UniversalId::Type_Globals); } void CSVDoc::View::addGmstsSubView() { - addSubView (CSMWorld::UniversalId::Type_Gmsts); + addSubView(CSMWorld::UniversalId::Type_Gmsts); } void CSVDoc::View::addSkillsSubView() { - addSubView (CSMWorld::UniversalId::Type_Skills); + addSubView(CSMWorld::UniversalId::Type_Skills); } void CSVDoc::View::addClassesSubView() { - addSubView (CSMWorld::UniversalId::Type_Classes); + addSubView(CSMWorld::UniversalId::Type_Classes); } void CSVDoc::View::addFactionsSubView() { - addSubView (CSMWorld::UniversalId::Type_Factions); + addSubView(CSMWorld::UniversalId::Type_Factions); } void CSVDoc::View::addRacesSubView() { - addSubView (CSMWorld::UniversalId::Type_Races); + addSubView(CSMWorld::UniversalId::Type_Races); } void CSVDoc::View::addSoundsSubView() { - addSubView (CSMWorld::UniversalId::Type_Sounds); + addSubView(CSMWorld::UniversalId::Type_Sounds); } void CSVDoc::View::addScriptsSubView() { - addSubView (CSMWorld::UniversalId::Type_Scripts); + addSubView(CSMWorld::UniversalId::Type_Scripts); } void CSVDoc::View::addRegionsSubView() { - addSubView (CSMWorld::UniversalId::Type_Regions); + addSubView(CSMWorld::UniversalId::Type_Regions); } void CSVDoc::View::addBirthsignsSubView() { - addSubView (CSMWorld::UniversalId::Type_Birthsigns); + addSubView(CSMWorld::UniversalId::Type_Birthsigns); } void CSVDoc::View::addSpellsSubView() { - addSubView (CSMWorld::UniversalId::Type_Spells); + addSubView(CSMWorld::UniversalId::Type_Spells); } void CSVDoc::View::addCellsSubView() { - addSubView (CSMWorld::UniversalId::Type_Cells); + addSubView(CSMWorld::UniversalId::Type_Cells); } void CSVDoc::View::addReferenceablesSubView() { - addSubView (CSMWorld::UniversalId::Type_Referenceables); + addSubView(CSMWorld::UniversalId::Type_Referenceables); } void CSVDoc::View::addReferencesSubView() { - addSubView (CSMWorld::UniversalId::Type_References); + addSubView(CSMWorld::UniversalId::Type_References); } void CSVDoc::View::addRegionMapSubView() { - addSubView (CSMWorld::UniversalId::Type_RegionMap); + addSubView(CSMWorld::UniversalId::Type_RegionMap); } void CSVDoc::View::addFiltersSubView() { - addSubView (CSMWorld::UniversalId::Type_Filters); + addSubView(CSMWorld::UniversalId::Type_Filters); } void CSVDoc::View::addTopicsSubView() { - addSubView (CSMWorld::UniversalId::Type_Topics); + addSubView(CSMWorld::UniversalId::Type_Topics); } void CSVDoc::View::addJournalsSubView() { - addSubView (CSMWorld::UniversalId::Type_Journals); + addSubView(CSMWorld::UniversalId::Type_Journals); } void CSVDoc::View::addTopicInfosSubView() { - addSubView (CSMWorld::UniversalId::Type_TopicInfos); + addSubView(CSMWorld::UniversalId::Type_TopicInfos); } void CSVDoc::View::addJournalInfosSubView() { - addSubView (CSMWorld::UniversalId::Type_JournalInfos); + addSubView(CSMWorld::UniversalId::Type_JournalInfos); } void CSVDoc::View::addEnchantmentsSubView() { - addSubView (CSMWorld::UniversalId::Type_Enchantments); + addSubView(CSMWorld::UniversalId::Type_Enchantments); } void CSVDoc::View::addBodyPartsSubView() { - addSubView (CSMWorld::UniversalId::Type_BodyParts); + addSubView(CSMWorld::UniversalId::Type_BodyParts); } void CSVDoc::View::addSoundGensSubView() { - addSubView (CSMWorld::UniversalId::Type_SoundGens); + addSubView(CSMWorld::UniversalId::Type_SoundGens); } void CSVDoc::View::addMeshesSubView() { - addSubView (CSMWorld::UniversalId::Type_Meshes); + addSubView(CSMWorld::UniversalId::Type_Meshes); } void CSVDoc::View::addIconsSubView() { - addSubView (CSMWorld::UniversalId::Type_Icons); + addSubView(CSMWorld::UniversalId::Type_Icons); } void CSVDoc::View::addMusicsSubView() { - addSubView (CSMWorld::UniversalId::Type_Musics); + addSubView(CSMWorld::UniversalId::Type_Musics); } void CSVDoc::View::addSoundsResSubView() { - addSubView (CSMWorld::UniversalId::Type_SoundsRes); + addSubView(CSMWorld::UniversalId::Type_SoundsRes); } void CSVDoc::View::addMagicEffectsSubView() { - addSubView (CSMWorld::UniversalId::Type_MagicEffects); + addSubView(CSMWorld::UniversalId::Type_MagicEffects); } void CSVDoc::View::addTexturesSubView() { - addSubView (CSMWorld::UniversalId::Type_Textures); + addSubView(CSMWorld::UniversalId::Type_Textures); } void CSVDoc::View::addVideosSubView() { - addSubView (CSMWorld::UniversalId::Type_Videos); + addSubView(CSMWorld::UniversalId::Type_Videos); } void CSVDoc::View::addDebugProfilesSubView() { - addSubView (CSMWorld::UniversalId::Type_DebugProfiles); + addSubView(CSMWorld::UniversalId::Type_DebugProfiles); } void CSVDoc::View::addRunLogSubView() { - addSubView (CSMWorld::UniversalId::Type_RunLog); + addSubView(CSMWorld::UniversalId::Type_RunLog); } void CSVDoc::View::addLandsSubView() { - addSubView (CSMWorld::UniversalId::Type_Lands); + addSubView(CSMWorld::UniversalId::Type_Lands); } void CSVDoc::View::addLandTexturesSubView() { - addSubView (CSMWorld::UniversalId::Type_LandTextures); + addSubView(CSMWorld::UniversalId::Type_LandTextures); } void CSVDoc::View::addPathgridSubView() { - addSubView (CSMWorld::UniversalId::Type_Pathgrids); + addSubView(CSMWorld::UniversalId::Type_Pathgrids); } void CSVDoc::View::addStartScriptsSubView() { - addSubView (CSMWorld::UniversalId::Type_StartScripts); + addSubView(CSMWorld::UniversalId::Type_StartScripts); } void CSVDoc::View::addSearchSubView() { - addSubView (mDocument->newSearch()); + addSubView(mDocument->newSearch()); } void CSVDoc::View::addMetaDataSubView() { - addSubView (CSMWorld::UniversalId (CSMWorld::UniversalId::Type_MetaData, "sys::meta")); + addSubView(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_MetaData, "sys::meta")); } -void CSVDoc::View::abortOperation (int type) +void CSVDoc::View::abortOperation(int type) { - mDocument->abortOperation (type); + mDocument->abortOperation(type); updateActions(); } -CSVDoc::Operations *CSVDoc::View::getOperations() const +CSVDoc::Operations* CSVDoc::View::getOperations() const { return mOperations; } void CSVDoc::View::exit() { - emit exitApplicationRequest (this); + emit exitApplicationRequest(this); } -void CSVDoc::View::resizeViewWidth (int width) +void CSVDoc::View::resizeViewWidth(int width) { if (width >= 0) - resize (width, geometry().height()); + resize(width, geometry().height()); } -void CSVDoc::View::resizeViewHeight (int height) +void CSVDoc::View::resizeViewHeight(int height) { if (height >= 0) - resize (geometry().width(), height); + resize(geometry().width(), height); } -void CSVDoc::View::toggleShowStatusBar (bool show) +void CSVDoc::View::toggleShowStatusBar(bool show) { - for (QObject *view : mSubViewWindow.children()) + for (QObject* view : mSubViewWindow.children()) { - if (CSVDoc::SubView *subView = dynamic_cast (view)) - subView->setStatusBar (show); + if (CSVDoc::SubView* subView = dynamic_cast(view)) + subView->setStatusBar(show); } } @@ -1031,12 +1037,12 @@ void CSVDoc::View::toggleStatusBar(bool checked) void CSVDoc::View::loadErrorLog() { - addSubView (CSMWorld::UniversalId (CSMWorld::UniversalId::Type_LoadErrorLog, 0)); + addSubView(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_LoadErrorLog, 0)); } -void CSVDoc::View::run (const std::string& profile, const std::string& startupInstruction) +void CSVDoc::View::run(const std::string& profile, const std::string& startupInstruction) { - mDocument->startRunning (profile, startupInstruction); + mDocument->startRunning(profile, startupInstruction); } void CSVDoc::View::stop() @@ -1044,23 +1050,23 @@ void CSVDoc::View::stop() mDocument->stopRunning(); } -void CSVDoc::View::closeRequest (SubView *subView) +void CSVDoc::View::closeRequest(SubView* subView) { CSMPrefs::Category& windows = CSMPrefs::State::get()["Windows"]; - if (mSubViews.size()>1 || mViewTotal<=1 || !windows["hide-subview"].isTrue()) + if (mSubViews.size() > 1 || mViewTotal <= 1 || !windows["hide-subview"].isTrue()) { subView->deleteLater(); - mSubViews.removeOne (subView); + mSubViews.removeOne(subView); } - else if (mViewManager.closeRequest (this)) - mViewManager.removeDocAndView (mDocument); + else if (mViewManager.closeRequest(this)) + mViewManager.removeDocAndView(mDocument); } void CSVDoc::View::updateScrollbar() { QRect rect; - QWidget *topLevel = QApplication::topLevelAt(pos()); + QWidget* topLevel = QApplication::topLevelAt(pos()); if (topLevel) rect = topLevel->rect(); else @@ -1074,7 +1080,7 @@ void CSVDoc::View::updateScrollbar() int frameWidth = frameGeometry().width() - width(); - if ((newWidth+frameWidth) >= rect.width()) + if ((newWidth + frameWidth) >= rect.width()) mSubViewWindow.setMinimumWidth(newWidth); else mSubViewWindow.setMinimumWidth(0); @@ -1082,12 +1088,12 @@ void CSVDoc::View::updateScrollbar() void CSVDoc::View::merge() { - emit mergeDocument (mDocument); + emit mergeDocument(mDocument); } void CSVDoc::View::updateWidth(bool isGrowLimit, int minSubViewWidth) { - QDesktopWidget *dw = QApplication::desktop(); + QDesktopWidget* dw = QApplication::desktop(); QRect rect; if (isGrowLimit) rect = dw->screenGeometry(this); @@ -1096,20 +1102,20 @@ void CSVDoc::View::updateWidth(bool isGrowLimit, int minSubViewWidth) if (!mScrollbarOnly && mScroll && mSubViews.size() > 1) { - int newWidth = width()+minSubViewWidth; + int newWidth = width() + minSubViewWidth; int frameWidth = frameGeometry().width() - width(); - if (newWidth+frameWidth <= rect.width()) + if (newWidth + frameWidth <= rect.width()) { resize(newWidth, height()); // WARNING: below code assumes that new subviews are added to the right - if (x() > rect.width()-(newWidth+frameWidth)) - move(rect.width()-(newWidth+frameWidth), y()); // shift left to stay within the screen + if (x() > rect.width() - (newWidth + frameWidth)) + move(rect.width() - (newWidth + frameWidth), y()); // shift left to stay within the screen } else { // full width - resize(rect.width()-frameWidth, height()); - mSubViewWindow.setMinimumWidth(mSubViewWindow.width()+minSubViewWidth); + resize(rect.width() - frameWidth, height()); + mSubViewWindow.setMinimumWidth(mSubViewWindow.width() + minSubViewWidth); move(0, y()); } } @@ -1123,15 +1129,15 @@ void CSVDoc::View::createScrollArea() setCentralWidget(mScroll); } -void CSVDoc::View::onRequestFocus (const std::string& id) +void CSVDoc::View::onRequestFocus(const std::string& id) { - if(CSMPrefs::get()["3D Scene Editing"]["open-list-view"].isTrue()) + if (CSMPrefs::get()["3D Scene Editing"]["open-list-view"].isTrue()) { addReferencesSubView(); emit requestFocus(id); } else { - addSubView(CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Reference, id)); + addSubView(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Reference, id)); } } diff --git a/apps/opencs/view/doc/view.hpp b/apps/opencs/view/doc/view.hpp index c0d036daae..5c1cc6d5e9 100644 --- a/apps/opencs/view/doc/view.hpp +++ b/apps/opencs/view/doc/view.hpp @@ -1,8 +1,8 @@ #ifndef CSV_DOC_VIEW_H #define CSV_DOC_VIEW_H -#include #include +#include #include @@ -35,241 +35,240 @@ namespace CSVDoc class View : public QMainWindow { - Q_OBJECT - - ViewManager& mViewManager; - CSMDoc::Document *mDocument; - int mViewIndex; - int mViewTotal; - QList mSubViews; - QAction *mUndo; - QAction *mRedo; - QAction *mSave; - QAction *mVerify; - QAction *mShowStatusBar; - QAction *mStopDebug; - QAction *mMerge; - std::vector mEditingActions; - Operations *mOperations; - SubViewFactoryManager mSubViewFactory; - QMainWindow mSubViewWindow; - GlobalDebugProfileMenu *mGlobalDebugProfileMenu; - QScrollArea *mScroll; - bool mScrollbarOnly; - + Q_OBJECT - // not implemented - View (const View&); - View& operator= (const View&); + ViewManager& mViewManager; + CSMDoc::Document* mDocument; + int mViewIndex; + int mViewTotal; + QList mSubViews; + QAction* mUndo; + QAction* mRedo; + QAction* mSave; + QAction* mVerify; + QAction* mShowStatusBar; + QAction* mStopDebug; + QAction* mMerge; + std::vector mEditingActions; + Operations* mOperations; + SubViewFactoryManager mSubViewFactory; + QMainWindow mSubViewWindow; + GlobalDebugProfileMenu* mGlobalDebugProfileMenu; + QScrollArea* mScroll; + bool mScrollbarOnly; - private: + // not implemented + View(const View&); + View& operator=(const View&); - void closeEvent (QCloseEvent *event) override; + private: + void closeEvent(QCloseEvent* event) override; - QAction* createMenuEntry(CSMWorld::UniversalId::Type type, QMenu* menu, const char* shortcutName); - QAction* createMenuEntry(const std::string& title, const std::string& iconName, QMenu* menu, const char* shortcutName); + QAction* createMenuEntry(CSMWorld::UniversalId::Type type, QMenu* menu, const char* shortcutName); + QAction* createMenuEntry( + const std::string& title, const std::string& iconName, QMenu* menu, const char* shortcutName); - void setupFileMenu(); + void setupFileMenu(); - void setupEditMenu(); + void setupEditMenu(); - void setupViewMenu(); + void setupViewMenu(); - void setupWorldMenu(); + void setupWorldMenu(); - void setupMechanicsMenu(); + void setupMechanicsMenu(); - void setupCharacterMenu(); + void setupCharacterMenu(); - void setupAssetsMenu(); + void setupAssetsMenu(); - void setupDebugMenu(); + void setupDebugMenu(); - void setupHelpMenu(); + void setupHelpMenu(); - void setupUi(); + void setupUi(); - void setupShortcut(const char* name, QAction* action); + void setupShortcut(const char* name, QAction* action); - void updateActions(); + void updateActions(); - void exitApplication(); + void exitApplication(); - /// User preference function - void resizeViewWidth (int width); + /// User preference function + void resizeViewWidth(int width); - /// User preference function - void resizeViewHeight (int height); + /// User preference function + void resizeViewHeight(int height); - void updateScrollbar(); - void updateWidth(bool isGrowLimit, int minSubViewWidth); - void createScrollArea(); - public: + void updateScrollbar(); + void updateWidth(bool isGrowLimit, int minSubViewWidth); + void createScrollArea(); - View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews); + public: + View(ViewManager& viewManager, CSMDoc::Document* document, int totalViews); - ///< The ownership of \a document is not transferred to *this. + ///< The ownership of \a document is not transferred to *this. - ~View() override; + ~View() override; - const CSMDoc::Document *getDocument() const; + const CSMDoc::Document* getDocument() const; - CSMDoc::Document *getDocument(); + CSMDoc::Document* getDocument(); - void setIndex (int viewIndex, int totalViews); + void setIndex(int viewIndex, int totalViews); - void updateDocumentState(); + void updateDocumentState(); - void updateProgress (int current, int max, int type, int threads); + void updateProgress(int current, int max, int type, int threads); - void toggleStatusBar(bool checked); + void toggleStatusBar(bool checked); - Operations *getOperations() const; + Operations* getOperations() const; - signals: + signals: - void newGameRequest(); + void newGameRequest(); - void newAddonRequest(); + void newAddonRequest(); - void loadDocumentRequest(); + void loadDocumentRequest(); - void exitApplicationRequest (CSVDoc::View *view); + void exitApplicationRequest(CSVDoc::View* view); - void editSettingsRequest(); + void editSettingsRequest(); - void mergeDocument (CSMDoc::Document *document); + void mergeDocument(CSMDoc::Document* document); - void requestFocus (const std::string& id); + void requestFocus(const std::string& id); - public slots: + public slots: - void addSubView (const CSMWorld::UniversalId& id, const std::string& hint = ""); - ///< \param hint Suggested view point (e.g. coordinates in a 3D scene or a line number - /// in a script). + void addSubView(const CSMWorld::UniversalId& id, const std::string& hint = ""); + ///< \param hint Suggested view point (e.g. coordinates in a 3D scene or a line number + /// in a script). - void abortOperation (int type); + void abortOperation(int type); - void updateTitle(); + void updateTitle(); - // called when subviews are added or removed - void updateSubViewIndices (SubView *view = nullptr); + // called when subviews are added or removed + void updateSubViewIndices(SubView* view = nullptr); - private slots: + private slots: - void settingChanged (const CSMPrefs::Setting *setting); + void settingChanged(const CSMPrefs::Setting* setting); - void undoActionChanged(); + void undoActionChanged(); - void redoActionChanged(); + void redoActionChanged(); - void newView(); + void newView(); - void save(); + void save(); - void exit(); + void exit(); - static void openHelp(); + static void openHelp(); - static void tutorial(); + static void tutorial(); - void infoAbout(); + void infoAbout(); - void infoAboutQt(); + void infoAboutQt(); - void verify(); + void verify(); - void addGlobalsSubView(); + void addGlobalsSubView(); - void addGmstsSubView(); + void addGmstsSubView(); - void addSkillsSubView(); + void addSkillsSubView(); - void addClassesSubView(); + void addClassesSubView(); - void addFactionsSubView(); + void addFactionsSubView(); - void addRacesSubView(); + void addRacesSubView(); - void addSoundsSubView(); + void addSoundsSubView(); - void addScriptsSubView(); + void addScriptsSubView(); - void addRegionsSubView(); + void addRegionsSubView(); - void addBirthsignsSubView(); + void addBirthsignsSubView(); - void addSpellsSubView(); + void addSpellsSubView(); - void addCellsSubView(); + void addCellsSubView(); - void addReferenceablesSubView(); + void addReferenceablesSubView(); - void addReferencesSubView(); + void addReferencesSubView(); - void addRegionMapSubView(); + void addRegionMapSubView(); - void addFiltersSubView(); + void addFiltersSubView(); - void addTopicsSubView(); + void addTopicsSubView(); - void addJournalsSubView(); + void addJournalsSubView(); - void addTopicInfosSubView(); + void addTopicInfosSubView(); - void addJournalInfosSubView(); + void addJournalInfosSubView(); - void addEnchantmentsSubView(); + void addEnchantmentsSubView(); - void addBodyPartsSubView(); + void addBodyPartsSubView(); - void addSoundGensSubView(); + void addSoundGensSubView(); - void addMagicEffectsSubView(); + void addMagicEffectsSubView(); - void addMeshesSubView(); + void addMeshesSubView(); - void addIconsSubView(); + void addIconsSubView(); - void addMusicsSubView(); + void addMusicsSubView(); - void addSoundsResSubView(); + void addSoundsResSubView(); - void addTexturesSubView(); + void addTexturesSubView(); - void addVideosSubView(); + void addVideosSubView(); - void addDebugProfilesSubView(); + void addDebugProfilesSubView(); - void addRunLogSubView(); + void addRunLogSubView(); - void addLandsSubView(); + void addLandsSubView(); - void addLandTexturesSubView(); + void addLandTexturesSubView(); - void addPathgridSubView(); + void addPathgridSubView(); - void addStartScriptsSubView(); + void addStartScriptsSubView(); - void addSearchSubView(); + void addSearchSubView(); - void addMetaDataSubView(); + void addMetaDataSubView(); - void toggleShowStatusBar (bool show); + void toggleShowStatusBar(bool show); - void loadErrorLog(); + void loadErrorLog(); - void run (const std::string& profile, const std::string& startupInstruction = ""); + void run(const std::string& profile, const std::string& startupInstruction = ""); - void stop(); + void stop(); - void closeRequest (SubView *subView); + void closeRequest(SubView* subView); - void moveScrollBarToEnd(int min, int max); + void moveScrollBarToEnd(int min, int max); - void merge(); + void merge(); - void onRequestFocus (const std::string& id); + void onRequestFocus(const std::string& id); }; } diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index fc839a4c7b..b26952ee34 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -1,7 +1,7 @@ #include "viewmanager.hpp" -#include #include +#include #include #include @@ -18,58 +18,56 @@ #include "../../model/prefs/state.hpp" -#include "../world/util.hpp" +#include "../world/colordelegate.hpp" #include "../world/enumdelegate.hpp" -#include "../world/vartypedelegate.hpp" -#include "../world/recordstatusdelegate.hpp" -#include "../world/idtypedelegate.hpp" #include "../world/idcompletiondelegate.hpp" -#include "../world/colordelegate.hpp" +#include "../world/idtypedelegate.hpp" +#include "../world/recordstatusdelegate.hpp" +#include "../world/util.hpp" +#include "../world/vartypedelegate.hpp" #include "view.hpp" void CSVDoc::ViewManager::updateIndices() { - std::map > documents; + std::map> documents; - for (std::vector::const_iterator iter (mViews.begin()); iter!=mViews.end(); ++iter) + for (std::vector::const_iterator iter(mViews.begin()); iter != mViews.end(); ++iter) { - std::map >::iterator document = documents.find ((*iter)->getDocument()); + std::map>::iterator document = documents.find((*iter)->getDocument()); - if (document==documents.end()) - document = - documents.insert ( - std::make_pair ((*iter)->getDocument(), std::make_pair (0, countViews ((*iter)->getDocument())))). - first; + if (document == documents.end()) + document = documents + .insert(std::make_pair( + (*iter)->getDocument(), std::make_pair(0, countViews((*iter)->getDocument())))) + .first; - (*iter)->setIndex (document->second.first++, document->second.second); + (*iter)->setIndex(document->second.first++, document->second.second); } } -CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) - : mDocumentManager (documentManager), mExitOnSaveStateChange(false), mUserWarned(false) +CSVDoc::ViewManager::ViewManager(CSMDoc::DocumentManager& documentManager) + : mDocumentManager(documentManager) + , mExitOnSaveStateChange(false) + , mUserWarned(false) { mDelegateFactories = new CSVWorld::CommandDelegateFactoryCollection; - mDelegateFactories->add (CSMWorld::ColumnBase::Display_GmstVarType, - new CSVWorld::VarTypeDelegateFactory (ESM::VT_None, ESM::VT_String, ESM::VT_Int, ESM::VT_Float)); + mDelegateFactories->add(CSMWorld::ColumnBase::Display_GmstVarType, + new CSVWorld::VarTypeDelegateFactory(ESM::VT_None, ESM::VT_String, ESM::VT_Int, ESM::VT_Float)); - mDelegateFactories->add (CSMWorld::ColumnBase::Display_GlobalVarType, - new CSVWorld::VarTypeDelegateFactory (ESM::VT_Short, ESM::VT_Long, ESM::VT_Float)); + mDelegateFactories->add(CSMWorld::ColumnBase::Display_GlobalVarType, + new CSVWorld::VarTypeDelegateFactory(ESM::VT_Short, ESM::VT_Long, ESM::VT_Float)); - mDelegateFactories->add (CSMWorld::ColumnBase::Display_RecordState, - new CSVWorld::RecordStatusDelegateFactory()); + mDelegateFactories->add(CSMWorld::ColumnBase::Display_RecordState, new CSVWorld::RecordStatusDelegateFactory()); - mDelegateFactories->add (CSMWorld::ColumnBase::Display_RefRecordType, - new CSVWorld::IdTypeDelegateFactory()); + mDelegateFactories->add(CSMWorld::ColumnBase::Display_RefRecordType, new CSVWorld::IdTypeDelegateFactory()); - mDelegateFactories->add (CSMWorld::ColumnBase::Display_Colour, - new CSVWorld::ColorDelegateFactory()); + mDelegateFactories->add(CSMWorld::ColumnBase::Display_Colour, new CSVWorld::ColorDelegateFactory()); std::vector idCompletionColumns = CSMWorld::IdCompletionManager::getDisplayTypes(); for (std::vector::const_iterator current = idCompletionColumns.begin(); - current != idCompletionColumns.end(); - ++current) + current != idCompletionColumns.end(); ++current) { mDelegateFactories->add(*current, new CSVWorld::IdCompletionDelegateFactory()); } @@ -81,8 +79,7 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) bool mAllowNone; }; - static const Mapping sMapping[] = - { + static const Mapping sMapping[] = { { CSMWorld::ColumnBase::Display_Specialisation, CSMWorld::Columns::ColumnId_Specialisation, false }, { CSMWorld::ColumnBase::Display_Attribute, CSMWorld::Columns::ColumnId_Attribute, true }, { CSMWorld::ColumnBase::Display_SpellType, CSMWorld::Columns::ColumnId_SpellType, false }, @@ -115,71 +112,65 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager) { CSMWorld::ColumnBase::Display_GenderNpc, CSMWorld::Columns::ColumnId_Gender, false }, }; - for (std::size_t i=0; iadd (sMapping[i].mDisplay, new CSVWorld::EnumDelegateFactory ( - CSMWorld::Columns::getEnums (sMapping[i].mColumnId), sMapping[i].mAllowNone)); + for (std::size_t i = 0; i < sizeof(sMapping) / sizeof(Mapping); ++i) + mDelegateFactories->add(sMapping[i].mDisplay, + new CSVWorld::EnumDelegateFactory( + CSMWorld::Columns::getEnums(sMapping[i].mColumnId), sMapping[i].mAllowNone)); - connect (&mDocumentManager, &CSMDoc::DocumentManager::loadRequest, - &mLoader, &Loader::add); + connect(&mDocumentManager, &CSMDoc::DocumentManager::loadRequest, &mLoader, &Loader::add); - connect (&mDocumentManager, &CSMDoc::DocumentManager::loadingStopped, - &mLoader, &Loader::loadingStopped); + connect(&mDocumentManager, &CSMDoc::DocumentManager::loadingStopped, &mLoader, &Loader::loadingStopped); - connect (&mDocumentManager, &CSMDoc::DocumentManager::nextStage, - &mLoader, &Loader::nextStage); + connect(&mDocumentManager, &CSMDoc::DocumentManager::nextStage, &mLoader, &Loader::nextStage); - connect (&mDocumentManager, &CSMDoc::DocumentManager::nextRecord, - &mLoader, &Loader::nextRecord); + connect(&mDocumentManager, &CSMDoc::DocumentManager::nextRecord, &mLoader, &Loader::nextRecord); - connect (&mDocumentManager, &CSMDoc::DocumentManager::loadMessage, - &mLoader, &Loader::loadMessage); + connect(&mDocumentManager, &CSMDoc::DocumentManager::loadMessage, &mLoader, &Loader::loadMessage); - connect (&mLoader, &Loader::cancel, - &mDocumentManager, &CSMDoc::DocumentManager::cancelLoading); + connect(&mLoader, &Loader::cancel, &mDocumentManager, &CSMDoc::DocumentManager::cancelLoading); - connect (&mLoader, &Loader::close, - &mDocumentManager, &CSMDoc::DocumentManager::removeDocument); + connect(&mLoader, &Loader::close, &mDocumentManager, &CSMDoc::DocumentManager::removeDocument); } CSVDoc::ViewManager::~ViewManager() { delete mDelegateFactories; - for (std::vector::iterator iter (mViews.begin()); iter!=mViews.end(); ++iter) + for (std::vector::iterator iter(mViews.begin()); iter != mViews.end(); ++iter) delete *iter; } -CSVDoc::View *CSVDoc::ViewManager::addView (CSMDoc::Document *document) +CSVDoc::View* CSVDoc::ViewManager::addView(CSMDoc::Document* document) { - if (countViews (document)==0) + if (countViews(document) == 0) { // new document - connect (document, &CSMDoc::Document::stateChanged, - this, &ViewManager::documentStateChanged); + connect(document, &CSMDoc::Document::stateChanged, this, &ViewManager::documentStateChanged); - connect (document, qOverload(&CSMDoc::Document::progress), - this, &ViewManager::progress); + connect(document, qOverload(&CSMDoc::Document::progress), this, + &ViewManager::progress); } - View *view = new View (*this, document, countViews (document)+1); + View* view = new View(*this, document, countViews(document) + 1); - mViews.push_back (view); + mViews.push_back(view); - view->toggleStatusBar (CSMPrefs::get()["Windows"]["show-statusbar"].isTrue()); + view->toggleStatusBar(CSMPrefs::get()["Windows"]["show-statusbar"].isTrue()); view->show(); - connect (view, &View::newGameRequest, this, &ViewManager::newGameRequest); - connect (view, &View::newAddonRequest, this, &ViewManager::newAddonRequest); - connect (view, &View::loadDocumentRequest, this, &ViewManager::loadDocumentRequest); - connect (view, &View::editSettingsRequest, this, &ViewManager::editSettingsRequest); - connect (view, &View::mergeDocument, this, &ViewManager::mergeDocument); + connect(view, &View::newGameRequest, this, &ViewManager::newGameRequest); + connect(view, &View::newAddonRequest, this, &ViewManager::newAddonRequest); + connect(view, &View::loadDocumentRequest, this, &ViewManager::loadDocumentRequest); + connect(view, &View::editSettingsRequest, this, &ViewManager::editSettingsRequest); + connect(view, &View::mergeDocument, this, &ViewManager::mergeDocument); updateIndices(); return view; } -CSVDoc::View *CSVDoc::ViewManager::addView (CSMDoc::Document *document, const CSMWorld::UniversalId& id, const std::string& hint) +CSVDoc::View* CSVDoc::ViewManager::addView( + CSMDoc::Document* document, const CSMWorld::UniversalId& id, const std::string& hint) { View* view = addView(document); view->addSubView(id, hint); @@ -187,33 +178,33 @@ CSVDoc::View *CSVDoc::ViewManager::addView (CSMDoc::Document *document, const CS return view; } -int CSVDoc::ViewManager::countViews (const CSMDoc::Document *document) const +int CSVDoc::ViewManager::countViews(const CSMDoc::Document* document) const { int count = 0; - for (std::vector::const_iterator iter (mViews.begin()); iter!=mViews.end(); ++iter) - if ((*iter)->getDocument()==document) + for (std::vector::const_iterator iter(mViews.begin()); iter != mViews.end(); ++iter) + if ((*iter)->getDocument() == document) ++count; return count; } -bool CSVDoc::ViewManager::closeRequest (View *view) +bool CSVDoc::ViewManager::closeRequest(View* view) { - std::vector::iterator iter = std::find (mViews.begin(), mViews.end(), view); + std::vector::iterator iter = std::find(mViews.begin(), mViews.end(), view); bool continueWithClose = false; - if (iter!=mViews.end()) + if (iter != mViews.end()) { - bool last = countViews (view->getDocument())<=1; + bool last = countViews(view->getDocument()) <= 1; if (last) - continueWithClose = notifySaveOnClose (view); + continueWithClose = notifySaveOnClose(view); else { (*iter)->deleteLater(); - mViews.erase (iter); + mViews.erase(iter); updateIndices(); } @@ -223,16 +214,16 @@ bool CSVDoc::ViewManager::closeRequest (View *view) } // NOTE: This method assumes that it is called only if the last document -void CSVDoc::ViewManager::removeDocAndView (CSMDoc::Document *document) +void CSVDoc::ViewManager::removeDocAndView(CSMDoc::Document* document) { - for (std::vector::iterator iter (mViews.begin()); iter!=mViews.end(); ++iter) + for (std::vector::iterator iter(mViews.begin()); iter != mViews.end(); ++iter) { // the first match should also be the only match - if((*iter)->getDocument() == document) + if ((*iter)->getDocument() == document) { mDocumentManager.removeDocument(document); (*iter)->deleteLater(); - mViews.erase (iter); + mViews.erase(iter); updateIndices(); return; @@ -240,43 +231,43 @@ void CSVDoc::ViewManager::removeDocAndView (CSMDoc::Document *document) } } -bool CSVDoc::ViewManager::notifySaveOnClose (CSVDoc::View *view) +bool CSVDoc::ViewManager::notifySaveOnClose(CSVDoc::View* view) { bool result = true; - CSMDoc::Document *document = view->getDocument(); + CSMDoc::Document* document = view->getDocument(); - //notify user of saving in progress - if ( (document->getState() & CSMDoc::State_Saving) ) - result = showSaveInProgressMessageBox (view); + // notify user of saving in progress + if ((document->getState() & CSMDoc::State_Saving)) + result = showSaveInProgressMessageBox(view); - //notify user of unsaved changes and process response - else if ( document->getState() & CSMDoc::State_Modified) - result = showModifiedDocumentMessageBox (view); + // notify user of unsaved changes and process response + else if (document->getState() & CSMDoc::State_Modified) + result = showModifiedDocumentMessageBox(view); return result; } -bool CSVDoc::ViewManager::showModifiedDocumentMessageBox (CSVDoc::View *view) +bool CSVDoc::ViewManager::showModifiedDocumentMessageBox(CSVDoc::View* view) { emit closeMessageBox(); QMessageBox messageBox(view); - CSMDoc::Document *document = view->getDocument(); - - messageBox.setWindowTitle (Files::pathToQString(document->getSavePath().filename())); - messageBox.setText ("The document has been modified."); - messageBox.setInformativeText ("Do you want to save your changes?"); - messageBox.setStandardButtons (QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); - messageBox.setDefaultButton (QMessageBox::Save); - messageBox.setWindowModality (Qt::NonModal); + CSMDoc::Document* document = view->getDocument(); + + messageBox.setWindowTitle(Files::pathToQString(document->getSavePath().filename())); + messageBox.setText("The document has been modified."); + messageBox.setInformativeText("Do you want to save your changes?"); + messageBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); + messageBox.setDefaultButton(QMessageBox::Save); + messageBox.setWindowModality(Qt::NonModal); messageBox.hide(); messageBox.show(); bool retVal = true; - connect (this, &ViewManager::closeMessageBox, &messageBox, &QMessageBox::close); + connect(this, &ViewManager::closeMessageBox, &messageBox, &QMessageBox::close); - connect (document, &CSMDoc::Document::stateChanged, this, &ViewManager::onExitWarningHandler); + connect(document, &CSMDoc::Document::stateChanged, this, &ViewManager::onExitWarningHandler); mUserWarned = true; int response = messageBox.exec(); @@ -289,67 +280,64 @@ bool CSVDoc::ViewManager::showModifiedDocumentMessageBox (CSVDoc::View *view) document->save(); mExitOnSaveStateChange = true; retVal = false; - break; + break; case QMessageBox::Discard: - disconnect (document, &CSMDoc::Document::stateChanged, - this, &ViewManager::onExitWarningHandler); - break; + disconnect(document, &CSMDoc::Document::stateChanged, this, &ViewManager::onExitWarningHandler); + break; case QMessageBox::Cancel: - //disconnect to prevent unintended view closures - disconnect (document, &CSMDoc::Document::stateChanged, - this, &ViewManager::onExitWarningHandler); + // disconnect to prevent unintended view closures + disconnect(document, &CSMDoc::Document::stateChanged, this, &ViewManager::onExitWarningHandler); retVal = false; - break; + break; default: - break; - + break; } return retVal; } -bool CSVDoc::ViewManager::showSaveInProgressMessageBox (CSVDoc::View *view) +bool CSVDoc::ViewManager::showSaveInProgressMessageBox(CSVDoc::View* view) { QMessageBox messageBox; - CSMDoc::Document *document = view->getDocument(); + CSMDoc::Document* document = view->getDocument(); - messageBox.setText ("The document is currently being saved."); + messageBox.setText("The document is currently being saved."); messageBox.setInformativeText("Do you want to close now and abort saving, or wait until saving has completed?"); - QPushButton* waitButton = messageBox.addButton (tr("Wait"), QMessageBox::YesRole); - QPushButton* closeButton = messageBox.addButton (tr("Close Now"), QMessageBox::RejectRole); - QPushButton* cancelButton = messageBox.addButton (tr("Cancel"), QMessageBox::NoRole); + QPushButton* waitButton = messageBox.addButton(tr("Wait"), QMessageBox::YesRole); + QPushButton* closeButton = messageBox.addButton(tr("Close Now"), QMessageBox::RejectRole); + QPushButton* cancelButton = messageBox.addButton(tr("Cancel"), QMessageBox::NoRole); - messageBox.setDefaultButton (waitButton); + messageBox.setDefaultButton(waitButton); bool retVal = true; - //Connections shut down message box if operation ends before user makes a decision. - connect (document, &CSMDoc::Document::stateChanged, this, &ViewManager::onExitWarningHandler); - connect (this, &ViewManager::closeMessageBox, &messageBox, &QMessageBox::close); + // Connections shut down message box if operation ends before user makes a decision. + connect(document, &CSMDoc::Document::stateChanged, this, &ViewManager::onExitWarningHandler); + connect(this, &ViewManager::closeMessageBox, &messageBox, &QMessageBox::close); - //set / clear the user warned flag to indicate whether or not the message box is currently active. + // set / clear the user warned flag to indicate whether or not the message box is currently active. mUserWarned = true; messageBox.exec(); mUserWarned = false; - //if closed by the warning handler, defaults to the RejectRole button (closeButton) + // if closed by the warning handler, defaults to the RejectRole button (closeButton) if (messageBox.clickedButton() == waitButton) { - //save the View iterator for shutdown after the save operation ends + // save the View iterator for shutdown after the save operation ends mExitOnSaveStateChange = true; retVal = false; } else if (messageBox.clickedButton() == closeButton) { - //disconnect to avoid segmentation fault - disconnect (document, &CSMDoc::Document::stateChanged, this, &ViewManager::onExitWarningHandler); + // disconnect to avoid segmentation fault + disconnect(document, &CSMDoc::Document::stateChanged, this, &ViewManager::onExitWarningHandler); view->abortOperation(CSMDoc::State_Saving); mExitOnSaveStateChange = true; @@ -357,59 +345,59 @@ bool CSVDoc::ViewManager::showSaveInProgressMessageBox (CSVDoc::View *view) else if (messageBox.clickedButton() == cancelButton) { - //abort shutdown, allow save to complete - //disconnection to prevent unintended view closures + // abort shutdown, allow save to complete + // disconnection to prevent unintended view closures mExitOnSaveStateChange = false; - disconnect (document, &CSMDoc::Document::stateChanged, this, &ViewManager::onExitWarningHandler); + disconnect(document, &CSMDoc::Document::stateChanged, this, &ViewManager::onExitWarningHandler); retVal = false; } return retVal; } -void CSVDoc::ViewManager::documentStateChanged (int state, CSMDoc::Document *document) +void CSVDoc::ViewManager::documentStateChanged(int state, CSMDoc::Document* document) { - for (std::vector::const_iterator iter (mViews.begin()); iter!=mViews.end(); ++iter) - if ((*iter)->getDocument()==document) - (*iter)->updateDocumentState(); + for (std::vector::const_iterator iter(mViews.begin()); iter != mViews.end(); ++iter) + if ((*iter)->getDocument() == document) + (*iter)->updateDocumentState(); } -void CSVDoc::ViewManager::progress (int current, int max, int type, int threads, CSMDoc::Document *document) +void CSVDoc::ViewManager::progress(int current, int max, int type, int threads, CSMDoc::Document* document) { - for (std::vector::const_iterator iter (mViews.begin()); iter!=mViews.end(); ++iter) - if ((*iter)->getDocument()==document) - (*iter)->updateProgress (current, max, type, threads); + for (std::vector::const_iterator iter(mViews.begin()); iter != mViews.end(); ++iter) + if ((*iter)->getDocument() == document) + (*iter)->updateProgress(current, max, type, threads); } -void CSVDoc::ViewManager::onExitWarningHandler (int state, CSMDoc::Document *document) +void CSVDoc::ViewManager::onExitWarningHandler(int state, CSMDoc::Document* document) { - if ( !(state & CSMDoc::State_Saving) ) + if (!(state & CSMDoc::State_Saving)) { - //if the user is being warned (message box is active), shut down the message box, - //as there is no save operation currently running - if ( mUserWarned ) + // if the user is being warned (message box is active), shut down the message box, + // as there is no save operation currently running + if (mUserWarned) emit closeMessageBox(); - //otherwise, the user has closed the message box before the save operation ended. - //exit the application + // otherwise, the user has closed the message box before the save operation ended. + // exit the application else if (mExitOnSaveStateChange) QApplication::instance()->exit(); } } -bool CSVDoc::ViewManager::removeDocument (CSVDoc::View *view) +bool CSVDoc::ViewManager::removeDocument(CSVDoc::View* view) { - if(!notifySaveOnClose(view)) + if (!notifySaveOnClose(view)) return false; else { // don't bother closing views or updating indicies, but remove from mViews - CSMDoc::Document * document = view->getDocument(); - std::vector remainingViews; - std::vector::const_iterator iter = mViews.begin(); - for (; iter!=mViews.end(); ++iter) + CSMDoc::Document* document = view->getDocument(); + std::vector remainingViews; + std::vector::const_iterator iter = mViews.begin(); + for (; iter != mViews.end(); ++iter) { - if(document == (*iter)->getDocument()) + if (document == (*iter)->getDocument()) (*iter)->setVisible(false); else remainingViews.push_back(*iter); @@ -420,16 +408,16 @@ bool CSVDoc::ViewManager::removeDocument (CSVDoc::View *view) return true; } -void CSVDoc::ViewManager::exitApplication (CSVDoc::View *view) +void CSVDoc::ViewManager::exitApplication(CSVDoc::View* view) { - if(!removeDocument(view)) // close the current document first + if (!removeDocument(view)) // close the current document first return; - while(!mViews.empty()) // attempt to close all other documents + while (!mViews.empty()) // attempt to close all other documents { mViews.back()->activateWindow(); mViews.back()->raise(); // raise the window to alert the user - if(!removeDocument(mViews.back())) + if (!removeDocument(mViews.back())) return; } // Editor exits (via a signal) when the last document is deleted diff --git a/apps/opencs/view/doc/viewmanager.hpp b/apps/opencs/view/doc/viewmanager.hpp index fe136027ca..8034b99f29 100644 --- a/apps/opencs/view/doc/viewmanager.hpp +++ b/apps/opencs/view/doc/viewmanager.hpp @@ -29,67 +29,66 @@ namespace CSVDoc class ViewManager : public QObject { - Q_OBJECT + Q_OBJECT - CSMDoc::DocumentManager& mDocumentManager; - std::vector mViews; - CSVWorld::CommandDelegateFactoryCollection *mDelegateFactories; - bool mExitOnSaveStateChange; - bool mUserWarned; - Loader mLoader; + CSMDoc::DocumentManager& mDocumentManager; + std::vector mViews; + CSVWorld::CommandDelegateFactoryCollection* mDelegateFactories; + bool mExitOnSaveStateChange; + bool mUserWarned; + Loader mLoader; - // not implemented - ViewManager (const ViewManager&); - ViewManager& operator= (const ViewManager&); + // not implemented + ViewManager(const ViewManager&); + ViewManager& operator=(const ViewManager&); - void updateIndices(); - bool notifySaveOnClose (View *view = nullptr); - bool showModifiedDocumentMessageBox (View *view); - bool showSaveInProgressMessageBox (View *view); - bool removeDocument(View *view); + void updateIndices(); + bool notifySaveOnClose(View* view = nullptr); + bool showModifiedDocumentMessageBox(View* view); + bool showSaveInProgressMessageBox(View* view); + bool removeDocument(View* view); - public: + public: + ViewManager(CSMDoc::DocumentManager& documentManager); - ViewManager (CSMDoc::DocumentManager& documentManager); + ~ViewManager() override; - ~ViewManager() override; + View* addView(CSMDoc::Document* document); + ///< The ownership of the returned view is not transferred. - View *addView (CSMDoc::Document *document); - ///< The ownership of the returned view is not transferred. + View* addView(CSMDoc::Document* document, const CSMWorld::UniversalId& id, const std::string& hint); - View *addView (CSMDoc::Document *document, const CSMWorld::UniversalId& id, const std::string& hint); + int countViews(const CSMDoc::Document* document) const; + ///< Return number of views for \a document. - int countViews (const CSMDoc::Document *document) const; - ///< Return number of views for \a document. + bool closeRequest(View* view); + void removeDocAndView(CSMDoc::Document* document); - bool closeRequest (View *view); - void removeDocAndView (CSMDoc::Document *document); + signals: - signals: + void newGameRequest(); - void newGameRequest(); + void newAddonRequest(); - void newAddonRequest(); + void loadDocumentRequest(); - void loadDocumentRequest(); + void closeMessageBox(); - void closeMessageBox(); + void editSettingsRequest(); - void editSettingsRequest(); + void mergeDocument(CSMDoc::Document* document); - void mergeDocument (CSMDoc::Document *document); + public slots: - public slots: + void exitApplication(CSVDoc::View* view); - void exitApplication (CSVDoc::View *view); + private slots: - private slots: + void documentStateChanged(int state, CSMDoc::Document* document); - void documentStateChanged (int state, CSMDoc::Document *document); + void progress(int current, int max, int type, int threads, CSMDoc::Document* document); - void progress (int current, int max, int type, int threads, CSMDoc::Document *document); - - void onExitWarningHandler(int state, CSMDoc::Document* document); + void onExitWarningHandler(int state, CSMDoc::Document* document); }; } diff --git a/apps/opencs/view/filter/editwidget.cpp b/apps/opencs/view/filter/editwidget.cpp index 7dc92c3dc4..b94d59083b 100644 --- a/apps/opencs/view/filter/editwidget.cpp +++ b/apps/opencs/view/filter/editwidget.cpp @@ -3,104 +3,104 @@ #include #include +#include #include #include #include -#include #include +#include "../../model/prefs/shortcut.hpp" +#include "../../model/world/columns.hpp" #include "../../model/world/data.hpp" #include "../../model/world/idtablebase.hpp" -#include "../../model/world/columns.hpp" -#include "../../model/prefs/shortcut.hpp" -CSVFilter::EditWidget::EditWidget (CSMWorld::Data& data, QWidget *parent) -: QLineEdit (parent), mParser (data), mIsEmpty(true) +CSVFilter::EditWidget::EditWidget(CSMWorld::Data& data, QWidget* parent) + : QLineEdit(parent) + , mParser(data) + , mIsEmpty(true) { mPalette = palette(); - connect (this, &QLineEdit::textChanged, this, &EditWidget::textChanged); + connect(this, &QLineEdit::textChanged, this, &EditWidget::textChanged); - const CSMWorld::IdTableBase *model = - static_cast (data.getTableModel (CSMWorld::UniversalId::Type_Filters)); + const CSMWorld::IdTableBase* model + = static_cast(data.getTableModel(CSMWorld::UniversalId::Type_Filters)); - connect (model, &CSMWorld::IdTableBase::dataChanged, - this, &EditWidget::filterDataChanged, Qt::QueuedConnection); - connect (model, &CSMWorld::IdTableBase::rowsRemoved, - this, &EditWidget::filterRowsRemoved, Qt::QueuedConnection); - connect (model, &CSMWorld::IdTableBase::rowsInserted, - this, &EditWidget::filterRowsInserted, Qt::QueuedConnection); + connect(model, &CSMWorld::IdTableBase::dataChanged, this, &EditWidget::filterDataChanged, Qt::QueuedConnection); + connect(model, &CSMWorld::IdTableBase::rowsRemoved, this, &EditWidget::filterRowsRemoved, Qt::QueuedConnection); + connect(model, &CSMWorld::IdTableBase::rowsInserted, this, &EditWidget::filterRowsInserted, Qt::QueuedConnection); - mStateColumnIndex = model->findColumnIndex(CSMWorld::Columns::ColumnId_Modification); - mDescColumnIndex = model->findColumnIndex(CSMWorld::Columns::ColumnId_Description); + mStateColumnIndex = model->findColumnIndex(CSMWorld::Columns::ColumnId_Modification); + mDescColumnIndex = model->findColumnIndex(CSMWorld::Columns::ColumnId_Description); - mHelpAction = new QAction (tr ("Help"), this); - connect (mHelpAction, &QAction::triggered, this, &EditWidget::openHelp); + mHelpAction = new QAction(tr("Help"), this); + connect(mHelpAction, &QAction::triggered, this, &EditWidget::openHelp); mHelpAction->setIcon(QIcon(":/info.png")); - addAction (mHelpAction); + addAction(mHelpAction); auto* openHelpShortcut = new CSMPrefs::Shortcut("help", this); openHelpShortcut->associateAction(mHelpAction); setText("!string(\"ID\", \".*\")"); } -void CSVFilter::EditWidget::textChanged (const QString& text) +void CSVFilter::EditWidget::textChanged(const QString& text) { - //no need to parse and apply filter if it was empty and now is empty too. - //e.g. - we modifiing content of filter with already opened some other (big) tables. - if (text.length() == 0){ + // no need to parse and apply filter if it was empty and now is empty too. + // e.g. - we modifiing content of filter with already opened some other (big) tables. + if (text.length() == 0) + { if (mIsEmpty) return; else mIsEmpty = true; - }else + } + else mIsEmpty = false; - if (mParser.parse (text.toUtf8().constData())) + if (mParser.parse(text.toUtf8().constData())) { - setPalette (mPalette); - emit filterChanged (mParser.getFilter()); + setPalette(mPalette); + emit filterChanged(mParser.getFilter()); } else { - QPalette palette (mPalette); - palette.setColor (QPalette::Text, Qt::red); - setPalette (palette); + QPalette palette(mPalette); + palette.setColor(QPalette::Text, Qt::red); + setPalette(palette); /// \todo improve error reporting; mark only the faulty part } } -void CSVFilter::EditWidget::filterDataChanged (const QModelIndex& topLeft, - const QModelIndex& bottomRight) +void CSVFilter::EditWidget::filterDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) { for (int i = topLeft.column(); i <= bottomRight.column(); ++i) if (i != mStateColumnIndex && i != mDescColumnIndex) - textChanged (text()); + textChanged(text()); } -void CSVFilter::EditWidget::filterRowsRemoved (const QModelIndex& parent, int start, int end) +void CSVFilter::EditWidget::filterRowsRemoved(const QModelIndex& parent, int start, int end) { - textChanged (text()); + textChanged(text()); } -void CSVFilter::EditWidget::filterRowsInserted (const QModelIndex& parent, int start, int end) +void CSVFilter::EditWidget::filterRowsInserted(const QModelIndex& parent, int start, int end) { - textChanged (text()); + textChanged(text()); } -void CSVFilter::EditWidget::createFilterRequest (std::vector< std::pair< std::string, std::vector< std::string > > >& filterSource, - Qt::DropAction action) +void CSVFilter::EditWidget::createFilterRequest( + std::vector>>& filterSource, Qt::DropAction action) { const unsigned count = filterSource.size(); bool multipleElements = false; - switch (count) //setting multipleElements; + switch (count) // setting multipleElements; { - case 0: //empty - return; //nothing to do here + case 0: // empty + return; // nothing to do here - case 1: //only single + case 1: // only single multipleElements = false; break; @@ -110,12 +110,12 @@ void CSVFilter::EditWidget::createFilterRequest (std::vector< std::pair< std::st } Qt::KeyboardModifiers key = QApplication::keyboardModifiers(); - QString oldContent (text()); + QString oldContent(text()); bool replaceMode = false; std::string orAnd; - switch (key) //setting replaceMode and string used to glue expressions + switch (key) // setting replaceMode and string used to glue expressions { case Qt::ShiftModifier: orAnd = "!or("; @@ -132,14 +132,16 @@ void CSVFilter::EditWidget::createFilterRequest (std::vector< std::pair< std::st break; } - if (oldContent.isEmpty() || !oldContent.contains (QRegExp ("^!.*$", Qt::CaseInsensitive))) //if line edit is empty or it does not contain one shot filter go into replace mode + if (oldContent.isEmpty() + || !oldContent.contains(QRegExp("^!.*$", + Qt::CaseInsensitive))) // if line edit is empty or it does not contain one shot filter go into replace mode { replaceMode = true; } if (!replaceMode) { - oldContent.remove ('!'); + oldContent.remove('!'); } std::stringstream ss; @@ -148,86 +150,93 @@ void CSVFilter::EditWidget::createFilterRequest (std::vector< std::pair< std::st { if (replaceMode) { - ss<<"!or("; - } else { + ss << "!or("; + } + else + { ss << orAnd << oldContent.toUtf8().constData() << ','; } for (unsigned i = 0; i < count; ++i) { - ss<4) + if (ss.str().length() > 4) { clear(); - insert (QString::fromUtf8(ss.str().c_str())); + insert(QString::fromUtf8(ss.str().c_str())); } } -std::string CSVFilter::EditWidget::generateFilter (std::pair< std::string, std::vector< std::string > >& seekedString) const +std::string CSVFilter::EditWidget::generateFilter(std::pair>& seekedString) const { const unsigned columns = seekedString.second.size(); bool multipleColumns = false; switch (columns) { - case 0: //empty - return ""; //no column to filter + case 0: // empty + return ""; // no column to filter - case 1: //one column to look for - multipleColumns = false; - break; + case 1: // one column to look for + multipleColumns = false; + break; - default: - multipleColumns = true; - break; + default: + multipleColumns = true; + break; } std::stringstream ss; if (multipleColumns) { - ss<<"or("; + ss << "or("; for (unsigned i = 0; i < columns; ++i) { - ss<<"string("<<'"'<addAction(mHelpAction); menu->exec(event->globalPos()); delete menu; @@ -237,4 +246,3 @@ void CSVFilter::EditWidget::openHelp() { Misc::HelpViewer::openHelp("manuals/openmw-cs/record-filters.html"); } - diff --git a/apps/opencs/view/filter/editwidget.hpp b/apps/opencs/view/filter/editwidget.hpp index c15e4ef913..af6ea2c8d6 100644 --- a/apps/opencs/view/filter/editwidget.hpp +++ b/apps/opencs/view/filter/editwidget.hpp @@ -4,8 +4,8 @@ #include #include -#include "../../model/filter/parser.hpp" #include "../../model/filter/node.hpp" +#include "../../model/filter/parser.hpp" class QModelIndex; @@ -18,43 +18,40 @@ namespace CSVFilter { class EditWidget : public QLineEdit { - Q_OBJECT - - CSMFilter::Parser mParser; - QPalette mPalette; - bool mIsEmpty; - int mStateColumnIndex; - int mDescColumnIndex; - QAction *mHelpAction; + Q_OBJECT - public: + CSMFilter::Parser mParser; + QPalette mPalette; + bool mIsEmpty; + int mStateColumnIndex; + int mDescColumnIndex; + QAction* mHelpAction; - EditWidget (CSMWorld::Data& data, QWidget *parent = nullptr); + public: + EditWidget(CSMWorld::Data& data, QWidget* parent = nullptr); - void createFilterRequest(std::vector > >& filterSource, - Qt::DropAction action); + void createFilterRequest( + std::vector>>& filterSource, Qt::DropAction action); - signals: + signals: - void filterChanged (std::shared_ptr filter); + void filterChanged(std::shared_ptr filter); private: - std::string generateFilter(std::pair >& seekedString) const; - void contextMenuEvent (QContextMenuEvent *event) override; - - private slots: - - void textChanged (const QString& text); + std::string generateFilter(std::pair>& seekedString) const; + void contextMenuEvent(QContextMenuEvent* event) override; - void filterDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); + private slots: - void filterRowsRemoved (const QModelIndex& parent, int start, int end); + void textChanged(const QString& text); - void filterRowsInserted (const QModelIndex& parent, int start, int end); + void filterDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); - static void openHelp(); + void filterRowsRemoved(const QModelIndex& parent, int start, int end); + void filterRowsInserted(const QModelIndex& parent, int start, int end); + static void openHelp(); }; } diff --git a/apps/opencs/view/filter/filterbox.cpp b/apps/opencs/view/filter/filterbox.cpp index 30c22c2f51..00edfe04ad 100644 --- a/apps/opencs/view/filter/filterbox.cpp +++ b/apps/opencs/view/filter/filterbox.cpp @@ -1,39 +1,38 @@ #include "filterbox.hpp" -#include #include +#include #include "recordfilterbox.hpp" #include -CSVFilter::FilterBox::FilterBox (CSMWorld::Data& data, QWidget *parent) -: QWidget (parent) +CSVFilter::FilterBox::FilterBox(CSMWorld::Data& data, QWidget* parent) + : QWidget(parent) { - QHBoxLayout *layout = new QHBoxLayout (this); + QHBoxLayout* layout = new QHBoxLayout(this); - layout->setContentsMargins (0, 0, 0, 0); + layout->setContentsMargins(0, 0, 0, 0); - mRecordFilterBox = new RecordFilterBox (data, this); + mRecordFilterBox = new RecordFilterBox(data, this); - layout->addWidget (mRecordFilterBox); + layout->addWidget(mRecordFilterBox); - setLayout (layout); + setLayout(layout); - connect (mRecordFilterBox, &RecordFilterBox::filterChanged, - this, &FilterBox::recordFilterChanged); + connect(mRecordFilterBox, &RecordFilterBox::filterChanged, this, &FilterBox::recordFilterChanged); setAcceptDrops(true); } -void CSVFilter::FilterBox::setRecordFilter (const std::string& filter) +void CSVFilter::FilterBox::setRecordFilter(const std::string& filter) { - mRecordFilterBox->setFilter (filter); + mRecordFilterBox->setFilter(filter); } -void CSVFilter::FilterBox::dropEvent (QDropEvent* event) +void CSVFilter::FilterBox::dropEvent(QDropEvent* event) { - const CSMWorld::TableMimeData* mime = dynamic_cast (event->mimeData()); + const CSMWorld::TableMimeData* mime = dynamic_cast(event->mimeData()); if (!mime) // May happen when non-records (e.g. plain text) are dragged and dropped return; @@ -42,18 +41,18 @@ void CSVFilter::FilterBox::dropEvent (QDropEvent* event) emit recordDropped(universalIdData, event->proposedAction()); } -void CSVFilter::FilterBox::dragEnterEvent (QDragEnterEvent* event) +void CSVFilter::FilterBox::dragEnterEvent(QDragEnterEvent* event) { event->acceptProposedAction(); } -void CSVFilter::FilterBox::dragMoveEvent (QDragMoveEvent* event) +void CSVFilter::FilterBox::dragMoveEvent(QDragMoveEvent* event) { event->accept(); } -void CSVFilter::FilterBox::createFilterRequest (std::vector< std::pair< std::string, std::vector< std::string > > >& filterSource, - Qt::DropAction action) +void CSVFilter::FilterBox::createFilterRequest( + std::vector>>& filterSource, Qt::DropAction action) { mRecordFilterBox->createFilterRequest(filterSource, action); } diff --git a/apps/opencs/view/filter/filterbox.hpp b/apps/opencs/view/filter/filterbox.hpp index e01f77ce6b..1bd89fe3f8 100644 --- a/apps/opencs/view/filter/filterbox.hpp +++ b/apps/opencs/view/filter/filterbox.hpp @@ -19,32 +19,30 @@ namespace CSVFilter class FilterBox : public QWidget { - Q_OBJECT + Q_OBJECT - RecordFilterBox *mRecordFilterBox; + RecordFilterBox* mRecordFilterBox; - public: - FilterBox (CSMWorld::Data& data, QWidget *parent = nullptr); + public: + FilterBox(CSMWorld::Data& data, QWidget* parent = nullptr); - void setRecordFilter (const std::string& filter); + void setRecordFilter(const std::string& filter); - void createFilterRequest(std::vector > >& filterSource, - Qt::DropAction action); + void createFilterRequest( + std::vector>>& filterSource, Qt::DropAction action); + private: + void dragEnterEvent(QDragEnterEvent* event) override; - private: - void dragEnterEvent (QDragEnterEvent* event) override; + void dropEvent(QDropEvent* event) override; - void dropEvent (QDropEvent* event) override; + void dragMoveEvent(QDragMoveEvent* event) override; - void dragMoveEvent(QDragMoveEvent *event) override; - - signals: - void recordFilterChanged (std::shared_ptr filter); - void recordDropped (std::vector& types, Qt::DropAction action); + signals: + void recordFilterChanged(std::shared_ptr filter); + void recordDropped(std::vector& types, Qt::DropAction action); }; } #endif - diff --git a/apps/opencs/view/filter/recordfilterbox.cpp b/apps/opencs/view/filter/recordfilterbox.cpp index face275ef6..41c60f7d1f 100644 --- a/apps/opencs/view/filter/recordfilterbox.cpp +++ b/apps/opencs/view/filter/recordfilterbox.cpp @@ -5,35 +5,34 @@ #include "editwidget.hpp" -CSVFilter::RecordFilterBox::RecordFilterBox (CSMWorld::Data& data, QWidget *parent) -: QWidget (parent) +CSVFilter::RecordFilterBox::RecordFilterBox(CSMWorld::Data& data, QWidget* parent) + : QWidget(parent) { - QHBoxLayout *layout = new QHBoxLayout (this); + QHBoxLayout* layout = new QHBoxLayout(this); - layout->setContentsMargins (0, 6, 5, 0); + layout->setContentsMargins(0, 6, 5, 0); - QLabel *label = new QLabel("Record Filter", this); + QLabel* label = new QLabel("Record Filter", this); label->setIndent(2); - layout->addWidget (label); + layout->addWidget(label); - mEdit = new EditWidget (data, this); + mEdit = new EditWidget(data, this); - layout->addWidget (mEdit); + layout->addWidget(mEdit); - setLayout (layout); + setLayout(layout); - connect (mEdit, &EditWidget::filterChanged, - this, &RecordFilterBox::filterChanged); + connect(mEdit, &EditWidget::filterChanged, this, &RecordFilterBox::filterChanged); } -void CSVFilter::RecordFilterBox::setFilter (const std::string& filter) +void CSVFilter::RecordFilterBox::setFilter(const std::string& filter) { mEdit->clear(); - mEdit->setText (QString::fromUtf8 (filter.c_str())); + mEdit->setText(QString::fromUtf8(filter.c_str())); } -void CSVFilter::RecordFilterBox::createFilterRequest (std::vector< std::pair< std::string, std::vector< std::string > > >& filterSource, - Qt::DropAction action) +void CSVFilter::RecordFilterBox::createFilterRequest( + std::vector>>& filterSource, Qt::DropAction action) { mEdit->createFilterRequest(filterSource, action); } diff --git a/apps/opencs/view/filter/recordfilterbox.hpp b/apps/opencs/view/filter/recordfilterbox.hpp index b6e04b2758..5583a8c873 100644 --- a/apps/opencs/view/filter/recordfilterbox.hpp +++ b/apps/opencs/view/filter/recordfilterbox.hpp @@ -16,24 +16,23 @@ namespace CSVFilter class RecordFilterBox : public QWidget { - Q_OBJECT + Q_OBJECT - EditWidget *mEdit; + EditWidget* mEdit; - public: + public: + RecordFilterBox(CSMWorld::Data& data, QWidget* parent = nullptr); - RecordFilterBox (CSMWorld::Data& data, QWidget *parent = nullptr); + void setFilter(const std::string& filter); - void setFilter (const std::string& filter); + void useFilterRequest(const std::string& idOfFilter); - void useFilterRequest(const std::string& idOfFilter); + void createFilterRequest( + std::vector>>& filterSource, Qt::DropAction action); - void createFilterRequest(std::vector > >& filterSource, - Qt::DropAction action); + signals: - signals: - - void filterChanged (std::shared_ptr filter); + void filterChanged(std::shared_ptr filter); }; } diff --git a/apps/opencs/view/prefs/contextmenulist.cpp b/apps/opencs/view/prefs/contextmenulist.cpp index 8115c3ecc5..bf7a5f289f 100644 --- a/apps/opencs/view/prefs/contextmenulist.cpp +++ b/apps/opencs/view/prefs/contextmenulist.cpp @@ -1,13 +1,13 @@ #include "contextmenulist.hpp" -#include #include +#include #include #include "../../model/prefs/state.hpp" CSVPrefs::ContextMenuList::ContextMenuList(QWidget* parent) - :QListWidget(parent) + : QListWidget(parent) { } diff --git a/apps/opencs/view/prefs/contextmenulist.hpp b/apps/opencs/view/prefs/contextmenulist.hpp index f527057d2f..42063cea18 100644 --- a/apps/opencs/view/prefs/contextmenulist.hpp +++ b/apps/opencs/view/prefs/contextmenulist.hpp @@ -10,24 +10,22 @@ namespace CSVPrefs { class ContextMenuList : public QListWidget { - Q_OBJECT - - public: - - ContextMenuList(QWidget* parent = nullptr); - - protected: - - void contextMenuEvent(QContextMenuEvent* e) override; - - void mousePressEvent(QMouseEvent* e) override; - - private slots: - - void resetCategory(); - - void resetAll(); - }; + Q_OBJECT + + public: + ContextMenuList(QWidget* parent = nullptr); + + protected: + void contextMenuEvent(QContextMenuEvent* e) override; + + void mousePressEvent(QMouseEvent* e) override; + + private slots: + + void resetCategory(); + + void resetAll(); + }; } #endif diff --git a/apps/opencs/view/prefs/dialogue.cpp b/apps/opencs/view/prefs/dialogue.cpp index 369c23eb62..6be85cda0b 100644 --- a/apps/opencs/view/prefs/dialogue.cpp +++ b/apps/opencs/view/prefs/dialogue.cpp @@ -1,79 +1,77 @@ #include "dialogue.hpp" #include -#include -#include #include #include +#include +#include #include #include "../../model/prefs/state.hpp" -#include "page.hpp" -#include "keybindingpage.hpp" #include "contextmenulist.hpp" +#include "keybindingpage.hpp" +#include "page.hpp" -void CSVPrefs::Dialogue::buildCategorySelector (QSplitter *main) +void CSVPrefs::Dialogue::buildCategorySelector(QSplitter* main) { - CSVPrefs::ContextMenuList* list = new CSVPrefs::ContextMenuList (main); - list->setMinimumWidth (50); - list->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Expanding); + CSVPrefs::ContextMenuList* list = new CSVPrefs::ContextMenuList(main); + list->setMinimumWidth(50); + list->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - list->setSelectionBehavior (QAbstractItemView::SelectItems); + list->setSelectionBehavior(QAbstractItemView::SelectItems); - main->addWidget (list); + main->addWidget(list); - QFontMetrics metrics (QApplication::font(list)); + QFontMetrics metrics(QApplication::font(list)); int maxWidth = 1; - for (CSMPrefs::State::Iterator iter = CSMPrefs::get().begin(); iter!=CSMPrefs::get().end(); - ++iter) + for (CSMPrefs::State::Iterator iter = CSMPrefs::get().begin(); iter != CSMPrefs::get().end(); ++iter) { - QString label = QString::fromUtf8 (iter->second.getKey().c_str()); + QString label = QString::fromUtf8(iter->second.getKey().c_str()); - maxWidth = std::max (maxWidth, metrics.horizontalAdvance (label)); + maxWidth = std::max(maxWidth, metrics.horizontalAdvance(label)); - list->addItem (label); + list->addItem(label); } - list->setMaximumWidth (maxWidth + 10); + list->setMaximumWidth(maxWidth + 10); - connect (list, &ContextMenuList::currentItemChanged, - this, &Dialogue::selectionChanged); + connect(list, &ContextMenuList::currentItemChanged, this, &Dialogue::selectionChanged); } -void CSVPrefs::Dialogue::buildContentArea (QSplitter *main) +void CSVPrefs::Dialogue::buildContentArea(QSplitter* main) { - mContent = new QStackedWidget (main); - mContent->setSizePolicy (QSizePolicy::Preferred, QSizePolicy::Expanding); + mContent = new QStackedWidget(main); + mContent->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); - main->addWidget (mContent); + main->addWidget(mContent); } -CSVPrefs::PageBase *CSVPrefs::Dialogue::makePage (const std::string& key) +CSVPrefs::PageBase* CSVPrefs::Dialogue::makePage(const std::string& key) { // special case page code goes here if (key == "Key Bindings") return new KeyBindingPage(CSMPrefs::get()[key], mContent); else - return new Page (CSMPrefs::get()[key], mContent); + return new Page(CSMPrefs::get()[key], mContent); } CSVPrefs::Dialogue::Dialogue() { - setWindowTitle ("User Settings"); + setWindowTitle("User Settings"); - setSizePolicy (QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); - setMinimumSize (600, 400); + setMinimumSize(600, 400); - QSplitter *main = new QSplitter (this); + QSplitter* main = new QSplitter(this); - setCentralWidget (main); - buildCategorySelector (main); - buildContentArea (main); + setCentralWidget(main); + buildCategorySelector(main); + buildContentArea(main); } CSVPrefs::Dialogue::~Dialogue() @@ -83,26 +81,26 @@ CSVPrefs::Dialogue::~Dialogue() if (isVisible()) CSMPrefs::State::get().save(); } - catch(const std::exception& e) + catch (const std::exception& e) { Log(Debug::Error) << "Error in the destructor: " << e.what(); } } -void CSVPrefs::Dialogue::closeEvent (QCloseEvent *event) +void CSVPrefs::Dialogue::closeEvent(QCloseEvent* event) { - QMainWindow::closeEvent (event); + QMainWindow::closeEvent(event); CSMPrefs::State::get().save(); } void CSVPrefs::Dialogue::show() { - if (QWidget *active = QApplication::activeWindow()) + if (QWidget* active = QApplication::activeWindow()) { // place at the centre of the window with focus QSize size = active->size(); - move (active->geometry().x()+(size.width() - frameGeometry().width())/2, - active->geometry().y()+(size.height() - frameGeometry().height())/2); + move(active->geometry().x() + (size.width() - frameGeometry().width()) / 2, + active->geometry().y() + (size.height() - frameGeometry().height()) / 2); } else { @@ -111,30 +109,30 @@ void CSVPrefs::Dialogue::show() // otherwise place at the centre of the screen QPoint screenCenter = scr.center(); - move (screenCenter - QPoint(frameGeometry().width()/2, frameGeometry().height()/2)); + move(screenCenter - QPoint(frameGeometry().width() / 2, frameGeometry().height() / 2)); } QWidget::show(); } -void CSVPrefs::Dialogue::selectionChanged (QListWidgetItem *current, QListWidgetItem *previous) +void CSVPrefs::Dialogue::selectionChanged(QListWidgetItem* current, QListWidgetItem* previous) { if (current) { std::string key = current->text().toUtf8().data(); - for (int i=0; icount(); ++i) + for (int i = 0; i < mContent->count(); ++i) { - PageBase& page = dynamic_cast (*mContent->widget (i)); + PageBase& page = dynamic_cast(*mContent->widget(i)); - if (page.getCategory().getKey()==key) + if (page.getCategory().getKey() == key) { - mContent->setCurrentIndex (i); + mContent->setCurrentIndex(i); return; } } - PageBase *page = makePage (key); - mContent->setCurrentIndex (mContent->addWidget (page)); + PageBase* page = makePage(key); + mContent->setCurrentIndex(mContent->addWidget(page)); } } diff --git a/apps/opencs/view/prefs/dialogue.hpp b/apps/opencs/view/prefs/dialogue.hpp index 00b2e10ec9..70ee40586c 100644 --- a/apps/opencs/view/prefs/dialogue.hpp +++ b/apps/opencs/view/prefs/dialogue.hpp @@ -14,35 +14,32 @@ namespace CSVPrefs class Dialogue : public QMainWindow { - Q_OBJECT + Q_OBJECT - QStackedWidget *mContent; + QStackedWidget* mContent; - private: + private: + void buildCategorySelector(QSplitter* main); - void buildCategorySelector (QSplitter *main); + void buildContentArea(QSplitter* main); - void buildContentArea (QSplitter *main); + PageBase* makePage(const std::string& key); - PageBase *makePage (const std::string& key); + public: + Dialogue(); - public: + ~Dialogue() override; - Dialogue(); + protected: + void closeEvent(QCloseEvent* event) override; - ~Dialogue() override; + public slots: - protected: + void show(); - void closeEvent (QCloseEvent *event) override; + private slots: - public slots: - - void show(); - - private slots: - - void selectionChanged (QListWidgetItem *current, QListWidgetItem *previous); + void selectionChanged(QListWidgetItem* current, QListWidgetItem* previous); }; } diff --git a/apps/opencs/view/prefs/keybindingpage.cpp b/apps/opencs/view/prefs/keybindingpage.cpp index 37315d3fbc..8af2ff2ea4 100644 --- a/apps/opencs/view/prefs/keybindingpage.cpp +++ b/apps/opencs/view/prefs/keybindingpage.cpp @@ -8,8 +8,8 @@ #include #include -#include "../../model/prefs/setting.hpp" #include "../../model/prefs/category.hpp" +#include "../../model/prefs/setting.hpp" #include "../../model/prefs/state.hpp" namespace CSVPrefs @@ -29,15 +29,15 @@ namespace CSVPrefs mStackedLayout = new QStackedLayout(stackedWidget); mPageSelector = new QComboBox(); - connect(mPageSelector, qOverload(&QComboBox::currentIndexChanged), - mStackedLayout, &QStackedLayout::setCurrentIndex); + connect(mPageSelector, qOverload(&QComboBox::currentIndexChanged), mStackedLayout, + &QStackedLayout::setCurrentIndex); QFrame* lineSeparator = new QFrame(topWidget); lineSeparator->setFrameShape(QFrame::HLine); lineSeparator->setFrameShadow(QFrame::Sunken); // Reset key bindings button - QPushButton* resetButton = new QPushButton ("Reset to Defaults", topWidget); + QPushButton* resetButton = new QPushButton("Reset to Defaults", topWidget); connect(resetButton, &QPushButton::clicked, this, &KeyBindingPage::resetKeyBindings); topLayout->addWidget(mPageSelector); @@ -47,16 +47,16 @@ namespace CSVPrefs topLayout->setSizeConstraint(QLayout::SetMinAndMaxSize); // Add each option - for (CSMPrefs::Category::Iterator iter = category.begin(); iter!=category.end(); ++iter) - addSetting (*iter); + for (CSMPrefs::Category::Iterator iter = category.begin(); iter != category.end(); ++iter) + addSetting(*iter); setWidgetResizable(true); setWidget(topWidget); } - void KeyBindingPage::addSetting(CSMPrefs::Setting *setting) + void KeyBindingPage::addSetting(CSMPrefs::Setting* setting) { - std::pair widgets = setting->makeWidgets (this); + std::pair widgets = setting->makeWidgets(this); if (widgets.first) { diff --git a/apps/opencs/view/prefs/keybindingpage.hpp b/apps/opencs/view/prefs/keybindingpage.hpp index 05c4b22dbc..ad8e125032 100644 --- a/apps/opencs/view/prefs/keybindingpage.hpp +++ b/apps/opencs/view/prefs/keybindingpage.hpp @@ -16,23 +16,21 @@ namespace CSVPrefs { class KeyBindingPage : public PageBase { - Q_OBJECT + Q_OBJECT - public: + public: + KeyBindingPage(CSMPrefs::Category& category, QWidget* parent); - KeyBindingPage(CSMPrefs::Category& category, QWidget* parent); + void addSetting(CSMPrefs::Setting* setting); - void addSetting(CSMPrefs::Setting* setting); + private: + QStackedLayout* mStackedLayout; + QGridLayout* mPageLayout; + QComboBox* mPageSelector; - private: + private slots: - QStackedLayout* mStackedLayout; - QGridLayout* mPageLayout; - QComboBox* mPageSelector; - - private slots: - - void resetKeyBindings(); + void resetKeyBindings(); }; } diff --git a/apps/opencs/view/prefs/page.cpp b/apps/opencs/view/prefs/page.cpp index c23e9f64fe..e2fa057fc6 100644 --- a/apps/opencs/view/prefs/page.cpp +++ b/apps/opencs/view/prefs/page.cpp @@ -3,38 +3,38 @@ #include -#include "../../model/prefs/setting.hpp" #include "../../model/prefs/category.hpp" +#include "../../model/prefs/setting.hpp" -CSVPrefs::Page::Page (CSMPrefs::Category& category, QWidget *parent) -: PageBase (category, parent) +CSVPrefs::Page::Page(CSMPrefs::Category& category, QWidget* parent) + : PageBase(category, parent) { - QWidget *widget = new QWidget (parent); - mGrid = new QGridLayout (widget); + QWidget* widget = new QWidget(parent); + mGrid = new QGridLayout(widget); - for (CSMPrefs::Category::Iterator iter = category.begin(); iter!=category.end(); ++iter) - addSetting (*iter); + for (CSMPrefs::Category::Iterator iter = category.begin(); iter != category.end(); ++iter) + addSetting(*iter); - setWidget (widget); + setWidget(widget); } -void CSVPrefs::Page::addSetting (CSMPrefs::Setting *setting) +void CSVPrefs::Page::addSetting(CSMPrefs::Setting* setting) { - std::pair widgets = setting->makeWidgets (this); + std::pair widgets = setting->makeWidgets(this); int next = mGrid->rowCount(); if (widgets.first) { - mGrid->addWidget (widgets.first, next, 0); - mGrid->addWidget (widgets.second, next, 1); + mGrid->addWidget(widgets.first, next, 0); + mGrid->addWidget(widgets.second, next, 1); } else if (widgets.second) { - mGrid->addWidget (widgets.second, next, 0, 1, 2); + mGrid->addWidget(widgets.second, next, 0, 1, 2); } else { - mGrid->addWidget (new QWidget (this), next, 0); + mGrid->addWidget(new QWidget(this), next, 0); } } diff --git a/apps/opencs/view/prefs/page.hpp b/apps/opencs/view/prefs/page.hpp index ce13e5d9b9..32b057071e 100644 --- a/apps/opencs/view/prefs/page.hpp +++ b/apps/opencs/view/prefs/page.hpp @@ -14,15 +14,14 @@ namespace CSVPrefs { class Page : public PageBase { - Q_OBJECT + Q_OBJECT - QGridLayout *mGrid; + QGridLayout* mGrid; - public: + public: + Page(CSMPrefs::Category& category, QWidget* parent); - Page (CSMPrefs::Category& category, QWidget *parent); - - void addSetting (CSMPrefs::Setting *setting); + void addSetting(CSMPrefs::Setting* setting); }; } diff --git a/apps/opencs/view/prefs/pagebase.cpp b/apps/opencs/view/prefs/pagebase.cpp index 15535b785f..ea9af3256d 100644 --- a/apps/opencs/view/prefs/pagebase.cpp +++ b/apps/opencs/view/prefs/pagebase.cpp @@ -1,15 +1,17 @@ #include "pagebase.hpp" -#include #include +#include #include "../../model/prefs/category.hpp" #include "../../model/prefs/state.hpp" -CSVPrefs::PageBase::PageBase (CSMPrefs::Category& category, QWidget *parent) -: QScrollArea (parent), mCategory (category) -{} +CSVPrefs::PageBase::PageBase(CSMPrefs::Category& category, QWidget* parent) + : QScrollArea(parent) + , mCategory(category) +{ +} CSMPrefs::Category& CSVPrefs::PageBase::getCategory() { diff --git a/apps/opencs/view/prefs/pagebase.hpp b/apps/opencs/view/prefs/pagebase.hpp index ce5b378b35..b5e0836dde 100644 --- a/apps/opencs/view/prefs/pagebase.hpp +++ b/apps/opencs/view/prefs/pagebase.hpp @@ -14,25 +14,23 @@ namespace CSVPrefs { class PageBase : public QScrollArea { - Q_OBJECT + Q_OBJECT - CSMPrefs::Category& mCategory; + CSMPrefs::Category& mCategory; - public: + public: + PageBase(CSMPrefs::Category& category, QWidget* parent); - PageBase (CSMPrefs::Category& category, QWidget *parent); + CSMPrefs::Category& getCategory(); - CSMPrefs::Category& getCategory(); + protected: + void contextMenuEvent(QContextMenuEvent*) override; - protected: + private slots: - void contextMenuEvent(QContextMenuEvent*) override; + void resetCategory(); - private slots: - - void resetCategory(); - - void resetAll(); + void resetAll(); }; } diff --git a/apps/opencs/view/render/actor.cpp b/apps/opencs/view/render/actor.cpp index 99b2b342ff..2ac5bdea80 100644 --- a/apps/opencs/view/render/actor.cpp +++ b/apps/opencs/view/render/actor.cpp @@ -23,8 +23,7 @@ namespace CSVRender , mSkeleton(nullptr) { mActorData = mData.getActorAdapter()->getActorData(mId); - connect(mData.getActorAdapter(), &CSMWorld::ActorAdapter::actorChanged, - this, &Actor::handleActorChanged); + connect(mData.getActorAdapter(), &CSMWorld::ActorAdapter::actorChanged, this, &Actor::handleActorChanged); } osg::Group* Actor::getBaseNode() @@ -38,7 +37,8 @@ namespace CSVRender // Load skeleton std::string skeletonModel = mActorData->getSkeleton(); - skeletonModel = Misc::ResourceHelpers::correctActorModelPath(skeletonModel, mData.getResourceSystem()->getVFS()); + skeletonModel + = Misc::ResourceHelpers::correctActorModelPath(skeletonModel, mData.getResourceSystem()->getVFS()); loadSkeleton(skeletonModel); if (!mActorData->isCreature()) @@ -88,14 +88,13 @@ namespace CSVRender mNodeMap.clear(); SceneUtil::NodeMapVisitor nmVisitor(mNodeMap); mSkeleton->accept(nmVisitor); - } void Actor::loadBodyParts() { for (int i = 0; i < ESM::PRT_Count; ++i) { - auto type = (ESM::PartReferenceType) i; + auto type = (ESM::PartReferenceType)i; const std::string_view partId = mActorData->getPart(type); attachBodyPart(type, getBodyPartMesh(partId)); } diff --git a/apps/opencs/view/render/brushdraw.cpp b/apps/opencs/view/render/brushdraw.cpp index 6b33e336ea..c89cfe41a5 100644 --- a/apps/opencs/view/render/brushdraw.cpp +++ b/apps/opencs/view/render/brushdraw.cpp @@ -2,9 +2,9 @@ #include -#include -#include #include +#include +#include #include @@ -12,8 +12,9 @@ #include "../widget/brushshapes.hpp" #include "mask.hpp" -CSVRender::BrushDraw::BrushDraw(osg::ref_ptr parentNode, bool textureMode) : - mParentNode(parentNode), mTextureMode(textureMode) +CSVRender::BrushDraw::BrushDraw(osg::ref_ptr parentNode, bool textureMode) + : mParentNode(parentNode) + , mTextureMode(textureMode) { mBrushDrawNode = new osg::Group(); mGeometry = new osg::Geometry(); @@ -33,7 +34,7 @@ CSVRender::BrushDraw::~BrushDraw() mParentNode->removeChild(mBrushDrawNode); } -float CSVRender::BrushDraw::getIntersectionHeight (const osg::Vec3d& point) +float CSVRender::BrushDraw::getIntersectionHeight(const osg::Vec3d& point) { osg::Vec3d start = point; osg::Vec3d end = point; @@ -42,8 +43,8 @@ float CSVRender::BrushDraw::getIntersectionHeight (const osg::Vec3d& point) osg::Vec3d direction = end - start; // Get intersection - osg::ref_ptr intersector (new osgUtil::LineSegmentIntersector( - osgUtil::Intersector::MODEL, start, end) ); + osg::ref_ptr intersector( + new osgUtil::LineSegmentIntersector(osgUtil::Intersector::MODEL, start, end)); intersector->setIntersectionLimit(osgUtil::LineSegmentIntersector::NO_LIMIT); osgUtil::IntersectionVisitor visitor(intersector); @@ -69,44 +70,28 @@ float CSVRender::BrushDraw::getIntersectionHeight (const osg::Vec3d& point) void CSVRender::BrushDraw::buildPointGeometry(const osg::Vec3d& point) { - osg::ref_ptr geom (new osg::Geometry()); - osg::ref_ptr vertices (new osg::Vec3Array()); - osg::ref_ptr colors (new osg::Vec4Array()); - const float brushOutlineHeight (1.0f); - const float crossHeadSize (8.0f); + osg::ref_ptr geom(new osg::Geometry()); + osg::ref_ptr vertices(new osg::Vec3Array()); + osg::ref_ptr colors(new osg::Vec4Array()); + const float brushOutlineHeight(1.0f); + const float crossHeadSize(8.0f); osg::Vec4f lineColor(1.0f, 1.0f, 1.0f, 0.6f); - vertices->push_back(osg::Vec3d( - point.x() - crossHeadSize, - point.y() - crossHeadSize, - getIntersectionHeight(osg::Vec3d( - point.x() - crossHeadSize, - point.y() - crossHeadSize, - point.z()) ) + brushOutlineHeight)); + vertices->push_back(osg::Vec3d(point.x() - crossHeadSize, point.y() - crossHeadSize, + getIntersectionHeight(osg::Vec3d(point.x() - crossHeadSize, point.y() - crossHeadSize, point.z())) + + brushOutlineHeight)); colors->push_back(lineColor); - vertices->push_back(osg::Vec3d( - point.x() + crossHeadSize, - point.y() + crossHeadSize, - getIntersectionHeight(osg::Vec3d( - point.x() + crossHeadSize, - point.y() + crossHeadSize, - point.z()) ) + brushOutlineHeight)); + vertices->push_back(osg::Vec3d(point.x() + crossHeadSize, point.y() + crossHeadSize, + getIntersectionHeight(osg::Vec3d(point.x() + crossHeadSize, point.y() + crossHeadSize, point.z())) + + brushOutlineHeight)); colors->push_back(lineColor); - vertices->push_back(osg::Vec3d( - point.x() + crossHeadSize, - point.y() - crossHeadSize, - getIntersectionHeight(osg::Vec3d( - point.x() + crossHeadSize, - point.y() - crossHeadSize, - point.z()) ) + brushOutlineHeight)); + vertices->push_back(osg::Vec3d(point.x() + crossHeadSize, point.y() - crossHeadSize, + getIntersectionHeight(osg::Vec3d(point.x() + crossHeadSize, point.y() - crossHeadSize, point.z())) + + brushOutlineHeight)); colors->push_back(lineColor); - vertices->push_back(osg::Vec3d( - point.x() - crossHeadSize, - point.y() + crossHeadSize, - getIntersectionHeight(osg::Vec3d( - point.x() - crossHeadSize, - point.y() + crossHeadSize, - point.z()) ) + brushOutlineHeight)); + vertices->push_back(osg::Vec3d(point.x() - crossHeadSize, point.y() + crossHeadSize, + getIntersectionHeight(osg::Vec3d(point.x() - crossHeadSize, point.y() + crossHeadSize, point.z())) + + brushOutlineHeight)); colors->push_back(lineColor); geom->setVertexArray(vertices); @@ -117,14 +102,14 @@ void CSVRender::BrushDraw::buildPointGeometry(const osg::Vec3d& point) void CSVRender::BrushDraw::buildSquareGeometry(const float& radius, const osg::Vec3d& point) { - osg::ref_ptr geom (new osg::Geometry()); - osg::ref_ptr vertices (new osg::Vec3Array()); - osg::ref_ptr colors (new osg::Vec4Array()); + osg::ref_ptr geom(new osg::Geometry()); + osg::ref_ptr vertices(new osg::Vec3Array()); + osg::ref_ptr colors(new osg::Vec4Array()); - const float brushOutlineHeight (1.0f); + const float brushOutlineHeight(1.0f); float diameter = radius * 2; - int resolution = static_cast(2.f * diameter / mLandSizeFactor); //half a vertex resolution - float resAdjustedLandSizeFactor = mLandSizeFactor / 2; //128 + int resolution = static_cast(2.f * diameter / mLandSizeFactor); // half a vertex resolution + float resAdjustedLandSizeFactor = mLandSizeFactor / 2; // 128 if (resolution > 128) // limit accuracy for performance { @@ -139,62 +124,30 @@ void CSVRender::BrushDraw::buildSquareGeometry(const float& radius, const osg::V int step = i * resAdjustedLandSizeFactor; int step2 = (i + 1) * resAdjustedLandSizeFactor; - osg::Vec3d upHorizontalLinePoint1( - point.x() - radius + step, - point.y() - radius, - getIntersectionHeight(osg::Vec3d( - point.x() - radius + step, - point.y() - radius, - point.z())) + brushOutlineHeight); - osg::Vec3d upHorizontalLinePoint2( - point.x() - radius + step2, - point.y() - radius, - getIntersectionHeight(osg::Vec3d( - point.x() - radius + step2, - point.y() - radius, - point.z())) + brushOutlineHeight); - osg::Vec3d upVerticalLinePoint1( - point.x() - radius, - point.y() - radius + step, - getIntersectionHeight(osg::Vec3d( - point.x() - radius, - point.y() - radius + step, - point.z())) + brushOutlineHeight); - osg::Vec3d upVerticalLinePoint2( - point.x() - radius, - point.y() - radius + step2, - getIntersectionHeight(osg::Vec3d( - point.x() - radius, - point.y() - radius + step2, - point.z())) + brushOutlineHeight); - osg::Vec3d downHorizontalLinePoint1( - point.x() + radius - step, - point.y() + radius, - getIntersectionHeight(osg::Vec3d( - point.x() + radius - step, - point.y() + radius, - point.z())) + brushOutlineHeight); - osg::Vec3d downHorizontalLinePoint2( - point.x() + radius - step2, - point.y() + radius, - getIntersectionHeight(osg::Vec3d( - point.x() + radius - step2, - point.y() + radius, - point.z())) + brushOutlineHeight); - osg::Vec3d downVerticalLinePoint1( - point.x() + radius, - point.y() + radius - step, - getIntersectionHeight(osg::Vec3d( - point.x() + radius, - point.y() + radius - step, - point.z())) + brushOutlineHeight); - osg::Vec3d downVerticalLinePoint2( - point.x() + radius, - point.y() + radius - step2, - getIntersectionHeight(osg::Vec3d( - point.x() + radius, - point.y() + radius - step2, - point.z())) + brushOutlineHeight); + osg::Vec3d upHorizontalLinePoint1(point.x() - radius + step, point.y() - radius, + getIntersectionHeight(osg::Vec3d(point.x() - radius + step, point.y() - radius, point.z())) + + brushOutlineHeight); + osg::Vec3d upHorizontalLinePoint2(point.x() - radius + step2, point.y() - radius, + getIntersectionHeight(osg::Vec3d(point.x() - radius + step2, point.y() - radius, point.z())) + + brushOutlineHeight); + osg::Vec3d upVerticalLinePoint1(point.x() - radius, point.y() - radius + step, + getIntersectionHeight(osg::Vec3d(point.x() - radius, point.y() - radius + step, point.z())) + + brushOutlineHeight); + osg::Vec3d upVerticalLinePoint2(point.x() - radius, point.y() - radius + step2, + getIntersectionHeight(osg::Vec3d(point.x() - radius, point.y() - radius + step2, point.z())) + + brushOutlineHeight); + osg::Vec3d downHorizontalLinePoint1(point.x() + radius - step, point.y() + radius, + getIntersectionHeight(osg::Vec3d(point.x() + radius - step, point.y() + radius, point.z())) + + brushOutlineHeight); + osg::Vec3d downHorizontalLinePoint2(point.x() + radius - step2, point.y() + radius, + getIntersectionHeight(osg::Vec3d(point.x() + radius - step2, point.y() + radius, point.z())) + + brushOutlineHeight); + osg::Vec3d downVerticalLinePoint1(point.x() + radius, point.y() + radius - step, + getIntersectionHeight(osg::Vec3d(point.x() + radius, point.y() + radius - step, point.z())) + + brushOutlineHeight); + osg::Vec3d downVerticalLinePoint2(point.x() + radius, point.y() + radius - step2, + getIntersectionHeight(osg::Vec3d(point.x() + radius, point.y() + radius - step2, point.z())) + + brushOutlineHeight); vertices->push_back(upHorizontalLinePoint1); colors->push_back(lineColor); vertices->push_back(upHorizontalLinePoint2); @@ -221,34 +174,28 @@ void CSVRender::BrushDraw::buildSquareGeometry(const float& radius, const osg::V void CSVRender::BrushDraw::buildCircleGeometry(const float& radius, const osg::Vec3d& point) { - osg::ref_ptr geom (new osg::Geometry()); - osg::ref_ptr vertices (new osg::Vec3Array()); - osg::ref_ptr colors (new osg::Vec4Array()); + osg::ref_ptr geom(new osg::Geometry()); + osg::ref_ptr vertices(new osg::Vec3Array()); + osg::ref_ptr colors(new osg::Vec4Array()); const int amountOfPoints = 128; - const float step ((osg::PI * 2.0f) / static_cast(amountOfPoints)); - const float brushOutlineHeight (1.0f); + const float step((osg::PI * 2.0f) / static_cast(amountOfPoints)); + const float brushOutlineHeight(1.0f); osg::Vec4f lineColor(1.0f, 1.0f, 1.0f, 0.6f); for (int i = 0; i < amountOfPoints + 2; i++) { - float angle (i * step); - vertices->push_back(osg::Vec3d( - point.x() + radius * cosf(angle), - point.y() + radius * sinf(angle), - getIntersectionHeight(osg::Vec3d( - point.x() + radius * cosf(angle), - point.y() + radius * sinf(angle), - point.z()) ) + brushOutlineHeight)); + float angle(i * step); + vertices->push_back(osg::Vec3d(point.x() + radius * cosf(angle), point.y() + radius * sinf(angle), + getIntersectionHeight( + osg::Vec3d(point.x() + radius * cosf(angle), point.y() + radius * sinf(angle), point.z())) + + brushOutlineHeight)); colors->push_back(lineColor); angle = static_cast(i + 1) * step; - vertices->push_back(osg::Vec3d( - point.x() + radius * cosf(angle), - point.y() + radius * sinf(angle), - getIntersectionHeight(osg::Vec3d( - point.x() + radius * cosf(angle), - point.y() + radius * sinf(angle), - point.z()) ) + brushOutlineHeight)); + vertices->push_back(osg::Vec3d(point.x() + radius * cosf(angle), point.y() + radius * sinf(angle), + getIntersectionHeight( + osg::Vec3d(point.x() + radius * cosf(angle), point.y() + radius * sinf(angle), point.z())) + + brushOutlineHeight)); colors->push_back(lineColor); } @@ -272,36 +219,32 @@ void CSVRender::BrushDraw::update(osg::Vec3d point, int brushSize, CSVWidget::Br if (mTextureMode) { std::pair snapToGridXY = CSMWorld::CellCoordinates::toTextureCoords(point); - float offsetToMiddle = mLandSizeFactor * 0.5f; + float offsetToMiddle = mLandSizeFactor * 0.5f; snapToGridPoint = osg::Vec3d( CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(snapToGridXY.first) + offsetToMiddle, - CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(snapToGridXY.second) + offsetToMiddle, - point.z()); + CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(snapToGridXY.second) + offsetToMiddle, point.z()); } else { std::pair snapToGridXY = CSMWorld::CellCoordinates::toVertexCoords(point); - snapToGridPoint = osg::Vec3d( - CSMWorld::CellCoordinates::vertexGlobalToWorldCoords(snapToGridXY.first), - CSMWorld::CellCoordinates::vertexGlobalToWorldCoords(snapToGridXY.second), - point.z()); + snapToGridPoint = osg::Vec3d(CSMWorld::CellCoordinates::vertexGlobalToWorldCoords(snapToGridXY.first), + CSMWorld::CellCoordinates::vertexGlobalToWorldCoords(snapToGridXY.second), point.z()); } - switch (toolShape) { - case (CSVWidget::BrushShape_Point) : + case (CSVWidget::BrushShape_Point): buildPointGeometry(snapToGridPoint); break; - case (CSVWidget::BrushShape_Square) : + case (CSVWidget::BrushShape_Square): buildSquareGeometry(radius, snapToGridPoint); break; - case (CSVWidget::BrushShape_Circle) : + case (CSVWidget::BrushShape_Circle): buildCircleGeometry(radius, snapToGridPoint); break; - case (CSVWidget::BrushShape_Custom) : + case (CSVWidget::BrushShape_Custom): buildSquareGeometry(1, snapToGridPoint); - //buildCustomGeometry + // buildCustomGeometry break; } diff --git a/apps/opencs/view/render/brushdraw.hpp b/apps/opencs/view/render/brushdraw.hpp index f95a0c5a7c..64ded1c10b 100644 --- a/apps/opencs/view/render/brushdraw.hpp +++ b/apps/opencs/view/render/brushdraw.hpp @@ -1,35 +1,35 @@ #ifndef CSV_RENDER_BRUSHDRAW_H #define CSV_RENDER_BRUSHDRAW_H -#include #include +#include -#include #include "../widget/brushshapes.hpp" +#include namespace CSVRender { class BrushDraw { - public: - BrushDraw(osg::ref_ptr parentNode, bool textureMode = false); - ~BrushDraw(); + public: + BrushDraw(osg::ref_ptr parentNode, bool textureMode = false); + ~BrushDraw(); - void update(osg::Vec3d point, int brushSize, CSVWidget::BrushShape toolShape); - void hide(); + void update(osg::Vec3d point, int brushSize, CSVWidget::BrushShape toolShape); + void hide(); - private: - void buildPointGeometry(const osg::Vec3d& point); - void buildSquareGeometry(const float& radius, const osg::Vec3d& point); - void buildCircleGeometry(const float& radius, const osg::Vec3d& point); - void buildCustomGeometry(const float& radius, const osg::Vec3d& point); - float getIntersectionHeight (const osg::Vec3d& point); + private: + void buildPointGeometry(const osg::Vec3d& point); + void buildSquareGeometry(const float& radius, const osg::Vec3d& point); + void buildCircleGeometry(const float& radius, const osg::Vec3d& point); + void buildCustomGeometry(const float& radius, const osg::Vec3d& point); + float getIntersectionHeight(const osg::Vec3d& point); - osg::ref_ptr mParentNode; - osg::ref_ptr mBrushDrawNode; - osg::ref_ptr mGeometry; - bool mTextureMode; - float mLandSizeFactor; + osg::ref_ptr mParentNode; + osg::ref_ptr mBrushDrawNode; + osg::ref_ptr mGeometry; + bool mTextureMode; + float mLandSizeFactor; }; } diff --git a/apps/opencs/view/render/cameracontroller.cpp b/apps/opencs/view/render/cameracontroller.cpp index 32d0b4268a..87ba7e58f3 100644 --- a/apps/opencs/view/render/cameracontroller.cpp +++ b/apps/opencs/view/render/cameracontroller.cpp @@ -35,16 +35,14 @@ namespace CSVRender : QObject(parent) , mActive(false) , mInverted(false) - , mCameraSensitivity(1/650.f) + , mCameraSensitivity(1 / 650.f) , mSecondaryMoveMult(50) , mWheelMoveMult(8) , mCamera(nullptr) { } - CameraController::~CameraController() - { - } + CameraController::~CameraController() {} bool CameraController::isActive() const { @@ -179,67 +177,63 @@ namespace CSVRender { CSMPrefs::Shortcut* naviPrimaryShortcut = new CSMPrefs::Shortcut("scene-navi-primary", widget); naviPrimaryShortcut->enable(false); - connect(naviPrimaryShortcut, qOverload(&CSMPrefs::Shortcut::activated), - this, &FreeCameraController::naviPrimary); + connect(naviPrimaryShortcut, qOverload(&CSMPrefs::Shortcut::activated), this, + &FreeCameraController::naviPrimary); addShortcut(naviPrimaryShortcut); CSMPrefs::Shortcut* naviSecondaryShortcut = new CSMPrefs::Shortcut("scene-navi-secondary", widget); naviSecondaryShortcut->enable(false); - connect(naviSecondaryShortcut, qOverload(&CSMPrefs::Shortcut::activated), - this, &FreeCameraController::naviSecondary); + connect(naviSecondaryShortcut, qOverload(&CSMPrefs::Shortcut::activated), this, + &FreeCameraController::naviSecondary); addShortcut(naviSecondaryShortcut); - CSMPrefs::Shortcut* forwardShortcut = new CSMPrefs::Shortcut("free-forward", "scene-speed-modifier", - CSMPrefs::Shortcut::SM_Detach, widget); + CSMPrefs::Shortcut* forwardShortcut + = new CSMPrefs::Shortcut("free-forward", "scene-speed-modifier", CSMPrefs::Shortcut::SM_Detach, widget); forwardShortcut->enable(false); - connect(forwardShortcut, qOverload(&CSMPrefs::Shortcut::activated), - this, &FreeCameraController::forward); - connect(forwardShortcut, qOverload(&CSMPrefs::Shortcut::secondary), - this, &FreeCameraController::alternateFast); + connect(forwardShortcut, qOverload(&CSMPrefs::Shortcut::activated), this, &FreeCameraController::forward); + connect(forwardShortcut, qOverload(&CSMPrefs::Shortcut::secondary), this, + &FreeCameraController::alternateFast); addShortcut(forwardShortcut); CSMPrefs::Shortcut* leftShortcut = new CSMPrefs::Shortcut("free-left", widget); leftShortcut->enable(false); - connect(leftShortcut, qOverload(&CSMPrefs::Shortcut::activated), - this, &FreeCameraController::left); + connect(leftShortcut, qOverload(&CSMPrefs::Shortcut::activated), this, &FreeCameraController::left); addShortcut(leftShortcut); CSMPrefs::Shortcut* backShortcut = new CSMPrefs::Shortcut("free-backward", widget); backShortcut->enable(false); - connect(backShortcut, qOverload(&CSMPrefs::Shortcut::activated), - this, &FreeCameraController::backward); + connect(backShortcut, qOverload(&CSMPrefs::Shortcut::activated), this, &FreeCameraController::backward); addShortcut(backShortcut); CSMPrefs::Shortcut* rightShortcut = new CSMPrefs::Shortcut("free-right", widget); rightShortcut->enable(false); - connect(rightShortcut, qOverload(&CSMPrefs::Shortcut::activated), - this, &FreeCameraController::right); + connect(rightShortcut, qOverload(&CSMPrefs::Shortcut::activated), this, &FreeCameraController::right); addShortcut(rightShortcut); CSMPrefs::Shortcut* rollLeftShortcut = new CSMPrefs::Shortcut("free-roll-left", widget); rollLeftShortcut->enable(false); - connect(rollLeftShortcut, qOverload(&CSMPrefs::Shortcut::activated), - this, &FreeCameraController::rollLeft); + connect( + rollLeftShortcut, qOverload(&CSMPrefs::Shortcut::activated), this, &FreeCameraController::rollLeft); addShortcut(rollLeftShortcut); CSMPrefs::Shortcut* rollRightShortcut = new CSMPrefs::Shortcut("free-roll-right", widget); rollRightShortcut->enable(false); - connect(rollRightShortcut, qOverload(&CSMPrefs::Shortcut::activated), - this, &FreeCameraController::rollRight); + connect( + rollRightShortcut, qOverload(&CSMPrefs::Shortcut::activated), this, &FreeCameraController::rollRight); addShortcut(rollRightShortcut); CSMPrefs::Shortcut* speedModeShortcut = new CSMPrefs::Shortcut("free-speed-mode", widget); speedModeShortcut->enable(false); - connect(speedModeShortcut, qOverload<>(&CSMPrefs::Shortcut::activated), - this, &FreeCameraController::swapSpeedMode); + connect( + speedModeShortcut, qOverload<>(&CSMPrefs::Shortcut::activated), this, &FreeCameraController::swapSpeedMode); addShortcut(speedModeShortcut); } @@ -342,7 +336,7 @@ namespace CSVRender if (mRollRight) roll(rotDist); } - else if(mModified) + else if (mModified) { stabilize(); mModified = false; @@ -469,7 +463,7 @@ namespace CSVRender , mRollLeft(false) , mRollRight(false) , mPickingMask(~0u) - , mCenter(0,0,0) + , mCenter(0, 0, 0) , mDistance(0) , mOrbitSpeed(osg::PI / 4) , mOrbitSpeedMult(4) @@ -477,67 +471,63 @@ namespace CSVRender { CSMPrefs::Shortcut* naviPrimaryShortcut = new CSMPrefs::Shortcut("scene-navi-primary", widget); naviPrimaryShortcut->enable(false); - connect(naviPrimaryShortcut, qOverload(&CSMPrefs::Shortcut::activated), - this, &OrbitCameraController::naviPrimary); + connect(naviPrimaryShortcut, qOverload(&CSMPrefs::Shortcut::activated), this, + &OrbitCameraController::naviPrimary); addShortcut(naviPrimaryShortcut); CSMPrefs::Shortcut* naviSecondaryShortcut = new CSMPrefs::Shortcut("scene-navi-secondary", widget); naviSecondaryShortcut->enable(false); - connect(naviSecondaryShortcut, qOverload(&CSMPrefs::Shortcut::activated), - this, &OrbitCameraController::naviSecondary); + connect(naviSecondaryShortcut, qOverload(&CSMPrefs::Shortcut::activated), this, + &OrbitCameraController::naviSecondary); addShortcut(naviSecondaryShortcut); - CSMPrefs::Shortcut* upShortcut = new CSMPrefs::Shortcut("orbit-up", "scene-speed-modifier", - CSMPrefs::Shortcut::SM_Detach, widget); + CSMPrefs::Shortcut* upShortcut + = new CSMPrefs::Shortcut("orbit-up", "scene-speed-modifier", CSMPrefs::Shortcut::SM_Detach, widget); upShortcut->enable(false); - connect(upShortcut, qOverload(&CSMPrefs::Shortcut::activated), - this, &OrbitCameraController::up); - connect(upShortcut, qOverload(&CSMPrefs::Shortcut::secondary), - this, &OrbitCameraController::alternateFast); + connect(upShortcut, qOverload(&CSMPrefs::Shortcut::activated), this, &OrbitCameraController::up); + connect( + upShortcut, qOverload(&CSMPrefs::Shortcut::secondary), this, &OrbitCameraController::alternateFast); addShortcut(upShortcut); CSMPrefs::Shortcut* leftShortcut = new CSMPrefs::Shortcut("orbit-left", widget); leftShortcut->enable(false); - connect(leftShortcut, qOverload(&CSMPrefs::Shortcut::activated), - this, &OrbitCameraController::left); + connect(leftShortcut, qOverload(&CSMPrefs::Shortcut::activated), this, &OrbitCameraController::left); addShortcut(leftShortcut); CSMPrefs::Shortcut* downShortcut = new CSMPrefs::Shortcut("orbit-down", widget); downShortcut->enable(false); - connect(downShortcut, qOverload(&CSMPrefs::Shortcut::activated), - this, &OrbitCameraController::down); + connect(downShortcut, qOverload(&CSMPrefs::Shortcut::activated), this, &OrbitCameraController::down); addShortcut(downShortcut); CSMPrefs::Shortcut* rightShortcut = new CSMPrefs::Shortcut("orbit-right", widget); rightShortcut->enable(false); - connect(rightShortcut, qOverload(&CSMPrefs::Shortcut::activated), - this, &OrbitCameraController::right); + connect(rightShortcut, qOverload(&CSMPrefs::Shortcut::activated), this, &OrbitCameraController::right); addShortcut(rightShortcut); CSMPrefs::Shortcut* rollLeftShortcut = new CSMPrefs::Shortcut("orbit-roll-left", widget); rollLeftShortcut->enable(false); - connect(rollLeftShortcut, qOverload(&CSMPrefs::Shortcut::activated), - this, &OrbitCameraController::rollLeft); + connect( + rollLeftShortcut, qOverload(&CSMPrefs::Shortcut::activated), this, &OrbitCameraController::rollLeft); addShortcut(rollLeftShortcut); CSMPrefs::Shortcut* rollRightShortcut = new CSMPrefs::Shortcut("orbit-roll-right", widget); rollRightShortcut->enable(false); - connect(rollRightShortcut, qOverload(&CSMPrefs::Shortcut::activated), - this, &OrbitCameraController::rollRight); + connect(rollRightShortcut, qOverload(&CSMPrefs::Shortcut::activated), this, + &OrbitCameraController::rollRight); addShortcut(rollRightShortcut); CSMPrefs::Shortcut* speedModeShortcut = new CSMPrefs::Shortcut("orbit-speed-mode", widget); speedModeShortcut->enable(false); - connect(speedModeShortcut, qOverload<>(&CSMPrefs::Shortcut::activated), - this, &OrbitCameraController::swapSpeedMode); + connect(speedModeShortcut, qOverload<>(&CSMPrefs::Shortcut::activated), this, + &OrbitCameraController::swapSpeedMode); addShortcut(speedModeShortcut); } @@ -663,8 +653,8 @@ namespace CSVRender static const int DefaultStartDistance = 10000.f; // Try to intelligently pick focus object - osg::ref_ptr intersector (new osgUtil::LineSegmentIntersector( - osgUtil::Intersector::PROJECTION, osg::Vec3d(0, 0, 0), LocalForward)); + osg::ref_ptr intersector( + new osgUtil::LineSegmentIntersector(osgUtil::Intersector::PROJECTION, osg::Vec3d(0, 0, 0), LocalForward)); intersector->setIntersectionLimit(osgUtil::LineSegmentIntersector::LIMIT_NEAREST); osgUtil::IntersectionVisitor visitor(intersector); @@ -699,7 +689,7 @@ namespace CSVRender { osg::Vec3d eye, center, up; getCamera()->getViewMatrixAsLookAt(eye, center, up); - osg::Vec3d absoluteUp = osg::Vec3(0,0,1); + osg::Vec3d absoluteUp = osg::Vec3(0, 0, 1); osg::Quat rotation = osg::Quat(value, mConstRoll ? absoluteUp : up); osg::Vec3d oldOffset = eye - mCenter; @@ -719,7 +709,7 @@ namespace CSVRender osg::Vec3d forward = center - eye; osg::Vec3d axis = up ^ forward; - osg::Quat rotation = osg::Quat(value,axis); + osg::Quat rotation = osg::Quat(value, axis); osg::Vec3d oldOffset = eye - mCenter; osg::Vec3d newOffset = rotation * oldOffset; diff --git a/apps/opencs/view/render/cameracontroller.hpp b/apps/opencs/view/render/cameracontroller.hpp index dff0f212e9..4ebca23930 100644 --- a/apps/opencs/view/render/cameracontroller.hpp +++ b/apps/opencs/view/render/cameracontroller.hpp @@ -6,8 +6,8 @@ #include -#include #include +#include namespace osg { @@ -26,177 +26,170 @@ namespace CSVRender class CameraController : public QObject { - Q_OBJECT - - public: - - static const osg::Vec3d WorldUp; - - static const osg::Vec3d LocalUp; - static const osg::Vec3d LocalLeft; - static const osg::Vec3d LocalForward; + Q_OBJECT - CameraController(QObject* parent); - virtual ~CameraController(); + public: + static const osg::Vec3d WorldUp; - bool isActive() const; + static const osg::Vec3d LocalUp; + static const osg::Vec3d LocalLeft; + static const osg::Vec3d LocalForward; - osg::Camera* getCamera() const; - double getCameraSensitivity() const; - bool getInverted() const; - double getSecondaryMovementMultiplier() const; - double getWheelMovementMultiplier() const; + CameraController(QObject* parent); + virtual ~CameraController(); - void setCamera(osg::Camera*); - void setCameraSensitivity(double value); - void setInverted(bool value); - void setSecondaryMovementMultiplier(double value); - void setWheelMovementMultiplier(double value); + bool isActive() const; - // moves the camera to an intelligent position - void setup(osg::Group* root, unsigned int mask, const osg::Vec3d& up); + osg::Camera* getCamera() const; + double getCameraSensitivity() const; + bool getInverted() const; + double getSecondaryMovementMultiplier() const; + double getWheelMovementMultiplier() const; - virtual void handleMouseMoveEvent(int x, int y) = 0; - virtual void handleMouseScrollEvent(int x) = 0; + void setCamera(osg::Camera*); + void setCameraSensitivity(double value); + void setInverted(bool value); + void setSecondaryMovementMultiplier(double value); + void setWheelMovementMultiplier(double value); - virtual void update(double dt) = 0; + // moves the camera to an intelligent position + void setup(osg::Group* root, unsigned int mask, const osg::Vec3d& up); - protected: + virtual void handleMouseMoveEvent(int x, int y) = 0; + virtual void handleMouseScrollEvent(int x) = 0; - void addShortcut(CSMPrefs::Shortcut* shortcut); + virtual void update(double dt) = 0; - private: + protected: + void addShortcut(CSMPrefs::Shortcut* shortcut); - bool mActive, mInverted; - double mCameraSensitivity; - double mSecondaryMoveMult; - double mWheelMoveMult; + private: + bool mActive, mInverted; + double mCameraSensitivity; + double mSecondaryMoveMult; + double mWheelMoveMult; - osg::Camera* mCamera; + osg::Camera* mCamera; - std::vector mShortcuts; + std::vector mShortcuts; }; class FreeCameraController : public CameraController { - Q_OBJECT + Q_OBJECT - public: + public: + FreeCameraController(QWidget* parent); - FreeCameraController(QWidget* parent); + double getLinearSpeed() const; + double getRotationalSpeed() const; + double getSpeedMultiplier() const; - double getLinearSpeed() const; - double getRotationalSpeed() const; - double getSpeedMultiplier() const; + void setLinearSpeed(double value); + void setRotationalSpeed(double value); + void setSpeedMultiplier(double value); - void setLinearSpeed(double value); - void setRotationalSpeed(double value); - void setSpeedMultiplier(double value); + void fixUpAxis(const osg::Vec3d& up); + void unfixUpAxis(); - void fixUpAxis(const osg::Vec3d& up); - void unfixUpAxis(); + void handleMouseMoveEvent(int x, int y) override; + void handleMouseScrollEvent(int x) override; - void handleMouseMoveEvent(int x, int y) override; - void handleMouseScrollEvent(int x) override; + void update(double dt) override; - void update(double dt) override; + private: + void yaw(double value); + void pitch(double value); + void roll(double value); + void translate(const osg::Vec3d& offset); - private: + void stabilize(); - void yaw(double value); - void pitch(double value); - void roll(double value); - void translate(const osg::Vec3d& offset); + bool mLockUpright, mModified; + bool mNaviPrimary, mNaviSecondary; + bool mFast, mFastAlternate; + bool mLeft, mRight, mForward, mBackward, mRollLeft, mRollRight; + osg::Vec3d mUp; - void stabilize(); + double mLinSpeed; + double mRotSpeed; + double mSpeedMult; - bool mLockUpright, mModified; - bool mNaviPrimary, mNaviSecondary; - bool mFast, mFastAlternate; - bool mLeft, mRight, mForward, mBackward, mRollLeft, mRollRight; - osg::Vec3d mUp; + private slots: - double mLinSpeed; - double mRotSpeed; - double mSpeedMult; - - private slots: - - void naviPrimary(bool active); - void naviSecondary(bool active); - void forward(bool active); - void left(bool active); - void backward(bool active); - void right(bool active); - void rollLeft(bool active); - void rollRight(bool active); - void alternateFast(bool active); - void swapSpeedMode(); + void naviPrimary(bool active); + void naviSecondary(bool active); + void forward(bool active); + void left(bool active); + void backward(bool active); + void right(bool active); + void rollLeft(bool active); + void rollRight(bool active); + void alternateFast(bool active); + void swapSpeedMode(); }; class OrbitCameraController : public CameraController { - Q_OBJECT - - public: - - OrbitCameraController(QWidget* parent); + Q_OBJECT - osg::Vec3d getCenter() const; - double getOrbitSpeed() const; - double getOrbitSpeedMultiplier() const; - unsigned int getPickingMask() const; + public: + OrbitCameraController(QWidget* parent); - void setCenter(const osg::Vec3d& center); - void setOrbitSpeed(double value); - void setOrbitSpeedMultiplier(double value); - void setPickingMask(unsigned int value); + osg::Vec3d getCenter() const; + double getOrbitSpeed() const; + double getOrbitSpeedMultiplier() const; + unsigned int getPickingMask() const; - void handleMouseMoveEvent(int x, int y) override; - void handleMouseScrollEvent(int x) override; + void setCenter(const osg::Vec3d& center); + void setOrbitSpeed(double value); + void setOrbitSpeedMultiplier(double value); + void setPickingMask(unsigned int value); - void update(double dt) override; + void handleMouseMoveEvent(int x, int y) override; + void handleMouseScrollEvent(int x) override; - /// \brief Flag controller to be re-initialized. - void reset(); + void update(double dt) override; - void setConstRoll(bool enable); + /// \brief Flag controller to be re-initialized. + void reset(); - private: + void setConstRoll(bool enable); - void initialize(); + private: + void initialize(); - void rotateHorizontal(double value); - void rotateVertical(double value); - void roll(double value); - void translate(const osg::Vec3d& offset); - void zoom(double value); + void rotateHorizontal(double value); + void rotateVertical(double value); + void roll(double value); + void translate(const osg::Vec3d& offset); + void zoom(double value); - bool mInitialized; - bool mNaviPrimary, mNaviSecondary; - bool mFast, mFastAlternate; - bool mLeft, mRight, mUp, mDown, mRollLeft, mRollRight; - unsigned int mPickingMask; - osg::Vec3d mCenter; - double mDistance; + bool mInitialized; + bool mNaviPrimary, mNaviSecondary; + bool mFast, mFastAlternate; + bool mLeft, mRight, mUp, mDown, mRollLeft, mRollRight; + unsigned int mPickingMask; + osg::Vec3d mCenter; + double mDistance; - double mOrbitSpeed; - double mOrbitSpeedMult; + double mOrbitSpeed; + double mOrbitSpeedMult; - bool mConstRoll; + bool mConstRoll; - private slots: + private slots: - void naviPrimary(bool active); - void naviSecondary(bool active); - void up(bool active); - void left(bool active); - void down(bool active); - void right(bool active); - void rollLeft(bool active); - void rollRight(bool active); - void alternateFast(bool active); - void swapSpeedMode(); + void naviPrimary(bool active); + void naviSecondary(bool active); + void up(bool active); + void left(bool active); + void down(bool active); + void right(bool active); + void rollLeft(bool active); + void rollRight(bool active); + void alternateFast(bool active); + void swapSpeedMode(); }; } diff --git a/apps/opencs/view/render/cell.cpp b/apps/opencs/view/render/cell.cpp index 7f8974ba6c..6b6544b56e 100644 --- a/apps/opencs/view/render/cell.cpp +++ b/apps/opencs/view/render/cell.cpp @@ -1,95 +1,94 @@ #include "cell.hpp" -#include #include +#include -#include #include #include +#include #include #include "../../model/world/idtable.hpp" -#include "cellwater.hpp" -#include "cellborder.hpp" #include "cellarrow.hpp" +#include "cellborder.hpp" #include "cellmarker.hpp" +#include "cellwater.hpp" +#include "instancedragmodes.hpp" #include "mask.hpp" +#include "object.hpp" #include "pathgrid.hpp" #include "terrainstorage.hpp" -#include "object.hpp" -#include "instancedragmodes.hpp" namespace CSVRender { class CellNodeContainer : public osg::Referenced { - public: - - CellNodeContainer(Cell* cell) : mCell(cell) {} - - Cell* getCell(){ return mCell; } + public: + CellNodeContainer(Cell* cell) + : mCell(cell) + { + } - private: + Cell* getCell() { return mCell; } - Cell* mCell; + private: + Cell* mCell; }; class CellNodeCallback : public osg::NodeCallback { - public: - - void operator()(osg::Node* node, osg::NodeVisitor* nv) override - { - traverse(node, nv); - CellNodeContainer* container = static_cast(node->getUserData()); - container->getCell()->updateLand(); - } + public: + void operator()(osg::Node* node, osg::NodeVisitor* nv) override + { + traverse(node, nv); + CellNodeContainer* container = static_cast(node->getUserData()); + container->getCell()->updateLand(); + } }; } -bool CSVRender::Cell::removeObject (const std::string& id) +bool CSVRender::Cell::removeObject(const std::string& id) { - std::map::iterator iter = - mObjects.find (Misc::StringUtils::lowerCase (id)); + std::map::iterator iter = mObjects.find(Misc::StringUtils::lowerCase(id)); - if (iter==mObjects.end()) + if (iter == mObjects.end()) return false; - removeObject (iter); + removeObject(iter); return true; } -std::map::iterator CSVRender::Cell::removeObject ( - std::map::iterator iter) +std::map::iterator CSVRender::Cell::removeObject( + std::map::iterator iter) { delete iter->second; - mObjects.erase (iter++); + mObjects.erase(iter++); return iter; } -bool CSVRender::Cell::addObjects (int start, int end) +bool CSVRender::Cell::addObjects(int start, int end) { bool modified = false; const CSMWorld::RefCollection& collection = mData.getReferences(); - for (int i=start; i<=end; ++i) + for (int i = start; i <= end; ++i) { - std::string cell = Misc::StringUtils::lowerCase (collection.getRecord (i).get().mCell); + std::string cell = Misc::StringUtils::lowerCase(collection.getRecord(i).get().mCell); - CSMWorld::RecordBase::State state = collection.getRecord (i).mState; + CSMWorld::RecordBase::State state = collection.getRecord(i).mState; - if (cell==mId && state!=CSMWorld::RecordBase::State_Deleted) + if (cell == mId && state != CSMWorld::RecordBase::State_Deleted) { - std::string id = Misc::StringUtils::lowerCase (collection.getRecord (i).get().mId); + std::string id = Misc::StringUtils::lowerCase(collection.getRecord(i).get().mId); auto object = std::make_unique(mData, mCellNode, id, false); if (mSubModeElementMask & Mask_Reference) - object->setSubMode (mSubMode); + object->setSubMode(mSubMode); - mObjects.insert (std::make_pair (id, object.release())); + mObjects.insert(std::make_pair(id, object.release())); modified = true; } } @@ -118,7 +117,7 @@ void CSVRender::Cell::updateLand() { const ESM::Land& esmLand = land.getRecord(mId).get(); - if (esmLand.getLandData (ESM::Land::DATA_VHGT)) + if (esmLand.getLandData(ESM::Land::DATA_VHGT)) { if (mTerrain) { @@ -127,8 +126,8 @@ void CSVRender::Cell::updateLand() } else { - mTerrain = std::make_unique(mCellNode, mCellNode, - mData.getResourceSystem().get(), mTerrainStorage, Mask_Terrain); + mTerrain = std::make_unique( + mCellNode, mCellNode, mData.getResourceSystem().get(), mTerrainStorage, Mask_Terrain); } mTerrain->loadCell(esmLand.mX, esmLand.mY); @@ -146,7 +145,7 @@ void CSVRender::Cell::updateLand() unloadLand(); } -void CSVRender::Cell::unloadLand() +void CSVRender::Cell::unloadLand() { if (mTerrain) mTerrain->unloadCell(mCoordinates.getX(), mCoordinates.getY()); @@ -155,12 +154,16 @@ void CSVRender::Cell::unloadLand() mCellBorder.reset(); } -CSVRender::Cell::Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::string& id, - bool deleted) -: mData (data), mId (Misc::StringUtils::lowerCase (id)), mDeleted (deleted), mSubMode (0), - mSubModeElementMask (0), mUpdateLand(true), mLandDeleted(false) +CSVRender::Cell::Cell(CSMWorld::Data& data, osg::Group* rootNode, const std::string& id, bool deleted) + : mData(data) + , mId(Misc::StringUtils::lowerCase(id)) + , mDeleted(deleted) + , mSubMode(0) + , mSubModeElementMask(0) + , mUpdateLand(true) + , mLandDeleted(false) { - std::pair result = CSMWorld::CellCoordinates::fromId (id); + std::pair result = CSMWorld::CellCoordinates::fromId(id); mTerrainStorage = new TerrainStorage(mData); @@ -176,12 +179,12 @@ CSVRender::Cell::Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::st if (!mDeleted) { - CSMWorld::IdTable& references = dynamic_cast ( - *mData.getTableModel (CSMWorld::UniversalId::Type_References)); + CSMWorld::IdTable& references + = dynamic_cast(*mData.getTableModel(CSMWorld::UniversalId::Type_References)); int rows = references.rowCount(); - addObjects (0, rows-1); + addObjects(0, rows - 1); updateLand(); @@ -192,8 +195,7 @@ CSVRender::Cell::Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::st CSVRender::Cell::~Cell() { - for (std::map::iterator iter (mObjects.begin()); - iter!=mObjects.end(); ++iter) + for (std::map::iterator iter(mObjects.begin()); iter != mObjects.end(); ++iter) delete iter->second; mCellNode->getParent(0)->removeChild(mCellNode); @@ -204,86 +206,81 @@ CSVRender::Pathgrid* CSVRender::Cell::getPathgrid() const return mPathgrid.get(); } -bool CSVRender::Cell::referenceableDataChanged (const QModelIndex& topLeft, - const QModelIndex& bottomRight) +bool CSVRender::Cell::referenceableDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) { bool modified = false; - for (std::map::iterator iter (mObjects.begin()); - iter!=mObjects.end(); ++iter) - if (iter->second->referenceableDataChanged (topLeft, bottomRight)) + for (std::map::iterator iter(mObjects.begin()); iter != mObjects.end(); ++iter) + if (iter->second->referenceableDataChanged(topLeft, bottomRight)) modified = true; return modified; } -bool CSVRender::Cell::referenceableAboutToBeRemoved (const QModelIndex& parent, int start, - int end) +bool CSVRender::Cell::referenceableAboutToBeRemoved(const QModelIndex& parent, int start, int end) { if (parent.isValid()) return false; bool modified = false; - for (std::map::iterator iter (mObjects.begin()); - iter!=mObjects.end(); ++iter) - if (iter->second->referenceableAboutToBeRemoved (parent, start, end)) + for (std::map::iterator iter(mObjects.begin()); iter != mObjects.end(); ++iter) + if (iter->second->referenceableAboutToBeRemoved(parent, start, end)) modified = true; return modified; } -bool CSVRender::Cell::referenceDataChanged (const QModelIndex& topLeft, - const QModelIndex& bottomRight) +bool CSVRender::Cell::referenceDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) { if (mDeleted) return false; - CSMWorld::IdTable& references = dynamic_cast ( - *mData.getTableModel (CSMWorld::UniversalId::Type_References)); + CSMWorld::IdTable& references + = dynamic_cast(*mData.getTableModel(CSMWorld::UniversalId::Type_References)); - int idColumn = references.findColumnIndex (CSMWorld::Columns::ColumnId_Id); - int cellColumn = references.findColumnIndex (CSMWorld::Columns::ColumnId_Cell); - int stateColumn = references.findColumnIndex (CSMWorld::Columns::ColumnId_Modification); + int idColumn = references.findColumnIndex(CSMWorld::Columns::ColumnId_Id); + int cellColumn = references.findColumnIndex(CSMWorld::Columns::ColumnId_Cell); + int stateColumn = references.findColumnIndex(CSMWorld::Columns::ColumnId_Modification); // list IDs in cell std::map ids; // id, deleted state - for (int i=topLeft.row(); i<=bottomRight.row(); ++i) + for (int i = topLeft.row(); i <= bottomRight.row(); ++i) { - std::string cell = Misc::StringUtils::lowerCase (references.data ( - references.index (i, cellColumn)).toString().toUtf8().constData()); + std::string cell = Misc::StringUtils::lowerCase( + references.data(references.index(i, cellColumn)).toString().toUtf8().constData()); - if (cell==mId) + if (cell == mId) { - std::string id = Misc::StringUtils::lowerCase (references.data ( - references.index (i, idColumn)).toString().toUtf8().constData()); + std::string id = Misc::StringUtils::lowerCase( + references.data(references.index(i, idColumn)).toString().toUtf8().constData()); - int state = references.data (references.index (i, stateColumn)).toInt(); + int state = references.data(references.index(i, stateColumn)).toInt(); - ids.insert (std::make_pair (id, state==CSMWorld::RecordBase::State_Deleted)); + ids.insert(std::make_pair(id, state == CSMWorld::RecordBase::State_Deleted)); } } // perform update and remove where needed bool modified = false; - std::map::iterator iter = mObjects.begin(); - while (iter!=mObjects.end()) + std::map::iterator iter = mObjects.begin(); + while (iter != mObjects.end()) { - if (iter->second->referenceDataChanged (topLeft, bottomRight)) + if (iter->second->referenceDataChanged(topLeft, bottomRight)) modified = true; - std::map::iterator iter2 = ids.find (iter->first); + std::map::iterator iter2 = ids.find(iter->first); - if (iter2!=ids.end()) + if (iter2 != ids.end()) { bool deleted = iter2->second; - ids.erase (iter2); + ids.erase(iter2); if (deleted) { - iter = removeObject (iter); + iter = removeObject(iter); modified = true; continue; } @@ -293,12 +290,11 @@ bool CSVRender::Cell::referenceDataChanged (const QModelIndex& topLeft, } // add new objects - for (std::map::iterator mapIter (ids.begin()); mapIter!=ids.end(); ++mapIter) + for (std::map::iterator mapIter(ids.begin()); mapIter != ids.end(); ++mapIter) { if (!mapIter->second) { - mObjects.insert (std::make_pair ( - mapIter->first, new Object (mData, mCellNode, mapIter->first, false))); + mObjects.insert(std::make_pair(mapIter->first, new Object(mData, mCellNode, mapIter->first, false))); modified = true; } @@ -307,8 +303,7 @@ bool CSVRender::Cell::referenceDataChanged (const QModelIndex& topLeft, return modified; } -bool CSVRender::Cell::referenceAboutToBeRemoved (const QModelIndex& parent, int start, - int end) +bool CSVRender::Cell::referenceAboutToBeRemoved(const QModelIndex& parent, int start, int end) { if (parent.isValid()) return false; @@ -316,22 +311,21 @@ bool CSVRender::Cell::referenceAboutToBeRemoved (const QModelIndex& parent, int if (mDeleted) return false; - CSMWorld::IdTable& references = dynamic_cast ( - *mData.getTableModel (CSMWorld::UniversalId::Type_References)); + CSMWorld::IdTable& references + = dynamic_cast(*mData.getTableModel(CSMWorld::UniversalId::Type_References)); - int idColumn = references.findColumnIndex (CSMWorld::Columns::ColumnId_Id); + int idColumn = references.findColumnIndex(CSMWorld::Columns::ColumnId_Id); bool modified = false; - for (int row = start; row<=end; ++row) - if (removeObject (references.data ( - references.index (row, idColumn)).toString().toUtf8().constData())) + for (int row = start; row <= end; ++row) + if (removeObject(references.data(references.index(row, idColumn)).toString().toUtf8().constData())) modified = true; return modified; } -bool CSVRender::Cell::referenceAdded (const QModelIndex& parent, int start, int end) +bool CSVRender::Cell::referenceAdded(const QModelIndex& parent, int start, int end) { if (parent.isValid()) return false; @@ -339,7 +333,7 @@ bool CSVRender::Cell::referenceAdded (const QModelIndex& parent, int start, int if (mDeleted) return false; - return addObjects (start, end); + return addObjects(start, end); } void CSVRender::Cell::setAlteredHeight(int inCellX, int inCellY, float height) @@ -376,42 +370,41 @@ void CSVRender::Cell::pathgridRemoved() mPathgrid->removeGeometry(); } -void CSVRender::Cell::landDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) +void CSVRender::Cell::landDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) { mUpdateLand = true; } -void CSVRender::Cell::landAboutToBeRemoved (const QModelIndex& parent, int start, int end) +void CSVRender::Cell::landAboutToBeRemoved(const QModelIndex& parent, int start, int end) { mLandDeleted = true; unloadLand(); } -void CSVRender::Cell::landAdded (const QModelIndex& parent, int start, int end) +void CSVRender::Cell::landAdded(const QModelIndex& parent, int start, int end) { mUpdateLand = true; mLandDeleted = false; } -void CSVRender::Cell::landTextureChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) +void CSVRender::Cell::landTextureChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) { mUpdateLand = true; } -void CSVRender::Cell::landTextureAboutToBeRemoved (const QModelIndex& parent, int start, int end) +void CSVRender::Cell::landTextureAboutToBeRemoved(const QModelIndex& parent, int start, int end) { mUpdateLand = true; } -void CSVRender::Cell::landTextureAdded (const QModelIndex& parent, int start, int end) +void CSVRender::Cell::landTextureAdded(const QModelIndex& parent, int start, int end) { mUpdateLand = true; } void CSVRender::Cell::reloadAssets() { - for (std::map::const_iterator iter (mObjects.begin()); - iter != mObjects.end(); ++iter) + for (std::map::const_iterator iter(mObjects.begin()); iter != mObjects.end(); ++iter) { iter->second->reloadAssets(); } @@ -426,23 +419,28 @@ void CSVRender::Cell::reloadAssets() mCellWater->reloadAssets(); } -void CSVRender::Cell::setSelection (int elementMask, Selection mode) +void CSVRender::Cell::setSelection(int elementMask, Selection mode) { if (elementMask & Mask_Reference) { - for (std::map::const_iterator iter (mObjects.begin()); - iter!=mObjects.end(); ++iter) + for (std::map::const_iterator iter(mObjects.begin()); iter != mObjects.end(); ++iter) { bool selected = false; switch (mode) { - case Selection_Clear: selected = false; break; - case Selection_All: selected = true; break; - case Selection_Invert: selected = !iter->second->getSelected(); break; + case Selection_Clear: + selected = false; + break; + case Selection_All: + selected = true; + break; + case Selection_Invert: + selected = !iter->second->getSelected(); + break; } - iter->second->setSelected (selected); + iter->second->setSelected(selected); } } if (mPathgrid && elementMask & Mask_Pathgrid) @@ -468,24 +466,21 @@ void CSVRender::Cell::setSelection (int elementMask, Selection mode) } } -void CSVRender::Cell::selectAllWithSameParentId (int elementMask) +void CSVRender::Cell::selectAllWithSameParentId(int elementMask) { std::set ids; - for (std::map::const_iterator iter (mObjects.begin()); - iter!=mObjects.end(); ++iter) + for (std::map::const_iterator iter(mObjects.begin()); iter != mObjects.end(); ++iter) { if (iter->second->getSelected()) - ids.insert (iter->second->getReferenceableId()); + ids.insert(iter->second->getReferenceableId()); } - for (std::map::const_iterator iter (mObjects.begin()); - iter!=mObjects.end(); ++iter) + for (std::map::const_iterator iter(mObjects.begin()); iter != mObjects.end(); ++iter) { - if (!iter->second->getSelected() && - ids.find (iter->second->getReferenceableId())!=ids.end()) + if (!iter->second->getSelected() && ids.find(iter->second->getReferenceableId()) != ids.end()) { - iter->second->setSelected (true); + iter->second->setSelected(true); } } } @@ -499,26 +494,27 @@ void CSVRender::Cell::handleSelectDrag(Object* object, DragMode dragMode) object->setSelected(false); else if (dragMode == DragMode_Select_Invert) - object->setSelected (!object->getSelected()); + object->setSelected(!object->getSelected()); } void CSVRender::Cell::selectInsideCube(const osg::Vec3d& pointA, const osg::Vec3d& pointB, DragMode dragMode) { for (auto& object : mObjects) { - if (dragMode == DragMode_Select_Only) object.second->setSelected (false); + if (dragMode == DragMode_Select_Only) + object.second->setSelected(false); - if ( ( object.second->getPosition().pos[0] > pointA[0] && object.second->getPosition().pos[0] < pointB[0] ) || - ( object.second->getPosition().pos[0] > pointB[0] && object.second->getPosition().pos[0] < pointA[0] )) + if ((object.second->getPosition().pos[0] > pointA[0] && object.second->getPosition().pos[0] < pointB[0]) + || (object.second->getPosition().pos[0] > pointB[0] && object.second->getPosition().pos[0] < pointA[0])) { - if ( ( object.second->getPosition().pos[1] > pointA[1] && object.second->getPosition().pos[1] < pointB[1] ) || - ( object.second->getPosition().pos[1] > pointB[1] && object.second->getPosition().pos[1] < pointA[1] )) + if ((object.second->getPosition().pos[1] > pointA[1] && object.second->getPosition().pos[1] < pointB[1]) + || (object.second->getPosition().pos[1] > pointB[1] && object.second->getPosition().pos[1] < pointA[1])) { - if ( ( object.second->getPosition().pos[2] > pointA[2] && object.second->getPosition().pos[2] < pointB[2] ) || - ( object.second->getPosition().pos[2] > pointB[2] && object.second->getPosition().pos[2] < pointA[2] )) + if ((object.second->getPosition().pos[2] > pointA[2] && object.second->getPosition().pos[2] < pointB[2]) + || (object.second->getPosition().pos[2] > pointB[2] + && object.second->getPosition().pos[2] < pointA[2])) handleSelectDrag(object.second, dragMode); } - } } } @@ -527,27 +523,29 @@ void CSVRender::Cell::selectWithinDistance(const osg::Vec3d& point, float distan { for (auto& object : mObjects) { - if (dragMode == DragMode_Select_Only) object.second->setSelected (false); + if (dragMode == DragMode_Select_Only) + object.second->setSelected(false); float distanceFromObject = (point - object.second->getPosition().asVec3()).length(); - if (distanceFromObject < distance) handleSelectDrag(object.second, dragMode); + if (distanceFromObject < distance) + handleSelectDrag(object.second, dragMode); } } -void CSVRender::Cell::setCellArrows (int mask) +void CSVRender::Cell::setCellArrows(int mask) { - for (int i=0; i<4; ++i) + for (int i = 0; i < 4; ++i) { - CellArrow::Direction direction = static_cast (1<(1 << i); bool enable = mask & direction; - if (enable!=(mCellArrows[i].get()!=nullptr)) + if (enable != (mCellArrows[i].get() != nullptr)) { if (enable) mCellArrows[i] = std::make_unique(mCellNode, direction, mCoordinates); else - mCellArrows[i].reset (nullptr); + mCellArrows[i].reset(nullptr); } } } @@ -565,7 +563,8 @@ void CSVRender::Cell::setCellMarker() isInteriorCell = cellRecord.get().mData.mFlags & ESM::Cell::Interior; } - if (!isInteriorCell) { + if (!isInteriorCell) + { mCellMarker = std::make_unique(mCellNode, mCoordinates, cellExists); } } @@ -580,15 +579,14 @@ bool CSVRender::Cell::isDeleted() const return mDeleted; } -std::vector > CSVRender::Cell::getSelection (unsigned int elementMask) const +std::vector> CSVRender::Cell::getSelection(unsigned int elementMask) const { - std::vector > result; + std::vector> result; if (elementMask & Mask_Reference) - for (std::map::const_iterator iter (mObjects.begin()); - iter!=mObjects.end(); ++iter) + for (std::map::const_iterator iter(mObjects.begin()); iter != mObjects.end(); ++iter) if (iter->second->getSelected()) - result.push_back (iter->second->getTag()); + result.push_back(iter->second->getTag()); if (mPathgrid && elementMask & Mask_Pathgrid) if (mPathgrid->isSelected()) result.emplace_back(mPathgrid->getTag()); @@ -596,35 +594,32 @@ std::vector > CSVRender::Cell::getSelection (un return result; } -std::vector > CSVRender::Cell::getEdited (unsigned int elementMask) const +std::vector> CSVRender::Cell::getEdited(unsigned int elementMask) const { - std::vector > result; + std::vector> result; if (elementMask & Mask_Reference) - for (std::map::const_iterator iter (mObjects.begin()); - iter!=mObjects.end(); ++iter) + for (std::map::const_iterator iter(mObjects.begin()); iter != mObjects.end(); ++iter) if (iter->second->isEdited()) - result.push_back (iter->second->getTag()); + result.push_back(iter->second->getTag()); return result; } -void CSVRender::Cell::setSubMode (int subMode, unsigned int elementMask) +void CSVRender::Cell::setSubMode(int subMode, unsigned int elementMask) { mSubMode = subMode; mSubModeElementMask = elementMask; if (elementMask & Mask_Reference) - for (std::map::const_iterator iter (mObjects.begin()); - iter!=mObjects.end(); ++iter) - iter->second->setSubMode (subMode); + for (std::map::const_iterator iter(mObjects.begin()); iter != mObjects.end(); ++iter) + iter->second->setSubMode(subMode); } -void CSVRender::Cell::reset (unsigned int elementMask) +void CSVRender::Cell::reset(unsigned int elementMask) { if (elementMask & Mask_Reference) - for (std::map::const_iterator iter (mObjects.begin()); - iter!=mObjects.end(); ++iter) + for (std::map::const_iterator iter(mObjects.begin()); iter != mObjects.end(); ++iter) iter->second->reset(); if (mPathgrid && elementMask & Mask_Pathgrid) mPathgrid->resetIndicators(); diff --git a/apps/opencs/view/render/cell.hpp b/apps/opencs/view/render/cell.hpp index 12f6f0ccdb..42f61c0956 100644 --- a/apps/opencs/view/render/cell.hpp +++ b/apps/opencs/view/render/cell.hpp @@ -1,16 +1,16 @@ #ifndef OPENCS_VIEW_CELL_H #define OPENCS_VIEW_CELL_H -#include #include #include +#include #include #include #include "../../model/world/cellcoordinates.hpp" -#include "terrainstorage.hpp" #include "instancedragmodes.hpp" +#include "terrainstorage.hpp" class QModelIndex; @@ -44,141 +44,136 @@ namespace CSVRender class Cell { - CSMWorld::Data& mData; - std::string mId; - osg::ref_ptr mCellNode; - std::map mObjects; - std::unique_ptr mTerrain; - CSMWorld::CellCoordinates mCoordinates; - std::unique_ptr mCellArrows[4]; - std::unique_ptr mCellMarker; - std::unique_ptr mCellBorder; - std::unique_ptr mCellWater; - std::unique_ptr mPathgrid; - bool mDeleted; - int mSubMode; - unsigned int mSubModeElementMask; - bool mUpdateLand, mLandDeleted; - TerrainStorage *mTerrainStorage; - - /// Ignored if cell does not have an object with the given ID. - /// - /// \return Was the object deleted? - bool removeObject (const std::string& id); - - // Remove object and return iterator to next object. - std::map::iterator removeObject ( - std::map::iterator iter); + CSMWorld::Data& mData; + std::string mId; + osg::ref_ptr mCellNode; + std::map mObjects; + std::unique_ptr mTerrain; + CSMWorld::CellCoordinates mCoordinates; + std::unique_ptr mCellArrows[4]; + std::unique_ptr mCellMarker; + std::unique_ptr mCellBorder; + std::unique_ptr mCellWater; + std::unique_ptr mPathgrid; + bool mDeleted; + int mSubMode; + unsigned int mSubModeElementMask; + bool mUpdateLand, mLandDeleted; + TerrainStorage* mTerrainStorage; - /// Add objects from reference table that are within this cell. - /// - /// \return Have any objects been added? - bool addObjects (int start, int end); + /// Ignored if cell does not have an object with the given ID. + /// + /// \return Was the object deleted? + bool removeObject(const std::string& id); - void updateLand(); - void unloadLand(); + // Remove object and return iterator to next object. + std::map::iterator removeObject(std::map::iterator iter); - public: + /// Add objects from reference table that are within this cell. + /// + /// \return Have any objects been added? + bool addObjects(int start, int end); - enum Selection - { - Selection_Clear, - Selection_All, - Selection_Invert - }; + void updateLand(); + void unloadLand(); - public: + public: + enum Selection + { + Selection_Clear, + Selection_All, + Selection_Invert + }; - /// \note Deleted covers both cells that are deleted and cells that don't exist in - /// the first place. - Cell (CSMWorld::Data& data, osg::Group* rootNode, const std::string& id, - bool deleted = false); + public: + /// \note Deleted covers both cells that are deleted and cells that don't exist in + /// the first place. + Cell(CSMWorld::Data& data, osg::Group* rootNode, const std::string& id, bool deleted = false); - ~Cell(); + ~Cell(); - /// \note Returns the pathgrid representation which will exist as long as the cell exists - Pathgrid* getPathgrid() const; + /// \note Returns the pathgrid representation which will exist as long as the cell exists + Pathgrid* getPathgrid() const; - /// \return Did this call result in a modification of the visual representation of - /// this cell? - bool referenceableDataChanged (const QModelIndex& topLeft, - const QModelIndex& bottomRight); + /// \return Did this call result in a modification of the visual representation of + /// this cell? + bool referenceableDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); - /// \return Did this call result in a modification of the visual representation of - /// this cell? - bool referenceableAboutToBeRemoved (const QModelIndex& parent, int start, int end); + /// \return Did this call result in a modification of the visual representation of + /// this cell? + bool referenceableAboutToBeRemoved(const QModelIndex& parent, int start, int end); - /// \return Did this call result in a modification of the visual representation of - /// this cell? - bool referenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); + /// \return Did this call result in a modification of the visual representation of + /// this cell? + bool referenceDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); - /// \return Did this call result in a modification of the visual representation of - /// this cell? - bool referenceAboutToBeRemoved (const QModelIndex& parent, int start, int end); + /// \return Did this call result in a modification of the visual representation of + /// this cell? + bool referenceAboutToBeRemoved(const QModelIndex& parent, int start, int end); - /// \return Did this call result in a modification of the visual representation of - /// this cell? - bool referenceAdded (const QModelIndex& parent, int start, int end); + /// \return Did this call result in a modification of the visual representation of + /// this cell? + bool referenceAdded(const QModelIndex& parent, int start, int end); - void setAlteredHeight(int inCellX, int inCellY, float height); + void setAlteredHeight(int inCellX, int inCellY, float height); - float getSumOfAlteredAndTrueHeight(int cellX, int cellY, int inCellX, int inCellY); + float getSumOfAlteredAndTrueHeight(int cellX, int cellY, int inCellX, int inCellY); - float* getAlteredHeight(int inCellX, int inCellY); + float* getAlteredHeight(int inCellX, int inCellY); - void resetAlteredHeights(); + void resetAlteredHeights(); - void pathgridModified(); + void pathgridModified(); - void pathgridRemoved(); + void pathgridRemoved(); - void landDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); + void landDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); - void landAboutToBeRemoved (const QModelIndex& parent, int start, int end); + void landAboutToBeRemoved(const QModelIndex& parent, int start, int end); - void landAdded (const QModelIndex& parent, int start, int end); + void landAdded(const QModelIndex& parent, int start, int end); - void landTextureChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); + void landTextureChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); - void landTextureAboutToBeRemoved (const QModelIndex& parent, int start, int end); + void landTextureAboutToBeRemoved(const QModelIndex& parent, int start, int end); - void landTextureAdded (const QModelIndex& parent, int start, int end); + void landTextureAdded(const QModelIndex& parent, int start, int end); - void reloadAssets(); + void reloadAssets(); - void setSelection (int elementMask, Selection mode); + void setSelection(int elementMask, Selection mode); - // Select everything that references the same ID as at least one of the elements - // already selected - void selectAllWithSameParentId (int elementMask); + // Select everything that references the same ID as at least one of the elements + // already selected + void selectAllWithSameParentId(int elementMask); - void handleSelectDrag(Object* object, DragMode dragMode); + void handleSelectDrag(Object* object, DragMode dragMode); - void selectInsideCube(const osg::Vec3d& pointA, const osg::Vec3d& pointB, DragMode dragMode); + void selectInsideCube(const osg::Vec3d& pointA, const osg::Vec3d& pointB, DragMode dragMode); - void selectWithinDistance(const osg::Vec3d& pointA, float distance, DragMode dragMode); + void selectWithinDistance(const osg::Vec3d& pointA, float distance, DragMode dragMode); - void setCellArrows (int mask); + void setCellArrows(int mask); - /// \brief Set marker for this cell. - void setCellMarker(); + /// \brief Set marker for this cell. + void setCellMarker(); - /// Returns 0, 0 in case of an unpaged cell. - CSMWorld::CellCoordinates getCoordinates() const; + /// Returns 0, 0 in case of an unpaged cell. + CSMWorld::CellCoordinates getCoordinates() const; - bool isDeleted() const; + bool isDeleted() const; - std::vector > getSelection (unsigned int elementMask) const; + std::vector> getSelection(unsigned int elementMask) const; - std::vector > getEdited (unsigned int elementMask) const; + std::vector> getEdited(unsigned int elementMask) const; - void setSubMode (int subMode, unsigned int elementMask); + void setSubMode(int subMode, unsigned int elementMask); - /// Erase all overrides and restore the visual representation of the cell to its - /// true state. - void reset (unsigned int elementMask); + /// Erase all overrides and restore the visual representation of the cell to its + /// true state. + void reset(unsigned int elementMask); - friend class CellNodeCallback; + friend class CellNodeCallback; }; } diff --git a/apps/opencs/view/render/cellarrow.cpp b/apps/opencs/view/render/cellarrow.cpp index 9ad4932698..62549a301b 100644 --- a/apps/opencs/view/render/cellarrow.cpp +++ b/apps/opencs/view/render/cellarrow.cpp @@ -1,8 +1,8 @@ #include "cellarrow.hpp" +#include #include #include -#include #include #include "../../model/prefs/state.hpp" @@ -11,25 +11,35 @@ #include "mask.hpp" -CSVRender::CellArrowTag::CellArrowTag (CellArrow *arrow) -: TagBase (Mask_CellArrow), mArrow (arrow) -{} +CSVRender::CellArrowTag::CellArrowTag(CellArrow* arrow) + : TagBase(Mask_CellArrow) + , mArrow(arrow) +{ +} -CSVRender::CellArrow *CSVRender::CellArrowTag::getCellArrow() const +CSVRender::CellArrow* CSVRender::CellArrowTag::getCellArrow() const { return mArrow; } QString CSVRender::CellArrowTag::getToolTip(bool hideBasics, const WorldspaceHitResult& /*hit*/) const { - QString text ("Direction: "); + QString text("Direction: "); switch (mArrow->getDirection()) { - case CellArrow::Direction_North: text += "North"; break; - case CellArrow::Direction_West: text += "West"; break; - case CellArrow::Direction_South: text += "South"; break; - case CellArrow::Direction_East: text += "East"; break; + case CellArrow::Direction_North: + text += "North"; + break; + case CellArrow::Direction_West: + text += "West"; + break; + case CellArrow::Direction_South: + text += "South"; + break; + case CellArrow::Direction_East: + text += "East"; + break; } if (!hideBasics) @@ -52,124 +62,138 @@ QString CSVRender::CellArrowTag::getToolTip(bool hideBasics, const WorldspaceHit return CSMPrefs::State::get().getShortcutManager().processToolTip(text); } - void CSVRender::CellArrow::adjustTransform() { // position const int cellSize = Constants::CellSizeInUnits; const int offset = cellSize / 2 + 600; - int x = mCoordinates.getX()*cellSize + cellSize/2; - int y = mCoordinates.getY()*cellSize + cellSize/2; + int x = mCoordinates.getX() * cellSize + cellSize / 2; + int y = mCoordinates.getY() * cellSize + cellSize / 2; float xr = 0; float yr = 0; float zr = 0; - float angle = osg::DegreesToRadians (90.0f); + float angle = osg::DegreesToRadians(90.0f); switch (mDirection) { - case Direction_North: y += offset; xr = -angle; zr = angle; break; - case Direction_West: x -= offset; yr = -angle; break; - case Direction_South: y -= offset; xr = angle; zr = angle; break; - case Direction_East: x += offset; yr = angle; break; + case Direction_North: + y += offset; + xr = -angle; + zr = angle; + break; + case Direction_West: + x -= offset; + yr = -angle; + break; + case Direction_South: + y -= offset; + xr = angle; + zr = angle; + break; + case Direction_East: + x += offset; + yr = angle; + break; }; - mBaseNode->setPosition (osg::Vec3f (x, y, 0)); + mBaseNode->setPosition(osg::Vec3f(x, y, 0)); // orientation - osg::Quat xr2 (xr, osg::Vec3f (1,0,0)); - osg::Quat yr2 (yr, osg::Vec3f (0,1,0)); - osg::Quat zr2 (zr, osg::Vec3f (0,0,1)); - mBaseNode->setAttitude (zr2*yr2*xr2); + osg::Quat xr2(xr, osg::Vec3f(1, 0, 0)); + osg::Quat yr2(yr, osg::Vec3f(0, 1, 0)); + osg::Quat zr2(zr, osg::Vec3f(0, 0, 1)); + mBaseNode->setAttitude(zr2 * yr2 * xr2); } void CSVRender::CellArrow::buildShape() { - osg::ref_ptr geometry (new osg::Geometry); + osg::ref_ptr geometry(new osg::Geometry); const int arrowWidth = 2700; const int arrowLength = 1350; const int arrowHeight = 300; - osg::Vec3Array *vertices = new osg::Vec3Array; - for (int i2=0; i2<2; ++i2) - for (int i=0; i<2; ++i) + osg::Vec3Array* vertices = new osg::Vec3Array; + for (int i2 = 0; i2 < 2; ++i2) + for (int i = 0; i < 2; ++i) { - float height = i ? -arrowHeight/2 : arrowHeight/2; - vertices->push_back (osg::Vec3f (height, -arrowWidth/2, 0)); - vertices->push_back (osg::Vec3f (height, arrowWidth/2, 0)); - vertices->push_back (osg::Vec3f (height, 0, arrowLength)); + float height = i ? -arrowHeight / 2 : arrowHeight / 2; + vertices->push_back(osg::Vec3f(height, -arrowWidth / 2, 0)); + vertices->push_back(osg::Vec3f(height, arrowWidth / 2, 0)); + vertices->push_back(osg::Vec3f(height, 0, arrowLength)); } - geometry->setVertexArray (vertices); + geometry->setVertexArray(vertices); - osg::DrawElementsUShort *primitives = new osg::DrawElementsUShort (osg::PrimitiveSet::TRIANGLES, 0); + osg::DrawElementsUShort* primitives = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES, 0); // top - primitives->push_back (0); - primitives->push_back (1); - primitives->push_back (2); + primitives->push_back(0); + primitives->push_back(1); + primitives->push_back(2); // bottom - primitives->push_back (5); - primitives->push_back (4); - primitives->push_back (3); + primitives->push_back(5); + primitives->push_back(4); + primitives->push_back(3); // back - primitives->push_back (3+6); - primitives->push_back (4+6); - primitives->push_back (1+6); + primitives->push_back(3 + 6); + primitives->push_back(4 + 6); + primitives->push_back(1 + 6); - primitives->push_back (3+6); - primitives->push_back (1+6); - primitives->push_back (0+6); + primitives->push_back(3 + 6); + primitives->push_back(1 + 6); + primitives->push_back(0 + 6); // sides - primitives->push_back (0+6); - primitives->push_back (2+6); - primitives->push_back (5+6); + primitives->push_back(0 + 6); + primitives->push_back(2 + 6); + primitives->push_back(5 + 6); - primitives->push_back (0+6); - primitives->push_back (5+6); - primitives->push_back (3+6); + primitives->push_back(0 + 6); + primitives->push_back(5 + 6); + primitives->push_back(3 + 6); - primitives->push_back (4+6); - primitives->push_back (5+6); - primitives->push_back (2+6); + primitives->push_back(4 + 6); + primitives->push_back(5 + 6); + primitives->push_back(2 + 6); - primitives->push_back (4+6); - primitives->push_back (2+6); - primitives->push_back (1+6); + primitives->push_back(4 + 6); + primitives->push_back(2 + 6); + primitives->push_back(1 + 6); - geometry->addPrimitiveSet (primitives); + geometry->addPrimitiveSet(primitives); - osg::Vec4Array *colours = new osg::Vec4Array; + osg::Vec4Array* colours = new osg::Vec4Array; - for (int i=0; i<6; ++i) - colours->push_back (osg::Vec4f (0.11f, 0.6f, 0.95f, 1.0f)); - for (int i=0; i<6; ++i) - colours->push_back (osg::Vec4f (0.08f, 0.44f, 0.7f, 1.0f)); + for (int i = 0; i < 6; ++i) + colours->push_back(osg::Vec4f(0.11f, 0.6f, 0.95f, 1.0f)); + for (int i = 0; i < 6; ++i) + colours->push_back(osg::Vec4f(0.08f, 0.44f, 0.7f, 1.0f)); - geometry->setColorArray (colours, osg::Array::BIND_PER_VERTEX); + geometry->setColorArray(colours, osg::Array::BIND_PER_VERTEX); - geometry->getOrCreateStateSet()->setMode (GL_LIGHTING, osg::StateAttribute::OFF); + geometry->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); - mBaseNode->addChild (geometry); + mBaseNode->addChild(geometry); } -CSVRender::CellArrow::CellArrow (osg::Group *cellNode, Direction direction, - const CSMWorld::CellCoordinates& coordinates) -: mDirection (direction), mParentNode (cellNode), mCoordinates (coordinates) +CSVRender::CellArrow::CellArrow(osg::Group* cellNode, Direction direction, const CSMWorld::CellCoordinates& coordinates) + : mDirection(direction) + , mParentNode(cellNode) + , mCoordinates(coordinates) { mBaseNode = new osg::PositionAttitudeTransform; - mBaseNode->setUserData (new CellArrowTag (this)); + mBaseNode->setUserData(new CellArrowTag(this)); - mParentNode->addChild (mBaseNode); + mParentNode->addChild(mBaseNode); - mBaseNode->setNodeMask (Mask_CellArrow); + mBaseNode->setNodeMask(Mask_CellArrow); adjustTransform(); buildShape(); @@ -177,7 +201,7 @@ CSVRender::CellArrow::CellArrow (osg::Group *cellNode, Direction direction, CSVRender::CellArrow::~CellArrow() { - mParentNode->removeChild (mBaseNode); + mParentNode->removeChild(mBaseNode); } CSMWorld::CellCoordinates CSVRender::CellArrow::getCoordinates() const diff --git a/apps/opencs/view/render/cellarrow.hpp b/apps/opencs/view/render/cellarrow.hpp index ed71410610..9bf66bdcd8 100644 --- a/apps/opencs/view/render/cellarrow.hpp +++ b/apps/opencs/view/render/cellarrow.hpp @@ -19,55 +19,49 @@ namespace CSVRender class CellArrowTag : public TagBase { - CellArrow *mArrow; + CellArrow* mArrow; - public: + public: + CellArrowTag(CellArrow* arrow); - CellArrowTag (CellArrow *arrow); + CellArrow* getCellArrow() const; - CellArrow *getCellArrow() const; - - QString getToolTip(bool hideBasics, const WorldspaceHitResult& hit) const override; + QString getToolTip(bool hideBasics, const WorldspaceHitResult& hit) const override; }; - class CellArrow { - public: - - enum Direction - { - Direction_North = 1, - Direction_West = 2, - Direction_South = 4, - Direction_East = 8 - }; - - private: - - // not implemented - CellArrow (const CellArrow&); - CellArrow& operator= (const CellArrow&); + public: + enum Direction + { + Direction_North = 1, + Direction_West = 2, + Direction_South = 4, + Direction_East = 8 + }; - Direction mDirection; - osg::Group* mParentNode; - osg::ref_ptr mBaseNode; - CSMWorld::CellCoordinates mCoordinates; + private: + // not implemented + CellArrow(const CellArrow&); + CellArrow& operator=(const CellArrow&); - void adjustTransform(); + Direction mDirection; + osg::Group* mParentNode; + osg::ref_ptr mBaseNode; + CSMWorld::CellCoordinates mCoordinates; - void buildShape(); + void adjustTransform(); - public: + void buildShape(); - CellArrow (osg::Group *cellNode, Direction direction, - const CSMWorld::CellCoordinates& coordinates); + public: + CellArrow(osg::Group* cellNode, Direction direction, const CSMWorld::CellCoordinates& coordinates); - ~CellArrow(); + ~CellArrow(); - CSMWorld::CellCoordinates getCoordinates() const; + CSMWorld::CellCoordinates getCoordinates() const; - Direction getDirection() const; + Direction getDirection() const; }; } diff --git a/apps/opencs/view/render/cellborder.cpp b/apps/opencs/view/render/cellborder.cpp index b93b5d1fcf..67154adee3 100644 --- a/apps/opencs/view/render/cellborder.cpp +++ b/apps/opencs/view/render/cellborder.cpp @@ -1,8 +1,8 @@ #include "cellborder.hpp" +#include #include #include -#include #include #include @@ -19,12 +19,11 @@ const int CSVRender::CellBorder::CellSize = ESM::Land::REAL_SIZE; */ const int CSVRender::CellBorder::VertexCount = (ESM::Land::LAND_SIZE * 4) - 4; - CSVRender::CellBorder::CellBorder(osg::Group* cellNode, const CSMWorld::CellCoordinates& coords) : mParentNode(cellNode) { mBorderGeometry = new osg::Geometry(); - + mBaseNode = new osg::PositionAttitudeTransform(); mBaseNode->setNodeMask(Mask_CellBorder); mBaseNode->setPosition(osg::Vec3f(coords.getX() * CellSize, coords.getY() * CellSize, 10)); @@ -79,8 +78,8 @@ void CSVRender::CellBorder::buildShape(const ESM::Land& esmLand) mBorderGeometry->setColorArray(colors, osg::Array::BIND_PER_PRIMITIVE_SET); - osg::ref_ptr primitives = - new osg::DrawElementsUShort(osg::PrimitiveSet::LINE_STRIP, VertexCount + 1); + osg::ref_ptr primitives + = new osg::DrawElementsUShort(osg::PrimitiveSet::LINE_STRIP, VertexCount + 1); // Assign one primitive to each vertex. for (size_t i = 0; i < VertexCount; ++i) diff --git a/apps/opencs/view/render/cellborder.hpp b/apps/opencs/view/render/cellborder.hpp index be2e18eeee..e1201a1f39 100644 --- a/apps/opencs/view/render/cellborder.hpp +++ b/apps/opencs/view/render/cellborder.hpp @@ -28,14 +28,12 @@ namespace CSVRender class CellBorder { public: - CellBorder(osg::Group* cellNode, const CSMWorld::CellCoordinates& coords); ~CellBorder(); void buildShape(const ESM::Land& esmLand); private: - static const int CellSize; static const int VertexCount; diff --git a/apps/opencs/view/render/cellmarker.cpp b/apps/opencs/view/render/cellmarker.cpp index ddd4f4caf3..692728a995 100644 --- a/apps/opencs/view/render/cellmarker.cpp +++ b/apps/opencs/view/render/cellmarker.cpp @@ -6,11 +6,13 @@ #include -CSVRender::CellMarkerTag::CellMarkerTag(CellMarker *marker) -: TagBase(Mask_CellMarker), mMarker(marker) -{} +CSVRender::CellMarkerTag::CellMarkerTag(CellMarker* marker) + : TagBase(Mask_CellMarker) + , mMarker(marker) +{ +} -CSVRender::CellMarker *CSVRender::CellMarkerTag::getCellMarker() const +CSVRender::CellMarker* CSVRender::CellMarkerTag::getCellMarker() const { return mMarker; } @@ -20,7 +22,7 @@ void CSVRender::CellMarker::buildMarker() const int characterSize = 20; // Set up attributes of marker text. - osg::ref_ptr markerText (new osgText::Text); + osg::ref_ptr markerText(new osgText::Text); markerText->setLayout(osgText::Text::LEFT_TO_RIGHT); markerText->setCharacterSize(characterSize); markerText->setAlignment(osgText::Text::CENTER_CENTER); @@ -37,9 +39,7 @@ void CSVRender::CellMarker::buildMarker() } // Add text containing cell's coordinates. - std::string coordinatesText = - std::to_string(mCoordinates.getX()) + "," + - std::to_string(mCoordinates.getY()); + std::string coordinatesText = std::to_string(mCoordinates.getX()) + "," + std::to_string(mCoordinates.getY()); markerText->setText(coordinatesText); // Add text to marker node. @@ -58,12 +58,10 @@ void CSVRender::CellMarker::positionMarker() } CSVRender::CellMarker::CellMarker( - osg::Group *cellNode, - const CSMWorld::CellCoordinates& coordinates, - const bool cellExists -) : mCellNode(cellNode), - mCoordinates(coordinates), - mExists(cellExists) + osg::Group* cellNode, const CSMWorld::CellCoordinates& coordinates, const bool cellExists) + : mCellNode(cellNode) + , mCoordinates(coordinates) + , mExists(cellExists) { // Set up node for cell marker. mMarkerNode = new osg::AutoTransform(); diff --git a/apps/opencs/view/render/cellmarker.hpp b/apps/opencs/view/render/cellmarker.hpp index 4246b20b8d..c623a29605 100644 --- a/apps/opencs/view/render/cellmarker.hpp +++ b/apps/opencs/view/render/cellmarker.hpp @@ -19,49 +19,42 @@ namespace CSVRender class CellMarkerTag : public TagBase { - private: + private: + CellMarker* mMarker; - CellMarker *mMarker; + public: + CellMarkerTag(CellMarker* marker); - public: - - CellMarkerTag(CellMarker *marker); - - CellMarker *getCellMarker() const; + CellMarker* getCellMarker() const; }; /// \brief Marker to display cell coordinates. class CellMarker { - private: - - osg::Group* mCellNode; - osg::ref_ptr mMarkerNode; - CSMWorld::CellCoordinates mCoordinates; - bool mExists; - - // Not implemented. - CellMarker(const CellMarker&); - CellMarker& operator=(const CellMarker&); - - /// \brief Build marker containing cell's coordinates. - void buildMarker(); - - /// \brief Position marker at center of cell. - void positionMarker(); - - public: - - /// \brief Constructor. - /// \param cellNode Cell to create marker for. - /// \param coordinates Coordinates of cell. - /// \param cellExists Whether or not cell exists. - CellMarker( - osg::Group *cellNode, - const CSMWorld::CellCoordinates& coordinates, - const bool cellExists); - - ~CellMarker(); + private: + osg::Group* mCellNode; + osg::ref_ptr mMarkerNode; + CSMWorld::CellCoordinates mCoordinates; + bool mExists; + + // Not implemented. + CellMarker(const CellMarker&); + CellMarker& operator=(const CellMarker&); + + /// \brief Build marker containing cell's coordinates. + void buildMarker(); + + /// \brief Position marker at center of cell. + void positionMarker(); + + public: + /// \brief Constructor. + /// \param cellNode Cell to create marker for. + /// \param coordinates Coordinates of cell. + /// \param cellExists Whether or not cell exists. + CellMarker(osg::Group* cellNode, const CSMWorld::CellCoordinates& coordinates, const bool cellExists); + + ~CellMarker(); }; } diff --git a/apps/opencs/view/render/cellwater.cpp b/apps/opencs/view/render/cellwater.cpp index 9681e5cdce..cb55e48daa 100644 --- a/apps/opencs/view/render/cellwater.cpp +++ b/apps/opencs/view/render/cellwater.cpp @@ -21,8 +21,8 @@ namespace CSVRender { const int CellWater::CellSize = ESM::Land::REAL_SIZE; - CellWater::CellWater(CSMWorld::Data& data, osg::Group* cellNode, const std::string& id, - const CSMWorld::CellCoordinates& cellCoords) + CellWater::CellWater( + CSMWorld::Data& data, osg::Group* cellNode, const std::string& id, const CSMWorld::CellCoordinates& cellCoords) : mData(data) , mId(id) , mParentNode(cellNode) @@ -34,8 +34,8 @@ namespace CSVRender , mHasWater(false) { mWaterTransform = new osg::PositionAttitudeTransform(); - mWaterTransform->setPosition(osg::Vec3f(cellCoords.getX() * CellSize + CellSize / 2.f, - cellCoords.getY() * CellSize + CellSize / 2.f, 0)); + mWaterTransform->setPosition(osg::Vec3f( + cellCoords.getX() * CellSize + CellSize / 2.f, cellCoords.getY() * CellSize + CellSize / 2.f, 0)); mWaterTransform->setNodeMask(Mask_Water); mParentNode->addChild(mWaterTransform); @@ -175,7 +175,6 @@ namespace CSVRender mWaterGeometry->getStateSet()->setTextureAttributeAndModes(0, waterTexture, osg::StateAttribute::ON); - mWaterGroup->addChild(mWaterGeometry); } } diff --git a/apps/opencs/view/render/cellwater.hpp b/apps/opencs/view/render/cellwater.hpp index be1786955b..8a965d743e 100644 --- a/apps/opencs/view/render/cellwater.hpp +++ b/apps/opencs/view/render/cellwater.hpp @@ -5,8 +5,8 @@ #include -#include #include +#include #include "../../model/world/record.hpp" @@ -30,41 +30,39 @@ namespace CSVRender /// adds a large patch of water much larger than the typical size of a cell. class CellWater : public QObject { - Q_OBJECT - - public: - - CellWater(CSMWorld::Data& data, osg::Group* cellNode, const std::string& id, - const CSMWorld::CellCoordinates& cellCoords); + Q_OBJECT - ~CellWater(); + public: + CellWater(CSMWorld::Data& data, osg::Group* cellNode, const std::string& id, + const CSMWorld::CellCoordinates& cellCoords); - void updateCellData(const CSMWorld::Record& cellRecord); + ~CellWater(); - void reloadAssets(); + void updateCellData(const CSMWorld::Record& cellRecord); - private slots: + void reloadAssets(); - void cellDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); + private slots: - private: + void cellDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); - void recreate(); + private: + void recreate(); - static const int CellSize; + static const int CellSize; - CSMWorld::Data& mData; - std::string mId; + CSMWorld::Data& mData; + std::string mId; - osg::Group* mParentNode; + osg::Group* mParentNode; - osg::ref_ptr mWaterTransform; - osg::ref_ptr mWaterGroup; - osg::ref_ptr mWaterGeometry; + osg::ref_ptr mWaterTransform; + osg::ref_ptr mWaterGroup; + osg::ref_ptr mWaterGeometry; - bool mDeleted; - bool mExterior; - bool mHasWater; + bool mDeleted; + bool mExterior; + bool mHasWater; }; } diff --git a/apps/opencs/view/render/commands.cpp b/apps/opencs/view/render/commands.cpp index 515948489e..cbc97e3d4b 100644 --- a/apps/opencs/view/render/commands.cpp +++ b/apps/opencs/view/render/commands.cpp @@ -5,9 +5,11 @@ #include "terrainshapemode.hpp" #include "worldspacewidget.hpp" -CSVRender::DrawTerrainSelectionCommand::DrawTerrainSelectionCommand(WorldspaceWidget* worldspaceWidget, QUndoCommand* parent) +CSVRender::DrawTerrainSelectionCommand::DrawTerrainSelectionCommand( + WorldspaceWidget* worldspaceWidget, QUndoCommand* parent) : mWorldspaceWidget(worldspaceWidget) -{ } +{ +} void CSVRender::DrawTerrainSelectionCommand::redo() { diff --git a/apps/opencs/view/render/editmode.cpp b/apps/opencs/view/render/editmode.cpp index ca4aa0fd55..cdca3b1e46 100644 --- a/apps/opencs/view/render/editmode.cpp +++ b/apps/opencs/view/render/editmode.cpp @@ -8,72 +8,72 @@ CSVRender::WorldspaceWidget& CSVRender::EditMode::getWorldspaceWidget() return *mWorldspaceWidget; } -CSVRender::EditMode::EditMode (WorldspaceWidget *worldspaceWidget, const QIcon& icon, - unsigned int mask, const QString& tooltip, QWidget *parent) -: ModeButton (icon, tooltip, parent), mWorldspaceWidget (worldspaceWidget), mMask (mask) -{} +CSVRender::EditMode::EditMode( + WorldspaceWidget* worldspaceWidget, const QIcon& icon, unsigned int mask, const QString& tooltip, QWidget* parent) + : ModeButton(icon, tooltip, parent) + , mWorldspaceWidget(worldspaceWidget) + , mMask(mask) +{ +} unsigned int CSVRender::EditMode::getInteractionMask() const { return mMask; } -void CSVRender::EditMode::activate (CSVWidget::SceneToolbar *toolbar) +void CSVRender::EditMode::activate(CSVWidget::SceneToolbar* toolbar) { - mWorldspaceWidget->setInteractionMask (mMask); - mWorldspaceWidget->clearSelection (~mMask); + mWorldspaceWidget->setInteractionMask(mMask); + mWorldspaceWidget->clearSelection(~mMask); } -void CSVRender::EditMode::setEditLock (bool locked) -{ - -} +void CSVRender::EditMode::setEditLock(bool locked) {} -void CSVRender::EditMode::primaryOpenPressed (const WorldspaceHitResult& hit) {} +void CSVRender::EditMode::primaryOpenPressed(const WorldspaceHitResult& hit) {} -void CSVRender::EditMode::primaryEditPressed (const WorldspaceHitResult& hit) {} +void CSVRender::EditMode::primaryEditPressed(const WorldspaceHitResult& hit) {} -void CSVRender::EditMode::secondaryEditPressed (const WorldspaceHitResult& hit) {} +void CSVRender::EditMode::secondaryEditPressed(const WorldspaceHitResult& hit) {} -void CSVRender::EditMode::primarySelectPressed (const WorldspaceHitResult& hit) {} +void CSVRender::EditMode::primarySelectPressed(const WorldspaceHitResult& hit) {} -void CSVRender::EditMode::secondarySelectPressed (const WorldspaceHitResult& hit) {} +void CSVRender::EditMode::secondarySelectPressed(const WorldspaceHitResult& hit) {} -bool CSVRender::EditMode::primaryEditStartDrag (const QPoint& pos) +bool CSVRender::EditMode::primaryEditStartDrag(const QPoint& pos) { return false; } -bool CSVRender::EditMode::secondaryEditStartDrag (const QPoint& pos) +bool CSVRender::EditMode::secondaryEditStartDrag(const QPoint& pos) { return false; } -bool CSVRender::EditMode::primarySelectStartDrag (const QPoint& pos) +bool CSVRender::EditMode::primarySelectStartDrag(const QPoint& pos) { return false; } -bool CSVRender::EditMode::secondarySelectStartDrag (const QPoint& pos) +bool CSVRender::EditMode::secondarySelectStartDrag(const QPoint& pos) { return false; } -void CSVRender::EditMode::drag (const QPoint& pos, int diffX, int diffY, double speedFactor) {} +void CSVRender::EditMode::drag(const QPoint& pos, int diffX, int diffY, double speedFactor) {} void CSVRender::EditMode::dragCompleted(const QPoint& pos) {} void CSVRender::EditMode::dragAborted() {} -void CSVRender::EditMode::dragWheel (int diff, double speedFactor) {} +void CSVRender::EditMode::dragWheel(int diff, double speedFactor) {} -void CSVRender::EditMode::dragEnterEvent (QDragEnterEvent *event) {} +void CSVRender::EditMode::dragEnterEvent(QDragEnterEvent* event) {} -void CSVRender::EditMode::dropEvent (QDropEvent *event) {} +void CSVRender::EditMode::dropEvent(QDropEvent* event) {} -void CSVRender::EditMode::dragMoveEvent (QDragMoveEvent *event) {} +void CSVRender::EditMode::dragMoveEvent(QDragMoveEvent* event) {} -void CSVRender::EditMode::mouseMoveEvent (QMouseEvent *event) {} +void CSVRender::EditMode::mouseMoveEvent(QMouseEvent* event) {} int CSVRender::EditMode::getSubMode() const { diff --git a/apps/opencs/view/render/editmode.hpp b/apps/opencs/view/render/editmode.hpp index 52c35811d2..3de1d26916 100644 --- a/apps/opencs/view/render/editmode.hpp +++ b/apps/opencs/view/render/editmode.hpp @@ -18,90 +18,88 @@ namespace CSVRender class EditMode : public CSVWidget::ModeButton { - Q_OBJECT + Q_OBJECT - WorldspaceWidget *mWorldspaceWidget; - unsigned int mMask; + WorldspaceWidget* mWorldspaceWidget; + unsigned int mMask; - protected: + protected: + WorldspaceWidget& getWorldspaceWidget(); - WorldspaceWidget& getWorldspaceWidget(); + public: + EditMode(WorldspaceWidget* worldspaceWidget, const QIcon& icon, unsigned int mask, const QString& tooltip = "", + QWidget* parent = nullptr); - public: + unsigned int getInteractionMask() const; - EditMode (WorldspaceWidget *worldspaceWidget, const QIcon& icon, unsigned int mask, - const QString& tooltip = "", QWidget *parent = nullptr); + void activate(CSVWidget::SceneToolbar* toolbar) override; - unsigned int getInteractionMask() const; + /// Default-implementation: Ignored. + virtual void setEditLock(bool locked); - void activate (CSVWidget::SceneToolbar *toolbar) override; + /// Default-implementation: Ignored. + virtual void primaryOpenPressed(const WorldspaceHitResult& hit); - /// Default-implementation: Ignored. - virtual void setEditLock (bool locked); + /// Default-implementation: Ignored. + virtual void primaryEditPressed(const WorldspaceHitResult& hit); - /// Default-implementation: Ignored. - virtual void primaryOpenPressed (const WorldspaceHitResult& hit); + /// Default-implementation: Ignored. + virtual void secondaryEditPressed(const WorldspaceHitResult& hit); - /// Default-implementation: Ignored. - virtual void primaryEditPressed (const WorldspaceHitResult& hit); + /// Default-implementation: Ignored. + virtual void primarySelectPressed(const WorldspaceHitResult& hit); - /// Default-implementation: Ignored. - virtual void secondaryEditPressed (const WorldspaceHitResult& hit); + /// Default-implementation: Ignored. + virtual void secondarySelectPressed(const WorldspaceHitResult& hit); - /// Default-implementation: Ignored. - virtual void primarySelectPressed (const WorldspaceHitResult& hit); + /// Default-implementation: ignore and return false + /// + /// \return Drag accepted? + virtual bool primaryEditStartDrag(const QPoint& pos); - /// Default-implementation: Ignored. - virtual void secondarySelectPressed (const WorldspaceHitResult& hit); + /// Default-implementation: ignore and return false + /// + /// \return Drag accepted? + virtual bool secondaryEditStartDrag(const QPoint& pos); - /// Default-implementation: ignore and return false - /// - /// \return Drag accepted? - virtual bool primaryEditStartDrag (const QPoint& pos); + /// Default-implementation: ignore and return false + /// + /// \return Drag accepted? + virtual bool primarySelectStartDrag(const QPoint& pos); - /// Default-implementation: ignore and return false - /// - /// \return Drag accepted? - virtual bool secondaryEditStartDrag (const QPoint& pos); + /// Default-implementation: ignore and return false + /// + /// \return Drag accepted? + virtual bool secondarySelectStartDrag(const QPoint& pos); - /// Default-implementation: ignore and return false - /// - /// \return Drag accepted? - virtual bool primarySelectStartDrag (const QPoint& pos); + /// Default-implementation: ignored + virtual void drag(const QPoint& pos, int diffX, int diffY, double speedFactor); - /// Default-implementation: ignore and return false - /// - /// \return Drag accepted? - virtual bool secondarySelectStartDrag (const QPoint& pos); + /// Default-implementation: ignored + virtual void dragCompleted(const QPoint& pos); - /// Default-implementation: ignored - virtual void drag (const QPoint& pos, int diffX, int diffY, double speedFactor); + /// Default-implementation: ignored + /// + /// \note dragAborted will not be called, if the drag is aborted via changing + /// editing mode + virtual void dragAborted(); - /// Default-implementation: ignored - virtual void dragCompleted(const QPoint& pos); + /// Default-implementation: ignored + virtual void dragWheel(int diff, double speedFactor); - /// Default-implementation: ignored - /// - /// \note dragAborted will not be called, if the drag is aborted via changing - /// editing mode - virtual void dragAborted(); + /// Default-implementation: ignored + void dragEnterEvent(QDragEnterEvent* event) override; - /// Default-implementation: ignored - virtual void dragWheel (int diff, double speedFactor); + /// Default-implementation: ignored + void dropEvent(QDropEvent* event) override; - /// Default-implementation: ignored - void dragEnterEvent (QDragEnterEvent *event) override; + /// Default-implementation: ignored + void dragMoveEvent(QDragMoveEvent* event) override; - /// Default-implementation: ignored - void dropEvent (QDropEvent *event) override; + void mouseMoveEvent(QMouseEvent* event) override; - /// Default-implementation: ignored - void dragMoveEvent (QDragMoveEvent *event) override; - - void mouseMoveEvent (QMouseEvent *event) override; - - /// Default: return -1 - virtual int getSubMode() const; + /// Default: return -1 + virtual int getSubMode() const; }; } diff --git a/apps/opencs/view/render/instancemode.cpp b/apps/opencs/view/render/instancemode.cpp index 0f5696b472..6b47e4b1e8 100644 --- a/apps/opencs/view/render/instancemode.cpp +++ b/apps/opencs/view/render/instancemode.cpp @@ -12,27 +12,27 @@ #include #include +#include "../../model/prefs/shortcut.hpp" +#include "../../model/world/commandmacro.hpp" +#include "../../model/world/commands.hpp" #include "../../model/world/idtable.hpp" #include "../../model/world/idtree.hpp" -#include "../../model/world/commands.hpp" -#include "../../model/world/commandmacro.hpp" #include "../../model/world/tablemimedata.hpp" -#include "../../model/prefs/shortcut.hpp" #include "../widget/scenetoolbar.hpp" #include "../widget/scenetoolmode.hpp" #include "mask.hpp" +#include "instancemovemode.hpp" +#include "instanceselectionmode.hpp" #include "object.hpp" -#include "worldspacewidget.hpp" #include "pagedworldspacewidget.hpp" -#include "instanceselectionmode.hpp" -#include "instancemovemode.hpp" +#include "worldspacewidget.hpp" -int CSVRender::InstanceMode::getSubModeFromId (const std::string& id) const +int CSVRender::InstanceMode::getSubModeFromId(const std::string& id) const { - return id=="move" ? 0 : (id=="rotate" ? 1 : 2); + return id == "move" ? 0 : (id == "rotate" ? 1 : 2); } osg::Vec3f CSVRender::InstanceMode::quatToEuler(const osg::Quat& rot) const @@ -58,9 +58,9 @@ osg::Vec3f CSVRender::InstanceMode::quatToEuler(const osg::Quat& rot) const osg::Quat CSVRender::InstanceMode::eulerToQuat(const osg::Vec3f& euler) const { - osg::Quat xr = osg::Quat(-euler[0], osg::Vec3f(1,0,0)); - osg::Quat yr = osg::Quat(-euler[1], osg::Vec3f(0,1,0)); - osg::Quat zr = osg::Quat(-euler[2], osg::Vec3f(0,0,1)); + osg::Quat xr = osg::Quat(-euler[0], osg::Vec3f(1, 0, 0)); + osg::Quat yr = osg::Quat(-euler[1], osg::Vec3f(0, 1, 0)); + osg::Quat zr = osg::Quat(-euler[2], osg::Vec3f(0, 0, 1)); return zr * yr * xr; } @@ -70,14 +70,14 @@ float CSVRender::InstanceMode::roundFloatToMult(const float val, const double mu return round(val / mult) * mult; } -osg::Vec3f CSVRender::InstanceMode::getSelectionCenter(const std::vector >& selection) const +osg::Vec3f CSVRender::InstanceMode::getSelectionCenter(const std::vector>& selection) const { osg::Vec3f center = osg::Vec3f(0, 0, 0); int objectCount = 0; - for (std::vector >::const_iterator iter (selection.begin()); iter!=selection.end(); ++iter) + for (std::vector>::const_iterator iter(selection.begin()); iter != selection.end(); ++iter) { - if (CSVRender::ObjectTag *objectTag = dynamic_cast (iter->get())) + if (CSVRender::ObjectTag* objectTag = dynamic_cast(iter->get())) { const ESM::Position& position = objectTag->mObject->getPosition(); center += osg::Vec3f(position.pos[0], position.pos[1], position.pos[2]); @@ -129,95 +129,107 @@ osg::Vec3f CSVRender::InstanceMode::getMousePlaneCoords(const QPoint& point, con return mousePlanePoint; } -CSVRender::InstanceMode::InstanceMode (WorldspaceWidget *worldspaceWidget, osg::ref_ptr parentNode, QWidget *parent) -: EditMode (worldspaceWidget, QIcon (":scenetoolbar/editing-instance"), Mask_Reference | Mask_Terrain, "Instance editing", - parent), mSubMode (nullptr), mSubModeId ("move"), mSelectionMode (nullptr), mDragMode (DragMode_None), - mDragAxis (-1), mLocked (false), mUnitScaleDist(1), mParentNode (parentNode) +CSVRender::InstanceMode::InstanceMode( + WorldspaceWidget* worldspaceWidget, osg::ref_ptr parentNode, QWidget* parent) + : EditMode(worldspaceWidget, QIcon(":scenetoolbar/editing-instance"), Mask_Reference | Mask_Terrain, + "Instance editing", parent) + , mSubMode(nullptr) + , mSubModeId("move") + , mSelectionMode(nullptr) + , mDragMode(DragMode_None) + , mDragAxis(-1) + , mLocked(false) + , mUnitScaleDist(1) + , mParentNode(parentNode) { - connect(this, &InstanceMode::requestFocus, - worldspaceWidget, &WorldspaceWidget::requestFocus); + connect(this, &InstanceMode::requestFocus, worldspaceWidget, &WorldspaceWidget::requestFocus); CSMPrefs::Shortcut* deleteShortcut = new CSMPrefs::Shortcut("scene-delete", worldspaceWidget); - connect(deleteShortcut, qOverload(&CSMPrefs::Shortcut::activated), - this, &InstanceMode::deleteSelectedInstances); - - // Following classes could be simplified by using QSignalMapper, which is obsolete in Qt5.10, but not in Qt4.8 and Qt5.14 - CSMPrefs::Shortcut* dropToCollisionShortcut = new CSMPrefs::Shortcut("scene-instance-drop-collision", worldspaceWidget); - connect(dropToCollisionShortcut, qOverload<>(&CSMPrefs::Shortcut::activated), - this, &InstanceMode::dropSelectedInstancesToCollision); - CSMPrefs::Shortcut* dropToTerrainLevelShortcut = new CSMPrefs::Shortcut("scene-instance-drop-terrain", worldspaceWidget); - connect(dropToTerrainLevelShortcut, qOverload<>(&CSMPrefs::Shortcut::activated), - this, &InstanceMode::dropSelectedInstancesToTerrain); - CSMPrefs::Shortcut* dropToCollisionShortcut2 = new CSMPrefs::Shortcut("scene-instance-drop-collision-separately", worldspaceWidget); - connect(dropToCollisionShortcut2, qOverload<>(&CSMPrefs::Shortcut::activated), - this, &InstanceMode::dropSelectedInstancesToCollisionSeparately); - CSMPrefs::Shortcut* dropToTerrainLevelShortcut2 = new CSMPrefs::Shortcut("scene-instance-drop-terrain-separately", worldspaceWidget); - connect(dropToTerrainLevelShortcut2, qOverload<>(&CSMPrefs::Shortcut::activated), - this, &InstanceMode::dropSelectedInstancesToTerrainSeparately); + connect( + deleteShortcut, qOverload(&CSMPrefs::Shortcut::activated), this, &InstanceMode::deleteSelectedInstances); + + // Following classes could be simplified by using QSignalMapper, which is obsolete in Qt5.10, but not in Qt4.8 and + // Qt5.14 + CSMPrefs::Shortcut* dropToCollisionShortcut + = new CSMPrefs::Shortcut("scene-instance-drop-collision", worldspaceWidget); + connect(dropToCollisionShortcut, qOverload<>(&CSMPrefs::Shortcut::activated), this, + &InstanceMode::dropSelectedInstancesToCollision); + CSMPrefs::Shortcut* dropToTerrainLevelShortcut + = new CSMPrefs::Shortcut("scene-instance-drop-terrain", worldspaceWidget); + connect(dropToTerrainLevelShortcut, qOverload<>(&CSMPrefs::Shortcut::activated), this, + &InstanceMode::dropSelectedInstancesToTerrain); + CSMPrefs::Shortcut* dropToCollisionShortcut2 + = new CSMPrefs::Shortcut("scene-instance-drop-collision-separately", worldspaceWidget); + connect(dropToCollisionShortcut2, qOverload<>(&CSMPrefs::Shortcut::activated), this, + &InstanceMode::dropSelectedInstancesToCollisionSeparately); + CSMPrefs::Shortcut* dropToTerrainLevelShortcut2 + = new CSMPrefs::Shortcut("scene-instance-drop-terrain-separately", worldspaceWidget); + connect(dropToTerrainLevelShortcut2, qOverload<>(&CSMPrefs::Shortcut::activated), this, + &InstanceMode::dropSelectedInstancesToTerrainSeparately); } -void CSVRender::InstanceMode::activate (CSVWidget::SceneToolbar *toolbar) +void CSVRender::InstanceMode::activate(CSVWidget::SceneToolbar* toolbar) { if (!mSubMode) { - mSubMode = new CSVWidget::SceneToolMode (toolbar, "Edit Sub-Mode"); - mSubMode->addButton (new InstanceMoveMode (this), "move"); - mSubMode->addButton (":scenetoolbar/transform-rotate", "rotate", + mSubMode = new CSVWidget::SceneToolMode(toolbar, "Edit Sub-Mode"); + mSubMode->addButton(new InstanceMoveMode(this), "move"); + mSubMode->addButton(":scenetoolbar/transform-rotate", "rotate", "Rotate selected instances" "
  • Use {scene-edit-primary} to rotate instances freely
  • " "
  • Use {scene-edit-secondary} to rotate instances within the grid
  • " "
  • The center of the view acts as the axis of rotation
  • " "
"); - mSubMode->addButton (":scenetoolbar/transform-scale", "scale", + mSubMode->addButton(":scenetoolbar/transform-scale", "scale", "Scale selected instances" "
  • Use {scene-edit-primary} to scale instances freely
  • " "
  • Use {scene-edit-secondary} to scale instances along the grid
  • " "
  • The scaling rate is based on how close the start of a drag is to the center of the screen
  • " "
"); - mSubMode->setButton (mSubModeId); + mSubMode->setButton(mSubModeId); - connect (mSubMode, &CSVWidget::SceneToolMode::modeChanged, this, &InstanceMode::subModeChanged); + connect(mSubMode, &CSVWidget::SceneToolMode::modeChanged, this, &InstanceMode::subModeChanged); } if (!mSelectionMode) - mSelectionMode = new InstanceSelectionMode (toolbar, getWorldspaceWidget(), mParentNode); + mSelectionMode = new InstanceSelectionMode(toolbar, getWorldspaceWidget(), mParentNode); mDragMode = DragMode_None; - EditMode::activate (toolbar); + EditMode::activate(toolbar); - toolbar->addTool (mSubMode); - toolbar->addTool (mSelectionMode); + toolbar->addTool(mSubMode); + toolbar->addTool(mSelectionMode); std::string subMode = mSubMode->getCurrentId(); - getWorldspaceWidget().setSubMode (getSubModeFromId (subMode), Mask_Reference); + getWorldspaceWidget().setSubMode(getSubModeFromId(subMode), Mask_Reference); } -void CSVRender::InstanceMode::deactivate (CSVWidget::SceneToolbar *toolbar) +void CSVRender::InstanceMode::deactivate(CSVWidget::SceneToolbar* toolbar) { mDragMode = DragMode_None; - getWorldspaceWidget().reset (Mask_Reference); + getWorldspaceWidget().reset(Mask_Reference); if (mSelectionMode) { - toolbar->removeTool (mSelectionMode); + toolbar->removeTool(mSelectionMode); delete mSelectionMode; mSelectionMode = nullptr; } if (mSubMode) { - toolbar->removeTool (mSubMode); + toolbar->removeTool(mSubMode); delete mSubMode; mSubMode = nullptr; } - EditMode::deactivate (toolbar); + EditMode::deactivate(toolbar); } -void CSVRender::InstanceMode::setEditLock (bool locked) +void CSVRender::InstanceMode::setEditLock(bool locked) { mLocked = locked; @@ -225,17 +237,17 @@ void CSVRender::InstanceMode::setEditLock (bool locked) getWorldspaceWidget().abortDrag(); } -void CSVRender::InstanceMode::primaryEditPressed (const WorldspaceHitResult& hit) +void CSVRender::InstanceMode::primaryEditPressed(const WorldspaceHitResult& hit) { if (CSMPrefs::get()["3D Scene Input"]["context-select"].isTrue()) - primarySelectPressed (hit); + primarySelectPressed(hit); } -void CSVRender::InstanceMode::primaryOpenPressed (const WorldspaceHitResult& hit) +void CSVRender::InstanceMode::primaryOpenPressed(const WorldspaceHitResult& hit) { - if(hit.tag) + if (hit.tag) { - if (CSVRender::ObjectTag *objectTag = dynamic_cast (hit.tag.get())) + if (CSVRender::ObjectTag* objectTag = dynamic_cast(hit.tag.get())) { const std::string refId = objectTag->mObject->getReferenceId(); emit requestFocus(refId); @@ -243,78 +255,77 @@ void CSVRender::InstanceMode::primaryOpenPressed (const WorldspaceHitResult& hit } } -void CSVRender::InstanceMode::secondaryEditPressed (const WorldspaceHitResult& hit) +void CSVRender::InstanceMode::secondaryEditPressed(const WorldspaceHitResult& hit) { if (CSMPrefs::get()["3D Scene Input"]["context-select"].isTrue()) - secondarySelectPressed (hit); + secondarySelectPressed(hit); } -void CSVRender::InstanceMode::primarySelectPressed (const WorldspaceHitResult& hit) +void CSVRender::InstanceMode::primarySelectPressed(const WorldspaceHitResult& hit) { - getWorldspaceWidget().clearSelection (Mask_Reference); + getWorldspaceWidget().clearSelection(Mask_Reference); if (hit.tag) { - if (CSVRender::ObjectTag *objectTag = dynamic_cast (hit.tag.get())) + if (CSVRender::ObjectTag* objectTag = dynamic_cast(hit.tag.get())) { // hit an Object, select it CSVRender::Object* object = objectTag->mObject; - object->setSelected (true); + object->setSelected(true); return; } } } -void CSVRender::InstanceMode::secondarySelectPressed (const WorldspaceHitResult& hit) +void CSVRender::InstanceMode::secondarySelectPressed(const WorldspaceHitResult& hit) { if (hit.tag) { - if (CSVRender::ObjectTag *objectTag = dynamic_cast (hit.tag.get())) + if (CSVRender::ObjectTag* objectTag = dynamic_cast(hit.tag.get())) { // hit an Object, toggle its selection state CSVRender::Object* object = objectTag->mObject; - object->setSelected (!object->getSelected()); + object->setSelected(!object->getSelected()); return; } } } -bool CSVRender::InstanceMode::primaryEditStartDrag (const QPoint& pos) +bool CSVRender::InstanceMode::primaryEditStartDrag(const QPoint& pos) { - if (mDragMode!=DragMode_None || mLocked) + if (mDragMode != DragMode_None || mLocked) return false; - WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask()); + WorldspaceHitResult hit = getWorldspaceWidget().mousePick(pos, getWorldspaceWidget().getInteractionMask()); - std::vector > selection = getWorldspaceWidget().getSelection (Mask_Reference); + std::vector> selection = getWorldspaceWidget().getSelection(Mask_Reference); if (selection.empty()) { // Only change selection at the start of drag if no object is already selected if (hit.tag && CSMPrefs::get()["3D Scene Input"]["context-select"].isTrue()) { - getWorldspaceWidget().clearSelection (Mask_Reference); - if (CSVRender::ObjectTag *objectTag = dynamic_cast (hit.tag.get())) + getWorldspaceWidget().clearSelection(Mask_Reference); + if (CSVRender::ObjectTag* objectTag = dynamic_cast(hit.tag.get())) { CSVRender::Object* object = objectTag->mObject; - object->setSelected (true); + object->setSelected(true); } } - selection = getWorldspaceWidget().getSelection (Mask_Reference); + selection = getWorldspaceWidget().getSelection(Mask_Reference); if (selection.empty()) return false; } mObjectsAtDragStart.clear(); - for (std::vector >::iterator iter (selection.begin()); - iter!=selection.end(); ++iter) + for (std::vector>::iterator iter(selection.begin()); iter != selection.end(); ++iter) { - if (CSVRender::ObjectTag *objectTag = dynamic_cast (iter->get())) + if (CSVRender::ObjectTag* objectTag = dynamic_cast(iter->get())) { if (mSubModeId == "move") { - objectTag->mObject->setEdited (Object::Override_Position); + objectTag->mObject->setEdited(Object::Override_Position); float x = objectTag->mObject->getPosition().pos[0]; float y = objectTag->mObject->getPosition().pos[1]; float z = objectTag->mObject->getPosition().pos[2]; @@ -325,16 +336,16 @@ bool CSVRender::InstanceMode::primaryEditStartDrag (const QPoint& pos) } else if (mSubModeId == "rotate") { - objectTag->mObject->setEdited (Object::Override_Rotation); + objectTag->mObject->setEdited(Object::Override_Rotation); mDragMode = DragMode_Rotate; } else if (mSubModeId == "scale") { - objectTag->mObject->setEdited (Object::Override_Scale); + objectTag->mObject->setEdited(Object::Override_Scale); mDragMode = DragMode_Scale; // Calculate scale factor - std::vector > editedSelection = getWorldspaceWidget().getEdited (Mask_Reference); + std::vector> editedSelection = getWorldspaceWidget().getEdited(Mask_Reference); osg::Vec3f center = getScreenCoords(getSelectionCenter(editedSelection)); int widgetHeight = getWorldspaceWidget().height(); @@ -347,7 +358,7 @@ bool CSVRender::InstanceMode::primaryEditStartDrag (const QPoint& pos) } } - if (CSVRender::ObjectMarkerTag *objectTag = dynamic_cast (hit.tag.get())) + if (CSVRender::ObjectMarkerTag* objectTag = dynamic_cast(hit.tag.get())) { mDragAxis = objectTag->mAxis; } @@ -357,21 +368,21 @@ bool CSVRender::InstanceMode::primaryEditStartDrag (const QPoint& pos) return true; } -bool CSVRender::InstanceMode::secondaryEditStartDrag (const QPoint& pos) +bool CSVRender::InstanceMode::secondaryEditStartDrag(const QPoint& pos) { if (mDragMode != DragMode_None || mLocked) return false; WorldspaceHitResult hit = getWorldspaceWidget().mousePick(pos, getWorldspaceWidget().getInteractionMask()); - std::vector > selection = getWorldspaceWidget().getSelection(Mask_Reference); + std::vector> selection = getWorldspaceWidget().getSelection(Mask_Reference); if (selection.empty()) { // Only change selection at the start of drag if no object is already selected if (hit.tag && CSMPrefs::get()["3D Scene Input"]["context-select"].isTrue()) { getWorldspaceWidget().clearSelection(Mask_Reference); - if (CSVRender::ObjectTag* objectTag = dynamic_cast (hit.tag.get())) + if (CSVRender::ObjectTag* objectTag = dynamic_cast(hit.tag.get())) { CSVRender::Object* object = objectTag->mObject; object->setSelected(true); @@ -385,10 +396,9 @@ bool CSVRender::InstanceMode::secondaryEditStartDrag (const QPoint& pos) mObjectsAtDragStart.clear(); - for (std::vector >::iterator iter(selection.begin()); - iter != selection.end(); ++iter) + for (std::vector>::iterator iter(selection.begin()); iter != selection.end(); ++iter) { - if (CSVRender::ObjectTag* objectTag = dynamic_cast (iter->get())) + if (CSVRender::ObjectTag* objectTag = dynamic_cast(iter->get())) { if (mSubModeId == "move") { @@ -413,7 +423,7 @@ bool CSVRender::InstanceMode::secondaryEditStartDrag (const QPoint& pos) mDragMode = DragMode_Scale_Snap; // Calculate scale factor - std::vector > editedSelection = getWorldspaceWidget().getEdited(Mask_Reference); + std::vector> editedSelection = getWorldspaceWidget().getEdited(Mask_Reference); osg::Vec3f center = getScreenCoords(getSelectionCenter(editedSelection)); int widgetHeight = getWorldspaceWidget().height(); @@ -426,7 +436,7 @@ bool CSVRender::InstanceMode::secondaryEditStartDrag (const QPoint& pos) } } - if (CSVRender::ObjectMarkerTag* objectTag = dynamic_cast (hit.tag.get())) + if (CSVRender::ObjectMarkerTag* objectTag = dynamic_cast(hit.tag.get())) { mDragAxis = objectTag->mAxis; } @@ -436,54 +446,64 @@ bool CSVRender::InstanceMode::secondaryEditStartDrag (const QPoint& pos) return true; } -bool CSVRender::InstanceMode::primarySelectStartDrag (const QPoint& pos) +bool CSVRender::InstanceMode::primarySelectStartDrag(const QPoint& pos) { - if (mDragMode!=DragMode_None || mLocked) + if (mDragMode != DragMode_None || mLocked) return false; std::string primarySelectAction = CSMPrefs::get()["3D Scene Editing"]["primary-select-action"].toString(); - if ( primarySelectAction == "Select only" ) mDragMode = DragMode_Select_Only; - else if ( primarySelectAction == "Add to selection" ) mDragMode = DragMode_Select_Add; - else if ( primarySelectAction == "Remove from selection" ) mDragMode = DragMode_Select_Remove; - else if ( primarySelectAction == "Invert selection" ) mDragMode = DragMode_Select_Invert; + if (primarySelectAction == "Select only") + mDragMode = DragMode_Select_Only; + else if (primarySelectAction == "Add to selection") + mDragMode = DragMode_Select_Add; + else if (primarySelectAction == "Remove from selection") + mDragMode = DragMode_Select_Remove; + else if (primarySelectAction == "Invert selection") + mDragMode = DragMode_Select_Invert; - WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask()); + WorldspaceHitResult hit = getWorldspaceWidget().mousePick(pos, getWorldspaceWidget().getInteractionMask()); mSelectionMode->setDragStart(hit.worldPos); return true; } -bool CSVRender::InstanceMode::secondarySelectStartDrag (const QPoint& pos) +bool CSVRender::InstanceMode::secondarySelectStartDrag(const QPoint& pos) { - if (mDragMode!=DragMode_None || mLocked) + if (mDragMode != DragMode_None || mLocked) return false; std::string secondarySelectAction = CSMPrefs::get()["3D Scene Editing"]["secondary-select-action"].toString(); - if ( secondarySelectAction == "Select only" ) mDragMode = DragMode_Select_Only; - else if ( secondarySelectAction == "Add to selection" ) mDragMode = DragMode_Select_Add; - else if ( secondarySelectAction == "Remove from selection" ) mDragMode = DragMode_Select_Remove; - else if ( secondarySelectAction == "Invert selection" ) mDragMode = DragMode_Select_Invert; + if (secondarySelectAction == "Select only") + mDragMode = DragMode_Select_Only; + else if (secondarySelectAction == "Add to selection") + mDragMode = DragMode_Select_Add; + else if (secondarySelectAction == "Remove from selection") + mDragMode = DragMode_Select_Remove; + else if (secondarySelectAction == "Invert selection") + mDragMode = DragMode_Select_Invert; - WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask()); + WorldspaceHitResult hit = getWorldspaceWidget().mousePick(pos, getWorldspaceWidget().getInteractionMask()); mSelectionMode->setDragStart(hit.worldPos); return true; } -void CSVRender::InstanceMode::drag (const QPoint& pos, int diffX, int diffY, double speedFactor) +void CSVRender::InstanceMode::drag(const QPoint& pos, int diffX, int diffY, double speedFactor) { osg::Vec3f offset; osg::Quat rotation; - std::vector > selection = getWorldspaceWidget().getEdited (Mask_Reference); + std::vector> selection = getWorldspaceWidget().getEdited(Mask_Reference); - if (mDragMode == DragMode_Move || mDragMode == DragMode_Move_Snap) {} + if (mDragMode == DragMode_Move || mDragMode == DragMode_Move_Snap) + { + } else if (mDragMode == DragMode_Rotate || mDragMode == DragMode_Rotate_Snap) { osg::Vec3f eye, centre, up; - getWorldspaceWidget().getCamera()->getViewMatrix().getLookAt (eye, centre, up); + getWorldspaceWidget().getCamera()->getViewMatrix().getLookAt(eye, centre, up); float angle; osg::Vec3f axis; @@ -499,7 +519,7 @@ void CSVRender::InstanceMode::drag (const QPoint& pos, int diffX, int diffY, dou osg::Vec3f screenDir = cameraRotation * osg::Vec3f(diffX, diffY, 0); screenDir.normalize(); - angle = std::sqrt(diffX*diffX + diffY*diffY) * rotationFactor; + angle = std::sqrt(diffX * diffX + diffY * diffY) * rotationFactor; axis = screenDir ^ camForward; } else @@ -563,28 +583,28 @@ void CSVRender::InstanceMode::drag (const QPoint& pos, int diffX, int diffY, dou else if (mSelectionMode->getCurrentId() == "cube-centre") { osg::Vec3f mousePlanePoint = getMousePlaneCoords(pos, getProjectionSpaceCoords(mSelectionMode->getDragStart())); - mSelectionMode->drawSelectionCubeCentre (mousePlanePoint); + mSelectionMode->drawSelectionCubeCentre(mousePlanePoint); return; } else if (mSelectionMode->getCurrentId() == "cube-corner") { osg::Vec3f mousePlanePoint = getMousePlaneCoords(pos, getProjectionSpaceCoords(mSelectionMode->getDragStart())); - mSelectionMode->drawSelectionCubeCorner (mousePlanePoint); + mSelectionMode->drawSelectionCubeCorner(mousePlanePoint); return; } else if (mSelectionMode->getCurrentId() == "sphere") { osg::Vec3f mousePlanePoint = getMousePlaneCoords(pos, getProjectionSpaceCoords(mSelectionMode->getDragStart())); - mSelectionMode->drawSelectionSphere (mousePlanePoint); + mSelectionMode->drawSelectionSphere(mousePlanePoint); return; } int i = 0; // Apply - for (std::vector >::iterator iter (selection.begin()); iter!=selection.end(); ++iter, i++) + for (std::vector>::iterator iter(selection.begin()); iter != selection.end(); ++iter, i++) { - if (CSVRender::ObjectTag *objectTag = dynamic_cast (iter->get())) + if (CSVRender::ObjectTag* objectTag = dynamic_cast(iter->get())) { if (mDragMode == DragMode_Move || mDragMode == DragMode_Move_Snap) { @@ -597,7 +617,7 @@ void CSVRender::InstanceMode::drag (const QPoint& pos, int diffX, int diffY, dou position.pos[1] = mObjectsAtDragStart[i].y() + addToY; position.pos[2] = mObjectsAtDragStart[i].z() + addToZ; - if (mDragMode == DragMode_Move_Snap) + if (mDragMode == DragMode_Move_Snap) { double snap = CSMPrefs::get()["3D Scene Editing"]["gridsnap-movement"].toDouble(); position.pos[0] = CSVRender::InstanceMode::roundFloatToMult(position.pos[0], snap); @@ -646,10 +666,11 @@ void CSVRender::InstanceMode::drag (const QPoint& pos, int diffX, int diffY, dou if (mDragMode == DragMode_Scale_Snap) { - scale = CSVRender::InstanceMode::roundFloatToMult(scale, CSMPrefs::get()["3D Scene Editing"]["gridsnap-scale"].toDouble()); + scale = CSVRender::InstanceMode::roundFloatToMult( + scale, CSMPrefs::get()["3D Scene Editing"]["gridsnap-scale"].toDouble()); } - objectTag->mObject->setScale (scale); + objectTag->mObject->setScale(scale); } } } @@ -657,8 +678,7 @@ void CSVRender::InstanceMode::drag (const QPoint& pos, int diffX, int diffY, dou void CSVRender::InstanceMode::dragCompleted(const QPoint& pos) { - std::vector > selection = - getWorldspaceWidget().getEdited (Mask_Reference); + std::vector> selection = getWorldspaceWidget().getEdited(Mask_Reference); QUndoStack& undoStack = getWorldspaceWidget().getDocument().getUndoStack(); @@ -666,51 +686,65 @@ void CSVRender::InstanceMode::dragCompleted(const QPoint& pos) switch (mDragMode) { - case DragMode_Move: description = "Move Instances"; break; - case DragMode_Rotate: description = "Rotate Instances"; break; - case DragMode_Scale: description = "Scale Instances"; break; - case DragMode_Select_Only : + case DragMode_Move: + description = "Move Instances"; + break; + case DragMode_Rotate: + description = "Rotate Instances"; + break; + case DragMode_Scale: + description = "Scale Instances"; + break; + case DragMode_Select_Only: handleSelectDrag(pos); return; break; - case DragMode_Select_Add : + case DragMode_Select_Add: handleSelectDrag(pos); return; break; - case DragMode_Select_Remove : + case DragMode_Select_Remove: handleSelectDrag(pos); return; break; - case DragMode_Select_Invert : + case DragMode_Select_Invert: handleSelectDrag(pos); return; break; - case DragMode_Move_Snap: description = "Move Instances"; break; - case DragMode_Rotate_Snap: description = "Rotate Instances"; break; - case DragMode_Scale_Snap: description = "Scale Instances"; break; - case DragMode_None: break; + case DragMode_Move_Snap: + description = "Move Instances"; + break; + case DragMode_Rotate_Snap: + description = "Rotate Instances"; + break; + case DragMode_Scale_Snap: + description = "Scale Instances"; + break; + case DragMode_None: + break; } + CSMWorld::CommandMacro macro(undoStack, description); - CSMWorld::CommandMacro macro (undoStack, description); - - for (std::vector >::iterator iter (selection.begin()); - iter!=selection.end(); ++iter) + for (std::vector>::iterator iter(selection.begin()); iter != selection.end(); ++iter) { - if (CSVRender::ObjectTag *objectTag = dynamic_cast (iter->get())) + if (CSVRender::ObjectTag* objectTag = dynamic_cast(iter->get())) { if (mDragMode == DragMode_Rotate_Snap) { ESM::Position position = objectTag->mObject->getPosition(); double snap = CSMPrefs::get()["3D Scene Editing"]["gridsnap-rotation"].toDouble(); - position.rot[0] = CSVRender::InstanceMode::roundFloatToMult(position.rot[0], osg::DegreesToRadians(snap)); - position.rot[1] = CSVRender::InstanceMode::roundFloatToMult(position.rot[1], osg::DegreesToRadians(snap)); - position.rot[2] = CSVRender::InstanceMode::roundFloatToMult(position.rot[2], osg::DegreesToRadians(snap)); + position.rot[0] + = CSVRender::InstanceMode::roundFloatToMult(position.rot[0], osg::DegreesToRadians(snap)); + position.rot[1] + = CSVRender::InstanceMode::roundFloatToMult(position.rot[1], osg::DegreesToRadians(snap)); + position.rot[2] + = CSVRender::InstanceMode::roundFloatToMult(position.rot[2], osg::DegreesToRadians(snap)); objectTag->mObject->setRotation(position.rot); } - objectTag->mObject->apply (macro); + objectTag->mObject->apply(macro); } } @@ -720,36 +754,34 @@ void CSVRender::InstanceMode::dragCompleted(const QPoint& pos) void CSVRender::InstanceMode::dragAborted() { - getWorldspaceWidget().reset (Mask_Reference); + getWorldspaceWidget().reset(Mask_Reference); mDragMode = DragMode_None; } -void CSVRender::InstanceMode::dragWheel (int diff, double speedFactor) +void CSVRender::InstanceMode::dragWheel(int diff, double speedFactor) { - if (mDragMode==DragMode_Move || mDragMode==DragMode_Move_Snap) + if (mDragMode == DragMode_Move || mDragMode == DragMode_Move_Snap) { osg::Vec3f eye; osg::Vec3f centre; osg::Vec3f up; - getWorldspaceWidget().getCamera()->getViewMatrix().getLookAt (eye, centre, up); + getWorldspaceWidget().getCamera()->getViewMatrix().getLookAt(eye, centre, up); osg::Vec3f offset = centre - eye; offset.normalize(); offset *= diff * speedFactor; - std::vector > selection = - getWorldspaceWidget().getEdited (Mask_Reference); + std::vector> selection = getWorldspaceWidget().getEdited(Mask_Reference); int j = 0; - for (std::vector >::iterator iter (selection.begin()); - iter!=selection.end(); ++iter, j++) + for (std::vector>::iterator iter(selection.begin()); iter != selection.end(); ++iter, j++) { - if (CSVRender::ObjectTag *objectTag = dynamic_cast (iter->get())) + if (CSVRender::ObjectTag* objectTag = dynamic_cast(iter->get())) { ESM::Position position = objectTag->mObject->getPosition(); - for (int i=0; i<3; ++i) + for (int i = 0; i < 3; ++i) position.pos[i] += offset[i]; if (mDragMode == DragMode_Move_Snap) @@ -760,123 +792,120 @@ void CSVRender::InstanceMode::dragWheel (int diff, double speedFactor) position.pos[2] = CSVRender::InstanceMode::roundFloatToMult(position.pos[2], snap); } - objectTag->mObject->setPosition (position.pos); + objectTag->mObject->setPosition(position.pos); osg::Vec3f thisPoint(position.pos[0], position.pos[1], position.pos[2]); - mDragStart = getMousePlaneCoords(getWorldspaceWidget().mapFromGlobal(QCursor::pos()), getProjectionSpaceCoords(thisPoint)); + mDragStart = getMousePlaneCoords( + getWorldspaceWidget().mapFromGlobal(QCursor::pos()), getProjectionSpaceCoords(thisPoint)); mObjectsAtDragStart[j] = thisPoint; } } } } -void CSVRender::InstanceMode::dragEnterEvent (QDragEnterEvent *event) +void CSVRender::InstanceMode::dragEnterEvent(QDragEnterEvent* event) { - if (const CSMWorld::TableMimeData* mime = dynamic_cast (event->mimeData())) + if (const CSMWorld::TableMimeData* mime = dynamic_cast(event->mimeData())) { - if (!mime->fromDocument (getWorldspaceWidget().getDocument())) + if (!mime->fromDocument(getWorldspaceWidget().getDocument())) return; - if (mime->holdsType (CSMWorld::UniversalId::Type_Referenceable)) + if (mime->holdsType(CSMWorld::UniversalId::Type_Referenceable)) event->accept(); } } -void CSVRender::InstanceMode::dropEvent (QDropEvent* event) +void CSVRender::InstanceMode::dropEvent(QDropEvent* event) { - if (const CSMWorld::TableMimeData* mime = dynamic_cast (event->mimeData())) + if (const CSMWorld::TableMimeData* mime = dynamic_cast(event->mimeData())) { CSMDoc::Document& document = getWorldspaceWidget().getDocument(); - if (!mime->fromDocument (document)) + if (!mime->fromDocument(document)) return; - WorldspaceHitResult hit = getWorldspaceWidget().mousePick (event->pos(), getWorldspaceWidget().getInteractionMask()); + WorldspaceHitResult hit + = getWorldspaceWidget().mousePick(event->pos(), getWorldspaceWidget().getInteractionMask()); - std::string cellId = getWorldspaceWidget().getCellId (hit.worldPos); + std::string cellId = getWorldspaceWidget().getCellId(hit.worldPos); - CSMWorld::IdTree& cellTable = dynamic_cast ( - *document.getData().getTableModel (CSMWorld::UniversalId::Type_Cells)); + CSMWorld::IdTree& cellTable + = dynamic_cast(*document.getData().getTableModel(CSMWorld::UniversalId::Type_Cells)); - bool noCell = document.getData().getCells().searchId (cellId)==-1; + bool noCell = document.getData().getCells().searchId(cellId) == -1; if (noCell) { std::string mode = CSMPrefs::get()["3D Scene Editing"]["outside-drop"].toString(); // target cell does not exist - if (mode=="Discard") + if (mode == "Discard") return; - if (mode=="Create cell and insert") + if (mode == "Create cell and insert") { - std::unique_ptr createCommand ( - new CSMWorld::CreateCommand (cellTable, cellId)); + std::unique_ptr createCommand(new CSMWorld::CreateCommand(cellTable, cellId)); - int parentIndex = cellTable.findColumnIndex (CSMWorld::Columns::ColumnId_Cell); - int index = cellTable.findNestedColumnIndex (parentIndex, CSMWorld::Columns::ColumnId_Interior); - createCommand->addNestedValue (parentIndex, index, false); + int parentIndex = cellTable.findColumnIndex(CSMWorld::Columns::ColumnId_Cell); + int index = cellTable.findNestedColumnIndex(parentIndex, CSMWorld::Columns::ColumnId_Interior); + createCommand->addNestedValue(parentIndex, index, false); - document.getUndoStack().push (createCommand.release()); + document.getUndoStack().push(createCommand.release()); - if (CSVRender::PagedWorldspaceWidget *paged = - dynamic_cast (&getWorldspaceWidget())) + if (CSVRender::PagedWorldspaceWidget* paged + = dynamic_cast(&getWorldspaceWidget())) { CSMWorld::CellSelection selection = paged->getCellSelection(); - selection.add (CSMWorld::CellCoordinates::fromId (cellId).first); - paged->setCellSelection (selection); + selection.add(CSMWorld::CellCoordinates::fromId(cellId).first); + paged->setCellSelection(selection); } } } - else if (CSVRender::PagedWorldspaceWidget *paged = - dynamic_cast (&getWorldspaceWidget())) + else if (CSVRender::PagedWorldspaceWidget* paged + = dynamic_cast(&getWorldspaceWidget())) { CSMWorld::CellSelection selection = paged->getCellSelection(); - if (!selection.has (CSMWorld::CellCoordinates::fromId (cellId).first)) + if (!selection.has(CSMWorld::CellCoordinates::fromId(cellId).first)) { // target cell exists, but is not shown - std::string mode = - CSMPrefs::get()["3D Scene Editing"]["outside-visible-drop"].toString(); + std::string mode = CSMPrefs::get()["3D Scene Editing"]["outside-visible-drop"].toString(); - if (mode=="Discard") + if (mode == "Discard") return; - if (mode=="Show cell and insert") + if (mode == "Show cell and insert") { - selection.add (CSMWorld::CellCoordinates::fromId (cellId).first); - paged->setCellSelection (selection); + selection.add(CSMWorld::CellCoordinates::fromId(cellId).first); + paged->setCellSelection(selection); } } } - CSMWorld::IdTable& referencesTable = dynamic_cast ( - *document.getData().getTableModel (CSMWorld::UniversalId::Type_References)); + CSMWorld::IdTable& referencesTable = dynamic_cast( + *document.getData().getTableModel(CSMWorld::UniversalId::Type_References)); bool dropped = false; std::vector ids = mime->getData(); - for (std::vector::const_iterator iter (ids.begin()); - iter!=ids.end(); ++iter) - if (mime->isReferencable (iter->getType())) + for (std::vector::const_iterator iter(ids.begin()); iter != ids.end(); ++iter) + if (mime->isReferencable(iter->getType())) { // create reference - std::unique_ptr createCommand ( - new CSMWorld::CreateCommand ( - referencesTable, document.getData().getReferences().getNewId())); - - createCommand->addValue (referencesTable.findColumnIndex ( - CSMWorld::Columns::ColumnId_Cell), QString::fromUtf8 (cellId.c_str())); - createCommand->addValue (referencesTable.findColumnIndex ( - CSMWorld::Columns::ColumnId_PositionXPos), hit.worldPos.x()); - createCommand->addValue (referencesTable.findColumnIndex ( - CSMWorld::Columns::ColumnId_PositionYPos), hit.worldPos.y()); - createCommand->addValue (referencesTable.findColumnIndex ( - CSMWorld::Columns::ColumnId_PositionZPos), hit.worldPos.z()); - createCommand->addValue (referencesTable.findColumnIndex ( - CSMWorld::Columns::ColumnId_ReferenceableId), - QString::fromUtf8 (iter->getId().c_str())); - - document.getUndoStack().push (createCommand.release()); + std::unique_ptr createCommand( + new CSMWorld::CreateCommand(referencesTable, document.getData().getReferences().getNewId())); + + createCommand->addValue(referencesTable.findColumnIndex(CSMWorld::Columns::ColumnId_Cell), + QString::fromUtf8(cellId.c_str())); + createCommand->addValue( + referencesTable.findColumnIndex(CSMWorld::Columns::ColumnId_PositionXPos), hit.worldPos.x()); + createCommand->addValue( + referencesTable.findColumnIndex(CSMWorld::Columns::ColumnId_PositionYPos), hit.worldPos.y()); + createCommand->addValue( + referencesTable.findColumnIndex(CSMWorld::Columns::ColumnId_PositionZPos), hit.worldPos.z()); + createCommand->addValue(referencesTable.findColumnIndex(CSMWorld::Columns::ColumnId_ReferenceableId), + QString::fromUtf8(iter->getId().c_str())); + + document.getUndoStack().push(createCommand.release()); dropped = true; } @@ -888,39 +917,40 @@ void CSVRender::InstanceMode::dropEvent (QDropEvent* event) int CSVRender::InstanceMode::getSubMode() const { - return mSubMode ? getSubModeFromId (mSubMode->getCurrentId()) : 0; + return mSubMode ? getSubModeFromId(mSubMode->getCurrentId()) : 0; } -void CSVRender::InstanceMode::subModeChanged (const std::string& id) +void CSVRender::InstanceMode::subModeChanged(const std::string& id) { mSubModeId = id; getWorldspaceWidget().abortDrag(); - getWorldspaceWidget().setSubMode (getSubModeFromId (id), Mask_Reference); + getWorldspaceWidget().setSubMode(getSubModeFromId(id), Mask_Reference); } void CSVRender::InstanceMode::handleSelectDrag(const QPoint& pos) { osg::Vec3f mousePlanePoint = getMousePlaneCoords(pos, getProjectionSpaceCoords(mSelectionMode->getDragStart())); - mSelectionMode->dragEnded (mousePlanePoint, mDragMode); + mSelectionMode->dragEnded(mousePlanePoint, mDragMode); mDragMode = DragMode_None; } void CSVRender::InstanceMode::deleteSelectedInstances(bool active) { - std::vector > selection = getWorldspaceWidget().getSelection (Mask_Reference); - if (selection.empty()) return; + std::vector> selection = getWorldspaceWidget().getSelection(Mask_Reference); + if (selection.empty()) + return; CSMDoc::Document& document = getWorldspaceWidget().getDocument(); - CSMWorld::IdTable& referencesTable = dynamic_cast ( - *document.getData().getTableModel (CSMWorld::UniversalId::Type_References)); + CSMWorld::IdTable& referencesTable + = dynamic_cast(*document.getData().getTableModel(CSMWorld::UniversalId::Type_References)); QUndoStack& undoStack = document.getUndoStack(); - CSMWorld::CommandMacro macro (undoStack, "Delete Instances"); - for(osg::ref_ptr tag: selection) - if (CSVRender::ObjectTag *objectTag = dynamic_cast (tag.get())) + CSMWorld::CommandMacro macro(undoStack, "Delete Instances"); + for (osg::ref_ptr tag : selection) + if (CSVRender::ObjectTag* objectTag = dynamic_cast(tag.get())) macro.push(new CSMWorld::DeleteCommand(referencesTable, objectTag->mObject->getReferenceId())); - getWorldspaceWidget().clearSelection (Mask_Reference); + getWorldspaceWidget().clearSelection(Mask_Reference); } void CSVRender::InstanceMode::dropInstance(CSVRender::Object* object, float dropHeight) @@ -940,8 +970,8 @@ float CSVRender::InstanceMode::calculateDropHeight(DropMode dropMode, CSVRender: osg::Vec3d end = point; end.z() = std::numeric_limits::lowest(); - osg::ref_ptr intersector (new osgUtil::LineSegmentIntersector( - osgUtil::Intersector::MODEL, start, end) ); + osg::ref_ptr intersector( + new osgUtil::LineSegmentIntersector(osgUtil::Intersector::MODEL, start, end)); intersector->setIntersectionLimit(osgUtil::LineSegmentIntersector::NO_LIMIT); osgUtil::IntersectionVisitor visitor(intersector); @@ -985,18 +1015,18 @@ void CSVRender::InstanceMode::dropSelectedInstancesToTerrainSeparately() void CSVRender::InstanceMode::handleDropMethod(DropMode dropMode, QString commandMsg) { - std::vector > selection = getWorldspaceWidget().getSelection (Mask_Reference); + std::vector> selection = getWorldspaceWidget().getSelection(Mask_Reference); if (selection.empty()) return; CSMDoc::Document& document = getWorldspaceWidget().getDocument(); QUndoStack& undoStack = document.getUndoStack(); - CSMWorld::CommandMacro macro (undoStack, commandMsg); + CSMWorld::CommandMacro macro(undoStack, commandMsg); DropObjectHeightHandler dropObjectDataHandler(&getWorldspaceWidget()); - if(dropMode & Separate) + if (dropMode & Separate) { int counter = 0; for (osg::ref_ptr tag : selection) @@ -1034,10 +1064,10 @@ void CSVRender::InstanceMode::handleDropMethod(DropMode dropMode, QString comman CSVRender::DropObjectHeightHandler::DropObjectHeightHandler(WorldspaceWidget* worldspacewidget) : mWorldspaceWidget(worldspacewidget) { - std::vector > selection = mWorldspaceWidget->getSelection (Mask_Reference); - for(osg::ref_ptr tag: selection) + std::vector> selection = mWorldspaceWidget->getSelection(Mask_Reference); + for (osg::ref_ptr tag : selection) { - if (CSVRender::ObjectTag *objectTag = dynamic_cast (tag.get())) + if (CSVRender::ObjectTag* objectTag = dynamic_cast(tag.get())) { osg::ref_ptr objectNodeWithGUI = objectTag->mObject->getRootNode(); osg::ref_ptr objectNodeWithoutGUI = objectTag->mObject->getBaseNode(); @@ -1060,11 +1090,11 @@ CSVRender::DropObjectHeightHandler::DropObjectHeightHandler(WorldspaceWidget* wo CSVRender::DropObjectHeightHandler::~DropObjectHeightHandler() { - std::vector > selection = mWorldspaceWidget->getSelection (Mask_Reference); + std::vector> selection = mWorldspaceWidget->getSelection(Mask_Reference); int counter = 0; - for(osg::ref_ptr tag: selection) + for (osg::ref_ptr tag : selection) { - if (CSVRender::ObjectTag *objectTag = dynamic_cast (tag.get())) + if (CSVRender::ObjectTag* objectTag = dynamic_cast(tag.get())) { osg::ref_ptr objectNodeWithGUI = objectTag->mObject->getRootNode(); objectNodeWithGUI->setNodeMask(mOldMasks[counter]); diff --git a/apps/opencs/view/render/instancemode.hpp b/apps/opencs/view/render/instancemode.hpp index feb307807a..814afd2293 100644 --- a/apps/opencs/view/render/instancemode.hpp +++ b/apps/opencs/view/render/instancemode.hpp @@ -3,10 +3,10 @@ #include -#include #include #include #include +#include #include "editmode.hpp" #include "instancedragmodes.hpp" @@ -24,115 +24,115 @@ namespace CSVRender class InstanceMode : public EditMode { - Q_OBJECT - - enum DropMode - { - Separate = 0b1, + Q_OBJECT - Collision = 0b10, - Terrain = 0b100, + enum DropMode + { + Separate = 0b1, - CollisionSep = Collision | Separate, - TerrainSep = Terrain | Separate, - }; + Collision = 0b10, + Terrain = 0b100, - CSVWidget::SceneToolMode *mSubMode; - std::string mSubModeId; - InstanceSelectionMode *mSelectionMode; - DragMode mDragMode; - int mDragAxis; - bool mLocked; - float mUnitScaleDist; - osg::ref_ptr mParentNode; - osg::Vec3f mDragStart; - std::vector mObjectsAtDragStart; + CollisionSep = Collision | Separate, + TerrainSep = Terrain | Separate, + }; - int getSubModeFromId (const std::string& id) const; + CSVWidget::SceneToolMode* mSubMode; + std::string mSubModeId; + InstanceSelectionMode* mSelectionMode; + DragMode mDragMode; + int mDragAxis; + bool mLocked; + float mUnitScaleDist; + osg::ref_ptr mParentNode; + osg::Vec3f mDragStart; + std::vector mObjectsAtDragStart; - osg::Vec3f quatToEuler(const osg::Quat& quat) const; - osg::Quat eulerToQuat(const osg::Vec3f& euler) const; + int getSubModeFromId(const std::string& id) const; - float roundFloatToMult(const float val, const double mult) const; + osg::Vec3f quatToEuler(const osg::Quat& quat) const; + osg::Quat eulerToQuat(const osg::Vec3f& euler) const; - osg::Vec3f getSelectionCenter(const std::vector >& selection) const; - osg::Vec3f getScreenCoords(const osg::Vec3f& pos); - osg::Vec3f getProjectionSpaceCoords(const osg::Vec3f& pos); - osg::Vec3f getMousePlaneCoords(const QPoint& point, const osg::Vec3d& dragStart); - void handleSelectDrag(const QPoint& pos); - void dropInstance(CSVRender::Object* object, float dropHeight); - float calculateDropHeight(DropMode dropMode, CSVRender::Object* object, float objectHeight); + float roundFloatToMult(const float val, const double mult) const; - public: + osg::Vec3f getSelectionCenter(const std::vector>& selection) const; + osg::Vec3f getScreenCoords(const osg::Vec3f& pos); + osg::Vec3f getProjectionSpaceCoords(const osg::Vec3f& pos); + osg::Vec3f getMousePlaneCoords(const QPoint& point, const osg::Vec3d& dragStart); + void handleSelectDrag(const QPoint& pos); + void dropInstance(CSVRender::Object* object, float dropHeight); + float calculateDropHeight(DropMode dropMode, CSVRender::Object* object, float objectHeight); - InstanceMode (WorldspaceWidget *worldspaceWidget, osg::ref_ptr parentNode, QWidget *parent = nullptr); + public: + InstanceMode( + WorldspaceWidget* worldspaceWidget, osg::ref_ptr parentNode, QWidget* parent = nullptr); - void activate (CSVWidget::SceneToolbar *toolbar) override; + void activate(CSVWidget::SceneToolbar* toolbar) override; - void deactivate (CSVWidget::SceneToolbar *toolbar) override; + void deactivate(CSVWidget::SceneToolbar* toolbar) override; - void setEditLock (bool locked) override; + void setEditLock(bool locked) override; - void primaryOpenPressed (const WorldspaceHitResult& hit) override; + void primaryOpenPressed(const WorldspaceHitResult& hit) override; - void primaryEditPressed (const WorldspaceHitResult& hit) override; + void primaryEditPressed(const WorldspaceHitResult& hit) override; - void secondaryEditPressed (const WorldspaceHitResult& hit) override; + void secondaryEditPressed(const WorldspaceHitResult& hit) override; - void primarySelectPressed (const WorldspaceHitResult& hit) override; + void primarySelectPressed(const WorldspaceHitResult& hit) override; - void secondarySelectPressed (const WorldspaceHitResult& hit) override; + void secondarySelectPressed(const WorldspaceHitResult& hit) override; - bool primaryEditStartDrag (const QPoint& pos) override; + bool primaryEditStartDrag(const QPoint& pos) override; - bool secondaryEditStartDrag (const QPoint& pos) override; + bool secondaryEditStartDrag(const QPoint& pos) override; - bool primarySelectStartDrag(const QPoint& pos) override; + bool primarySelectStartDrag(const QPoint& pos) override; - bool secondarySelectStartDrag(const QPoint& pos) override; + bool secondarySelectStartDrag(const QPoint& pos) override; - void drag (const QPoint& pos, int diffX, int diffY, double speedFactor) override; + void drag(const QPoint& pos, int diffX, int diffY, double speedFactor) override; - void dragCompleted(const QPoint& pos) override; + void dragCompleted(const QPoint& pos) override; - /// \note dragAborted will not be called, if the drag is aborted via changing - /// editing mode - void dragAborted() override; + /// \note dragAborted will not be called, if the drag is aborted via changing + /// editing mode + void dragAborted() override; - void dragWheel (int diff, double speedFactor) override; + void dragWheel(int diff, double speedFactor) override; - void dragEnterEvent (QDragEnterEvent *event) override; + void dragEnterEvent(QDragEnterEvent* event) override; - void dropEvent (QDropEvent *event) override; + void dropEvent(QDropEvent* event) override; - int getSubMode() const override; + int getSubMode() const override; - signals: + signals: - void requestFocus (const std::string& id); + void requestFocus(const std::string& id); - private slots: + private slots: - void subModeChanged (const std::string& id); - void deleteSelectedInstances(bool active); - void dropSelectedInstancesToCollision(); - void dropSelectedInstancesToTerrain(); - void dropSelectedInstancesToCollisionSeparately(); - void dropSelectedInstancesToTerrainSeparately(); - void handleDropMethod(DropMode dropMode, QString commandMsg); + void subModeChanged(const std::string& id); + void deleteSelectedInstances(bool active); + void dropSelectedInstancesToCollision(); + void dropSelectedInstancesToTerrain(); + void dropSelectedInstancesToCollisionSeparately(); + void dropSelectedInstancesToTerrainSeparately(); + void handleDropMethod(DropMode dropMode, QString commandMsg); }; /// \brief Helper class to handle object mask data in safe way class DropObjectHeightHandler { - public: - DropObjectHeightHandler(WorldspaceWidget* worldspacewidget); - ~DropObjectHeightHandler(); - std::vector mObjectHeights; - - private: - WorldspaceWidget* mWorldspaceWidget; - std::vector mOldMasks; + public: + DropObjectHeightHandler(WorldspaceWidget* worldspacewidget); + ~DropObjectHeightHandler(); + std::vector mObjectHeights; + + private: + WorldspaceWidget* mWorldspaceWidget; + std::vector mOldMasks; }; } diff --git a/apps/opencs/view/render/instancemovemode.cpp b/apps/opencs/view/render/instancemovemode.cpp index 5591035492..a4582ec252 100644 --- a/apps/opencs/view/render/instancemovemode.cpp +++ b/apps/opencs/view/render/instancemovemode.cpp @@ -1,11 +1,12 @@ #include "instancemovemode.hpp" -CSVRender::InstanceMoveMode::InstanceMoveMode (QWidget *parent) -: ModeButton (QIcon (QPixmap (":scenetoolbar/transform-move")), - "Move selected instances" - "
  • Use {scene-edit-primary} to move instances around freely
  • " - "
  • Use {scene-edit-secondary} to move instances around within the grid
  • " - "
", - parent) -{} +CSVRender::InstanceMoveMode::InstanceMoveMode(QWidget* parent) + : ModeButton(QIcon(QPixmap(":scenetoolbar/transform-move")), + "Move selected instances" + "
  • Use {scene-edit-primary} to move instances around freely
  • " + "
  • Use {scene-edit-secondary} to move instances around within the grid
  • " + "
", + parent) +{ +} diff --git a/apps/opencs/view/render/instancemovemode.hpp b/apps/opencs/view/render/instancemovemode.hpp index 62e6b6a1f8..fd7ed9d3f8 100644 --- a/apps/opencs/view/render/instancemovemode.hpp +++ b/apps/opencs/view/render/instancemovemode.hpp @@ -7,11 +7,10 @@ namespace CSVRender { class InstanceMoveMode : public CSVWidget::ModeButton { - Q_OBJECT + Q_OBJECT - public: - - InstanceMoveMode (QWidget *parent = nullptr); + public: + InstanceMoveMode(QWidget* parent = nullptr); }; } diff --git a/apps/opencs/view/render/instanceselectionmode.cpp b/apps/opencs/view/render/instanceselectionmode.cpp index beabec7aad..8506646510 100644 --- a/apps/opencs/view/render/instanceselectionmode.cpp +++ b/apps/opencs/view/render/instanceselectionmode.cpp @@ -1,25 +1,27 @@ #include "instanceselectionmode.hpp" -#include #include +#include #include #include #include -#include #include +#include -#include "../../model/world/idtable.hpp" #include "../../model/world/commands.hpp" +#include "../../model/world/idtable.hpp" #include "instancedragmodes.hpp" -#include "worldspacewidget.hpp" #include "object.hpp" +#include "worldspacewidget.hpp" namespace CSVRender { - InstanceSelectionMode::InstanceSelectionMode(CSVWidget::SceneToolbar* parent, WorldspaceWidget& worldspaceWidget, osg::Group *cellNode) - : SelectionMode(parent, worldspaceWidget, Mask_Reference), mParentNode(cellNode) + InstanceSelectionMode::InstanceSelectionMode( + CSVWidget::SceneToolbar* parent, WorldspaceWidget& worldspaceWidget, osg::Group* cellNode) + : SelectionMode(parent, worldspaceWidget, Mask_Reference) + , mParentNode(cellNode) { mSelectSame = new QAction("Extend selection to instances with same object ID", this); mDeleteSelection = new QAction("Delete selected instances", this); @@ -46,7 +48,8 @@ namespace CSVRender void InstanceSelectionMode::dragEnded(const osg::Vec3d& dragEndPoint, DragMode dragMode) { float dragDistance = (mDragStart - dragEndPoint).length(); - if (mBaseNode) mParentNode->removeChild (mBaseNode); + if (mBaseNode) + mParentNode->removeChild(mBaseNode); if (getCurrentId() == "cube-centre") { osg::Vec3d pointA(mDragStart[0] - dragDistance, mDragStart[1] - dragDistance, mDragStart[2] - dragDistance); @@ -76,196 +79,198 @@ namespace CSVRender void InstanceSelectionMode::drawSelectionBox(const osg::Vec3d& pointA, const osg::Vec3d& pointB) { - if (mBaseNode) mParentNode->removeChild (mBaseNode); + if (mBaseNode) + mParentNode->removeChild(mBaseNode); mBaseNode = new osg::PositionAttitudeTransform; mBaseNode->setPosition(pointA); - osg::ref_ptr geometry (new osg::Geometry); + osg::ref_ptr geometry(new osg::Geometry); - osg::Vec3Array *vertices = new osg::Vec3Array; - vertices->push_back (osg::Vec3f (0.0f, 0.0f, 0.0f)); - vertices->push_back (osg::Vec3f (0.0f, 0.0f, pointB[2] - pointA[2])); - vertices->push_back (osg::Vec3f (0.0f, pointB[1] - pointA[1], 0.0f)); - vertices->push_back (osg::Vec3f (0.0f, pointB[1] - pointA[1], pointB[2] - pointA[2])); + osg::Vec3Array* vertices = new osg::Vec3Array; + vertices->push_back(osg::Vec3f(0.0f, 0.0f, 0.0f)); + vertices->push_back(osg::Vec3f(0.0f, 0.0f, pointB[2] - pointA[2])); + vertices->push_back(osg::Vec3f(0.0f, pointB[1] - pointA[1], 0.0f)); + vertices->push_back(osg::Vec3f(0.0f, pointB[1] - pointA[1], pointB[2] - pointA[2])); - vertices->push_back (osg::Vec3f (pointB[0] - pointA[0], 0.0f, 0.0f)); - vertices->push_back (osg::Vec3f (pointB[0] - pointA[0], 0.0f, pointB[2] - pointA[2])); - vertices->push_back (osg::Vec3f (pointB[0] - pointA[0], pointB[1] - pointA[1], 0.0f)); - vertices->push_back (osg::Vec3f (pointB[0] - pointA[0], pointB[1] - pointA[1], pointB[2] - pointA[2])); + vertices->push_back(osg::Vec3f(pointB[0] - pointA[0], 0.0f, 0.0f)); + vertices->push_back(osg::Vec3f(pointB[0] - pointA[0], 0.0f, pointB[2] - pointA[2])); + vertices->push_back(osg::Vec3f(pointB[0] - pointA[0], pointB[1] - pointA[1], 0.0f)); + vertices->push_back(osg::Vec3f(pointB[0] - pointA[0], pointB[1] - pointA[1], pointB[2] - pointA[2])); - geometry->setVertexArray (vertices); + geometry->setVertexArray(vertices); - osg::DrawElementsUShort *primitives = new osg::DrawElementsUShort (osg::PrimitiveSet::TRIANGLES, 0); + osg::DrawElementsUShort* primitives = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES, 0); // top - primitives->push_back (2); - primitives->push_back (1); - primitives->push_back (0); + primitives->push_back(2); + primitives->push_back(1); + primitives->push_back(0); - primitives->push_back (3); - primitives->push_back (1); - primitives->push_back (2); + primitives->push_back(3); + primitives->push_back(1); + primitives->push_back(2); // bottom - primitives->push_back (4); - primitives->push_back (5); - primitives->push_back (6); + primitives->push_back(4); + primitives->push_back(5); + primitives->push_back(6); - primitives->push_back (6); - primitives->push_back (5); - primitives->push_back (7); + primitives->push_back(6); + primitives->push_back(5); + primitives->push_back(7); // sides - primitives->push_back (1); - primitives->push_back (4); - primitives->push_back (0); + primitives->push_back(1); + primitives->push_back(4); + primitives->push_back(0); - primitives->push_back (4); - primitives->push_back (1); - primitives->push_back (5); + primitives->push_back(4); + primitives->push_back(1); + primitives->push_back(5); - primitives->push_back (4); - primitives->push_back (2); - primitives->push_back (0); + primitives->push_back(4); + primitives->push_back(2); + primitives->push_back(0); - primitives->push_back (6); - primitives->push_back (2); - primitives->push_back (4); + primitives->push_back(6); + primitives->push_back(2); + primitives->push_back(4); - primitives->push_back (6); - primitives->push_back (3); - primitives->push_back (2); + primitives->push_back(6); + primitives->push_back(3); + primitives->push_back(2); - primitives->push_back (7); - primitives->push_back (3); - primitives->push_back (6); + primitives->push_back(7); + primitives->push_back(3); + primitives->push_back(6); - primitives->push_back (1); - primitives->push_back (3); - primitives->push_back (5); + primitives->push_back(1); + primitives->push_back(3); + primitives->push_back(5); - primitives->push_back (5); - primitives->push_back (3); - primitives->push_back (7); + primitives->push_back(5); + primitives->push_back(3); + primitives->push_back(7); - geometry->addPrimitiveSet (primitives); + geometry->addPrimitiveSet(primitives); - osg::Vec4Array *colours = new osg::Vec4Array; + osg::Vec4Array* colours = new osg::Vec4Array; - colours->push_back (osg::Vec4f (0.3f, 0.3f, 0.5f, 0.2f)); - colours->push_back (osg::Vec4f (0.9f, 0.9f, 1.0f, 0.2f)); - colours->push_back (osg::Vec4f (0.3f, 0.3f, 0.4f, 0.2f)); - colours->push_back (osg::Vec4f (0.9f, 0.9f, 1.0f, 0.2f)); - colours->push_back (osg::Vec4f (0.3f, 0.3f, 0.4f, 0.2f)); - colours->push_back (osg::Vec4f (0.9f, 0.9f, 1.0f, 0.2f)); - colours->push_back (osg::Vec4f (0.3f, 0.3f, 0.4f, 0.2f)); - colours->push_back (osg::Vec4f (0.9f, 0.9f, 1.0f, 0.2f)); + colours->push_back(osg::Vec4f(0.3f, 0.3f, 0.5f, 0.2f)); + colours->push_back(osg::Vec4f(0.9f, 0.9f, 1.0f, 0.2f)); + colours->push_back(osg::Vec4f(0.3f, 0.3f, 0.4f, 0.2f)); + colours->push_back(osg::Vec4f(0.9f, 0.9f, 1.0f, 0.2f)); + colours->push_back(osg::Vec4f(0.3f, 0.3f, 0.4f, 0.2f)); + colours->push_back(osg::Vec4f(0.9f, 0.9f, 1.0f, 0.2f)); + colours->push_back(osg::Vec4f(0.3f, 0.3f, 0.4f, 0.2f)); + colours->push_back(osg::Vec4f(0.9f, 0.9f, 1.0f, 0.2f)); - geometry->setColorArray (colours, osg::Array::BIND_PER_VERTEX); + geometry->setColorArray(colours, osg::Array::BIND_PER_VERTEX); - geometry->getOrCreateStateSet()->setMode (GL_LIGHTING, osg::StateAttribute::OFF); - geometry->getOrCreateStateSet()->setMode (GL_BLEND, osg::StateAttribute::ON); + geometry->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); + geometry->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON); geometry->getOrCreateStateSet()->setMode(GL_CULL_FACE, osg::StateAttribute::OFF); geometry->getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); - mBaseNode->addChild (geometry); + mBaseNode->addChild(geometry); mParentNode->addChild(mBaseNode); } void InstanceSelectionMode::drawSelectionCube(const osg::Vec3d& point, float radius) { - if (mBaseNode) mParentNode->removeChild (mBaseNode); + if (mBaseNode) + mParentNode->removeChild(mBaseNode); mBaseNode = new osg::PositionAttitudeTransform; mBaseNode->setPosition(point); - osg::ref_ptr geometry (new osg::Geometry); + osg::ref_ptr geometry(new osg::Geometry); - osg::Vec3Array *vertices = new osg::Vec3Array; + osg::Vec3Array* vertices = new osg::Vec3Array; for (int i = 0; i < 2; ++i) { float height = i ? -radius : radius; - vertices->push_back (osg::Vec3f (height, -radius, -radius)); - vertices->push_back (osg::Vec3f (height, -radius, radius)); - vertices->push_back (osg::Vec3f (height, radius, -radius)); - vertices->push_back (osg::Vec3f (height, radius, radius)); + vertices->push_back(osg::Vec3f(height, -radius, -radius)); + vertices->push_back(osg::Vec3f(height, -radius, radius)); + vertices->push_back(osg::Vec3f(height, radius, -radius)); + vertices->push_back(osg::Vec3f(height, radius, radius)); } - geometry->setVertexArray (vertices); + geometry->setVertexArray(vertices); - osg::DrawElementsUShort *primitives = new osg::DrawElementsUShort (osg::PrimitiveSet::TRIANGLES, 0); + osg::DrawElementsUShort* primitives = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES, 0); // top - primitives->push_back (2); - primitives->push_back (1); - primitives->push_back (0); + primitives->push_back(2); + primitives->push_back(1); + primitives->push_back(0); - primitives->push_back (3); - primitives->push_back (1); - primitives->push_back (2); + primitives->push_back(3); + primitives->push_back(1); + primitives->push_back(2); // bottom - primitives->push_back (4); - primitives->push_back (5); - primitives->push_back (6); + primitives->push_back(4); + primitives->push_back(5); + primitives->push_back(6); - primitives->push_back (6); - primitives->push_back (5); - primitives->push_back (7); + primitives->push_back(6); + primitives->push_back(5); + primitives->push_back(7); // sides - primitives->push_back (1); - primitives->push_back (4); - primitives->push_back (0); + primitives->push_back(1); + primitives->push_back(4); + primitives->push_back(0); - primitives->push_back (4); - primitives->push_back (1); - primitives->push_back (5); + primitives->push_back(4); + primitives->push_back(1); + primitives->push_back(5); - primitives->push_back (4); - primitives->push_back (2); - primitives->push_back (0); + primitives->push_back(4); + primitives->push_back(2); + primitives->push_back(0); - primitives->push_back (6); - primitives->push_back (2); - primitives->push_back (4); + primitives->push_back(6); + primitives->push_back(2); + primitives->push_back(4); - primitives->push_back (6); - primitives->push_back (3); - primitives->push_back (2); + primitives->push_back(6); + primitives->push_back(3); + primitives->push_back(2); - primitives->push_back (7); - primitives->push_back (3); - primitives->push_back (6); + primitives->push_back(7); + primitives->push_back(3); + primitives->push_back(6); - primitives->push_back (1); - primitives->push_back (3); - primitives->push_back (5); + primitives->push_back(1); + primitives->push_back(3); + primitives->push_back(5); - primitives->push_back (5); - primitives->push_back (3); - primitives->push_back (7); + primitives->push_back(5); + primitives->push_back(3); + primitives->push_back(7); - geometry->addPrimitiveSet (primitives); + geometry->addPrimitiveSet(primitives); - osg::Vec4Array *colours = new osg::Vec4Array; + osg::Vec4Array* colours = new osg::Vec4Array; - colours->push_back (osg::Vec4f (0.3f, 0.3f, 0.5f, 0.2f)); - colours->push_back (osg::Vec4f (0.9f, 0.9f, 1.0f, 0.2f)); - colours->push_back (osg::Vec4f (0.3f, 0.3f, 0.4f, 0.2f)); - colours->push_back (osg::Vec4f (0.9f, 0.9f, 1.0f, 0.2f)); - colours->push_back (osg::Vec4f (0.3f, 0.3f, 0.4f, 0.2f)); - colours->push_back (osg::Vec4f (0.9f, 0.9f, 1.0f, 0.2f)); - colours->push_back (osg::Vec4f (0.3f, 0.3f, 0.4f, 0.2f)); - colours->push_back (osg::Vec4f (0.9f, 0.9f, 1.0f, 0.2f)); + colours->push_back(osg::Vec4f(0.3f, 0.3f, 0.5f, 0.2f)); + colours->push_back(osg::Vec4f(0.9f, 0.9f, 1.0f, 0.2f)); + colours->push_back(osg::Vec4f(0.3f, 0.3f, 0.4f, 0.2f)); + colours->push_back(osg::Vec4f(0.9f, 0.9f, 1.0f, 0.2f)); + colours->push_back(osg::Vec4f(0.3f, 0.3f, 0.4f, 0.2f)); + colours->push_back(osg::Vec4f(0.9f, 0.9f, 1.0f, 0.2f)); + colours->push_back(osg::Vec4f(0.3f, 0.3f, 0.4f, 0.2f)); + colours->push_back(osg::Vec4f(0.9f, 0.9f, 1.0f, 0.2f)); - geometry->setColorArray (colours, osg::Array::BIND_PER_VERTEX); + geometry->setColorArray(colours, osg::Array::BIND_PER_VERTEX); - geometry->getOrCreateStateSet()->setMode (GL_LIGHTING, osg::StateAttribute::OFF); - geometry->getOrCreateStateSet()->setMode (GL_BLEND, osg::StateAttribute::ON); + geometry->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); + geometry->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON); geometry->getOrCreateStateSet()->setMode(GL_CULL_FACE, osg::StateAttribute::OFF); geometry->getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); - mBaseNode->addChild (geometry); + mBaseNode->addChild(geometry); mParentNode->addChild(mBaseNode); } @@ -277,32 +282,33 @@ namespace CSVRender void InstanceSelectionMode::drawSelectionSphere(const osg::Vec3d& point, float radius) { - if (mBaseNode) mParentNode->removeChild (mBaseNode); + if (mBaseNode) + mParentNode->removeChild(mBaseNode); mBaseNode = new osg::PositionAttitudeTransform; mBaseNode->setPosition(point); - osg::ref_ptr geometry (new osg::Geometry); + osg::ref_ptr geometry(new osg::Geometry); - osg::Vec3Array *vertices = new osg::Vec3Array; + osg::Vec3Array* vertices = new osg::Vec3Array; constexpr int resolution = 32; float radiusPerResolution = radius / resolution; float reciprocalResolution = 1.0f / resolution; float doubleReciprocalRes = reciprocalResolution * 2; - osg::Vec4Array *colours = new osg::Vec4Array; + osg::Vec4Array* colours = new osg::Vec4Array; for (int i = 0; i <= resolution; i += 2) { float iShifted = (static_cast(i) - resolution / 2.0f); // i - 16 = -16 ... 16 float xPercentile = iShifted * doubleReciprocalRes; float x = xPercentile * radius; - float thisRadius = sqrt (radius * radius - x * x); + float thisRadius = sqrt(radius * radius - x * x); - //the next row + // the next row float iShifted2 = (static_cast(i + 1) - resolution / 2.0f); float xPercentile2 = iShifted2 * doubleReciprocalRes; float x2 = xPercentile2 * radius; - float thisRadius2 = sqrt (radius * radius - x2 * x2); + float thisRadius2 = sqrt(radius * radius - x2 * x2); for (int j = 0; j < resolution; ++j) { @@ -310,57 +316,62 @@ namespace CSVRender float vertexY = i * radiusPerResolution * 2 - radius; float vertexZ = thisRadius * cos(j * reciprocalResolution * osg::PI * 2); float heightPercentage = (vertexZ + radius) / (radius * 2); - vertices->push_back (osg::Vec3f (vertexX, vertexY, vertexZ)); - colours->push_back (osg::Vec4f (heightPercentage, heightPercentage, heightPercentage, 0.3f)); + vertices->push_back(osg::Vec3f(vertexX, vertexY, vertexZ)); + colours->push_back(osg::Vec4f(heightPercentage, heightPercentage, heightPercentage, 0.3f)); float vertexNextRowX = thisRadius2 * sin(j * reciprocalResolution * osg::PI * 2); float vertexNextRowY = (i + 1) * radiusPerResolution * 2 - radius; float vertexNextRowZ = thisRadius2 * cos(j * reciprocalResolution * osg::PI * 2); float heightPercentageNextRow = (vertexZ + radius) / (radius * 2); - vertices->push_back (osg::Vec3f (vertexNextRowX, vertexNextRowY, vertexNextRowZ)); - colours->push_back (osg::Vec4f (heightPercentageNextRow, heightPercentageNextRow, heightPercentageNextRow, 0.3f)); + vertices->push_back(osg::Vec3f(vertexNextRowX, vertexNextRowY, vertexNextRowZ)); + colours->push_back( + osg::Vec4f(heightPercentageNextRow, heightPercentageNextRow, heightPercentageNextRow, 0.3f)); } } - geometry->setVertexArray (vertices); + geometry->setVertexArray(vertices); - osg::DrawElementsUShort *primitives = new osg::DrawElementsUShort (osg::PrimitiveSet::TRIANGLE_STRIP, 0); + osg::DrawElementsUShort* primitives = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLE_STRIP, 0); for (int i = 0; i < resolution; ++i) { - //Even + // Even for (int j = 0; j < resolution * 2; ++j) { - if (i * resolution * 2 + j > static_cast(vertices->size()) - 1) continue; - primitives->push_back (i * resolution * 2 + j); + if (i * resolution * 2 + j > static_cast(vertices->size()) - 1) + continue; + primitives->push_back(i * resolution * 2 + j); } - if (i * resolution * 2 > static_cast(vertices->size()) - 1) continue; - primitives->push_back (i * resolution * 2); - primitives->push_back (i * resolution * 2 + 1); + if (i * resolution * 2 > static_cast(vertices->size()) - 1) + continue; + primitives->push_back(i * resolution * 2); + primitives->push_back(i * resolution * 2 + 1); - //Odd + // Odd for (int j = 1; j < resolution * 2 - 2; j += 2) { - if ((i + 1) * resolution * 2 + j - 1 > static_cast(vertices->size()) - 1) continue; - primitives->push_back ((i + 1) * resolution * 2 + j - 1); - primitives->push_back (i * resolution * 2 + j + 2); + if ((i + 1) * resolution * 2 + j - 1 > static_cast(vertices->size()) - 1) + continue; + primitives->push_back((i + 1) * resolution * 2 + j - 1); + primitives->push_back(i * resolution * 2 + j + 2); } - if ((i + 2) * resolution * 2 - 2 > static_cast(vertices->size()) - 1) continue; - primitives->push_back ((i + 2) * resolution * 2 - 2); - primitives->push_back (i * resolution * 2 + 1); - primitives->push_back ((i + 1) * resolution * 2); + if ((i + 2) * resolution * 2 - 2 > static_cast(vertices->size()) - 1) + continue; + primitives->push_back((i + 2) * resolution * 2 - 2); + primitives->push_back(i * resolution * 2 + 1); + primitives->push_back((i + 1) * resolution * 2); } - geometry->addPrimitiveSet (primitives); + geometry->addPrimitiveSet(primitives); - geometry->setColorArray (colours, osg::Array::BIND_PER_VERTEX); + geometry->setColorArray(colours, osg::Array::BIND_PER_VERTEX); - geometry->getOrCreateStateSet()->setMode (GL_LIGHTING, osg::StateAttribute::OFF); - geometry->getOrCreateStateSet()->setMode (GL_BLEND, osg::StateAttribute::ON); + geometry->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); + geometry->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON); geometry->getOrCreateStateSet()->setMode(GL_CULL_FACE, osg::StateAttribute::OFF); geometry->getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); - mBaseNode->addChild (geometry); + mBaseNode->addChild(geometry); mParentNode->addChild(mBaseNode); } @@ -384,15 +395,15 @@ namespace CSVRender void InstanceSelectionMode::deleteSelection() { - std::vector > selection = getWorldspaceWidget().getSelection(Mask_Reference); + std::vector> selection = getWorldspaceWidget().getSelection(Mask_Reference); CSMWorld::IdTable& referencesTable = dynamic_cast( *getWorldspaceWidget().getDocument().getData().getTableModel(CSMWorld::UniversalId::Type_References)); - for (std::vector >::iterator iter = selection.begin(); iter != selection.end(); ++iter) + for (std::vector>::iterator iter = selection.begin(); iter != selection.end(); ++iter) { - CSMWorld::DeleteCommand* command = new CSMWorld::DeleteCommand(referencesTable, - static_cast(iter->get())->mObject->getReferenceId()); + CSMWorld::DeleteCommand* command = new CSMWorld::DeleteCommand( + referencesTable, static_cast(iter->get())->mObject->getReferenceId()); getWorldspaceWidget().getDocument().getUndoStack().push(command); } diff --git a/apps/opencs/view/render/instanceselectionmode.hpp b/apps/opencs/view/render/instanceselectionmode.hpp index 81795d5d3e..cd5afd5d1a 100644 --- a/apps/opencs/view/render/instanceselectionmode.hpp +++ b/apps/opencs/view/render/instanceselectionmode.hpp @@ -6,62 +6,61 @@ #include #include -#include "selectionmode.hpp" #include "instancedragmodes.hpp" +#include "selectionmode.hpp" namespace CSVRender { class InstanceSelectionMode : public SelectionMode { - Q_OBJECT - - public: - - InstanceSelectionMode(CSVWidget::SceneToolbar* parent, WorldspaceWidget& worldspaceWidget, osg::Group *cellNode); + Q_OBJECT - ~InstanceSelectionMode(); + public: + InstanceSelectionMode( + CSVWidget::SceneToolbar* parent, WorldspaceWidget& worldspaceWidget, osg::Group* cellNode); - /// Store the worldspace-coordinate when drag begins - void setDragStart(const osg::Vec3d& dragStart); + ~InstanceSelectionMode(); - /// Store the worldspace-coordinate when drag begins - const osg::Vec3d& getDragStart(); + /// Store the worldspace-coordinate when drag begins + void setDragStart(const osg::Vec3d& dragStart); - /// Store the screen-coordinate when drag begins - void setScreenDragStart(const QPoint& dragStartPoint); + /// Store the worldspace-coordinate when drag begins + const osg::Vec3d& getDragStart(); - /// Apply instance selection changes - void dragEnded(const osg::Vec3d& dragEndPoint, DragMode dragMode); + /// Store the screen-coordinate when drag begins + void setScreenDragStart(const QPoint& dragStartPoint); - void drawSelectionCubeCentre(const osg::Vec3f& mousePlanePoint ); - void drawSelectionCubeCorner(const osg::Vec3f& mousePlanePoint ); - void drawSelectionSphere(const osg::Vec3f& mousePlanePoint ); - protected: + /// Apply instance selection changes + void dragEnded(const osg::Vec3d& dragEndPoint, DragMode dragMode); - /// Add context menu items to \a menu. - /// - /// \attention menu can be a 0-pointer - /// - /// \return Have there been any menu items to be added (if menu is 0 and there - /// items to be added, the function must return true anyway. - bool createContextMenu(QMenu* menu) override; + void drawSelectionCubeCentre(const osg::Vec3f& mousePlanePoint); + void drawSelectionCubeCorner(const osg::Vec3f& mousePlanePoint); + void drawSelectionSphere(const osg::Vec3f& mousePlanePoint); - private: + protected: + /// Add context menu items to \a menu. + /// + /// \attention menu can be a 0-pointer + /// + /// \return Have there been any menu items to be added (if menu is 0 and there + /// items to be added, the function must return true anyway. + bool createContextMenu(QMenu* menu) override; - void drawSelectionBox(const osg::Vec3d& pointA, const osg::Vec3d& pointB); - void drawSelectionCube(const osg::Vec3d& point, float radius); - void drawSelectionSphere(const osg::Vec3d& point, float radius); + private: + void drawSelectionBox(const osg::Vec3d& pointA, const osg::Vec3d& pointB); + void drawSelectionCube(const osg::Vec3d& point, float radius); + void drawSelectionSphere(const osg::Vec3d& point, float radius); - QAction* mDeleteSelection; - QAction* mSelectSame; - osg::Vec3d mDragStart; - osg::Group* mParentNode; - osg::ref_ptr mBaseNode; + QAction* mDeleteSelection; + QAction* mSelectSame; + osg::Vec3d mDragStart; + osg::Group* mParentNode; + osg::ref_ptr mBaseNode; - private slots: + private slots: - void deleteSelection(); - void selectSame(); + void deleteSelection(); + void selectSame(); }; } diff --git a/apps/opencs/view/render/lighting.cpp b/apps/opencs/view/render/lighting.cpp index c7bee79289..93b343c2b7 100644 --- a/apps/opencs/view/render/lighting.cpp +++ b/apps/opencs/view/render/lighting.cpp @@ -15,9 +15,10 @@ public: DayNightSwitchVisitor(int index) : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) , mIndex(index) - { } + { + } - void apply(osg::Switch &switchNode) override + void apply(osg::Switch& switchNode) override { constexpr int NoIndex = -1; diff --git a/apps/opencs/view/render/lighting.hpp b/apps/opencs/view/render/lighting.hpp index d9d90767f0..28747dd765 100644 --- a/apps/opencs/view/render/lighting.hpp +++ b/apps/opencs/view/render/lighting.hpp @@ -14,23 +14,24 @@ namespace CSVRender { class Lighting { - public: + public: + Lighting() + : mRootNode(nullptr) + { + } + virtual ~Lighting(); - Lighting() : mRootNode(nullptr) {} - virtual ~Lighting(); + virtual void activate(osg::Group* rootNode, bool isExterior) = 0; - virtual void activate (osg::Group* rootNode, bool isExterior) = 0; + virtual void deactivate() = 0; - virtual void deactivate() = 0; + virtual osg::Vec4f getAmbientColour(osg::Vec4f* defaultAmbient) = 0; - virtual osg::Vec4f getAmbientColour(osg::Vec4f* defaultAmbient) = 0; + protected: + void updateDayNightMode(int index); - protected: - - void updateDayNightMode(int index); - - osg::ref_ptr mLightSource; - osg::Group* mRootNode; + osg::ref_ptr mLightSource; + osg::Group* mRootNode; }; } diff --git a/apps/opencs/view/render/lightingbright.cpp b/apps/opencs/view/render/lightingbright.cpp index d76823fb3c..f7649d42f5 100644 --- a/apps/opencs/view/render/lightingbright.cpp +++ b/apps/opencs/view/render/lightingbright.cpp @@ -4,13 +4,13 @@ CSVRender::LightingBright::LightingBright() {} -void CSVRender::LightingBright::activate (osg::Group* rootNode, bool /*isExterior*/) +void CSVRender::LightingBright::activate(osg::Group* rootNode, bool /*isExterior*/) { mRootNode = rootNode; mLightSource = (new osg::LightSource); - osg::ref_ptr light (new osg::Light); + osg::ref_ptr light(new osg::Light); light->setAmbient(osg::Vec4f(0.f, 0.f, 0.f, 1.f)); light->setPosition(osg::Vec4f(0.f, 0.f, 1.f, 0.f)); light->setDiffuse(osg::Vec4f(1.f, 1.f, 1.f, 1.f)); diff --git a/apps/opencs/view/render/lightingbright.hpp b/apps/opencs/view/render/lightingbright.hpp index aa14927524..0f7de195c1 100644 --- a/apps/opencs/view/render/lightingbright.hpp +++ b/apps/opencs/view/render/lightingbright.hpp @@ -13,15 +13,14 @@ namespace CSVRender { class LightingBright : public Lighting { - public: + public: + LightingBright(); - LightingBright(); + void activate(osg::Group* rootNode, bool /*isExterior*/) override; - void activate (osg::Group* rootNode, bool /*isExterior*/) override; + void deactivate() override; - void deactivate() override; - - osg::Vec4f getAmbientColour(osg::Vec4f* defaultAmbient) override; + osg::Vec4f getAmbientColour(osg::Vec4f* defaultAmbient) override; }; } diff --git a/apps/opencs/view/render/lightingday.cpp b/apps/opencs/view/render/lightingday.cpp index dc4592b21c..91b098c707 100644 --- a/apps/opencs/view/render/lightingday.cpp +++ b/apps/opencs/view/render/lightingday.cpp @@ -2,15 +2,15 @@ #include -CSVRender::LightingDay::LightingDay(){} +CSVRender::LightingDay::LightingDay() {} -void CSVRender::LightingDay::activate (osg::Group* rootNode, bool /*isExterior*/) +void CSVRender::LightingDay::activate(osg::Group* rootNode, bool /*isExterior*/) { mRootNode = rootNode; mLightSource = new osg::LightSource; - osg::ref_ptr light (new osg::Light); + osg::ref_ptr light(new osg::Light); light->setPosition(osg::Vec4f(0.f, 0.f, 1.f, 0.f)); light->setAmbient(osg::Vec4f(0.f, 0.f, 0.f, 1.f)); light->setDiffuse(osg::Vec4f(1.f, 1.f, 1.f, 1.f)); @@ -29,7 +29,7 @@ void CSVRender::LightingDay::deactivate() mRootNode->removeChild(mLightSource); } -osg::Vec4f CSVRender::LightingDay::getAmbientColour(osg::Vec4f *defaultAmbient) +osg::Vec4f CSVRender::LightingDay::getAmbientColour(osg::Vec4f* defaultAmbient) { if (defaultAmbient) return *defaultAmbient; diff --git a/apps/opencs/view/render/lightingday.hpp b/apps/opencs/view/render/lightingday.hpp index eafc6b8e81..fb7ff440b7 100644 --- a/apps/opencs/view/render/lightingday.hpp +++ b/apps/opencs/view/render/lightingday.hpp @@ -7,15 +7,14 @@ namespace CSVRender { class LightingDay : public Lighting { - public: + public: + LightingDay(); - LightingDay(); + void activate(osg::Group* rootNode, bool /*isExterior*/) override; - void activate (osg::Group* rootNode, bool /*isExterior*/) override; + void deactivate() override; - void deactivate() override; - - osg::Vec4f getAmbientColour(osg::Vec4f *defaultAmbient) override; + osg::Vec4f getAmbientColour(osg::Vec4f* defaultAmbient) override; }; } diff --git a/apps/opencs/view/render/lightingnight.cpp b/apps/opencs/view/render/lightingnight.cpp index fbebb46a11..80aac5b7f4 100644 --- a/apps/opencs/view/render/lightingnight.cpp +++ b/apps/opencs/view/render/lightingnight.cpp @@ -4,13 +4,13 @@ CSVRender::LightingNight::LightingNight() {} -void CSVRender::LightingNight::activate (osg::Group* rootNode, bool isExterior) +void CSVRender::LightingNight::activate(osg::Group* rootNode, bool isExterior) { mRootNode = rootNode; mLightSource = new osg::LightSource; - osg::ref_ptr light (new osg::Light); + osg::ref_ptr light(new osg::Light); light->setPosition(osg::Vec4f(0.f, 0.f, 1.f, 0.f)); light->setAmbient(osg::Vec4f(0.f, 0.f, 0.f, 1.f)); light->setDiffuse(osg::Vec4f(0.2f, 0.2f, 0.2f, 1.f)); @@ -30,7 +30,7 @@ void CSVRender::LightingNight::deactivate() mRootNode->removeChild(mLightSource); } -osg::Vec4f CSVRender::LightingNight::getAmbientColour(osg::Vec4f *defaultAmbient) +osg::Vec4f CSVRender::LightingNight::getAmbientColour(osg::Vec4f* defaultAmbient) { if (defaultAmbient) return *defaultAmbient; diff --git a/apps/opencs/view/render/lightingnight.hpp b/apps/opencs/view/render/lightingnight.hpp index bfa94ce972..2a4e0f87ff 100644 --- a/apps/opencs/view/render/lightingnight.hpp +++ b/apps/opencs/view/render/lightingnight.hpp @@ -7,14 +7,13 @@ namespace CSVRender { class LightingNight : public Lighting { - public: + public: + LightingNight(); - LightingNight(); + void activate(osg::Group* rootNode, bool isExterior) override; + void deactivate() override; - void activate (osg::Group* rootNode, bool isExterior) override; - void deactivate() override; - - osg::Vec4f getAmbientColour(osg::Vec4f *defaultAmbient) override; + osg::Vec4f getAmbientColour(osg::Vec4f* defaultAmbient) override; }; } diff --git a/apps/opencs/view/render/object.cpp b/apps/opencs/view/render/object.cpp index 6ab24928e6..3b2f26504b 100644 --- a/apps/opencs/view/render/object.cpp +++ b/apps/opencs/view/render/object.cpp @@ -7,79 +7,76 @@ #include #include -#include -#include #include #include +#include +#include #include -#include "../../model/world/data.hpp" -#include "../../model/world/commands.hpp" -#include "../../model/world/commandmacro.hpp" -#include "../../model/world/cellcoordinates.hpp" #include "../../model/prefs/state.hpp" +#include "../../model/world/cellcoordinates.hpp" +#include "../../model/world/commandmacro.hpp" +#include "../../model/world/commands.hpp" +#include "../../model/world/data.hpp" #include #include -#include #include +#include #include "actor.hpp" #include "mask.hpp" - const float CSVRender::Object::MarkerShaftWidth = 30; const float CSVRender::Object::MarkerShaftBaseLength = 70; const float CSVRender::Object::MarkerHeadWidth = 50; const float CSVRender::Object::MarkerHeadLength = 50; - namespace { osg::ref_ptr createErrorCube() { - osg::ref_ptr shape(new osg::Box(osg::Vec3f(0,0,0), 50.f)); + osg::ref_ptr shape(new osg::Box(osg::Vec3f(0, 0, 0), 50.f)); osg::ref_ptr shapedrawable(new osg::ShapeDrawable); shapedrawable->setShape(shape); - osg::ref_ptr group (new osg::Group); + osg::ref_ptr group(new osg::Group); group->addChild(shapedrawable); return group; } } - -CSVRender::ObjectTag::ObjectTag (Object* object) -: TagBase (Mask_Reference), mObject (object) -{} +CSVRender::ObjectTag::ObjectTag(Object* object) + : TagBase(Mask_Reference) + , mObject(object) +{ +} QString CSVRender::ObjectTag::getToolTip(bool /*hideBasics*/, const WorldspaceHitResult& /*hit*/) const { - return QString::fromUtf8 (mObject->getReferenceableId().c_str()); + return QString::fromUtf8(mObject->getReferenceableId().c_str()); } - -CSVRender::ObjectMarkerTag::ObjectMarkerTag (Object* object, int axis) -: ObjectTag (object), mAxis (axis) -{} - - -void CSVRender::Object::clear() +CSVRender::ObjectMarkerTag::ObjectMarkerTag(Object* object, int axis) + : ObjectTag(object) + , mAxis(axis) { } +void CSVRender::Object::clear() {} + void CSVRender::Object::update() { clear(); const CSMWorld::RefIdCollection& referenceables = mData.getReferenceables(); const int TypeIndex = referenceables.findColumnIndex(CSMWorld::Columns::ColumnId_RecordType); - const int ModelIndex = referenceables.findColumnIndex (CSMWorld::Columns::ColumnId_Model); + const int ModelIndex = referenceables.findColumnIndex(CSMWorld::Columns::ColumnId_Model); - int index = referenceables.searchId (mReferenceableId); + int index = referenceables.searchId(mReferenceableId); const ESM::Light* light = nullptr; mBaseNode->removeChildren(0, mBaseNode->getNumChildren()); @@ -97,7 +94,7 @@ void CSVRender::Object::update() if (recordType == CSMWorld::UniversalId::Type_Light) { - light = &dynamic_cast& >(referenceables.getRecord(index)).get(); + light = &dynamic_cast&>(referenceables.getRecord(index)).get(); if (model.empty()) model = "marker_light.nif"; } @@ -112,7 +109,8 @@ void CSVRender::Object::update() { if (recordType == CSMWorld::UniversalId::Type_Npc || recordType == CSMWorld::UniversalId::Type_Creature) { - if (!mActor) mActor = std::make_unique(mReferenceableId, mData); + if (!mActor) + mActor = std::make_unique(mReferenceableId, mData); mActor->update(); mBaseNode->addChild(mActor->getBaseNode()); } @@ -147,13 +145,14 @@ void CSVRender::Object::adjustTransform() ESM::Position position = getPosition(); // position - mRootNode->setPosition(mForceBaseToZero ? osg::Vec3() : osg::Vec3f(position.pos[0], position.pos[1], position.pos[2])); + mRootNode->setPosition( + mForceBaseToZero ? osg::Vec3() : osg::Vec3f(position.pos[0], position.pos[1], position.pos[2])); // orientation - osg::Quat xr (-position.rot[0], osg::Vec3f(1,0,0)); - osg::Quat yr (-position.rot[1], osg::Vec3f(0,1,0)); - osg::Quat zr (-position.rot[2], osg::Vec3f(0,0,1)); - mBaseNode->setAttitude(zr*yr*xr); + osg::Quat xr(-position.rot[0], osg::Vec3f(1, 0, 0)); + osg::Quat yr(-position.rot[1], osg::Vec3f(0, 1, 0)); + osg::Quat zr(-position.rot[2], osg::Vec3f(0, 0, 1)); + mBaseNode->setAttitude(zr * yr * xr); float scale = getScale(); @@ -163,141 +162,141 @@ void CSVRender::Object::adjustTransform() const CSMWorld::CellRef& CSVRender::Object::getReference() const { if (mReferenceId.empty()) - throw std::logic_error ("object does not represent a reference"); + throw std::logic_error("object does not represent a reference"); - return mData.getReferences().getRecord (mReferenceId).get(); + return mData.getReferences().getRecord(mReferenceId).get(); } void CSVRender::Object::updateMarker() { - for (int i=0; i<3; ++i) + for (int i = 0; i < 3; ++i) { if (mMarker[i]) { - mRootNode->removeChild (mMarker[i]); + mRootNode->removeChild(mMarker[i]); mMarker[i] = osg::ref_ptr(); } if (mSelected) { - if (mSubMode==0) + if (mSubMode == 0) { - mMarker[i] = makeMoveOrScaleMarker (i); - mMarker[i]->setUserData(new ObjectMarkerTag (this, i)); + mMarker[i] = makeMoveOrScaleMarker(i); + mMarker[i]->setUserData(new ObjectMarkerTag(this, i)); - mRootNode->addChild (mMarker[i]); + mRootNode->addChild(mMarker[i]); } - else if (mSubMode==1) + else if (mSubMode == 1) { - mMarker[i] = makeRotateMarker (i); - mMarker[i]->setUserData(new ObjectMarkerTag (this, i)); + mMarker[i] = makeRotateMarker(i); + mMarker[i]->setUserData(new ObjectMarkerTag(this, i)); - mRootNode->addChild (mMarker[i]); + mRootNode->addChild(mMarker[i]); } - else if (mSubMode==2) + else if (mSubMode == 2) { - mMarker[i] = makeMoveOrScaleMarker (i); - mMarker[i]->setUserData(new ObjectMarkerTag (this, i)); + mMarker[i] = makeMoveOrScaleMarker(i); + mMarker[i]->setUserData(new ObjectMarkerTag(this, i)); - mRootNode->addChild (mMarker[i]); + mRootNode->addChild(mMarker[i]); } } } } -osg::ref_ptr CSVRender::Object::makeMoveOrScaleMarker (int axis) +osg::ref_ptr CSVRender::Object::makeMoveOrScaleMarker(int axis) { - osg::ref_ptr geometry (new osg::Geometry); + osg::ref_ptr geometry(new osg::Geometry); float shaftLength = MarkerShaftBaseLength + mBaseNode->getBound().radius(); // shaft - osg::Vec3Array *vertices = new osg::Vec3Array; + osg::Vec3Array* vertices = new osg::Vec3Array; - for (int i=0; i<2; ++i) + for (int i = 0; i < 2; ++i) { float length = i ? shaftLength : MarkerShaftWidth; - vertices->push_back (getMarkerPosition (-MarkerShaftWidth/2, -MarkerShaftWidth/2, length, axis)); - vertices->push_back (getMarkerPosition (-MarkerShaftWidth/2, MarkerShaftWidth/2, length, axis)); - vertices->push_back (getMarkerPosition (MarkerShaftWidth/2, MarkerShaftWidth/2, length, axis)); - vertices->push_back (getMarkerPosition (MarkerShaftWidth/2, -MarkerShaftWidth/2, length, axis)); + vertices->push_back(getMarkerPosition(-MarkerShaftWidth / 2, -MarkerShaftWidth / 2, length, axis)); + vertices->push_back(getMarkerPosition(-MarkerShaftWidth / 2, MarkerShaftWidth / 2, length, axis)); + vertices->push_back(getMarkerPosition(MarkerShaftWidth / 2, MarkerShaftWidth / 2, length, axis)); + vertices->push_back(getMarkerPosition(MarkerShaftWidth / 2, -MarkerShaftWidth / 2, length, axis)); } // head backside - vertices->push_back (getMarkerPosition (-MarkerHeadWidth/2, -MarkerHeadWidth/2, shaftLength, axis)); - vertices->push_back (getMarkerPosition (-MarkerHeadWidth/2, MarkerHeadWidth/2, shaftLength, axis)); - vertices->push_back (getMarkerPosition (MarkerHeadWidth/2, MarkerHeadWidth/2, shaftLength, axis)); - vertices->push_back (getMarkerPosition (MarkerHeadWidth/2, -MarkerHeadWidth/2, shaftLength, axis)); + vertices->push_back(getMarkerPosition(-MarkerHeadWidth / 2, -MarkerHeadWidth / 2, shaftLength, axis)); + vertices->push_back(getMarkerPosition(-MarkerHeadWidth / 2, MarkerHeadWidth / 2, shaftLength, axis)); + vertices->push_back(getMarkerPosition(MarkerHeadWidth / 2, MarkerHeadWidth / 2, shaftLength, axis)); + vertices->push_back(getMarkerPosition(MarkerHeadWidth / 2, -MarkerHeadWidth / 2, shaftLength, axis)); // head - vertices->push_back (getMarkerPosition (0, 0, shaftLength+MarkerHeadLength, axis)); + vertices->push_back(getMarkerPosition(0, 0, shaftLength + MarkerHeadLength, axis)); - geometry->setVertexArray (vertices); + geometry->setVertexArray(vertices); - osg::DrawElementsUShort *primitives = new osg::DrawElementsUShort (osg::PrimitiveSet::TRIANGLES, 0); + osg::DrawElementsUShort* primitives = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES, 0); // shaft - for (int i=0; i<4; ++i) + for (int i = 0; i < 4; ++i) { - int i2 = i==3 ? 0 : i+1; - primitives->push_back (i); - primitives->push_back (4+i); - primitives->push_back (i2); - - primitives->push_back (4+i); - primitives->push_back (4+i2); - primitives->push_back (i2); + int i2 = i == 3 ? 0 : i + 1; + primitives->push_back(i); + primitives->push_back(4 + i); + primitives->push_back(i2); + + primitives->push_back(4 + i); + primitives->push_back(4 + i2); + primitives->push_back(i2); } // cap - primitives->push_back (0); - primitives->push_back (1); - primitives->push_back (2); + primitives->push_back(0); + primitives->push_back(1); + primitives->push_back(2); - primitives->push_back (2); - primitives->push_back (3); - primitives->push_back (0); + primitives->push_back(2); + primitives->push_back(3); + primitives->push_back(0); // head, backside - primitives->push_back (0+8); - primitives->push_back (1+8); - primitives->push_back (2+8); + primitives->push_back(0 + 8); + primitives->push_back(1 + 8); + primitives->push_back(2 + 8); - primitives->push_back (2+8); - primitives->push_back (3+8); - primitives->push_back (0+8); + primitives->push_back(2 + 8); + primitives->push_back(3 + 8); + primitives->push_back(0 + 8); - for (int i=0; i<4; ++i) + for (int i = 0; i < 4; ++i) { - primitives->push_back (12); - primitives->push_back (8+(i==3 ? 0 : i+1)); - primitives->push_back (8+i); + primitives->push_back(12); + primitives->push_back(8 + (i == 3 ? 0 : i + 1)); + primitives->push_back(8 + i); } - geometry->addPrimitiveSet (primitives); + geometry->addPrimitiveSet(primitives); - osg::Vec4Array *colours = new osg::Vec4Array; + osg::Vec4Array* colours = new osg::Vec4Array; - for (int i=0; i<8; ++i) - colours->push_back (osg::Vec4f (axis==0 ? 1.0f : 0.2f, axis==1 ? 1.0f : 0.2f, - axis==2 ? 1.0f : 0.2f, mMarkerTransparency)); + for (int i = 0; i < 8; ++i) + colours->push_back( + osg::Vec4f(axis == 0 ? 1.0f : 0.2f, axis == 1 ? 1.0f : 0.2f, axis == 2 ? 1.0f : 0.2f, mMarkerTransparency)); - for (int i=8; i<8+4+1; ++i) - colours->push_back (osg::Vec4f (axis==0 ? 1.0f : 0.0f, axis==1 ? 1.0f : 0.0f, - axis==2 ? 1.0f : 0.0f, mMarkerTransparency)); + for (int i = 8; i < 8 + 4 + 1; ++i) + colours->push_back( + osg::Vec4f(axis == 0 ? 1.0f : 0.0f, axis == 1 ? 1.0f : 0.0f, axis == 2 ? 1.0f : 0.0f, mMarkerTransparency)); - geometry->setColorArray (colours, osg::Array::BIND_PER_VERTEX); + geometry->setColorArray(colours, osg::Array::BIND_PER_VERTEX); setupCommonMarkerState(geometry); - osg::ref_ptr group (new osg::Group); + osg::ref_ptr group(new osg::Group); group->addChild(geometry); return group; } -osg::ref_ptr CSVRender::Object::makeRotateMarker (int axis) +osg::ref_ptr CSVRender::Object::makeRotateMarker(int axis) { const float InnerRadius = std::max(MarkerShaftBaseLength, mBaseNode->getBound().radius()); const float OuterRadius = InnerRadius + MarkerShaftWidth; @@ -312,24 +311,18 @@ osg::ref_ptr CSVRender::Object::makeRotateMarker (int axis) const float Angle = 2 * osg::PI / SegmentCount; - const unsigned short IndexPattern[IndicesPerSegment] = - { - 0, 4, 5, 0, 5, 1, - 2, 6, 4, 2, 4, 0, - 3, 7, 6, 3, 6, 2, - 1, 5, 7, 1, 7, 3 - }; - + const unsigned short IndexPattern[IndicesPerSegment] + = { 0, 4, 5, 0, 5, 1, 2, 6, 4, 2, 4, 0, 3, 7, 6, 3, 6, 2, 1, 5, 7, 1, 7, 3 }; osg::ref_ptr geometry = new osg::Geometry(); osg::ref_ptr vertices = new osg::Vec3Array(VertexCount); osg::ref_ptr colors = new osg::Vec4Array(1); - osg::ref_ptr primitives = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES, - IndexCount); + osg::ref_ptr primitives + = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES, IndexCount); // prevent some depth collision issues from overlaps - osg::Vec3f offset = getMarkerPosition(0, MarkerShaftWidth/4, 0, axis); + osg::Vec3f offset = getMarkerPosition(0, MarkerShaftWidth / 4, 0, axis); for (size_t i = 0; i < SegmentCount; ++i) { @@ -341,17 +334,14 @@ osg::ref_ptr CSVRender::Object::makeRotateMarker (int axis) float outerX = OuterRadius * std::cos(i * Angle); float outerY = OuterRadius * std::sin(i * Angle); - vertices->at(index++) = getMarkerPosition(innerX, innerY, MarkerShaftWidth / 2, axis) + offset; + vertices->at(index++) = getMarkerPosition(innerX, innerY, MarkerShaftWidth / 2, axis) + offset; vertices->at(index++) = getMarkerPosition(innerX, innerY, -MarkerShaftWidth / 2, axis) + offset; - vertices->at(index++) = getMarkerPosition(outerX, outerY, MarkerShaftWidth / 2, axis) + offset; + vertices->at(index++) = getMarkerPosition(outerX, outerY, MarkerShaftWidth / 2, axis) + offset; vertices->at(index++) = getMarkerPosition(outerX, outerY, -MarkerShaftWidth / 2, axis) + offset; } - colors->at(0) = osg::Vec4f ( - axis==0 ? 1.0f : 0.2f, - axis==1 ? 1.0f : 0.2f, - axis==2 ? 1.0f : 0.2f, - mMarkerTransparency); + colors->at(0) + = osg::Vec4f(axis == 0 ? 1.0f : 0.2f, axis == 1 ? 1.0f : 0.2f, axis == 2 ? 1.0f : 0.2f, mMarkerTransparency); for (size_t i = 0; i < SegmentCount; ++i) { @@ -392,24 +382,35 @@ void CSVRender::Object::setupCommonMarkerState(osg::ref_ptr geome state->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); } -osg::Vec3f CSVRender::Object::getMarkerPosition (float x, float y, float z, int axis) +osg::Vec3f CSVRender::Object::getMarkerPosition(float x, float y, float z, int axis) { switch (axis) { - case 2: return osg::Vec3f (x, y, z); - case 0: return osg::Vec3f (z, x, y); - case 1: return osg::Vec3f (y, z, x); + case 2: + return osg::Vec3f(x, y, z); + case 0: + return osg::Vec3f(z, x, y); + case 1: + return osg::Vec3f(y, z, x); default: - throw std::logic_error ("invalid axis for marker geometry"); + throw std::logic_error("invalid axis for marker geometry"); } } -CSVRender::Object::Object (CSMWorld::Data& data, osg::Group* parentNode, - const std::string& id, bool referenceable, bool forceBaseToZero) -: mData (data), mBaseNode(nullptr), mSelected(false), mParentNode(parentNode), mResourceSystem(data.getResourceSystem().get()), mForceBaseToZero (forceBaseToZero), - mScaleOverride (1), mOverrideFlags (0), mSubMode (-1), mMarkerTransparency(0.5f) +CSVRender::Object::Object( + CSMWorld::Data& data, osg::Group* parentNode, const std::string& id, bool referenceable, bool forceBaseToZero) + : mData(data) + , mBaseNode(nullptr) + , mSelected(false) + , mParentNode(parentNode) + , mResourceSystem(data.getResourceSystem().get()) + , mForceBaseToZero(forceBaseToZero) + , mScaleOverride(1) + , mOverrideFlags(0) + , mSubMode(-1) + , mMarkerTransparency(0.5f) { mRootNode = new osg::PositionAttitudeTransform; @@ -420,9 +421,9 @@ CSVRender::Object::Object (CSMWorld::Data& data, osg::Group* parentNode, mBaseNode->setUserData(new ObjectTag(this)); - mRootNode->addChild (mBaseNode); + mRootNode->addChild(mBaseNode); - parentNode->addChild (mRootNode); + parentNode->addChild(mRootNode); mRootNode->setNodeMask(Mask_Reference); @@ -445,7 +446,7 @@ CSVRender::Object::~Object() { clear(); - mParentNode->removeChild (mRootNode); + mParentNode->removeChild(mRootNode); } void CSVRender::Object::setSelected(bool selected) @@ -482,14 +483,13 @@ osg::ref_ptr CSVRender::Object::getBaseNode() return mBaseNode; } -bool CSVRender::Object::referenceableDataChanged (const QModelIndex& topLeft, - const QModelIndex& bottomRight) +bool CSVRender::Object::referenceableDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) { const CSMWorld::RefIdCollection& referenceables = mData.getReferenceables(); - int index = referenceables.searchId (mReferenceableId); + int index = referenceables.searchId(mReferenceableId); - if (index!=-1 && index>=topLeft.row() && index<=bottomRight.row()) + if (index != -1 && index >= topLeft.row() && index <= bottomRight.row()) { adjustTransform(); update(); @@ -500,14 +500,13 @@ bool CSVRender::Object::referenceableDataChanged (const QModelIndex& topLeft, return false; } -bool CSVRender::Object::referenceableAboutToBeRemoved (const QModelIndex& parent, int start, - int end) +bool CSVRender::Object::referenceableAboutToBeRemoved(const QModelIndex& parent, int start, int end) { const CSMWorld::RefIdCollection& referenceables = mData.getReferenceables(); - int index = referenceables.searchId (mReferenceableId); + int index = referenceables.searchId(mReferenceableId); - if (index!=-1 && index>=start && index<=end) + if (index != -1 && index >= start && index <= end) { // Deletion of referenceable-type objects is handled outside of Object. if (!mReferenceId.empty()) @@ -521,27 +520,24 @@ bool CSVRender::Object::referenceableAboutToBeRemoved (const QModelIndex& parent return false; } -bool CSVRender::Object::referenceDataChanged (const QModelIndex& topLeft, - const QModelIndex& bottomRight) +bool CSVRender::Object::referenceDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) { if (mReferenceId.empty()) return false; const CSMWorld::RefCollection& references = mData.getReferences(); - int index = references.searchId (mReferenceId); + int index = references.searchId(mReferenceId); - if (index!=-1 && index>=topLeft.row() && index<=bottomRight.row()) + if (index != -1 && index >= topLeft.row() && index <= bottomRight.row()) { - int columnIndex = - references.findColumnIndex (CSMWorld::Columns::ColumnId_ReferenceableId); + int columnIndex = references.findColumnIndex(CSMWorld::Columns::ColumnId_ReferenceableId); adjustTransform(); - if (columnIndex>=topLeft.column() && columnIndex<=bottomRight.row()) + if (columnIndex >= topLeft.column() && columnIndex <= bottomRight.row()) { - mReferenceableId = - references.getData (index, columnIndex).toString().toUtf8().constData(); + mReferenceableId = references.getData(index, columnIndex).toString().toUtf8().constData(); update(); updateMarker(); @@ -571,7 +567,7 @@ std::string CSVRender::Object::getReferenceableId() const osg::ref_ptr CSVRender::Object::getTag() const { - return static_cast (mBaseNode->getUserData()); + return static_cast(mBaseNode->getUserData()); } bool CSVRender::Object::isEdited() const @@ -579,7 +575,7 @@ bool CSVRender::Object::isEdited() const return mOverrideFlags; } -void CSVRender::Object::setEdited (int flags) +void CSVRender::Object::setEdited(int flags) { bool discard = mOverrideFlags & ~flags; int added = flags & ~mOverrideFlags; @@ -587,11 +583,11 @@ void CSVRender::Object::setEdited (int flags) mOverrideFlags = flags; if (added & Override_Position) - for (int i=0; i<3; ++i) + for (int i = 0; i < 3; ++i) mPositionOverride.pos[i] = getReference().mPos.pos[i]; if (added & Override_Rotation) - for (int i=0; i<3; ++i) + for (int i = 0; i < 3; ++i) mPositionOverride.rot[i] = getReference().mPos.rot[i]; if (added & Override_Scale) @@ -606,11 +602,11 @@ ESM::Position CSVRender::Object::getPosition() const ESM::Position position = getReference().mPos; if (mOverrideFlags & Override_Position) - for (int i=0; i<3; ++i) + for (int i = 0; i < 3; ++i) position.pos[i] = mPositionOverride.pos[i]; if (mOverrideFlags & Override_Rotation) - for (int i=0; i<3; ++i) + for (int i = 0; i < 3; ++i) position.rot[i] = mPositionOverride.rot[i]; return position; @@ -621,27 +617,27 @@ float CSVRender::Object::getScale() const return (mOverrideFlags & Override_Scale) ? mScaleOverride : getReference().mScale; } -void CSVRender::Object::setPosition (const float position[3]) +void CSVRender::Object::setPosition(const float position[3]) { mOverrideFlags |= Override_Position; - for (int i=0; i<3; ++i) + for (int i = 0; i < 3; ++i) mPositionOverride.pos[i] = position[i]; adjustTransform(); } -void CSVRender::Object::setRotation (const float rotation[3]) +void CSVRender::Object::setRotation(const float rotation[3]) { mOverrideFlags |= Override_Rotation; - for (int i=0; i<3; ++i) + for (int i = 0; i < 3; ++i) mPositionOverride.rot[i] = rotation[i]; adjustTransform(); } -void CSVRender::Object::setScale (float scale) +void CSVRender::Object::setScale(float scale) { mOverrideFlags |= Override_Scale; @@ -656,80 +652,79 @@ void CSVRender::Object::setMarkerTransparency(float value) updateMarker(); } -void CSVRender::Object::apply (CSMWorld::CommandMacro& commands) +void CSVRender::Object::apply(CSMWorld::CommandMacro& commands) { const CSMWorld::RefCollection& collection = mData.getReferences(); - QAbstractItemModel *model = mData.getTableModel (CSMWorld::UniversalId::Type_References); + QAbstractItemModel* model = mData.getTableModel(CSMWorld::UniversalId::Type_References); - int recordIndex = collection.getIndex (mReferenceId); + int recordIndex = collection.getIndex(mReferenceId); if (mOverrideFlags & Override_Position) { - //Do cell check first so positions can be compared + // Do cell check first so positions can be compared const CSMWorld::CellRef& ref = collection.getRecord(recordIndex).get(); if (CSMWorld::CellCoordinates::isExteriorCell(ref.mCell)) { // Find cell index at new position - std::pair cellIndex = CSMWorld::CellCoordinates::coordinatesToCellIndex( - mPositionOverride.pos[0], mPositionOverride.pos[1]); + std::pair cellIndex + = CSMWorld::CellCoordinates::coordinatesToCellIndex(mPositionOverride.pos[0], mPositionOverride.pos[1]); std::pair originalIndex = ref.getCellIndex(); - int cellColumn = collection.findColumnIndex (static_cast ( - CSMWorld::Columns::ColumnId_Cell)); - int origCellColumn = collection.findColumnIndex(static_cast ( - CSMWorld::Columns::ColumnId_OriginalCell)); + int cellColumn = collection.findColumnIndex( + static_cast(CSMWorld::Columns::ColumnId_Cell)); + int origCellColumn = collection.findColumnIndex( + static_cast(CSMWorld::Columns::ColumnId_OriginalCell)); if (cellIndex != originalIndex) { /// \todo figure out worldspace (not important until multiple worldspaces are supported) std::string origCellId = CSMWorld::CellCoordinates(originalIndex).getId(""); - std::string cellId = CSMWorld::CellCoordinates (cellIndex).getId (""); + std::string cellId = CSMWorld::CellCoordinates(cellIndex).getId(""); - commands.push (new CSMWorld::ModifyCommand (*model, - model->index (recordIndex, origCellColumn), QString::fromUtf8 (origCellId.c_str()))); - commands.push(new CSMWorld::ModifyCommand(*model, - model->index(recordIndex, cellColumn), QString::fromUtf8(cellId.c_str()))); + commands.push(new CSMWorld::ModifyCommand( + *model, model->index(recordIndex, origCellColumn), QString::fromUtf8(origCellId.c_str()))); + commands.push(new CSMWorld::ModifyCommand( + *model, model->index(recordIndex, cellColumn), QString::fromUtf8(cellId.c_str()))); // NOTE: refnum is not modified for moving a reference to another cell } } - for (int i=0; i<3; ++i) + for (int i = 0; i < 3; ++i) { - int column = collection.findColumnIndex (static_cast ( - CSMWorld::Columns::ColumnId_PositionXPos+i)); + int column = collection.findColumnIndex( + static_cast(CSMWorld::Columns::ColumnId_PositionXPos + i)); - commands.push (new CSMWorld::ModifyCommand (*model, - model->index (recordIndex, column), mPositionOverride.pos[i])); + commands.push( + new CSMWorld::ModifyCommand(*model, model->index(recordIndex, column), mPositionOverride.pos[i])); } } if (mOverrideFlags & Override_Rotation) { - for (int i=0; i<3; ++i) + for (int i = 0; i < 3; ++i) { - int column = collection.findColumnIndex (static_cast ( - CSMWorld::Columns::ColumnId_PositionXRot+i)); + int column = collection.findColumnIndex( + static_cast(CSMWorld::Columns::ColumnId_PositionXRot + i)); - commands.push (new CSMWorld::ModifyCommand (*model, - model->index (recordIndex, column), osg::RadiansToDegrees(mPositionOverride.rot[i]))); + commands.push(new CSMWorld::ModifyCommand( + *model, model->index(recordIndex, column), osg::RadiansToDegrees(mPositionOverride.rot[i]))); } } if (mOverrideFlags & Override_Scale) { - int column = collection.findColumnIndex (CSMWorld::Columns::ColumnId_Scale); + int column = collection.findColumnIndex(CSMWorld::Columns::ColumnId_Scale); - commands.push (new CSMWorld::ModifyCommand (*model, - model->index (recordIndex, column), mScaleOverride)); + commands.push(new CSMWorld::ModifyCommand(*model, model->index(recordIndex, column), mScaleOverride)); } mOverrideFlags = 0; } -void CSVRender::Object::setSubMode (int subMode) +void CSVRender::Object::setSubMode(int subMode) { - if (subMode!=mSubMode) + if (subMode != mSubMode) { mSubMode = subMode; updateMarker(); diff --git a/apps/opencs/view/render/object.hpp b/apps/opencs/view/render/object.hpp index 6c477b57d8..47bd09f657 100644 --- a/apps/opencs/view/render/object.hpp +++ b/apps/opencs/view/render/object.hpp @@ -4,9 +4,9 @@ #include #include -#include #include #include +#include #include @@ -44,164 +44,158 @@ namespace CSVRender class Actor; class Object; - // An object to attach as user data to the osg::Node, allows us to get an Object back from a Node when we are doing a ray query + // An object to attach as user data to the osg::Node, allows us to get an Object back from a Node when we are doing + // a ray query class ObjectTag : public TagBase { - public: + public: + ObjectTag(Object* object); - ObjectTag (Object* object); + Object* mObject; - Object* mObject; - - QString getToolTip (bool hideBasics, const WorldspaceHitResult& hit) const override; + QString getToolTip(bool hideBasics, const WorldspaceHitResult& hit) const override; }; class ObjectMarkerTag : public ObjectTag { - public: - - ObjectMarkerTag (Object* object, int axis); + public: + ObjectMarkerTag(Object* object, int axis); - int mAxis; + int mAxis; }; class Object { - public: - - enum OverrideFlags - { - Override_Position = 1, - Override_Rotation = 2, - Override_Scale = 4 - }; - - private: - - static const float MarkerShaftWidth; - static const float MarkerShaftBaseLength; - static const float MarkerHeadWidth; - static const float MarkerHeadLength; + public: + enum OverrideFlags + { + Override_Position = 1, + Override_Rotation = 2, + Override_Scale = 4 + }; - CSMWorld::Data& mData; - std::string mReferenceId; - std::string mReferenceableId; - osg::ref_ptr mRootNode; - osg::ref_ptr mBaseNode; - osg::ref_ptr mOutline; - bool mSelected; - osg::Group* mParentNode; - Resource::ResourceSystem* mResourceSystem; - bool mForceBaseToZero; - ESM::Position mPositionOverride; - float mScaleOverride; - int mOverrideFlags; - osg::ref_ptr mMarker[3]; - int mSubMode; - float mMarkerTransparency; - std::unique_ptr mActor; + private: + static const float MarkerShaftWidth; + static const float MarkerShaftBaseLength; + static const float MarkerHeadWidth; + static const float MarkerHeadLength; - /// Not implemented - Object (const Object&); + CSMWorld::Data& mData; + std::string mReferenceId; + std::string mReferenceableId; + osg::ref_ptr mRootNode; + osg::ref_ptr mBaseNode; + osg::ref_ptr mOutline; + bool mSelected; + osg::Group* mParentNode; + Resource::ResourceSystem* mResourceSystem; + bool mForceBaseToZero; + ESM::Position mPositionOverride; + float mScaleOverride; + int mOverrideFlags; + osg::ref_ptr mMarker[3]; + int mSubMode; + float mMarkerTransparency; + std::unique_ptr mActor; - /// Not implemented - Object& operator= (const Object&); + /// Not implemented + Object(const Object&); - /// Remove object from node (includes deleting) - void clear(); + /// Not implemented + Object& operator=(const Object&); - /// Update model - /// @note Make sure adjustTransform() was called first so world space particles get positioned correctly - void update(); + /// Remove object from node (includes deleting) + void clear(); - /// Adjust position, orientation and scale - void adjustTransform(); + /// Update model + /// @note Make sure adjustTransform() was called first so world space particles get positioned correctly + void update(); - /// Throws an exception if *this was constructed with referenceable - const CSMWorld::CellRef& getReference() const; + /// Adjust position, orientation and scale + void adjustTransform(); - void updateMarker(); + /// Throws an exception if *this was constructed with referenceable + const CSMWorld::CellRef& getReference() const; - osg::ref_ptr makeMoveOrScaleMarker (int axis); - osg::ref_ptr makeRotateMarker (int axis); + void updateMarker(); - /// Sets up a stateset with properties common to all marker types. - void setupCommonMarkerState(osg::ref_ptr geometry); + osg::ref_ptr makeMoveOrScaleMarker(int axis); + osg::ref_ptr makeRotateMarker(int axis); - osg::Vec3f getMarkerPosition (float x, float y, float z, int axis); + /// Sets up a stateset with properties common to all marker types. + void setupCommonMarkerState(osg::ref_ptr geometry); - public: + osg::Vec3f getMarkerPosition(float x, float y, float z, int axis); - Object (CSMWorld::Data& data, osg::Group *cellNode, - const std::string& id, bool referenceable, - bool forceBaseToZero = false); - /// \param forceBaseToZero If this is a reference ignore the coordinates and place - /// it at 0, 0, 0 instead. + public: + Object(CSMWorld::Data& data, osg::Group* cellNode, const std::string& id, bool referenceable, + bool forceBaseToZero = false); + /// \param forceBaseToZero If this is a reference ignore the coordinates and place + /// it at 0, 0, 0 instead. - ~Object(); + ~Object(); - /// Mark the object as selected, selected objects show an outline effect - void setSelected(bool selected); + /// Mark the object as selected, selected objects show an outline effect + void setSelected(bool selected); - bool getSelected() const; + bool getSelected() const; - /// Get object node with GUI graphics - osg::ref_ptr getRootNode(); + /// Get object node with GUI graphics + osg::ref_ptr getRootNode(); - /// Get object node without GUI graphics - osg::ref_ptr getBaseNode(); + /// Get object node without GUI graphics + osg::ref_ptr getBaseNode(); - /// \return Did this call result in a modification of the visual representation of - /// this object? - bool referenceableDataChanged (const QModelIndex& topLeft, - const QModelIndex& bottomRight); + /// \return Did this call result in a modification of the visual representation of + /// this object? + bool referenceableDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); - /// \return Did this call result in a modification of the visual representation of - /// this object? - bool referenceableAboutToBeRemoved (const QModelIndex& parent, int start, int end); + /// \return Did this call result in a modification of the visual representation of + /// this object? + bool referenceableAboutToBeRemoved(const QModelIndex& parent, int start, int end); - /// \return Did this call result in a modification of the visual representation of - /// this object? - bool referenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); + /// \return Did this call result in a modification of the visual representation of + /// this object? + bool referenceDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); - /// Reloads the underlying asset - void reloadAssets(); + /// Reloads the underlying asset + void reloadAssets(); - /// Returns an empty string if this is a refereceable-type object. - std::string getReferenceId() const; + /// Returns an empty string if this is a refereceable-type object. + std::string getReferenceId() const; - std::string getReferenceableId() const; + std::string getReferenceableId() const; - osg::ref_ptr getTag() const; + osg::ref_ptr getTag() const; - /// Is there currently an editing operation running on this object? - bool isEdited() const; + /// Is there currently an editing operation running on this object? + bool isEdited() const; - void setEdited (int flags); + void setEdited(int flags); - ESM::Position getPosition() const; + ESM::Position getPosition() const; - float getScale() const; + float getScale() const; - /// Set override position. - void setPosition (const float position[3]); + /// Set override position. + void setPosition(const float position[3]); - /// Set override rotation - void setRotation (const float rotation[3]); + /// Set override rotation + void setRotation(const float rotation[3]); - /// Set override scale - void setScale (float scale); + /// Set override scale + void setScale(float scale); - void setMarkerTransparency(float value); + void setMarkerTransparency(float value); - /// Apply override changes via command and end edit mode - void apply (CSMWorld::CommandMacro& commands); + /// Apply override changes via command and end edit mode + void apply(CSMWorld::CommandMacro& commands); - void setSubMode (int subMode); + void setSubMode(int subMode); - /// Erase all overrides and restore the visual representation of the object to its - /// true state. - void reset(); + /// Erase all overrides and restore the visual representation of the object to its + /// true state. + void reset(); }; } diff --git a/apps/opencs/view/render/orbitcameramode.cpp b/apps/opencs/view/render/orbitcameramode.cpp index 612efc3b01..670b4af8a1 100644 --- a/apps/opencs/view/render/orbitcameramode.cpp +++ b/apps/opencs/view/render/orbitcameramode.cpp @@ -8,21 +8,18 @@ namespace CSVRender { - OrbitCameraMode::OrbitCameraMode(WorldspaceWidget* worldspaceWidget, const QIcon& icon, const QString& tooltip, - QWidget* parent) + OrbitCameraMode::OrbitCameraMode( + WorldspaceWidget* worldspaceWidget, const QIcon& icon, const QString& tooltip, QWidget* parent) : ModeButton(icon, tooltip, parent) , mWorldspaceWidget(worldspaceWidget) , mCenterOnSelection(nullptr) { mCenterShortcut = new CSMPrefs::Shortcut("orbit-center-selection", worldspaceWidget); mCenterShortcut->enable(false); - connect(mCenterShortcut, qOverload<>(&CSMPrefs::Shortcut::activated), - this, &OrbitCameraMode::centerSelection); + connect(mCenterShortcut, qOverload<>(&CSMPrefs::Shortcut::activated), this, &OrbitCameraMode::centerSelection); } - OrbitCameraMode::~OrbitCameraMode() - { - } + OrbitCameraMode::~OrbitCameraMode() {} void OrbitCameraMode::activate(CSVWidget::SceneToolbar* toolbar) { diff --git a/apps/opencs/view/render/orbitcameramode.hpp b/apps/opencs/view/render/orbitcameramode.hpp index 10bc97b0f1..89fa93d3b8 100644 --- a/apps/opencs/view/render/orbitcameramode.hpp +++ b/apps/opencs/view/render/orbitcameramode.hpp @@ -16,27 +16,25 @@ namespace CSVRender class OrbitCameraMode : public CSVWidget::ModeButton { - Q_OBJECT + Q_OBJECT - public: + public: + OrbitCameraMode(WorldspaceWidget* worldspaceWidget, const QIcon& icon, const QString& tooltip = "", + QWidget* parent = nullptr); + ~OrbitCameraMode(); - OrbitCameraMode(WorldspaceWidget* worldspaceWidget, const QIcon& icon, const QString& tooltip = "", - QWidget* parent = nullptr); - ~OrbitCameraMode(); + void activate(CSVWidget::SceneToolbar* toolbar) override; + void deactivate(CSVWidget::SceneToolbar* toolbar) override; + bool createContextMenu(QMenu* menu) override; - void activate(CSVWidget::SceneToolbar* toolbar) override; - void deactivate(CSVWidget::SceneToolbar* toolbar) override; - bool createContextMenu(QMenu* menu) override; + private: + WorldspaceWidget* mWorldspaceWidget; + QAction* mCenterOnSelection; + CSMPrefs::Shortcut* mCenterShortcut; - private: + private slots: - WorldspaceWidget* mWorldspaceWidget; - QAction* mCenterOnSelection; - CSMPrefs::Shortcut* mCenterShortcut; - - private slots: - - void centerSelection(); + void centerSelection(); }; } diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 6e58af24da..97ff1a9788 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -4,22 +4,21 @@ #include #include - #include #include "../../model/prefs/shortcut.hpp" #include "../../model/world/idtable.hpp" -#include "../widget/scenetooltoggle2.hpp" #include "../widget/scenetoolmode.hpp" +#include "../widget/scenetooltoggle2.hpp" -#include "editmode.hpp" -#include "mask.hpp" #include "cameracontroller.hpp" #include "cellarrow.hpp" -#include "terraintexturemode.hpp" +#include "editmode.hpp" +#include "mask.hpp" #include "terrainshapemode.hpp" +#include "terraintexturemode.hpp" bool CSVRender::PagedWorldspaceWidget::adjustCells() { @@ -29,32 +28,31 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() { // remove/update - std::map::iterator iter (mCells.begin()); + std::map::iterator iter(mCells.begin()); - while (iter!=mCells.end()) + while (iter != mCells.end()) { - if (!mSelection.has (iter->first)) + if (!mSelection.has(iter->first)) { // remove delete iter->second; - mCells.erase (iter++); + mCells.erase(iter++); modified = true; } else { // update - int index = cells.searchId (iter->first.getId (mWorldspace)); + int index = cells.searchId(iter->first.getId(mWorldspace)); - bool deleted = index==-1 || - cells.getRecord (index).mState==CSMWorld::RecordBase::State_Deleted; + bool deleted = index == -1 || cells.getRecord(index).mState == CSMWorld::RecordBase::State_Deleted; - if (deleted!=iter->second->isDeleted()) + if (deleted != iter->second->isDeleted()) { modified = true; - auto cell = std::make_unique(mDocument.getData(), mRootNode, - iter->first.getId (mWorldspace), deleted); + auto cell = std::make_unique( + mDocument.getData(), mRootNode, iter->first.getId(mWorldspace), deleted); delete iter->second; iter->second = cell.release(); @@ -65,8 +63,8 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() // TODO check if name or region field has changed (cell marker) // FIXME: config setting - //std::string name = cells.getRecord(index).get().mName; - //std::string region = cells.getRecord(index).get().mRegion; + // std::string name = cells.getRecord(index).get().mName; + // std::string region = cells.getRecord(index).get().mRegion; modified = true; } @@ -77,79 +75,79 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() } // add - for (CSMWorld::CellSelection::Iterator iter (mSelection.begin()); iter!=mSelection.end(); - ++iter) + for (CSMWorld::CellSelection::Iterator iter(mSelection.begin()); iter != mSelection.end(); ++iter) { - if (mCells.find (*iter)==mCells.end()) + if (mCells.find(*iter) == mCells.end()) { - addCellToScene (*iter); + addCellToScene(*iter); modified = true; } } if (modified) { - for (std::map::const_iterator iter (mCells.begin()); - iter!=mCells.end(); ++iter) + for (std::map::const_iterator iter(mCells.begin()); iter != mCells.end(); + ++iter) { int mask = 0; - for (int i=CellArrow::Direction_North; i<=CellArrow::Direction_East; i *= 2) + for (int i = CellArrow::Direction_North; i <= CellArrow::Direction_East; i *= 2) { - CSMWorld::CellCoordinates coordinates (iter->second->getCoordinates()); + CSMWorld::CellCoordinates coordinates(iter->second->getCoordinates()); switch (i) { - case CellArrow::Direction_North: coordinates = coordinates.move (0, 1); break; - case CellArrow::Direction_West: coordinates = coordinates.move (-1, 0); break; - case CellArrow::Direction_South: coordinates = coordinates.move (0, -1); break; - case CellArrow::Direction_East: coordinates = coordinates.move (1, 0); break; + case CellArrow::Direction_North: + coordinates = coordinates.move(0, 1); + break; + case CellArrow::Direction_West: + coordinates = coordinates.move(-1, 0); + break; + case CellArrow::Direction_South: + coordinates = coordinates.move(0, -1); + break; + case CellArrow::Direction_East: + coordinates = coordinates.move(1, 0); + break; } - if (!mSelection.has (coordinates)) + if (!mSelection.has(coordinates)) mask |= i; } - iter->second->setCellArrows (mask); + iter->second->setCellArrows(mask); } } return modified; } -void CSVRender::PagedWorldspaceWidget::addVisibilitySelectorButtons ( - CSVWidget::SceneToolToggle2 *tool) +void CSVRender::PagedWorldspaceWidget::addVisibilitySelectorButtons(CSVWidget::SceneToolToggle2* tool) { - WorldspaceWidget::addVisibilitySelectorButtons (tool); - tool->addButton (Button_Terrain, Mask_Terrain, "Terrain"); - tool->addButton (Button_Fog, Mask_Fog, "Fog", "", true); + WorldspaceWidget::addVisibilitySelectorButtons(tool); + tool->addButton(Button_Terrain, Mask_Terrain, "Terrain"); + tool->addButton(Button_Fog, Mask_Fog, "Fog", "", true); } -void CSVRender::PagedWorldspaceWidget::addEditModeSelectorButtons ( - CSVWidget::SceneToolMode *tool) +void CSVRender::PagedWorldspaceWidget::addEditModeSelectorButtons(CSVWidget::SceneToolMode* tool) { - WorldspaceWidget::addEditModeSelectorButtons (tool); + WorldspaceWidget::addEditModeSelectorButtons(tool); /// \todo replace EditMode with suitable subclasses - tool->addButton ( - new TerrainShapeMode (this, mRootNode, tool), "terrain-shape"); - tool->addButton ( - new TerrainTextureMode (this, mRootNode, tool), "terrain-texture"); - tool->addButton ( - new EditMode (this, QIcon (":placeholder"), Mask_Reference, "Terrain vertex paint editing"), - "terrain-vertex"); - tool->addButton ( - new EditMode (this, QIcon (":placeholder"), Mask_Reference, "Terrain movement"), - "terrain-move"); + tool->addButton(new TerrainShapeMode(this, mRootNode, tool), "terrain-shape"); + tool->addButton(new TerrainTextureMode(this, mRootNode, tool), "terrain-texture"); + tool->addButton( + new EditMode(this, QIcon(":placeholder"), Mask_Reference, "Terrain vertex paint editing"), "terrain-vertex"); + tool->addButton(new EditMode(this, QIcon(":placeholder"), Mask_Reference, "Terrain movement"), "terrain-move"); } -void CSVRender::PagedWorldspaceWidget::handleInteractionPress (const WorldspaceHitResult& hit, InteractionType type) +void CSVRender::PagedWorldspaceWidget::handleInteractionPress(const WorldspaceHitResult& hit, InteractionType type) { - if (hit.tag && hit.tag->getMask()==Mask_CellArrow) + if (hit.tag && hit.tag->getMask() == Mask_CellArrow) { - if (CellArrowTag *cellArrowTag = dynamic_cast (hit.tag.get())) + if (CellArrowTag* cellArrowTag = dynamic_cast(hit.tag.get())) { - CellArrow *arrow = cellArrowTag->getCellArrow(); + CellArrow* arrow = cellArrowTag->getCellArrow(); CSMWorld::CellCoordinates coordinates = arrow->getCoordinates(); @@ -160,41 +158,49 @@ void CSVRender::PagedWorldspaceWidget::handleInteractionPress (const WorldspaceH switch (direction) { - case CellArrow::Direction_North: y = 1; break; - case CellArrow::Direction_West: x = -1; break; - case CellArrow::Direction_South: y = -1; break; - case CellArrow::Direction_East: x = 1; break; + case CellArrow::Direction_North: + y = 1; + break; + case CellArrow::Direction_West: + x = -1; + break; + case CellArrow::Direction_South: + y = -1; + break; + case CellArrow::Direction_East: + x = 1; + break; } bool modified = false; if (type == InteractionType_PrimarySelect) { - addCellSelection (x, y); + addCellSelection(x, y); modified = true; } else if (type == InteractionType_SecondarySelect) { - moveCellSelection (x, y); + moveCellSelection(x, y); modified = true; } else // Primary/SecondaryEdit { - CSMWorld::CellCoordinates newCoordinates = coordinates.move (x, y); + CSMWorld::CellCoordinates newCoordinates = coordinates.move(x, y); - if (mCells.find (newCoordinates)==mCells.end()) + if (mCells.find(newCoordinates) == mCells.end()) { - addCellToScene (newCoordinates); - mSelection.add (newCoordinates); + addCellToScene(newCoordinates); + mSelection.add(newCoordinates); modified = true; } if (type == InteractionType_SecondaryEdit) { - if (mCells.find (coordinates)!=mCells.end()) + if (mCells.find(coordinates) != mCells.end()) { - removeCellFromScene (coordinates); - mSelection.remove (coordinates); + removeCellFromScene(coordinates); + mSelection.remove(coordinates); modified = true; } } @@ -207,73 +213,61 @@ void CSVRender::PagedWorldspaceWidget::handleInteractionPress (const WorldspaceH } } - WorldspaceWidget::handleInteractionPress (hit, type); + WorldspaceWidget::handleInteractionPress(hit, type); } -void CSVRender::PagedWorldspaceWidget::referenceableDataChanged (const QModelIndex& topLeft, - const QModelIndex& bottomRight) +void CSVRender::PagedWorldspaceWidget::referenceableDataChanged( + const QModelIndex& topLeft, const QModelIndex& bottomRight) { - for (std::map::iterator iter (mCells.begin()); - iter!=mCells.end(); ++iter) - if (iter->second->referenceableDataChanged (topLeft, bottomRight)) + for (std::map::iterator iter(mCells.begin()); iter != mCells.end(); ++iter) + if (iter->second->referenceableDataChanged(topLeft, bottomRight)) flagAsModified(); } -void CSVRender::PagedWorldspaceWidget::referenceableAboutToBeRemoved ( - const QModelIndex& parent, int start, int end) +void CSVRender::PagedWorldspaceWidget::referenceableAboutToBeRemoved(const QModelIndex& parent, int start, int end) { - for (std::map::iterator iter (mCells.begin()); - iter!=mCells.end(); ++iter) - if (iter->second->referenceableAboutToBeRemoved (parent, start, end)) + for (std::map::iterator iter(mCells.begin()); iter != mCells.end(); ++iter) + if (iter->second->referenceableAboutToBeRemoved(parent, start, end)) flagAsModified(); } -void CSVRender::PagedWorldspaceWidget::referenceableAdded (const QModelIndex& parent, - int start, int end) +void CSVRender::PagedWorldspaceWidget::referenceableAdded(const QModelIndex& parent, int start, int end) { - CSMWorld::IdTable& referenceables = dynamic_cast ( - *mDocument.getData().getTableModel (CSMWorld::UniversalId::Type_Referenceables)); + CSMWorld::IdTable& referenceables = dynamic_cast( + *mDocument.getData().getTableModel(CSMWorld::UniversalId::Type_Referenceables)); - for (std::map::iterator iter (mCells.begin()); - iter!=mCells.end(); ++iter) + for (std::map::iterator iter(mCells.begin()); iter != mCells.end(); ++iter) { - QModelIndex topLeft = referenceables.index (start, 0); - QModelIndex bottomRight = - referenceables.index (end, referenceables.columnCount()); + QModelIndex topLeft = referenceables.index(start, 0); + QModelIndex bottomRight = referenceables.index(end, referenceables.columnCount()); - if (iter->second->referenceableDataChanged (topLeft, bottomRight)) + if (iter->second->referenceableDataChanged(topLeft, bottomRight)) flagAsModified(); } } -void CSVRender::PagedWorldspaceWidget::referenceDataChanged (const QModelIndex& topLeft, - const QModelIndex& bottomRight) +void CSVRender::PagedWorldspaceWidget::referenceDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) { - for (std::map::iterator iter (mCells.begin()); - iter!=mCells.end(); ++iter) - if (iter->second->referenceDataChanged (topLeft, bottomRight)) + for (std::map::iterator iter(mCells.begin()); iter != mCells.end(); ++iter) + if (iter->second->referenceDataChanged(topLeft, bottomRight)) flagAsModified(); } -void CSVRender::PagedWorldspaceWidget::referenceAboutToBeRemoved (const QModelIndex& parent, - int start, int end) +void CSVRender::PagedWorldspaceWidget::referenceAboutToBeRemoved(const QModelIndex& parent, int start, int end) { - for (std::map::iterator iter (mCells.begin()); - iter!=mCells.end(); ++iter) - if (iter->second->referenceAboutToBeRemoved (parent, start, end)) + for (std::map::iterator iter(mCells.begin()); iter != mCells.end(); ++iter) + if (iter->second->referenceAboutToBeRemoved(parent, start, end)) flagAsModified(); } -void CSVRender::PagedWorldspaceWidget::referenceAdded (const QModelIndex& parent, int start, - int end) +void CSVRender::PagedWorldspaceWidget::referenceAdded(const QModelIndex& parent, int start, int end) { - for (std::map::iterator iter (mCells.begin()); - iter!=mCells.end(); ++iter) - if (iter->second->referenceAdded (parent, start, end)) + for (std::map::iterator iter(mCells.begin()); iter != mCells.end(); ++iter) + if (iter->second->referenceAdded(parent, start, end)) flagAsModified(); } -void CSVRender::PagedWorldspaceWidget::pathgridDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) +void CSVRender::PagedWorldspaceWidget::pathgridDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) { const CSMWorld::SubCellCollection& pathgrids = mDocument.getData().getPathgrids(); @@ -305,7 +299,7 @@ void CSVRender::PagedWorldspaceWidget::pathgridDataChanged (const QModelIndex& t } } -void CSVRender::PagedWorldspaceWidget::pathgridAboutToBeRemoved (const QModelIndex& parent, int start, int end) +void CSVRender::PagedWorldspaceWidget::pathgridAboutToBeRemoved(const QModelIndex& parent, int start, int end) { const CSMWorld::SubCellCollection& pathgrids = mDocument.getData().getPathgrids(); @@ -329,7 +323,7 @@ void CSVRender::PagedWorldspaceWidget::pathgridAboutToBeRemoved (const QModelInd void CSVRender::PagedWorldspaceWidget::pathgridAdded(const QModelIndex& parent, int start, int end) { - const CSMWorld::SubCellCollection& pathgrids = mDocument.getData().getPathgrids(); + const CSMWorld::SubCellCollection& pathgrids = mDocument.getData().getPathgrids(); if (!parent.isValid()) { @@ -348,7 +342,7 @@ void CSVRender::PagedWorldspaceWidget::pathgridAdded(const QModelIndex& parent, } } -void CSVRender::PagedWorldspaceWidget::landDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) +void CSVRender::PagedWorldspaceWidget::landDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) { for (int r = topLeft.row(); r <= bottomRight.row(); ++r) { @@ -363,7 +357,7 @@ void CSVRender::PagedWorldspaceWidget::landDataChanged (const QModelIndex& topLe } } -void CSVRender::PagedWorldspaceWidget::landAboutToBeRemoved (const QModelIndex& parent, int start, int end) +void CSVRender::PagedWorldspaceWidget::landAboutToBeRemoved(const QModelIndex& parent, int start, int end) { for (int r = start; r <= end; ++r) { @@ -378,7 +372,7 @@ void CSVRender::PagedWorldspaceWidget::landAboutToBeRemoved (const QModelIndex& } } -void CSVRender::PagedWorldspaceWidget::landAdded (const QModelIndex& parent, int start, int end) +void CSVRender::PagedWorldspaceWidget::landAdded(const QModelIndex& parent, int start, int end) { for (int r = start; r <= end; ++r) { @@ -393,28 +387,28 @@ void CSVRender::PagedWorldspaceWidget::landAdded (const QModelIndex& parent, int } } -void CSVRender::PagedWorldspaceWidget::landTextureDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) +void CSVRender::PagedWorldspaceWidget::landTextureDataChanged( + const QModelIndex& topLeft, const QModelIndex& bottomRight) { for (auto cellIt : mCells) cellIt.second->landTextureChanged(topLeft, bottomRight); flagAsModified(); } -void CSVRender::PagedWorldspaceWidget::landTextureAboutToBeRemoved (const QModelIndex& parent, int start, int end) +void CSVRender::PagedWorldspaceWidget::landTextureAboutToBeRemoved(const QModelIndex& parent, int start, int end) { for (auto cellIt : mCells) cellIt.second->landTextureAboutToBeRemoved(parent, start, end); flagAsModified(); } -void CSVRender::PagedWorldspaceWidget::landTextureAdded (const QModelIndex& parent, int start, int end) +void CSVRender::PagedWorldspaceWidget::landTextureAdded(const QModelIndex& parent, int start, int end) { for (auto cellIt : mCells) cellIt.second->landTextureAdded(parent, start, end); flagAsModified(); } - std::string CSVRender::PagedWorldspaceWidget::getStartupInstruction() { osg::Vec3d eye, center, up; @@ -423,82 +417,73 @@ std::string CSVRender::PagedWorldspaceWidget::getStartupInstruction() std::ostringstream stream; - stream - << "player->position " - << position.x() << ", " << position.y() << ", " << position.z() - << ", 0"; + stream << "player->position " << position.x() << ", " << position.y() << ", " << position.z() << ", 0"; return stream.str(); } -void CSVRender::PagedWorldspaceWidget::addCellToScene ( - const CSMWorld::CellCoordinates& coordinates) +void CSVRender::PagedWorldspaceWidget::addCellToScene(const CSMWorld::CellCoordinates& coordinates) { const CSMWorld::IdCollection& cells = mDocument.getData().getCells(); - int index = cells.searchId (coordinates.getId (mWorldspace)); + int index = cells.searchId(coordinates.getId(mWorldspace)); - bool deleted = index==-1 || - cells.getRecord (index).mState==CSMWorld::RecordBase::State_Deleted; + bool deleted = index == -1 || cells.getRecord(index).mState == CSMWorld::RecordBase::State_Deleted; - auto cell = std::make_unique(mDocument.getData(), mRootNode, coordinates.getId (mWorldspace), deleted); - EditMode *editMode = getEditMode(); - cell->setSubMode (editMode->getSubMode(), editMode->getInteractionMask()); + auto cell = std::make_unique(mDocument.getData(), mRootNode, coordinates.getId(mWorldspace), deleted); + EditMode* editMode = getEditMode(); + cell->setSubMode(editMode->getSubMode(), editMode->getInteractionMask()); - mCells.insert (std::make_pair (coordinates, cell.release())); + mCells.insert(std::make_pair(coordinates, cell.release())); } -void CSVRender::PagedWorldspaceWidget::removeCellFromScene ( - const CSMWorld::CellCoordinates& coordinates) +void CSVRender::PagedWorldspaceWidget::removeCellFromScene(const CSMWorld::CellCoordinates& coordinates) { - std::map::iterator iter = mCells.find (coordinates); + std::map::iterator iter = mCells.find(coordinates); - if (iter!=mCells.end()) + if (iter != mCells.end()) { delete iter->second; - mCells.erase (iter); + mCells.erase(iter); } } -void CSVRender::PagedWorldspaceWidget::addCellSelection (int x, int y) +void CSVRender::PagedWorldspaceWidget::addCellSelection(int x, int y) { CSMWorld::CellSelection newSelection = mSelection; - newSelection.move (x, y); + newSelection.move(x, y); - for (CSMWorld::CellSelection::Iterator iter (newSelection.begin()); iter!=newSelection.end(); - ++iter) + for (CSMWorld::CellSelection::Iterator iter(newSelection.begin()); iter != newSelection.end(); ++iter) { - if (mCells.find (*iter)==mCells.end()) + if (mCells.find(*iter) == mCells.end()) { - addCellToScene (*iter); - mSelection.add (*iter); + addCellToScene(*iter); + mSelection.add(*iter); } } } -void CSVRender::PagedWorldspaceWidget::moveCellSelection (int x, int y) +void CSVRender::PagedWorldspaceWidget::moveCellSelection(int x, int y) { CSMWorld::CellSelection newSelection = mSelection; - newSelection.move (x, y); + newSelection.move(x, y); - for (CSMWorld::CellSelection::Iterator iter (mSelection.begin()); iter!=mSelection.end(); - ++iter) + for (CSMWorld::CellSelection::Iterator iter(mSelection.begin()); iter != mSelection.end(); ++iter) { - if (!newSelection.has (*iter)) - removeCellFromScene (*iter); + if (!newSelection.has(*iter)) + removeCellFromScene(*iter); } - for (CSMWorld::CellSelection::Iterator iter (newSelection.begin()); iter!=newSelection.end(); - ++iter) + for (CSMWorld::CellSelection::Iterator iter(newSelection.begin()); iter != newSelection.end(); ++iter) { - if (!mSelection.has (*iter)) - addCellToScene (*iter); + if (!mSelection.has(*iter)) + addCellToScene(*iter); } mSelection = newSelection; } -void CSVRender::PagedWorldspaceWidget::addCellToSceneFromCamera (int offsetX, int offsetY) +void CSVRender::PagedWorldspaceWidget::addCellToSceneFromCamera(int offsetX, int offsetY) { osg::Vec3f eye, center, up; getCamera()->getViewMatrixAsLookAt(eye, center, up); @@ -517,84 +502,76 @@ void CSVRender::PagedWorldspaceWidget::addCellToSceneFromCamera (int offsetX, in } } -CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget (QWidget* parent, CSMDoc::Document& document) -: WorldspaceWidget (document, parent), mDocument (document), mWorldspace ("std::default"), - mControlElements(nullptr), mDisplayCellCoord(true) +CSVRender::PagedWorldspaceWidget::PagedWorldspaceWidget(QWidget* parent, CSMDoc::Document& document) + : WorldspaceWidget(document, parent) + , mDocument(document) + , mWorldspace("std::default") + , mControlElements(nullptr) + , mDisplayCellCoord(true) { - QAbstractItemModel *cells = - document.getData().getTableModel (CSMWorld::UniversalId::Type_Cells); + QAbstractItemModel* cells = document.getData().getTableModel(CSMWorld::UniversalId::Type_Cells); - connect (cells, &QAbstractItemModel::dataChanged, - this, &PagedWorldspaceWidget::cellDataChanged); - connect (cells, &QAbstractItemModel::rowsRemoved, - this, &PagedWorldspaceWidget::cellRemoved); - connect (cells, &QAbstractItemModel::rowsInserted, - this, &PagedWorldspaceWidget::cellAdded); + connect(cells, &QAbstractItemModel::dataChanged, this, &PagedWorldspaceWidget::cellDataChanged); + connect(cells, &QAbstractItemModel::rowsRemoved, this, &PagedWorldspaceWidget::cellRemoved); + connect(cells, &QAbstractItemModel::rowsInserted, this, &PagedWorldspaceWidget::cellAdded); - connect (&document.getData(), &CSMWorld::Data::assetTablesChanged, - this, &PagedWorldspaceWidget::assetTablesChanged); + connect(&document.getData(), &CSMWorld::Data::assetTablesChanged, this, &PagedWorldspaceWidget::assetTablesChanged); - QAbstractItemModel *lands = document.getData().getTableModel (CSMWorld::UniversalId::Type_Lands); + QAbstractItemModel* lands = document.getData().getTableModel(CSMWorld::UniversalId::Type_Lands); - connect (lands, &QAbstractItemModel::dataChanged, - this, &PagedWorldspaceWidget::landDataChanged); - connect (lands, &QAbstractItemModel::rowsAboutToBeRemoved, - this, &PagedWorldspaceWidget::landAboutToBeRemoved); - connect (lands, &QAbstractItemModel::rowsInserted, - this, &PagedWorldspaceWidget::landAdded); + connect(lands, &QAbstractItemModel::dataChanged, this, &PagedWorldspaceWidget::landDataChanged); + connect(lands, &QAbstractItemModel::rowsAboutToBeRemoved, this, &PagedWorldspaceWidget::landAboutToBeRemoved); + connect(lands, &QAbstractItemModel::rowsInserted, this, &PagedWorldspaceWidget::landAdded); - QAbstractItemModel *ltexs = document.getData().getTableModel (CSMWorld::UniversalId::Type_LandTextures); + QAbstractItemModel* ltexs = document.getData().getTableModel(CSMWorld::UniversalId::Type_LandTextures); - connect (ltexs, &QAbstractItemModel::dataChanged, - this, &PagedWorldspaceWidget::landTextureDataChanged); - connect (ltexs, &QAbstractItemModel::rowsAboutToBeRemoved, - this, &PagedWorldspaceWidget::landTextureAboutToBeRemoved); - connect (ltexs, &QAbstractItemModel::rowsInserted, - this, &PagedWorldspaceWidget::landTextureAdded); + connect(ltexs, &QAbstractItemModel::dataChanged, this, &PagedWorldspaceWidget::landTextureDataChanged); + connect( + ltexs, &QAbstractItemModel::rowsAboutToBeRemoved, this, &PagedWorldspaceWidget::landTextureAboutToBeRemoved); + connect(ltexs, &QAbstractItemModel::rowsInserted, this, &PagedWorldspaceWidget::landTextureAdded); // Shortcuts CSMPrefs::Shortcut* loadCameraCellShortcut = new CSMPrefs::Shortcut("scene-load-cam-cell", this); - connect(loadCameraCellShortcut, qOverload<>(&CSMPrefs::Shortcut::activated), - this, &PagedWorldspaceWidget::loadCameraCell); + connect(loadCameraCellShortcut, qOverload<>(&CSMPrefs::Shortcut::activated), this, + &PagedWorldspaceWidget::loadCameraCell); CSMPrefs::Shortcut* loadCameraEastCellShortcut = new CSMPrefs::Shortcut("scene-load-cam-eastcell", this); - connect(loadCameraEastCellShortcut, qOverload<>(&CSMPrefs::Shortcut::activated), - this, &PagedWorldspaceWidget::loadEastCell); + connect(loadCameraEastCellShortcut, qOverload<>(&CSMPrefs::Shortcut::activated), this, + &PagedWorldspaceWidget::loadEastCell); CSMPrefs::Shortcut* loadCameraNorthCellShortcut = new CSMPrefs::Shortcut("scene-load-cam-northcell", this); - connect(loadCameraNorthCellShortcut, qOverload<>(&CSMPrefs::Shortcut::activated), - this, &PagedWorldspaceWidget::loadNorthCell); + connect(loadCameraNorthCellShortcut, qOverload<>(&CSMPrefs::Shortcut::activated), this, + &PagedWorldspaceWidget::loadNorthCell); CSMPrefs::Shortcut* loadCameraWestCellShortcut = new CSMPrefs::Shortcut("scene-load-cam-westcell", this); - connect(loadCameraWestCellShortcut, qOverload<>(&CSMPrefs::Shortcut::activated), - this, &PagedWorldspaceWidget::loadWestCell); + connect(loadCameraWestCellShortcut, qOverload<>(&CSMPrefs::Shortcut::activated), this, + &PagedWorldspaceWidget::loadWestCell); CSMPrefs::Shortcut* loadCameraSouthCellShortcut = new CSMPrefs::Shortcut("scene-load-cam-southcell", this); - connect(loadCameraSouthCellShortcut, qOverload<>(&CSMPrefs::Shortcut::activated), - this, &PagedWorldspaceWidget::loadSouthCell); + connect(loadCameraSouthCellShortcut, qOverload<>(&CSMPrefs::Shortcut::activated), this, + &PagedWorldspaceWidget::loadSouthCell); } CSVRender::PagedWorldspaceWidget::~PagedWorldspaceWidget() { - for (std::map::iterator iter (mCells.begin()); - iter!=mCells.end(); ++iter) + for (std::map::iterator iter(mCells.begin()); iter != mCells.end(); ++iter) { delete iter->second; } } -void CSVRender::PagedWorldspaceWidget::useViewHint (const std::string& hint) +void CSVRender::PagedWorldspaceWidget::useViewHint(const std::string& hint) { if (!hint.empty()) { CSMWorld::CellSelection selection; - if (hint[0]=='c') + if (hint[0] == 'c') { // syntax: c:#x1 y1; #x2 y2 (number of coordinate pairs can be 0 or larger) char ignore; - std::istringstream stream (hint.c_str()); + std::istringstream stream(hint.c_str()); if (stream >> ignore) { char ignore1; // : or ; @@ -604,61 +581,63 @@ void CSVRender::PagedWorldspaceWidget::useViewHint (const std::string& hint) // Loop through all the coordinates to add them to selection while (stream >> ignore1 >> ignore2 >> x >> y) - selection.add (CSMWorld::CellCoordinates (x, y)); + selection.add(CSMWorld::CellCoordinates(x, y)); // Mark that camera needs setup - mCamPositionSet=false; + mCamPositionSet = false; } } - else if (hint[0]=='r') + else if (hint[0] == 'r') { // syntax r:ref#number (e.g. r:ref#100) char ignore; - std::istringstream stream (hint.c_str()); + std::istringstream stream(hint.c_str()); if (stream >> ignore) // ignore r { char ignore1; // : or ; std::string refCode; // ref#number (e.g. ref#100) - while (stream >> ignore1 >> refCode) {} + while (stream >> ignore1 >> refCode) + { + } - //Find out cell coordinate - CSMWorld::IdTable& references = dynamic_cast ( - *mDocument.getData().getTableModel (CSMWorld::UniversalId::Type_References)); + // Find out cell coordinate + CSMWorld::IdTable& references = dynamic_cast( + *mDocument.getData().getTableModel(CSMWorld::UniversalId::Type_References)); int cellColumn = references.findColumnIndex(CSMWorld::Columns::ColumnId_Cell); QVariant cell = references.data(references.getModelIndex(refCode, cellColumn)).value(); QString cellqs = cell.toString(); - std::istringstream streamCellCoord (cellqs.toStdString().c_str()); + std::istringstream streamCellCoord(cellqs.toStdString().c_str()); - if (streamCellCoord >> ignore) //ignore # + if (streamCellCoord >> ignore) // ignore # { // Current coordinate int x, y; // Loop through all the coordinates to add them to selection while (streamCellCoord >> x >> y) - selection.add (CSMWorld::CellCoordinates (x, y)); + selection.add(CSMWorld::CellCoordinates(x, y)); // Mark that camera needs setup - mCamPositionSet=false; + mCamPositionSet = false; } } } - setCellSelection (selection); + setCellSelection(selection); } } -void CSVRender::PagedWorldspaceWidget::setCellSelection (const CSMWorld::CellSelection& selection) +void CSVRender::PagedWorldspaceWidget::setCellSelection(const CSMWorld::CellSelection& selection) { mSelection = selection; if (adjustCells()) flagAsModified(); - emit cellSelectionChanged (mSelection); + emit cellSelectionChanged(mSelection); } const CSMWorld::CellSelection& CSVRender::PagedWorldspaceWidget::getCellSelection() const @@ -666,22 +645,22 @@ const CSMWorld::CellSelection& CSVRender::PagedWorldspaceWidget::getCellSelectio return mSelection; } -std::pair< int, int > CSVRender::PagedWorldspaceWidget::getCoordinatesFromId (const std::string& record) const +std::pair CSVRender::PagedWorldspaceWidget::getCoordinatesFromId(const std::string& record) const { - std::istringstream stream (record.c_str()); + std::istringstream stream(record.c_str()); char ignore; int x, y; stream >> ignore >> x >> y; return std::make_pair(x, y); } -bool CSVRender::PagedWorldspaceWidget::handleDrop ( - const std::vector< CSMWorld::UniversalId >& universalIdData, DropType type) +bool CSVRender::PagedWorldspaceWidget::handleDrop( + const std::vector& universalIdData, DropType type) { - if (WorldspaceWidget::handleDrop (universalIdData, type)) + if (WorldspaceWidget::handleDrop(universalIdData, type)) return true; - if (type!=Type_CellsExterior) + if (type != Type_CellsExterior) return false; bool selectionChanged = false; @@ -704,11 +683,12 @@ bool CSVRender::PagedWorldspaceWidget::handleDrop ( return true; } -CSVRender::WorldspaceWidget::dropRequirments CSVRender::PagedWorldspaceWidget::getDropRequirements (CSVRender::WorldspaceWidget::DropType type) const +CSVRender::WorldspaceWidget::dropRequirments CSVRender::PagedWorldspaceWidget::getDropRequirements( + CSVRender::WorldspaceWidget::DropType type) const { - dropRequirments requirements = WorldspaceWidget::getDropRequirements (type); + dropRequirments requirements = WorldspaceWidget::getDropRequirements(type); - if (requirements!=ignored) + if (requirements != ignored) return requirements; switch (type) @@ -729,47 +709,44 @@ unsigned int CSVRender::PagedWorldspaceWidget::getVisibilityMask() const return WorldspaceWidget::getVisibilityMask() | mControlElements->getSelectionMask(); } -void CSVRender::PagedWorldspaceWidget::clearSelection (int elementMask) +void CSVRender::PagedWorldspaceWidget::clearSelection(int elementMask) { - for (std::map::iterator iter = mCells.begin(); - iter!=mCells.end(); ++iter) - iter->second->setSelection (elementMask, Cell::Selection_Clear); + for (std::map::iterator iter = mCells.begin(); iter != mCells.end(); ++iter) + iter->second->setSelection(elementMask, Cell::Selection_Clear); flagAsModified(); } -void CSVRender::PagedWorldspaceWidget::invertSelection (int elementMask) +void CSVRender::PagedWorldspaceWidget::invertSelection(int elementMask) { - for (std::map::iterator iter = mCells.begin(); - iter!=mCells.end(); ++iter) - iter->second->setSelection (elementMask, Cell::Selection_Invert); + for (std::map::iterator iter = mCells.begin(); iter != mCells.end(); ++iter) + iter->second->setSelection(elementMask, Cell::Selection_Invert); flagAsModified(); } -void CSVRender::PagedWorldspaceWidget::selectAll (int elementMask) +void CSVRender::PagedWorldspaceWidget::selectAll(int elementMask) { - for (std::map::iterator iter = mCells.begin(); - iter!=mCells.end(); ++iter) - iter->second->setSelection (elementMask, Cell::Selection_All); + for (std::map::iterator iter = mCells.begin(); iter != mCells.end(); ++iter) + iter->second->setSelection(elementMask, Cell::Selection_All); flagAsModified(); } -void CSVRender::PagedWorldspaceWidget::selectAllWithSameParentId (int elementMask) +void CSVRender::PagedWorldspaceWidget::selectAllWithSameParentId(int elementMask) { - for (std::map::iterator iter = mCells.begin(); - iter!=mCells.end(); ++iter) - iter->second->selectAllWithSameParentId (elementMask); + for (std::map::iterator iter = mCells.begin(); iter != mCells.end(); ++iter) + iter->second->selectAllWithSameParentId(elementMask); flagAsModified(); } -void CSVRender::PagedWorldspaceWidget::selectInsideCube(const osg::Vec3d& pointA, const osg::Vec3d& pointB, DragMode dragMode) +void CSVRender::PagedWorldspaceWidget::selectInsideCube( + const osg::Vec3d& pointA, const osg::Vec3d& pointB, DragMode dragMode) { for (auto& cell : mCells) { - cell.second->selectInsideCube (pointA, pointB, dragMode); + cell.second->selectInsideCube(pointA, pointB, dragMode); } } @@ -777,24 +754,22 @@ void CSVRender::PagedWorldspaceWidget::selectWithinDistance(const osg::Vec3d& po { for (auto& cell : mCells) { - cell.second->selectWithinDistance (point, distance, dragMode); + cell.second->selectWithinDistance(point, distance, dragMode); } } -std::string CSVRender::PagedWorldspaceWidget::getCellId (const osg::Vec3f& point) const +std::string CSVRender::PagedWorldspaceWidget::getCellId(const osg::Vec3f& point) const { - CSMWorld::CellCoordinates cellCoordinates ( - static_cast (std::floor (point.x() / Constants::CellSizeInUnits)), - static_cast (std::floor (point.y() / Constants::CellSizeInUnits))); + CSMWorld::CellCoordinates cellCoordinates(static_cast(std::floor(point.x() / Constants::CellSizeInUnits)), + static_cast(std::floor(point.y() / Constants::CellSizeInUnits))); - return cellCoordinates.getId (mWorldspace); + return cellCoordinates.getId(mWorldspace); } CSVRender::Cell* CSVRender::PagedWorldspaceWidget::getCell(const osg::Vec3d& point) const { - CSMWorld::CellCoordinates coords( - static_cast (std::floor (point.x() / Constants::CellSizeInUnits)), - static_cast (std::floor (point.y() / Constants::CellSizeInUnits))); + CSMWorld::CellCoordinates coords(static_cast(std::floor(point.x() / Constants::CellSizeInUnits)), + static_cast(std::floor(point.y() / Constants::CellSizeInUnits))); std::map::const_iterator searchResult = mCells.find(coords); if (searchResult != mCells.end()) @@ -812,14 +787,16 @@ CSVRender::Cell* CSVRender::PagedWorldspaceWidget::getCell(const CSMWorld::CellC return nullptr; } -void CSVRender::PagedWorldspaceWidget::setCellAlteredHeight(const CSMWorld::CellCoordinates& coords, int inCellX, int inCellY, float height) +void CSVRender::PagedWorldspaceWidget::setCellAlteredHeight( + const CSMWorld::CellCoordinates& coords, int inCellX, int inCellY, float height) { std::map::iterator searchResult = mCells.find(coords); if (searchResult != mCells.end()) searchResult->second->setAlteredHeight(inCellX, inCellY, height); } -float* CSVRender::PagedWorldspaceWidget::getCellAlteredHeight(const CSMWorld::CellCoordinates& coords, int inCellX, int inCellY) +float* CSVRender::PagedWorldspaceWidget::getCellAlteredHeight( + const CSMWorld::CellCoordinates& coords, int inCellX, int inCellY) { std::map::iterator searchResult = mCells.find(coords); if (searchResult != mCells.end()) @@ -833,89 +810,80 @@ void CSVRender::PagedWorldspaceWidget::resetAllAlteredHeights() cell.second->resetAlteredHeights(); } -std::vector > CSVRender::PagedWorldspaceWidget::getSelection ( +std::vector> CSVRender::PagedWorldspaceWidget::getSelection( unsigned int elementMask) const { - std::vector > result; + std::vector> result; - for (std::map::const_iterator iter = mCells.begin(); - iter!=mCells.end(); ++iter) + for (std::map::const_iterator iter = mCells.begin(); iter != mCells.end(); ++iter) { - std::vector > cellResult = - iter->second->getSelection (elementMask); + std::vector> cellResult = iter->second->getSelection(elementMask); - result.insert (result.end(), cellResult.begin(), cellResult.end()); + result.insert(result.end(), cellResult.begin(), cellResult.end()); } return result; } -std::vector > CSVRender::PagedWorldspaceWidget::getEdited ( +std::vector> CSVRender::PagedWorldspaceWidget::getEdited( unsigned int elementMask) const { - std::vector > result; + std::vector> result; - for (std::map::const_iterator iter = mCells.begin(); - iter!=mCells.end(); ++iter) + for (std::map::const_iterator iter = mCells.begin(); iter != mCells.end(); ++iter) { - std::vector > cellResult = - iter->second->getEdited (elementMask); + std::vector> cellResult = iter->second->getEdited(elementMask); - result.insert (result.end(), cellResult.begin(), cellResult.end()); + result.insert(result.end(), cellResult.begin(), cellResult.end()); } return result; } -void CSVRender::PagedWorldspaceWidget::setSubMode (int subMode, unsigned int elementMask) +void CSVRender::PagedWorldspaceWidget::setSubMode(int subMode, unsigned int elementMask) { - for (std::map::const_iterator iter = mCells.begin(); - iter!=mCells.end(); ++iter) - iter->second->setSubMode (subMode, elementMask); + for (std::map::const_iterator iter = mCells.begin(); iter != mCells.end(); ++iter) + iter->second->setSubMode(subMode, elementMask); } -void CSVRender::PagedWorldspaceWidget::reset (unsigned int elementMask) +void CSVRender::PagedWorldspaceWidget::reset(unsigned int elementMask) { - for (std::map::const_iterator iter = mCells.begin(); - iter!=mCells.end(); ++iter) - iter->second->reset (elementMask); + for (std::map::const_iterator iter = mCells.begin(); iter != mCells.end(); ++iter) + iter->second->reset(elementMask); } -CSVWidget::SceneToolToggle2 *CSVRender::PagedWorldspaceWidget::makeControlVisibilitySelector ( - CSVWidget::SceneToolbar *parent) +CSVWidget::SceneToolToggle2* CSVRender::PagedWorldspaceWidget::makeControlVisibilitySelector( + CSVWidget::SceneToolbar* parent) { - mControlElements = new CSVWidget::SceneToolToggle2 (parent, - "Controls & Guides Visibility", ":scenetoolbar/scene-view-marker-c", ":scenetoolbar/scene-view-marker-"); + mControlElements = new CSVWidget::SceneToolToggle2(parent, "Controls & Guides Visibility", + ":scenetoolbar/scene-view-marker-c", ":scenetoolbar/scene-view-marker-"); - mControlElements->addButton (1, Mask_CellMarker, "Cell Marker"); - mControlElements->addButton (2, Mask_CellArrow, "Cell Arrows"); - mControlElements->addButton (4, Mask_CellBorder, "Cell Border"); + mControlElements->addButton(1, Mask_CellMarker, "Cell Marker"); + mControlElements->addButton(2, Mask_CellArrow, "Cell Arrows"); + mControlElements->addButton(4, Mask_CellBorder, "Cell Border"); - mControlElements->setSelectionMask (0xffffffff); + mControlElements->setSelectionMask(0xffffffff); - connect (mControlElements, &CSVWidget::SceneToolToggle2::selectionChanged, - this, &PagedWorldspaceWidget::elementSelectionChanged); + connect(mControlElements, &CSVWidget::SceneToolToggle2::selectionChanged, this, + &PagedWorldspaceWidget::elementSelectionChanged); return mControlElements; } -void CSVRender::PagedWorldspaceWidget::cellDataChanged (const QModelIndex& topLeft, - const QModelIndex& bottomRight) +void CSVRender::PagedWorldspaceWidget::cellDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) { /// \todo check if no selected cell is affected and do not update, if that is the case if (adjustCells()) flagAsModified(); } -void CSVRender::PagedWorldspaceWidget::cellRemoved (const QModelIndex& parent, int start, - int end) +void CSVRender::PagedWorldspaceWidget::cellRemoved(const QModelIndex& parent, int start, int end) { if (adjustCells()) flagAsModified(); } -void CSVRender::PagedWorldspaceWidget::cellAdded (const QModelIndex& index, int start, - int end) +void CSVRender::PagedWorldspaceWidget::cellAdded(const QModelIndex& index, int start, int end) { /// \todo check if no selected cell is affected and do not update, if that is the case if (adjustCells()) @@ -924,8 +892,8 @@ void CSVRender::PagedWorldspaceWidget::cellAdded (const QModelIndex& index, int void CSVRender::PagedWorldspaceWidget::assetTablesChanged() { - std::map::iterator iter = mCells.begin(); - for ( ; iter != mCells.end(); ++iter) + std::map::iterator iter = mCells.begin(); + for (; iter != mCells.end(); ++iter) { iter->second->reloadAssets(); } diff --git a/apps/opencs/view/render/pagedworldspacewidget.hpp b/apps/opencs/view/render/pagedworldspacewidget.hpp index beab0c575b..697fbb62e4 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.hpp +++ b/apps/opencs/view/render/pagedworldspacewidget.hpp @@ -5,14 +5,14 @@ #include "../../model/world/cellselection.hpp" -#include "worldspacewidget.hpp" #include "cell.hpp" #include "instancedragmodes.hpp" +#include "worldspacewidget.hpp" namespace CSVWidget { - class SceneToolToggle; - class SceneToolToggle2; + class SceneToolToggle; + class SceneToolToggle2; } namespace CSVRender @@ -22,172 +22,163 @@ namespace CSVRender class PagedWorldspaceWidget : public WorldspaceWidget { - Q_OBJECT - - CSMDoc::Document& mDocument; - CSMWorld::CellSelection mSelection; - std::map mCells; - std::string mWorldspace; - CSVWidget::SceneToolToggle2 *mControlElements; - bool mDisplayCellCoord; - - private: - - std::pair getCoordinatesFromId(const std::string& record) const; - - /// Bring mCells into sync with mSelection again. - /// - /// \return Any cells added or removed? - bool adjustCells(); + Q_OBJECT - void referenceableDataChanged (const QModelIndex& topLeft, - const QModelIndex& bottomRight) override; + CSMDoc::Document& mDocument; + CSMWorld::CellSelection mSelection; + std::map mCells; + std::string mWorldspace; + CSVWidget::SceneToolToggle2* mControlElements; + bool mDisplayCellCoord; - void referenceableAboutToBeRemoved (const QModelIndex& parent, int start, int end) override; + private: + std::pair getCoordinatesFromId(const std::string& record) const; - void referenceableAdded (const QModelIndex& index, int start, int end) override; + /// Bring mCells into sync with mSelection again. + /// + /// \return Any cells added or removed? + bool adjustCells(); - void referenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) override; + void referenceableDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) override; - void referenceAboutToBeRemoved (const QModelIndex& parent, int start, int end) override; + void referenceableAboutToBeRemoved(const QModelIndex& parent, int start, int end) override; - void referenceAdded (const QModelIndex& index, int start, int end) override; + void referenceableAdded(const QModelIndex& index, int start, int end) override; - void pathgridDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) override; + void referenceDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) override; - void pathgridAboutToBeRemoved (const QModelIndex& parent, int start, int end) override; + void referenceAboutToBeRemoved(const QModelIndex& parent, int start, int end) override; - void pathgridAdded (const QModelIndex& parent, int start, int end) override; + void referenceAdded(const QModelIndex& index, int start, int end) override; - std::string getStartupInstruction() override; + void pathgridDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) override; - /// \note Does not update the view or any cell marker - void addCellToScene (const CSMWorld::CellCoordinates& coordinates); + void pathgridAboutToBeRemoved(const QModelIndex& parent, int start, int end) override; - /// \note Does not update the view or any cell marker - /// - /// \note Calling this function for a cell that is not in the selection is a no-op. - void removeCellFromScene (const CSMWorld::CellCoordinates& coordinates); + void pathgridAdded(const QModelIndex& parent, int start, int end) override; - /// \note Does not update the view or any cell marker - void addCellSelection (int x, int y); + std::string getStartupInstruction() override; - /// \note Does not update the view or any cell marker - void moveCellSelection (int x, int y); + /// \note Does not update the view or any cell marker + void addCellToScene(const CSMWorld::CellCoordinates& coordinates); - void addCellToSceneFromCamera (int offsetX, int offsetY); + /// \note Does not update the view or any cell marker + /// + /// \note Calling this function for a cell that is not in the selection is a no-op. + void removeCellFromScene(const CSMWorld::CellCoordinates& coordinates); - public: + /// \note Does not update the view or any cell marker + void addCellSelection(int x, int y); - PagedWorldspaceWidget (QWidget *parent, CSMDoc::Document& document); - ///< \note Sets the cell area selection to an invalid value to indicate that currently - /// no cells are displayed. The cells to be displayed will be specified later through - /// hint system. + /// \note Does not update the view or any cell marker + void moveCellSelection(int x, int y); - virtual ~PagedWorldspaceWidget(); + void addCellToSceneFromCamera(int offsetX, int offsetY); - /// Decodes the the hint string to set of cell that are rendered. - void useViewHint (const std::string& hint) override; + public: + PagedWorldspaceWidget(QWidget* parent, CSMDoc::Document& document); + ///< \note Sets the cell area selection to an invalid value to indicate that currently + /// no cells are displayed. The cells to be displayed will be specified later through + /// hint system. - void setCellSelection(const CSMWorld::CellSelection& selection); + virtual ~PagedWorldspaceWidget(); - const CSMWorld::CellSelection& getCellSelection() const; + /// Decodes the the hint string to set of cell that are rendered. + void useViewHint(const std::string& hint) override; - /// \return Drop handled? - bool handleDrop (const std::vector& data, - DropType type) override; + void setCellSelection(const CSMWorld::CellSelection& selection); - dropRequirments getDropRequirements(DropType type) const override; + const CSMWorld::CellSelection& getCellSelection() const; - /// \attention The created tool is not added to the toolbar (via addTool). Doing - /// that is the responsibility of the calling function. - virtual CSVWidget::SceneToolToggle2 *makeControlVisibilitySelector ( - CSVWidget::SceneToolbar *parent); + /// \return Drop handled? + bool handleDrop(const std::vector& data, DropType type) override; - unsigned int getVisibilityMask() const override; + dropRequirments getDropRequirements(DropType type) const override; - /// \param elementMask Elements to be affected by the clear operation - void clearSelection (int elementMask) override; + /// \attention The created tool is not added to the toolbar (via addTool). Doing + /// that is the responsibility of the calling function. + virtual CSVWidget::SceneToolToggle2* makeControlVisibilitySelector(CSVWidget::SceneToolbar* parent); - /// \param elementMask Elements to be affected by the select operation - void invertSelection (int elementMask) override; + unsigned int getVisibilityMask() const override; - /// \param elementMask Elements to be affected by the select operation - void selectAll (int elementMask) override; + /// \param elementMask Elements to be affected by the clear operation + void clearSelection(int elementMask) override; - // Select everything that references the same ID as at least one of the elements - // already selected - // - /// \param elementMask Elements to be affected by the select operation - void selectAllWithSameParentId (int elementMask) override; + /// \param elementMask Elements to be affected by the select operation + void invertSelection(int elementMask) override; - void selectInsideCube(const osg::Vec3d& pointA, const osg::Vec3d& pointB, DragMode dragMode) override; + /// \param elementMask Elements to be affected by the select operation + void selectAll(int elementMask) override; - void selectWithinDistance(const osg::Vec3d& point, float distance, DragMode dragMode) override; + // Select everything that references the same ID as at least one of the elements + // already selected + // + /// \param elementMask Elements to be affected by the select operation + void selectAllWithSameParentId(int elementMask) override; - std::string getCellId (const osg::Vec3f& point) const override; + void selectInsideCube(const osg::Vec3d& pointA, const osg::Vec3d& pointB, DragMode dragMode) override; - Cell* getCell(const osg::Vec3d& point) const override; + void selectWithinDistance(const osg::Vec3d& point, float distance, DragMode dragMode) override; - Cell* getCell(const CSMWorld::CellCoordinates& coords) const override; + std::string getCellId(const osg::Vec3f& point) const override; - void setCellAlteredHeight(const CSMWorld::CellCoordinates& coords, int inCellX, int inCellY, float height); + Cell* getCell(const osg::Vec3d& point) const override; - float* getCellAlteredHeight(const CSMWorld::CellCoordinates& coords, int inCellX, int inCellY); + Cell* getCell(const CSMWorld::CellCoordinates& coords) const override; - void resetAllAlteredHeights(); + void setCellAlteredHeight(const CSMWorld::CellCoordinates& coords, int inCellX, int inCellY, float height); - std::vector > getSelection (unsigned int elementMask) - const override; + float* getCellAlteredHeight(const CSMWorld::CellCoordinates& coords, int inCellX, int inCellY); - std::vector > getEdited (unsigned int elementMask) - const override; + void resetAllAlteredHeights(); - void setSubMode (int subMode, unsigned int elementMask) override; + std::vector> getSelection(unsigned int elementMask) const override; - /// Erase all overrides and restore the visual representation to its true state. - void reset (unsigned int elementMask) override; + std::vector> getEdited(unsigned int elementMask) const override; - protected: + void setSubMode(int subMode, unsigned int elementMask) override; - void addVisibilitySelectorButtons (CSVWidget::SceneToolToggle2 *tool) override; + /// Erase all overrides and restore the visual representation to its true state. + void reset(unsigned int elementMask) override; - void addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool) override; + protected: + void addVisibilitySelectorButtons(CSVWidget::SceneToolToggle2* tool) override; - void handleInteractionPress (const WorldspaceHitResult& hit, InteractionType type) override; + void addEditModeSelectorButtons(CSVWidget::SceneToolMode* tool) override; - signals: + void handleInteractionPress(const WorldspaceHitResult& hit, InteractionType type) override; - void cellSelectionChanged (const CSMWorld::CellSelection& selection); + signals: - private slots: + void cellSelectionChanged(const CSMWorld::CellSelection& selection); - virtual void cellDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); + private slots: - virtual void cellRemoved (const QModelIndex& parent, int start, int end); + virtual void cellDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); - virtual void cellAdded (const QModelIndex& index, int start, int end); + virtual void cellRemoved(const QModelIndex& parent, int start, int end); - virtual void landDataChanged (const QModelIndex& topLeft, const QModelIndex& botomRight); - virtual void landAboutToBeRemoved (const QModelIndex& parent, int start, int end); - virtual void landAdded (const QModelIndex& parent, int start, int end); + virtual void cellAdded(const QModelIndex& index, int start, int end); - virtual void landTextureDataChanged (const QModelIndex& topLeft, const QModelIndex& botomRight); - virtual void landTextureAboutToBeRemoved (const QModelIndex& parent, int start, int end); - virtual void landTextureAdded (const QModelIndex& parent, int start, int end); + virtual void landDataChanged(const QModelIndex& topLeft, const QModelIndex& botomRight); + virtual void landAboutToBeRemoved(const QModelIndex& parent, int start, int end); + virtual void landAdded(const QModelIndex& parent, int start, int end); - void assetTablesChanged (); + virtual void landTextureDataChanged(const QModelIndex& topLeft, const QModelIndex& botomRight); + virtual void landTextureAboutToBeRemoved(const QModelIndex& parent, int start, int end); + virtual void landTextureAdded(const QModelIndex& parent, int start, int end); - void loadCameraCell(); + void assetTablesChanged(); - void loadEastCell(); + void loadCameraCell(); - void loadNorthCell(); + void loadEastCell(); - void loadWestCell(); + void loadNorthCell(); - void loadSouthCell(); + void loadWestCell(); + void loadSouthCell(); }; } diff --git a/apps/opencs/view/render/pathgrid.cpp b/apps/opencs/view/render/pathgrid.cpp index a45a4b427e..6de471ba67 100644 --- a/apps/opencs/view/render/pathgrid.cpp +++ b/apps/opencs/view/render/pathgrid.cpp @@ -10,8 +10,8 @@ #include -#include "../../model/world/commands.hpp" #include "../../model/world/commandmacro.hpp" +#include "../../model/world/commands.hpp" #include "../../model/world/data.hpp" #include "../../model/world/idtree.hpp" #include "worldspacewidget.hpp" @@ -20,17 +20,17 @@ namespace CSVRender { class PathgridNodeCallback : public osg::NodeCallback { - public: - - void operator()(osg::Node* node, osg::NodeVisitor* nv) override - { - PathgridTag* tag = static_cast(node->getUserData()); - tag->getPathgrid()->update(); - } + public: + void operator()(osg::Node* node, osg::NodeVisitor* nv) override + { + PathgridTag* tag = static_cast(node->getUserData()); + tag->getPathgrid()->update(); + } }; PathgridTag::PathgridTag(Pathgrid* pathgrid) - : TagBase(Mask_Pathgrid), mPathgrid(pathgrid) + : TagBase(Mask_Pathgrid) + , mPathgrid(pathgrid) { } @@ -68,7 +68,7 @@ namespace CSVRender { const float CoordScalar = ESM::Land::REAL_SIZE; - mBaseNode = new osg::PositionAttitudeTransform (); + mBaseNode = new osg::PositionAttitudeTransform(); mBaseNode->setPosition(osg::Vec3f(mCoords.getX() * CoordScalar, mCoords.getY() * CoordScalar, 0.f)); mBaseNode->setUserData(mTag); mBaseNode->setUpdateCallback(new PathgridNodeCallback()); @@ -226,7 +226,8 @@ namespace CSVRender void Pathgrid::applyPoint(CSMWorld::CommandMacro& commands, const osg::Vec3d& worldPos) { - CSMWorld::IdTree* model = &dynamic_cast(*mData.getTableModel(CSMWorld::UniversalId::Type_Pathgrids)); + CSMWorld::IdTree* model + = &dynamic_cast(*mData.getTableModel(CSMWorld::UniversalId::Type_Pathgrids)); const CSMWorld::Pathgrid* source = getPathgridSource(); if (source) @@ -237,17 +238,17 @@ namespace CSVRender int posY = clampToCell(static_cast(localCoords.y())); int posZ = clampToCell(static_cast(localCoords.z())); - int recordIndex = mPathgridCollection.getIndex (mId); + int recordIndex = mPathgridCollection.getIndex(mId); int parentColumn = mPathgridCollection.findColumnIndex(CSMWorld::Columns::ColumnId_PathgridPoints); - int posXColumn = mPathgridCollection.searchNestedColumnIndex(parentColumn, - CSMWorld::Columns::ColumnId_PathgridPosX); + int posXColumn + = mPathgridCollection.searchNestedColumnIndex(parentColumn, CSMWorld::Columns::ColumnId_PathgridPosX); - int posYColumn = mPathgridCollection.searchNestedColumnIndex(parentColumn, - CSMWorld::Columns::ColumnId_PathgridPosY); + int posYColumn + = mPathgridCollection.searchNestedColumnIndex(parentColumn, CSMWorld::Columns::ColumnId_PathgridPosY); - int posZColumn = mPathgridCollection.searchNestedColumnIndex(parentColumn, - CSMWorld::Columns::ColumnId_PathgridPosZ); + int posZColumn + = mPathgridCollection.searchNestedColumnIndex(parentColumn, CSMWorld::Columns::ColumnId_PathgridPosZ); QModelIndex parent = model->index(recordIndex, parentColumn); int row = static_cast(source->mPoints.size()); @@ -304,14 +305,14 @@ namespace CSVRender int recordIndex = mPathgridCollection.getIndex(mId); int parentColumn = mPathgridCollection.findColumnIndex(CSMWorld::Columns::ColumnId_PathgridPoints); - int posXColumn = mPathgridCollection.searchNestedColumnIndex(parentColumn, - CSMWorld::Columns::ColumnId_PathgridPosX); + int posXColumn + = mPathgridCollection.searchNestedColumnIndex(parentColumn, CSMWorld::Columns::ColumnId_PathgridPosX); - int posYColumn = mPathgridCollection.searchNestedColumnIndex(parentColumn, - CSMWorld::Columns::ColumnId_PathgridPosY); + int posYColumn + = mPathgridCollection.searchNestedColumnIndex(parentColumn, CSMWorld::Columns::ColumnId_PathgridPosY); - int posZColumn = mPathgridCollection.searchNestedColumnIndex(parentColumn, - CSMWorld::Columns::ColumnId_PathgridPosZ); + int posZColumn + = mPathgridCollection.searchNestedColumnIndex(parentColumn, CSMWorld::Columns::ColumnId_PathgridPosZ); QModelIndex parent = model->index(recordIndex, parentColumn); @@ -320,14 +321,14 @@ namespace CSVRender const CSMWorld::Pathgrid::Point& point = source->mPoints[mSelected[i]]; int row = static_cast(mSelected[i]); - commands.push(new CSMWorld::ModifyCommand(*model, model->index(row, posXColumn, parent), - clampToCell(point.mX + offsetX))); + commands.push(new CSMWorld::ModifyCommand( + *model, model->index(row, posXColumn, parent), clampToCell(point.mX + offsetX))); - commands.push(new CSMWorld::ModifyCommand(*model, model->index(row, posYColumn, parent), - clampToCell(point.mY + offsetY))); + commands.push(new CSMWorld::ModifyCommand( + *model, model->index(row, posYColumn, parent), clampToCell(point.mY + offsetY))); - commands.push(new CSMWorld::ModifyCommand(*model, model->index(row, posZColumn, parent), - clampToCell(point.mZ + offsetZ))); + commands.push(new CSMWorld::ModifyCommand( + *model, model->index(row, posZColumn, parent), clampToCell(point.mZ + offsetZ))); } } } @@ -358,7 +359,8 @@ namespace CSVRender const CSMWorld::Pathgrid* source = getPathgridSource(); if (source) { - CSMWorld::IdTree* model = &dynamic_cast(*mData.getTableModel(CSMWorld::UniversalId::Type_Pathgrids)); + CSMWorld::IdTree* model + = &dynamic_cast(*mData.getTableModel(CSMWorld::UniversalId::Type_Pathgrids)); // Want to remove nodes from end of list first std::sort(mSelected.begin(), mSelected.end(), std::greater()); @@ -372,15 +374,15 @@ namespace CSVRender } // Fix/remove edges - std::set > edgeRowsToRemove; + std::set> edgeRowsToRemove; parentColumn = mPathgridCollection.findColumnIndex(CSMWorld::Columns::ColumnId_PathgridEdges); - int edge0Column = mPathgridCollection.searchNestedColumnIndex(parentColumn, - CSMWorld::Columns::ColumnId_PathgridEdge0); + int edge0Column + = mPathgridCollection.searchNestedColumnIndex(parentColumn, CSMWorld::Columns::ColumnId_PathgridEdge0); - int edge1Column = mPathgridCollection.searchNestedColumnIndex(parentColumn, - CSMWorld::Columns::ColumnId_PathgridEdge1); + int edge1Column + = mPathgridCollection.searchNestedColumnIndex(parentColumn, CSMWorld::Columns::ColumnId_PathgridEdge1); QModelIndex parent = model->index(recordIndex, parentColumn); @@ -411,19 +413,19 @@ namespace CSVRender if (adjustment0 != 0) { int adjustedEdge = source->mEdges[edge].mV0 + adjustment0; - commands.push(new CSMWorld::ModifyCommand(*model, model->index(edge, edge0Column, parent), - adjustedEdge)); + commands.push( + new CSMWorld::ModifyCommand(*model, model->index(edge, edge0Column, parent), adjustedEdge)); } if (adjustment1 != 0) { int adjustedEdge = source->mEdges[edge].mV1 + adjustment1; - commands.push(new CSMWorld::ModifyCommand(*model, model->index(edge, edge1Column, parent), - adjustedEdge)); + commands.push( + new CSMWorld::ModifyCommand(*model, model->index(edge, edge1Column, parent), adjustedEdge)); } } - std::set >::iterator row; + std::set>::iterator row; for (row = edgeRowsToRemove.begin(); row != edgeRowsToRemove.end(); ++row) { commands.push(new CSMWorld::DeleteNestedCommand(*model, mId, *row, parentColumn)); @@ -439,7 +441,7 @@ namespace CSVRender if (source) { // Want to remove from end of row first - std::set > rowsToRemove; + std::set> rowsToRemove; for (size_t i = 0; i <= mSelected.size(); ++i) { for (size_t j = i + 1; j < mSelected.size(); ++j) @@ -458,10 +460,11 @@ namespace CSVRender } } - CSMWorld::IdTree* model = &dynamic_cast(*mData.getTableModel(CSMWorld::UniversalId::Type_Pathgrids)); + CSMWorld::IdTree* model + = &dynamic_cast(*mData.getTableModel(CSMWorld::UniversalId::Type_Pathgrids)); int parentColumn = mPathgridCollection.findColumnIndex(CSMWorld::Columns::ColumnId_PathgridEdges); - std::set >::iterator row; + std::set>::iterator row; for (row = rowsToRemove.begin(); row != rowsToRemove.end(); ++row) { commands.push(new CSMWorld::DeleteNestedCommand(*model, mId, *row, parentColumn)); @@ -628,19 +631,20 @@ namespace CSVRender return -1; } - void Pathgrid::addEdge(CSMWorld::CommandMacro& commands, const CSMWorld::Pathgrid& source, unsigned short node1, - unsigned short node2) + void Pathgrid::addEdge( + CSMWorld::CommandMacro& commands, const CSMWorld::Pathgrid& source, unsigned short node1, unsigned short node2) { - CSMWorld::IdTree* model = &dynamic_cast(*mData.getTableModel(CSMWorld::UniversalId::Type_Pathgrids)); + CSMWorld::IdTree* model + = &dynamic_cast(*mData.getTableModel(CSMWorld::UniversalId::Type_Pathgrids)); int recordIndex = mPathgridCollection.getIndex(mId); int parentColumn = mPathgridCollection.findColumnIndex(CSMWorld::Columns::ColumnId_PathgridEdges); - int edge0Column = mPathgridCollection.searchNestedColumnIndex(parentColumn, - CSMWorld::Columns::ColumnId_PathgridEdge0); + int edge0Column + = mPathgridCollection.searchNestedColumnIndex(parentColumn, CSMWorld::Columns::ColumnId_PathgridEdge0); - int edge1Column = mPathgridCollection.searchNestedColumnIndex(parentColumn, - CSMWorld::Columns::ColumnId_PathgridEdge1); + int edge1Column + = mPathgridCollection.searchNestedColumnIndex(parentColumn, CSMWorld::Columns::ColumnId_PathgridEdge1); QModelIndex parent = model->index(recordIndex, parentColumn); int row = static_cast(source.mEdges.size()); diff --git a/apps/opencs/view/render/pathgrid.hpp b/apps/opencs/view/render/pathgrid.hpp index ea17942e81..1e3ce081cb 100644 --- a/apps/opencs/view/render/pathgrid.hpp +++ b/apps/opencs/view/render/pathgrid.hpp @@ -4,8 +4,8 @@ #include #include -#include #include +#include #include "../../model/world/cellcoordinates.hpp" #include "../../model/world/subcellcollection.hpp" @@ -32,103 +32,99 @@ namespace CSVRender class PathgridTag : public TagBase { - public: - - PathgridTag (Pathgrid* pathgrid); + public: + PathgridTag(Pathgrid* pathgrid); - Pathgrid* getPathgrid () const; + Pathgrid* getPathgrid() const; - QString getToolTip (bool hideBasics, const WorldspaceHitResult& hit) const override; + QString getToolTip(bool hideBasics, const WorldspaceHitResult& hit) const override; - private: - - Pathgrid* mPathgrid; + private: + Pathgrid* mPathgrid; }; class Pathgrid { - public: - - typedef std::vector NodeList; - - Pathgrid(CSMWorld::Data& data, osg::Group* parent, const std::string& pathgridId, - const CSMWorld::CellCoordinates& coordinates); + public: + typedef std::vector NodeList; - ~Pathgrid(); + Pathgrid(CSMWorld::Data& data, osg::Group* parent, const std::string& pathgridId, + const CSMWorld::CellCoordinates& coordinates); - const CSMWorld::CellCoordinates& getCoordinates() const; - const std::string& getId() const; + ~Pathgrid(); - bool isSelected() const; - const NodeList& getSelected() const; - void selectAll(); - void toggleSelected(unsigned short node); // Adds to end of vector - void invertSelected(); - void clearSelected(); + const CSMWorld::CellCoordinates& getCoordinates() const; + const std::string& getId() const; - void moveSelected(const osg::Vec3d& offset); - void setDragOrigin(unsigned short node); - void setDragEndpoint(unsigned short node); - void setDragEndpoint(const osg::Vec3d& pos); + bool isSelected() const; + const NodeList& getSelected() const; + void selectAll(); + void toggleSelected(unsigned short node); // Adds to end of vector + void invertSelected(); + void clearSelected(); - void resetIndicators(); + void moveSelected(const osg::Vec3d& offset); + void setDragOrigin(unsigned short node); + void setDragEndpoint(unsigned short node); + void setDragEndpoint(const osg::Vec3d& pos); - void applyPoint(CSMWorld::CommandMacro& commands, const osg::Vec3d& worldPos); - void applyPosition(CSMWorld::CommandMacro& commands); - void applyEdge(CSMWorld::CommandMacro& commands, unsigned short node1, unsigned short node2); - void applyEdges(CSMWorld::CommandMacro& commands, unsigned short node); - void applyRemoveNodes(CSMWorld::CommandMacro& commands); - void applyRemoveEdges(CSMWorld::CommandMacro& commands); + void resetIndicators(); - osg::ref_ptr getTag() const; + void applyPoint(CSMWorld::CommandMacro& commands, const osg::Vec3d& worldPos); + void applyPosition(CSMWorld::CommandMacro& commands); + void applyEdge(CSMWorld::CommandMacro& commands, unsigned short node1, unsigned short node2); + void applyEdges(CSMWorld::CommandMacro& commands, unsigned short node); + void applyRemoveNodes(CSMWorld::CommandMacro& commands); + void applyRemoveEdges(CSMWorld::CommandMacro& commands); - void recreateGeometry(); - void removeGeometry(); + osg::ref_ptr getTag() const; - void update(); + void recreateGeometry(); + void removeGeometry(); - private: + void update(); - CSMWorld::Data& mData; - CSMWorld::SubCellCollection& mPathgridCollection; - std::string mId; - CSMWorld::CellCoordinates mCoords; - bool mInterior; + private: + CSMWorld::Data& mData; + CSMWorld::SubCellCollection& mPathgridCollection; + std::string mId; + CSMWorld::CellCoordinates mCoords; + bool mInterior; - NodeList mSelected; - osg::Vec3d mMoveOffset; - unsigned short mDragOrigin; + NodeList mSelected; + osg::Vec3d mMoveOffset; + unsigned short mDragOrigin; - bool mChangeGeometry; - bool mRemoveGeometry; - bool mUseOffset; + bool mChangeGeometry; + bool mRemoveGeometry; + bool mUseOffset; - osg::Group* mParent; - osg::ref_ptr mBaseNode; - osg::ref_ptr mPathgridGroup; - osg::ref_ptr mPathgridGeometry; - osg::ref_ptr mSelectedGeometry; - osg::ref_ptr mDragGeometry; + osg::Group* mParent; + osg::ref_ptr mBaseNode; + osg::ref_ptr mPathgridGroup; + osg::ref_ptr mPathgridGeometry; + osg::ref_ptr mSelectedGeometry; + osg::ref_ptr mDragGeometry; - osg::ref_ptr mTag; + osg::ref_ptr mTag; - void createGeometry(); - void createSelectedGeometry(); - void createSelectedGeometry(const CSMWorld::Pathgrid& source); - void removePathgridGeometry(); - void removeSelectedGeometry(); + void createGeometry(); + void createSelectedGeometry(); + void createSelectedGeometry(const CSMWorld::Pathgrid& source); + void removePathgridGeometry(); + void removeSelectedGeometry(); - void createDragGeometry(const osg::Vec3f& start, const osg::Vec3f& end, bool valid); + void createDragGeometry(const osg::Vec3f& start, const osg::Vec3f& end, bool valid); - const CSMWorld::Pathgrid* getPathgridSource(); + const CSMWorld::Pathgrid* getPathgridSource(); - int edgeExists(const CSMWorld::Pathgrid& source, unsigned short node1, unsigned short node2); - void addEdge(CSMWorld::CommandMacro& commands, const CSMWorld::Pathgrid& source, unsigned short node1, - unsigned short node2); - void removeEdge(CSMWorld::CommandMacro& commands, const CSMWorld::Pathgrid& source, unsigned short node1, - unsigned short node2); + int edgeExists(const CSMWorld::Pathgrid& source, unsigned short node1, unsigned short node2); + void addEdge(CSMWorld::CommandMacro& commands, const CSMWorld::Pathgrid& source, unsigned short node1, + unsigned short node2); + void removeEdge(CSMWorld::CommandMacro& commands, const CSMWorld::Pathgrid& source, unsigned short node1, + unsigned short node2); - int clampToCell(int v); + int clampToCell(int v); }; } diff --git a/apps/opencs/view/render/pathgridmode.cpp b/apps/opencs/view/render/pathgridmode.cpp index c267f5762d..b5a94fe0e4 100644 --- a/apps/opencs/view/render/pathgridmode.cpp +++ b/apps/opencs/view/render/pathgridmode.cpp @@ -6,8 +6,8 @@ #include "../../model/prefs/state.hpp" -#include "../../model/world/commands.hpp" #include "../../model/world/commandmacro.hpp" +#include "../../model/world/commands.hpp" #include "../widget/scenetoolbar.hpp" @@ -20,8 +20,8 @@ namespace CSVRender { PathgridMode::PathgridMode(WorldspaceWidget* worldspaceWidget, QWidget* parent) - : EditMode(worldspaceWidget, QIcon(":placeholder"), Mask_Pathgrid | Mask_Terrain | Mask_Reference, - getTooltip(), parent) + : EditMode(worldspaceWidget, QIcon(":placeholder"), Mask_Pathgrid | Mask_Terrain | Mask_Reference, getTooltip(), + parent) , mDragMode(DragMode_None) , mFromNode(0) , mSelectionMode(nullptr) @@ -54,24 +54,22 @@ namespace CSVRender { if (mSelectionMode) { - toolbar->removeTool (mSelectionMode); + toolbar->removeTool(mSelectionMode); delete mSelectionMode; mSelectionMode = nullptr; } } - void PathgridMode::primaryOpenPressed(const WorldspaceHitResult& hitResult) - { - } + void PathgridMode::primaryOpenPressed(const WorldspaceHitResult& hitResult) {} void PathgridMode::primaryEditPressed(const WorldspaceHitResult& hitResult) { - if (CSMPrefs::get()["3D Scene Input"]["context-select"].isTrue() && - dynamic_cast(hitResult.tag.get())) + if (CSMPrefs::get()["3D Scene Input"]["context-select"].isTrue() + && dynamic_cast(hitResult.tag.get())) { primarySelectPressed(hitResult); } - else if (Cell* cell = getWorldspaceWidget().getCell (hitResult.worldPos)) + else if (Cell* cell = getWorldspaceWidget().getCell(hitResult.worldPos)) { if (cell->getPathgrid()) { @@ -144,16 +142,16 @@ namespace CSVRender bool PathgridMode::primaryEditStartDrag(const QPoint& pos) { - std::vector > selection = getWorldspaceWidget().getSelection (Mask_Pathgrid); + std::vector> selection = getWorldspaceWidget().getSelection(Mask_Pathgrid); if (CSMPrefs::get()["3D Scene Input"]["context-select"].isTrue()) { - WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask()); + WorldspaceHitResult hit = getWorldspaceWidget().mousePick(pos, getWorldspaceWidget().getInteractionMask()); if (dynamic_cast(hit.tag.get())) { primarySelectPressed(hit); - selection = getWorldspaceWidget().getSelection (Mask_Pathgrid); + selection = getWorldspaceWidget().getSelection(Mask_Pathgrid); } } @@ -168,7 +166,7 @@ namespace CSVRender bool PathgridMode::secondaryEditStartDrag(const QPoint& pos) { - WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask()); + WorldspaceHitResult hit = getWorldspaceWidget().mousePick(pos, getWorldspaceWidget().getInteractionMask()); if (hit.tag) { if (PathgridTag* tag = dynamic_cast(hit.tag.get())) @@ -189,14 +187,14 @@ namespace CSVRender { if (mDragMode == DragMode_Move) { - std::vector > selection = getWorldspaceWidget().getSelection(Mask_Pathgrid); + std::vector> selection = getWorldspaceWidget().getSelection(Mask_Pathgrid); - for (std::vector >::iterator it = selection.begin(); it != selection.end(); ++it) + for (std::vector>::iterator it = selection.begin(); it != selection.end(); ++it) { if (PathgridTag* tag = dynamic_cast(it->get())) { osg::Vec3d eye, center, up, offset; - getWorldspaceWidget().getCamera()->getViewMatrix().getLookAt (eye, center, up); + getWorldspaceWidget().getCamera()->getViewMatrix().getLookAt(eye, center, up); offset = (up * diffY * speedFactor) + (((center - eye) ^ up) * diffX * speedFactor); @@ -206,13 +204,14 @@ namespace CSVRender } else if (mDragMode == DragMode_Edge) { - WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask()); + WorldspaceHitResult hit = getWorldspaceWidget().mousePick(pos, getWorldspaceWidget().getInteractionMask()); Cell* cell = getWorldspaceWidget().getCell(hit.worldPos); if (cell && cell->getPathgrid()) { PathgridTag* tag = nullptr; - if (hit.tag && (tag = dynamic_cast(hit.tag.get())) && tag->getPathgrid()->getId() == mEdgeId) + if (hit.tag && (tag = dynamic_cast(hit.tag.get())) + && tag->getPathgrid()->getId() == mEdgeId) { unsigned short node = SceneUtil::getPathgridNode(static_cast(hit.index0)); cell->getPathgrid()->setDragEndpoint(node); @@ -221,7 +220,6 @@ namespace CSVRender { cell->getPathgrid()->setDragEndpoint(hit.worldPos); } - } } } @@ -230,8 +228,8 @@ namespace CSVRender { if (mDragMode == DragMode_Move) { - std::vector > selection = getWorldspaceWidget().getSelection (Mask_Pathgrid); - for (std::vector >::iterator it = selection.begin(); it != selection.end(); ++it) + std::vector> selection = getWorldspaceWidget().getSelection(Mask_Pathgrid); + for (std::vector>::iterator it = selection.begin(); it != selection.end(); ++it) { if (PathgridTag* tag = dynamic_cast(it->get())) { diff --git a/apps/opencs/view/render/pathgridmode.hpp b/apps/opencs/view/render/pathgridmode.hpp index cc61dfe9b0..5273838e5c 100644 --- a/apps/opencs/view/render/pathgridmode.hpp +++ b/apps/opencs/view/render/pathgridmode.hpp @@ -11,54 +11,52 @@ namespace CSVRender class PathgridMode : public EditMode { - Q_OBJECT + Q_OBJECT - public: + public: + PathgridMode(WorldspaceWidget* worldspace, QWidget* parent = nullptr); - PathgridMode(WorldspaceWidget* worldspace, QWidget* parent=nullptr); + void activate(CSVWidget::SceneToolbar* toolbar) override; - void activate(CSVWidget::SceneToolbar* toolbar) override; + void deactivate(CSVWidget::SceneToolbar* toolbar) override; - void deactivate(CSVWidget::SceneToolbar* toolbar) override; + void primaryOpenPressed(const WorldspaceHitResult& hit) override; - void primaryOpenPressed(const WorldspaceHitResult& hit) override; + void primaryEditPressed(const WorldspaceHitResult& hit) override; - void primaryEditPressed(const WorldspaceHitResult& hit) override; + void secondaryEditPressed(const WorldspaceHitResult& hit) override; - void secondaryEditPressed(const WorldspaceHitResult& hit) override; + void primarySelectPressed(const WorldspaceHitResult& hit) override; - void primarySelectPressed(const WorldspaceHitResult& hit) override; + void secondarySelectPressed(const WorldspaceHitResult& hit) override; - void secondarySelectPressed(const WorldspaceHitResult& hit) override; + bool primaryEditStartDrag(const QPoint& pos) override; - bool primaryEditStartDrag (const QPoint& pos) override; + bool secondaryEditStartDrag(const QPoint& pos) override; - bool secondaryEditStartDrag (const QPoint& pos) override; + void drag(const QPoint& pos, int diffX, int diffY, double speedFactor) override; - void drag (const QPoint& pos, int diffX, int diffY, double speedFactor) override; + void dragCompleted(const QPoint& pos) override; - void dragCompleted(const QPoint& pos) override; + /// \note dragAborted will not be called, if the drag is aborted via changing + /// editing mode + void dragAborted() override; - /// \note dragAborted will not be called, if the drag is aborted via changing - /// editing mode - void dragAborted() override; + private: + enum DragMode + { + DragMode_None, + DragMode_Move, + DragMode_Edge + }; - private: + DragMode mDragMode; + std::string mLastId, mEdgeId; + unsigned short mFromNode; - enum DragMode - { - DragMode_None, - DragMode_Move, - DragMode_Edge - }; + PathgridSelectionMode* mSelectionMode; - DragMode mDragMode; - std::string mLastId, mEdgeId; - unsigned short mFromNode; - - PathgridSelectionMode* mSelectionMode; - - QString getTooltip(); + QString getTooltip(); }; } diff --git a/apps/opencs/view/render/pathgridselectionmode.cpp b/apps/opencs/view/render/pathgridselectionmode.cpp index 6f101add8a..77a232b4e8 100644 --- a/apps/opencs/view/render/pathgridselectionmode.cpp +++ b/apps/opencs/view/render/pathgridselectionmode.cpp @@ -1,14 +1,14 @@ #include "pathgridselectionmode.hpp" -#include #include +#include -#include "../../model/world/idtable.hpp" -#include "../../model/world/commands.hpp" #include "../../model/world/commandmacro.hpp" +#include "../../model/world/commands.hpp" +#include "../../model/world/idtable.hpp" -#include "worldspacewidget.hpp" #include "pathgrid.hpp" +#include "worldspacewidget.hpp" namespace CSVRender { @@ -37,9 +37,9 @@ namespace CSVRender void PathgridSelectionMode::removeSelectedNodes() { - std::vector > selection = getWorldspaceWidget().getSelection (Mask_Pathgrid); + std::vector> selection = getWorldspaceWidget().getSelection(Mask_Pathgrid); - for (std::vector >::iterator it = selection.begin(); it != selection.end(); ++it) + for (std::vector>::iterator it = selection.begin(); it != selection.end(); ++it) { if (PathgridTag* tag = dynamic_cast(it->get())) { @@ -54,9 +54,9 @@ namespace CSVRender void PathgridSelectionMode::removeSelectedEdges() { - std::vector > selection = getWorldspaceWidget().getSelection (Mask_Pathgrid); + std::vector> selection = getWorldspaceWidget().getSelection(Mask_Pathgrid); - for (std::vector >::iterator it = selection.begin(); it != selection.end(); ++it) + for (std::vector>::iterator it = selection.begin(); it != selection.end(); ++it) { if (PathgridTag* tag = dynamic_cast(it->get())) { diff --git a/apps/opencs/view/render/pathgridselectionmode.hpp b/apps/opencs/view/render/pathgridselectionmode.hpp index 19bfca803e..1227501ec8 100644 --- a/apps/opencs/view/render/pathgridselectionmode.hpp +++ b/apps/opencs/view/render/pathgridselectionmode.hpp @@ -7,31 +7,28 @@ namespace CSVRender { class PathgridSelectionMode : public SelectionMode { - Q_OBJECT + Q_OBJECT - public: + public: + PathgridSelectionMode(CSVWidget::SceneToolbar* parent, WorldspaceWidget& worldspaceWidget); - PathgridSelectionMode(CSVWidget::SceneToolbar* parent, WorldspaceWidget& worldspaceWidget); + protected: + /// Add context menu items to \a menu. + /// + /// \attention menu can be a 0-pointer + /// + /// \return Have there been any menu items to be added (if menu is 0 and there + /// items to be added, the function must return true anyway. + bool createContextMenu(QMenu* menu) override; - protected: + private: + QAction* mRemoveSelectedNodes; + QAction* mRemoveSelectedEdges; - /// Add context menu items to \a menu. - /// - /// \attention menu can be a 0-pointer - /// - /// \return Have there been any menu items to be added (if menu is 0 and there - /// items to be added, the function must return true anyway. - bool createContextMenu(QMenu* menu) override; + private slots: - private: - - QAction* mRemoveSelectedNodes; - QAction* mRemoveSelectedEdges; - - private slots: - - void removeSelectedNodes(); - void removeSelectedEdges(); + void removeSelectedNodes(); + void removeSelectedEdges(); }; } diff --git a/apps/opencs/view/render/previewwidget.cpp b/apps/opencs/view/render/previewwidget.cpp index ee1299dc66..ffc3be193a 100644 --- a/apps/opencs/view/render/previewwidget.cpp +++ b/apps/opencs/view/render/previewwidget.cpp @@ -3,71 +3,65 @@ #include "../../model/world/data.hpp" #include "../../model/world/idtable.hpp" -CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data, - const std::string& id, bool referenceable, QWidget *parent) -: SceneWidget (data.getResourceSystem(), parent), mData (data), mObject(data, mRootNode, id, referenceable) +CSVRender::PreviewWidget::PreviewWidget( + CSMWorld::Data& data, const std::string& id, bool referenceable, QWidget* parent) + : SceneWidget(data.getResourceSystem(), parent) + , mData(data) + , mObject(data, mRootNode, id, referenceable) { selectNavigationMode("orbit"); - QAbstractItemModel *referenceables = - mData.getTableModel (CSMWorld::UniversalId::Type_Referenceables); + QAbstractItemModel* referenceables = mData.getTableModel(CSMWorld::UniversalId::Type_Referenceables); - connect (referenceables, &QAbstractItemModel::dataChanged, - this, &PreviewWidget::referenceableDataChanged); - connect (referenceables, &QAbstractItemModel::rowsAboutToBeRemoved, - this, &PreviewWidget::referenceableAboutToBeRemoved); + connect(referenceables, &QAbstractItemModel::dataChanged, this, &PreviewWidget::referenceableDataChanged); + connect( + referenceables, &QAbstractItemModel::rowsAboutToBeRemoved, this, &PreviewWidget::referenceableAboutToBeRemoved); - connect (&mData, &CSMWorld::Data::assetTablesChanged, - this, &PreviewWidget::assetTablesChanged); + connect(&mData, &CSMWorld::Data::assetTablesChanged, this, &PreviewWidget::assetTablesChanged); setExterior(false); if (!referenceable) { - QAbstractItemModel *references = - mData.getTableModel (CSMWorld::UniversalId::Type_References); + QAbstractItemModel* references = mData.getTableModel(CSMWorld::UniversalId::Type_References); - connect (references, &QAbstractItemModel::dataChanged, - this, &PreviewWidget::referenceDataChanged); - connect (references, &QAbstractItemModel::rowsAboutToBeRemoved, - this, &PreviewWidget::referenceAboutToBeRemoved); + connect(references, &QAbstractItemModel::dataChanged, this, &PreviewWidget::referenceDataChanged); + connect(references, &QAbstractItemModel::rowsAboutToBeRemoved, this, &PreviewWidget::referenceAboutToBeRemoved); } } -void CSVRender::PreviewWidget::referenceableDataChanged (const QModelIndex& topLeft, - const QModelIndex& bottomRight) +void CSVRender::PreviewWidget::referenceableDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) { - if (mObject.referenceableDataChanged (topLeft, bottomRight)) + if (mObject.referenceableDataChanged(topLeft, bottomRight)) flagAsModified(); if (mObject.getReferenceId().empty()) { - CSMWorld::IdTable& referenceables = dynamic_cast ( - *mData.getTableModel (CSMWorld::UniversalId::Type_Referenceables)); + CSMWorld::IdTable& referenceables + = dynamic_cast(*mData.getTableModel(CSMWorld::UniversalId::Type_Referenceables)); - QModelIndex index = referenceables.getModelIndex (mObject.getReferenceableId(), - referenceables.findColumnIndex (CSMWorld::Columns::ColumnId_Modification)); + QModelIndex index = referenceables.getModelIndex( + mObject.getReferenceableId(), referenceables.findColumnIndex(CSMWorld::Columns::ColumnId_Modification)); - if (referenceables.data (index).toInt()==CSMWorld::RecordBase::State_Deleted) + if (referenceables.data(index).toInt() == CSMWorld::RecordBase::State_Deleted) emit closeRequest(); } } -void CSVRender::PreviewWidget::referenceableAboutToBeRemoved (const QModelIndex& parent, int start, - int end) +void CSVRender::PreviewWidget::referenceableAboutToBeRemoved(const QModelIndex& parent, int start, int end) { - if (mObject.referenceableAboutToBeRemoved (parent, start, end)) + if (mObject.referenceableAboutToBeRemoved(parent, start, end)) flagAsModified(); if (mObject.getReferenceableId().empty()) return; - CSMWorld::IdTable& referenceables = dynamic_cast ( - *mData.getTableModel (CSMWorld::UniversalId::Type_Referenceables)); + CSMWorld::IdTable& referenceables + = dynamic_cast(*mData.getTableModel(CSMWorld::UniversalId::Type_Referenceables)); - QModelIndex index = referenceables.getModelIndex (mObject.getReferenceableId(), 0); + QModelIndex index = referenceables.getModelIndex(mObject.getReferenceableId(), 0); - if (index.row()>=start && index.row()<=end) + if (index.row() >= start && index.row() <= end) { if (mObject.getReferenceId().empty()) { @@ -77,55 +71,53 @@ void CSVRender::PreviewWidget::referenceableAboutToBeRemoved (const QModelIndex& } } -void CSVRender::PreviewWidget::referenceDataChanged (const QModelIndex& topLeft, - const QModelIndex& bottomRight) +void CSVRender::PreviewWidget::referenceDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) { - if (mObject.referenceDataChanged (topLeft, bottomRight)) + if (mObject.referenceDataChanged(topLeft, bottomRight)) flagAsModified(); if (mObject.getReferenceId().empty()) return; - CSMWorld::IdTable& references = dynamic_cast ( - *mData.getTableModel (CSMWorld::UniversalId::Type_References)); + CSMWorld::IdTable& references + = dynamic_cast(*mData.getTableModel(CSMWorld::UniversalId::Type_References)); // check for deleted state { - QModelIndex index = references.getModelIndex (mObject.getReferenceId(), - references.findColumnIndex (CSMWorld::Columns::ColumnId_Modification)); + QModelIndex index = references.getModelIndex( + mObject.getReferenceId(), references.findColumnIndex(CSMWorld::Columns::ColumnId_Modification)); - if (references.data (index).toInt()==CSMWorld::RecordBase::State_Deleted) + if (references.data(index).toInt() == CSMWorld::RecordBase::State_Deleted) { emit closeRequest(); return; } } - int columnIndex = references.findColumnIndex (CSMWorld::Columns::ColumnId_ReferenceableId); + int columnIndex = references.findColumnIndex(CSMWorld::Columns::ColumnId_ReferenceableId); - QModelIndex index = references.getModelIndex (mObject.getReferenceId(), columnIndex); + QModelIndex index = references.getModelIndex(mObject.getReferenceId(), columnIndex); - if (index.row()>=topLeft.row() && index.row()<=bottomRight.row()) - if (index.column()>=topLeft.column() && index.column()<=bottomRight.row()) - emit referenceableIdChanged (mObject.getReferenceableId()); + if (index.row() >= topLeft.row() && index.row() <= bottomRight.row()) + if (index.column() >= topLeft.column() && index.column() <= bottomRight.row()) + emit referenceableIdChanged(mObject.getReferenceableId()); } -void CSVRender::PreviewWidget::referenceAboutToBeRemoved (const QModelIndex& parent, int start, - int end) +void CSVRender::PreviewWidget::referenceAboutToBeRemoved(const QModelIndex& parent, int start, int end) { if (mObject.getReferenceId().empty()) return; - CSMWorld::IdTable& references = dynamic_cast ( - *mData.getTableModel (CSMWorld::UniversalId::Type_References)); + CSMWorld::IdTable& references + = dynamic_cast(*mData.getTableModel(CSMWorld::UniversalId::Type_References)); - QModelIndex index = references.getModelIndex (mObject.getReferenceId(), 0); + QModelIndex index = references.getModelIndex(mObject.getReferenceId(), 0); - if (index.row()>=start && index.row()<=end) + if (index.row() >= start && index.row() <= end) emit closeRequest(); } -void CSVRender::PreviewWidget::assetTablesChanged () +void CSVRender::PreviewWidget::assetTablesChanged() { mObject.reloadAssets(); } diff --git a/apps/opencs/view/render/previewwidget.hpp b/apps/opencs/view/render/previewwidget.hpp index a8d73729a4..6851922e8d 100644 --- a/apps/opencs/view/render/previewwidget.hpp +++ b/apps/opencs/view/render/previewwidget.hpp @@ -21,34 +21,31 @@ namespace CSVRender { class PreviewWidget : public SceneWidget { - Q_OBJECT + Q_OBJECT - CSMWorld::Data& mData; - CSVRender::Object mObject; + CSMWorld::Data& mData; + CSVRender::Object mObject; - public: + public: + PreviewWidget(CSMWorld::Data& data, const std::string& id, bool referenceable, QWidget* parent = nullptr); - PreviewWidget (CSMWorld::Data& data, const std::string& id, bool referenceable, - QWidget *parent = nullptr); + signals: - signals: + void closeRequest(); - void closeRequest(); + void referenceableIdChanged(const std::string& id); - void referenceableIdChanged (const std::string& id); + private slots: - private slots: + void referenceableDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); - void referenceableDataChanged (const QModelIndex& topLeft, - const QModelIndex& bottomRight); + void referenceableAboutToBeRemoved(const QModelIndex& parent, int start, int end); - void referenceableAboutToBeRemoved (const QModelIndex& parent, int start, int end); + void referenceDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); - void referenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); + void referenceAboutToBeRemoved(const QModelIndex& parent, int start, int end); - void referenceAboutToBeRemoved (const QModelIndex& parent, int start, int end); - - void assetTablesChanged (); + void assetTablesChanged(); }; } diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 070259075a..7f8ea94da6 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -3,595 +3,586 @@ #include #include -#include #include +#include #include #include -#include -#include #include #include +#include +#include #include -#include #include +#include #include #include "../widget/scenetoolmode.hpp" -#include "../../model/prefs/state.hpp" #include "../../model/prefs/shortcut.hpp" +#include "../../model/prefs/state.hpp" +#include "cameracontroller.hpp" #include "lighting.hpp" #include "mask.hpp" -#include "cameracontroller.hpp" namespace CSVRender { -RenderWidget::RenderWidget(QWidget *parent, Qt::WindowFlags f) - : QWidget(parent, f) - , mRootNode(nullptr) -{ - - osgViewer::CompositeViewer& viewer = CompositeViewer::get(); - - osg::DisplaySettings* ds = osg::DisplaySettings::instance().get(); - //ds->setNumMultiSamples(8); - - osg::ref_ptr traits = new osg::GraphicsContext::Traits; - traits->windowName.clear(); - traits->windowDecoration = true; - traits->x = 0; - traits->y = 0; - traits->width = width(); - traits->height = height(); - traits->doubleBuffer = true; - traits->alpha = ds->getMinimumNumAlphaBits(); - traits->stencil = ds->getMinimumNumStencilBits(); - traits->sampleBuffers = ds->getMultiSamples(); - traits->samples = ds->getNumMultiSamples(); - // Doesn't make much sense as we're running on demand updates, and there seems to be a bug with the refresh rate when running multiple QGLWidgets - traits->vsync = false; - - mView = new osgViewer::View; - updateCameraParameters( traits->width / static_cast(traits->height) ); - - osg::ref_ptr window = new osgQt::GraphicsWindowQt(traits.get()); - QLayout* layout = new QHBoxLayout(this); - layout->setContentsMargins(0, 0, 0, 0); - layout->addWidget(window->getGLWidget()); - setLayout(layout); - - mView->getCamera()->setGraphicsContext(window); - mView->getCamera()->setViewport( new osg::Viewport(0, 0, traits->width, traits->height) ); - - SceneUtil::LightManager* lightMgr = new SceneUtil::LightManager; - lightMgr->setStartLight(1); - lightMgr->setLightingMask(Mask_Lighting); - mRootNode = lightMgr; - - mView->getCamera()->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON); - mView->getCamera()->getOrCreateStateSet()->setMode(GL_CULL_FACE, osg::StateAttribute::ON); - osg::ref_ptr defaultMat (new osg::Material); - defaultMat->setColorMode(osg::Material::OFF); - defaultMat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(1,1,1,1)); - defaultMat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(1,1,1,1)); - defaultMat->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4f(0.f, 0.f, 0.f, 0.f)); - mView->getCamera()->getOrCreateStateSet()->setAttribute(defaultMat); - - mView->setSceneData(mRootNode); - - // Add ability to signal osg to show its statistics for debugging purposes - mView->addEventHandler(new osgViewer::StatsHandler); - - viewer.addView(mView); - viewer.setDone(false); - viewer.realize(); -} + RenderWidget::RenderWidget(QWidget* parent, Qt::WindowFlags f) + : QWidget(parent, f) + , mRootNode(nullptr) + { -RenderWidget::~RenderWidget() -{ - try + osgViewer::CompositeViewer& viewer = CompositeViewer::get(); + + osg::DisplaySettings* ds = osg::DisplaySettings::instance().get(); + // ds->setNumMultiSamples(8); + + osg::ref_ptr traits = new osg::GraphicsContext::Traits; + traits->windowName.clear(); + traits->windowDecoration = true; + traits->x = 0; + traits->y = 0; + traits->width = width(); + traits->height = height(); + traits->doubleBuffer = true; + traits->alpha = ds->getMinimumNumAlphaBits(); + traits->stencil = ds->getMinimumNumStencilBits(); + traits->sampleBuffers = ds->getMultiSamples(); + traits->samples = ds->getNumMultiSamples(); + // Doesn't make much sense as we're running on demand updates, and there seems to be a bug with the refresh rate + // when running multiple QGLWidgets + traits->vsync = false; + + mView = new osgViewer::View; + updateCameraParameters(traits->width / static_cast(traits->height)); + + osg::ref_ptr window = new osgQt::GraphicsWindowQt(traits.get()); + QLayout* layout = new QHBoxLayout(this); + layout->setContentsMargins(0, 0, 0, 0); + layout->addWidget(window->getGLWidget()); + setLayout(layout); + + mView->getCamera()->setGraphicsContext(window); + mView->getCamera()->setViewport(new osg::Viewport(0, 0, traits->width, traits->height)); + + SceneUtil::LightManager* lightMgr = new SceneUtil::LightManager; + lightMgr->setStartLight(1); + lightMgr->setLightingMask(Mask_Lighting); + mRootNode = lightMgr; + + mView->getCamera()->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON); + mView->getCamera()->getOrCreateStateSet()->setMode(GL_CULL_FACE, osg::StateAttribute::ON); + osg::ref_ptr defaultMat(new osg::Material); + defaultMat->setColorMode(osg::Material::OFF); + defaultMat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(1, 1, 1, 1)); + defaultMat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(1, 1, 1, 1)); + defaultMat->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4f(0.f, 0.f, 0.f, 0.f)); + mView->getCamera()->getOrCreateStateSet()->setAttribute(defaultMat); + + mView->setSceneData(mRootNode); + + // Add ability to signal osg to show its statistics for debugging purposes + mView->addEventHandler(new osgViewer::StatsHandler); + + viewer.addView(mView); + viewer.setDone(false); + viewer.realize(); + } + + RenderWidget::~RenderWidget() { - CompositeViewer::get().removeView(mView); + try + { + CompositeViewer::get().removeView(mView); + } + catch (const std::exception& e) + { + Log(Debug::Error) << "Error in the destructor: " << e.what(); + } } - catch(const std::exception& e) + + void RenderWidget::flagAsModified() { - Log(Debug::Error) << "Error in the destructor: " << e.what(); + mView->requestRedraw(); } -} - -void RenderWidget::flagAsModified() -{ - mView->requestRedraw(); -} -void RenderWidget::setVisibilityMask(unsigned int mask) -{ - mView->getCamera()->setCullMask(mask | Mask_ParticleSystem | Mask_Lighting); -} - -osg::Camera *RenderWidget::getCamera() -{ - return mView->getCamera(); -} - -void RenderWidget::toggleRenderStats() -{ - osgViewer::GraphicsWindow* window = - static_cast(mView->getCamera()->getGraphicsContext()); - - window->getEventQueue()->keyPress(osgGA::GUIEventAdapter::KEY_S); - window->getEventQueue()->keyRelease(osgGA::GUIEventAdapter::KEY_S); -} - - -// -------------------------------------------------- + void RenderWidget::setVisibilityMask(unsigned int mask) + { + mView->getCamera()->setCullMask(mask | Mask_ParticleSystem | Mask_Lighting); + } -CompositeViewer::CompositeViewer() - : mSimulationTime(0.0) -{ - // TODO: Upgrade osgQt to support osgViewer::ViewerBase::DrawThreadPerContext - // https://gitlab.com/OpenMW/openmw/-/issues/5481 - setThreadingModel(osgViewer::ViewerBase::SingleThreaded); + osg::Camera* RenderWidget::getCamera() + { + return mView->getCamera(); + } - setUseConfigureAffinity(false); + void RenderWidget::toggleRenderStats() + { + osgViewer::GraphicsWindow* window + = static_cast(mView->getCamera()->getGraphicsContext()); - // disable the default setting of viewer.done() by pressing Escape. - setKeyEventSetsDone(0); + window->getEventQueue()->keyPress(osgGA::GUIEventAdapter::KEY_S); + window->getEventQueue()->keyRelease(osgGA::GUIEventAdapter::KEY_S); + } - // Only render when the camera position changed, or content flagged dirty - //setRunFrameScheme(osgViewer::ViewerBase::ON_DEMAND); - setRunFrameScheme(osgViewer::ViewerBase::CONTINUOUS); + // -------------------------------------------------- - connect(&mTimer, &QTimer::timeout, this, &CompositeViewer::update); - mTimer.start( 10 ); + CompositeViewer::CompositeViewer() + : mSimulationTime(0.0) + { + // TODO: Upgrade osgQt to support osgViewer::ViewerBase::DrawThreadPerContext + // https://gitlab.com/OpenMW/openmw/-/issues/5481 + setThreadingModel(osgViewer::ViewerBase::SingleThreaded); - int frameRateLimit = CSMPrefs::get()["Rendering"]["framerate-limit"].toInt(); - setRunMaxFrameRate(frameRateLimit); -} + setUseConfigureAffinity(false); -CompositeViewer &CompositeViewer::get() -{ - static CompositeViewer sThis; - return sThis; -} + // disable the default setting of viewer.done() by pressing Escape. + setKeyEventSetsDone(0); -void CompositeViewer::update() -{ - double dt = mFrameTimer.time_s(); - mFrameTimer.setStartTick(); + // Only render when the camera position changed, or content flagged dirty + // setRunFrameScheme(osgViewer::ViewerBase::ON_DEMAND); + setRunFrameScheme(osgViewer::ViewerBase::CONTINUOUS); - emit simulationUpdated(dt); + connect(&mTimer, &QTimer::timeout, this, &CompositeViewer::update); + mTimer.start(10); - mSimulationTime += dt; - frame(mSimulationTime); + int frameRateLimit = CSMPrefs::get()["Rendering"]["framerate-limit"].toInt(); + setRunMaxFrameRate(frameRateLimit); + } - double minFrameTime = _runMaxFrameRate > 0.0 ? 1.0 / _runMaxFrameRate : 0.0; - if (dt < minFrameTime) + CompositeViewer& CompositeViewer::get() { - std::this_thread::sleep_for(std::chrono::duration(minFrameTime - dt)); + static CompositeViewer sThis; + return sThis; } -} - -// --------------------------------------------------- - -SceneWidget::SceneWidget(std::shared_ptr resourceSystem, QWidget *parent, Qt::WindowFlags f, - bool retrieveInput) - : RenderWidget(parent, f) - , mResourceSystem(resourceSystem) - , mLighting(nullptr) - , mHasDefaultAmbient(false) - , mIsExterior(true) - , mPrevMouseX(0) - , mPrevMouseY(0) - , mCamPositionSet(false) -{ - mFreeCamControl = new FreeCameraController(this); - mOrbitCamControl = new OrbitCameraController(this); - mCurrentCamControl = mFreeCamControl; - mOrbitCamControl->setPickingMask(Mask_Reference | Mask_Terrain); - - mOrbitCamControl->setConstRoll( CSMPrefs::get()["3D Scene Input"]["navi-orbit-const-roll"].isTrue() ); + void CompositeViewer::update() + { + double dt = mFrameTimer.time_s(); + mFrameTimer.setStartTick(); - // set up gradient view or configured clear color - QColor bgColour = CSMPrefs::get()["Rendering"]["scene-day-background-colour"].toColor(); + emit simulationUpdated(dt); - if (CSMPrefs::get()["Rendering"]["scene-use-gradient"].isTrue()) { - QColor gradientColour = CSMPrefs::get()["Rendering"]["scene-day-gradient-colour"].toColor(); - mGradientCamera = createGradientCamera(bgColour, gradientColour); + mSimulationTime += dt; + frame(mSimulationTime); - mView->getCamera()->setClearMask(0); - mView->getCamera()->addChild(mGradientCamera.get()); - } - else { - mView->getCamera()->setClearColor(osg::Vec4( - bgColour.redF(), - bgColour.greenF(), - bgColour.blueF(), - 1.0f - )); + double minFrameTime = _runMaxFrameRate > 0.0 ? 1.0 / _runMaxFrameRate : 0.0; + if (dt < minFrameTime) + { + std::this_thread::sleep_for(std::chrono::duration(minFrameTime - dt)); + } } - // we handle lighting manually - mView->setLightingMode(osgViewer::View::NO_LIGHT); - - setLighting(&mLightingDay); - - mResourceSystem->getSceneManager()->setParticleSystemMask(Mask_ParticleSystem); + // --------------------------------------------------- - // Recieve mouse move event even if mouse button is not pressed - setMouseTracking(true); - setFocusPolicy(Qt::ClickFocus); + SceneWidget::SceneWidget(std::shared_ptr resourceSystem, QWidget* parent, + Qt::WindowFlags f, bool retrieveInput) + : RenderWidget(parent, f) + , mResourceSystem(resourceSystem) + , mLighting(nullptr) + , mHasDefaultAmbient(false) + , mIsExterior(true) + , mPrevMouseX(0) + , mPrevMouseY(0) + , mCamPositionSet(false) + { + mFreeCamControl = new FreeCameraController(this); + mOrbitCamControl = new OrbitCameraController(this); + mCurrentCamControl = mFreeCamControl; - connect (&CSMPrefs::State::get(), &CSMPrefs::State::settingChanged, - this, &SceneWidget::settingChanged); + mOrbitCamControl->setPickingMask(Mask_Reference | Mask_Terrain); - // TODO update this outside of the constructor where virtual methods can be used - if (retrieveInput) - { - CSMPrefs::get()["3D Scene Input"].update(); - CSMPrefs::get()["Tooltips"].update(); - } + mOrbitCamControl->setConstRoll(CSMPrefs::get()["3D Scene Input"]["navi-orbit-const-roll"].isTrue()); - connect (&CompositeViewer::get(), &CompositeViewer::simulationUpdated, this, &SceneWidget::update); + // set up gradient view or configured clear color + QColor bgColour = CSMPrefs::get()["Rendering"]["scene-day-background-colour"].toColor(); - // Shortcuts - CSMPrefs::Shortcut* focusToolbarShortcut = new CSMPrefs::Shortcut("scene-focus-toolbar", this); - connect(focusToolbarShortcut, qOverload<>(&CSMPrefs::Shortcut::activated), - this, &SceneWidget::focusToolbarRequest); + if (CSMPrefs::get()["Rendering"]["scene-use-gradient"].isTrue()) + { + QColor gradientColour = CSMPrefs::get()["Rendering"]["scene-day-gradient-colour"].toColor(); + mGradientCamera = createGradientCamera(bgColour, gradientColour); - CSMPrefs::Shortcut* renderStatsShortcut = new CSMPrefs::Shortcut("scene-render-stats", this); - connect(renderStatsShortcut, qOverload<>(&CSMPrefs::Shortcut::activated), - this, &SceneWidget::toggleRenderStats); -} + mView->getCamera()->setClearMask(0); + mView->getCamera()->addChild(mGradientCamera.get()); + } + else + { + mView->getCamera()->setClearColor(osg::Vec4(bgColour.redF(), bgColour.greenF(), bgColour.blueF(), 1.0f)); + } -SceneWidget::~SceneWidget() -{ - // Since we're holding on to the resources past the existence of this graphics context, we'll need to manually release the created objects - mResourceSystem->releaseGLObjects(mView->getCamera()->getGraphicsContext()->getState()); -} + // we handle lighting manually + mView->setLightingMode(osgViewer::View::NO_LIGHT); + setLighting(&mLightingDay); -osg::ref_ptr SceneWidget::createGradientRectangle(QColor bgColour, QColor gradientColour) -{ - osg::ref_ptr geometry = new osg::Geometry; + mResourceSystem->getSceneManager()->setParticleSystemMask(Mask_ParticleSystem); - osg::ref_ptr vertices = new osg::Vec3Array; + // Recieve mouse move event even if mouse button is not pressed + setMouseTracking(true); + setFocusPolicy(Qt::ClickFocus); - vertices->push_back(osg::Vec3(0.0f, 0.0f, -1.0f)); - vertices->push_back(osg::Vec3(1.0f, 0.0f, -1.0f)); - vertices->push_back(osg::Vec3(0.0f, 1.0f, -1.0f)); - vertices->push_back(osg::Vec3(1.0f, 1.0f, -1.0f)); + connect(&CSMPrefs::State::get(), &CSMPrefs::State::settingChanged, this, &SceneWidget::settingChanged); - geometry->setVertexArray(vertices); + // TODO update this outside of the constructor where virtual methods can be used + if (retrieveInput) + { + CSMPrefs::get()["3D Scene Input"].update(); + CSMPrefs::get()["Tooltips"].update(); + } - osg::ref_ptr primitives = new osg::DrawElementsUShort (osg::PrimitiveSet::TRIANGLES, 0); + connect(&CompositeViewer::get(), &CompositeViewer::simulationUpdated, this, &SceneWidget::update); - // triangle 1 - primitives->push_back (0); - primitives->push_back (1); - primitives->push_back (2); + // Shortcuts + CSMPrefs::Shortcut* focusToolbarShortcut = new CSMPrefs::Shortcut("scene-focus-toolbar", this); + connect( + focusToolbarShortcut, qOverload<>(&CSMPrefs::Shortcut::activated), this, &SceneWidget::focusToolbarRequest); - // triangle 2 - primitives->push_back (2); - primitives->push_back (1); - primitives->push_back (3); + CSMPrefs::Shortcut* renderStatsShortcut = new CSMPrefs::Shortcut("scene-render-stats", this); + connect( + renderStatsShortcut, qOverload<>(&CSMPrefs::Shortcut::activated), this, &SceneWidget::toggleRenderStats); + } - geometry->addPrimitiveSet(primitives); + SceneWidget::~SceneWidget() + { + // Since we're holding on to the resources past the existence of this graphics context, we'll need to manually + // release the created objects + mResourceSystem->releaseGLObjects(mView->getCamera()->getGraphicsContext()->getState()); + } - osg::ref_ptr colours = new osg::Vec4ubArray; - colours->push_back(osg::Vec4ub(gradientColour.red(), gradientColour.green(), gradientColour.blue(), 1.0f)); - colours->push_back(osg::Vec4ub(gradientColour.red(), gradientColour.green(), gradientColour.blue(), 1.0f)); - colours->push_back(osg::Vec4ub(bgColour.red(), bgColour.green(), bgColour.blue(), 1.0f)); - colours->push_back(osg::Vec4ub(bgColour.red(), bgColour.green(), bgColour.blue(), 1.0f)); + osg::ref_ptr SceneWidget::createGradientRectangle(QColor bgColour, QColor gradientColour) + { + osg::ref_ptr geometry = new osg::Geometry; - geometry->setColorArray(colours, osg::Array::BIND_PER_VERTEX); + osg::ref_ptr vertices = new osg::Vec3Array; - geometry->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); - geometry->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF); + vertices->push_back(osg::Vec3(0.0f, 0.0f, -1.0f)); + vertices->push_back(osg::Vec3(1.0f, 0.0f, -1.0f)); + vertices->push_back(osg::Vec3(0.0f, 1.0f, -1.0f)); + vertices->push_back(osg::Vec3(1.0f, 1.0f, -1.0f)); - return geometry; -} + geometry->setVertexArray(vertices); + osg::ref_ptr primitives = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES, 0); -osg::ref_ptr SceneWidget::createGradientCamera(QColor bgColour, QColor gradientColour) -{ - osg::ref_ptr camera = new osg::Camera(); - camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); - camera->setProjectionMatrix(osg::Matrix::ortho2D(0, 1.0f, 0, 1.0f)); - camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); - camera->setViewMatrix(osg::Matrix::identity()); + // triangle 1 + primitives->push_back(0); + primitives->push_back(1); + primitives->push_back(2); - camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); - camera->setAllowEventFocus(false); + // triangle 2 + primitives->push_back(2); + primitives->push_back(1); + primitives->push_back(3); - // draw subgraph before main camera view. - camera->setRenderOrder(osg::Camera::PRE_RENDER); + geometry->addPrimitiveSet(primitives); - camera->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF); + osg::ref_ptr colours = new osg::Vec4ubArray; + colours->push_back(osg::Vec4ub(gradientColour.red(), gradientColour.green(), gradientColour.blue(), 1.0f)); + colours->push_back(osg::Vec4ub(gradientColour.red(), gradientColour.green(), gradientColour.blue(), 1.0f)); + colours->push_back(osg::Vec4ub(bgColour.red(), bgColour.green(), bgColour.blue(), 1.0f)); + colours->push_back(osg::Vec4ub(bgColour.red(), bgColour.green(), bgColour.blue(), 1.0f)); - osg::ref_ptr gradientQuad = createGradientRectangle(bgColour, gradientColour); + geometry->setColorArray(colours, osg::Array::BIND_PER_VERTEX); - camera->addChild(gradientQuad); - return camera; -} + geometry->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); + geometry->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF); + return geometry; + } -void SceneWidget::updateGradientCamera(QColor bgColour, QColor gradientColour) -{ - osg::ref_ptr gradientRect = createGradientRectangle(bgColour, gradientColour); - // Replaces previous rectangle - mGradientCamera->setChild(0, gradientRect.get()); -} + osg::ref_ptr SceneWidget::createGradientCamera(QColor bgColour, QColor gradientColour) + { + osg::ref_ptr camera = new osg::Camera(); + camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); + camera->setProjectionMatrix(osg::Matrix::ortho2D(0, 1.0f, 0, 1.0f)); + camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); + camera->setViewMatrix(osg::Matrix::identity()); -void SceneWidget::setLighting(Lighting *lighting) -{ - if (mLighting) - mLighting->deactivate(); + camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + camera->setAllowEventFocus(false); - mLighting = lighting; - mLighting->activate (mRootNode, mIsExterior); + // draw subgraph before main camera view. + camera->setRenderOrder(osg::Camera::PRE_RENDER); - osg::Vec4f ambient = mLighting->getAmbientColour(mHasDefaultAmbient ? &mDefaultAmbient : nullptr); - setAmbient(ambient); + camera->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF); - flagAsModified(); -} + osg::ref_ptr gradientQuad = createGradientRectangle(bgColour, gradientColour); -void SceneWidget::setAmbient(const osg::Vec4f& ambient) -{ - osg::ref_ptr stateset = new osg::StateSet; - osg::ref_ptr lightmodel = new osg::LightModel; - lightmodel->setAmbientIntensity(ambient); - stateset->setMode(GL_LIGHTING, osg::StateAttribute::ON); - stateset->setMode(GL_LIGHT0, osg::StateAttribute::ON); - stateset->setAttributeAndModes(lightmodel, osg::StateAttribute::ON); - mRootNode->setStateSet(stateset); -} + camera->addChild(gradientQuad); + return camera; + } -void SceneWidget::selectLightingMode (const std::string& mode) -{ - QColor backgroundColour; - QColor gradientColour; - if (mode == "day") + void SceneWidget::updateGradientCamera(QColor bgColour, QColor gradientColour) { - backgroundColour = CSMPrefs::get()["Rendering"]["scene-day-background-colour"].toColor(); - gradientColour = CSMPrefs::get()["Rendering"]["scene-day-gradient-colour"].toColor(); - setLighting(&mLightingDay); + osg::ref_ptr gradientRect = createGradientRectangle(bgColour, gradientColour); + // Replaces previous rectangle + mGradientCamera->setChild(0, gradientRect.get()); } - else if (mode == "night") + + void SceneWidget::setLighting(Lighting* lighting) { - backgroundColour = CSMPrefs::get()["Rendering"]["scene-night-background-colour"].toColor(); - gradientColour = CSMPrefs::get()["Rendering"]["scene-night-gradient-colour"].toColor(); - setLighting(&mLightingNight); + if (mLighting) + mLighting->deactivate(); + + mLighting = lighting; + mLighting->activate(mRootNode, mIsExterior); + + osg::Vec4f ambient = mLighting->getAmbientColour(mHasDefaultAmbient ? &mDefaultAmbient : nullptr); + setAmbient(ambient); + + flagAsModified(); } - else if (mode == "bright") + + void SceneWidget::setAmbient(const osg::Vec4f& ambient) { - backgroundColour = CSMPrefs::get()["Rendering"]["scene-bright-background-colour"].toColor(); - gradientColour = CSMPrefs::get()["Rendering"]["scene-bright-gradient-colour"].toColor(); - setLighting(&mLightingBright); + osg::ref_ptr stateset = new osg::StateSet; + osg::ref_ptr lightmodel = new osg::LightModel; + lightmodel->setAmbientIntensity(ambient); + stateset->setMode(GL_LIGHTING, osg::StateAttribute::ON); + stateset->setMode(GL_LIGHT0, osg::StateAttribute::ON); + stateset->setAttributeAndModes(lightmodel, osg::StateAttribute::ON); + mRootNode->setStateSet(stateset); } - if (CSMPrefs::get()["Rendering"]["scene-use-gradient"].isTrue()) { - if (mGradientCamera.get() != nullptr) { - // we can go ahead and update since this camera still exists - updateGradientCamera(backgroundColour, gradientColour); - if (!mView->getCamera()->containsNode(mGradientCamera.get())) + void SceneWidget::selectLightingMode(const std::string& mode) + { + QColor backgroundColour; + QColor gradientColour; + if (mode == "day") + { + backgroundColour = CSMPrefs::get()["Rendering"]["scene-day-background-colour"].toColor(); + gradientColour = CSMPrefs::get()["Rendering"]["scene-day-gradient-colour"].toColor(); + setLighting(&mLightingDay); + } + else if (mode == "night") + { + backgroundColour = CSMPrefs::get()["Rendering"]["scene-night-background-colour"].toColor(); + gradientColour = CSMPrefs::get()["Rendering"]["scene-night-gradient-colour"].toColor(); + setLighting(&mLightingNight); + } + else if (mode == "bright") + { + backgroundColour = CSMPrefs::get()["Rendering"]["scene-bright-background-colour"].toColor(); + gradientColour = CSMPrefs::get()["Rendering"]["scene-bright-gradient-colour"].toColor(); + setLighting(&mLightingBright); + } + if (CSMPrefs::get()["Rendering"]["scene-use-gradient"].isTrue()) + { + if (mGradientCamera.get() != nullptr) { - // need to re-attach the gradient camera + // we can go ahead and update since this camera still exists + updateGradientCamera(backgroundColour, gradientColour); + + if (!mView->getCamera()->containsNode(mGradientCamera.get())) + { + // need to re-attach the gradient camera + mView->getCamera()->setClearMask(0); + mView->getCamera()->addChild(mGradientCamera.get()); + } + } + else + { + // need to create the gradient camera + mGradientCamera = createGradientCamera(backgroundColour, gradientColour); mView->getCamera()->setClearMask(0); mView->getCamera()->addChild(mGradientCamera.get()); } - } - else { - // need to create the gradient camera - mGradientCamera = createGradientCamera(backgroundColour, gradientColour); - mView->getCamera()->setClearMask(0); - mView->getCamera()->addChild(mGradientCamera.get()); } - } - else { - // Fall back to using the clear color for the camera - mView->getCamera()->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - mView->getCamera()->setClearColor(osg::Vec4( - backgroundColour.redF(), - backgroundColour.greenF(), - backgroundColour.blueF(), - 1.0f - )); - if (mGradientCamera.get() != nullptr && mView->getCamera()->containsNode(mGradientCamera.get())) { - // Remove the child to prevent the gradient from rendering - mView->getCamera()->removeChild(mGradientCamera.get()); + else + { + // Fall back to using the clear color for the camera + mView->getCamera()->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + mView->getCamera()->setClearColor( + osg::Vec4(backgroundColour.redF(), backgroundColour.greenF(), backgroundColour.blueF(), 1.0f)); + if (mGradientCamera.get() != nullptr && mView->getCamera()->containsNode(mGradientCamera.get())) + { + // Remove the child to prevent the gradient from rendering + mView->getCamera()->removeChild(mGradientCamera.get()); + } } } -} - -CSVWidget::SceneToolMode *SceneWidget::makeLightingSelector (CSVWidget::SceneToolbar *parent) -{ - CSVWidget::SceneToolMode *tool = new CSVWidget::SceneToolMode (parent, "Lighting Mode"); - - /// \todo replace icons - tool->addButton (":scenetoolbar/day", "day", - "Day" - "
  • Cell specific ambient in interiors
  • " - "
  • Low ambient in exteriors
  • " - "
  • Strong directional light source
  • " - "
  • This mode closely resembles day time in-game
"); - tool->addButton (":scenetoolbar/night", "night", - "Night" - "
  • Cell specific ambient in interiors
  • " - "
  • Low ambient in exteriors
  • " - "
  • Weak directional light source
  • " - "
  • This mode closely resembles night time in-game
"); - tool->addButton (":scenetoolbar/bright", "bright", - "Bright" - "
  • Maximum ambient
  • " - "
  • Strong directional light source
"); - - connect (tool, &CSVWidget::SceneToolMode::modeChanged, this, &SceneWidget::selectLightingMode); - - return tool; -} - -void SceneWidget::setDefaultAmbient (const osg::Vec4f& colour) -{ - mDefaultAmbient = colour; - mHasDefaultAmbient = true; - - setAmbient(mLighting->getAmbientColour(&mDefaultAmbient)); -} - -void SceneWidget::setExterior (bool isExterior) -{ - mIsExterior = isExterior; -} - -void SceneWidget::mouseMoveEvent (QMouseEvent *event) -{ - mCurrentCamControl->handleMouseMoveEvent(event->x() - mPrevMouseX, event->y() - mPrevMouseY); - - mPrevMouseX = event->x(); - mPrevMouseY = event->y(); -} - -void SceneWidget::wheelEvent(QWheelEvent *event) -{ - mCurrentCamControl->handleMouseScrollEvent(event->angleDelta().y()); -} -void SceneWidget::update(double dt) -{ - if (mCamPositionSet) + CSVWidget::SceneToolMode* SceneWidget::makeLightingSelector(CSVWidget::SceneToolbar* parent) { - mCurrentCamControl->update(dt); - } - else + CSVWidget::SceneToolMode* tool = new CSVWidget::SceneToolMode(parent, "Lighting Mode"); + + /// \todo replace icons + tool->addButton(":scenetoolbar/day", "day", + "Day" + "
  • Cell specific ambient in interiors
  • " + "
  • Low ambient in exteriors
  • " + "
  • Strong directional light source
  • " + "
  • This mode closely resembles day time in-game
"); + tool->addButton(":scenetoolbar/night", "night", + "Night" + "
  • Cell specific ambient in interiors
  • " + "
  • Low ambient in exteriors
  • " + "
  • Weak directional light source
  • " + "
  • This mode closely resembles night time in-game
"); + tool->addButton(":scenetoolbar/bright", "bright", + "Bright" + "
  • Maximum ambient
  • " + "
  • Strong directional light source
"); + + connect(tool, &CSVWidget::SceneToolMode::modeChanged, this, &SceneWidget::selectLightingMode); + + return tool; + } + + void SceneWidget::setDefaultAmbient(const osg::Vec4f& colour) { - mCurrentCamControl->setup(mRootNode, Mask_Reference | Mask_Terrain, CameraController::WorldUp); - mCamPositionSet = true; - } -} + mDefaultAmbient = colour; + mHasDefaultAmbient = true; -void SceneWidget::settingChanged (const CSMPrefs::Setting *setting) -{ - if (*setting=="3D Scene Input/p-navi-free-sensitivity") - { - mFreeCamControl->setCameraSensitivity(setting->toDouble()); - } - else if (*setting=="3D Scene Input/p-navi-orbit-sensitivity") - { - mOrbitCamControl->setCameraSensitivity(setting->toDouble()); - } - else if (*setting=="3D Scene Input/p-navi-free-invert") - { - mFreeCamControl->setInverted(setting->isTrue()); - } - else if (*setting=="3D Scene Input/p-navi-orbit-invert") - { - mOrbitCamControl->setInverted(setting->isTrue()); - } - else if (*setting=="3D Scene Input/s-navi-sensitivity") - { - mFreeCamControl->setSecondaryMovementMultiplier(setting->toDouble()); - mOrbitCamControl->setSecondaryMovementMultiplier(setting->toDouble()); - } - else if (*setting=="3D Scene Input/navi-wheel-factor") - { - mFreeCamControl->setWheelMovementMultiplier(setting->toDouble()); - mOrbitCamControl->setWheelMovementMultiplier(setting->toDouble()); - } - else if (*setting=="3D Scene Input/navi-free-lin-speed") - { - mFreeCamControl->setLinearSpeed(setting->toDouble()); - } - else if (*setting=="3D Scene Input/navi-free-rot-speed") - { - mFreeCamControl->setRotationalSpeed(setting->toDouble()); + setAmbient(mLighting->getAmbientColour(&mDefaultAmbient)); } - else if (*setting=="3D Scene Input/navi-free-speed-mult") - { - mFreeCamControl->setSpeedMultiplier(setting->toDouble()); - } - else if (*setting=="3D Scene Input/navi-orbit-rot-speed") - { - mOrbitCamControl->setOrbitSpeed(setting->toDouble()); - } - else if (*setting=="3D Scene Input/navi-orbit-speed-mult") + + void SceneWidget::setExterior(bool isExterior) { - mOrbitCamControl->setOrbitSpeedMultiplier(setting->toDouble()); + mIsExterior = isExterior; } - else if (*setting=="3D Scene Input/navi-orbit-const-roll") + + void SceneWidget::mouseMoveEvent(QMouseEvent* event) { - mOrbitCamControl->setConstRoll(setting->isTrue()); + mCurrentCamControl->handleMouseMoveEvent(event->x() - mPrevMouseX, event->y() - mPrevMouseY); + + mPrevMouseX = event->x(); + mPrevMouseY = event->y(); } - else if (*setting=="Rendering/framerate-limit") + + void SceneWidget::wheelEvent(QWheelEvent* event) { - CompositeViewer::get().setRunMaxFrameRate(setting->toInt()); + mCurrentCamControl->handleMouseScrollEvent(event->angleDelta().y()); } - else if (*setting=="Rendering/camera-fov" || - *setting=="Rendering/camera-ortho" || - *setting=="Rendering/camera-ortho-size") + + void SceneWidget::update(double dt) { - updateCameraParameters(); + if (mCamPositionSet) + { + mCurrentCamControl->update(dt); + } + else + { + mCurrentCamControl->setup(mRootNode, Mask_Reference | Mask_Terrain, CameraController::WorldUp); + mCamPositionSet = true; + } } - else if (*setting == "Rendering/scene-day-night-switch-nodes") + + void SceneWidget::settingChanged(const CSMPrefs::Setting* setting) { - if (mLighting) - setLighting(mLighting); + if (*setting == "3D Scene Input/p-navi-free-sensitivity") + { + mFreeCamControl->setCameraSensitivity(setting->toDouble()); + } + else if (*setting == "3D Scene Input/p-navi-orbit-sensitivity") + { + mOrbitCamControl->setCameraSensitivity(setting->toDouble()); + } + else if (*setting == "3D Scene Input/p-navi-free-invert") + { + mFreeCamControl->setInverted(setting->isTrue()); + } + else if (*setting == "3D Scene Input/p-navi-orbit-invert") + { + mOrbitCamControl->setInverted(setting->isTrue()); + } + else if (*setting == "3D Scene Input/s-navi-sensitivity") + { + mFreeCamControl->setSecondaryMovementMultiplier(setting->toDouble()); + mOrbitCamControl->setSecondaryMovementMultiplier(setting->toDouble()); + } + else if (*setting == "3D Scene Input/navi-wheel-factor") + { + mFreeCamControl->setWheelMovementMultiplier(setting->toDouble()); + mOrbitCamControl->setWheelMovementMultiplier(setting->toDouble()); + } + else if (*setting == "3D Scene Input/navi-free-lin-speed") + { + mFreeCamControl->setLinearSpeed(setting->toDouble()); + } + else if (*setting == "3D Scene Input/navi-free-rot-speed") + { + mFreeCamControl->setRotationalSpeed(setting->toDouble()); + } + else if (*setting == "3D Scene Input/navi-free-speed-mult") + { + mFreeCamControl->setSpeedMultiplier(setting->toDouble()); + } + else if (*setting == "3D Scene Input/navi-orbit-rot-speed") + { + mOrbitCamControl->setOrbitSpeed(setting->toDouble()); + } + else if (*setting == "3D Scene Input/navi-orbit-speed-mult") + { + mOrbitCamControl->setOrbitSpeedMultiplier(setting->toDouble()); + } + else if (*setting == "3D Scene Input/navi-orbit-const-roll") + { + mOrbitCamControl->setConstRoll(setting->isTrue()); + } + else if (*setting == "Rendering/framerate-limit") + { + CompositeViewer::get().setRunMaxFrameRate(setting->toInt()); + } + else if (*setting == "Rendering/camera-fov" || *setting == "Rendering/camera-ortho" + || *setting == "Rendering/camera-ortho-size") + { + updateCameraParameters(); + } + else if (*setting == "Rendering/scene-day-night-switch-nodes") + { + if (mLighting) + setLighting(mLighting); + } } -} - -void RenderWidget::updateCameraParameters(double overrideAspect) -{ - const float nearDist = 1.0; - const float farDist = 1000.0; - if (CSMPrefs::get()["Rendering"]["camera-ortho"].isTrue()) + void RenderWidget::updateCameraParameters(double overrideAspect) { - const float size = CSMPrefs::get()["Rendering"]["camera-ortho-size"].toInt(); - const float aspect = overrideAspect >= 0.0 ? overrideAspect : (width() / static_cast(height())); - const float halfH = size * 10.0; - const float halfW = halfH * aspect; + const float nearDist = 1.0; + const float farDist = 1000.0; - mView->getCamera()->setProjectionMatrixAsOrtho( - -halfW, halfW, -halfH, halfH, nearDist, farDist); - } - else - { - mView->getCamera()->setProjectionMatrixAsPerspective( - CSMPrefs::get()["Rendering"]["camera-fov"].toInt(), - static_cast(width())/static_cast(height()), - nearDist, farDist); - } -} + if (CSMPrefs::get()["Rendering"]["camera-ortho"].isTrue()) + { + const float size = CSMPrefs::get()["Rendering"]["camera-ortho-size"].toInt(); + const float aspect = overrideAspect >= 0.0 ? overrideAspect : (width() / static_cast(height())); + const float halfH = size * 10.0; + const float halfW = halfH * aspect; -void SceneWidget::selectNavigationMode (const std::string& mode) -{ - if (mode=="1st") - { - mCurrentCamControl->setCamera(nullptr); - mCurrentCamControl = mFreeCamControl; - mFreeCamControl->setCamera(getCamera()); - mFreeCamControl->fixUpAxis(CameraController::WorldUp); - } - else if (mode=="free") - { - mCurrentCamControl->setCamera(nullptr); - mCurrentCamControl = mFreeCamControl; - mFreeCamControl->setCamera(getCamera()); - mFreeCamControl->unfixUpAxis(); + mView->getCamera()->setProjectionMatrixAsOrtho(-halfW, halfW, -halfH, halfH, nearDist, farDist); + } + else + { + mView->getCamera()->setProjectionMatrixAsPerspective(CSMPrefs::get()["Rendering"]["camera-fov"].toInt(), + static_cast(width()) / static_cast(height()), nearDist, farDist); + } } - else if (mode=="orbit") + + void SceneWidget::selectNavigationMode(const std::string& mode) { - mCurrentCamControl->setCamera(nullptr); - mCurrentCamControl = mOrbitCamControl; - mOrbitCamControl->setCamera(getCamera()); - mOrbitCamControl->reset(); + if (mode == "1st") + { + mCurrentCamControl->setCamera(nullptr); + mCurrentCamControl = mFreeCamControl; + mFreeCamControl->setCamera(getCamera()); + mFreeCamControl->fixUpAxis(CameraController::WorldUp); + } + else if (mode == "free") + { + mCurrentCamControl->setCamera(nullptr); + mCurrentCamControl = mFreeCamControl; + mFreeCamControl->setCamera(getCamera()); + mFreeCamControl->unfixUpAxis(); + } + else if (mode == "orbit") + { + mCurrentCamControl->setCamera(nullptr); + mCurrentCamControl = mOrbitCamControl; + mOrbitCamControl->setCamera(getCamera()); + mOrbitCamControl->reset(); + } } -} } diff --git a/apps/opencs/view/render/scenewidget.hpp b/apps/opencs/view/render/scenewidget.hpp index 922776e9fb..6d2230aa7e 100644 --- a/apps/opencs/view/render/scenewidget.hpp +++ b/apps/opencs/view/render/scenewidget.hpp @@ -4,16 +4,15 @@ #include #include -#include #include +#include -#include #include +#include +#include "lightingbright.hpp" #include "lightingday.hpp" #include "lightingnight.hpp" -#include "lightingbright.hpp" - namespace Resource { @@ -46,124 +45,123 @@ namespace CSVRender class RenderWidget : public QWidget { - Q_OBJECT - - public: - RenderWidget(QWidget* parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags()); - virtual ~RenderWidget(); + Q_OBJECT - /// Initiates a request to redraw the view - void flagAsModified(); + public: + RenderWidget(QWidget* parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags()); + virtual ~RenderWidget(); - void setVisibilityMask(unsigned int mask); + /// Initiates a request to redraw the view + void flagAsModified(); - osg::Camera *getCamera(); + void setVisibilityMask(unsigned int mask); - protected: + osg::Camera* getCamera(); - osg::ref_ptr mView; - osg::ref_ptr mRootNode; + protected: + osg::ref_ptr mView; + osg::ref_ptr mRootNode; - void updateCameraParameters(double overrideAspect = -1.0); + void updateCameraParameters(double overrideAspect = -1.0); - QTimer mTimer; + QTimer mTimer; - protected slots: + protected slots: - void toggleRenderStats(); + void toggleRenderStats(); }; /// Extension of RenderWidget to support lighting mode selection & toolbar class SceneWidget : public RenderWidget { - Q_OBJECT - public: - SceneWidget(std::shared_ptr resourceSystem, QWidget* parent = nullptr, - Qt::WindowFlags f = Qt::WindowFlags(), bool retrieveInput = true); - virtual ~SceneWidget(); + Q_OBJECT + public: + SceneWidget(std::shared_ptr resourceSystem, QWidget* parent = nullptr, + Qt::WindowFlags f = Qt::WindowFlags(), bool retrieveInput = true); + virtual ~SceneWidget(); - CSVWidget::SceneToolMode *makeLightingSelector (CSVWidget::SceneToolbar *parent); - ///< \attention The created tool is not added to the toolbar (via addTool). Doing that - /// is the responsibility of the calling function. + CSVWidget::SceneToolMode* makeLightingSelector(CSVWidget::SceneToolbar* parent); + ///< \attention The created tool is not added to the toolbar (via addTool). Doing that + /// is the responsibility of the calling function. - void setDefaultAmbient (const osg::Vec4f& colour); - ///< \note The actual ambient colour may differ based on lighting settings. + void setDefaultAmbient(const osg::Vec4f& colour); + ///< \note The actual ambient colour may differ based on lighting settings. - void setExterior (bool isExterior); + void setExterior(bool isExterior); - protected: - void setLighting (Lighting *lighting); - ///< \attention The ownership of \a lighting is not transferred to *this. + protected: + void setLighting(Lighting* lighting); + ///< \attention The ownership of \a lighting is not transferred to *this. - void setAmbient(const osg::Vec4f& ambient); + void setAmbient(const osg::Vec4f& ambient); - void mouseMoveEvent (QMouseEvent *event) override; - void wheelEvent (QWheelEvent *event) override; + void mouseMoveEvent(QMouseEvent* event) override; + void wheelEvent(QWheelEvent* event) override; - osg::ref_ptr createGradientRectangle(QColor bgColour, QColor gradientColour); - osg::ref_ptr createGradientCamera(QColor bgColour, QColor gradientColour); - void updateGradientCamera(QColor bgColour, QColor gradientColour); + osg::ref_ptr createGradientRectangle(QColor bgColour, QColor gradientColour); + osg::ref_ptr createGradientCamera(QColor bgColour, QColor gradientColour); + void updateGradientCamera(QColor bgColour, QColor gradientColour); - std::shared_ptr mResourceSystem; + std::shared_ptr mResourceSystem; - Lighting* mLighting; - - osg::ref_ptr mGradientCamera; - osg::Vec4f mDefaultAmbient; - bool mHasDefaultAmbient; - bool mIsExterior; - LightingDay mLightingDay; - LightingNight mLightingNight; - LightingBright mLightingBright; + Lighting* mLighting; - int mPrevMouseX, mPrevMouseY; - - /// Tells update that camera isn't set - bool mCamPositionSet; + osg::ref_ptr mGradientCamera; + osg::Vec4f mDefaultAmbient; + bool mHasDefaultAmbient; + bool mIsExterior; + LightingDay mLightingDay; + LightingNight mLightingNight; + LightingBright mLightingBright; - FreeCameraController* mFreeCamControl; - OrbitCameraController* mOrbitCamControl; - CameraController* mCurrentCamControl; + int mPrevMouseX, mPrevMouseY; - public slots: - void update(double dt); + /// Tells update that camera isn't set + bool mCamPositionSet; - protected slots: + FreeCameraController* mFreeCamControl; + OrbitCameraController* mOrbitCamControl; + CameraController* mCurrentCamControl; - virtual void settingChanged (const CSMPrefs::Setting *setting); + public slots: + void update(double dt); - void selectNavigationMode (const std::string& mode); + protected slots: - private slots: + virtual void settingChanged(const CSMPrefs::Setting* setting); - void selectLightingMode (const std::string& mode); + void selectNavigationMode(const std::string& mode); - signals: + private slots: - void focusToolbarRequest(); - }; + void selectLightingMode(const std::string& mode); + signals: + + void focusToolbarRequest(); + }; - // There are rendering glitches when using multiple Viewer instances, work around using CompositeViewer with multiple views + // There are rendering glitches when using multiple Viewer instances, work around using CompositeViewer with + // multiple views class CompositeViewer : public QObject, public osgViewer::CompositeViewer { - Q_OBJECT - public: - CompositeViewer(); + Q_OBJECT + public: + CompositeViewer(); - static CompositeViewer& get(); + static CompositeViewer& get(); - QTimer mTimer; + QTimer mTimer; - private: - osg::Timer mFrameTimer; - double mSimulationTime; + private: + osg::Timer mFrameTimer; + double mSimulationTime; - public slots: - void update(); + public slots: + void update(); - signals: - void simulationUpdated(double dt); + signals: + void simulationUpdated(double dt); }; } diff --git a/apps/opencs/view/render/selectionmode.cpp b/apps/opencs/view/render/selectionmode.cpp index 431181d5e7..23eb0cd75a 100644 --- a/apps/opencs/view/render/selectionmode.cpp +++ b/apps/opencs/view/render/selectionmode.cpp @@ -1,40 +1,43 @@ #include "selectionmode.hpp" -#include #include +#include #include "worldspacewidget.hpp" namespace CSVRender { - SelectionMode::SelectionMode(CSVWidget::SceneToolbar* parent, WorldspaceWidget& worldspaceWidget, - unsigned int interactionMask) + SelectionMode::SelectionMode( + CSVWidget::SceneToolbar* parent, WorldspaceWidget& worldspaceWidget, unsigned int interactionMask) : SceneToolMode(parent, "Selection mode") , mWorldspaceWidget(worldspaceWidget) , mInteractionMask(interactionMask) { addButton(":scenetoolbar/selection-mode-cube", "cube-centre", "Centred cube" - "
  • Drag with {scene-select-primary} for primary select or {scene-select-secondary} for secondary select " - "from the centre of the selection cube outwards.
  • " + "
    • Drag with {scene-select-primary} for primary select or {scene-select-secondary} for secondary " + "select " + "from the centre of the selection cube outwards.
    • " "
    • The selection cube is aligned to the word space axis
    • " "
    • If context selection mode is enabled, a drag with {scene-edit-primary} or {scene-edit-secondary} not " - "starting on an instance will have the same effect
    • " + "starting on an instance will have the same effect" "
    "); addButton(":scenetoolbar/selection-mode-cube-corner", "cube-corner", "Cube corner to corner" - "
    • Drag with {scene-select-primary} for primary select or {scene-select-secondary} for secondary select " - "from one corner of the selection cube to the opposite corner
    • " + "
      • Drag with {scene-select-primary} for primary select or {scene-select-secondary} for secondary " + "select " + "from one corner of the selection cube to the opposite corner
      • " "
      • The selection cube is aligned to the word space axis
      • " "
      • If context selection mode is enabled, a drag with {scene-edit-primary} or {scene-edit-secondary} not " - "starting on an instance will have the same effect
      • " + "starting on an instance will have the same effect" "
      "); addButton(":scenetoolbar/selection-mode-cube-sphere", "sphere", "Centred sphere" - "
      • Drag with {scene-select-primary} for primary select or {scene-select-secondary} for secondary select " - "from the centre of the selection sphere outwards
      • " + "
        • Drag with {scene-select-primary} for primary select or {scene-select-secondary} for secondary " + "select " + "from the centre of the selection sphere outwards
        • " "
        • If context selection mode is enabled, a drag with {scene-edit-primary} or {scene-edit-secondary} not " - "starting on an instance will have the same effect
        • " + "starting on an instance will have the same effect" "
        "); mSelectAll = new QAction("Select all", this); @@ -51,7 +54,7 @@ namespace CSVRender return mWorldspaceWidget; } - bool SelectionMode::createContextMenu (QMenu* menu) + bool SelectionMode::createContextMenu(QMenu* menu) { if (menu) { diff --git a/apps/opencs/view/render/selectionmode.hpp b/apps/opencs/view/render/selectionmode.hpp index 28e44b85b1..8aa82f24b6 100644 --- a/apps/opencs/view/render/selectionmode.hpp +++ b/apps/opencs/view/render/selectionmode.hpp @@ -11,38 +11,35 @@ namespace CSVRender class SelectionMode : public CSVWidget::SceneToolMode { - Q_OBJECT - - public: - - SelectionMode(CSVWidget::SceneToolbar* parent, WorldspaceWidget& worldspaceWidget, - unsigned int interactionMask); - - protected: - - WorldspaceWidget& getWorldspaceWidget(); - - /// Add context menu items to \a menu. - /// - /// \attention menu can be a 0-pointer - /// - /// \return Have there been any menu items to be added (if menu is 0 and there - /// items to be added, the function must return true anyway. - bool createContextMenu (QMenu* menu) override; - - private: - - WorldspaceWidget& mWorldspaceWidget; - unsigned int mInteractionMask; - QAction* mSelectAll; - QAction* mDeselectAll; - QAction* mInvertSelection; - - protected slots: - - virtual void selectAll(); - virtual void clearSelection(); - virtual void invertSelection(); + Q_OBJECT + + public: + SelectionMode( + CSVWidget::SceneToolbar* parent, WorldspaceWidget& worldspaceWidget, unsigned int interactionMask); + + protected: + WorldspaceWidget& getWorldspaceWidget(); + + /// Add context menu items to \a menu. + /// + /// \attention menu can be a 0-pointer + /// + /// \return Have there been any menu items to be added (if menu is 0 and there + /// items to be added, the function must return true anyway. + bool createContextMenu(QMenu* menu) override; + + private: + WorldspaceWidget& mWorldspaceWidget; + unsigned int mInteractionMask; + QAction* mSelectAll; + QAction* mDeselectAll; + QAction* mInvertSelection; + + protected slots: + + virtual void selectAll(); + virtual void clearSelection(); + virtual void invertSelection(); }; } diff --git a/apps/opencs/view/render/tagbase.cpp b/apps/opencs/view/render/tagbase.cpp index 61a94215dd..bbbbc78390 100644 --- a/apps/opencs/view/render/tagbase.cpp +++ b/apps/opencs/view/render/tagbase.cpp @@ -1,14 +1,17 @@ #include "tagbase.hpp" -CSVRender::TagBase::TagBase (Mask mask) : mMask (mask) {} +CSVRender::TagBase::TagBase(Mask mask) + : mMask(mask) +{ +} CSVRender::Mask CSVRender::TagBase::getMask() const { return mMask; } -QString CSVRender::TagBase::getToolTip (bool hideBasics, const WorldspaceHitResult& /*hit*/) const +QString CSVRender::TagBase::getToolTip(bool hideBasics, const WorldspaceHitResult& /*hit*/) const { return ""; } diff --git a/apps/opencs/view/render/tagbase.hpp b/apps/opencs/view/render/tagbase.hpp index 50295d508d..a93267b6f4 100644 --- a/apps/opencs/view/render/tagbase.hpp +++ b/apps/opencs/view/render/tagbase.hpp @@ -13,16 +13,14 @@ namespace CSVRender class TagBase : public osg::Referenced { - Mask mMask; + Mask mMask; - public: + public: + TagBase(Mask mask); - TagBase (Mask mask); - - Mask getMask() const; - - virtual QString getToolTip (bool hideBasics, const WorldspaceHitResult& hit) const; + Mask getMask() const; + virtual QString getToolTip(bool hideBasics, const WorldspaceHitResult& hit) const; }; } diff --git a/apps/opencs/view/render/terrainselection.cpp b/apps/opencs/view/render/terrainselection.cpp index dc1886d57c..b8ef4bad0d 100644 --- a/apps/opencs/view/render/terrainselection.cpp +++ b/apps/opencs/view/render/terrainselection.cpp @@ -2,8 +2,8 @@ #include -#include #include +#include #include @@ -13,8 +13,11 @@ #include "cell.hpp" #include "worldspacewidget.hpp" -CSVRender::TerrainSelection::TerrainSelection(osg::Group* parentNode, WorldspaceWidget *worldspaceWidget, TerrainSelectionType type): -mParentNode(parentNode), mWorldspaceWidget (worldspaceWidget), mSelectionType(type) +CSVRender::TerrainSelection::TerrainSelection( + osg::Group* parentNode, WorldspaceWidget* worldspaceWidget, TerrainSelectionType type) + : mParentNode(parentNode) + , mWorldspaceWidget(worldspaceWidget) + , mSelectionType(type) { mGeometry = new osg::Geometry(); @@ -36,7 +39,7 @@ std::vector> CSVRender::TerrainSelection::getTerrainSelectio return mSelection; } -void CSVRender::TerrainSelection::onlySelect(const std::vector> &localPositions) +void CSVRender::TerrainSelection::onlySelect(const std::vector>& localPositions) { mSelection = localPositions; @@ -65,7 +68,8 @@ void CSVRender::TerrainSelection::clearTemporarySelection() void CSVRender::TerrainSelection::activate() { - if (!mParentNode->containsNode(mSelectionNode)) mParentNode->addChild(mSelectionNode); + if (!mParentNode->containsNode(mSelectionNode)) + mParentNode->addChild(mSelectionNode); } void CSVRender::TerrainSelection::deactivate() @@ -78,20 +82,23 @@ void CSVRender::TerrainSelection::update() mSelectionNode->removeChild(mGeometry); mGeometry = new osg::Geometry(); - const osg::ref_ptr vertices (new osg::Vec3Array); + const osg::ref_ptr vertices(new osg::Vec3Array); switch (mSelectionType) { - case TerrainSelectionType::Texture : drawTextureSelection(vertices); - break; - case TerrainSelectionType::Shape : drawShapeSelection(vertices); - break; + case TerrainSelectionType::Texture: + drawTextureSelection(vertices); + break; + case TerrainSelectionType::Shape: + drawShapeSelection(vertices); + break; } mGeometry->setVertexArray(vertices); osg::ref_ptr drawArrays = new osg::DrawArrays(osg::PrimitiveSet::LINES); drawArrays->setCount(vertices->size()); - if (vertices->size() != 0) mGeometry->addPrimitiveSet(drawArrays); + if (vertices->size() != 0) + mGeometry->addPrimitiveSet(drawArrays); mSelectionNode->addChild(mGeometry); } @@ -99,10 +106,10 @@ void CSVRender::TerrainSelection::drawShapeSelection(const osg::ref_ptr &localPos : mSelection) + for (std::pair& localPos : mSelection) { - int x (localPos.first); - int y (localPos.second); + int x(localPos.first); + int y(localPos.second); float xWorldCoord(CSMWorld::CellCoordinates::vertexGlobalToWorldCoords(x)); float yWorldCoord(CSMWorld::CellCoordinates::vertexGlobalToWorldCoords(y)); @@ -110,13 +117,17 @@ void CSVRender::TerrainSelection::drawShapeSelection(const osg::ref_ptrpush_back(pointXY); - vertices->push_back(osg::Vec3f(xWorldCoord, CSMWorld::CellCoordinates::vertexGlobalToWorldCoords(y - 1), calculateLandHeight(x, y - 1))); + vertices->push_back(osg::Vec3f(xWorldCoord, CSMWorld::CellCoordinates::vertexGlobalToWorldCoords(y - 1), + calculateLandHeight(x, y - 1))); vertices->push_back(pointXY); - vertices->push_back(osg::Vec3f(CSMWorld::CellCoordinates::vertexGlobalToWorldCoords(x - 1), yWorldCoord, calculateLandHeight(x - 1, y))); + vertices->push_back(osg::Vec3f(CSMWorld::CellCoordinates::vertexGlobalToWorldCoords(x - 1), yWorldCoord, + calculateLandHeight(x - 1, y))); vertices->push_back(pointXY); - vertices->push_back(osg::Vec3f(xWorldCoord, CSMWorld::CellCoordinates::vertexGlobalToWorldCoords(y + 1), calculateLandHeight(x, y + 1))); + vertices->push_back(osg::Vec3f(xWorldCoord, CSMWorld::CellCoordinates::vertexGlobalToWorldCoords(y + 1), + calculateLandHeight(x, y + 1))); vertices->push_back(pointXY); - vertices->push_back(osg::Vec3f(CSMWorld::CellCoordinates::vertexGlobalToWorldCoords(x + 1), yWorldCoord, calculateLandHeight(x + 1, y))); + vertices->push_back(osg::Vec3f(CSMWorld::CellCoordinates::vertexGlobalToWorldCoords(x + 1), yWorldCoord, + calculateLandHeight(x + 1, y))); } } } @@ -125,14 +136,15 @@ void CSVRender::TerrainSelection::drawTextureSelection(const osg::ref_ptr &localPos : mSelection) + for (std::pair& localPos : mSelection) { - int x (localPos.first); - int y (localPos.second); + int x(localPos.first); + int y(localPos.second); // convert texture selection to global vertex coordinates at selection box corners int x1 = x * textureSizeToLandSizeModifier + landHeightsNudge; @@ -145,55 +157,75 @@ void CSVRender::TerrainSelection::drawTextureSelection(const osg::ref_ptrpush_back(osg::Vec3f(drawPreviousX, CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y + 1), calculateLandHeight(x1+(i-1), y2))); - vertices->push_back(osg::Vec3f(drawCurrentX, CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y + 1), calculateLandHeight(x1+i, y2))); + float drawPreviousX = CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(x) + + (i - 1) * (ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1)); + float drawCurrentX = CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(x) + + i * (ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1)); + vertices->push_back( + osg::Vec3f(drawPreviousX, CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y + 1), + calculateLandHeight(x1 + (i - 1), y2))); + vertices->push_back( + osg::Vec3f(drawCurrentX, CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y + 1), + calculateLandHeight(x1 + i, y2))); } } const auto south = std::find(mSelection.begin(), mSelection.end(), std::make_pair(x, y - 1)); if (south == mSelection.end()) { - for(int i = 1; i < (textureSizeToLandSizeModifier + 1); i++) + for (int i = 1; i < (textureSizeToLandSizeModifier + 1); i++) { - float drawPreviousX = CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(x) + (i - 1) *(ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1)); - float drawCurrentX = CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(x) + i * (ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1)); - vertices->push_back(osg::Vec3f(drawPreviousX, CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y), calculateLandHeight(x1+(i-1), y1))); - vertices->push_back(osg::Vec3f(drawCurrentX, CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y), calculateLandHeight(x1+i, y1))); + float drawPreviousX = CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(x) + + (i - 1) * (ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1)); + float drawCurrentX = CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(x) + + i * (ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1)); + vertices->push_back( + osg::Vec3f(drawPreviousX, CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y), + calculateLandHeight(x1 + (i - 1), y1))); + vertices->push_back(osg::Vec3f(drawCurrentX, + CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y), calculateLandHeight(x1 + i, y1))); } } const auto east = std::find(mSelection.begin(), mSelection.end(), std::make_pair(x + 1, y)); if (east == mSelection.end()) { - for(int i = 1; i < (textureSizeToLandSizeModifier + 1); i++) + for (int i = 1; i < (textureSizeToLandSizeModifier + 1); i++) { - float drawPreviousY = CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y) + (i - 1) * (ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1)); - float drawCurrentY = CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y) + i * (ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1)); - vertices->push_back(osg::Vec3f(CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(x + 1), drawPreviousY, calculateLandHeight(x2, y1+(i-1)))); - vertices->push_back(osg::Vec3f(CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(x + 1), drawCurrentY, calculateLandHeight(x2, y1+i))); + float drawPreviousY = CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y) + + (i - 1) * (ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1)); + float drawCurrentY = CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y) + + i * (ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1)); + vertices->push_back(osg::Vec3f(CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(x + 1), + drawPreviousY, calculateLandHeight(x2, y1 + (i - 1)))); + vertices->push_back(osg::Vec3f(CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(x + 1), + drawCurrentY, calculateLandHeight(x2, y1 + i))); } } const auto west = std::find(mSelection.begin(), mSelection.end(), std::make_pair(x - 1, y)); if (west == mSelection.end()) { - for(int i = 1; i < (textureSizeToLandSizeModifier + 1); i++) + for (int i = 1; i < (textureSizeToLandSizeModifier + 1); i++) { - float drawPreviousY = CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y) + (i - 1) * (ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1)); - float drawCurrentY = CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y) + i * (ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1)); - vertices->push_back(osg::Vec3f(CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(x), drawPreviousY, calculateLandHeight(x1, y1+(i-1)))); - vertices->push_back(osg::Vec3f(CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(x), drawCurrentY, calculateLandHeight(x1, y1+i))); + float drawPreviousY = CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y) + + (i - 1) * (ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1)); + float drawCurrentY = CSMWorld::CellCoordinates::textureGlobalYToWorldCoords(y) + + i * (ESM::Land::REAL_SIZE / (ESM::Land::LAND_SIZE - 1)); + vertices->push_back(osg::Vec3f(CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(x), + drawPreviousY, calculateLandHeight(x1, y1 + (i - 1)))); + vertices->push_back(osg::Vec3f(CSMWorld::CellCoordinates::textureGlobalXToWorldCoords(x), + drawCurrentY, calculateLandHeight(x1, y1 + i))); } } } } } -void CSVRender::TerrainSelection::handleSelection(const std::vector>& localPositions, SelectionMethod selectionMethod) +void CSVRender::TerrainSelection::handleSelection( + const std::vector>& localPositions, SelectionMethod selectionMethod) { for (auto const& localPos : localPositions) { @@ -248,14 +280,14 @@ bool CSVRender::TerrainSelection::noCell(const std::string& cellId) { CSMDoc::Document& document = mWorldspaceWidget->getDocument(); const CSMWorld::IdCollection& cellCollection = document.getData().getCells(); - return cellCollection.searchId (cellId) == -1; + return cellCollection.searchId(cellId) == -1; } bool CSVRender::TerrainSelection::noLand(const std::string& cellId) { CSMDoc::Document& document = mWorldspaceWidget->getDocument(); const CSMWorld::IdCollection& landCollection = document.getData().getLand(); - return landCollection.searchId (cellId) == -1; + return landCollection.searchId(cellId) == -1; } bool CSVRender::TerrainSelection::noLandLoaded(const std::string& cellId) @@ -267,7 +299,8 @@ bool CSVRender::TerrainSelection::noLandLoaded(const std::string& cellId) bool CSVRender::TerrainSelection::isLandLoaded(const std::string& cellId) { - if (!noCell(cellId) && !noLand(cellId) && !noLandLoaded(cellId)) return true; + if (!noCell(cellId) && !noLand(cellId) && !noLandLoaded(cellId)) + return true; return false; } @@ -278,7 +311,7 @@ int CSVRender::TerrainSelection::calculateLandHeight(int x, int y) // global ver int localX = x - cellX * (ESM::Land::LAND_SIZE - 1); int localY = y - cellY * (ESM::Land::LAND_SIZE - 1); - CSMWorld::CellCoordinates coords (cellX, cellY); + CSMWorld::CellCoordinates coords(cellX, cellY); float landHeight = 0.f; if (CSVRender::Cell* cell = dynamic_cast(mWorldspaceWidget->getCell(coords))) @@ -289,8 +322,9 @@ int CSVRender::TerrainSelection::calculateLandHeight(int x, int y) // global ver { CSMDoc::Document& document = mWorldspaceWidget->getDocument(); std::string cellId = CSMWorld::CellCoordinates::generateId(cellX, cellY); - const ESM::Land::LandData* landData = document.getData().getLand().getRecord(cellId).get().getLandData(ESM::Land::DATA_VHGT); - return landData->mHeights[localY*ESM::Land::LAND_SIZE + localX]; + const ESM::Land::LandData* landData + = document.getData().getLand().getRecord(cellId).get().getLandData(ESM::Land::DATA_VHGT); + return landData->mHeights[localY * ESM::Land::LAND_SIZE + localX]; } return landHeight; diff --git a/apps/opencs/view/render/terrainselection.hpp b/apps/opencs/view/render/terrainselection.hpp index 864414ad34..e0fbbd28f3 100644 --- a/apps/opencs/view/render/terrainselection.hpp +++ b/apps/opencs/view/render/terrainselection.hpp @@ -4,9 +4,9 @@ #include #include +#include #include #include -#include #include @@ -37,51 +37,50 @@ namespace CSVRender /// \brief Class handling the terrain selection data and rendering class TerrainSelection { - public: - - TerrainSelection(osg::Group* parentNode, WorldspaceWidget *worldspaceWidget, TerrainSelectionType type); - ~TerrainSelection(); - - void onlySelect(const std::vector> &localPositions); - void addSelect(const std::vector>& localPositions); - void removeSelect(const std::vector>& localPositions); - void toggleSelect(const std::vector> &localPositions); - void clearTemporarySelection(); - - void activate(); - void deactivate(); + public: + TerrainSelection(osg::Group* parentNode, WorldspaceWidget* worldspaceWidget, TerrainSelectionType type); + ~TerrainSelection(); - std::vector> getTerrainSelection() const; + void onlySelect(const std::vector>& localPositions); + void addSelect(const std::vector>& localPositions); + void removeSelect(const std::vector>& localPositions); + void toggleSelect(const std::vector>& localPositions); + void clearTemporarySelection(); - void update(); + void activate(); + void deactivate(); - protected: + std::vector> getTerrainSelection() const; - void drawShapeSelection(const osg::ref_ptr vertices); - void drawTextureSelection(const osg::ref_ptr vertices); + void update(); - int calculateLandHeight(int x, int y); + protected: + void drawShapeSelection(const osg::ref_ptr vertices); + void drawTextureSelection(const osg::ref_ptr vertices); - private: + int calculateLandHeight(int x, int y); - void handleSelection(const std::vector>& localPositions, SelectionMethod selectionMethod); + private: + void handleSelection(const std::vector>& localPositions, SelectionMethod selectionMethod); - bool noCell(const std::string& cellId); + bool noCell(const std::string& cellId); - bool noLand(const std::string& cellId); + bool noLand(const std::string& cellId); - bool noLandLoaded(const std::string& cellId); + bool noLandLoaded(const std::string& cellId); - bool isLandLoaded(const std::string& cellId); + bool isLandLoaded(const std::string& cellId); - osg::Group* mParentNode; - WorldspaceWidget *mWorldspaceWidget; - osg::ref_ptr mBaseNode; - osg::ref_ptr mGeometry; - osg::ref_ptr mSelectionNode; - std::vector> mSelection; // Global terrain selection coordinate in either vertex or texture units - std::vector> mTemporarySelection; // Used during toggle to compare the most recent drag operation - TerrainSelectionType mSelectionType; + osg::Group* mParentNode; + WorldspaceWidget* mWorldspaceWidget; + osg::ref_ptr mBaseNode; + osg::ref_ptr mGeometry; + osg::ref_ptr mSelectionNode; + std::vector> + mSelection; // Global terrain selection coordinate in either vertex or texture units + std::vector> + mTemporarySelection; // Used during toggle to compare the most recent drag operation + TerrainSelectionType mSelectionType; }; } diff --git a/apps/opencs/view/render/terrainshapemode.cpp b/apps/opencs/view/render/terrainshapemode.cpp index af39d23cf5..be3ed672d8 100644 --- a/apps/opencs/view/render/terrainshapemode.cpp +++ b/apps/opencs/view/render/terrainshapemode.cpp @@ -1,39 +1,41 @@ #include "terrainshapemode.hpp" #include -#include #include +#include -#include -#include -#include #include +#include +#include +#include #include #include -#include #include +#include #include "../widget/scenetoolbar.hpp" #include "../widget/scenetoolshapebrush.hpp" #include "../../model/prefs/state.hpp" -#include "../../model/world/idtree.hpp" #include "../../model/world/commands.hpp" +#include "../../model/world/idtree.hpp" #include "brushdraw.hpp" #include "commands.hpp" #include "editmode.hpp" -#include "pagedworldspacewidget.hpp" #include "mask.hpp" +#include "pagedworldspacewidget.hpp" #include "tagbase.hpp" #include "terrainselection.hpp" #include "worldspacewidget.hpp" -CSVRender::TerrainShapeMode::TerrainShapeMode (WorldspaceWidget *worldspaceWidget, osg::Group* parentNode, QWidget *parent) -: EditMode (worldspaceWidget, QIcon {":scenetoolbar/editing-terrain-shape"}, Mask_Terrain, "Terrain land editing", parent), - mParentNode(parentNode) +CSVRender::TerrainShapeMode::TerrainShapeMode( + WorldspaceWidget* worldspaceWidget, osg::Group* parentNode, QWidget* parent) + : EditMode( + worldspaceWidget, QIcon{ ":scenetoolbar/editing-terrain-shape" }, Mask_Terrain, "Terrain land editing", parent) + , mParentNode(parentNode) { } @@ -41,32 +43,40 @@ void CSVRender::TerrainShapeMode::activate(CSVWidget::SceneToolbar* toolbar) { if (!mTerrainShapeSelection) { - mTerrainShapeSelection = std::make_shared(mParentNode, &getWorldspaceWidget(), TerrainSelectionType::Shape); + mTerrainShapeSelection + = std::make_shared(mParentNode, &getWorldspaceWidget(), TerrainSelectionType::Shape); } - if(!mShapeBrushScenetool) + if (!mShapeBrushScenetool) { - mShapeBrushScenetool = new CSVWidget::SceneToolShapeBrush (toolbar, "scenetoolshapebrush", getWorldspaceWidget().getDocument()); - connect(mShapeBrushScenetool, &CSVWidget::SceneTool::clicked, mShapeBrushScenetool, &CSVWidget::SceneToolShapeBrush::activate); - connect(mShapeBrushScenetool->mShapeBrushWindow, &CSVWidget::ShapeBrushWindow::passBrushSize, this, &TerrainShapeMode::setBrushSize); - connect(mShapeBrushScenetool->mShapeBrushWindow, &CSVWidget::ShapeBrushWindow::passBrushShape, this, &TerrainShapeMode::setBrushShape); - connect(mShapeBrushScenetool->mShapeBrushWindow->mSizeSliders->mBrushSizeSlider, &QSlider::valueChanged, this, &TerrainShapeMode::setBrushSize); - connect(mShapeBrushScenetool->mShapeBrushWindow->mToolSelector, qOverload(&QComboBox::currentIndexChanged), this, &TerrainShapeMode::setShapeEditTool); - connect(mShapeBrushScenetool->mShapeBrushWindow->mToolStrengthSlider, &QSlider::valueChanged, this, &TerrainShapeMode::setShapeEditToolStrength); + mShapeBrushScenetool + = new CSVWidget::SceneToolShapeBrush(toolbar, "scenetoolshapebrush", getWorldspaceWidget().getDocument()); + connect(mShapeBrushScenetool, &CSVWidget::SceneTool::clicked, mShapeBrushScenetool, + &CSVWidget::SceneToolShapeBrush::activate); + connect(mShapeBrushScenetool->mShapeBrushWindow, &CSVWidget::ShapeBrushWindow::passBrushSize, this, + &TerrainShapeMode::setBrushSize); + connect(mShapeBrushScenetool->mShapeBrushWindow, &CSVWidget::ShapeBrushWindow::passBrushShape, this, + &TerrainShapeMode::setBrushShape); + connect(mShapeBrushScenetool->mShapeBrushWindow->mSizeSliders->mBrushSizeSlider, &QSlider::valueChanged, this, + &TerrainShapeMode::setBrushSize); + connect(mShapeBrushScenetool->mShapeBrushWindow->mToolSelector, qOverload(&QComboBox::currentIndexChanged), + this, &TerrainShapeMode::setShapeEditTool); + connect(mShapeBrushScenetool->mShapeBrushWindow->mToolStrengthSlider, &QSlider::valueChanged, this, + &TerrainShapeMode::setShapeEditToolStrength); } if (!mBrushDraw) mBrushDraw = std::make_unique(mParentNode); EditMode::activate(toolbar); - toolbar->addTool (mShapeBrushScenetool); + toolbar->addTool(mShapeBrushScenetool); } void CSVRender::TerrainShapeMode::deactivate(CSVWidget::SceneToolbar* toolbar) { - if(mShapeBrushScenetool) + if (mShapeBrushScenetool) { - toolbar->removeTool (mShapeBrushScenetool); + toolbar->removeTool(mShapeBrushScenetool); } if (mTerrainShapeSelection) @@ -80,7 +90,7 @@ void CSVRender::TerrainShapeMode::deactivate(CSVWidget::SceneToolbar* toolbar) EditMode::deactivate(toolbar); } -void CSVRender::TerrainShapeMode::primaryOpenPressed (const WorldspaceHitResult& hit) // Apply changes here +void CSVRender::TerrainShapeMode::primaryOpenPressed(const WorldspaceHitResult& hit) // Apply changes here { } @@ -101,7 +111,7 @@ void CSVRender::TerrainShapeMode::primaryEditPressed(const WorldspaceHitResult& void CSVRender::TerrainShapeMode::primarySelectPressed(const WorldspaceHitResult& hit) { - if(hit.hit && hit.tag == nullptr) + if (hit.hit && hit.tag == nullptr) { selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 0); mTerrainShapeSelection->clearTemporarySelection(); @@ -110,16 +120,16 @@ void CSVRender::TerrainShapeMode::primarySelectPressed(const WorldspaceHitResult void CSVRender::TerrainShapeMode::secondarySelectPressed(const WorldspaceHitResult& hit) { - if(hit.hit && hit.tag == nullptr) + if (hit.hit && hit.tag == nullptr) { selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 1); mTerrainShapeSelection->clearTemporarySelection(); } } -bool CSVRender::TerrainShapeMode::primaryEditStartDrag (const QPoint& pos) +bool CSVRender::TerrainShapeMode::primaryEditStartDrag(const QPoint& pos) { - WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask()); + WorldspaceHitResult hit = getWorldspaceWidget().mousePick(pos, getWorldspaceWidget().getInteractionMask()); mDragMode = InteractionType_PrimaryEdit; @@ -134,14 +144,14 @@ bool CSVRender::TerrainShapeMode::primaryEditStartDrag (const QPoint& pos) return true; } -bool CSVRender::TerrainShapeMode::secondaryEditStartDrag (const QPoint& pos) +bool CSVRender::TerrainShapeMode::secondaryEditStartDrag(const QPoint& pos) { return false; } -bool CSVRender::TerrainShapeMode::primarySelectStartDrag (const QPoint& pos) +bool CSVRender::TerrainShapeMode::primarySelectStartDrag(const QPoint& pos) { - WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask()); + WorldspaceHitResult hit = getWorldspaceWidget().mousePick(pos, getWorldspaceWidget().getInteractionMask()); mDragMode = InteractionType_PrimarySelect; if (!hit.hit || hit.tag != nullptr) { @@ -152,9 +162,9 @@ bool CSVRender::TerrainShapeMode::primarySelectStartDrag (const QPoint& pos) return true; } -bool CSVRender::TerrainShapeMode::secondarySelectStartDrag (const QPoint& pos) +bool CSVRender::TerrainShapeMode::secondarySelectStartDrag(const QPoint& pos) { - WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask()); + WorldspaceHitResult hit = getWorldspaceWidget().mousePick(pos, getWorldspaceWidget().getInteractionMask()); mDragMode = InteractionType_SecondarySelect; if (!hit.hit || hit.tag != nullptr) { @@ -165,29 +175,33 @@ bool CSVRender::TerrainShapeMode::secondarySelectStartDrag (const QPoint& pos) return true; } -void CSVRender::TerrainShapeMode::drag (const QPoint& pos, int diffX, int diffY, double speedFactor) +void CSVRender::TerrainShapeMode::drag(const QPoint& pos, int diffX, int diffY, double speedFactor) { if (mDragMode == InteractionType_PrimaryEdit) { - WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask()); + WorldspaceHitResult hit = getWorldspaceWidget().mousePick(pos, getWorldspaceWidget().getInteractionMask()); mTotalDiffY += diffY; if (mIsEditing) { - if (mShapeEditTool == ShapeEditTool_Drag) editTerrainShapeGrid(CSMWorld::CellCoordinates::toVertexCoords(mEditingPos), true); - else editTerrainShapeGrid(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), true); + if (mShapeEditTool == ShapeEditTool_Drag) + editTerrainShapeGrid(CSMWorld::CellCoordinates::toVertexCoords(mEditingPos), true); + else + editTerrainShapeGrid(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), true); } } if (mDragMode == InteractionType_PrimarySelect) { - WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask()); - if (hit.hit && hit.tag == nullptr) selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 0); + WorldspaceHitResult hit = getWorldspaceWidget().mousePick(pos, getWorldspaceWidget().getInteractionMask()); + if (hit.hit && hit.tag == nullptr) + selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 0); } if (mDragMode == InteractionType_SecondarySelect) { - WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask()); - if (hit.hit && hit.tag == nullptr) selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 1); + WorldspaceHitResult hit = getWorldspaceWidget().mousePick(pos, getWorldspaceWidget().getInteractionMask()); + if (hit.hit && hit.tag == nullptr) + selectTerrainShapes(CSMWorld::CellCoordinates::toVertexCoords(hit.worldPos), 1); } } @@ -204,16 +218,13 @@ void CSVRender::TerrainShapeMode::dragCompleted(const QPoint& pos) } } - void CSVRender::TerrainShapeMode::dragAborted() { - clearTransientEdits(); - mDragMode = InteractionType_None; + clearTransientEdits(); + mDragMode = InteractionType_None; } -void CSVRender::TerrainShapeMode::dragWheel (int diff, double speedFactor) -{ -} +void CSVRender::TerrainShapeMode::dragWheel(int diff, double speedFactor) {} void CSVRender::TerrainShapeMode::sortAndLimitAlteredCells() { @@ -226,19 +237,23 @@ void CSVRender::TerrainShapeMode::sortAndLimitAlteredCells() while (!passing) // Multiple passes are needed when steepness problems arise for both x and y axis simultaneously { passing = true; - for(CSMWorld::CellCoordinates cellCoordinates: mAlteredCells) + for (CSMWorld::CellCoordinates cellCoordinates : mAlteredCells) { limitAlteredHeights(cellCoordinates); } - std::reverse(mAlteredCells.begin(), mAlteredCells.end()); //Instead of alphabetical order, this should be fixed to sort cells by cell coordinates - for(CSMWorld::CellCoordinates cellCoordinates: mAlteredCells) + std::reverse(mAlteredCells.begin(), + mAlteredCells + .end()); // Instead of alphabetical order, this should be fixed to sort cells by cell coordinates + for (CSMWorld::CellCoordinates cellCoordinates : mAlteredCells) { - if (!limitAlteredHeights(cellCoordinates, true)) passing = false; + if (!limitAlteredHeights(cellCoordinates, true)) + passing = false; } ++passes; if (passes > 2) { - Log(Debug::Warning) << "Warning: User edit exceeds accepted slope steepness. Automatic limiting has failed, edit has been discarded."; + Log(Debug::Warning) << "Warning: User edit exceeds accepted slope steepness. Automatic limiting has " + "failed, edit has been discarded."; clearTransientEdits(); return; } @@ -250,7 +265,8 @@ void CSVRender::TerrainShapeMode::clearTransientEdits() mTotalDiffY = 0; mIsEditing = false; mAlteredCells.clear(); - if (CSVRender::PagedWorldspaceWidget *paged = dynamic_cast (&getWorldspaceWidget())) + if (CSVRender::PagedWorldspaceWidget* paged + = dynamic_cast(&getWorldspaceWidget())) paged->resetAllAlteredHeights(); mTerrainShapeSelection->update(); } @@ -258,10 +274,10 @@ void CSVRender::TerrainShapeMode::clearTransientEdits() void CSVRender::TerrainShapeMode::applyTerrainEditChanges() { CSMDoc::Document& document = getWorldspaceWidget().getDocument(); - CSMWorld::IdTable& landTable = dynamic_cast ( - *document.getData().getTableModel (CSMWorld::UniversalId::Type_Land)); - CSMWorld::IdTable& ltexTable = dynamic_cast ( - *document.getData().getTableModel (CSMWorld::UniversalId::Type_LandTextures)); + CSMWorld::IdTable& landTable + = dynamic_cast(*document.getData().getTableModel(CSMWorld::UniversalId::Type_Land)); + CSMWorld::IdTable& ltexTable + = dynamic_cast(*document.getData().getTableModel(CSMWorld::UniversalId::Type_LandTextures)); int landshapeColumn = landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandHeightsIndex); int landnormalsColumn = landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandNormalsIndex); @@ -270,26 +286,30 @@ void CSVRender::TerrainShapeMode::applyTerrainEditChanges() sortAndLimitAlteredCells(); - undoStack.beginMacro ("Edit shape and normal records"); + undoStack.beginMacro("Edit shape and normal records"); // One command at the beginning of the macro for redrawing the terrain-selection grid when undoing the changes. undoStack.push(new DrawTerrainSelectionCommand(&getWorldspaceWidget())); - for(CSMWorld::CellCoordinates cellCoordinates: mAlteredCells) + for (CSMWorld::CellCoordinates cellCoordinates : mAlteredCells) { std::string cellId = CSMWorld::CellCoordinates::generateId(cellCoordinates.getX(), cellCoordinates.getY()); - undoStack.push (new CSMWorld::TouchLandCommand(landTable, ltexTable, cellId)); - const CSMWorld::LandHeightsColumn::DataType landShapePointer = landTable.data(landTable.getModelIndex(cellId, landshapeColumn)).value(); + undoStack.push(new CSMWorld::TouchLandCommand(landTable, ltexTable, cellId)); + const CSMWorld::LandHeightsColumn::DataType landShapePointer + = landTable.data(landTable.getModelIndex(cellId, landshapeColumn)) + .value(); CSMWorld::LandHeightsColumn::DataType landShapeNew(landShapePointer); - CSVRender::PagedWorldspaceWidget *paged = dynamic_cast (&getWorldspaceWidget()); + CSVRender::PagedWorldspaceWidget* paged + = dynamic_cast(&getWorldspaceWidget()); // Generate land height record - for(int i = 0; i < ESM::Land::LAND_SIZE; ++i) + for (int i = 0; i < ESM::Land::LAND_SIZE; ++i) { - for(int j = 0; j < ESM::Land::LAND_SIZE; ++j) + for (int j = 0; j < ESM::Land::LAND_SIZE; ++j) { if (paged && paged->getCellAlteredHeight(cellCoordinates, i, j)) - landShapeNew[j * ESM::Land::LAND_SIZE + i] = landShapePointer[j * ESM::Land::LAND_SIZE + i] + *paged->getCellAlteredHeight(cellCoordinates, i, j); + landShapeNew[j * ESM::Land::LAND_SIZE + i] = landShapePointer[j * ESM::Land::LAND_SIZE + i] + + *paged->getCellAlteredHeight(cellCoordinates, i, j); else landShapeNew[j * ESM::Land::LAND_SIZE + i] = 0; } @@ -298,37 +318,59 @@ void CSVRender::TerrainShapeMode::applyTerrainEditChanges() pushEditToCommand(landShapeNew, document, landTable, cellId); } - for(CSMWorld::CellCoordinates cellCoordinates: mAlteredCells) + for (CSMWorld::CellCoordinates cellCoordinates : mAlteredCells) { std::string cellId = CSMWorld::CellCoordinates::generateId(cellCoordinates.getX(), cellCoordinates.getY()); - const CSMWorld::LandHeightsColumn::DataType landShapePointer = landTable.data(landTable.getModelIndex(cellId, landshapeColumn)).value(); - const CSMWorld::LandHeightsColumn::DataType landRightShapePointer = landTable.data(landTable.getModelIndex(CSMWorld::CellCoordinates::generateId(cellCoordinates.getX() + 1, cellCoordinates.getY()), landshapeColumn)).value(); - const CSMWorld::LandHeightsColumn::DataType landDownShapePointer = landTable.data(landTable.getModelIndex(CSMWorld::CellCoordinates::generateId(cellCoordinates.getX(), cellCoordinates.getY() + 1), landshapeColumn)).value(); - const CSMWorld::LandNormalsColumn::DataType landNormalsPointer = landTable.data(landTable.getModelIndex(cellId, landnormalsColumn)).value(); + const CSMWorld::LandHeightsColumn::DataType landShapePointer + = landTable.data(landTable.getModelIndex(cellId, landshapeColumn)) + .value(); + const CSMWorld::LandHeightsColumn::DataType landRightShapePointer + = landTable + .data(landTable.getModelIndex( + CSMWorld::CellCoordinates::generateId(cellCoordinates.getX() + 1, cellCoordinates.getY()), + landshapeColumn)) + .value(); + const CSMWorld::LandHeightsColumn::DataType landDownShapePointer + = landTable + .data(landTable.getModelIndex( + CSMWorld::CellCoordinates::generateId(cellCoordinates.getX(), cellCoordinates.getY() + 1), + landshapeColumn)) + .value(); + const CSMWorld::LandNormalsColumn::DataType landNormalsPointer + = landTable.data(landTable.getModelIndex(cellId, landnormalsColumn)) + .value(); CSMWorld::LandNormalsColumn::DataType landNormalsNew(landNormalsPointer); // Generate land normals record - for(int i = 0; i < ESM::Land::LAND_SIZE; ++i) + for (int i = 0; i < ESM::Land::LAND_SIZE; ++i) { - for(int j = 0; j < ESM::Land::LAND_SIZE; ++j) + for (int j = 0; j < ESM::Land::LAND_SIZE; ++j) { osg::Vec3f v1(128, 0, 0); osg::Vec3f v2(0, 128, 0); - if (i < ESM::Land::LAND_SIZE - 1) v1.z() = landShapePointer[j * ESM::Land::LAND_SIZE + i + 1] - landShapePointer[j * ESM::Land::LAND_SIZE + i]; + if (i < ESM::Land::LAND_SIZE - 1) + v1.z() = landShapePointer[j * ESM::Land::LAND_SIZE + i + 1] + - landShapePointer[j * ESM::Land::LAND_SIZE + i]; else { - std::string shiftedCellId = CSMWorld::CellCoordinates::generateId(cellCoordinates.getX() + 1, cellCoordinates.getY()); + std::string shiftedCellId + = CSMWorld::CellCoordinates::generateId(cellCoordinates.getX() + 1, cellCoordinates.getY()); if (isLandLoaded(shiftedCellId)) - v1.z() = landRightShapePointer[j * ESM::Land::LAND_SIZE + 1] - landShapePointer[j * ESM::Land::LAND_SIZE + i]; + v1.z() = landRightShapePointer[j * ESM::Land::LAND_SIZE + 1] + - landShapePointer[j * ESM::Land::LAND_SIZE + i]; } - if (j < ESM::Land::LAND_SIZE - 1) v2.z() = landShapePointer[(j + 1) * ESM::Land::LAND_SIZE + i] - landShapePointer[j * ESM::Land::LAND_SIZE + i]; + if (j < ESM::Land::LAND_SIZE - 1) + v2.z() = landShapePointer[(j + 1) * ESM::Land::LAND_SIZE + i] + - landShapePointer[j * ESM::Land::LAND_SIZE + i]; else { - std::string shiftedCellId = CSMWorld::CellCoordinates::generateId(cellCoordinates.getX(), cellCoordinates.getY() + 1); + std::string shiftedCellId + = CSMWorld::CellCoordinates::generateId(cellCoordinates.getX(), cellCoordinates.getY() + 1); if (isLandLoaded(shiftedCellId)) - v2.z() = landDownShapePointer[ESM::Land::LAND_SIZE + i] - landShapePointer[j * ESM::Land::LAND_SIZE + i]; + v2.z() = landDownShapePointer[ESM::Land::LAND_SIZE + i] + - landShapePointer[j * ESM::Land::LAND_SIZE + i]; } osg::Vec3f normal = v1 ^ v2; @@ -353,18 +395,22 @@ void CSVRender::TerrainShapeMode::applyTerrainEditChanges() float CSVRender::TerrainShapeMode::calculateBumpShape(float distance, int radius, float height) { float distancePerRadius = distance / radius; - return height - height * (3 * distancePerRadius * distancePerRadius - 2 * distancePerRadius * distancePerRadius * distancePerRadius); + return height + - height + * (3 * distancePerRadius * distancePerRadius - 2 * distancePerRadius * distancePerRadius * distancePerRadius); } void CSVRender::TerrainShapeMode::editTerrainShapeGrid(const std::pair& vertexCoords, bool dragOperation) { int r = mBrushSize / 2; - if (r == 0) r = 1; // Prevent division by zero later, which might happen when mBrushSize == 1 + if (r == 0) + r = 1; // Prevent division by zero later, which might happen when mBrushSize == 1 - if (CSVRender::PagedWorldspaceWidget *paged = - dynamic_cast (&getWorldspaceWidget())) + if (CSVRender::PagedWorldspaceWidget* paged + = dynamic_cast(&getWorldspaceWidget())) { - if (mShapeEditTool == ShapeEditTool_Drag) paged->resetAllAlteredHeights(); + if (mShapeEditTool == ShapeEditTool_Drag) + paged->resetAllAlteredHeights(); } if (mBrushShape == CSVWidget::BrushShape_Point) @@ -373,45 +419,55 @@ void CSVRender::TerrainShapeMode::editTerrainShapeGrid(const std::pair CSMWorld::CellCoordinates cellCoords = CSMWorld::CellCoordinates::fromId(cellId).first; int x = CSMWorld::CellCoordinates::vertexGlobalToInCellCoords(vertexCoords.first); int y = CSMWorld::CellCoordinates::vertexGlobalToInCellCoords(vertexCoords.second); - if (mShapeEditTool == ShapeEditTool_Drag) alterHeight(cellCoords, x, y, mTotalDiffY); + if (mShapeEditTool == ShapeEditTool_Drag) + alterHeight(cellCoords, x, y, mTotalDiffY); if (mShapeEditTool == ShapeEditTool_PaintToRaise || mShapeEditTool == ShapeEditTool_PaintToLower) { alterHeight(cellCoords, x, y, mShapeEditToolStrength); - float smoothMultiplier = static_cast(CSMPrefs::get()["3D Scene Editing"]["landedit-post-smoothstrength"].toDouble()); - if (CSMPrefs::get()["3D Scene Editing"]["landedit-post-smoothpainting"].isTrue()) smoothHeight(cellCoords, x, y, mShapeEditToolStrength * smoothMultiplier); + float smoothMultiplier + = static_cast(CSMPrefs::get()["3D Scene Editing"]["landedit-post-smoothstrength"].toDouble()); + if (CSMPrefs::get()["3D Scene Editing"]["landedit-post-smoothpainting"].isTrue()) + smoothHeight(cellCoords, x, y, mShapeEditToolStrength * smoothMultiplier); } - if (mShapeEditTool == ShapeEditTool_Smooth) smoothHeight(cellCoords, x, y, mShapeEditToolStrength); - if (mShapeEditTool == ShapeEditTool_Flatten) flattenHeight(cellCoords, x, y, mShapeEditToolStrength, mTargetHeight); + if (mShapeEditTool == ShapeEditTool_Smooth) + smoothHeight(cellCoords, x, y, mShapeEditToolStrength); + if (mShapeEditTool == ShapeEditTool_Flatten) + flattenHeight(cellCoords, x, y, mShapeEditToolStrength, mTargetHeight); } if (mBrushShape == CSVWidget::BrushShape_Square) { - for(int i = vertexCoords.first - r; i <= vertexCoords.first + r; ++i) + for (int i = vertexCoords.first - r; i <= vertexCoords.first + r; ++i) { - for(int j = vertexCoords.second - r; j <= vertexCoords.second + r; ++j) + for (int j = vertexCoords.second - r; j <= vertexCoords.second + r; ++j) { std::string cellId = CSMWorld::CellCoordinates::vertexGlobalToCellId(std::make_pair(i, j)); CSMWorld::CellCoordinates cellCoords = CSMWorld::CellCoordinates::fromId(cellId).first; int x = CSMWorld::CellCoordinates::vertexGlobalToInCellCoords(i); int y = CSMWorld::CellCoordinates::vertexGlobalToInCellCoords(j); - if (mShapeEditTool == ShapeEditTool_Drag) alterHeight(cellCoords, x, y, mTotalDiffY); + if (mShapeEditTool == ShapeEditTool_Drag) + alterHeight(cellCoords, x, y, mTotalDiffY); if (mShapeEditTool == ShapeEditTool_PaintToRaise || mShapeEditTool == ShapeEditTool_PaintToLower) { alterHeight(cellCoords, x, y, mShapeEditToolStrength); - float smoothMultiplier = static_cast(CSMPrefs::get()["3D Scene Editing"]["landedit-post-smoothstrength"].toDouble()); - if (CSMPrefs::get()["3D Scene Editing"]["landedit-post-smoothpainting"].isTrue()) smoothHeight(cellCoords, x, y, mShapeEditToolStrength * smoothMultiplier); + float smoothMultiplier = static_cast( + CSMPrefs::get()["3D Scene Editing"]["landedit-post-smoothstrength"].toDouble()); + if (CSMPrefs::get()["3D Scene Editing"]["landedit-post-smoothpainting"].isTrue()) + smoothHeight(cellCoords, x, y, mShapeEditToolStrength * smoothMultiplier); } - if (mShapeEditTool == ShapeEditTool_Smooth) smoothHeight(cellCoords, x, y, mShapeEditToolStrength); - if (mShapeEditTool == ShapeEditTool_Flatten) flattenHeight(cellCoords, x, y, mShapeEditToolStrength, mTargetHeight); + if (mShapeEditTool == ShapeEditTool_Smooth) + smoothHeight(cellCoords, x, y, mShapeEditToolStrength); + if (mShapeEditTool == ShapeEditTool_Flatten) + flattenHeight(cellCoords, x, y, mShapeEditToolStrength, mTargetHeight); } } } if (mBrushShape == CSVWidget::BrushShape_Circle) { - for(int i = vertexCoords.first - r; i <= vertexCoords.first + r; ++i) + for (int i = vertexCoords.first - r; i <= vertexCoords.first + r; ++i) { - for(int j = vertexCoords.second - r; j <= vertexCoords.second + r; ++j) + for (int j = vertexCoords.second - r; j <= vertexCoords.second + r; ++j) { std::string cellId = CSMWorld::CellCoordinates::vertexGlobalToCellId(std::make_pair(i, j)); CSMWorld::CellCoordinates cellCoords = CSMWorld::CellCoordinates::fromId(cellId).first; @@ -419,46 +475,59 @@ void CSVRender::TerrainShapeMode::editTerrainShapeGrid(const std::pair int y = CSMWorld::CellCoordinates::vertexGlobalToInCellCoords(j); int distanceX = abs(i - vertexCoords.first); int distanceY = abs(j - vertexCoords.second); - float distance = sqrt(pow(distanceX, 2)+pow(distanceY, 2)); + float distance = sqrt(pow(distanceX, 2) + pow(distanceY, 2)); float smoothedByDistance = 0.0f; - if (mShapeEditTool == ShapeEditTool_Drag) smoothedByDistance = calculateBumpShape(distance, r, mTotalDiffY); - if (mShapeEditTool == ShapeEditTool_PaintToRaise || mShapeEditTool == ShapeEditTool_PaintToLower) smoothedByDistance = calculateBumpShape(distance, r, r + mShapeEditToolStrength); + if (mShapeEditTool == ShapeEditTool_Drag) + smoothedByDistance = calculateBumpShape(distance, r, mTotalDiffY); + if (mShapeEditTool == ShapeEditTool_PaintToRaise || mShapeEditTool == ShapeEditTool_PaintToLower) + smoothedByDistance = calculateBumpShape(distance, r, r + mShapeEditToolStrength); // Using floating-point radius here to prevent selecting too few vertices. if (distance <= mBrushSize / 2.0f) { - if (mShapeEditTool == ShapeEditTool_Drag) alterHeight(cellCoords, x, y, smoothedByDistance); + if (mShapeEditTool == ShapeEditTool_Drag) + alterHeight(cellCoords, x, y, smoothedByDistance); if (mShapeEditTool == ShapeEditTool_PaintToRaise || mShapeEditTool == ShapeEditTool_PaintToLower) { alterHeight(cellCoords, x, y, smoothedByDistance); - float smoothMultiplier = static_cast(CSMPrefs::get()["3D Scene Editing"]["landedit-post-smoothstrength"].toDouble()); - if (CSMPrefs::get()["3D Scene Editing"]["landedit-post-smoothpainting"].isTrue()) smoothHeight(cellCoords, x, y, mShapeEditToolStrength * smoothMultiplier); + float smoothMultiplier = static_cast( + CSMPrefs::get()["3D Scene Editing"]["landedit-post-smoothstrength"].toDouble()); + if (CSMPrefs::get()["3D Scene Editing"]["landedit-post-smoothpainting"].isTrue()) + smoothHeight(cellCoords, x, y, mShapeEditToolStrength * smoothMultiplier); } - if (mShapeEditTool == ShapeEditTool_Smooth) smoothHeight(cellCoords, x, y, mShapeEditToolStrength); - if (mShapeEditTool == ShapeEditTool_Flatten) flattenHeight(cellCoords, x, y, mShapeEditToolStrength, mTargetHeight); + if (mShapeEditTool == ShapeEditTool_Smooth) + smoothHeight(cellCoords, x, y, mShapeEditToolStrength); + if (mShapeEditTool == ShapeEditTool_Flatten) + flattenHeight(cellCoords, x, y, mShapeEditToolStrength, mTargetHeight); } } } } if (mBrushShape == CSVWidget::BrushShape_Custom) { - if(!mCustomBrushShape.empty()) + if (!mCustomBrushShape.empty()) { - for(auto const& value: mCustomBrushShape) + for (auto const& value : mCustomBrushShape) { - std::string cellId = CSMWorld::CellCoordinates::vertexGlobalToCellId(std::make_pair(vertexCoords.first + value.first, vertexCoords.second + value.second)); + std::string cellId = CSMWorld::CellCoordinates::vertexGlobalToCellId( + std::make_pair(vertexCoords.first + value.first, vertexCoords.second + value.second)); CSMWorld::CellCoordinates cellCoords = CSMWorld::CellCoordinates::fromId(cellId).first; int x = CSMWorld::CellCoordinates::vertexGlobalToInCellCoords(vertexCoords.first + value.first); int y = CSMWorld::CellCoordinates::vertexGlobalToInCellCoords(vertexCoords.second + value.second); - if (mShapeEditTool == ShapeEditTool_Drag) alterHeight(cellCoords, x, y, mTotalDiffY); + if (mShapeEditTool == ShapeEditTool_Drag) + alterHeight(cellCoords, x, y, mTotalDiffY); if (mShapeEditTool == ShapeEditTool_PaintToRaise || mShapeEditTool == ShapeEditTool_PaintToLower) { alterHeight(cellCoords, x, y, mShapeEditToolStrength); - float smoothMultiplier = static_cast(CSMPrefs::get()["3D Scene Editing"]["landedit-post-smoothstrength"].toDouble()); - if (CSMPrefs::get()["3D Scene Editing"]["landedit-post-smoothpainting"].isTrue()) smoothHeight(cellCoords, x, y, mShapeEditToolStrength * smoothMultiplier); + float smoothMultiplier = static_cast( + CSMPrefs::get()["3D Scene Editing"]["landedit-post-smoothstrength"].toDouble()); + if (CSMPrefs::get()["3D Scene Editing"]["landedit-post-smoothpainting"].isTrue()) + smoothHeight(cellCoords, x, y, mShapeEditToolStrength * smoothMultiplier); } - if (mShapeEditTool == ShapeEditTool_Smooth) smoothHeight(cellCoords, x, y, mShapeEditToolStrength); - if (mShapeEditTool == ShapeEditTool_Flatten) flattenHeight(cellCoords, x, y, mShapeEditToolStrength, mTargetHeight); + if (mShapeEditTool == ShapeEditTool_Smooth) + smoothHeight(cellCoords, x, y, mShapeEditToolStrength); + if (mShapeEditTool == ShapeEditTool_Flatten) + flattenHeight(cellCoords, x, y, mShapeEditToolStrength, mTargetHeight); } } } @@ -473,23 +542,24 @@ void CSVRender::TerrainShapeMode::setFlattenToolTargetHeight(const WorldspaceHit int inCellY = CSMWorld::CellCoordinates::vertexGlobalToInCellCoords(vertexCoords.second); CSMDoc::Document& document = getWorldspaceWidget().getDocument(); - CSMWorld::IdTable& landTable = dynamic_cast ( - *document.getData().getTableModel (CSMWorld::UniversalId::Type_Land)); + CSMWorld::IdTable& landTable + = dynamic_cast(*document.getData().getTableModel(CSMWorld::UniversalId::Type_Land)); int landshapeColumn = landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandHeightsIndex); - const CSMWorld::LandHeightsColumn::DataType landShapePointer = - landTable.data(landTable.getModelIndex(cellId, landshapeColumn)).value(); + const CSMWorld::LandHeightsColumn::DataType landShapePointer + = landTable.data(landTable.getModelIndex(cellId, landshapeColumn)) + .value(); mTargetHeight = landShapePointer[inCellY * ESM::Land::LAND_SIZE + inCellX]; } - -void CSVRender::TerrainShapeMode::alterHeight(const CSMWorld::CellCoordinates& cellCoords, int inCellX, int inCellY, float alteredHeight, bool useTool) +void CSVRender::TerrainShapeMode::alterHeight( + const CSMWorld::CellCoordinates& cellCoords, int inCellX, int inCellY, float alteredHeight, bool useTool) { std::string cellId = CSMWorld::CellCoordinates::generateId(cellCoords.getX(), cellCoords.getY()); if (!(allowLandShapeEditing(cellId, useTool) && (useTool || (isLandLoaded(cellId))))) return; - CSVRender::PagedWorldspaceWidget *paged = dynamic_cast (&getWorldspaceWidget()); + CSVRender::PagedWorldspaceWidget* paged = dynamic_cast(&getWorldspaceWidget()); if (!paged) return; @@ -513,75 +583,96 @@ void CSVRender::TerrainShapeMode::alterHeight(const CSMWorld::CellCoordinates& c osg::Vec3d distance = eye - mEditingPos; alteredHeight = alteredHeight * (distance.length() / 500); } - if (mShapeEditTool == ShapeEditTool_PaintToRaise) alteredHeight = *paged->getCellAlteredHeight(cellCoords, inCellX, inCellY) + alteredHeight; - if (mShapeEditTool == ShapeEditTool_PaintToLower) alteredHeight = *paged->getCellAlteredHeight(cellCoords, inCellX, inCellY) - alteredHeight; - if (mShapeEditTool == ShapeEditTool_Smooth) alteredHeight = *paged->getCellAlteredHeight(cellCoords, inCellX, inCellY) + alteredHeight; + if (mShapeEditTool == ShapeEditTool_PaintToRaise) + alteredHeight = *paged->getCellAlteredHeight(cellCoords, inCellX, inCellY) + alteredHeight; + if (mShapeEditTool == ShapeEditTool_PaintToLower) + alteredHeight = *paged->getCellAlteredHeight(cellCoords, inCellX, inCellY) - alteredHeight; + if (mShapeEditTool == ShapeEditTool_Smooth) + alteredHeight = *paged->getCellAlteredHeight(cellCoords, inCellX, inCellY) + alteredHeight; } if (inCellX != 0 && inCellY != 0 && inCellX != ESM::Land::LAND_SIZE - 1 && inCellY != ESM::Land::LAND_SIZE - 1) - paged->setCellAlteredHeight(cellCoords, inCellX, inCellY, alteredHeight); + paged->setCellAlteredHeight(cellCoords, inCellX, inCellY, alteredHeight); // Change values of cornering cells if ((inCellX == 0 && inCellY == 0) && (useTool || isLandLoaded(cellUpLeftId))) { - if(allowLandShapeEditing(cellUpLeftId, useTool) && allowLandShapeEditing(cellLeftId, useTool) && allowLandShapeEditing(cellUpId, useTool)) + if (allowLandShapeEditing(cellUpLeftId, useTool) && allowLandShapeEditing(cellLeftId, useTool) + && allowLandShapeEditing(cellUpId, useTool)) { CSMWorld::CellCoordinates cornerCellCoords = cellCoords.move(-1, -1); - if (useTool && std::find(mAlteredCells.begin(), mAlteredCells.end(), cornerCellCoords) == mAlteredCells.end()) - mAlteredCells.emplace_back(cornerCellCoords); - paged->setCellAlteredHeight(cornerCellCoords, ESM::Land::LAND_SIZE - 1, ESM::Land::LAND_SIZE - 1, alteredHeight); - } else return; + if (useTool + && std::find(mAlteredCells.begin(), mAlteredCells.end(), cornerCellCoords) == mAlteredCells.end()) + mAlteredCells.emplace_back(cornerCellCoords); + paged->setCellAlteredHeight( + cornerCellCoords, ESM::Land::LAND_SIZE - 1, ESM::Land::LAND_SIZE - 1, alteredHeight); + } + else + return; } else if ((inCellX == 0 && inCellY == ESM::Land::LAND_SIZE - 1) && (useTool || isLandLoaded(cellDownLeftId))) { - if (allowLandShapeEditing(cellDownLeftId, useTool) && allowLandShapeEditing(cellLeftId, useTool) && allowLandShapeEditing(cellDownId, useTool)) + if (allowLandShapeEditing(cellDownLeftId, useTool) && allowLandShapeEditing(cellLeftId, useTool) + && allowLandShapeEditing(cellDownId, useTool)) { CSMWorld::CellCoordinates cornerCellCoords = cellCoords.move(-1, 1); - if (useTool && std::find(mAlteredCells.begin(), mAlteredCells.end(), cornerCellCoords) == mAlteredCells.end()) - mAlteredCells.emplace_back(cornerCellCoords); + if (useTool + && std::find(mAlteredCells.begin(), mAlteredCells.end(), cornerCellCoords) == mAlteredCells.end()) + mAlteredCells.emplace_back(cornerCellCoords); paged->setCellAlteredHeight(cornerCellCoords, ESM::Land::LAND_SIZE - 1, 0, alteredHeight); - } else return; + } + else + return; } else if ((inCellX == ESM::Land::LAND_SIZE - 1 && inCellY == 0) && (useTool || isLandLoaded(cellUpRightId))) { - if (allowLandShapeEditing(cellUpRightId, useTool) && allowLandShapeEditing(cellRightId, useTool) && allowLandShapeEditing(cellUpId, useTool)) + if (allowLandShapeEditing(cellUpRightId, useTool) && allowLandShapeEditing(cellRightId, useTool) + && allowLandShapeEditing(cellUpId, useTool)) { CSMWorld::CellCoordinates cornerCellCoords = cellCoords.move(1, -1); - if (useTool && std::find(mAlteredCells.begin(), mAlteredCells.end(), cornerCellCoords) == mAlteredCells.end()) - mAlteredCells.emplace_back(cornerCellCoords); + if (useTool + && std::find(mAlteredCells.begin(), mAlteredCells.end(), cornerCellCoords) == mAlteredCells.end()) + mAlteredCells.emplace_back(cornerCellCoords); paged->setCellAlteredHeight(cornerCellCoords, 0, ESM::Land::LAND_SIZE - 1, alteredHeight); - } else return; + } + else + return; } - else if ((inCellX == ESM::Land::LAND_SIZE - 1 && inCellY == ESM::Land::LAND_SIZE - 1) && (useTool || isLandLoaded(cellDownRightId))) + else if ((inCellX == ESM::Land::LAND_SIZE - 1 && inCellY == ESM::Land::LAND_SIZE - 1) + && (useTool || isLandLoaded(cellDownRightId))) { - if(allowLandShapeEditing(cellDownRightId, useTool) && allowLandShapeEditing(cellRightId, useTool) && allowLandShapeEditing(cellDownId, useTool)) + if (allowLandShapeEditing(cellDownRightId, useTool) && allowLandShapeEditing(cellRightId, useTool) + && allowLandShapeEditing(cellDownId, useTool)) { CSMWorld::CellCoordinates cornerCellCoords = cellCoords.move(1, 1); - if (useTool && std::find(mAlteredCells.begin(), mAlteredCells.end(), cornerCellCoords) == mAlteredCells.end()) - mAlteredCells.emplace_back(cornerCellCoords); + if (useTool + && std::find(mAlteredCells.begin(), mAlteredCells.end(), cornerCellCoords) == mAlteredCells.end()) + mAlteredCells.emplace_back(cornerCellCoords); paged->setCellAlteredHeight(cornerCellCoords, 0, 0, alteredHeight); - } else return; + } + else + return; } // Change values of edging cells if ((inCellX == 0) && (useTool || isLandLoaded(cellLeftId))) { - if(allowLandShapeEditing(cellLeftId, useTool)) + if (allowLandShapeEditing(cellLeftId, useTool)) { CSMWorld::CellCoordinates edgeCellCoords = cellCoords.move(-1, 0); if (useTool && std::find(mAlteredCells.begin(), mAlteredCells.end(), edgeCellCoords) == mAlteredCells.end()) - mAlteredCells.emplace_back(edgeCellCoords); + mAlteredCells.emplace_back(edgeCellCoords); paged->setCellAlteredHeight(cellCoords, inCellX, inCellY, alteredHeight); paged->setCellAlteredHeight(edgeCellCoords, ESM::Land::LAND_SIZE - 1, inCellY, alteredHeight); } } if ((inCellY == 0) && (useTool || isLandLoaded(cellUpId))) { - if(allowLandShapeEditing(cellUpId, useTool)) + if (allowLandShapeEditing(cellUpId, useTool)) { CSMWorld::CellCoordinates edgeCellCoords = cellCoords.move(0, -1); if (useTool && std::find(mAlteredCells.begin(), mAlteredCells.end(), edgeCellCoords) == mAlteredCells.end()) - mAlteredCells.emplace_back(edgeCellCoords); + mAlteredCells.emplace_back(edgeCellCoords); paged->setCellAlteredHeight(cellCoords, inCellX, inCellY, alteredHeight); paged->setCellAlteredHeight(edgeCellCoords, inCellX, ESM::Land::LAND_SIZE - 1, alteredHeight); } @@ -589,41 +680,43 @@ void CSVRender::TerrainShapeMode::alterHeight(const CSMWorld::CellCoordinates& c if ((inCellX == ESM::Land::LAND_SIZE - 1) && (useTool || isLandLoaded(cellRightId))) { - if(allowLandShapeEditing(cellRightId, useTool)) + if (allowLandShapeEditing(cellRightId, useTool)) { CSMWorld::CellCoordinates edgeCellCoords = cellCoords.move(1, 0); if (useTool && std::find(mAlteredCells.begin(), mAlteredCells.end(), edgeCellCoords) == mAlteredCells.end()) - mAlteredCells.emplace_back(edgeCellCoords); + mAlteredCells.emplace_back(edgeCellCoords); paged->setCellAlteredHeight(cellCoords, inCellX, inCellY, alteredHeight); paged->setCellAlteredHeight(edgeCellCoords, 0, inCellY, alteredHeight); } } if ((inCellY == ESM::Land::LAND_SIZE - 1) && (useTool || isLandLoaded(cellDownId))) { - if(allowLandShapeEditing(cellDownId, useTool)) + if (allowLandShapeEditing(cellDownId, useTool)) { CSMWorld::CellCoordinates edgeCellCoords = cellCoords.move(0, 1); if (useTool && std::find(mAlteredCells.begin(), mAlteredCells.end(), edgeCellCoords) == mAlteredCells.end()) - mAlteredCells.emplace_back(edgeCellCoords); + mAlteredCells.emplace_back(edgeCellCoords); paged->setCellAlteredHeight(cellCoords, inCellX, inCellY, alteredHeight); paged->setCellAlteredHeight(edgeCellCoords, inCellX, 0, alteredHeight); } } - } -void CSVRender::TerrainShapeMode::smoothHeight(const CSMWorld::CellCoordinates& cellCoords, int inCellX, int inCellY, int toolStrength) +void CSVRender::TerrainShapeMode::smoothHeight( + const CSMWorld::CellCoordinates& cellCoords, int inCellX, int inCellY, int toolStrength) { - if (CSVRender::PagedWorldspaceWidget *paged = - dynamic_cast (&getWorldspaceWidget())) + if (CSVRender::PagedWorldspaceWidget* paged + = dynamic_cast(&getWorldspaceWidget())) { CSMDoc::Document& document = getWorldspaceWidget().getDocument(); - CSMWorld::IdTable& landTable = dynamic_cast ( - *document.getData().getTableModel (CSMWorld::UniversalId::Type_Land)); + CSMWorld::IdTable& landTable + = dynamic_cast(*document.getData().getTableModel(CSMWorld::UniversalId::Type_Land)); int landshapeColumn = landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandHeightsIndex); std::string cellId = CSMWorld::CellCoordinates::generateId(cellCoords.getX(), cellCoords.getY()); - const CSMWorld::LandHeightsColumn::DataType landShapePointer = landTable.data(landTable.getModelIndex(cellId, landshapeColumn)).value(); + const CSMWorld::LandHeightsColumn::DataType landShapePointer + = landTable.data(landTable.getModelIndex(cellId, landshapeColumn)) + .value(); // ### Variable naming key ### // Variables here hold either the real value, or the altered value of current edit. @@ -643,24 +736,30 @@ void CSVRender::TerrainShapeMode::smoothHeight(const CSMWorld::CellCoordinates& float downAlteredHeight = 0.0f; float upHeight = 0.0f; - if(allowLandShapeEditing(cellId)) + if (allowLandShapeEditing(cellId)) { - //Get key values for calculating average, handle cell edges, check for null pointers + // Get key values for calculating average, handle cell edges, check for null pointers if (inCellX == 0) { cellId = CSMWorld::CellCoordinates::generateId(cellCoords.getX() - 1, cellCoords.getY()); - const CSMWorld::LandHeightsColumn::DataType landLeftShapePointer = landTable.data(landTable.getModelIndex(cellId, landshapeColumn)).value(); + const CSMWorld::LandHeightsColumn::DataType landLeftShapePointer + = landTable.data(landTable.getModelIndex(cellId, landshapeColumn)) + .value(); leftHeight = landLeftShapePointer[inCellY * ESM::Land::LAND_SIZE + (ESM::Land::LAND_SIZE - 2)]; if (paged->getCellAlteredHeight(cellCoords.move(-1, 0), inCellX, ESM::Land::LAND_SIZE - 2)) - leftAlteredHeight = *paged->getCellAlteredHeight(cellCoords.move(-1, 0), ESM::Land::LAND_SIZE - 2, inCellY); + leftAlteredHeight + = *paged->getCellAlteredHeight(cellCoords.move(-1, 0), ESM::Land::LAND_SIZE - 2, inCellY); } if (inCellY == 0) { cellId = CSMWorld::CellCoordinates::generateId(cellCoords.getX(), cellCoords.getY() - 1); - const CSMWorld::LandHeightsColumn::DataType landUpShapePointer = landTable.data(landTable.getModelIndex(cellId, landshapeColumn)).value(); + const CSMWorld::LandHeightsColumn::DataType landUpShapePointer + = landTable.data(landTable.getModelIndex(cellId, landshapeColumn)) + .value(); upHeight = landUpShapePointer[(ESM::Land::LAND_SIZE - 2) * ESM::Land::LAND_SIZE + inCellX]; if (paged->getCellAlteredHeight(cellCoords.move(0, -1), inCellX, ESM::Land::LAND_SIZE - 2)) - upAlteredHeight = *paged->getCellAlteredHeight(cellCoords.move(0, -1), inCellX, ESM::Land::LAND_SIZE - 2); + upAlteredHeight + = *paged->getCellAlteredHeight(cellCoords.move(0, -1), inCellX, ESM::Land::LAND_SIZE - 2); } if (inCellX > 0) { @@ -675,8 +774,9 @@ void CSVRender::TerrainShapeMode::smoothHeight(const CSMWorld::CellCoordinates& if (inCellX == ESM::Land::LAND_SIZE - 1) { cellId = CSMWorld::CellCoordinates::generateId(cellCoords.getX() + 1, cellCoords.getY()); - const CSMWorld::LandHeightsColumn::DataType landRightShapePointer = - landTable.data(landTable.getModelIndex(cellId, landshapeColumn)).value(); + const CSMWorld::LandHeightsColumn::DataType landRightShapePointer + = landTable.data(landTable.getModelIndex(cellId, landshapeColumn)) + .value(); rightHeight = landRightShapePointer[inCellY * ESM::Land::LAND_SIZE + 1]; if (paged->getCellAlteredHeight(cellCoords.move(1, 0), 1, inCellY)) { @@ -686,8 +786,9 @@ void CSVRender::TerrainShapeMode::smoothHeight(const CSMWorld::CellCoordinates& if (inCellY == ESM::Land::LAND_SIZE - 1) { cellId = CSMWorld::CellCoordinates::generateId(cellCoords.getX(), cellCoords.getY() + 1); - const CSMWorld::LandHeightsColumn::DataType landDownShapePointer = - landTable.data(landTable.getModelIndex(cellId, landshapeColumn)).value(); + const CSMWorld::LandHeightsColumn::DataType landDownShapePointer + = landTable.data(landTable.getModelIndex(cellId, landshapeColumn)) + .value(); downHeight = landDownShapePointer[1 * ESM::Land::LAND_SIZE + inCellX]; if (paged->getCellAlteredHeight(cellCoords.move(0, 1), inCellX, 1)) { @@ -697,31 +798,37 @@ void CSVRender::TerrainShapeMode::smoothHeight(const CSMWorld::CellCoordinates& if (inCellX < ESM::Land::LAND_SIZE - 1) { rightHeight = landShapePointer[inCellY * ESM::Land::LAND_SIZE + inCellX + 1]; - if(paged->getCellAlteredHeight(cellCoords, inCellX + 1, inCellY)) + if (paged->getCellAlteredHeight(cellCoords, inCellX + 1, inCellY)) rightAlteredHeight = *paged->getCellAlteredHeight(cellCoords, inCellX + 1, inCellY); } if (inCellY < ESM::Land::LAND_SIZE - 1) { downHeight = landShapePointer[(inCellY + 1) * ESM::Land::LAND_SIZE + inCellX]; - if(paged->getCellAlteredHeight(cellCoords, inCellX, inCellY + 1)) + if (paged->getCellAlteredHeight(cellCoords, inCellX, inCellY + 1)) downAlteredHeight = *paged->getCellAlteredHeight(cellCoords, inCellX, inCellY + 1); } - float averageHeight = (upHeight + downHeight + rightHeight + leftHeight + - upAlteredHeight + downAlteredHeight + rightAlteredHeight + leftAlteredHeight) / 4; - if ((thisHeight + thisAlteredHeight) != averageHeight) mAlteredCells.emplace_back(cellCoords); - if (toolStrength > abs(thisHeight + thisAlteredHeight - averageHeight)) toolStrength = abs(thisHeight + thisAlteredHeight - averageHeight); - if (thisHeight + thisAlteredHeight > averageHeight) alterHeight(cellCoords, inCellX, inCellY, - toolStrength); - if (thisHeight + thisAlteredHeight < averageHeight) alterHeight(cellCoords, inCellX, inCellY, + toolStrength); + float averageHeight = (upHeight + downHeight + rightHeight + leftHeight + upAlteredHeight + + downAlteredHeight + rightAlteredHeight + leftAlteredHeight) + / 4; + if ((thisHeight + thisAlteredHeight) != averageHeight) + mAlteredCells.emplace_back(cellCoords); + if (toolStrength > abs(thisHeight + thisAlteredHeight - averageHeight)) + toolStrength = abs(thisHeight + thisAlteredHeight - averageHeight); + if (thisHeight + thisAlteredHeight > averageHeight) + alterHeight(cellCoords, inCellX, inCellY, -toolStrength); + if (thisHeight + thisAlteredHeight < averageHeight) + alterHeight(cellCoords, inCellX, inCellY, +toolStrength); } } } -void CSVRender::TerrainShapeMode::flattenHeight(const CSMWorld::CellCoordinates& cellCoords, int inCellX, int inCellY, int toolStrength, int targetHeight) +void CSVRender::TerrainShapeMode::flattenHeight( + const CSMWorld::CellCoordinates& cellCoords, int inCellX, int inCellY, int toolStrength, int targetHeight) { CSMDoc::Document& document = getWorldspaceWidget().getDocument(); - CSMWorld::IdTable& landTable = dynamic_cast ( - *document.getData().getTableModel (CSMWorld::UniversalId::Type_Land)); + CSMWorld::IdTable& landTable + = dynamic_cast(*document.getData().getTableModel(CSMWorld::UniversalId::Type_Land)); int landshapeColumn = landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandHeightsIndex); float thisHeight = 0.0f; @@ -729,33 +836,37 @@ void CSVRender::TerrainShapeMode::flattenHeight(const CSMWorld::CellCoordinates& std::string cellId = CSMWorld::CellCoordinates::generateId(cellCoords.getX(), cellCoords.getY()); - if (CSVRender::PagedWorldspaceWidget *paged = - dynamic_cast (&getWorldspaceWidget())) + if (CSVRender::PagedWorldspaceWidget* paged + = dynamic_cast(&getWorldspaceWidget())) { if (!noCell(cellId) && !noLand(cellId)) { - const CSMWorld::LandHeightsColumn::DataType landShapePointer = - landTable.data(landTable.getModelIndex(cellId, landshapeColumn)).value(); + const CSMWorld::LandHeightsColumn::DataType landShapePointer + = landTable.data(landTable.getModelIndex(cellId, landshapeColumn)) + .value(); - if(paged->getCellAlteredHeight(cellCoords, inCellX, inCellY)) + if (paged->getCellAlteredHeight(cellCoords, inCellX, inCellY)) thisAlteredHeight = *paged->getCellAlteredHeight(cellCoords, inCellX, inCellY); thisHeight = landShapePointer[inCellY * ESM::Land::LAND_SIZE + inCellX]; } } - if (toolStrength > abs(thisHeight - targetHeight) && toolStrength > 8.0f) toolStrength = - abs(thisHeight - targetHeight); //Cut down excessive changes - if (thisHeight + thisAlteredHeight > targetHeight) alterHeight(cellCoords, inCellX, inCellY, thisAlteredHeight - toolStrength); - if (thisHeight + thisAlteredHeight < targetHeight) alterHeight(cellCoords, inCellX, inCellY, thisAlteredHeight + toolStrength); + if (toolStrength > abs(thisHeight - targetHeight) && toolStrength > 8.0f) + toolStrength = abs(thisHeight - targetHeight); // Cut down excessive changes + if (thisHeight + thisAlteredHeight > targetHeight) + alterHeight(cellCoords, inCellX, inCellY, thisAlteredHeight - toolStrength); + if (thisHeight + thisAlteredHeight < targetHeight) + alterHeight(cellCoords, inCellX, inCellY, thisAlteredHeight + toolStrength); } -void CSVRender::TerrainShapeMode::updateKeyHeightValues(const CSMWorld::CellCoordinates& cellCoords, int inCellX, int inCellY, float* thisHeight, - float* thisAlteredHeight, float* leftHeight, float* leftAlteredHeight, float* upHeight, float* upAlteredHeight, float* rightHeight, - float* rightAlteredHeight, float* downHeight, float* downAlteredHeight) +void CSVRender::TerrainShapeMode::updateKeyHeightValues(const CSMWorld::CellCoordinates& cellCoords, int inCellX, + int inCellY, float* thisHeight, float* thisAlteredHeight, float* leftHeight, float* leftAlteredHeight, + float* upHeight, float* upAlteredHeight, float* rightHeight, float* rightAlteredHeight, float* downHeight, + float* downAlteredHeight) { CSMDoc::Document& document = getWorldspaceWidget().getDocument(); - CSMWorld::IdTable& landTable = dynamic_cast ( - *document.getData().getTableModel (CSMWorld::UniversalId::Type_Land)); + CSMWorld::IdTable& landTable + = dynamic_cast(*document.getData().getTableModel(CSMWorld::UniversalId::Type_Land)); int landshapeColumn = landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandHeightsIndex); std::string cellId = CSMWorld::CellCoordinates::generateId(cellCoords.getX(), cellCoords.getY()); @@ -765,7 +876,7 @@ void CSVRender::TerrainShapeMode::updateKeyHeightValues(const CSMWorld::CellCoor std::string cellDownId = CSMWorld::CellCoordinates::generateId(cellCoords.getX(), cellCoords.getY() + 1); *thisHeight = 0.0f; // real + altered height - *thisAlteredHeight = 0.0f; // only altered height + *thisAlteredHeight = 0.0f; // only altered height *leftHeight = 0.0f; *leftAlteredHeight = 0.0f; *upHeight = 0.0f; @@ -775,60 +886,66 @@ void CSVRender::TerrainShapeMode::updateKeyHeightValues(const CSMWorld::CellCoor *downHeight = 0.0f; *downAlteredHeight = 0.0f; - if (CSVRender::PagedWorldspaceWidget *paged = - dynamic_cast (&getWorldspaceWidget())) + if (CSVRender::PagedWorldspaceWidget* paged + = dynamic_cast(&getWorldspaceWidget())) { if (!noCell(cellId) && !noLand(cellId)) { - const CSMWorld::LandHeightsColumn::DataType landShapePointer = - landTable.data(landTable.getModelIndex(cellId, landshapeColumn)).value(); + const CSMWorld::LandHeightsColumn::DataType landShapePointer + = landTable.data(landTable.getModelIndex(cellId, landshapeColumn)) + .value(); - if(paged->getCellAlteredHeight(cellCoords, inCellX, inCellY)) + if (paged->getCellAlteredHeight(cellCoords, inCellX, inCellY)) *thisAlteredHeight = *paged->getCellAlteredHeight(cellCoords, inCellX, inCellY); *thisHeight = landShapePointer[inCellY * ESM::Land::LAND_SIZE + inCellX] + *thisAlteredHeight; - // Default to the same value as thisHeight, which happens in the case of cell edge where next cell/land is not found, - // which is to prevent unnecessary action at limitHeightChange(). + // Default to the same value as thisHeight, which happens in the case of cell edge where next cell/land is + // not found, which is to prevent unnecessary action at limitHeightChange(). *leftHeight = *thisHeight; *upHeight = *thisHeight; *rightHeight = *thisHeight; *downHeight = *thisHeight; - //If at edge, get values from neighboring cell + // If at edge, get values from neighboring cell if (inCellX == 0) { - if(isLandLoaded(cellLeftId)) + if (isLandLoaded(cellLeftId)) { - const CSMWorld::LandHeightsColumn::DataType landLeftShapePointer = - landTable.data(landTable.getModelIndex(cellLeftId, landshapeColumn)).value(); + const CSMWorld::LandHeightsColumn::DataType landLeftShapePointer + = landTable.data(landTable.getModelIndex(cellLeftId, landshapeColumn)) + .value(); *leftHeight = landLeftShapePointer[inCellY * ESM::Land::LAND_SIZE + (ESM::Land::LAND_SIZE - 2)]; if (paged->getCellAlteredHeight(cellCoords.move(-1, 0), ESM::Land::LAND_SIZE - 2, inCellY)) { - *leftAlteredHeight = *paged->getCellAlteredHeight(cellCoords.move(-1, 0), ESM::Land::LAND_SIZE - 2, inCellY); + *leftAlteredHeight + = *paged->getCellAlteredHeight(cellCoords.move(-1, 0), ESM::Land::LAND_SIZE - 2, inCellY); *leftHeight += *leftAlteredHeight; } } } if (inCellY == 0) { - if(isLandLoaded(cellUpId)) + if (isLandLoaded(cellUpId)) { - const CSMWorld::LandHeightsColumn::DataType landUpShapePointer = - landTable.data(landTable.getModelIndex(cellUpId, landshapeColumn)).value(); + const CSMWorld::LandHeightsColumn::DataType landUpShapePointer + = landTable.data(landTable.getModelIndex(cellUpId, landshapeColumn)) + .value(); *upHeight = landUpShapePointer[(ESM::Land::LAND_SIZE - 2) * ESM::Land::LAND_SIZE + inCellX]; - if (paged->getCellAlteredHeight(cellCoords.move(0,-1), inCellX, ESM::Land::LAND_SIZE - 2)) + if (paged->getCellAlteredHeight(cellCoords.move(0, -1), inCellX, ESM::Land::LAND_SIZE - 2)) { - *upAlteredHeight = *paged->getCellAlteredHeight(cellCoords.move(0, -1), inCellX, ESM::Land::LAND_SIZE - 2); + *upAlteredHeight + = *paged->getCellAlteredHeight(cellCoords.move(0, -1), inCellX, ESM::Land::LAND_SIZE - 2); *upHeight += *upAlteredHeight; } } } if (inCellX == ESM::Land::LAND_SIZE - 1) { - if(isLandLoaded(cellRightId)) + if (isLandLoaded(cellRightId)) { - const CSMWorld::LandHeightsColumn::DataType landRightShapePointer = - landTable.data(landTable.getModelIndex(cellRightId, landshapeColumn)).value(); + const CSMWorld::LandHeightsColumn::DataType landRightShapePointer + = landTable.data(landTable.getModelIndex(cellRightId, landshapeColumn)) + .value(); *rightHeight = landRightShapePointer[inCellY * ESM::Land::LAND_SIZE + 1]; if (paged->getCellAlteredHeight(cellCoords.move(1, 0), 1, inCellY)) { @@ -839,10 +956,11 @@ void CSVRender::TerrainShapeMode::updateKeyHeightValues(const CSMWorld::CellCoor } if (inCellY == ESM::Land::LAND_SIZE - 1) { - if(isLandLoaded(cellDownId)) + if (isLandLoaded(cellDownId)) { - const CSMWorld::LandHeightsColumn::DataType landDownShapePointer = - landTable.data(landTable.getModelIndex(cellDownId, landshapeColumn)).value(); + const CSMWorld::LandHeightsColumn::DataType landDownShapePointer + = landTable.data(landTable.getModelIndex(cellDownId, landshapeColumn)) + .value(); *downHeight = landDownShapePointer[ESM::Land::LAND_SIZE + inCellX]; if (paged->getCellAlteredHeight(cellCoords.move(0, 1), inCellX, 1)) { @@ -852,7 +970,7 @@ void CSVRender::TerrainShapeMode::updateKeyHeightValues(const CSMWorld::CellCoor } } - //If not at edge, get values from the same cell + // If not at edge, get values from the same cell if (inCellX != 0) { *leftHeight = landShapePointer[inCellY * ESM::Land::LAND_SIZE + inCellX - 1]; @@ -881,18 +999,18 @@ void CSVRender::TerrainShapeMode::updateKeyHeightValues(const CSMWorld::CellCoor *downAlteredHeight = *paged->getCellAlteredHeight(cellCoords, inCellX, inCellY + 1); *downHeight += *downAlteredHeight; } - } } } -void CSVRender::TerrainShapeMode::compareAndLimit(const CSMWorld::CellCoordinates& cellCoords, int inCellX, int inCellY, float* limitedAlteredHeightXAxis, float* limitedAlteredHeightYAxis, bool* steepnessIsWithinLimits) +void CSVRender::TerrainShapeMode::compareAndLimit(const CSMWorld::CellCoordinates& cellCoords, int inCellX, int inCellY, + float* limitedAlteredHeightXAxis, float* limitedAlteredHeightYAxis, bool* steepnessIsWithinLimits) { if (limitedAlteredHeightXAxis) { if (limitedAlteredHeightYAxis) { - if(std::abs(*limitedAlteredHeightXAxis) >= std::abs(*limitedAlteredHeightYAxis)) + if (std::abs(*limitedAlteredHeightXAxis) >= std::abs(*limitedAlteredHeightYAxis)) { alterHeight(cellCoords, inCellX, inCellY, *limitedAlteredHeightXAxis, false); *steepnessIsWithinLimits = false; @@ -919,7 +1037,8 @@ void CSVRender::TerrainShapeMode::compareAndLimit(const CSMWorld::CellCoordinate bool CSVRender::TerrainShapeMode::limitAlteredHeights(const CSMWorld::CellCoordinates& cellCoords, bool reverseMode) { CSMDoc::Document& document = getWorldspaceWidget().getDocument(); - CSMWorld::IdTable& landTable = dynamic_cast (*document.getData().getTableModel(CSMWorld::UniversalId::Type_Land)); + CSMWorld::IdTable& landTable + = dynamic_cast(*document.getData().getTableModel(CSMWorld::UniversalId::Type_Land)); int landshapeColumn = landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandHeightsIndex); std::string cellId = CSMWorld::CellCoordinates::generateId(cellCoords.getX(), cellCoords.getY()); @@ -929,8 +1048,9 @@ bool CSVRender::TerrainShapeMode::limitAlteredHeights(const CSMWorld::CellCoordi if (isLandLoaded(cellId)) { - const CSMWorld::LandHeightsColumn::DataType landShapePointer = - landTable.data(landTable.getModelIndex(cellId, landshapeColumn)).value(); + const CSMWorld::LandHeightsColumn::DataType landShapePointer + = landTable.data(landTable.getModelIndex(cellId, landshapeColumn)) + .value(); float thisHeight = 0.0f; float thisAlteredHeight = 0.0f; @@ -945,58 +1065,70 @@ bool CSVRender::TerrainShapeMode::limitAlteredHeights(const CSMWorld::CellCoordi if (!reverseMode) { - for(int inCellY = 0; inCellY < ESM::Land::LAND_SIZE; ++inCellY) + for (int inCellY = 0; inCellY < ESM::Land::LAND_SIZE; ++inCellY) { - for(int inCellX = 0; inCellX < ESM::Land::LAND_SIZE; ++inCellX) + for (int inCellX = 0; inCellX < ESM::Land::LAND_SIZE; ++inCellX) { std::unique_ptr limitedAlteredHeightXAxis(nullptr); std::unique_ptr limitedAlteredHeightYAxis(nullptr); - updateKeyHeightValues(cellCoords, inCellX, inCellY, &thisHeight, &thisAlteredHeight, &leftHeight, &leftAlteredHeight, - &upHeight, &upAlteredHeight, &rightHeight, &rightAlteredHeight, &downHeight, &downAlteredHeight); + updateKeyHeightValues(cellCoords, inCellX, inCellY, &thisHeight, &thisAlteredHeight, &leftHeight, + &leftAlteredHeight, &upHeight, &upAlteredHeight, &rightHeight, &rightAlteredHeight, &downHeight, + &downAlteredHeight); // Check for height limits on x-axis if (leftHeight - thisHeight > limitHeightChange) - limitedAlteredHeightXAxis = std::make_unique(leftHeight - limitHeightChange - (thisHeight - thisAlteredHeight)); + limitedAlteredHeightXAxis = std::make_unique( + leftHeight - limitHeightChange - (thisHeight - thisAlteredHeight)); else if (leftHeight - thisHeight < -limitHeightChange) - limitedAlteredHeightXAxis = std::make_unique(leftHeight + limitHeightChange - (thisHeight - thisAlteredHeight)); + limitedAlteredHeightXAxis = std::make_unique( + leftHeight + limitHeightChange - (thisHeight - thisAlteredHeight)); // Check for height limits on y-axis if (upHeight - thisHeight > limitHeightChange) - limitedAlteredHeightYAxis = std::make_unique(upHeight - limitHeightChange - (thisHeight - thisAlteredHeight)); + limitedAlteredHeightYAxis + = std::make_unique(upHeight - limitHeightChange - (thisHeight - thisAlteredHeight)); else if (upHeight - thisHeight < -limitHeightChange) - limitedAlteredHeightYAxis = std::make_unique(upHeight + limitHeightChange - (thisHeight - thisAlteredHeight)); + limitedAlteredHeightYAxis + = std::make_unique(upHeight + limitHeightChange - (thisHeight - thisAlteredHeight)); // Limit altered height value based on x or y, whichever is the smallest - compareAndLimit(cellCoords, inCellX, inCellY, limitedAlteredHeightXAxis.get(), limitedAlteredHeightYAxis.get(), &steepnessIsWithinLimits); + compareAndLimit(cellCoords, inCellX, inCellY, limitedAlteredHeightXAxis.get(), + limitedAlteredHeightYAxis.get(), &steepnessIsWithinLimits); } } } if (reverseMode) { - for(int inCellY = ESM::Land::LAND_SIZE - 1; inCellY >= 0; --inCellY) + for (int inCellY = ESM::Land::LAND_SIZE - 1; inCellY >= 0; --inCellY) { - for(int inCellX = ESM::Land::LAND_SIZE - 1; inCellX >= 0; --inCellX) + for (int inCellX = ESM::Land::LAND_SIZE - 1; inCellX >= 0; --inCellX) { std::unique_ptr limitedAlteredHeightXAxis(nullptr); std::unique_ptr limitedAlteredHeightYAxis(nullptr); - updateKeyHeightValues(cellCoords, inCellX, inCellY, &thisHeight, &thisAlteredHeight, &leftHeight, &leftAlteredHeight, - &upHeight, &upAlteredHeight, &rightHeight, &rightAlteredHeight, &downHeight, &downAlteredHeight); + updateKeyHeightValues(cellCoords, inCellX, inCellY, &thisHeight, &thisAlteredHeight, &leftHeight, + &leftAlteredHeight, &upHeight, &upAlteredHeight, &rightHeight, &rightAlteredHeight, &downHeight, + &downAlteredHeight); // Check for height limits on x-axis if (rightHeight - thisHeight > limitHeightChange) - limitedAlteredHeightXAxis = std::make_unique(rightHeight - limitHeightChange - (thisHeight - thisAlteredHeight)); + limitedAlteredHeightXAxis = std::make_unique( + rightHeight - limitHeightChange - (thisHeight - thisAlteredHeight)); else if (rightHeight - thisHeight < -limitHeightChange) - limitedAlteredHeightXAxis = std::make_unique(rightHeight + limitHeightChange - (thisHeight - thisAlteredHeight)); + limitedAlteredHeightXAxis = std::make_unique( + rightHeight + limitHeightChange - (thisHeight - thisAlteredHeight)); // Check for height limits on y-axis if (downHeight - thisHeight > limitHeightChange) - limitedAlteredHeightYAxis = std::make_unique(downHeight - limitHeightChange - (thisHeight - thisAlteredHeight)); + limitedAlteredHeightYAxis = std::make_unique( + downHeight - limitHeightChange - (thisHeight - thisAlteredHeight)); else if (downHeight - thisHeight < -limitHeightChange) - limitedAlteredHeightYAxis = std::make_unique(downHeight + limitHeightChange - (thisHeight - thisAlteredHeight)); + limitedAlteredHeightYAxis = std::make_unique( + downHeight + limitHeightChange - (thisHeight - thisAlteredHeight)); // Limit altered height value based on x or y, whichever is the smallest - compareAndLimit(cellCoords, inCellX, inCellY, limitedAlteredHeightXAxis.get(), limitedAlteredHeightYAxis.get(), &steepnessIsWithinLimits); + compareAndLimit(cellCoords, inCellX, inCellY, limitedAlteredHeightXAxis.get(), + limitedAlteredHeightYAxis.get(), &steepnessIsWithinLimits); } } } @@ -1006,7 +1138,8 @@ bool CSVRender::TerrainShapeMode::limitAlteredHeights(const CSMWorld::CellCoordi bool CSVRender::TerrainShapeMode::isInCellSelection(int globalSelectionX, int globalSelectionY) { - if (CSVRender::PagedWorldspaceWidget *paged = dynamic_cast (&getWorldspaceWidget())) + if (CSVRender::PagedWorldspaceWidget* paged + = dynamic_cast(&getWorldspaceWidget())) { std::pair vertexCoords = std::make_pair(globalSelectionX, globalSelectionY); std::string cellId = CSMWorld::CellCoordinates::vertexGlobalToCellId(vertexCoords); @@ -1015,9 +1148,11 @@ bool CSVRender::TerrainShapeMode::isInCellSelection(int globalSelectionX, int gl return false; } -void CSVRender::TerrainShapeMode::handleSelection(int globalSelectionX, int globalSelectionY, std::vector>* selections) +void CSVRender::TerrainShapeMode::handleSelection( + int globalSelectionX, int globalSelectionY, std::vector>* selections) { - if (isInCellSelection(globalSelectionX, globalSelectionY)) selections->emplace_back(globalSelectionX, globalSelectionY); + if (isInCellSelection(globalSelectionX, globalSelectionY)) + selections->emplace_back(globalSelectionX, globalSelectionY); else { int moduloX = globalSelectionX % (ESM::Land::LAND_SIZE - 1); @@ -1031,7 +1166,8 @@ void CSVRender::TerrainShapeMode::handleSelection(int globalSelectionX, int glob /* The northern and eastern edges don't belong to the current cell. - If the corresponding adjacent cell is not loaded, some special handling is necessary to select border vertices. + If the corresponding adjacent cell is not loaded, some special handling is necessary to select border + vertices. */ if (xIsAtCellBorder && yIsAtCellBorder) { @@ -1074,9 +1210,9 @@ void CSVRender::TerrainShapeMode::selectTerrainShapes(const std::pair& if (mBrushShape == CSVWidget::BrushShape_Square) { - for(int i = vertexCoords.first - r; i <= vertexCoords.first + r; ++i) + for (int i = vertexCoords.first - r; i <= vertexCoords.first + r; ++i) { - for(int j = vertexCoords.second - r; j <= vertexCoords.second + r; ++j) + for (int j = vertexCoords.second - r; j <= vertexCoords.second + r; ++j) { handleSelection(i, j, &selections); } @@ -1085,13 +1221,13 @@ void CSVRender::TerrainShapeMode::selectTerrainShapes(const std::pair& if (mBrushShape == CSVWidget::BrushShape_Circle) { - for(int i = vertexCoords.first - r; i <= vertexCoords.first + r; ++i) + for (int i = vertexCoords.first - r; i <= vertexCoords.first + r; ++i) { - for(int j = vertexCoords.second - r; j <= vertexCoords.second + r; ++j) + for (int j = vertexCoords.second - r; j <= vertexCoords.second + r; ++j) { int distanceX = abs(i - vertexCoords.first); int distanceY = abs(j - vertexCoords.second); - float distance = sqrt(pow(distanceX, 2)+pow(distanceY, 2)); + float distance = sqrt(pow(distanceX, 2) + pow(distanceY, 2)); // Using floating-point radius here to prevent selecting too few vertices. if (distance <= mBrushSize / 2.0f) @@ -1102,11 +1238,12 @@ void CSVRender::TerrainShapeMode::selectTerrainShapes(const std::pair& if (mBrushShape == CSVWidget::BrushShape_Custom) { - if(!mCustomBrushShape.empty()) + if (!mCustomBrushShape.empty()) { - for(auto const& value: mCustomBrushShape) + for (auto const& value : mCustomBrushShape) { - std::pair localVertexCoords (vertexCoords.first + value.first, vertexCoords.second + value.second); + std::pair localVertexCoords( + vertexCoords.first + value.first, vertexCoords.second + value.second); handleSelection(localVertexCoords.first, localVertexCoords.second, &selections); } } @@ -1129,42 +1266,44 @@ void CSVRender::TerrainShapeMode::selectTerrainShapes(const std::pair& mTerrainShapeSelection->toggleSelect(selections); } -void CSVRender::TerrainShapeMode::pushEditToCommand(const CSMWorld::LandHeightsColumn::DataType& newLandGrid, CSMDoc::Document& document, - CSMWorld::IdTable& landTable, const std::string& cellId) +void CSVRender::TerrainShapeMode::pushEditToCommand(const CSMWorld::LandHeightsColumn::DataType& newLandGrid, + CSMDoc::Document& document, CSMWorld::IdTable& landTable, const std::string& cellId) { QVariant changedLand; changedLand.setValue(newLandGrid); - QModelIndex index(landTable.getModelIndex (cellId, landTable.findColumnIndex (CSMWorld::Columns::ColumnId_LandHeightsIndex))); + QModelIndex index( + landTable.getModelIndex(cellId, landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandHeightsIndex))); QUndoStack& undoStack = document.getUndoStack(); - undoStack.push (new CSMWorld::ModifyCommand(landTable, index, changedLand)); + undoStack.push(new CSMWorld::ModifyCommand(landTable, index, changedLand)); } -void CSVRender::TerrainShapeMode::pushNormalsEditToCommand(const CSMWorld::LandNormalsColumn::DataType& newLandGrid, CSMDoc::Document& document, - CSMWorld::IdTable& landTable, const std::string& cellId) +void CSVRender::TerrainShapeMode::pushNormalsEditToCommand(const CSMWorld::LandNormalsColumn::DataType& newLandGrid, + CSMDoc::Document& document, CSMWorld::IdTable& landTable, const std::string& cellId) { QVariant changedLand; changedLand.setValue(newLandGrid); - QModelIndex index(landTable.getModelIndex (cellId, landTable.findColumnIndex (CSMWorld::Columns::ColumnId_LandNormalsIndex))); + QModelIndex index( + landTable.getModelIndex(cellId, landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandNormalsIndex))); QUndoStack& undoStack = document.getUndoStack(); - undoStack.push (new CSMWorld::ModifyCommand(landTable, index, changedLand)); + undoStack.push(new CSMWorld::ModifyCommand(landTable, index, changedLand)); } bool CSVRender::TerrainShapeMode::noCell(const std::string& cellId) { CSMDoc::Document& document = getWorldspaceWidget().getDocument(); const CSMWorld::IdCollection& cellCollection = document.getData().getCells(); - return cellCollection.searchId (cellId) == -1; + return cellCollection.searchId(cellId) == -1; } bool CSVRender::TerrainShapeMode::noLand(const std::string& cellId) { CSMDoc::Document& document = getWorldspaceWidget().getDocument(); const CSMWorld::IdCollection& landCollection = document.getData().getLand(); - return landCollection.searchId (cellId) == -1; + return landCollection.searchId(cellId) == -1; } bool CSVRender::TerrainShapeMode::noLandLoaded(const std::string& cellId) @@ -1176,17 +1315,18 @@ bool CSVRender::TerrainShapeMode::noLandLoaded(const std::string& cellId) bool CSVRender::TerrainShapeMode::isLandLoaded(const std::string& cellId) { - if (!noCell(cellId) && !noLand(cellId) && !noLandLoaded(cellId)) return true; + if (!noCell(cellId) && !noLand(cellId) && !noLandLoaded(cellId)) + return true; return false; } void CSVRender::TerrainShapeMode::createNewLandData(const CSMWorld::CellCoordinates& cellCoords) { CSMDoc::Document& document = getWorldspaceWidget().getDocument(); - CSMWorld::IdTable& landTable = dynamic_cast ( - *document.getData().getTableModel (CSMWorld::UniversalId::Type_Land)); - CSMWorld::IdTable& ltexTable = dynamic_cast ( - *document.getData().getTableModel (CSMWorld::UniversalId::Type_LandTextures)); + CSMWorld::IdTable& landTable + = dynamic_cast(*document.getData().getTableModel(CSMWorld::UniversalId::Type_Land)); + CSMWorld::IdTable& ltexTable + = dynamic_cast(*document.getData().getTableModel(CSMWorld::UniversalId::Type_LandTextures)); int landshapeColumn = landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandHeightsIndex); int landnormalsColumn = landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandNormalsIndex); @@ -1208,60 +1348,74 @@ void CSVRender::TerrainShapeMode::createNewLandData(const CSMWorld::CellCoordina float upCellSampleHeight = 0.0f; float downCellSampleHeight = 0.0f; - const CSMWorld::LandHeightsColumn::DataType landShapePointer = landTable.data(landTable.getModelIndex(cellId, landshapeColumn)).value(); - const CSMWorld::LandNormalsColumn::DataType landNormalsPointer = landTable.data(landTable.getModelIndex(cellId, landnormalsColumn)).value(); + const CSMWorld::LandHeightsColumn::DataType landShapePointer + = landTable.data(landTable.getModelIndex(cellId, landshapeColumn)) + .value(); + const CSMWorld::LandNormalsColumn::DataType landNormalsPointer + = landTable.data(landTable.getModelIndex(cellId, landnormalsColumn)) + .value(); CSMWorld::LandHeightsColumn::DataType landShapeNew(landShapePointer); CSMWorld::LandNormalsColumn::DataType landNormalsNew(landNormalsPointer); - if (CSVRender::PagedWorldspaceWidget *paged = - dynamic_cast (&getWorldspaceWidget())) + if (CSVRender::PagedWorldspaceWidget* paged + = dynamic_cast(&getWorldspaceWidget())) { if (isLandLoaded(cellLeftId)) { - const CSMWorld::LandHeightsColumn::DataType landLeftShapePointer = - landTable.data(landTable.getModelIndex(cellLeftId, landshapeColumn)).value(); + const CSMWorld::LandHeightsColumn::DataType landLeftShapePointer + = landTable.data(landTable.getModelIndex(cellLeftId, landshapeColumn)) + .value(); ++averageDivider; - leftCellSampleHeight = landLeftShapePointer[(ESM::Land::LAND_SIZE / 2) * ESM::Land::LAND_SIZE + ESM::Land::LAND_SIZE - 1]; - if(paged->getCellAlteredHeight(cellLeftCoords, ESM::Land::LAND_SIZE - 1, ESM::Land::LAND_SIZE / 2)) - leftCellSampleHeight += *paged->getCellAlteredHeight(cellLeftCoords, ESM::Land::LAND_SIZE - 1, ESM::Land::LAND_SIZE / 2); + leftCellSampleHeight + = landLeftShapePointer[(ESM::Land::LAND_SIZE / 2) * ESM::Land::LAND_SIZE + ESM::Land::LAND_SIZE - 1]; + if (paged->getCellAlteredHeight(cellLeftCoords, ESM::Land::LAND_SIZE - 1, ESM::Land::LAND_SIZE / 2)) + leftCellSampleHeight + += *paged->getCellAlteredHeight(cellLeftCoords, ESM::Land::LAND_SIZE - 1, ESM::Land::LAND_SIZE / 2); } if (isLandLoaded(cellRightId)) { - const CSMWorld::LandHeightsColumn::DataType landRightShapePointer = - landTable.data(landTable.getModelIndex(cellRightId, landshapeColumn)).value(); + const CSMWorld::LandHeightsColumn::DataType landRightShapePointer + = landTable.data(landTable.getModelIndex(cellRightId, landshapeColumn)) + .value(); ++averageDivider; rightCellSampleHeight = landRightShapePointer[(ESM::Land::LAND_SIZE / 2) * ESM::Land::LAND_SIZE]; - if(paged->getCellAlteredHeight(cellRightCoords, 0, ESM::Land::LAND_SIZE / 2)) + if (paged->getCellAlteredHeight(cellRightCoords, 0, ESM::Land::LAND_SIZE / 2)) rightCellSampleHeight += *paged->getCellAlteredHeight(cellRightCoords, 0, ESM::Land::LAND_SIZE / 2); } if (isLandLoaded(cellUpId)) { - const CSMWorld::LandHeightsColumn::DataType landUpShapePointer = - landTable.data(landTable.getModelIndex(cellUpId, landshapeColumn)).value(); + const CSMWorld::LandHeightsColumn::DataType landUpShapePointer + = landTable.data(landTable.getModelIndex(cellUpId, landshapeColumn)) + .value(); ++averageDivider; - upCellSampleHeight = landUpShapePointer[(ESM::Land::LAND_SIZE - 1) * ESM::Land::LAND_SIZE + (ESM::Land::LAND_SIZE / 2)]; - if(paged->getCellAlteredHeight(cellUpCoords, ESM::Land::LAND_SIZE / 2, ESM::Land::LAND_SIZE - 1)) - upCellSampleHeight += *paged->getCellAlteredHeight(cellUpCoords, ESM::Land::LAND_SIZE / 2, ESM::Land::LAND_SIZE - 1); + upCellSampleHeight + = landUpShapePointer[(ESM::Land::LAND_SIZE - 1) * ESM::Land::LAND_SIZE + (ESM::Land::LAND_SIZE / 2)]; + if (paged->getCellAlteredHeight(cellUpCoords, ESM::Land::LAND_SIZE / 2, ESM::Land::LAND_SIZE - 1)) + upCellSampleHeight + += *paged->getCellAlteredHeight(cellUpCoords, ESM::Land::LAND_SIZE / 2, ESM::Land::LAND_SIZE - 1); } if (isLandLoaded(cellDownId)) { - const CSMWorld::LandHeightsColumn::DataType landDownShapePointer = - landTable.data(landTable.getModelIndex(cellDownId, landshapeColumn)).value(); + const CSMWorld::LandHeightsColumn::DataType landDownShapePointer + = landTable.data(landTable.getModelIndex(cellDownId, landshapeColumn)) + .value(); ++averageDivider; downCellSampleHeight = landDownShapePointer[ESM::Land::LAND_SIZE / 2]; - if(paged->getCellAlteredHeight(cellDownCoords, ESM::Land::LAND_SIZE / 2, 0)) + if (paged->getCellAlteredHeight(cellDownCoords, ESM::Land::LAND_SIZE / 2, 0)) downCellSampleHeight += *paged->getCellAlteredHeight(cellDownCoords, ESM::Land::LAND_SIZE / 2, 0); } } - if (averageDivider > 0) defaultHeight = (leftCellSampleHeight + rightCellSampleHeight + upCellSampleHeight + downCellSampleHeight) / averageDivider; + if (averageDivider > 0) + defaultHeight = (leftCellSampleHeight + rightCellSampleHeight + upCellSampleHeight + downCellSampleHeight) + / averageDivider; - for(int i = 0; i < ESM::Land::LAND_SIZE; ++i) + for (int i = 0; i < ESM::Land::LAND_SIZE; ++i) { - for(int j = 0; j < ESM::Land::LAND_SIZE; ++j) + for (int j = 0; j < ESM::Land::LAND_SIZE; ++j) { landShapeNew[j * ESM::Land::LAND_SIZE + i] = defaultHeight; landNormalsNew[(j * ESM::Land::LAND_SIZE + i) * 3 + 0] = 0; @@ -1273,63 +1427,64 @@ void CSVRender::TerrainShapeMode::createNewLandData(const CSMWorld::CellCoordina changedShape.setValue(landShapeNew); QVariant changedNormals; changedNormals.setValue(landNormalsNew); - QModelIndex indexShape(landTable.getModelIndex (cellId, landTable.findColumnIndex (CSMWorld::Columns::ColumnId_LandHeightsIndex))); - QModelIndex indexNormal(landTable.getModelIndex (cellId, landTable.findColumnIndex (CSMWorld::Columns::ColumnId_LandNormalsIndex))); - document.getUndoStack().push (new CSMWorld::TouchLandCommand(landTable, ltexTable, cellId)); - document.getUndoStack().push (new CSMWorld::ModifyCommand(landTable, indexShape, changedShape)); - document.getUndoStack().push (new CSMWorld::ModifyCommand(landTable, indexNormal, changedNormals)); + QModelIndex indexShape( + landTable.getModelIndex(cellId, landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandHeightsIndex))); + QModelIndex indexNormal( + landTable.getModelIndex(cellId, landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandNormalsIndex))); + document.getUndoStack().push(new CSMWorld::TouchLandCommand(landTable, ltexTable, cellId)); + document.getUndoStack().push(new CSMWorld::ModifyCommand(landTable, indexShape, changedShape)); + document.getUndoStack().push(new CSMWorld::ModifyCommand(landTable, indexNormal, changedNormals)); } bool CSVRender::TerrainShapeMode::allowLandShapeEditing(const std::string& cellId, bool useTool) { CSMDoc::Document& document = getWorldspaceWidget().getDocument(); - CSMWorld::IdTable& landTable = dynamic_cast ( - *document.getData().getTableModel (CSMWorld::UniversalId::Type_Land)); - CSMWorld::IdTree& cellTable = dynamic_cast ( - *document.getData().getTableModel (CSMWorld::UniversalId::Type_Cells)); + CSMWorld::IdTable& landTable + = dynamic_cast(*document.getData().getTableModel(CSMWorld::UniversalId::Type_Land)); + CSMWorld::IdTree& cellTable + = dynamic_cast(*document.getData().getTableModel(CSMWorld::UniversalId::Type_Cells)); if (noCell(cellId)) { std::string mode = CSMPrefs::get()["3D Scene Editing"]["outside-landedit"].toString(); // target cell does not exist - if (mode=="Discard") + if (mode == "Discard") return false; - if (mode=="Create cell and land, then edit" && useTool) + if (mode == "Create cell and land, then edit" && useTool) { auto createCommand = std::make_unique(cellTable, cellId); - int parentIndex = cellTable.findColumnIndex (CSMWorld::Columns::ColumnId_Cell); - int index = cellTable.findNestedColumnIndex (parentIndex, CSMWorld::Columns::ColumnId_Interior); - createCommand->addNestedValue (parentIndex, index, false); - document.getUndoStack().push (createCommand.release()); + int parentIndex = cellTable.findColumnIndex(CSMWorld::Columns::ColumnId_Cell); + int index = cellTable.findNestedColumnIndex(parentIndex, CSMWorld::Columns::ColumnId_Interior); + createCommand->addNestedValue(parentIndex, index, false); + document.getUndoStack().push(createCommand.release()); - if (CSVRender::PagedWorldspaceWidget *paged = - dynamic_cast (&getWorldspaceWidget())) + if (CSVRender::PagedWorldspaceWidget* paged + = dynamic_cast(&getWorldspaceWidget())) { CSMWorld::CellSelection selection = paged->getCellSelection(); - selection.add (CSMWorld::CellCoordinates::fromId (cellId).first); - paged->setCellSelection (selection); + selection.add(CSMWorld::CellCoordinates::fromId(cellId).first); + paged->setCellSelection(selection); } } } - else if (CSVRender::PagedWorldspaceWidget *paged = - dynamic_cast (&getWorldspaceWidget())) + else if (CSVRender::PagedWorldspaceWidget* paged + = dynamic_cast(&getWorldspaceWidget())) { CSMWorld::CellSelection selection = paged->getCellSelection(); - if (!selection.has (CSMWorld::CellCoordinates::fromId (cellId).first)) + if (!selection.has(CSMWorld::CellCoordinates::fromId(cellId).first)) { // target cell exists, but is not shown - std::string mode = - CSMPrefs::get()["3D Scene Editing"]["outside-visible-landedit"].toString(); + std::string mode = CSMPrefs::get()["3D Scene Editing"]["outside-visible-landedit"].toString(); - if (mode=="Discard") + if (mode == "Discard") return false; - if (mode=="Show cell and edit" && useTool) + if (mode == "Show cell and edit" && useTool) { - selection.add (CSMWorld::CellCoordinates::fromId (cellId).first); - paged->setCellSelection (selection); + selection.add(CSMWorld::CellCoordinates::fromId(cellId).first); + paged->setCellSelection(selection); } } } @@ -1339,12 +1494,12 @@ bool CSVRender::TerrainShapeMode::allowLandShapeEditing(const std::string& cellI std::string mode = CSMPrefs::get()["3D Scene Editing"]["outside-landedit"].toString(); // target cell does not exist - if (mode=="Discard") + if (mode == "Discard") return false; - if (mode=="Create cell and land, then edit" && useTool) + if (mode == "Create cell and land, then edit" && useTool) { - document.getUndoStack().push (new CSMWorld::CreateCommand (landTable, cellId)); + document.getUndoStack().push(new CSMWorld::CreateCommand(landTable, cellId)); createNewLandData(CSMWorld::CellCoordinates::fromId(cellId).first); fixEdges(CSMWorld::CellCoordinates::fromId(cellId).first); sortAndLimitAlteredCells(); @@ -1354,10 +1509,10 @@ bool CSVRender::TerrainShapeMode::allowLandShapeEditing(const std::string& cellI { std::string mode = CSMPrefs::get()["3D Scene Editing"]["outside-landedit"].toString(); - if (mode=="Discard") + if (mode == "Discard") return false; - if (mode=="Create cell and land, then edit" && useTool) + if (mode == "Create cell and land, then edit" && useTool) { createNewLandData(CSMWorld::CellCoordinates::fromId(cellId).first); fixEdges(CSMWorld::CellCoordinates::fromId(cellId).first); @@ -1376,8 +1531,8 @@ bool CSVRender::TerrainShapeMode::allowLandShapeEditing(const std::string& cellI void CSVRender::TerrainShapeMode::fixEdges(CSMWorld::CellCoordinates cellCoords) { CSMDoc::Document& document = getWorldspaceWidget().getDocument(); - CSMWorld::IdTable& landTable = dynamic_cast ( - *document.getData().getTableModel (CSMWorld::UniversalId::Type_Land)); + CSMWorld::IdTable& landTable + = dynamic_cast(*document.getData().getTableModel(CSMWorld::UniversalId::Type_Land)); int landshapeColumn = landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandHeightsIndex); std::string cellId = CSMWorld::CellCoordinates::generateId(cellCoords.getX(), cellCoords.getY()); std::string cellLeftId = CSMWorld::CellCoordinates::generateId(cellCoords.getX() - 1, cellCoords.getY()); @@ -1385,42 +1540,55 @@ void CSVRender::TerrainShapeMode::fixEdges(CSMWorld::CellCoordinates cellCoords) std::string cellUpId = CSMWorld::CellCoordinates::generateId(cellCoords.getX(), cellCoords.getY() - 1); std::string cellDownId = CSMWorld::CellCoordinates::generateId(cellCoords.getX(), cellCoords.getY() + 1); - const CSMWorld::LandHeightsColumn::DataType landShapePointer = landTable.data(landTable.getModelIndex(cellId, landshapeColumn)).value(); - const CSMWorld::LandHeightsColumn::DataType landLeftShapePointer = landTable.data(landTable.getModelIndex(cellLeftId, landshapeColumn)).value(); - const CSMWorld::LandHeightsColumn::DataType landRightShapePointer = landTable.data(landTable.getModelIndex(cellRightId, landshapeColumn)).value(); - const CSMWorld::LandHeightsColumn::DataType landUpShapePointer = landTable.data(landTable.getModelIndex(cellUpId, landshapeColumn)).value(); - const CSMWorld::LandHeightsColumn::DataType landDownShapePointer = landTable.data(landTable.getModelIndex(cellDownId, landshapeColumn)).value(); + const CSMWorld::LandHeightsColumn::DataType landShapePointer + = landTable.data(landTable.getModelIndex(cellId, landshapeColumn)) + .value(); + const CSMWorld::LandHeightsColumn::DataType landLeftShapePointer + = landTable.data(landTable.getModelIndex(cellLeftId, landshapeColumn)) + .value(); + const CSMWorld::LandHeightsColumn::DataType landRightShapePointer + = landTable.data(landTable.getModelIndex(cellRightId, landshapeColumn)) + .value(); + const CSMWorld::LandHeightsColumn::DataType landUpShapePointer + = landTable.data(landTable.getModelIndex(cellUpId, landshapeColumn)) + .value(); + const CSMWorld::LandHeightsColumn::DataType landDownShapePointer + = landTable.data(landTable.getModelIndex(cellDownId, landshapeColumn)) + .value(); CSMWorld::LandHeightsColumn::DataType landShapeNew(landShapePointer); - for(int i = 0; i < ESM::Land::LAND_SIZE; ++i) + for (int i = 0; i < ESM::Land::LAND_SIZE; ++i) { - if (isLandLoaded(cellLeftId) && - landShapePointer[i * ESM::Land::LAND_SIZE] != landLeftShapePointer[i * ESM::Land::LAND_SIZE + ESM::Land::LAND_SIZE - 1]) - landShapeNew[i * ESM::Land::LAND_SIZE] = landLeftShapePointer[i * ESM::Land::LAND_SIZE + ESM::Land::LAND_SIZE - 1]; - if (isLandLoaded(cellRightId) && - landShapePointer[i * ESM::Land::LAND_SIZE + ESM::Land::LAND_SIZE - 1] != landRightShapePointer[i * ESM::Land::LAND_SIZE]) - landShapeNew[i * ESM::Land::LAND_SIZE + ESM::Land::LAND_SIZE - 1] = landRightShapePointer[i * ESM::Land::LAND_SIZE]; - if (isLandLoaded(cellUpId) && - landShapePointer[i] != landUpShapePointer[(ESM::Land::LAND_SIZE - 1) * ESM::Land::LAND_SIZE + i]) + if (isLandLoaded(cellLeftId) + && landShapePointer[i * ESM::Land::LAND_SIZE] + != landLeftShapePointer[i * ESM::Land::LAND_SIZE + ESM::Land::LAND_SIZE - 1]) + landShapeNew[i * ESM::Land::LAND_SIZE] + = landLeftShapePointer[i * ESM::Land::LAND_SIZE + ESM::Land::LAND_SIZE - 1]; + if (isLandLoaded(cellRightId) + && landShapePointer[i * ESM::Land::LAND_SIZE + ESM::Land::LAND_SIZE - 1] + != landRightShapePointer[i * ESM::Land::LAND_SIZE]) + landShapeNew[i * ESM::Land::LAND_SIZE + ESM::Land::LAND_SIZE - 1] + = landRightShapePointer[i * ESM::Land::LAND_SIZE]; + if (isLandLoaded(cellUpId) + && landShapePointer[i] != landUpShapePointer[(ESM::Land::LAND_SIZE - 1) * ESM::Land::LAND_SIZE + i]) landShapeNew[i] = landUpShapePointer[(ESM::Land::LAND_SIZE - 1) * ESM::Land::LAND_SIZE + i]; - if (isLandLoaded(cellDownId) && - landShapePointer[(ESM::Land::LAND_SIZE - 1) * ESM::Land::LAND_SIZE + i] != landDownShapePointer[i]) + if (isLandLoaded(cellDownId) + && landShapePointer[(ESM::Land::LAND_SIZE - 1) * ESM::Land::LAND_SIZE + i] != landDownShapePointer[i]) landShapeNew[(ESM::Land::LAND_SIZE - 1) * ESM::Land::LAND_SIZE + i] = landDownShapePointer[i]; } QVariant changedLand; changedLand.setValue(landShapeNew); - QModelIndex index(landTable.getModelIndex (cellId, landTable.findColumnIndex (CSMWorld::Columns::ColumnId_LandHeightsIndex))); + QModelIndex index( + landTable.getModelIndex(cellId, landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandHeightsIndex))); QUndoStack& undoStack = document.getUndoStack(); - undoStack.push (new CSMWorld::ModifyCommand(landTable, index, changedLand)); + undoStack.push(new CSMWorld::ModifyCommand(landTable, index, changedLand)); } -void CSVRender::TerrainShapeMode::dragMoveEvent (QDragMoveEvent *event) -{ -} +void CSVRender::TerrainShapeMode::dragMoveEvent(QDragMoveEvent* event) {} -void CSVRender::TerrainShapeMode::mouseMoveEvent (QMouseEvent *event) +void CSVRender::TerrainShapeMode::mouseMoveEvent(QMouseEvent* event) { WorldspaceHitResult hit = getWorldspaceWidget().mousePick(event->pos(), getInteractionMask()); if (hit.hit && mBrushDraw && !(mShapeEditTool == ShapeEditTool_Drag && mIsEditing)) @@ -1443,7 +1611,7 @@ void CSVRender::TerrainShapeMode::setBrushShape(CSVWidget::BrushShape brushShape { mBrushShape = brushShape; - //Set custom brush shape + // Set custom brush shape if (mBrushShape == CSVWidget::BrushShape_Custom && !mTerrainShapeSelection->getTerrainSelection().empty()) { auto terrainSelection = mTerrainShapeSelection->getTerrainSelection(); @@ -1451,7 +1619,7 @@ void CSVRender::TerrainShapeMode::setBrushShape(CSVWidget::BrushShape brushShape int selectionCenterY = 0; int selectionAmount = 0; - for(auto const& value: terrainSelection) + for (auto const& value : terrainSelection) { selectionCenterX = selectionCenterX + value.first; selectionCenterY = selectionCenterY + value.second; @@ -1465,8 +1633,8 @@ void CSVRender::TerrainShapeMode::setBrushShape(CSVWidget::BrushShape brushShape } mCustomBrushShape.clear(); - std::pair differentialPos {}; - for(auto const& value: terrainSelection) + std::pair differentialPos{}; + for (auto const& value : terrainSelection) { differentialPos.first = value.first - selectionCenterX; differentialPos.second = value.second - selectionCenterY; diff --git a/apps/opencs/view/render/terrainshapemode.hpp b/apps/opencs/view/render/terrainshapemode.hpp index 0497f24da9..ed3cfa2f99 100644 --- a/apps/opencs/view/render/terrainshapemode.hpp +++ b/apps/opencs/view/render/terrainshapemode.hpp @@ -3,16 +3,16 @@ #include "editmode.hpp" -#include #include +#include -#include #include +#include #ifndef Q_MOC_RUN #include "../../model/doc/document.hpp" -#include "../../model/world/idtable.hpp" #include "../../model/world/columnimp.hpp" +#include "../../model/world/idtable.hpp" #include "../widget/brushshapes.hpp" #endif @@ -38,165 +38,168 @@ namespace CSVRender { Q_OBJECT - public: - - enum InteractionType - { - InteractionType_PrimaryEdit, - InteractionType_PrimarySelect, - InteractionType_SecondaryEdit, - InteractionType_SecondarySelect, - InteractionType_None - }; + public: + enum InteractionType + { + InteractionType_PrimaryEdit, + InteractionType_PrimarySelect, + InteractionType_SecondaryEdit, + InteractionType_SecondarySelect, + InteractionType_None + }; - enum ShapeEditTool - { - ShapeEditTool_Drag = 0, - ShapeEditTool_PaintToRaise = 1, - ShapeEditTool_PaintToLower = 2, - ShapeEditTool_Smooth = 3, - ShapeEditTool_Flatten = 4 - }; + enum ShapeEditTool + { + ShapeEditTool_Drag = 0, + ShapeEditTool_PaintToRaise = 1, + ShapeEditTool_PaintToLower = 2, + ShapeEditTool_Smooth = 3, + ShapeEditTool_Flatten = 4 + }; - /// Editmode for terrain shape grid - TerrainShapeMode(WorldspaceWidget*, osg::Group* parentNode, QWidget* parent = nullptr); + /// Editmode for terrain shape grid + TerrainShapeMode(WorldspaceWidget*, osg::Group* parentNode, QWidget* parent = nullptr); - void primaryOpenPressed (const WorldspaceHitResult& hit) override; + void primaryOpenPressed(const WorldspaceHitResult& hit) override; - /// Create single command for one-click shape editing - void primaryEditPressed (const WorldspaceHitResult& hit) override; + /// Create single command for one-click shape editing + void primaryEditPressed(const WorldspaceHitResult& hit) override; - /// Open brush settings window - void primarySelectPressed(const WorldspaceHitResult&) override; + /// Open brush settings window + void primarySelectPressed(const WorldspaceHitResult&) override; - void secondarySelectPressed(const WorldspaceHitResult&) override; + void secondarySelectPressed(const WorldspaceHitResult&) override; - void activate(CSVWidget::SceneToolbar*) override; - void deactivate(CSVWidget::SceneToolbar*) override; + void activate(CSVWidget::SceneToolbar*) override; + void deactivate(CSVWidget::SceneToolbar*) override; - /// Start shape editing command macro - bool primaryEditStartDrag (const QPoint& pos) override; + /// Start shape editing command macro + bool primaryEditStartDrag(const QPoint& pos) override; - bool secondaryEditStartDrag (const QPoint& pos) override; - bool primarySelectStartDrag (const QPoint& pos) override; - bool secondarySelectStartDrag (const QPoint& pos) override; + bool secondaryEditStartDrag(const QPoint& pos) override; + bool primarySelectStartDrag(const QPoint& pos) override; + bool secondarySelectStartDrag(const QPoint& pos) override; - /// Handle shape edit behavior during dragging - void drag (const QPoint& pos, int diffX, int diffY, double speedFactor) override; + /// Handle shape edit behavior during dragging + void drag(const QPoint& pos, int diffX, int diffY, double speedFactor) override; - /// End shape editing command macro - void dragCompleted(const QPoint& pos) override; + /// End shape editing command macro + void dragCompleted(const QPoint& pos) override; - /// Cancel shape editing, and reset all pending changes - void dragAborted() override; + /// Cancel shape editing, and reset all pending changes + void dragAborted() override; - void dragWheel (int diff, double speedFactor) override; - void dragMoveEvent (QDragMoveEvent *event) override; - void mouseMoveEvent (QMouseEvent *event) override; + void dragWheel(int diff, double speedFactor) override; + void dragMoveEvent(QDragMoveEvent* event) override; + void mouseMoveEvent(QMouseEvent* event) override; - std::shared_ptr getTerrainSelection(); + std::shared_ptr getTerrainSelection(); - private: + private: + /// Remove duplicates and sort mAlteredCells, then limitAlteredHeights forward and reverse + void sortAndLimitAlteredCells(); - /// Remove duplicates and sort mAlteredCells, then limitAlteredHeights forward and reverse - void sortAndLimitAlteredCells(); + /// Reset everything in the current edit + void clearTransientEdits(); - /// Reset everything in the current edit - void clearTransientEdits(); + /// Move pending alteredHeights changes to omwgame/omwaddon -data + void applyTerrainEditChanges(); - /// Move pending alteredHeights changes to omwgame/omwaddon -data - void applyTerrainEditChanges(); + /// Handle brush mechanics for shape editing + void editTerrainShapeGrid(const std::pair& vertexCoords, bool dragOperation); - /// Handle brush mechanics for shape editing - void editTerrainShapeGrid (const std::pair& vertexCoords, bool dragOperation); + /// Calculate height, when aiming for bump-shaped terrain change + float calculateBumpShape(float distance, int radius, float height); - /// Calculate height, when aiming for bump-shaped terrain change - float calculateBumpShape(float distance, int radius, float height); + /// set the target height for flatten tool + void setFlattenToolTargetHeight(const WorldspaceHitResult& hit); - /// set the target height for flatten tool - void setFlattenToolTargetHeight(const WorldspaceHitResult& hit); + /// Do a single height alteration for transient shape edit map + void alterHeight(const CSMWorld::CellCoordinates& cellCoords, int inCellX, int inCellY, float alteredHeight, + bool useTool = true); - /// Do a single height alteration for transient shape edit map - void alterHeight(const CSMWorld::CellCoordinates& cellCoords, int inCellX, int inCellY, float alteredHeight, bool useTool = true); + /// Do a single smoothing height alteration for transient shape edit map + void smoothHeight(const CSMWorld::CellCoordinates& cellCoords, int inCellX, int inCellY, int toolStrength); - /// Do a single smoothing height alteration for transient shape edit map - void smoothHeight(const CSMWorld::CellCoordinates& cellCoords, int inCellX, int inCellY, int toolStrength); + /// Do a single flattening height alteration for transient shape edit map + void flattenHeight( + const CSMWorld::CellCoordinates& cellCoords, int inCellX, int inCellY, int toolStrength, int targetHeight); - /// Do a single flattening height alteration for transient shape edit map - void flattenHeight(const CSMWorld::CellCoordinates& cellCoords, int inCellX, int inCellY, int toolStrength, int targetHeight); + /// Get altered height values around one vertex + void updateKeyHeightValues(const CSMWorld::CellCoordinates& cellCoords, int inCellX, int inCellY, + float* thisHeight, float* thisAlteredHeight, float* leftHeight, float* leftAlteredHeight, float* upHeight, + float* upAlteredHeight, float* rightHeight, float* rightAlteredHeight, float* downHeight, + float* downAlteredHeight); - /// Get altered height values around one vertex - void updateKeyHeightValues(const CSMWorld::CellCoordinates& cellCoords, int inCellX, int inCellY, float* thisHeight, - float* thisAlteredHeight, float* leftHeight, float* leftAlteredHeight, float* upHeight, float* upAlteredHeight, - float* rightHeight, float* rightAlteredHeight, float* downHeight, float* downAlteredHeight); + /// Limit steepness based on either X or Y and return false if steepness is limited + void compareAndLimit(const CSMWorld::CellCoordinates& cellCoords, int inCellX, int inCellY, + float* limitedAlteredHeightXAxis, float* limitedAlteredHeightYAxis, bool* steepnessIsWithinLimits); - ///Limit steepness based on either X or Y and return false if steepness is limited - void compareAndLimit(const CSMWorld::CellCoordinates& cellCoords, int inCellX, int inCellY, float* limitedAlteredHeightXAxis, - float* limitedAlteredHeightYAxis, bool* steepnessIsWithinLimits); + /// Check that the edit doesn't break save format limits, fix if necessary, return true if slope steepness is + /// within limits + bool limitAlteredHeights(const CSMWorld::CellCoordinates& cellCoords, bool reverseMode = false); - /// Check that the edit doesn't break save format limits, fix if necessary, return true if slope steepness is within limits - bool limitAlteredHeights(const CSMWorld::CellCoordinates& cellCoords, bool reverseMode = false); + /// Check if global selection coordinate belongs to cell in view + bool isInCellSelection(int globalSelectionX, int globalSelectionY); - /// Check if global selection coordinate belongs to cell in view - bool isInCellSelection(int globalSelectionX, int globalSelectionY); + /// Select vertex at global selection coordinate + void handleSelection(int globalSelectionX, int globalSelectionY, std::vector>* selections); - /// Select vertex at global selection coordinate - void handleSelection(int globalSelectionX, int globalSelectionY, std::vector>* selections); + /// Handle brush mechanics for terrain shape selection + void selectTerrainShapes(const std::pair& vertexCoords, unsigned char selectMode); - /// Handle brush mechanics for terrain shape selection - void selectTerrainShapes (const std::pair& vertexCoords, unsigned char selectMode); + /// Push terrain shape edits to command macro + void pushEditToCommand(const CSMWorld::LandHeightsColumn::DataType& newLandGrid, CSMDoc::Document& document, + CSMWorld::IdTable& landTable, const std::string& cellId); - /// Push terrain shape edits to command macro - void pushEditToCommand (const CSMWorld::LandHeightsColumn::DataType& newLandGrid, CSMDoc::Document& document, - CSMWorld::IdTable& landTable, const std::string& cellId); + /// Push land normals edits to command macro + void pushNormalsEditToCommand(const CSMWorld::LandNormalsColumn::DataType& newLandGrid, + CSMDoc::Document& document, CSMWorld::IdTable& landTable, const std::string& cellId); - /// Push land normals edits to command macro - void pushNormalsEditToCommand(const CSMWorld::LandNormalsColumn::DataType& newLandGrid, CSMDoc::Document& document, - CSMWorld::IdTable& landTable, const std::string& cellId); + bool noCell(const std::string& cellId); - bool noCell(const std::string& cellId); + bool noLand(const std::string& cellId); - bool noLand(const std::string& cellId); + bool noLandLoaded(const std::string& cellId); - bool noLandLoaded(const std::string& cellId); + bool isLandLoaded(const std::string& cellId); - bool isLandLoaded(const std::string& cellId); + /// Create new blank height record and new normals, if there are valid adjancent cell, take sample points and + /// set the average height based on that + void createNewLandData(const CSMWorld::CellCoordinates& cellCoords); - /// Create new blank height record and new normals, if there are valid adjancent cell, take sample points and set the average height based on that - void createNewLandData(const CSMWorld::CellCoordinates& cellCoords); + /// Create new cell and land if needed, only user tools may ask for opening new cells (useTool == false is for + /// automated land changes) + bool allowLandShapeEditing(const std::string& textureFileName, bool useTool = true); - /// Create new cell and land if needed, only user tools may ask for opening new cells (useTool == false is for automated land changes) - bool allowLandShapeEditing(const std::string& textureFileName, bool useTool = true); + /// Bind the edging vertice to the values of the adjancent cells + void fixEdges(CSMWorld::CellCoordinates cellCoords); - /// Bind the edging vertice to the values of the adjancent cells - void fixEdges(CSMWorld::CellCoordinates cellCoords); + std::string mBrushTexture; + int mBrushSize = 1; + CSVWidget::BrushShape mBrushShape = CSVWidget::BrushShape_Point; + std::unique_ptr mBrushDraw; + std::vector> mCustomBrushShape; + CSVWidget::SceneToolShapeBrush* mShapeBrushScenetool = nullptr; + int mDragMode = InteractionType_None; + osg::Group* mParentNode; + bool mIsEditing = false; + std::shared_ptr mTerrainShapeSelection; + int mTotalDiffY = 0; + std::vector mAlteredCells; + osg::Vec3d mEditingPos; + int mShapeEditTool = ShapeEditTool_Drag; + int mShapeEditToolStrength = 8; + int mTargetHeight = 0; - std::string mBrushTexture; - int mBrushSize = 1; - CSVWidget::BrushShape mBrushShape = CSVWidget::BrushShape_Point; - std::unique_ptr mBrushDraw; - std::vector> mCustomBrushShape; - CSVWidget::SceneToolShapeBrush *mShapeBrushScenetool = nullptr; - int mDragMode = InteractionType_None; - osg::Group* mParentNode; - bool mIsEditing = false; - std::shared_ptr mTerrainShapeSelection; - int mTotalDiffY = 0; - std::vector mAlteredCells; - osg::Vec3d mEditingPos; - int mShapeEditTool = ShapeEditTool_Drag; - int mShapeEditToolStrength = 8; - int mTargetHeight = 0; + PagedWorldspaceWidget& getPagedWorldspaceWidget(); - PagedWorldspaceWidget& getPagedWorldspaceWidget(); - - public slots: - void setBrushSize(int brushSize); - void setBrushShape(CSVWidget::BrushShape brushShape); - void setShapeEditTool(int shapeEditTool); - void setShapeEditToolStrength(int shapeEditToolStrength); + public slots: + void setBrushSize(int brushSize); + void setBrushShape(CSVWidget::BrushShape brushShape); + void setShapeEditTool(int shapeEditTool); + void setShapeEditToolStrength(int shapeEditToolStrength); }; } - #endif diff --git a/apps/opencs/view/render/terrainstorage.cpp b/apps/opencs/view/render/terrainstorage.cpp index a3f1a91b62..a4da6754d0 100644 --- a/apps/opencs/view/render/terrainstorage.cpp +++ b/apps/opencs/view/render/terrainstorage.cpp @@ -2,10 +2,9 @@ #include - namespace CSVRender { - TerrainStorage::TerrainStorage(const CSMWorld::Data &data) + TerrainStorage::TerrainStorage(const CSMWorld::Data& data) : ESMTerrain::Storage(data.getResourceSystem()->getVFS()) , mData(data) { @@ -21,7 +20,8 @@ namespace CSVRender return nullptr; const ESM::Land& land = mData.getLand().getRecord(index).get(); - return new ESMTerrain::LandObject(&land, ESM::Land::DATA_VHGT | ESM::Land::DATA_VNML | ESM::Land::DATA_VCLR | ESM::Land::DATA_VTEX); + return new ESMTerrain::LandObject( + &land, ESM::Land::DATA_VHGT | ESM::Land::DATA_VNML | ESM::Land::DATA_VCLR | ESM::Land::DATA_VTEX); } const ESM::LandTexture* TerrainStorage::getLandTexture(int index, short plugin) @@ -35,7 +35,8 @@ namespace CSVRender void TerrainStorage::setAlteredHeight(int inCellX, int inCellY, float height) { - mAlteredHeight[inCellY*ESM::Land::LAND_SIZE + inCellX] = height - fmod(height, 8); //Limit to divisible by 8 to avoid cell seam breakage + mAlteredHeight[inCellY * ESM::Land::LAND_SIZE + inCellX] + = height - fmod(height, 8); // Limit to divisible by 8 to avoid cell seam breakage } void TerrainStorage::resetHeights() @@ -52,89 +53,92 @@ namespace CSVRender return height; const ESM::Land::LandData* landData = mData.getLand().getRecord(index).get().getLandData(ESM::Land::DATA_VHGT); - height = landData->mHeights[inCellY*ESM::Land::LAND_SIZE + inCellX]; - return mAlteredHeight[inCellY*ESM::Land::LAND_SIZE + inCellX] + height; + height = landData->mHeights[inCellY * ESM::Land::LAND_SIZE + inCellX]; + return mAlteredHeight[inCellY * ESM::Land::LAND_SIZE + inCellX] + height; } float* TerrainStorage::getAlteredHeight(int inCellX, int inCellY) { - return &mAlteredHeight[inCellY*ESM::Land::LAND_SIZE + inCellX]; + return &mAlteredHeight[inCellY * ESM::Land::LAND_SIZE + inCellX]; } - void TerrainStorage::getBounds(float &minX, float &maxX, float &minY, float &maxY) + void TerrainStorage::getBounds(float& minX, float& maxX, float& minY, float& maxY) { // not needed at the moment - this returns the bounds of the whole world, but we only edit individual cells throw std::runtime_error("getBounds not implemented"); } - int TerrainStorage::getThisHeight(int col, int row, const ESM::Land::LandData *heightData) const + int TerrainStorage::getThisHeight(int col, int row, const ESM::Land::LandData* heightData) const { - return heightData->mHeights[col*ESM::Land::LAND_SIZE + row] + - mAlteredHeight[static_cast(col*ESM::Land::LAND_SIZE + row)]; + return heightData->mHeights[col * ESM::Land::LAND_SIZE + row] + + mAlteredHeight[static_cast(col * ESM::Land::LAND_SIZE + row)]; } - int TerrainStorage::getLeftHeight(int col, int row, const ESM::Land::LandData *heightData) const + int TerrainStorage::getLeftHeight(int col, int row, const ESM::Land::LandData* heightData) const { - return heightData->mHeights[(col)*ESM::Land::LAND_SIZE + row - 1] + - mAlteredHeight[static_cast((col)*ESM::Land::LAND_SIZE + row - 1)]; + return heightData->mHeights[(col)*ESM::Land::LAND_SIZE + row - 1] + + mAlteredHeight[static_cast((col)*ESM::Land::LAND_SIZE + row - 1)]; } - int TerrainStorage::getRightHeight(int col, int row, const ESM::Land::LandData *heightData) const + int TerrainStorage::getRightHeight(int col, int row, const ESM::Land::LandData* heightData) const { - return heightData->mHeights[col*ESM::Land::LAND_SIZE + row + 1] + - mAlteredHeight[static_cast(col*ESM::Land::LAND_SIZE + row + 1)]; + return heightData->mHeights[col * ESM::Land::LAND_SIZE + row + 1] + + mAlteredHeight[static_cast(col * ESM::Land::LAND_SIZE + row + 1)]; } - int TerrainStorage::getUpHeight(int col, int row, const ESM::Land::LandData *heightData) const + int TerrainStorage::getUpHeight(int col, int row, const ESM::Land::LandData* heightData) const { - return heightData->mHeights[(col - 1)*ESM::Land::LAND_SIZE + row] + - mAlteredHeight[static_cast((col - 1)*ESM::Land::LAND_SIZE + row)]; + return heightData->mHeights[(col - 1) * ESM::Land::LAND_SIZE + row] + + mAlteredHeight[static_cast((col - 1) * ESM::Land::LAND_SIZE + row)]; } - int TerrainStorage::getDownHeight(int col, int row, const ESM::Land::LandData *heightData) const + int TerrainStorage::getDownHeight(int col, int row, const ESM::Land::LandData* heightData) const { - return heightData->mHeights[(col + 1)*ESM::Land::LAND_SIZE + row] + - mAlteredHeight[static_cast((col + 1)*ESM::Land::LAND_SIZE + row)]; + return heightData->mHeights[(col + 1) * ESM::Land::LAND_SIZE + row] + + mAlteredHeight[static_cast((col + 1) * ESM::Land::LAND_SIZE + row)]; } - int TerrainStorage::getHeightDifferenceToLeft(int col, int row, const ESM::Land::LandData *heightData) const + int TerrainStorage::getHeightDifferenceToLeft(int col, int row, const ESM::Land::LandData* heightData) const { return abs(getThisHeight(col, row, heightData) - getLeftHeight(col, row, heightData)); } - int TerrainStorage::getHeightDifferenceToRight(int col, int row, const ESM::Land::LandData *heightData) const + int TerrainStorage::getHeightDifferenceToRight(int col, int row, const ESM::Land::LandData* heightData) const { return abs(getThisHeight(col, row, heightData) - getRightHeight(col, row, heightData)); } - int TerrainStorage::getHeightDifferenceToUp(int col, int row, const ESM::Land::LandData *heightData) const + int TerrainStorage::getHeightDifferenceToUp(int col, int row, const ESM::Land::LandData* heightData) const { return abs(getThisHeight(col, row, heightData) - getUpHeight(col, row, heightData)); } - int TerrainStorage::getHeightDifferenceToDown(int col, int row, const ESM::Land::LandData *heightData) const + int TerrainStorage::getHeightDifferenceToDown(int col, int row, const ESM::Land::LandData* heightData) const { return abs(getThisHeight(col, row, heightData) - getDownHeight(col, row, heightData)); } - bool TerrainStorage::leftOrUpIsOverTheLimit(int col, int row, int heightWarningLimit, const ESM::Land::LandData *heightData) const + bool TerrainStorage::leftOrUpIsOverTheLimit( + int col, int row, int heightWarningLimit, const ESM::Land::LandData* heightData) const { - return getHeightDifferenceToLeft(col, row, heightData) >= heightWarningLimit || - getHeightDifferenceToUp(col, row, heightData) >= heightWarningLimit; + return getHeightDifferenceToLeft(col, row, heightData) >= heightWarningLimit + || getHeightDifferenceToUp(col, row, heightData) >= heightWarningLimit; } - bool TerrainStorage::rightOrDownIsOverTheLimit(int col, int row, int heightWarningLimit, const ESM::Land::LandData *heightData) const + bool TerrainStorage::rightOrDownIsOverTheLimit( + int col, int row, int heightWarningLimit, const ESM::Land::LandData* heightData) const { - return getHeightDifferenceToRight(col, row, heightData) >= heightWarningLimit || - getHeightDifferenceToDown(col, row, heightData) >= heightWarningLimit; + return getHeightDifferenceToRight(col, row, heightData) >= heightWarningLimit + || getHeightDifferenceToDown(col, row, heightData) >= heightWarningLimit; } - void TerrainStorage::adjustColor(int col, int row, const ESM::Land::LandData *heightData, osg::Vec4ub& color) const + void TerrainStorage::adjustColor(int col, int row, const ESM::Land::LandData* heightData, osg::Vec4ub& color) const { // Highlight broken height changes int heightWarningLimit = 1024; - if (((col > 0 && row > 0) && leftOrUpIsOverTheLimit(col, row, heightWarningLimit, heightData)) || - ((col < ESM::Land::LAND_SIZE - 1 && row < ESM::Land::LAND_SIZE - 1) && rightOrDownIsOverTheLimit(col, row, heightWarningLimit, heightData))) + if (((col > 0 && row > 0) && leftOrUpIsOverTheLimit(col, row, heightWarningLimit, heightData)) + || ((col < ESM::Land::LAND_SIZE - 1 && row < ESM::Land::LAND_SIZE - 1) + && rightOrDownIsOverTheLimit(col, row, heightWarningLimit, heightData))) { color.r() = 255; color.g() = 0; @@ -144,6 +148,6 @@ namespace CSVRender float TerrainStorage::getAlteredHeight(int col, int row) const { - return mAlteredHeight[static_cast(col*ESM::Land::LAND_SIZE + row)]; + return mAlteredHeight[static_cast(col * ESM::Land::LAND_SIZE + row)]; } } diff --git a/apps/opencs/view/render/terrainstorage.hpp b/apps/opencs/view/render/terrainstorage.hpp index dbb39a44ad..64c026b76d 100644 --- a/apps/opencs/view/render/terrainstorage.hpp +++ b/apps/opencs/view/render/terrainstorage.hpp @@ -27,24 +27,26 @@ namespace CSVRender const CSMWorld::Data& mData; std::array mAlteredHeight; - osg::ref_ptr getLand (int cellX, int cellY) override; + osg::ref_ptr getLand(int cellX, int cellY) override; const ESM::LandTexture* getLandTexture(int index, short plugin) override; void getBounds(float& minX, float& maxX, float& minY, float& maxY) override; - int getThisHeight(int col, int row, const ESM::Land::LandData *heightData) const; - int getLeftHeight(int col, int row, const ESM::Land::LandData *heightData) const; - int getRightHeight(int col, int row, const ESM::Land::LandData *heightData) const; - int getUpHeight(int col, int row, const ESM::Land::LandData *heightData) const; - int getDownHeight(int col, int row, const ESM::Land::LandData *heightData) const; - int getHeightDifferenceToLeft(int col, int row, const ESM::Land::LandData *heightData) const; - int getHeightDifferenceToRight(int col, int row, const ESM::Land::LandData *heightData) const; - int getHeightDifferenceToUp(int col, int row, const ESM::Land::LandData *heightData) const; - int getHeightDifferenceToDown(int col, int row, const ESM::Land::LandData *heightData) const; - bool leftOrUpIsOverTheLimit(int col, int row, int heightWarningLimit, const ESM::Land::LandData *heightData) const; - bool rightOrDownIsOverTheLimit(int col, int row, int heightWarningLimit, const ESM::Land::LandData *heightData) const; - - void adjustColor(int col, int row, const ESM::Land::LandData *heightData, osg::Vec4ub& color) const override; + int getThisHeight(int col, int row, const ESM::Land::LandData* heightData) const; + int getLeftHeight(int col, int row, const ESM::Land::LandData* heightData) const; + int getRightHeight(int col, int row, const ESM::Land::LandData* heightData) const; + int getUpHeight(int col, int row, const ESM::Land::LandData* heightData) const; + int getDownHeight(int col, int row, const ESM::Land::LandData* heightData) const; + int getHeightDifferenceToLeft(int col, int row, const ESM::Land::LandData* heightData) const; + int getHeightDifferenceToRight(int col, int row, const ESM::Land::LandData* heightData) const; + int getHeightDifferenceToUp(int col, int row, const ESM::Land::LandData* heightData) const; + int getHeightDifferenceToDown(int col, int row, const ESM::Land::LandData* heightData) const; + bool leftOrUpIsOverTheLimit( + int col, int row, int heightWarningLimit, const ESM::Land::LandData* heightData) const; + bool rightOrDownIsOverTheLimit( + int col, int row, int heightWarningLimit, const ESM::Land::LandData* heightData) const; + + void adjustColor(int col, int row, const ESM::Land::LandData* heightData, osg::Vec4ub& color) const override; float getAlteredHeight(int col, int row) const override; }; diff --git a/apps/opencs/view/render/terraintexturemode.cpp b/apps/opencs/view/render/terraintexturemode.cpp index 2494e4378c..9a7b76f110 100644 --- a/apps/opencs/view/render/terraintexturemode.cpp +++ b/apps/opencs/view/render/terraintexturemode.cpp @@ -2,9 +2,9 @@ #include -#include -#include #include +#include +#include #include @@ -25,57 +25,70 @@ #include "brushdraw.hpp" #include "editmode.hpp" -#include "pagedworldspacewidget.hpp" #include "mask.hpp" #include "object.hpp" // Something small needed regarding pointers from here () +#include "pagedworldspacewidget.hpp" #include "worldspacewidget.hpp" -CSVRender::TerrainTextureMode::TerrainTextureMode (WorldspaceWidget *worldspaceWidget, osg::Group* parentNode, QWidget *parent) -: EditMode (worldspaceWidget, QIcon {":scenetoolbar/editing-terrain-texture"}, Mask_Terrain | Mask_Reference, "Terrain texture editing", parent), - mBrushTexture("L0#0"), - mBrushSize(1), - mBrushShape(CSVWidget::BrushShape_Point), - mTextureBrushScenetool(nullptr), - mDragMode(InteractionType_None), - mParentNode(parentNode), - mIsEditing(false) +CSVRender::TerrainTextureMode::TerrainTextureMode( + WorldspaceWidget* worldspaceWidget, osg::Group* parentNode, QWidget* parent) + : EditMode(worldspaceWidget, QIcon{ ":scenetoolbar/editing-terrain-texture" }, Mask_Terrain | Mask_Reference, + "Terrain texture editing", parent) + , mBrushTexture("L0#0") + , mBrushSize(1) + , mBrushShape(CSVWidget::BrushShape_Point) + , mTextureBrushScenetool(nullptr) + , mDragMode(InteractionType_None) + , mParentNode(parentNode) + , mIsEditing(false) { } void CSVRender::TerrainTextureMode::activate(CSVWidget::SceneToolbar* toolbar) { - if(!mTextureBrushScenetool) + if (!mTextureBrushScenetool) { - mTextureBrushScenetool = new CSVWidget::SceneToolTextureBrush (toolbar, "scenetooltexturebrush", getWorldspaceWidget().getDocument()); - connect(mTextureBrushScenetool, &CSVWidget::SceneTool::clicked, mTextureBrushScenetool, &CSVWidget::SceneToolTextureBrush::activate); - connect(mTextureBrushScenetool->mTextureBrushWindow, &CSVWidget::TextureBrushWindow::passBrushSize, this, &TerrainTextureMode::setBrushSize); - connect(mTextureBrushScenetool->mTextureBrushWindow, &CSVWidget::TextureBrushWindow::passBrushShape, this, &TerrainTextureMode::setBrushShape); - connect(mTextureBrushScenetool->mTextureBrushWindow->mSizeSliders->mBrushSizeSlider, &QSlider::valueChanged, this, &TerrainTextureMode::setBrushSize); - connect(mTextureBrushScenetool, &CSVWidget::SceneToolTextureBrush::passTextureId, this, &TerrainTextureMode::setBrushTexture); - connect(mTextureBrushScenetool->mTextureBrushWindow, &CSVWidget::TextureBrushWindow::passTextureId, this, &TerrainTextureMode::setBrushTexture); - - connect(mTextureBrushScenetool, qOverload(&CSVWidget::SceneToolTextureBrush::passEvent), this, &TerrainTextureMode::handleDropEvent); - connect(this, &TerrainTextureMode::passBrushTexture, mTextureBrushScenetool->mTextureBrushWindow, &CSVWidget::TextureBrushWindow::setBrushTexture); - connect(this, &TerrainTextureMode::passBrushTexture, mTextureBrushScenetool, &CSVWidget::SceneToolTextureBrush::updateBrushHistory); + mTextureBrushScenetool = new CSVWidget::SceneToolTextureBrush( + toolbar, "scenetooltexturebrush", getWorldspaceWidget().getDocument()); + connect(mTextureBrushScenetool, &CSVWidget::SceneTool::clicked, mTextureBrushScenetool, + &CSVWidget::SceneToolTextureBrush::activate); + connect(mTextureBrushScenetool->mTextureBrushWindow, &CSVWidget::TextureBrushWindow::passBrushSize, this, + &TerrainTextureMode::setBrushSize); + connect(mTextureBrushScenetool->mTextureBrushWindow, &CSVWidget::TextureBrushWindow::passBrushShape, this, + &TerrainTextureMode::setBrushShape); + connect(mTextureBrushScenetool->mTextureBrushWindow->mSizeSliders->mBrushSizeSlider, &QSlider::valueChanged, + this, &TerrainTextureMode::setBrushSize); + connect(mTextureBrushScenetool, &CSVWidget::SceneToolTextureBrush::passTextureId, this, + &TerrainTextureMode::setBrushTexture); + connect(mTextureBrushScenetool->mTextureBrushWindow, &CSVWidget::TextureBrushWindow::passTextureId, this, + &TerrainTextureMode::setBrushTexture); + + connect(mTextureBrushScenetool, qOverload(&CSVWidget::SceneToolTextureBrush::passEvent), this, + &TerrainTextureMode::handleDropEvent); + connect(this, &TerrainTextureMode::passBrushTexture, mTextureBrushScenetool->mTextureBrushWindow, + &CSVWidget::TextureBrushWindow::setBrushTexture); + connect(this, &TerrainTextureMode::passBrushTexture, mTextureBrushScenetool, + &CSVWidget::SceneToolTextureBrush::updateBrushHistory); } if (!mTerrainTextureSelection) { - mTerrainTextureSelection = std::make_shared(mParentNode, &getWorldspaceWidget(), TerrainSelectionType::Texture); + mTerrainTextureSelection + = std::make_shared(mParentNode, &getWorldspaceWidget(), TerrainSelectionType::Texture); } if (!mBrushDraw) mBrushDraw = std::make_unique(mParentNode, true); EditMode::activate(toolbar); - toolbar->addTool (mTextureBrushScenetool); + toolbar->addTool(mTextureBrushScenetool); } void CSVRender::TerrainTextureMode::deactivate(CSVWidget::SceneToolbar* toolbar) { - if(mTextureBrushScenetool) + if (mTextureBrushScenetool) { - toolbar->removeTool (mTextureBrushScenetool); + toolbar->removeTool(mTextureBrushScenetool); delete mTextureBrushScenetool; mTextureBrushScenetool = nullptr; } @@ -98,12 +111,12 @@ void CSVRender::TerrainTextureMode::primaryOpenPressed(const WorldspaceHitResult void CSVRender::TerrainTextureMode::primaryEditPressed(const WorldspaceHitResult& hit) // Apply changes here { CSMDoc::Document& document = getWorldspaceWidget().getDocument(); - CSMWorld::IdTable& landTable = dynamic_cast ( - *document.getData().getTableModel (CSMWorld::UniversalId::Type_Land)); - CSMWorld::IdTable& ltexTable = dynamic_cast ( - *document.getData().getTableModel (CSMWorld::UniversalId::Type_LandTextures)); + CSMWorld::IdTable& landTable + = dynamic_cast(*document.getData().getTableModel(CSMWorld::UniversalId::Type_Land)); + CSMWorld::IdTable& ltexTable + = dynamic_cast(*document.getData().getTableModel(CSMWorld::UniversalId::Type_LandTextures)); - mCellId = getWorldspaceWidget().getCellId (hit.worldPos); + mCellId = getWorldspaceWidget().getCellId(hit.worldPos); QUndoStack& undoStack = document.getUndoStack(); CSMWorld::IdCollection& landtexturesCollection = document.getData().getLandTextures(); @@ -111,10 +124,10 @@ void CSVRender::TerrainTextureMode::primaryEditPressed(const WorldspaceHitResult if (index != -1 && !landtexturesCollection.getRecord(index).isDeleted() && hit.hit && hit.tag == nullptr) { - undoStack.beginMacro ("Edit texture records"); - if(allowLandTextureEditing(mCellId)) + undoStack.beginMacro("Edit texture records"); + if (allowLandTextureEditing(mCellId)) { - undoStack.push (new CSMWorld::TouchLandCommand(landTable, ltexTable, mCellId)); + undoStack.push(new CSMWorld::TouchLandCommand(landTable, ltexTable, mCellId)); editTerrainTextureGrid(hit); } undoStack.endMacro(); @@ -123,7 +136,7 @@ void CSVRender::TerrainTextureMode::primaryEditPressed(const WorldspaceHitResult void CSVRender::TerrainTextureMode::primarySelectPressed(const WorldspaceHitResult& hit) { - if(hit.hit && hit.tag == nullptr) + if (hit.hit && hit.tag == nullptr) { selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 0); mTerrainTextureSelection->clearTemporarySelection(); @@ -132,24 +145,24 @@ void CSVRender::TerrainTextureMode::primarySelectPressed(const WorldspaceHitResu void CSVRender::TerrainTextureMode::secondarySelectPressed(const WorldspaceHitResult& hit) { - if(hit.hit && hit.tag == nullptr) + if (hit.hit && hit.tag == nullptr) { selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 1); mTerrainTextureSelection->clearTemporarySelection(); } } -bool CSVRender::TerrainTextureMode::primaryEditStartDrag (const QPoint& pos) +bool CSVRender::TerrainTextureMode::primaryEditStartDrag(const QPoint& pos) { - WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask()); + WorldspaceHitResult hit = getWorldspaceWidget().mousePick(pos, getWorldspaceWidget().getInteractionMask()); CSMDoc::Document& document = getWorldspaceWidget().getDocument(); - CSMWorld::IdTable& landTable = dynamic_cast ( - *document.getData().getTableModel (CSMWorld::UniversalId::Type_Land)); - CSMWorld::IdTable& ltexTable = dynamic_cast ( - *document.getData().getTableModel (CSMWorld::UniversalId::Type_LandTextures)); + CSMWorld::IdTable& landTable + = dynamic_cast(*document.getData().getTableModel(CSMWorld::UniversalId::Type_Land)); + CSMWorld::IdTable& ltexTable + = dynamic_cast(*document.getData().getTableModel(CSMWorld::UniversalId::Type_LandTextures)); - mCellId = getWorldspaceWidget().getCellId (hit.worldPos); + mCellId = getWorldspaceWidget().getCellId(hit.worldPos); QUndoStack& undoStack = document.getUndoStack(); @@ -160,11 +173,11 @@ bool CSVRender::TerrainTextureMode::primaryEditStartDrag (const QPoint& pos) if (index != -1 && !landtexturesCollection.getRecord(index).isDeleted() && hit.hit && hit.tag == nullptr) { - undoStack.beginMacro ("Edit texture records"); + undoStack.beginMacro("Edit texture records"); mIsEditing = true; - if(allowLandTextureEditing(mCellId)) + if (allowLandTextureEditing(mCellId)) { - undoStack.push (new CSMWorld::TouchLandCommand(landTable, ltexTable, mCellId)); + undoStack.push(new CSMWorld::TouchLandCommand(landTable, ltexTable, mCellId)); editTerrainTextureGrid(hit); } } @@ -172,14 +185,14 @@ bool CSVRender::TerrainTextureMode::primaryEditStartDrag (const QPoint& pos) return true; } -bool CSVRender::TerrainTextureMode::secondaryEditStartDrag (const QPoint& pos) +bool CSVRender::TerrainTextureMode::secondaryEditStartDrag(const QPoint& pos) { return false; } -bool CSVRender::TerrainTextureMode::primarySelectStartDrag (const QPoint& pos) +bool CSVRender::TerrainTextureMode::primarySelectStartDrag(const QPoint& pos) { - WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask()); + WorldspaceHitResult hit = getWorldspaceWidget().mousePick(pos, getWorldspaceWidget().getInteractionMask()); mDragMode = InteractionType_PrimarySelect; if (!hit.hit || hit.tag != nullptr) { @@ -190,9 +203,9 @@ bool CSVRender::TerrainTextureMode::primarySelectStartDrag (const QPoint& pos) return true; } -bool CSVRender::TerrainTextureMode::secondarySelectStartDrag (const QPoint& pos) +bool CSVRender::TerrainTextureMode::secondarySelectStartDrag(const QPoint& pos) { - WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask()); + WorldspaceHitResult hit = getWorldspaceWidget().mousePick(pos, getWorldspaceWidget().getInteractionMask()); mDragMode = InteractionType_SecondarySelect; if (!hit.hit || hit.tag != nullptr) { @@ -203,12 +216,12 @@ bool CSVRender::TerrainTextureMode::secondarySelectStartDrag (const QPoint& pos) return true; } -void CSVRender::TerrainTextureMode::drag (const QPoint& pos, int diffX, int diffY, double speedFactor) +void CSVRender::TerrainTextureMode::drag(const QPoint& pos, int diffX, int diffY, double speedFactor) { if (mDragMode == InteractionType_PrimaryEdit) { - WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask()); - std::string cellId = getWorldspaceWidget().getCellId (hit.worldPos); + WorldspaceHitResult hit = getWorldspaceWidget().mousePick(pos, getWorldspaceWidget().getInteractionMask()); + std::string cellId = getWorldspaceWidget().getCellId(hit.worldPos); CSMDoc::Document& document = getWorldspaceWidget().getDocument(); CSMWorld::IdCollection& landtexturesCollection = document.getData().getLandTextures(); @@ -222,14 +235,16 @@ void CSVRender::TerrainTextureMode::drag (const QPoint& pos, int diffX, int diff if (mDragMode == InteractionType_PrimarySelect) { - WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask()); - if (hit.hit && hit.tag == nullptr) selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 0); + WorldspaceHitResult hit = getWorldspaceWidget().mousePick(pos, getWorldspaceWidget().getInteractionMask()); + if (hit.hit && hit.tag == nullptr) + selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 0); } if (mDragMode == InteractionType_SecondarySelect) { - WorldspaceHitResult hit = getWorldspaceWidget().mousePick (pos, getWorldspaceWidget().getInteractionMask()); - if (hit.hit && hit.tag == nullptr) selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 1); + WorldspaceHitResult hit = getWorldspaceWidget().mousePick(pos, getWorldspaceWidget().getInteractionMask()); + if (hit.hit && hit.tag == nullptr) + selectTerrainTextures(CSMWorld::CellCoordinates::toTextureCoords(hit.worldPos), 1); } } @@ -245,69 +260,67 @@ void CSVRender::TerrainTextureMode::dragCompleted(const QPoint& pos) if (index != -1 && !landtexturesCollection.getRecord(index).isDeleted()) { - undoStack.endMacro(); - mIsEditing = false; + undoStack.endMacro(); + mIsEditing = false; } } mTerrainTextureSelection->clearTemporarySelection(); } -void CSVRender::TerrainTextureMode::dragAborted() -{ -} +void CSVRender::TerrainTextureMode::dragAborted() {} -void CSVRender::TerrainTextureMode::dragWheel (int diff, double speedFactor) -{ -} +void CSVRender::TerrainTextureMode::dragWheel(int diff, double speedFactor) {} -void CSVRender::TerrainTextureMode::handleDropEvent (QDropEvent *event) +void CSVRender::TerrainTextureMode::handleDropEvent(QDropEvent* event) { - const CSMWorld::TableMimeData* mime = dynamic_cast (event->mimeData()); - - if (!mime) // May happen when non-records (e.g. plain text) are dragged and dropped - return; - - if (mime->holdsType (CSMWorld::UniversalId::Type_LandTexture)) - { - const std::vector ids = mime->getData(); - - for (const CSMWorld::UniversalId& uid : ids) - { - mBrushTexture = uid.getId(); - emit passBrushTexture(mBrushTexture); - } - } - if (mime->holdsType (CSMWorld::UniversalId::Type_Texture)) - { - const std::vector ids = mime->getData(); - - for (const CSMWorld::UniversalId& uid : ids) - { - std::string textureFileName = uid.toString(); - createTexture(textureFileName); - emit passBrushTexture(mBrushTexture); - } - } + const CSMWorld::TableMimeData* mime = dynamic_cast(event->mimeData()); + + if (!mime) // May happen when non-records (e.g. plain text) are dragged and dropped + return; + + if (mime->holdsType(CSMWorld::UniversalId::Type_LandTexture)) + { + const std::vector ids = mime->getData(); + + for (const CSMWorld::UniversalId& uid : ids) + { + mBrushTexture = uid.getId(); + emit passBrushTexture(mBrushTexture); + } + } + if (mime->holdsType(CSMWorld::UniversalId::Type_Texture)) + { + const std::vector ids = mime->getData(); + + for (const CSMWorld::UniversalId& uid : ids) + { + std::string textureFileName = uid.toString(); + createTexture(textureFileName); + emit passBrushTexture(mBrushTexture); + } + } } void CSVRender::TerrainTextureMode::editTerrainTextureGrid(const WorldspaceHitResult& hit) { CSMDoc::Document& document = getWorldspaceWidget().getDocument(); - CSMWorld::IdTable& landTable = dynamic_cast ( - *document.getData().getTableModel (CSMWorld::UniversalId::Type_Land)); + CSMWorld::IdTable& landTable + = dynamic_cast(*document.getData().getTableModel(CSMWorld::UniversalId::Type_Land)); - mCellId = getWorldspaceWidget().getCellId (hit.worldPos); - if(allowLandTextureEditing(mCellId)) {} + mCellId = getWorldspaceWidget().getCellId(hit.worldPos); + if (allowLandTextureEditing(mCellId)) + { + } - std::pair cellCoordinates_pair = CSMWorld::CellCoordinates::fromId (mCellId); + std::pair cellCoordinates_pair = CSMWorld::CellCoordinates::fromId(mCellId); int cellX = cellCoordinates_pair.first.getX(); int cellY = cellCoordinates_pair.first.getY(); // The coordinates of hit in mCellId - int xHitInCell (float(((hit.worldPos.x() - (cellX* cellSize)) * landTextureSize / cellSize) - 0.25)); - int yHitInCell (float(((hit.worldPos.y() - (cellY* cellSize)) * landTextureSize / cellSize) + 0.25)); + int xHitInCell(float(((hit.worldPos.x() - (cellX * cellSize)) * landTextureSize / cellSize) - 0.25)); + int yHitInCell(float(((hit.worldPos.y() - (cellY * cellSize)) * landTextureSize / cellSize) + 0.25)); if (xHitInCell < 0) { xHitInCell = xHitInCell + landTextureSize; @@ -320,71 +333,89 @@ void CSVRender::TerrainTextureMode::editTerrainTextureGrid(const WorldspaceHitRe } mCellId = CSMWorld::CellCoordinates::generateId(cellX, cellY); - if(allowLandTextureEditing(mCellId)) {} + if (allowLandTextureEditing(mCellId)) + { + } std::string iteratedCellId; int textureColumn = landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandTexturesIndex); std::size_t hashlocation = mBrushTexture.find('#'); - std::string mBrushTextureInt = mBrushTexture.substr (hashlocation+1); - int brushInt = stoi(mBrushTexture.substr (hashlocation+1))+1; // All indices are offset by +1 + std::string mBrushTextureInt = mBrushTexture.substr(hashlocation + 1); + int brushInt = stoi(mBrushTexture.substr(hashlocation + 1)) + 1; // All indices are offset by +1 int r = static_cast(mBrushSize) / 2; if (mBrushShape == CSVWidget::BrushShape_Point) { - CSMWorld::LandTexturesColumn::DataType newTerrainPointer = landTable.data(landTable.getModelIndex(mCellId, textureColumn)).value(); + CSMWorld::LandTexturesColumn::DataType newTerrainPointer + = landTable.data(landTable.getModelIndex(mCellId, textureColumn)) + .value(); CSMWorld::LandTexturesColumn::DataType newTerrain(newTerrainPointer); - if(allowLandTextureEditing(mCellId)) + if (allowLandTextureEditing(mCellId)) { - newTerrain[yHitInCell*landTextureSize+xHitInCell] = brushInt; + newTerrain[yHitInCell * landTextureSize + xHitInCell] = brushInt; pushEditToCommand(newTerrain, document, landTable, mCellId); } } if (mBrushShape == CSVWidget::BrushShape_Square) { - int upperLeftCellX = cellX - std::floor(r / landTextureSize); - int upperLeftCellY = cellY - std::floor(r / landTextureSize); - if (xHitInCell - (r % landTextureSize) < 0) upperLeftCellX--; - if (yHitInCell - (r % landTextureSize) < 0) upperLeftCellY--; + int upperLeftCellX = cellX - std::floor(r / landTextureSize); + int upperLeftCellY = cellY - std::floor(r / landTextureSize); + if (xHitInCell - (r % landTextureSize) < 0) + upperLeftCellX--; + if (yHitInCell - (r % landTextureSize) < 0) + upperLeftCellY--; int lowerrightCellX = cellX + std::floor(r / landTextureSize); int lowerrightCellY = cellY + std::floor(r / landTextureSize); - if (xHitInCell + (r % landTextureSize) > landTextureSize - 1) lowerrightCellX++; - if (yHitInCell + (r % landTextureSize) > landTextureSize - 1) lowerrightCellY++; + if (xHitInCell + (r % landTextureSize) > landTextureSize - 1) + lowerrightCellX++; + if (yHitInCell + (r % landTextureSize) > landTextureSize - 1) + lowerrightCellY++; - for(int i_cell = upperLeftCellX; i_cell <= lowerrightCellX; i_cell++) + for (int i_cell = upperLeftCellX; i_cell <= lowerrightCellX; i_cell++) { - for(int j_cell = upperLeftCellY; j_cell <= lowerrightCellY; j_cell++) + for (int j_cell = upperLeftCellY; j_cell <= lowerrightCellY; j_cell++) { iteratedCellId = CSMWorld::CellCoordinates::generateId(i_cell, j_cell); - if(allowLandTextureEditing(iteratedCellId)) + if (allowLandTextureEditing(iteratedCellId)) { - CSMWorld::LandTexturesColumn::DataType newTerrainPointer = landTable.data(landTable.getModelIndex(iteratedCellId, textureColumn)).value(); + CSMWorld::LandTexturesColumn::DataType newTerrainPointer + = landTable.data(landTable.getModelIndex(iteratedCellId, textureColumn)) + .value(); CSMWorld::LandTexturesColumn::DataType newTerrain(newTerrainPointer); - for(int i = 0; i < landTextureSize; i++) + for (int i = 0; i < landTextureSize; i++) { - for(int j = 0; j < landTextureSize; j++) + for (int j = 0; j < landTextureSize; j++) { - if (i_cell == cellX && j_cell == cellY && abs(i-xHitInCell) < r && abs(j-yHitInCell) < r) + if (i_cell == cellX && j_cell == cellY && abs(i - xHitInCell) < r + && abs(j - yHitInCell) < r) { - newTerrain[j*landTextureSize+i] = brushInt; + newTerrain[j * landTextureSize + i] = brushInt; } else { int distanceX(0); int distanceY(0); - if (i_cell < cellX) distanceX = xHitInCell + landTextureSize * abs(i_cell-cellX) - i; - if (j_cell < cellY) distanceY = yHitInCell + landTextureSize * abs(j_cell-cellY) - j; - if (i_cell > cellX) distanceX = -xHitInCell + landTextureSize * abs(i_cell-cellX) + i; - if (j_cell > cellY) distanceY = -yHitInCell + landTextureSize * abs(j_cell-cellY) + j; - if (i_cell == cellX) distanceX = abs(i-xHitInCell); - if (j_cell == cellY) distanceY = abs(j-yHitInCell); - if (distanceX < r && distanceY < r) newTerrain[j*landTextureSize+i] = brushInt; + if (i_cell < cellX) + distanceX = xHitInCell + landTextureSize * abs(i_cell - cellX) - i; + if (j_cell < cellY) + distanceY = yHitInCell + landTextureSize * abs(j_cell - cellY) - j; + if (i_cell > cellX) + distanceX = -xHitInCell + landTextureSize * abs(i_cell - cellX) + i; + if (j_cell > cellY) + distanceY = -yHitInCell + landTextureSize * abs(j_cell - cellY) + j; + if (i_cell == cellX) + distanceX = abs(i - xHitInCell); + if (j_cell == cellY) + distanceY = abs(j - yHitInCell); + if (distanceX < r && distanceY < r) + newTerrain[j * landTextureSize + i] = brushInt; } } } @@ -396,50 +427,65 @@ void CSVRender::TerrainTextureMode::editTerrainTextureGrid(const WorldspaceHitRe if (mBrushShape == CSVWidget::BrushShape_Circle) { - int upperLeftCellX = cellX - std::floor(r / landTextureSize); - int upperLeftCellY = cellY - std::floor(r / landTextureSize); - if (xHitInCell - (r % landTextureSize) < 0) upperLeftCellX--; - if (yHitInCell - (r % landTextureSize) < 0) upperLeftCellY--; + int upperLeftCellX = cellX - std::floor(r / landTextureSize); + int upperLeftCellY = cellY - std::floor(r / landTextureSize); + if (xHitInCell - (r % landTextureSize) < 0) + upperLeftCellX--; + if (yHitInCell - (r % landTextureSize) < 0) + upperLeftCellY--; int lowerrightCellX = cellX + std::floor(r / landTextureSize); int lowerrightCellY = cellY + std::floor(r / landTextureSize); - if (xHitInCell + (r % landTextureSize) > landTextureSize - 1) lowerrightCellX++; - if (yHitInCell + (r % landTextureSize) > landTextureSize - 1) lowerrightCellY++; + if (xHitInCell + (r % landTextureSize) > landTextureSize - 1) + lowerrightCellX++; + if (yHitInCell + (r % landTextureSize) > landTextureSize - 1) + lowerrightCellY++; - for(int i_cell = upperLeftCellX; i_cell <= lowerrightCellX; i_cell++) + for (int i_cell = upperLeftCellX; i_cell <= lowerrightCellX; i_cell++) { - for(int j_cell = upperLeftCellY; j_cell <= lowerrightCellY; j_cell++) + for (int j_cell = upperLeftCellY; j_cell <= lowerrightCellY; j_cell++) { iteratedCellId = CSMWorld::CellCoordinates::generateId(i_cell, j_cell); - if(allowLandTextureEditing(iteratedCellId)) + if (allowLandTextureEditing(iteratedCellId)) { - CSMWorld::LandTexturesColumn::DataType newTerrainPointer = landTable.data(landTable.getModelIndex(iteratedCellId, textureColumn)).value(); + CSMWorld::LandTexturesColumn::DataType newTerrainPointer + = landTable.data(landTable.getModelIndex(iteratedCellId, textureColumn)) + .value(); CSMWorld::LandTexturesColumn::DataType newTerrain(newTerrainPointer); - for(int i = 0; i < landTextureSize; i++) + for (int i = 0; i < landTextureSize; i++) { - for(int j = 0; j < landTextureSize; j++) + for (int j = 0; j < landTextureSize; j++) { - if (i_cell == cellX && j_cell == cellY && abs(i-xHitInCell) < r && abs(j-yHitInCell) < r) + if (i_cell == cellX && j_cell == cellY && abs(i - xHitInCell) < r + && abs(j - yHitInCell) < r) { - int distanceX = abs(i-xHitInCell); - int distanceY = abs(j-yHitInCell); - float distance = std::round(sqrt(pow(distanceX, 2)+pow(distanceY, 2))); + int distanceX = abs(i - xHitInCell); + int distanceY = abs(j - yHitInCell); + float distance = std::round(sqrt(pow(distanceX, 2) + pow(distanceY, 2))); float rf = static_cast(mBrushSize) / 2; - if (distance < rf) newTerrain[j*landTextureSize+i] = brushInt; + if (distance < rf) + newTerrain[j * landTextureSize + i] = brushInt; } else { int distanceX(0); int distanceY(0); - if (i_cell < cellX) distanceX = xHitInCell + landTextureSize * abs(i_cell-cellX) - i; - if (j_cell < cellY) distanceY = yHitInCell + landTextureSize * abs(j_cell-cellY) - j; - if (i_cell > cellX) distanceX = -xHitInCell + landTextureSize * abs(i_cell-cellX) + i; - if (j_cell > cellY) distanceY = -yHitInCell + landTextureSize * abs(j_cell-cellY) + j; - if (i_cell == cellX) distanceX = abs(i-xHitInCell); - if (j_cell == cellY) distanceY = abs(j-yHitInCell); - float distance = std::round(sqrt(pow(distanceX, 2)+pow(distanceY, 2))); + if (i_cell < cellX) + distanceX = xHitInCell + landTextureSize * abs(i_cell - cellX) - i; + if (j_cell < cellY) + distanceY = yHitInCell + landTextureSize * abs(j_cell - cellY) - j; + if (i_cell > cellX) + distanceX = -xHitInCell + landTextureSize * abs(i_cell - cellX) + i; + if (j_cell > cellY) + distanceY = -yHitInCell + landTextureSize * abs(j_cell - cellY) + j; + if (i_cell == cellX) + distanceX = abs(i - xHitInCell); + if (j_cell == cellY) + distanceY = abs(j - yHitInCell); + float distance = std::round(sqrt(pow(distanceX, 2) + pow(distanceY, 2))); float rf = static_cast(mBrushSize) / 2; - if (distance < rf) newTerrain[j*landTextureSize+i] = brushInt; + if (distance < rf) + newTerrain[j * landTextureSize + i] = brushInt; } } } @@ -451,30 +497,36 @@ void CSVRender::TerrainTextureMode::editTerrainTextureGrid(const WorldspaceHitRe if (mBrushShape == CSVWidget::BrushShape_Custom) { - CSMWorld::LandTexturesColumn::DataType newTerrainPointer = landTable.data(landTable.getModelIndex(mCellId, textureColumn)).value(); + CSMWorld::LandTexturesColumn::DataType newTerrainPointer + = landTable.data(landTable.getModelIndex(mCellId, textureColumn)) + .value(); CSMWorld::LandTexturesColumn::DataType newTerrain(newTerrainPointer); - if(allowLandTextureEditing(mCellId) && !mCustomBrushShape.empty()) + if (allowLandTextureEditing(mCellId) && !mCustomBrushShape.empty()) { - for(auto const& value: mCustomBrushShape) + for (auto const& value : mCustomBrushShape) { - if(yHitInCell + value.second >= 0 && yHitInCell + value.second <= 15 && xHitInCell + value.first >= 0 && xHitInCell + value.first <= 15) + if (yHitInCell + value.second >= 0 && yHitInCell + value.second <= 15 && xHitInCell + value.first >= 0 + && xHitInCell + value.first <= 15) { - newTerrain[(yHitInCell+value.second)*landTextureSize+xHitInCell+value.first] = brushInt; + newTerrain[(yHitInCell + value.second) * landTextureSize + xHitInCell + value.first] = brushInt; } else { - int cellXDifference = std::floor(1.0f*(xHitInCell + value.first)/landTextureSize); - int cellYDifference = std::floor(1.0f*(yHitInCell + value.second)/landTextureSize); + int cellXDifference = std::floor(1.0f * (xHitInCell + value.first) / landTextureSize); + int cellYDifference = std::floor(1.0f * (yHitInCell + value.second) / landTextureSize); int xInOtherCell = xHitInCell + value.first - cellXDifference * landTextureSize; int yInOtherCell = yHitInCell + value.second - cellYDifference * landTextureSize; - std::string cellId = CSMWorld::CellCoordinates::generateId(cellX+cellXDifference, cellY+cellYDifference); + std::string cellId + = CSMWorld::CellCoordinates::generateId(cellX + cellXDifference, cellY + cellYDifference); if (allowLandTextureEditing(cellId)) { - CSMWorld::LandTexturesColumn::DataType newTerrainPointerOtherCell = landTable.data(landTable.getModelIndex(cellId, textureColumn)).value(); + CSMWorld::LandTexturesColumn::DataType newTerrainPointerOtherCell + = landTable.data(landTable.getModelIndex(cellId, textureColumn)) + .value(); CSMWorld::LandTexturesColumn::DataType newTerrainOtherCell(newTerrainPointerOtherCell); - newTerrainOtherCell[yInOtherCell*landTextureSize+xInOtherCell] = brushInt; + newTerrainOtherCell[yInOtherCell * landTextureSize + xInOtherCell] = brushInt; pushEditToCommand(newTerrainOtherCell, document, landTable, cellId); } } @@ -486,7 +538,8 @@ void CSVRender::TerrainTextureMode::editTerrainTextureGrid(const WorldspaceHitRe bool CSVRender::TerrainTextureMode::isInCellSelection(int globalSelectionX, int globalSelectionY) { - if (CSVRender::PagedWorldspaceWidget *paged = dynamic_cast (&getWorldspaceWidget())) + if (CSVRender::PagedWorldspaceWidget* paged + = dynamic_cast(&getWorldspaceWidget())) { std::pair textureCoords = std::make_pair(globalSelectionX, globalSelectionY); std::string cellId = CSMWorld::CellCoordinates::textureGlobalToCellId(textureCoords); @@ -495,15 +548,16 @@ bool CSVRender::TerrainTextureMode::isInCellSelection(int globalSelectionX, int return false; } - -void CSVRender::TerrainTextureMode::selectTerrainTextures(const std::pair& texCoords, unsigned char selectMode) +void CSVRender::TerrainTextureMode::selectTerrainTextures( + const std::pair& texCoords, unsigned char selectMode) { int r = mBrushSize / 2; std::vector> selections; if (mBrushShape == CSVWidget::BrushShape_Point) { - if (isInCellSelection(texCoords.first, texCoords.second)) selections.emplace_back(texCoords); + if (isInCellSelection(texCoords.first, texCoords.second)) + selections.emplace_back(texCoords); } if (mBrushShape == CSVWidget::BrushShape_Square) @@ -528,7 +582,7 @@ void CSVRender::TerrainTextureMode::selectTerrainTextures(const std::pair(mBrushSize) / 2; if (std::round(coords.length()) < rf) { @@ -545,9 +599,9 @@ void CSVRender::TerrainTextureMode::selectTerrainTextures(const std::pairtoggleSelect(selections); } -void CSVRender::TerrainTextureMode::pushEditToCommand(CSMWorld::LandTexturesColumn::DataType& newLandGrid, CSMDoc::Document& document, - CSMWorld::IdTable& landTable, std::string cellId) +void CSVRender::TerrainTextureMode::pushEditToCommand(CSMWorld::LandTexturesColumn::DataType& newLandGrid, + CSMDoc::Document& document, CSMWorld::IdTable& landTable, std::string cellId) { - CSMWorld::IdTable& ltexTable = dynamic_cast ( - *document.getData().getTableModel (CSMWorld::UniversalId::Type_LandTextures)); + CSMWorld::IdTable& ltexTable + = dynamic_cast(*document.getData().getTableModel(CSMWorld::UniversalId::Type_LandTextures)); QVariant changedLand; changedLand.setValue(newLandGrid); - QModelIndex index(landTable.getModelIndex (cellId, landTable.findColumnIndex (CSMWorld::Columns::ColumnId_LandTexturesIndex))); + QModelIndex index( + landTable.getModelIndex(cellId, landTable.findColumnIndex(CSMWorld::Columns::ColumnId_LandTexturesIndex))); QUndoStack& undoStack = document.getUndoStack(); - undoStack.push (new CSMWorld::ModifyCommand(landTable, index, changedLand)); - undoStack.push (new CSMWorld::TouchLandCommand(landTable, ltexTable, cellId)); + undoStack.push(new CSMWorld::ModifyCommand(landTable, index, changedLand)); + undoStack.push(new CSMWorld::TouchLandCommand(landTable, ltexTable, cellId)); } void CSVRender::TerrainTextureMode::createTexture(std::string textureFileName) { CSMDoc::Document& document = getWorldspaceWidget().getDocument(); - CSMWorld::IdTable& ltexTable = dynamic_cast ( - *document.getData().getTableModel (CSMWorld::UniversalId::Type_LandTextures)); + CSMWorld::IdTable& ltexTable + = dynamic_cast(*document.getData().getTableModel(CSMWorld::UniversalId::Type_LandTextures)); QUndoStack& undoStack = document.getUndoStack(); std::string newId; - int counter=0; + int counter = 0; bool freeIndexFound = false; do { @@ -611,7 +666,8 @@ void CSVRender::TerrainTextureMode::createTexture(std::string textureFileName) try { newId = CSMWorld::LandTexture::createUniqueRecordId(0, counter); - if (ltexTable.getRecord(newId).isDeleted() == 0) counter = (counter + 1) % maxCounter; + if (ltexTable.getRecord(newId).isDeleted() == 0) + counter = (counter + 1) % maxCounter; } catch (const std::exception&) { @@ -621,18 +677,18 @@ void CSVRender::TerrainTextureMode::createTexture(std::string textureFileName) } while (freeIndexFound == false); std::size_t idlocation = textureFileName.find("Texture: "); - textureFileName = textureFileName.substr (idlocation + 9); + textureFileName = textureFileName.substr(idlocation + 9); QVariant textureNameVariant; QVariant textureFileNameVariant; textureFileNameVariant.setValue(QString::fromStdString(textureFileName)); - undoStack.beginMacro ("Add land texture record"); + undoStack.beginMacro("Add land texture record"); - undoStack.push (new CSMWorld::CreateCommand (ltexTable, newId)); - QModelIndex index(ltexTable.getModelIndex (newId, ltexTable.findColumnIndex (CSMWorld::Columns::ColumnId_Texture))); - undoStack.push (new CSMWorld::ModifyCommand(ltexTable, index, textureFileNameVariant)); + undoStack.push(new CSMWorld::CreateCommand(ltexTable, newId)); + QModelIndex index(ltexTable.getModelIndex(newId, ltexTable.findColumnIndex(CSMWorld::Columns::ColumnId_Texture))); + undoStack.push(new CSMWorld::ModifyCommand(ltexTable, index, textureFileNameVariant)); undoStack.endMacro(); mBrushTexture = newId; } @@ -640,56 +696,55 @@ void CSVRender::TerrainTextureMode::createTexture(std::string textureFileName) bool CSVRender::TerrainTextureMode::allowLandTextureEditing(std::string cellId) { CSMDoc::Document& document = getWorldspaceWidget().getDocument(); - CSMWorld::IdTable& landTable = dynamic_cast ( - *document.getData().getTableModel (CSMWorld::UniversalId::Type_Land)); - CSMWorld::IdTree& cellTable = dynamic_cast ( - *document.getData().getTableModel (CSMWorld::UniversalId::Type_Cells)); + CSMWorld::IdTable& landTable + = dynamic_cast(*document.getData().getTableModel(CSMWorld::UniversalId::Type_Land)); + CSMWorld::IdTree& cellTable + = dynamic_cast(*document.getData().getTableModel(CSMWorld::UniversalId::Type_Cells)); - bool noCell = document.getData().getCells().searchId (cellId)==-1; - bool noLand = document.getData().getLand().searchId (cellId)==-1; + bool noCell = document.getData().getCells().searchId(cellId) == -1; + bool noLand = document.getData().getLand().searchId(cellId) == -1; if (noCell) { std::string mode = CSMPrefs::get()["3D Scene Editing"]["outside-landedit"].toString(); // target cell does not exist - if (mode=="Discard") + if (mode == "Discard") return false; - if (mode=="Create cell and land, then edit") + if (mode == "Create cell and land, then edit") { auto createCommand = std::make_unique(cellTable, cellId); - int parentIndex = cellTable.findColumnIndex (CSMWorld::Columns::ColumnId_Cell); - int index = cellTable.findNestedColumnIndex (parentIndex, CSMWorld::Columns::ColumnId_Interior); - createCommand->addNestedValue (parentIndex, index, false); - document.getUndoStack().push (createCommand.release()); + int parentIndex = cellTable.findColumnIndex(CSMWorld::Columns::ColumnId_Cell); + int index = cellTable.findNestedColumnIndex(parentIndex, CSMWorld::Columns::ColumnId_Interior); + createCommand->addNestedValue(parentIndex, index, false); + document.getUndoStack().push(createCommand.release()); - if (CSVRender::PagedWorldspaceWidget *paged = - dynamic_cast (&getWorldspaceWidget())) + if (CSVRender::PagedWorldspaceWidget* paged + = dynamic_cast(&getWorldspaceWidget())) { CSMWorld::CellSelection selection = paged->getCellSelection(); - selection.add (CSMWorld::CellCoordinates::fromId (cellId).first); - paged->setCellSelection (selection); + selection.add(CSMWorld::CellCoordinates::fromId(cellId).first); + paged->setCellSelection(selection); } } } - else if (CSVRender::PagedWorldspaceWidget *paged = - dynamic_cast (&getWorldspaceWidget())) + else if (CSVRender::PagedWorldspaceWidget* paged + = dynamic_cast(&getWorldspaceWidget())) { CSMWorld::CellSelection selection = paged->getCellSelection(); - if (!selection.has (CSMWorld::CellCoordinates::fromId (cellId).first)) + if (!selection.has(CSMWorld::CellCoordinates::fromId(cellId).first)) { // target cell exists, but is not shown - std::string mode = - CSMPrefs::get()["3D Scene Editing"]["outside-visible-landedit"].toString(); + std::string mode = CSMPrefs::get()["3D Scene Editing"]["outside-visible-landedit"].toString(); - if (mode=="Discard") + if (mode == "Discard") return false; - if (mode=="Show cell and edit") + if (mode == "Show cell and edit") { - selection.add (CSMWorld::CellCoordinates::fromId (cellId).first); - paged->setCellSelection (selection); + selection.add(CSMWorld::CellCoordinates::fromId(cellId).first); + paged->setCellSelection(selection); } } } @@ -699,23 +754,21 @@ bool CSVRender::TerrainTextureMode::allowLandTextureEditing(std::string cellId) std::string mode = CSMPrefs::get()["3D Scene Editing"]["outside-landedit"].toString(); // target cell does not exist - if (mode=="Discard") + if (mode == "Discard") return false; - if (mode=="Create cell and land, then edit") + if (mode == "Create cell and land, then edit") { - document.getUndoStack().push (new CSMWorld::CreateCommand (landTable, cellId)); + document.getUndoStack().push(new CSMWorld::CreateCommand(landTable, cellId)); } } return true; } -void CSVRender::TerrainTextureMode::dragMoveEvent (QDragMoveEvent *event) -{ -} +void CSVRender::TerrainTextureMode::dragMoveEvent(QDragMoveEvent* event) {} -void CSVRender::TerrainTextureMode::mouseMoveEvent (QMouseEvent *event) +void CSVRender::TerrainTextureMode::mouseMoveEvent(QMouseEvent* event) { WorldspaceHitResult hit = getWorldspaceWidget().mousePick(event->pos(), getInteractionMask()); if (hit.hit && mBrushDraw) @@ -729,7 +782,6 @@ std::shared_ptr CSVRender::TerrainTextureMode::getT return mTerrainTextureSelection; } - void CSVRender::TerrainTextureMode::setBrushSize(int brushSize) { mBrushSize = brushSize; @@ -739,7 +791,7 @@ void CSVRender::TerrainTextureMode::setBrushShape(CSVWidget::BrushShape brushSha { mBrushShape = brushShape; - //Set custom brush shape + // Set custom brush shape if (mBrushShape == CSVWidget::BrushShape_Custom && !mTerrainTextureSelection->getTerrainSelection().empty()) { auto terrainSelection = mTerrainTextureSelection->getTerrainSelection(); @@ -747,7 +799,7 @@ void CSVRender::TerrainTextureMode::setBrushShape(CSVWidget::BrushShape brushSha int selectionCenterY = 0; int selectionAmount = 0; - for(auto const& value: terrainSelection) + for (auto const& value : terrainSelection) { selectionCenterX += value.first; selectionCenterY += value.second; @@ -761,7 +813,7 @@ void CSVRender::TerrainTextureMode::setBrushShape(CSVWidget::BrushShape brushSha } mCustomBrushShape.clear(); - for (auto const& value: terrainSelection) + for (auto const& value : terrainSelection) mCustomBrushShape.emplace_back(value.first - selectionCenterX, value.second - selectionCenterY); } } diff --git a/apps/opencs/view/render/terraintexturemode.hpp b/apps/opencs/view/render/terraintexturemode.hpp index e91a69342c..f3a44c09ed 100644 --- a/apps/opencs/view/render/terraintexturemode.hpp +++ b/apps/opencs/view/render/terraintexturemode.hpp @@ -3,16 +3,16 @@ #include "editmode.hpp" -#include #include +#include -#include #include +#include #ifndef Q_MOC_RUN #include "../../model/doc/document.hpp" -#include "../../model/world/idtable.hpp" #include "../../model/world/columnimp.hpp" +#include "../../model/world/idtable.hpp" #include "../widget/brushshapes.hpp" #include "brushdraw.hpp" #endif @@ -35,99 +35,97 @@ namespace CSVRender { Q_OBJECT - public: + public: + enum InteractionType + { + InteractionType_PrimaryEdit, + InteractionType_PrimarySelect, + InteractionType_SecondaryEdit, + InteractionType_SecondarySelect, + InteractionType_None + }; - enum InteractionType - { - InteractionType_PrimaryEdit, - InteractionType_PrimarySelect, - InteractionType_SecondaryEdit, - InteractionType_SecondarySelect, - InteractionType_None - }; + /// \brief Editmode for terrain texture grid + TerrainTextureMode(WorldspaceWidget*, osg::Group* parentNode, QWidget* parent = nullptr); - /// \brief Editmode for terrain texture grid - TerrainTextureMode(WorldspaceWidget*, osg::Group* parentNode, QWidget* parent = nullptr); + void primaryOpenPressed(const WorldspaceHitResult& hit) override; - void primaryOpenPressed (const WorldspaceHitResult& hit) override; + /// \brief Create single command for one-click texture editing + void primaryEditPressed(const WorldspaceHitResult& hit) override; - /// \brief Create single command for one-click texture editing - void primaryEditPressed (const WorldspaceHitResult& hit) override; + /// \brief Open brush settings window + void primarySelectPressed(const WorldspaceHitResult&) override; - /// \brief Open brush settings window - void primarySelectPressed(const WorldspaceHitResult&) override; + void secondarySelectPressed(const WorldspaceHitResult&) override; - void secondarySelectPressed(const WorldspaceHitResult&) override; + void activate(CSVWidget::SceneToolbar*) override; + void deactivate(CSVWidget::SceneToolbar*) override; - void activate(CSVWidget::SceneToolbar*) override; - void deactivate(CSVWidget::SceneToolbar*) override; + /// \brief Start texture editing command macro + bool primaryEditStartDrag(const QPoint& pos) override; - /// \brief Start texture editing command macro - bool primaryEditStartDrag (const QPoint& pos) override; + bool secondaryEditStartDrag(const QPoint& pos) override; + bool primarySelectStartDrag(const QPoint& pos) override; + bool secondarySelectStartDrag(const QPoint& pos) override; - bool secondaryEditStartDrag (const QPoint& pos) override; - bool primarySelectStartDrag (const QPoint& pos) override; - bool secondarySelectStartDrag (const QPoint& pos) override; + /// \brief Handle texture edit behavior during dragging + void drag(const QPoint& pos, int diffX, int diffY, double speedFactor) override; - /// \brief Handle texture edit behavior during dragging - void drag (const QPoint& pos, int diffX, int diffY, double speedFactor) override; + /// \brief End texture editing command macro + void dragCompleted(const QPoint& pos) override; - /// \brief End texture editing command macro - void dragCompleted(const QPoint& pos) override; + void dragAborted() override; + void dragWheel(int diff, double speedFactor) override; + void dragMoveEvent(QDragMoveEvent* event) override; - void dragAborted() override; - void dragWheel (int diff, double speedFactor) override; - void dragMoveEvent (QDragMoveEvent *event) override; + void mouseMoveEvent(QMouseEvent* event) override; - void mouseMoveEvent (QMouseEvent *event) override; + std::shared_ptr getTerrainSelection(); - std::shared_ptr getTerrainSelection(); + private: + /// \brief Handle brush mechanics, maths regarding worldspace hit etc. + void editTerrainTextureGrid(const WorldspaceHitResult& hit); - private: - /// \brief Handle brush mechanics, maths regarding worldspace hit etc. - void editTerrainTextureGrid (const WorldspaceHitResult& hit); + /// \brief Check if global selection coordinate belongs to cell in view + bool isInCellSelection(int globalSelectionX, int globalSelectionY); - /// \brief Check if global selection coordinate belongs to cell in view - bool isInCellSelection(int globalSelectionX, int globalSelectionY); + /// \brief Handle brush mechanics for texture selection + void selectTerrainTextures(const std::pair& texCoords, unsigned char selectMode); - /// \brief Handle brush mechanics for texture selection - void selectTerrainTextures (const std::pair& texCoords, unsigned char selectMode); + /// \brief Push texture edits to command macro + void pushEditToCommand(CSMWorld::LandTexturesColumn::DataType& newLandGrid, CSMDoc::Document& document, + CSMWorld::IdTable& landTable, std::string cellId); - /// \brief Push texture edits to command macro - void pushEditToCommand (CSMWorld::LandTexturesColumn::DataType& newLandGrid, CSMDoc::Document& document, - CSMWorld::IdTable& landTable, std::string cellId); + /// \brief Create new land texture record from texture asset + void createTexture(std::string textureFileName); - /// \brief Create new land texture record from texture asset - void createTexture(std::string textureFileName); + /// \brief Create new cell and land if needed + bool allowLandTextureEditing(std::string textureFileName); - /// \brief Create new cell and land if needed - bool allowLandTextureEditing(std::string textureFileName); + std::string mCellId; + std::string mBrushTexture; + int mBrushSize; + CSVWidget::BrushShape mBrushShape; + std::unique_ptr mBrushDraw; + std::vector> mCustomBrushShape; + CSVWidget::SceneToolTextureBrush* mTextureBrushScenetool; + int mDragMode; + osg::Group* mParentNode; + bool mIsEditing; + std::shared_ptr mTerrainTextureSelection; - std::string mCellId; - std::string mBrushTexture; - int mBrushSize; - CSVWidget::BrushShape mBrushShape; - std::unique_ptr mBrushDraw; - std::vector> mCustomBrushShape; - CSVWidget::SceneToolTextureBrush *mTextureBrushScenetool; - int mDragMode; - osg::Group* mParentNode; - bool mIsEditing; - std::shared_ptr mTerrainTextureSelection; + const int cellSize{ ESM::Land::REAL_SIZE }; + const int landTextureSize{ ESM::Land::LAND_TEXTURE_SIZE }; - const int cellSize {ESM::Land::REAL_SIZE}; - const int landTextureSize {ESM::Land::LAND_TEXTURE_SIZE}; + signals: + void passBrushTexture(std::string brushTexture); - signals: - void passBrushTexture(std::string brushTexture); - - public slots: - void handleDropEvent(QDropEvent *event); - void setBrushSize(int brushSize); - void setBrushShape(CSVWidget::BrushShape brushShape); - void setBrushTexture(std::string brushShape); + public slots: + void handleDropEvent(QDropEvent* event); + void setBrushSize(int brushSize); + void setBrushShape(CSVWidget::BrushShape brushShape); + void setBrushTexture(std::string brushShape); }; } - #endif diff --git a/apps/opencs/view/render/unpagedworldspacewidget.cpp b/apps/opencs/view/render/unpagedworldspacewidget.cpp index eb0d5ce38d..98c8231cae 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.cpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.cpp @@ -18,12 +18,12 @@ void CSVRender::UnpagedWorldspaceWidget::update() { - const CSMWorld::Record& record = - dynamic_cast&> (mCellsModel->getRecord (mCellId)); + const CSMWorld::Record& record + = dynamic_cast&>(mCellsModel->getRecord(mCellId)); osg::Vec4f colour = SceneUtil::colourFromRGB(record.get().mAmbi.mAmbient); - setDefaultAmbient (colour); + setDefaultAmbient(colour); bool isInterior = (record.get().mData.mFlags & ESM::Cell::Interior) != 0; bool behaveLikeExterior = (record.get().mData.mFlags & ESM::Cell::QuasiEx) != 0; @@ -35,37 +35,38 @@ void CSVRender::UnpagedWorldspaceWidget::update() flagAsModified(); } -CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget (const std::string& cellId, CSMDoc::Document& document, QWidget* parent) -: WorldspaceWidget (document, parent), mDocument(document), mCellId (cellId) +CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget( + const std::string& cellId, CSMDoc::Document& document, QWidget* parent) + : WorldspaceWidget(document, parent) + , mDocument(document) + , mCellId(cellId) { - mCellsModel = &dynamic_cast ( - *document.getData().getTableModel (CSMWorld::UniversalId::Type_Cells)); + mCellsModel + = &dynamic_cast(*document.getData().getTableModel(CSMWorld::UniversalId::Type_Cells)); - mReferenceablesModel = &dynamic_cast ( - *document.getData().getTableModel (CSMWorld::UniversalId::Type_Referenceables)); + mReferenceablesModel = &dynamic_cast( + *document.getData().getTableModel(CSMWorld::UniversalId::Type_Referenceables)); - connect (mCellsModel, &CSMWorld::IdTable::dataChanged, - this, &UnpagedWorldspaceWidget::cellDataChanged); - connect (mCellsModel, &CSMWorld::IdTable::rowsAboutToBeRemoved, - this, &UnpagedWorldspaceWidget::cellRowsAboutToBeRemoved); + connect(mCellsModel, &CSMWorld::IdTable::dataChanged, this, &UnpagedWorldspaceWidget::cellDataChanged); + connect(mCellsModel, &CSMWorld::IdTable::rowsAboutToBeRemoved, this, + &UnpagedWorldspaceWidget::cellRowsAboutToBeRemoved); - connect (&document.getData(), &CSMWorld::Data::assetTablesChanged, - this, &UnpagedWorldspaceWidget::assetTablesChanged); + connect( + &document.getData(), &CSMWorld::Data::assetTablesChanged, this, &UnpagedWorldspaceWidget::assetTablesChanged); update(); mCell = std::make_unique(document.getData(), mRootNode, mCellId); } -void CSVRender::UnpagedWorldspaceWidget::cellDataChanged (const QModelIndex& topLeft, - const QModelIndex& bottomRight) +void CSVRender::UnpagedWorldspaceWidget::cellDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) { - int index = mCellsModel->findColumnIndex (CSMWorld::Columns::ColumnId_Modification); - QModelIndex cellIndex = mCellsModel->getModelIndex (mCellId, index); + int index = mCellsModel->findColumnIndex(CSMWorld::Columns::ColumnId_Modification); + QModelIndex cellIndex = mCellsModel->getModelIndex(mCellId, index); - if (cellIndex.row()>=topLeft.row() && cellIndex.row()<=bottomRight.row()) + if (cellIndex.row() >= topLeft.row() && cellIndex.row() <= bottomRight.row()) { - if (mCellsModel->data (cellIndex).toInt()==CSMWorld::RecordBase::State_Deleted) + if (mCellsModel->data(cellIndex).toInt() == CSMWorld::RecordBase::State_Deleted) { emit closeRequest(); } @@ -78,12 +79,11 @@ void CSVRender::UnpagedWorldspaceWidget::cellDataChanged (const QModelIndex& top } } -void CSVRender::UnpagedWorldspaceWidget::cellRowsAboutToBeRemoved (const QModelIndex& parent, - int start, int end) +void CSVRender::UnpagedWorldspaceWidget::cellRowsAboutToBeRemoved(const QModelIndex& parent, int start, int end) { - QModelIndex cellIndex = mCellsModel->getModelIndex (mCellId, 0); + QModelIndex cellIndex = mCellsModel->getModelIndex(mCellId, 0); - if (cellIndex.row()>=start && cellIndex.row()<=end) + if (cellIndex.row() >= start && cellIndex.row() <= end) emit closeRequest(); } @@ -93,12 +93,13 @@ void CSVRender::UnpagedWorldspaceWidget::assetTablesChanged() mCell->reloadAssets(); } -bool CSVRender::UnpagedWorldspaceWidget::handleDrop (const std::vector& universalIdData, DropType type) +bool CSVRender::UnpagedWorldspaceWidget::handleDrop( + const std::vector& universalIdData, DropType type) { - if (WorldspaceWidget::handleDrop (universalIdData, type)) + if (WorldspaceWidget::handleDrop(universalIdData, type)) return true; - if (type!=Type_CellsInterior) + if (type != Type_CellsInterior) return false; mCellId = universalIdData.begin()->getId(); @@ -113,41 +114,43 @@ bool CSVRender::UnpagedWorldspaceWidget::handleDrop (const std::vectorsetSelection (elementMask, Cell::Selection_Clear); + mCell->setSelection(elementMask, Cell::Selection_Clear); flagAsModified(); } -void CSVRender::UnpagedWorldspaceWidget::invertSelection (int elementMask) +void CSVRender::UnpagedWorldspaceWidget::invertSelection(int elementMask) { - mCell->setSelection (elementMask, Cell::Selection_Invert); + mCell->setSelection(elementMask, Cell::Selection_Invert); flagAsModified(); } -void CSVRender::UnpagedWorldspaceWidget::selectAll (int elementMask) +void CSVRender::UnpagedWorldspaceWidget::selectAll(int elementMask) { - mCell->setSelection (elementMask, Cell::Selection_All); + mCell->setSelection(elementMask, Cell::Selection_All); flagAsModified(); } -void CSVRender::UnpagedWorldspaceWidget::selectAllWithSameParentId (int elementMask) +void CSVRender::UnpagedWorldspaceWidget::selectAllWithSameParentId(int elementMask) { - mCell->selectAllWithSameParentId (elementMask); + mCell->selectAllWithSameParentId(elementMask); flagAsModified(); } -void CSVRender::UnpagedWorldspaceWidget::selectInsideCube(const osg::Vec3d& pointA, const osg::Vec3d& pointB, DragMode dragMode) +void CSVRender::UnpagedWorldspaceWidget::selectInsideCube( + const osg::Vec3d& pointA, const osg::Vec3d& pointB, DragMode dragMode) { - mCell->selectInsideCube (pointA, pointB, dragMode); + mCell->selectInsideCube(pointA, pointB, dragMode); } -void CSVRender::UnpagedWorldspaceWidget::selectWithinDistance(const osg::Vec3d& point, float distance, DragMode dragMode) +void CSVRender::UnpagedWorldspaceWidget::selectWithinDistance( + const osg::Vec3d& point, float distance, DragMode dragMode) { - mCell->selectWithinDistance (point, distance, dragMode); + mCell->selectWithinDistance(point, distance, dragMode); } -std::string CSVRender::UnpagedWorldspaceWidget::getCellId (const osg::Vec3f& point) const +std::string CSVRender::UnpagedWorldspaceWidget::getCellId(const osg::Vec3f& point) const { return mCellId; } @@ -162,83 +165,78 @@ CSVRender::Cell* CSVRender::UnpagedWorldspaceWidget::getCell(const CSMWorld::Cel return mCell.get(); } -std::vector > CSVRender::UnpagedWorldspaceWidget::getSelection ( +std::vector> CSVRender::UnpagedWorldspaceWidget::getSelection( unsigned int elementMask) const { - return mCell->getSelection (elementMask); + return mCell->getSelection(elementMask); } -std::vector > CSVRender::UnpagedWorldspaceWidget::getEdited ( +std::vector> CSVRender::UnpagedWorldspaceWidget::getEdited( unsigned int elementMask) const { - return mCell->getEdited (elementMask); + return mCell->getEdited(elementMask); } -void CSVRender::UnpagedWorldspaceWidget::setSubMode (int subMode, unsigned int elementMask) +void CSVRender::UnpagedWorldspaceWidget::setSubMode(int subMode, unsigned int elementMask) { - mCell->setSubMode (subMode, elementMask); + mCell->setSubMode(subMode, elementMask); } -void CSVRender::UnpagedWorldspaceWidget::reset (unsigned int elementMask) +void CSVRender::UnpagedWorldspaceWidget::reset(unsigned int elementMask) { - mCell->reset (elementMask); + mCell->reset(elementMask); } -void CSVRender::UnpagedWorldspaceWidget::referenceableDataChanged (const QModelIndex& topLeft, - const QModelIndex& bottomRight) +void CSVRender::UnpagedWorldspaceWidget::referenceableDataChanged( + const QModelIndex& topLeft, const QModelIndex& bottomRight) { if (mCell.get()) - if (mCell.get()->referenceableDataChanged (topLeft, bottomRight)) + if (mCell.get()->referenceableDataChanged(topLeft, bottomRight)) flagAsModified(); } -void CSVRender::UnpagedWorldspaceWidget::referenceableAboutToBeRemoved ( - const QModelIndex& parent, int start, int end) +void CSVRender::UnpagedWorldspaceWidget::referenceableAboutToBeRemoved(const QModelIndex& parent, int start, int end) { if (mCell.get()) - if (mCell.get()->referenceableAboutToBeRemoved (parent, start, end)) + if (mCell.get()->referenceableAboutToBeRemoved(parent, start, end)) flagAsModified(); } -void CSVRender::UnpagedWorldspaceWidget::referenceableAdded (const QModelIndex& parent, - int start, int end) +void CSVRender::UnpagedWorldspaceWidget::referenceableAdded(const QModelIndex& parent, int start, int end) { if (mCell.get()) { - QModelIndex topLeft = mReferenceablesModel->index (start, 0); - QModelIndex bottomRight = - mReferenceablesModel->index (end, mReferenceablesModel->columnCount()); + QModelIndex topLeft = mReferenceablesModel->index(start, 0); + QModelIndex bottomRight = mReferenceablesModel->index(end, mReferenceablesModel->columnCount()); - if (mCell.get()->referenceableDataChanged (topLeft, bottomRight)) + if (mCell.get()->referenceableDataChanged(topLeft, bottomRight)) flagAsModified(); } } -void CSVRender::UnpagedWorldspaceWidget::referenceDataChanged (const QModelIndex& topLeft, - const QModelIndex& bottomRight) +void CSVRender::UnpagedWorldspaceWidget::referenceDataChanged( + const QModelIndex& topLeft, const QModelIndex& bottomRight) { if (mCell.get()) - if (mCell.get()->referenceDataChanged (topLeft, bottomRight)) + if (mCell.get()->referenceDataChanged(topLeft, bottomRight)) flagAsModified(); } -void CSVRender::UnpagedWorldspaceWidget::referenceAboutToBeRemoved (const QModelIndex& parent, - int start, int end) +void CSVRender::UnpagedWorldspaceWidget::referenceAboutToBeRemoved(const QModelIndex& parent, int start, int end) { if (mCell.get()) - if (mCell.get()->referenceAboutToBeRemoved (parent, start, end)) + if (mCell.get()->referenceAboutToBeRemoved(parent, start, end)) flagAsModified(); } -void CSVRender::UnpagedWorldspaceWidget::referenceAdded (const QModelIndex& parent, int start, - int end) +void CSVRender::UnpagedWorldspaceWidget::referenceAdded(const QModelIndex& parent, int start, int end) { if (mCell.get()) - if (mCell.get()->referenceAdded (parent, start, end)) + if (mCell.get()->referenceAdded(parent, start, end)) flagAsModified(); } -void CSVRender::UnpagedWorldspaceWidget::pathgridDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) +void CSVRender::UnpagedWorldspaceWidget::pathgridDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) { const CSMWorld::SubCellCollection& pathgrids = mDocument.getData().getPathgrids(); @@ -268,7 +266,7 @@ void CSVRender::UnpagedWorldspaceWidget::pathgridDataChanged (const QModelIndex& } } -void CSVRender::UnpagedWorldspaceWidget::pathgridAboutToBeRemoved (const QModelIndex& parent, int start, int end) +void CSVRender::UnpagedWorldspaceWidget::pathgridAboutToBeRemoved(const QModelIndex& parent, int start, int end) { const CSMWorld::SubCellCollection& pathgrids = mDocument.getData().getPathgrids(); @@ -288,7 +286,7 @@ void CSVRender::UnpagedWorldspaceWidget::pathgridAboutToBeRemoved (const QModelI } } -void CSVRender::UnpagedWorldspaceWidget::pathgridAdded (const QModelIndex& parent, int start, int end) +void CSVRender::UnpagedWorldspaceWidget::pathgridAdded(const QModelIndex& parent, int start, int end) { const CSMWorld::SubCellCollection& pathgrids = mDocument.getData().getPathgrids(); @@ -307,12 +305,11 @@ void CSVRender::UnpagedWorldspaceWidget::pathgridAdded (const QModelIndex& paren } } -void CSVRender::UnpagedWorldspaceWidget::addVisibilitySelectorButtons ( - CSVWidget::SceneToolToggle2 *tool) +void CSVRender::UnpagedWorldspaceWidget::addVisibilitySelectorButtons(CSVWidget::SceneToolToggle2* tool) { - WorldspaceWidget::addVisibilitySelectorButtons (tool); - tool->addButton (Button_Terrain, Mask_Terrain, "Terrain", "", true); - tool->addButton (Button_Fog, Mask_Fog, "Fog"); + WorldspaceWidget::addVisibilitySelectorButtons(tool); + tool->addButton(Button_Terrain, Mask_Terrain, "Terrain", "", true); + tool->addButton(Button_Fog, Mask_Fog, "Fog"); } std::string CSVRender::UnpagedWorldspaceWidget::getStartupInstruction() @@ -323,22 +320,21 @@ std::string CSVRender::UnpagedWorldspaceWidget::getStartupInstruction() std::ostringstream stream; - stream - << "player->positionCell " - << position.x() << ", " << position.y() << ", " << position.z() - << ", 0, \"" << mCellId << "\""; + stream << "player->positionCell " << position.x() << ", " << position.y() << ", " << position.z() << ", 0, \"" + << mCellId << "\""; return stream.str(); } -CSVRender::WorldspaceWidget::dropRequirments CSVRender::UnpagedWorldspaceWidget::getDropRequirements (CSVRender::WorldspaceWidget::DropType type) const +CSVRender::WorldspaceWidget::dropRequirments CSVRender::UnpagedWorldspaceWidget::getDropRequirements( + CSVRender::WorldspaceWidget::DropType type) const { - dropRequirments requirements = WorldspaceWidget::getDropRequirements (type); + dropRequirments requirements = WorldspaceWidget::getDropRequirements(type); - if (requirements!=ignored) + if (requirements != ignored) return requirements; - switch(type) + switch (type) { case Type_CellsInterior: return canHandle; diff --git a/apps/opencs/view/render/unpagedworldspacewidget.hpp b/apps/opencs/view/render/unpagedworldspacewidget.hpp index 83233c3270..776dfae5f9 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.hpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.hpp @@ -1,11 +1,11 @@ #ifndef OPENCS_VIEW_UNPAGEDWORLDSPACEWIDGET_H #define OPENCS_VIEW_UNPAGEDWORLDSPACEWIDGET_H -#include #include +#include -#include "worldspacewidget.hpp" #include "cell.hpp" +#include "worldspacewidget.hpp" class QModelIndex; @@ -24,101 +24,93 @@ namespace CSVRender { class UnpagedWorldspaceWidget : public WorldspaceWidget { - Q_OBJECT - - CSMDoc::Document& mDocument; - std::string mCellId; - CSMWorld::IdTable *mCellsModel; - CSMWorld::IdTable *mReferenceablesModel; - std::unique_ptr mCell; - - void update(); - - public: + Q_OBJECT - UnpagedWorldspaceWidget (const std::string& cellId, CSMDoc::Document& document, - QWidget *parent); + CSMDoc::Document& mDocument; + std::string mCellId; + CSMWorld::IdTable* mCellsModel; + CSMWorld::IdTable* mReferenceablesModel; + std::unique_ptr mCell; - dropRequirments getDropRequirements(DropType type) const override; + void update(); - /// \return Drop handled? - bool handleDrop (const std::vector& data, - DropType type) override; + public: + UnpagedWorldspaceWidget(const std::string& cellId, CSMDoc::Document& document, QWidget* parent); - /// \param elementMask Elements to be affected by the clear operation - void clearSelection (int elementMask) override; + dropRequirments getDropRequirements(DropType type) const override; - /// \param elementMask Elements to be affected by the select operation - void invertSelection (int elementMask) override; + /// \return Drop handled? + bool handleDrop(const std::vector& data, DropType type) override; - /// \param elementMask Elements to be affected by the select operation - void selectAll (int elementMask) override; + /// \param elementMask Elements to be affected by the clear operation + void clearSelection(int elementMask) override; - // Select everything that references the same ID as at least one of the elements - // already selected - // - /// \param elementMask Elements to be affected by the select operation - void selectAllWithSameParentId (int elementMask) override; + /// \param elementMask Elements to be affected by the select operation + void invertSelection(int elementMask) override; - void selectInsideCube(const osg::Vec3d& pointA, const osg::Vec3d& pointB, DragMode dragMode) override; + /// \param elementMask Elements to be affected by the select operation + void selectAll(int elementMask) override; - void selectWithinDistance(const osg::Vec3d& point, float distance, DragMode dragMode) override; + // Select everything that references the same ID as at least one of the elements + // already selected + // + /// \param elementMask Elements to be affected by the select operation + void selectAllWithSameParentId(int elementMask) override; - std::string getCellId (const osg::Vec3f& point) const override; + void selectInsideCube(const osg::Vec3d& pointA, const osg::Vec3d& pointB, DragMode dragMode) override; - Cell* getCell(const osg::Vec3d& point) const override; + void selectWithinDistance(const osg::Vec3d& point, float distance, DragMode dragMode) override; - Cell* getCell(const CSMWorld::CellCoordinates& coords) const override; + std::string getCellId(const osg::Vec3f& point) const override; - std::vector > getSelection (unsigned int elementMask) - const override; + Cell* getCell(const osg::Vec3d& point) const override; - std::vector > getEdited (unsigned int elementMask) - const override; + Cell* getCell(const CSMWorld::CellCoordinates& coords) const override; - void setSubMode (int subMode, unsigned int elementMask) override; + std::vector> getSelection(unsigned int elementMask) const override; - /// Erase all overrides and restore the visual representation to its true state. - void reset (unsigned int elementMask) override; + std::vector> getEdited(unsigned int elementMask) const override; - private: + void setSubMode(int subMode, unsigned int elementMask) override; - void referenceableDataChanged (const QModelIndex& topLeft, - const QModelIndex& bottomRight) override; + /// Erase all overrides and restore the visual representation to its true state. + void reset(unsigned int elementMask) override; - void referenceableAboutToBeRemoved (const QModelIndex& parent, int start, int end) override; + private: + void referenceableDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) override; - void referenceableAdded (const QModelIndex& index, int start, int end) override; + void referenceableAboutToBeRemoved(const QModelIndex& parent, int start, int end) override; - void referenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) override; + void referenceableAdded(const QModelIndex& index, int start, int end) override; - void referenceAboutToBeRemoved (const QModelIndex& parent, int start, int end) override; + void referenceDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) override; - void referenceAdded (const QModelIndex& index, int start, int end) override; + void referenceAboutToBeRemoved(const QModelIndex& parent, int start, int end) override; - void pathgridDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) override; + void referenceAdded(const QModelIndex& index, int start, int end) override; - void pathgridAboutToBeRemoved (const QModelIndex& parent, int start, int end) override; + void pathgridDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) override; - void pathgridAdded (const QModelIndex& parent, int start, int end) override; + void pathgridAboutToBeRemoved(const QModelIndex& parent, int start, int end) override; - std::string getStartupInstruction() override; + void pathgridAdded(const QModelIndex& parent, int start, int end) override; - protected: + std::string getStartupInstruction() override; - void addVisibilitySelectorButtons (CSVWidget::SceneToolToggle2 *tool) override; + protected: + void addVisibilitySelectorButtons(CSVWidget::SceneToolToggle2* tool) override; - private slots: + private slots: - void cellDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); + void cellDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); - void cellRowsAboutToBeRemoved (const QModelIndex& parent, int start, int end); + void cellRowsAboutToBeRemoved(const QModelIndex& parent, int start, int end); - void assetTablesChanged (); + void assetTablesChanged(); - signals: + signals: - void cellChanged(const CSMWorld::UniversalId& id); + void cellChanged(const CSMWorld::UniversalId& id); }; } diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 11fe7c6717..ccc884bdeb 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -10,9 +10,9 @@ #include -#include "../../model/world/universalid.hpp" #include "../../model/world/idtable.hpp" #include "../../model/world/tablemimedata.hpp" +#include "../../model/world/universalid.hpp" #include "../../model/prefs/shortcut.hpp" #include "../../model/prefs/state.hpp" @@ -20,125 +20,107 @@ #include "../render/orbitcameramode.hpp" #include "../widget/scenetoolmode.hpp" -#include "../widget/scenetooltoggle2.hpp" #include "../widget/scenetoolrun.hpp" +#include "../widget/scenetooltoggle2.hpp" -#include "object.hpp" -#include "mask.hpp" +#include "cameracontroller.hpp" #include "instancemode.hpp" +#include "mask.hpp" +#include "object.hpp" #include "pathgridmode.hpp" -#include "cameracontroller.hpp" -CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidget* parent) - : SceneWidget (document.getData().getResourceSystem(), parent, Qt::WindowFlags(), false) +CSVRender::WorldspaceWidget::WorldspaceWidget(CSMDoc::Document& document, QWidget* parent) + : SceneWidget(document.getData().getResourceSystem(), parent, Qt::WindowFlags(), false) , mSceneElements(nullptr) , mRun(nullptr) , mDocument(document) - , mInteractionMask (0) - , mEditMode (nullptr) - , mLocked (false) + , mInteractionMask(0) + , mEditMode(nullptr) + , mLocked(false) , mDragMode(InteractionType_None) - , mDragging (false) + , mDragging(false) , mDragX(0) , mDragY(0) , mSpeedMode(false) , mDragFactor(0) , mDragWheelFactor(0) , mDragShiftFactor(0) - , mToolTipPos (-1, -1) + , mToolTipPos(-1, -1) , mShowToolTips(false) , mToolTipDelay(0) , mInConstructor(true) { setAcceptDrops(true); - QAbstractItemModel *referenceables = - document.getData().getTableModel (CSMWorld::UniversalId::Type_Referenceables); + QAbstractItemModel* referenceables = document.getData().getTableModel(CSMWorld::UniversalId::Type_Referenceables); - connect (referenceables, &QAbstractItemModel::dataChanged, - this, &WorldspaceWidget::referenceableDataChanged); - connect (referenceables, &QAbstractItemModel::rowsAboutToBeRemoved, - this, &WorldspaceWidget::referenceableAboutToBeRemoved); - connect (referenceables, &QAbstractItemModel::rowsInserted, - this, &WorldspaceWidget::referenceableAdded); + connect(referenceables, &QAbstractItemModel::dataChanged, this, &WorldspaceWidget::referenceableDataChanged); + connect(referenceables, &QAbstractItemModel::rowsAboutToBeRemoved, this, + &WorldspaceWidget::referenceableAboutToBeRemoved); + connect(referenceables, &QAbstractItemModel::rowsInserted, this, &WorldspaceWidget::referenceableAdded); - QAbstractItemModel *references = - document.getData().getTableModel (CSMWorld::UniversalId::Type_References); + QAbstractItemModel* references = document.getData().getTableModel(CSMWorld::UniversalId::Type_References); - connect (references, &QAbstractItemModel::dataChanged, - this, &WorldspaceWidget::referenceDataChanged); - connect (references, &QAbstractItemModel::rowsAboutToBeRemoved, - this, &WorldspaceWidget::referenceAboutToBeRemoved); - connect (references, &QAbstractItemModel::rowsInserted, - this, &WorldspaceWidget::referenceAdded); + connect(references, &QAbstractItemModel::dataChanged, this, &WorldspaceWidget::referenceDataChanged); + connect(references, &QAbstractItemModel::rowsAboutToBeRemoved, this, &WorldspaceWidget::referenceAboutToBeRemoved); + connect(references, &QAbstractItemModel::rowsInserted, this, &WorldspaceWidget::referenceAdded); - QAbstractItemModel *pathgrids = document.getData().getTableModel (CSMWorld::UniversalId::Type_Pathgrids); + QAbstractItemModel* pathgrids = document.getData().getTableModel(CSMWorld::UniversalId::Type_Pathgrids); - connect (pathgrids, &QAbstractItemModel::dataChanged, - this, &WorldspaceWidget::pathgridDataChanged); - connect (pathgrids, &QAbstractItemModel::rowsAboutToBeRemoved, - this, &WorldspaceWidget::pathgridAboutToBeRemoved); - connect (pathgrids, &QAbstractItemModel::rowsInserted, - this, &WorldspaceWidget::pathgridAdded); + connect(pathgrids, &QAbstractItemModel::dataChanged, this, &WorldspaceWidget::pathgridDataChanged); + connect(pathgrids, &QAbstractItemModel::rowsAboutToBeRemoved, this, &WorldspaceWidget::pathgridAboutToBeRemoved); + connect(pathgrids, &QAbstractItemModel::rowsInserted, this, &WorldspaceWidget::pathgridAdded); - QAbstractItemModel *debugProfiles = - document.getData().getTableModel (CSMWorld::UniversalId::Type_DebugProfiles); + QAbstractItemModel* debugProfiles = document.getData().getTableModel(CSMWorld::UniversalId::Type_DebugProfiles); - connect (debugProfiles, &QAbstractItemModel::dataChanged, - this, &WorldspaceWidget::debugProfileDataChanged); - connect (debugProfiles, &QAbstractItemModel::rowsAboutToBeRemoved, - this, &WorldspaceWidget::debugProfileAboutToBeRemoved); + connect(debugProfiles, &QAbstractItemModel::dataChanged, this, &WorldspaceWidget::debugProfileDataChanged); + connect(debugProfiles, &QAbstractItemModel::rowsAboutToBeRemoved, this, + &WorldspaceWidget::debugProfileAboutToBeRemoved); - mToolTipDelayTimer.setSingleShot (true); - connect (&mToolTipDelayTimer, &QTimer::timeout, this, &WorldspaceWidget::showToolTip); + mToolTipDelayTimer.setSingleShot(true); + connect(&mToolTipDelayTimer, &QTimer::timeout, this, &WorldspaceWidget::showToolTip); CSMPrefs::get()["3D Scene Input"].update(); CSMPrefs::get()["Tooltips"].update(); // Shortcuts - CSMPrefs::Shortcut* primaryEditShortcut = new CSMPrefs::Shortcut("scene-edit-primary", "scene-speed-modifier", - CSMPrefs::Shortcut::SM_Detach, this); + CSMPrefs::Shortcut* primaryEditShortcut + = new CSMPrefs::Shortcut("scene-edit-primary", "scene-speed-modifier", CSMPrefs::Shortcut::SM_Detach, this); CSMPrefs::Shortcut* primaryOpenShortcut = new CSMPrefs::Shortcut("scene-open-primary", this); - connect(primaryOpenShortcut, qOverload(&CSMPrefs::Shortcut::activated), - this, &WorldspaceWidget::primaryOpen); - connect(primaryEditShortcut, qOverload(&CSMPrefs::Shortcut::activated), - this, &WorldspaceWidget::primaryEdit); - connect(primaryEditShortcut, qOverload(&CSMPrefs::Shortcut::secondary), - this, &WorldspaceWidget::speedMode); + connect(primaryOpenShortcut, qOverload(&CSMPrefs::Shortcut::activated), this, &WorldspaceWidget::primaryOpen); + connect(primaryEditShortcut, qOverload(&CSMPrefs::Shortcut::activated), this, &WorldspaceWidget::primaryEdit); + connect(primaryEditShortcut, qOverload(&CSMPrefs::Shortcut::secondary), this, &WorldspaceWidget::speedMode); CSMPrefs::Shortcut* secondaryEditShortcut = new CSMPrefs::Shortcut("scene-edit-secondary", this); - connect(secondaryEditShortcut, qOverload(&CSMPrefs::Shortcut::activated), - this, &WorldspaceWidget::secondaryEdit); + connect( + secondaryEditShortcut, qOverload(&CSMPrefs::Shortcut::activated), this, &WorldspaceWidget::secondaryEdit); CSMPrefs::Shortcut* primarySelectShortcut = new CSMPrefs::Shortcut("scene-select-primary", this); - connect(primarySelectShortcut, qOverload(&CSMPrefs::Shortcut::activated), - this, &WorldspaceWidget::primarySelect); + connect( + primarySelectShortcut, qOverload(&CSMPrefs::Shortcut::activated), this, &WorldspaceWidget::primarySelect); CSMPrefs::Shortcut* secondarySelectShortcut = new CSMPrefs::Shortcut("scene-select-secondary", this); - connect(secondarySelectShortcut, qOverload(&CSMPrefs::Shortcut::activated), - this, &WorldspaceWidget::secondarySelect); + connect(secondarySelectShortcut, qOverload(&CSMPrefs::Shortcut::activated), this, + &WorldspaceWidget::secondarySelect); CSMPrefs::Shortcut* abortShortcut = new CSMPrefs::Shortcut("scene-edit-abort", this); - connect(abortShortcut, qOverload<>(&CSMPrefs::Shortcut::activated), - this, &WorldspaceWidget::abortDrag); + connect(abortShortcut, qOverload<>(&CSMPrefs::Shortcut::activated), this, &WorldspaceWidget::abortDrag); mInConstructor = false; } -CSVRender::WorldspaceWidget::~WorldspaceWidget () -{ -} +CSVRender::WorldspaceWidget::~WorldspaceWidget() {} -void CSVRender::WorldspaceWidget::settingChanged (const CSMPrefs::Setting *setting) +void CSVRender::WorldspaceWidget::settingChanged(const CSMPrefs::Setting* setting) { - if (*setting=="3D Scene Input/drag-factor") + if (*setting == "3D Scene Input/drag-factor") mDragFactor = setting->toDouble(); - else if (*setting=="3D Scene Input/drag-wheel-factor") + else if (*setting == "3D Scene Input/drag-wheel-factor") mDragWheelFactor = setting->toDouble(); - else if (*setting=="3D Scene Input/drag-shift-factor") + else if (*setting == "3D Scene Input/drag-shift-factor") mDragShiftFactor = setting->toDouble(); - else if (*setting=="Rendering/object-marker-alpha" && !mInConstructor) + else if (*setting == "Rendering/object-marker-alpha" && !mInConstructor) { float alpha = setting->toDouble(); // getSelection is virtual, thus this can not be called from the constructor @@ -149,16 +131,15 @@ void CSVRender::WorldspaceWidget::settingChanged (const CSMPrefs::Setting *setti objTag->mObject->setMarkerTransparency(alpha); } } - else if (*setting=="Tooltips/scene-delay") + else if (*setting == "Tooltips/scene-delay") mToolTipDelay = setting->toInt(); - else if (*setting=="Tooltips/scene") + else if (*setting == "Tooltips/scene") mShowToolTips = setting->isTrue(); else SceneWidget::settingChanged(setting); } - -void CSVRender::WorldspaceWidget::useViewHint (const std::string& hint) {} +void CSVRender::WorldspaceWidget::useViewHint(const std::string& hint) {} void CSVRender::WorldspaceWidget::selectDefaultNavigationMode() { @@ -167,25 +148,24 @@ void CSVRender::WorldspaceWidget::selectDefaultNavigationMode() void CSVRender::WorldspaceWidget::centerOrbitCameraOnSelection() { - std::vector > selection = getSelection(~0u); + std::vector> selection = getSelection(~0u); - for (std::vector >::iterator it = selection.begin(); it!=selection.end(); ++it) + for (std::vector>::iterator it = selection.begin(); it != selection.end(); ++it) { - if (CSVRender::ObjectTag *objectTag = dynamic_cast (it->get())) + if (CSVRender::ObjectTag* objectTag = dynamic_cast(it->get())) { mOrbitCamControl->setCenter(objectTag->mObject->getPosition().asVec3()); } } } -CSVWidget::SceneToolMode *CSVRender::WorldspaceWidget::makeNavigationSelector ( - CSVWidget::SceneToolbar *parent) +CSVWidget::SceneToolMode* CSVRender::WorldspaceWidget::makeNavigationSelector(CSVWidget::SceneToolbar* parent) { - CSVWidget::SceneToolMode *tool = new CSVWidget::SceneToolMode (parent, "Camera Mode"); + CSVWidget::SceneToolMode* tool = new CSVWidget::SceneToolMode(parent, "Camera Mode"); /// \todo replace icons /// \todo consider user-defined button-mapping - tool->addButton (":scenetoolbar/1st-person", "1st", + tool->addButton(":scenetoolbar/1st-person", "1st", "First Person" "
        • Camera is held upright
        • " "
        • Mouse-Look while holding {scene-navi-primary}
        • " @@ -194,7 +174,7 @@ CSVWidget::SceneToolMode *CSVRender::WorldspaceWidget::makeNavigationSelector ( "
        • Mouse wheel moves the camera forward/backward
        • " "
        • Hold {scene-speed-modifier} to speed up movement
        • " "
        "); - tool->addButton (":scenetoolbar/free-camera", "free", + tool->addButton(":scenetoolbar/free-camera", "free", "Free Camera" "
        • Mouse-Look while holding {scene-navi-primary}
        • " "
        • Movement keys: {free-forward}(forward), {free-left}(left), {free-backward}(back), {free-right}(right)
        • " @@ -208,131 +188,123 @@ CSVWidget::SceneToolMode *CSVRender::WorldspaceWidget::makeNavigationSelector ( "Orbiting Camera" "
          • Always facing the centre point
          • " "
          • Rotate around the centre point via {orbit-up}, {orbit-left}, {orbit-down}, {orbit-right} or by moving " - "the mouse while holding {scene-navi-primary}
          • " + "the mouse while holding {scene-navi-primary}" "
          • Roll camera with {orbit-roll-left} and {orbit-roll-right} keys
          • " - "
          • Strafing (also vertically) by holding {scene-navi-secondary} (includes relocation of the centre point)
          • " + "
          • Strafing (also vertically) by holding {scene-navi-secondary} (includes relocation of the centre " + "point)
          • " "
          • Mouse wheel moves camera away or towards centre point but can not pass through it
          • " "
          • Hold {scene-speed-modifier} to speed up movement
          • " - "
          ", tool), + "
        ", + tool), "orbit"); - connect (tool, &CSVWidget::SceneToolMode::modeChanged, - this, &WorldspaceWidget::selectNavigationMode); + connect(tool, &CSVWidget::SceneToolMode::modeChanged, this, &WorldspaceWidget::selectNavigationMode); return tool; } -CSVWidget::SceneToolToggle2 *CSVRender::WorldspaceWidget::makeSceneVisibilitySelector (CSVWidget::SceneToolbar *parent) +CSVWidget::SceneToolToggle2* CSVRender::WorldspaceWidget::makeSceneVisibilitySelector(CSVWidget::SceneToolbar* parent) { - mSceneElements = new CSVWidget::SceneToolToggle2 (parent, - "Scene Element Visibility", ":scenetoolbar/scene-view-c", ":scenetoolbar/scene-view-"); + mSceneElements = new CSVWidget::SceneToolToggle2( + parent, "Scene Element Visibility", ":scenetoolbar/scene-view-c", ":scenetoolbar/scene-view-"); - addVisibilitySelectorButtons (mSceneElements); + addVisibilitySelectorButtons(mSceneElements); - mSceneElements->setSelectionMask (0xffffffff); + mSceneElements->setSelectionMask(0xffffffff); - connect (mSceneElements, &CSVWidget::SceneToolToggle2::selectionChanged, - this, &WorldspaceWidget::elementSelectionChanged); + connect(mSceneElements, &CSVWidget::SceneToolToggle2::selectionChanged, this, + &WorldspaceWidget::elementSelectionChanged); return mSceneElements; } -CSVWidget::SceneToolRun *CSVRender::WorldspaceWidget::makeRunTool ( - CSVWidget::SceneToolbar *parent) +CSVWidget::SceneToolRun* CSVRender::WorldspaceWidget::makeRunTool(CSVWidget::SceneToolbar* parent) { - CSMWorld::IdTable& debugProfiles = dynamic_cast ( - *mDocument.getData().getTableModel (CSMWorld::UniversalId::Type_DebugProfiles)); + CSMWorld::IdTable& debugProfiles = dynamic_cast( + *mDocument.getData().getTableModel(CSMWorld::UniversalId::Type_DebugProfiles)); std::vector profiles; - int idColumn = debugProfiles.findColumnIndex (CSMWorld::Columns::ColumnId_Id); - int stateColumn = debugProfiles.findColumnIndex (CSMWorld::Columns::ColumnId_Modification); - int defaultColumn = debugProfiles.findColumnIndex ( - CSMWorld::Columns::ColumnId_DefaultProfile); + int idColumn = debugProfiles.findColumnIndex(CSMWorld::Columns::ColumnId_Id); + int stateColumn = debugProfiles.findColumnIndex(CSMWorld::Columns::ColumnId_Modification); + int defaultColumn = debugProfiles.findColumnIndex(CSMWorld::Columns::ColumnId_DefaultProfile); int size = debugProfiles.rowCount(); - for (int i=0; i& data) +CSVRender::WorldspaceWidget::DropType CSVRender::WorldspaceWidget::getDropType( + const std::vector& data) { DropType output = Type_Other; - for (std::vector::const_iterator iter (data.begin()); - iter!=data.end(); ++iter) + for (std::vector::const_iterator iter(data.begin()); iter != data.end(); ++iter) { DropType type = Type_Other; - if (iter->getType()==CSMWorld::UniversalId::Type_Cell || - iter->getType()==CSMWorld::UniversalId::Type_Cell_Missing) + if (iter->getType() == CSMWorld::UniversalId::Type_Cell + || iter->getType() == CSMWorld::UniversalId::Type_Cell_Missing) { - type = iter->getId().substr (0, 1)=="#" ? Type_CellsExterior : Type_CellsInterior; + type = iter->getId().substr(0, 1) == "#" ? Type_CellsExterior : Type_CellsInterior; } - else if (iter->getType()==CSMWorld::UniversalId::Type_DebugProfile) + else if (iter->getType() == CSMWorld::UniversalId::Type_DebugProfile) type = Type_DebugProfile; - if (iter==data.begin()) + if (iter == data.begin()) output = type; - else if (output!=type) // mixed types -> ignore + else if (output != type) // mixed types -> ignore return Type_Other; } return output; } -CSVRender::WorldspaceWidget::dropRequirments - CSVRender::WorldspaceWidget::getDropRequirements (DropType type) const +CSVRender::WorldspaceWidget::dropRequirments CSVRender::WorldspaceWidget::getDropRequirements(DropType type) const { - if (type==Type_DebugProfile) + if (type == Type_DebugProfile) return canHandle; return ignored; } -bool CSVRender::WorldspaceWidget::handleDrop (const std::vector& universalIdData, - DropType type) +bool CSVRender::WorldspaceWidget::handleDrop(const std::vector& universalIdData, DropType type) { - if (type==Type_DebugProfile) + if (type == Type_DebugProfile) { if (mRun) { - for (std::vector::const_iterator iter (universalIdData.begin()); - iter!=universalIdData.end(); ++iter) - mRun->addProfile (iter->getId()); + for (std::vector::const_iterator iter(universalIdData.begin()); + iter != universalIdData.end(); ++iter) + mRun->addProfile(iter->getId()); } return true; @@ -346,7 +318,7 @@ unsigned int CSVRender::WorldspaceWidget::getVisibilityMask() const return mSceneElements->getSelectionMask(); } -void CSVRender::WorldspaceWidget::setInteractionMask (unsigned int mask) +void CSVRender::WorldspaceWidget::setInteractionMask(unsigned int mask) { mInteractionMask = mask | Mask_CellMarker | Mask_CellArrow; } @@ -356,24 +328,23 @@ unsigned int CSVRender::WorldspaceWidget::getInteractionMask() const return mInteractionMask & getVisibilityMask(); } -void CSVRender::WorldspaceWidget::setEditLock (bool locked) +void CSVRender::WorldspaceWidget::setEditLock(bool locked) { - dynamic_cast (*mEditMode->getCurrent()).setEditLock (locked); + dynamic_cast(*mEditMode->getCurrent()).setEditLock(locked); } -void CSVRender::WorldspaceWidget::addVisibilitySelectorButtons ( - CSVWidget::SceneToolToggle2 *tool) +void CSVRender::WorldspaceWidget::addVisibilitySelectorButtons(CSVWidget::SceneToolToggle2* tool) { - tool->addButton (Button_Reference, Mask_Reference, "Instances"); - tool->addButton (Button_Water, Mask_Water, "Water"); - tool->addButton (Button_Pathgrid, Mask_Pathgrid, "Pathgrid"); + tool->addButton(Button_Reference, Mask_Reference, "Instances"); + tool->addButton(Button_Water, Mask_Water, "Water"); + tool->addButton(Button_Pathgrid, Mask_Pathgrid, "Pathgrid"); } -void CSVRender::WorldspaceWidget::addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool) +void CSVRender::WorldspaceWidget::addEditModeSelectorButtons(CSVWidget::SceneToolMode* tool) { /// \todo replace EditMode with suitable subclasses - tool->addButton (new InstanceMode (this, mRootNode, tool), "object"); - tool->addButton (new PathgridMode (this, tool), "pathgrid"); + tool->addButton(new InstanceMode(this, mRootNode, tool), "object"); + tool->addButton(new PathgridMode(this, tool), "pathgrid"); } CSMDoc::Document& CSVRender::WorldspaceWidget::getDocument() @@ -381,8 +352,8 @@ CSMDoc::Document& CSVRender::WorldspaceWidget::getDocument() return mDocument; } -CSVRender::WorldspaceHitResult CSVRender::WorldspaceWidget::mousePick (const QPoint& localPos, - unsigned int interactionMask) const +CSVRender::WorldspaceHitResult CSVRender::WorldspaceWidget::mousePick( + const QPoint& localPos, unsigned int interactionMask) const { // (0,0) is considered the lower left corner of an OpenGL window int x = localPos.x(); @@ -390,18 +361,18 @@ CSVRender::WorldspaceHitResult CSVRender::WorldspaceWidget::mousePick (const QPo // Convert from screen space to world space osg::Matrixd wpvMat; - wpvMat.preMult (mView->getCamera()->getViewport()->computeWindowMatrix()); - wpvMat.preMult (mView->getCamera()->getProjectionMatrix()); - wpvMat.preMult (mView->getCamera()->getViewMatrix()); - wpvMat = osg::Matrixd::inverse (wpvMat); + wpvMat.preMult(mView->getCamera()->getViewport()->computeWindowMatrix()); + wpvMat.preMult(mView->getCamera()->getProjectionMatrix()); + wpvMat.preMult(mView->getCamera()->getViewMatrix()); + wpvMat = osg::Matrixd::inverse(wpvMat); - osg::Vec3d start = wpvMat.preMult (osg::Vec3d(x, y, 0)); - osg::Vec3d end = wpvMat.preMult (osg::Vec3d(x, y, 1)); + osg::Vec3d start = wpvMat.preMult(osg::Vec3d(x, y, 0)); + osg::Vec3d end = wpvMat.preMult(osg::Vec3d(x, y, 1)); osg::Vec3d direction = end - start; // Get intersection - osg::ref_ptr intersector (new osgUtil::LineSegmentIntersector( - osgUtil::Intersector::MODEL, start, end)); + osg::ref_ptr intersector( + new osgUtil::LineSegmentIntersector(osgUtil::Intersector::MODEL, start, end)); intersector->setIntersectionLimit(osgUtil::LineSegmentIntersector::NO_LIMIT); osgUtil::IntersectionVisitor visitor(intersector); @@ -422,10 +393,11 @@ CSVRender::WorldspaceHitResult CSVRender::WorldspaceWidget::mousePick (const QPo continue; } - for (std::vector::iterator nodeIter = intersection.nodePath.begin(); nodeIter != intersection.nodePath.end(); ++nodeIter) + for (std::vector::iterator nodeIter = intersection.nodePath.begin(); + nodeIter != intersection.nodePath.end(); ++nodeIter) { osg::Node* node = *nodeIter; - if (osg::ref_ptr tag = dynamic_cast(node->getUserData())) + if (osg::ref_ptr tag = dynamic_cast(node->getUserData())) { WorldspaceHitResult hit = { true, tag, 0, 0, 0, intersection.getWorldIntersectPoint() }; if (intersection.indexList.size() >= 3) @@ -457,114 +429,111 @@ CSVRender::WorldspaceHitResult CSVRender::WorldspaceWidget::mousePick (const QPo return hit; } -CSVRender::EditMode *CSVRender::WorldspaceWidget::getEditMode() +CSVRender::EditMode* CSVRender::WorldspaceWidget::getEditMode() { - return dynamic_cast (mEditMode->getCurrent()); + return dynamic_cast(mEditMode->getCurrent()); } void CSVRender::WorldspaceWidget::abortDrag() { if (mDragging) { - EditMode& editMode = dynamic_cast (*mEditMode->getCurrent()); + EditMode& editMode = dynamic_cast(*mEditMode->getCurrent()); editMode.dragAborted(); mDragMode = InteractionType_None; } } -void CSVRender::WorldspaceWidget::dragEnterEvent (QDragEnterEvent* event) +void CSVRender::WorldspaceWidget::dragEnterEvent(QDragEnterEvent* event) { - const CSMWorld::TableMimeData* mime = dynamic_cast (event->mimeData()); + const CSMWorld::TableMimeData* mime = dynamic_cast(event->mimeData()); if (!mime) // May happen when non-records (e.g. plain text) are dragged and dropped return; - if (mime->fromDocument (mDocument)) + if (mime->fromDocument(mDocument)) { - if (mime->holdsType (CSMWorld::UniversalId::Type_Cell) || - mime->holdsType (CSMWorld::UniversalId::Type_Cell_Missing) || - mime->holdsType (CSMWorld::UniversalId::Type_DebugProfile)) + if (mime->holdsType(CSMWorld::UniversalId::Type_Cell) + || mime->holdsType(CSMWorld::UniversalId::Type_Cell_Missing) + || mime->holdsType(CSMWorld::UniversalId::Type_DebugProfile)) { // These drops are handled through the subview object. event->accept(); } else - dynamic_cast (*mEditMode->getCurrent()).dragEnterEvent (event); + dynamic_cast(*mEditMode->getCurrent()).dragEnterEvent(event); } } -void CSVRender::WorldspaceWidget::dragMoveEvent(QDragMoveEvent *event) +void CSVRender::WorldspaceWidget::dragMoveEvent(QDragMoveEvent* event) { - const CSMWorld::TableMimeData* mime = dynamic_cast (event->mimeData()); + const CSMWorld::TableMimeData* mime = dynamic_cast(event->mimeData()); if (!mime) // May happen when non-records (e.g. plain text) are dragged and dropped return; - if (mime->fromDocument (mDocument)) + if (mime->fromDocument(mDocument)) { - if (mime->holdsType (CSMWorld::UniversalId::Type_Cell) || - mime->holdsType (CSMWorld::UniversalId::Type_Cell_Missing) || - mime->holdsType (CSMWorld::UniversalId::Type_DebugProfile)) + if (mime->holdsType(CSMWorld::UniversalId::Type_Cell) + || mime->holdsType(CSMWorld::UniversalId::Type_Cell_Missing) + || mime->holdsType(CSMWorld::UniversalId::Type_DebugProfile)) { // These drops are handled through the subview object. event->accept(); } else - dynamic_cast (*mEditMode->getCurrent()).dragMoveEvent (event); + dynamic_cast(*mEditMode->getCurrent()).dragMoveEvent(event); } } -void CSVRender::WorldspaceWidget::dropEvent (QDropEvent* event) +void CSVRender::WorldspaceWidget::dropEvent(QDropEvent* event) { - const CSMWorld::TableMimeData* mime = dynamic_cast (event->mimeData()); + const CSMWorld::TableMimeData* mime = dynamic_cast(event->mimeData()); if (!mime) // May happen when non-records (e.g. plain text) are dragged and dropped return; - if (mime->fromDocument (mDocument)) + if (mime->fromDocument(mDocument)) { - if (mime->holdsType (CSMWorld::UniversalId::Type_Cell) || - mime->holdsType (CSMWorld::UniversalId::Type_Cell_Missing) || - mime->holdsType (CSMWorld::UniversalId::Type_DebugProfile)) + if (mime->holdsType(CSMWorld::UniversalId::Type_Cell) + || mime->holdsType(CSMWorld::UniversalId::Type_Cell_Missing) + || mime->holdsType(CSMWorld::UniversalId::Type_DebugProfile)) { emit dataDropped(mime->getData()); } else - dynamic_cast (*mEditMode->getCurrent()).dropEvent (event); + dynamic_cast(*mEditMode->getCurrent()).dropEvent(event); } } -void CSVRender::WorldspaceWidget::runRequest (const std::string& profile) +void CSVRender::WorldspaceWidget::runRequest(const std::string& profile) { - mDocument.startRunning (profile, getStartupInstruction()); + mDocument.startRunning(profile, getStartupInstruction()); } -void CSVRender::WorldspaceWidget::debugProfileDataChanged (const QModelIndex& topLeft, - const QModelIndex& bottomRight) +void CSVRender::WorldspaceWidget::debugProfileDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) { if (!mRun) return; - CSMWorld::IdTable& debugProfiles = dynamic_cast ( - *mDocument.getData().getTableModel (CSMWorld::UniversalId::Type_DebugProfiles)); + CSMWorld::IdTable& debugProfiles = dynamic_cast( + *mDocument.getData().getTableModel(CSMWorld::UniversalId::Type_DebugProfiles)); - int idColumn = debugProfiles.findColumnIndex (CSMWorld::Columns::ColumnId_Id); - int stateColumn = debugProfiles.findColumnIndex (CSMWorld::Columns::ColumnId_Modification); + int idColumn = debugProfiles.findColumnIndex(CSMWorld::Columns::ColumnId_Id); + int stateColumn = debugProfiles.findColumnIndex(CSMWorld::Columns::ColumnId_Modification); - for (int i=topLeft.row(); i<=bottomRight.row(); ++i) + for (int i = topLeft.row(); i <= bottomRight.row(); ++i) { - int state = debugProfiles.data (debugProfiles.index (i, stateColumn)).toInt(); + int state = debugProfiles.data(debugProfiles.index(i, stateColumn)).toInt(); // As of version 0.33 this case can not happen because debug profiles exist only in // project or session scope, which means they will never be in deleted state. But we // are adding the code for the sake of completeness and to avoid surprises if debug // profile ever get extended to content scope. - if (state==CSMWorld::RecordBase::State_Deleted) - mRun->removeProfile (debugProfiles.data ( - debugProfiles.index (i, idColumn)).toString().toUtf8().constData()); + if (state == CSMWorld::RecordBase::State_Deleted) + mRun->removeProfile(debugProfiles.data(debugProfiles.index(i, idColumn)).toString().toUtf8().constData()); } } -void CSVRender::WorldspaceWidget::debugProfileAboutToBeRemoved (const QModelIndex& parent, - int start, int end) +void CSVRender::WorldspaceWidget::debugProfileAboutToBeRemoved(const QModelIndex& parent, int start, int end) { if (parent.isValid()) return; @@ -572,21 +541,20 @@ void CSVRender::WorldspaceWidget::debugProfileAboutToBeRemoved (const QModelInde if (!mRun) return; - CSMWorld::IdTable& debugProfiles = dynamic_cast ( - *mDocument.getData().getTableModel (CSMWorld::UniversalId::Type_DebugProfiles)); + CSMWorld::IdTable& debugProfiles = dynamic_cast( + *mDocument.getData().getTableModel(CSMWorld::UniversalId::Type_DebugProfiles)); - int idColumn = debugProfiles.findColumnIndex (CSMWorld::Columns::ColumnId_Id); + int idColumn = debugProfiles.findColumnIndex(CSMWorld::Columns::ColumnId_Id); - for (int i=start; i<=end; ++i) + for (int i = start; i <= end; ++i) { - mRun->removeProfile (debugProfiles.data ( - debugProfiles.index (i, idColumn)).toString().toUtf8().constData()); + mRun->removeProfile(debugProfiles.data(debugProfiles.index(i, idColumn)).toString().toUtf8().constData()); } } -void CSVRender::WorldspaceWidget::editModeChanged (const std::string& id) +void CSVRender::WorldspaceWidget::editModeChanged(const std::string& id) { - dynamic_cast (*mEditMode->getCurrent()).setEditLock (mLocked); + dynamic_cast(*mEditMode->getCurrent()).setEditLock(mLocked); mDragging = false; mDragMode = InteractionType_None; } @@ -597,7 +565,7 @@ void CSVRender::WorldspaceWidget::showToolTip() { QPoint pos = QCursor::pos(); - WorldspaceHitResult hit = mousePick (mapFromGlobal (pos), getInteractionMask()); + WorldspaceHitResult hit = mousePick(mapFromGlobal(pos), getInteractionMask()); if (hit.tag) { bool hideBasics = CSMPrefs::get()["Tooltips"]["scene-hide-basic"].isTrue(); @@ -608,18 +576,16 @@ void CSVRender::WorldspaceWidget::showToolTip() void CSVRender::WorldspaceWidget::elementSelectionChanged() { - setVisibilityMask (getVisibilityMask()); + setVisibilityMask(getVisibilityMask()); flagAsModified(); updateOverlay(); } -void CSVRender::WorldspaceWidget::updateOverlay() -{ -} +void CSVRender::WorldspaceWidget::updateOverlay() {} -void CSVRender::WorldspaceWidget::mouseMoveEvent (QMouseEvent *event) +void CSVRender::WorldspaceWidget::mouseMoveEvent(QMouseEvent* event) { - dynamic_cast (*mEditMode->getCurrent()).mouseMoveEvent (event); + dynamic_cast(*mEditMode->getCurrent()).mouseMoveEvent(event); if (mDragging) { @@ -634,22 +600,22 @@ void CSVRender::WorldspaceWidget::mouseMoveEvent (QMouseEvent *event) if (mSpeedMode) factor *= mDragShiftFactor; - EditMode& editMode = dynamic_cast (*mEditMode->getCurrent()); + EditMode& editMode = dynamic_cast(*mEditMode->getCurrent()); - editMode.drag (event->pos(), diffX, diffY, factor); + editMode.drag(event->pos(), diffX, diffY, factor); } else if (mDragMode != InteractionType_None) { - EditMode& editMode = dynamic_cast (*mEditMode->getCurrent()); + EditMode& editMode = dynamic_cast(*mEditMode->getCurrent()); if (mDragMode == InteractionType_PrimaryEdit) - mDragging = editMode.primaryEditStartDrag (event->pos()); + mDragging = editMode.primaryEditStartDrag(event->pos()); else if (mDragMode == InteractionType_SecondaryEdit) - mDragging = editMode.secondaryEditStartDrag (event->pos()); + mDragging = editMode.secondaryEditStartDrag(event->pos()); else if (mDragMode == InteractionType_PrimarySelect) - mDragging = editMode.primarySelectStartDrag (event->pos()); + mDragging = editMode.primarySelectStartDrag(event->pos()); else if (mDragMode == InteractionType_SecondarySelect) - mDragging = editMode.secondarySelectStartDrag (event->pos()); + mDragging = editMode.secondarySelectStartDrag(event->pos()); if (mDragging) { @@ -659,14 +625,14 @@ void CSVRender::WorldspaceWidget::mouseMoveEvent (QMouseEvent *event) } else { - if (event->globalPos()!=mToolTipPos) + if (event->globalPos() != mToolTipPos) { mToolTipPos = event->globalPos(); if (mShowToolTips) { QToolTip::hideText(); - mToolTipDelayTimer.start (mToolTipDelay); + mToolTipDelayTimer.start(mToolTipDelay); } } @@ -674,7 +640,7 @@ void CSVRender::WorldspaceWidget::mouseMoveEvent (QMouseEvent *event) } } -void CSVRender::WorldspaceWidget::wheelEvent (QWheelEvent *event) +void CSVRender::WorldspaceWidget::wheelEvent(QWheelEvent* event) { if (mDragging) { @@ -683,27 +649,27 @@ void CSVRender::WorldspaceWidget::wheelEvent (QWheelEvent *event) if (mSpeedMode) factor *= mDragShiftFactor; - EditMode& editMode = dynamic_cast (*mEditMode->getCurrent()); - editMode.dragWheel (event->angleDelta().y(), factor); + EditMode& editMode = dynamic_cast(*mEditMode->getCurrent()); + editMode.dragWheel(event->angleDelta().y(), factor); } else SceneWidget::wheelEvent(event); } -void CSVRender::WorldspaceWidget::handleInteractionPress (const WorldspaceHitResult& hit, InteractionType type) +void CSVRender::WorldspaceWidget::handleInteractionPress(const WorldspaceHitResult& hit, InteractionType type) { - EditMode& editMode = dynamic_cast (*mEditMode->getCurrent()); + EditMode& editMode = dynamic_cast(*mEditMode->getCurrent()); if (type == InteractionType_PrimaryEdit) - editMode.primaryEditPressed (hit); + editMode.primaryEditPressed(hit); else if (type == InteractionType_SecondaryEdit) - editMode.secondaryEditPressed (hit); + editMode.secondaryEditPressed(hit); else if (type == InteractionType_PrimarySelect) - editMode.primarySelectPressed (hit); + editMode.primarySelectPressed(hit); else if (type == InteractionType_SecondarySelect) - editMode.secondarySelectPressed (hit); + editMode.secondarySelectPressed(hit); else if (type == InteractionType_PrimaryOpen) - editMode.primaryOpenPressed (hit); + editMode.primaryOpenPressed(hit); } void CSVRender::WorldspaceWidget::primaryOpen(bool activate) diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index 6e12153394..9933c9d7ab 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -45,254 +45,244 @@ namespace CSVRender class WorldspaceWidget : public SceneWidget { - Q_OBJECT - - CSVWidget::SceneToolToggle2 *mSceneElements; - CSVWidget::SceneToolRun *mRun; - CSMDoc::Document& mDocument; - unsigned int mInteractionMask; - CSVWidget::SceneToolMode *mEditMode; - bool mLocked; - int mDragMode; - bool mDragging; - int mDragX; - int mDragY; - bool mSpeedMode; - double mDragFactor; - double mDragWheelFactor; - double mDragShiftFactor; - QTimer mToolTipDelayTimer; - QPoint mToolTipPos; - bool mShowToolTips; - int mToolTipDelay; - bool mInConstructor; - - public: - - enum DropType - { - Type_CellsInterior, - Type_CellsExterior, - Type_Other, - Type_DebugProfile - }; - - enum dropRequirments - { - canHandle, - needPaged, - needUnpaged, - ignored //either mixed cells, or not cells - }; + Q_OBJECT + + CSVWidget::SceneToolToggle2* mSceneElements; + CSVWidget::SceneToolRun* mRun; + CSMDoc::Document& mDocument; + unsigned int mInteractionMask; + CSVWidget::SceneToolMode* mEditMode; + bool mLocked; + int mDragMode; + bool mDragging; + int mDragX; + int mDragY; + bool mSpeedMode; + double mDragFactor; + double mDragWheelFactor; + double mDragShiftFactor; + QTimer mToolTipDelayTimer; + QPoint mToolTipPos; + bool mShowToolTips; + int mToolTipDelay; + bool mInConstructor; + + public: + enum DropType + { + Type_CellsInterior, + Type_CellsExterior, + Type_Other, + Type_DebugProfile + }; - enum InteractionType - { - InteractionType_PrimaryEdit, - InteractionType_PrimarySelect, - InteractionType_SecondaryEdit, - InteractionType_SecondarySelect, - InteractionType_PrimaryOpen, - InteractionType_None - }; + enum dropRequirments + { + canHandle, + needPaged, + needUnpaged, + ignored // either mixed cells, or not cells + }; - WorldspaceWidget (CSMDoc::Document& document, QWidget *parent = nullptr); - ~WorldspaceWidget (); + enum InteractionType + { + InteractionType_PrimaryEdit, + InteractionType_PrimarySelect, + InteractionType_SecondaryEdit, + InteractionType_SecondarySelect, + InteractionType_PrimaryOpen, + InteractionType_None + }; + + WorldspaceWidget(CSMDoc::Document& document, QWidget* parent = nullptr); + ~WorldspaceWidget(); + + CSVWidget::SceneToolMode* makeNavigationSelector(CSVWidget::SceneToolbar* parent); + ///< \attention The created tool is not added to the toolbar (via addTool). Doing that + /// is the responsibility of the calling function. - CSVWidget::SceneToolMode *makeNavigationSelector (CSVWidget::SceneToolbar *parent); - ///< \attention The created tool is not added to the toolbar (via addTool). Doing that - /// is the responsibility of the calling function. + /// \attention The created tool is not added to the toolbar (via addTool). Doing + /// that is the responsibility of the calling function. + CSVWidget::SceneToolToggle2* makeSceneVisibilitySelector(CSVWidget::SceneToolbar* parent); - /// \attention The created tool is not added to the toolbar (via addTool). Doing - /// that is the responsibility of the calling function. - CSVWidget::SceneToolToggle2 *makeSceneVisibilitySelector ( - CSVWidget::SceneToolbar *parent); + /// \attention The created tool is not added to the toolbar (via addTool). Doing + /// that is the responsibility of the calling function. + CSVWidget::SceneToolRun* makeRunTool(CSVWidget::SceneToolbar* parent); - /// \attention The created tool is not added to the toolbar (via addTool). Doing - /// that is the responsibility of the calling function. - CSVWidget::SceneToolRun *makeRunTool (CSVWidget::SceneToolbar *parent); + /// \attention The created tool is not added to the toolbar (via addTool). Doing + /// that is the responsibility of the calling function. + CSVWidget::SceneToolMode* makeEditModeSelector(CSVWidget::SceneToolbar* parent); - /// \attention The created tool is not added to the toolbar (via addTool). Doing - /// that is the responsibility of the calling function. - CSVWidget::SceneToolMode *makeEditModeSelector (CSVWidget::SceneToolbar *parent); + void selectDefaultNavigationMode(); - void selectDefaultNavigationMode(); + void centerOrbitCameraOnSelection(); - void centerOrbitCameraOnSelection(); + static DropType getDropType(const std::vector& data); - static DropType getDropType(const std::vector& data); + virtual dropRequirments getDropRequirements(DropType type) const; - virtual dropRequirments getDropRequirements(DropType type) const; + virtual void useViewHint(const std::string& hint); + ///< Default-implementation: ignored. - virtual void useViewHint (const std::string& hint); - ///< Default-implementation: ignored. + /// \return Drop handled? + virtual bool handleDrop(const std::vector& data, DropType type); - /// \return Drop handled? - virtual bool handleDrop (const std::vector& data, - DropType type); + virtual unsigned int getVisibilityMask() const; - virtual unsigned int getVisibilityMask() const; + /// \note This function will implicitly add elements that are independent of the + /// selected edit mode. + virtual void setInteractionMask(unsigned int mask); - /// \note This function will implicitly add elements that are independent of the - /// selected edit mode. - virtual void setInteractionMask (unsigned int mask); + /// \note This function will only return those elements that are both visible and + /// marked for interaction. + unsigned int getInteractionMask() const; - /// \note This function will only return those elements that are both visible and - /// marked for interaction. - unsigned int getInteractionMask() const; + virtual void setEditLock(bool locked); - virtual void setEditLock (bool locked); + CSMDoc::Document& getDocument(); - CSMDoc::Document& getDocument(); + /// \param elementMask Elements to be affected by the clear operation + virtual void clearSelection(int elementMask) = 0; - /// \param elementMask Elements to be affected by the clear operation - virtual void clearSelection (int elementMask) = 0; + /// \param elementMask Elements to be affected by the select operation + virtual void invertSelection(int elementMask) = 0; - /// \param elementMask Elements to be affected by the select operation - virtual void invertSelection (int elementMask) = 0; + /// \param elementMask Elements to be affected by the select operation + virtual void selectAll(int elementMask) = 0; - /// \param elementMask Elements to be affected by the select operation - virtual void selectAll (int elementMask) = 0; + // Select everything that references the same ID as at least one of the elements + // already selected + // + /// \param elementMask Elements to be affected by the select operation + virtual void selectAllWithSameParentId(int elementMask) = 0; - // Select everything that references the same ID as at least one of the elements - // already selected - // - /// \param elementMask Elements to be affected by the select operation - virtual void selectAllWithSameParentId (int elementMask) = 0; + virtual void selectInsideCube(const osg::Vec3d& pointA, const osg::Vec3d& pointB, DragMode dragMode) = 0; - virtual void selectInsideCube(const osg::Vec3d& pointA, const osg::Vec3d& pointB, DragMode dragMode) = 0; + virtual void selectWithinDistance(const osg::Vec3d& point, float distance, DragMode dragMode) = 0; - virtual void selectWithinDistance(const osg::Vec3d& point, float distance, DragMode dragMode) = 0; + /// Return the next intersection with scene elements matched by + /// \a interactionMask based on \a localPos and the camera vector. + /// If there is no such intersection, instead a point "in front" of \a localPos will be + /// returned. + WorldspaceHitResult mousePick(const QPoint& localPos, unsigned int interactionMask) const; - /// Return the next intersection with scene elements matched by - /// \a interactionMask based on \a localPos and the camera vector. - /// If there is no such intersection, instead a point "in front" of \a localPos will be - /// returned. - WorldspaceHitResult mousePick (const QPoint& localPos, unsigned int interactionMask) const; + virtual std::string getCellId(const osg::Vec3f& point) const = 0; - virtual std::string getCellId (const osg::Vec3f& point) const = 0; + /// \note Returns the cell if it exists, otherwise a null pointer + virtual Cell* getCell(const osg::Vec3d& point) const = 0; - /// \note Returns the cell if it exists, otherwise a null pointer - virtual Cell* getCell(const osg::Vec3d& point) const = 0; + virtual Cell* getCell(const CSMWorld::CellCoordinates& coords) const = 0; - virtual Cell* getCell(const CSMWorld::CellCoordinates& coords) const = 0; + virtual std::vector> getSelection(unsigned int elementMask) const = 0; - virtual std::vector > getSelection (unsigned int elementMask) - const = 0; + virtual std::vector> getEdited(unsigned int elementMask) const = 0; - virtual std::vector > getEdited (unsigned int elementMask) - const = 0; + virtual void setSubMode(int subMode, unsigned int elementMask) = 0; - virtual void setSubMode (int subMode, unsigned int elementMask) = 0; + /// Erase all overrides and restore the visual representation to its true state. + virtual void reset(unsigned int elementMask) = 0; - /// Erase all overrides and restore the visual representation to its true state. - virtual void reset (unsigned int elementMask) = 0; + EditMode* getEditMode(); - EditMode *getEditMode(); + protected: + /// Visual elements in a scene + /// @note do not change the enumeration values, they are used in pre-existing button file names! + enum ButtonId + { + Button_Reference = 0x1, + Button_Pathgrid = 0x2, + Button_Water = 0x4, + Button_Fog = 0x8, + Button_Terrain = 0x10 + }; - protected: + virtual void addVisibilitySelectorButtons(CSVWidget::SceneToolToggle2* tool); - /// Visual elements in a scene - /// @note do not change the enumeration values, they are used in pre-existing button file names! - enum ButtonId - { - Button_Reference = 0x1, - Button_Pathgrid = 0x2, - Button_Water = 0x4, - Button_Fog = 0x8, - Button_Terrain = 0x10 - }; + virtual void addEditModeSelectorButtons(CSVWidget::SceneToolMode* tool); - virtual void addVisibilitySelectorButtons (CSVWidget::SceneToolToggle2 *tool); + virtual void updateOverlay(); - virtual void addEditModeSelectorButtons (CSVWidget::SceneToolMode *tool); + void mouseMoveEvent(QMouseEvent* event) override; + void wheelEvent(QWheelEvent* event) override; - virtual void updateOverlay(); + virtual void handleInteractionPress(const WorldspaceHitResult& hit, InteractionType type); - void mouseMoveEvent (QMouseEvent *event) override; - void wheelEvent (QWheelEvent *event) override; + void settingChanged(const CSMPrefs::Setting* setting) override; - virtual void handleInteractionPress (const WorldspaceHitResult& hit, InteractionType type); + bool getSpeedMode(); - void settingChanged (const CSMPrefs::Setting *setting) override; + private: + void dragEnterEvent(QDragEnterEvent* event) override; - bool getSpeedMode(); + void dropEvent(QDropEvent* event) override; - private: + void dragMoveEvent(QDragMoveEvent* event) override; - void dragEnterEvent(QDragEnterEvent *event) override; + virtual std::string getStartupInstruction() = 0; - void dropEvent(QDropEvent* event) override; + void handleInteraction(InteractionType type, bool activate); - void dragMoveEvent(QDragMoveEvent *event) override; + public slots: - virtual std::string getStartupInstruction() = 0; + /// \note Drags will be automatically aborted when the aborting is triggered + /// (either explicitly or implicitly) from within this class. This function only + /// needs to be called, when the drag abort is triggered externally (e.g. from + /// an edit mode). + void abortDrag(); - void handleInteraction(InteractionType type, bool activate); + private slots: - public slots: + virtual void referenceableDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) = 0; - /// \note Drags will be automatically aborted when the aborting is triggered - /// (either explicitly or implicitly) from within this class. This function only - /// needs to be called, when the drag abort is triggered externally (e.g. from - /// an edit mode). - void abortDrag(); + virtual void referenceableAboutToBeRemoved(const QModelIndex& parent, int start, int end) = 0; - private slots: + virtual void referenceableAdded(const QModelIndex& index, int start, int end) = 0; - virtual void referenceableDataChanged (const QModelIndex& topLeft, - const QModelIndex& bottomRight) = 0; + virtual void referenceDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) = 0; - virtual void referenceableAboutToBeRemoved (const QModelIndex& parent, int start, int end) = 0; + virtual void referenceAboutToBeRemoved(const QModelIndex& parent, int start, int end) = 0; - virtual void referenceableAdded (const QModelIndex& index, int start, int end) = 0; + virtual void referenceAdded(const QModelIndex& index, int start, int end) = 0; - virtual void referenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) = 0; + virtual void pathgridDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) = 0; - virtual void referenceAboutToBeRemoved (const QModelIndex& parent, int start, int end) = 0; + virtual void pathgridAboutToBeRemoved(const QModelIndex& parent, int start, int end) = 0; - virtual void referenceAdded (const QModelIndex& index, int start, int end) = 0; + virtual void pathgridAdded(const QModelIndex& parent, int start, int end) = 0; - virtual void pathgridDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) = 0; + virtual void runRequest(const std::string& profile); - virtual void pathgridAboutToBeRemoved (const QModelIndex& parent, int start, int end) = 0; + void debugProfileDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); - virtual void pathgridAdded (const QModelIndex& parent, int start, int end) = 0; + void debugProfileAboutToBeRemoved(const QModelIndex& parent, int start, int end); + void editModeChanged(const std::string& id); - virtual void runRequest (const std::string& profile); + void showToolTip(); - void debugProfileDataChanged (const QModelIndex& topLeft, - const QModelIndex& bottomRight); + void primaryOpen(bool activate); - void debugProfileAboutToBeRemoved (const QModelIndex& parent, int start, int end); + void primaryEdit(bool activate); - void editModeChanged (const std::string& id); + void secondaryEdit(bool activate); - void showToolTip(); + void primarySelect(bool activate); - void primaryOpen(bool activate); + void secondarySelect(bool activate); - void primaryEdit(bool activate); + void speedMode(bool activate); - void secondaryEdit(bool activate); + protected slots: - void primarySelect(bool activate); + void elementSelectionChanged(); - void secondarySelect(bool activate); + signals: - void speedMode(bool activate); + void closeRequest(); - protected slots: + void dataDropped(const std::vector& data); - void elementSelectionChanged(); - - signals: - - void closeRequest(); - - void dataDropped(const std::vector& data); - - void requestFocus (const std::string& id); + void requestFocus(const std::string& id); friend class MouseState; }; diff --git a/apps/opencs/view/tools/merge.cpp b/apps/opencs/view/tools/merge.cpp index 35f4b6c1d0..43c182368e 100644 --- a/apps/opencs/view/tools/merge.cpp +++ b/apps/opencs/view/tools/merge.cpp @@ -16,104 +16,105 @@ #include "../../model/doc/documentmanager.hpp" #include "../../model/doc/state.hpp" -#include "../doc/filewidget.hpp" #include "../doc/adjusterwidget.hpp" +#include "../doc/filewidget.hpp" -void CSVTools::Merge::keyPressEvent (QKeyEvent *event) +void CSVTools::Merge::keyPressEvent(QKeyEvent* event) { - if (event->key()==Qt::Key_Escape) + if (event->key() == Qt::Key_Escape) { event->accept(); cancel(); } else - QWidget::keyPressEvent (event); + QWidget::keyPressEvent(event); } -CSVTools::Merge::Merge (CSMDoc::DocumentManager& documentManager, QWidget *parent) -: QWidget (parent), mDocument (nullptr), mDocumentManager (documentManager) +CSVTools::Merge::Merge(CSMDoc::DocumentManager& documentManager, QWidget* parent) + : QWidget(parent) + , mDocument(nullptr) + , mDocumentManager(documentManager) { - setWindowTitle ("Merge Content Files into a new Game File"); + setWindowTitle("Merge Content Files into a new Game File"); - QVBoxLayout *mainLayout = new QVBoxLayout; - setLayout (mainLayout); + QVBoxLayout* mainLayout = new QVBoxLayout; + setLayout(mainLayout); - QSplitter *splitter = new QSplitter (Qt::Horizontal, this); + QSplitter* splitter = new QSplitter(Qt::Horizontal, this); - mainLayout->addWidget (splitter, 1); + mainLayout->addWidget(splitter, 1); // left panel (files to be merged) - QWidget *left = new QWidget (this); - left->setContentsMargins (0, 0, 0, 0); - splitter->addWidget (left); + QWidget* left = new QWidget(this); + left->setContentsMargins(0, 0, 0, 0); + splitter->addWidget(left); - QVBoxLayout *leftLayout = new QVBoxLayout; - left->setLayout (leftLayout); + QVBoxLayout* leftLayout = new QVBoxLayout; + left->setLayout(leftLayout); - leftLayout->addWidget (new QLabel ("Files to be merged", this)); + leftLayout->addWidget(new QLabel("Files to be merged", this)); - mFiles = new QListWidget (this); - leftLayout->addWidget (mFiles, 1); + mFiles = new QListWidget(this); + leftLayout->addWidget(mFiles, 1); // right panel (new game file) - QWidget *right = new QWidget (this); - right->setContentsMargins (0, 0, 0, 0); - splitter->addWidget (right); + QWidget* right = new QWidget(this); + right->setContentsMargins(0, 0, 0, 0); + splitter->addWidget(right); - QVBoxLayout *rightLayout = new QVBoxLayout; - rightLayout->setAlignment (Qt::AlignTop); - right->setLayout (rightLayout); + QVBoxLayout* rightLayout = new QVBoxLayout; + rightLayout->setAlignment(Qt::AlignTop); + right->setLayout(rightLayout); - rightLayout->addWidget (new QLabel ("New game file", this)); + rightLayout->addWidget(new QLabel("New game file", this)); - mNewFile = new CSVDoc::FileWidget (this); - mNewFile->setType (false); - mNewFile->extensionLabelIsVisible (true); - rightLayout->addWidget (mNewFile); + mNewFile = new CSVDoc::FileWidget(this); + mNewFile->setType(false); + mNewFile->extensionLabelIsVisible(true); + rightLayout->addWidget(mNewFile); - mAdjuster = new CSVDoc::AdjusterWidget (this); + mAdjuster = new CSVDoc::AdjusterWidget(this); - rightLayout->addWidget (mAdjuster); + rightLayout->addWidget(mAdjuster); - connect (mNewFile, &CSVDoc::FileWidget::nameChanged, mAdjuster, &CSVDoc::AdjusterWidget::setName); - connect (mAdjuster, &CSVDoc::AdjusterWidget::stateChanged, this, &Merge::stateChanged); + connect(mNewFile, &CSVDoc::FileWidget::nameChanged, mAdjuster, &CSVDoc::AdjusterWidget::setName); + connect(mAdjuster, &CSVDoc::AdjusterWidget::stateChanged, this, &Merge::stateChanged); // buttons - QDialogButtonBox *buttons = new QDialogButtonBox (QDialogButtonBox::Cancel, Qt::Horizontal, this); + QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Cancel, Qt::Horizontal, this); - connect (buttons->button(QDialogButtonBox::Cancel), &QPushButton::clicked, this, &Merge::cancel); + connect(buttons->button(QDialogButtonBox::Cancel), &QPushButton::clicked, this, &Merge::cancel); - mOkay = new QPushButton ("Merge", this); - connect (mOkay, &QPushButton::clicked, this, &Merge::accept); - mOkay->setDefault (true); - buttons->addButton (mOkay, QDialogButtonBox::AcceptRole); + mOkay = new QPushButton("Merge", this); + connect(mOkay, &QPushButton::clicked, this, &Merge::accept); + mOkay->setDefault(true); + buttons->addButton(mOkay, QDialogButtonBox::AcceptRole); - mainLayout->addWidget (buttons); + mainLayout->addWidget(buttons); } -void CSVTools::Merge::configure (CSMDoc::Document *document) +void CSVTools::Merge::configure(CSMDoc::Document* document) { mDocument = document; - mNewFile->setName (""); + mNewFile->setName(""); // content files while (mFiles->count()) - delete mFiles->takeItem (0); + delete mFiles->takeItem(0); std::vector files = document->getContentFiles(); - for (std::vector::const_iterator iter (files.begin()); - iter!=files.end(); ++iter) - mFiles->addItem (Files::pathToQString(iter->filename())); + for (std::vector::const_iterator iter(files.begin()); iter != files.end(); ++iter) + mFiles->addItem(Files::pathToQString(iter->filename())); } -void CSVTools::Merge::setLocalData (const std::filesystem::path& localData) +void CSVTools::Merge::setLocalData(const std::filesystem::path& localData) { - mAdjuster->setLocalData (localData); + mAdjuster->setLocalData(localData); } -CSMDoc::Document *CSVTools::Merge::getDocument() const +CSMDoc::Document* CSVTools::Merge::getDocument() const { return mDocument; } @@ -126,20 +127,19 @@ void CSVTools::Merge::cancel() void CSVTools::Merge::accept() { - if ((mDocument->getState() & CSMDoc::State_Merging)==0) + if ((mDocument->getState() & CSMDoc::State_Merging) == 0) { - std::vector< std::filesystem::path > files { mAdjuster->getPath() }; + std::vector files{ mAdjuster->getPath() }; - std::unique_ptr target ( - mDocumentManager.makeDocument (files, files[0], true)); + std::unique_ptr target(mDocumentManager.makeDocument(files, files[0], true)); - mDocument->runMerge (std::move(target)); + mDocument->runMerge(std::move(target)); hide(); } } -void CSVTools::Merge::stateChanged (bool valid) +void CSVTools::Merge::stateChanged(bool valid) { - mOkay->setEnabled (valid); + mOkay->setEnabled(valid); } diff --git a/apps/opencs/view/tools/merge.hpp b/apps/opencs/view/tools/merge.hpp index 51633c5bb4..cfb36d2613 100644 --- a/apps/opencs/view/tools/merge.hpp +++ b/apps/opencs/view/tools/merge.hpp @@ -24,37 +24,36 @@ namespace CSVTools { class Merge : public QWidget { - Q_OBJECT + Q_OBJECT - CSMDoc::Document *mDocument; - QPushButton *mOkay; - QListWidget *mFiles; - CSVDoc::FileWidget *mNewFile; - CSVDoc::AdjusterWidget *mAdjuster; - CSMDoc::DocumentManager& mDocumentManager; + CSMDoc::Document* mDocument; + QPushButton* mOkay; + QListWidget* mFiles; + CSVDoc::FileWidget* mNewFile; + CSVDoc::AdjusterWidget* mAdjuster; + CSMDoc::DocumentManager& mDocumentManager; - void keyPressEvent (QKeyEvent *event) override; + void keyPressEvent(QKeyEvent* event) override; - public: + public: + Merge(CSMDoc::DocumentManager& documentManager, QWidget* parent = nullptr); - Merge (CSMDoc::DocumentManager& documentManager, QWidget *parent = nullptr); + /// Configure dialogue for a new merge + void configure(CSMDoc::Document* document); - /// Configure dialogue for a new merge - void configure (CSMDoc::Document *document); + void setLocalData(const std::filesystem::path& localData); - void setLocalData (const std::filesystem::path& localData); + CSMDoc::Document* getDocument() const; - CSMDoc::Document *getDocument() const; + public slots: - public slots: + void cancel(); - void cancel(); + private slots: - private slots: + void accept(); - void accept(); - - void stateChanged (bool valid); + void stateChanged(bool valid); }; } diff --git a/apps/opencs/view/tools/reportsubview.cpp b/apps/opencs/view/tools/reportsubview.cpp index c505ce7e31..d55217bf8e 100644 --- a/apps/opencs/view/tools/reportsubview.cpp +++ b/apps/opencs/view/tools/reportsubview.cpp @@ -2,28 +2,30 @@ #include "reporttable.hpp" -#include "../../model/doc/state.hpp" #include "../../model/doc/document.hpp" +#include "../../model/doc/state.hpp" -CSVTools::ReportSubView::ReportSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) -: CSVDoc::SubView (id), mDocument (document), mRefreshState (0) +CSVTools::ReportSubView::ReportSubView(const CSMWorld::UniversalId& id, CSMDoc::Document& document) + : CSVDoc::SubView(id) + , mDocument(document) + , mRefreshState(0) { - if (id.getType()==CSMWorld::UniversalId::Type_VerificationResults) + if (id.getType() == CSMWorld::UniversalId::Type_VerificationResults) mRefreshState = CSMDoc::State_Verifying; - setWidget (mTable = new ReportTable (document, id, false, mRefreshState, this)); + setWidget(mTable = new ReportTable(document, id, false, mRefreshState, this)); + + connect(mTable, &ReportTable::editRequest, this, &ReportSubView::focusId); - connect (mTable, &ReportTable::editRequest, this, &ReportSubView::focusId); - - if (mRefreshState==CSMDoc::State_Verifying) + if (mRefreshState == CSMDoc::State_Verifying) { - connect (mTable, &ReportTable::refreshRequest, this, &ReportSubView::refreshRequest); + connect(mTable, &ReportTable::refreshRequest, this, &ReportSubView::refreshRequest); - connect (&document, &CSMDoc::Document::stateChanged, mTable, &ReportTable::stateChanged); + connect(&document, &CSMDoc::Document::stateChanged, mTable, &ReportTable::stateChanged); } } -void CSVTools::ReportSubView::setEditLock (bool locked) +void CSVTools::ReportSubView::setEditLock(bool locked) { // ignored. We don't change document state anyway. } @@ -32,10 +34,10 @@ void CSVTools::ReportSubView::refreshRequest() { if (!(mDocument.getState() & mRefreshState)) { - if (mRefreshState==CSMDoc::State_Verifying) + if (mRefreshState == CSMDoc::State_Verifying) { mTable->clear(); - mDocument.verify (getUniversalId()); + mDocument.verify(getUniversalId()); } } } diff --git a/apps/opencs/view/tools/reportsubview.hpp b/apps/opencs/view/tools/reportsubview.hpp index 6d48690b43..ea07098fba 100644 --- a/apps/opencs/view/tools/reportsubview.hpp +++ b/apps/opencs/view/tools/reportsubview.hpp @@ -17,21 +17,20 @@ namespace CSVTools class ReportSubView : public CSVDoc::SubView { - Q_OBJECT + Q_OBJECT - ReportTable *mTable; - CSMDoc::Document& mDocument; - int mRefreshState; + ReportTable* mTable; + CSMDoc::Document& mDocument; + int mRefreshState; - public: + public: + ReportSubView(const CSMWorld::UniversalId& id, CSMDoc::Document& document); - ReportSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document); + void setEditLock(bool locked) override; - void setEditLock (bool locked) override; + private slots: - private slots: - - void refreshRequest(); + void refreshRequest(); }; } diff --git a/apps/opencs/view/tools/reporttable.cpp b/apps/opencs/view/tools/reporttable.cpp index 4c61c574cd..25276bba62 100644 --- a/apps/opencs/view/tools/reporttable.cpp +++ b/apps/opencs/view/tools/reporttable.cpp @@ -2,20 +2,20 @@ #include -#include #include -#include -#include -#include -#include #include +#include +#include #include +#include #include +#include +#include #include "../../model/tools/reportmodel.hpp" -#include "../../model/prefs/state.hpp" #include "../../model/prefs/shortcut.hpp" +#include "../../model/prefs/state.hpp" #include "../../view/world/idtypedelegate.hpp" @@ -23,52 +23,50 @@ namespace CSVTools { class RichTextDelegate : public QStyledItemDelegate { - public: + public: + RichTextDelegate(QObject* parent = nullptr); - RichTextDelegate (QObject *parent = nullptr); - - void paint(QPainter *painter, const QStyleOptionViewItem& option, - const QModelIndex& index) const override; + void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override; }; } -CSVTools::RichTextDelegate::RichTextDelegate (QObject *parent) : QStyledItemDelegate (parent) -{} +CSVTools::RichTextDelegate::RichTextDelegate(QObject* parent) + : QStyledItemDelegate(parent) +{ +} -void CSVTools::RichTextDelegate::paint(QPainter *painter, const QStyleOptionViewItem& option, - const QModelIndex& index) const +void CSVTools::RichTextDelegate::paint( + QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { QTextDocument document; - QVariant value = index.data (Qt::DisplayRole); + QVariant value = index.data(Qt::DisplayRole); if (value.isValid() && !value.isNull()) { - document.setHtml (value.toString()); - painter->translate (option.rect.topLeft()); - document.drawContents (painter); - painter->translate (-option.rect.topLeft()); + document.setHtml(value.toString()); + painter->translate(option.rect.topLeft()); + document.drawContents(painter); + painter->translate(-option.rect.topLeft()); } } - -void CSVTools::ReportTable::contextMenuEvent (QContextMenuEvent *event) +void CSVTools::ReportTable::contextMenuEvent(QContextMenuEvent* event) { QModelIndexList selectedRows = selectionModel()->selectedRows(); // create context menu - QMenu menu (this); + QMenu menu(this); if (!selectedRows.empty()) { - menu.addAction (mShowAction); - menu.addAction (mRemoveAction); + menu.addAction(mShowAction); + menu.addAction(mRemoveAction); bool found = false; - for (QModelIndexList::const_iterator iter (selectedRows.begin()); - iter!=selectedRows.end(); ++iter) + for (QModelIndexList::const_iterator iter(selectedRows.begin()); iter != selectedRows.end(); ++iter) { - QString hint = mProxyModel->data (mProxyModel->index (iter->row(), 2)).toString(); + QString hint = mProxyModel->data(mProxyModel->index(iter->row(), 2)).toString(); - if (!hint.isEmpty() && hint[0]=='R') + if (!hint.isEmpty() && hint[0] == 'R') { found = true; break; @@ -76,35 +74,33 @@ void CSVTools::ReportTable::contextMenuEvent (QContextMenuEvent *event) } if (found) - menu.addAction (mReplaceAction); + menu.addAction(mReplaceAction); } if (mRefreshAction) - menu.addAction (mRefreshAction); + menu.addAction(mRefreshAction); - menu.exec (event->globalPos()); + menu.exec(event->globalPos()); } -void CSVTools::ReportTable::mouseMoveEvent (QMouseEvent *event) +void CSVTools::ReportTable::mouseMoveEvent(QMouseEvent* event) { if (event->buttons() & Qt::LeftButton) - startDragFromTable (*this); + startDragFromTable(*this); } -void CSVTools::ReportTable::mouseDoubleClickEvent (QMouseEvent *event) +void CSVTools::ReportTable::mouseDoubleClickEvent(QMouseEvent* event) { - Qt::KeyboardModifiers modifiers = - event->modifiers() & (Qt::ShiftModifier | Qt::ControlModifier); + Qt::KeyboardModifiers modifiers = event->modifiers() & (Qt::ShiftModifier | Qt::ControlModifier); QModelIndex index = currentIndex(); - selectionModel()->select (index, - QItemSelectionModel::Clear | QItemSelectionModel::Select | QItemSelectionModel::Rows); + selectionModel()->select( + index, QItemSelectionModel::Clear | QItemSelectionModel::Select | QItemSelectionModel::Rows); - std::map::iterator iter = - mDoubleClickActions.find (modifiers); + std::map::iterator iter = mDoubleClickActions.find(modifiers); - if (iter==mDoubleClickActions.end()) + if (iter == mDoubleClickActions.end()) { event->accept(); return; @@ -138,69 +134,68 @@ void CSVTools::ReportTable::mouseDoubleClickEvent (QMouseEvent *event) } } -CSVTools::ReportTable::ReportTable (CSMDoc::Document& document, - const CSMWorld::UniversalId& id, bool richTextDescription, int refreshState, - QWidget *parent) -: CSVWorld::DragRecordTable (document, parent), mModel (document.getReport (id)), - mRefreshAction (nullptr), mRefreshState (refreshState) +CSVTools::ReportTable::ReportTable(CSMDoc::Document& document, const CSMWorld::UniversalId& id, + bool richTextDescription, int refreshState, QWidget* parent) + : CSVWorld::DragRecordTable(document, parent) + , mModel(document.getReport(id)) + , mRefreshAction(nullptr) + , mRefreshState(refreshState) { - horizontalHeader()->setSectionResizeMode (QHeaderView::Interactive); - horizontalHeader()->setStretchLastSection (true); + horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); + horizontalHeader()->setStretchLastSection(true); verticalHeader()->hide(); - setSortingEnabled (true); - setSelectionBehavior (QAbstractItemView::SelectRows); - setSelectionMode (QAbstractItemView::ExtendedSelection); + setSortingEnabled(true); + setSelectionBehavior(QAbstractItemView::SelectRows); + setSelectionMode(QAbstractItemView::ExtendedSelection); - mProxyModel = new QSortFilterProxyModel (this); + mProxyModel = new QSortFilterProxyModel(this); mProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); - mProxyModel->setSourceModel (mModel); + mProxyModel->setSourceModel(mModel); mProxyModel->setSortRole(Qt::UserRole); - setModel (mProxyModel); - setColumnHidden (2, true); + setModel(mProxyModel); + setColumnHidden(2, true); - mIdTypeDelegate = CSVWorld::IdTypeDelegateFactory().makeDelegate (nullptr, - mDocument, this); + mIdTypeDelegate = CSVWorld::IdTypeDelegateFactory().makeDelegate(nullptr, mDocument, this); - setItemDelegateForColumn (0, mIdTypeDelegate); + setItemDelegateForColumn(0, mIdTypeDelegate); if (richTextDescription) - setItemDelegateForColumn (mModel->columnCount()-1, new RichTextDelegate (this)); + setItemDelegateForColumn(mModel->columnCount() - 1, new RichTextDelegate(this)); - mShowAction = new QAction (tr ("Show"), this); - connect (mShowAction, &QAction::triggered, this, &ReportTable::showSelection); - addAction (mShowAction); + mShowAction = new QAction(tr("Show"), this); + connect(mShowAction, &QAction::triggered, this, &ReportTable::showSelection); + addAction(mShowAction); CSMPrefs::Shortcut* showShortcut = new CSMPrefs::Shortcut("reporttable-show", this); showShortcut->associateAction(mShowAction); - mRemoveAction = new QAction (tr ("Remove from list"), this); - connect (mRemoveAction, &QAction::triggered, this, &ReportTable::removeSelection); - addAction (mRemoveAction); + mRemoveAction = new QAction(tr("Remove from list"), this); + connect(mRemoveAction, &QAction::triggered, this, &ReportTable::removeSelection); + addAction(mRemoveAction); CSMPrefs::Shortcut* removeShortcut = new CSMPrefs::Shortcut("reporttable-remove", this); removeShortcut->associateAction(mRemoveAction); - mReplaceAction = new QAction (tr ("Replace"), this); - connect (mReplaceAction, &QAction::triggered, this, &ReportTable::replaceRequest); - addAction (mReplaceAction); + mReplaceAction = new QAction(tr("Replace"), this); + connect(mReplaceAction, &QAction::triggered, this, &ReportTable::replaceRequest); + addAction(mReplaceAction); CSMPrefs::Shortcut* replaceShortcut = new CSMPrefs::Shortcut("reporttable-replace", this); replaceShortcut->associateAction(mReplaceAction); if (mRefreshState) { - mRefreshAction = new QAction (tr ("Refresh"), this); - mRefreshAction->setEnabled (!(mDocument.getState() & mRefreshState)); - connect (mRefreshAction, &QAction::triggered, this, &ReportTable::refreshRequest); - addAction (mRefreshAction); + mRefreshAction = new QAction(tr("Refresh"), this); + mRefreshAction->setEnabled(!(mDocument.getState() & mRefreshState)); + connect(mRefreshAction, &QAction::triggered, this, &ReportTable::refreshRequest); + addAction(mRefreshAction); CSMPrefs::Shortcut* refreshShortcut = new CSMPrefs::Shortcut("reporttable-refresh", this); refreshShortcut->associateAction(mRefreshAction); } - mDoubleClickActions.insert (std::make_pair (Qt::NoModifier, Action_Edit)); - mDoubleClickActions.insert (std::make_pair (Qt::ShiftModifier, Action_Remove)); - mDoubleClickActions.insert (std::make_pair (Qt::ControlModifier, Action_EditAndRemove)); + mDoubleClickActions.insert(std::make_pair(Qt::NoModifier, Action_Edit)); + mDoubleClickActions.insert(std::make_pair(Qt::ShiftModifier, Action_Remove)); + mDoubleClickActions.insert(std::make_pair(Qt::ControlModifier, Action_EditAndRemove)); - connect (&CSMPrefs::State::get(), &CSMPrefs::State::settingChanged, - this, &ReportTable::settingChanged); + connect(&CSMPrefs::State::get(), &CSMPrefs::State::settingChanged, this, &ReportTable::settingChanged); CSMPrefs::get()["Reports"].update(); } @@ -210,16 +205,15 @@ std::vector CSVTools::ReportTable::getDraggedRecords() co QModelIndexList selectedRows = selectionModel()->selectedRows(); - for (QModelIndexList::const_iterator iter (selectedRows.begin()); iter!=selectedRows.end(); - ++iter) + for (QModelIndexList::const_iterator iter(selectedRows.begin()); iter != selectedRows.end(); ++iter) { - ids.push_back (mModel->getUniversalId (mProxyModel->mapToSource (*iter).row())); + ids.push_back(mModel->getUniversalId(mProxyModel->mapToSource(*iter).row())); } return ids; } -std::vector CSVTools::ReportTable::getReplaceIndices (bool selection) const +std::vector CSVTools::ReportTable::getReplaceIndices(bool selection) const { std::vector indices; @@ -229,68 +223,67 @@ std::vector CSVTools::ReportTable::getReplaceIndices (bool selection) const std::vector rows; - for (QModelIndexList::const_iterator iter (selectedRows.begin()); iter!=selectedRows.end(); - ++iter) + for (QModelIndexList::const_iterator iter(selectedRows.begin()); iter != selectedRows.end(); ++iter) { - rows.push_back (mProxyModel->mapToSource (*iter).row()); + rows.push_back(mProxyModel->mapToSource(*iter).row()); } - std::sort (rows.begin(), rows.end()); + std::sort(rows.begin(), rows.end()); - for (std::vector::const_iterator iter (rows.begin()); iter!=rows.end(); ++iter) + for (std::vector::const_iterator iter(rows.begin()); iter != rows.end(); ++iter) { - QString hint = mModel->data (mModel->index (*iter, 2)).toString(); + QString hint = mModel->data(mModel->index(*iter, 2)).toString(); - if (!hint.isEmpty() && hint[0]=='R') - indices.push_back (*iter); + if (!hint.isEmpty() && hint[0] == 'R') + indices.push_back(*iter); } } else { - for (int i=0; irowCount(); ++i) + for (int i = 0; i < mModel->rowCount(); ++i) { - QString hint = mModel->data (mModel->index (i, 2)).toString(); + QString hint = mModel->data(mModel->index(i, 2)).toString(); - if (!hint.isEmpty() && hint[0]=='R') - indices.push_back (i); + if (!hint.isEmpty() && hint[0] == 'R') + indices.push_back(i); } } return indices; } -void CSVTools::ReportTable::flagAsReplaced (int index) +void CSVTools::ReportTable::flagAsReplaced(int index) { - mModel->flagAsReplaced (index); + mModel->flagAsReplaced(index); } -void CSVTools::ReportTable::settingChanged (const CSMPrefs::Setting *setting) +void CSVTools::ReportTable::settingChanged(const CSMPrefs::Setting* setting) { - if (setting->getParent()->getKey()=="Reports") + if (setting->getParent()->getKey() == "Reports") { - QString base ("double"); + QString base("double"); QString key = setting->getKey().c_str(); - if (key.startsWith (base)) + if (key.startsWith(base)) { - QString modifierString = key.mid (base.size()); + QString modifierString = key.mid(base.size()); Qt::KeyboardModifiers modifiers; - if (modifierString=="-s") + if (modifierString == "-s") modifiers = Qt::ShiftModifier; - else if (modifierString=="-c") + else if (modifierString == "-c") modifiers = Qt::ControlModifier; - else if (modifierString=="-sc") + else if (modifierString == "-sc") modifiers = Qt::ShiftModifier | Qt::ControlModifier; DoubleClickAction action = Action_None; std::string value = setting->toString(); - if (value=="Edit") + if (value == "Edit") action = Action_Edit; - else if (value=="Remove") + else if (value == "Remove") action = Action_Remove; - else if (value=="Edit And Remove") + else if (value == "Edit And Remove") action = Action_EditAndRemove; mDoubleClickActions[modifiers] = action; @@ -298,19 +291,18 @@ void CSVTools::ReportTable::settingChanged (const CSMPrefs::Setting *setting) return; } } - else if (*setting=="Records/type-format") - mIdTypeDelegate->settingChanged (setting); + else if (*setting == "Records/type-format") + mIdTypeDelegate->settingChanged(setting); } void CSVTools::ReportTable::showSelection() { QModelIndexList selectedRows = selectionModel()->selectedRows(); - for (QModelIndexList::const_iterator iter (selectedRows.begin()); iter!=selectedRows.end(); - ++iter) + for (QModelIndexList::const_iterator iter(selectedRows.begin()); iter != selectedRows.end(); ++iter) { - int row = mProxyModel->mapToSource (*iter).row(); - emit editRequest (mModel->getUniversalId (row), mModel->getHint (row)); + int row = mProxyModel->mapToSource(*iter).row(); + emit editRequest(mModel->getUniversalId(row), mModel->getHint(row)); } } @@ -320,16 +312,15 @@ void CSVTools::ReportTable::removeSelection() std::vector rows; - for (QModelIndexList::iterator iter (selectedRows.begin()); iter!=selectedRows.end(); - ++iter) + for (QModelIndexList::iterator iter(selectedRows.begin()); iter != selectedRows.end(); ++iter) { - rows.push_back (mProxyModel->mapToSource (*iter).row()); + rows.push_back(mProxyModel->mapToSource(*iter).row()); } - std::sort (rows.begin(), rows.end()); + std::sort(rows.begin(), rows.end()); - for (std::vector::const_reverse_iterator iter (rows.rbegin()); iter!=rows.rend(); ++iter) - mProxyModel->removeRows (*iter, 1); + for (std::vector::const_reverse_iterator iter(rows.rbegin()); iter != rows.rend(); ++iter) + mProxyModel->removeRows(*iter, 1); selectionModel()->clear(); } @@ -339,8 +330,8 @@ void CSVTools::ReportTable::clear() mModel->clear(); } -void CSVTools::ReportTable::stateChanged (int state, CSMDoc::Document *document) +void CSVTools::ReportTable::stateChanged(int state, CSMDoc::Document* document) { if (mRefreshAction) - mRefreshAction->setEnabled (!(state & mRefreshState)); + mRefreshAction->setEnabled(!(state & mRefreshState)); } diff --git a/apps/opencs/view/tools/reporttable.hpp b/apps/opencs/view/tools/reporttable.hpp index f39dd6f857..a65d06456f 100644 --- a/apps/opencs/view/tools/reporttable.hpp +++ b/apps/opencs/view/tools/reporttable.hpp @@ -27,76 +27,74 @@ namespace CSVTools { class ReportTable : public CSVWorld::DragRecordTable { - Q_OBJECT + Q_OBJECT - enum DoubleClickAction - { - Action_None, - Action_Edit, - Action_Remove, - Action_EditAndRemove - }; + enum DoubleClickAction + { + Action_None, + Action_Edit, + Action_Remove, + Action_EditAndRemove + }; - QSortFilterProxyModel *mProxyModel; - CSMTools::ReportModel *mModel; - CSVWorld::CommandDelegate *mIdTypeDelegate; - QAction *mShowAction; - QAction *mRemoveAction; - QAction *mReplaceAction; - QAction *mRefreshAction; - std::map mDoubleClickActions; - int mRefreshState; + QSortFilterProxyModel* mProxyModel; + CSMTools::ReportModel* mModel; + CSVWorld::CommandDelegate* mIdTypeDelegate; + QAction* mShowAction; + QAction* mRemoveAction; + QAction* mReplaceAction; + QAction* mRefreshAction; + std::map mDoubleClickActions; + int mRefreshState; - private: + private: + void contextMenuEvent(QContextMenuEvent* event) override; - void contextMenuEvent (QContextMenuEvent *event) override; + void mouseMoveEvent(QMouseEvent* event) override; - void mouseMoveEvent (QMouseEvent *event) override; + void mouseDoubleClickEvent(QMouseEvent* event) override; - void mouseDoubleClickEvent (QMouseEvent *event) override; + public: + /// \param richTextDescription Use rich text in the description column. + /// \param refreshState Document state to check for refresh function. If value is + /// 0 no refresh function exists. If the document current has the specified state + /// the refresh function is disabled. + ReportTable(CSMDoc::Document& document, const CSMWorld::UniversalId& id, bool richTextDescription, + int refreshState = 0, QWidget* parent = nullptr); - public: + std::vector getDraggedRecords() const override; - /// \param richTextDescription Use rich text in the description column. - /// \param refreshState Document state to check for refresh function. If value is - /// 0 no refresh function exists. If the document current has the specified state - /// the refresh function is disabled. - ReportTable (CSMDoc::Document& document, const CSMWorld::UniversalId& id, - bool richTextDescription, int refreshState = 0, QWidget *parent = nullptr); + void clear(); - std::vector getDraggedRecords() const override; + /// Return indices of rows that are suitable for replacement. + /// + /// \param selection Only list selected rows. + /// + /// \return rows in the original model + std::vector getReplaceIndices(bool selection) const; - void clear(); + /// \param index row in the original model + void flagAsReplaced(int index); - /// Return indices of rows that are suitable for replacement. - /// - /// \param selection Only list selected rows. - /// - /// \return rows in the original model - std::vector getReplaceIndices (bool selection) const; + private slots: - /// \param index row in the original model - void flagAsReplaced (int index); + void settingChanged(const CSMPrefs::Setting* setting); - private slots: + void showSelection(); - void settingChanged (const CSMPrefs::Setting *setting); + void removeSelection(); - void showSelection(); + public slots: - void removeSelection(); + void stateChanged(int state, CSMDoc::Document* document); - public slots: + signals: - void stateChanged (int state, CSMDoc::Document *document); + void editRequest(const CSMWorld::UniversalId& id, const std::string& hint); - signals: + void replaceRequest(); - void editRequest (const CSMWorld::UniversalId& id, const std::string& hint); - - void replaceRequest(); - - void refreshRequest(); + void refreshRequest(); }; } diff --git a/apps/opencs/view/tools/searchbox.cpp b/apps/opencs/view/tools/searchbox.cpp index 880060ac25..0235d10b31 100644 --- a/apps/opencs/view/tools/searchbox.cpp +++ b/apps/opencs/view/tools/searchbox.cpp @@ -11,7 +11,7 @@ void CSVTools::SearchBox::updateSearchButton() { if (!mSearchEnabled) - mSearch.setEnabled (false); + mSearch.setEnabled(false); else { switch (mMode.currentIndex()) @@ -21,75 +21,77 @@ void CSVTools::SearchBox::updateSearchButton() case 2: case 3: - mSearch.setEnabled (!mText.text().isEmpty()); + mSearch.setEnabled(!mText.text().isEmpty()); break; case 4: - mSearch.setEnabled (true); + mSearch.setEnabled(true); break; } } } -CSVTools::SearchBox::SearchBox (QWidget *parent) -: QWidget (parent), mSearch (tr("Search")), mSearchEnabled (false), mReplace (tr("Replace All")) +CSVTools::SearchBox::SearchBox(QWidget* parent) + : QWidget(parent) + , mSearch(tr("Search")) + , mSearchEnabled(false) + , mReplace(tr("Replace All")) { - mLayout = new QGridLayout (this); + mLayout = new QGridLayout(this); // search panel - std::vector> states = - CSMWorld::Columns::getEnums (CSMWorld::Columns::ColumnId_Modification); - states.resize (states.size()-1); // ignore erased state + std::vector> states + = CSMWorld::Columns::getEnums(CSMWorld::Columns::ColumnId_Modification); + states.resize(states.size() - 1); // ignore erased state - for (std::vector>::const_iterator iter (states.begin()); iter!=states.end(); - ++iter) - mRecordState.addItem (QString::fromUtf8 (iter->second.c_str())); + for (std::vector>::const_iterator iter(states.begin()); iter != states.end(); ++iter) + mRecordState.addItem(QString::fromUtf8(iter->second.c_str())); - mMode.addItem (tr("Text")); - mMode.addItem (tr("Text (RegEx)")); - mMode.addItem (tr("ID")); - mMode.addItem (tr("ID (RegEx)")); - mMode.addItem (tr("Record State")); - connect (&mMode, qOverload(&QComboBox::activated), this, &SearchBox::modeSelected); - mLayout->addWidget (&mMode, 0, 0); + mMode.addItem(tr("Text")); + mMode.addItem(tr("Text (RegEx)")); + mMode.addItem(tr("ID")); + mMode.addItem(tr("ID (RegEx)")); + mMode.addItem(tr("Record State")); + connect(&mMode, qOverload(&QComboBox::activated), this, &SearchBox::modeSelected); + mLayout->addWidget(&mMode, 0, 0); - connect (&mText, &QLineEdit::textChanged, this, &SearchBox::textChanged); - connect (&mText, &QLineEdit::returnPressed, this, [this](){ this->startSearch(false); }); - mInput.insertWidget (0, &mText); + connect(&mText, &QLineEdit::textChanged, this, &SearchBox::textChanged); + connect(&mText, &QLineEdit::returnPressed, this, [this]() { this->startSearch(false); }); + mInput.insertWidget(0, &mText); - mInput.insertWidget (1, &mRecordState); - mLayout->addWidget (&mInput, 0, 1); + mInput.insertWidget(1, &mRecordState); + mLayout->addWidget(&mInput, 0, 1); - mCaseSensitive.setText (tr ("Case")); - mLayout->addWidget (&mCaseSensitive, 0, 2); + mCaseSensitive.setText(tr("Case")); + mLayout->addWidget(&mCaseSensitive, 0, 2); - connect (&mSearch, &QPushButton::clicked, this, qOverload(&SearchBox::startSearch)); - mLayout->addWidget (&mSearch, 0, 3); + connect(&mSearch, &QPushButton::clicked, this, qOverload(&SearchBox::startSearch)); + mLayout->addWidget(&mSearch, 0, 3); // replace panel - mReplaceInput.insertWidget (0, &mReplaceText); - mReplaceInput.insertWidget (1, &mReplacePlaceholder); + mReplaceInput.insertWidget(0, &mReplaceText); + mReplaceInput.insertWidget(1, &mReplacePlaceholder); - mLayout->addWidget (&mReplaceInput, 1, 1); + mLayout->addWidget(&mReplaceInput, 1, 1); - mLayout->addWidget (&mReplace, 1, 3); + mLayout->addWidget(&mReplace, 1, 3); // layout adjustments - mLayout->setColumnMinimumWidth (2, 50); - mLayout->setColumnStretch (1, 1); + mLayout->setColumnMinimumWidth(2, 50); + mLayout->setColumnStretch(1, 1); - mLayout->setContentsMargins (0, 0, 0, 0); + mLayout->setContentsMargins(0, 0, 0, 0); - connect (&mReplace, &QPushButton::clicked, this, qOverload(&SearchBox::replaceAll)); + connect(&mReplace, &QPushButton::clicked, this, qOverload(&SearchBox::replaceAll)); // update - modeSelected (0); + modeSelected(0); updateSearchButton(); } -void CSVTools::SearchBox::setSearchMode (bool enabled) +void CSVTools::SearchBox::setSearchMode(bool enabled) { mSearchEnabled = enabled; updateSearchButton(); @@ -97,7 +99,7 @@ void CSVTools::SearchBox::setSearchMode (bool enabled) CSMTools::Search CSVTools::SearchBox::getSearch() const { - CSMTools::Search::Type type = static_cast (mMode.currentIndex()); + CSMTools::Search::Type type = static_cast(mMode.currentIndex()); bool caseSensitive = mCaseSensitive.isChecked(); switch (type) @@ -105,28 +107,28 @@ CSMTools::Search CSVTools::SearchBox::getSearch() const case CSMTools::Search::Type_Text: case CSMTools::Search::Type_Id: - return CSMTools::Search (type, caseSensitive, std::string (mText.text().toUtf8().data())); + return CSMTools::Search(type, caseSensitive, std::string(mText.text().toUtf8().data())); case CSMTools::Search::Type_TextRegEx: case CSMTools::Search::Type_IdRegEx: - return CSMTools::Search (type, caseSensitive, QRegExp (mText.text().toUtf8().data(), Qt::CaseInsensitive)); + return CSMTools::Search(type, caseSensitive, QRegExp(mText.text().toUtf8().data(), Qt::CaseInsensitive)); case CSMTools::Search::Type_RecordState: - return CSMTools::Search (type, caseSensitive, mRecordState.currentIndex()); + return CSMTools::Search(type, caseSensitive, mRecordState.currentIndex()); case CSMTools::Search::Type_None: break; } - throw std::logic_error ("invalid search mode index"); + throw std::logic_error("invalid search mode index"); } std::string CSVTools::SearchBox::getReplaceText() const { - CSMTools::Search::Type type = static_cast (mMode.currentIndex()); + CSMTools::Search::Type type = static_cast(mMode.currentIndex()); switch (type) { @@ -139,13 +141,13 @@ std::string CSVTools::SearchBox::getReplaceText() const default: - throw std::logic_error ("Invalid search mode for replace"); + throw std::logic_error("Invalid search mode for replace"); } } -void CSVTools::SearchBox::setEditLock (bool locked) +void CSVTools::SearchBox::setEditLock(bool locked) { - mReplace.setEnabled (!locked); + mReplace.setEnabled(!locked); } void CSVTools::SearchBox::focus() @@ -153,7 +155,7 @@ void CSVTools::SearchBox::focus() mInput.currentWidget()->setFocus(); } -void CSVTools::SearchBox::modeSelected (int index) +void CSVTools::SearchBox::modeSelected(int index) { switch (index) { @@ -162,13 +164,13 @@ void CSVTools::SearchBox::modeSelected (int index) case CSMTools::Search::Type_Id: case CSMTools::Search::Type_IdRegEx: - mInput.setCurrentIndex (0); - mReplaceInput.setCurrentIndex (0); + mInput.setCurrentIndex(0); + mReplaceInput.setCurrentIndex(0); break; case CSMTools::Search::Type_RecordState: - mInput.setCurrentIndex (1); - mReplaceInput.setCurrentIndex (1); + mInput.setCurrentIndex(1); + mReplaceInput.setCurrentIndex(1); break; } @@ -177,18 +179,18 @@ void CSVTools::SearchBox::modeSelected (int index) updateSearchButton(); } -void CSVTools::SearchBox::textChanged (const QString& text) +void CSVTools::SearchBox::textChanged(const QString& text) { updateSearchButton(); } -void CSVTools::SearchBox::startSearch (bool checked) +void CSVTools::SearchBox::startSearch(bool checked) { if (mSearch.isEnabled()) - emit startSearch (getSearch()); + emit startSearch(getSearch()); } -void CSVTools::SearchBox::replaceAll (bool checked) +void CSVTools::SearchBox::replaceAll(bool checked) { emit replaceAll(); } diff --git a/apps/opencs/view/tools/searchbox.hpp b/apps/opencs/view/tools/searchbox.hpp index cbeb150d8b..76712fee4b 100644 --- a/apps/opencs/view/tools/searchbox.hpp +++ b/apps/opencs/view/tools/searchbox.hpp @@ -1,13 +1,13 @@ #ifndef CSV_TOOLS_SEARCHBOX_H #define CSV_TOOLS_SEARCHBOX_H -#include -#include -#include #include -#include -#include +#include #include +#include +#include +#include +#include class QGridLayout; @@ -20,54 +20,52 @@ namespace CSVTools { class SearchBox : public QWidget { - Q_OBJECT - - QStackedWidget mInput; - QLineEdit mText; - QComboBox mRecordState; - QCheckBox mCaseSensitive; - QPushButton mSearch; - QGridLayout *mLayout; - QComboBox mMode; - bool mSearchEnabled; - QStackedWidget mReplaceInput; - QLineEdit mReplaceText; - QLabel mReplacePlaceholder; - QPushButton mReplace; + Q_OBJECT - private: + QStackedWidget mInput; + QLineEdit mText; + QComboBox mRecordState; + QCheckBox mCaseSensitive; + QPushButton mSearch; + QGridLayout* mLayout; + QComboBox mMode; + bool mSearchEnabled; + QStackedWidget mReplaceInput; + QLineEdit mReplaceText; + QLabel mReplacePlaceholder; + QPushButton mReplace; - void updateSearchButton(); - - public: + private: + void updateSearchButton(); - SearchBox (QWidget *parent = nullptr); + public: + SearchBox(QWidget* parent = nullptr); - void setSearchMode (bool enabled); + void setSearchMode(bool enabled); - CSMTools::Search getSearch() const; + CSMTools::Search getSearch() const; - std::string getReplaceText() const; + std::string getReplaceText() const; - void setEditLock (bool locked); + void setEditLock(bool locked); - void focus(); + void focus(); - private slots: + private slots: - void modeSelected (int index); + void modeSelected(int index); - void textChanged (const QString& text); + void textChanged(const QString& text); - void startSearch (bool checked = true); + void startSearch(bool checked = true); - void replaceAll (bool checked); + void replaceAll(bool checked); - signals: + signals: - void startSearch (const CSMTools::Search& search); + void startSearch(const CSMTools::Search& search); - void replaceAll(); + void replaceAll(); }; } diff --git a/apps/opencs/view/tools/searchsubview.cpp b/apps/opencs/view/tools/searchsubview.cpp index 64e0e133d0..8567384e97 100644 --- a/apps/opencs/view/tools/searchsubview.cpp +++ b/apps/opencs/view/tools/searchsubview.cpp @@ -4,158 +4,153 @@ #include "../../model/doc/document.hpp" #include "../../model/doc/state.hpp" -#include "../../model/tools/search.hpp" +#include "../../model/prefs/state.hpp" #include "../../model/tools/reportmodel.hpp" +#include "../../model/tools/search.hpp" #include "../../model/world/idtablebase.hpp" -#include "../../model/prefs/state.hpp" -#include "../world/tablebottombox.hpp" #include "../world/creator.hpp" +#include "../world/tablebottombox.hpp" #include "reporttable.hpp" #include "searchbox.hpp" -void CSVTools::SearchSubView::replace (bool selection) +void CSVTools::SearchSubView::replace(bool selection) { if (mLocked) return; - std::vector indices = mTable->getReplaceIndices (selection); + std::vector indices = mTable->getReplaceIndices(selection); std::string replace = mSearchBox.getReplaceText(); - const CSMTools::ReportModel& model = - dynamic_cast (*mTable->model()); + const CSMTools::ReportModel& model = dynamic_cast(*mTable->model()); bool autoDelete = CSMPrefs::get()["Search & Replace"]["auto-delete"].isTrue(); - CSMTools::Search search (mSearch); - CSMWorld::IdTableBase *currentTable = nullptr; + CSMTools::Search search(mSearch); + CSMWorld::IdTableBase* currentTable = nullptr; // We are running through the indices in reverse order to avoid messing up multiple results // in a single string. - for (std::vector::const_reverse_iterator iter (indices.rbegin()); iter!=indices.rend(); ++iter) + for (std::vector::const_reverse_iterator iter(indices.rbegin()); iter != indices.rend(); ++iter) { - const CSMWorld::UniversalId& id = model.getUniversalId (*iter); + const CSMWorld::UniversalId& id = model.getUniversalId(*iter); - CSMWorld::UniversalId::Type type = CSMWorld::UniversalId::getParentType (id.getType()); + CSMWorld::UniversalId::Type type = CSMWorld::UniversalId::getParentType(id.getType()); - CSMWorld::IdTableBase *table = &dynamic_cast ( - *mDocument.getData().getTableModel (type)); + CSMWorld::IdTableBase* table = &dynamic_cast(*mDocument.getData().getTableModel(type)); - if (table!=currentTable) + if (table != currentTable) { - search.configure (table); + search.configure(table); currentTable = table; } - std::string hint = model.getHint (*iter); + std::string hint = model.getHint(*iter); - if (search.verify (mDocument, table, id, hint)) + if (search.verify(mDocument, table, id, hint)) { - search.replace (mDocument, table, id, hint, replace); - mTable->flagAsReplaced (*iter); + search.replace(mDocument, table, id, hint, replace); + mTable->flagAsReplaced(*iter); if (autoDelete) - mTable->model()->removeRows (*iter, 1); + mTable->model()->removeRows(*iter, 1); } } } -void CSVTools::SearchSubView::showEvent (QShowEvent *event) +void CSVTools::SearchSubView::showEvent(QShowEvent* event) { - CSVDoc::SubView::showEvent (event); + CSVDoc::SubView::showEvent(event); mSearchBox.focus(); } -CSVTools::SearchSubView::SearchSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) -: CSVDoc::SubView (id), mDocument (document), mLocked (false) +CSVTools::SearchSubView::SearchSubView(const CSMWorld::UniversalId& id, CSMDoc::Document& document) + : CSVDoc::SubView(id) + , mDocument(document) + , mLocked(false) { - QVBoxLayout *layout = new QVBoxLayout; + QVBoxLayout* layout = new QVBoxLayout; - layout->addWidget (&mSearchBox); + layout->addWidget(&mSearchBox); - layout->addWidget (mTable = new ReportTable (document, id, true), 2); + layout->addWidget(mTable = new ReportTable(document, id, true), 2); - layout->addWidget (mBottom = - new CSVWorld::TableBottomBox (CSVWorld::NullCreatorFactory(), document, id, this), 0); + layout->addWidget(mBottom = new CSVWorld::TableBottomBox(CSVWorld::NullCreatorFactory(), document, id, this), 0); - QWidget *widget = new QWidget; + QWidget* widget = new QWidget; - widget->setLayout (layout); + widget->setLayout(layout); - setWidget (widget); + setWidget(widget); - stateChanged (document.getState(), &document); + stateChanged(document.getState(), &document); - connect (mTable, &ReportTable::editRequest, this, &SearchSubView::focusId); + connect(mTable, &ReportTable::editRequest, this, &SearchSubView::focusId); - connect (mTable, &ReportTable::replaceRequest, this, &SearchSubView::replaceRequest); + connect(mTable, &ReportTable::replaceRequest, this, &SearchSubView::replaceRequest); - connect (&document, &CSMDoc::Document::stateChanged, this, &SearchSubView::stateChanged); + connect(&document, &CSMDoc::Document::stateChanged, this, &SearchSubView::stateChanged); - connect (&mSearchBox, qOverload(&SearchBox::startSearch), - this, &SearchSubView::startSearch); + connect( + &mSearchBox, qOverload(&SearchBox::startSearch), this, &SearchSubView::startSearch); - connect (&mSearchBox, qOverload<>(&SearchBox::replaceAll), this, - &SearchSubView::replaceAllRequest); + connect(&mSearchBox, qOverload<>(&SearchBox::replaceAll), this, &SearchSubView::replaceAllRequest); - connect (document.getReport(id), &CSMTools::ReportModel::rowsRemoved, - this, &SearchSubView::tableSizeUpdate); + connect(document.getReport(id), &CSMTools::ReportModel::rowsRemoved, this, &SearchSubView::tableSizeUpdate); - connect (document.getReport(id), &CSMTools::ReportModel::rowsInserted, - this, &SearchSubView::tableSizeUpdate); + connect(document.getReport(id), &CSMTools::ReportModel::rowsInserted, this, &SearchSubView::tableSizeUpdate); - connect (&document, &CSMDoc::Document::operationDone, this, &SearchSubView::operationDone); + connect(&document, &CSMDoc::Document::operationDone, this, &SearchSubView::operationDone); } -void CSVTools::SearchSubView::setEditLock (bool locked) +void CSVTools::SearchSubView::setEditLock(bool locked) { mLocked = locked; - mSearchBox.setEditLock (locked); + mSearchBox.setEditLock(locked); } -void CSVTools::SearchSubView::setStatusBar (bool show) +void CSVTools::SearchSubView::setStatusBar(bool show) { mBottom->setStatusBar(show); } -void CSVTools::SearchSubView::stateChanged (int state, CSMDoc::Document *document) +void CSVTools::SearchSubView::stateChanged(int state, CSMDoc::Document* document) { - mSearchBox.setSearchMode (!(state & CSMDoc::State_Searching)); + mSearchBox.setSearchMode(!(state & CSMDoc::State_Searching)); } -void CSVTools::SearchSubView::startSearch (const CSMTools::Search& search) +void CSVTools::SearchSubView::startSearch(const CSMTools::Search& search) { CSMPrefs::Category& settings = CSMPrefs::get()["Search & Replace"]; mSearch = search; - mSearch.setPadding (settings["char-before"].toInt(), settings["char-after"].toInt()); + mSearch.setPadding(settings["char-before"].toInt(), settings["char-after"].toInt()); mTable->clear(); - mDocument.runSearch (getUniversalId(), mSearch); + mDocument.runSearch(getUniversalId(), mSearch); } void CSVTools::SearchSubView::replaceRequest() { - replace (true); + replace(true); } void CSVTools::SearchSubView::replaceAllRequest() { - replace (false); + replace(false); } void CSVTools::SearchSubView::tableSizeUpdate() { - mBottom->tableSizeChanged (mDocument.getReport (getUniversalId())->rowCount(), 0, 0); + mBottom->tableSizeChanged(mDocument.getReport(getUniversalId())->rowCount(), 0, 0); } -void CSVTools::SearchSubView::operationDone (int type, bool failed) +void CSVTools::SearchSubView::operationDone(int type, bool failed) { - if (type==CSMDoc::State_Searching && !failed && - !mDocument.getReport (getUniversalId())->rowCount()) + if (type == CSMDoc::State_Searching && !failed && !mDocument.getReport(getUniversalId())->rowCount()) { - mBottom->setStatusMessage ("No Results"); + mBottom->setStatusMessage("No Results"); } } diff --git a/apps/opencs/view/tools/searchsubview.hpp b/apps/opencs/view/tools/searchsubview.hpp index cbcb01577e..2c895351f4 100644 --- a/apps/opencs/view/tools/searchsubview.hpp +++ b/apps/opencs/view/tools/searchsubview.hpp @@ -26,44 +26,41 @@ namespace CSVTools class SearchSubView : public CSVDoc::SubView { - Q_OBJECT + Q_OBJECT - ReportTable *mTable; - SearchBox mSearchBox; - CSMDoc::Document& mDocument; - CSMTools::Search mSearch; - bool mLocked; - CSVWorld::TableBottomBox *mBottom; + ReportTable* mTable; + SearchBox mSearchBox; + CSMDoc::Document& mDocument; + CSMTools::Search mSearch; + bool mLocked; + CSVWorld::TableBottomBox* mBottom; - private: + private: + void replace(bool selection); - void replace (bool selection); + protected: + void showEvent(QShowEvent* event) override; - protected: + public: + SearchSubView(const CSMWorld::UniversalId& id, CSMDoc::Document& document); - void showEvent (QShowEvent *event) override; + void setEditLock(bool locked) override; - public: + void setStatusBar(bool show) override; - SearchSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document); + private slots: - void setEditLock (bool locked) override; + void stateChanged(int state, CSMDoc::Document* document); - void setStatusBar (bool show) override; + void startSearch(const CSMTools::Search& search); - private slots: + void replaceRequest(); - void stateChanged (int state, CSMDoc::Document *document); + void replaceAllRequest(); - void startSearch (const CSMTools::Search& search); + void tableSizeUpdate(); - void replaceRequest(); - - void replaceAllRequest(); - - void tableSizeUpdate(); - - void operationDone (int type, bool failed); + void operationDone(int type, bool failed); }; } diff --git a/apps/opencs/view/tools/subviews.cpp b/apps/opencs/view/tools/subviews.cpp index 8c3d6d50ea..d0f44e0033 100644 --- a/apps/opencs/view/tools/subviews.cpp +++ b/apps/opencs/view/tools/subviews.cpp @@ -5,12 +5,9 @@ #include "reportsubview.hpp" #include "searchsubview.hpp" -void CSVTools::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) +void CSVTools::addSubViewFactories(CSVDoc::SubViewFactoryManager& manager) { - manager.add (CSMWorld::UniversalId::Type_VerificationResults, - new CSVDoc::SubViewFactory); - manager.add (CSMWorld::UniversalId::Type_LoadErrorLog, - new CSVDoc::SubViewFactory); - manager.add (CSMWorld::UniversalId::Type_Search, - new CSVDoc::SubViewFactory); + manager.add(CSMWorld::UniversalId::Type_VerificationResults, new CSVDoc::SubViewFactory); + manager.add(CSMWorld::UniversalId::Type_LoadErrorLog, new CSVDoc::SubViewFactory); + manager.add(CSMWorld::UniversalId::Type_Search, new CSVDoc::SubViewFactory); } diff --git a/apps/opencs/view/tools/subviews.hpp b/apps/opencs/view/tools/subviews.hpp index 1bac322282..bd76ec0c71 100644 --- a/apps/opencs/view/tools/subviews.hpp +++ b/apps/opencs/view/tools/subviews.hpp @@ -8,7 +8,7 @@ namespace CSVDoc namespace CSVTools { - void addSubViewFactories (CSVDoc::SubViewFactoryManager& manager); + void addSubViewFactories(CSVDoc::SubViewFactoryManager& manager); } #endif diff --git a/apps/opencs/view/widget/coloreditor.cpp b/apps/opencs/view/widget/coloreditor.cpp index 460c3fc707..477c36c91f 100644 --- a/apps/opencs/view/widget/coloreditor.cpp +++ b/apps/opencs/view/widget/coloreditor.cpp @@ -2,48 +2,46 @@ #include #include -#include #include +#include #include "colorpickerpopup.hpp" -CSVWidget::ColorEditor::ColorEditor(const QColor &color, QWidget *parent, const bool popupOnStart) +CSVWidget::ColorEditor::ColorEditor(const QColor& color, QWidget* parent, const bool popupOnStart) : ColorEditor(parent, popupOnStart) { setColor(color); } -CSVWidget::ColorEditor::ColorEditor(const int colorInt, QWidget *parent, const bool popupOnStart) +CSVWidget::ColorEditor::ColorEditor(const int colorInt, QWidget* parent, const bool popupOnStart) : ColorEditor(parent, popupOnStart) { setColor(colorInt); } -CSVWidget::ColorEditor::ColorEditor(QWidget *parent, const bool popupOnStart) - : QPushButton(parent), - mColorPicker(new ColorPickerPopup(this)), - mPopupOnStart(popupOnStart) +CSVWidget::ColorEditor::ColorEditor(QWidget* parent, const bool popupOnStart) + : QPushButton(parent) + , mColorPicker(new ColorPickerPopup(this)) + , mPopupOnStart(popupOnStart) { connect(this, &ColorEditor::clicked, this, &ColorEditor::showPicker); connect(mColorPicker, &ColorPickerPopup::colorChanged, this, &ColorEditor::pickerColorChanged); } -void CSVWidget::ColorEditor::paintEvent(QPaintEvent *event) +void CSVWidget::ColorEditor::paintEvent(QPaintEvent* event) { QPushButton::paintEvent(event); QRect buttonRect = rect(); QRect coloredRect(buttonRect.x() + qRound(buttonRect.width() / 4.0), - buttonRect.y() + qRound(buttonRect.height() / 4.0), - buttonRect.width() / 2, - buttonRect.height() / 2); + buttonRect.y() + qRound(buttonRect.height() / 4.0), buttonRect.width() / 2, buttonRect.height() / 2); QPainter painter(this); painter.fillRect(coloredRect, mColor); painter.setPen(Qt::black); painter.drawRect(coloredRect); } -void CSVWidget::ColorEditor::showEvent(QShowEvent *event) +void CSVWidget::ColorEditor::showEvent(QShowEvent* event) { QPushButton::showEvent(event); if (isVisible() && mPopupOnStart) @@ -64,7 +62,7 @@ int CSVWidget::ColorEditor::colorInt() const return (mColor.blue() << 16) | (mColor.green() << 8) | (mColor.red()); } -void CSVWidget::ColorEditor::setColor(const QColor &color) +void CSVWidget::ColorEditor::setColor(const QColor& color) { mColor = color; update(); @@ -84,7 +82,7 @@ void CSVWidget::ColorEditor::showPicker() emit pickingFinished(); } -void CSVWidget::ColorEditor::pickerColorChanged(const QColor &color) +void CSVWidget::ColorEditor::pickerColorChanged(const QColor& color) { mColor = color; update(); diff --git a/apps/opencs/view/widget/coloreditor.hpp b/apps/opencs/view/widget/coloreditor.hpp index aa746da682..284de9f6c6 100644 --- a/apps/opencs/view/widget/coloreditor.hpp +++ b/apps/opencs/view/widget/coloreditor.hpp @@ -13,42 +13,42 @@ namespace CSVWidget class ColorEditor : public QPushButton { - Q_OBJECT + Q_OBJECT - QColor mColor; - ColorPickerPopup *mColorPicker; - bool mPopupOnStart; + QColor mColor; + ColorPickerPopup* mColorPicker; + bool mPopupOnStart; - QPoint calculatePopupPosition(); + QPoint calculatePopupPosition(); - public: - ColorEditor(const QColor &color, QWidget *parent = nullptr, const bool popupOnStart = false); - ColorEditor(const int colorInt, QWidget *parent = nullptr, const bool popupOnStart = false); + public: + ColorEditor(const QColor& color, QWidget* parent = nullptr, const bool popupOnStart = false); + ColorEditor(const int colorInt, QWidget* parent = nullptr, const bool popupOnStart = false); - QColor color() const; + QColor color() const; - /// \return Color RGB value encoded in an int. - int colorInt() const; + /// \return Color RGB value encoded in an int. + int colorInt() const; - void setColor(const QColor &color); + void setColor(const QColor& color); - /// \brief Set color using given int value. - /// \param colorInt RGB color value encoded as an integer. - void setColor(const int colorInt); + /// \brief Set color using given int value. + /// \param colorInt RGB color value encoded as an integer. + void setColor(const int colorInt); - protected: - void paintEvent(QPaintEvent *event) override; - void showEvent(QShowEvent *event) override; + protected: + void paintEvent(QPaintEvent* event) override; + void showEvent(QShowEvent* event) override; - private: - ColorEditor(QWidget *parent = nullptr, const bool popupOnStart = false); + private: + ColorEditor(QWidget* parent = nullptr, const bool popupOnStart = false); - private slots: - void showPicker(); - void pickerColorChanged(const QColor &color); + private slots: + void showPicker(); + void pickerColorChanged(const QColor& color); - signals: - void pickingFinished(); + signals: + void pickingFinished(); }; } diff --git a/apps/opencs/view/widget/colorpickerpopup.cpp b/apps/opencs/view/widget/colorpickerpopup.cpp index 5a48b87f39..1a6842bb25 100644 --- a/apps/opencs/view/widget/colorpickerpopup.cpp +++ b/apps/opencs/view/widget/colorpickerpopup.cpp @@ -1,13 +1,13 @@ #include "colorpickerpopup.hpp" #include -#include #include #include +#include #include #include -CSVWidget::ColorPickerPopup::ColorPickerPopup(QWidget *parent) +CSVWidget::ColorPickerPopup::ColorPickerPopup(QWidget* parent) : QFrame(parent) { setWindowFlags(Qt::Popup); @@ -18,10 +18,9 @@ CSVWidget::ColorPickerPopup::ColorPickerPopup(QWidget *parent) mColorPicker->setWindowFlags(Qt::Widget); mColorPicker->setOptions(QColorDialog::NoButtons | QColorDialog::DontUseNativeDialog); mColorPicker->installEventFilter(this); - connect(mColorPicker, &QColorDialog::currentColorChanged, - this, &ColorPickerPopup::colorChanged); + connect(mColorPicker, &QColorDialog::currentColorChanged, this, &ColorPickerPopup::colorChanged); - QVBoxLayout *layout = new QVBoxLayout(this); + QVBoxLayout* layout = new QVBoxLayout(this); layout->addWidget(mColorPicker); layout->setAlignment(Qt::AlignTop | Qt::AlignLeft); layout->setContentsMargins(0, 0, 0, 0); @@ -29,7 +28,7 @@ CSVWidget::ColorPickerPopup::ColorPickerPopup(QWidget *parent) setFixedSize(mColorPicker->size()); } -void CSVWidget::ColorPickerPopup::showPicker(const QPoint &position, const QColor &initialColor) +void CSVWidget::ColorPickerPopup::showPicker(const QPoint& position, const QColor& initialColor) { QRect geometry = this->geometry(); geometry.moveTo(position); @@ -41,9 +40,9 @@ void CSVWidget::ColorPickerPopup::showPicker(const QPoint &position, const QColo mColorPicker->setCurrentColor(color); } -void CSVWidget::ColorPickerPopup::mousePressEvent(QMouseEvent *event) +void CSVWidget::ColorPickerPopup::mousePressEvent(QMouseEvent* event) { - QPushButton *button = qobject_cast(parentWidget()); + QPushButton* button = qobject_cast(parentWidget()); if (button != nullptr) { QStyleOptionButton option; @@ -61,11 +60,11 @@ void CSVWidget::ColorPickerPopup::mousePressEvent(QMouseEvent *event) QFrame::mousePressEvent(event); } -bool CSVWidget::ColorPickerPopup::eventFilter(QObject *object, QEvent *event) +bool CSVWidget::ColorPickerPopup::eventFilter(QObject* object, QEvent* event) { if (object == mColorPicker && event->type() == QEvent::KeyPress) { - QKeyEvent *keyEvent = static_cast(event); + QKeyEvent* keyEvent = static_cast(event); // Prevent QColorDialog from closing when Escape is pressed. // Instead, hide the popup. if (keyEvent->key() == Qt::Key_Escape) diff --git a/apps/opencs/view/widget/colorpickerpopup.hpp b/apps/opencs/view/widget/colorpickerpopup.hpp index d653d68fbb..8a3eb030fb 100644 --- a/apps/opencs/view/widget/colorpickerpopup.hpp +++ b/apps/opencs/view/widget/colorpickerpopup.hpp @@ -11,19 +11,19 @@ namespace CSVWidget { Q_OBJECT - QColorDialog *mColorPicker; + QColorDialog* mColorPicker; public: - explicit ColorPickerPopup(QWidget *parent); - - void showPicker(const QPoint &position, const QColor &initialColor); + explicit ColorPickerPopup(QWidget* parent); + + void showPicker(const QPoint& position, const QColor& initialColor); protected: - void mousePressEvent(QMouseEvent *event) override; - bool eventFilter(QObject *object, QEvent *event) override; + void mousePressEvent(QMouseEvent* event) override; + bool eventFilter(QObject* object, QEvent* event) override; signals: - void colorChanged(const QColor &color); + void colorChanged(const QColor& color); }; } diff --git a/apps/opencs/view/widget/completerpopup.cpp b/apps/opencs/view/widget/completerpopup.cpp index be509bcb93..0a52295642 100644 --- a/apps/opencs/view/widget/completerpopup.cpp +++ b/apps/opencs/view/widget/completerpopup.cpp @@ -1,6 +1,6 @@ #include "completerpopup.hpp" -CSVWidget::CompleterPopup::CompleterPopup(QWidget *parent) +CSVWidget::CompleterPopup::CompleterPopup(QWidget* parent) : QListView(parent) { setEditTriggers(QAbstractItemView::NoEditTriggers); @@ -23,6 +23,6 @@ int CSVWidget::CompleterPopup::sizeHintForRow(int row) const ensurePolished(); QModelIndex index = model()->index(row, modelColumn()); QStyleOptionViewItem option = viewOptions(); - QAbstractItemDelegate *delegate = itemDelegate(index); + QAbstractItemDelegate* delegate = itemDelegate(index); return delegate->sizeHint(option, index).height(); } diff --git a/apps/opencs/view/widget/completerpopup.hpp b/apps/opencs/view/widget/completerpopup.hpp index 96675f56f4..673d288000 100644 --- a/apps/opencs/view/widget/completerpopup.hpp +++ b/apps/opencs/view/widget/completerpopup.hpp @@ -7,10 +7,10 @@ namespace CSVWidget { class CompleterPopup : public QListView { - public: - CompleterPopup(QWidget *parent = nullptr); + public: + CompleterPopup(QWidget* parent = nullptr); - int sizeHintForRow(int row) const override; + int sizeHintForRow(int row) const override; }; } diff --git a/apps/opencs/view/widget/droplineedit.cpp b/apps/opencs/view/widget/droplineedit.cpp index 2ca3064613..3e429402c0 100644 --- a/apps/opencs/view/widget/droplineedit.cpp +++ b/apps/opencs/view/widget/droplineedit.cpp @@ -7,14 +7,14 @@ #include "../world/dragdroputils.hpp" -CSVWidget::DropLineEdit::DropLineEdit(CSMWorld::ColumnBase::Display type, QWidget *parent) - : QLineEdit(parent), - mDropType(type) +CSVWidget::DropLineEdit::DropLineEdit(CSMWorld::ColumnBase::Display type, QWidget* parent) + : QLineEdit(parent) + , mDropType(type) { setAcceptDrops(true); } -void CSVWidget::DropLineEdit::dragEnterEvent(QDragEnterEvent *event) +void CSVWidget::DropLineEdit::dragEnterEvent(QDragEnterEvent* event) { if (CSVWorld::DragDropUtils::canAcceptData(*event, mDropType)) { @@ -22,7 +22,7 @@ void CSVWidget::DropLineEdit::dragEnterEvent(QDragEnterEvent *event) } } -void CSVWidget::DropLineEdit::dragMoveEvent(QDragMoveEvent *event) +void CSVWidget::DropLineEdit::dragMoveEvent(QDragMoveEvent* event) { if (CSVWorld::DragDropUtils::canAcceptData(*event, mDropType)) { @@ -30,7 +30,7 @@ void CSVWidget::DropLineEdit::dragMoveEvent(QDragMoveEvent *event) } } -void CSVWidget::DropLineEdit::dropEvent(QDropEvent *event) +void CSVWidget::DropLineEdit::dropEvent(QDropEvent* event) { if (CSVWorld::DragDropUtils::canAcceptData(*event, mDropType)) { diff --git a/apps/opencs/view/widget/droplineedit.hpp b/apps/opencs/view/widget/droplineedit.hpp index 9110518736..5d6fd26227 100644 --- a/apps/opencs/view/widget/droplineedit.hpp +++ b/apps/opencs/view/widget/droplineedit.hpp @@ -20,21 +20,21 @@ namespace CSVWidget { class DropLineEdit : public QLineEdit { - Q_OBJECT + Q_OBJECT - CSMWorld::ColumnBase::Display mDropType; - ///< The accepted Display type for this LineEdit. + CSMWorld::ColumnBase::Display mDropType; + ///< The accepted Display type for this LineEdit. - public: - DropLineEdit(CSMWorld::ColumnBase::Display type, QWidget *parent = nullptr); + public: + DropLineEdit(CSMWorld::ColumnBase::Display type, QWidget* parent = nullptr); - protected: - void dragEnterEvent(QDragEnterEvent *event) override; - void dragMoveEvent(QDragMoveEvent *event) override; - void dropEvent(QDropEvent *event) override; + protected: + void dragEnterEvent(QDragEnterEvent* event) override; + void dragMoveEvent(QDragMoveEvent* event) override; + void dropEvent(QDropEvent* event) override; - signals: - void tableMimeDataDropped(const CSMWorld::UniversalId &id, const CSMDoc::Document *document); + signals: + void tableMimeDataDropped(const CSMWorld::UniversalId& id, const CSMDoc::Document* document); }; } diff --git a/apps/opencs/view/widget/modebutton.cpp b/apps/opencs/view/widget/modebutton.cpp index 88f0502479..042f845575 100644 --- a/apps/opencs/view/widget/modebutton.cpp +++ b/apps/opencs/view/widget/modebutton.cpp @@ -1,14 +1,15 @@ #include "modebutton.hpp" -CSVWidget::ModeButton::ModeButton (const QIcon& icon, const QString& tooltip, QWidget *parent) -: PushButton (icon, Type_Mode, tooltip, parent) -{} +CSVWidget::ModeButton::ModeButton(const QIcon& icon, const QString& tooltip, QWidget* parent) + : PushButton(icon, Type_Mode, tooltip, parent) +{ +} -void CSVWidget::ModeButton::activate (SceneToolbar *toolbar) {} +void CSVWidget::ModeButton::activate(SceneToolbar* toolbar) {} -void CSVWidget::ModeButton::deactivate (SceneToolbar *toolbar) {} +void CSVWidget::ModeButton::deactivate(SceneToolbar* toolbar) {} -bool CSVWidget::ModeButton::createContextMenu (QMenu *menu) +bool CSVWidget::ModeButton::createContextMenu(QMenu* menu) { return false; } diff --git a/apps/opencs/view/widget/modebutton.hpp b/apps/opencs/view/widget/modebutton.hpp index f595969231..75b05e28e3 100644 --- a/apps/opencs/view/widget/modebutton.hpp +++ b/apps/opencs/view/widget/modebutton.hpp @@ -12,26 +12,24 @@ namespace CSVWidget /// \brief Specialist PushButton of Type_Mode for use in SceneToolMode class ModeButton : public PushButton { - Q_OBJECT + Q_OBJECT - public: + public: + ModeButton(const QIcon& icon, const QString& tooltip = "", QWidget* parent = nullptr); - ModeButton (const QIcon& icon, const QString& tooltip = "", - QWidget *parent = nullptr); + /// Default-Implementation: do nothing + virtual void activate(SceneToolbar* toolbar); - /// Default-Implementation: do nothing - virtual void activate (SceneToolbar *toolbar); + /// Default-Implementation: do nothing + virtual void deactivate(SceneToolbar* toolbar); - /// Default-Implementation: do nothing - virtual void deactivate (SceneToolbar *toolbar); - - /// Add context menu items to \a menu. Default-implementation: return false - /// - /// \attention menu can be a 0-pointer - /// - /// \return Have there been any menu items to be added (if menu is 0 and there - /// items to be added, the function must return true anyway. - virtual bool createContextMenu (QMenu *menu); + /// Add context menu items to \a menu. Default-implementation: return false + /// + /// \attention menu can be a 0-pointer + /// + /// \return Have there been any menu items to be added (if menu is 0 and there + /// items to be added, the function must return true anyway. + virtual bool createContextMenu(QMenu* menu); }; } diff --git a/apps/opencs/view/widget/pushbutton.cpp b/apps/opencs/view/widget/pushbutton.cpp index 31fdf5a19f..c1c3f9d285 100644 --- a/apps/opencs/view/widget/pushbutton.cpp +++ b/apps/opencs/view/widget/pushbutton.cpp @@ -1,10 +1,10 @@ #include "pushbutton.hpp" -#include #include +#include -#include "../../model/prefs/state.hpp" #include "../../model/prefs/shortcutmanager.hpp" +#include "../../model/prefs/state.hpp" void CSVWidget::PushButton::processShortcuts() { @@ -22,8 +22,7 @@ void CSVWidget::PushButton::setExtendedToolTip() { case Type_TopMode: - tooltip += - "

        (left click to change mode)"; + tooltip += "

        (left click to change mode)"; break; @@ -50,52 +49,56 @@ void CSVWidget::PushButton::setExtendedToolTip() break; } - setToolTip (tooltip); + setToolTip(tooltip); } -void CSVWidget::PushButton::keyPressEvent (QKeyEvent *event) +void CSVWidget::PushButton::keyPressEvent(QKeyEvent* event) { - if (event->key()!=Qt::Key_Shift) + if (event->key() != Qt::Key_Shift) mKeepOpen = false; - QPushButton::keyPressEvent (event); + QPushButton::keyPressEvent(event); } -void CSVWidget::PushButton::keyReleaseEvent (QKeyEvent *event) +void CSVWidget::PushButton::keyReleaseEvent(QKeyEvent* event) { - if (event->key()==Qt::Key_Space) + if (event->key() == Qt::Key_Space) mKeepOpen = event->modifiers() & Qt::ShiftModifier; - QPushButton::keyReleaseEvent (event); + QPushButton::keyReleaseEvent(event); } -void CSVWidget::PushButton::mouseReleaseEvent (QMouseEvent *event) +void CSVWidget::PushButton::mouseReleaseEvent(QMouseEvent* event) { - mKeepOpen = event->button()==Qt::LeftButton && (event->modifiers() & Qt::ShiftModifier); - QPushButton::mouseReleaseEvent (event); + mKeepOpen = event->button() == Qt::LeftButton && (event->modifiers() & Qt::ShiftModifier); + QPushButton::mouseReleaseEvent(event); } -CSVWidget::PushButton::PushButton (const QIcon& icon, Type type, const QString& tooltip, - QWidget *parent) -: QPushButton (icon, "", parent), mKeepOpen (false), mType (type), mToolTip (tooltip) +CSVWidget::PushButton::PushButton(const QIcon& icon, Type type, const QString& tooltip, QWidget* parent) + : QPushButton(icon, "", parent) + , mKeepOpen(false) + , mType(type) + , mToolTip(tooltip) { - if (type==Type_Mode || type==Type_Toggle) + if (type == Type_Mode || type == Type_Toggle) { - setCheckable (true); - connect (this, &PushButton::toggled, this, &PushButton::checkedStateChanged); + setCheckable(true); + connect(this, &PushButton::toggled, this, &PushButton::checkedStateChanged); } - setCheckable (type==Type_Mode || type==Type_Toggle); + setCheckable(type == Type_Mode || type == Type_Toggle); processShortcuts(); setExtendedToolTip(); - connect (&CSMPrefs::State::get(), &CSMPrefs::State::settingChanged, - this, &PushButton::settingChanged); + connect(&CSMPrefs::State::get(), &CSMPrefs::State::settingChanged, this, &PushButton::settingChanged); } -CSVWidget::PushButton::PushButton (Type type, const QString& tooltip, QWidget *parent) -: QPushButton (parent), mKeepOpen (false), mType (type), mToolTip (tooltip) +CSVWidget::PushButton::PushButton(Type type, const QString& tooltip, QWidget* parent) + : QPushButton(parent) + , mKeepOpen(false) + , mType(type) + , mToolTip(tooltip) { - setCheckable (type==Type_Mode || type==Type_Toggle); + setCheckable(type == Type_Mode || type == Type_Toggle); processShortcuts(); setExtendedToolTip(); } @@ -115,12 +118,12 @@ CSVWidget::PushButton::Type CSVWidget::PushButton::getType() const return mType; } -void CSVWidget::PushButton::checkedStateChanged (bool checked) +void CSVWidget::PushButton::checkedStateChanged(bool checked) { setExtendedToolTip(); } -void CSVWidget::PushButton::settingChanged (const CSMPrefs::Setting *setting) +void CSVWidget::PushButton::settingChanged(const CSMPrefs::Setting* setting) { if (setting->getParent()->getKey() == "Key Bindings") { diff --git a/apps/opencs/view/widget/pushbutton.hpp b/apps/opencs/view/widget/pushbutton.hpp index b3aaaebef2..b5a07173af 100644 --- a/apps/opencs/view/widget/pushbutton.hpp +++ b/apps/opencs/view/widget/pushbutton.hpp @@ -12,59 +12,52 @@ namespace CSVWidget { class PushButton : public QPushButton { - Q_OBJECT + Q_OBJECT - public: + public: + enum Type + { + Type_TopMode, // top level button for mode selector panel + Type_TopAction, // top level button that triggers an action + Type_Mode, // mode button + Type_Toggle + }; - enum Type - { - Type_TopMode, // top level button for mode selector panel - Type_TopAction, // top level button that triggers an action - Type_Mode, // mode button - Type_Toggle - }; + private: + bool mKeepOpen; + Type mType; + QString mToolTip; + QString mProcessedToolTip; - private: + private: + void processShortcuts(); + void setExtendedToolTip(); - bool mKeepOpen; - Type mType; - QString mToolTip; - QString mProcessedToolTip; + protected: + void keyPressEvent(QKeyEvent* event) override; - private: + void keyReleaseEvent(QKeyEvent* event) override; - void processShortcuts(); - void setExtendedToolTip(); + void mouseReleaseEvent(QMouseEvent* event) override; - protected: + public: + /// \param push Do not maintain a toggle state + PushButton(const QIcon& icon, Type type, const QString& tooltip = "", QWidget* parent = nullptr); - void keyPressEvent (QKeyEvent *event) override; + /// \param push Do not maintain a toggle state + PushButton(Type type, const QString& tooltip = "", QWidget* parent = nullptr); - void keyReleaseEvent (QKeyEvent *event) override; + bool hasKeepOpen() const; - void mouseReleaseEvent (QMouseEvent *event) override; + /// Return tooltip used at construction (without any button-specific modifications) + QString getBaseToolTip() const; - public: + Type getType() const; - /// \param push Do not maintain a toggle state - PushButton (const QIcon& icon, Type type, const QString& tooltip = "", - QWidget *parent = nullptr); + private slots: - /// \param push Do not maintain a toggle state - PushButton (Type type, const QString& tooltip = "", - QWidget *parent = nullptr); - - bool hasKeepOpen() const; - - /// Return tooltip used at construction (without any button-specific modifications) - QString getBaseToolTip() const; - - Type getType() const; - - private slots: - - void checkedStateChanged (bool checked); - void settingChanged (const CSMPrefs::Setting *setting); + void checkedStateChanged(bool checked); + void settingChanged(const CSMPrefs::Setting* setting); }; } diff --git a/apps/opencs/view/widget/scenetool.cpp b/apps/opencs/view/widget/scenetool.cpp index 9923c26e96..3eecf6d95d 100644 --- a/apps/opencs/view/widget/scenetool.cpp +++ b/apps/opencs/view/widget/scenetool.cpp @@ -4,30 +4,30 @@ #include "scenetoolbar.hpp" -CSVWidget::SceneTool::SceneTool (SceneToolbar *parent, Type type) -: PushButton (type, "", parent) +CSVWidget::SceneTool::SceneTool(SceneToolbar* parent, Type type) + : PushButton(type, "", parent) { - setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed)); - setIconSize (QSize (parent->getIconSize(), parent->getIconSize())); - setFixedSize (parent->getButtonSize(), parent->getButtonSize()); + setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); + setIconSize(QSize(parent->getIconSize(), parent->getIconSize())); + setFixedSize(parent->getButtonSize(), parent->getButtonSize()); - connect (this, &SceneTool::clicked, this, &SceneTool::openRequest); + connect(this, &SceneTool::clicked, this, &SceneTool::openRequest); } void CSVWidget::SceneTool::activate() {} -void CSVWidget::SceneTool::mouseReleaseEvent (QMouseEvent *event) +void CSVWidget::SceneTool::mouseReleaseEvent(QMouseEvent* event) { - if (getType()==Type_TopAction && event->button()==Qt::RightButton) - showPanel (parentWidget()->mapToGlobal (pos())); + if (getType() == Type_TopAction && event->button() == Qt::RightButton) + showPanel(parentWidget()->mapToGlobal(pos())); else - PushButton::mouseReleaseEvent (event); + PushButton::mouseReleaseEvent(event); } void CSVWidget::SceneTool::openRequest() { - if (getType()==Type_TopAction) + if (getType() == Type_TopAction) activate(); else - showPanel (parentWidget()->mapToGlobal (pos())); + showPanel(parentWidget()->mapToGlobal(pos())); } diff --git a/apps/opencs/view/widget/scenetool.hpp b/apps/opencs/view/widget/scenetool.hpp index 295375f26d..b4f7fbeb1b 100644 --- a/apps/opencs/view/widget/scenetool.hpp +++ b/apps/opencs/view/widget/scenetool.hpp @@ -10,25 +10,23 @@ namespace CSVWidget ///< \brief Tool base class class SceneTool : public PushButton { - Q_OBJECT + Q_OBJECT - public: + public: + SceneTool(SceneToolbar* parent, Type type = Type_TopMode); - SceneTool (SceneToolbar *parent, Type type = Type_TopMode); + virtual void showPanel(const QPoint& position) = 0; - virtual void showPanel (const QPoint& position) = 0; + /// This function will only called for buttons of type Type_TopAction. The default + /// implementation is empty. + virtual void activate(); - /// This function will only called for buttons of type Type_TopAction. The default - /// implementation is empty. - virtual void activate(); + protected: + void mouseReleaseEvent(QMouseEvent* event) override; - protected: + private slots: - void mouseReleaseEvent (QMouseEvent *event) override; - - private slots: - - void openRequest(); + void openRequest(); }; } diff --git a/apps/opencs/view/widget/scenetoolbar.cpp b/apps/opencs/view/widget/scenetoolbar.cpp index 81155150b8..bd6ce827a0 100644 --- a/apps/opencs/view/widget/scenetoolbar.cpp +++ b/apps/opencs/view/widget/scenetoolbar.cpp @@ -6,45 +6,46 @@ #include "scenetool.hpp" -void CSVWidget::SceneToolbar::focusInEvent (QFocusEvent *event) +void CSVWidget::SceneToolbar::focusInEvent(QFocusEvent* event) { - QWidget::focusInEvent (event); + QWidget::focusInEvent(event); if (mLayout->count()) - dynamic_cast (*mLayout->itemAt (0)).widget()->setFocus(); + dynamic_cast(*mLayout->itemAt(0)).widget()->setFocus(); } -CSVWidget::SceneToolbar::SceneToolbar (int buttonSize, QWidget *parent) -: QWidget (parent), mButtonSize (buttonSize), mIconSize (buttonSize-6) +CSVWidget::SceneToolbar::SceneToolbar(int buttonSize, QWidget* parent) + : QWidget(parent) + , mButtonSize(buttonSize) + , mIconSize(buttonSize - 6) { - setFixedWidth (mButtonSize); + setFixedWidth(mButtonSize); - mLayout = new QVBoxLayout (this); - mLayout->setAlignment (Qt::AlignTop); + mLayout = new QVBoxLayout(this); + mLayout->setAlignment(Qt::AlignTop); - mLayout->setContentsMargins (QMargins (0, 0, 0, 0)); + mLayout->setContentsMargins(QMargins(0, 0, 0, 0)); - setLayout (mLayout); + setLayout(mLayout); CSMPrefs::Shortcut* focusSceneShortcut = new CSMPrefs::Shortcut("scene-focus-toolbar", this); - connect(focusSceneShortcut, qOverload<>(&CSMPrefs::Shortcut::activated), - this, &SceneToolbar::focusSceneRequest); + connect(focusSceneShortcut, qOverload<>(&CSMPrefs::Shortcut::activated), this, &SceneToolbar::focusSceneRequest); } -void CSVWidget::SceneToolbar::addTool (SceneTool *tool, SceneTool *insertPoint) +void CSVWidget::SceneToolbar::addTool(SceneTool* tool, SceneTool* insertPoint) { if (!insertPoint) - mLayout->addWidget (tool, 0, Qt::AlignTop); + mLayout->addWidget(tool, 0, Qt::AlignTop); else { - int index = mLayout->indexOf (insertPoint); - mLayout->insertWidget (index+1, tool, 0, Qt::AlignTop); + int index = mLayout->indexOf(insertPoint); + mLayout->insertWidget(index + 1, tool, 0, Qt::AlignTop); } } -void CSVWidget::SceneToolbar::removeTool (SceneTool *tool) +void CSVWidget::SceneToolbar::removeTool(SceneTool* tool) { - mLayout->removeWidget (tool); + mLayout->removeWidget(tool); } int CSVWidget::SceneToolbar::getButtonSize() const diff --git a/apps/opencs/view/widget/scenetoolbar.hpp b/apps/opencs/view/widget/scenetoolbar.hpp index 70f5807652..6b4e503bd2 100644 --- a/apps/opencs/view/widget/scenetoolbar.hpp +++ b/apps/opencs/view/widget/scenetoolbar.hpp @@ -11,33 +11,31 @@ namespace CSVWidget class SceneToolbar : public QWidget { - Q_OBJECT + Q_OBJECT - QVBoxLayout *mLayout; - int mButtonSize; - int mIconSize; + QVBoxLayout* mLayout; + int mButtonSize; + int mIconSize; - protected: + protected: + void focusInEvent(QFocusEvent* event) override; - void focusInEvent (QFocusEvent *event) override; + public: + SceneToolbar(int buttonSize, QWidget* parent = nullptr); - public: + /// If insertPoint==0, insert \a tool at the end of the scrollbar. Otherwise + /// insert tool after \a insertPoint. + void addTool(SceneTool* tool, SceneTool* insertPoint = nullptr); - SceneToolbar (int buttonSize, QWidget *parent = nullptr); + void removeTool(SceneTool* tool); - /// If insertPoint==0, insert \a tool at the end of the scrollbar. Otherwise - /// insert tool after \a insertPoint. - void addTool (SceneTool *tool, SceneTool *insertPoint = nullptr); + int getButtonSize() const; - void removeTool (SceneTool *tool); + int getIconSize() const; - int getButtonSize() const; + signals: - int getIconSize() const; - - signals: - - void focusSceneRequest(); + void focusSceneRequest(); }; } diff --git a/apps/opencs/view/widget/scenetoolmode.cpp b/apps/opencs/view/widget/scenetoolmode.cpp index 90b6c36e31..c415216978 100644 --- a/apps/opencs/view/widget/scenetoolmode.cpp +++ b/apps/opencs/view/widget/scenetoolmode.cpp @@ -1,30 +1,30 @@ #include "scenetoolmode.hpp" -#include -#include -#include #include #include +#include +#include +#include -#include "scenetoolbar.hpp" #include "modebutton.hpp" +#include "scenetoolbar.hpp" -void CSVWidget::SceneToolMode::contextMenuEvent (QContextMenuEvent *event) +void CSVWidget::SceneToolMode::contextMenuEvent(QContextMenuEvent* event) { - QMenu menu (this); - if (createContextMenu (&menu)) - menu.exec (event->globalPos()); + QMenu menu(this); + if (createContextMenu(&menu)) + menu.exec(event->globalPos()); } -bool CSVWidget::SceneToolMode::createContextMenu (QMenu *menu) +bool CSVWidget::SceneToolMode::createContextMenu(QMenu* menu) { if (mCurrent) - return mCurrent->createContextMenu (menu); + return mCurrent->createContextMenu(menu); return false; } -void CSVWidget::SceneToolMode::adjustToolTip (const ModeButton *activeMode) +void CSVWidget::SceneToolMode::adjustToolTip(const ModeButton* activeMode) { QString toolTip = mToolTip; @@ -32,103 +32,105 @@ void CSVWidget::SceneToolMode::adjustToolTip (const ModeButton *activeMode) toolTip += "

        (left click to change mode)"; - if (createContextMenu (nullptr)) + if (createContextMenu(nullptr)) toolTip += "
        (right click to access context menu)"; - setToolTip (toolTip); + setToolTip(toolTip); } -void CSVWidget::SceneToolMode::setButton (std::map::iterator iter) +void CSVWidget::SceneToolMode::setButton(std::map::iterator iter) { - for (std::map::const_iterator iter2 = mButtons.begin(); - iter2!=mButtons.end(); ++iter2) - iter2->first->setChecked (iter2==iter); + for (std::map::const_iterator iter2 = mButtons.begin(); iter2 != mButtons.end(); ++iter2) + iter2->first->setChecked(iter2 == iter); - setIcon (iter->first->icon()); - adjustToolTip (iter->first); + setIcon(iter->first->icon()); + adjustToolTip(iter->first); - if (mCurrent!=iter->first) + if (mCurrent != iter->first) { if (mCurrent) - mCurrent->deactivate (mToolbar); + mCurrent->deactivate(mToolbar); mCurrent = iter->first; - mCurrent->activate (mToolbar); + mCurrent->activate(mToolbar); } - emit modeChanged (iter->second); + emit modeChanged(iter->second); } -CSVWidget::SceneToolMode::SceneToolMode (SceneToolbar *parent, const QString& toolTip) -: SceneTool (parent), mButtonSize (parent->getButtonSize()), mIconSize (parent->getIconSize()), - mToolTip (toolTip), mFirst (nullptr), mCurrent (nullptr), mToolbar (parent) +CSVWidget::SceneToolMode::SceneToolMode(SceneToolbar* parent, const QString& toolTip) + : SceneTool(parent) + , mButtonSize(parent->getButtonSize()) + , mIconSize(parent->getIconSize()) + , mToolTip(toolTip) + , mFirst(nullptr) + , mCurrent(nullptr) + , mToolbar(parent) { - mPanel = new QFrame (this, Qt::Popup); + mPanel = new QFrame(this, Qt::Popup); - mLayout = new QHBoxLayout (mPanel); + mLayout = new QHBoxLayout(mPanel); - mLayout->setContentsMargins (QMargins (0, 0, 0, 0)); + mLayout->setContentsMargins(QMargins(0, 0, 0, 0)); - mPanel->setLayout (mLayout); + mPanel->setLayout(mLayout); } -void CSVWidget::SceneToolMode::showPanel (const QPoint& position) +void CSVWidget::SceneToolMode::showPanel(const QPoint& position) { - mPanel->move (position); + mPanel->move(position); mPanel->show(); if (mFirst) - mFirst->setFocus (Qt::OtherFocusReason); + mFirst->setFocus(Qt::OtherFocusReason); } -void CSVWidget::SceneToolMode::addButton (const std::string& icon, const std::string& id, - const QString& tooltip) +void CSVWidget::SceneToolMode::addButton(const std::string& icon, const std::string& id, const QString& tooltip) { - ModeButton *button = new ModeButton (QIcon (QPixmap (icon.c_str())), tooltip, mPanel); - addButton (button, id); + ModeButton* button = new ModeButton(QIcon(QPixmap(icon.c_str())), tooltip, mPanel); + addButton(button, id); } -void CSVWidget::SceneToolMode::addButton (ModeButton *button, const std::string& id) +void CSVWidget::SceneToolMode::addButton(ModeButton* button, const std::string& id) { - button->setParent (mPanel); + button->setParent(mPanel); - button->setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed)); - button->setIconSize (QSize (mIconSize, mIconSize)); - button->setFixedSize (mButtonSize, mButtonSize); + button->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); + button->setIconSize(QSize(mIconSize, mIconSize)); + button->setFixedSize(mButtonSize, mButtonSize); - mLayout->addWidget (button); + mLayout->addWidget(button); - mButtons.insert (std::make_pair (button, id)); + mButtons.insert(std::make_pair(button, id)); - connect (button, &ModeButton::clicked, this, &SceneToolMode::selected); + connect(button, &ModeButton::clicked, this, &SceneToolMode::selected); - if (mButtons.size()==1) + if (mButtons.size() == 1) { mFirst = mCurrent = button; - setIcon (button->icon()); - button->setChecked (true); - adjustToolTip (button); - mCurrent->activate (mToolbar); + setIcon(button->icon()); + button->setChecked(true); + adjustToolTip(button); + mCurrent->activate(mToolbar); } } -CSVWidget::ModeButton *CSVWidget::SceneToolMode::getCurrent() +CSVWidget::ModeButton* CSVWidget::SceneToolMode::getCurrent() { return mCurrent; } std::string CSVWidget::SceneToolMode::getCurrentId() const { - return mButtons.find (mCurrent)->second; + return mButtons.find(mCurrent)->second; } -void CSVWidget::SceneToolMode::setButton (const std::string& id) +void CSVWidget::SceneToolMode::setButton(const std::string& id) { - for (std::map::iterator iter = mButtons.begin(); - iter!=mButtons.end(); ++iter) - if (iter->second==id) + for (std::map::iterator iter = mButtons.begin(); iter != mButtons.end(); ++iter) + if (iter->second == id) { - setButton (iter); + setButton(iter); break; } } @@ -145,14 +147,13 @@ bool CSVWidget::SceneToolMode::event(QEvent* event) void CSVWidget::SceneToolMode::selected() { - std::map::iterator iter = - mButtons.find (dynamic_cast (sender())); + std::map::iterator iter = mButtons.find(dynamic_cast(sender())); - if (iter!=mButtons.end()) + if (iter != mButtons.end()) { if (!iter->first->hasKeepOpen()) mPanel->hide(); - setButton (iter); + setButton(iter); } } diff --git a/apps/opencs/view/widget/scenetoolmode.hpp b/apps/opencs/view/widget/scenetoolmode.hpp index 896a6d9c66..ee19f678be 100644 --- a/apps/opencs/view/widget/scenetoolmode.hpp +++ b/apps/opencs/view/widget/scenetoolmode.hpp @@ -17,65 +17,62 @@ namespace CSVWidget ///< \brief Mode selector tool class SceneToolMode : public SceneTool { - Q_OBJECT + Q_OBJECT - QWidget *mPanel; - QHBoxLayout *mLayout; - std::map mButtons; // widget, id - int mButtonSize; - int mIconSize; - QString mToolTip; - PushButton *mFirst; - ModeButton *mCurrent; - SceneToolbar *mToolbar; + QWidget* mPanel; + QHBoxLayout* mLayout; + std::map mButtons; // widget, id + int mButtonSize; + int mIconSize; + QString mToolTip; + PushButton* mFirst; + ModeButton* mCurrent; + SceneToolbar* mToolbar; - void adjustToolTip (const ModeButton *activeMode); + void adjustToolTip(const ModeButton* activeMode); - void contextMenuEvent (QContextMenuEvent *event) override; + void contextMenuEvent(QContextMenuEvent* event) override; - /// Add context menu items to \a menu. Default-implementation: Pass on request to - /// current mode button or return false, if there is no current mode button. - /// - /// \attention menu can be a 0-pointer - /// - /// \return Have there been any menu items to be added (if menu is 0 and there - /// items to be added, the function must return true anyway. - virtual bool createContextMenu (QMenu *menu); + /// Add context menu items to \a menu. Default-implementation: Pass on request to + /// current mode button or return false, if there is no current mode button. + /// + /// \attention menu can be a 0-pointer + /// + /// \return Have there been any menu items to be added (if menu is 0 and there + /// items to be added, the function must return true anyway. + virtual bool createContextMenu(QMenu* menu); - void setButton (std::map::iterator iter); + void setButton(std::map::iterator iter); - protected: + protected: + bool event(QEvent* event) override; - bool event(QEvent* event) override; + public: + SceneToolMode(SceneToolbar* parent, const QString& toolTip); - public: + void showPanel(const QPoint& position) override; - SceneToolMode (SceneToolbar *parent, const QString& toolTip); + void addButton(const std::string& icon, const std::string& id, const QString& tooltip = ""); - void showPanel (const QPoint& position) override; + /// The ownership of \a button is transferred to *this. + void addButton(ModeButton* button, const std::string& id); - void addButton (const std::string& icon, const std::string& id, - const QString& tooltip = ""); + /// Will return a 0-pointer only if the mode does not have any buttons yet. + ModeButton* getCurrent(); - /// The ownership of \a button is transferred to *this. - void addButton (ModeButton *button, const std::string& id); + /// Must not be called if there aren't any buttons yet. + std::string getCurrentId() const; - /// Will return a 0-pointer only if the mode does not have any buttons yet. - ModeButton *getCurrent(); + /// Manually change the current mode + void setButton(const std::string& id); - /// Must not be called if there aren't any buttons yet. - std::string getCurrentId() const; + signals: - /// Manually change the current mode - void setButton (const std::string& id); + void modeChanged(const std::string& id); - signals: + private slots: - void modeChanged (const std::string& id); - - private slots: - - void selected(); + void selected(); }; } diff --git a/apps/opencs/view/widget/scenetoolrun.cpp b/apps/opencs/view/widget/scenetoolrun.cpp index 5dde1a2ccd..4b60e6845e 100644 --- a/apps/opencs/view/widget/scenetoolrun.cpp +++ b/apps/opencs/view/widget/scenetoolrun.cpp @@ -2,123 +2,124 @@ #include +#include #include -#include #include #include -#include +#include void CSVWidget::SceneToolRun::adjustToolTips() { QString toolTip = mToolTip; - if (mSelected==mProfiles.end()) + if (mSelected == mProfiles.end()) toolTip += "

        No debug profile selected (function disabled)"; else { - toolTip += "

        Debug profile: " + QString::fromUtf8 (mSelected->c_str()); + toolTip += "

        Debug profile: " + QString::fromUtf8(mSelected->c_str()); toolTip += "

        (right click to switch to a different profile)"; } - setToolTip (toolTip); + setToolTip(toolTip); } void CSVWidget::SceneToolRun::updateIcon() { - setDisabled (mSelected==mProfiles.end()); + setDisabled(mSelected == mProfiles.end()); } void CSVWidget::SceneToolRun::updatePanel() { - mTable->setRowCount (static_cast(mProfiles.size())); + mTable->setRowCount(static_cast(mProfiles.size())); int i = 0; - for (std::set::const_iterator iter (mProfiles.begin()); iter!=mProfiles.end(); - ++iter, ++i) + for (std::set::const_iterator iter(mProfiles.begin()); iter != mProfiles.end(); ++iter, ++i) { - mTable->setItem (i, 0, new QTableWidgetItem (QString::fromUtf8 (iter->c_str()))); + mTable->setItem(i, 0, new QTableWidgetItem(QString::fromUtf8(iter->c_str()))); - mTable->setItem (i, 1, new QTableWidgetItem ( - QApplication::style()->standardIcon (QStyle::SP_TitleBarCloseButton), "")); + mTable->setItem( + i, 1, new QTableWidgetItem(QApplication::style()->standardIcon(QStyle::SP_TitleBarCloseButton), "")); } } -CSVWidget::SceneToolRun::SceneToolRun (SceneToolbar *parent, const QString& toolTip, - const QString& icon, const std::vector& profiles) -: SceneTool (parent, Type_TopAction), mProfiles (profiles.begin(), profiles.end()), - mSelected (mProfiles.begin()), mToolTip (toolTip) +CSVWidget::SceneToolRun::SceneToolRun( + SceneToolbar* parent, const QString& toolTip, const QString& icon, const std::vector& profiles) + : SceneTool(parent, Type_TopAction) + , mProfiles(profiles.begin(), profiles.end()) + , mSelected(mProfiles.begin()) + , mToolTip(toolTip) { - setIcon (QIcon (icon)); + setIcon(QIcon(icon)); updateIcon(); adjustToolTips(); - mPanel = new QFrame (this, Qt::Popup); + mPanel = new QFrame(this, Qt::Popup); - QHBoxLayout *layout = new QHBoxLayout (mPanel); + QHBoxLayout* layout = new QHBoxLayout(mPanel); - layout->setContentsMargins (QMargins (0, 0, 0, 0)); + layout->setContentsMargins(QMargins(0, 0, 0, 0)); - mTable = new QTableWidget (0, 2, this); + mTable = new QTableWidget(0, 2, this); - mTable->setShowGrid (false); + mTable->setShowGrid(false); mTable->verticalHeader()->hide(); mTable->horizontalHeader()->hide(); - mTable->horizontalHeader()->setSectionResizeMode (0, QHeaderView::Stretch); - mTable->horizontalHeader()->setSectionResizeMode (1, QHeaderView::ResizeToContents); - mTable->setSelectionMode (QAbstractItemView::NoSelection); + mTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); + mTable->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents); + mTable->setSelectionMode(QAbstractItemView::NoSelection); - layout->addWidget (mTable); + layout->addWidget(mTable); - connect (mTable, &QTableWidget::clicked, this, &SceneToolRun::clicked); + connect(mTable, &QTableWidget::clicked, this, &SceneToolRun::clicked); } -void CSVWidget::SceneToolRun::showPanel (const QPoint& position) +void CSVWidget::SceneToolRun::showPanel(const QPoint& position) { updatePanel(); - mPanel->move (position); + mPanel->move(position); mPanel->show(); } void CSVWidget::SceneToolRun::activate() { - if (mSelected!=mProfiles.end()) - emit runRequest (*mSelected); + if (mSelected != mProfiles.end()) + emit runRequest(*mSelected); } -void CSVWidget::SceneToolRun::removeProfile (const std::string& profile) +void CSVWidget::SceneToolRun::removeProfile(const std::string& profile) { - std::set::iterator iter = mProfiles.find (profile); + std::set::iterator iter = mProfiles.find(profile); - if (iter!=mProfiles.end()) + if (iter != mProfiles.end()) { - if (iter==mSelected) + if (iter == mSelected) { - if (iter!=mProfiles.begin()) + if (iter != mProfiles.begin()) --mSelected; else ++mSelected; } - mProfiles.erase (iter); + mProfiles.erase(iter); - if (mSelected==mProfiles.end()) + if (mSelected == mProfiles.end()) updateIcon(); adjustToolTips(); } } -void CSVWidget::SceneToolRun::addProfile (const std::string& profile) +void CSVWidget::SceneToolRun::addProfile(const std::string& profile) { - std::set::iterator iter = mProfiles.find (profile); + std::set::iterator iter = mProfiles.find(profile); - if (iter==mProfiles.end()) + if (iter == mProfiles.end()) { - mProfiles.insert (profile); + mProfiles.insert(profile); - if (mSelected==mProfiles.end()) + if (mSelected == mProfiles.end()) { mSelected = mProfiles.begin(); updateIcon(); @@ -128,22 +129,22 @@ void CSVWidget::SceneToolRun::addProfile (const std::string& profile) } } -void CSVWidget::SceneToolRun::clicked (const QModelIndex& index) +void CSVWidget::SceneToolRun::clicked(const QModelIndex& index) { - if (index.column()==0) + if (index.column() == 0) { // select profile mSelected = mProfiles.begin(); - std::advance (mSelected, index.row()); + std::advance(mSelected, index.row()); mPanel->hide(); adjustToolTips(); } - else if (index.column()==1) + else if (index.column() == 1) { // remove profile from list std::set::iterator iter = mProfiles.begin(); - std::advance (iter, index.row()); - removeProfile (*iter); + std::advance(iter, index.row()); + removeProfile(*iter); updatePanel(); } } diff --git a/apps/opencs/view/widget/scenetoolrun.hpp b/apps/opencs/view/widget/scenetoolrun.hpp index 4a90aa7c06..83142bd1e6 100644 --- a/apps/opencs/view/widget/scenetoolrun.hpp +++ b/apps/opencs/view/widget/scenetoolrun.hpp @@ -14,48 +14,46 @@ namespace CSVWidget { class SceneToolRun : public SceneTool { - Q_OBJECT + Q_OBJECT - std::set mProfiles; - std::set::iterator mSelected; - QString mToolTip; - QFrame *mPanel; - QTableWidget *mTable; + std::set mProfiles; + std::set::iterator mSelected; + QString mToolTip; + QFrame* mPanel; + QTableWidget* mTable; - private: + private: + void adjustToolTips(); - void adjustToolTips(); + void updateIcon(); - void updateIcon(); + void updatePanel(); - void updatePanel(); + public: + SceneToolRun(SceneToolbar* parent, const QString& toolTip, const QString& icon, + const std::vector& profiles); - public: + void showPanel(const QPoint& position) override; - SceneToolRun (SceneToolbar *parent, const QString& toolTip, const QString& icon, - const std::vector& profiles); + void activate() override; - void showPanel (const QPoint& position) override; + /// \attention This function does not remove the profile from the profile selection + /// panel. + void removeProfile(const std::string& profile); - void activate() override; + /// \attention This function doe not add the profile to the profile selection + /// panel. This only happens when the panel is re-opened. + /// + /// \note Adding profiles that are already listed is a no-op. + void addProfile(const std::string& profile); - /// \attention This function does not remove the profile from the profile selection - /// panel. - void removeProfile (const std::string& profile); + private slots: - /// \attention This function doe not add the profile to the profile selection - /// panel. This only happens when the panel is re-opened. - /// - /// \note Adding profiles that are already listed is a no-op. - void addProfile (const std::string& profile); + void clicked(const QModelIndex& index); - private slots: + signals: - void clicked (const QModelIndex& index); - - signals: - - void runRequest (const std::string& profile); + void runRequest(const std::string& profile); }; } diff --git a/apps/opencs/view/widget/scenetoolshapebrush.cpp b/apps/opencs/view/widget/scenetoolshapebrush.cpp index 834f739e2f..8674cd1a0a 100644 --- a/apps/opencs/view/widget/scenetoolshapebrush.cpp +++ b/apps/opencs/view/widget/scenetoolshapebrush.cpp @@ -23,8 +23,7 @@ #include "../../model/prefs/state.hpp" #include "../../model/world/commands.hpp" - -CSVWidget::ShapeBrushSizeControls::ShapeBrushSizeControls(const QString &title, QWidget *parent) +CSVWidget::ShapeBrushSizeControls::ShapeBrushSizeControls(const QString& title, QWidget* parent) : QGroupBox(title, parent) { mBrushSizeSlider->setTickPosition(QSlider::TicksBothSides); @@ -35,44 +34,44 @@ CSVWidget::ShapeBrushSizeControls::ShapeBrushSizeControls(const QString &title, mBrushSizeSpinBox->setRange(1, CSMPrefs::get()["3D Scene Editing"]["shapebrush-maximumsize"].toInt()); mBrushSizeSpinBox->setSingleStep(1); - QHBoxLayout *layoutSliderSize = new QHBoxLayout; + QHBoxLayout* layoutSliderSize = new QHBoxLayout; layoutSliderSize->addWidget(mBrushSizeSlider); layoutSliderSize->addWidget(mBrushSizeSpinBox); - connect(mBrushSizeSlider, &QSlider::valueChanged, mBrushSizeSpinBox, &QSpinBox::setValue); + connect(mBrushSizeSlider, &QSlider::valueChanged, mBrushSizeSpinBox, &QSpinBox::setValue); connect(mBrushSizeSpinBox, qOverload(&QSpinBox::valueChanged), mBrushSizeSlider, &QSlider::setValue); setLayout(layoutSliderSize); } -CSVWidget::ShapeBrushWindow::ShapeBrushWindow(CSMDoc::Document& document, QWidget *parent) - : QFrame(parent, Qt::Popup), - mDocument(document) +CSVWidget::ShapeBrushWindow::ShapeBrushWindow(CSMDoc::Document& document, QWidget* parent) + : QFrame(parent, Qt::Popup) + , mDocument(document) { - mButtonPoint = new QPushButton(QIcon (QPixmap (":scenetoolbar/brush-point")), "", this); - mButtonSquare = new QPushButton(QIcon (QPixmap (":scenetoolbar/brush-square")), "", this); - mButtonCircle = new QPushButton(QIcon (QPixmap (":scenetoolbar/brush-circle")), "", this); - mButtonCustom = new QPushButton(QIcon (QPixmap (":scenetoolbar/brush-custom")), "", this); + mButtonPoint = new QPushButton(QIcon(QPixmap(":scenetoolbar/brush-point")), "", this); + mButtonSquare = new QPushButton(QIcon(QPixmap(":scenetoolbar/brush-square")), "", this); + mButtonCircle = new QPushButton(QIcon(QPixmap(":scenetoolbar/brush-circle")), "", this); + mButtonCustom = new QPushButton(QIcon(QPixmap(":scenetoolbar/brush-custom")), "", this); mSizeSliders = new ShapeBrushSizeControls("Brush size", this); - QVBoxLayout *layoutMain = new QVBoxLayout; + QVBoxLayout* layoutMain = new QVBoxLayout; layoutMain->setSpacing(0); - layoutMain->setContentsMargins(4,0,4,4); + layoutMain->setContentsMargins(4, 0, 4, 4); - QHBoxLayout *layoutHorizontal = new QHBoxLayout; + QHBoxLayout* layoutHorizontal = new QHBoxLayout; layoutHorizontal->setSpacing(0); - layoutHorizontal->setContentsMargins (QMargins (0, 0, 0, 0)); + layoutHorizontal->setContentsMargins(QMargins(0, 0, 0, 0)); configureButtonInitialSettings(mButtonPoint); configureButtonInitialSettings(mButtonSquare); configureButtonInitialSettings(mButtonCircle); configureButtonInitialSettings(mButtonCustom); - mButtonPoint->setToolTip (toolTipPoint); - mButtonSquare->setToolTip (toolTipSquare); - mButtonCircle->setToolTip (toolTipCircle); - mButtonCustom->setToolTip (toolTipCustom); + mButtonPoint->setToolTip(toolTipPoint); + mButtonSquare->setToolTip(toolTipSquare); + mButtonCircle->setToolTip(toolTipCircle); + mButtonCustom->setToolTip(toolTipCustom); QButtonGroup* brushButtonGroup = new QButtonGroup(this); brushButtonGroup->addButton(mButtonPoint); @@ -97,7 +96,7 @@ CSVWidget::ShapeBrushWindow::ShapeBrushWindow(CSMDoc::Document& document, QWidge mToolSelector->addItem(tr("Smooth (paint)")); mToolSelector->addItem(tr("Flatten (paint)")); - QLabel *brushStrengthLabel = new QLabel(this); + QLabel* brushStrengthLabel = new QLabel(this); brushStrengthLabel->setText("Brush strength:"); mToolStrengthSlider = new QSlider(Qt::Horizontal); @@ -121,13 +120,13 @@ CSVWidget::ShapeBrushWindow::ShapeBrushWindow(CSMDoc::Document& document, QWidge connect(mButtonCustom, &QPushButton::clicked, this, &ShapeBrushWindow::setBrushShape); } -void CSVWidget::ShapeBrushWindow::configureButtonInitialSettings(QPushButton *button) +void CSVWidget::ShapeBrushWindow::configureButtonInitialSettings(QPushButton* button) { - button->setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed)); - button->setContentsMargins (QMargins (0, 0, 0, 0)); - button->setIconSize (QSize (48-6, 48-6)); - button->setFixedSize (48, 48); - button->setCheckable(true); + button->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); + button->setContentsMargins(QMargins(0, 0, 0, 0)); + button->setIconSize(QSize(48 - 6, 48 - 6)); + button->setFixedSize(48, 48); + button->setCheckable(true); } void CSVWidget::ShapeBrushWindow::setBrushSize(int brushSize) @@ -138,49 +137,51 @@ void CSVWidget::ShapeBrushWindow::setBrushSize(int brushSize) void CSVWidget::ShapeBrushWindow::setBrushShape() { - if(mButtonPoint->isChecked()) mBrushShape = BrushShape_Point; - if(mButtonSquare->isChecked()) mBrushShape = BrushShape_Square; - if(mButtonCircle->isChecked()) mBrushShape = BrushShape_Circle; - if(mButtonCustom->isChecked()) mBrushShape = BrushShape_Custom; + if (mButtonPoint->isChecked()) + mBrushShape = BrushShape_Point; + if (mButtonSquare->isChecked()) + mBrushShape = BrushShape_Square; + if (mButtonCircle->isChecked()) + mBrushShape = BrushShape_Circle; + if (mButtonCustom->isChecked()) + mBrushShape = BrushShape_Custom; emit passBrushShape(mBrushShape); } -void CSVWidget::SceneToolShapeBrush::adjustToolTips() -{ -} +void CSVWidget::SceneToolShapeBrush::adjustToolTips() {} -CSVWidget::SceneToolShapeBrush::SceneToolShapeBrush (SceneToolbar *parent, const QString& toolTip, CSMDoc::Document& document) -: SceneTool (parent, Type_TopAction), - mToolTip (toolTip), - mDocument (document), - mShapeBrushWindow(new ShapeBrushWindow(document, this)) +CSVWidget::SceneToolShapeBrush::SceneToolShapeBrush( + SceneToolbar* parent, const QString& toolTip, CSMDoc::Document& document) + : SceneTool(parent, Type_TopAction) + , mToolTip(toolTip) + , mDocument(document) + , mShapeBrushWindow(new ShapeBrushWindow(document, this)) { setAcceptDrops(true); connect(mShapeBrushWindow, &ShapeBrushWindow::passBrushShape, this, &SceneToolShapeBrush::setButtonIcon); setButtonIcon(mShapeBrushWindow->mBrushShape); - mPanel = new QFrame (this, Qt::Popup); + mPanel = new QFrame(this, Qt::Popup); - QHBoxLayout *layout = new QHBoxLayout (mPanel); + QHBoxLayout* layout = new QHBoxLayout(mPanel); - layout->setContentsMargins (QMargins (0, 0, 0, 0)); + layout->setContentsMargins(QMargins(0, 0, 0, 0)); - mTable = new QTableWidget (0, 2, this); + mTable = new QTableWidget(0, 2, this); - mTable->setShowGrid (true); + mTable->setShowGrid(true); mTable->verticalHeader()->hide(); mTable->horizontalHeader()->hide(); - mTable->horizontalHeader()->setSectionResizeMode (0, QHeaderView::Stretch); - mTable->horizontalHeader()->setSectionResizeMode (1, QHeaderView::Stretch); - mTable->setSelectionMode (QAbstractItemView::NoSelection); + mTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); + mTable->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch); + mTable->setSelectionMode(QAbstractItemView::NoSelection); - layout->addWidget (mTable); - - connect (mTable, &QTableWidget::clicked, this, &SceneToolShapeBrush::clicked); + layout->addWidget(mTable); + connect(mTable, &QTableWidget::clicked, this, &SceneToolShapeBrush::clicked); } -void CSVWidget::SceneToolShapeBrush::setButtonIcon (CSVWidget::BrushShape brushShape) +void CSVWidget::SceneToolShapeBrush::setButtonIcon(CSVWidget::BrushShape brushShape) { QString tooltip = "Change brush settings

        Currently selected: "; @@ -188,59 +189,55 @@ void CSVWidget::SceneToolShapeBrush::setButtonIcon (CSVWidget::BrushShape brushS { case BrushShape_Point: - setIcon (QIcon (QPixmap (":scenetoolbar/brush-point"))); + setIcon(QIcon(QPixmap(":scenetoolbar/brush-point"))); tooltip += mShapeBrushWindow->toolTipPoint; break; case BrushShape_Square: - setIcon (QIcon (QPixmap (":scenetoolbar/brush-square"))); + setIcon(QIcon(QPixmap(":scenetoolbar/brush-square"))); tooltip += mShapeBrushWindow->toolTipSquare; break; case BrushShape_Circle: - setIcon (QIcon (QPixmap (":scenetoolbar/brush-circle"))); + setIcon(QIcon(QPixmap(":scenetoolbar/brush-circle"))); tooltip += mShapeBrushWindow->toolTipCircle; break; case BrushShape_Custom: - setIcon (QIcon (QPixmap (":scenetoolbar/brush-custom"))); + setIcon(QIcon(QPixmap(":scenetoolbar/brush-custom"))); tooltip += mShapeBrushWindow->toolTipCustom; break; } - setToolTip (tooltip); + setToolTip(tooltip); } -void CSVWidget::SceneToolShapeBrush::showPanel (const QPoint& position) -{ -} +void CSVWidget::SceneToolShapeBrush::showPanel(const QPoint& position) {} -void CSVWidget::SceneToolShapeBrush::updatePanel () -{ -} +void CSVWidget::SceneToolShapeBrush::updatePanel() {} -void CSVWidget::SceneToolShapeBrush::clicked (const QModelIndex& index) -{ -} +void CSVWidget::SceneToolShapeBrush::clicked(const QModelIndex& index) {} -void CSVWidget::SceneToolShapeBrush::activate () +void CSVWidget::SceneToolShapeBrush::activate() { QPoint position = QCursor::pos(); - mShapeBrushWindow->mSizeSliders->mBrushSizeSlider->setRange(1, CSMPrefs::get()["3D Scene Editing"]["shapebrush-maximumsize"].toInt()); - mShapeBrushWindow->mSizeSliders->mBrushSizeSpinBox->setRange(1, CSMPrefs::get()["3D Scene Editing"]["shapebrush-maximumsize"].toInt()); - mShapeBrushWindow->move (position); + mShapeBrushWindow->mSizeSliders->mBrushSizeSlider->setRange( + 1, CSMPrefs::get()["3D Scene Editing"]["shapebrush-maximumsize"].toInt()); + mShapeBrushWindow->mSizeSliders->mBrushSizeSpinBox->setRange( + 1, CSMPrefs::get()["3D Scene Editing"]["shapebrush-maximumsize"].toInt()); + mShapeBrushWindow->move(position); mShapeBrushWindow->show(); } -void CSVWidget::SceneToolShapeBrush::dragEnterEvent (QDragEnterEvent *event) +void CSVWidget::SceneToolShapeBrush::dragEnterEvent(QDragEnterEvent* event) { emit passEvent(event); event->accept(); } -void CSVWidget::SceneToolShapeBrush::dropEvent (QDropEvent *event) +void CSVWidget::SceneToolShapeBrush::dropEvent(QDropEvent* event) { emit passEvent(event); event->accept(); diff --git a/apps/opencs/view/widget/scenetoolshapebrush.hpp b/apps/opencs/view/widget/scenetoolshapebrush.hpp index e616e6958e..7dc4b2e6a6 100644 --- a/apps/opencs/view/widget/scenetoolshapebrush.hpp +++ b/apps/opencs/view/widget/scenetoolshapebrush.hpp @@ -4,12 +4,12 @@ #include #include -#include #include -#include #include -#include #include +#include +#include +#include #ifndef Q_MOC_RUN #include "brushshapes.hpp" @@ -32,12 +32,12 @@ namespace CSVWidget { Q_OBJECT - public: - ShapeBrushSizeControls(const QString &title, QWidget *parent); + public: + ShapeBrushSizeControls(const QString& title, QWidget* parent); - private: - QSlider *mBrushSizeSlider = new QSlider(Qt::Horizontal); - QSpinBox *mBrushSizeSpinBox = new QSpinBox; + private: + QSlider* mBrushSizeSlider = new QSlider(Qt::Horizontal); + QSpinBox* mBrushSizeSpinBox = new QSpinBox; friend class SceneToolShapeBrush; friend class CSVRender::TerrainShapeMode; @@ -48,75 +48,72 @@ namespace CSVWidget { Q_OBJECT - public: - - ShapeBrushWindow(CSMDoc::Document& document, QWidget *parent = nullptr); - void configureButtonInitialSettings(QPushButton *button); - - const QString toolTipPoint = "Paint single point"; - const QString toolTipSquare = "Paint with square brush"; - const QString toolTipCircle = "Paint with circle brush"; - const QString toolTipCustom = "Paint with custom brush, defined by terrain selection"; - - private: - CSVWidget::BrushShape mBrushShape = CSVWidget::BrushShape_Point; - int mBrushSize = 1; - CSMDoc::Document& mDocument; - QGroupBox *mHorizontalGroupBox; - QComboBox *mToolSelector; - QSlider *mToolStrengthSlider; - QPushButton *mButtonPoint; - QPushButton *mButtonSquare; - QPushButton *mButtonCircle; - QPushButton *mButtonCustom; - ShapeBrushSizeControls* mSizeSliders; + public: + ShapeBrushWindow(CSMDoc::Document& document, QWidget* parent = nullptr); + void configureButtonInitialSettings(QPushButton* button); + + const QString toolTipPoint = "Paint single point"; + const QString toolTipSquare = "Paint with square brush"; + const QString toolTipCircle = "Paint with circle brush"; + const QString toolTipCustom = "Paint with custom brush, defined by terrain selection"; + + private: + CSVWidget::BrushShape mBrushShape = CSVWidget::BrushShape_Point; + int mBrushSize = 1; + CSMDoc::Document& mDocument; + QGroupBox* mHorizontalGroupBox; + QComboBox* mToolSelector; + QSlider* mToolStrengthSlider; + QPushButton* mButtonPoint; + QPushButton* mButtonSquare; + QPushButton* mButtonCircle; + QPushButton* mButtonCustom; + ShapeBrushSizeControls* mSizeSliders; friend class SceneToolShapeBrush; friend class CSVRender::TerrainShapeMode; - public slots: - void setBrushShape(); - void setBrushSize(int brushSize); + public slots: + void setBrushShape(); + void setBrushSize(int brushSize); - signals: - void passBrushSize (int brushSize); - void passBrushShape(CSVWidget::BrushShape brushShape); + signals: + void passBrushSize(int brushSize); + void passBrushShape(CSVWidget::BrushShape brushShape); }; class SceneToolShapeBrush : public SceneTool { - Q_OBJECT - - QString mToolTip; - CSMDoc::Document& mDocument; - QFrame *mPanel; - QTableWidget *mTable; - ShapeBrushWindow *mShapeBrushWindow; - - private: + Q_OBJECT - void adjustToolTips(); + QString mToolTip; + CSMDoc::Document& mDocument; + QFrame* mPanel; + QTableWidget* mTable; + ShapeBrushWindow* mShapeBrushWindow; - public: + private: + void adjustToolTips(); - SceneToolShapeBrush (SceneToolbar *parent, const QString& toolTip, CSMDoc::Document& document); + public: + SceneToolShapeBrush(SceneToolbar* parent, const QString& toolTip, CSMDoc::Document& document); - void showPanel (const QPoint& position) override; - void updatePanel (); + void showPanel(const QPoint& position) override; + void updatePanel(); - void dropEvent (QDropEvent *event) override; - void dragEnterEvent (QDragEnterEvent *event) override; + void dropEvent(QDropEvent* event) override; + void dragEnterEvent(QDragEnterEvent* event) override; friend class CSVRender::TerrainShapeMode; - public slots: - void setButtonIcon(CSVWidget::BrushShape brushShape); - void clicked (const QModelIndex& index); - void activate() override; + public slots: + void setButtonIcon(CSVWidget::BrushShape brushShape); + void clicked(const QModelIndex& index); + void activate() override; - signals: - void passEvent(QDropEvent *event); - void passEvent(QDragEnterEvent *event); + signals: + void passEvent(QDropEvent* event); + void passEvent(QDragEnterEvent* event); }; } diff --git a/apps/opencs/view/widget/scenetooltexturebrush.cpp b/apps/opencs/view/widget/scenetooltexturebrush.cpp index 2ba0d3bcb0..e3e47677c2 100644 --- a/apps/opencs/view/widget/scenetooltexturebrush.cpp +++ b/apps/opencs/view/widget/scenetooltexturebrush.cpp @@ -26,12 +26,11 @@ #include "../../model/world/landtexture.hpp" #include "../../model/world/universalid.hpp" - -CSVWidget::BrushSizeControls::BrushSizeControls(const QString &title, QWidget *parent) - : QGroupBox(title, parent), - mLayoutSliderSize(new QHBoxLayout), - mBrushSizeSlider(new QSlider(Qt::Horizontal)), - mBrushSizeSpinBox(new QSpinBox) +CSVWidget::BrushSizeControls::BrushSizeControls(const QString& title, QWidget* parent) + : QGroupBox(title, parent) + , mLayoutSliderSize(new QHBoxLayout) + , mBrushSizeSlider(new QSlider(Qt::Horizontal)) + , mBrushSizeSpinBox(new QSpinBox) { mBrushSizeSlider->setTickPosition(QSlider::TicksBothSides); mBrushSizeSlider->setTickInterval(10); @@ -44,15 +43,15 @@ CSVWidget::BrushSizeControls::BrushSizeControls(const QString &title, QWidget *p mLayoutSliderSize->addWidget(mBrushSizeSlider); mLayoutSliderSize->addWidget(mBrushSizeSpinBox); - connect(mBrushSizeSlider, &QSlider::valueChanged, mBrushSizeSpinBox, &QSpinBox::setValue); + connect(mBrushSizeSlider, &QSlider::valueChanged, mBrushSizeSpinBox, &QSpinBox::setValue); connect(mBrushSizeSpinBox, qOverload(&QSpinBox::valueChanged), mBrushSizeSlider, &QSlider::setValue); setLayout(mLayoutSliderSize); } -CSVWidget::TextureBrushWindow::TextureBrushWindow(CSMDoc::Document& document, QWidget *parent) - : QFrame(parent, Qt::Popup), - mDocument(document) +CSVWidget::TextureBrushWindow::TextureBrushWindow(CSMDoc::Document& document, QWidget* parent) + : QFrame(parent, Qt::Popup) + , mDocument(document) { mBrushTextureLabel = "Selected texture: " + mBrushTexture + " "; @@ -63,37 +62,39 @@ CSVWidget::TextureBrushWindow::TextureBrushWindow(CSMDoc::Document& document, QW if (index != -1 && !landtexturesCollection.getRecord(index).isDeleted()) { - mSelectedBrush = new QLabel(QString::fromStdString(mBrushTextureLabel) + landtexturesCollection.getData(index, landTextureFilename).value()); - } else + mSelectedBrush = new QLabel(QString::fromStdString(mBrushTextureLabel) + + landtexturesCollection.getData(index, landTextureFilename).value()); + } + else { mBrushTextureLabel = "No selected texture or invalid texture"; mSelectedBrush = new QLabel(QString::fromStdString(mBrushTextureLabel)); } - mButtonPoint = new QPushButton(QIcon (QPixmap (":scenetoolbar/brush-point")), "", this); - mButtonSquare = new QPushButton(QIcon (QPixmap (":scenetoolbar/brush-square")), "", this); - mButtonCircle = new QPushButton(QIcon (QPixmap (":scenetoolbar/brush-circle")), "", this); - mButtonCustom = new QPushButton(QIcon (QPixmap (":scenetoolbar/brush-custom")), "", this); + mButtonPoint = new QPushButton(QIcon(QPixmap(":scenetoolbar/brush-point")), "", this); + mButtonSquare = new QPushButton(QIcon(QPixmap(":scenetoolbar/brush-square")), "", this); + mButtonCircle = new QPushButton(QIcon(QPixmap(":scenetoolbar/brush-circle")), "", this); + mButtonCustom = new QPushButton(QIcon(QPixmap(":scenetoolbar/brush-custom")), "", this); mSizeSliders = new BrushSizeControls("Brush size", this); - QVBoxLayout *layoutMain = new QVBoxLayout; + QVBoxLayout* layoutMain = new QVBoxLayout; layoutMain->setSpacing(0); - layoutMain->setContentsMargins(4,0,4,4); + layoutMain->setContentsMargins(4, 0, 4, 4); - QHBoxLayout *layoutHorizontal = new QHBoxLayout; + QHBoxLayout* layoutHorizontal = new QHBoxLayout; layoutHorizontal->setSpacing(0); - layoutHorizontal->setContentsMargins (QMargins (0, 0, 0, 0)); + layoutHorizontal->setContentsMargins(QMargins(0, 0, 0, 0)); configureButtonInitialSettings(mButtonPoint); configureButtonInitialSettings(mButtonSquare); configureButtonInitialSettings(mButtonCircle); configureButtonInitialSettings(mButtonCustom); - mButtonPoint->setToolTip (toolTipPoint); - mButtonSquare->setToolTip (toolTipSquare); - mButtonCircle->setToolTip (toolTipCircle); - mButtonCustom->setToolTip (toolTipCustom); + mButtonPoint->setToolTip(toolTipPoint); + mButtonSquare->setToolTip(toolTipSquare); + mButtonCircle->setToolTip(toolTipCircle); + mButtonCustom->setToolTip(toolTipCustom); QButtonGroup* brushButtonGroup = new QButtonGroup(this); brushButtonGroup->addButton(mButtonPoint); @@ -123,19 +124,19 @@ CSVWidget::TextureBrushWindow::TextureBrushWindow(CSMDoc::Document& document, QW connect(mButtonCustom, &QPushButton::clicked, this, &TextureBrushWindow::setBrushShape); } -void CSVWidget::TextureBrushWindow::configureButtonInitialSettings(QPushButton *button) +void CSVWidget::TextureBrushWindow::configureButtonInitialSettings(QPushButton* button) { - button->setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed)); - button->setContentsMargins (QMargins (0, 0, 0, 0)); - button->setIconSize (QSize (48-6, 48-6)); - button->setFixedSize (48, 48); - button->setCheckable(true); + button->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); + button->setContentsMargins(QMargins(0, 0, 0, 0)); + button->setIconSize(QSize(48 - 6, 48 - 6)); + button->setFixedSize(48, 48); + button->setCheckable(true); } void CSVWidget::TextureBrushWindow::setBrushTexture(std::string brushTexture) { - CSMWorld::IdTable& ltexTable = dynamic_cast ( - *mDocument.getData().getTableModel (CSMWorld::UniversalId::Type_LandTextures)); + CSMWorld::IdTable& ltexTable = dynamic_cast( + *mDocument.getData().getTableModel(CSMWorld::UniversalId::Type_LandTextures)); QUndoStack& undoStack = mDocument.getUndoStack(); CSMWorld::IdCollection& landtexturesCollection = mDocument.getData().getLandTextures(); @@ -155,30 +156,35 @@ void CSVWidget::TextureBrushWindow::setBrushTexture(std::string brushTexture) { if (rowInBase == -1) { - int counter=0; + int counter = 0; bool freeIndexFound = false; const int maxCounter = std::numeric_limits::max() - 1; - do { + do + { newBrushTextureId = CSMWorld::LandTexture::createUniqueRecordId(0, counter); - if (landtexturesCollection.searchId(brushTexture) != -1 && - landtexturesCollection.getRecord(brushTexture).isDeleted() == 0 && - landtexturesCollection.searchId(newBrushTextureId) != -1 && - landtexturesCollection.getRecord(newBrushTextureId).isDeleted() == 0) - counter = (counter + 1) % maxCounter; - else freeIndexFound = true; + if (landtexturesCollection.searchId(brushTexture) != -1 + && landtexturesCollection.getRecord(brushTexture).isDeleted() == 0 + && landtexturesCollection.searchId(newBrushTextureId) != -1 + && landtexturesCollection.getRecord(newBrushTextureId).isDeleted() == 0) + counter = (counter + 1) % maxCounter; + else + freeIndexFound = true; } while (freeIndexFound == false || counter < maxCounter); } - undoStack.beginMacro ("Add land texture record"); - undoStack.push (new CSMWorld::CloneCommand (ltexTable, brushTexture, newBrushTextureId, CSMWorld::UniversalId::Type_LandTexture)); + undoStack.beginMacro("Add land texture record"); + undoStack.push(new CSMWorld::CloneCommand( + ltexTable, brushTexture, newBrushTextureId, CSMWorld::UniversalId::Type_LandTexture)); undoStack.endMacro(); } if (index != -1 && !landtexturesCollection.getRecord(rowInNew).isDeleted()) { mBrushTextureLabel = "Selected texture: " + newBrushTextureId + " "; - mSelectedBrush->setText(QString::fromStdString(mBrushTextureLabel) + landtexturesCollection.getData(rowInNew, landTextureFilename).value()); - } else + mSelectedBrush->setText(QString::fromStdString(mBrushTextureLabel) + + landtexturesCollection.getData(rowInNew, landTextureFilename).value()); + } + else { newBrushTextureId.clear(); mBrushTextureLabel = "No selected texture or invalid texture"; @@ -210,15 +216,14 @@ void CSVWidget::TextureBrushWindow::setBrushShape() emit passBrushShape(mBrushShape); } -void CSVWidget::SceneToolTextureBrush::adjustToolTips() -{ -} +void CSVWidget::SceneToolTextureBrush::adjustToolTips() {} -CSVWidget::SceneToolTextureBrush::SceneToolTextureBrush (SceneToolbar *parent, const QString& toolTip, CSMDoc::Document& document) -: SceneTool (parent, Type_TopAction), - mToolTip (toolTip), - mDocument (document), - mTextureBrushWindow(new TextureBrushWindow(document, this)) +CSVWidget::SceneToolTextureBrush::SceneToolTextureBrush( + SceneToolbar* parent, const QString& toolTip, CSMDoc::Document& document) + : SceneTool(parent, Type_TopAction) + , mToolTip(toolTip) + , mDocument(document) + , mTextureBrushWindow(new TextureBrushWindow(document, this)) { mBrushHistory.resize(1); mBrushHistory[0] = "L0#0"; @@ -227,28 +232,27 @@ CSVWidget::SceneToolTextureBrush::SceneToolTextureBrush (SceneToolbar *parent, c connect(mTextureBrushWindow, &TextureBrushWindow::passBrushShape, this, &SceneToolTextureBrush::setButtonIcon); setButtonIcon(mTextureBrushWindow->mBrushShape); - mPanel = new QFrame (this, Qt::Popup); + mPanel = new QFrame(this, Qt::Popup); - QHBoxLayout *layout = new QHBoxLayout (mPanel); + QHBoxLayout* layout = new QHBoxLayout(mPanel); - layout->setContentsMargins (QMargins (0, 0, 0, 0)); + layout->setContentsMargins(QMargins(0, 0, 0, 0)); - mTable = new QTableWidget (0, 2, this); + mTable = new QTableWidget(0, 2, this); - mTable->setShowGrid (true); + mTable->setShowGrid(true); mTable->verticalHeader()->hide(); mTable->horizontalHeader()->hide(); - mTable->horizontalHeader()->setSectionResizeMode (0, QHeaderView::Stretch); - mTable->horizontalHeader()->setSectionResizeMode (1, QHeaderView::Stretch); - mTable->setSelectionMode (QAbstractItemView::NoSelection); + mTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); + mTable->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch); + mTable->setSelectionMode(QAbstractItemView::NoSelection); - layout->addWidget (mTable); - - connect (mTable, &QTableWidget::clicked, this, &SceneToolTextureBrush::clicked); + layout->addWidget(mTable); + connect(mTable, &QTableWidget::clicked, this, &SceneToolTextureBrush::clicked); } -void CSVWidget::SceneToolTextureBrush::setButtonIcon (CSVWidget::BrushShape brushShape) +void CSVWidget::SceneToolTextureBrush::setButtonIcon(CSVWidget::BrushShape brushShape) { QString tooltip = "Change brush settings

        Currently selected: "; @@ -256,32 +260,31 @@ void CSVWidget::SceneToolTextureBrush::setButtonIcon (CSVWidget::BrushShape brus { case BrushShape_Point: - setIcon (QIcon (QPixmap (":scenetoolbar/brush-point"))); + setIcon(QIcon(QPixmap(":scenetoolbar/brush-point"))); tooltip += mTextureBrushWindow->toolTipPoint; break; case BrushShape_Square: - setIcon (QIcon (QPixmap (":scenetoolbar/brush-square"))); + setIcon(QIcon(QPixmap(":scenetoolbar/brush-square"))); tooltip += mTextureBrushWindow->toolTipSquare; break; case BrushShape_Circle: - setIcon (QIcon (QPixmap (":scenetoolbar/brush-circle"))); + setIcon(QIcon(QPixmap(":scenetoolbar/brush-circle"))); tooltip += mTextureBrushWindow->toolTipCircle; break; case BrushShape_Custom: - setIcon (QIcon (QPixmap (":scenetoolbar/brush-custom"))); + setIcon(QIcon(QPixmap(":scenetoolbar/brush-custom"))); tooltip += mTextureBrushWindow->toolTipCustom; break; } tooltip += "

        (right click to access of previously used brush settings)"; - CSMWorld::IdCollection& landtexturesCollection = mDocument.getData().getLandTextures(); int landTextureFilename = landtexturesCollection.findColumnIndex(CSMWorld::Columns::ColumnId_Texture); @@ -292,27 +295,28 @@ void CSVWidget::SceneToolTextureBrush::setButtonIcon (CSVWidget::BrushShape brus tooltip += "

        Selected texture: " + QString::fromStdString(mTextureBrushWindow->mBrushTexture) + " "; tooltip += landtexturesCollection.getData(index, landTextureFilename).value(); - } else + } + else { tooltip += "

        No selected texture or invalid texture"; } tooltip += "
        (drop texture here to change)"; - setToolTip (tooltip); + setToolTip(tooltip); } -void CSVWidget::SceneToolTextureBrush::showPanel (const QPoint& position) +void CSVWidget::SceneToolTextureBrush::showPanel(const QPoint& position) { updatePanel(); - mPanel->move (position); + mPanel->move(position); mPanel->show(); } void CSVWidget::SceneToolTextureBrush::updatePanel() { - mTable->setRowCount (mBrushHistory.size()); + mTable->setRowCount(mBrushHistory.size()); - for (int i = mBrushHistory.size()-1; i >= 0; --i) + for (int i = mBrushHistory.size() - 1; i >= 0; --i) { CSMWorld::IdCollection& landtexturesCollection = mDocument.getData().getLandTextures(); int landTextureFilename = landtexturesCollection.findColumnIndex(CSMWorld::Columns::ColumnId_Texture); @@ -320,25 +324,28 @@ void CSVWidget::SceneToolTextureBrush::updatePanel() if (index != -1 && !landtexturesCollection.getRecord(index).isDeleted()) { - mTable->setItem (i, 1, new QTableWidgetItem (landtexturesCollection.getData(index, landTextureFilename).value())); - mTable->setItem (i, 0, new QTableWidgetItem (QString::fromStdString(mBrushHistory[i]))); - } else + mTable->setItem(i, 1, + new QTableWidgetItem(landtexturesCollection.getData(index, landTextureFilename).value())); + mTable->setItem(i, 0, new QTableWidgetItem(QString::fromStdString(mBrushHistory[i]))); + } + else { - mTable->setItem (i, 1, new QTableWidgetItem ("Invalid/deleted texture")); - mTable->setItem (i, 0, new QTableWidgetItem (QString::fromStdString(mBrushHistory[i]))); + mTable->setItem(i, 1, new QTableWidgetItem("Invalid/deleted texture")); + mTable->setItem(i, 0, new QTableWidgetItem(QString::fromStdString(mBrushHistory[i]))); } } } -void CSVWidget::SceneToolTextureBrush::updateBrushHistory (const std::string& brushTexture) +void CSVWidget::SceneToolTextureBrush::updateBrushHistory(const std::string& brushTexture) { mBrushHistory.insert(mBrushHistory.begin(), brushTexture); - if(mBrushHistory.size() > 5) mBrushHistory.pop_back(); + if (mBrushHistory.size() > 5) + mBrushHistory.pop_back(); } -void CSVWidget::SceneToolTextureBrush::clicked (const QModelIndex& index) +void CSVWidget::SceneToolTextureBrush::clicked(const QModelIndex& index) { - if (index.column()==0 || index.column()==1) + if (index.column() == 0 || index.column() == 1) { std::string brushTexture = mBrushHistory[index.row()]; std::swap(mBrushHistory[index.row()], mBrushHistory[0]); @@ -349,21 +356,23 @@ void CSVWidget::SceneToolTextureBrush::clicked (const QModelIndex& index) } } -void CSVWidget::SceneToolTextureBrush::activate () +void CSVWidget::SceneToolTextureBrush::activate() { QPoint position = QCursor::pos(); - mTextureBrushWindow->mSizeSliders->mBrushSizeSlider->setRange(1, CSMPrefs::get()["3D Scene Editing"]["texturebrush-maximumsize"].toInt()); - mTextureBrushWindow->mSizeSliders->mBrushSizeSpinBox->setRange(1, CSMPrefs::get()["3D Scene Editing"]["texturebrush-maximumsize"].toInt()); - mTextureBrushWindow->move (position); + mTextureBrushWindow->mSizeSliders->mBrushSizeSlider->setRange( + 1, CSMPrefs::get()["3D Scene Editing"]["texturebrush-maximumsize"].toInt()); + mTextureBrushWindow->mSizeSliders->mBrushSizeSpinBox->setRange( + 1, CSMPrefs::get()["3D Scene Editing"]["texturebrush-maximumsize"].toInt()); + mTextureBrushWindow->move(position); mTextureBrushWindow->show(); } -void CSVWidget::SceneToolTextureBrush::dragEnterEvent (QDragEnterEvent *event) +void CSVWidget::SceneToolTextureBrush::dragEnterEvent(QDragEnterEvent* event) { emit passEvent(event); event->accept(); } -void CSVWidget::SceneToolTextureBrush::dropEvent (QDropEvent *event) +void CSVWidget::SceneToolTextureBrush::dropEvent(QDropEvent* event) { emit passEvent(event); event->accept(); diff --git a/apps/opencs/view/widget/scenetooltexturebrush.hpp b/apps/opencs/view/widget/scenetooltexturebrush.hpp index 929ed1ebae..f08b1dcabe 100644 --- a/apps/opencs/view/widget/scenetooltexturebrush.hpp +++ b/apps/opencs/view/widget/scenetooltexturebrush.hpp @@ -34,13 +34,13 @@ namespace CSVWidget { Q_OBJECT - public: - BrushSizeControls(const QString &title, QWidget *parent); + public: + BrushSizeControls(const QString& title, QWidget* parent); - private: - QHBoxLayout *mLayoutSliderSize; - QSlider *mBrushSizeSlider; - QSpinBox *mBrushSizeSpinBox; + private: + QHBoxLayout* mLayoutSliderSize; + QSlider* mBrushSizeSlider; + QSpinBox* mBrushSizeSpinBox; friend class SceneToolTextureBrush; friend class CSVRender::TerrainTextureMode; @@ -53,80 +53,78 @@ namespace CSVWidget { Q_OBJECT - public: - TextureBrushWindow(CSMDoc::Document& document, QWidget *parent = nullptr); - void configureButtonInitialSettings(QPushButton *button); - - const QString toolTipPoint = "Paint single point"; - const QString toolTipSquare = "Paint with square brush"; - const QString toolTipCircle = "Paint with circle brush"; - const QString toolTipCustom = "Paint custom selection (not implemented yet)"; - - private: - CSVWidget::BrushShape mBrushShape = CSVWidget::BrushShape_Point; - int mBrushSize = 1; - std::string mBrushTexture = "L0#0"; - CSMDoc::Document& mDocument; - QLabel *mSelectedBrush; - QGroupBox *mHorizontalGroupBox; - std::string mBrushTextureLabel; - QPushButton *mButtonPoint; - QPushButton *mButtonSquare; - QPushButton *mButtonCircle; - QPushButton *mButtonCustom; - BrushSizeControls* mSizeSliders; + public: + TextureBrushWindow(CSMDoc::Document& document, QWidget* parent = nullptr); + void configureButtonInitialSettings(QPushButton* button); + + const QString toolTipPoint = "Paint single point"; + const QString toolTipSquare = "Paint with square brush"; + const QString toolTipCircle = "Paint with circle brush"; + const QString toolTipCustom = "Paint custom selection (not implemented yet)"; + + private: + CSVWidget::BrushShape mBrushShape = CSVWidget::BrushShape_Point; + int mBrushSize = 1; + std::string mBrushTexture = "L0#0"; + CSMDoc::Document& mDocument; + QLabel* mSelectedBrush; + QGroupBox* mHorizontalGroupBox; + std::string mBrushTextureLabel; + QPushButton* mButtonPoint; + QPushButton* mButtonSquare; + QPushButton* mButtonCircle; + QPushButton* mButtonCustom; + BrushSizeControls* mSizeSliders; friend class SceneToolTextureBrush; friend class CSVRender::TerrainTextureMode; - public slots: - void setBrushTexture(std::string brushTexture); - void setBrushShape(); - void setBrushSize(int brushSize); + public slots: + void setBrushTexture(std::string brushTexture); + void setBrushShape(); + void setBrushSize(int brushSize); - signals: - void passBrushSize (int brushSize); - void passBrushShape(CSVWidget::BrushShape brushShape); - void passTextureId(std::string brushTexture); + signals: + void passBrushSize(int brushSize); + void passBrushShape(CSVWidget::BrushShape brushShape); + void passTextureId(std::string brushTexture); }; class SceneToolTextureBrush : public SceneTool { - Q_OBJECT - - QString mToolTip; - CSMDoc::Document& mDocument; - QFrame *mPanel; - QTableWidget *mTable; - std::vector mBrushHistory; - TextureBrushWindow *mTextureBrushWindow; - - private: + Q_OBJECT - void adjustToolTips(); + QString mToolTip; + CSMDoc::Document& mDocument; + QFrame* mPanel; + QTableWidget* mTable; + std::vector mBrushHistory; + TextureBrushWindow* mTextureBrushWindow; - public: + private: + void adjustToolTips(); - SceneToolTextureBrush (SceneToolbar *parent, const QString& toolTip, CSMDoc::Document& document); + public: + SceneToolTextureBrush(SceneToolbar* parent, const QString& toolTip, CSMDoc::Document& document); - void showPanel (const QPoint& position) override; - void updatePanel (); + void showPanel(const QPoint& position) override; + void updatePanel(); - void dropEvent (QDropEvent *event) override; - void dragEnterEvent (QDragEnterEvent *event) override; + void dropEvent(QDropEvent* event) override; + void dragEnterEvent(QDragEnterEvent* event) override; friend class CSVRender::TerrainTextureMode; - public slots: - void setButtonIcon(CSVWidget::BrushShape brushShape); - void updateBrushHistory (const std::string& mBrushTexture); - void clicked (const QModelIndex& index); - void activate() override; + public slots: + void setButtonIcon(CSVWidget::BrushShape brushShape); + void updateBrushHistory(const std::string& mBrushTexture); + void clicked(const QModelIndex& index); + void activate() override; - signals: - void passEvent(QDropEvent *event); - void passEvent(QDragEnterEvent *event); - void passTextureId(std::string brushTexture); + signals: + void passEvent(QDropEvent* event); + void passEvent(QDragEnterEvent* event); + void passTextureId(std::string brushTexture); }; } diff --git a/apps/opencs/view/widget/scenetooltoggle.cpp b/apps/opencs/view/widget/scenetooltoggle.cpp index c9bdaba6db..01dfb7582e 100644 --- a/apps/opencs/view/widget/scenetooltoggle.cpp +++ b/apps/opencs/view/widget/scenetooltoggle.cpp @@ -2,13 +2,13 @@ #include -#include #include +#include #include #include -#include "scenetoolbar.hpp" #include "pushbutton.hpp" +#include "scenetoolbar.hpp" void CSVWidget::SceneToolToggle::adjustToolTip() { @@ -18,8 +18,7 @@ void CSVWidget::SceneToolToggle::adjustToolTip() bool first = true; - for (std::map::const_iterator iter (mButtons.begin()); - iter!=mButtons.end(); ++iter) + for (std::map::const_iterator iter(mButtons.begin()); iter != mButtons.end(); ++iter) if (iter->first->isChecked()) { if (!first) @@ -35,36 +34,36 @@ void CSVWidget::SceneToolToggle::adjustToolTip() toolTip += "

        (left click to alter selection)"; - setToolTip (toolTip); + setToolTip(toolTip); } void CSVWidget::SceneToolToggle::adjustIcon() { unsigned int selection = getSelectionMask(); if (!selection) - setIcon (QIcon (QString::fromUtf8 (mEmptyIcon.c_str()))); + setIcon(QIcon(QString::fromUtf8(mEmptyIcon.c_str()))); else { - QPixmap pixmap (48, 48); - pixmap.fill (QColor (0, 0, 0, 0)); + QPixmap pixmap(48, 48); + pixmap.fill(QColor(0, 0, 0, 0)); { - QPainter painter (&pixmap); + QPainter painter(&pixmap); - for (std::map::const_iterator iter (mButtons.begin()); - iter!=mButtons.end(); ++iter) + for (std::map::const_iterator iter(mButtons.begin()); iter != mButtons.end(); + ++iter) if (iter->first->isChecked()) { - painter.drawImage (getIconBox (iter->second.mIndex), - QImage (QString::fromUtf8 (iter->second.mSmallIcon.c_str()))); + painter.drawImage( + getIconBox(iter->second.mIndex), QImage(QString::fromUtf8(iter->second.mSmallIcon.c_str()))); } } - setIcon (pixmap); + setIcon(pixmap); } } -QRect CSVWidget::SceneToolToggle::getIconBox (int index) const +QRect CSVWidget::SceneToolToggle::getIconBox(int index) const { // layout for a 3x3 grid int xMax = 3; @@ -74,27 +73,27 @@ QRect CSVWidget::SceneToolToggle::getIconBox (int index) const int xBorder = 1; int yBorder = 1; - int iconXSize = (mIconSize-xBorder*(xMax+1))/xMax; - int iconYSize = (mIconSize-yBorder*(yMax+1))/yMax; + int iconXSize = (mIconSize - xBorder * (xMax + 1)) / xMax; + int iconYSize = (mIconSize - yBorder * (yMax + 1)) / yMax; int y = index / xMax; int x = index % xMax; int total = static_cast(mButtons.size()); - int actualYIcons = total/xMax; + int actualYIcons = total / xMax; if (total % xMax) ++actualYIcons; - if (actualYIcons!=yMax) + if (actualYIcons != yMax) { // space out icons vertically, if there aren't enough to populate all rows int diff = yMax - actualYIcons; - yBorder += (diff*(yBorder+iconXSize)) / (actualYIcons+1); + yBorder += (diff * (yBorder + iconXSize)) / (actualYIcons + 1); } - if (y==actualYIcons-1) + if (y == actualYIcons - 1) { // generating the last row of icons int actualXIcons = total % xMax; @@ -104,51 +103,53 @@ QRect CSVWidget::SceneToolToggle::getIconBox (int index) const // space out icons horizontally, if there aren't enough to fill the last row int diff = xMax - actualXIcons; - xBorder += (diff*(xBorder+iconXSize)) / (actualXIcons+1); + xBorder += (diff * (xBorder + iconXSize)) / (actualXIcons + 1); } } - return QRect ((iconXSize+xBorder)*x+xBorder, (iconYSize+yBorder)*y+yBorder, - iconXSize, iconYSize); + return QRect((iconXSize + xBorder) * x + xBorder, (iconYSize + yBorder) * y + yBorder, iconXSize, iconYSize); } -CSVWidget::SceneToolToggle::SceneToolToggle (SceneToolbar *parent, const QString& toolTip, - const std::string& emptyIcon) -: SceneTool (parent), mEmptyIcon (emptyIcon), mButtonSize (parent->getButtonSize()), - mIconSize (parent->getIconSize()), mToolTip (toolTip), mFirst (nullptr) +CSVWidget::SceneToolToggle::SceneToolToggle(SceneToolbar* parent, const QString& toolTip, const std::string& emptyIcon) + : SceneTool(parent) + , mEmptyIcon(emptyIcon) + , mButtonSize(parent->getButtonSize()) + , mIconSize(parent->getIconSize()) + , mToolTip(toolTip) + , mFirst(nullptr) { - mPanel = new QFrame (this, Qt::Popup); + mPanel = new QFrame(this, Qt::Popup); - mLayout = new QHBoxLayout (mPanel); + mLayout = new QHBoxLayout(mPanel); - mLayout->setContentsMargins (QMargins (0, 0, 0, 0)); + mLayout->setContentsMargins(QMargins(0, 0, 0, 0)); - mPanel->setLayout (mLayout); + mPanel->setLayout(mLayout); } -void CSVWidget::SceneToolToggle::showPanel (const QPoint& position) +void CSVWidget::SceneToolToggle::showPanel(const QPoint& position) { - mPanel->move (position); + mPanel->move(position); mPanel->show(); if (mFirst) - mFirst->setFocus (Qt::OtherFocusReason); + mFirst->setFocus(Qt::OtherFocusReason); } -void CSVWidget::SceneToolToggle::addButton (const std::string& icon, unsigned int mask, - const std::string& smallIcon, const QString& name, const QString& tooltip) +void CSVWidget::SceneToolToggle::addButton(const std::string& icon, unsigned int mask, const std::string& smallIcon, + const QString& name, const QString& tooltip) { - if (mButtons.size()>=9) - throw std::runtime_error ("Exceeded number of buttons in toggle type tool"); + if (mButtons.size() >= 9) + throw std::runtime_error("Exceeded number of buttons in toggle type tool"); - PushButton *button = new PushButton (QIcon (QPixmap (icon.c_str())), - PushButton::Type_Toggle, tooltip.isEmpty() ? name: tooltip, mPanel); + PushButton* button = new PushButton( + QIcon(QPixmap(icon.c_str())), PushButton::Type_Toggle, tooltip.isEmpty() ? name : tooltip, mPanel); - button->setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed)); - button->setIconSize (QSize (mIconSize, mIconSize)); - button->setFixedSize (mButtonSize, mButtonSize); + button->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); + button->setIconSize(QSize(mIconSize, mIconSize)); + button->setFixedSize(mButtonSize, mButtonSize); - mLayout->addWidget (button); + mLayout->addWidget(button); ButtonDesc desc; desc.mMask = mask; @@ -156,11 +157,11 @@ void CSVWidget::SceneToolToggle::addButton (const std::string& icon, unsigned in desc.mName = name; desc.mIndex = static_cast(mButtons.size()); - mButtons.insert (std::make_pair (button, desc)); + mButtons.insert(std::make_pair(button, desc)); - connect (button, &PushButton::clicked, this, &SceneToolToggle::selected); + connect(button, &PushButton::clicked, this, &SceneToolToggle::selected); - if (mButtons.size()==1) + if (mButtons.size() == 1) mFirst = button; } @@ -168,19 +169,17 @@ unsigned int CSVWidget::SceneToolToggle::getSelectionMask() const { unsigned int selection = 0; - for (std::map::const_iterator iter (mButtons.begin()); - iter!=mButtons.end(); ++iter) + for (std::map::const_iterator iter(mButtons.begin()); iter != mButtons.end(); ++iter) if (iter->first->isChecked()) selection |= iter->second.mMask; return selection; } -void CSVWidget::SceneToolToggle::setSelectionMask (unsigned int selection) +void CSVWidget::SceneToolToggle::setSelectionMask(unsigned int selection) { - for (std::map::iterator iter (mButtons.begin()); - iter!=mButtons.end(); ++iter) - iter->first->setChecked (selection & iter->second.mMask); + for (std::map::iterator iter(mButtons.begin()); iter != mButtons.end(); ++iter) + iter->first->setChecked(selection & iter->second.mMask); adjustToolTip(); adjustIcon(); @@ -188,10 +187,9 @@ void CSVWidget::SceneToolToggle::setSelectionMask (unsigned int selection) void CSVWidget::SceneToolToggle::selected() { - std::map::const_iterator iter = - mButtons.find (dynamic_cast (sender())); + std::map::const_iterator iter = mButtons.find(dynamic_cast(sender())); - if (iter!=mButtons.end()) + if (iter != mButtons.end()) { if (!iter->first->hasKeepOpen()) mPanel->hide(); diff --git a/apps/opencs/view/widget/scenetooltoggle.hpp b/apps/opencs/view/widget/scenetooltoggle.hpp index f08d117fb2..039355e348 100644 --- a/apps/opencs/view/widget/scenetooltoggle.hpp +++ b/apps/opencs/view/widget/scenetooltoggle.hpp @@ -16,59 +16,57 @@ namespace CSVWidget ///< \brief Multi-Toggle tool class SceneToolToggle : public SceneTool { - Q_OBJECT + Q_OBJECT - struct ButtonDesc - { - unsigned int mMask; - std::string mSmallIcon; - QString mName; - int mIndex; - }; + struct ButtonDesc + { + unsigned int mMask; + std::string mSmallIcon; + QString mName; + int mIndex; + }; - std::string mEmptyIcon; - QWidget *mPanel; - QHBoxLayout *mLayout; - std::map mButtons; // widget, id - int mButtonSize; - int mIconSize; - QString mToolTip; - PushButton *mFirst; + std::string mEmptyIcon; + QWidget* mPanel; + QHBoxLayout* mLayout; + std::map mButtons; // widget, id + int mButtonSize; + int mIconSize; + QString mToolTip; + PushButton* mFirst; - void adjustToolTip(); + void adjustToolTip(); - void adjustIcon(); + void adjustIcon(); - QRect getIconBox (int index) const; + QRect getIconBox(int index) const; - public: + public: + SceneToolToggle(SceneToolbar* parent, const QString& toolTip, const std::string& emptyIcon); - SceneToolToggle (SceneToolbar *parent, const QString& toolTip, - const std::string& emptyIcon); + void showPanel(const QPoint& position) override; - void showPanel (const QPoint& position) override; + /// \attention After the last button has been added, setSelection must be called at + /// least once to finalise the layout. + /// + /// \note The layout algorithm can not handle more than 9 buttons. To prevent this An + /// attempt to add more will result in an exception being thrown. + /// The small icons will be sized at (x-4)/3 (where x is the main icon size). + void addButton(const std::string& icon, unsigned int mask, const std::string& smallIcon, const QString& name, + const QString& tooltip = ""); - /// \attention After the last button has been added, setSelection must be called at - /// least once to finalise the layout. - /// - /// \note The layout algorithm can not handle more than 9 buttons. To prevent this An - /// attempt to add more will result in an exception being thrown. - /// The small icons will be sized at (x-4)/3 (where x is the main icon size). - void addButton (const std::string& icon, unsigned int mask, - const std::string& smallIcon, const QString& name, const QString& tooltip = ""); + unsigned int getSelectionMask() const; - unsigned int getSelectionMask() const; + /// \param or'ed button masks. buttons that do not exist will be ignored. + void setSelectionMask(unsigned int selection); - /// \param or'ed button masks. buttons that do not exist will be ignored. - void setSelectionMask (unsigned int selection); + signals: - signals: + void selectionChanged(); - void selectionChanged(); + private slots: - private slots: - - void selected(); + void selected(); }; } diff --git a/apps/opencs/view/widget/scenetooltoggle2.cpp b/apps/opencs/view/widget/scenetooltoggle2.cpp index 53f4ece105..558c7f9850 100644 --- a/apps/opencs/view/widget/scenetooltoggle2.cpp +++ b/apps/opencs/view/widget/scenetooltoggle2.cpp @@ -1,14 +1,14 @@ #include "scenetooltoggle2.hpp" -#include #include +#include -#include #include +#include #include -#include "scenetoolbar.hpp" #include "pushbutton.hpp" +#include "scenetoolbar.hpp" void CSVWidget::SceneToolToggle2::adjustToolTip() { @@ -18,8 +18,7 @@ void CSVWidget::SceneToolToggle2::adjustToolTip() bool first = true; - for (std::map::const_iterator iter (mButtons.begin()); - iter!=mButtons.end(); ++iter) + for (std::map::const_iterator iter(mButtons.begin()); iter != mButtons.end(); ++iter) if (iter->first->isChecked()) { if (!first) @@ -35,64 +34,67 @@ void CSVWidget::SceneToolToggle2::adjustToolTip() toolTip += "

        (left click to alter selection)"; - setToolTip (toolTip); + setToolTip(toolTip); } void CSVWidget::SceneToolToggle2::adjustIcon() { unsigned int buttonIds = 0; - for (std::map::const_iterator iter (mButtons.begin()); - iter!=mButtons.end(); ++iter) + for (std::map::const_iterator iter(mButtons.begin()); iter != mButtons.end(); ++iter) if (iter->first->isChecked()) buttonIds |= iter->second.mButtonId; std::ostringstream stream; stream << mCompositeIcon << buttonIds; - setIcon (QIcon (QString::fromUtf8 (stream.str().c_str()))); + setIcon(QIcon(QString::fromUtf8(stream.str().c_str()))); } -CSVWidget::SceneToolToggle2::SceneToolToggle2 (SceneToolbar *parent, const QString& toolTip, - const std::string& compositeIcon, const std::string& singleIcon) -: SceneTool (parent), mCompositeIcon (compositeIcon), mSingleIcon (singleIcon), - mButtonSize (parent->getButtonSize()), mIconSize (parent->getIconSize()), mToolTip (toolTip), - mFirst (nullptr) +CSVWidget::SceneToolToggle2::SceneToolToggle2( + SceneToolbar* parent, const QString& toolTip, const std::string& compositeIcon, const std::string& singleIcon) + : SceneTool(parent) + , mCompositeIcon(compositeIcon) + , mSingleIcon(singleIcon) + , mButtonSize(parent->getButtonSize()) + , mIconSize(parent->getIconSize()) + , mToolTip(toolTip) + , mFirst(nullptr) { - mPanel = new QFrame (this, Qt::Popup); + mPanel = new QFrame(this, Qt::Popup); - mLayout = new QHBoxLayout (mPanel); + mLayout = new QHBoxLayout(mPanel); - mLayout->setContentsMargins (QMargins (0, 0, 0, 0)); + mLayout->setContentsMargins(QMargins(0, 0, 0, 0)); - mPanel->setLayout (mLayout); + mPanel->setLayout(mLayout); } -void CSVWidget::SceneToolToggle2::showPanel (const QPoint& position) +void CSVWidget::SceneToolToggle2::showPanel(const QPoint& position) { - mPanel->move (position); + mPanel->move(position); mPanel->show(); if (mFirst) - mFirst->setFocus (Qt::OtherFocusReason); + mFirst->setFocus(Qt::OtherFocusReason); } -void CSVWidget::SceneToolToggle2::addButton (unsigned int id, unsigned int mask, - const QString& name, const QString& tooltip, bool disabled) +void CSVWidget::SceneToolToggle2::addButton( + unsigned int id, unsigned int mask, const QString& name, const QString& tooltip, bool disabled) { std::ostringstream stream; stream << mSingleIcon << id; - PushButton *button = new PushButton (QIcon (QPixmap (stream.str().c_str())), - PushButton::Type_Toggle, tooltip.isEmpty() ? name: tooltip, mPanel); + PushButton* button = new PushButton( + QIcon(QPixmap(stream.str().c_str())), PushButton::Type_Toggle, tooltip.isEmpty() ? name : tooltip, mPanel); - button->setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed)); - button->setIconSize (QSize (mIconSize, mIconSize)); - button->setFixedSize (mButtonSize, mButtonSize); + button->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); + button->setIconSize(QSize(mIconSize, mIconSize)); + button->setFixedSize(mButtonSize, mButtonSize); if (disabled) - button->setDisabled (true); + button->setDisabled(true); - mLayout->addWidget (button); + mLayout->addWidget(button); ButtonDesc desc; desc.mButtonId = id; @@ -100,11 +102,11 @@ void CSVWidget::SceneToolToggle2::addButton (unsigned int id, unsigned int mask, desc.mName = name; desc.mIndex = static_cast(mButtons.size()); - mButtons.insert (std::make_pair (button, desc)); + mButtons.insert(std::make_pair(button, desc)); - connect (button, &QPushButton::clicked, this, &SceneToolToggle2::selected); + connect(button, &QPushButton::clicked, this, &SceneToolToggle2::selected); - if (mButtons.size()==1 && !disabled) + if (mButtons.size() == 1 && !disabled) mFirst = button; } @@ -112,19 +114,17 @@ unsigned int CSVWidget::SceneToolToggle2::getSelectionMask() const { unsigned int selection = 0; - for (std::map::const_iterator iter (mButtons.begin()); - iter!=mButtons.end(); ++iter) + for (std::map::const_iterator iter(mButtons.begin()); iter != mButtons.end(); ++iter) if (iter->first->isChecked()) selection |= iter->second.mMask; return selection; } -void CSVWidget::SceneToolToggle2::setSelectionMask (unsigned int selection) +void CSVWidget::SceneToolToggle2::setSelectionMask(unsigned int selection) { - for (std::map::iterator iter (mButtons.begin()); - iter!=mButtons.end(); ++iter) - iter->first->setChecked (selection & iter->second.mMask); + for (std::map::iterator iter(mButtons.begin()); iter != mButtons.end(); ++iter) + iter->first->setChecked(selection & iter->second.mMask); adjustToolTip(); adjustIcon(); @@ -132,10 +132,9 @@ void CSVWidget::SceneToolToggle2::setSelectionMask (unsigned int selection) void CSVWidget::SceneToolToggle2::selected() { - std::map::const_iterator iter = - mButtons.find (dynamic_cast (sender())); + std::map::const_iterator iter = mButtons.find(dynamic_cast(sender())); - if (iter!=mButtons.end()) + if (iter != mButtons.end()) { if (!iter->first->hasKeepOpen()) mPanel->hide(); diff --git a/apps/opencs/view/widget/scenetooltoggle2.hpp b/apps/opencs/view/widget/scenetooltoggle2.hpp index e250192984..c300243e1e 100644 --- a/apps/opencs/view/widget/scenetooltoggle2.hpp +++ b/apps/opencs/view/widget/scenetooltoggle2.hpp @@ -18,61 +18,60 @@ namespace CSVWidget /// Top level button is using predefined icons instead building a composite icon. class SceneToolToggle2 : public SceneTool { - Q_OBJECT + Q_OBJECT - struct ButtonDesc - { - unsigned int mButtonId; - unsigned int mMask; - QString mName; - int mIndex; - }; + struct ButtonDesc + { + unsigned int mButtonId; + unsigned int mMask; + QString mName; + int mIndex; + }; - std::string mCompositeIcon; - std::string mSingleIcon; - QWidget *mPanel; - QHBoxLayout *mLayout; - std::map mButtons; // widget, id - int mButtonSize; - int mIconSize; - QString mToolTip; - PushButton *mFirst; + std::string mCompositeIcon; + std::string mSingleIcon; + QWidget* mPanel; + QHBoxLayout* mLayout; + std::map mButtons; // widget, id + int mButtonSize; + int mIconSize; + QString mToolTip; + PushButton* mFirst; - void adjustToolTip(); + void adjustToolTip(); - void adjustIcon(); + void adjustIcon(); - public: + public: + /// The top level icon is compositeIcon + sum of bitpatterns for active buttons (in + /// decimal) + /// + /// The icon for individual toggle buttons is signleIcon + bitmask for button (in + /// decimal) + SceneToolToggle2(SceneToolbar* parent, const QString& toolTip, const std::string& compositeIcon, + const std::string& singleIcon); - /// The top level icon is compositeIcon + sum of bitpatterns for active buttons (in - /// decimal) - /// - /// The icon for individual toggle buttons is signleIcon + bitmask for button (in - /// decimal) - SceneToolToggle2 (SceneToolbar *parent, const QString& toolTip, - const std::string& compositeIcon, const std::string& singleIcon); + void showPanel(const QPoint& position) override; - void showPanel (const QPoint& position) override; + /// \param buttonId used to compose the icon filename + /// \param mask used for the reported getSelectionMask() / setSelectionMask() + /// \attention After the last button has been added, setSelection must be called at + /// least once to finalise the layout. + void addButton(unsigned int buttonId, unsigned int mask, const QString& name, const QString& tooltip = "", + bool disabled = false); - /// \param buttonId used to compose the icon filename - /// \param mask used for the reported getSelectionMask() / setSelectionMask() - /// \attention After the last button has been added, setSelection must be called at - /// least once to finalise the layout. - void addButton (unsigned int buttonId, unsigned int mask, - const QString& name, const QString& tooltip = "", bool disabled = false); + unsigned int getSelectionMask() const; - unsigned int getSelectionMask() const; + /// \param or'ed button masks. buttons that do not exist will be ignored. + void setSelectionMask(unsigned int selection); - /// \param or'ed button masks. buttons that do not exist will be ignored. - void setSelectionMask (unsigned int selection); + signals: - signals: + void selectionChanged(); - void selectionChanged(); + private slots: - private slots: - - void selected(); + void selected(); }; } diff --git a/apps/opencs/view/world/bodypartcreator.cpp b/apps/opencs/view/world/bodypartcreator.cpp index 29061ae1dc..2df61bb7e4 100644 --- a/apps/opencs/view/world/bodypartcreator.cpp +++ b/apps/opencs/view/world/bodypartcreator.cpp @@ -17,11 +17,8 @@ std::string CSVWorld::BodyPartCreator::getId() const return id; } -CSVWorld::BodyPartCreator::BodyPartCreator( - CSMWorld::Data& data, - QUndoStack& undoStack, - const CSMWorld::UniversalId& id -) : GenericCreator(data, undoStack, id) +CSVWorld::BodyPartCreator::BodyPartCreator(CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id) + : GenericCreator(data, undoStack, id) { mFirstPerson = new QCheckBox("First Person", this); insertBeforeButtons(mFirstPerson, false); diff --git a/apps/opencs/view/world/bodypartcreator.hpp b/apps/opencs/view/world/bodypartcreator.hpp index f526b7faeb..adb795eace 100644 --- a/apps/opencs/view/world/bodypartcreator.hpp +++ b/apps/opencs/view/world/bodypartcreator.hpp @@ -18,29 +18,24 @@ namespace CSVWorld { Q_OBJECT - QCheckBox *mFirstPerson; + QCheckBox* mFirstPerson; - private: + private: + /// \return ID entered by user. + std::string getId() const override; - /// \return ID entered by user. - std::string getId() const override; + public: + BodyPartCreator(CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id); - public: + /// \return Error description for current user input. + std::string getErrors() const override; - BodyPartCreator( - CSMWorld::Data& data, - QUndoStack& undoStack, - const CSMWorld::UniversalId& id); + /// \brief Clear ID and checkbox input widgets. + void reset() override; - /// \return Error description for current user input. - std::string getErrors() const override; + private slots: - /// \brief Clear ID and checkbox input widgets. - void reset() override; - - private slots: - - void checkboxClicked(); + void checkboxClicked(); }; } diff --git a/apps/opencs/view/world/cellcreator.cpp b/apps/opencs/view/world/cellcreator.cpp index 9f721aa51d..808d28c79a 100644 --- a/apps/opencs/view/world/cellcreator.cpp +++ b/apps/opencs/view/world/cellcreator.cpp @@ -4,15 +4,15 @@ #include #include -#include #include +#include #include "../../model/world/commands.hpp" #include "../../model/world/idtree.hpp" std::string CSVWorld::CellCreator::getId() const { - if (mType->currentIndex()==0) + if (mType->currentIndex() == 0) return GenericCreator::getId(); std::ostringstream stream; @@ -31,83 +31,83 @@ void CSVWorld::CellCreator::configureCreateCommand(CSMWorld::CreateCommand& comm command.addNestedValue(parentIndex, index, mType->currentIndex() == 0); } -CSVWorld::CellCreator::CellCreator (CSMWorld::Data& data, QUndoStack& undoStack, - const CSMWorld::UniversalId& id) -: GenericCreator (data, undoStack, id) +CSVWorld::CellCreator::CellCreator(CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id) + : GenericCreator(data, undoStack, id) { - mY = new QSpinBox (this); - mY->setVisible (false); - mY->setMinimum (std::numeric_limits::min()); - mY->setMaximum (std::numeric_limits::max()); - connect (mY, qOverload(&QSpinBox::valueChanged), this, &CellCreator::valueChanged); - insertAtBeginning (mY, true); + mY = new QSpinBox(this); + mY->setVisible(false); + mY->setMinimum(std::numeric_limits::min()); + mY->setMaximum(std::numeric_limits::max()); + connect(mY, qOverload(&QSpinBox::valueChanged), this, &CellCreator::valueChanged); + insertAtBeginning(mY, true); - mYLabel = new QLabel ("Y", this); - mYLabel->setVisible (false); - insertAtBeginning (mYLabel, false); + mYLabel = new QLabel("Y", this); + mYLabel->setVisible(false); + insertAtBeginning(mYLabel, false); - mX = new QSpinBox (this); - mX->setVisible (false); - mX->setMinimum (std::numeric_limits::min()); - mX->setMaximum (std::numeric_limits::max()); - connect (mX, qOverload(&QSpinBox::valueChanged), this, &CellCreator::valueChanged); - insertAtBeginning (mX, true); + mX = new QSpinBox(this); + mX->setVisible(false); + mX->setMinimum(std::numeric_limits::min()); + mX->setMaximum(std::numeric_limits::max()); + connect(mX, qOverload(&QSpinBox::valueChanged), this, &CellCreator::valueChanged); + insertAtBeginning(mX, true); - mXLabel = new QLabel ("X", this); - mXLabel->setVisible (false); - insertAtBeginning (mXLabel, false); + mXLabel = new QLabel("X", this); + mXLabel->setVisible(false); + insertAtBeginning(mXLabel, false); - mType = new QComboBox (this); + mType = new QComboBox(this); - mType->addItem ("Interior Cell"); - mType->addItem ("Exterior Cell"); + mType->addItem("Interior Cell"); + mType->addItem("Exterior Cell"); - connect (mType, qOverload(&QComboBox::currentIndexChanged), this, &CellCreator::setType); + connect(mType, qOverload(&QComboBox::currentIndexChanged), this, &CellCreator::setType); - insertAtBeginning (mType, false); + insertAtBeginning(mType, false); } void CSVWorld::CellCreator::reset() { - mX->setValue (0); - mY->setValue (0); - mType->setCurrentIndex (0); + mX->setValue(0); + mY->setValue(0); + mType->setCurrentIndex(0); setType(0); GenericCreator::reset(); } -void CSVWorld::CellCreator::setType (int index) +void CSVWorld::CellCreator::setType(int index) { - setManualEditing (index==0); - mXLabel->setVisible (index==1); - mX->setVisible (index==1); - mYLabel->setVisible (index==1); - mY->setVisible (index==1); + setManualEditing(index == 0); + mXLabel->setVisible(index == 1); + mX->setVisible(index == 1); + mYLabel->setVisible(index == 1); + mY->setVisible(index == 1); // The cell name is limited to 64 characters. (ESM::Header::GMDT::mCurrentCell) std::string text = mType->currentText().toStdString(); if (text == "Interior Cell") - GenericCreator::setEditorMaxLength (64); + GenericCreator::setEditorMaxLength(64); else - GenericCreator::setEditorMaxLength (32767); + GenericCreator::setEditorMaxLength(32767); update(); } -void CSVWorld::CellCreator::valueChanged (int index) +void CSVWorld::CellCreator::valueChanged(int index) { update(); } -void CSVWorld::CellCreator::cloneMode(const std::string& originId, - const CSMWorld::UniversalId::Type type) +void CSVWorld::CellCreator::cloneMode(const std::string& originId, const CSMWorld::UniversalId::Type type) { CSVWorld::GenericCreator::cloneMode(originId, type); - if (*(originId.begin()) == '#') //if originid points to the exterior cell + if (*(originId.begin()) == '#') // if originid points to the exterior cell { - setType(1); //enable x and y controls + setType(1); // enable x and y controls mType->setCurrentIndex(1); - } else { + } + else + { setType(0); mType->setCurrentIndex(0); } diff --git a/apps/opencs/view/world/cellcreator.hpp b/apps/opencs/view/world/cellcreator.hpp index 032096aa24..4e68b1bf3e 100644 --- a/apps/opencs/view/world/cellcreator.hpp +++ b/apps/opencs/view/world/cellcreator.hpp @@ -11,39 +11,36 @@ namespace CSVWorld { class CellCreator : public GenericCreator { - Q_OBJECT + Q_OBJECT - QComboBox *mType; - QLabel *mXLabel; - QSpinBox *mX; - QLabel *mYLabel; - QSpinBox *mY; + QComboBox* mType; + QLabel* mXLabel; + QSpinBox* mX; + QLabel* mYLabel; + QSpinBox* mY; - protected: + protected: + std::string getId() const override; - std::string getId() const override; + /// Allow subclasses to add additional data to \a command. + void configureCreateCommand(CSMWorld::CreateCommand& command) const override; - /// Allow subclasses to add additional data to \a command. - void configureCreateCommand(CSMWorld::CreateCommand& command) const override; + public: + CellCreator(CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id); - public: + void reset() override; - CellCreator (CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id); + void cloneMode(const std::string& originId, const CSMWorld::UniversalId::Type type) override; - void reset() override; + std::string getErrors() const override; + ///< Return formatted error descriptions for the current state of the creator. if an empty + /// string is returned, there is no error. - void cloneMode(const std::string& originId, - const CSMWorld::UniversalId::Type type) override; + private slots: - std::string getErrors() const override; - ///< Return formatted error descriptions for the current state of the creator. if an empty - /// string is returned, there is no error. + void setType(int index); - private slots: - - void setType (int index); - - void valueChanged (int index); + void valueChanged(int index); }; } diff --git a/apps/opencs/view/world/colordelegate.cpp b/apps/opencs/view/world/colordelegate.cpp index 8d5f5485df..cf2af1ae3a 100644 --- a/apps/opencs/view/world/colordelegate.cpp +++ b/apps/opencs/view/world/colordelegate.cpp @@ -2,23 +2,20 @@ #include -CSVWorld::ColorDelegate::ColorDelegate(CSMWorld::CommandDispatcher *dispatcher, - CSMDoc::Document& document, - QObject *parent) +CSVWorld::ColorDelegate::ColorDelegate( + CSMWorld::CommandDispatcher* dispatcher, CSMDoc::Document& document, QObject* parent) : CommandDelegate(dispatcher, document, parent) -{} +{ +} -void CSVWorld::ColorDelegate::paint(QPainter *painter, - const QStyleOptionViewItem &option, - const QModelIndex &index) const +void CSVWorld::ColorDelegate::paint( + QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { int colorInt = index.data().toInt(); QColor color(colorInt & 0xff, (colorInt >> 8) & 0xff, (colorInt >> 16) & 0xff); QRect coloredRect(option.rect.x() + qRound(option.rect.width() / 4.0), - option.rect.y() + qRound(option.rect.height() / 4.0), - option.rect.width() / 2, - option.rect.height() / 2); + option.rect.y() + qRound(option.rect.height() / 4.0), option.rect.width() / 2, option.rect.height() / 2); painter->save(); painter->fillRect(coloredRect, color); painter->setPen(Qt::black); @@ -26,11 +23,8 @@ void CSVWorld::ColorDelegate::paint(QPainter *painter, painter->restore(); } -CSVWorld::CommandDelegate *CSVWorld::ColorDelegateFactory::makeDelegate(CSMWorld::CommandDispatcher *dispatcher, - CSMDoc::Document &document, - QObject *parent) const +CSVWorld::CommandDelegate* CSVWorld::ColorDelegateFactory::makeDelegate( + CSMWorld::CommandDispatcher* dispatcher, CSMDoc::Document& document, QObject* parent) const { return new ColorDelegate(dispatcher, document, parent); } - - diff --git a/apps/opencs/view/world/colordelegate.hpp b/apps/opencs/view/world/colordelegate.hpp index 041051d132..b1f2a7f00e 100644 --- a/apps/opencs/view/world/colordelegate.hpp +++ b/apps/opencs/view/world/colordelegate.hpp @@ -14,23 +14,18 @@ namespace CSVWorld { class ColorDelegate : public CommandDelegate { - public: - ColorDelegate(CSMWorld::CommandDispatcher *dispatcher, - CSMDoc::Document& document, - QObject *parent); + public: + ColorDelegate(CSMWorld::CommandDispatcher* dispatcher, CSMDoc::Document& document, QObject* parent); - void paint(QPainter *painter, - const QStyleOptionViewItem &option, - const QModelIndex &index) const override; + void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override; }; class ColorDelegateFactory : public CommandDelegateFactory { - public: - CommandDelegate *makeDelegate(CSMWorld::CommandDispatcher *dispatcher, - CSMDoc::Document &document, - QObject *parent) const override; - ///< The ownership of the returned CommandDelegate is transferred to the caller. + public: + CommandDelegate* makeDelegate( + CSMWorld::CommandDispatcher* dispatcher, CSMDoc::Document& document, QObject* parent) const override; + ///< The ownership of the returned CommandDelegate is transferred to the caller. }; } diff --git a/apps/opencs/view/world/creator.cpp b/apps/opencs/view/world/creator.cpp index 53664c186a..04db050a09 100644 --- a/apps/opencs/view/world/creator.cpp +++ b/apps/opencs/view/world/creator.cpp @@ -4,18 +4,16 @@ CSVWorld::Creator::~Creator() {} -void CSVWorld::Creator::setScope (unsigned int scope) +void CSVWorld::Creator::setScope(unsigned int scope) { - if (scope!=CSMWorld::Scope_Content) - throw std::logic_error ("Invalid scope in creator"); + if (scope != CSMWorld::Scope_Content) + throw std::logic_error("Invalid scope in creator"); } - CSVWorld::CreatorFactoryBase::~CreatorFactoryBase() {} - -CSVWorld::Creator *CSVWorld::NullCreatorFactory::makeCreator (CSMDoc::Document& document, - const CSMWorld::UniversalId& id) const +CSVWorld::Creator* CSVWorld::NullCreatorFactory::makeCreator( + CSMDoc::Document& document, const CSMWorld::UniversalId& id) const { return nullptr; } diff --git a/apps/opencs/view/world/creator.hpp b/apps/opencs/view/world/creator.hpp index 7c61c6e6be..67f68ee6fb 100644 --- a/apps/opencs/view/world/creator.hpp +++ b/apps/opencs/view/world/creator.hpp @@ -22,83 +22,78 @@ namespace CSVWorld /// \brief Record creator UI base class class Creator : public QWidget { - Q_OBJECT + Q_OBJECT - public: + public: + virtual ~Creator(); - virtual ~Creator(); + virtual void reset() = 0; - virtual void reset() = 0; + virtual void cloneMode(const std::string& originId, const CSMWorld::UniversalId::Type type) = 0; - virtual void cloneMode(const std::string& originId, - const CSMWorld::UniversalId::Type type) = 0; + /// Touches a record, if the creator supports it. + virtual void touch(const std::vector& ids) = 0; - /// Touches a record, if the creator supports it. - virtual void touch(const std::vector& ids) = 0; + virtual void setEditLock(bool locked) = 0; - virtual void setEditLock (bool locked) = 0; + virtual void toggleWidgets(bool active = true) = 0; - virtual void toggleWidgets(bool active = true) = 0; + /// Default implementation: Throw an exception if scope!=Scope_Content. + virtual void setScope(unsigned int scope); - /// Default implementation: Throw an exception if scope!=Scope_Content. - virtual void setScope (unsigned int scope); + /// Focus main input widget + virtual void focus() = 0; - /// Focus main input widget - virtual void focus() = 0; + signals: - signals: + void done(); - void done(); - - void requestFocus (const std::string& id); - ///< Request owner of this creator to focus the just created \a id. The owner may - /// ignore this request. + void requestFocus(const std::string& id); + ///< Request owner of this creator to focus the just created \a id. The owner may + /// ignore this request. }; /// \brief Base class for Creator factory class CreatorFactoryBase { - public: - - virtual ~CreatorFactoryBase(); - - virtual Creator *makeCreator (CSMDoc::Document& document, const CSMWorld::UniversalId& id) const = 0; - ///< The ownership of the returned Creator is transferred to the caller. - /// - /// \note The function can return a 0-pointer, which means no UI for creating/deleting - /// records should be provided. + public: + virtual ~CreatorFactoryBase(); + + virtual Creator* makeCreator(CSMDoc::Document& document, const CSMWorld::UniversalId& id) const = 0; + ///< The ownership of the returned Creator is transferred to the caller. + /// + /// \note The function can return a 0-pointer, which means no UI for creating/deleting + /// records should be provided. }; /// \brief Creator factory that does not produces any creator class NullCreatorFactory : public CreatorFactoryBase { - public: - - Creator *makeCreator (CSMDoc::Document& document, const CSMWorld::UniversalId& id) const override; - ///< The ownership of the returned Creator is transferred to the caller. - /// - /// \note The function always returns 0. + public: + Creator* makeCreator(CSMDoc::Document& document, const CSMWorld::UniversalId& id) const override; + ///< The ownership of the returned Creator is transferred to the caller. + /// + /// \note The function always returns 0. }; - template + template class CreatorFactory : public CreatorFactoryBase { - public: - - Creator *makeCreator (CSMDoc::Document& document, const CSMWorld::UniversalId& id) const override; - ///< The ownership of the returned Creator is transferred to the caller. - /// - /// \note The function can return a 0-pointer, which means no UI for creating/deleting - /// records should be provided. + public: + Creator* makeCreator(CSMDoc::Document& document, const CSMWorld::UniversalId& id) const override; + ///< The ownership of the returned Creator is transferred to the caller. + /// + /// \note The function can return a 0-pointer, which means no UI for creating/deleting + /// records should be provided. }; - template - Creator *CreatorFactory::makeCreator (CSMDoc::Document& document, - const CSMWorld::UniversalId& id) const + template + Creator* CreatorFactory::makeCreator( + CSMDoc::Document& document, const CSMWorld::UniversalId& id) const { auto creator = std::make_unique(document.getData(), document.getUndoStack(), id); - creator->setScope (scope); + creator->setScope(scope); return creator.release(); } diff --git a/apps/opencs/view/world/datadisplaydelegate.cpp b/apps/opencs/view/world/datadisplaydelegate.cpp index 6da62d4089..bbf7cf863f 100644 --- a/apps/opencs/view/world/datadisplaydelegate.cpp +++ b/apps/opencs/view/world/datadisplaydelegate.cpp @@ -5,25 +5,24 @@ #include #include -CSVWorld::DataDisplayDelegate::DataDisplayDelegate(const ValueList &values, - const IconList &icons, - CSMWorld::CommandDispatcher *dispatcher, - CSMDoc::Document& document, - const std::string &pageName, - const std::string &settingName, - QObject *parent) - : EnumDelegate (values, dispatcher, document, parent), mDisplayMode (Mode_TextOnly), - mIcons (icons), mIconSize (QSize(16, 16)), - mHorizontalMargin(QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1), - mTextLeftOffset(8), mSettingKey (pageName + '/' + settingName) +CSVWorld::DataDisplayDelegate::DataDisplayDelegate(const ValueList& values, const IconList& icons, + CSMWorld::CommandDispatcher* dispatcher, CSMDoc::Document& document, const std::string& pageName, + const std::string& settingName, QObject* parent) + : EnumDelegate(values, dispatcher, document, parent) + , mDisplayMode(Mode_TextOnly) + , mIcons(icons) + , mIconSize(QSize(16, 16)) + , mHorizontalMargin(QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1) + , mTextLeftOffset(8) + , mSettingKey(pageName + '/' + settingName) { buildPixmaps(); if (!pageName.empty()) - updateDisplayMode (CSMPrefs::get()[pageName][settingName].toString()); + updateDisplayMode(CSMPrefs::get()[pageName][settingName].toString()); } -void CSVWorld::DataDisplayDelegate::buildPixmaps () +void CSVWorld::DataDisplayDelegate::buildPixmaps() { if (!mPixmaps.empty()) mPixmaps.clear(); @@ -32,7 +31,7 @@ void CSVWorld::DataDisplayDelegate::buildPixmaps () while (it != mIcons.end()) { - mPixmaps.emplace_back (it->mValue, it->mIcon.pixmap (mIconSize) ); + mPixmaps.emplace_back(it->mValue, it->mIcon.pixmap(mIconSize)); ++it; } } @@ -48,7 +47,7 @@ void CSVWorld::DataDisplayDelegate::setTextLeftOffset(int offset) mTextLeftOffset = offset; } -QSize CSVWorld::DataDisplayDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const +QSize CSVWorld::DataDisplayDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const { QSize size = EnumDelegate::sizeHint(option, index); @@ -72,11 +71,12 @@ QSize CSVWorld::DataDisplayDelegate::sizeHint(const QStyleOptionViewItem &option return size; } -void CSVWorld::DataDisplayDelegate::paint (QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +void CSVWorld::DataDisplayDelegate::paint( + QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { painter->save(); - //default to enum delegate's paint method for text-only conditions + // default to enum delegate's paint method for text-only conditions if (mDisplayMode == Mode_TextOnly) EnumDelegate::paint(painter, option, index); else @@ -91,7 +91,7 @@ void CSVWorld::DataDisplayDelegate::paint (QPainter *painter, const QStyleOption painter->restore(); } -void CSVWorld::DataDisplayDelegate::paintIcon (QPainter *painter, const QStyleOptionViewItem &option, int index) const +void CSVWorld::DataDisplayDelegate::paintIcon(QPainter* painter, const QStyleOptionViewItem& option, int index) const { QRect iconRect = option.rect; QRect textRect = iconRect; @@ -104,20 +104,14 @@ void CSVWorld::DataDisplayDelegate::paintIcon (QPainter *painter, const QStyleOp textRect.setLeft(iconRect.right() + mTextLeftOffset); textRect.setRight(option.rect.right() - mHorizontalMargin); - QString text = option.fontMetrics.elidedText(mValues.at(index).second, - option.textElideMode, - textRect.width()); - QApplication::style()->drawItemText(painter, - textRect, - Qt::AlignLeft | Qt::AlignVCenter, - option.palette, - true, - text); + QString text = option.fontMetrics.elidedText(mValues.at(index).second, option.textElideMode, textRect.width()); + QApplication::style()->drawItemText( + painter, textRect, Qt::AlignLeft | Qt::AlignVCenter, option.palette, true, text); } QApplication::style()->drawItemPixmap(painter, iconRect, Qt::AlignCenter, mPixmaps.at(index).second); } -void CSVWorld::DataDisplayDelegate::updateDisplayMode (const std::string &mode) +void CSVWorld::DataDisplayDelegate::updateDisplayMode(const std::string& mode) { if (mode == "Icon and Text") mDisplayMode = Mode_IconAndText; @@ -129,18 +123,15 @@ void CSVWorld::DataDisplayDelegate::updateDisplayMode (const std::string &mode) mDisplayMode = Mode_TextOnly; } -CSVWorld::DataDisplayDelegate::~DataDisplayDelegate() -{ -} +CSVWorld::DataDisplayDelegate::~DataDisplayDelegate() {} -void CSVWorld::DataDisplayDelegate::settingChanged (const CSMPrefs::Setting *setting) +void CSVWorld::DataDisplayDelegate::settingChanged(const CSMPrefs::Setting* setting) { - if (*setting==mSettingKey) - updateDisplayMode (setting->toString()); + if (*setting == mSettingKey) + updateDisplayMode(setting->toString()); } - -void CSVWorld::DataDisplayDelegateFactory::add (int enumValue, const QString& enumName, const QString& iconFilename) +void CSVWorld::DataDisplayDelegateFactory::add(int enumValue, const QString& enumName, const QString& iconFilename) { EnumDelegateFactory::add(enumValue, enumName); @@ -149,7 +140,7 @@ void CSVWorld::DataDisplayDelegateFactory::add (int enumValue, const QString& en icon.mName = enumName; icon.mIcon = QIcon(iconFilename); - for (auto it=mIcons.begin(); it!=mIcons.end(); ++it) + for (auto it = mIcons.begin(); it != mIcons.end(); ++it) { if (it->mName > enumName) { @@ -161,8 +152,8 @@ void CSVWorld::DataDisplayDelegateFactory::add (int enumValue, const QString& en mIcons.push_back(icon); } -CSVWorld::CommandDelegate *CSVWorld::DataDisplayDelegateFactory::makeDelegate ( - CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) const +CSVWorld::CommandDelegate* CSVWorld::DataDisplayDelegateFactory::makeDelegate( + CSMWorld::CommandDispatcher* dispatcher, CSMDoc::Document& document, QObject* parent) const { - return new DataDisplayDelegate (mValues, mIcons, dispatcher, document, "", "", parent); + return new DataDisplayDelegate(mValues, mIcons, dispatcher, document, "", "", parent); } diff --git a/apps/opencs/view/world/datadisplaydelegate.hpp b/apps/opencs/view/world/datadisplaydelegate.hpp index 52e2294f03..e80760bb73 100755 --- a/apps/opencs/view/world/datadisplaydelegate.hpp +++ b/apps/opencs/view/world/datadisplaydelegate.hpp @@ -20,12 +20,10 @@ namespace CSVWorld class DataDisplayDelegate : public EnumDelegate { public: - typedef std::vector IconList; - typedef std::vector > ValueList; + typedef std::vector> ValueList; protected: - enum DisplayMode { Mode_TextOnly, @@ -37,8 +35,7 @@ namespace CSVWorld IconList mIcons; private: - - std::vector > mPixmaps; + std::vector> mPixmaps; QSize mIconSize; int mHorizontalMargin; int mTextLeftOffset; @@ -46,51 +43,46 @@ namespace CSVWorld std::string mSettingKey; public: - DataDisplayDelegate (const ValueList & values, const IconList & icons, - CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, - const std::string& pageName, const std::string& settingName, QObject *parent); + DataDisplayDelegate(const ValueList& values, const IconList& icons, CSMWorld::CommandDispatcher* dispatcher, + CSMDoc::Document& document, const std::string& pageName, const std::string& settingName, QObject* parent); ~DataDisplayDelegate(); - void paint (QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; + void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override; - QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override; + QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override; /// pass a QSize defining height / width of icon. Default is QSize (16,16). - void setIconSize (const QSize& icon); + void setIconSize(const QSize& icon); /// offset the horizontal position of the text from the right edge of the icon. Default is 8 pixels. - void setTextLeftOffset (int offset); + void setTextLeftOffset(int offset); private: - /// update the display mode based on a passed string - void updateDisplayMode (const std::string &); + void updateDisplayMode(const std::string&); /// custom paint function for painting the icon. Mode_IconAndText and Mode_Icon only. - void paintIcon (QPainter *painter, const QStyleOptionViewItem &option, int i) const; + void paintIcon(QPainter* painter, const QStyleOptionViewItem& option, int i) const; /// rebuild the list of pixmaps from the provided icons (called when icon size is changed) void buildPixmaps(); - void settingChanged (const CSMPrefs::Setting *setting) override; + void settingChanged(const CSMPrefs::Setting* setting) override; }; class DataDisplayDelegateFactory : public EnumDelegateFactory { protected: - DataDisplayDelegate::IconList mIcons; public: - - CommandDelegate *makeDelegate (CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) const override; + CommandDelegate* makeDelegate( + CSMWorld::CommandDispatcher* dispatcher, CSMDoc::Document& document, QObject* parent) const override; ///< The ownership of the returned CommandDelegate is transferred to the caller. protected: - - void add (int enumValue, const QString& enumName, const QString& iconFilename); - + void add(int enumValue, const QString& enumName, const QString& iconFilename); }; } diff --git a/apps/opencs/view/world/dialoguecreator.cpp b/apps/opencs/view/world/dialoguecreator.cpp index 9317aa95cd..9656e43d13 100644 --- a/apps/opencs/view/world/dialoguecreator.cpp +++ b/apps/opencs/view/world/dialoguecreator.cpp @@ -5,28 +5,29 @@ #include "../../model/world/commands.hpp" #include "../../model/world/idtable.hpp" -void CSVWorld::DialogueCreator::configureCreateCommand (CSMWorld::CreateCommand& command) const +void CSVWorld::DialogueCreator::configureCreateCommand(CSMWorld::CreateCommand& command) const { - int index = - dynamic_cast (*getData().getTableModel (getCollectionId())). - findColumnIndex (CSMWorld::Columns::ColumnId_DialogueType); + int index = dynamic_cast(*getData().getTableModel(getCollectionId())) + .findColumnIndex(CSMWorld::Columns::ColumnId_DialogueType); - command.addValue (index, mType); + command.addValue(index, mType); } -CSVWorld::DialogueCreator::DialogueCreator (CSMWorld::Data& data, QUndoStack& undoStack, - const CSMWorld::UniversalId& id, int type) -: GenericCreator (data, undoStack, id, true), mType (type) -{} +CSVWorld::DialogueCreator::DialogueCreator( + CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id, int type) + : GenericCreator(data, undoStack, id, true) + , mType(type) +{ +} -CSVWorld::Creator *CSVWorld::TopicCreatorFactory::makeCreator (CSMDoc::Document& document, - const CSMWorld::UniversalId& id) const +CSVWorld::Creator* CSVWorld::TopicCreatorFactory::makeCreator( + CSMDoc::Document& document, const CSMWorld::UniversalId& id) const { - return new DialogueCreator (document.getData(), document.getUndoStack(), id, ESM::Dialogue::Topic); + return new DialogueCreator(document.getData(), document.getUndoStack(), id, ESM::Dialogue::Topic); } -CSVWorld::Creator *CSVWorld::JournalCreatorFactory::makeCreator (CSMDoc::Document& document, - const CSMWorld::UniversalId& id) const +CSVWorld::Creator* CSVWorld::JournalCreatorFactory::makeCreator( + CSMDoc::Document& document, const CSMWorld::UniversalId& id) const { - return new DialogueCreator (document.getData(), document.getUndoStack(), id, ESM::Dialogue::Journal); + return new DialogueCreator(document.getData(), document.getUndoStack(), id, ESM::Dialogue::Journal); } diff --git a/apps/opencs/view/world/dialoguecreator.hpp b/apps/opencs/view/world/dialoguecreator.hpp index 0aef2f84df..74a1ab6b4f 100644 --- a/apps/opencs/view/world/dialoguecreator.hpp +++ b/apps/opencs/view/world/dialoguecreator.hpp @@ -7,32 +7,27 @@ namespace CSVWorld { class DialogueCreator : public GenericCreator { - int mType; + int mType; - protected: + protected: + void configureCreateCommand(CSMWorld::CreateCommand& command) const override; - void configureCreateCommand (CSMWorld::CreateCommand& command) const override; - - public: - - DialogueCreator (CSMWorld::Data& data, QUndoStack& undoStack, - const CSMWorld::UniversalId& id, int type); + public: + DialogueCreator(CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id, int type); }; class TopicCreatorFactory : public CreatorFactoryBase { - public: - - Creator *makeCreator (CSMDoc::Document& document, const CSMWorld::UniversalId& id) const override; - ///< The ownership of the returned Creator is transferred to the caller. + public: + Creator* makeCreator(CSMDoc::Document& document, const CSMWorld::UniversalId& id) const override; + ///< The ownership of the returned Creator is transferred to the caller. }; class JournalCreatorFactory : public CreatorFactoryBase { - public: - - Creator *makeCreator (CSMDoc::Document& document, const CSMWorld::UniversalId& id) const override; - ///< The ownership of the returned Creator is transferred to the caller. + public: + Creator* makeCreator(CSMDoc::Document& document, const CSMWorld::UniversalId& id) const override; + ///< The ownership of the returned Creator is transferred to the caller. }; } diff --git a/apps/opencs/view/world/dialoguespinbox.cpp b/apps/opencs/view/world/dialoguespinbox.cpp index 1228ca0da9..25b15e51b6 100644 --- a/apps/opencs/view/world/dialoguespinbox.cpp +++ b/apps/opencs/view/world/dialoguespinbox.cpp @@ -2,24 +2,25 @@ #include -CSVWorld::DialogueSpinBox::DialogueSpinBox(QWidget *parent) : QSpinBox(parent) +CSVWorld::DialogueSpinBox::DialogueSpinBox(QWidget* parent) + : QSpinBox(parent) { setFocusPolicy(Qt::StrongFocus); } -void CSVWorld::DialogueSpinBox::focusInEvent(QFocusEvent *event) +void CSVWorld::DialogueSpinBox::focusInEvent(QFocusEvent* event) { setFocusPolicy(Qt::WheelFocus); QSpinBox::focusInEvent(event); } -void CSVWorld::DialogueSpinBox::focusOutEvent(QFocusEvent *event) +void CSVWorld::DialogueSpinBox::focusOutEvent(QFocusEvent* event) { setFocusPolicy(Qt::StrongFocus); QSpinBox::focusOutEvent(event); } -void CSVWorld::DialogueSpinBox::wheelEvent(QWheelEvent *event) +void CSVWorld::DialogueSpinBox::wheelEvent(QWheelEvent* event) { if (!hasFocus()) event->ignore(); @@ -27,24 +28,25 @@ void CSVWorld::DialogueSpinBox::wheelEvent(QWheelEvent *event) QSpinBox::wheelEvent(event); } -CSVWorld::DialogueDoubleSpinBox::DialogueDoubleSpinBox(QWidget *parent) : QDoubleSpinBox(parent) +CSVWorld::DialogueDoubleSpinBox::DialogueDoubleSpinBox(QWidget* parent) + : QDoubleSpinBox(parent) { setFocusPolicy(Qt::StrongFocus); } -void CSVWorld::DialogueDoubleSpinBox::focusInEvent(QFocusEvent *event) +void CSVWorld::DialogueDoubleSpinBox::focusInEvent(QFocusEvent* event) { setFocusPolicy(Qt::WheelFocus); QDoubleSpinBox::focusInEvent(event); } -void CSVWorld::DialogueDoubleSpinBox::focusOutEvent(QFocusEvent *event) +void CSVWorld::DialogueDoubleSpinBox::focusOutEvent(QFocusEvent* event) { setFocusPolicy(Qt::StrongFocus); QDoubleSpinBox::focusOutEvent(event); } -void CSVWorld::DialogueDoubleSpinBox::wheelEvent(QWheelEvent *event) +void CSVWorld::DialogueDoubleSpinBox::wheelEvent(QWheelEvent* event) { if (!hasFocus()) event->ignore(); diff --git a/apps/opencs/view/world/dialoguespinbox.hpp b/apps/opencs/view/world/dialoguespinbox.hpp index 90fe8d20cd..beffb56562 100644 --- a/apps/opencs/view/world/dialoguespinbox.hpp +++ b/apps/opencs/view/world/dialoguespinbox.hpp @@ -1,8 +1,8 @@ #ifndef CSV_WORLD_DIALOGUESPINBOX_H #define CSV_WORLD_DIALOGUESPINBOX_H -#include #include +#include namespace CSVWorld { @@ -10,30 +10,26 @@ namespace CSVWorld { Q_OBJECT - public: - - DialogueSpinBox (QWidget *parent = nullptr); + public: + DialogueSpinBox(QWidget* parent = nullptr); - protected: - - void focusInEvent(QFocusEvent *event) override; - void focusOutEvent(QFocusEvent *event) override; - void wheelEvent(QWheelEvent *event) override; + protected: + void focusInEvent(QFocusEvent* event) override; + void focusOutEvent(QFocusEvent* event) override; + void wheelEvent(QWheelEvent* event) override; }; class DialogueDoubleSpinBox : public QDoubleSpinBox { Q_OBJECT - public: - - DialogueDoubleSpinBox (QWidget *parent = nullptr); - - protected: + public: + DialogueDoubleSpinBox(QWidget* parent = nullptr); - void focusInEvent(QFocusEvent *event) override; - void focusOutEvent(QFocusEvent *event) override; - void wheelEvent(QWheelEvent *event) override; + protected: + void focusInEvent(QFocusEvent* event) override; + void focusOutEvent(QFocusEvent* event) override; + void wheelEvent(QWheelEvent* event) override; }; } diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 8d7fa875f1..7e2b39571d 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -1,8 +1,8 @@ #include "dialoguesubview.hpp" -#include #include #include +#include #include #include @@ -17,38 +17,39 @@ #include #include -#include "../../model/world/nestedtableproxymodel.hpp" +#include "../../model/doc/document.hpp" #include "../../model/world/columnbase.hpp" +#include "../../model/world/columns.hpp" +#include "../../model/world/commands.hpp" #include "../../model/world/idtable.hpp" #include "../../model/world/idtree.hpp" -#include "../../model/world/columns.hpp" +#include "../../model/world/nestedtableproxymodel.hpp" #include "../../model/world/record.hpp" #include "../../model/world/tablemimedata.hpp" -#include "../../model/world/commands.hpp" -#include "../../model/doc/document.hpp" #include "../../model/prefs/state.hpp" #include "../widget/coloreditor.hpp" #include "../widget/droplineedit.hpp" -#include "recordstatusdelegate.hpp" -#include "util.hpp" -#include "tablebottombox.hpp" #include "nestedtable.hpp" #include "recordbuttonbar.hpp" +#include "recordstatusdelegate.hpp" +#include "tablebottombox.hpp" +#include "util.hpp" /* ==============================NotEditableSubDelegate========================================== */ -CSVWorld::NotEditableSubDelegate::NotEditableSubDelegate(const CSMWorld::IdTable* table, QObject * parent) : -QAbstractItemDelegate(parent), -mTable(table) -{} +CSVWorld::NotEditableSubDelegate::NotEditableSubDelegate(const CSMWorld::IdTable* table, QObject* parent) + : QAbstractItemDelegate(parent) + , mTable(table) +{ +} -void CSVWorld::NotEditableSubDelegate::setEditorData (QWidget* editor, const QModelIndex& index) const +void CSVWorld::NotEditableSubDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const { QLabel* label = qobject_cast(editor); - if(!label) + if (!label) return; QVariant v = index.data(Qt::EditRole); @@ -61,61 +62,64 @@ void CSVWorld::NotEditableSubDelegate::setEditorData (QWidget* editor, const QMo } } - CSMWorld::Columns::ColumnId columnId = static_cast ( - mTable->getColumnId (index.column())); + CSMWorld::Columns::ColumnId columnId + = static_cast(mTable->getColumnId(index.column())); if (QVariant::String == v.type()) { label->setText(v.toString()); } - else if (CSMWorld::Columns::hasEnums (columnId)) + else if (CSMWorld::Columns::hasEnums(columnId)) { int data = v.toInt(); - std::vector> enumNames (CSMWorld::Columns::getEnums (columnId)); + std::vector> enumNames(CSMWorld::Columns::getEnums(columnId)); label->setText(QString::fromUtf8(enumNames.at(data).second.c_str())); } else { - label->setText (v.toString()); + label->setText(v.toString()); } } -void CSVWorld::NotEditableSubDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const +void CSVWorld::NotEditableSubDelegate::setModelData( + QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const { - //not editable widgets will not save model data + // not editable widgets will not save model data } -void CSVWorld::NotEditableSubDelegate::paint (QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const +void CSVWorld::NotEditableSubDelegate::paint( + QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { - //does nothing + // does nothing } -QSize CSVWorld::NotEditableSubDelegate::sizeHint (const QStyleOptionViewItem& option, const QModelIndex& index) const +QSize CSVWorld::NotEditableSubDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const { return QSize(); } -QWidget* CSVWorld::NotEditableSubDelegate::createEditor (QWidget *parent, - const QStyleOptionViewItem& option, - const QModelIndex& index) const +QWidget* CSVWorld::NotEditableSubDelegate::createEditor( + QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const { - QLabel *label = new QLabel(parent); - label->setTextInteractionFlags (Qt::TextSelectableByMouse); + QLabel* label = new QLabel(parent); + label->setTextInteractionFlags(Qt::TextSelectableByMouse); return label; } /* ==============================DialogueDelegateDispatcherProxy========================================== */ -CSVWorld::DialogueDelegateDispatcherProxy::refWrapper::refWrapper(const QModelIndex& index) : -mIndex(index) -{} +CSVWorld::DialogueDelegateDispatcherProxy::refWrapper::refWrapper(const QModelIndex& index) + : mIndex(index) +{ +} -CSVWorld::DialogueDelegateDispatcherProxy::DialogueDelegateDispatcherProxy(QWidget* editor, CSMWorld::ColumnBase::Display display) : -mEditor(editor), -mDisplay(display), -mIndexWrapper(nullptr) +CSVWorld::DialogueDelegateDispatcherProxy::DialogueDelegateDispatcherProxy( + QWidget* editor, CSMWorld::ColumnBase::Display display) + : mEditor(editor) + , mDisplay(display) + , mIndexWrapper(nullptr) { } @@ -141,54 +145,58 @@ QWidget* CSVWorld::DialogueDelegateDispatcherProxy::getEditor() const ==============================DialogueDelegateDispatcher========================================== */ -CSVWorld::DialogueDelegateDispatcher::DialogueDelegateDispatcher(QObject* parent, - CSMWorld::IdTable* table, CSMWorld::CommandDispatcher& commandDispatcher, - CSMDoc::Document& document, QAbstractItemModel *model) : -mParent(parent), -mTable(model ? model : table), -mCommandDispatcher (commandDispatcher), mDocument (document), -mNotEditableDelegate(table, parent) +CSVWorld::DialogueDelegateDispatcher::DialogueDelegateDispatcher(QObject* parent, CSMWorld::IdTable* table, + CSMWorld::CommandDispatcher& commandDispatcher, CSMDoc::Document& document, QAbstractItemModel* model) + : mParent(parent) + , mTable(model ? model : table) + , mCommandDispatcher(commandDispatcher) + , mDocument(document) + , mNotEditableDelegate(table, parent) { } CSVWorld::CommandDelegate* CSVWorld::DialogueDelegateDispatcher::makeDelegate(CSMWorld::ColumnBase::Display display) { - CommandDelegate *delegate = nullptr; + CommandDelegate* delegate = nullptr; std::map::const_iterator delegateIt(mDelegates.find(display)); if (delegateIt == mDelegates.end()) { - delegate = CommandDelegateFactoryCollection::get().makeDelegate ( - display, &mCommandDispatcher, mDocument, mParent); + delegate + = CommandDelegateFactoryCollection::get().makeDelegate(display, &mCommandDispatcher, mDocument, mParent); mDelegates.insert(std::make_pair(display, delegate)); - } else + } + else { delegate = delegateIt->second; } return delegate; } -void CSVWorld::DialogueDelegateDispatcher::editorDataCommited(QWidget* editor, - const QModelIndex& index, CSMWorld::ColumnBase::Display display) +void CSVWorld::DialogueDelegateDispatcher::editorDataCommited( + QWidget* editor, const QModelIndex& index, CSMWorld::ColumnBase::Display display) { setModelData(editor, mTable, index, display); } -void CSVWorld::DialogueDelegateDispatcher::setEditorData (QWidget* editor, const QModelIndex& index) const +void CSVWorld::DialogueDelegateDispatcher::setEditorData(QWidget* editor, const QModelIndex& index) const { CSMWorld::ColumnBase::Display display = CSMWorld::ColumnBase::Display_None; if (index.parent().isValid()) { - display = static_cast - (static_cast(mTable)->nestedHeaderData (index.parent().column(), index.column(), Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); + display + = static_cast(static_cast(mTable) + ->nestedHeaderData(index.parent().column(), index.column(), + Qt::Horizontal, CSMWorld::ColumnBase::Role_Display) + .toInt()); } else { - display = static_cast - (mTable->headerData (index.column(), Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); + display = static_cast( + mTable->headerData(index.column(), Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); } QLabel* label = qobject_cast(editor); - if(label) + if (label) { mNotEditableDelegate.setEditorData(label, index); return; @@ -202,21 +210,21 @@ void CSVWorld::DialogueDelegateDispatcher::setEditorData (QWidget* editor, const for (unsigned i = 0; i < mProxys.size(); ++i) { - if (mProxys[i]->getEditor() == editor) + if (mProxys[i]->getEditor() == editor) { mProxys[i]->setIndex(index); } } } -void CSVWorld::DialogueDelegateDispatcher::setModelData(QWidget* editor, - QAbstractItemModel* model, const QModelIndex& index) const +void CSVWorld::DialogueDelegateDispatcher::setModelData( + QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const { setModelData(editor, model, index, CSMWorld::ColumnBase::Display_None); } -void CSVWorld::DialogueDelegateDispatcher::setModelData(QWidget* editor, - QAbstractItemModel* model, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const +void CSVWorld::DialogueDelegateDispatcher::setModelData( + QWidget* editor, QAbstractItemModel* model, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const { std::map::const_iterator delegateIt(mDelegates.find(display)); if (delegateIt != mDelegates.end()) @@ -225,20 +233,19 @@ void CSVWorld::DialogueDelegateDispatcher::setModelData(QWidget* editor, } } -void CSVWorld::DialogueDelegateDispatcher::paint (QPainter* painter, - const QStyleOptionViewItem& option, const QModelIndex& index) const +void CSVWorld::DialogueDelegateDispatcher::paint( + QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { - //Does nothing + // Does nothing } -QSize CSVWorld::DialogueDelegateDispatcher::sizeHint (const QStyleOptionViewItem& option, - const QModelIndex& index) const +QSize CSVWorld::DialogueDelegateDispatcher::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const { - return QSize(); //silencing warning, otherwise does nothing + return QSize(); // silencing warning, otherwise does nothing } -QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase::Display display, - const QModelIndex& index) +QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor( + CSMWorld::ColumnBase::Display display, const QModelIndex& index) { QVariant variant = index.data(); if (!variant.isValid()) @@ -251,18 +258,17 @@ QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase:: } QWidget* editor = nullptr; - if (! (mTable->flags (index) & Qt::ItemIsEditable)) + if (!(mTable->flags(index) & Qt::ItemIsEditable)) { - return mNotEditableDelegate.createEditor(qobject_cast(mParent), - QStyleOptionViewItem(), index); + return mNotEditableDelegate.createEditor(qobject_cast(mParent), QStyleOptionViewItem(), index); } std::map::iterator delegateIt(mDelegates.find(display)); if (delegateIt != mDelegates.end()) { - editor = delegateIt->second->createEditor(qobject_cast(mParent), - QStyleOptionViewItem(), index, display); + editor + = delegateIt->second->createEditor(qobject_cast(mParent), QStyleOptionViewItem(), index, display); DialogueDelegateDispatcherProxy* proxy = new DialogueDelegateDispatcherProxy(editor, display); @@ -270,44 +276,46 @@ QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase:: // is required here if (qobject_cast(editor)) { - connect(static_cast(editor), &CSVWidget::DropLineEdit::editingFinished, - proxy, qOverload<>(&DialogueDelegateDispatcherProxy::editorDataCommited)); + connect(static_cast(editor), &CSVWidget::DropLineEdit::editingFinished, proxy, + qOverload<>(&DialogueDelegateDispatcherProxy::editorDataCommited)); connect(static_cast(editor), &CSVWidget::DropLineEdit::tableMimeDataDropped, - proxy, qOverload<>(&DialogueDelegateDispatcherProxy::editorDataCommited)); + proxy, qOverload<>(&DialogueDelegateDispatcherProxy::editorDataCommited)); } else if (qobject_cast(editor)) { - connect(static_cast(editor), &QCheckBox::stateChanged, - proxy, qOverload<>(&DialogueDelegateDispatcherProxy::editorDataCommited)); + connect(static_cast(editor), &QCheckBox::stateChanged, proxy, + qOverload<>(&DialogueDelegateDispatcherProxy::editorDataCommited)); } else if (qobject_cast(editor)) { connect(static_cast(editor), &QPlainTextEdit::textChanged, proxy, - qOverload<>(&DialogueDelegateDispatcherProxy::editorDataCommited)); + qOverload<>(&DialogueDelegateDispatcherProxy::editorDataCommited)); } else if (qobject_cast(editor)) { - connect(static_cast(editor), qOverload(&QComboBox::currentIndexChanged), - proxy, qOverload<>(&DialogueDelegateDispatcherProxy::editorDataCommited)); + connect(static_cast(editor), qOverload(&QComboBox::currentIndexChanged), proxy, + qOverload<>(&DialogueDelegateDispatcherProxy::editorDataCommited)); } else if (qobject_cast(editor) || qobject_cast(editor)) { - connect(static_cast(editor), &QAbstractSpinBox::editingFinished, - proxy, qOverload<>(&DialogueDelegateDispatcherProxy::editorDataCommited)); + connect(static_cast(editor), &QAbstractSpinBox::editingFinished, proxy, + qOverload<>(&DialogueDelegateDispatcherProxy::editorDataCommited)); } - else if (qobject_cast(editor)) + else if (qobject_cast(editor)) { - connect(static_cast(editor), &CSVWidget::ColorEditor::pickingFinished, - proxy, qOverload<>(&DialogueDelegateDispatcherProxy::editorDataCommited)); + connect(static_cast(editor), &CSVWidget::ColorEditor::pickingFinished, proxy, + qOverload<>(&DialogueDelegateDispatcherProxy::editorDataCommited)); } else // throw an exception because this is a coding error - throw std::logic_error ("Dialogue editor type missing"); + throw std::logic_error("Dialogue editor type missing"); - connect(proxy, qOverload(&DialogueDelegateDispatcherProxy::editorDataCommited), - this, &DialogueDelegateDispatcher::editorDataCommited); + connect(proxy, + qOverload( + &DialogueDelegateDispatcherProxy::editorDataCommited), + this, &DialogueDelegateDispatcher::editorDataCommited); - mProxys.push_back(proxy); //deleted in the destructor + mProxys.push_back(proxy); // deleted in the destructor } return editor; } @@ -316,29 +324,26 @@ CSVWorld::DialogueDelegateDispatcher::~DialogueDelegateDispatcher() { for (unsigned i = 0; i < mProxys.size(); ++i) { - delete mProxys[i]; //unique_ptr could be handy + delete mProxys[i]; // unique_ptr could be handy } } - -CSVWorld::IdContextMenu::IdContextMenu(QWidget *widget, CSMWorld::ColumnBase::Display display) - : QObject(widget), - mWidget(widget), - mIdType(CSMWorld::TableMimeData::convertEnums(display)) +CSVWorld::IdContextMenu::IdContextMenu(QWidget* widget, CSMWorld::ColumnBase::Display display) + : QObject(widget) + , mWidget(widget) + , mIdType(CSMWorld::TableMimeData::convertEnums(display)) { Q_ASSERT(mWidget != nullptr); Q_ASSERT(CSMWorld::ColumnBase::isId(display)); Q_ASSERT(mIdType != CSMWorld::UniversalId::Type_None); mWidget->setContextMenuPolicy(Qt::CustomContextMenu); - connect(mWidget, &QWidget::customContextMenuRequested, - this, &IdContextMenu::showContextMenu); + connect(mWidget, &QWidget::customContextMenuRequested, this, &IdContextMenu::showContextMenu); mEditIdAction = new QAction(this); - connect(mEditIdAction, &QAction::triggered, - this, qOverload<>(&IdContextMenu::editIdRequest)); + connect(mEditIdAction, &QAction::triggered, this, qOverload<>(&IdContextMenu::editIdRequest)); - QLineEdit *lineEdit = qobject_cast(mWidget); + QLineEdit* lineEdit = qobject_cast(mWidget); if (lineEdit != nullptr) { mContextMenu = lineEdit->createStandardContextMenu(); @@ -349,15 +354,15 @@ CSVWorld::IdContextMenu::IdContextMenu(QWidget *widget, CSMWorld::ColumnBase::Di } } -void CSVWorld::IdContextMenu::excludeId(const std::string &id) +void CSVWorld::IdContextMenu::excludeId(const std::string& id) { mExcludedIds.insert(id); } QString CSVWorld::IdContextMenu::getWidgetValue() const { - QLineEdit *lineEdit = qobject_cast(mWidget); - QLabel *label = qobject_cast(mWidget); + QLineEdit* lineEdit = qobject_cast(mWidget); + QLabel* label = qobject_cast(mWidget); QString value = ""; if (lineEdit != nullptr) @@ -371,7 +376,7 @@ QString CSVWorld::IdContextMenu::getWidgetValue() const return value; } -void CSVWorld::IdContextMenu::addEditIdActionToMenu(const QString &text) +void CSVWorld::IdContextMenu::addEditIdActionToMenu(const QString& text) { mEditIdAction->setText(text); if (mContextMenu->actions().isEmpty()) @@ -380,7 +385,7 @@ void CSVWorld::IdContextMenu::addEditIdActionToMenu(const QString &text) } else if (mContextMenu->actions().first() != mEditIdAction) { - QAction *action = mContextMenu->actions().first(); + QAction* action = mContextMenu->actions().first(); mContextMenu->insertAction(action, mEditIdAction); mContextMenu->insertSeparator(action); } @@ -403,7 +408,7 @@ void CSVWorld::IdContextMenu::removeEditIdActionFromMenu() } } -void CSVWorld::IdContextMenu::showContextMenu(const QPoint &pos) +void CSVWorld::IdContextMenu::showContextMenu(const QPoint& pos) { QString value = getWidgetValue(); bool isExcludedId = mExcludedIds.find(value.toUtf8().constData()) != mExcludedIds.end(); @@ -432,23 +437,22 @@ void CSVWorld::IdContextMenu::editIdRequest() =============================================================EditWidget===================================================== */ -void CSVWorld::EditWidget::createEditorContextMenu(QWidget *editor, - CSMWorld::ColumnBase::Display display, - int currentRow) const +void CSVWorld::EditWidget::createEditorContextMenu( + QWidget* editor, CSMWorld::ColumnBase::Display display, int currentRow) const { Q_ASSERT(editor != nullptr); - if (CSMWorld::ColumnBase::isId(display) && - CSMWorld::TableMimeData::convertEnums(display) != CSMWorld::UniversalId::Type_None) + if (CSMWorld::ColumnBase::isId(display) + && CSMWorld::TableMimeData::convertEnums(display) != CSMWorld::UniversalId::Type_None) { int idColumn = mTable->findColumnIndex(CSMWorld::Columns::ColumnId_Id); QString id = mTable->data(mTable->index(currentRow, idColumn)).toString(); - IdContextMenu *menu = new IdContextMenu(editor, display); + IdContextMenu* menu = new IdContextMenu(editor, display); // Current ID is already opened, so no need to create Edit 'ID' action for it menu->excludeId(id.toUtf8().constData()); - connect(menu, qOverload(&IdContextMenu::editIdRequest), - this, &EditWidget::editIdRequest); + connect(menu, qOverload(&IdContextMenu::editIdRequest), this, + &EditWidget::editIdRequest); } } @@ -464,30 +468,29 @@ CSVWorld::EditWidget::~EditWidget() delete mNestedTableDispatcher; } -CSVWorld::EditWidget::EditWidget(QWidget *parent, - int row, CSMWorld::IdTable* table, CSMWorld::CommandDispatcher& commandDispatcher, - CSMDoc::Document& document, bool createAndDelete) : -QScrollArea(parent), -mWidgetMapper(nullptr), -mNestedTableMapper(nullptr), -mDispatcher(nullptr), -mNestedTableDispatcher(nullptr), -mMainWidget(nullptr), -mTable(table), -mCommandDispatcher (commandDispatcher), -mDocument (document) +CSVWorld::EditWidget::EditWidget(QWidget* parent, int row, CSMWorld::IdTable* table, + CSMWorld::CommandDispatcher& commandDispatcher, CSMDoc::Document& document, bool createAndDelete) + : QScrollArea(parent) + , mWidgetMapper(nullptr) + , mNestedTableMapper(nullptr) + , mDispatcher(nullptr) + , mNestedTableDispatcher(nullptr) + , mMainWidget(nullptr) + , mTable(table) + , mCommandDispatcher(commandDispatcher) + , mDocument(document) { - remake (row); + remake(row); } void CSVWorld::EditWidget::remake(int row) { if (mMainWidget) { - QWidget *del = this->takeWidget(); + QWidget* del = this->takeWidget(); del->deleteLater(); } - mMainWidget = new QWidget (this); + mMainWidget = new QWidget(this); for (unsigned i = 0; i < mNestedModels.size(); ++i) delete mNestedModels[i]; @@ -496,23 +499,22 @@ void CSVWorld::EditWidget::remake(int row) if (mDispatcher) delete mDispatcher; - mDispatcher = new DialogueDelegateDispatcher(nullptr/*this*/, mTable, mCommandDispatcher, mDocument); + mDispatcher = new DialogueDelegateDispatcher(nullptr /*this*/, mTable, mCommandDispatcher, mDocument); if (mNestedTableDispatcher) delete mNestedTableDispatcher; - //not sure if widget mapper can handle deleting the widgets that were mapped + // not sure if widget mapper can handle deleting the widgets that were mapped if (mWidgetMapper) delete mWidgetMapper; - mWidgetMapper = new QDataWidgetMapper (this); + mWidgetMapper = new QDataWidgetMapper(this); mWidgetMapper->setModel(mTable); mWidgetMapper->setItemDelegate(mDispatcher); if (mNestedTableMapper) delete mNestedTableMapper; - QFrame* line = new QFrame(mMainWidget); line->setObjectName(QString::fromUtf8("line")); line->setGeometry(QRect(320, 150, 118, 3)); @@ -525,10 +527,10 @@ void CSVWorld::EditWidget::remake(int row) line2->setFrameShape(QFrame::HLine); line2->setFrameShadow(QFrame::Sunken); - QVBoxLayout *mainLayout = new QVBoxLayout(mMainWidget); - QGridLayout *lockedLayout = new QGridLayout(); - QGridLayout *unlockedLayout = new QGridLayout(); - QVBoxLayout *tablesLayout = new QVBoxLayout(); + QVBoxLayout* mainLayout = new QVBoxLayout(mMainWidget); + QGridLayout* lockedLayout = new QGridLayout(); + QGridLayout* unlockedLayout = new QGridLayout(); + QVBoxLayout* tablesLayout = new QVBoxLayout(); mainLayout->addLayout(lockedLayout, QSizePolicy::Fixed); mainLayout->addWidget(line, 1); @@ -544,46 +546,47 @@ void CSVWorld::EditWidget::remake(int row) int locked = 0; const int columns = mTable->columnCount(); - for (int i=0; iheaderData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Flags).toInt(); + int flags = mTable->headerData(i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Flags).toInt(); if (flags & CSMWorld::ColumnBase::Flag_Dialogue) { - CSMWorld::ColumnBase::Display display = static_cast - (mTable->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); + CSMWorld::ColumnBase::Display display = static_cast( + mTable->headerData(i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); - if (mTable->hasChildren(mTable->index(row, i)) && - !(flags & CSMWorld::ColumnBase::Flag_Dialogue_List)) + if (mTable->hasChildren(mTable->index(row, i)) && !(flags & CSMWorld::ColumnBase::Flag_Dialogue_List)) { CSMWorld::IdTree* innerTable = &dynamic_cast(*mTable); - mNestedModels.push_back(new CSMWorld::NestedTableProxyModel (mTable->index(row, i), display, innerTable)); + mNestedModels.push_back( + new CSMWorld::NestedTableProxyModel(mTable->index(row, i), display, innerTable)); - int idColumn = mTable->findColumnIndex (CSMWorld::Columns::ColumnId_Id); - int typeColumn = mTable->findColumnIndex (CSMWorld::Columns::ColumnId_RecordType); + int idColumn = mTable->findColumnIndex(CSMWorld::Columns::ColumnId_Id); + int typeColumn = mTable->findColumnIndex(CSMWorld::Columns::ColumnId_RecordType); CSMWorld::UniversalId id = CSMWorld::UniversalId( - static_cast (mTable->data (mTable->index (row, typeColumn)).toInt()), - mTable->data (mTable->index (row, idColumn)).toString().toUtf8().constData()); + static_cast(mTable->data(mTable->index(row, typeColumn)).toInt()), + mTable->data(mTable->index(row, idColumn)).toString().toUtf8().constData()); bool editable = true; bool fixedRows = false; QVariant v = mTable->index(row, i).data(); if (v.canConvert()) { - assert (QString(v.typeName()) == "CSMWorld::ColumnBase::TableEditModes"); + assert(QString(v.typeName()) == "CSMWorld::ColumnBase::TableEditModes"); if (v.value() == CSMWorld::ColumnBase::TableEdit_None) editable = false; - else if (v.value() == CSMWorld::ColumnBase::TableEdit_FixedRows) + else if (v.value() + == CSMWorld::ColumnBase::TableEdit_FixedRows) fixedRows = true; } // Create and display nested table only if it's editable. if (editable) { - NestedTable* table = - new NestedTable(mDocument, id, mNestedModels.back(), this, editable, fixedRows); + NestedTable* table + = new NestedTable(mDocument, id, mNestedModels.back(), this, editable, fixedRows); table->resizeColumnsToContents(); if (isBlocked) table->setEditTriggers(QAbstractItemView::NoEditTriggers); @@ -594,47 +597,46 @@ void CSVWorld::EditWidget::remake(int row) int tableMaxHeight = (5 * rowHeight) + headerHeight + (2 * table->frameWidth()); table->setMinimumHeight(tableMaxHeight); - QString headerText = mTable->headerData (i, Qt::Horizontal, Qt::DisplayRole).toString(); - QLabel* label = new QLabel (headerText, mMainWidget); - label->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed); + QString headerText = mTable->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString(); + QLabel* label = new QLabel(headerText, mMainWidget); + label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); tablesLayout->addWidget(label); tablesLayout->addWidget(table); - connect(table, &NestedTable::editRequest, - this, &EditWidget::editIdRequest); + connect(table, &NestedTable::editRequest, this, &EditWidget::editIdRequest); } } else if (!(flags & CSMWorld::ColumnBase::Flag_Dialogue_List)) { - mDispatcher->makeDelegate (display); - QWidget* editor = mDispatcher->makeEditor (display, (mTable->index (row, i))); + mDispatcher->makeDelegate(display); + QWidget* editor = mDispatcher->makeEditor(display, (mTable->index(row, i))); if (editor) { - mWidgetMapper->addMapping (editor, i); + mWidgetMapper->addMapping(editor, i); - QLabel* label = new QLabel (mTable->headerData (i, Qt::Horizontal).toString(), mMainWidget); + QLabel* label = new QLabel(mTable->headerData(i, Qt::Horizontal).toString(), mMainWidget); - label->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed); - editor->setSizePolicy (QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); + label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + editor->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); // HACK: the blocked checkbox needs to keep the same position // FIXME: unfortunately blocked record displays a little differently to unblocked one - if (!(mTable->flags (mTable->index (row, i)) & Qt::ItemIsEditable) || i == blockedColumn) + if (!(mTable->flags(mTable->index(row, i)) & Qt::ItemIsEditable) || i == blockedColumn) { - lockedLayout->addWidget (label, locked, 0); - lockedLayout->addWidget (editor, locked, 1); + lockedLayout->addWidget(label, locked, 0); + lockedLayout->addWidget(editor, locked, 1); ++locked; } else { - unlockedLayout->addWidget (label, unlocked, 0); - unlockedLayout->addWidget (editor, unlocked, 1); + unlockedLayout->addWidget(label, unlocked, 0); + unlockedLayout->addWidget(editor, unlocked, 1); ++unlocked; } - if(mTable->index(row, i).data().type() == QVariant::UserType) + if (mTable->index(row, i).data().type() == QVariant::UserType) { editor->setEnabled(false); label->setEnabled(false); @@ -645,46 +647,46 @@ void CSVWorld::EditWidget::remake(int row) } else // Flag_Dialogue_List { - CSMWorld::IdTree *tree = static_cast(mTable); - mNestedTableMapper = new QDataWidgetMapper (this); + CSMWorld::IdTree* tree = static_cast(mTable); + mNestedTableMapper = new QDataWidgetMapper(this); mNestedTableMapper->setModel(tree); // FIXME: lack MIME support? - mNestedTableDispatcher = - new DialogueDelegateDispatcher (nullptr/*this*/, mTable, mCommandDispatcher, mDocument, tree); - mNestedTableMapper->setRootIndex (tree->index(row, i)); + mNestedTableDispatcher + = new DialogueDelegateDispatcher(nullptr /*this*/, mTable, mCommandDispatcher, mDocument, tree); + mNestedTableMapper->setRootIndex(tree->index(row, i)); mNestedTableMapper->setItemDelegate(mNestedTableDispatcher); int columnCount = tree->columnCount(tree->index(row, i)); for (int col = 0; col < columnCount; ++col) { - int displayRole = tree->nestedHeaderData (i, col, - Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt(); + int displayRole + = tree->nestedHeaderData(i, col, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt(); - display = static_cast (displayRole); + display = static_cast(displayRole); - mNestedTableDispatcher->makeDelegate (display); + mNestedTableDispatcher->makeDelegate(display); // FIXME: assumed all columns are editable - QWidget* editor = - mNestedTableDispatcher->makeEditor (display, tree->index (0, col, tree->index(row, i))); + QWidget* editor + = mNestedTableDispatcher->makeEditor(display, tree->index(0, col, tree->index(row, i))); if (editor) { - mNestedTableMapper->addMapping (editor, col); + mNestedTableMapper->addMapping(editor, col); // Need to use Qt::DisplayRole in order to get the correct string // from CSMWorld::Columns - QLabel* label = new QLabel (tree->nestedHeaderData (i, col, - Qt::Horizontal, Qt::DisplayRole).toString(), mMainWidget); + QLabel* label = new QLabel( + tree->nestedHeaderData(i, col, Qt::Horizontal, Qt::DisplayRole).toString(), mMainWidget); - label->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed); - editor->setSizePolicy (QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); + label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + editor->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - unlockedLayout->addWidget (label, unlocked, 0); - unlockedLayout->addWidget (editor, unlocked, 1); + unlockedLayout->addWidget(label, unlocked, 0); + unlockedLayout->addWidget(editor, unlocked, 1); ++unlocked; - if(tree->index(0, col, tree->index(row, i)).data().type() == QVariant::UserType) + if (tree->index(0, col, tree->index(row, i)).data().type() == QVariant::UserType) { editor->setEnabled(false); label->setEnabled(false); @@ -710,7 +712,6 @@ void CSVWorld::EditWidget::remake(int row) this->setWidgetResizable(true); } - QVBoxLayout& CSVWorld::SimpleDialogueSubView::getMainLayout() { return *mMainLayout; @@ -736,96 +737,96 @@ bool CSVWorld::SimpleDialogueSubView::isLocked() const return mLocked; } -CSVWorld::SimpleDialogueSubView::SimpleDialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) : - SubView (id), - mEditWidget(nullptr), - mMainLayout(nullptr), - mTable(dynamic_cast(document.getData().getTableModel(id))), - mLocked(false), - mDocument(document), - mCommandDispatcher (document, CSMWorld::UniversalId::getParentType (id.getType())) +CSVWorld::SimpleDialogueSubView::SimpleDialogueSubView(const CSMWorld::UniversalId& id, CSMDoc::Document& document) + : SubView(id) + , mEditWidget(nullptr) + , mMainLayout(nullptr) + , mTable(dynamic_cast(document.getData().getTableModel(id))) + , mLocked(false) + , mDocument(document) + , mCommandDispatcher(document, CSMWorld::UniversalId::getParentType(id.getType())) { connect(mTable, &CSMWorld::IdTable::dataChanged, this, &SimpleDialogueSubView::dataChanged); connect(mTable, &CSMWorld::IdTable::rowsAboutToBeRemoved, this, &SimpleDialogueSubView::rowsAboutToBeRemoved); updateCurrentId(); - QWidget *mainWidget = new QWidget(this); + QWidget* mainWidget = new QWidget(this); mMainLayout = new QVBoxLayout(mainWidget); - setWidget (mainWidget); + setWidget(mainWidget); - int idColumn = getTable().findColumnIndex (CSMWorld::Columns::ColumnId_Id); + int idColumn = getTable().findColumnIndex(CSMWorld::Columns::ColumnId_Id); - mEditWidget = new EditWidget(mainWidget, - mTable->getModelIndex(getUniversalId().getId(), idColumn).row(), mTable, mCommandDispatcher, document, false); + mEditWidget = new EditWidget(mainWidget, mTable->getModelIndex(getUniversalId().getId(), idColumn).row(), mTable, + mCommandDispatcher, document, false); mMainLayout->addWidget(mEditWidget); mEditWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); - dataChanged(mTable->getModelIndex (getUniversalId().getId(), idColumn)); + dataChanged(mTable->getModelIndex(getUniversalId().getId(), idColumn)); - connect(mEditWidget, &EditWidget::editIdRequest, - this, &SimpleDialogueSubView::focusId); + connect(mEditWidget, &EditWidget::editIdRequest, this, &SimpleDialogueSubView::focusId); } -void CSVWorld::SimpleDialogueSubView::setEditLock (bool locked) +void CSVWorld::SimpleDialogueSubView::setEditLock(bool locked) { if (!mEditWidget) // hack to indicate that getUniversalId().getId() is no longer valid return; - int idColumn = getTable().findColumnIndex (CSMWorld::Columns::ColumnId_Id); + int idColumn = getTable().findColumnIndex(CSMWorld::Columns::ColumnId_Id); mLocked = locked; QModelIndex currentIndex(mTable->getModelIndex(getUniversalId().getId(), idColumn)); if (currentIndex.isValid()) { - CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (currentIndex.row(), 1)).toInt()); + CSMWorld::RecordBase::State state + = static_cast(mTable->data(mTable->index(currentIndex.row(), 1)).toInt()); - mEditWidget->setDisabled (state==CSMWorld::RecordBase::State_Deleted || locked); + mEditWidget->setDisabled(state == CSMWorld::RecordBase::State_Deleted || locked); - mCommandDispatcher.setEditLock (locked); + mCommandDispatcher.setEditLock(locked); } - } -void CSVWorld::SimpleDialogueSubView::dataChanged (const QModelIndex & index) +void CSVWorld::SimpleDialogueSubView::dataChanged(const QModelIndex& index) { - int idColumn = getTable().findColumnIndex (CSMWorld::Columns::ColumnId_Id); + int idColumn = getTable().findColumnIndex(CSMWorld::Columns::ColumnId_Id); QModelIndex currentIndex(mTable->getModelIndex(getUniversalId().getId(), idColumn)); - if (currentIndex.isValid() && - (index.parent().isValid() ? index.parent().row() : index.row()) == currentIndex.row()) + if (currentIndex.isValid() && (index.parent().isValid() ? index.parent().row() : index.row()) == currentIndex.row()) { - CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (currentIndex.row(), 1)).toInt()); + CSMWorld::RecordBase::State state + = static_cast(mTable->data(mTable->index(currentIndex.row(), 1)).toInt()); - mEditWidget->setDisabled (state==CSMWorld::RecordBase::State_Deleted || mLocked); + mEditWidget->setDisabled(state == CSMWorld::RecordBase::State_Deleted || mLocked); // Check if the changed data should force refresh (rebuild) the dialogue subview int flags = 0; if (index.parent().isValid()) // TODO: check that index is topLeft { - flags = static_cast(mTable)->nestedHeaderData (index.parent().column(), - index.column(), Qt::Horizontal, CSMWorld::ColumnBase::Role_Flags).toInt(); + flags = static_cast(mTable) + ->nestedHeaderData( + index.parent().column(), index.column(), Qt::Horizontal, CSMWorld::ColumnBase::Role_Flags) + .toInt(); } else { - flags = mTable->headerData (index.column(), - Qt::Horizontal, CSMWorld::ColumnBase::Role_Flags).toInt(); + flags = mTable->headerData(index.column(), Qt::Horizontal, CSMWorld::ColumnBase::Role_Flags).toInt(); } if (flags & CSMWorld::ColumnBase::Flag_Dialogue_Refresh) { int y = mEditWidget->verticalScrollBar()->value(); - mEditWidget->remake (index.parent().isValid() ? index.parent().row() : index.row()); + mEditWidget->remake(index.parent().isValid() ? index.parent().row() : index.row()); mEditWidget->verticalScrollBar()->setValue(y); } } } -void CSVWorld::SimpleDialogueSubView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) +void CSVWorld::SimpleDialogueSubView::rowsAboutToBeRemoved(const QModelIndex& parent, int start, int end) { - int idColumn = getTable().findColumnIndex (CSMWorld::Columns::ColumnId_Id); + int idColumn = getTable().findColumnIndex(CSMWorld::Columns::ColumnId_Id); QModelIndex currentIndex(mTable->getModelIndex(getUniversalId().getId(), idColumn)); if (!currentIndex.isValid()) @@ -835,7 +836,7 @@ void CSVWorld::SimpleDialogueSubView::rowsAboutToBeRemoved(const QModelIndex &pa if (currentIndex.parent() == parent && currentIndex.row() >= start && currentIndex.row() <= end) { - if(mEditWidget) + if (mEditWidget) { delete mEditWidget; mEditWidget = nullptr; @@ -847,58 +848,55 @@ void CSVWorld::SimpleDialogueSubView::rowsAboutToBeRemoved(const QModelIndex &pa void CSVWorld::SimpleDialogueSubView::updateCurrentId() { std::vector selection; - selection.push_back (getUniversalId().getId()); + selection.push_back(getUniversalId().getId()); mCommandDispatcher.setSelection(selection); } - void CSVWorld::DialogueSubView::addButtonBar() { if (mButtons) return; - mButtons = new RecordButtonBar (getUniversalId(), getTable(), mBottom, - &getCommandDispatcher(), this); + mButtons = new RecordButtonBar(getUniversalId(), getTable(), mBottom, &getCommandDispatcher(), this); - getMainLayout().insertWidget (1, mButtons); + getMainLayout().insertWidget(1, mButtons); // connections - connect (mButtons, &RecordButtonBar::showPreview, this, &DialogueSubView::showPreview); - connect (mButtons, &RecordButtonBar::viewRecord, this, &DialogueSubView::viewRecord); - connect (mButtons, &RecordButtonBar::switchToRow, this, &DialogueSubView::switchToRow); + connect(mButtons, &RecordButtonBar::showPreview, this, &DialogueSubView::showPreview); + connect(mButtons, &RecordButtonBar::viewRecord, this, &DialogueSubView::viewRecord); + connect(mButtons, &RecordButtonBar::switchToRow, this, &DialogueSubView::switchToRow); - connect (this, &DialogueSubView::universalIdChanged, - mButtons, &RecordButtonBar::universalIdChanged); + connect(this, &DialogueSubView::universalIdChanged, mButtons, &RecordButtonBar::universalIdChanged); } -CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, - CSMDoc::Document& document, const CreatorFactoryBase& creatorFactory, bool sorting) -: SimpleDialogueSubView (id, document), mButtons (nullptr) +CSVWorld::DialogueSubView::DialogueSubView( + const CSMWorld::UniversalId& id, CSMDoc::Document& document, const CreatorFactoryBase& creatorFactory, bool sorting) + : SimpleDialogueSubView(id, document) + , mButtons(nullptr) { // bottom box - mBottom = new TableBottomBox (creatorFactory, document, id, this); + mBottom = new TableBottomBox(creatorFactory, document, id, this); - connect (mBottom, &TableBottomBox::requestFocus, this, &DialogueSubView::requestFocus); + connect(mBottom, &TableBottomBox::requestFocus, this, &DialogueSubView::requestFocus); // layout - getMainLayout().addWidget (mBottom); + getMainLayout().addWidget(mBottom); - connect (&CSMPrefs::State::get(), &CSMPrefs::State::settingChanged, - this, &DialogueSubView::settingChanged); + connect(&CSMPrefs::State::get(), &CSMPrefs::State::settingChanged, this, &DialogueSubView::settingChanged); CSMPrefs::get()["ID Dialogues"].update(); } -void CSVWorld::DialogueSubView::setEditLock (bool locked) +void CSVWorld::DialogueSubView::setEditLock(bool locked) { - SimpleDialogueSubView::setEditLock (locked); + SimpleDialogueSubView::setEditLock(locked); if (mButtons) - mButtons->setEditLock (locked); + mButtons->setEditLock(locked); } -void CSVWorld::DialogueSubView::settingChanged (const CSMPrefs::Setting *setting) +void CSVWorld::DialogueSubView::settingChanged(const CSMPrefs::Setting* setting) { - if (*setting=="ID Dialogues/toolbar") + if (*setting == "ID Dialogues/toolbar") { if (setting->isTrue()) { @@ -906,67 +904,65 @@ void CSVWorld::DialogueSubView::settingChanged (const CSMPrefs::Setting *setting } else if (mButtons) { - getMainLayout().removeWidget (mButtons); + getMainLayout().removeWidget(mButtons); delete mButtons; mButtons = nullptr; } } } -void CSVWorld::DialogueSubView::showPreview () +void CSVWorld::DialogueSubView::showPreview() { - int idColumn = getTable().findColumnIndex (CSMWorld::Columns::ColumnId_Id); - QModelIndex currentIndex (getTable().getModelIndex (getUniversalId().getId(), idColumn)); + int idColumn = getTable().findColumnIndex(CSMWorld::Columns::ColumnId_Id); + QModelIndex currentIndex(getTable().getModelIndex(getUniversalId().getId(), idColumn)); - if (currentIndex.isValid() && - getTable().getFeatures() & CSMWorld::IdTable::Feature_Preview && - currentIndex.row() < getTable().rowCount()) + if (currentIndex.isValid() && getTable().getFeatures() & CSMWorld::IdTable::Feature_Preview + && currentIndex.row() < getTable().rowCount()) { emit focusId(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Preview, getUniversalId().getId()), ""); } } -void CSVWorld::DialogueSubView::viewRecord () +void CSVWorld::DialogueSubView::viewRecord() { - int idColumn = getTable().findColumnIndex (CSMWorld::Columns::ColumnId_Id); - QModelIndex currentIndex (getTable().getModelIndex (getUniversalId().getId(), idColumn)); + int idColumn = getTable().findColumnIndex(CSMWorld::Columns::ColumnId_Id); + QModelIndex currentIndex(getTable().getModelIndex(getUniversalId().getId(), idColumn)); - if (currentIndex.isValid() && - currentIndex.row() < getTable().rowCount()) + if (currentIndex.isValid() && currentIndex.row() < getTable().rowCount()) { - std::pair params = getTable().view (currentIndex.row()); + std::pair params = getTable().view(currentIndex.row()); - if (params.first.getType()!=CSMWorld::UniversalId::Type_None) - emit focusId (params.first, params.second); + if (params.first.getType() != CSMWorld::UniversalId::Type_None) + emit focusId(params.first, params.second); } } -void CSVWorld::DialogueSubView::switchToRow (int row) +void CSVWorld::DialogueSubView::switchToRow(int row) { - int idColumn = getTable().findColumnIndex (CSMWorld::Columns::ColumnId_Id); - std::string id = getTable().data (getTable().index (row, idColumn)).toString().toUtf8().constData(); + int idColumn = getTable().findColumnIndex(CSMWorld::Columns::ColumnId_Id); + std::string id = getTable().data(getTable().index(row, idColumn)).toString().toUtf8().constData(); - int typeColumn = getTable().findColumnIndex (CSMWorld::Columns::ColumnId_RecordType); - CSMWorld::UniversalId::Type type = static_cast ( - getTable().data (getTable().index (row, typeColumn)).toInt()); + int typeColumn = getTable().findColumnIndex(CSMWorld::Columns::ColumnId_RecordType); + CSMWorld::UniversalId::Type type + = static_cast(getTable().data(getTable().index(row, typeColumn)).toInt()); - setUniversalId (CSMWorld::UniversalId (type, id)); + setUniversalId(CSMWorld::UniversalId(type, id)); updateCurrentId(); - getEditWidget().remake (row); + getEditWidget().remake(row); - int stateColumn = getTable().findColumnIndex (CSMWorld::Columns::ColumnId_Modification); - CSMWorld::RecordBase::State state = static_cast ( - getTable().data (getTable().index (row, stateColumn)).toInt()); + int stateColumn = getTable().findColumnIndex(CSMWorld::Columns::ColumnId_Modification); + CSMWorld::RecordBase::State state + = static_cast(getTable().data(getTable().index(row, stateColumn)).toInt()); - getEditWidget().setDisabled (isLocked() || state==CSMWorld::RecordBase::State_Deleted); + getEditWidget().setDisabled(isLocked() || state == CSMWorld::RecordBase::State_Deleted); } -void CSVWorld::DialogueSubView::requestFocus (const std::string& id) +void CSVWorld::DialogueSubView::requestFocus(const std::string& id) { - int idColumn = getTable().findColumnIndex (CSMWorld::Columns::ColumnId_Id); - QModelIndex index = getTable().getModelIndex (id, idColumn); + int idColumn = getTable().findColumnIndex(CSMWorld::Columns::ColumnId_Id); + QModelIndex index = getTable().getModelIndex(id, idColumn); if (index.isValid()) - switchToRow (index.row()); + switchToRow(index.row()); } diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index 2cf05f711e..598f701f91 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -1,9 +1,9 @@ #ifndef CSV_WORLD_DIALOGUESUBVIEW_H #define CSV_WORLD_DIALOGUESUBVIEW_H -#include #include #include +#include #include #include @@ -48,29 +48,25 @@ namespace CSVWorld class NotEditableSubDelegate : public QAbstractItemDelegate { const CSMWorld::IdTable* mTable; + public: - NotEditableSubDelegate(const CSMWorld::IdTable* table, - QObject * parent = nullptr); + NotEditableSubDelegate(const CSMWorld::IdTable* table, QObject* parent = nullptr); - void setEditorData (QWidget* editor, const QModelIndex& index) const override; + void setEditorData(QWidget* editor, const QModelIndex& index) const override; - void setModelData (QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const override; + void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const override; - void paint (QPainter* painter, - const QStyleOptionViewItem& option, - const QModelIndex& index) const override; + void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override; ///< does nothing - QSize sizeHint (const QStyleOptionViewItem& option, - const QModelIndex& index) const override; + QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override; ///< does nothing - QWidget *createEditor (QWidget *parent, - const QStyleOptionViewItem& option, - const QModelIndex& index) const override; + QWidget* createEditor( + QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override; }; - //this can't be nested into the DialogueDelegateDispatcher, because it needs to emit signals + // this can't be nested into the DialogueDelegateDispatcher, because it needs to emit signals class DialogueDelegateDispatcherProxy : public QObject { Q_OBJECT @@ -89,8 +85,7 @@ namespace CSVWorld std::unique_ptr mIndexWrapper; public: - DialogueDelegateDispatcherProxy(QWidget* editor, - CSMWorld::ColumnBase::Display display); + DialogueDelegateDispatcherProxy(QWidget* editor, CSMWorld::ColumnBase::Display display); QWidget* getEditor() const; public slots: @@ -98,10 +93,7 @@ namespace CSVWorld void setIndex(const QModelIndex& index); signals: - void editorDataCommited(QWidget* editor, - const QModelIndex& index, - CSMWorld::ColumnBase::Display display); - + void editorDataCommited(QWidget* editor, const QModelIndex& index, CSMWorld::ColumnBase::Display display); }; class DialogueDelegateDispatcher : public QAbstractItemDelegate @@ -119,14 +111,12 @@ namespace CSVWorld NotEditableSubDelegate mNotEditableDelegate; std::vector mProxys; - //once we move to the C++11 we should use unique_ptr + // once we move to the C++11 we should use unique_ptr public: - DialogueDelegateDispatcher(QObject* parent, - CSMWorld::IdTable* table, - CSMWorld::CommandDispatcher& commandDispatcher, - CSMDoc::Document& document, - QAbstractItemModel* model = nullptr); + DialogueDelegateDispatcher(QObject* parent, CSMWorld::IdTable* table, + CSMWorld::CommandDispatcher& commandDispatcher, CSMDoc::Document& document, + QAbstractItemModel* model = nullptr); ~DialogueDelegateDispatcher(); @@ -134,161 +124,148 @@ namespace CSVWorld QWidget* makeEditor(CSMWorld::ColumnBase::Display display, const QModelIndex& index); ///< will return null if delegate is not present, parent of the widget is - //same as for dispatcher itself + // same as for dispatcher itself - void setEditorData (QWidget* editor, const QModelIndex& index) const override; + void setEditorData(QWidget* editor, const QModelIndex& index) const override; - void setModelData (QWidget* editor, QAbstractItemModel* model, - const QModelIndex& index) const override; + void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const override; - virtual void setModelData (QWidget* editor, - QAbstractItemModel* model, const QModelIndex& index, - CSMWorld::ColumnBase::Display display) const; + virtual void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index, + CSMWorld::ColumnBase::Display display) const; - void paint (QPainter* painter, - const QStyleOptionViewItem& option, - const QModelIndex& index) const override; + void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override; ///< does nothing - QSize sizeHint (const QStyleOptionViewItem& option, - const QModelIndex& index) const override; + QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override; ///< does nothing private slots: - void editorDataCommited(QWidget* editor, const QModelIndex& index, - CSMWorld::ColumnBase::Display display); + void editorDataCommited(QWidget* editor, const QModelIndex& index, CSMWorld::ColumnBase::Display display); }; /// A context menu with "Edit 'ID'" action for editors in the dialogue subview class IdContextMenu : public QObject { - Q_OBJECT + Q_OBJECT - QWidget *mWidget; - CSMWorld::UniversalId::Type mIdType; - std::set mExcludedIds; - ///< A list of IDs that should not have the Edit 'ID' action. + QWidget* mWidget; + CSMWorld::UniversalId::Type mIdType; + std::set mExcludedIds; + ///< A list of IDs that should not have the Edit 'ID' action. - QMenu *mContextMenu; - QAction *mEditIdAction; + QMenu* mContextMenu; + QAction* mEditIdAction; - QString getWidgetValue() const; - void addEditIdActionToMenu(const QString &text); - void removeEditIdActionFromMenu(); + QString getWidgetValue() const; + void addEditIdActionToMenu(const QString& text); + void removeEditIdActionFromMenu(); - public: - IdContextMenu(QWidget *widget, CSMWorld::ColumnBase::Display display); + public: + IdContextMenu(QWidget* widget, CSMWorld::ColumnBase::Display display); - void excludeId(const std::string &id); + void excludeId(const std::string& id); - private slots: - void showContextMenu(const QPoint &pos); - void editIdRequest(); + private slots: + void showContextMenu(const QPoint& pos); + void editIdRequest(); - signals: - void editIdRequest(const CSMWorld::UniversalId &id, const std::string &hint); + signals: + void editIdRequest(const CSMWorld::UniversalId& id, const std::string& hint); }; class EditWidget : public QScrollArea { Q_OBJECT - QDataWidgetMapper *mWidgetMapper; - QDataWidgetMapper *mNestedTableMapper; - DialogueDelegateDispatcher *mDispatcher; - DialogueDelegateDispatcher *mNestedTableDispatcher; - QWidget* mMainWidget; - CSMWorld::IdTable* mTable; - CSMWorld::CommandDispatcher& mCommandDispatcher; - CSMDoc::Document& mDocument; - std::vector mNestedModels; //Plain, raw C pointers, deleted in the dtor - - void createEditorContextMenu(QWidget *editor, - CSMWorld::ColumnBase::Display display, - int currentRow) const; - public: + QDataWidgetMapper* mWidgetMapper; + QDataWidgetMapper* mNestedTableMapper; + DialogueDelegateDispatcher* mDispatcher; + DialogueDelegateDispatcher* mNestedTableDispatcher; + QWidget* mMainWidget; + CSMWorld::IdTable* mTable; + CSMWorld::CommandDispatcher& mCommandDispatcher; + CSMDoc::Document& mDocument; + std::vector mNestedModels; // Plain, raw C pointers, deleted in the dtor + + void createEditorContextMenu(QWidget* editor, CSMWorld::ColumnBase::Display display, int currentRow) const; - EditWidget (QWidget *parent, int row, CSMWorld::IdTable* table, - CSMWorld::CommandDispatcher& commandDispatcher, - CSMDoc::Document& document, bool createAndDelete = false); + public: + EditWidget(QWidget* parent, int row, CSMWorld::IdTable* table, CSMWorld::CommandDispatcher& commandDispatcher, + CSMDoc::Document& document, bool createAndDelete = false); - virtual ~EditWidget(); + virtual ~EditWidget(); - void remake(int row); + void remake(int row); - signals: - void editIdRequest(const CSMWorld::UniversalId &id, const std::string &hint); + signals: + void editIdRequest(const CSMWorld::UniversalId& id, const std::string& hint); }; class SimpleDialogueSubView : public CSVDoc::SubView { - Q_OBJECT - - EditWidget* mEditWidget; - QVBoxLayout* mMainLayout; - CSMWorld::IdTable* mTable; - bool mLocked; - const CSMDoc::Document& mDocument; - CSMWorld::CommandDispatcher mCommandDispatcher; + Q_OBJECT - protected: + EditWidget* mEditWidget; + QVBoxLayout* mMainLayout; + CSMWorld::IdTable* mTable; + bool mLocked; + const CSMDoc::Document& mDocument; + CSMWorld::CommandDispatcher mCommandDispatcher; - QVBoxLayout& getMainLayout(); + protected: + QVBoxLayout& getMainLayout(); - CSMWorld::IdTable& getTable(); + CSMWorld::IdTable& getTable(); - CSMWorld::CommandDispatcher& getCommandDispatcher(); + CSMWorld::CommandDispatcher& getCommandDispatcher(); - EditWidget& getEditWidget(); + EditWidget& getEditWidget(); - void updateCurrentId(); + void updateCurrentId(); - bool isLocked() const; + bool isLocked() const; - public: - - SimpleDialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document); + public: + SimpleDialogueSubView(const CSMWorld::UniversalId& id, CSMDoc::Document& document); - void setEditLock (bool locked) override; + void setEditLock(bool locked) override; - private slots: + private slots: - void dataChanged(const QModelIndex & index); - ///\brief we need to care for deleting currently edited record + void dataChanged(const QModelIndex& index); + ///\brief we need to care for deleting currently edited record - void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end); + void rowsAboutToBeRemoved(const QModelIndex& parent, int start, int end); }; class RecordButtonBar; class DialogueSubView : public SimpleDialogueSubView { - Q_OBJECT - - TableBottomBox* mBottom; - RecordButtonBar *mButtons; - - private: + Q_OBJECT - void addButtonBar(); + TableBottomBox* mBottom; + RecordButtonBar* mButtons; - public: + private: + void addButtonBar(); - DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, - const CreatorFactoryBase& creatorFactory, bool sorting = false); + public: + DialogueSubView(const CSMWorld::UniversalId& id, CSMDoc::Document& document, + const CreatorFactoryBase& creatorFactory, bool sorting = false); - void setEditLock (bool locked) override; + void setEditLock(bool locked) override; - private slots: + private slots: - void settingChanged (const CSMPrefs::Setting *setting); + void settingChanged(const CSMPrefs::Setting* setting); - void showPreview(); + void showPreview(); - void viewRecord(); + void viewRecord(); - void switchToRow (int row); + void switchToRow(int row); - void requestFocus (const std::string& id); + void requestFocus(const std::string& id); }; } diff --git a/apps/opencs/view/world/dragdroputils.cpp b/apps/opencs/view/world/dragdroputils.cpp index bb4d972737..819f6fadc3 100644 --- a/apps/opencs/view/world/dragdroputils.cpp +++ b/apps/opencs/view/world/dragdroputils.cpp @@ -4,31 +4,31 @@ #include "../../model/world/tablemimedata.hpp" -const CSMWorld::TableMimeData *CSVWorld::DragDropUtils::getTableMimeData(const QDropEvent &event) +const CSMWorld::TableMimeData* CSVWorld::DragDropUtils::getTableMimeData(const QDropEvent& event) { - return dynamic_cast(event.mimeData()); + return dynamic_cast(event.mimeData()); } -bool CSVWorld::DragDropUtils::canAcceptData(const QDropEvent &event, CSMWorld::ColumnBase::Display type) +bool CSVWorld::DragDropUtils::canAcceptData(const QDropEvent& event, CSMWorld::ColumnBase::Display type) { - const CSMWorld::TableMimeData *data = getTableMimeData(event); + const CSMWorld::TableMimeData* data = getTableMimeData(event); return data != nullptr && data->holdsType(type); } -bool CSVWorld::DragDropUtils::isInfo(const QDropEvent &event, CSMWorld::ColumnBase::Display type) +bool CSVWorld::DragDropUtils::isInfo(const QDropEvent& event, CSMWorld::ColumnBase::Display type) { - const CSMWorld::TableMimeData *data = getTableMimeData(event); - return data != nullptr && ( - data->holdsType(CSMWorld::UniversalId::Type_TopicInfo) || - data->holdsType(CSMWorld::UniversalId::Type_JournalInfo) ); + const CSMWorld::TableMimeData* data = getTableMimeData(event); + return data != nullptr + && (data->holdsType(CSMWorld::UniversalId::Type_TopicInfo) + || data->holdsType(CSMWorld::UniversalId::Type_JournalInfo)); } -CSMWorld::UniversalId CSVWorld::DragDropUtils::getAcceptedData(const QDropEvent &event, - CSMWorld::ColumnBase::Display type) +CSMWorld::UniversalId CSVWorld::DragDropUtils::getAcceptedData( + const QDropEvent& event, CSMWorld::ColumnBase::Display type) { if (canAcceptData(event, type)) { - if (const CSMWorld::TableMimeData *data = getTableMimeData(event)) + if (const CSMWorld::TableMimeData* data = getTableMimeData(event)) return data->returnMatching(type); } return CSMWorld::UniversalId::Type_None; diff --git a/apps/opencs/view/world/dragdroputils.hpp b/apps/opencs/view/world/dragdroputils.hpp index 2181e7606b..ab27198f71 100644 --- a/apps/opencs/view/world/dragdroputils.hpp +++ b/apps/opencs/view/world/dragdroputils.hpp @@ -15,15 +15,15 @@ namespace CSVWorld { namespace DragDropUtils { - const CSMWorld::TableMimeData *getTableMimeData(const QDropEvent &event); + const CSMWorld::TableMimeData* getTableMimeData(const QDropEvent& event); - bool canAcceptData(const QDropEvent &event, CSMWorld::ColumnBase::Display type); + bool canAcceptData(const QDropEvent& event, CSMWorld::ColumnBase::Display type); ///< Checks whether the \a event contains a valid CSMWorld::TableMimeData that holds the \a type - bool isInfo(const QDropEvent &event, CSMWorld::ColumnBase::Display type); + bool isInfo(const QDropEvent& event, CSMWorld::ColumnBase::Display type); ///< Info types can be dragged to sort the info table - CSMWorld::UniversalId getAcceptedData(const QDropEvent &event, CSMWorld::ColumnBase::Display type); + CSMWorld::UniversalId getAcceptedData(const QDropEvent& event, CSMWorld::ColumnBase::Display type); ///< Gets the accepted data from the \a event using the \a type ///< \return Type_None if the \a event data doesn't holds the \a type } diff --git a/apps/opencs/view/world/dragrecordtable.cpp b/apps/opencs/view/world/dragrecordtable.cpp index 8466e88b17..50878af074 100644 --- a/apps/opencs/view/world/dragrecordtable.cpp +++ b/apps/opencs/view/world/dragrecordtable.cpp @@ -5,12 +5,12 @@ #include "../../model/doc/document.hpp" -#include "../../model/world/tablemimedata.hpp" #include "../../model/world/commands.hpp" +#include "../../model/world/tablemimedata.hpp" #include "dragdroputils.hpp" -void CSVWorld::DragRecordTable::startDragFromTable (const CSVWorld::DragRecordTable& table) +void CSVWorld::DragRecordTable::startDragFromTable(const CSVWorld::DragRecordTable& table) { std::vector records = table.getDraggedRecords(); if (records.empty()) @@ -18,36 +18,36 @@ void CSVWorld::DragRecordTable::startDragFromTable (const CSVWorld::DragRecordTa return; } - CSMWorld::TableMimeData* mime = new CSMWorld::TableMimeData (records, mDocument); - QDrag* drag = new QDrag (this); - drag->setMimeData (mime); - drag->setPixmap (QString::fromUtf8 (mime->getIcon().c_str())); - drag->exec (Qt::CopyAction); + CSMWorld::TableMimeData* mime = new CSMWorld::TableMimeData(records, mDocument); + QDrag* drag = new QDrag(this); + drag->setMimeData(mime); + drag->setPixmap(QString::fromUtf8(mime->getIcon().c_str())); + drag->exec(Qt::CopyAction); } -CSVWorld::DragRecordTable::DragRecordTable (CSMDoc::Document& document, QWidget* parent) : -QTableView(parent), -mDocument(document), -mEditLock(false) +CSVWorld::DragRecordTable::DragRecordTable(CSMDoc::Document& document, QWidget* parent) + : QTableView(parent) + , mDocument(document) + , mEditLock(false) { setAcceptDrops(true); } -void CSVWorld::DragRecordTable::setEditLock (bool locked) +void CSVWorld::DragRecordTable::setEditLock(bool locked) { mEditLock = locked; } -void CSVWorld::DragRecordTable::dragEnterEvent(QDragEnterEvent *event) +void CSVWorld::DragRecordTable::dragEnterEvent(QDragEnterEvent* event) { event->acceptProposedAction(); } -void CSVWorld::DragRecordTable::dragMoveEvent(QDragMoveEvent *event) +void CSVWorld::DragRecordTable::dragMoveEvent(QDragMoveEvent* event) { QModelIndex index = indexAt(event->pos()); - if (CSVWorld::DragDropUtils::canAcceptData(*event, getIndexDisplayType(index)) || - CSVWorld::DragDropUtils::isInfo(*event, getIndexDisplayType(index)) ) + if (CSVWorld::DragDropUtils::canAcceptData(*event, getIndexDisplayType(index)) + || CSVWorld::DragDropUtils::isInfo(*event, getIndexDisplayType(index))) { if (index.flags() & Qt::ItemIsEditable) { @@ -58,13 +58,13 @@ void CSVWorld::DragRecordTable::dragMoveEvent(QDragMoveEvent *event) event->ignore(); } -void CSVWorld::DragRecordTable::dropEvent(QDropEvent *event) +void CSVWorld::DragRecordTable::dropEvent(QDropEvent* event) { QModelIndex index = indexAt(event->pos()); CSMWorld::ColumnBase::Display display = getIndexDisplayType(index); if (CSVWorld::DragDropUtils::canAcceptData(*event, display)) { - const CSMWorld::TableMimeData *tableMimeData = CSVWorld::DragDropUtils::getTableMimeData(*event); + const CSMWorld::TableMimeData* tableMimeData = CSVWorld::DragDropUtils::getTableMimeData(*event); if (tableMimeData->fromDocument(mDocument)) { CSMWorld::UniversalId id = CSVWorld::DragDropUtils::getAcceptedData(*event, display); @@ -82,7 +82,7 @@ void CSVWorld::DragRecordTable::dropEvent(QDropEvent *event) } } -CSMWorld::ColumnBase::Display CSVWorld::DragRecordTable::getIndexDisplayType(const QModelIndex &index) const +CSMWorld::ColumnBase::Display CSVWorld::DragRecordTable::getIndexDisplayType(const QModelIndex& index) const { Q_ASSERT(model() != nullptr); diff --git a/apps/opencs/view/world/dragrecordtable.hpp b/apps/opencs/view/world/dragrecordtable.hpp index b8a108b143..361cc071cb 100644 --- a/apps/opencs/view/world/dragrecordtable.hpp +++ b/apps/opencs/view/world/dragrecordtable.hpp @@ -24,35 +24,34 @@ namespace CSVWorld { Q_OBJECT - protected: - CSMDoc::Document& mDocument; - bool mEditLock; + protected: + CSMDoc::Document& mDocument; + bool mEditLock; - public: - DragRecordTable(CSMDoc::Document& document, QWidget* parent = nullptr); + public: + DragRecordTable(CSMDoc::Document& document, QWidget* parent = nullptr); - virtual std::vector getDraggedRecords() const = 0; + virtual std::vector getDraggedRecords() const = 0; - void setEditLock(bool locked); + void setEditLock(bool locked); - protected: - void startDragFromTable(const DragRecordTable& table); + protected: + void startDragFromTable(const DragRecordTable& table); - void dragEnterEvent(QDragEnterEvent *event) override; + void dragEnterEvent(QDragEnterEvent* event) override; - void dragMoveEvent(QDragMoveEvent *event) override; + void dragMoveEvent(QDragMoveEvent* event) override; - void dropEvent(QDropEvent *event) override; + void dropEvent(QDropEvent* event) override; - int sizeHintForColumn(int column) const override; + int sizeHintForColumn(int column) const override; - private: - CSMWorld::ColumnBase::Display getIndexDisplayType(const QModelIndex &index) const; + private: + CSMWorld::ColumnBase::Display getIndexDisplayType(const QModelIndex& index) const; - signals: - void moveRecordsFromSameTable(QDropEvent *event); + signals: + void moveRecordsFromSameTable(QDropEvent* event); }; } #endif - diff --git a/apps/opencs/view/world/enumdelegate.cpp b/apps/opencs/view/world/enumdelegate.cpp index 6ec585381c..42ce0c5005 100644 --- a/apps/opencs/view/world/enumdelegate.cpp +++ b/apps/opencs/view/world/enumdelegate.cpp @@ -3,12 +3,12 @@ #include #include -#include #include +#include #include "../../model/world/commands.hpp" -int CSVWorld::EnumDelegate::getValueIndex(const QModelIndex &index, int role) const +int CSVWorld::EnumDelegate::getValueIndex(const QModelIndex& index, int role) const { if (index.isValid() && index.data(role).isValid()) { @@ -26,66 +26,60 @@ int CSVWorld::EnumDelegate::getValueIndex(const QModelIndex &index, int role) co return -1; } -void CSVWorld::EnumDelegate::setModelDataImp (QWidget *editor, QAbstractItemModel *model, - const QModelIndex& index) const +void CSVWorld::EnumDelegate::setModelDataImp(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const { - if (QComboBox *comboBox = dynamic_cast (editor)) + if (QComboBox* comboBox = dynamic_cast(editor)) { QString value = comboBox->currentText(); - for (std::vector >::const_iterator iter (mValues.begin()); - iter!=mValues.end(); ++iter) - if (iter->second==value) + for (std::vector>::const_iterator iter(mValues.begin()); iter != mValues.end(); ++iter) + if (iter->second == value) { // do nothing if the value has not changed if (model->data(index).toInt() != iter->first) - addCommands (model, index, iter->first); + addCommands(model, index, iter->first); break; } } } -void CSVWorld::EnumDelegate::addCommands (QAbstractItemModel *model, - const QModelIndex& index, int type) const +void CSVWorld::EnumDelegate::addCommands(QAbstractItemModel* model, const QModelIndex& index, int type) const { - getUndoStack().push (new CSMWorld::ModifyCommand (*model, index, type)); + getUndoStack().push(new CSMWorld::ModifyCommand(*model, index, type)); } - -CSVWorld::EnumDelegate::EnumDelegate (const std::vector >& values, - CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) -: CommandDelegate (dispatcher, document, parent), mValues (values) +CSVWorld::EnumDelegate::EnumDelegate(const std::vector>& values, + CSMWorld::CommandDispatcher* dispatcher, CSMDoc::Document& document, QObject* parent) + : CommandDelegate(dispatcher, document, parent) + , mValues(values) { - } -QWidget *CSVWorld::EnumDelegate::createEditor(QWidget *parent, - const QStyleOptionViewItem& option, - const QModelIndex& index) const +QWidget* CSVWorld::EnumDelegate::createEditor( + QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const { return createEditor(parent, option, index, CSMWorld::ColumnBase::Display_None); } -QWidget *CSVWorld::EnumDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem& option, +QWidget* CSVWorld::EnumDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const { if (!index.data(Qt::EditRole).isValid() && !index.data(Qt::DisplayRole).isValid()) return nullptr; - QComboBox *comboBox = new QComboBox (parent); + QComboBox* comboBox = new QComboBox(parent); + + for (std::vector>::const_iterator iter(mValues.begin()); iter != mValues.end(); ++iter) + comboBox->addItem(iter->second); - for (std::vector >::const_iterator iter (mValues.begin()); - iter!=mValues.end(); ++iter) - comboBox->addItem (iter->second); - comboBox->setMaxVisibleItems(20); return comboBox; } -void CSVWorld::EnumDelegate::setEditorData (QWidget *editor, const QModelIndex& index, bool tryDisplay) const +void CSVWorld::EnumDelegate::setEditorData(QWidget* editor, const QModelIndex& index, bool tryDisplay) const { - if (QComboBox *comboBox = dynamic_cast(editor)) + if (QComboBox* comboBox = dynamic_cast(editor)) { int role = Qt::EditRole; if (tryDisplay && !index.data(role).isValid()) @@ -105,8 +99,8 @@ void CSVWorld::EnumDelegate::setEditorData (QWidget *editor, const QModelIndex& } } -void CSVWorld::EnumDelegate::paint (QPainter *painter, const QStyleOptionViewItem& option, - const QModelIndex& index) const +void CSVWorld::EnumDelegate::paint( + QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { int valueIndex = getValueIndex(index); if (valueIndex != -1) @@ -117,7 +111,7 @@ void CSVWorld::EnumDelegate::paint (QPainter *painter, const QStyleOptionViewIte } } -QSize CSVWorld::EnumDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const +QSize CSVWorld::EnumDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const { int valueIndex = getValueIndex(index); if (valueIndex != -1) @@ -130,7 +124,7 @@ QSize CSVWorld::EnumDelegate::sizeHint(const QStyleOptionViewItem &option, const itemOption.rect = option.rect; itemOption.state = option.state; - const QString &valueText = mValues.at(valueIndex).second; + const QString& valueText = mValues.at(valueIndex).second; QSize valueSize = QSize(itemOption.fontMetrics.horizontalAdvance(valueText), itemOption.fontMetrics.height()); itemOption.currentText = valueText; return QApplication::style()->sizeFromContents(QStyle::CT_ComboBox, &itemOption, valueSize); @@ -140,40 +134,40 @@ QSize CSVWorld::EnumDelegate::sizeHint(const QStyleOptionViewItem &option, const CSVWorld::EnumDelegateFactory::EnumDelegateFactory() {} -CSVWorld::EnumDelegateFactory::EnumDelegateFactory (const char **names, bool allowNone) +CSVWorld::EnumDelegateFactory::EnumDelegateFactory(const char** names, bool allowNone) { - assert (names); + assert(names); if (allowNone) - add (-1, ""); + add(-1, ""); - for (int i=0; names[i]; ++i) - add (i, names[i]); + for (int i = 0; names[i]; ++i) + add(i, names[i]); } -CSVWorld::EnumDelegateFactory::EnumDelegateFactory (const std::vector>& names, - bool allowNone) +CSVWorld::EnumDelegateFactory::EnumDelegateFactory( + const std::vector>& names, bool allowNone) { if (allowNone) - add (-1, ""); + add(-1, ""); - int size = static_cast (names.size()); + int size = static_cast(names.size()); - for (int i=0; isecond > name) { @@ -182,5 +176,5 @@ void CSVWorld::EnumDelegateFactory::add (int value, const QString& name) } } - mValues.emplace_back (value, name); + mValues.emplace_back(value, name); } diff --git a/apps/opencs/view/world/enumdelegate.hpp b/apps/opencs/view/world/enumdelegate.hpp index c5a851c9f8..6fcf746500 100644 --- a/apps/opencs/view/world/enumdelegate.hpp +++ b/apps/opencs/view/world/enumdelegate.hpp @@ -14,66 +14,55 @@ namespace CSVWorld /// \brief Integer value that represents an enum and is interacted with via a combobox class EnumDelegate : public CommandDelegate { - protected: + protected: + std::vector> mValues; - std::vector > mValues; + int getValueIndex(const QModelIndex& index, int role = Qt::DisplayRole) const; - int getValueIndex(const QModelIndex &index, int role = Qt::DisplayRole) const; + private: + void setModelDataImp(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const override; - private: + virtual void addCommands(QAbstractItemModel* model, const QModelIndex& index, int type) const; - void setModelDataImp (QWidget *editor, QAbstractItemModel *model, - const QModelIndex& index) const override; + public: + EnumDelegate(const std::vector>& values, CSMWorld::CommandDispatcher* dispatcher, + CSMDoc::Document& document, QObject* parent); - virtual void addCommands (QAbstractItemModel *model, - const QModelIndex& index, int type) const; + QWidget* createEditor( + QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override; - public: + QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index, + CSMWorld::ColumnBase::Display display = CSMWorld::ColumnBase::Display_None) const override; - EnumDelegate (const std::vector >& values, - CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent); + void setEditorData(QWidget* editor, const QModelIndex& index, bool tryDisplay = false) const override; - QWidget *createEditor(QWidget *parent, - const QStyleOptionViewItem& option, - const QModelIndex& index) const override; - - QWidget *createEditor(QWidget *parent, - const QStyleOptionViewItem& option, - const QModelIndex& index, - CSMWorld::ColumnBase::Display display = CSMWorld::ColumnBase::Display_None) const override; - - void setEditorData (QWidget *editor, const QModelIndex& index, bool tryDisplay = false) const override; - - void paint (QPainter *painter, const QStyleOptionViewItem& option, - const QModelIndex& index) const override; - - QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override; + void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override; + QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override; }; class EnumDelegateFactory : public CommandDelegateFactory { - protected: - std::vector > mValues; - - public: + protected: + std::vector> mValues; - EnumDelegateFactory(); + public: + EnumDelegateFactory(); - EnumDelegateFactory (const char **names, bool allowNone = false); - ///< \param names Array of char pointer with a 0-pointer as end mark - /// \param allowNone Use value of -1 for "none selected" (empty string) + EnumDelegateFactory(const char** names, bool allowNone = false); + ///< \param names Array of char pointer with a 0-pointer as end mark + /// \param allowNone Use value of -1 for "none selected" (empty string) - EnumDelegateFactory (const std::vector>& names, bool allowNone = false); - /// \param allowNone Use value of -1 for "none selected" (empty string) + EnumDelegateFactory(const std::vector>& names, bool allowNone = false); + /// \param allowNone Use value of -1 for "none selected" (empty string) - CommandDelegate *makeDelegate (CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) const override; - ///< The ownership of the returned CommandDelegate is transferred to the caller. + CommandDelegate* makeDelegate( + CSMWorld::CommandDispatcher* dispatcher, CSMDoc::Document& document, QObject* parent) const override; + ///< The ownership of the returned CommandDelegate is transferred to the caller. - void add (int value, const QString& name); + void add(int value, const QString& name); }; - } #endif diff --git a/apps/opencs/view/world/extendedcommandconfigurator.cpp b/apps/opencs/view/world/extendedcommandconfigurator.cpp index 10dd49781e..c0a1097ab7 100644 --- a/apps/opencs/view/world/extendedcommandconfigurator.cpp +++ b/apps/opencs/view/world/extendedcommandconfigurator.cpp @@ -2,25 +2,24 @@ #include -#include -#include #include +#include #include +#include #include "../../model/doc/document.hpp" #include "../../model/world/commanddispatcher.hpp" #include "../../model/world/data.hpp" -CSVWorld::ExtendedCommandConfigurator::ExtendedCommandConfigurator(CSMDoc::Document &document, - const CSMWorld::UniversalId &id, - QWidget *parent) - : QWidget(parent), - mNumUsedCheckBoxes(0), - mNumChecked(0), - mMode(Mode_None), - mData(document.getData()), - mEditLock(false) +CSVWorld::ExtendedCommandConfigurator::ExtendedCommandConfigurator( + CSMDoc::Document& document, const CSMWorld::UniversalId& id, QWidget* parent) + : QWidget(parent) + , mNumUsedCheckBoxes(0) + , mNumChecked(0) + , mMode(Mode_None) + , mData(document.getData()) + , mEditLock(false) { mCommandDispatcher = new CSMWorld::CommandDispatcher(document, id, this); @@ -37,11 +36,11 @@ CSVWorld::ExtendedCommandConfigurator::ExtendedCommandConfigurator(CSMDoc::Docum mTypeGroup = new QGroupBox(this); - QGridLayout *groupLayout = new QGridLayout(mTypeGroup); + QGridLayout* groupLayout = new QGridLayout(mTypeGroup); groupLayout->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); mTypeGroup->setLayout(groupLayout); - QHBoxLayout *mainLayout = new QHBoxLayout(this); + QHBoxLayout* mainLayout = new QHBoxLayout(this); mainLayout->setSizeConstraint(QLayout::SetNoConstraint); mainLayout->setContentsMargins(0, 0, 0, 0); mainLayout->addWidget(mTypeGroup); @@ -49,8 +48,8 @@ CSVWorld::ExtendedCommandConfigurator::ExtendedCommandConfigurator(CSMDoc::Docum mainLayout->addWidget(mCancelButton); } -void CSVWorld::ExtendedCommandConfigurator::configure(CSVWorld::ExtendedCommandConfigurator::Mode mode, - const std::vector &selectedIds) +void CSVWorld::ExtendedCommandConfigurator::configure( + CSVWorld::ExtendedCommandConfigurator::Mode mode, const std::vector& selectedIds) { mMode = mode; if (mMode != Mode_None) @@ -74,7 +73,7 @@ void CSVWorld::ExtendedCommandConfigurator::setEditLock(bool locked) } } -void CSVWorld::ExtendedCommandConfigurator::resizeEvent(QResizeEvent *event) +void CSVWorld::ExtendedCommandConfigurator::resizeEvent(QResizeEvent* event) { QWidget::resizeEvent(event); setupGroupLayout(); @@ -88,7 +87,7 @@ void CSVWorld::ExtendedCommandConfigurator::setupGroupLayout() } int groupWidth = mTypeGroup->geometry().width(); - QGridLayout *layout = qobject_cast(mTypeGroup->layout()); + QGridLayout* layout = qobject_cast(mTypeGroup->layout()); // Find the optimal number of rows to place the checkboxes within the available space int divider = 1; @@ -114,20 +113,19 @@ void CSVWorld::ExtendedCommandConfigurator::setupGroupLayout() ++counter; } divider *= 2; - } - while (groupWidth < mTypeGroup->sizeHint().width() && divider <= mNumUsedCheckBoxes); + } while (groupWidth < mTypeGroup->sizeHint().width() && divider <= mNumUsedCheckBoxes); } -void CSVWorld::ExtendedCommandConfigurator::setupCheckBoxes(const std::vector &types) +void CSVWorld::ExtendedCommandConfigurator::setupCheckBoxes(const std::vector& types) { // Make sure that we have enough checkboxes - int numTypes = static_cast(types.size()); + int numTypes = static_cast(types.size()); int numCheckBoxes = static_cast(mTypeCheckBoxes.size()); if (numTypes > numCheckBoxes) { for (int i = numTypes - numCheckBoxes; i > 0; --i) { - QCheckBox *checkBox = new QCheckBox(mTypeGroup); + QCheckBox* checkBox = new QCheckBox(mTypeGroup); connect(checkBox, &QCheckBox::stateChanged, this, &ExtendedCommandConfigurator::checkBoxStateChanged); mTypeCheckBoxes.insert(std::make_pair(checkBox, CSMWorld::UniversalId::Type_None)); } diff --git a/apps/opencs/view/world/extendedcommandconfigurator.hpp b/apps/opencs/view/world/extendedcommandconfigurator.hpp index 85862ac49e..d3354a5e5d 100644 --- a/apps/opencs/view/world/extendedcommandconfigurator.hpp +++ b/apps/opencs/view/world/extendedcommandconfigurator.hpp @@ -28,50 +28,54 @@ namespace CSVWorld { class ExtendedCommandConfigurator : public QWidget { - Q_OBJECT - - public: - enum Mode { Mode_None, Mode_Delete, Mode_Revert }; - - private: - typedef std::map CheckBoxMap; - - QPushButton *mPerformButton; - QPushButton *mCancelButton; - QGroupBox *mTypeGroup; - CheckBoxMap mTypeCheckBoxes; - int mNumUsedCheckBoxes; - int mNumChecked; - - Mode mMode; - CSMWorld::CommandDispatcher *mCommandDispatcher; - CSMWorld::Data &mData; - std::vector mSelectedIds; - - bool mEditLock; - - void setupGroupLayout(); - void setupCheckBoxes(const std::vector &types); - void lockWidgets(bool locked); - - public: - ExtendedCommandConfigurator(CSMDoc::Document &document, - const CSMWorld::UniversalId &id, - QWidget *parent = nullptr); - - void configure(Mode mode, const std::vector &selectedIds); - void setEditLock(bool locked); - - protected: - void resizeEvent(QResizeEvent *event) override; - - private slots: - void performExtendedCommand(); - void checkBoxStateChanged(int state); - void dataIdListChanged(); - - signals: - void done(); + Q_OBJECT + + public: + enum Mode + { + Mode_None, + Mode_Delete, + Mode_Revert + }; + + private: + typedef std::map CheckBoxMap; + + QPushButton* mPerformButton; + QPushButton* mCancelButton; + QGroupBox* mTypeGroup; + CheckBoxMap mTypeCheckBoxes; + int mNumUsedCheckBoxes; + int mNumChecked; + + Mode mMode; + CSMWorld::CommandDispatcher* mCommandDispatcher; + CSMWorld::Data& mData; + std::vector mSelectedIds; + + bool mEditLock; + + void setupGroupLayout(); + void setupCheckBoxes(const std::vector& types); + void lockWidgets(bool locked); + + public: + ExtendedCommandConfigurator( + CSMDoc::Document& document, const CSMWorld::UniversalId& id, QWidget* parent = nullptr); + + void configure(Mode mode, const std::vector& selectedIds); + void setEditLock(bool locked); + + protected: + void resizeEvent(QResizeEvent* event) override; + + private slots: + void performExtendedCommand(); + void checkBoxStateChanged(int state); + void dataIdListChanged(); + + signals: + void done(); }; } diff --git a/apps/opencs/view/world/genericcreator.cpp b/apps/opencs/view/world/genericcreator.cpp index 48a4aa445b..f12783e294 100644 --- a/apps/opencs/view/world/genericcreator.cpp +++ b/apps/opencs/view/world/genericcreator.cpp @@ -2,12 +2,12 @@ #include +#include #include -#include +#include #include +#include #include -#include -#include #include @@ -21,25 +21,25 @@ void CSVWorld::GenericCreator::update() { mErrors = getErrors(); - mCreate->setToolTip (QString::fromUtf8 (mErrors.c_str())); - mId->setToolTip (QString::fromUtf8 (mErrors.c_str())); + mCreate->setToolTip(QString::fromUtf8(mErrors.c_str())); + mId->setToolTip(QString::fromUtf8(mErrors.c_str())); - mCreate->setEnabled (mErrors.empty() && !mLocked); + mCreate->setEnabled(mErrors.empty() && !mLocked); } -void CSVWorld::GenericCreator::setManualEditing (bool enabled) +void CSVWorld::GenericCreator::setManualEditing(bool enabled) { - mId->setVisible (enabled); + mId->setVisible(enabled); } -void CSVWorld::GenericCreator::insertAtBeginning (QWidget *widget, bool stretched) +void CSVWorld::GenericCreator::insertAtBeginning(QWidget* widget, bool stretched) { - mLayout->insertWidget (0, widget, stretched ? 1 : 0); + mLayout->insertWidget(0, widget, stretched ? 1 : 0); } -void CSVWorld::GenericCreator::insertBeforeButtons (QWidget *widget, bool stretched) +void CSVWorld::GenericCreator::insertBeforeButtons(QWidget* widget, bool stretched) { - mLayout->insertWidget (mLayout->count()-2, widget, stretched ? 1 : 0); + mLayout->insertWidget(mLayout->count() - 2, widget, stretched ? 1 : 0); // Reset tab order relative to buttons. setTabOrder(widget, mCreate); @@ -66,12 +66,11 @@ std::string CSVWorld::GenericCreator::getIdValidatorResult() const return errors; } -void CSVWorld::GenericCreator::configureCreateCommand (CSMWorld::CreateCommand& command) const {} +void CSVWorld::GenericCreator::configureCreateCommand(CSMWorld::CreateCommand& command) const {} -void CSVWorld::GenericCreator::pushCommand (std::unique_ptr command, - const std::string& id) +void CSVWorld::GenericCreator::pushCommand(std::unique_ptr command, const std::string& id) { - mUndoStack.push (command.release()); + mUndoStack.push(command.release()); } CSMWorld::Data& CSVWorld::GenericCreator::getData() const @@ -95,7 +94,7 @@ std::string CSVWorld::GenericCreator::getNamespace() const if (mScope) { - scope = static_cast (mScope->itemData (mScope->currentIndex()).toInt()); + scope = static_cast(mScope->itemData(mScope->currentIndex()).toInt()); } else { @@ -107,9 +106,12 @@ std::string CSVWorld::GenericCreator::getNamespace() const switch (scope) { - case CSMWorld::Scope_Content: return ""; - case CSMWorld::Scope_Project: return "project::"; - case CSMWorld::Scope_Session: return "session::"; + case CSMWorld::Scope_Content: + return ""; + case CSMWorld::Scope_Project: + return "project::"; + case CSMWorld::Scope_Session: + return "session::"; } return ""; @@ -119,37 +121,41 @@ void CSVWorld::GenericCreator::updateNamespace() { std::string namespace_ = getNamespace(); - mValidator->setNamespace (namespace_); + mValidator->setNamespace(namespace_); - int index = mId->text().indexOf ("::"); + int index = mId->text().indexOf("::"); - if (index==-1) + if (index == -1) { // no namespace in old text - mId->setText (QString::fromUtf8 (namespace_.c_str()) + mId->text()); + mId->setText(QString::fromUtf8(namespace_.c_str()) + mId->text()); } else { - std::string oldNamespace = - Misc::StringUtils::lowerCase (mId->text().left (index).toUtf8().constData()); + std::string oldNamespace = Misc::StringUtils::lowerCase(mId->text().left(index).toUtf8().constData()); - if (oldNamespace=="project" || oldNamespace=="session") - mId->setText (QString::fromUtf8 (namespace_.c_str()) + mId->text().mid (index+2)); + if (oldNamespace == "project" || oldNamespace == "session") + mId->setText(QString::fromUtf8(namespace_.c_str()) + mId->text().mid(index + 2)); } } -void CSVWorld::GenericCreator::addScope (const QString& name, CSMWorld::Scope scope, - const QString& tooltip) +void CSVWorld::GenericCreator::addScope(const QString& name, CSMWorld::Scope scope, const QString& tooltip) { - mScope->addItem (name, static_cast (scope)); - mScope->setItemData (mScope->count()-1, tooltip, Qt::ToolTipRole); + mScope->addItem(name, static_cast(scope)); + mScope->setItemData(mScope->count() - 1, tooltip, Qt::ToolTipRole); } -CSVWorld::GenericCreator::GenericCreator (CSMWorld::Data& data, QUndoStack& undoStack, - const CSMWorld::UniversalId& id, bool relaxedIdRules) -: mData (data), mUndoStack (undoStack), mListId (id), mLocked (false), - mClonedType (CSMWorld::UniversalId::Type_None), mScopes (CSMWorld::Scope_Content), mScope (nullptr), - mScopeLabel (nullptr), mCloneMode (false) +CSVWorld::GenericCreator::GenericCreator( + CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id, bool relaxedIdRules) + : mData(data) + , mUndoStack(undoStack) + , mListId(id) + , mLocked(false) + , mClonedType(CSMWorld::UniversalId::Type_None) + , mScopes(CSMWorld::Scope_Content) + , mScope(nullptr) + , mScopeLabel(nullptr) + , mCloneMode(false) { // If the collection ID has a parent type, use it instead. // It will change IDs with Record/SubRecord class (used for creators in Dialogue subviews) @@ -161,35 +167,35 @@ CSVWorld::GenericCreator::GenericCreator (CSMWorld::Data& data, QUndoStack& undo } mLayout = new QHBoxLayout; - mLayout->setContentsMargins (0, 0, 0, 0); + mLayout->setContentsMargins(0, 0, 0, 0); mId = new QLineEdit; - mId->setValidator (mValidator = new IdValidator (relaxedIdRules, this)); - mLayout->addWidget (mId, 1); + mId->setValidator(mValidator = new IdValidator(relaxedIdRules, this)); + mLayout->addWidget(mId, 1); - mCreate = new QPushButton ("Create"); - mLayout->addWidget (mCreate); + mCreate = new QPushButton("Create"); + mLayout->addWidget(mCreate); mCancel = new QPushButton("Cancel"); mLayout->addWidget(mCancel); - setLayout (mLayout); + setLayout(mLayout); - connect (mCancel, &QPushButton::clicked, this, &GenericCreator::done); - connect (mCreate, &QPushButton::clicked, this, &GenericCreator::create); + connect(mCancel, &QPushButton::clicked, this, &GenericCreator::done); + connect(mCreate, &QPushButton::clicked, this, &GenericCreator::create); - connect (mId, &QLineEdit::textChanged, this, &GenericCreator::textChanged); - connect (mId, &QLineEdit::returnPressed, this, &GenericCreator::inputReturnPressed); + connect(mId, &QLineEdit::textChanged, this, &GenericCreator::textChanged); + connect(mId, &QLineEdit::returnPressed, this, &GenericCreator::inputReturnPressed); - connect (&mData, &CSMWorld::Data::idListChanged, this, &GenericCreator::dataIdListChanged); + connect(&mData, &CSMWorld::Data::idListChanged, this, &GenericCreator::dataIdListChanged); } -void CSVWorld::GenericCreator::setEditorMaxLength (int length) +void CSVWorld::GenericCreator::setEditorMaxLength(int length) { - mId->setMaxLength (length); + mId->setMaxLength(length); } -void CSVWorld::GenericCreator::setEditLock (bool locked) +void CSVWorld::GenericCreator::setEditLock(bool locked) { mLocked = locked; update(); @@ -198,7 +204,7 @@ void CSVWorld::GenericCreator::setEditLock (bool locked) void CSVWorld::GenericCreator::reset() { mCloneMode = false; - mId->setText (""); + mId->setText(""); update(); updateNamespace(); } @@ -209,13 +215,13 @@ std::string CSVWorld::GenericCreator::getErrors() const if (!mId->hasAcceptableInput()) errors = mValidator->getError(); - else if (mData.hasId (getId())) + else if (mData.hasId(getId())) errors = "ID is already in use"; return errors; } -void CSVWorld::GenericCreator::textChanged (const QString& text) +void CSVWorld::GenericCreator::textChanged(const QString& text) { update(); } @@ -239,25 +245,23 @@ void CSVWorld::GenericCreator::create() if (mCloneMode) { command = std::make_unique( - dynamic_cast (*mData.getTableModel(mListId)), mClonedId, id, mClonedType); + dynamic_cast(*mData.getTableModel(mListId)), mClonedId, id, mClonedType); } else { command = std::make_unique( - dynamic_cast (*mData.getTableModel (mListId)), id); - + dynamic_cast(*mData.getTableModel(mListId)), id); } - configureCreateCommand (*command); - pushCommand (std::move(command), id); + configureCreateCommand(*command); + pushCommand(std::move(command), id); emit done(); emit requestFocus(id); } } -void CSVWorld::GenericCreator::cloneMode(const std::string& originId, - const CSMWorld::UniversalId::Type type) +void CSVWorld::GenericCreator::cloneMode(const std::string& originId, const CSMWorld::UniversalId::Type type) { mCloneMode = true; mClonedId = originId; @@ -280,50 +284,46 @@ void CSVWorld::GenericCreator::touch(const std::vector& i mUndoStack.endMacro(); } -void CSVWorld::GenericCreator::toggleWidgets(bool active) -{ -} +void CSVWorld::GenericCreator::toggleWidgets(bool active) {} void CSVWorld::GenericCreator::focus() { mId->setFocus(); } -void CSVWorld::GenericCreator::setScope (unsigned int scope) +void CSVWorld::GenericCreator::setScope(unsigned int scope) { mScopes = scope; - int count = (mScopes & CSMWorld::Scope_Content) + (mScopes & CSMWorld::Scope_Project) + - (mScopes & CSMWorld::Scope_Session); + int count = (mScopes & CSMWorld::Scope_Content) + (mScopes & CSMWorld::Scope_Project) + + (mScopes & CSMWorld::Scope_Session); // scope selector widget - if (count>1) + if (count > 1) { - mScope = new QComboBox (this); - insertAtBeginning (mScope, false); + mScope = new QComboBox(this); + insertAtBeginning(mScope, false); if (mScopes & CSMWorld::Scope_Content) - addScope ("Content", CSMWorld::Scope_Content, - "Record will be stored in the currently edited content file."); + addScope("Content", CSMWorld::Scope_Content, "Record will be stored in the currently edited content file."); if (mScopes & CSMWorld::Scope_Project) - addScope ("Project", CSMWorld::Scope_Project, + addScope("Project", CSMWorld::Scope_Project, "Record will be stored in a local project file.

        " "Record will be created in the reserved namespace \"project\".

        " "Record is available when running OpenMW via OpenCS."); if (mScopes & CSMWorld::Scope_Session) - addScope ("Session", CSMWorld::Scope_Session, + addScope("Session", CSMWorld::Scope_Session, "Record exists only for the duration of the current editing session.

        " "Record will be created in the reserved namespace \"session\".

        " "Record is not available when running OpenMW via OpenCS."); - connect (mScope, qOverload(&QComboBox::currentIndexChanged), - this, &GenericCreator::scopeChanged); + connect(mScope, qOverload(&QComboBox::currentIndexChanged), this, &GenericCreator::scopeChanged); - mScopeLabel = new QLabel ("Scope", this); - insertAtBeginning (mScopeLabel, false); + mScopeLabel = new QLabel("Scope", this); + insertAtBeginning(mScopeLabel, false); - mScope->setCurrentIndex (0); + mScope->setCurrentIndex(0); } else { @@ -337,7 +337,7 @@ void CSVWorld::GenericCreator::setScope (unsigned int scope) updateNamespace(); } -void CSVWorld::GenericCreator::scopeChanged (int index) +void CSVWorld::GenericCreator::scopeChanged(int index) { update(); updateNamespace(); diff --git a/apps/opencs/view/world/genericcreator.hpp b/apps/opencs/view/world/genericcreator.hpp index 9d394b9d13..5423bb96c5 100644 --- a/apps/opencs/view/world/genericcreator.hpp +++ b/apps/opencs/view/world/genericcreator.hpp @@ -27,111 +27,105 @@ namespace CSVWorld class GenericCreator : public Creator { - Q_OBJECT + Q_OBJECT - CSMWorld::Data& mData; - QUndoStack& mUndoStack; - CSMWorld::UniversalId mListId; - QPushButton *mCreate; - QPushButton *mCancel; - QLineEdit *mId; - std::string mErrors; - QHBoxLayout *mLayout; - bool mLocked; - std::string mClonedId; - CSMWorld::UniversalId::Type mClonedType; - unsigned int mScopes; - QComboBox *mScope; - QLabel *mScopeLabel; - IdValidator *mValidator; + CSMWorld::Data& mData; + QUndoStack& mUndoStack; + CSMWorld::UniversalId mListId; + QPushButton* mCreate; + QPushButton* mCancel; + QLineEdit* mId; + std::string mErrors; + QHBoxLayout* mLayout; + bool mLocked; + std::string mClonedId; + CSMWorld::UniversalId::Type mClonedType; + unsigned int mScopes; + QComboBox* mScope; + QLabel* mScopeLabel; + IdValidator* mValidator; - protected: - bool mCloneMode; + protected: + bool mCloneMode; - protected: + protected: + void update(); - void update(); + virtual void setManualEditing(bool enabled); + ///< Enable/disable manual ID editing (enabled by default). - virtual void setManualEditing (bool enabled); - ///< Enable/disable manual ID editing (enabled by default). + void insertAtBeginning(QWidget* widget, bool stretched); - void insertAtBeginning (QWidget *widget, bool stretched); + /// \brief Insert given widget before Create and Cancel buttons. + /// \param widget Widget to add to layout. + /// \param stretched Whether widget should be streched or not. + void insertBeforeButtons(QWidget* widget, bool stretched); - /// \brief Insert given widget before Create and Cancel buttons. - /// \param widget Widget to add to layout. - /// \param stretched Whether widget should be streched or not. - void insertBeforeButtons (QWidget *widget, bool stretched); + virtual std::string getId() const; - virtual std::string getId() const; + std::string getClonedId() const; - std::string getClonedId() const; + virtual std::string getIdValidatorResult() const; - virtual std::string getIdValidatorResult() const; + /// Allow subclasses to add additional data to \a command. + virtual void configureCreateCommand(CSMWorld::CreateCommand& command) const; - /// Allow subclasses to add additional data to \a command. - virtual void configureCreateCommand (CSMWorld::CreateCommand& command) const; + /// Allow subclasses to wrap the create command together with additional commands + /// into a macro. + virtual void pushCommand(std::unique_ptr command, const std::string& id); - /// Allow subclasses to wrap the create command together with additional commands - /// into a macro. - virtual void pushCommand (std::unique_ptr command, - const std::string& id); + CSMWorld::Data& getData() const; - CSMWorld::Data& getData() const; + QUndoStack& getUndoStack(); - QUndoStack& getUndoStack(); + const CSMWorld::UniversalId& getCollectionId() const; - const CSMWorld::UniversalId& getCollectionId() const; + std::string getNamespace() const; - std::string getNamespace() const; + void setEditorMaxLength(int length); - void setEditorMaxLength(int length); + private: + void updateNamespace(); - private: + void addScope(const QString& name, CSMWorld::Scope scope, const QString& tooltip); - void updateNamespace(); + public: + GenericCreator( + CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id, bool relaxedIdRules = false); - void addScope (const QString& name, CSMWorld::Scope scope, - const QString& tooltip); + void setEditLock(bool locked) override; - public: + void reset() override; - GenericCreator (CSMWorld::Data& data, QUndoStack& undoStack, - const CSMWorld::UniversalId& id, bool relaxedIdRules = false); + void toggleWidgets(bool active = true) override; - void setEditLock (bool locked) override; + void cloneMode(const std::string& originId, const CSMWorld::UniversalId::Type type) override; - void reset() override; + void touch(const std::vector& ids) override; - void toggleWidgets (bool active = true) override; + virtual std::string getErrors() const; + ///< Return formatted error descriptions for the current state of the creator. if an empty + /// string is returned, there is no error. - void cloneMode(const std::string& originId, - const CSMWorld::UniversalId::Type type) override; + void setScope(unsigned int scope) override; - void touch(const std::vector& ids) override; + /// Focus main input widget + void focus() override; - virtual std::string getErrors() const; - ///< Return formatted error descriptions for the current state of the creator. if an empty - /// string is returned, there is no error. + protected slots: - void setScope (unsigned int scope) override; + /// \brief Create record if able to after Return key is pressed on input. + void inputReturnPressed(); - /// Focus main input widget - void focus() override; + private slots: - protected slots: + void textChanged(const QString& text); - /// \brief Create record if able to after Return key is pressed on input. - void inputReturnPressed(); + void create(); - private slots: + void scopeChanged(int index); - void textChanged (const QString& text); - - void create(); - - void scopeChanged (int index); - - void dataIdListChanged(); + void dataIdListChanged(); }; } diff --git a/apps/opencs/view/world/globalcreator.cpp b/apps/opencs/view/world/globalcreator.cpp index 6c5b75fb56..df4ac31c26 100644 --- a/apps/opencs/view/world/globalcreator.cpp +++ b/apps/opencs/view/world/globalcreator.cpp @@ -7,7 +7,7 @@ namespace CSVWorld { - void GlobalCreator::configureCreateCommand (CSMWorld::CreateCommand& command) const + void GlobalCreator::configureCreateCommand(CSMWorld::CreateCommand& command) const { CSMWorld::IdTable* table = static_cast(getData().getTableModel(getCollectionId())); @@ -18,7 +18,7 @@ namespace CSVWorld } GlobalCreator::GlobalCreator(CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id) - : GenericCreator (data, undoStack, id, true) + : GenericCreator(data, undoStack, id, true) { } } diff --git a/apps/opencs/view/world/globalcreator.hpp b/apps/opencs/view/world/globalcreator.hpp index 057798a4c2..09100d8cc8 100644 --- a/apps/opencs/view/world/globalcreator.hpp +++ b/apps/opencs/view/world/globalcreator.hpp @@ -7,15 +7,13 @@ namespace CSVWorld { class GlobalCreator : public GenericCreator { - Q_OBJECT + Q_OBJECT - public: + public: + GlobalCreator(CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id); - GlobalCreator(CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id); - - protected: - - void configureCreateCommand(CSMWorld::CreateCommand& command) const override; + protected: + void configureCreateCommand(CSMWorld::CreateCommand& command) const override; }; } diff --git a/apps/opencs/view/world/idcompletiondelegate.cpp b/apps/opencs/view/world/idcompletiondelegate.cpp index 9ef04ec3ab..a4171241a7 100644 --- a/apps/opencs/view/world/idcompletiondelegate.cpp +++ b/apps/opencs/view/world/idcompletiondelegate.cpp @@ -5,23 +5,20 @@ #include "../widget/droplineedit.hpp" -CSVWorld::IdCompletionDelegate::IdCompletionDelegate(CSMWorld::CommandDispatcher *dispatcher, - CSMDoc::Document& document, - QObject *parent) +CSVWorld::IdCompletionDelegate::IdCompletionDelegate( + CSMWorld::CommandDispatcher* dispatcher, CSMDoc::Document& document, QObject* parent) : CommandDelegate(dispatcher, document, parent) -{} +{ +} -QWidget *CSVWorld::IdCompletionDelegate::createEditor(QWidget *parent, - const QStyleOptionViewItem &option, - const QModelIndex &index) const +QWidget* CSVWorld::IdCompletionDelegate::createEditor( + QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const { return createEditor(parent, option, index, getDisplayTypeFromIndex(index)); } -QWidget *CSVWorld::IdCompletionDelegate::createEditor(QWidget *parent, - const QStyleOptionViewItem &option, - const QModelIndex &index, - CSMWorld::ColumnBase::Display display) const +QWidget* CSVWorld::IdCompletionDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, + const QModelIndex& index, CSMWorld::ColumnBase::Display display) const { if (!index.data(Qt::EditRole).isValid() && !index.data(Qt::DisplayRole).isValid()) { @@ -38,72 +35,70 @@ QWidget *CSVWorld::IdCompletionDelegate::createEditor(QWidget *parent, { case CSMWorld::ConstInfoSelectWrapper::Function_Global: { - return createEditor (parent, option, index, CSMWorld::ColumnBase::Display_GlobalVariable); + return createEditor(parent, option, index, CSMWorld::ColumnBase::Display_GlobalVariable); } case CSMWorld::ConstInfoSelectWrapper::Function_Journal: { - return createEditor (parent, option, index, CSMWorld::ColumnBase::Display_Journal); + return createEditor(parent, option, index, CSMWorld::ColumnBase::Display_Journal); } case CSMWorld::ConstInfoSelectWrapper::Function_Item: { - return createEditor (parent, option, index, CSMWorld::ColumnBase::Display_Referenceable); + return createEditor(parent, option, index, CSMWorld::ColumnBase::Display_Referenceable); } case CSMWorld::ConstInfoSelectWrapper::Function_Dead: case CSMWorld::ConstInfoSelectWrapper::Function_NotId: { - return createEditor (parent, option, index, CSMWorld::ColumnBase::Display_Referenceable); + return createEditor(parent, option, index, CSMWorld::ColumnBase::Display_Referenceable); } case CSMWorld::ConstInfoSelectWrapper::Function_NotFaction: { - return createEditor (parent, option, index, CSMWorld::ColumnBase::Display_Faction); + return createEditor(parent, option, index, CSMWorld::ColumnBase::Display_Faction); } case CSMWorld::ConstInfoSelectWrapper::Function_NotClass: { - return createEditor (parent, option, index, CSMWorld::ColumnBase::Display_Class); + return createEditor(parent, option, index, CSMWorld::ColumnBase::Display_Class); } case CSMWorld::ConstInfoSelectWrapper::Function_NotRace: { - return createEditor (parent, option, index, CSMWorld::ColumnBase::Display_Race); + return createEditor(parent, option, index, CSMWorld::ColumnBase::Display_Race); } case CSMWorld::ConstInfoSelectWrapper::Function_NotCell: { - return createEditor (parent, option, index, CSMWorld::ColumnBase::Display_Cell); + return createEditor(parent, option, index, CSMWorld::ColumnBase::Display_Cell); } case CSMWorld::ConstInfoSelectWrapper::Function_Local: case CSMWorld::ConstInfoSelectWrapper::Function_NotLocal: { return new CSVWidget::DropLineEdit(display, parent); } - default: return nullptr; // The rest of them can't be edited anyway + default: + return nullptr; // The rest of them can't be edited anyway } } - CSMWorld::IdCompletionManager &completionManager = getDocument().getIdCompletionManager(); - CSVWidget::DropLineEdit *editor = new CSVWidget::DropLineEdit(display, parent); + CSMWorld::IdCompletionManager& completionManager = getDocument().getIdCompletionManager(); + CSVWidget::DropLineEdit* editor = new CSVWidget::DropLineEdit(display, parent); editor->setCompleter(completionManager.getCompleter(display).get()); // The savegame format limits the player faction string to 32 characters. // The region sound name is limited to 32 characters. (ESM::Region::SoundRef::mSound) // The script name is limited to 32 characters. (ESM::Script::SCHD::mName) // The cell name is limited to 64 characters. (ESM::Header::GMDT::mCurrentCell) - if (display == CSMWorld::ColumnBase::Display_Faction || - display == CSMWorld::ColumnBase::Display_Sound || - display == CSMWorld::ColumnBase::Display_Script || - display == CSMWorld::ColumnBase::Display_Referenceable) + if (display == CSMWorld::ColumnBase::Display_Faction || display == CSMWorld::ColumnBase::Display_Sound + || display == CSMWorld::ColumnBase::Display_Script || display == CSMWorld::ColumnBase::Display_Referenceable) { - editor->setMaxLength (32); + editor->setMaxLength(32); } else if (display == CSMWorld::ColumnBase::Display_Cell) { - editor->setMaxLength (64); + editor->setMaxLength(64); } return editor; } -CSVWorld::CommandDelegate *CSVWorld::IdCompletionDelegateFactory::makeDelegate(CSMWorld::CommandDispatcher *dispatcher, - CSMDoc::Document& document, - QObject *parent) const +CSVWorld::CommandDelegate* CSVWorld::IdCompletionDelegateFactory::makeDelegate( + CSMWorld::CommandDispatcher* dispatcher, CSMDoc::Document& document, QObject* parent) const { return new IdCompletionDelegate(dispatcher, document, parent); } diff --git a/apps/opencs/view/world/idcompletiondelegate.hpp b/apps/opencs/view/world/idcompletiondelegate.hpp index 57c2c11c43..680a9bd3f2 100644 --- a/apps/opencs/view/world/idcompletiondelegate.hpp +++ b/apps/opencs/view/world/idcompletiondelegate.hpp @@ -8,28 +8,22 @@ namespace CSVWorld /// \brief Enables the Id completion for a column class IdCompletionDelegate : public CommandDelegate { - public: - IdCompletionDelegate(CSMWorld::CommandDispatcher *dispatcher, - CSMDoc::Document& document, - QObject *parent); + public: + IdCompletionDelegate(CSMWorld::CommandDispatcher* dispatcher, CSMDoc::Document& document, QObject* parent); - QWidget *createEditor (QWidget *parent, - const QStyleOptionViewItem &option, - const QModelIndex &index) const override; + QWidget* createEditor( + QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override; - QWidget *createEditor (QWidget *parent, - const QStyleOptionViewItem &option, - const QModelIndex &index, - CSMWorld::ColumnBase::Display display) const override; + QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index, + CSMWorld::ColumnBase::Display display) const override; }; class IdCompletionDelegateFactory : public CommandDelegateFactory { - public: - CommandDelegate *makeDelegate(CSMWorld::CommandDispatcher *dispatcher, - CSMDoc::Document& document, - QObject *parent) const override; - ///< The ownership of the returned CommandDelegate is transferred to the caller. + public: + CommandDelegate* makeDelegate( + CSMWorld::CommandDispatcher* dispatcher, CSMDoc::Document& document, QObject* parent) const override; + ///< The ownership of the returned CommandDelegate is transferred to the caller. }; } diff --git a/apps/opencs/view/world/idtypedelegate.cpp b/apps/opencs/view/world/idtypedelegate.cpp index ee35e07d41..1a84b8c573 100755 --- a/apps/opencs/view/world/idtypedelegate.cpp +++ b/apps/opencs/view/world/idtypedelegate.cpp @@ -2,26 +2,25 @@ #include "../../model/world/universalid.hpp" -CSVWorld::IdTypeDelegate::IdTypeDelegate - (const ValueList &values, const IconList &icons, CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) - : DataDisplayDelegate (values, icons, dispatcher, document, - "Records", "type-format", - parent) -{} +CSVWorld::IdTypeDelegate::IdTypeDelegate(const ValueList& values, const IconList& icons, + CSMWorld::CommandDispatcher* dispatcher, CSMDoc::Document& document, QObject* parent) + : DataDisplayDelegate(values, icons, dispatcher, document, "Records", "type-format", parent) +{ +} CSVWorld::IdTypeDelegateFactory::IdTypeDelegateFactory() { - for (int i=0; i (i)); + CSMWorld::UniversalId id(static_cast(i)); - DataDisplayDelegateFactory::add (id.getType(), QString::fromUtf8 (id.getTypeName().c_str()), - QString::fromUtf8 (id.getIcon().c_str())); + DataDisplayDelegateFactory::add( + id.getType(), QString::fromUtf8(id.getTypeName().c_str()), QString::fromUtf8(id.getIcon().c_str())); } } -CSVWorld::CommandDelegate *CSVWorld::IdTypeDelegateFactory::makeDelegate ( - CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) const +CSVWorld::CommandDelegate* CSVWorld::IdTypeDelegateFactory::makeDelegate( + CSMWorld::CommandDispatcher* dispatcher, CSMDoc::Document& document, QObject* parent) const { - return new IdTypeDelegate (mValues, mIcons, dispatcher, document, parent); + return new IdTypeDelegate(mValues, mIcons, dispatcher, document, parent); } diff --git a/apps/opencs/view/world/idtypedelegate.hpp b/apps/opencs/view/world/idtypedelegate.hpp index 3371ce42c0..db7fb46b5c 100755 --- a/apps/opencs/view/world/idtypedelegate.hpp +++ b/apps/opencs/view/world/idtypedelegate.hpp @@ -1,25 +1,26 @@ #ifndef IDTYPEDELEGATE_HPP #define IDTYPEDELEGATE_HPP -#include "util.hpp" #include "datadisplaydelegate.hpp" +#include "util.hpp" namespace CSVWorld { class IdTypeDelegate : public DataDisplayDelegate { - public: - IdTypeDelegate (const ValueList &mValues, const IconList &icons, CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent); + public: + IdTypeDelegate(const ValueList& mValues, const IconList& icons, CSMWorld::CommandDispatcher* dispatcher, + CSMDoc::Document& document, QObject* parent); }; class IdTypeDelegateFactory : public DataDisplayDelegateFactory { - public: - - IdTypeDelegateFactory(); + public: + IdTypeDelegateFactory(); - CommandDelegate *makeDelegate (CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) const override; - ///< The ownership of the returned CommandDelegate is transferred to the caller. + CommandDelegate* makeDelegate( + CSMWorld::CommandDispatcher* dispatcher, CSMDoc::Document& document, QObject* parent) const override; + ///< The ownership of the returned CommandDelegate is transferred to the caller. }; } diff --git a/apps/opencs/view/world/idvalidator.cpp b/apps/opencs/view/world/idvalidator.cpp index efba4c5af9..6f790d20cb 100644 --- a/apps/opencs/view/world/idvalidator.cpp +++ b/apps/opencs/view/world/idvalidator.cpp @@ -2,28 +2,30 @@ #include -bool CSVWorld::IdValidator::isValid (const QChar& c, bool first) const +bool CSVWorld::IdValidator::isValid(const QChar& c, bool first) const { - if (c.isLetter() || c=='_') + if (c.isLetter() || c == '_') return true; - if (!first && (c.isDigit() || c.isSpace())) + if (!first && (c.isDigit() || c.isSpace())) return true; return false; } -CSVWorld::IdValidator::IdValidator (bool relaxed, QObject *parent) -: QValidator (parent), mRelaxed (relaxed) -{} +CSVWorld::IdValidator::IdValidator(bool relaxed, QObject* parent) + : QValidator(parent) + , mRelaxed(relaxed) +{ +} -QValidator::State CSVWorld::IdValidator::validate (QString& input, int& pos) const +QValidator::State CSVWorld::IdValidator::validate(QString& input, int& pos) const { mError.clear(); if (mRelaxed) { - if (input.indexOf ('"')!=-1 || input.indexOf ("::")!=-1 || input.indexOf ("#")!=-1) + if (input.indexOf('"') != -1 || input.indexOf("::") != -1 || input.indexOf("#") != -1) return QValidator::Invalid; } else @@ -42,9 +44,9 @@ QValidator::State CSVWorld::IdValidator::validate (QString& input, int& pos) con if (!mNamespace.empty()) { - std::string namespace_ = input.left (static_cast(mNamespace.size())).toUtf8().constData(); + std::string namespace_ = input.left(static_cast(mNamespace.size())).toUtf8().constData(); - if (Misc::StringUtils::lowerCase (namespace_)!=mNamespace) + if (Misc::StringUtils::lowerCase(namespace_) != mNamespace) return QValidator::Invalid; // incorrect namespace iter += namespace_.size(); @@ -53,20 +55,20 @@ QValidator::State CSVWorld::IdValidator::validate (QString& input, int& pos) con } else { - int index = input.indexOf (":"); + int index = input.indexOf(":"); - if (index!=-1) + if (index != -1) { - QString namespace_ = input.left (index); + QString namespace_ = input.left(index); - if (namespace_=="project" || namespace_=="session") + if (namespace_ == "project" || namespace_ == "session") return QValidator::Invalid; // reserved namespace } } - for (; iter!=input.end(); ++iter, first = false) + for (; iter != input.end(); ++iter, first = false) { - if (*iter==':') + if (*iter == ':') { if (first) return QValidator::Invalid; // scope operator at the beginning @@ -90,7 +92,7 @@ QValidator::State CSVWorld::IdValidator::validate (QString& input, int& pos) con { prevScope = false; - if (!isValid (*iter, first)) + if (!isValid(*iter, first)) return QValidator::Invalid; } } @@ -111,9 +113,9 @@ QValidator::State CSVWorld::IdValidator::validate (QString& input, int& pos) con return QValidator::Acceptable; } -void CSVWorld::IdValidator::setNamespace (const std::string& namespace_) +void CSVWorld::IdValidator::setNamespace(const std::string& namespace_) { - mNamespace = Misc::StringUtils::lowerCase (namespace_); + mNamespace = Misc::StringUtils::lowerCase(namespace_); } std::string CSVWorld::IdValidator::getError() const diff --git a/apps/opencs/view/world/idvalidator.hpp b/apps/opencs/view/world/idvalidator.hpp index 278335a65b..e831542961 100644 --- a/apps/opencs/view/world/idvalidator.hpp +++ b/apps/opencs/view/world/idvalidator.hpp @@ -9,29 +9,26 @@ namespace CSVWorld { class IdValidator : public QValidator { - bool mRelaxed; - std::string mNamespace; - mutable std::string mError; + bool mRelaxed; + std::string mNamespace; + mutable std::string mError; - private: + private: + bool isValid(const QChar& c, bool first) const; - bool isValid (const QChar& c, bool first) const; + public: + IdValidator(bool relaxed = false, QObject* parent = nullptr); + ///< \param relaxed Relaxed rules for IDs that also functino as user visible text - public: + State validate(QString& input, int& pos) const override; - IdValidator (bool relaxed = false, QObject *parent = nullptr); - ///< \param relaxed Relaxed rules for IDs that also functino as user visible text - - State validate (QString& input, int& pos) const override; - - void setNamespace (const std::string& namespace_); - - /// Return a description of the error that resulted in the last call of validate - /// returning QValidator::Intermediate. If the last call to validate returned - /// a different value (or if there was no such call yet), an empty string is - /// returned. - std::string getError() const; + void setNamespace(const std::string& namespace_); + /// Return a description of the error that resulted in the last call of validate + /// returning QValidator::Intermediate. If the last call to validate returned + /// a different value (or if there was no such call yet), an empty string is + /// returned. + std::string getError() const; }; } diff --git a/apps/opencs/view/world/infocreator.cpp b/apps/opencs/view/world/infocreator.cpp index 805e4111b9..b7d467e2f2 100644 --- a/apps/opencs/view/world/infocreator.cpp +++ b/apps/opencs/view/world/infocreator.cpp @@ -9,40 +9,40 @@ #include "../../model/doc/document.hpp" -#include "../../model/world/data.hpp" -#include "../../model/world/commands.hpp" #include "../../model/world/columns.hpp" -#include "../../model/world/idtable.hpp" +#include "../../model/world/commands.hpp" +#include "../../model/world/data.hpp" #include "../../model/world/idcompletionmanager.hpp" +#include "../../model/world/idtable.hpp" #include "../widget/droplineedit.hpp" std::string CSVWorld::InfoCreator::getId() const { - std::string id = Misc::StringUtils::lowerCase (mTopic->text().toUtf8().constData()); + std::string id = Misc::StringUtils::lowerCase(mTopic->text().toUtf8().constData()); std::string unique = QUuid::createUuid().toByteArray().data(); - unique.erase (std::remove (unique.begin(), unique.end(), '-'), unique.end()); + unique.erase(std::remove(unique.begin(), unique.end(), '-'), unique.end()); - unique = unique.substr (1, unique.size()-2); + unique = unique.substr(1, unique.size() - 2); return id + '#' + unique; } -void CSVWorld::InfoCreator::configureCreateCommand (CSMWorld::CreateCommand& command) const +void CSVWorld::InfoCreator::configureCreateCommand(CSMWorld::CreateCommand& command) const { - CSMWorld::IdTable& table = dynamic_cast (*getData().getTableModel (getCollectionId())); + CSMWorld::IdTable& table = dynamic_cast(*getData().getTableModel(getCollectionId())); - CSMWorld::CloneCommand* cloneCommand = dynamic_cast (&command); + CSMWorld::CloneCommand* cloneCommand = dynamic_cast(&command); if (getCollectionId() == CSMWorld::UniversalId::Type_TopicInfos) { if (!cloneCommand) { - command.addValue (table.findColumnIndex(CSMWorld::Columns::ColumnId_Topic), mTopic->text()); - command.addValue (table.findColumnIndex(CSMWorld::Columns::ColumnId_Rank), -1); - command.addValue (table.findColumnIndex(CSMWorld::Columns::ColumnId_Gender), -1); - command.addValue (table.findColumnIndex(CSMWorld::Columns::ColumnId_PcRank), -1); + command.addValue(table.findColumnIndex(CSMWorld::Columns::ColumnId_Topic), mTopic->text()); + command.addValue(table.findColumnIndex(CSMWorld::Columns::ColumnId_Rank), -1); + command.addValue(table.findColumnIndex(CSMWorld::Columns::ColumnId_Gender), -1); + command.addValue(table.findColumnIndex(CSMWorld::Columns::ColumnId_PcRank), -1); } else { @@ -53,16 +53,16 @@ void CSVWorld::InfoCreator::configureCreateCommand (CSMWorld::CreateCommand& com { if (!cloneCommand) { - command.addValue (table.findColumnIndex(CSMWorld::Columns::ColumnId_Journal), mTopic->text()); + command.addValue(table.findColumnIndex(CSMWorld::Columns::ColumnId_Journal), mTopic->text()); } else cloneCommand->setOverrideValue(table.findColumnIndex(CSMWorld::Columns::ColumnId_Journal), mTopic->text()); } } -CSVWorld::InfoCreator::InfoCreator (CSMWorld::Data& data, QUndoStack& undoStack, - const CSMWorld::UniversalId& id, CSMWorld::IdCompletionManager& completionManager) -: GenericCreator (data, undoStack, id) +CSVWorld::InfoCreator::InfoCreator(CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id, + CSMWorld::IdCompletionManager& completionManager) + : GenericCreator(data, undoStack, id) { // Determine if we're dealing with topics or journals. CSMWorld::ColumnBase::Display displayType = CSMWorld::ColumnBase::Display_Topic; @@ -73,40 +73,37 @@ CSVWorld::InfoCreator::InfoCreator (CSMWorld::Data& data, QUndoStack& undoStack, labelText = "Journal"; } - QLabel *label = new QLabel (labelText, this); - insertBeforeButtons (label, false); + QLabel* label = new QLabel(labelText, this); + insertBeforeButtons(label, false); // Add topic/journal ID input with auto-completion. // Only existing topic/journal IDs are accepted so no ID validation is performed. mTopic = new CSVWidget::DropLineEdit(displayType, this); mTopic->setCompleter(completionManager.getCompleter(displayType).get()); - insertBeforeButtons (mTopic, true); + insertBeforeButtons(mTopic, true); - setManualEditing (false); + setManualEditing(false); - connect (mTopic, &CSVWidget::DropLineEdit::textChanged, this, &InfoCreator::topicChanged); - connect (mTopic, &CSVWidget::DropLineEdit::returnPressed, this, &InfoCreator::inputReturnPressed); + connect(mTopic, &CSVWidget::DropLineEdit::textChanged, this, &InfoCreator::topicChanged); + connect(mTopic, &CSVWidget::DropLineEdit::returnPressed, this, &InfoCreator::inputReturnPressed); } -void CSVWorld::InfoCreator::cloneMode (const std::string& originId, - const CSMWorld::UniversalId::Type type) +void CSVWorld::InfoCreator::cloneMode(const std::string& originId, const CSMWorld::UniversalId::Type type) { - CSMWorld::IdTable& infoTable = - dynamic_cast (*getData().getTableModel (getCollectionId())); + CSMWorld::IdTable& infoTable = dynamic_cast(*getData().getTableModel(getCollectionId())); - int topicColumn = infoTable.findColumnIndex ( - getCollectionId().getType()==CSMWorld::UniversalId::Type_TopicInfos ? - CSMWorld::Columns::ColumnId_Topic : CSMWorld::Columns::ColumnId_Journal); + int topicColumn = infoTable.findColumnIndex(getCollectionId().getType() == CSMWorld::UniversalId::Type_TopicInfos + ? CSMWorld::Columns::ColumnId_Topic + : CSMWorld::Columns::ColumnId_Journal); - mTopic->setText ( - infoTable.data (infoTable.getModelIndex (originId, topicColumn)).toString()); + mTopic->setText(infoTable.data(infoTable.getModelIndex(originId, topicColumn)).toString()); - GenericCreator::cloneMode (originId, type); + GenericCreator::cloneMode(originId, type); } void CSVWorld::InfoCreator::reset() { - mTopic->setText (""); + mTopic->setText(""); GenericCreator::reset(); } @@ -117,8 +114,10 @@ std::string CSVWorld::InfoCreator::getErrors() const std::string topic = mTopic->text().toUtf8().constData(); - if ((getCollectionId().getType()==CSMWorld::UniversalId::Type_TopicInfos ? - getData().getTopics() : getData().getJournals()).searchId (topic)==-1) + if ((getCollectionId().getType() == CSMWorld::UniversalId::Type_TopicInfos ? getData().getTopics() + : getData().getJournals()) + .searchId(topic) + == -1) { errors += "Invalid Topic ID"; } @@ -136,11 +135,8 @@ void CSVWorld::InfoCreator::topicChanged() update(); } -CSVWorld::Creator *CSVWorld::InfoCreatorFactory::makeCreator(CSMDoc::Document& document, - const CSMWorld::UniversalId& id) const +CSVWorld::Creator* CSVWorld::InfoCreatorFactory::makeCreator( + CSMDoc::Document& document, const CSMWorld::UniversalId& id) const { - return new InfoCreator(document.getData(), - document.getUndoStack(), - id, - document.getIdCompletionManager()); + return new InfoCreator(document.getData(), document.getUndoStack(), id, document.getIdCompletionManager()); } diff --git a/apps/opencs/view/world/infocreator.hpp b/apps/opencs/view/world/infocreator.hpp index 404dcf3727..5288ddbd1b 100644 --- a/apps/opencs/view/world/infocreator.hpp +++ b/apps/opencs/view/world/infocreator.hpp @@ -18,42 +18,39 @@ namespace CSVWorld { class InfoCreator : public GenericCreator { - Q_OBJECT + Q_OBJECT - CSVWidget::DropLineEdit *mTopic; + CSVWidget::DropLineEdit* mTopic; - std::string getId() const override; + std::string getId() const override; - void configureCreateCommand (CSMWorld::CreateCommand& command) const override; + void configureCreateCommand(CSMWorld::CreateCommand& command) const override; - public: + public: + InfoCreator(CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id, + CSMWorld::IdCompletionManager& completionManager); - InfoCreator (CSMWorld::Data& data, QUndoStack& undoStack, - const CSMWorld::UniversalId& id, CSMWorld::IdCompletionManager& completionManager); + void cloneMode(const std::string& originId, const CSMWorld::UniversalId::Type type) override; - void cloneMode (const std::string& originId, - const CSMWorld::UniversalId::Type type) override; + void reset() override; - void reset() override; + std::string getErrors() const override; + ///< Return formatted error descriptions for the current state of the creator. if an empty + /// string is returned, there is no error. - std::string getErrors() const override; - ///< Return formatted error descriptions for the current state of the creator. if an empty - /// string is returned, there is no error. - - /// Focus main input widget - void focus() override; - - private slots: + /// Focus main input widget + void focus() override; - void topicChanged(); + private slots: + + void topicChanged(); }; class InfoCreatorFactory : public CreatorFactoryBase { - public: - - Creator *makeCreator (CSMDoc::Document& document, const CSMWorld::UniversalId& id) const override; - ///< The ownership of the returned Creator is transferred to the caller. + public: + Creator* makeCreator(CSMDoc::Document& document, const CSMWorld::UniversalId& id) const override; + ///< The ownership of the returned Creator is transferred to the caller. }; } diff --git a/apps/opencs/view/world/landcreator.cpp b/apps/opencs/view/world/landcreator.cpp index 8d98f1b0a6..b229966ac7 100644 --- a/apps/opencs/view/world/landcreator.cpp +++ b/apps/opencs/view/world/landcreator.cpp @@ -37,8 +37,8 @@ namespace CSVWorld insertBeforeButtons(mYLabel, false); insertBeforeButtons(mY, true); - connect (mX, qOverload(&QSpinBox::valueChanged), this, &LandCreator::coordChanged); - connect (mY, qOverload(&QSpinBox::valueChanged), this, &LandCreator::coordChanged); + connect(mX, qOverload(&QSpinBox::valueChanged), this, &LandCreator::coordChanged); + connect(mY, qOverload(&QSpinBox::valueChanged), this, &LandCreator::coordChanged); } void LandCreator::cloneMode(const std::string& originId, const CSMWorld::UniversalId::Type type) @@ -57,8 +57,10 @@ namespace CSVWorld // Combine multiple touch commands into one "macro" command getUndoStack().beginMacro("Touch records"); - CSMWorld::IdTable& lands = dynamic_cast(*getData().getTableModel(CSMWorld::UniversalId::Type_Lands)); - CSMWorld::IdTable& ltexs = dynamic_cast(*getData().getTableModel(CSMWorld::UniversalId::Type_LandTextures)); + CSMWorld::IdTable& lands + = dynamic_cast(*getData().getTableModel(CSMWorld::UniversalId::Type_Lands)); + CSMWorld::IdTable& ltexs + = dynamic_cast(*getData().getTableModel(CSMWorld::UniversalId::Type_LandTextures)); for (const CSMWorld::UniversalId& uid : ids) { CSMWorld::TouchLandCommand* touchCmd = new CSMWorld::TouchLandCommand(lands, ltexs, uid.getId()); @@ -98,19 +100,22 @@ namespace CSVWorld { if (mCloneMode) { - CSMWorld::IdTable& lands = dynamic_cast(*getData().getTableModel(CSMWorld::UniversalId::Type_Lands)); - CSMWorld::IdTable& ltexs = dynamic_cast(*getData().getTableModel(CSMWorld::UniversalId::Type_LandTextures)); + CSMWorld::IdTable& lands + = dynamic_cast(*getData().getTableModel(CSMWorld::UniversalId::Type_Lands)); + CSMWorld::IdTable& ltexs + = dynamic_cast(*getData().getTableModel(CSMWorld::UniversalId::Type_LandTextures)); getUndoStack().beginMacro(("Clone " + id).c_str()); getUndoStack().push(command.release()); - CSMWorld::CopyLandTexturesCommand* ltexCopy = new CSMWorld::CopyLandTexturesCommand(lands, ltexs, getClonedId(), getId()); + CSMWorld::CopyLandTexturesCommand* ltexCopy + = new CSMWorld::CopyLandTexturesCommand(lands, ltexs, getClonedId(), getId()); getUndoStack().push(ltexCopy); getUndoStack().endMacro(); } else - getUndoStack().push (command.release()); + getUndoStack().push(command.release()); } void LandCreator::coordChanged(int value) diff --git a/apps/opencs/view/world/landcreator.hpp b/apps/opencs/view/world/landcreator.hpp index e0c5577e42..0ba4633cf7 100644 --- a/apps/opencs/view/world/landcreator.hpp +++ b/apps/opencs/view/world/landcreator.hpp @@ -10,37 +10,34 @@ namespace CSVWorld { class LandCreator : public GenericCreator { - Q_OBJECT + Q_OBJECT - QLabel* mXLabel; - QLabel* mYLabel; - QSpinBox* mX; - QSpinBox* mY; + QLabel* mXLabel; + QLabel* mYLabel; + QSpinBox* mX; + QSpinBox* mY; - public: + public: + LandCreator(CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id); - LandCreator(CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id); + void cloneMode(const std::string& originId, const CSMWorld::UniversalId::Type type) override; - void cloneMode(const std::string& originId, const CSMWorld::UniversalId::Type type) override; + void touch(const std::vector& ids) override; - void touch(const std::vector& ids) override; + void focus() override; - void focus() override; + void reset() override; - void reset() override; + std::string getErrors() const override; - std::string getErrors() const override; + protected: + std::string getId() const override; - protected: + void pushCommand(std::unique_ptr command, const std::string& id) override; - std::string getId() const override; + private slots: - void pushCommand(std::unique_ptr command, - const std::string& id) override; - - private slots: - - void coordChanged(int value); + void coordChanged(int value); }; } diff --git a/apps/opencs/view/world/landtexturecreator.cpp b/apps/opencs/view/world/landtexturecreator.cpp index bc577378fe..ca21c449d4 100644 --- a/apps/opencs/view/world/landtexturecreator.cpp +++ b/apps/opencs/view/world/landtexturecreator.cpp @@ -36,8 +36,7 @@ namespace CSVWorld insertBeforeButtons(mIndexBox, true); connect(mNameEdit, &QLineEdit::textChanged, this, &LandTextureCreator::nameChanged); - connect(mIndexBox, qOverload(&QSpinBox::valueChanged), - this, &LandTextureCreator::indexChanged); + connect(mIndexBox, qOverload(&QSpinBox::valueChanged), this, &LandTextureCreator::indexChanged); } void LandTextureCreator::cloneMode(const std::string& originId, const CSMWorld::UniversalId::Type type) diff --git a/apps/opencs/view/world/landtexturecreator.hpp b/apps/opencs/view/world/landtexturecreator.hpp index b11c47758a..b71b05ba20 100644 --- a/apps/opencs/view/world/landtexturecreator.hpp +++ b/apps/opencs/view/world/landtexturecreator.hpp @@ -12,37 +12,34 @@ namespace CSVWorld { class LandTextureCreator : public GenericCreator { - Q_OBJECT + Q_OBJECT - public: + public: + LandTextureCreator(CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id); - LandTextureCreator(CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id); + void cloneMode(const std::string& originId, const CSMWorld::UniversalId::Type type) override; - void cloneMode(const std::string& originId, const CSMWorld::UniversalId::Type type) override; + void focus() override; - void focus() override; + void reset() override; - void reset() override; + std::string getErrors() const override; - std::string getErrors() const override; + protected: + void configureCreateCommand(CSMWorld::CreateCommand& command) const override; - protected: + std::string getId() const override; - void configureCreateCommand(CSMWorld::CreateCommand& command) const override; + private slots: - std::string getId() const override; + void nameChanged(const QString& val); + void indexChanged(int val); - private slots: + private: + QLineEdit* mNameEdit; + QSpinBox* mIndexBox; - void nameChanged(const QString& val); - void indexChanged(int val); - - private: - - QLineEdit* mNameEdit; - QSpinBox* mIndexBox; - - std::string mName; + std::string mName; }; } diff --git a/apps/opencs/view/world/nestedtable.cpp b/apps/opencs/view/world/nestedtable.cpp index 997dbc2927..d56204d652 100644 --- a/apps/opencs/view/world/nestedtable.cpp +++ b/apps/opencs/view/world/nestedtable.cpp @@ -1,51 +1,45 @@ #include "nestedtable.hpp" -#include #include +#include #include #include "../../model/prefs/shortcut.hpp" -#include "../../model/world/nestedtableproxymodel.hpp" -#include "../../model/world/universalid.hpp" -#include "../../model/world/commands.hpp" #include "../../model/world/commanddispatcher.hpp" #include "../../model/world/commandmacro.hpp" +#include "../../model/world/commands.hpp" +#include "../../model/world/nestedtableproxymodel.hpp" +#include "../../model/world/universalid.hpp" #include "tableeditidaction.hpp" #include "util.hpp" -CSVWorld::NestedTable::NestedTable(CSMDoc::Document& document, - CSMWorld::UniversalId id, - CSMWorld::NestedTableProxyModel* model, - QWidget* parent, - bool editable, - bool fixedRows) - : DragRecordTable(document, parent), - mAddNewRowAction(nullptr), - mRemoveRowAction(nullptr), - mEditIdAction(nullptr), - mModel(model) +CSVWorld::NestedTable::NestedTable(CSMDoc::Document& document, CSMWorld::UniversalId id, + CSMWorld::NestedTableProxyModel* model, QWidget* parent, bool editable, bool fixedRows) + : DragRecordTable(document, parent) + , mAddNewRowAction(nullptr) + , mRemoveRowAction(nullptr) + , mEditIdAction(nullptr) + , mModel(model) { - mDispatcher = new CSMWorld::CommandDispatcher (document, id, this); + mDispatcher = new CSMWorld::CommandDispatcher(document, id, this); - setSelectionBehavior (QAbstractItemView::SelectRows); - setSelectionMode (QAbstractItemView::ExtendedSelection); + setSelectionBehavior(QAbstractItemView::SelectRows); + setSelectionMode(QAbstractItemView::ExtendedSelection); - horizontalHeader()->setSectionResizeMode (QHeaderView::Interactive); + horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); verticalHeader()->hide(); int columns = model->columnCount(QModelIndex()); - for(int i = 0 ; i < columns; ++i) + for (int i = 0; i < columns; ++i) { - CSMWorld::ColumnBase::Display display = static_cast ( - model->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); + CSMWorld::ColumnBase::Display display = static_cast( + model->headerData(i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); - CommandDelegate *delegate = CommandDelegateFactoryCollection::get().makeDelegate(display, - mDispatcher, - document, - this); + CommandDelegate* delegate + = CommandDelegateFactoryCollection::get().makeDelegate(display, mDispatcher, document, this); setItemDelegateForColumn(i, delegate); } @@ -56,15 +50,13 @@ CSVWorld::NestedTable::NestedTable(CSMDoc::Document& document, { if (!fixedRows) { - mAddNewRowAction = new QAction (tr ("Add new row"), this); - connect(mAddNewRowAction, &QAction::triggered, - this, &NestedTable::addNewRowActionTriggered); + mAddNewRowAction = new QAction(tr("Add new row"), this); + connect(mAddNewRowAction, &QAction::triggered, this, &NestedTable::addNewRowActionTriggered); CSMPrefs::Shortcut* addRowShortcut = new CSMPrefs::Shortcut("table-add", this); addRowShortcut->associateAction(mAddNewRowAction); - mRemoveRowAction = new QAction (tr ("Remove rows"), this); - connect(mRemoveRowAction, &QAction::triggered, - this, &NestedTable::removeRowActionTriggered); + mRemoveRowAction = new QAction(tr("Remove rows"), this); + connect(mRemoveRowAction, &QAction::triggered, this, &NestedTable::removeRowActionTriggered); CSMPrefs::Shortcut* removeRowShortcut = new CSMPrefs::Shortcut("table-remove", this); removeRowShortcut->associateAction(mRemoveRowAction); } @@ -80,7 +72,7 @@ std::vector CSVWorld::NestedTable::getDraggedRecords() co return std::vector(); } -void CSVWorld::NestedTable::contextMenuEvent (QContextMenuEvent *event) +void CSVWorld::NestedTable::contextMenuEvent(QContextMenuEvent* event) { if (!mEditIdAction) return; @@ -104,13 +96,13 @@ void CSVWorld::NestedTable::contextMenuEvent (QContextMenuEvent *event) menu.addAction(mRemoveRowAction); } - menu.exec (event->globalPos()); + menu.exec(event->globalPos()); } void CSVWorld::NestedTable::removeRowActionTriggered() { - CSMWorld::CommandMacro macro(mDocument.getUndoStack(), - selectionModel()->selectedRows().size() > 1 ? tr("Remove rows") : ""); + CSMWorld::CommandMacro macro( + mDocument.getUndoStack(), selectionModel()->selectedRows().size() > 1 ? tr("Remove rows") : ""); // Remove rows in reverse order for (int i = selectionModel()->selectedRows().size() - 1; i >= 0; --i) @@ -127,10 +119,8 @@ void CSVWorld::NestedTable::addNewRowActionTriggered() if (!selectionModel()->selectedRows().empty()) row = selectionModel()->selectedRows().back().row() + 1; - mDocument.getUndoStack().push(new CSMWorld::AddNestedCommand(*(mModel->model()), - mModel->getParentId(), - row, - mModel->getParentColumn())); + mDocument.getUndoStack().push( + new CSMWorld::AddNestedCommand(*(mModel->model()), mModel->getParentId(), row, mModel->getParentColumn())); } void CSVWorld::NestedTable::editCell() diff --git a/apps/opencs/view/world/nestedtable.hpp b/apps/opencs/view/world/nestedtable.hpp index da4afe6420..e53bc31f94 100644 --- a/apps/opencs/view/world/nestedtable.hpp +++ b/apps/opencs/view/world/nestedtable.hpp @@ -26,24 +26,20 @@ namespace CSVWorld { Q_OBJECT - QAction *mAddNewRowAction; - QAction *mRemoveRowAction; - TableEditIdAction *mEditIdAction; + QAction* mAddNewRowAction; + QAction* mRemoveRowAction; + TableEditIdAction* mEditIdAction; CSMWorld::NestedTableProxyModel* mModel; - CSMWorld::CommandDispatcher *mDispatcher; + CSMWorld::CommandDispatcher* mDispatcher; public: - NestedTable(CSMDoc::Document& document, - CSMWorld::UniversalId id, - CSMWorld::NestedTableProxyModel* model, - QWidget* parent = nullptr, - bool editable = true, - bool fixedRows = false); + NestedTable(CSMDoc::Document& document, CSMWorld::UniversalId id, CSMWorld::NestedTableProxyModel* model, + QWidget* parent = nullptr, bool editable = true, bool fixedRows = false); std::vector getDraggedRecords() const override; private: - void contextMenuEvent (QContextMenuEvent *event) override; + void contextMenuEvent(QContextMenuEvent* event) override; private slots: void removeRowActionTriggered(); @@ -53,7 +49,7 @@ namespace CSVWorld void editCell(); signals: - void editRequest(const CSMWorld::UniversalId &id, const std::string &hint); + void editRequest(const CSMWorld::UniversalId& id, const std::string& hint); }; } diff --git a/apps/opencs/view/world/pathgridcreator.cpp b/apps/opencs/view/world/pathgridcreator.cpp index a685fbb14c..9a8b51199d 100644 --- a/apps/opencs/view/world/pathgridcreator.cpp +++ b/apps/opencs/view/world/pathgridcreator.cpp @@ -18,21 +18,16 @@ std::string CSVWorld::PathgridCreator::getId() const CSMWorld::IdTable& CSVWorld::PathgridCreator::getPathgridsTable() const { - return dynamic_cast ( - *getData().getTableModel(getCollectionId()) - ); + return dynamic_cast(*getData().getTableModel(getCollectionId())); } -CSVWorld::PathgridCreator::PathgridCreator( - CSMWorld::Data& data, - QUndoStack& undoStack, - const CSMWorld::UniversalId& id, - CSMWorld::IdCompletionManager& completionManager -) : GenericCreator(data, undoStack, id) +CSVWorld::PathgridCreator::PathgridCreator(CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id, + CSMWorld::IdCompletionManager& completionManager) + : GenericCreator(data, undoStack, id) { setManualEditing(false); - QLabel *label = new QLabel("Cell", this); + QLabel* label = new QLabel("Cell", this); insertBeforeButtons(label, false); // Add cell ID input with auto-completion. @@ -46,9 +41,7 @@ CSVWorld::PathgridCreator::PathgridCreator( connect(mCell, &CSVWidget::DropLineEdit::returnPressed, this, &PathgridCreator::inputReturnPressed); } -void CSVWorld::PathgridCreator::cloneMode( - const std::string& originId, - const CSMWorld::UniversalId::Type type) +void CSVWorld::PathgridCreator::cloneMode(const std::string& originId, const CSMWorld::UniversalId::Type type) { CSVWorld::GenericCreator::cloneMode(originId, type); @@ -96,14 +89,8 @@ void CSVWorld::PathgridCreator::cellChanged() update(); } -CSVWorld::Creator *CSVWorld::PathgridCreatorFactory::makeCreator( - CSMDoc::Document& document, - const CSMWorld::UniversalId& id) const +CSVWorld::Creator* CSVWorld::PathgridCreatorFactory::makeCreator( + CSMDoc::Document& document, const CSMWorld::UniversalId& id) const { - return new PathgridCreator( - document.getData(), - document.getUndoStack(), - id, - document.getIdCompletionManager() - ); + return new PathgridCreator(document.getData(), document.getUndoStack(), id, document.getIdCompletionManager()); } diff --git a/apps/opencs/view/world/pathgridcreator.hpp b/apps/opencs/view/world/pathgridcreator.hpp index 773735e25c..42a39cd504 100644 --- a/apps/opencs/view/world/pathgridcreator.hpp +++ b/apps/opencs/view/world/pathgridcreator.hpp @@ -28,54 +28,44 @@ namespace CSVWorld { Q_OBJECT - CSVWidget::DropLineEdit *mCell; + CSVWidget::DropLineEdit* mCell; - private: + private: + /// \return Cell ID entered by user. + std::string getId() const override; - /// \return Cell ID entered by user. - std::string getId() const override; + /// \return reference to table containing pathgrids. + CSMWorld::IdTable& getPathgridsTable() const; - /// \return reference to table containing pathgrids. - CSMWorld::IdTable& getPathgridsTable() const; + public: + PathgridCreator(CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id, + CSMWorld::IdCompletionManager& completionManager); - public: + /// \brief Set cell ID input widget to ID of record to be cloned. + /// \param originId Cell ID to be cloned. + /// \param type Type of record to be cloned. + void cloneMode(const std::string& originId, const CSMWorld::UniversalId::Type type) override; - PathgridCreator( - CSMWorld::Data& data, - QUndoStack& undoStack, - const CSMWorld::UniversalId& id, - CSMWorld::IdCompletionManager& completionManager); + /// \return Error description for current user input. + std::string getErrors() const override; - /// \brief Set cell ID input widget to ID of record to be cloned. - /// \param originId Cell ID to be cloned. - /// \param type Type of record to be cloned. - void cloneMode( - const std::string& originId, - const CSMWorld::UniversalId::Type type) override; + /// \brief Set focus to cell ID input widget. + void focus() override; - /// \return Error description for current user input. - std::string getErrors() const override; + /// \brief Clear cell ID input widget. + void reset() override; - /// \brief Set focus to cell ID input widget. - void focus() override; + private slots: - /// \brief Clear cell ID input widget. - void reset() override; - - private slots: - - /// \brief Check user input for errors. - void cellChanged(); + /// \brief Check user input for errors. + void cellChanged(); }; /// \brief Creator factory for pathgrid record creator. class PathgridCreatorFactory : public CreatorFactoryBase { - public: - - Creator *makeCreator( - CSMDoc::Document& document, - const CSMWorld::UniversalId& id) const override; + public: + Creator* makeCreator(CSMDoc::Document& document, const CSMWorld::UniversalId& id) const override; }; } diff --git a/apps/opencs/view/world/previewsubview.cpp b/apps/opencs/view/world/previewsubview.cpp index 151824790a..075c786c2b 100644 --- a/apps/opencs/view/world/previewsubview.cpp +++ b/apps/opencs/view/world/previewsubview.cpp @@ -9,66 +9,63 @@ #include "../../model/doc/document.hpp" -CSVWorld::PreviewSubView::PreviewSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) -: SubView (id), mTitle (id.toString().c_str()) +CSVWorld::PreviewSubView::PreviewSubView(const CSMWorld::UniversalId& id, CSMDoc::Document& document) + : SubView(id) + , mTitle(id.toString().c_str()) { - QHBoxLayout *layout = new QHBoxLayout; + QHBoxLayout* layout = new QHBoxLayout; - if (document.getData().getReferenceables().searchId (id.getId())==-1) + if (document.getData().getReferenceables().searchId(id.getId()) == -1) { - std::string referenceableId = - document.getData().getReferences().getRecord (id.getId()).get().mRefID; + std::string referenceableId = document.getData().getReferences().getRecord(id.getId()).get().mRefID; - referenceableIdChanged (referenceableId); + referenceableIdChanged(referenceableId); - mScene = - new CSVRender::PreviewWidget (document.getData(), id.getId(), false, this); + mScene = new CSVRender::PreviewWidget(document.getData(), id.getId(), false, this); } else - mScene = new CSVRender::PreviewWidget (document.getData(), id.getId(), true, this); + mScene = new CSVRender::PreviewWidget(document.getData(), id.getId(), true, this); mScene->setExterior(true); - CSVWidget::SceneToolbar *toolbar = new CSVWidget::SceneToolbar (48+6, this); + CSVWidget::SceneToolbar* toolbar = new CSVWidget::SceneToolbar(48 + 6, this); - CSVWidget::SceneToolMode *lightingTool = mScene->makeLightingSelector (toolbar); - toolbar->addTool (lightingTool); + CSVWidget::SceneToolMode* lightingTool = mScene->makeLightingSelector(toolbar); + toolbar->addTool(lightingTool); - layout->addWidget (toolbar, 0); + layout->addWidget(toolbar, 0); - layout->addWidget (mScene, 1); + layout->addWidget(mScene, 1); - QWidget *widget = new QWidget; + QWidget* widget = new QWidget; - widget->setLayout (layout); + widget->setLayout(layout); - setWidget (widget); + setWidget(widget); - connect (mScene, &CSVRender::PreviewWidget::closeRequest, - this, qOverload<>(&PreviewSubView::closeRequest)); - connect (mScene, &CSVRender::PreviewWidget::referenceableIdChanged, - this, &PreviewSubView::referenceableIdChanged); - connect (mScene, &CSVRender::PreviewWidget::focusToolbarRequest, - toolbar, qOverload<>(&CSVWidget::SceneToolbar::setFocus)); - connect (toolbar, &CSVWidget::SceneToolbar::focusSceneRequest, - mScene, qOverload<>(&CSVRender::PreviewWidget::setFocus)); + connect(mScene, &CSVRender::PreviewWidget::closeRequest, this, qOverload<>(&PreviewSubView::closeRequest)); + connect(mScene, &CSVRender::PreviewWidget::referenceableIdChanged, this, &PreviewSubView::referenceableIdChanged); + connect(mScene, &CSVRender::PreviewWidget::focusToolbarRequest, toolbar, + qOverload<>(&CSVWidget::SceneToolbar::setFocus)); + connect( + toolbar, &CSVWidget::SceneToolbar::focusSceneRequest, mScene, qOverload<>(&CSVRender::PreviewWidget::setFocus)); } -void CSVWorld::PreviewSubView::setEditLock (bool locked) {} +void CSVWorld::PreviewSubView::setEditLock(bool locked) {} std::string CSVWorld::PreviewSubView::getTitle() const { return mTitle; } -void CSVWorld::PreviewSubView::referenceableIdChanged (const std::string& id) +void CSVWorld::PreviewSubView::referenceableIdChanged(const std::string& id) { if (id.empty()) mTitle = "Preview: Reference to "; else mTitle = "Preview: Reference to " + id; - setWindowTitle (QString::fromUtf8 (mTitle.c_str())); + setWindowTitle(QString::fromUtf8(mTitle.c_str())); emit updateTitle(); } diff --git a/apps/opencs/view/world/previewsubview.hpp b/apps/opencs/view/world/previewsubview.hpp index ed88d04887..a767cc3365 100644 --- a/apps/opencs/view/world/previewsubview.hpp +++ b/apps/opencs/view/world/previewsubview.hpp @@ -17,22 +17,21 @@ namespace CSVWorld { class PreviewSubView : public CSVDoc::SubView { - Q_OBJECT + Q_OBJECT - CSVRender::PreviewWidget *mScene; - std::string mTitle; + CSVRender::PreviewWidget* mScene; + std::string mTitle; - public: + public: + PreviewSubView(const CSMWorld::UniversalId& id, CSMDoc::Document& document); - PreviewSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document); + void setEditLock(bool locked) override; - void setEditLock (bool locked) override; + std::string getTitle() const override; - std::string getTitle() const override; + private slots: - private slots: - - void referenceableIdChanged (const std::string& id); + void referenceableIdChanged(const std::string& id); }; } diff --git a/apps/opencs/view/world/recordbuttonbar.cpp b/apps/opencs/view/world/recordbuttonbar.cpp index 5df012144b..7e986877fa 100644 --- a/apps/opencs/view/world/recordbuttonbar.cpp +++ b/apps/opencs/view/world/recordbuttonbar.cpp @@ -3,8 +3,8 @@ #include #include -#include "../../model/world/idtable.hpp" #include "../../model/world/commanddispatcher.hpp" +#include "../../model/world/idtable.hpp" #include "../../model/prefs/state.hpp" @@ -14,147 +14,145 @@ void CSVWorld::RecordButtonBar::updateModificationButtons() { bool createAndDeleteDisabled = !mBottom || !mBottom->canCreateAndDelete() || mLocked; - mCloneButton->setDisabled (createAndDeleteDisabled); - mAddButton->setDisabled (createAndDeleteDisabled); + mCloneButton->setDisabled(createAndDeleteDisabled); + mAddButton->setDisabled(createAndDeleteDisabled); bool commandDisabled = !mCommandDispatcher || mLocked; - mRevertButton->setDisabled (commandDisabled); - mDeleteButton->setDisabled (commandDisabled || createAndDeleteDisabled); + mRevertButton->setDisabled(commandDisabled); + mDeleteButton->setDisabled(commandDisabled || createAndDeleteDisabled); } void CSVWorld::RecordButtonBar::updatePrevNextButtons() { int rows = mTable.rowCount(); - if (rows<=1) + if (rows <= 1) { - mPrevButton->setDisabled (true); - mNextButton->setDisabled (true); + mPrevButton->setDisabled(true); + mNextButton->setDisabled(true); } else if (CSMPrefs::get()["General Input"]["cycle"].isTrue()) { - mPrevButton->setDisabled (false); - mNextButton->setDisabled (false); + mPrevButton->setDisabled(false); + mNextButton->setDisabled(false); } else { - int row = mTable.getModelIndex (mId.getId(), 0).row(); + int row = mTable.getModelIndex(mId.getId(), 0).row(); - mPrevButton->setDisabled (row<=0); - mNextButton->setDisabled (row>=rows-1); + mPrevButton->setDisabled(row <= 0); + mNextButton->setDisabled(row >= rows - 1); } } -CSVWorld::RecordButtonBar::RecordButtonBar (const CSMWorld::UniversalId& id, - CSMWorld::IdTable& table, TableBottomBox *bottomBox, - CSMWorld::CommandDispatcher *commandDispatcher, QWidget *parent) -: QWidget (parent), mId (id), mTable (table), mBottom (bottomBox), - mCommandDispatcher (commandDispatcher), mLocked (false) +CSVWorld::RecordButtonBar::RecordButtonBar(const CSMWorld::UniversalId& id, CSMWorld::IdTable& table, + TableBottomBox* bottomBox, CSMWorld::CommandDispatcher* commandDispatcher, QWidget* parent) + : QWidget(parent) + , mId(id) + , mTable(table) + , mBottom(bottomBox) + , mCommandDispatcher(commandDispatcher) + , mLocked(false) { - QHBoxLayout *buttonsLayout = new QHBoxLayout; - buttonsLayout->setContentsMargins (0, 0, 0, 0); + QHBoxLayout* buttonsLayout = new QHBoxLayout; + buttonsLayout->setContentsMargins(0, 0, 0, 0); // left section - mPrevButton = new QToolButton (this); + mPrevButton = new QToolButton(this); mPrevButton->setIcon(QIcon(":record-previous")); - mPrevButton->setToolTip ("Switch to previous record"); - buttonsLayout->addWidget (mPrevButton, 0); + mPrevButton->setToolTip("Switch to previous record"); + buttonsLayout->addWidget(mPrevButton, 0); - mNextButton = new QToolButton (this); + mNextButton = new QToolButton(this); mNextButton->setIcon(QIcon(":/record-next")); - mNextButton->setToolTip ("Switch to next record"); - buttonsLayout->addWidget (mNextButton, 1); + mNextButton->setToolTip("Switch to next record"); + buttonsLayout->addWidget(mNextButton, 1); buttonsLayout->addStretch(2); // optional buttons of the right section if (mTable.getFeatures() & CSMWorld::IdTable::Feature_Preview) { - QToolButton* previewButton = new QToolButton (this); + QToolButton* previewButton = new QToolButton(this); previewButton->setIcon(QIcon(":edit-preview")); - previewButton->setToolTip ("Open a preview of this record"); + previewButton->setToolTip("Open a preview of this record"); buttonsLayout->addWidget(previewButton); - connect (previewButton, &QToolButton::clicked, this, &RecordButtonBar::showPreview); + connect(previewButton, &QToolButton::clicked, this, &RecordButtonBar::showPreview); } if (mTable.getFeatures() & CSMWorld::IdTable::Feature_View) { - QToolButton* viewButton = new QToolButton (this); + QToolButton* viewButton = new QToolButton(this); viewButton->setIcon(QIcon(":/cell.png")); - viewButton->setToolTip ("Open a scene view of the cell this record is located in"); + viewButton->setToolTip("Open a scene view of the cell this record is located in"); buttonsLayout->addWidget(viewButton); - connect (viewButton, &QToolButton::clicked, this, &RecordButtonBar::viewRecord); + connect(viewButton, &QToolButton::clicked, this, &RecordButtonBar::viewRecord); } // right section - mCloneButton = new QToolButton (this); + mCloneButton = new QToolButton(this); mCloneButton->setIcon(QIcon(":edit-clone")); - mCloneButton->setToolTip ("Clone record"); + mCloneButton->setToolTip("Clone record"); buttonsLayout->addWidget(mCloneButton); - mAddButton = new QToolButton (this); + mAddButton = new QToolButton(this); mAddButton->setIcon(QIcon(":edit-add")); - mAddButton->setToolTip ("Add new record"); + mAddButton->setToolTip("Add new record"); buttonsLayout->addWidget(mAddButton); - mDeleteButton = new QToolButton (this); + mDeleteButton = new QToolButton(this); mDeleteButton->setIcon(QIcon(":edit-delete")); - mDeleteButton->setToolTip ("Delete record"); + mDeleteButton->setToolTip("Delete record"); buttonsLayout->addWidget(mDeleteButton); - mRevertButton = new QToolButton (this); + mRevertButton = new QToolButton(this); mRevertButton->setIcon(QIcon(":edit-undo")); - mRevertButton->setToolTip ("Revert record"); + mRevertButton->setToolTip("Revert record"); buttonsLayout->addWidget(mRevertButton); - setLayout (buttonsLayout); + setLayout(buttonsLayout); // connections - if(mBottom && mBottom->canCreateAndDelete()) + if (mBottom && mBottom->canCreateAndDelete()) { - connect (mAddButton, &QToolButton::clicked, mBottom, &TableBottomBox::createRequest); - connect (mCloneButton, &QToolButton::clicked, this, &RecordButtonBar::cloneRequest); + connect(mAddButton, &QToolButton::clicked, mBottom, &TableBottomBox::createRequest); + connect(mCloneButton, &QToolButton::clicked, this, &RecordButtonBar::cloneRequest); } - connect (mNextButton, &QToolButton::clicked, this, &RecordButtonBar::nextId); - connect (mPrevButton, &QToolButton::clicked, this, &RecordButtonBar::prevId); + connect(mNextButton, &QToolButton::clicked, this, &RecordButtonBar::nextId); + connect(mPrevButton, &QToolButton::clicked, this, &RecordButtonBar::prevId); if (mCommandDispatcher) { - connect (mRevertButton, &QToolButton::clicked, - mCommandDispatcher, &CSMWorld::CommandDispatcher::executeRevert); - connect (mDeleteButton, &QToolButton::clicked, - mCommandDispatcher, &CSMWorld::CommandDispatcher::executeDelete); + connect(mRevertButton, &QToolButton::clicked, mCommandDispatcher, &CSMWorld::CommandDispatcher::executeRevert); + connect(mDeleteButton, &QToolButton::clicked, mCommandDispatcher, &CSMWorld::CommandDispatcher::executeDelete); } - connect (&mTable, &CSMWorld::IdTable::rowsInserted, - this, &RecordButtonBar::rowNumberChanged); - connect (&mTable, &CSMWorld::IdTable::rowsRemoved, - this, &RecordButtonBar::rowNumberChanged); + connect(&mTable, &CSMWorld::IdTable::rowsInserted, this, &RecordButtonBar::rowNumberChanged); + connect(&mTable, &CSMWorld::IdTable::rowsRemoved, this, &RecordButtonBar::rowNumberChanged); - connect (&CSMPrefs::State::get(), &CSMPrefs::State::settingChanged, - this, &RecordButtonBar::settingChanged); + connect(&CSMPrefs::State::get(), &CSMPrefs::State::settingChanged, this, &RecordButtonBar::settingChanged); updateModificationButtons(); updatePrevNextButtons(); } -void CSVWorld::RecordButtonBar::setEditLock (bool locked) +void CSVWorld::RecordButtonBar::setEditLock(bool locked) { mLocked = locked; updateModificationButtons(); } -void CSVWorld::RecordButtonBar::universalIdChanged (const CSMWorld::UniversalId& id) +void CSVWorld::RecordButtonBar::universalIdChanged(const CSMWorld::UniversalId& id) { mId = id; updatePrevNextButtons(); } -void CSVWorld::RecordButtonBar::settingChanged (const CSMPrefs::Setting *setting) +void CSVWorld::RecordButtonBar::settingChanged(const CSMPrefs::Setting* setting) { - if (*setting=="General Input/cycle") + if (*setting == "General Input/cycle") updatePrevNextButtons(); } @@ -162,19 +160,18 @@ void CSVWorld::RecordButtonBar::cloneRequest() { if (mBottom) { - int typeColumn = mTable.findColumnIndex (CSMWorld::Columns::ColumnId_RecordType); + int typeColumn = mTable.findColumnIndex(CSMWorld::Columns::ColumnId_RecordType); - QModelIndex typeIndex = mTable.getModelIndex (mId.getId(), typeColumn); - CSMWorld::UniversalId::Type type = static_cast ( - mTable.data (typeIndex).toInt()); + QModelIndex typeIndex = mTable.getModelIndex(mId.getId(), typeColumn); + CSMWorld::UniversalId::Type type = static_cast(mTable.data(typeIndex).toInt()); - mBottom->cloneRequest (mId.getId(), type); + mBottom->cloneRequest(mId.getId(), type); } } void CSVWorld::RecordButtonBar::nextId() { - int newRow = mTable.getModelIndex (mId.getId(), 0).row() + 1; + int newRow = mTable.getModelIndex(mId.getId(), 0).row() + 1; if (newRow >= mTable.rowCount()) { @@ -184,25 +181,25 @@ void CSVWorld::RecordButtonBar::nextId() return; } - emit switchToRow (newRow); + emit switchToRow(newRow); } void CSVWorld::RecordButtonBar::prevId() { - int newRow = mTable.getModelIndex (mId.getId(), 0).row() - 1; + int newRow = mTable.getModelIndex(mId.getId(), 0).row() - 1; if (newRow < 0) { if (CSMPrefs::get()["General Input"]["cycle"].isTrue()) - newRow = mTable.rowCount()-1; + newRow = mTable.rowCount() - 1; else return; } - emit switchToRow (newRow); + emit switchToRow(newRow); } -void CSVWorld::RecordButtonBar::rowNumberChanged (const QModelIndex& parent, int start, int end) +void CSVWorld::RecordButtonBar::rowNumberChanged(const QModelIndex& parent, int start, int end) { updatePrevNextButtons(); } diff --git a/apps/opencs/view/world/recordbuttonbar.hpp b/apps/opencs/view/world/recordbuttonbar.hpp index aca3211f8a..605738670c 100644 --- a/apps/opencs/view/world/recordbuttonbar.hpp +++ b/apps/opencs/view/world/recordbuttonbar.hpp @@ -35,57 +35,54 @@ namespace CSVWorld /// - view (optional) class RecordButtonBar : public QWidget { - Q_OBJECT + Q_OBJECT - CSMWorld::UniversalId mId; - CSMWorld::IdTable& mTable; - TableBottomBox *mBottom; - CSMWorld::CommandDispatcher *mCommandDispatcher; - QToolButton *mPrevButton; - QToolButton *mNextButton; - QToolButton *mCloneButton; - QToolButton *mAddButton; - QToolButton *mDeleteButton; - QToolButton *mRevertButton; - bool mLocked; + CSMWorld::UniversalId mId; + CSMWorld::IdTable& mTable; + TableBottomBox* mBottom; + CSMWorld::CommandDispatcher* mCommandDispatcher; + QToolButton* mPrevButton; + QToolButton* mNextButton; + QToolButton* mCloneButton; + QToolButton* mAddButton; + QToolButton* mDeleteButton; + QToolButton* mRevertButton; + bool mLocked; - private: + private: + void updateModificationButtons(); - void updateModificationButtons(); + void updatePrevNextButtons(); - void updatePrevNextButtons(); + public: + RecordButtonBar(const CSMWorld::UniversalId& id, CSMWorld::IdTable& table, TableBottomBox* bottomBox = nullptr, + CSMWorld::CommandDispatcher* commandDispatcher = nullptr, QWidget* parent = nullptr); - public: + void setEditLock(bool locked); - RecordButtonBar (const CSMWorld::UniversalId& id, - CSMWorld::IdTable& table, TableBottomBox *bottomBox = nullptr, - CSMWorld::CommandDispatcher *commandDispatcher = nullptr, QWidget *parent = nullptr); + public slots: - void setEditLock (bool locked); + void universalIdChanged(const CSMWorld::UniversalId& id); - public slots: + private slots: - void universalIdChanged (const CSMWorld::UniversalId& id); + void settingChanged(const CSMPrefs::Setting* setting); - private slots: + void cloneRequest(); - void settingChanged (const CSMPrefs::Setting *setting); + void nextId(); - void cloneRequest(); + void prevId(); - void nextId(); + void rowNumberChanged(const QModelIndex& parent, int start, int end); - void prevId(); + signals: - void rowNumberChanged (const QModelIndex& parent, int start, int end); + void showPreview(); - signals: + void viewRecord(); - void showPreview(); - - void viewRecord(); - - void switchToRow (int row); + void switchToRow(int row); }; } diff --git a/apps/opencs/view/world/recordstatusdelegate.cpp b/apps/opencs/view/world/recordstatusdelegate.cpp index dd45baff0f..8804d8c177 100644 --- a/apps/opencs/view/world/recordstatusdelegate.cpp +++ b/apps/opencs/view/world/recordstatusdelegate.cpp @@ -2,33 +2,29 @@ #include "../../model/world/columns.hpp" -CSVWorld::RecordStatusDelegate::RecordStatusDelegate(const ValueList& values, - const IconList & icons, - CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) - : DataDisplayDelegate (values, icons, dispatcher, document, - "Records", "status-format", - parent) -{} +CSVWorld::RecordStatusDelegate::RecordStatusDelegate(const ValueList& values, const IconList& icons, + CSMWorld::CommandDispatcher* dispatcher, CSMDoc::Document& document, QObject* parent) + : DataDisplayDelegate(values, icons, dispatcher, document, "Records", "status-format", parent) +{ +} -CSVWorld::CommandDelegate *CSVWorld::RecordStatusDelegateFactory::makeDelegate ( - CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) const +CSVWorld::CommandDelegate* CSVWorld::RecordStatusDelegateFactory::makeDelegate( + CSMWorld::CommandDispatcher* dispatcher, CSMDoc::Document& document, QObject* parent) const { - return new RecordStatusDelegate (mValues, mIcons, dispatcher, document, parent); + return new RecordStatusDelegate(mValues, mIcons, dispatcher, document, parent); } CSVWorld::RecordStatusDelegateFactory::RecordStatusDelegateFactory() { - std::vector> enums = - CSMWorld::Columns::getEnums (CSMWorld::Columns::ColumnId_Modification); + std::vector> enums + = CSMWorld::Columns::getEnums(CSMWorld::Columns::ColumnId_Modification); - static const char *sIcons[] = - { - ":list-base", ":list-modified", ":list-added", ":list-removed", ":list-removed", 0 - }; + static const char* sIcons[] + = { ":list-base", ":list-modified", ":list-added", ":list-removed", ":list-removed", 0 }; - for (int i=0; sIcons[i]; ++i) + for (int i = 0; sIcons[i]; ++i) { auto& enumPair = enums.at(i); - add (enumPair.first, enumPair.second.c_str(), sIcons[i]); + add(enumPair.first, enumPair.second.c_str(), sIcons[i]); } } diff --git a/apps/opencs/view/world/recordstatusdelegate.hpp b/apps/opencs/view/world/recordstatusdelegate.hpp index e70e1af26b..a3aa9f5d50 100644 --- a/apps/opencs/view/world/recordstatusdelegate.hpp +++ b/apps/opencs/view/world/recordstatusdelegate.hpp @@ -13,22 +13,18 @@ namespace CSVWorld class RecordStatusDelegate : public DataDisplayDelegate { public: - - RecordStatusDelegate (const ValueList& values, const IconList& icons, - CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, - QObject *parent = nullptr); + RecordStatusDelegate(const ValueList& values, const IconList& icons, CSMWorld::CommandDispatcher* dispatcher, + CSMDoc::Document& document, QObject* parent = nullptr); }; class RecordStatusDelegateFactory : public DataDisplayDelegateFactory { - public: - - RecordStatusDelegateFactory(); - - CommandDelegate *makeDelegate (CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) const override; - ///< The ownership of the returned CommandDelegate is transferred to the caller. + public: + RecordStatusDelegateFactory(); + CommandDelegate* makeDelegate( + CSMWorld::CommandDispatcher* dispatcher, CSMDoc::Document& document, QObject* parent) const override; + ///< The ownership of the returned CommandDelegate is transferred to the caller. }; } #endif // RECORDSTATUSDELEGATE_HPP - diff --git a/apps/opencs/view/world/referenceablecreator.cpp b/apps/opencs/view/world/referenceablecreator.cpp index eb699fd777..48227397a0 100644 --- a/apps/opencs/view/world/referenceablecreator.cpp +++ b/apps/opencs/view/world/referenceablecreator.cpp @@ -3,78 +3,64 @@ #include #include -#include "../../model/world/universalid.hpp" #include "../../model/world/commands.hpp" +#include "../../model/world/universalid.hpp" -void CSVWorld::ReferenceableCreator::configureCreateCommand (CSMWorld::CreateCommand& command) const +void CSVWorld::ReferenceableCreator::configureCreateCommand(CSMWorld::CreateCommand& command) const { - command.setType ( - static_cast (mType->itemData (mType->currentIndex()).toInt())); + command.setType(static_cast(mType->itemData(mType->currentIndex()).toInt())); } -CSVWorld::ReferenceableCreator::ReferenceableCreator (CSMWorld::Data& data, QUndoStack& undoStack, - const CSMWorld::UniversalId& id) -: GenericCreator (data, undoStack, id) +CSVWorld::ReferenceableCreator::ReferenceableCreator( + CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id) + : GenericCreator(data, undoStack, id) { - QLabel *label = new QLabel ("Type", this); - insertBeforeButtons (label, false); + QLabel* label = new QLabel("Type", this); + insertBeforeButtons(label, false); std::vector types = CSMWorld::UniversalId::listReferenceableTypes(); - mType = new QComboBox (this); + mType = new QComboBox(this); mType->setMaxVisibleItems(20); - for (std::vector::const_iterator iter (types.begin()); - iter!=types.end(); ++iter) + for (std::vector::const_iterator iter(types.begin()); iter != types.end(); ++iter) { - CSMWorld::UniversalId id2 (*iter, ""); + CSMWorld::UniversalId id2(*iter, ""); - mType->addItem (QIcon (id2.getIcon().c_str()), id2.getTypeName().c_str(), - static_cast (id2.getType())); + mType->addItem(QIcon(id2.getIcon().c_str()), id2.getTypeName().c_str(), static_cast(id2.getType())); } mType->model()->sort(0); - insertBeforeButtons (mType, false); + insertBeforeButtons(mType, false); - connect (mType, qOverload(&QComboBox::currentIndexChanged), this, &ReferenceableCreator::setType); + connect(mType, qOverload(&QComboBox::currentIndexChanged), this, &ReferenceableCreator::setType); } void CSVWorld::ReferenceableCreator::reset() { - mType->setCurrentIndex (0); + mType->setCurrentIndex(0); GenericCreator::reset(); } -void CSVWorld::ReferenceableCreator::setType (int index) +void CSVWorld::ReferenceableCreator::setType(int index) { // container items have name limit of 32 characters std::string text = mType->currentText().toStdString(); - if (text == "Potion" || - text == "Apparatus" || - text == "Armor" || - text == "Book" || - text == "Clothing" || - text == "Ingredient" || - text == "ItemLevelledList" || - text == "Light" || - text == "Lockpick" || - text == "Miscellaneous" || - text == "Probe" || - text == "Repair" || - text == "Weapon") + if (text == "Potion" || text == "Apparatus" || text == "Armor" || text == "Book" || text == "Clothing" + || text == "Ingredient" || text == "ItemLevelledList" || text == "Light" || text == "Lockpick" + || text == "Miscellaneous" || text == "Probe" || text == "Repair" || text == "Weapon") { - GenericCreator::setEditorMaxLength (32); + GenericCreator::setEditorMaxLength(32); } else - GenericCreator::setEditorMaxLength (32767); + GenericCreator::setEditorMaxLength(32767); } -void CSVWorld::ReferenceableCreator::cloneMode (const std::string& originId, - const CSMWorld::UniversalId::Type type) +void CSVWorld::ReferenceableCreator::cloneMode(const std::string& originId, const CSMWorld::UniversalId::Type type) { - GenericCreator::cloneMode (originId, type); - mType->setCurrentIndex (mType->findData (static_cast (type))); + GenericCreator::cloneMode(originId, type); + mType->setCurrentIndex(mType->findData(static_cast(type))); } void CSVWorld::ReferenceableCreator::toggleWidgets(bool active) diff --git a/apps/opencs/view/world/referenceablecreator.hpp b/apps/opencs/view/world/referenceablecreator.hpp index 354347cc88..15ad4f6865 100644 --- a/apps/opencs/view/world/referenceablecreator.hpp +++ b/apps/opencs/view/world/referenceablecreator.hpp @@ -9,29 +9,25 @@ namespace CSVWorld { class ReferenceableCreator : public GenericCreator { - Q_OBJECT + Q_OBJECT - QComboBox *mType; + QComboBox* mType; - private: + private: + void configureCreateCommand(CSMWorld::CreateCommand& command) const override; - void configureCreateCommand (CSMWorld::CreateCommand& command) const override; + public: + ReferenceableCreator(CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id); - public: + void reset() override; - ReferenceableCreator (CSMWorld::Data& data, QUndoStack& undoStack, - const CSMWorld::UniversalId& id); + void cloneMode(const std::string& originId, const CSMWorld::UniversalId::Type type) override; - void reset() override; + void toggleWidgets(bool active = true) override; - void cloneMode (const std::string& originId, - const CSMWorld::UniversalId::Type type) override; + private slots: - void toggleWidgets(bool active = true) override; - - private slots: - - void setType (int index); + void setType(int index); }; } diff --git a/apps/opencs/view/world/referencecreator.cpp b/apps/opencs/view/world/referencecreator.cpp index 62035e9117..334f140fcc 100644 --- a/apps/opencs/view/world/referencecreator.cpp +++ b/apps/opencs/view/world/referencecreator.cpp @@ -4,12 +4,12 @@ #include "../../model/doc/document.hpp" -#include "../../model/world/data.hpp" -#include "../../model/world/commands.hpp" #include "../../model/world/columns.hpp" -#include "../../model/world/idtable.hpp" -#include "../../model/world/idcompletionmanager.hpp" #include "../../model/world/commandmacro.hpp" +#include "../../model/world/commands.hpp" +#include "../../model/world/data.hpp" +#include "../../model/world/idcompletionmanager.hpp" +#include "../../model/world/idtable.hpp" #include "../widget/droplineedit.hpp" @@ -18,39 +18,38 @@ std::string CSVWorld::ReferenceCreator::getId() const return mId; } -void CSVWorld::ReferenceCreator::configureCreateCommand (CSMWorld::CreateCommand& command) const +void CSVWorld::ReferenceCreator::configureCreateCommand(CSMWorld::CreateCommand& command) const { // Set cellID - int cellIdColumn = - dynamic_cast (*getData().getTableModel (getCollectionId())). - findColumnIndex (CSMWorld::Columns::ColumnId_Cell); + int cellIdColumn = dynamic_cast(*getData().getTableModel(getCollectionId())) + .findColumnIndex(CSMWorld::Columns::ColumnId_Cell); - command.addValue (cellIdColumn, mCell->text()); + command.addValue(cellIdColumn, mCell->text()); } -CSVWorld::ReferenceCreator::ReferenceCreator (CSMWorld::Data& data, QUndoStack& undoStack, - const CSMWorld::UniversalId& id, CSMWorld::IdCompletionManager &completionManager) -: GenericCreator (data, undoStack, id) +CSVWorld::ReferenceCreator::ReferenceCreator(CSMWorld::Data& data, QUndoStack& undoStack, + const CSMWorld::UniversalId& id, CSMWorld::IdCompletionManager& completionManager) + : GenericCreator(data, undoStack, id) { - QLabel *label = new QLabel ("Cell", this); - insertBeforeButtons (label, false); + QLabel* label = new QLabel("Cell", this); + insertBeforeButtons(label, false); // Add cell ID input with auto-completion. // Only existing cell IDs are accepted so no ID validation is performed. mCell = new CSVWidget::DropLineEdit(CSMWorld::ColumnBase::Display_Cell, this); mCell->setCompleter(completionManager.getCompleter(CSMWorld::ColumnBase::Display_Cell).get()); - insertBeforeButtons (mCell, true); + insertBeforeButtons(mCell, true); - setManualEditing (false); + setManualEditing(false); - connect (mCell, &CSVWidget::DropLineEdit::textChanged, this, &ReferenceCreator::cellChanged); - connect (mCell, &CSVWidget::DropLineEdit::returnPressed, this, &ReferenceCreator::inputReturnPressed); + connect(mCell, &CSVWidget::DropLineEdit::textChanged, this, &ReferenceCreator::cellChanged); + connect(mCell, &CSVWidget::DropLineEdit::returnPressed, this, &ReferenceCreator::inputReturnPressed); } void CSVWorld::ReferenceCreator::reset() { GenericCreator::reset(); - mCell->setText (""); + mCell->setText(""); mId = getData().getReferences().getNewId(); } @@ -64,7 +63,7 @@ std::string CSVWorld::ReferenceCreator::getErrors() const if (cell.empty()) errors += "Missing Cell ID"; - else if (getData().getCells().searchId (cell)==-1) + else if (getData().getCells().searchId(cell) == -1) errors += "Invalid Cell ID"; return errors; @@ -80,26 +79,21 @@ void CSVWorld::ReferenceCreator::cellChanged() update(); } -void CSVWorld::ReferenceCreator::cloneMode(const std::string& originId, - const CSMWorld::UniversalId::Type type) +void CSVWorld::ReferenceCreator::cloneMode(const std::string& originId, const CSMWorld::UniversalId::Type type) { - CSMWorld::IdTable& referenceTable = dynamic_cast ( - *getData().getTableModel (CSMWorld::UniversalId::Type_References)); + CSMWorld::IdTable& referenceTable + = dynamic_cast(*getData().getTableModel(CSMWorld::UniversalId::Type_References)); - int cellIdColumn = referenceTable.findColumnIndex (CSMWorld::Columns::ColumnId_Cell); + int cellIdColumn = referenceTable.findColumnIndex(CSMWorld::Columns::ColumnId_Cell); - mCell->setText ( - referenceTable.data (referenceTable.getModelIndex (originId, cellIdColumn)).toString()); + mCell->setText(referenceTable.data(referenceTable.getModelIndex(originId, cellIdColumn)).toString()); CSVWorld::GenericCreator::cloneMode(originId, type); - cellChanged(); //otherwise ok button will remain disabled + cellChanged(); // otherwise ok button will remain disabled } -CSVWorld::Creator *CSVWorld::ReferenceCreatorFactory::makeCreator (CSMDoc::Document& document, - const CSMWorld::UniversalId& id) const +CSVWorld::Creator* CSVWorld::ReferenceCreatorFactory::makeCreator( + CSMDoc::Document& document, const CSMWorld::UniversalId& id) const { - return new ReferenceCreator(document.getData(), - document.getUndoStack(), - id, - document.getIdCompletionManager()); + return new ReferenceCreator(document.getData(), document.getUndoStack(), id, document.getIdCompletionManager()); } diff --git a/apps/opencs/view/world/referencecreator.hpp b/apps/opencs/view/world/referencecreator.hpp index 3903900ad2..29135d6eb2 100644 --- a/apps/opencs/view/world/referencecreator.hpp +++ b/apps/opencs/view/world/referencecreator.hpp @@ -18,45 +18,41 @@ namespace CSVWorld class ReferenceCreator : public GenericCreator { - Q_OBJECT + Q_OBJECT - CSVWidget::DropLineEdit *mCell; - std::string mId; + CSVWidget::DropLineEdit* mCell; + std::string mId; - private: + private: + std::string getId() const override; - std::string getId() const override; + void configureCreateCommand(CSMWorld::CreateCommand& command) const override; - void configureCreateCommand (CSMWorld::CreateCommand& command) const override; + public: + ReferenceCreator(CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id, + CSMWorld::IdCompletionManager& completionManager); - public: + void cloneMode(const std::string& originId, const CSMWorld::UniversalId::Type type) override; - ReferenceCreator (CSMWorld::Data& data, QUndoStack& undoStack, - const CSMWorld::UniversalId& id, CSMWorld::IdCompletionManager &completionManager); + void reset() override; - void cloneMode(const std::string& originId, - const CSMWorld::UniversalId::Type type) override; + std::string getErrors() const override; + ///< Return formatted error descriptions for the current state of the creator. if an empty + /// string is returned, there is no error. - void reset() override; + /// Focus main input widget + void focus() override; - std::string getErrors() const override; - ///< Return formatted error descriptions for the current state of the creator. if an empty - /// string is returned, there is no error. + private slots: - /// Focus main input widget - void focus() override; - - private slots: - - void cellChanged(); + void cellChanged(); }; class ReferenceCreatorFactory : public CreatorFactoryBase { - public: - - Creator *makeCreator (CSMDoc::Document& document, const CSMWorld::UniversalId& id) const override; - ///< The ownership of the returned Creator is transferred to the caller. + public: + Creator* makeCreator(CSMDoc::Document& document, const CSMWorld::UniversalId& id) const override; + ///< The ownership of the returned Creator is transferred to the caller. }; } diff --git a/apps/opencs/view/world/regionmap.cpp b/apps/opencs/view/world/regionmap.cpp index 143b291074..6fe8b20c02 100644 --- a/apps/opencs/view/world/regionmap.cpp +++ b/apps/opencs/view/world/regionmap.cpp @@ -4,113 +4,112 @@ #include #include -#include #include +#include #include #include "../../model/doc/document.hpp" -#include "../../model/world/regionmap.hpp" -#include "../../model/world/universalid.hpp" +#include "../../model/world/columns.hpp" +#include "../../model/world/commandmacro.hpp" +#include "../../model/world/commands.hpp" #include "../../model/world/data.hpp" #include "../../model/world/idtable.hpp" -#include "../../model/world/commands.hpp" -#include "../../model/world/columns.hpp" +#include "../../model/world/regionmap.hpp" #include "../../model/world/tablemimedata.hpp" -#include "../../model/world/commandmacro.hpp" +#include "../../model/world/universalid.hpp" -void CSVWorld::RegionMap::contextMenuEvent (QContextMenuEvent *event) +void CSVWorld::RegionMap::contextMenuEvent(QContextMenuEvent* event) { - QMenu menu (this); + QMenu menu(this); - if (getUnselectedCells().size()>0) - menu.addAction (mSelectAllAction); + if (getUnselectedCells().size() > 0) + menu.addAction(mSelectAllAction); - if (selectionModel()->selectedIndexes().size()>0) - menu.addAction (mClearSelectionAction); + if (selectionModel()->selectedIndexes().size() > 0) + menu.addAction(mClearSelectionAction); - if (getMissingRegionCells().size()>0) - menu.addAction (mSelectRegionsAction); + if (getMissingRegionCells().size() > 0) + menu.addAction(mSelectRegionsAction); - int selectedNonExistentCells = getSelectedCells (false, true).size(); + int selectedNonExistentCells = getSelectedCells(false, true).size(); - if (selectedNonExistentCells>0) + if (selectedNonExistentCells > 0) { - if (selectedNonExistentCells==1) - mCreateCellsAction->setText ("Create one Cell"); + if (selectedNonExistentCells == 1) + mCreateCellsAction->setText("Create one Cell"); else { std::ostringstream stream; stream << "Create " << selectedNonExistentCells << " cells"; - mCreateCellsAction->setText (QString::fromUtf8 (stream.str().c_str())); + mCreateCellsAction->setText(QString::fromUtf8(stream.str().c_str())); } - menu.addAction (mCreateCellsAction); + menu.addAction(mCreateCellsAction); } - if (getSelectedCells().size()>0) + if (getSelectedCells().size() > 0) { if (!mRegionId.empty()) { - mSetRegionAction->setText (QString::fromUtf8 (("Set Region to " + mRegionId).c_str())); - menu.addAction (mSetRegionAction); + mSetRegionAction->setText(QString::fromUtf8(("Set Region to " + mRegionId).c_str())); + menu.addAction(mSetRegionAction); } - menu.addAction (mUnsetRegionAction); + menu.addAction(mUnsetRegionAction); - menu.addAction (mViewInTableAction); + menu.addAction(mViewInTableAction); } - if (selectionModel()->selectedIndexes().size()>0) - menu.addAction (mViewAction); + if (selectionModel()->selectedIndexes().size() > 0) + menu.addAction(mViewAction); - menu.exec (event->globalPos()); + menu.exec(event->globalPos()); } QModelIndexList CSVWorld::RegionMap::getUnselectedCells() const { - const QAbstractItemModel *model = QTableView::model(); + const QAbstractItemModel* model = QTableView::model(); int rows = model->rowCount(); int columns = model->columnCount(); QModelIndexList selected = selectionModel()->selectedIndexes(); - std::sort (selected.begin(), selected.end()); + std::sort(selected.begin(), selected.end()); QModelIndexList all; - for (int y=0; yindex (y, x); - if (model->data (index, Qt::BackgroundRole)!=QBrush (Qt::DiagCrossPattern)) - all.push_back (index); + QModelIndex index = model->index(y, x); + if (model->data(index, Qt::BackgroundRole) != QBrush(Qt::DiagCrossPattern)) + all.push_back(index); } - std::sort (all.begin(), all.end()); + std::sort(all.begin(), all.end()); QModelIndexList list; - std::set_difference (all.begin(), all.end(), selected.begin(), selected.end(), - std::back_inserter (list)); + std::set_difference(all.begin(), all.end(), selected.begin(), selected.end(), std::back_inserter(list)); return list; } -QModelIndexList CSVWorld::RegionMap::getSelectedCells (bool existent, bool nonExistent) const +QModelIndexList CSVWorld::RegionMap::getSelectedCells(bool existent, bool nonExistent) const { - const QAbstractItemModel *model = QTableView::model(); + const QAbstractItemModel* model = QTableView::model(); QModelIndexList selected = selectionModel()->selectedIndexes(); QModelIndexList list; - for (QModelIndexList::const_iterator iter (selected.begin()); iter!=selected.end(); ++iter) + for (QModelIndexList::const_iterator iter(selected.begin()); iter != selected.end(); ++iter) { - bool exists = model->data (*iter, Qt::BackgroundRole)!=QBrush (Qt::DiagCrossPattern); + bool exists = model->data(*iter, Qt::BackgroundRole) != QBrush(Qt::DiagCrossPattern); if ((exists && existent) || (!exists && nonExistent)) - list.push_back (*iter); + list.push_back(*iter); } return list; @@ -118,107 +117,103 @@ QModelIndexList CSVWorld::RegionMap::getSelectedCells (bool existent, bool nonEx QModelIndexList CSVWorld::RegionMap::getMissingRegionCells() const { - const QAbstractItemModel *model = QTableView::model(); + const QAbstractItemModel* model = QTableView::model(); QModelIndexList selected = selectionModel()->selectedIndexes(); std::set regions; - for (QModelIndexList::const_iterator iter (selected.begin()); iter!=selected.end(); ++iter) + for (QModelIndexList::const_iterator iter(selected.begin()); iter != selected.end(); ++iter) { - std::string region = - model->data (*iter, CSMWorld::RegionMap::Role_Region).toString().toUtf8().constData(); + std::string region = model->data(*iter, CSMWorld::RegionMap::Role_Region).toString().toUtf8().constData(); if (!region.empty()) - regions.insert (region); + regions.insert(region); } QModelIndexList list; QModelIndexList unselected = getUnselectedCells(); - for (QModelIndexList::const_iterator iter (unselected.begin()); iter!=unselected.end(); ++iter) + for (QModelIndexList::const_iterator iter(unselected.begin()); iter != unselected.end(); ++iter) { - std::string region = - model->data (*iter, CSMWorld::RegionMap::Role_Region).toString().toUtf8().constData(); + std::string region = model->data(*iter, CSMWorld::RegionMap::Role_Region).toString().toUtf8().constData(); - if (!region.empty() && regions.find (region)!=regions.end()) - list.push_back (*iter); + if (!region.empty() && regions.find(region) != regions.end()) + list.push_back(*iter); } return list; } -void CSVWorld::RegionMap::setRegion (const std::string& regionId) +void CSVWorld::RegionMap::setRegion(const std::string& regionId) { QModelIndexList selected = getSelectedCells(); - QAbstractItemModel *regionModel = model(); + QAbstractItemModel* regionModel = model(); - CSMWorld::IdTable *cellsModel = &dynamic_cast (* - mDocument.getData().getTableModel (CSMWorld::UniversalId::Type_Cells)); + CSMWorld::IdTable* cellsModel + = &dynamic_cast(*mDocument.getData().getTableModel(CSMWorld::UniversalId::Type_Cells)); - QString regionId2 = QString::fromUtf8 (regionId.c_str()); + QString regionId2 = QString::fromUtf8(regionId.c_str()); - CSMWorld::CommandMacro macro (mDocument.getUndoStack(), selected.size()>1 ? tr ("Set Region") : ""); + CSMWorld::CommandMacro macro(mDocument.getUndoStack(), selected.size() > 1 ? tr("Set Region") : ""); - for (QModelIndexList::const_iterator iter (selected.begin()); iter!=selected.end(); ++iter) + for (QModelIndexList::const_iterator iter(selected.begin()); iter != selected.end(); ++iter) { - std::string cellId = regionModel->data (*iter, CSMWorld::RegionMap::Role_CellId). - toString().toUtf8().constData(); + std::string cellId = regionModel->data(*iter, CSMWorld::RegionMap::Role_CellId).toString().toUtf8().constData(); - QModelIndex index = cellsModel->getModelIndex (cellId, - cellsModel->findColumnIndex (CSMWorld::Columns::ColumnId_Region)); + QModelIndex index + = cellsModel->getModelIndex(cellId, cellsModel->findColumnIndex(CSMWorld::Columns::ColumnId_Region)); - macro.push (new CSMWorld::ModifyCommand (*cellsModel, index, regionId2)); + macro.push(new CSMWorld::ModifyCommand(*cellsModel, index, regionId2)); } } -CSVWorld::RegionMap::RegionMap (const CSMWorld::UniversalId& universalId, - CSMDoc::Document& document, QWidget *parent) -: DragRecordTable(document, parent) +CSVWorld::RegionMap::RegionMap(const CSMWorld::UniversalId& universalId, CSMDoc::Document& document, QWidget* parent) + : DragRecordTable(document, parent) { verticalHeader()->hide(); horizontalHeader()->hide(); - setSelectionMode (QAbstractItemView::ExtendedSelection); + setSelectionMode(QAbstractItemView::ExtendedSelection); - setModel (document.getData().getTableModel (universalId)); + setModel(document.getData().getTableModel(universalId)); resizeColumnsToContents(); resizeRowsToContents(); - mSelectAllAction = new QAction (tr ("Select All"), this); - connect (mSelectAllAction, &QAction::triggered, this, &RegionMap::selectAll); - addAction (mSelectAllAction); + mSelectAllAction = new QAction(tr("Select All"), this); + connect(mSelectAllAction, &QAction::triggered, this, &RegionMap::selectAll); + addAction(mSelectAllAction); - mClearSelectionAction = new QAction (tr ("Clear Selection"), this); - connect (mClearSelectionAction, &QAction::triggered, this, &RegionMap::clearSelection); - addAction (mClearSelectionAction); + mClearSelectionAction = new QAction(tr("Clear Selection"), this); + connect(mClearSelectionAction, &QAction::triggered, this, &RegionMap::clearSelection); + addAction(mClearSelectionAction); - mSelectRegionsAction = new QAction (tr ("Select Regions"), this); - connect (mSelectRegionsAction, &QAction::triggered, this, &RegionMap::selectRegions); - addAction (mSelectRegionsAction); + mSelectRegionsAction = new QAction(tr("Select Regions"), this); + connect(mSelectRegionsAction, &QAction::triggered, this, &RegionMap::selectRegions); + addAction(mSelectRegionsAction); - mCreateCellsAction = new QAction (tr ("Create Cells Action"), this); - connect (mCreateCellsAction, &QAction::triggered, this, &RegionMap::createCells); - addAction (mCreateCellsAction); + mCreateCellsAction = new QAction(tr("Create Cells Action"), this); + connect(mCreateCellsAction, &QAction::triggered, this, &RegionMap::createCells); + addAction(mCreateCellsAction); - mSetRegionAction = new QAction (tr ("Set Region"), this); - connect (mSetRegionAction, &QAction::triggered, this, qOverload<>(&RegionMap::setRegion)); - addAction (mSetRegionAction); + mSetRegionAction = new QAction(tr("Set Region"), this); + connect(mSetRegionAction, &QAction::triggered, this, qOverload<>(&RegionMap::setRegion)); + addAction(mSetRegionAction); - mUnsetRegionAction = new QAction (tr ("Unset Region"), this); - connect (mUnsetRegionAction, &QAction::triggered, this, &RegionMap::unsetRegion); - addAction (mUnsetRegionAction); + mUnsetRegionAction = new QAction(tr("Unset Region"), this); + connect(mUnsetRegionAction, &QAction::triggered, this, &RegionMap::unsetRegion); + addAction(mUnsetRegionAction); - mViewAction = new QAction (tr ("View Cells"), this); - connect (mViewAction, &QAction::triggered, this, &RegionMap::view); - addAction (mViewAction); + mViewAction = new QAction(tr("View Cells"), this); + connect(mViewAction, &QAction::triggered, this, &RegionMap::view); + addAction(mViewAction); - mViewInTableAction = new QAction (tr ("View Cells in Table"), this); - connect (mViewInTableAction, &QAction::triggered, this, &RegionMap::viewInTable); - addAction (mViewInTableAction); + mViewInTableAction = new QAction(tr("View Cells in Table"), this); + connect(mViewInTableAction, &QAction::triggered, this, &RegionMap::viewInTable); + addAction(mViewInTableAction); setAcceptDrops(true); } @@ -227,8 +222,8 @@ void CSVWorld::RegionMap::selectAll() { QModelIndexList unselected = getUnselectedCells(); - for (QModelIndexList::const_iterator iter (unselected.begin()); iter!=unselected.end(); ++iter) - selectionModel()->select (*iter, QItemSelectionModel::Select); + for (QModelIndexList::const_iterator iter(unselected.begin()); iter != unselected.end(); ++iter) + selectionModel()->select(*iter, QItemSelectionModel::Select); } void CSVWorld::RegionMap::clearSelection() @@ -240,8 +235,8 @@ void CSVWorld::RegionMap::selectRegions() { QModelIndexList unselected = getMissingRegionCells(); - for (QModelIndexList::const_iterator iter (unselected.begin()); iter!=unselected.end(); ++iter) - selectionModel()->select (*iter, QItemSelectionModel::Select); + for (QModelIndexList::const_iterator iter(unselected.begin()); iter != unselected.end(); ++iter) + selectionModel()->select(*iter, QItemSelectionModel::Select); } void CSVWorld::RegionMap::createCells() @@ -249,19 +244,18 @@ void CSVWorld::RegionMap::createCells() if (mEditLock) return; - QModelIndexList selected = getSelectedCells (false, true); + QModelIndexList selected = getSelectedCells(false, true); - CSMWorld::IdTable *cellsModel = &dynamic_cast (* - mDocument.getData().getTableModel (CSMWorld::UniversalId::Type_Cells)); + CSMWorld::IdTable* cellsModel + = &dynamic_cast(*mDocument.getData().getTableModel(CSMWorld::UniversalId::Type_Cells)); - CSMWorld::CommandMacro macro (mDocument.getUndoStack(), selected.size()>1 ? tr ("Create cells"): ""); + CSMWorld::CommandMacro macro(mDocument.getUndoStack(), selected.size() > 1 ? tr("Create cells") : ""); - for (QModelIndexList::const_iterator iter (selected.begin()); iter!=selected.end(); ++iter) + for (QModelIndexList::const_iterator iter(selected.begin()); iter != selected.end(); ++iter) { - std::string cellId = model()->data (*iter, CSMWorld::RegionMap::Role_CellId). - toString().toUtf8().constData(); + std::string cellId = model()->data(*iter, CSMWorld::RegionMap::Role_CellId).toString().toUtf8().constData(); - macro.push (new CSMWorld::CreateCommand (*cellsModel, cellId)); + macro.push(new CSMWorld::CreateCommand(*cellsModel, cellId)); } } @@ -270,7 +264,7 @@ void CSVWorld::RegionMap::setRegion() if (mEditLock) return; - setRegion (mRegionId); + setRegion(mRegionId); } void CSVWorld::RegionMap::unsetRegion() @@ -278,7 +272,7 @@ void CSVWorld::RegionMap::unsetRegion() if (mEditLock) return; - setRegion (""); + setRegion(""); } void CSVWorld::RegionMap::view() @@ -290,10 +284,9 @@ void CSVWorld::RegionMap::view() bool first = true; - for (QModelIndexList::const_iterator iter (selected.begin()); iter!=selected.end(); ++iter) + for (QModelIndexList::const_iterator iter(selected.begin()); iter != selected.end(); ++iter) { - std::string cellId = model()->data (*iter, CSMWorld::RegionMap::Role_CellId). - toString().toUtf8().constData(); + std::string cellId = model()->data(*iter, CSMWorld::RegionMap::Role_CellId).toString().toUtf8().constData(); if (first) first = false; @@ -303,8 +296,8 @@ void CSVWorld::RegionMap::view() hint << cellId; } - emit editRequest (CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Scene, ESM::CellId::sDefaultWorldspace), - hint.str()); + emit editRequest( + CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Scene, ESM::CellId::sDefaultWorldspace), hint.str()); } void CSVWorld::RegionMap::viewInTable() @@ -316,10 +309,9 @@ void CSVWorld::RegionMap::viewInTable() bool first = true; - for (QModelIndexList::const_iterator iter (selected.begin()); iter!=selected.end(); ++iter) + for (QModelIndexList::const_iterator iter(selected.begin()); iter != selected.end(); ++iter) { - std::string cellId = model()->data (*iter, CSMWorld::RegionMap::Role_CellId). - toString().toUtf8().constData(); + std::string cellId = model()->data(*iter, CSMWorld::RegionMap::Role_CellId).toString().toUtf8().constData(); if (first) first = false; @@ -331,66 +323,63 @@ void CSVWorld::RegionMap::viewInTable() hint << ")"; - emit editRequest (CSMWorld::UniversalId::Type_Cells, hint.str()); + emit editRequest(CSMWorld::UniversalId::Type_Cells, hint.str()); } -void CSVWorld::RegionMap::mouseMoveEvent (QMouseEvent* event) +void CSVWorld::RegionMap::mouseMoveEvent(QMouseEvent* event) { startDragFromTable(*this); } -std::vector< CSMWorld::UniversalId > CSVWorld::RegionMap::getDraggedRecords() const +std::vector CSVWorld::RegionMap::getDraggedRecords() const { QModelIndexList selected(getSelectedCells(true, false)); std::vector ids; for (const QModelIndex& it : selected) { - ids.emplace_back( - CSMWorld::UniversalId::Type_Cell, - model()->data(it, CSMWorld::RegionMap::Role_CellId).toString().toUtf8().constData()); + ids.emplace_back(CSMWorld::UniversalId::Type_Cell, + model()->data(it, CSMWorld::RegionMap::Role_CellId).toString().toUtf8().constData()); } selected = getSelectedCells(false, true); for (const QModelIndex& it : selected) { - ids.emplace_back( - CSMWorld::UniversalId::Type_Cell_Missing, - model()->data(it, CSMWorld::RegionMap::Role_CellId).toString().toUtf8().constData()); + ids.emplace_back(CSMWorld::UniversalId::Type_Cell_Missing, + model()->data(it, CSMWorld::RegionMap::Role_CellId).toString().toUtf8().constData()); } return ids; } -void CSVWorld::RegionMap::dropEvent (QDropEvent* event) +void CSVWorld::RegionMap::dropEvent(QDropEvent* event) { - QModelIndex index = indexAt (event->pos()); + QModelIndex index = indexAt(event->pos()); - bool exists = QTableView::model()->data(index, Qt::BackgroundRole)!=QBrush (Qt::DiagCrossPattern); + bool exists = QTableView::model()->data(index, Qt::BackgroundRole) != QBrush(Qt::DiagCrossPattern); if (!index.isValid() || !exists) { return; } - const CSMWorld::TableMimeData* mime = dynamic_cast (event->mimeData()); + const CSMWorld::TableMimeData* mime = dynamic_cast(event->mimeData()); if (!mime) // May happen when non-records (e.g. plain text) are dragged and dropped return; if (mime->fromDocument(mDocument) && mime->holdsType(CSMWorld::UniversalId::Type_Region)) { - CSMWorld::UniversalId record (mime->returnMatching (CSMWorld::UniversalId::Type_Region)); + CSMWorld::UniversalId record(mime->returnMatching(CSMWorld::UniversalId::Type_Region)); - QAbstractItemModel *regionModel = model(); + QAbstractItemModel* regionModel = model(); - CSMWorld::IdTable *cellsModel = &dynamic_cast (* - mDocument.getData().getTableModel (CSMWorld::UniversalId::Type_Cells)); + CSMWorld::IdTable* cellsModel + = &dynamic_cast(*mDocument.getData().getTableModel(CSMWorld::UniversalId::Type_Cells)); - std::string cellId(regionModel->data (index, CSMWorld::RegionMap::Role_CellId). - toString().toUtf8().constData()); + std::string cellId(regionModel->data(index, CSMWorld::RegionMap::Role_CellId).toString().toUtf8().constData()); - QModelIndex index2(cellsModel->getModelIndex (cellId, - cellsModel->findColumnIndex (CSMWorld::Columns::ColumnId_Region))); + QModelIndex index2( + cellsModel->getModelIndex(cellId, cellsModel->findColumnIndex(CSMWorld::Columns::ColumnId_Region))); - mDocument.getUndoStack().push(new CSMWorld::ModifyCommand - (*cellsModel, index2, QString::fromUtf8(record.getId().c_str()))); + mDocument.getUndoStack().push( + new CSMWorld::ModifyCommand(*cellsModel, index2, QString::fromUtf8(record.getId().c_str()))); mRegionId = record.getId(); } diff --git a/apps/opencs/view/world/regionmap.hpp b/apps/opencs/view/world/regionmap.hpp index fe88987848..356e86074f 100644 --- a/apps/opencs/view/world/regionmap.hpp +++ b/apps/opencs/view/world/regionmap.hpp @@ -22,67 +22,64 @@ namespace CSVWorld { class RegionMap : public DragRecordTable { - Q_OBJECT + Q_OBJECT - QAction *mSelectAllAction; - QAction *mClearSelectionAction; - QAction *mSelectRegionsAction; - QAction *mCreateCellsAction; - QAction *mSetRegionAction; - QAction *mUnsetRegionAction; - QAction *mViewAction; - QAction *mViewInTableAction; - std::string mRegionId; + QAction* mSelectAllAction; + QAction* mClearSelectionAction; + QAction* mSelectRegionsAction; + QAction* mCreateCellsAction; + QAction* mSetRegionAction; + QAction* mUnsetRegionAction; + QAction* mViewAction; + QAction* mViewInTableAction; + std::string mRegionId; - private: + private: + void contextMenuEvent(QContextMenuEvent* event) override; - void contextMenuEvent (QContextMenuEvent *event) override; + QModelIndexList getUnselectedCells() const; + ///< \note Non-existent cells are not listed. - QModelIndexList getUnselectedCells() const; - ///< \note Non-existent cells are not listed. + QModelIndexList getSelectedCells(bool existent = true, bool nonExistent = false) const; + ///< \param existent Include existent cells. + /// \param nonExistent Include non-existent cells. - QModelIndexList getSelectedCells (bool existent = true, bool nonExistent = false) const; - ///< \param existent Include existent cells. - /// \param nonExistent Include non-existent cells. + QModelIndexList getMissingRegionCells() const; + ///< Unselected cells within all regions that have at least one selected cell. - QModelIndexList getMissingRegionCells() const; - ///< Unselected cells within all regions that have at least one selected cell. + void setRegion(const std::string& regionId); + ///< Set region Id of selected cells. - void setRegion (const std::string& regionId); - ///< Set region Id of selected cells. + void mouseMoveEvent(QMouseEvent* event) override; - void mouseMoveEvent(QMouseEvent *event) override; + void dropEvent(QDropEvent* event) override; - void dropEvent(QDropEvent* event) override; + public: + RegionMap(const CSMWorld::UniversalId& universalId, CSMDoc::Document& document, QWidget* parent = nullptr); - public: + std::vector getDraggedRecords() const override; - RegionMap (const CSMWorld::UniversalId& universalId, CSMDoc::Document& document, - QWidget *parent = nullptr); + signals: - std::vector getDraggedRecords() const override; + void editRequest(const CSMWorld::UniversalId& id, const std::string& hint); - signals: + private slots: - void editRequest (const CSMWorld::UniversalId& id, const std::string& hint); + void selectAll() override; - private slots: + void clearSelection(); - void selectAll() override; + void selectRegions(); - void clearSelection(); + void createCells(); - void selectRegions(); + void setRegion(); - void createCells(); + void unsetRegion(); - void setRegion(); + void view(); - void unsetRegion(); - - void view(); - - void viewInTable(); + void viewInTable(); }; } diff --git a/apps/opencs/view/world/regionmapsubview.cpp b/apps/opencs/view/world/regionmapsubview.cpp index 659c7597f0..5d76c9459b 100644 --- a/apps/opencs/view/world/regionmapsubview.cpp +++ b/apps/opencs/view/world/regionmapsubview.cpp @@ -2,24 +2,22 @@ #include "regionmap.hpp" -CSVWorld::RegionMapSubView::RegionMapSubView (CSMWorld::UniversalId universalId, - CSMDoc::Document& document) -: CSVDoc::SubView (universalId) +CSVWorld::RegionMapSubView::RegionMapSubView(CSMWorld::UniversalId universalId, CSMDoc::Document& document) + : CSVDoc::SubView(universalId) { - mRegionMap = new RegionMap (universalId, document, this); + mRegionMap = new RegionMap(universalId, document, this); - setWidget (mRegionMap); + setWidget(mRegionMap); - connect (mRegionMap, &RegionMap::editRequest, this, &RegionMapSubView::editRequest); + connect(mRegionMap, &RegionMap::editRequest, this, &RegionMapSubView::editRequest); } -void CSVWorld::RegionMapSubView::setEditLock (bool locked) +void CSVWorld::RegionMapSubView::setEditLock(bool locked) { - mRegionMap->setEditLock (locked); + mRegionMap->setEditLock(locked); } -void CSVWorld::RegionMapSubView::editRequest (const CSMWorld::UniversalId& id, - const std::string& hint) +void CSVWorld::RegionMapSubView::editRequest(const CSMWorld::UniversalId& id, const std::string& hint) { - focusId (id, hint); + focusId(id, hint); } diff --git a/apps/opencs/view/world/regionmapsubview.hpp b/apps/opencs/view/world/regionmapsubview.hpp index 232d88fc64..1874236a30 100644 --- a/apps/opencs/view/world/regionmapsubview.hpp +++ b/apps/opencs/view/world/regionmapsubview.hpp @@ -16,19 +16,18 @@ namespace CSVWorld class RegionMapSubView : public CSVDoc::SubView { - Q_OBJECT + Q_OBJECT - RegionMap *mRegionMap; + RegionMap* mRegionMap; - public: + public: + RegionMapSubView(CSMWorld::UniversalId universalId, CSMDoc::Document& document); - RegionMapSubView (CSMWorld::UniversalId universalId, CSMDoc::Document& document); + void setEditLock(bool locked) override; - void setEditLock (bool locked) override; + private slots: - private slots: - - void editRequest (const CSMWorld::UniversalId& id, const std::string& hint); + void editRequest(const CSMWorld::UniversalId& id, const std::string& hint); }; } diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index 414ab7183f..2316596675 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -2,9 +2,9 @@ #include -#include #include #include +#include #include #include "../../model/doc/document.hpp" @@ -18,30 +18,34 @@ #include "../widget/scenetoolbar.hpp" #include "../widget/scenetoolmode.hpp" +#include "../widget/scenetoolrun.hpp" #include "../widget/scenetooltoggle.hpp" #include "../widget/scenetooltoggle2.hpp" -#include "../widget/scenetoolrun.hpp" -#include "tablebottombox.hpp" #include "creator.hpp" +#include "tablebottombox.hpp" -CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) -: SubView (id), mScene(nullptr), mLayout(new QHBoxLayout), mDocument(document), mToolbar(nullptr) +CSVWorld::SceneSubView::SceneSubView(const CSMWorld::UniversalId& id, CSMDoc::Document& document) + : SubView(id) + , mScene(nullptr) + , mLayout(new QHBoxLayout) + , mDocument(document) + , mToolbar(nullptr) { - QVBoxLayout *layout = new QVBoxLayout; + QVBoxLayout* layout = new QVBoxLayout; - layout->addWidget (mBottom = new TableBottomBox (NullCreatorFactory(), document, id, this), 0); + layout->addWidget(mBottom = new TableBottomBox(NullCreatorFactory(), document, id, this), 0); - mLayout->setContentsMargins (QMargins (0, 0, 0, 0)); + mLayout->setContentsMargins(QMargins(0, 0, 0, 0)); CSVRender::WorldspaceWidget* worldspaceWidget = nullptr; widgetType whatWidget; - if (id.getId()==ESM::CellId::sDefaultWorldspace) + if (id.getId() == ESM::CellId::sDefaultWorldspace) { whatWidget = widget_Paged; - CSVRender::PagedWorldspaceWidget *newWidget = new CSVRender::PagedWorldspaceWidget (this, document); + CSVRender::PagedWorldspaceWidget* newWidget = new CSVRender::PagedWorldspaceWidget(this, document); worldspaceWidget = newWidget; @@ -51,7 +55,8 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D { whatWidget = widget_Unpaged; - CSVRender::UnpagedWorldspaceWidget *newWidget = new CSVRender::UnpagedWorldspaceWidget (id.getId(), document, this); + CSVRender::UnpagedWorldspaceWidget* newWidget + = new CSVRender::UnpagedWorldspaceWidget(id.getId(), document, this); worldspaceWidget = newWidget; @@ -60,93 +65,85 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D replaceToolbarAndWorldspace(worldspaceWidget, makeToolbar(worldspaceWidget, whatWidget)); - layout->insertLayout (0, mLayout, 1); + layout->insertLayout(0, mLayout, 1); - CSVFilter::FilterBox *filterBox = new CSVFilter::FilterBox (document.getData(), this); + CSVFilter::FilterBox* filterBox = new CSVFilter::FilterBox(document.getData(), this); - layout->insertWidget (0, filterBox); + layout->insertWidget(0, filterBox); - QWidget *widget = new QWidget; + QWidget* widget = new QWidget; - widget->setLayout (layout); + widget->setLayout(layout); - setWidget (widget); + setWidget(widget); } -void CSVWorld::SceneSubView::makeConnections (CSVRender::UnpagedWorldspaceWidget* widget) +void CSVWorld::SceneSubView::makeConnections(CSVRender::UnpagedWorldspaceWidget* widget) { - connect(widget, &CSVRender::UnpagedWorldspaceWidget::closeRequest, - this, qOverload<>(&SceneSubView::closeRequest)); + connect(widget, &CSVRender::UnpagedWorldspaceWidget::closeRequest, this, qOverload<>(&SceneSubView::closeRequest)); - connect(widget, &CSVRender::UnpagedWorldspaceWidget::dataDropped, - this, &SceneSubView::handleDrop); + connect(widget, &CSVRender::UnpagedWorldspaceWidget::dataDropped, this, &SceneSubView::handleDrop); - connect(widget, &CSVRender::UnpagedWorldspaceWidget::cellChanged, - this, qOverload(&SceneSubView::cellSelectionChanged)); + connect(widget, &CSVRender::UnpagedWorldspaceWidget::cellChanged, this, + qOverload(&SceneSubView::cellSelectionChanged)); - connect(widget, &CSVRender::UnpagedWorldspaceWidget::requestFocus, - this, &SceneSubView::requestFocus); + connect(widget, &CSVRender::UnpagedWorldspaceWidget::requestFocus, this, &SceneSubView::requestFocus); } -void CSVWorld::SceneSubView::makeConnections (CSVRender::PagedWorldspaceWidget* widget) +void CSVWorld::SceneSubView::makeConnections(CSVRender::PagedWorldspaceWidget* widget) { - connect(widget, &CSVRender::PagedWorldspaceWidget::closeRequest, - this, qOverload<>(&SceneSubView::closeRequest)); + connect(widget, &CSVRender::PagedWorldspaceWidget::closeRequest, this, qOverload<>(&SceneSubView::closeRequest)); - connect(widget, &CSVRender::PagedWorldspaceWidget::dataDropped, - this, &SceneSubView::handleDrop); + connect(widget, &CSVRender::PagedWorldspaceWidget::dataDropped, this, &SceneSubView::handleDrop); - connect(widget, &CSVRender::PagedWorldspaceWidget::cellSelectionChanged, - this, qOverload(&SceneSubView::cellSelectionChanged)); + connect(widget, &CSVRender::PagedWorldspaceWidget::cellSelectionChanged, this, + qOverload(&SceneSubView::cellSelectionChanged)); - connect(widget, &CSVRender::PagedWorldspaceWidget::requestFocus, - this, &SceneSubView::requestFocus); + connect(widget, &CSVRender::PagedWorldspaceWidget::requestFocus, this, &SceneSubView::requestFocus); } -CSVWidget::SceneToolbar* CSVWorld::SceneSubView::makeToolbar (CSVRender::WorldspaceWidget* widget, widgetType type) +CSVWidget::SceneToolbar* CSVWorld::SceneSubView::makeToolbar(CSVRender::WorldspaceWidget* widget, widgetType type) { - CSVWidget::SceneToolbar* toolbar = new CSVWidget::SceneToolbar (48+6, this); + CSVWidget::SceneToolbar* toolbar = new CSVWidget::SceneToolbar(48 + 6, this); - CSVWidget::SceneToolMode *navigationTool = widget->makeNavigationSelector (toolbar); - toolbar->addTool (navigationTool); + CSVWidget::SceneToolMode* navigationTool = widget->makeNavigationSelector(toolbar); + toolbar->addTool(navigationTool); - CSVWidget::SceneToolMode *lightingTool = widget->makeLightingSelector (toolbar); - toolbar->addTool (lightingTool); + CSVWidget::SceneToolMode* lightingTool = widget->makeLightingSelector(toolbar); + toolbar->addTool(lightingTool); - CSVWidget::SceneToolToggle2 *sceneVisibilityTool = - widget->makeSceneVisibilitySelector (toolbar); - toolbar->addTool (sceneVisibilityTool); + CSVWidget::SceneToolToggle2* sceneVisibilityTool = widget->makeSceneVisibilitySelector(toolbar); + toolbar->addTool(sceneVisibilityTool); - if (type==widget_Paged) + if (type == widget_Paged) { - CSVWidget::SceneToolToggle2 *controlVisibilityTool = - dynamic_cast (*widget). - makeControlVisibilitySelector (toolbar); + CSVWidget::SceneToolToggle2* controlVisibilityTool + = dynamic_cast(*widget).makeControlVisibilitySelector(toolbar); - toolbar->addTool (controlVisibilityTool); + toolbar->addTool(controlVisibilityTool); } - CSVWidget::SceneToolRun *runTool = widget->makeRunTool (toolbar); - toolbar->addTool (runTool); + CSVWidget::SceneToolRun* runTool = widget->makeRunTool(toolbar); + toolbar->addTool(runTool); - toolbar->addTool (widget->makeEditModeSelector (toolbar), runTool); + toolbar->addTool(widget->makeEditModeSelector(toolbar), runTool); return toolbar; } -void CSVWorld::SceneSubView::setEditLock (bool locked) +void CSVWorld::SceneSubView::setEditLock(bool locked) { - mScene->setEditLock (locked); + mScene->setEditLock(locked); } -void CSVWorld::SceneSubView::setStatusBar (bool show) +void CSVWorld::SceneSubView::setStatusBar(bool show) { - mBottom->setStatusBar (show); + mBottom->setStatusBar(show); } -void CSVWorld::SceneSubView::useHint (const std::string& hint) +void CSVWorld::SceneSubView::useHint(const std::string& hint) { - mScene->useViewHint (hint); + mScene->useViewHint(hint); } std::string CSVWorld::SceneSubView::getTitle() const @@ -154,16 +151,16 @@ std::string CSVWorld::SceneSubView::getTitle() const return mTitle; } -void CSVWorld::SceneSubView::cellSelectionChanged (const CSMWorld::UniversalId& id) +void CSVWorld::SceneSubView::cellSelectionChanged(const CSMWorld::UniversalId& id) { setUniversalId(id); mTitle = "Scene: " + getUniversalId().getId(); - setWindowTitle (QString::fromUtf8 (mTitle.c_str())); + setWindowTitle(QString::fromUtf8(mTitle.c_str())); emit updateTitle(); } -void CSVWorld::SceneSubView::cellSelectionChanged (const CSMWorld::CellSelection& selection) +void CSVWorld::SceneSubView::cellSelectionChanged(const CSMWorld::CellSelection& selection) { setUniversalId(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Scene, ESM::CellId::sDefaultWorldspace)); int size = selection.getSize(); @@ -171,39 +168,39 @@ void CSVWorld::SceneSubView::cellSelectionChanged (const CSMWorld::CellSelection std::ostringstream stream; stream << "Scene: " << getUniversalId().getId(); - if (size==0) + if (size == 0) stream << " (empty)"; - else if (size==1) + else if (size == 1) { stream << " (" << *selection.begin() << ")"; } else { - stream << " (" << selection.getCentre() << " and " << size-1 << " more "; + stream << " (" << selection.getCentre() << " and " << size - 1 << " more "; - if (size>1) + if (size > 1) stream << "cells around it)"; else stream << "cell around it)"; } mTitle = stream.str(); - setWindowTitle (QString::fromUtf8 (mTitle.c_str())); + setWindowTitle(QString::fromUtf8(mTitle.c_str())); emit updateTitle(); } -void CSVWorld::SceneSubView::handleDrop (const std::vector< CSMWorld::UniversalId >& universalIdData) +void CSVWorld::SceneSubView::handleDrop(const std::vector& universalIdData) { CSVRender::PagedWorldspaceWidget* pagedNewWidget = nullptr; CSVRender::UnpagedWorldspaceWidget* unPagedNewWidget = nullptr; CSVWidget::SceneToolbar* toolbar = nullptr; - CSVRender::WorldspaceWidget::DropType type = CSVRender::WorldspaceWidget::getDropType (universalIdData); + CSVRender::WorldspaceWidget::DropType type = CSVRender::WorldspaceWidget::getDropType(universalIdData); - switch (mScene->getDropRequirements (type)) + switch (mScene->getDropRequirements(type)) { case CSVRender::WorldspaceWidget::canHandle: - mScene->handleDrop (universalIdData, type); + mScene->handleDrop(universalIdData, type); break; case CSVRender::WorldspaceWidget::needPaged: @@ -211,11 +208,12 @@ void CSVWorld::SceneSubView::handleDrop (const std::vector< CSMWorld::UniversalI toolbar = makeToolbar(pagedNewWidget, widget_Paged); makeConnections(pagedNewWidget); replaceToolbarAndWorldspace(pagedNewWidget, toolbar); - mScene->handleDrop (universalIdData, type); + mScene->handleDrop(universalIdData, type); break; case CSVRender::WorldspaceWidget::needUnpaged: - unPagedNewWidget = new CSVRender::UnpagedWorldspaceWidget(universalIdData.begin()->getId(), mDocument, this); + unPagedNewWidget + = new CSVRender::UnpagedWorldspaceWidget(universalIdData.begin()->getId(), mDocument, this); toolbar = makeToolbar(unPagedNewWidget, widget_Unpaged); makeConnections(unPagedNewWidget); replaceToolbarAndWorldspace(unPagedNewWidget, toolbar); @@ -227,7 +225,8 @@ void CSVWorld::SceneSubView::handleDrop (const std::vector< CSMWorld::UniversalI } } -void CSVWorld::SceneSubView::replaceToolbarAndWorldspace (CSVRender::WorldspaceWidget* widget, CSVWidget::SceneToolbar* toolbar) +void CSVWorld::SceneSubView::replaceToolbarAndWorldspace( + CSVRender::WorldspaceWidget* widget, CSVWidget::SceneToolbar* toolbar) { assert(mLayout); @@ -246,14 +245,14 @@ void CSVWorld::SceneSubView::replaceToolbarAndWorldspace (CSVRender::WorldspaceW mScene = widget; mToolbar = toolbar; - connect (mScene, &CSVRender::WorldspaceWidget::focusToolbarRequest, - mToolbar, qOverload<>(&CSVWidget::SceneToolbar::setFocus)); - connect (mToolbar, &CSVWidget::SceneToolbar::focusSceneRequest, - mScene, qOverload<>(&CSVRender::WorldspaceWidget::setFocus)); + connect(mScene, &CSVRender::WorldspaceWidget::focusToolbarRequest, mToolbar, + qOverload<>(&CSVWidget::SceneToolbar::setFocus)); + connect(mToolbar, &CSVWidget::SceneToolbar::focusSceneRequest, mScene, + qOverload<>(&CSVRender::WorldspaceWidget::setFocus)); - mLayout->addWidget (mToolbar, 0); - mLayout->addWidget (mScene, 1); + mLayout->addWidget(mToolbar, 0); + mLayout->addWidget(mScene, 1); mScene->selectDefaultNavigationMode(); - setFocusProxy (mScene); + setFocusProxy(mScene); } diff --git a/apps/opencs/view/world/scenesubview.hpp b/apps/opencs/view/world/scenesubview.hpp index 53cd54e7ac..446a7a5e89 100644 --- a/apps/opencs/view/world/scenesubview.hpp +++ b/apps/opencs/view/world/scenesubview.hpp @@ -37,54 +37,52 @@ namespace CSVWorld class SceneSubView : public CSVDoc::SubView { - Q_OBJECT + Q_OBJECT - TableBottomBox *mBottom; - CSVRender::WorldspaceWidget *mScene; - QHBoxLayout* mLayout; - CSMDoc::Document& mDocument; - CSVWidget::SceneToolbar* mToolbar; - std::string mTitle; + TableBottomBox* mBottom; + CSVRender::WorldspaceWidget* mScene; + QHBoxLayout* mLayout; + CSMDoc::Document& mDocument; + CSVWidget::SceneToolbar* mToolbar; + std::string mTitle; - public: + public: + SceneSubView(const CSMWorld::UniversalId& id, CSMDoc::Document& document); - SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document); + void setEditLock(bool locked) override; - void setEditLock (bool locked) override; + void setStatusBar(bool show) override; - void setStatusBar (bool show) override; + void useHint(const std::string& hint) override; - void useHint (const std::string& hint) override; + std::string getTitle() const override; - std::string getTitle() const override; + private: + void makeConnections(CSVRender::PagedWorldspaceWidget* widget); - private: + void makeConnections(CSVRender::UnpagedWorldspaceWidget* widget); - void makeConnections(CSVRender::PagedWorldspaceWidget* widget); + void replaceToolbarAndWorldspace(CSVRender::WorldspaceWidget* widget, CSVWidget::SceneToolbar* toolbar); - void makeConnections(CSVRender::UnpagedWorldspaceWidget* widget); + enum widgetType + { + widget_Paged, + widget_Unpaged + }; - void replaceToolbarAndWorldspace(CSVRender::WorldspaceWidget* widget, CSVWidget::SceneToolbar* toolbar); + CSVWidget::SceneToolbar* makeToolbar(CSVRender::WorldspaceWidget* widget, widgetType type); - enum widgetType - { - widget_Paged, - widget_Unpaged - }; + private slots: - CSVWidget::SceneToolbar* makeToolbar(CSVRender::WorldspaceWidget* widget, widgetType type); + void cellSelectionChanged(const CSMWorld::CellSelection& selection); - private slots: + void cellSelectionChanged(const CSMWorld::UniversalId& id); - void cellSelectionChanged (const CSMWorld::CellSelection& selection); + void handleDrop(const std::vector& data); - void cellSelectionChanged (const CSMWorld::UniversalId& id); + signals: - void handleDrop(const std::vector& data); - - signals: - - void requestFocus (const std::string& id); + void requestFocus(const std::string& id); }; } diff --git a/apps/opencs/view/world/scriptedit.cpp b/apps/opencs/view/world/scriptedit.cpp index 547553dbf5..142e559a26 100644 --- a/apps/opencs/view/world/scriptedit.cpp +++ b/apps/opencs/view/world/scriptedit.cpp @@ -3,19 +3,20 @@ #include #include -#include +#include #include +#include #include -#include #include "../../model/doc/document.hpp" -#include "../../model/world/universalid.hpp" -#include "../../model/world/tablemimedata.hpp" -#include "../../model/prefs/state.hpp" #include "../../model/prefs/shortcut.hpp" +#include "../../model/prefs/state.hpp" +#include "../../model/world/tablemimedata.hpp" +#include "../../model/world/universalid.hpp" -CSVWorld::ScriptEdit::ChangeLock::ChangeLock (ScriptEdit& edit) : mEdit (edit) +CSVWorld::ScriptEdit::ChangeLock::ChangeLock(ScriptEdit& edit) + : mEdit(edit) { ++mEdit.mChangeLocked; } @@ -25,95 +26,77 @@ CSVWorld::ScriptEdit::ChangeLock::~ChangeLock() --mEdit.mChangeLocked; } -bool CSVWorld::ScriptEdit::event (QEvent *event) +bool CSVWorld::ScriptEdit::event(QEvent* event) { // ignore undo and redo shortcuts - if (event->type()==QEvent::ShortcutOverride) + if (event->type() == QEvent::ShortcutOverride) { - QKeyEvent *keyEvent = static_cast (event); + QKeyEvent* keyEvent = static_cast(event); - if (keyEvent->matches (QKeySequence::Undo) || keyEvent->matches (QKeySequence::Redo)) + if (keyEvent->matches(QKeySequence::Undo) || keyEvent->matches(QKeySequence::Redo)) return true; } - return QPlainTextEdit::event (event); + return QPlainTextEdit::event(event); } -CSVWorld::ScriptEdit::ScriptEdit( - const CSMDoc::Document& document, - ScriptHighlighter::Mode mode, - QWidget* parent -) : QPlainTextEdit(parent), - mChangeLocked(0), - mShowLineNum(false), - mLineNumberArea(nullptr), - mDefaultFont(font()), - mMonoFont(QFont("Monospace")), - mTabCharCount(4), - mMarkOccurrences(true), - mDocument(document), - mWhiteListQoutes("^[a-z|_]{1}[a-z|0-9|_]{0,}$", Qt::CaseInsensitive) +CSVWorld::ScriptEdit::ScriptEdit(const CSMDoc::Document& document, ScriptHighlighter::Mode mode, QWidget* parent) + : QPlainTextEdit(parent) + , mChangeLocked(0) + , mShowLineNum(false) + , mLineNumberArea(nullptr) + , mDefaultFont(font()) + , mMonoFont(QFont("Monospace")) + , mTabCharCount(4) + , mMarkOccurrences(true) + , mDocument(document) + , mWhiteListQoutes("^[a-z|_]{1}[a-z|0-9|_]{0,}$", Qt::CaseInsensitive) { wrapLines(false); setTabWidth(); - setUndoRedoEnabled (false); // we use OpenCS-wide undo/redo instead - - mAllowedTypes <associateAction(mCommentAction); - mUncommentAction = new QAction (tr ("Uncomment Selection"), this); + mUncommentAction = new QAction(tr("Uncomment Selection"), this); connect(mUncommentAction, &QAction::triggered, this, &ScriptEdit::uncommentSelection); - CSMPrefs::Shortcut *uncommentShortcut = new CSMPrefs::Shortcut("script-editor-uncomment", this); + CSMPrefs::Shortcut* uncommentShortcut = new CSMPrefs::Shortcut("script-editor-uncomment", this); uncommentShortcut->associateAction(mUncommentAction); - mHighlighter = new ScriptHighlighter (document.getData(), mode, ScriptEdit::document()); + mHighlighter = new ScriptHighlighter(document.getData(), mode, ScriptEdit::document()); - connect (&document.getData(), &CSMWorld::Data::idListChanged, this, &ScriptEdit::idListChanged); + connect(&document.getData(), &CSMWorld::Data::idListChanged, this, &ScriptEdit::idListChanged); - connect (&mUpdateTimer, &QTimer::timeout, this, &ScriptEdit::updateHighlighting); + connect(&mUpdateTimer, &QTimer::timeout, this, &ScriptEdit::updateHighlighting); - connect (&CSMPrefs::State::get(), &CSMPrefs::State::settingChanged, - this, &ScriptEdit::settingChanged); + connect(&CSMPrefs::State::get(), &CSMPrefs::State::settingChanged, this, &ScriptEdit::settingChanged); { - ChangeLock lock (*this); + ChangeLock lock(*this); CSMPrefs::get()["Scripts"].update(); } - mUpdateTimer.setSingleShot (true); + mUpdateTimer.setSingleShot(true); // TODO: provide a font selector dialogue mMonoFont.setStyleHint(QFont::TypeWriter); @@ -128,7 +111,7 @@ CSVWorld::ScriptEdit::ScriptEdit( void CSVWorld::ScriptEdit::showLineNum(bool show) { - if(show!=mShowLineNum) + if (show != mShowLineNum) { mShowLineNum = show; updateLineNumberAreaWidth(0); @@ -137,67 +120,69 @@ void CSVWorld::ScriptEdit::showLineNum(bool show) bool CSVWorld::ScriptEdit::isChangeLocked() const { - return mChangeLocked!=0; + return mChangeLocked != 0; } -void CSVWorld::ScriptEdit::dragEnterEvent (QDragEnterEvent* event) +void CSVWorld::ScriptEdit::dragEnterEvent(QDragEnterEvent* event) { - const CSMWorld::TableMimeData* mime = dynamic_cast (event->mimeData()); + const CSMWorld::TableMimeData* mime = dynamic_cast(event->mimeData()); if (!mime) QPlainTextEdit::dragEnterEvent(event); else { - setTextCursor (cursorForPosition (event->pos())); + setTextCursor(cursorForPosition(event->pos())); event->acceptProposedAction(); } } -void CSVWorld::ScriptEdit::dragMoveEvent (QDragMoveEvent* event) +void CSVWorld::ScriptEdit::dragMoveEvent(QDragMoveEvent* event) { - const CSMWorld::TableMimeData* mime = dynamic_cast (event->mimeData()); + const CSMWorld::TableMimeData* mime = dynamic_cast(event->mimeData()); if (!mime) QPlainTextEdit::dragMoveEvent(event); else { - setTextCursor (cursorForPosition (event->pos())); + setTextCursor(cursorForPosition(event->pos())); event->accept(); } } -void CSVWorld::ScriptEdit::dropEvent (QDropEvent* event) +void CSVWorld::ScriptEdit::dropEvent(QDropEvent* event) { - const CSMWorld::TableMimeData* mime = dynamic_cast (event->mimeData()); + const CSMWorld::TableMimeData* mime = dynamic_cast(event->mimeData()); if (!mime) // May happen when non-records (e.g. plain text) are dragged and dropped { QPlainTextEdit::dropEvent(event); return; } - setTextCursor (cursorForPosition (event->pos())); + setTextCursor(cursorForPosition(event->pos())); - if (mime->fromDocument (mDocument)) + if (mime->fromDocument(mDocument)) { - std::vector records (mime->getData()); + std::vector records(mime->getData()); for (std::vector::iterator it = records.begin(); it != records.end(); ++it) { - if (mAllowedTypes.contains (it->getType())) + if (mAllowedTypes.contains(it->getType())) { if (stringNeedsQuote(it->getId())) { - insertPlainText(QString::fromUtf8 (('"' + it->getId() + '"').c_str())); - } else { - insertPlainText(QString::fromUtf8 (it->getId().c_str())); + insertPlainText(QString::fromUtf8(('"' + it->getId() + '"').c_str())); + } + else + { + insertPlainText(QString::fromUtf8(it->getId().c_str())); } } } } } -bool CSVWorld::ScriptEdit::stringNeedsQuote (const std::string& id) const +bool CSVWorld::ScriptEdit::stringNeedsQuote(const std::string& id) const { const QString string(QString::fromUtf8(id.c_str())); // is only for c++11, so let's use qregexp for now. - //I'm not quite sure when do we need to put quotes. To be safe we will use quotes for anything other than… + // I'm not quite sure when do we need to put quotes. To be safe we will use quotes for anything other than… return !(string.contains(mWhiteListQoutes)); } @@ -219,7 +204,7 @@ void CSVWorld::ScriptEdit::wrapLines(bool wrap) } } -void CSVWorld::ScriptEdit::settingChanged(const CSMPrefs::Setting *setting) +void CSVWorld::ScriptEdit::settingChanged(const CSMPrefs::Setting* setting) { // Determine which setting was changed. if (mHighlighter->settingChanged(setting)) @@ -258,7 +243,7 @@ void CSVWorld::ScriptEdit::idListChanged() mHighlighter->invalidateIds(); if (!mUpdateTimer.isActive()) - mUpdateTimer.start (0); + mUpdateTimer.start(0); } void CSVWorld::ScriptEdit::updateHighlighting() @@ -266,14 +251,14 @@ void CSVWorld::ScriptEdit::updateHighlighting() if (isChangeLocked()) return; - ChangeLock lock (*this); + ChangeLock lock(*this); mHighlighter->rehighlight(); } int CSVWorld::ScriptEdit::lineNumberAreaWidth() { - if(!mShowLineNum) + if (!mShowLineNum) return 0; int digits = 1; @@ -293,7 +278,7 @@ void CSVWorld::ScriptEdit::updateLineNumberAreaWidth(int /* newBlockCount */) setViewportMargins(lineNumberAreaWidth(), 0, 0, 0); } -void CSVWorld::ScriptEdit::updateLineNumberArea(const QRect &rect, int dy) +void CSVWorld::ScriptEdit::updateLineNumberArea(const QRect& rect, int dy) { if (dy) mLineNumberArea->scroll(0, dy); @@ -322,7 +307,7 @@ void CSVWorld::ScriptEdit::markOccurrences() mHighlighter->rehighlight(); } } - + void CSVWorld::ScriptEdit::commentSelection() { QTextCursor begin = textCursor(); @@ -355,7 +340,8 @@ void CSVWorld::ScriptEdit::uncommentSelection() begin.beginEditBlock(); - for (; begin < end; begin.movePosition(QTextCursor::EndOfLine), begin.movePosition(QTextCursor::Right)) { + for (; begin < end; begin.movePosition(QTextCursor::EndOfLine), begin.movePosition(QTextCursor::Right)) + { begin.select(QTextCursor::LineUnderCursor); QString line = begin.selectedText(); @@ -382,7 +368,7 @@ void CSVWorld::ScriptEdit::uncommentSelection() begin.endEditBlock(); } -void CSVWorld::ScriptEdit::resizeEvent(QResizeEvent *e) +void CSVWorld::ScriptEdit::resizeEvent(QResizeEvent* e) { QPlainTextEdit::resizeEvent(e); @@ -390,9 +376,9 @@ void CSVWorld::ScriptEdit::resizeEvent(QResizeEvent *e) mLineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height())); } -void CSVWorld::ScriptEdit::contextMenuEvent(QContextMenuEvent *event) +void CSVWorld::ScriptEdit::contextMenuEvent(QContextMenuEvent* event) { - QMenu *menu = createStandardContextMenu(); + QMenu* menu = createStandardContextMenu(); // remove redo/undo since they are disabled QList menuActions = menu->actions(); @@ -410,22 +396,22 @@ void CSVWorld::ScriptEdit::contextMenuEvent(QContextMenuEvent *event) delete menu; } -void CSVWorld::ScriptEdit::lineNumberAreaPaintEvent(QPaintEvent *event) +void CSVWorld::ScriptEdit::lineNumberAreaPaintEvent(QPaintEvent* event) { QPainter painter(mLineNumberArea); QTextBlock block = firstVisibleBlock(); int blockNumber = block.blockNumber(); - int top = (int) blockBoundingGeometry(block).translated(contentOffset()).top(); - int bottom = top + (int) blockBoundingRect(block).height(); + int top = (int)blockBoundingGeometry(block).translated(contentOffset()).top(); + int bottom = top + (int)blockBoundingRect(block).height(); int startBlock = textCursor().blockNumber(); int endBlock = textCursor().blockNumber(); - if(textCursor().hasSelection()) + if (textCursor().hasSelection()) { QString str = textCursor().selection().toPlainText(); int offset = str.count("\n"); - if(textCursor().position() < textCursor().anchor()) + if (textCursor().position() < textCursor().anchor()) endBlock += offset; else startBlock -= offset; @@ -440,7 +426,7 @@ void CSVWorld::ScriptEdit::lineNumberAreaPaintEvent(QPaintEvent *event) { QFont newFont = painter.font(); QString number = QString::number(blockNumber + 1); - if(blockNumber >= startBlock && blockNumber <= endBlock) + if (blockNumber >= startBlock && blockNumber <= endBlock) { painter.setBackground(Qt::cyan); painter.setPen(Qt::darkMagenta); @@ -452,27 +438,29 @@ void CSVWorld::ScriptEdit::lineNumberAreaPaintEvent(QPaintEvent *event) painter.setPen(Qt::black); } painter.setFont(newFont); - painter.drawText(0, top, mLineNumberArea->width(), fontMetrics().height(), - Qt::AlignRight, number); + painter.drawText(0, top, mLineNumberArea->width(), fontMetrics().height(), Qt::AlignRight, number); painter.setFont(font); } block = block.next(); top = bottom; - bottom = top + (int) blockBoundingRect(block).height(); + bottom = top + (int)blockBoundingRect(block).height(); ++blockNumber; } } -CSVWorld::LineNumberArea::LineNumberArea(ScriptEdit *editor) : QWidget(editor), mScriptEdit(editor) -{} +CSVWorld::LineNumberArea::LineNumberArea(ScriptEdit* editor) + : QWidget(editor) + , mScriptEdit(editor) +{ +} QSize CSVWorld::LineNumberArea::sizeHint() const { return QSize(mScriptEdit->lineNumberAreaWidth(), 0); } -void CSVWorld::LineNumberArea::paintEvent(QPaintEvent *event) +void CSVWorld::LineNumberArea::paintEvent(QPaintEvent* event) { mScriptEdit->lineNumberAreaPaintEvent(event); } diff --git a/apps/opencs/view/world/scriptedit.hpp b/apps/opencs/view/world/scriptedit.hpp index 21fabee587..bb7018efd0 100644 --- a/apps/opencs/view/world/scriptedit.hpp +++ b/apps/opencs/view/world/scriptedit.hpp @@ -1,12 +1,12 @@ #ifndef SCRIPTEDIT_H #define SCRIPTEDIT_H +#include +#include #include -#include -#include #include -#include -#include +#include +#include #include "../../model/world/universalid.hpp" @@ -26,118 +26,107 @@ namespace CSVWorld /// \brief Editor for scripts. class ScriptEdit : public QPlainTextEdit { - Q_OBJECT - - public: + Q_OBJECT - class ChangeLock - { - ScriptEdit& mEdit; + public: + class ChangeLock + { + ScriptEdit& mEdit; - ChangeLock (const ChangeLock&); - ChangeLock& operator= (const ChangeLock&); + ChangeLock(const ChangeLock&); + ChangeLock& operator=(const ChangeLock&); - public: - - ChangeLock (ScriptEdit& edit); - ~ChangeLock(); - }; - - friend class ChangeLock; - - private: - - int mChangeLocked; - ScriptHighlighter *mHighlighter; - QTimer mUpdateTimer; - bool mShowLineNum; - LineNumberArea *mLineNumberArea; - QFont mDefaultFont; - QFont mMonoFont; - int mTabCharCount; - bool mMarkOccurrences; - QAction *mCommentAction; - QAction *mUncommentAction; - - protected: + public: + ChangeLock(ScriptEdit& edit); + ~ChangeLock(); + }; - bool event (QEvent *event) override; + friend class ChangeLock; - public: + private: + int mChangeLocked; + ScriptHighlighter* mHighlighter; + QTimer mUpdateTimer; + bool mShowLineNum; + LineNumberArea* mLineNumberArea; + QFont mDefaultFont; + QFont mMonoFont; + int mTabCharCount; + bool mMarkOccurrences; + QAction* mCommentAction; + QAction* mUncommentAction; - ScriptEdit (const CSMDoc::Document& document, ScriptHighlighter::Mode mode, - QWidget* parent); + protected: + bool event(QEvent* event) override; - /// Should changes to the data be ignored (i.e. not cause updated)? - /// - /// \note This mechanism is used to avoid infinite update recursions - bool isChangeLocked() const; + public: + ScriptEdit(const CSMDoc::Document& document, ScriptHighlighter::Mode mode, QWidget* parent); - void lineNumberAreaPaintEvent(QPaintEvent *event); - int lineNumberAreaWidth(); - void showLineNum(bool show); + /// Should changes to the data be ignored (i.e. not cause updated)? + /// + /// \note This mechanism is used to avoid infinite update recursions + bool isChangeLocked() const; - protected: + void lineNumberAreaPaintEvent(QPaintEvent* event); + int lineNumberAreaWidth(); + void showLineNum(bool show); - void resizeEvent(QResizeEvent *e) override; + protected: + void resizeEvent(QResizeEvent* e) override; - void contextMenuEvent(QContextMenuEvent *event) override; + void contextMenuEvent(QContextMenuEvent* event) override; - private: + private: + QVector mAllowedTypes; + const CSMDoc::Document& mDocument; + const QRegExp mWhiteListQoutes; - QVector mAllowedTypes; - const CSMDoc::Document& mDocument; - const QRegExp mWhiteListQoutes; + void dragEnterEvent(QDragEnterEvent* event) override; - void dragEnterEvent (QDragEnterEvent* event) override; + void dropEvent(QDropEvent* event) override; - void dropEvent (QDropEvent* event) override; + void dragMoveEvent(QDragMoveEvent* event) override; - void dragMoveEvent (QDragMoveEvent* event) override; + bool stringNeedsQuote(const std::string& id) const; - bool stringNeedsQuote(const std::string& id) const; + /// \brief Set tab width for script editor. + void setTabWidth(); - /// \brief Set tab width for script editor. - void setTabWidth(); + /// \brief Turn line wrapping in script editor on or off. + /// \param wrap Whether or not to wrap lines. + void wrapLines(bool wrap); - /// \brief Turn line wrapping in script editor on or off. - /// \param wrap Whether or not to wrap lines. - void wrapLines(bool wrap); + private slots: - private slots: + /// \brief Update editor when related setting is changed. + /// \param setting Setting that was changed. + void settingChanged(const CSMPrefs::Setting* setting); - /// \brief Update editor when related setting is changed. - /// \param setting Setting that was changed. - void settingChanged(const CSMPrefs::Setting *setting); + void idListChanged(); - void idListChanged(); + void updateHighlighting(); - void updateHighlighting(); + void updateLineNumberAreaWidth(int newBlockCount); - void updateLineNumberAreaWidth(int newBlockCount); + void updateLineNumberArea(const QRect&, int); - void updateLineNumberArea(const QRect &, int); + void markOccurrences(); - void markOccurrences(); - - void commentSelection(); + void commentSelection(); - void uncommentSelection(); - + void uncommentSelection(); }; class LineNumberArea : public QWidget { - ScriptEdit *mScriptEdit; - - public: - - LineNumberArea(ScriptEdit *editor); - QSize sizeHint() const override; + ScriptEdit* mScriptEdit; - protected: + public: + LineNumberArea(ScriptEdit* editor); + QSize sizeHint() const override; - void paintEvent(QPaintEvent *event) override; + protected: + void paintEvent(QPaintEvent* event) override; }; } #endif // SCRIPTEDIT_H diff --git a/apps/opencs/view/world/scripterrortable.cpp b/apps/opencs/view/world/scripterrortable.cpp index aefddd354b..6467913a7d 100644 --- a/apps/opencs/view/world/scripterrortable.cpp +++ b/apps/opencs/view/world/scripterrortable.cpp @@ -4,118 +4,122 @@ #include -#include -#include -#include #include #include +#include +#include +#include #include "../../model/doc/document.hpp" #include "../../model/prefs/state.hpp" -void CSVWorld::ScriptErrorTable::report (const std::string& message, const Compiler::TokenLoc& loc, Type type) +void CSVWorld::ScriptErrorTable::report(const std::string& message, const Compiler::TokenLoc& loc, Type type) { std::ostringstream stream; stream << message << " (" << loc.mLiteral << ")"; - addMessage (stream.str(), type==Compiler::ErrorHandler::WarningMessage ? - CSMDoc::Message::Severity_Warning : CSMDoc::Message::Severity_Error, - loc.mLine, loc.mColumn-loc.mLiteral.length()); + addMessage(stream.str(), + type == Compiler::ErrorHandler::WarningMessage ? CSMDoc::Message::Severity_Warning + : CSMDoc::Message::Severity_Error, + loc.mLine, loc.mColumn - loc.mLiteral.length()); } -void CSVWorld::ScriptErrorTable::report (const std::string& message, Type type) +void CSVWorld::ScriptErrorTable::report(const std::string& message, Type type) { - addMessage (message, type==Compiler::ErrorHandler::WarningMessage ? - CSMDoc::Message::Severity_Warning : CSMDoc::Message::Severity_Error); + addMessage(message, + type == Compiler::ErrorHandler::WarningMessage ? CSMDoc::Message::Severity_Warning + : CSMDoc::Message::Severity_Error); } -void CSVWorld::ScriptErrorTable::addMessage (const std::string& message, - CSMDoc::Message::Severity severity, int line, int column) +void CSVWorld::ScriptErrorTable::addMessage( + const std::string& message, CSMDoc::Message::Severity severity, int line, int column) { int row = rowCount(); - setRowCount (row+1); + setRowCount(row + 1); - QTableWidgetItem *severityItem = new QTableWidgetItem ( - QString::fromUtf8 (CSMDoc::Message::toString (severity).c_str())); - severityItem->setFlags (severityItem->flags() ^ Qt::ItemIsEditable); - setItem (row, 0, severityItem); + QTableWidgetItem* severityItem + = new QTableWidgetItem(QString::fromUtf8(CSMDoc::Message::toString(severity).c_str())); + severityItem->setFlags(severityItem->flags() ^ Qt::ItemIsEditable); + setItem(row, 0, severityItem); - if (line!=-1) + if (line != -1) { - QTableWidgetItem *lineItem = new QTableWidgetItem; - lineItem->setData (Qt::DisplayRole, line+1); - lineItem->setFlags (lineItem->flags() ^ Qt::ItemIsEditable); - setItem (row, 1, lineItem); - - QTableWidgetItem *columnItem = new QTableWidgetItem; - columnItem->setData (Qt::DisplayRole, column); - columnItem->setFlags (columnItem->flags() ^ Qt::ItemIsEditable); - setItem (row, 3, columnItem); + QTableWidgetItem* lineItem = new QTableWidgetItem; + lineItem->setData(Qt::DisplayRole, line + 1); + lineItem->setFlags(lineItem->flags() ^ Qt::ItemIsEditable); + setItem(row, 1, lineItem); + + QTableWidgetItem* columnItem = new QTableWidgetItem; + columnItem->setData(Qt::DisplayRole, column); + columnItem->setFlags(columnItem->flags() ^ Qt::ItemIsEditable); + setItem(row, 3, columnItem); } else { - QTableWidgetItem *lineItem = new QTableWidgetItem; - lineItem->setData (Qt::DisplayRole, "-"); - lineItem->setFlags (lineItem->flags() ^ Qt::ItemIsEditable); - setItem (row, 1, lineItem); + QTableWidgetItem* lineItem = new QTableWidgetItem; + lineItem->setData(Qt::DisplayRole, "-"); + lineItem->setFlags(lineItem->flags() ^ Qt::ItemIsEditable); + setItem(row, 1, lineItem); } - QTableWidgetItem *messageItem = new QTableWidgetItem (QString::fromUtf8 (message.c_str())); - messageItem->setFlags (messageItem->flags() ^ Qt::ItemIsEditable); - setItem (row, 2, messageItem); + QTableWidgetItem* messageItem = new QTableWidgetItem(QString::fromUtf8(message.c_str())); + messageItem->setFlags(messageItem->flags() ^ Qt::ItemIsEditable); + setItem(row, 2, messageItem); } -void CSVWorld::ScriptErrorTable::setWarningsMode (const std::string& value) +void CSVWorld::ScriptErrorTable::setWarningsMode(const std::string& value) { - if (value=="Ignore") - Compiler::ErrorHandler::setWarningsMode (0); - else if (value=="Normal") - Compiler::ErrorHandler::setWarningsMode (1); - else if (value=="Strict") - Compiler::ErrorHandler::setWarningsMode (2); + if (value == "Ignore") + Compiler::ErrorHandler::setWarningsMode(0); + else if (value == "Normal") + Compiler::ErrorHandler::setWarningsMode(1); + else if (value == "Strict") + Compiler::ErrorHandler::setWarningsMode(2); } -CSVWorld::ScriptErrorTable::ScriptErrorTable (const CSMDoc::Document& document, QWidget *parent) -: QTableWidget (parent), mContext (document.getData()) +CSVWorld::ScriptErrorTable::ScriptErrorTable(const CSMDoc::Document& document, QWidget* parent) + : QTableWidget(parent) + , mContext(document.getData()) { - setColumnCount (4); + setColumnCount(4); QStringList headers; - headers << "Severity" << "Line" << "Description"; - setHorizontalHeaderLabels (headers); - horizontalHeader()->setSectionResizeMode (0, QHeaderView::ResizeToContents); - horizontalHeader()->setSectionResizeMode (1, QHeaderView::ResizeToContents); - horizontalHeader()->setStretchLastSection (true); + headers << "Severity" + << "Line" + << "Description"; + setHorizontalHeaderLabels(headers); + horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents); + horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents); + horizontalHeader()->setStretchLastSection(true); verticalHeader()->hide(); - setColumnHidden (3, true); + setColumnHidden(3, true); - setSelectionMode (QAbstractItemView::NoSelection); + setSelectionMode(QAbstractItemView::NoSelection); - Compiler::registerExtensions (mExtensions); - mContext.setExtensions (&mExtensions); + Compiler::registerExtensions(mExtensions); + mContext.setExtensions(&mExtensions); - connect (&CSMPrefs::State::get(), &CSMPrefs::State::settingChanged, - this, &ScriptErrorTable::settingChanged); + connect(&CSMPrefs::State::get(), &CSMPrefs::State::settingChanged, this, &ScriptErrorTable::settingChanged); CSMPrefs::get()["Scripts"].update(); - connect (this, &QTableWidget::cellClicked, this, &ScriptErrorTable::cellClicked); + connect(this, &QTableWidget::cellClicked, this, &ScriptErrorTable::cellClicked); } -void CSVWorld::ScriptErrorTable::update (const std::string& source) +void CSVWorld::ScriptErrorTable::update(const std::string& source) { clear(); try { - std::istringstream input (source); + std::istringstream input(source); - Compiler::Scanner scanner (*this, input, mContext.getExtensions()); + Compiler::Scanner scanner(*this, input, mContext.getExtensions()); - Compiler::FileParser parser (*this, mContext); + Compiler::FileParser parser(*this, mContext); - scanner.scan (parser); + scanner.scan(parser); } catch (const Compiler::SourceException&) { @@ -123,32 +127,32 @@ void CSVWorld::ScriptErrorTable::update (const std::string& source) } catch (const std::exception& error) { - addMessage (error.what(), CSMDoc::Message::Severity_SeriousError); + addMessage(error.what(), CSMDoc::Message::Severity_SeriousError); } } void CSVWorld::ScriptErrorTable::clear() { - setRowCount (0); + setRowCount(0); } -bool CSVWorld::ScriptErrorTable::clearLocals (const std::string& script) +bool CSVWorld::ScriptErrorTable::clearLocals(const std::string& script) { - return mContext.clearLocals (script); + return mContext.clearLocals(script); } -void CSVWorld::ScriptErrorTable::settingChanged (const CSMPrefs::Setting *setting) +void CSVWorld::ScriptErrorTable::settingChanged(const CSMPrefs::Setting* setting) { - if (*setting=="Scripts/warnings") - setWarningsMode (setting->toString()); + if (*setting == "Scripts/warnings") + setWarningsMode(setting->toString()); } -void CSVWorld::ScriptErrorTable::cellClicked (int row, int column) +void CSVWorld::ScriptErrorTable::cellClicked(int row, int column) { - if (item (row, 3)) + if (item(row, 3)) { - int scriptLine = item (row, 1)->data (Qt::DisplayRole).toInt(); - int scriptColumn = item (row, 3)->data (Qt::DisplayRole).toInt(); - emit highlightError (scriptLine-1, scriptColumn); + int scriptLine = item(row, 1)->data(Qt::DisplayRole).toInt(); + int scriptColumn = item(row, 3)->data(Qt::DisplayRole).toInt(); + emit highlightError(scriptLine - 1, scriptColumn); } } diff --git a/apps/opencs/view/world/scripterrortable.hpp b/apps/opencs/view/world/scripterrortable.hpp index 7165d0fc6a..c002d3c632 100644 --- a/apps/opencs/view/world/scripterrortable.hpp +++ b/apps/opencs/view/world/scripterrortable.hpp @@ -6,8 +6,8 @@ #include #include -#include "../../model/world/scriptcontext.hpp" #include "../../model/doc/messages.hpp" +#include "../../model/world/scriptcontext.hpp" namespace CSMDoc { @@ -23,44 +23,42 @@ namespace CSVWorld { class ScriptErrorTable : public QTableWidget, private Compiler::ErrorHandler { - Q_OBJECT - - Compiler::Extensions mExtensions; - CSMWorld::ScriptContext mContext; + Q_OBJECT - void report (const std::string& message, const Compiler::TokenLoc& loc, Type type) override; - ///< Report error to the user. + Compiler::Extensions mExtensions; + CSMWorld::ScriptContext mContext; - void report (const std::string& message, Type type) override; - ///< Report a file related error + void report(const std::string& message, const Compiler::TokenLoc& loc, Type type) override; + ///< Report error to the user. - void addMessage (const std::string& message, CSMDoc::Message::Severity severity, - int line = -1, int column = -1); + void report(const std::string& message, Type type) override; + ///< Report a file related error - void setWarningsMode (const std::string& value); + void addMessage(const std::string& message, CSMDoc::Message::Severity severity, int line = -1, int column = -1); - public: + void setWarningsMode(const std::string& value); - ScriptErrorTable (const CSMDoc::Document& document, QWidget *parent = nullptr); + public: + ScriptErrorTable(const CSMDoc::Document& document, QWidget* parent = nullptr); - void update (const std::string& source); + void update(const std::string& source); - void clear(); + void clear(); - /// Clear local variable cache for \a script. - /// - /// \return Were there any locals that needed clearing? - bool clearLocals (const std::string& script); + /// Clear local variable cache for \a script. + /// + /// \return Were there any locals that needed clearing? + bool clearLocals(const std::string& script); - private slots: + private slots: - void settingChanged (const CSMPrefs::Setting *setting); + void settingChanged(const CSMPrefs::Setting* setting); - void cellClicked (int row, int column); + void cellClicked(int row, int column); - signals: + signals: - void highlightError (int line, int column); + void highlightError(int line, int column); }; } diff --git a/apps/opencs/view/world/scripthighlighter.cpp b/apps/opencs/view/world/scripthighlighter.cpp index 147beb82a8..68f5faefdc 100644 --- a/apps/opencs/view/world/scripthighlighter.cpp +++ b/apps/opencs/view/world/scripthighlighter.cpp @@ -2,73 +2,69 @@ #include -#include #include +#include -#include "../../model/prefs/setting.hpp" #include "../../model/prefs/category.hpp" +#include "../../model/prefs/setting.hpp" -bool CSVWorld::ScriptHighlighter::parseInt (int value, const Compiler::TokenLoc& loc, - Compiler::Scanner& scanner) +bool CSVWorld::ScriptHighlighter::parseInt(int value, const Compiler::TokenLoc& loc, Compiler::Scanner& scanner) { - highlight (loc, Type_Int); + highlight(loc, Type_Int); return true; } -bool CSVWorld::ScriptHighlighter::parseFloat (float value, const Compiler::TokenLoc& loc, - Compiler::Scanner& scanner) +bool CSVWorld::ScriptHighlighter::parseFloat(float value, const Compiler::TokenLoc& loc, Compiler::Scanner& scanner) { - highlight (loc, Type_Float); + highlight(loc, Type_Float); return true; } -bool CSVWorld::ScriptHighlighter::parseName (const std::string& name, const Compiler::TokenLoc& loc, - Compiler::Scanner& scanner) +bool CSVWorld::ScriptHighlighter::parseName( + const std::string& name, const Compiler::TokenLoc& loc, Compiler::Scanner& scanner) { - highlight (loc, mContext.isId (name) ? Type_Id : Type_Name); + highlight(loc, mContext.isId(name) ? Type_Id : Type_Name); return true; } -bool CSVWorld::ScriptHighlighter::parseKeyword (int keyword, const Compiler::TokenLoc& loc, - Compiler::Scanner& scanner) +bool CSVWorld::ScriptHighlighter::parseKeyword(int keyword, const Compiler::TokenLoc& loc, Compiler::Scanner& scanner) { - if (((mMode==Mode_Console || mMode==Mode_Dialogue) && - (keyword==Compiler::Scanner::K_begin || keyword==Compiler::Scanner::K_end || - keyword==Compiler::Scanner::K_short || keyword==Compiler::Scanner::K_long || - keyword==Compiler::Scanner::K_float)) - || (mMode==Mode_Console && (keyword==Compiler::Scanner::K_if || - keyword==Compiler::Scanner::K_endif || keyword==Compiler::Scanner::K_else || - keyword==Compiler::Scanner::K_elseif || keyword==Compiler::Scanner::K_while || - keyword==Compiler::Scanner::K_endwhile))) - return parseName (loc.mLiteral, loc, scanner); - - highlight (loc, Type_Keyword); + if (((mMode == Mode_Console || mMode == Mode_Dialogue) + && (keyword == Compiler::Scanner::K_begin || keyword == Compiler::Scanner::K_end + || keyword == Compiler::Scanner::K_short || keyword == Compiler::Scanner::K_long + || keyword == Compiler::Scanner::K_float)) + || (mMode == Mode_Console + && (keyword == Compiler::Scanner::K_if || keyword == Compiler::Scanner::K_endif + || keyword == Compiler::Scanner::K_else || keyword == Compiler::Scanner::K_elseif + || keyword == Compiler::Scanner::K_while || keyword == Compiler::Scanner::K_endwhile))) + return parseName(loc.mLiteral, loc, scanner); + + highlight(loc, Type_Keyword); return true; } -bool CSVWorld::ScriptHighlighter::parseSpecial (int code, const Compiler::TokenLoc& loc, - Compiler::Scanner& scanner) +bool CSVWorld::ScriptHighlighter::parseSpecial(int code, const Compiler::TokenLoc& loc, Compiler::Scanner& scanner) { - highlight (loc, Type_Special); + highlight(loc, Type_Special); return true; } -bool CSVWorld::ScriptHighlighter::parseComment (const std::string& comment, - const Compiler::TokenLoc& loc, Compiler::Scanner& scanner) +bool CSVWorld::ScriptHighlighter::parseComment( + const std::string& comment, const Compiler::TokenLoc& loc, Compiler::Scanner& scanner) { - highlight (loc, Type_Comment); + highlight(loc, Type_Comment); return true; } -void CSVWorld::ScriptHighlighter::parseEOF (Compiler::Scanner& scanner) -{} +void CSVWorld::ScriptHighlighter::parseEOF(Compiler::Scanner& scanner) {} -void CSVWorld::ScriptHighlighter::highlight (const Compiler::TokenLoc& loc, Type type) +void CSVWorld::ScriptHighlighter::highlight(const Compiler::TokenLoc& loc, Type type) { // We should take in account multibyte characters int length = 0; const char* token = loc.mLiteral.c_str(); - while (*token) length += (*token++ & 0xc0) != 0x80; + while (*token) + length += (*token++ & 0xc0) != 0x80; int index = loc.mColumn; @@ -79,40 +75,41 @@ void CSVWorld::ScriptHighlighter::highlight (const Compiler::TokenLoc& loc, Type if (mMarkOccurrences && type == Type_Name && loc.mLiteral == mMarkedWord) scheme.merge(mScheme[Type_Highlight]); - setFormat (index, length, scheme); + setFormat(index, length, scheme); } -CSVWorld::ScriptHighlighter::ScriptHighlighter (const CSMWorld::Data& data, Mode mode, - QTextDocument *parent) - : QSyntaxHighlighter (parent) - , Compiler::Parser (mErrorHandler, mContext) - , mContext (data) - , mMode (mode) - , mMarkOccurrences (false) +CSVWorld::ScriptHighlighter::ScriptHighlighter(const CSMWorld::Data& data, Mode mode, QTextDocument* parent) + : QSyntaxHighlighter(parent) + , Compiler::Parser(mErrorHandler, mContext) + , mContext(data) + , mMode(mode) + , mMarkOccurrences(false) { - QColor color ("black"); + QColor color("black"); QTextCharFormat format; - format.setForeground (color); + format.setForeground(color); - for (int i=0; i<=Type_Id; ++i) - mScheme.insert (std::make_pair (static_cast (i), format)); + for (int i = 0; i <= Type_Id; ++i) + mScheme.insert(std::make_pair(static_cast(i), format)); // configure compiler - Compiler::registerExtensions (mExtensions); - mContext.setExtensions (&mExtensions); + Compiler::registerExtensions(mExtensions); + mContext.setExtensions(&mExtensions); } -void CSVWorld::ScriptHighlighter::highlightBlock (const QString& text) +void CSVWorld::ScriptHighlighter::highlightBlock(const QString& text) { - std::istringstream stream (text.toUtf8().constData()); + std::istringstream stream(text.toUtf8().constData()); - Compiler::Scanner scanner (mErrorHandler, stream, mContext.getExtensions()); + Compiler::Scanner scanner(mErrorHandler, stream, mContext.getExtensions()); try { - scanner.scan (*this); + scanner.scan(*this); } - catch (...) {} // ignore syntax errors + catch (...) + { + } // ignore syntax errors } void CSVWorld::ScriptHighlighter::setMarkOccurrences(bool flag) @@ -130,26 +127,22 @@ void CSVWorld::ScriptHighlighter::invalidateIds() mContext.invalidateIds(); } -bool CSVWorld::ScriptHighlighter::settingChanged (const CSMPrefs::Setting *setting) +bool CSVWorld::ScriptHighlighter::settingChanged(const CSMPrefs::Setting* setting) { - if (setting->getParent()->getKey()=="Scripts") + if (setting->getParent()->getKey() == "Scripts") { - static const char *const colours[Type_Id+2] = - { - "colour-int", "colour-float", "colour-name", "colour-keyword", - "colour-special", "colour-comment", "colour-highlight", "colour-id", - 0 - }; - - for (int i=0; colours[i]; ++i) - if (setting->getKey()==colours[i]) + static const char* const colours[Type_Id + 2] = { "colour-int", "colour-float", "colour-name", "colour-keyword", + "colour-special", "colour-comment", "colour-highlight", "colour-id", 0 }; + + for (int i = 0; colours[i]; ++i) + if (setting->getKey() == colours[i]) { QTextCharFormat format; if (i == Type_Highlight) - format.setBackground (setting->toColor()); + format.setBackground(setting->toColor()); else - format.setForeground (setting->toColor()); - mScheme[static_cast (i)] = format; + format.setForeground(setting->toColor()); + mScheme[static_cast(i)] = format; return true; } } diff --git a/apps/opencs/view/world/scripthighlighter.hpp b/apps/opencs/view/world/scripthighlighter.hpp index 9b4a5b7be0..cefe7e1fef 100644 --- a/apps/opencs/view/world/scripthighlighter.hpp +++ b/apps/opencs/view/world/scripthighlighter.hpp @@ -6,9 +6,9 @@ #include +#include #include #include -#include #include "../../model/world/scriptcontext.hpp" @@ -21,87 +21,78 @@ namespace CSVWorld { class ScriptHighlighter : public QSyntaxHighlighter, private Compiler::Parser { - public: - - enum Type - { - Type_Int = 0, - Type_Float = 1, - Type_Name = 2, - Type_Keyword = 3, - Type_Special = 4, - Type_Comment = 5, - Type_Highlight = 6, - Type_Id = 7 - }; - - enum Mode - { - Mode_General, - Mode_Console, - Mode_Dialogue - }; - - private: - - Compiler::NullErrorHandler mErrorHandler; - Compiler::Extensions mExtensions; - CSMWorld::ScriptContext mContext; - std::map mScheme; - Mode mMode; - bool mMarkOccurrences; - std::string mMarkedWord; - - private: - - bool parseInt (int value, const Compiler::TokenLoc& loc, - Compiler::Scanner& scanner) override; - ///< Handle an int token. - /// \return fetch another token? - - bool parseFloat (float value, const Compiler::TokenLoc& loc, - Compiler::Scanner& scanner) override; - ///< Handle a float token. - /// \return fetch another token? - - bool parseName (const std::string& name, - const Compiler::TokenLoc& loc, Compiler::Scanner& scanner) override; - ///< Handle a name token. - /// \return fetch another token? - - bool parseKeyword (int keyword, const Compiler::TokenLoc& loc, - Compiler::Scanner& scanner) override; - ///< Handle a keyword token. - /// \return fetch another token? - - bool parseSpecial (int code, const Compiler::TokenLoc& loc, - Compiler::Scanner& scanner) override; - ///< Handle a special character token. - /// \return fetch another token? - - bool parseComment (const std::string& comment, const Compiler::TokenLoc& loc, - Compiler::Scanner& scanner) override; - ///< Handle comment token. - /// \return fetch another token? - - void parseEOF (Compiler::Scanner& scanner) override; - ///< Handle EOF token. - - void highlight (const Compiler::TokenLoc& loc, Type type); - - public: - - ScriptHighlighter (const CSMWorld::Data& data, Mode mode, QTextDocument *parent); - - void highlightBlock (const QString& text) override; - - void setMarkOccurrences(bool); - - void setMarkedWord(const std::string& name); - - void invalidateIds(); - - bool settingChanged (const CSMPrefs::Setting *setting); + public: + enum Type + { + Type_Int = 0, + Type_Float = 1, + Type_Name = 2, + Type_Keyword = 3, + Type_Special = 4, + Type_Comment = 5, + Type_Highlight = 6, + Type_Id = 7 + }; + + enum Mode + { + Mode_General, + Mode_Console, + Mode_Dialogue + }; + + private: + Compiler::NullErrorHandler mErrorHandler; + Compiler::Extensions mExtensions; + CSMWorld::ScriptContext mContext; + std::map mScheme; + Mode mMode; + bool mMarkOccurrences; + std::string mMarkedWord; + + private: + bool parseInt(int value, const Compiler::TokenLoc& loc, Compiler::Scanner& scanner) override; + ///< Handle an int token. + /// \return fetch another token? + + bool parseFloat(float value, const Compiler::TokenLoc& loc, Compiler::Scanner& scanner) override; + ///< Handle a float token. + /// \return fetch another token? + + bool parseName(const std::string& name, const Compiler::TokenLoc& loc, Compiler::Scanner& scanner) override; + ///< Handle a name token. + /// \return fetch another token? + + bool parseKeyword(int keyword, const Compiler::TokenLoc& loc, Compiler::Scanner& scanner) override; + ///< Handle a keyword token. + /// \return fetch another token? + + bool parseSpecial(int code, const Compiler::TokenLoc& loc, Compiler::Scanner& scanner) override; + ///< Handle a special character token. + /// \return fetch another token? + + bool parseComment( + const std::string& comment, const Compiler::TokenLoc& loc, Compiler::Scanner& scanner) override; + ///< Handle comment token. + /// \return fetch another token? + + void parseEOF(Compiler::Scanner& scanner) override; + ///< Handle EOF token. + + void highlight(const Compiler::TokenLoc& loc, Type type); + + public: + ScriptHighlighter(const CSMWorld::Data& data, Mode mode, QTextDocument* parent); + + void highlightBlock(const QString& text) override; + + void setMarkOccurrences(bool); + + void setMarkedWord(const std::string& name); + + void invalidateIds(); + + bool settingChanged(const CSMPrefs::Setting* setting); }; } diff --git a/apps/opencs/view/world/scriptsubview.cpp b/apps/opencs/view/world/scriptsubview.cpp index e4cc3dc86c..a9bccd394c 100644 --- a/apps/opencs/view/world/scriptsubview.cpp +++ b/apps/opencs/view/world/scriptsubview.cpp @@ -8,42 +8,42 @@ #include #include "../../model/doc/document.hpp" -#include "../../model/world/universalid.hpp" -#include "../../model/world/data.hpp" +#include "../../model/prefs/state.hpp" #include "../../model/world/commands.hpp" +#include "../../model/world/data.hpp" #include "../../model/world/idtable.hpp" -#include "../../model/prefs/state.hpp" +#include "../../model/world/universalid.hpp" -#include "scriptedit.hpp" -#include "recordbuttonbar.hpp" -#include "tablebottombox.hpp" #include "genericcreator.hpp" +#include "recordbuttonbar.hpp" +#include "scriptedit.hpp" #include "scripterrortable.hpp" +#include "tablebottombox.hpp" void CSVWorld::ScriptSubView::addButtonBar() { if (mButtons) return; - mButtons = new RecordButtonBar (getUniversalId(), *mModel, mBottom, &mCommandDispatcher, this); + mButtons = new RecordButtonBar(getUniversalId(), *mModel, mBottom, &mCommandDispatcher, this); - mLayout.insertWidget (1, mButtons); + mLayout.insertWidget(1, mButtons); - connect (mButtons, &RecordButtonBar::switchToRow, this, &ScriptSubView::switchToRow); + connect(mButtons, &RecordButtonBar::switchToRow, this, &ScriptSubView::switchToRow); - connect (this, &ScriptSubView::universalIdChanged, mButtons, &RecordButtonBar::universalIdChanged); + connect(this, &ScriptSubView::universalIdChanged, mButtons, &RecordButtonBar::universalIdChanged); } void CSVWorld::ScriptSubView::recompile() { if (!mCompileDelay->isActive() && !isDeleted()) - mCompileDelay->start (CSMPrefs::get()["Scripts"]["compile-delay"].toInt()); + mCompileDelay->start(CSMPrefs::get()["Scripts"]["compile-delay"].toInt()); } bool CSVWorld::ScriptSubView::isDeleted() const { - return mModel->data (mModel->getModelIndex (getUniversalId().getId(), mStateColumn)).toInt() - ==CSMWorld::RecordBase::State_Deleted; + return mModel->data(mModel->getModelIndex(getUniversalId().getId(), mStateColumn)).toInt() + == CSMWorld::RecordBase::State_Deleted; } void CSVWorld::ScriptSubView::updateDeletedState() @@ -52,11 +52,11 @@ void CSVWorld::ScriptSubView::updateDeletedState() { mErrors->clear(); adjustSplitter(); - mEditor->setEnabled (false); + mEditor->setEnabled(false); } else { - mEditor->setEnabled (true); + mEditor->setEnabled(true); recompile(); } } @@ -70,7 +70,7 @@ void CSVWorld::ScriptSubView::adjustSplitter() if (mErrors->height()) return; // keep old height if the error panel was already open - sizes << (mMain->height()-mErrorHeight-mMain->handleWidth()) << mErrorHeight; + sizes << (mMain->height() - mErrorHeight - mMain->handleWidth()) << mErrorHeight; } else { @@ -80,87 +80,88 @@ void CSVWorld::ScriptSubView::adjustSplitter() sizes << 1 << 0; } - mMain->setSizes (sizes); + mMain->setSizes(sizes); } -CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) -: SubView (id), mDocument (document), mColumn (-1), mBottom(nullptr), mButtons (nullptr), - mCommandDispatcher (document, CSMWorld::UniversalId::getParentType (id.getType())), - mErrorHeight (CSMPrefs::get()["Scripts"]["error-height"].toInt()) +CSVWorld::ScriptSubView::ScriptSubView(const CSMWorld::UniversalId& id, CSMDoc::Document& document) + : SubView(id) + , mDocument(document) + , mColumn(-1) + , mBottom(nullptr) + , mButtons(nullptr) + , mCommandDispatcher(document, CSMWorld::UniversalId::getParentType(id.getType())) + , mErrorHeight(CSMPrefs::get()["Scripts"]["error-height"].toInt()) { - std::vector selection (1, id.getId()); - mCommandDispatcher.setSelection (selection); + std::vector selection(1, id.getId()); + mCommandDispatcher.setSelection(selection); - mMain = new QSplitter (this); - mMain->setOrientation (Qt::Vertical); - mLayout.addWidget (mMain, 2); + mMain = new QSplitter(this); + mMain->setOrientation(Qt::Vertical); + mLayout.addWidget(mMain, 2); - mEditor = new ScriptEdit (mDocument, ScriptHighlighter::Mode_General, this); - mMain->addWidget (mEditor); - mMain->setCollapsible (0, false); + mEditor = new ScriptEdit(mDocument, ScriptHighlighter::Mode_General, this); + mMain->addWidget(mEditor); + mMain->setCollapsible(0, false); - mErrors = new ScriptErrorTable (document, this); - mMain->addWidget (mErrors); + mErrors = new ScriptErrorTable(document, this); + mMain->addWidget(mErrors); QList sizes; sizes << 1 << 0; - mMain->setSizes (sizes); + mMain->setSizes(sizes); - QWidget *widget = new QWidget (this); - widget->setLayout (&mLayout); - setWidget (widget); + QWidget* widget = new QWidget(this); + widget->setLayout(&mLayout); + setWidget(widget); - mModel = &dynamic_cast ( - *document.getData().getTableModel (CSMWorld::UniversalId::Type_Scripts)); + mModel = &dynamic_cast(*document.getData().getTableModel(CSMWorld::UniversalId::Type_Scripts)); - mColumn = mModel->findColumnIndex (CSMWorld::Columns::ColumnId_ScriptText); - mIdColumn = mModel->findColumnIndex (CSMWorld::Columns::ColumnId_Id); - mStateColumn = mModel->findColumnIndex (CSMWorld::Columns::ColumnId_Modification); + mColumn = mModel->findColumnIndex(CSMWorld::Columns::ColumnId_ScriptText); + mIdColumn = mModel->findColumnIndex(CSMWorld::Columns::ColumnId_Id); + mStateColumn = mModel->findColumnIndex(CSMWorld::Columns::ColumnId_Modification); - QString source = mModel->data (mModel->getModelIndex (id.getId(), mColumn)).toString(); + QString source = mModel->data(mModel->getModelIndex(id.getId(), mColumn)).toString(); - mEditor->setPlainText (source); + mEditor->setPlainText(source); // bottom box and buttons - mBottom = new TableBottomBox (CreatorFactory(), document, id, this); + mBottom = new TableBottomBox(CreatorFactory(), document, id, this); - connect (mBottom, &TableBottomBox::requestFocus, this, &ScriptSubView::switchToId); + connect(mBottom, &TableBottomBox::requestFocus, this, &ScriptSubView::switchToId); - mLayout.addWidget (mBottom); + mLayout.addWidget(mBottom); // signals - connect (mEditor, &ScriptEdit::textChanged, this, &ScriptSubView::textChanged); + connect(mEditor, &ScriptEdit::textChanged, this, &ScriptSubView::textChanged); - connect (mModel, &CSMWorld::IdTable::dataChanged, this, &ScriptSubView::dataChanged); + connect(mModel, &CSMWorld::IdTable::dataChanged, this, &ScriptSubView::dataChanged); - connect (mModel, &CSMWorld::IdTable::rowsAboutToBeRemoved, - this, &ScriptSubView::rowsAboutToBeRemoved); + connect(mModel, &CSMWorld::IdTable::rowsAboutToBeRemoved, this, &ScriptSubView::rowsAboutToBeRemoved); updateStatusBar(); connect(mEditor, &ScriptEdit::cursorPositionChanged, this, &ScriptSubView::updateStatusBar); - mErrors->update (source.toUtf8().constData()); + mErrors->update(source.toUtf8().constData()); - connect (mErrors, &ScriptErrorTable::highlightError, this, &ScriptSubView::highlightError); + connect(mErrors, &ScriptErrorTable::highlightError, this, &ScriptSubView::highlightError); - mCompileDelay = new QTimer (this); - mCompileDelay->setSingleShot (true); - connect (mCompileDelay, &QTimer::timeout, this, &ScriptSubView::updateRequest); + mCompileDelay = new QTimer(this); + mCompileDelay->setSingleShot(true); + connect(mCompileDelay, &QTimer::timeout, this, &ScriptSubView::updateRequest); updateDeletedState(); - connect (&CSMPrefs::State::get(), &CSMPrefs::State::settingChanged, - this, &ScriptSubView::settingChanged); + connect(&CSMPrefs::State::get(), &CSMPrefs::State::settingChanged, this, &ScriptSubView::settingChanged); CSMPrefs::get()["Scripts"].update(); } -void CSVWorld::ScriptSubView::setStatusBar (bool show) +void CSVWorld::ScriptSubView::setStatusBar(bool show) { - mBottom->setStatusBar (show); + mBottom->setStatusBar(show); } -void CSVWorld::ScriptSubView::settingChanged (const CSMPrefs::Setting *setting) +void CSVWorld::ScriptSubView::settingChanged(const CSMPrefs::Setting* setting) { - if (*setting=="Scripts/toolbar") + if (*setting == "Scripts/toolbar") { if (setting->isTrue()) { @@ -168,58 +169,58 @@ void CSVWorld::ScriptSubView::settingChanged (const CSMPrefs::Setting *setting) } else if (mButtons) { - mLayout.removeWidget (mButtons); + mLayout.removeWidget(mButtons); delete mButtons; mButtons = nullptr; } } - else if (*setting=="Scripts/compile-delay") + else if (*setting == "Scripts/compile-delay") { - mCompileDelay->setInterval (setting->toInt()); + mCompileDelay->setInterval(setting->toInt()); } - else if (*setting=="Scripts/warnings") + else if (*setting == "Scripts/warnings") recompile(); } -void CSVWorld::ScriptSubView::updateStatusBar () +void CSVWorld::ScriptSubView::updateStatusBar() { - mBottom->positionChanged (mEditor->textCursor().blockNumber() + 1, - mEditor->textCursor().columnNumber() + 1); + mBottom->positionChanged(mEditor->textCursor().blockNumber() + 1, mEditor->textCursor().columnNumber() + 1); } -void CSVWorld::ScriptSubView::setEditLock (bool locked) +void CSVWorld::ScriptSubView::setEditLock(bool locked) { - mEditor->setReadOnly (locked); + mEditor->setReadOnly(locked); if (mButtons) - mButtons->setEditLock (locked); + mButtons->setEditLock(locked); - mCommandDispatcher.setEditLock (locked); + mCommandDispatcher.setEditLock(locked); } -void CSVWorld::ScriptSubView::useHint (const std::string& hint) +void CSVWorld::ScriptSubView::useHint(const std::string& hint) { if (hint.empty()) return; unsigned line = 0, column = 0; char c; - std::istringstream stream (hint.c_str()+1); - switch(hint[0]) + std::istringstream stream(hint.c_str() + 1); + switch (hint[0]) { case 'R': case 'r': { - QModelIndex index = mModel->getModelIndex (getUniversalId().getId(), mColumn); - QString source = mModel->data (index).toString(); + QModelIndex index = mModel->getModelIndex(getUniversalId().getId(), mColumn); + QString source = mModel->data(index).toString(); unsigned stringSize = source.length(); unsigned pos, dummy; - if (!(stream >> c >> dummy >> pos) ) + if (!(stream >> c >> dummy >> pos)) return; if (pos > stringSize) { - Log(Debug::Warning) << "CSVWorld::ScriptSubView: requested position is higher than actual string length"; + Log(Debug::Warning) + << "CSVWorld::ScriptSubView: requested position is higher than actual string length"; pos = stringSize; } @@ -228,7 +229,7 @@ void CSVWorld::ScriptSubView::useHint (const std::string& hint) if (source[i] == '\n') { ++line; - column = i+1; + column = i + 1; } } column = pos - column; @@ -241,12 +242,12 @@ void CSVWorld::ScriptSubView::useHint (const std::string& hint) QTextCursor cursor = mEditor->textCursor(); - cursor.movePosition (QTextCursor::Start); - if (cursor.movePosition (QTextCursor::Down, QTextCursor::MoveAnchor, line)) - cursor.movePosition (QTextCursor::Right, QTextCursor::MoveAnchor, column); + cursor.movePosition(QTextCursor::Start); + if (cursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, line)) + cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, column); mEditor->setFocus(); - mEditor->setTextCursor (cursor); + mEditor->setTextCursor(cursor); } void CSVWorld::ScriptSubView::textChanged() @@ -254,46 +255,46 @@ void CSVWorld::ScriptSubView::textChanged() if (mEditor->isChangeLocked()) return; - ScriptEdit::ChangeLock lock (*mEditor); + ScriptEdit::ChangeLock lock(*mEditor); QString source = mEditor->toPlainText(); - mDocument.getUndoStack().push (new CSMWorld::ModifyCommand (*mModel, - mModel->getModelIndex (getUniversalId().getId(), mColumn), source)); + mDocument.getUndoStack().push( + new CSMWorld::ModifyCommand(*mModel, mModel->getModelIndex(getUniversalId().getId(), mColumn), source)); recompile(); } -void CSVWorld::ScriptSubView::dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) +void CSVWorld::ScriptSubView::dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) { if (mEditor->isChangeLocked()) return; - ScriptEdit::ChangeLock lock (*mEditor); + ScriptEdit::ChangeLock lock(*mEditor); bool updateRequired = false; - for (int i=topLeft.row(); i<=bottomRight.row(); ++i) + for (int i = topLeft.row(); i <= bottomRight.row(); ++i) { - std::string id = mModel->data (mModel->index (i, mIdColumn)).toString().toUtf8().constData(); - if (mErrors->clearLocals (id)) + std::string id = mModel->data(mModel->index(i, mIdColumn)).toString().toUtf8().constData(); + if (mErrors->clearLocals(id)) updateRequired = true; } - QModelIndex index = mModel->getModelIndex (getUniversalId().getId(), mColumn); + QModelIndex index = mModel->getModelIndex(getUniversalId().getId(), mColumn); - if (index.row()>=topLeft.row() && index.row()<=bottomRight.row()) + if (index.row() >= topLeft.row() && index.row() <= bottomRight.row()) { - if (mStateColumn>=topLeft.column() && mStateColumn<=bottomRight.column()) + if (mStateColumn >= topLeft.column() && mStateColumn <= bottomRight.column()) updateDeletedState(); - if (mColumn>=topLeft.column() && mColumn<=bottomRight.column()) + if (mColumn >= topLeft.column() && mColumn <= bottomRight.column()) { - QString source = mModel->data (index).toString(); + QString source = mModel->data(index).toString(); QTextCursor cursor = mEditor->textCursor(); - mEditor->setPlainText (source); - mEditor->setTextCursor (cursor); + mEditor->setPlainText(source); + mEditor->setTextCursor(cursor); updateRequired = true; } @@ -303,66 +304,66 @@ void CSVWorld::ScriptSubView::dataChanged (const QModelIndex& topLeft, const QMo recompile(); } -void CSVWorld::ScriptSubView::rowsAboutToBeRemoved (const QModelIndex& parent, int start, int end) +void CSVWorld::ScriptSubView::rowsAboutToBeRemoved(const QModelIndex& parent, int start, int end) { bool updateRequired = false; - for (int i=start; i<=end; ++i) + for (int i = start; i <= end; ++i) { - std::string id = mModel->data (mModel->index (i, mIdColumn)).toString().toUtf8().constData(); - if (mErrors->clearLocals (id)) + std::string id = mModel->data(mModel->index(i, mIdColumn)).toString().toUtf8().constData(); + if (mErrors->clearLocals(id)) updateRequired = true; } if (updateRequired) recompile(); - QModelIndex index = mModel->getModelIndex (getUniversalId().getId(), mColumn); + QModelIndex index = mModel->getModelIndex(getUniversalId().getId(), mColumn); - if (!parent.isValid() && index.row()>=start && index.row()<=end) + if (!parent.isValid() && index.row() >= start && index.row() <= end) emit closeRequest(); } -void CSVWorld::ScriptSubView::switchToRow (int row) +void CSVWorld::ScriptSubView::switchToRow(int row) { - int idColumn = mModel->findColumnIndex (CSMWorld::Columns::ColumnId_Id); - std::string id = mModel->data (mModel->index (row, idColumn)).toString().toUtf8().constData(); - setUniversalId (CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Script, id)); + int idColumn = mModel->findColumnIndex(CSMWorld::Columns::ColumnId_Id); + std::string id = mModel->data(mModel->index(row, idColumn)).toString().toUtf8().constData(); + setUniversalId(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Script, id)); - bool oldSignalsState = mEditor->blockSignals( true ); - mEditor->setPlainText( mModel->data(mModel->index(row, mColumn)).toString() ); - mEditor->blockSignals( oldSignalsState ); + bool oldSignalsState = mEditor->blockSignals(true); + mEditor->setPlainText(mModel->data(mModel->index(row, mColumn)).toString()); + mEditor->blockSignals(oldSignalsState); - std::vector selection (1, id); - mCommandDispatcher.setSelection (selection); + std::vector selection(1, id); + mCommandDispatcher.setSelection(selection); updateDeletedState(); } -void CSVWorld::ScriptSubView::switchToId (const std::string& id) +void CSVWorld::ScriptSubView::switchToId(const std::string& id) { - switchToRow (mModel->getModelIndex (id, 0).row()); + switchToRow(mModel->getModelIndex(id, 0).row()); } -void CSVWorld::ScriptSubView::highlightError (int line, int column) +void CSVWorld::ScriptSubView::highlightError(int line, int column) { QTextCursor cursor = mEditor->textCursor(); - cursor.movePosition (QTextCursor::Start); - if (cursor.movePosition (QTextCursor::Down, QTextCursor::MoveAnchor, line)) - cursor.movePosition (QTextCursor::Right, QTextCursor::MoveAnchor, column); + cursor.movePosition(QTextCursor::Start); + if (cursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, line)) + cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, column); mEditor->setFocus(); - mEditor->setTextCursor (cursor); + mEditor->setTextCursor(cursor); } void CSVWorld::ScriptSubView::updateRequest() { - QModelIndex index = mModel->getModelIndex (getUniversalId().getId(), mColumn); + QModelIndex index = mModel->getModelIndex(getUniversalId().getId(), mColumn); - QString source = mModel->data (index).toString(); + QString source = mModel->data(index).toString(); - mErrors->update (source.toUtf8().constData()); + mErrors->update(source.toUtf8().constData()); adjustSplitter(); } diff --git a/apps/opencs/view/world/scriptsubview.hpp b/apps/opencs/view/world/scriptsubview.hpp index a4171db6ee..3fe0b4dbe9 100644 --- a/apps/opencs/view/world/scriptsubview.hpp +++ b/apps/opencs/view/world/scriptsubview.hpp @@ -36,66 +36,64 @@ namespace CSVWorld class ScriptSubView : public CSVDoc::SubView { - Q_OBJECT + Q_OBJECT - ScriptEdit *mEditor; - CSMDoc::Document& mDocument; - CSMWorld::IdTable *mModel; - int mColumn; - int mIdColumn; - int mStateColumn; - TableBottomBox *mBottom; - RecordButtonBar *mButtons; - CSMWorld::CommandDispatcher mCommandDispatcher; - QVBoxLayout mLayout; - QSplitter *mMain; - ScriptErrorTable *mErrors; - QTimer *mCompileDelay; - int mErrorHeight; + ScriptEdit* mEditor; + CSMDoc::Document& mDocument; + CSMWorld::IdTable* mModel; + int mColumn; + int mIdColumn; + int mStateColumn; + TableBottomBox* mBottom; + RecordButtonBar* mButtons; + CSMWorld::CommandDispatcher mCommandDispatcher; + QVBoxLayout mLayout; + QSplitter* mMain; + ScriptErrorTable* mErrors; + QTimer* mCompileDelay; + int mErrorHeight; - private: + private: + void addButtonBar(); - void addButtonBar(); + void recompile(); - void recompile(); + bool isDeleted() const; - bool isDeleted() const; + void updateDeletedState(); - void updateDeletedState(); + void adjustSplitter(); - void adjustSplitter(); + public: + ScriptSubView(const CSMWorld::UniversalId& id, CSMDoc::Document& document); - public: + void setEditLock(bool locked) override; - ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document); + void useHint(const std::string& hint) override; - void setEditLock (bool locked) override; + void setStatusBar(bool show) override; - void useHint (const std::string& hint) override; + public slots: - void setStatusBar (bool show) override; + void textChanged(); - public slots: + void dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); - void textChanged(); + void rowsAboutToBeRemoved(const QModelIndex& parent, int start, int end); - void dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); + private slots: - void rowsAboutToBeRemoved (const QModelIndex& parent, int start, int end); + void settingChanged(const CSMPrefs::Setting* setting); - private slots: + void updateStatusBar(); - void settingChanged (const CSMPrefs::Setting *setting); + void switchToRow(int row); - void updateStatusBar(); + void switchToId(const std::string& id); - void switchToRow (int row); + void highlightError(int line, int column); - void switchToId (const std::string& id); - - void highlightError (int line, int column); - - void updateRequest(); + void updateRequest(); }; } diff --git a/apps/opencs/view/world/startscriptcreator.cpp b/apps/opencs/view/world/startscriptcreator.cpp index 25b0301fb8..2bbb25933e 100644 --- a/apps/opencs/view/world/startscriptcreator.cpp +++ b/apps/opencs/view/world/startscriptcreator.cpp @@ -19,22 +19,17 @@ std::string CSVWorld::StartScriptCreator::getId() const CSMWorld::IdTable& CSVWorld::StartScriptCreator::getStartScriptsTable() const { - return dynamic_cast ( - *getData().getTableModel(getCollectionId()) - ); + return dynamic_cast(*getData().getTableModel(getCollectionId())); } -CSVWorld::StartScriptCreator::StartScriptCreator( - CSMWorld::Data &data, - QUndoStack &undoStack, - const CSMWorld::UniversalId &id, - CSMWorld::IdCompletionManager& completionManager -) : GenericCreator(data, undoStack, id) +CSVWorld::StartScriptCreator::StartScriptCreator(CSMWorld::Data& data, QUndoStack& undoStack, + const CSMWorld::UniversalId& id, CSMWorld::IdCompletionManager& completionManager) + : GenericCreator(data, undoStack, id) { setManualEditing(false); // Add script ID input label. - QLabel *label = new QLabel("Script", this); + QLabel* label = new QLabel("Script", this); insertBeforeButtons(label, false); // Add script ID input with auto-completion. @@ -48,9 +43,7 @@ CSVWorld::StartScriptCreator::StartScriptCreator( connect(mScript, &CSVWidget::DropLineEdit::returnPressed, this, &StartScriptCreator::inputReturnPressed); } -void CSVWorld::StartScriptCreator::cloneMode( - const std::string& originId, - const CSMWorld::UniversalId::Type type) +void CSVWorld::StartScriptCreator::cloneMode(const std::string& originId, const CSMWorld::UniversalId::Type type) { CSVWorld::GenericCreator::cloneMode(originId, type); @@ -98,14 +91,8 @@ void CSVWorld::StartScriptCreator::scriptChanged() update(); } -CSVWorld::Creator *CSVWorld::StartScriptCreatorFactory::makeCreator( - CSMDoc::Document& document, - const CSMWorld::UniversalId& id) const +CSVWorld::Creator* CSVWorld::StartScriptCreatorFactory::makeCreator( + CSMDoc::Document& document, const CSMWorld::UniversalId& id) const { - return new StartScriptCreator( - document.getData(), - document.getUndoStack(), - id, - document.getIdCompletionManager() - ); + return new StartScriptCreator(document.getData(), document.getUndoStack(), id, document.getIdCompletionManager()); } diff --git a/apps/opencs/view/world/startscriptcreator.hpp b/apps/opencs/view/world/startscriptcreator.hpp index cb7f3f619c..f13cd1cec4 100644 --- a/apps/opencs/view/world/startscriptcreator.hpp +++ b/apps/opencs/view/world/startscriptcreator.hpp @@ -21,55 +21,45 @@ namespace CSVWorld { Q_OBJECT - CSVWidget::DropLineEdit *mScript; + CSVWidget::DropLineEdit* mScript; - private: + private: + /// \return script ID entered by user. + std::string getId() const override; - /// \return script ID entered by user. - std::string getId() const override; + /// \return reference to table containing start scripts. + CSMWorld::IdTable& getStartScriptsTable() const; - /// \return reference to table containing start scripts. - CSMWorld::IdTable& getStartScriptsTable() const; + public: + StartScriptCreator(CSMWorld::Data& data, QUndoStack& undoStack, const CSMWorld::UniversalId& id, + CSMWorld::IdCompletionManager& completionManager); - public: + /// \brief Set script ID input widget to ID of record to be cloned. + /// \param originId Script ID to be cloned. + /// \param type Type of record to be cloned. + void cloneMode(const std::string& originId, const CSMWorld::UniversalId::Type type) override; - StartScriptCreator( - CSMWorld::Data& data, - QUndoStack& undoStack, - const CSMWorld::UniversalId& id, - CSMWorld::IdCompletionManager& completionManager); + /// \return Error description for current user input. + std::string getErrors() const override; - /// \brief Set script ID input widget to ID of record to be cloned. - /// \param originId Script ID to be cloned. - /// \param type Type of record to be cloned. - void cloneMode( - const std::string& originId, - const CSMWorld::UniversalId::Type type) override; + /// \brief Set focus to script ID input widget. + void focus() override; - /// \return Error description for current user input. - std::string getErrors() const override; + /// \brief Clear script ID input widget. + void reset() override; - /// \brief Set focus to script ID input widget. - void focus() override; + private slots: - /// \brief Clear script ID input widget. - void reset() override; + /// \brief Check user input for any errors. + void scriptChanged(); + }; - private slots: - - /// \brief Check user input for any errors. - void scriptChanged(); - }; - - /// \brief Creator factory for start script record creator. - class StartScriptCreatorFactory : public CreatorFactoryBase - { - public: - - Creator *makeCreator( - CSMDoc::Document& document, - const CSMWorld::UniversalId& id) const override; - }; + /// \brief Creator factory for start script record creator. + class StartScriptCreatorFactory : public CreatorFactoryBase + { + public: + Creator* makeCreator(CSMDoc::Document& document, const CSMWorld::UniversalId& id) const override; + }; } #endif // STARTSCRIPTCREATOR_HPP diff --git a/apps/opencs/view/world/subviews.cpp b/apps/opencs/view/world/subviews.cpp index e6bb13b6be..307ff0de51 100644 --- a/apps/opencs/view/world/subviews.cpp +++ b/apps/opencs/view/world/subviews.cpp @@ -2,40 +2,39 @@ #include "../doc/subviewfactoryimp.hpp" -#include "tablesubview.hpp" +#include "bodypartcreator.hpp" +#include "cellcreator.hpp" +#include "dialoguecreator.hpp" #include "dialoguesubview.hpp" -#include "scriptsubview.hpp" -#include "regionmapsubview.hpp" #include "genericcreator.hpp" #include "globalcreator.hpp" -#include "cellcreator.hpp" -#include "referenceablecreator.hpp" -#include "referencecreator.hpp" -#include "startscriptcreator.hpp" -#include "scenesubview.hpp" -#include "dialoguecreator.hpp" #include "infocreator.hpp" -#include "pathgridcreator.hpp" -#include "previewsubview.hpp" -#include "bodypartcreator.hpp" #include "landcreator.hpp" #include "landtexturecreator.hpp" +#include "pathgridcreator.hpp" +#include "previewsubview.hpp" +#include "referenceablecreator.hpp" +#include "referencecreator.hpp" +#include "regionmapsubview.hpp" +#include "scenesubview.hpp" +#include "scriptsubview.hpp" +#include "startscriptcreator.hpp" +#include "tablesubview.hpp" -void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) +void CSVWorld::addSubViewFactories(CSVDoc::SubViewFactoryManager& manager) { // Regular record tables (including references which are actually sub-records, but are promoted // to top-level records within the editor) - manager.add (CSMWorld::UniversalId::Type_Gmsts, - new CSVDoc::SubViewFactoryWithCreator); + manager.add( + CSMWorld::UniversalId::Type_Gmsts, new CSVDoc::SubViewFactoryWithCreator); - manager.add (CSMWorld::UniversalId::Type_Skills, - new CSVDoc::SubViewFactoryWithCreator); + manager.add( + CSMWorld::UniversalId::Type_Skills, new CSVDoc::SubViewFactoryWithCreator); - manager.add (CSMWorld::UniversalId::Type_MagicEffects, + manager.add(CSMWorld::UniversalId::Type_MagicEffects, new CSVDoc::SubViewFactoryWithCreator); - static const CSMWorld::UniversalId::Type sTableTypes[] = - { + static const CSMWorld::UniversalId::Type sTableTypes[] = { CSMWorld::UniversalId::Type_Classes, CSMWorld::UniversalId::Type_Factions, CSMWorld::UniversalId::Type_Races, @@ -49,88 +48,86 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) CSMWorld::UniversalId::Type_None, }; - for (int i=0; sTableTypes[i]!=CSMWorld::UniversalId::Type_None; ++i) - manager.add (sTableTypes[i], - new CSVDoc::SubViewFactoryWithCreator >); + for (int i = 0; sTableTypes[i] != CSMWorld::UniversalId::Type_None; ++i) + manager.add( + sTableTypes[i], new CSVDoc::SubViewFactoryWithCreator>); - manager.add (CSMWorld::UniversalId::Type_BodyParts, - new CSVDoc::SubViewFactoryWithCreator >); + manager.add(CSMWorld::UniversalId::Type_BodyParts, + new CSVDoc::SubViewFactoryWithCreator>); - manager.add (CSMWorld::UniversalId::Type_StartScripts, + manager.add(CSMWorld::UniversalId::Type_StartScripts, new CSVDoc::SubViewFactoryWithCreator); - manager.add (CSMWorld::UniversalId::Type_Cells, - new CSVDoc::SubViewFactoryWithCreator >); + manager.add(CSMWorld::UniversalId::Type_Cells, + new CSVDoc::SubViewFactoryWithCreator>); - manager.add (CSMWorld::UniversalId::Type_Referenceables, - new CSVDoc::SubViewFactoryWithCreator >); + manager.add(CSMWorld::UniversalId::Type_Referenceables, + new CSVDoc::SubViewFactoryWithCreator>); - manager.add (CSMWorld::UniversalId::Type_References, + manager.add(CSMWorld::UniversalId::Type_References, new CSVDoc::SubViewFactoryWithCreator); - manager.add (CSMWorld::UniversalId::Type_Topics, - new CSVDoc::SubViewFactoryWithCreator); + manager.add( + CSMWorld::UniversalId::Type_Topics, new CSVDoc::SubViewFactoryWithCreator); - manager.add (CSMWorld::UniversalId::Type_Journals, + manager.add(CSMWorld::UniversalId::Type_Journals, new CSVDoc::SubViewFactoryWithCreator); - manager.add (CSMWorld::UniversalId::Type_TopicInfos, + manager.add(CSMWorld::UniversalId::Type_TopicInfos, new CSVDoc::SubViewFactoryWithCreator(false)); - manager.add (CSMWorld::UniversalId::Type_JournalInfos, + manager.add(CSMWorld::UniversalId::Type_JournalInfos, new CSVDoc::SubViewFactoryWithCreator(false)); - manager.add (CSMWorld::UniversalId::Type_Pathgrids, + manager.add(CSMWorld::UniversalId::Type_Pathgrids, new CSVDoc::SubViewFactoryWithCreator); - manager.add (CSMWorld::UniversalId::Type_Lands, - new CSVDoc::SubViewFactoryWithCreator >); + manager.add(CSMWorld::UniversalId::Type_Lands, + new CSVDoc::SubViewFactoryWithCreator>); - manager.add (CSMWorld::UniversalId::Type_LandTextures, - new CSVDoc::SubViewFactoryWithCreator >); + manager.add(CSMWorld::UniversalId::Type_LandTextures, + new CSVDoc::SubViewFactoryWithCreator>); - manager.add (CSMWorld::UniversalId::Type_Globals, - new CSVDoc::SubViewFactoryWithCreator >); + manager.add(CSMWorld::UniversalId::Type_Globals, + new CSVDoc::SubViewFactoryWithCreator>); // Subviews for resources tables - manager.add (CSMWorld::UniversalId::Type_Meshes, - new CSVDoc::SubViewFactoryWithCreator); - manager.add (CSMWorld::UniversalId::Type_Icons, - new CSVDoc::SubViewFactoryWithCreator); - manager.add (CSMWorld::UniversalId::Type_Musics, - new CSVDoc::SubViewFactoryWithCreator); - manager.add (CSMWorld::UniversalId::Type_SoundsRes, - new CSVDoc::SubViewFactoryWithCreator); - manager.add (CSMWorld::UniversalId::Type_Textures, - new CSVDoc::SubViewFactoryWithCreator); - manager.add (CSMWorld::UniversalId::Type_Videos, - new CSVDoc::SubViewFactoryWithCreator); - + manager.add( + CSMWorld::UniversalId::Type_Meshes, new CSVDoc::SubViewFactoryWithCreator); + manager.add( + CSMWorld::UniversalId::Type_Icons, new CSVDoc::SubViewFactoryWithCreator); + manager.add( + CSMWorld::UniversalId::Type_Musics, new CSVDoc::SubViewFactoryWithCreator); + manager.add( + CSMWorld::UniversalId::Type_SoundsRes, new CSVDoc::SubViewFactoryWithCreator); + manager.add( + CSMWorld::UniversalId::Type_Textures, new CSVDoc::SubViewFactoryWithCreator); + manager.add( + CSMWorld::UniversalId::Type_Videos, new CSVDoc::SubViewFactoryWithCreator); // Subviews for editing/viewing individual records - manager.add (CSMWorld::UniversalId::Type_Script, new CSVDoc::SubViewFactory); + manager.add(CSMWorld::UniversalId::Type_Script, new CSVDoc::SubViewFactory); // Other stuff (combined record tables) - manager.add (CSMWorld::UniversalId::Type_RegionMap, new CSVDoc::SubViewFactory); + manager.add(CSMWorld::UniversalId::Type_RegionMap, new CSVDoc::SubViewFactory); - manager.add (CSMWorld::UniversalId::Type_Scene, new CSVDoc::SubViewFactory); + manager.add(CSMWorld::UniversalId::Type_Scene, new CSVDoc::SubViewFactory); // More other stuff - manager.add (CSMWorld::UniversalId::Type_Filters, + manager.add(CSMWorld::UniversalId::Type_Filters, new CSVDoc::SubViewFactoryWithCreator >); + CreatorFactory>); - manager.add (CSMWorld::UniversalId::Type_DebugProfiles, + manager.add(CSMWorld::UniversalId::Type_DebugProfiles, new CSVDoc::SubViewFactoryWithCreator >); + CreatorFactory>); - manager.add (CSMWorld::UniversalId::Type_Scripts, - new CSVDoc::SubViewFactoryWithCreator >); + manager.add(CSMWorld::UniversalId::Type_Scripts, + new CSVDoc::SubViewFactoryWithCreator>); // Dialogue subviews - static const CSMWorld::UniversalId::Type sTableTypes2[] = - { + static const CSMWorld::UniversalId::Type sTableTypes2[] = { CSMWorld::UniversalId::Type_Region, CSMWorld::UniversalId::Type_Spell, CSMWorld::UniversalId::Type_Birthsign, @@ -145,65 +142,65 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) CSMWorld::UniversalId::Type_None, }; - for (int i=0; sTableTypes2[i]!=CSMWorld::UniversalId::Type_None; ++i) - manager.add (sTableTypes2[i], - new CSVDoc::SubViewFactoryWithCreator > (false)); + for (int i = 0; sTableTypes2[i] != CSMWorld::UniversalId::Type_None; ++i) + manager.add(sTableTypes2[i], + new CSVDoc::SubViewFactoryWithCreator>(false)); - manager.add (CSMWorld::UniversalId::Type_BodyPart, - new CSVDoc::SubViewFactoryWithCreator > (false)); + manager.add(CSMWorld::UniversalId::Type_BodyPart, + new CSVDoc::SubViewFactoryWithCreator>(false)); - manager.add (CSMWorld::UniversalId::Type_StartScript, + manager.add(CSMWorld::UniversalId::Type_StartScript, new CSVDoc::SubViewFactoryWithCreator(false)); - manager.add (CSMWorld::UniversalId::Type_Skill, - new CSVDoc::SubViewFactoryWithCreator (false)); + manager.add(CSMWorld::UniversalId::Type_Skill, + new CSVDoc::SubViewFactoryWithCreator(false)); - manager.add (CSMWorld::UniversalId::Type_MagicEffect, - new CSVDoc::SubViewFactoryWithCreator (false)); + manager.add(CSMWorld::UniversalId::Type_MagicEffect, + new CSVDoc::SubViewFactoryWithCreator(false)); - manager.add (CSMWorld::UniversalId::Type_Gmst, - new CSVDoc::SubViewFactoryWithCreator (false)); + manager.add(CSMWorld::UniversalId::Type_Gmst, + new CSVDoc::SubViewFactoryWithCreator(false)); - manager.add (CSMWorld::UniversalId::Type_Referenceable, - new CSVDoc::SubViewFactoryWithCreator > (false)); + manager.add(CSMWorld::UniversalId::Type_Referenceable, + new CSVDoc::SubViewFactoryWithCreator>(false)); - manager.add (CSMWorld::UniversalId::Type_Reference, - new CSVDoc::SubViewFactoryWithCreator (false)); + manager.add(CSMWorld::UniversalId::Type_Reference, + new CSVDoc::SubViewFactoryWithCreator(false)); - manager.add (CSMWorld::UniversalId::Type_Cell, - new CSVDoc::SubViewFactoryWithCreator > (false)); + manager.add(CSMWorld::UniversalId::Type_Cell, + new CSVDoc::SubViewFactoryWithCreator>(false)); - manager.add (CSMWorld::UniversalId::Type_JournalInfo, - new CSVDoc::SubViewFactoryWithCreator (false)); + manager.add(CSMWorld::UniversalId::Type_JournalInfo, + new CSVDoc::SubViewFactoryWithCreator(false)); - manager.add (CSMWorld::UniversalId::Type_TopicInfo, + manager.add(CSMWorld::UniversalId::Type_TopicInfo, new CSVDoc::SubViewFactoryWithCreator(false)); - manager.add (CSMWorld::UniversalId::Type_Topic, - new CSVDoc::SubViewFactoryWithCreator (false)); + manager.add(CSMWorld::UniversalId::Type_Topic, + new CSVDoc::SubViewFactoryWithCreator(false)); - manager.add (CSMWorld::UniversalId::Type_Journal, - new CSVDoc::SubViewFactoryWithCreator (false)); + manager.add(CSMWorld::UniversalId::Type_Journal, + new CSVDoc::SubViewFactoryWithCreator(false)); - manager.add (CSMWorld::UniversalId::Type_Pathgrid, - new CSVDoc::SubViewFactoryWithCreator (false)); + manager.add(CSMWorld::UniversalId::Type_Pathgrid, + new CSVDoc::SubViewFactoryWithCreator(false)); - manager.add (CSMWorld::UniversalId::Type_Land, - new CSVDoc::SubViewFactoryWithCreator >(false)); + manager.add(CSMWorld::UniversalId::Type_Land, + new CSVDoc::SubViewFactoryWithCreator>(false)); - manager.add (CSMWorld::UniversalId::Type_LandTexture, - new CSVDoc::SubViewFactoryWithCreator >(false)); + manager.add(CSMWorld::UniversalId::Type_LandTexture, + new CSVDoc::SubViewFactoryWithCreator>(false)); - manager.add (CSMWorld::UniversalId::Type_DebugProfile, - new CSVDoc::SubViewFactoryWithCreator > (false)); + manager.add(CSMWorld::UniversalId::Type_DebugProfile, + new CSVDoc::SubViewFactoryWithCreator>(false)); - manager.add (CSMWorld::UniversalId::Type_Filter, - new CSVDoc::SubViewFactoryWithCreator > (false)); + manager.add(CSMWorld::UniversalId::Type_Filter, + new CSVDoc::SubViewFactoryWithCreator>(false)); - manager.add (CSMWorld::UniversalId::Type_MetaData, - new CSVDoc::SubViewFactory); + manager.add(CSMWorld::UniversalId::Type_MetaData, new CSVDoc::SubViewFactory); - //preview - manager.add (CSMWorld::UniversalId::Type_Preview, new CSVDoc::SubViewFactory); + // preview + manager.add(CSMWorld::UniversalId::Type_Preview, new CSVDoc::SubViewFactory); } diff --git a/apps/opencs/view/world/subviews.hpp b/apps/opencs/view/world/subviews.hpp index 51e4cb0830..cfa5a82139 100644 --- a/apps/opencs/view/world/subviews.hpp +++ b/apps/opencs/view/world/subviews.hpp @@ -8,7 +8,7 @@ namespace CSVDoc namespace CSVWorld { - void addSubViewFactories (CSVDoc::SubViewFactoryManager& manager); + void addSubViewFactories(CSVDoc::SubViewFactoryManager& manager); } #endif diff --git a/apps/opencs/view/world/table.cpp b/apps/opencs/view/world/table.cpp index 228834f6b4..1c059ce490 100644 --- a/apps/opencs/view/world/table.cpp +++ b/apps/opencs/view/world/table.cpp @@ -1,11 +1,11 @@ #include "table.hpp" -#include #include -#include #include -#include +#include +#include #include +#include #include #include @@ -13,32 +13,32 @@ #include "../../model/doc/document.hpp" +#include "../../model/world/commanddispatcher.hpp" #include "../../model/world/commands.hpp" -#include "../../model/world/infotableproxymodel.hpp" -#include "../../model/world/idtablebase.hpp" #include "../../model/world/idtable.hpp" +#include "../../model/world/idtablebase.hpp" +#include "../../model/world/infotableproxymodel.hpp" #include "../../model/world/landtexturetableproxymodel.hpp" -#include "../../model/world/commanddispatcher.hpp" -#include "../../model/prefs/state.hpp" #include "../../model/prefs/shortcut.hpp" +#include "../../model/prefs/state.hpp" #include "tableeditidaction.hpp" #include "tableheadermouseeventhandler.hpp" #include "util.hpp" -void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event) +void CSVWorld::Table::contextMenuEvent(QContextMenuEvent* event) { // configure dispatcher - mDispatcher->setSelection (getSelectedIds()); + mDispatcher->setSelection(getSelectedIds()); std::vector extendedTypes = mDispatcher->getExtendedTypes(); - mDispatcher->setExtendedTypes (extendedTypes); + mDispatcher->setExtendedTypes(extendedTypes); // create context menu QModelIndexList selectedRows = selectionModel()->selectedRows(); - QMenu menu (this); + QMenu menu(this); /// \todo add menu items for select all and clear selection @@ -53,50 +53,49 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event) if (!mEditLock && !(mModel->getFeatures() & CSMWorld::IdTableBase::Feature_Constant)) { - if (selectedRows.size()==1) + if (selectedRows.size() == 1) { - menu.addAction (mEditAction); + menu.addAction(mEditAction); if (mCreateAction) menu.addAction(mCloneAction); } if (mTouchAction) - menu.addAction (mTouchAction); + menu.addAction(mTouchAction); if (mCreateAction) - menu.addAction (mCreateAction); + menu.addAction(mCreateAction); if (mDispatcher->canRevert()) { - menu.addAction (mRevertAction); + menu.addAction(mRevertAction); if (!extendedTypes.empty()) - menu.addAction (mExtendedRevertAction); + menu.addAction(mExtendedRevertAction); } if (mDispatcher->canDelete()) { - menu.addAction (mDeleteAction); + menu.addAction(mDeleteAction); if (!extendedTypes.empty()) - menu.addAction (mExtendedDeleteAction); + menu.addAction(mExtendedDeleteAction); } if (mModel->getFeatures() & CSMWorld::IdTableBase::Feature_ReorderWithinTopic) { /// \todo allow reordering of multiple rows - if (selectedRows.size()==1) + if (selectedRows.size() == 1) { - int column = mModel->searchColumnIndex (CSMWorld::Columns::ColumnId_Topic); + int column = mModel->searchColumnIndex(CSMWorld::Columns::ColumnId_Topic); - if (column==-1) - column = mModel->searchColumnIndex (CSMWorld::Columns::ColumnId_Journal); + if (column == -1) + column = mModel->searchColumnIndex(CSMWorld::Columns::ColumnId_Journal); - if (column!=-1) + if (column != -1) { - int row = mProxyModel->mapToSource ( - mProxyModel->index (selectedRows.begin()->row(), 0)).row(); + int row = mProxyModel->mapToSource(mProxyModel->index(selectedRows.begin()->row(), 0)).row(); QString curData = mModel->data(mModel->index(row, column)).toString(); if (row > 0) @@ -121,22 +120,22 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event) } } - if (selectedRows.size()==1) + if (selectedRows.size() == 1) { int row = selectedRows.begin()->row(); - row = mProxyModel->mapToSource (mProxyModel->index (row, 0)).row(); + row = mProxyModel->mapToSource(mProxyModel->index(row, 0)).row(); if (mModel->getFeatures() & CSMWorld::IdTableBase::Feature_View) { - CSMWorld::UniversalId id = mModel->view (row).first; + CSMWorld::UniversalId id = mModel->view(row).first; - int index = mDocument.getData().getCells().searchId (id.getId()); + int index = mDocument.getData().getCells().searchId(id.getId()); // index==-1: the ID references a worldspace instead of a cell (ignore for now and go // ahead) - if (index==-1 || !mDocument.getData().getCells().getRecord (index).isDeleted()) - menu.addAction (mViewAction); + if (index == -1 || !mDocument.getData().getCells().getRecord(index).isDeleted()) + menu.addAction(mViewAction); } if (mModel->getFeatures() & CSMWorld::IdTableBase::Feature_Preview) @@ -144,37 +143,33 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event) const CSMWorld::UniversalId id = getUniversalId(currentRow); const CSMWorld::UniversalId::Type type = id.getType(); - QModelIndex index = mModel->index (row, - mModel->findColumnIndex (CSMWorld::Columns::ColumnId_Modification)); + QModelIndex index = mModel->index(row, mModel->findColumnIndex(CSMWorld::Columns::ColumnId_Modification)); - CSMWorld::RecordBase::State state = static_cast ( - mModel->data (index).toInt()); + CSMWorld::RecordBase::State state = static_cast(mModel->data(index).toInt()); - if (state!=CSMWorld::RecordBase::State_Deleted && type != CSMWorld::UniversalId::Type_ItemLevelledList) - menu.addAction (mPreviewAction); + if (state != CSMWorld::RecordBase::State_Deleted && type != CSMWorld::UniversalId::Type_ItemLevelledList) + menu.addAction(mPreviewAction); } } if (mHelpAction) - menu.addAction (mHelpAction); + menu.addAction(mHelpAction); - menu.exec (event->globalPos()); + menu.exec(event->globalPos()); } -void CSVWorld::Table::mouseDoubleClickEvent (QMouseEvent *event) +void CSVWorld::Table::mouseDoubleClickEvent(QMouseEvent* event) { - Qt::KeyboardModifiers modifiers = - event->modifiers() & (Qt::ShiftModifier | Qt::ControlModifier); + Qt::KeyboardModifiers modifiers = event->modifiers() & (Qt::ShiftModifier | Qt::ControlModifier); QModelIndex index = currentIndex(); - selectionModel()->select (index, - QItemSelectionModel::Clear | QItemSelectionModel::Select | QItemSelectionModel::Rows); + selectionModel()->select( + index, QItemSelectionModel::Clear | QItemSelectionModel::Select | QItemSelectionModel::Rows); - std::map::iterator iter = - mDoubleClickActions.find (modifiers); + std::map::iterator iter = mDoubleClickActions.find(modifiers); - if (iter==mDoubleClickActions.end()) + if (iter == mDoubleClickActions.end()) { event->accept(); return; @@ -189,7 +184,7 @@ void CSVWorld::Table::mouseDoubleClickEvent (QMouseEvent *event) case Action_InPlaceEdit: - DragRecordTable::mouseDoubleClickEvent (event); + DragRecordTable::mouseDoubleClickEvent(event); break; case Action_EditRecord: @@ -234,87 +229,92 @@ void CSVWorld::Table::mouseDoubleClickEvent (QMouseEvent *event) } } -CSVWorld::Table::Table (const CSMWorld::UniversalId& id, - bool createAndDelete, bool sorting, CSMDoc::Document& document) - : DragRecordTable(document), mCreateAction (nullptr), mCloneAction(nullptr), mTouchAction(nullptr), - mRecordStatusDisplay (0), mJumpToAddedRecord(false), mUnselectAfterJump(false), mAutoJump (false) +CSVWorld::Table::Table(const CSMWorld::UniversalId& id, bool createAndDelete, bool sorting, CSMDoc::Document& document) + : DragRecordTable(document) + , mCreateAction(nullptr) + , mCloneAction(nullptr) + , mTouchAction(nullptr) + , mRecordStatusDisplay(0) + , mJumpToAddedRecord(false) + , mUnselectAfterJump(false) + , mAutoJump(false) { - mModel = &dynamic_cast (*mDocument.getData().getTableModel (id)); + mModel = &dynamic_cast(*mDocument.getData().getTableModel(id)); - bool isInfoTable = id.getType() == CSMWorld::UniversalId::Type_TopicInfos || - id.getType() == CSMWorld::UniversalId::Type_JournalInfos; + bool isInfoTable = id.getType() == CSMWorld::UniversalId::Type_TopicInfos + || id.getType() == CSMWorld::UniversalId::Type_JournalInfos; bool isLtexTable = (id.getType() == CSMWorld::UniversalId::Type_LandTextures); if (isInfoTable) { mProxyModel = new CSMWorld::InfoTableProxyModel(id.getType(), this); - connect (this, &CSVWorld::DragRecordTable::moveRecordsFromSameTable, this, &CSVWorld::Table::moveRecords); + connect(this, &CSVWorld::DragRecordTable::moveRecordsFromSameTable, this, &CSVWorld::Table::moveRecords); } else if (isLtexTable) { - mProxyModel = new CSMWorld::LandTextureTableProxyModel (this); + mProxyModel = new CSMWorld::LandTextureTableProxyModel(this); } else { - mProxyModel = new CSMWorld::IdTableProxyModel (this); + mProxyModel = new CSMWorld::IdTableProxyModel(this); } - mProxyModel->setSourceModel (mModel); + mProxyModel->setSourceModel(mModel); - mDispatcher = new CSMWorld::CommandDispatcher (document, id, this); + mDispatcher = new CSMWorld::CommandDispatcher(document, id, this); - setModel (mProxyModel); - horizontalHeader()->setSectionResizeMode (QHeaderView::Interactive); + setModel(mProxyModel); + horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); // The number is arbitrary but autoresize would be way too slow otherwise. constexpr int autoResizePrecision = 500; horizontalHeader()->setResizeContentsPrecision(autoResizePrecision); resizeColumnsToContents(); verticalHeader()->hide(); - setSelectionBehavior (QAbstractItemView::SelectRows); - setSelectionMode (QAbstractItemView::ExtendedSelection); + setSelectionBehavior(QAbstractItemView::SelectRows); + setSelectionMode(QAbstractItemView::ExtendedSelection); int columns = mModel->columnCount(); - for (int i=0; iheaderData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Flags).toInt(); + int flags = mModel->headerData(i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Flags).toInt(); if (flags & CSMWorld::ColumnBase::Flag_Table) { - CSMWorld::ColumnBase::Display display = static_cast ( - mModel->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); + CSMWorld::ColumnBase::Display display = static_cast( + mModel->headerData(i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); - CommandDelegate *delegate = CommandDelegateFactoryCollection::get().makeDelegate (display, - mDispatcher, document, this); + CommandDelegate* delegate + = CommandDelegateFactoryCollection::get().makeDelegate(display, mDispatcher, document, this); - mDelegates.push_back (delegate); - setItemDelegateForColumn (i, delegate); + mDelegates.push_back(delegate); + setItemDelegateForColumn(i, delegate); } else - hideColumn (i); + hideColumn(i); } if (sorting) { // FIXME: some tables (e.g. CellRef) have this column hidden, which makes it confusing - sortByColumn (mModel->findColumnIndex(CSMWorld::Columns::ColumnId_Id), Qt::AscendingOrder); + sortByColumn(mModel->findColumnIndex(CSMWorld::Columns::ColumnId_Id), Qt::AscendingOrder); } - setSortingEnabled (sorting); + setSortingEnabled(sorting); - mEditAction = new QAction (tr ("Edit Record"), this); - connect (mEditAction, &QAction::triggered, this, &Table::editRecord); + mEditAction = new QAction(tr("Edit Record"), this); + connect(mEditAction, &QAction::triggered, this, &Table::editRecord); mEditAction->setIcon(QIcon(":edit-edit")); - addAction (mEditAction); + addAction(mEditAction); CSMPrefs::Shortcut* editShortcut = new CSMPrefs::Shortcut("table-edit", this); editShortcut->associateAction(mEditAction); if (createAndDelete) { - mCreateAction = new QAction (tr ("Add Record"), this); - connect (mCreateAction, &QAction::triggered, this, &Table::createRequest); + mCreateAction = new QAction(tr("Add Record"), this); + connect(mCreateAction, &QAction::triggered, this, &Table::createRequest); mCreateAction->setIcon(QIcon(":edit-add")); - addAction (mCreateAction); + addAction(mCreateAction); CSMPrefs::Shortcut* createShortcut = new CSMPrefs::Shortcut("table-add", this); createShortcut->associateAction(mCreateAction); - mCloneAction = new QAction (tr ("Clone Record"), this); + mCloneAction = new QAction(tr("Clone Record"), this); connect(mCloneAction, &QAction::triggered, this, &Table::cloneRecord); mCloneAction->setIcon(QIcon(":edit-clone")); addAction(mCloneAction); @@ -332,134 +332,127 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id, touchShortcut->associateAction(mTouchAction); } - mRevertAction = new QAction (tr ("Revert Record"), this); - connect (mRevertAction, &QAction::triggered, mDispatcher, &CSMWorld::CommandDispatcher::executeRevert); + mRevertAction = new QAction(tr("Revert Record"), this); + connect(mRevertAction, &QAction::triggered, mDispatcher, &CSMWorld::CommandDispatcher::executeRevert); mRevertAction->setIcon(QIcon(":edit-undo")); - addAction (mRevertAction); + addAction(mRevertAction); CSMPrefs::Shortcut* revertShortcut = new CSMPrefs::Shortcut("table-revert", this); revertShortcut->associateAction(mRevertAction); - mDeleteAction = new QAction (tr ("Delete Record"), this); - connect (mDeleteAction, &QAction::triggered, mDispatcher, &CSMWorld::CommandDispatcher::executeDelete); + mDeleteAction = new QAction(tr("Delete Record"), this); + connect(mDeleteAction, &QAction::triggered, mDispatcher, &CSMWorld::CommandDispatcher::executeDelete); mDeleteAction->setIcon(QIcon(":edit-delete")); - addAction (mDeleteAction); + addAction(mDeleteAction); CSMPrefs::Shortcut* deleteShortcut = new CSMPrefs::Shortcut("table-remove", this); deleteShortcut->associateAction(mDeleteAction); - mMoveUpAction = new QAction (tr ("Move Up"), this); - connect (mMoveUpAction, &QAction::triggered, this, &Table::moveUpRecord); + mMoveUpAction = new QAction(tr("Move Up"), this); + connect(mMoveUpAction, &QAction::triggered, this, &Table::moveUpRecord); mMoveUpAction->setIcon(QIcon(":record-up")); - addAction (mMoveUpAction); + addAction(mMoveUpAction); CSMPrefs::Shortcut* moveUpShortcut = new CSMPrefs::Shortcut("table-moveup", this); moveUpShortcut->associateAction(mMoveUpAction); - mMoveDownAction = new QAction (tr ("Move Down"), this); - connect (mMoveDownAction, &QAction::triggered, this, &Table::moveDownRecord); + mMoveDownAction = new QAction(tr("Move Down"), this); + connect(mMoveDownAction, &QAction::triggered, this, &Table::moveDownRecord); mMoveDownAction->setIcon(QIcon(":record-down")); - addAction (mMoveDownAction); + addAction(mMoveDownAction); CSMPrefs::Shortcut* moveDownShortcut = new CSMPrefs::Shortcut("table-movedown", this); moveDownShortcut->associateAction(mMoveDownAction); - mViewAction = new QAction (tr ("View"), this); - connect (mViewAction, &QAction::triggered, this, &Table::viewRecord); + mViewAction = new QAction(tr("View"), this); + connect(mViewAction, &QAction::triggered, this, &Table::viewRecord); mViewAction->setIcon(QIcon(":/cell.png")); - addAction (mViewAction); + addAction(mViewAction); CSMPrefs::Shortcut* viewShortcut = new CSMPrefs::Shortcut("table-view", this); viewShortcut->associateAction(mViewAction); - mPreviewAction = new QAction (tr ("Preview"), this); - connect (mPreviewAction, &QAction::triggered, this, &Table::previewRecord); + mPreviewAction = new QAction(tr("Preview"), this); + connect(mPreviewAction, &QAction::triggered, this, &Table::previewRecord); mPreviewAction->setIcon(QIcon(":edit-preview")); - addAction (mPreviewAction); + addAction(mPreviewAction); CSMPrefs::Shortcut* previewShortcut = new CSMPrefs::Shortcut("table-preview", this); previewShortcut->associateAction(mPreviewAction); - mExtendedDeleteAction = new QAction (tr ("Extended Delete Record"), this); - connect (mExtendedDeleteAction, &QAction::triggered, this, &Table::executeExtendedDelete); + mExtendedDeleteAction = new QAction(tr("Extended Delete Record"), this); + connect(mExtendedDeleteAction, &QAction::triggered, this, &Table::executeExtendedDelete); mExtendedDeleteAction->setIcon(QIcon(":edit-delete")); - addAction (mExtendedDeleteAction); + addAction(mExtendedDeleteAction); CSMPrefs::Shortcut* extendedDeleteShortcut = new CSMPrefs::Shortcut("table-extendeddelete", this); extendedDeleteShortcut->associateAction(mExtendedDeleteAction); - mExtendedRevertAction = new QAction (tr ("Extended Revert Record"), this); - connect (mExtendedRevertAction, &QAction::triggered, this, &Table::executeExtendedRevert); + mExtendedRevertAction = new QAction(tr("Extended Revert Record"), this); + connect(mExtendedRevertAction, &QAction::triggered, this, &Table::executeExtendedRevert); mExtendedRevertAction->setIcon(QIcon(":edit-undo")); - addAction (mExtendedRevertAction); + addAction(mExtendedRevertAction); CSMPrefs::Shortcut* extendedRevertShortcut = new CSMPrefs::Shortcut("table-extendedrevert", this); extendedRevertShortcut->associateAction(mExtendedRevertAction); - mEditIdAction = new TableEditIdAction (*this, this); - connect (mEditIdAction, &QAction::triggered, this, &Table::editCell); - addAction (mEditIdAction); + mEditIdAction = new TableEditIdAction(*this, this); + connect(mEditIdAction, &QAction::triggered, this, &Table::editCell); + addAction(mEditIdAction); - mHelpAction = new QAction (tr ("Help"), this); - connect (mHelpAction, &QAction::triggered, this, &Table::openHelp); + mHelpAction = new QAction(tr("Help"), this); + connect(mHelpAction, &QAction::triggered, this, &Table::openHelp); mHelpAction->setIcon(QIcon(":/info.png")); - addAction (mHelpAction); + addAction(mHelpAction); CSMPrefs::Shortcut* openHelpShortcut = new CSMPrefs::Shortcut("help", this); openHelpShortcut->associateAction(mHelpAction); - connect (mProxyModel, &CSMWorld::IdTableProxyModel::rowsRemoved, - this, &Table::tableSizeUpdate); + connect(mProxyModel, &CSMWorld::IdTableProxyModel::rowsRemoved, this, &Table::tableSizeUpdate); - connect (mProxyModel, &CSMWorld::IdTableProxyModel::rowAdded, - this, &Table::rowAdded); + connect(mProxyModel, &CSMWorld::IdTableProxyModel::rowAdded, this, &Table::rowAdded); /// \note This signal could instead be connected to a slot that filters out changes not affecting /// the records status column (for permanence reasons) - connect (mProxyModel, &CSMWorld::IdTableProxyModel::dataChanged, - this, &Table::dataChangedEvent); + connect(mProxyModel, &CSMWorld::IdTableProxyModel::dataChanged, this, &Table::dataChangedEvent); - connect (selectionModel(), &QItemSelectionModel::selectionChanged, - this, &Table::selectionSizeUpdate); + connect(selectionModel(), &QItemSelectionModel::selectionChanged, this, &Table::selectionSizeUpdate); setAcceptDrops(true); - mDoubleClickActions.insert (std::make_pair (Qt::NoModifier, Action_InPlaceEdit)); - mDoubleClickActions.insert (std::make_pair (Qt::ShiftModifier, Action_EditRecord)); - mDoubleClickActions.insert (std::make_pair (Qt::ControlModifier, Action_View)); - mDoubleClickActions.insert (std::make_pair (Qt::ShiftModifier | Qt::ControlModifier, Action_EditRecordAndClose)); + mDoubleClickActions.insert(std::make_pair(Qt::NoModifier, Action_InPlaceEdit)); + mDoubleClickActions.insert(std::make_pair(Qt::ShiftModifier, Action_EditRecord)); + mDoubleClickActions.insert(std::make_pair(Qt::ControlModifier, Action_View)); + mDoubleClickActions.insert(std::make_pair(Qt::ShiftModifier | Qt::ControlModifier, Action_EditRecordAndClose)); - connect (&CSMPrefs::State::get(), &CSMPrefs::State::settingChanged, - this, &Table::settingChanged); + connect(&CSMPrefs::State::get(), &CSMPrefs::State::settingChanged, this, &Table::settingChanged); CSMPrefs::get()["ID Tables"].update(); new TableHeaderMouseEventHandler(this); } -void CSVWorld::Table::setEditLock (bool locked) +void CSVWorld::Table::setEditLock(bool locked) { - for (std::vector::iterator iter (mDelegates.begin()); iter!=mDelegates.end(); ++iter) - (*iter)->setEditLock (locked); + for (std::vector::iterator iter(mDelegates.begin()); iter != mDelegates.end(); ++iter) + (*iter)->setEditLock(locked); DragRecordTable::setEditLock(locked); - mDispatcher->setEditLock (locked); + mDispatcher->setEditLock(locked); } -CSMWorld::UniversalId CSVWorld::Table::getUniversalId (int row) const +CSMWorld::UniversalId CSVWorld::Table::getUniversalId(int row) const { - row = mProxyModel->mapToSource (mProxyModel->index (row, 0)).row(); + row = mProxyModel->mapToSource(mProxyModel->index(row, 0)).row(); - int idColumn = mModel->findColumnIndex (CSMWorld::Columns::ColumnId_Id); - int typeColumn = mModel->findColumnIndex (CSMWorld::Columns::ColumnId_RecordType); + int idColumn = mModel->findColumnIndex(CSMWorld::Columns::ColumnId_Id); + int typeColumn = mModel->findColumnIndex(CSMWorld::Columns::ColumnId_RecordType); - return CSMWorld::UniversalId ( - static_cast (mModel->data (mModel->index (row, typeColumn)).toInt()), - mModel->data (mModel->index (row, idColumn)).toString().toUtf8().constData()); + return CSMWorld::UniversalId( + static_cast(mModel->data(mModel->index(row, typeColumn)).toInt()), + mModel->data(mModel->index(row, idColumn)).toString().toUtf8().constData()); } std::vector CSVWorld::Table::getSelectedIds() const { std::vector ids; QModelIndexList selectedRows = selectionModel()->selectedRows(); - int columnIndex = mModel->findColumnIndex (CSMWorld::Columns::ColumnId_Id); + int columnIndex = mModel->findColumnIndex(CSMWorld::Columns::ColumnId_Id); - for (QModelIndexList::const_iterator iter (selectedRows.begin()); - iter != selectedRows.end(); - ++iter) + for (QModelIndexList::const_iterator iter(selectedRows.begin()); iter != selectedRows.end(); ++iter) { - int row = mProxyModel->mapToSource (mProxyModel->index (iter->row(), 0)).row(); - ids.emplace_back(mModel->data (mModel->index (row, columnIndex)).toString().toUtf8().constData()); + int row = mProxyModel->mapToSource(mProxyModel->index(iter->row(), 0)).row(); + ids.emplace_back(mModel->data(mModel->index(row, columnIndex)).toString().toUtf8().constData()); } return ids; } @@ -470,8 +463,8 @@ void CSVWorld::Table::editRecord() { QModelIndexList selectedRows = selectionModel()->selectedRows(); - if (selectedRows.size()==1) - emit editRequest (getUniversalId (selectedRows.begin()->row()), ""); + if (selectedRows.size() == 1) + emit editRequest(getUniversalId(selectedRows.begin()->row()), ""); } } @@ -483,7 +476,7 @@ void CSVWorld::Table::cloneRecord() const CSMWorld::UniversalId& toClone = getUniversalId(selectedRows.begin()->row()); if (selectedRows.size() == 1) { - emit cloneRequest (toClone); + emit cloneRequest(toClone); } } } @@ -511,28 +504,28 @@ void CSVWorld::Table::moveUpRecord() QModelIndexList selectedRows = selectionModel()->selectedRows(); - if (selectedRows.size()==1) + if (selectedRows.size() == 1) { - int row2 =selectedRows.begin()->row(); + int row2 = selectedRows.begin()->row(); - if (row2>0) + if (row2 > 0) { - int row = row2-1; + int row = row2 - 1; - row = mProxyModel->mapToSource (mProxyModel->index (row, 0)).row(); - row2 = mProxyModel->mapToSource (mProxyModel->index (row2, 0)).row(); + row = mProxyModel->mapToSource(mProxyModel->index(row, 0)).row(); + row2 = mProxyModel->mapToSource(mProxyModel->index(row2, 0)).row(); - if (row2<=row) - throw std::runtime_error ("Inconsistent row order"); + if (row2 <= row) + throw std::runtime_error("Inconsistent row order"); - std::vector newOrder (row2-row+1); - newOrder[0] = row2-row; - newOrder[row2-row] = 0; - for (int i=1; i newOrder(row2 - row + 1); + newOrder[0] = row2 - row; + newOrder[row2 - row] = 0; + for (int i = 1; i < row2 - row; ++i) newOrder[i] = i; - mDocument.getUndoStack().push (new CSMWorld::ReorderRowsCommand ( - dynamic_cast (*mModel), row, newOrder)); + mDocument.getUndoStack().push( + new CSMWorld::ReorderRowsCommand(dynamic_cast(*mModel), row, newOrder)); } } } @@ -544,33 +537,33 @@ void CSVWorld::Table::moveDownRecord() QModelIndexList selectedRows = selectionModel()->selectedRows(); - if (selectedRows.size()==1) + if (selectedRows.size() == 1) { - int row =selectedRows.begin()->row(); + int row = selectedRows.begin()->row(); - if (rowrowCount()-1) + if (row < mProxyModel->rowCount() - 1) { - int row2 = row+1; + int row2 = row + 1; - row = mProxyModel->mapToSource (mProxyModel->index (row, 0)).row(); - row2 = mProxyModel->mapToSource (mProxyModel->index (row2, 0)).row(); + row = mProxyModel->mapToSource(mProxyModel->index(row, 0)).row(); + row2 = mProxyModel->mapToSource(mProxyModel->index(row2, 0)).row(); - if (row2<=row) - throw std::runtime_error ("Inconsistent row order"); + if (row2 <= row) + throw std::runtime_error("Inconsistent row order"); - std::vector newOrder (row2-row+1); - newOrder[0] = row2-row; - newOrder[row2-row] = 0; - for (int i=1; i newOrder(row2 - row + 1); + newOrder[0] = row2 - row; + newOrder[row2 - row] = 0; + for (int i = 1; i < row2 - row; ++i) newOrder[i] = i; - mDocument.getUndoStack().push (new CSMWorld::ReorderRowsCommand ( - dynamic_cast (*mModel), row, newOrder)); + mDocument.getUndoStack().push( + new CSMWorld::ReorderRowsCommand(dynamic_cast(*mModel), row, newOrder)); } } } -void CSVWorld::Table::moveRecords(QDropEvent *event) +void CSVWorld::Table::moveRecords(QDropEvent* event) { if (mEditLock || (mModel->getFeatures() & CSMWorld::IdTableBase::Feature_Constant)) return; @@ -579,19 +572,21 @@ void CSVWorld::Table::moveRecords(QDropEvent *event) QModelIndexList selectedRows = selectionModel()->selectedRows(); int targetRowRaw = targedIndex.row(); - int targetRow = mProxyModel->mapToSource (mProxyModel->index (targetRowRaw, 0)).row(); + int targetRow = mProxyModel->mapToSource(mProxyModel->index(targetRowRaw, 0)).row(); int baseRowRaw = targedIndex.row() - 1; - int baseRow = mProxyModel->mapToSource (mProxyModel->index (baseRowRaw, 0)).row(); + int baseRow = mProxyModel->mapToSource(mProxyModel->index(baseRowRaw, 0)).row(); int highestDifference = 0; for (const auto& thisRowData : selectedRows) { - int thisRow = mProxyModel->mapToSource (mProxyModel->index (thisRowData.row(), 0)).row(); - if (std::abs(targetRow - thisRow) > highestDifference) highestDifference = std::abs(targetRow - thisRow); - if (thisRow - 1 < baseRow) baseRow = thisRow - 1; + int thisRow = mProxyModel->mapToSource(mProxyModel->index(thisRowData.row(), 0)).row(); + if (std::abs(targetRow - thisRow) > highestDifference) + highestDifference = std::abs(targetRow - thisRow); + if (thisRow - 1 < baseRow) + baseRow = thisRow - 1; } - std::vector newOrder (highestDifference + 1); + std::vector newOrder(highestDifference + 1); for (long unsigned int i = 0; i < newOrder.size(); ++i) { @@ -616,9 +611,9 @@ void CSVWorld::Table::moveRecords(QDropEvent *event) */ int originRowRaw = thisRowData.row(); - int originRow = mProxyModel->mapToSource (mProxyModel->index (originRowRaw, 0)).row(); + int originRow = mProxyModel->mapToSource(mProxyModel->index(originRowRaw, 0)).row(); - newOrder.erase(newOrder.begin() + originRow - baseRow - 1); + newOrder.erase(newOrder.begin() + originRow - baseRow - 1); newOrder.emplace(newOrder.begin() + originRow - baseRow - 1, targetRow - baseRow - 1); if (originRow > targetRow) @@ -635,10 +630,9 @@ void CSVWorld::Table::moveRecords(QDropEvent *event) --newOrder[i]; } } - } - mDocument.getUndoStack().push (new CSMWorld::ReorderRowsCommand ( - dynamic_cast (*mModel), baseRow + 1, newOrder)); + mDocument.getUndoStack().push( + new CSMWorld::ReorderRowsCommand(dynamic_cast(*mModel), baseRow + 1, newOrder)); } void CSVWorld::Table::editCell() @@ -658,16 +652,16 @@ void CSVWorld::Table::viewRecord() QModelIndexList selectedRows = selectionModel()->selectedRows(); - if (selectedRows.size()==1) + if (selectedRows.size() == 1) { int row = selectedRows.begin()->row(); - row = mProxyModel->mapToSource (mProxyModel->index (row, 0)).row(); + row = mProxyModel->mapToSource(mProxyModel->index(row, 0)).row(); - std::pair params = mModel->view (row); + std::pair params = mModel->view(row); - if (params.first.getType()!=CSMWorld::UniversalId::Type_None) - emit editRequest (params.first, params.second); + if (params.first.getType() != CSMWorld::UniversalId::Type_None) + emit editRequest(params.first, params.second); } } @@ -675,16 +669,15 @@ void CSVWorld::Table::previewRecord() { QModelIndexList selectedRows = selectionModel()->selectedRows(); - if (selectedRows.size()==1) + if (selectedRows.size() == 1) { - std::string id = getUniversalId (selectedRows.begin()->row()).getId(); + std::string id = getUniversalId(selectedRows.begin()->row()).getId(); - QModelIndex index = mModel->getModelIndex (id, - mModel->findColumnIndex (CSMWorld::Columns::ColumnId_Modification)); + QModelIndex index + = mModel->getModelIndex(id, mModel->findColumnIndex(CSMWorld::Columns::ColumnId_Modification)); - if (mModel->data (index)!=CSMWorld::RecordBase::State_Deleted) - emit editRequest (CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Preview, id), - ""); + if (mModel->data(index) != CSMWorld::RecordBase::State_Deleted) + emit editRequest(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Preview, id), ""); } } @@ -712,16 +705,16 @@ void CSVWorld::Table::executeExtendedRevert() } } -void CSVWorld::Table::settingChanged (const CSMPrefs::Setting *setting) +void CSVWorld::Table::settingChanged(const CSMPrefs::Setting* setting) { - if (*setting=="ID Tables/jump-to-added") + if (*setting == "ID Tables/jump-to-added") { - if (setting->toString()=="Jump and Select") + if (setting->toString() == "Jump and Select") { mJumpToAddedRecord = true; mUnselectAfterJump = false; } - else if (setting->toString()=="Jump Only") + else if (setting->toString() == "Jump Only") { mJumpToAddedRecord = true; mUnselectAfterJump = true; @@ -732,49 +725,47 @@ void CSVWorld::Table::settingChanged (const CSMPrefs::Setting *setting) mUnselectAfterJump = false; } } - else if (*setting=="Records/type-format" || *setting=="Records/status-format") + else if (*setting == "Records/type-format" || *setting == "Records/status-format") { int columns = mModel->columnCount(); - for (int i=0; i (*delegate).settingChanged (setting); - emit dataChanged (mModel->index (0, i), - mModel->index (mModel->rowCount()-1, i)); + dynamic_cast(*delegate).settingChanged(setting); + emit dataChanged(mModel->index(0, i), mModel->index(mModel->rowCount() - 1, i)); } } - else if (setting->getParent()->getKey()=="ID Tables" && - setting->getKey().substr (0, 6)=="double") + else if (setting->getParent()->getKey() == "ID Tables" && setting->getKey().substr(0, 6) == "double") { - std::string modifierString = setting->getKey().substr (6); + std::string modifierString = setting->getKey().substr(6); Qt::KeyboardModifiers modifiers; - if (modifierString=="-s") + if (modifierString == "-s") modifiers = Qt::ShiftModifier; - else if (modifierString=="-c") + else if (modifierString == "-c") modifiers = Qt::ControlModifier; - else if (modifierString=="-sc") + else if (modifierString == "-sc") modifiers = Qt::ShiftModifier | Qt::ControlModifier; DoubleClickAction action = Action_None; std::string value = setting->toString(); - if (value=="Edit in Place") + if (value == "Edit in Place") action = Action_InPlaceEdit; - else if (value=="Edit Record") + else if (value == "Edit Record") action = Action_EditRecord; - else if (value=="View") + else if (value == "View") action = Action_View; - else if (value=="Revert") + else if (value == "Revert") action = Action_Revert; - else if (value=="Delete") + else if (value == "Delete") action = Action_Delete; - else if (value=="Edit Record and Close") + else if (value == "Edit Record and Close") action = Action_EditRecordAndClose; - else if (value=="View and Close") + else if (value == "View and Close") action = Action_ViewAndClose; mDoubleClickActions[modifiers] = action; @@ -787,26 +778,37 @@ void CSVWorld::Table::tableSizeUpdate() int deleted = 0; int modified = 0; - if (mProxyModel->columnCount()>0) + if (mProxyModel->columnCount() > 0) { int rows = mProxyModel->rowCount(); - int columnIndex = mModel->searchColumnIndex (CSMWorld::Columns::ColumnId_Modification); + int columnIndex = mModel->searchColumnIndex(CSMWorld::Columns::ColumnId_Modification); - if (columnIndex!=-1) + if (columnIndex != -1) { - for (int i=0; imapToSource (mProxyModel->index (i, 0)); + QModelIndex index = mProxyModel->mapToSource(mProxyModel->index(i, 0)); - int state = mModel->data (mModel->index (index.row(), columnIndex)).toInt(); + int state = mModel->data(mModel->index(index.row(), columnIndex)).toInt(); switch (state) { - case CSMWorld::RecordBase::State_BaseOnly: ++size; break; - case CSMWorld::RecordBase::State_Modified: ++size; ++modified; break; - case CSMWorld::RecordBase::State_ModifiedOnly: ++size; ++modified; break; - case CSMWorld::RecordBase::State_Deleted: ++deleted; ++modified; break; + case CSMWorld::RecordBase::State_BaseOnly: + ++size; + break; + case CSMWorld::RecordBase::State_Modified: + ++size; + ++modified; + break; + case CSMWorld::RecordBase::State_ModifiedOnly: + ++size; + ++modified; + break; + case CSMWorld::RecordBase::State_Deleted: + ++deleted; + ++modified; + break; } } } @@ -814,35 +816,35 @@ void CSVWorld::Table::tableSizeUpdate() size = rows; } - emit tableSizeChanged (size, deleted, modified); + emit tableSizeChanged(size, deleted, modified); } void CSVWorld::Table::selectionSizeUpdate() { - emit selectionSizeChanged (selectionModel()->selectedRows().size()); + emit selectionSizeChanged(selectionModel()->selectedRows().size()); } -void CSVWorld::Table::requestFocus (const std::string& id) +void CSVWorld::Table::requestFocus(const std::string& id) { - QModelIndex index = mProxyModel->getModelIndex (id, 0); + QModelIndex index = mProxyModel->getModelIndex(id, 0); if (index.isValid()) { // This will scroll to the row. - selectRow (index.row()); + selectRow(index.row()); // This will actually select it. - selectionModel()->select (index, QItemSelectionModel::Select | QItemSelectionModel::Rows); + selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows); } } -void CSVWorld::Table::recordFilterChanged (std::shared_ptr filter) +void CSVWorld::Table::recordFilterChanged(std::shared_ptr filter) { - mProxyModel->setFilter (filter); + mProxyModel->setFilter(filter); tableSizeUpdate(); selectionSizeUpdate(); } -void CSVWorld::Table::mouseMoveEvent (QMouseEvent* event) +void CSVWorld::Table::mouseMoveEvent(QMouseEvent* event) { if (event->buttons() & Qt::LeftButton) { @@ -857,24 +859,24 @@ std::vector CSVWorld::Table::getColumnsWithDisplay(CSMWorld::Column std::vector titles; for (int i = 0; i < count; ++i) { - CSMWorld::ColumnBase::Display columndisplay = static_cast - (mModel->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); + CSMWorld::ColumnBase::Display columndisplay = static_cast( + mModel->headerData(i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); if (display == columndisplay) { - titles.emplace_back(mModel->headerData (i, Qt::Horizontal).toString().toUtf8().constData()); + titles.emplace_back(mModel->headerData(i, Qt::Horizontal).toString().toUtf8().constData()); } } return titles; } -std::vector< CSMWorld::UniversalId > CSVWorld::Table::getDraggedRecords() const +std::vector CSVWorld::Table::getDraggedRecords() const { QModelIndexList selectedRows = selectionModel()->selectedRows(); std::vector idToDrag; for (QModelIndex& it : selectedRows) - idToDrag.push_back (getUniversalId (it.row())); + idToDrag.push_back(getUniversalId(it.row())); return idToDrag; } @@ -883,10 +885,10 @@ std::vector< CSMWorld::UniversalId > CSVWorld::Table::getDraggedRecords() const // // If, for example, mModel was used instead, then scrolTo() should use the index // mProxyModel->mapFromSource(mModel->index(end, 0)) -void CSVWorld::Table::rowAdded(const std::string &id) +void CSVWorld::Table::rowAdded(const std::string& id) { tableSizeUpdate(); - if(mJumpToAddedRecord) + if (mJumpToAddedRecord) { int idColumn = mModel->findColumnIndex(CSMWorld::Columns::ColumnId_Id); int end = mProxyModel->getModelIndex(id, idColumn).row(); @@ -895,7 +897,7 @@ void CSVWorld::Table::rowAdded(const std::string &id) // without this delay the scroll works but goes to top for add/clone QMetaObject::invokeMethod(this, "queuedScrollTo", Qt::QueuedConnection, Q_ARG(int, end)); - if(mUnselectAfterJump) + if (mUnselectAfterJump) clearSelection(); } } @@ -905,7 +907,7 @@ void CSVWorld::Table::queuedScrollTo(int row) scrollTo(mProxyModel->index(row, 0), QAbstractItemView::PositionAtCenter); } -void CSVWorld::Table::dataChangedEvent(const QModelIndex &topLeft, const QModelIndex &bottomRight) +void CSVWorld::Table::dataChangedEvent(const QModelIndex& topLeft, const QModelIndex& bottomRight) { tableSizeUpdate(); @@ -918,7 +920,7 @@ void CSVWorld::Table::dataChangedEvent(const QModelIndex &topLeft, const QModelI void CSVWorld::Table::jumpAfterModChanged(int state) { - if(state == Qt::Checked) + if (state == Qt::Checked) mAutoJump = true; else mAutoJump = false; diff --git a/apps/opencs/view/world/table.hpp b/apps/opencs/view/world/table.hpp index caae3165cf..6834e5827a 100644 --- a/apps/opencs/view/world/table.hpp +++ b/apps/opencs/view/world/table.hpp @@ -1,8 +1,8 @@ #ifndef CSV_WORLD_TABLE_H #define CSV_WORLD_TABLE_H -#include #include +#include #include "../../model/filter/node.hpp" #include "../../model/world/columnbase.hpp" @@ -36,139 +36,135 @@ namespace CSVWorld ///< Table widget class Table : public DragRecordTable { - Q_OBJECT - - enum DoubleClickAction - { - Action_None, - Action_InPlaceEdit, - Action_EditRecord, - Action_View, - Action_Revert, - Action_Delete, - Action_EditRecordAndClose, - Action_ViewAndClose - }; - - std::vector mDelegates; - QAction *mEditAction; - QAction *mCreateAction; - QAction *mCloneAction; - QAction *mTouchAction; - QAction *mRevertAction; - QAction *mDeleteAction; - QAction *mMoveUpAction; - QAction *mMoveDownAction; - QAction *mViewAction; - QAction *mPreviewAction; - QAction *mExtendedDeleteAction; - QAction *mExtendedRevertAction; - QAction *mHelpAction; - TableEditIdAction *mEditIdAction; - CSMWorld::IdTableProxyModel *mProxyModel; - CSMWorld::IdTableBase *mModel; - int mRecordStatusDisplay; - CSMWorld::CommandDispatcher *mDispatcher; - std::map mDoubleClickActions; - bool mJumpToAddedRecord; - bool mUnselectAfterJump; - bool mAutoJump; - - private: + Q_OBJECT - void contextMenuEvent (QContextMenuEvent *event) override; + enum DoubleClickAction + { + Action_None, + Action_InPlaceEdit, + Action_EditRecord, + Action_View, + Action_Revert, + Action_Delete, + Action_EditRecordAndClose, + Action_ViewAndClose + }; - void mouseMoveEvent(QMouseEvent *event) override; + std::vector mDelegates; + QAction* mEditAction; + QAction* mCreateAction; + QAction* mCloneAction; + QAction* mTouchAction; + QAction* mRevertAction; + QAction* mDeleteAction; + QAction* mMoveUpAction; + QAction* mMoveDownAction; + QAction* mViewAction; + QAction* mPreviewAction; + QAction* mExtendedDeleteAction; + QAction* mExtendedRevertAction; + QAction* mHelpAction; + TableEditIdAction* mEditIdAction; + CSMWorld::IdTableProxyModel* mProxyModel; + CSMWorld::IdTableBase* mModel; + int mRecordStatusDisplay; + CSMWorld::CommandDispatcher* mDispatcher; + std::map mDoubleClickActions; + bool mJumpToAddedRecord; + bool mUnselectAfterJump; + bool mAutoJump; - protected: + private: + void contextMenuEvent(QContextMenuEvent* event) override; - void mouseDoubleClickEvent (QMouseEvent *event) override; + void mouseMoveEvent(QMouseEvent* event) override; - public: + protected: + void mouseDoubleClickEvent(QMouseEvent* event) override; - Table (const CSMWorld::UniversalId& id, bool createAndDelete, - bool sorting, CSMDoc::Document& document); - ///< \param createAndDelete Allow creation and deletion of records. - /// \param sorting Allow changing order of rows in the view via column headers. + public: + Table(const CSMWorld::UniversalId& id, bool createAndDelete, bool sorting, CSMDoc::Document& document); + ///< \param createAndDelete Allow creation and deletion of records. + /// \param sorting Allow changing order of rows in the view via column headers. - virtual void setEditLock (bool locked); + virtual void setEditLock(bool locked); - CSMWorld::UniversalId getUniversalId (int row) const; + CSMWorld::UniversalId getUniversalId(int row) const; - std::vector getColumnsWithDisplay(CSMWorld::ColumnBase::Display display) const; + std::vector getColumnsWithDisplay(CSMWorld::ColumnBase::Display display) const; - std::vector getSelectedIds() const; + std::vector getSelectedIds() const; - std::vector getDraggedRecords() const override; + std::vector getDraggedRecords() const override; - signals: + signals: - void editRequest (const CSMWorld::UniversalId& id, const std::string& hint); + void editRequest(const CSMWorld::UniversalId& id, const std::string& hint); - void selectionSizeChanged (int size); + void selectionSizeChanged(int size); - void tableSizeChanged (int size, int deleted, int modified); - ///< \param size Number of not deleted records - /// \param deleted Number of deleted records - /// \param modified Number of added and modified records + void tableSizeChanged(int size, int deleted, int modified); + ///< \param size Number of not deleted records + /// \param deleted Number of deleted records + /// \param modified Number of added and modified records - void createRequest(); + void createRequest(); - void cloneRequest(const CSMWorld::UniversalId&); + void cloneRequest(const CSMWorld::UniversalId&); - void touchRequest(const std::vector& ids); + void touchRequest(const std::vector& ids); - void closeRequest(); + void closeRequest(); - void extendedDeleteConfigRequest(const std::vector &selectedIds); + void extendedDeleteConfigRequest(const std::vector& selectedIds); - void extendedRevertConfigRequest(const std::vector &selectedIds); + void extendedRevertConfigRequest(const std::vector& selectedIds); - private slots: + private slots: - void editCell(); + void editCell(); - static void openHelp(); + static void openHelp(); - void editRecord(); + void editRecord(); - void cloneRecord(); + void cloneRecord(); - void touchRecord(); + void touchRecord(); - void moveUpRecord(); + void moveUpRecord(); - void moveDownRecord(); + void moveDownRecord(); - void moveRecords(QDropEvent *event); + void moveRecords(QDropEvent* event); - void viewRecord(); + void viewRecord(); - void previewRecord(); + void previewRecord(); - void executeExtendedDelete(); + void executeExtendedDelete(); - void executeExtendedRevert(); + void executeExtendedRevert(); - public slots: + public slots: - void settingChanged (const CSMPrefs::Setting *setting); + void settingChanged(const CSMPrefs::Setting* setting); - void tableSizeUpdate(); + void tableSizeUpdate(); - void selectionSizeUpdate(); + void selectionSizeUpdate(); - void requestFocus (const std::string& id); + void requestFocus(const std::string& id); - void recordFilterChanged (std::shared_ptr filter); + void recordFilterChanged(std::shared_ptr filter); - void rowAdded(const std::string &id); + void rowAdded(const std::string& id); - void dataChangedEvent(const QModelIndex &topLeft, const QModelIndex &bottomRight); + void dataChangedEvent(const QModelIndex& topLeft, const QModelIndex& bottomRight); - void jumpAfterModChanged(int state); + void jumpAfterModChanged(int state); - void queuedScrollTo(int state); + void queuedScrollTo(int state); }; } diff --git a/apps/opencs/view/world/tablebottombox.cpp b/apps/opencs/view/world/tablebottombox.cpp index 3d64280625..217e4308c9 100644 --- a/apps/opencs/view/world/tablebottombox.cpp +++ b/apps/opencs/view/world/tablebottombox.cpp @@ -2,11 +2,11 @@ #include -#include -#include -#include #include #include +#include +#include +#include #include "creator.hpp" @@ -30,29 +30,27 @@ void CSVWorld::TableBottomBox::updateStatus() { if (!mStatusMessage.isEmpty()) { - mStatus->setText (mStatusMessage); + mStatus->setText(mStatusMessage); return; } - static const char *sLabels[4] = { "record", "deleted", "touched", "selected" }; - static const char *sLabelsPlural[4] = { "records", "deleted", "touched", "selected" }; + static const char* sLabels[4] = { "record", "deleted", "touched", "selected" }; + static const char* sLabelsPlural[4] = { "records", "deleted", "touched", "selected" }; std::ostringstream stream; bool first = true; - for (int i=0; i<4; ++i) + for (int i = 0; i < 4; ++i) { - if (mStatusCount[i]>0) + if (mStatusCount[i] > 0) { if (first) first = false; else stream << ", "; - stream - << mStatusCount[i] << ' ' - << (mStatusCount[i]==1 ? sLabels[i] : sLabelsPlural[i]); + stream << mStatusCount[i] << ' ' << (mStatusCount[i] == 1 ? sLabels[i] : sLabelsPlural[i]); } } @@ -64,71 +62,73 @@ void CSVWorld::TableBottomBox::updateStatus() stream << "(" << mRow << ", " << mColumn << ")"; } - mStatus->setText (QString::fromUtf8 (stream.str().c_str())); + mStatus->setText(QString::fromUtf8(stream.str().c_str())); } } -void CSVWorld::TableBottomBox::extendedConfigRequest(CSVWorld::ExtendedCommandConfigurator::Mode mode, - const std::vector &selectedIds) +void CSVWorld::TableBottomBox::extendedConfigRequest( + CSVWorld::ExtendedCommandConfigurator::Mode mode, const std::vector& selectedIds) { - mExtendedConfigurator->configure (mode, selectedIds); - mLayout->setCurrentWidget (mExtendedConfigurator); + mExtendedConfigurator->configure(mode, selectedIds); + mLayout->setCurrentWidget(mExtendedConfigurator); mEditMode = EditMode_ExtendedConfig; - setVisible (true); + setVisible(true); mExtendedConfigurator->setFocus(); } -CSVWorld::TableBottomBox::TableBottomBox (const CreatorFactoryBase& creatorFactory, - CSMDoc::Document& document, - const CSMWorld::UniversalId& id, - QWidget *parent) -: QWidget (parent), mShowStatusBar (false), mEditMode(EditMode_None), mHasPosition(false), mRow(0), mColumn(0) +CSVWorld::TableBottomBox::TableBottomBox(const CreatorFactoryBase& creatorFactory, CSMDoc::Document& document, + const CSMWorld::UniversalId& id, QWidget* parent) + : QWidget(parent) + , mShowStatusBar(false) + , mEditMode(EditMode_None) + , mHasPosition(false) + , mRow(0) + , mColumn(0) { - for (int i=0; i<4; ++i) + for (int i = 0; i < 4; ++i) mStatusCount[i] = 0; - setVisible (false); + setVisible(false); mLayout = new QStackedLayout; - mLayout->setContentsMargins (0, 0, 0, 0); - connect (mLayout, &QStackedLayout::currentChanged, this, &TableBottomBox::currentWidgetChanged); + mLayout->setContentsMargins(0, 0, 0, 0); + connect(mLayout, &QStackedLayout::currentChanged, this, &TableBottomBox::currentWidgetChanged); mStatus = new QLabel; mStatusBar = new QStatusBar(this); - mStatusBar->addWidget (mStatus); + mStatusBar->addWidget(mStatus); - mLayout->addWidget (mStatusBar); + mLayout->addWidget(mStatusBar); - setLayout (mLayout); + setLayout(mLayout); - mCreator = creatorFactory.makeCreator (document, id); + mCreator = creatorFactory.makeCreator(document, id); if (mCreator) { mCreator->installEventFilter(this); - mLayout->addWidget (mCreator); + mLayout->addWidget(mCreator); - connect (mCreator, &Creator::done, this, &TableBottomBox::requestDone); + connect(mCreator, &Creator::done, this, &TableBottomBox::requestDone); - connect (mCreator, &Creator::requestFocus, this, &TableBottomBox::requestFocus); + connect(mCreator, &Creator::requestFocus, this, &TableBottomBox::requestFocus); } - mExtendedConfigurator = new ExtendedCommandConfigurator (document, id, this); + mExtendedConfigurator = new ExtendedCommandConfigurator(document, id, this); mExtendedConfigurator->installEventFilter(this); - mLayout->addWidget (mExtendedConfigurator); - connect (mExtendedConfigurator, &ExtendedCommandConfigurator::done, - this, &TableBottomBox::requestDone); + mLayout->addWidget(mExtendedConfigurator); + connect(mExtendedConfigurator, &ExtendedCommandConfigurator::done, this, &TableBottomBox::requestDone); updateSize(); } -void CSVWorld::TableBottomBox::setEditLock (bool locked) +void CSVWorld::TableBottomBox::setEditLock(bool locked) { if (mCreator) - mCreator->setEditLock (locked); - mExtendedConfigurator->setEditLock (locked); + mCreator->setEditLock(locked); + mExtendedConfigurator->setEditLock(locked); } CSVWorld::TableBottomBox::~TableBottomBox() @@ -136,11 +136,11 @@ CSVWorld::TableBottomBox::~TableBottomBox() delete mCreator; } -bool CSVWorld::TableBottomBox::eventFilter(QObject *object, QEvent *event) +bool CSVWorld::TableBottomBox::eventFilter(QObject* object, QEvent* event) { if (event->type() == QEvent::KeyPress) { - QKeyEvent *keyEvent = static_cast(event); + QKeyEvent* keyEvent = static_cast(event); if (keyEvent->key() == Qt::Key_Escape) { requestDone(); @@ -150,11 +150,11 @@ bool CSVWorld::TableBottomBox::eventFilter(QObject *object, QEvent *event) return QWidget::eventFilter(object, event); } -void CSVWorld::TableBottomBox::setStatusBar (bool show) +void CSVWorld::TableBottomBox::setStatusBar(bool show) { - if (show!=mShowStatusBar) + if (show != mShowStatusBar) { - setVisible (show || (mEditMode != EditMode_None)); + setVisible(show || (mEditMode != EditMode_None)); mShowStatusBar = show; @@ -171,11 +171,11 @@ bool CSVWorld::TableBottomBox::canCreateAndDelete() const void CSVWorld::TableBottomBox::requestDone() { if (!mShowStatusBar) - setVisible (false); + setVisible(false); else updateStatus(); - mLayout->setCurrentWidget (mStatusBar); + mLayout->setCurrentWidget(mStatusBar); mEditMode = EditMode_None; } @@ -184,15 +184,15 @@ void CSVWorld::TableBottomBox::currentWidgetChanged(int /*index*/) updateSize(); } -void CSVWorld::TableBottomBox::setStatusMessage (const QString& message) +void CSVWorld::TableBottomBox::setStatusMessage(const QString& message) { mStatusMessage = message; updateStatus(); } -void CSVWorld::TableBottomBox::selectionSizeChanged (int size) +void CSVWorld::TableBottomBox::selectionSizeChanged(int size) { - if (mStatusCount[3]!=size) + if (mStatusCount[3] != size) { mStatusMessage = ""; mStatusCount[3] = size; @@ -200,23 +200,23 @@ void CSVWorld::TableBottomBox::selectionSizeChanged (int size) } } -void CSVWorld::TableBottomBox::tableSizeChanged (int size, int deleted, int modified) +void CSVWorld::TableBottomBox::tableSizeChanged(int size, int deleted, int modified) { bool changed = false; - if (mStatusCount[0]!=size) + if (mStatusCount[0] != size) { mStatusCount[0] = size; changed = true; } - if (mStatusCount[1]!=deleted) + if (mStatusCount[1] != deleted) { mStatusCount[1] = deleted; changed = true; } - if (mStatusCount[2]!=modified) + if (mStatusCount[2] != modified) { mStatusCount[2] = modified; changed = true; @@ -229,7 +229,7 @@ void CSVWorld::TableBottomBox::tableSizeChanged (int size, int deleted, int modi } } -void CSVWorld::TableBottomBox::positionChanged (int row, int column) +void CSVWorld::TableBottomBox::positionChanged(int row, int column) { mRow = row; mColumn = column; @@ -247,20 +247,19 @@ void CSVWorld::TableBottomBox::createRequest() { mCreator->reset(); mCreator->toggleWidgets(true); - mLayout->setCurrentWidget (mCreator); - setVisible (true); + mLayout->setCurrentWidget(mCreator); + setVisible(true); mEditMode = EditMode_Creation; mCreator->focus(); } -void CSVWorld::TableBottomBox::cloneRequest(const std::string& id, - const CSMWorld::UniversalId::Type type) +void CSVWorld::TableBottomBox::cloneRequest(const std::string& id, const CSMWorld::UniversalId::Type type) { mCreator->reset(); mCreator->cloneMode(id, type); mLayout->setCurrentWidget(mCreator); mCreator->toggleWidgets(false); - setVisible (true); + setVisible(true); mEditMode = EditMode_Creation; mCreator->focus(); } @@ -270,12 +269,12 @@ void CSVWorld::TableBottomBox::touchRequest(const std::vectortouch(ids); } -void CSVWorld::TableBottomBox::extendedDeleteConfigRequest(const std::vector &selectedIds) +void CSVWorld::TableBottomBox::extendedDeleteConfigRequest(const std::vector& selectedIds) { extendedConfigRequest(ExtendedCommandConfigurator::Mode_Delete, selectedIds); } -void CSVWorld::TableBottomBox::extendedRevertConfigRequest(const std::vector &selectedIds) +void CSVWorld::TableBottomBox::extendedRevertConfigRequest(const std::vector& selectedIds) { extendedConfigRequest(ExtendedCommandConfigurator::Mode_Revert, selectedIds); } diff --git a/apps/opencs/view/world/tablebottombox.hpp b/apps/opencs/view/world/tablebottombox.hpp index ac5ad2fda6..c8b11b0edf 100644 --- a/apps/opencs/view/world/tablebottombox.hpp +++ b/apps/opencs/view/world/tablebottombox.hpp @@ -22,93 +22,92 @@ namespace CSVWorld class TableBottomBox : public QWidget { - Q_OBJECT + Q_OBJECT - enum EditMode { EditMode_None, EditMode_Creation, EditMode_ExtendedConfig }; + enum EditMode + { + EditMode_None, + EditMode_Creation, + EditMode_ExtendedConfig + }; - bool mShowStatusBar; - QLabel *mStatus; - QStatusBar *mStatusBar; - int mStatusCount[4]; + bool mShowStatusBar; + QLabel* mStatus; + QStatusBar* mStatusBar; + int mStatusCount[4]; - EditMode mEditMode; - Creator *mCreator; - ExtendedCommandConfigurator *mExtendedConfigurator; + EditMode mEditMode; + Creator* mCreator; + ExtendedCommandConfigurator* mExtendedConfigurator; - QStackedLayout *mLayout; - bool mHasPosition; - int mRow; - int mColumn; - QString mStatusMessage; + QStackedLayout* mLayout; + bool mHasPosition; + int mRow; + int mColumn; + QString mStatusMessage; - private: + private: + // not implemented + TableBottomBox(const TableBottomBox&); + TableBottomBox& operator=(const TableBottomBox&); - // not implemented - TableBottomBox (const TableBottomBox&); - TableBottomBox& operator= (const TableBottomBox&); + void updateSize(); - void updateSize(); + void updateStatus(); - void updateStatus(); + void extendedConfigRequest(ExtendedCommandConfigurator::Mode mode, const std::vector& selectedIds); - void extendedConfigRequest(ExtendedCommandConfigurator::Mode mode, - const std::vector &selectedIds); + public: + TableBottomBox(const CreatorFactoryBase& creatorFactory, CSMDoc::Document& document, + const CSMWorld::UniversalId& id, QWidget* parent = nullptr); - public: + ~TableBottomBox() override; - TableBottomBox (const CreatorFactoryBase& creatorFactory, - CSMDoc::Document& document, - const CSMWorld::UniversalId& id, - QWidget *parent = nullptr); + bool eventFilter(QObject* object, QEvent* event) override; - ~TableBottomBox() override; + void setEditLock(bool locked); - bool eventFilter(QObject *object, QEvent *event) override; + void setStatusBar(bool show); - void setEditLock (bool locked); + bool canCreateAndDelete() const; + ///< Is record creation and deletion supported? + /// + /// \note The BotomBox does not partake in the deletion of records. - void setStatusBar (bool show); + void setStatusMessage(const QString& message); - bool canCreateAndDelete() const; - ///< Is record creation and deletion supported? - /// - /// \note The BotomBox does not partake in the deletion of records. + signals: - void setStatusMessage (const QString& message); + void requestFocus(const std::string& id); + ///< Request owner of this box to focus the just created \a id. The owner may + /// ignore this request. - signals: + private slots: - void requestFocus (const std::string& id); - ///< Request owner of this box to focus the just created \a id. The owner may - /// ignore this request. + void requestDone(); + ///< \note This slot being called does not imply success. - private slots: + void currentWidgetChanged(int index); - void requestDone(); - ///< \note This slot being called does not imply success. + public slots: - void currentWidgetChanged(int index); + void selectionSizeChanged(int size); - public slots: + void tableSizeChanged(int size, int deleted, int modified); + ///< \param size Number of not deleted records + /// \param deleted Number of deleted records + /// \param modified Number of added and modified records - void selectionSizeChanged (int size); + void positionChanged(int row, int column); - void tableSizeChanged (int size, int deleted, int modified); - ///< \param size Number of not deleted records - /// \param deleted Number of deleted records - /// \param modified Number of added and modified records + void noMorePosition(); - void positionChanged (int row, int column); + void createRequest(); + void cloneRequest(const std::string& id, const CSMWorld::UniversalId::Type type); + void touchRequest(const std::vector&); - void noMorePosition(); - - void createRequest(); - void cloneRequest(const std::string& id, - const CSMWorld::UniversalId::Type type); - void touchRequest(const std::vector&); - - void extendedDeleteConfigRequest(const std::vector &selectedIds); - void extendedRevertConfigRequest(const std::vector &selectedIds); + void extendedDeleteConfigRequest(const std::vector& selectedIds); + void extendedRevertConfigRequest(const std::vector& selectedIds); }; } diff --git a/apps/opencs/view/world/tableeditidaction.cpp b/apps/opencs/view/world/tableeditidaction.cpp index 4dfc537cc8..427734b2f5 100644 --- a/apps/opencs/view/world/tableeditidaction.cpp +++ b/apps/opencs/view/world/tableeditidaction.cpp @@ -16,11 +16,12 @@ CSVWorld::TableEditIdAction::CellData CSVWorld::TableEditIdAction::getCellData(i return std::make_pair(CSMWorld::ColumnBase::Display_None, ""); } -CSVWorld::TableEditIdAction::TableEditIdAction(const QTableView &table, QWidget *parent) - : QAction(parent), - mTable(table), - mCurrentId(CSMWorld::UniversalId::Type_None) -{} +CSVWorld::TableEditIdAction::TableEditIdAction(const QTableView& table, QWidget* parent) + : QAction(parent) + , mTable(table) + , mCurrentId(CSMWorld::UniversalId::Type_None) +{ +} void CSVWorld::TableEditIdAction::setCell(int row, int column) { @@ -43,7 +44,6 @@ bool CSVWorld::TableEditIdAction::isValidIdCell(int row, int column) const { CellData data = getCellData(row, column); CSMWorld::UniversalId::Type idType = CSMWorld::TableMimeData::convertEnums(data.first); - return CSMWorld::ColumnBase::isId(data.first) && - idType != CSMWorld::UniversalId::Type_None && - !data.second.isEmpty(); + return CSMWorld::ColumnBase::isId(data.first) && idType != CSMWorld::UniversalId::Type_None + && !data.second.isEmpty(); } diff --git a/apps/opencs/view/world/tableeditidaction.hpp b/apps/opencs/view/world/tableeditidaction.hpp index 9fe41b0de2..ca1d2a794c 100644 --- a/apps/opencs/view/world/tableeditidaction.hpp +++ b/apps/opencs/view/world/tableeditidaction.hpp @@ -12,19 +12,19 @@ namespace CSVWorld { class TableEditIdAction : public QAction { - const QTableView &mTable; - CSMWorld::UniversalId mCurrentId; + const QTableView& mTable; + CSMWorld::UniversalId mCurrentId; - typedef std::pair CellData; - CellData getCellData(int row, int column) const; + typedef std::pair CellData; + CellData getCellData(int row, int column) const; - public: - TableEditIdAction(const QTableView &table, QWidget *parent = nullptr); + public: + TableEditIdAction(const QTableView& table, QWidget* parent = nullptr); - void setCell(int row, int column); + void setCell(int row, int column); - CSMWorld::UniversalId getCurrentId() const; - bool isValidIdCell(int row, int column) const; + CSMWorld::UniversalId getCurrentId() const; + bool isValidIdCell(int row, int column) const; }; } diff --git a/apps/opencs/view/world/tableheadermouseeventhandler.cpp b/apps/opencs/view/world/tableheadermouseeventhandler.cpp index 9c76cfaffe..5f786f77a6 100644 --- a/apps/opencs/view/world/tableheadermouseeventhandler.cpp +++ b/apps/opencs/view/world/tableheadermouseeventhandler.cpp @@ -2,64 +2,64 @@ #include "dragrecordtable.hpp" #include -#include #include +#include namespace CSVWorld { -TableHeaderMouseEventHandler::TableHeaderMouseEventHandler(DragRecordTable * parent) - : QWidget(parent) - , table(*parent) - , header(*table.horizontalHeader()) -{ - header.setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu); - connect( - &header, &QHeaderView::customContextMenuRequested, [this](const QPoint & position) { showContextMenu(position); }); + TableHeaderMouseEventHandler::TableHeaderMouseEventHandler(DragRecordTable* parent) + : QWidget(parent) + , table(*parent) + , header(*table.horizontalHeader()) + { + header.setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu); + connect(&header, &QHeaderView::customContextMenuRequested, + [this](const QPoint& position) { showContextMenu(position); }); - header.viewport()->installEventFilter(this); -} + header.viewport()->installEventFilter(this); + } -bool TableHeaderMouseEventHandler::eventFilter(QObject * tableWatched, QEvent * event) -{ - if (event->type() == QEvent::Type::MouseButtonPress) + bool TableHeaderMouseEventHandler::eventFilter(QObject* tableWatched, QEvent* event) { - auto & clickEvent = static_cast(*event); - if ((clickEvent.button() == Qt::MiddleButton)) + if (event->type() == QEvent::Type::MouseButtonPress) { - const auto & index = table.indexAt(clickEvent.pos()); - table.setColumnHidden(index.column(), true); - clickEvent.accept(); - return true; + auto& clickEvent = static_cast(*event); + if ((clickEvent.button() == Qt::MiddleButton)) + { + const auto& index = table.indexAt(clickEvent.pos()); + table.setColumnHidden(index.column(), true); + clickEvent.accept(); + return true; + } } + return false; } - return false; -} -void TableHeaderMouseEventHandler::showContextMenu(const QPoint & position) -{ - auto & menu{createContextMenu()}; - menu.popup(header.viewport()->mapToGlobal(position)); -} + void TableHeaderMouseEventHandler::showContextMenu(const QPoint& position) + { + auto& menu{ createContextMenu() }; + menu.popup(header.viewport()->mapToGlobal(position)); + } -QMenu & TableHeaderMouseEventHandler::createContextMenu() -{ - auto * menu = new QMenu(this); - for (int i = 0; i < table.model()->columnCount(); ++i) + QMenu& TableHeaderMouseEventHandler::createContextMenu() { - const auto & name = table.model()->headerData(i, Qt::Horizontal, Qt::DisplayRole); - QAction * action{new QAction(name.toString(), this)}; - action->setCheckable(true); - action->setChecked(!table.isColumnHidden(i)); - menu->addAction(action); + auto* menu = new QMenu(this); + for (int i = 0; i < table.model()->columnCount(); ++i) + { + const auto& name = table.model()->headerData(i, Qt::Horizontal, Qt::DisplayRole); + QAction* action{ new QAction(name.toString(), this) }; + action->setCheckable(true); + action->setChecked(!table.isColumnHidden(i)); + menu->addAction(action); - connect(action, &QAction::triggered, [this, &action, &i]() { - table.setColumnHidden(i, !action->isChecked()); - action->setChecked(!action->isChecked()); - action->toggle(); - }); + connect(action, &QAction::triggered, [this, &action, &i]() { + table.setColumnHidden(i, !action->isChecked()); + action->setChecked(!action->isChecked()); + action->toggle(); + }); + } + return *menu; } - return *menu; -} } // namespace CSVWorld diff --git a/apps/opencs/view/world/tableheadermouseeventhandler.hpp b/apps/opencs/view/world/tableheadermouseeventhandler.hpp index 381e127624..737e4d5367 100644 --- a/apps/opencs/view/world/tableheadermouseeventhandler.hpp +++ b/apps/opencs/view/world/tableheadermouseeventhandler.hpp @@ -1,25 +1,25 @@ #pragma once -#include #include +#include namespace CSVWorld { -class DragRecordTable; + class DragRecordTable; -class TableHeaderMouseEventHandler : public QWidget -{ -public: - explicit TableHeaderMouseEventHandler(DragRecordTable * parent); + class TableHeaderMouseEventHandler : public QWidget + { + public: + explicit TableHeaderMouseEventHandler(DragRecordTable* parent); - void showContextMenu(const QPoint &); + void showContextMenu(const QPoint&); -private: - DragRecordTable & table; - QHeaderView & header; + private: + DragRecordTable& table; + QHeaderView& header; - QMenu & createContextMenu(); - bool eventFilter(QObject *, QEvent *) override; + QMenu& createContextMenu(); + bool eventFilter(QObject*, QEvent*) override; -}; // class TableHeaderMouseEventHandler + }; // class TableHeaderMouseEventHandler } // namespace CSVWorld diff --git a/apps/opencs/view/world/tablesubview.cpp b/apps/opencs/view/world/tablesubview.cpp index bd29b3e634..0fafd0c29c 100644 --- a/apps/opencs/view/world/tablesubview.cpp +++ b/apps/opencs/view/world/tablesubview.cpp @@ -1,87 +1,88 @@ #include "tablesubview.hpp" -#include -#include -#include -#include -#include -#include #include +#include #include #include +#include +#include +#include +#include +#include #include "../../model/doc/document.hpp" #include "../../model/world/tablemimedata.hpp" #include "../doc/sizehint.hpp" #include "../filter/filterbox.hpp" +#include "creator.hpp" #include "table.hpp" #include "tablebottombox.hpp" -#include "creator.hpp" -CSVWorld::TableSubView::TableSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, - const CreatorFactoryBase& creatorFactory, bool sorting) -: SubView (id), mShowOptions(false), mOptions(0) +CSVWorld::TableSubView::TableSubView( + const CSMWorld::UniversalId& id, CSMDoc::Document& document, const CreatorFactoryBase& creatorFactory, bool sorting) + : SubView(id) + , mShowOptions(false) + , mOptions(0) { - QVBoxLayout *layout = new QVBoxLayout; + QVBoxLayout* layout = new QVBoxLayout; - layout->addWidget (mBottom = - new TableBottomBox (creatorFactory, document, id, this), 0); + layout->addWidget(mBottom = new TableBottomBox(creatorFactory, document, id, this), 0); - layout->insertWidget (0, mTable = - new Table (id, mBottom->canCreateAndDelete(), sorting, document), 2); + layout->insertWidget(0, mTable = new Table(id, mBottom->canCreateAndDelete(), sorting, document), 2); - mFilterBox = new CSVFilter::FilterBox (document.getData(), this); + mFilterBox = new CSVFilter::FilterBox(document.getData(), this); - QHBoxLayout *hLayout = new QHBoxLayout; - hLayout->insertWidget(0,mFilterBox); + QHBoxLayout* hLayout = new QHBoxLayout; + hLayout->insertWidget(0, mFilterBox); mOptions = new QWidget; - QHBoxLayout *optHLayout = new QHBoxLayout; - QCheckBox *autoJump = new QCheckBox("Auto Jump"); - autoJump->setToolTip ("Whether to jump to the modified record." - "\nCan be useful in finding the moved or modified" - "\nobject instance while 3D editing."); + QHBoxLayout* optHLayout = new QHBoxLayout; + QCheckBox* autoJump = new QCheckBox("Auto Jump"); + autoJump->setToolTip( + "Whether to jump to the modified record." + "\nCan be useful in finding the moved or modified" + "\nobject instance while 3D editing."); autoJump->setCheckState(Qt::Unchecked); connect(autoJump, &QCheckBox::stateChanged, mTable, &Table::jumpAfterModChanged); optHLayout->insertWidget(0, autoJump); - optHLayout->setContentsMargins (QMargins (0, 3, 0, 0)); + optHLayout->setContentsMargins(QMargins(0, 3, 0, 0)); mOptions->setLayout(optHLayout); mOptions->resize(mOptions->width(), mFilterBox->height()); mOptions->hide(); - QPushButton *opt = new QPushButton (); - opt->setIcon (QIcon (":startup/configure")); - opt->setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed)); - opt->setToolTip ("Open additional options for this subview."); - connect (opt, &QPushButton::clicked, this, &TableSubView::toggleOptions); + QPushButton* opt = new QPushButton(); + opt->setIcon(QIcon(":startup/configure")); + opt->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); + opt->setToolTip("Open additional options for this subview."); + connect(opt, &QPushButton::clicked, this, &TableSubView::toggleOptions); - QVBoxLayout *buttonLayout = new QVBoxLayout; // work around margin issues - buttonLayout->setContentsMargins (QMargins (0/*left*/, 3/*top*/, 3/*right*/, 0/*bottom*/)); - buttonLayout->insertWidget(0, opt, 0, Qt::AlignVCenter|Qt::AlignRight); + QVBoxLayout* buttonLayout = new QVBoxLayout; // work around margin issues + buttonLayout->setContentsMargins(QMargins(0 /*left*/, 3 /*top*/, 3 /*right*/, 0 /*bottom*/)); + buttonLayout->insertWidget(0, opt, 0, Qt::AlignVCenter | Qt::AlignRight); hLayout->insertWidget(1, mOptions); hLayout->insertLayout(2, buttonLayout); - layout->insertLayout (0, hLayout); + layout->insertLayout(0, hLayout); - CSVDoc::SizeHintWidget *widget = new CSVDoc::SizeHintWidget; + CSVDoc::SizeHintWidget* widget = new CSVDoc::SizeHintWidget; - widget->setLayout (layout); + widget->setLayout(layout); - setWidget (widget); + setWidget(widget); // prefer height of the screen and full width of the table const QRect rect = QApplication::desktop()->screenGeometry(this); int frameHeight = 40; // set a reasonable default - QWidget *topLevel = QApplication::topLevelAt(pos()); + QWidget* topLevel = QApplication::topLevelAt(pos()); if (topLevel) frameHeight = topLevel->frameGeometry().height() - topLevel->height(); - widget->setSizeHint(QSize(mTable->horizontalHeader()->length(), rect.height()-frameHeight)); + widget->setSizeHint(QSize(mTable->horizontalHeader()->length(), rect.height() - frameHeight)); - connect (mTable, &Table::editRequest, this, &TableSubView::editRequest); + connect(mTable, &Table::editRequest, this, &TableSubView::editRequest); - connect (mTable, &Table::selectionSizeChanged, mBottom, &TableBottomBox::selectionSizeChanged); - connect (mTable, &Table::tableSizeChanged, mBottom, &TableBottomBox::tableSizeChanged); + connect(mTable, &Table::selectionSizeChanged, mBottom, &TableBottomBox::selectionSizeChanged); + connect(mTable, &Table::tableSizeChanged, mBottom, &TableBottomBox::tableSizeChanged); mTable->tableSizeUpdate(); mTable->selectionSizeUpdate(); @@ -91,58 +92,51 @@ CSVWorld::TableSubView::TableSubView (const CSMWorld::UniversalId& id, CSMDoc::D if (mBottom->canCreateAndDelete()) { - connect (mTable, &Table::createRequest, mBottom, &TableBottomBox::createRequest); + connect(mTable, &Table::createRequest, mBottom, &TableBottomBox::createRequest); - connect (mTable, &Table::cloneRequest, - this, qOverload(&TableSubView::cloneRequest)); + connect( + mTable, &Table::cloneRequest, this, qOverload(&TableSubView::cloneRequest)); - connect (this, - qOverload(&TableSubView::cloneRequest), + connect(this, qOverload(&TableSubView::cloneRequest), mBottom, &TableBottomBox::cloneRequest); - connect (mTable, &Table::touchRequest, - mBottom, &TableBottomBox::touchRequest); + connect(mTable, &Table::touchRequest, mBottom, &TableBottomBox::touchRequest); - connect (mTable, &Table::extendedDeleteConfigRequest, - mBottom, &TableBottomBox::extendedDeleteConfigRequest); - connect (mTable, &Table::extendedRevertConfigRequest, - mBottom, &TableBottomBox::extendedRevertConfigRequest); + connect(mTable, &Table::extendedDeleteConfigRequest, mBottom, &TableBottomBox::extendedDeleteConfigRequest); + connect(mTable, &Table::extendedRevertConfigRequest, mBottom, &TableBottomBox::extendedRevertConfigRequest); } - connect (mBottom, &TableBottomBox::requestFocus, mTable, &Table::requestFocus); - - connect (mFilterBox, &CSVFilter::FilterBox::recordFilterChanged, - mTable, &Table::recordFilterChanged); + connect(mBottom, &TableBottomBox::requestFocus, mTable, &Table::requestFocus); - connect(mFilterBox, &CSVFilter::FilterBox::recordDropped, - this, &TableSubView::createFilterRequest); + connect(mFilterBox, &CSVFilter::FilterBox::recordFilterChanged, mTable, &Table::recordFilterChanged); + connect(mFilterBox, &CSVFilter::FilterBox::recordDropped, this, &TableSubView::createFilterRequest); - connect (mTable, &Table::closeRequest, this, qOverload<>(&TableSubView::closeRequest)); + connect(mTable, &Table::closeRequest, this, qOverload<>(&TableSubView::closeRequest)); } -void CSVWorld::TableSubView::setEditLock (bool locked) +void CSVWorld::TableSubView::setEditLock(bool locked) { - mTable->setEditLock (locked); - mBottom->setEditLock (locked); + mTable->setEditLock(locked); + mBottom->setEditLock(locked); } -void CSVWorld::TableSubView::editRequest (const CSMWorld::UniversalId& id, const std::string& hint) +void CSVWorld::TableSubView::editRequest(const CSMWorld::UniversalId& id, const std::string& hint) { - focusId (id, hint); + focusId(id, hint); } -void CSVWorld::TableSubView::setStatusBar (bool show) +void CSVWorld::TableSubView::setStatusBar(bool show) { - mBottom->setStatusBar (show); + mBottom->setStatusBar(show); } -void CSVWorld::TableSubView::useHint (const std::string& hint) +void CSVWorld::TableSubView::useHint(const std::string& hint) { if (hint.empty()) return; - if (hint[0]=='f' && hint.size()>=2) - mFilterBox->setRecordFilter (hint.substr (2)); + if (hint[0] == 'f' && hint.size() >= 2) + mFilterBox->setRecordFilter(hint.substr(2)); } void CSVWorld::TableSubView::cloneRequest(const CSMWorld::UniversalId& toClone) @@ -150,23 +144,24 @@ void CSVWorld::TableSubView::cloneRequest(const CSMWorld::UniversalId& toClone) emit cloneRequest(toClone.getId(), toClone.getType()); } -void CSVWorld::TableSubView::createFilterRequest (std::vector< CSMWorld::UniversalId>& types, Qt::DropAction action) +void CSVWorld::TableSubView::createFilterRequest(std::vector& types, Qt::DropAction action) { - std::vector > > filterSource; + std::vector>> filterSource; - std::vector refIdColumns = mTable->getColumnsWithDisplay(CSMWorld::TableMimeData::convertEnums(CSMWorld::UniversalId::Type_Referenceable)); + std::vector refIdColumns = mTable->getColumnsWithDisplay( + CSMWorld::TableMimeData::convertEnums(CSMWorld::UniversalId::Type_Referenceable)); bool hasRefIdDisplay = !refIdColumns.empty(); for (std::vector::iterator it(types.begin()); it != types.end(); ++it) { CSMWorld::UniversalId::Type type = it->getType(); std::vector col = mTable->getColumnsWithDisplay(CSMWorld::TableMimeData::convertEnums(type)); - if(!col.empty()) + if (!col.empty()) { filterSource.emplace_back(it->getId(), col); } - if(hasRefIdDisplay && CSMWorld::TableMimeData::isReferencable(type)) + if (hasRefIdDisplay && CSMWorld::TableMimeData::isReferencable(type)) { filterSource.emplace_back(it->getId(), refIdColumns); } @@ -175,13 +170,14 @@ void CSVWorld::TableSubView::createFilterRequest (std::vector< CSMWorld::Univers mFilterBox->createFilterRequest(filterSource, action); } -bool CSVWorld::TableSubView::eventFilter (QObject* object, QEvent* event) +bool CSVWorld::TableSubView::eventFilter(QObject* object, QEvent* event) { if (event->type() == QEvent::Drop) { if (QDropEvent* drop = dynamic_cast(event)) { - const CSMWorld::TableMimeData* tableMimeData = dynamic_cast(drop->mimeData()); + const CSMWorld::TableMimeData* tableMimeData + = dynamic_cast(drop->mimeData()); if (!tableMimeData) // May happen when non-records (e.g. plain text) are dragged and dropped return false; @@ -210,7 +206,7 @@ void CSVWorld::TableSubView::toggleOptions() } } -void CSVWorld::TableSubView::requestFocus (const std::string& id) +void CSVWorld::TableSubView::requestFocus(const std::string& id) { mTable->requestFocus(id); } diff --git a/apps/opencs/view/world/tablesubview.hpp b/apps/opencs/view/world/tablesubview.hpp index 97d2bf15f2..3f7188f2ac 100644 --- a/apps/opencs/view/world/tablesubview.hpp +++ b/apps/opencs/view/world/tablesubview.hpp @@ -29,43 +29,40 @@ namespace CSVWorld class TableSubView : public CSVDoc::SubView { - Q_OBJECT + Q_OBJECT - Table *mTable; - TableBottomBox *mBottom; - CSVFilter::FilterBox *mFilterBox; - bool mShowOptions; - QWidget *mOptions; + Table* mTable; + TableBottomBox* mBottom; + CSVFilter::FilterBox* mFilterBox; + bool mShowOptions; + QWidget* mOptions; - public: + public: + TableSubView(const CSMWorld::UniversalId& id, CSMDoc::Document& document, + const CreatorFactoryBase& creatorFactory, bool sorting); - TableSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, - const CreatorFactoryBase& creatorFactory, bool sorting); + void setEditLock(bool locked) override; - void setEditLock (bool locked) override; + void setStatusBar(bool show) override; - void setStatusBar (bool show) override; + void useHint(const std::string& hint) override; - void useHint (const std::string& hint) override; + protected: + bool eventFilter(QObject* object, QEvent* event) override; - protected: - bool eventFilter(QObject* object, QEvent *event) override; + signals: + void cloneRequest(const std::string&, const CSMWorld::UniversalId::Type); - signals: - void cloneRequest(const std::string&, - const CSMWorld::UniversalId::Type); + private slots: - private slots: + void editRequest(const CSMWorld::UniversalId& id, const std::string& hint); + void cloneRequest(const CSMWorld::UniversalId& toClone); + void createFilterRequest(std::vector& types, Qt::DropAction action); + void toggleOptions(); - void editRequest (const CSMWorld::UniversalId& id, const std::string& hint); - void cloneRequest (const CSMWorld::UniversalId& toClone); - void createFilterRequest(std::vector< CSMWorld::UniversalId >& types, - Qt::DropAction action); - void toggleOptions (); + public slots: - public slots: - - void requestFocus (const std::string& id); + void requestFocus(const std::string& id); }; } diff --git a/apps/opencs/view/world/util.cpp b/apps/opencs/view/world/util.cpp index 14033f20fb..36d22a8fa0 100644 --- a/apps/opencs/view/world/util.cpp +++ b/apps/opencs/view/world/util.cpp @@ -3,16 +3,16 @@ #include #include -#include -#include -#include #include -#include #include +#include +#include +#include +#include +#include "../../model/world/commanddispatcher.hpp" #include "../../model/world/commands.hpp" #include "../../model/world/tablemimedata.hpp" -#include "../../model/world/commanddispatcher.hpp" #include "../widget/coloreditor.hpp" #include "../widget/droplineedit.hpp" @@ -20,26 +20,27 @@ #include "dialoguespinbox.hpp" #include "scriptedit.hpp" -CSVWorld::NastyTableModelHack::NastyTableModelHack (QAbstractItemModel& model) -: mModel (model) -{} +CSVWorld::NastyTableModelHack::NastyTableModelHack(QAbstractItemModel& model) + : mModel(model) +{ +} -int CSVWorld::NastyTableModelHack::rowCount (const QModelIndex & parent) const +int CSVWorld::NastyTableModelHack::rowCount(const QModelIndex& parent) const { - return mModel.rowCount (parent); + return mModel.rowCount(parent); } -int CSVWorld::NastyTableModelHack::columnCount (const QModelIndex & parent) const +int CSVWorld::NastyTableModelHack::columnCount(const QModelIndex& parent) const { - return mModel.columnCount (parent); + return mModel.columnCount(parent); } -QVariant CSVWorld::NastyTableModelHack::data (const QModelIndex & index, int role) const +QVariant CSVWorld::NastyTableModelHack::data(const QModelIndex& index, int role) const { - return mModel.data (index, role); + return mModel.data(index, role); } -bool CSVWorld::NastyTableModelHack::setData ( const QModelIndex &index, const QVariant &value, int role) +bool CSVWorld::NastyTableModelHack::setData(const QModelIndex& index, const QVariant& value, int role) { mData = value; return true; @@ -50,16 +51,14 @@ QVariant CSVWorld::NastyTableModelHack::getData() const return mData; } - CSVWorld::CommandDelegateFactory::~CommandDelegateFactory() {} - -CSVWorld::CommandDelegateFactoryCollection *CSVWorld::CommandDelegateFactoryCollection::sThis = nullptr; +CSVWorld::CommandDelegateFactoryCollection* CSVWorld::CommandDelegateFactoryCollection::sThis = nullptr; CSVWorld::CommandDelegateFactoryCollection::CommandDelegateFactoryCollection() { if (sThis) - throw std::logic_error ("multiple instances of CSVWorld::CommandDelegateFactoryCollection"); + throw std::logic_error("multiple instances of CSVWorld::CommandDelegateFactoryCollection"); sThis = this; } @@ -68,39 +67,37 @@ CSVWorld::CommandDelegateFactoryCollection::~CommandDelegateFactoryCollection() { sThis = nullptr; - for (std::map::iterator iter ( - mFactories.begin()); - iter!=mFactories.end(); ++iter) - delete iter->second; + for (std::map::iterator iter(mFactories.begin()); + iter != mFactories.end(); ++iter) + delete iter->second; } -void CSVWorld::CommandDelegateFactoryCollection::add (CSMWorld::ColumnBase::Display display, - CommandDelegateFactory *factory) +void CSVWorld::CommandDelegateFactoryCollection::add( + CSMWorld::ColumnBase::Display display, CommandDelegateFactory* factory) { - mFactories.insert (std::make_pair (display, factory)); + mFactories.insert(std::make_pair(display, factory)); } -CSVWorld::CommandDelegate *CSVWorld::CommandDelegateFactoryCollection::makeDelegate ( - CSMWorld::ColumnBase::Display display, CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) const +CSVWorld::CommandDelegate* CSVWorld::CommandDelegateFactoryCollection::makeDelegate( + CSMWorld::ColumnBase::Display display, CSMWorld::CommandDispatcher* dispatcher, CSMDoc::Document& document, + QObject* parent) const { - std::map::const_iterator iter = - mFactories.find (display); + std::map::const_iterator iter = mFactories.find(display); - if (iter!=mFactories.end()) - return iter->second->makeDelegate (dispatcher, document, parent); + if (iter != mFactories.end()) + return iter->second->makeDelegate(dispatcher, document, parent); - return new CommandDelegate (dispatcher, document, parent); + return new CommandDelegate(dispatcher, document, parent); } const CSVWorld::CommandDelegateFactoryCollection& CSVWorld::CommandDelegateFactoryCollection::get() { if (!sThis) - throw std::logic_error ("no instance of CSVWorld::CommandDelegateFactoryCollection"); + throw std::logic_error("no instance of CSVWorld::CommandDelegateFactoryCollection"); return *sThis; } - QUndoStack& CSVWorld::CommandDelegate::getUndoStack() const { return mDocument.getUndoStack(); @@ -111,14 +108,14 @@ CSMDoc::Document& CSVWorld::CommandDelegate::getDocument() const return mDocument; } -CSMWorld::ColumnBase::Display CSVWorld::CommandDelegate::getDisplayTypeFromIndex(const QModelIndex &index) const +CSMWorld::ColumnBase::Display CSVWorld::CommandDelegate::getDisplayTypeFromIndex(const QModelIndex& index) const { int rawDisplay = index.data(CSMWorld::ColumnBase::Role_Display).toInt(); return static_cast(rawDisplay); } -void CSVWorld::CommandDelegate::setModelDataImp (QWidget *editor, QAbstractItemModel *model, - const QModelIndex& index) const +void CSVWorld::CommandDelegate::setModelDataImp( + QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const { if (!mCommandDispatcher) return; @@ -126,41 +123,43 @@ void CSVWorld::CommandDelegate::setModelDataImp (QWidget *editor, QAbstractItemM QVariant variant; // Color columns use a custom editor, so we need to fetch selected color from it. - CSVWidget::ColorEditor *colorEditor = qobject_cast(editor); + CSVWidget::ColorEditor* colorEditor = qobject_cast(editor); if (colorEditor != nullptr) { variant = colorEditor->colorInt(); } else { - NastyTableModelHack hack (*model); - QStyledItemDelegate::setModelData (editor, &hack, index); + NastyTableModelHack hack(*model); + QStyledItemDelegate::setModelData(editor, &hack, index); variant = hack.getData(); } - if ((model->data (index)!=variant) && (model->flags(index) & Qt::ItemIsEditable)) - mCommandDispatcher->executeModify (model, index, variant); + if ((model->data(index) != variant) && (model->flags(index) & Qt::ItemIsEditable)) + mCommandDispatcher->executeModify(model, index, variant); } -CSVWorld::CommandDelegate::CommandDelegate (CSMWorld::CommandDispatcher *commandDispatcher, - CSMDoc::Document& document, QObject *parent) -: QStyledItemDelegate (parent), mEditLock (false), - mCommandDispatcher (commandDispatcher), mDocument (document) -{} +CSVWorld::CommandDelegate::CommandDelegate( + CSMWorld::CommandDispatcher* commandDispatcher, CSMDoc::Document& document, QObject* parent) + : QStyledItemDelegate(parent) + , mEditLock(false) + , mCommandDispatcher(commandDispatcher) + , mDocument(document) +{ +} -void CSVWorld::CommandDelegate::setModelData (QWidget *editor, QAbstractItemModel *model, - const QModelIndex& index) const +void CSVWorld::CommandDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const { if (!mEditLock) { - setModelDataImp (editor, model, index); + setModelDataImp(editor, model, index); } ///< \todo provide some kind of feedback to the user, indicating that editing is currently not possible. } -QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleOptionViewItem& option, - const QModelIndex& index) const +QWidget* CSVWorld::CommandDelegate::createEditor( + QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const { CSMWorld::ColumnBase::Display display = getDisplayTypeFromIndex(index); @@ -178,10 +177,10 @@ QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleO { return new CSVWidget::ColorEditor(index.data().toInt(), parent, true); } - return createEditor (parent, option, index, display); + return createEditor(parent, option, index, display); } -QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleOptionViewItem& option, +QWidget* CSVWorld::CommandDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const { QVariant variant = index.data(); @@ -204,34 +203,34 @@ QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleO } case CSMWorld::ColumnBase::Display_Integer: { - DialogueSpinBox *sb = new DialogueSpinBox(parent); + DialogueSpinBox* sb = new DialogueSpinBox(parent); sb->setRange(std::numeric_limits::min(), std::numeric_limits::max()); return sb; } case CSMWorld::ColumnBase::Display_SignedInteger8: { - DialogueSpinBox *sb = new DialogueSpinBox(parent); + DialogueSpinBox* sb = new DialogueSpinBox(parent); sb->setRange(std::numeric_limits::min(), std::numeric_limits::max()); return sb; } case CSMWorld::ColumnBase::Display_SignedInteger16: { - DialogueSpinBox *sb = new DialogueSpinBox(parent); + DialogueSpinBox* sb = new DialogueSpinBox(parent); sb->setRange(std::numeric_limits::min(), std::numeric_limits::max()); return sb; } case CSMWorld::ColumnBase::Display_UnsignedInteger8: { - DialogueSpinBox *sb = new DialogueSpinBox(parent); + DialogueSpinBox* sb = new DialogueSpinBox(parent); sb->setRange(0, std::numeric_limits::max()); return sb; } case CSMWorld::ColumnBase::Display_UnsignedInteger16: { - DialogueSpinBox *sb = new DialogueSpinBox(parent); + DialogueSpinBox* sb = new DialogueSpinBox(parent); sb->setRange(0, std::numeric_limits::max()); return sb; } @@ -242,7 +241,7 @@ QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleO case CSMWorld::ColumnBase::Display_Float: { - DialogueDoubleSpinBox *dsb = new DialogueDoubleSpinBox(parent); + DialogueDoubleSpinBox* dsb = new DialogueDoubleSpinBox(parent); dsb->setRange(-std::numeric_limits::max(), std::numeric_limits::max()); dsb->setSingleStep(0.01f); dsb->setDecimals(3); @@ -251,7 +250,7 @@ QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleO case CSMWorld::ColumnBase::Display_Double: { - DialogueDoubleSpinBox *dsb = new DialogueDoubleSpinBox(parent); + DialogueDoubleSpinBox* dsb = new DialogueDoubleSpinBox(parent); dsb->setRange(-std::numeric_limits::max(), std::numeric_limits::max()); dsb->setSingleStep(0.01f); dsb->setDecimals(6); @@ -262,8 +261,8 @@ QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleO case CSMWorld::ColumnBase::Display_LongString: case CSMWorld::ColumnBase::Display_LongString256: { - QPlainTextEdit *edit = new QPlainTextEdit(parent); - edit->setUndoRedoEnabled (false); + QPlainTextEdit* edit = new QPlainTextEdit(parent); + edit->setUndoRedoEnabled(false); return edit; } @@ -273,36 +272,36 @@ QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleO case CSMWorld::ColumnBase::Display_ScriptLines: - return new ScriptEdit (mDocument, ScriptHighlighter::Mode_Console, parent); + return new ScriptEdit(mDocument, ScriptHighlighter::Mode_Console, parent); case CSMWorld::ColumnBase::Display_String: - // For other Display types (that represent record IDs) with drop support IdCompletionDelegate is used + // For other Display types (that represent record IDs) with drop support IdCompletionDelegate is used return new CSVWidget::DropLineEdit(display, parent); case CSMWorld::ColumnBase::Display_String32: { - // For other Display types (that represent record IDs) with drop support IdCompletionDelegate is used - CSVWidget::DropLineEdit *widget = new CSVWidget::DropLineEdit(display, parent); - widget->setMaxLength (32); + // For other Display types (that represent record IDs) with drop support IdCompletionDelegate is used + CSVWidget::DropLineEdit* widget = new CSVWidget::DropLineEdit(display, parent); + widget->setMaxLength(32); return widget; } case CSMWorld::ColumnBase::Display_String64: { - // For other Display types (that represent record IDs) with drop support IdCompletionDelegate is used - CSVWidget::DropLineEdit *widget = new CSVWidget::DropLineEdit(display, parent); - widget->setMaxLength (64); + // For other Display types (that represent record IDs) with drop support IdCompletionDelegate is used + CSVWidget::DropLineEdit* widget = new CSVWidget::DropLineEdit(display, parent); + widget->setMaxLength(64); return widget; } default: - return QStyledItemDelegate::createEditor (parent, option, index); + return QStyledItemDelegate::createEditor(parent, option, index); } } -void CSVWorld::CommandDelegate::setEditLock (bool locked) +void CSVWorld::CommandDelegate::setEditLock(bool locked) { mEditLock = locked; } @@ -312,12 +311,12 @@ bool CSVWorld::CommandDelegate::isEditLocked() const return mEditLock; } -void CSVWorld::CommandDelegate::setEditorData (QWidget *editor, const QModelIndex& index) const +void CSVWorld::CommandDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const { - setEditorData (editor, index, false); + setEditorData(editor, index, false); } -void CSVWorld::CommandDelegate::setEditorData (QWidget *editor, const QModelIndex& index, bool tryDisplay) const +void CSVWorld::CommandDelegate::setEditorData(QWidget* editor, const QModelIndex& index, bool tryDisplay) const { QVariant variant = index.data(Qt::EditRole); if (tryDisplay) @@ -331,7 +330,7 @@ void CSVWorld::CommandDelegate::setEditorData (QWidget *editor, const QModelInde } } QPlainTextEdit* plainTextEdit = qobject_cast(editor); - if(plainTextEdit) //for some reason it is easier to brake the loop here + if (plainTextEdit) // for some reason it is easier to brake the loop here { if (plainTextEdit->toPlainText() == variant.toString()) { @@ -341,7 +340,7 @@ void CSVWorld::CommandDelegate::setEditorData (QWidget *editor, const QModelInde } // Color columns use a custom editor, so we need explicitly set a data for it - CSVWidget::ColorEditor *colorEditor = qobject_cast(editor); + CSVWidget::ColorEditor* colorEditor = qobject_cast(editor); if (colorEditor != nullptr) { colorEditor->setColor(variant.toInt()); @@ -361,10 +360,9 @@ void CSVWorld::CommandDelegate::setEditorData (QWidget *editor, const QModelInde if (!n.isEmpty()) { if (!variant.isValid()) - variant = QVariant(editor->property(n).userType(), (const void *)nullptr); + variant = QVariant(editor->property(n).userType(), (const void*)nullptr); editor->setProperty(n, variant); } - } -void CSVWorld::CommandDelegate::settingChanged (const CSMPrefs::Setting *setting) {} +void CSVWorld::CommandDelegate::settingChanged(const CSMPrefs::Setting* setting) {} diff --git a/apps/opencs/view/world/util.hpp b/apps/opencs/view/world/util.hpp index 2c4537dac9..50ebfc7311 100644 --- a/apps/opencs/view/world/util.hpp +++ b/apps/opencs/view/world/util.hpp @@ -6,10 +6,9 @@ #include #include - #ifndef Q_MOC_RUN -#include "../../model/world/columnbase.hpp" #include "../../model/doc/document.hpp" +#include "../../model/world/columnbase.hpp" #endif class QUndoStack; @@ -33,122 +32,108 @@ namespace CSVWorld /// Really, Qt? Really? class NastyTableModelHack : public QAbstractTableModel { - QAbstractItemModel& mModel; - QVariant mData; + QAbstractItemModel& mModel; + QVariant mData; - public: + public: + NastyTableModelHack(QAbstractItemModel& model); - NastyTableModelHack (QAbstractItemModel& model); + int rowCount(const QModelIndex& parent = QModelIndex()) const override; - int rowCount (const QModelIndex & parent = QModelIndex()) const override; + int columnCount(const QModelIndex& parent = QModelIndex()) const override; - int columnCount (const QModelIndex & parent = QModelIndex()) const override; + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; - QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const override; + bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override; - bool setData (const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; - - QVariant getData() const; + QVariant getData() const; }; class CommandDelegate; class CommandDelegateFactory { - public: - - virtual ~CommandDelegateFactory(); + public: + virtual ~CommandDelegateFactory(); - virtual CommandDelegate *makeDelegate (CSMWorld::CommandDispatcher *dispatcher, - CSMDoc::Document& document, QObject *parent) - const = 0; - ///< The ownership of the returned CommandDelegate is transferred to the caller. + virtual CommandDelegate* makeDelegate( + CSMWorld::CommandDispatcher* dispatcher, CSMDoc::Document& document, QObject* parent) const = 0; + ///< The ownership of the returned CommandDelegate is transferred to the caller. }; class CommandDelegateFactoryCollection { - static CommandDelegateFactoryCollection *sThis; - std::map mFactories; + static CommandDelegateFactoryCollection* sThis; + std::map mFactories; - private: + private: + // not implemented + CommandDelegateFactoryCollection(const CommandDelegateFactoryCollection&); + CommandDelegateFactoryCollection& operator=(const CommandDelegateFactoryCollection&); - // not implemented - CommandDelegateFactoryCollection (const CommandDelegateFactoryCollection&); - CommandDelegateFactoryCollection& operator= (const CommandDelegateFactoryCollection&); + public: + CommandDelegateFactoryCollection(); - public: + ~CommandDelegateFactoryCollection(); - CommandDelegateFactoryCollection(); + void add(CSMWorld::ColumnBase::Display display, CommandDelegateFactory* factory); + ///< The ownership of \a factory is transferred to *this. + /// + /// This function must not be called more than once per value of \a display. - ~CommandDelegateFactoryCollection(); - - void add (CSMWorld::ColumnBase::Display display, CommandDelegateFactory *factory); - ///< The ownership of \a factory is transferred to *this. - /// - /// This function must not be called more than once per value of \a display. - - CommandDelegate *makeDelegate (CSMWorld::ColumnBase::Display display, - CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, - QObject *parent) const; - ///< The ownership of the returned CommandDelegate is transferred to the caller. - /// - /// If no factory is registered for \a display, a CommandDelegate will be returned. - - static const CommandDelegateFactoryCollection& get(); + CommandDelegate* makeDelegate(CSMWorld::ColumnBase::Display display, CSMWorld::CommandDispatcher* dispatcher, + CSMDoc::Document& document, QObject* parent) const; + ///< The ownership of the returned CommandDelegate is transferred to the caller. + /// + /// If no factory is registered for \a display, a CommandDelegate will be returned. + static const CommandDelegateFactoryCollection& get(); }; ///< \brief Use commands instead of manipulating the model directly class CommandDelegate : public QStyledItemDelegate { - Q_OBJECT - - bool mEditLock; - CSMWorld::CommandDispatcher *mCommandDispatcher; - CSMDoc::Document& mDocument; - - protected: + Q_OBJECT - QUndoStack& getUndoStack() const; + bool mEditLock; + CSMWorld::CommandDispatcher* mCommandDispatcher; + CSMDoc::Document& mDocument; - CSMDoc::Document& getDocument() const; + protected: + QUndoStack& getUndoStack() const; - CSMWorld::ColumnBase::Display getDisplayTypeFromIndex(const QModelIndex &index) const; + CSMDoc::Document& getDocument() const; - virtual void setModelDataImp (QWidget *editor, QAbstractItemModel *model, - const QModelIndex& index) const; + CSMWorld::ColumnBase::Display getDisplayTypeFromIndex(const QModelIndex& index) const; - public: + virtual void setModelDataImp(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const; - /// \param commandDispatcher If CommandDelegate will be only be used on read-only - /// cells, a 0-pointer can be passed here. - CommandDelegate (CSMWorld::CommandDispatcher *commandDispatcher, CSMDoc::Document& document, QObject *parent); + public: + /// \param commandDispatcher If CommandDelegate will be only be used on read-only + /// cells, a 0-pointer can be passed here. + CommandDelegate(CSMWorld::CommandDispatcher* commandDispatcher, CSMDoc::Document& document, QObject* parent); - void setModelData (QWidget *editor, QAbstractItemModel *model, - const QModelIndex& index) const override; + void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const override; - QWidget *createEditor (QWidget *parent, - const QStyleOptionViewItem& option, - const QModelIndex& index) const override; + QWidget* createEditor( + QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override; - virtual QWidget *createEditor (QWidget *parent, - const QStyleOptionViewItem& option, - const QModelIndex& index, - CSMWorld::ColumnBase::Display display) const; + virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index, + CSMWorld::ColumnBase::Display display) const; - void setEditLock (bool locked); + void setEditLock(bool locked); - bool isEditLocked() const; + bool isEditLocked() const; - ///< \return Does column require update? + ///< \return Does column require update? - void setEditorData (QWidget *editor, const QModelIndex& index) const override; + void setEditorData(QWidget* editor, const QModelIndex& index) const override; - virtual void setEditorData (QWidget *editor, const QModelIndex& index, bool tryDisplay) const; + virtual void setEditorData(QWidget* editor, const QModelIndex& index, bool tryDisplay) const; - /// \attention This is not a slot. For ordering reasons this function needs to be - /// called manually from the parent object's settingChanged function. - virtual void settingChanged (const CSMPrefs::Setting *setting); + /// \attention This is not a slot. For ordering reasons this function needs to be + /// called manually from the parent object's settingChanged function. + virtual void settingChanged(const CSMPrefs::Setting* setting); }; } diff --git a/apps/opencs/view/world/vartypedelegate.cpp b/apps/opencs/view/world/vartypedelegate.cpp index 80c96afce4..b5b1be2543 100644 --- a/apps/opencs/view/world/vartypedelegate.cpp +++ b/apps/opencs/view/world/vartypedelegate.cpp @@ -1,15 +1,14 @@ #include "vartypedelegate.hpp" -#include "../../model/world/commands.hpp" #include "../../model/world/columns.hpp" #include "../../model/world/commandmacro.hpp" +#include "../../model/world/commands.hpp" -void CSVWorld::VarTypeDelegate::addCommands (QAbstractItemModel *model, const QModelIndex& index, int type) - const +void CSVWorld::VarTypeDelegate::addCommands(QAbstractItemModel* model, const QModelIndex& index, int type) const { - QModelIndex next = model->index (index.row(), index.column()+1); + QModelIndex next = model->index(index.row(), index.column() + 1); - QVariant old = model->data (next); + QVariant old = model->data(next); QVariant value; @@ -32,50 +31,51 @@ void CSVWorld::VarTypeDelegate::addCommands (QAbstractItemModel *model, const QM value = old.toString(); break; - default: break; // ignore the rest + default: + break; // ignore the rest } - CSMWorld::CommandMacro macro (getUndoStack(), "Modify " + model->headerData (index.column(), Qt::Horizontal, Qt::DisplayRole).toString()); + CSMWorld::CommandMacro macro( + getUndoStack(), "Modify " + model->headerData(index.column(), Qt::Horizontal, Qt::DisplayRole).toString()); - macro.push (new CSMWorld::ModifyCommand (*model, index, type)); - macro.push (new CSMWorld::ModifyCommand (*model, next, value)); + macro.push(new CSMWorld::ModifyCommand(*model, index, type)); + macro.push(new CSMWorld::ModifyCommand(*model, next, value)); } -CSVWorld::VarTypeDelegate::VarTypeDelegate (const std::vector >& values, - CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) -: EnumDelegate (values, dispatcher, document, parent) -{} - +CSVWorld::VarTypeDelegate::VarTypeDelegate(const std::vector>& values, + CSMWorld::CommandDispatcher* dispatcher, CSMDoc::Document& document, QObject* parent) + : EnumDelegate(values, dispatcher, document, parent) +{ +} -CSVWorld::VarTypeDelegateFactory::VarTypeDelegateFactory (ESM::VarType type0, - ESM::VarType type1, ESM::VarType type2, ESM::VarType type3) +CSVWorld::VarTypeDelegateFactory::VarTypeDelegateFactory( + ESM::VarType type0, ESM::VarType type1, ESM::VarType type2, ESM::VarType type3) { - if (type0!=ESM::VT_Unknown) - add (type0); + if (type0 != ESM::VT_Unknown) + add(type0); - if (type1!=ESM::VT_Unknown) - add (type1); + if (type1 != ESM::VT_Unknown) + add(type1); - if (type2!=ESM::VT_Unknown) - add (type2); + if (type2 != ESM::VT_Unknown) + add(type2); - if (type3!=ESM::VT_Unknown) - add (type3); + if (type3 != ESM::VT_Unknown) + add(type3); } -CSVWorld::CommandDelegate *CSVWorld::VarTypeDelegateFactory::makeDelegate ( - CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) const +CSVWorld::CommandDelegate* CSVWorld::VarTypeDelegateFactory::makeDelegate( + CSMWorld::CommandDispatcher* dispatcher, CSMDoc::Document& document, QObject* parent) const { - return new VarTypeDelegate (mValues, dispatcher, document, parent); + return new VarTypeDelegate(mValues, dispatcher, document, parent); } -void CSVWorld::VarTypeDelegateFactory::add (ESM::VarType type) +void CSVWorld::VarTypeDelegateFactory::add(ESM::VarType type) { - std::vector> enums = - CSMWorld::Columns::getEnums (CSMWorld::Columns::ColumnId_ValueType); + std::vector> enums = CSMWorld::Columns::getEnums(CSMWorld::Columns::ColumnId_ValueType); if (static_cast(type) >= enums.size()) - throw std::logic_error ("Unsupported variable type"); + throw std::logic_error("Unsupported variable type"); - mValues.emplace_back(type, QString::fromUtf8 (enums[type].second.c_str())); + mValues.emplace_back(type, QString::fromUtf8(enums[type].second.c_str())); } diff --git a/apps/opencs/view/world/vartypedelegate.hpp b/apps/opencs/view/world/vartypedelegate.hpp index 5b0daec904..d841c0435e 100644 --- a/apps/opencs/view/world/vartypedelegate.hpp +++ b/apps/opencs/view/world/vartypedelegate.hpp @@ -9,32 +9,27 @@ namespace CSVWorld { class VarTypeDelegate : public EnumDelegate { - private: + private: + void addCommands(QAbstractItemModel* model, const QModelIndex& index, int type) const override; - void addCommands (QAbstractItemModel *model, - const QModelIndex& index, int type) const override; - - public: - - VarTypeDelegate (const std::vector >& values, - CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent); + public: + VarTypeDelegate(const std::vector>& values, CSMWorld::CommandDispatcher* dispatcher, + CSMDoc::Document& document, QObject* parent); }; class VarTypeDelegateFactory : public CommandDelegateFactory { - std::vector > mValues; - - public: + std::vector> mValues; - VarTypeDelegateFactory (ESM::VarType type0 = ESM::VT_Unknown, - ESM::VarType type1 = ESM::VT_Unknown, ESM::VarType type2 = ESM::VT_Unknown, - ESM::VarType type3 = ESM::VT_Unknown); + public: + VarTypeDelegateFactory(ESM::VarType type0 = ESM::VT_Unknown, ESM::VarType type1 = ESM::VT_Unknown, + ESM::VarType type2 = ESM::VT_Unknown, ESM::VarType type3 = ESM::VT_Unknown); - CommandDelegate *makeDelegate (CSMWorld::CommandDispatcher *dispatcher, - CSMDoc::Document& document, QObject *parent) const override; - ///< The ownership of the returned CommandDelegate is transferred to the caller. + CommandDelegate* makeDelegate( + CSMWorld::CommandDispatcher* dispatcher, CSMDoc::Document& document, QObject* parent) const override; + ///< The ownership of the returned CommandDelegate is transferred to the caller. - void add (ESM::VarType type); + void add(ESM::VarType type); }; } diff --git a/apps/openmw/android_main.cpp b/apps/openmw/android_main.cpp index 95365915df..ade009ae07 100644 --- a/apps/openmw/android_main.cpp +++ b/apps/openmw/android_main.cpp @@ -3,9 +3,9 @@ int stderr = 0; // Hack: fix linker error #endif #include "SDL_main.h" +#include #include #include -#include /******************************************************************************* Functions called by JNI @@ -16,43 +16,50 @@ int stderr = 0; // Hack: fix linker error extern void SDL_Android_Init(JNIEnv* env, jclass cls); extern int argcData; -extern const char **argvData; +extern const char** argvData; void releaseArgv(); - -extern "C" int Java_org_libsdl_app_SDLActivity_getMouseX(JNIEnv *env, jclass cls, jobject obj) { +extern "C" int Java_org_libsdl_app_SDLActivity_getMouseX(JNIEnv* env, jclass cls, jobject obj) +{ int ret = 0; SDL_GetMouseState(&ret, nullptr); return ret; } - -extern "C" int Java_org_libsdl_app_SDLActivity_getMouseY(JNIEnv *env, jclass cls, jobject obj) { +extern "C" int Java_org_libsdl_app_SDLActivity_getMouseY(JNIEnv* env, jclass cls, jobject obj) +{ int ret = 0; SDL_GetMouseState(nullptr, &ret); return ret; } -extern "C" int Java_org_libsdl_app_SDLActivity_isMouseShown(JNIEnv *env, jclass cls, jobject obj) { +extern "C" int Java_org_libsdl_app_SDLActivity_isMouseShown(JNIEnv* env, jclass cls, jobject obj) +{ return SDL_ShowCursor(SDL_QUERY); } -extern SDL_Window *Android_Window; -extern "C" int SDL_SendMouseMotion(SDL_Window * window, int mouseID, int relative, int x, int y); -extern "C" void Java_org_libsdl_app_SDLActivity_sendRelativeMouseMotion(JNIEnv *env, jclass cls, int x, int y) { +extern SDL_Window* Android_Window; +extern "C" int SDL_SendMouseMotion(SDL_Window* window, int mouseID, int relative, int x, int y); +extern "C" void Java_org_libsdl_app_SDLActivity_sendRelativeMouseMotion(JNIEnv* env, jclass cls, int x, int y) +{ SDL_SendMouseMotion(Android_Window, 0, 1, x, y); } -extern "C" int SDL_SendMouseButton(SDL_Window * window, int mouseID, Uint8 state, Uint8 button); -extern "C" void Java_org_libsdl_app_SDLActivity_sendMouseButton(JNIEnv *env, jclass cls, int state, int button) { +extern "C" int SDL_SendMouseButton(SDL_Window* window, int mouseID, Uint8 state, Uint8 button); +extern "C" void Java_org_libsdl_app_SDLActivity_sendMouseButton(JNIEnv* env, jclass cls, int state, int button) +{ SDL_SendMouseButton(Android_Window, 0, state, button); } -extern "C" int Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jclass cls, jobject obj) { +extern "C" int Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jclass cls, jobject obj) +{ setenv("OPENMW_DECOMPRESS_TEXTURES", "1", 1); // On Android, we use a virtual controller with guid="Virtual" - SDL_GameControllerAddMapping("5669727475616c000000000000000000,Virtual,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4"); + SDL_GameControllerAddMapping( + "5669727475616c000000000000000000,Virtual,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1," + "guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14," + "righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4"); return 0; } diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 724c2e48bb..4641ed8520 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -3,8 +3,8 @@ #include #include -#include #include +#include #include @@ -16,8 +16,8 @@ #include #include -#include #include +#include #include #include @@ -25,8 +25,8 @@ #include -#include #include +#include #include @@ -36,11 +36,11 @@ #include -#include -#include #include -#include +#include +#include #include +#include #include @@ -50,8 +50,8 @@ #include "mwlua/luamanagerimp.hpp" -#include "mwscript/scriptmanagerimp.hpp" #include "mwscript/interpretercontext.hpp" +#include "mwscript/scriptmanagerimp.hpp" #include "mwsound/soundmanagerimp.hpp" @@ -86,11 +86,12 @@ namespace const std::string mTaken; UserStats(const std::string& label, const std::string& prefix) - : mLabel(label), - mBegin(prefix + "_time_begin"), - mEnd(prefix + "_time_end"), - mTaken(prefix + "_time_taken") - {} + : mLabel(label) + , mBegin(prefix + "_time_begin") + , mEnd(prefix + "_time_end") + , mTaken(prefix + "_time_taken") + { + } }; enum class UserStatsType : std::size_t @@ -116,39 +117,38 @@ namespace }; template <> - const UserStats UserStatsValue::sValue {"Input", "input"}; + const UserStats UserStatsValue::sValue{ "Input", "input" }; template <> - const UserStats UserStatsValue::sValue {"Sound", "sound"}; + const UserStats UserStatsValue::sValue{ "Sound", "sound" }; template <> - const UserStats UserStatsValue::sValue {"State", "state"}; + const UserStats UserStatsValue::sValue{ "State", "state" }; template <> - const UserStats UserStatsValue::sValue {"Script", "script"}; + const UserStats UserStatsValue::sValue{ "Script", "script" }; template <> - const UserStats UserStatsValue::sValue {"Mech", "mechanics"}; + const UserStats UserStatsValue::sValue{ "Mech", "mechanics" }; template <> - const UserStats UserStatsValue::sValue {"Phys", "physics"}; + const UserStats UserStatsValue::sValue{ "Phys", "physics" }; template <> - const UserStats UserStatsValue::sValue {" -Async", "physicsworker"}; + const UserStats UserStatsValue::sValue{ " -Async", "physicsworker" }; template <> - const UserStats UserStatsValue::sValue {"World", "world"}; + const UserStats UserStatsValue::sValue{ "World", "world" }; template <> - const UserStats UserStatsValue::sValue {"Gui", "gui"}; + const UserStats UserStatsValue::sValue{ "Gui", "gui" }; template <> - const UserStats UserStatsValue::sValue {"Lua", "lua"}; + const UserStats UserStatsValue::sValue{ "Lua", "lua" }; template <> const UserStats UserStatsValue::sValue{ " -Sync", "luasyncupdate" }; - template struct ForEachUserStatsValue { @@ -165,7 +165,9 @@ namespace struct ForEachUserStatsValue { template - static void apply(F&&) {} + static void apply(F&&) + { + } }; template @@ -177,37 +179,37 @@ namespace template class ScopedProfile { - public: - ScopedProfile(osg::Timer_t frameStart, unsigned int frameNumber, const osg::Timer& timer, osg::Stats& stats) - : mScopeStart(timer.tick()), - mFrameStart(frameStart), - mFrameNumber(frameNumber), - mTimer(timer), - mStats(stats) - { - } + public: + ScopedProfile(osg::Timer_t frameStart, unsigned int frameNumber, const osg::Timer& timer, osg::Stats& stats) + : mScopeStart(timer.tick()) + , mFrameStart(frameStart) + , mFrameNumber(frameNumber) + , mTimer(timer) + , mStats(stats) + { + } - ScopedProfile(const ScopedProfile&) = delete; - ScopedProfile& operator=(const ScopedProfile&) = delete; + ScopedProfile(const ScopedProfile&) = delete; + ScopedProfile& operator=(const ScopedProfile&) = delete; - ~ScopedProfile() - { - if (!mStats.collectStats("engine")) - return; - const osg::Timer_t end = mTimer.tick(); - const UserStats& stats = UserStatsValue::sValue; - - mStats.setAttribute(mFrameNumber, stats.mBegin, mTimer.delta_s(mFrameStart, mScopeStart)); - mStats.setAttribute(mFrameNumber, stats.mTaken, mTimer.delta_s(mScopeStart, end)); - mStats.setAttribute(mFrameNumber, stats.mEnd, mTimer.delta_s(mFrameStart, end)); - } + ~ScopedProfile() + { + if (!mStats.collectStats("engine")) + return; + const osg::Timer_t end = mTimer.tick(); + const UserStats& stats = UserStatsValue::sValue; + + mStats.setAttribute(mFrameNumber, stats.mBegin, mTimer.delta_s(mFrameStart, mScopeStart)); + mStats.setAttribute(mFrameNumber, stats.mTaken, mTimer.delta_s(mScopeStart, end)); + mStats.setAttribute(mFrameNumber, stats.mEnd, mTimer.delta_s(mFrameStart, end)); + } - private: - const osg::Timer_t mScopeStart; - const osg::Timer_t mFrameStart; - const unsigned int mFrameNumber; - const osg::Timer& mTimer; - osg::Stats& mStats; + private: + const osg::Timer_t mScopeStart; + const osg::Timer_t mFrameStart; + const unsigned int mFrameNumber; + const osg::Timer& mTimer; + osg::Stats& mStats; }; void initStatsHandler(Resource::Profiler& profiler) @@ -219,10 +221,9 @@ namespace const bool averageInInverseSpace = false; const float maxValue = 10000; - forEachUserStatsValue([&] (const UserStats& v) - { - profiler.addUserStatsLine(v.mLabel, textColor, barColor, v.mTaken, multiplier, - average, averageInInverseSpace, v.mBegin, v.mEnd, maxValue); + forEachUserStatsValue([&](const UserStats& v) { + profiler.addUserStatsLine(v.mLabel, textColor, barColor, v.mTaken, multiplier, average, + averageInInverseSpace, v.mBegin, v.mEnd, maxValue); }); // the forEachUserStatsValue loop is "run" at compile time, hence the settings manager is not available. // Unconditionnally add the async physics stats, and then remove it at runtime if necessary @@ -234,7 +235,8 @@ namespace { void operator()(std::string message) const { - MWBase::Environment::get().getWindowManager()->scheduleMessageBox(std::move(message), MWGui::ShowInDialogueMode_Never); + MWBase::Environment::get().getWindowManager()->scheduleMessageBox( + std::move(message), MWGui::ShowInDialogueMode_Never); } }; @@ -246,8 +248,10 @@ namespace class IdentifyOpenGLOperation : public osg::GraphicsOperation { public: - IdentifyOpenGLOperation() : GraphicsOperation("IdentifyOpenGLOperation", false) - {} + IdentifyOpenGLOperation() + : GraphicsOperation("IdentifyOpenGLOperation", false) + { + } void operator()(osg::GraphicsContext* graphicsContext) override { @@ -271,8 +275,10 @@ namespace class InitializeStereoOperation final : public osg::GraphicsOperation { public: - InitializeStereoOperation() : GraphicsOperation("InitializeStereoOperation", false) - {} + InitializeStereoOperation() + : GraphicsOperation("InitializeStereoOperation", false) + { + } void operator()(osg::GraphicsContext* graphicsContext) override { @@ -289,9 +295,8 @@ void OMW::Engine::executeLocalScripts() std::pair script; while (localScripts.getNext(script)) { - MWScript::InterpreterContext interpreterContext ( - &script.second.getRefData().getLocals(), script.second); - mScriptManager->run (script.first, interpreterContext); + MWScript::InterpreterContext interpreterContext(&script.second.getRefData().getLocals(), script.second); + mScriptManager->run(script.first, interpreterContext); } } @@ -313,8 +318,9 @@ bool OMW::Engine::frame(float frametime) } // When the window is minimized, pause the game. Currently this *has* to be here to work around a MyGUI bug. - // If we are not currently rendering, then RenderItems will not be reused resulting in a memory leak upon changing widget textures (fixed in MyGUI 3.3.2), - // and destroyed widgets will not be deleted (not fixed yet, https://github.com/MyGUI/mygui/issues/21) + // If we are not currently rendering, then RenderItems will not be reused resulting in a memory leak upon + // changing widget textures (fixed in MyGUI 3.3.2), and destroyed widgets will not be deleted (not fixed yet, + // https://github.com/MyGUI/mygui/issues/21) { ScopedProfile profile(frameStart, frameNumber, *timer, *stats); @@ -333,7 +339,7 @@ bool OMW::Engine::frame(float frametime) // Main menu opened? Then scripts are also paused. bool paused = mWindowManager->containsMode(MWGui::GM_MainMenu); - + { ScopedProfile profile(frameStart, frameNumber, *timer, *stats); // Should be called after input manager update and before any change to the game world. @@ -344,7 +350,7 @@ bool OMW::Engine::frame(float frametime) // update game state { ScopedProfile profile(frameStart, frameNumber, *timer, *stats); - mStateManager->update (frametime); + mStateManager->update(frametime); } bool guiActive = mWindowManager->isGuiMode(); @@ -389,7 +395,7 @@ bool OMW::Engine::frame(float frametime) if (mStateManager->getState() == MWBase::StateManager::State_Running) { MWWorld::Ptr player = mWorld->getPlayerPtr(); - if(!guiActive && player.getClass().getCreatureStats(player).isDead()) + if (!guiActive && player.getClass().getCreatureStats(player).isDead()) mStateManager->endGame(); } } @@ -447,34 +453,35 @@ bool OMW::Engine::frame(float frametime) } OMW::Engine::Engine(Files::ConfigurationManager& configurationManager) - : mWindow(nullptr) - , mEncoding(ToUTF8::WINDOWS_1252) - , mScreenCaptureOperation(nullptr) - , mSelectDepthFormatOperation(new SceneUtil::SelectDepthFormatOperation()) - , mSelectColorFormatOperation(new SceneUtil::Color::SelectColorFormatOperation()) - , mStereoManager(nullptr) - , mSkipMenu (false) - , mUseSound (true) - , mCompileAll (false) - , mCompileAllDialogue (false) - , mWarningsMode (1) - , mScriptConsoleMode (false) - , mActivationDistanceOverride(-1) - , mGrab(true) - , mRandomSeed(0) - , mFSStrict (false) - , mScriptBlacklistUse (true) - , mNewGame (false) - , mCfgMgr(configurationManager) - , mGlMaxTextureImageUnits(0) + : mWindow(nullptr) + , mEncoding(ToUTF8::WINDOWS_1252) + , mScreenCaptureOperation(nullptr) + , mSelectDepthFormatOperation(new SceneUtil::SelectDepthFormatOperation()) + , mSelectColorFormatOperation(new SceneUtil::Color::SelectColorFormatOperation()) + , mStereoManager(nullptr) + , mSkipMenu(false) + , mUseSound(true) + , mCompileAll(false) + , mCompileAllDialogue(false) + , mWarningsMode(1) + , mScriptConsoleMode(false) + , mActivationDistanceOverride(-1) + , mGrab(true) + , mRandomSeed(0) + , mFSStrict(false) + , mScriptBlacklistUse(true) + , mNewGame(false) + , mCfgMgr(configurationManager) + , mGlMaxTextureImageUnits(0) { SDL_SetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, "0"); // We use only gamepads - Uint32 flags = SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE|SDL_INIT_GAMECONTROLLER|SDL_INIT_JOYSTICK|SDL_INIT_SENSOR; - if(SDL_WasInit(flags) == 0) + Uint32 flags + = SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE | SDL_INIT_GAMECONTROLLER | SDL_INIT_JOYSTICK | SDL_INIT_SENSOR; + if (SDL_WasInit(flags) == 0) { SDL_SetMainReady(); - if(SDL_Init(flags) != 0) + if (SDL_Init(flags) != 0) { throw std::runtime_error("Could not initialize SDL! " + std::string(SDL_GetError())); } @@ -525,26 +532,27 @@ void OMW::Engine::enableFSStrict(bool fsStrict) // Set data dir -void OMW::Engine::setDataDirs (const Files::PathContainer& dataDirs) +void OMW::Engine::setDataDirs(const Files::PathContainer& dataDirs) { mDataDirs = dataDirs; mDataDirs.insert(mDataDirs.begin(), mResDir / "vfs"); - mFileCollections = Files::Collections (mDataDirs, !mFSStrict); + mFileCollections = Files::Collections(mDataDirs, !mFSStrict); } // Add BSA archive -void OMW::Engine::addArchive (const std::string& archive) { +void OMW::Engine::addArchive(const std::string& archive) +{ mArchives.push_back(archive); } // Set resource dir -void OMW::Engine::setResourceDir (const std::filesystem::path& parResDir) +void OMW::Engine::setResourceDir(const std::filesystem::path& parResDir) { mResDir = parResDir; } // Set start cell name -void OMW::Engine::setCell (const std::string& cellName) +void OMW::Engine::setCell(const std::string& cellName) { mCellName = cellName; } @@ -559,7 +567,7 @@ void OMW::Engine::addGroundcoverFile(const std::string& file) mGroundcoverFiles.emplace_back(file); } -void OMW::Engine::setSkipMenu (bool skipMenu, bool newGame) +void OMW::Engine::setSkipMenu(bool skipMenu, bool newGame) { mSkipMenu = skipMenu; mNewGame = newGame; @@ -570,22 +578,22 @@ void OMW::Engine::createWindow() int screen = Settings::Manager::getInt("screen", "Video"); int width = Settings::Manager::getInt("resolution x", "Video"); int height = Settings::Manager::getInt("resolution y", "Video"); - Settings::WindowMode windowMode = static_cast(Settings::Manager::getInt("window mode", "Video")); + Settings::WindowMode windowMode + = static_cast(Settings::Manager::getInt("window mode", "Video")); bool windowBorder = Settings::Manager::getBool("window border", "Video"); bool vsync = Settings::Manager::getBool("vsync", "Video"); unsigned int antialiasing = std::max(0, Settings::Manager::getInt("antialiasing", "Video")); - int pos_x = SDL_WINDOWPOS_CENTERED_DISPLAY(screen), - pos_y = SDL_WINDOWPOS_CENTERED_DISPLAY(screen); + int pos_x = SDL_WINDOWPOS_CENTERED_DISPLAY(screen), pos_y = SDL_WINDOWPOS_CENTERED_DISPLAY(screen); - if(windowMode == Settings::WindowMode::Fullscreen || windowMode == Settings::WindowMode::WindowedFullscreen) + if (windowMode == Settings::WindowMode::Fullscreen || windowMode == Settings::WindowMode::WindowedFullscreen) { pos_x = SDL_WINDOWPOS_UNDEFINED_DISPLAY(screen); pos_y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(screen); } - Uint32 flags = SDL_WINDOW_OPENGL|SDL_WINDOW_SHOWN|SDL_WINDOW_RESIZABLE|SDL_WINDOW_ALLOW_HIGHDPI; - if(windowMode == Settings::WindowMode::Fullscreen) + Uint32 flags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI; + if (windowMode == Settings::WindowMode::Fullscreen) flags |= SDL_WINDOW_FULLSCREEN; else if (windowMode == Settings::WindowMode::WindowedFullscreen) flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; @@ -598,7 +606,7 @@ void OMW::Engine::createWindow() flags |= SDL_WINDOW_BORDERLESS; SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, - Settings::Manager::getBool("minimize on focus loss", "Video") ? "1" : "0"); + Settings::Manager::getBool("minimize on focus loss", "Video") ? "1" : "0"); checkSDLError(SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8)); checkSDLError(SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8)); @@ -625,7 +633,8 @@ void OMW::Engine::createWindow() // Try with a lower AA if (antialiasing > 0) { - Log(Debug::Warning) << "Warning: " << antialiasing << "x antialiasing not supported, trying " << antialiasing/2; + Log(Debug::Warning) << "Warning: " << antialiasing << "x antialiasing not supported, trying " + << antialiasing / 2; antialiasing /= 2; Settings::Manager::setInt("antialiasing", "Video", antialiasing); checkSDLError(SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, antialiasing)); @@ -642,11 +651,12 @@ void OMW::Engine::createWindow() // Since we use physical resolution internally, we have to create the window with scaled resolution, // but we can't get the scale before the window exists, so instead we have to resize aftewards. - int w,h; + int w, h; SDL_GetWindowSize(mWindow, &w, &h); - int dw,dh; + int dw, dh; SDL_GL_GetDrawableSize(mWindow, &dw, &dh); - if (dw != w || dh != h) { + if (dw != w || dh != h) + { SDL_SetWindowSize(mWindow, width / (dw / w), height / (dh / h)); } @@ -656,17 +666,19 @@ void OMW::Engine::createWindow() SDL_GetWindowPosition(mWindow, &traits->x, &traits->y); SDL_GL_GetDrawableSize(mWindow, &traits->width, &traits->height); traits->windowName = SDL_GetWindowTitle(mWindow); - traits->windowDecoration = !(SDL_GetWindowFlags(mWindow)&SDL_WINDOW_BORDERLESS); + traits->windowDecoration = !(SDL_GetWindowFlags(mWindow) & SDL_WINDOW_BORDERLESS); traits->screenNum = SDL_GetWindowDisplayIndex(mWindow); traits->vsync = vsync; traits->inheritedWindowData = new SDLUtil::GraphicsWindowSDL2::WindowData(mWindow); graphicsWindow = new SDLUtil::GraphicsWindowSDL2(traits); - if (!graphicsWindow->valid()) throw std::runtime_error("Failed to create GraphicsContext"); + if (!graphicsWindow->valid()) + throw std::runtime_error("Failed to create GraphicsContext"); if (traits->samples < antialiasing) { - Log(Debug::Warning) << "Warning: Framebuffer MSAA level is only " << traits->samples << "x instead of " << antialiasing << "x. Trying " << antialiasing / 2 << "x instead."; + Log(Debug::Warning) << "Warning: Framebuffer MSAA level is only " << traits->samples << "x instead of " + << antialiasing << "x. Trying " << antialiasing / 2 << "x instead."; graphicsWindow->closeImplementation(); SDL_DestroyWindow(mWindow); mWindow = nullptr; @@ -712,7 +724,8 @@ void OMW::Engine::createWindow() mViewer->realize(); mGlMaxTextureImageUnits = identifyOp->getMaxTextureImageUnits(); - mViewer->getEventQueue()->getCurrentEventState()->setWindowRectangle(0, 0, graphicsWindow->getTraits()->width, graphicsWindow->getTraits()->height); + mViewer->getEventQueue()->getCurrentEventState()->setWindowRectangle( + 0, 0, graphicsWindow->getTraits()->width, graphicsWindow->getTraits()->height); } void OMW::Engine::setWindowIcon() @@ -730,7 +743,8 @@ void OMW::Engine::setWindowIcon() } osgDB::ReaderWriter::ReadResult result = reader->readImage(windowIconStream); if (!result.success()) - Log(Debug::Error) << "Error: Failed to read " << windowIcon << ": " << result.message() << " code " << result.status(); + Log(Debug::Error) << "Error: Failed to read " << windowIcon << ": " << result.message() << " code " + << result.status(); else { osg::ref_ptr image = result.getImage(); @@ -757,13 +771,11 @@ void OMW::Engine::prepareEngine() mResourceSystem = std::make_unique(mVFS.get()); mResourceSystem->getSceneManager()->getShaderManager().setMaxTextureUnits(mGlMaxTextureImageUnits); - mResourceSystem->getSceneManager()->setUnRefImageDataAfterApply(false); // keep to Off for now to allow better state sharing - mResourceSystem->getSceneManager()->setFilterSettings( - Settings::Manager::getString("texture mag filter", "General"), + mResourceSystem->getSceneManager()->setUnRefImageDataAfterApply( + false); // keep to Off for now to allow better state sharing + mResourceSystem->getSceneManager()->setFilterSettings(Settings::Manager::getString("texture mag filter", "General"), Settings::Manager::getString("texture min filter", "General"), - Settings::Manager::getString("texture mipmap", "General"), - Settings::Manager::getInt("anisotropy", "General") - ); + Settings::Manager::getString("texture mipmap", "General"), Settings::Manager::getInt("anisotropy", "General")); mEnvironment.setResourceSystem(*mResourceSystem); int numThreads = Settings::Manager::getInt("preload num threads", "Cells"); @@ -772,16 +784,12 @@ void OMW::Engine::prepareEngine() mWorkQueue = new SceneUtil::WorkQueue(numThreads); mUnrefQueue = std::make_unique(); - mScreenCaptureOperation = new SceneUtil::AsyncScreenCaptureOperation( - mWorkQueue, - new SceneUtil::WriteScreenshotToFileOperation( - mCfgMgr.getScreenshotPath(), + mScreenCaptureOperation = new SceneUtil::AsyncScreenCaptureOperation(mWorkQueue, + new SceneUtil::WriteScreenshotToFileOperation(mCfgMgr.getScreenshotPath(), Settings::Manager::getString("screenshot format", "General"), Settings::Manager::getBool("notify on saved screenshot", "General") - ? std::function(ScheduleNonDialogMessageBox {}) - : std::function(IgnoreString {}) - ) - ); + ? std::function(ScheduleNonDialogMessageBox{}) + : std::function(IgnoreString{}))); mScreenCaptureHandler = new osgViewer::ScreenCaptureHandler(mScreenCaptureOperation); @@ -795,10 +803,11 @@ void OMW::Engine::prepareEngine() const auto keybinderUser = mCfgMgr.getUserConfigPath() / "input_v3.xml"; bool keybinderUserExists = std::filesystem::exists(keybinderUser); - if(!keybinderUserExists) + if (!keybinderUserExists) { const auto input2 = (mCfgMgr.getUserConfigPath() / "input_v2.xml"); - if(std::filesystem::exists(input2)) { + if (std::filesystem::exists(input2)) + { keybinderUserExists = std::filesystem::copy_file(input2, keybinderUser); Log(Debug::Info) << "Loading keybindings file: " << keybinderUser; } @@ -819,7 +828,7 @@ void OMW::Engine::prepareEngine() gameControllerdb = localdefault; else if (std::filesystem::exists(globaldefault)) gameControllerdb = globaldefault; - //else if it doesn't exist, pass in an empty string + // else if it doesn't exist, pass in an empty string // gui needs our shaders path before everything else mResourceSystem->getSceneManager()->setShaderPath(mResDir / "shaders"); @@ -839,10 +848,9 @@ void OMW::Engine::prepareEngine() mStereoManager->disableStereoForNode(guiRoot); rootNode->addChild(guiRoot); - mWindowManager = std::make_unique(mWindow, mViewer, guiRoot, mResourceSystem.get(), mWorkQueue.get(), - mCfgMgr.getLogPath(), - mScriptConsoleMode, mTranslationDataStorage, mEncoding, - Version::getOpenmwVersionDescription(mResDir), shadersSupported); + mWindowManager = std::make_unique(mWindow, mViewer, guiRoot, mResourceSystem.get(), + mWorkQueue.get(), mCfgMgr.getLogPath(), mScriptConsoleMode, mTranslationDataStorage, mEncoding, + Version::getOpenmwVersionDescription(mResDir), shadersSupported); mEnvironment.setWindowManager(*mWindowManager); mInputManager = std::make_unique(mWindow, mViewer, mScreenCaptureHandler, @@ -872,16 +880,16 @@ void OMW::Engine::prepareEngine() mLuaManager->initL10n(); mWindowManager->initUI(); - //Load translation data + // Load translation data mTranslationDataStorage.setEncoder(mEncoder.get()); - for (auto & mContentFile : mContentFiles) - mTranslationDataStorage.loadTranslationData(mFileCollections, mContentFile); + for (auto& mContentFile : mContentFiles) + mTranslationDataStorage.loadTranslationData(mFileCollections, mContentFile); - Compiler::registerExtensions (mExtensions); + Compiler::registerExtensions(mExtensions); // Create script system mScriptContext = std::make_unique(MWScript::CompilerContext::Type_Full); - mScriptContext->setExtensions (&mExtensions); + mScriptContext->setExtensions(&mExtensions); mScriptManager = std::make_unique(mWorld->getStore(), *mScriptContext, mWarningsMode, mScriptBlacklistUse ? mScriptBlacklist : std::vector()); @@ -903,19 +911,16 @@ void OMW::Engine::prepareEngine() { std::pair result = mScriptManager->compileAll(); if (result.first) - Log(Debug::Info) - << "compiled " << result.second << " of " << result.first << " scripts (" - << 100*static_cast (result.second)/result.first - << "%)"; + Log(Debug::Info) << "compiled " << result.second << " of " << result.first << " scripts (" + << 100 * static_cast(result.second) / result.first << "%)"; } if (mCompileAllDialogue) { std::pair result = MWDialogue::ScriptTest::compileAll(&mExtensions, mWarningsMode); if (result.first) - Log(Debug::Info) - << "compiled " << result.second << " of " << result.first << " dialogue script/actor combinations a(" - << 100*static_cast (result.second)/result.first - << "%)"; + Log(Debug::Info) << "compiled " << result.second << " of " << result.first + << " dialogue script/actor combinations a(" + << 100 * static_cast(result.second) / result.first << "%)"; } mLuaManager->init(); @@ -925,17 +930,19 @@ void OMW::Engine::prepareEngine() class OMW::Engine::LuaWorker { public: - explicit LuaWorker(Engine* engine) : mEngine(engine) + explicit LuaWorker(Engine* engine) + : mEngine(engine) { if (Settings::Manager::getInt("lua num threads", "Lua") > 0) - mThread = std::thread([this]{ threadBody(); }); + mThread = std::thread([this] { threadBody(); }); }; ~LuaWorker() { if (mThread && mThread->joinable()) { - Log(Debug::Error) << "Unexpected destruction of LuaWorker; likely there is an unhandled exception in the main thread."; + Log(Debug::Error) + << "Unexpected destruction of LuaWorker; likely there is an unhandled exception in the main thread."; join(); } } @@ -956,7 +963,7 @@ public: if (mThread) { std::unique_lock lk(mMutex); - mCV.wait(lk, [&]{ return !mUpdateRequest; }); + mCV.wait(lk, [&] { return !mUpdateRequest; }); } else update(); @@ -981,7 +988,8 @@ private: const auto& viewer = mEngine->mViewer; const osg::Timer_t frameStart = viewer->getStartTick(); const unsigned int frameNumber = viewer->getFrameStamp()->getFrameNumber(); - ScopedProfile profile(frameStart, frameNumber, *osg::Timer::instance(), *viewer->getViewerStats()); + ScopedProfile profile( + frameStart, frameNumber, *osg::Timer::instance(), *viewer->getViewerStats()); mEngine->mLuaManager->update(); } @@ -991,7 +999,7 @@ private: while (true) { std::unique_lock lk(mMutex); - mCV.wait(lk, [&]{ return mUpdateRequest || mJoinRequest; }); + mCV.wait(lk, [&] { return mUpdateRequest || mJoinRequest; }); if (mJoinRequest) break; @@ -1014,12 +1022,13 @@ private: // Initialise and enter main loop. void OMW::Engine::go() { - assert (!mContentFiles.empty()); + assert(!mContentFiles.empty()); Log(Debug::Info) << "OSG version: " << osgGetVersion(); SDL_version sdlVersion; SDL_GetVersion(&sdlVersion); - Log(Debug::Info) << "SDL version: " << (int)sdlVersion.major << "." << (int)sdlVersion.minor << "." << (int)sdlVersion.patch; + Log(Debug::Info) << "SDL version: " << (int)sdlVersion.major << "." << (int)sdlVersion.minor << "." + << (int)sdlVersion.patch; Misc::Rng::init(mRandomSeed); @@ -1082,15 +1091,15 @@ void OMW::Engine::go() else if (!mSkipMenu) { // start in main menu - mWindowManager->pushGuiMode (MWGui::GM_MainMenu); + mWindowManager->pushGuiMode(MWGui::GM_MainMenu); mSoundManager->playTitleMusic(); std::string_view logo = Fallback::Map::getString("Movies_Morrowind_Logo"); if (!logo.empty()) - mWindowManager->playVideo(logo, /*allowSkipping*/true, /*overrideSounds*/false); + mWindowManager->playVideo(logo, /*allowSkipping*/ true, /*overrideSounds*/ false); } else { - mStateManager->newGame (!mNewGame); + mStateManager->newGame(!mNewGame); } if (!mStartupScript.empty() && mStateManager->getState() == MWState::StateManager::State_Running) @@ -1098,7 +1107,7 @@ void OMW::Engine::go() mWindowManager->executeInConsole(mStartupScript); } - LuaWorker luaWorker(this); // starts a separate lua thread if "lua num threads" > 0 + LuaWorker luaWorker(this); // starts a separate lua thread if "lua num threads" > 0 // Start the main rendering loop double simulationTime = 0.0; @@ -1106,10 +1115,10 @@ void OMW::Engine::go() const std::chrono::steady_clock::duration maxSimulationInterval(std::chrono::milliseconds(200)); while (!mViewer->done() && !mStateManager->hasQuitRequest()) { - const double dt = std::chrono::duration_cast>(std::min( - frameRateLimiter.getLastFrameDuration(), - maxSimulationInterval - )).count() * mEnvironment.getWorld()->getSimulationTimeScale(); + const double dt = std::chrono::duration_cast>( + std::min(frameRateLimiter.getLastFrameDuration(), maxSimulationInterval)) + .count() + * mEnvironment.getWorld()->getSimulationTimeScale(); mViewer->advance(simulationTime); @@ -1125,7 +1134,7 @@ void OMW::Engine::go() mWorld->updateWindowManager(); - luaWorker.allowUpdate(); // if there is a separate Lua thread, it starts the update now + luaWorker.allowUpdate(); // if there is a separate Lua thread, it starts the update now mViewer->renderingTraversals(); @@ -1162,12 +1171,12 @@ void OMW::Engine::go() Log(Debug::Info) << "Quitting peacefully."; } -void OMW::Engine::setCompileAll (bool all) +void OMW::Engine::setCompileAll(bool all) { mCompileAll = all; } -void OMW::Engine::setCompileAllDialogue (bool all) +void OMW::Engine::setCompileAllDialogue(bool all) { mCompileAllDialogue = all; } @@ -1182,37 +1191,37 @@ void OMW::Engine::setEncoding(const ToUTF8::FromType& encoding) mEncoding = encoding; } -void OMW::Engine::setScriptConsoleMode (bool enabled) +void OMW::Engine::setScriptConsoleMode(bool enabled) { mScriptConsoleMode = enabled; } -void OMW::Engine::setStartupScript (const std::string& path) +void OMW::Engine::setStartupScript(const std::string& path) { mStartupScript = path; } -void OMW::Engine::setActivationDistanceOverride (int distance) +void OMW::Engine::setActivationDistanceOverride(int distance) { mActivationDistanceOverride = distance; } -void OMW::Engine::setWarningsMode (int mode) +void OMW::Engine::setWarningsMode(int mode) { mWarningsMode = mode; } -void OMW::Engine::setScriptBlacklist (const std::vector& list) +void OMW::Engine::setScriptBlacklist(const std::vector& list) { mScriptBlacklist = list; } -void OMW::Engine::setScriptBlacklistUse (bool use) +void OMW::Engine::setScriptBlacklistUse(bool use) { mScriptBlacklistUse = use; } -void OMW::Engine::setSaveGameFile(const std::filesystem::path &savegame) +void OMW::Engine::setSaveGameFile(const std::filesystem::path& savegame) { mSaveGameFile = savegame; } diff --git a/apps/openmw/engine.hpp b/apps/openmw/engine.hpp index 98d667dc43..cdc54c7018 100644 --- a/apps/openmw/engine.hpp +++ b/apps/openmw/engine.hpp @@ -5,8 +5,8 @@ #include #include -#include #include +#include #include #include @@ -117,153 +117,153 @@ namespace OMW /// \brief Main engine class, that brings together all the components of OpenMW class Engine { - SDL_Window* mWindow; - std::unique_ptr mVFS; - std::unique_ptr mResourceSystem; - osg::ref_ptr mWorkQueue; - std::unique_ptr mUnrefQueue; - std::unique_ptr mWorld; - std::unique_ptr mSoundManager; - std::unique_ptr mScriptManager; - std::unique_ptr mWindowManager; - std::unique_ptr mMechanicsManager; - std::unique_ptr mDialogueManager; - std::unique_ptr mJournal; - std::unique_ptr mInputManager; - std::unique_ptr mStateManager; - std::unique_ptr mLuaManager; - MWBase::Environment mEnvironment; - ToUTF8::FromType mEncoding; - std::unique_ptr mEncoder; - Files::PathContainer mDataDirs; - std::vector mArchives; - std::filesystem::path mResDir; - osg::ref_ptr mViewer; - osg::ref_ptr mScreenCaptureHandler; - osg::ref_ptr mScreenCaptureOperation; - osg::ref_ptr mSelectDepthFormatOperation; - osg::ref_ptr mSelectColorFormatOperation; - std::string mCellName; - std::vector mContentFiles; - std::vector mGroundcoverFiles; - - std::unique_ptr mStereoManager; - - bool mSkipMenu; - bool mUseSound; - bool mCompileAll; - bool mCompileAllDialogue; - int mWarningsMode; - std::string mFocusName; - bool mScriptConsoleMode; - std::string mStartupScript; - int mActivationDistanceOverride; - std::filesystem::path mSaveGameFile; - // Grab mouse? - bool mGrab; - - unsigned int mRandomSeed; - - Compiler::Extensions mExtensions; - std::unique_ptr mScriptContext; - - Files::Collections mFileCollections; - bool mFSStrict; - Translation::Storage mTranslationDataStorage; - std::vector mScriptBlacklist; - bool mScriptBlacklistUse; - bool mNewGame; - - // not implemented - Engine (const Engine&); - Engine& operator= (const Engine&); - - void executeLocalScripts(); - - bool frame (float dt); - - /// Prepare engine for game play - void prepareEngine(); - - void createWindow(); - void setWindowIcon(); - - public: - Engine(Files::ConfigurationManager& configurationManager); - virtual ~Engine(); - - /// Enable strict filesystem mode (do not fold case) - /// - /// \attention The strict mode must be specified before any path-related settings - /// are given to the engine. - void enableFSStrict(bool fsStrict); - - /// Set data dirs - void setDataDirs(const Files::PathContainer& dataDirs); - - /// Add BSA archive - void addArchive(const std::string& archive); - - /// Set resource dir - void setResourceDir(const std::filesystem::path& parResDir); - - /// Set start cell name - void setCell(const std::string& cellName); - - /** - * @brief addContentFile - Adds content file (ie. esm/esp, or omwgame/omwaddon) to the content files container. - * @param file - filename (extension is required) - */ - void addContentFile(const std::string& file); - void addGroundcoverFile(const std::string& file); - - /// Disable or enable all sounds - void setSoundUsage(bool soundUsage); - - /// Skip main menu and go directly into the game - /// - /// \param newGame Start a new game instead off dumping the player into the game - /// (ignored if !skipMenu). - void setSkipMenu (bool skipMenu, bool newGame); - - void setGrabMouse(bool grab) { mGrab = grab; } - - /// Initialise and enter main loop. - void go(); + SDL_Window* mWindow; + std::unique_ptr mVFS; + std::unique_ptr mResourceSystem; + osg::ref_ptr mWorkQueue; + std::unique_ptr mUnrefQueue; + std::unique_ptr mWorld; + std::unique_ptr mSoundManager; + std::unique_ptr mScriptManager; + std::unique_ptr mWindowManager; + std::unique_ptr mMechanicsManager; + std::unique_ptr mDialogueManager; + std::unique_ptr mJournal; + std::unique_ptr mInputManager; + std::unique_ptr mStateManager; + std::unique_ptr mLuaManager; + MWBase::Environment mEnvironment; + ToUTF8::FromType mEncoding; + std::unique_ptr mEncoder; + Files::PathContainer mDataDirs; + std::vector mArchives; + std::filesystem::path mResDir; + osg::ref_ptr mViewer; + osg::ref_ptr mScreenCaptureHandler; + osg::ref_ptr mScreenCaptureOperation; + osg::ref_ptr mSelectDepthFormatOperation; + osg::ref_ptr mSelectColorFormatOperation; + std::string mCellName; + std::vector mContentFiles; + std::vector mGroundcoverFiles; + + std::unique_ptr mStereoManager; + + bool mSkipMenu; + bool mUseSound; + bool mCompileAll; + bool mCompileAllDialogue; + int mWarningsMode; + std::string mFocusName; + bool mScriptConsoleMode; + std::string mStartupScript; + int mActivationDistanceOverride; + std::filesystem::path mSaveGameFile; + // Grab mouse? + bool mGrab; + + unsigned int mRandomSeed; + + Compiler::Extensions mExtensions; + std::unique_ptr mScriptContext; + + Files::Collections mFileCollections; + bool mFSStrict; + Translation::Storage mTranslationDataStorage; + std::vector mScriptBlacklist; + bool mScriptBlacklistUse; + bool mNewGame; + + // not implemented + Engine(const Engine&); + Engine& operator=(const Engine&); + + void executeLocalScripts(); + + bool frame(float dt); + + /// Prepare engine for game play + void prepareEngine(); + + void createWindow(); + void setWindowIcon(); + + public: + Engine(Files::ConfigurationManager& configurationManager); + virtual ~Engine(); + + /// Enable strict filesystem mode (do not fold case) + /// + /// \attention The strict mode must be specified before any path-related settings + /// are given to the engine. + void enableFSStrict(bool fsStrict); + + /// Set data dirs + void setDataDirs(const Files::PathContainer& dataDirs); + + /// Add BSA archive + void addArchive(const std::string& archive); + + /// Set resource dir + void setResourceDir(const std::filesystem::path& parResDir); + + /// Set start cell name + void setCell(const std::string& cellName); + + /** + * @brief addContentFile - Adds content file (ie. esm/esp, or omwgame/omwaddon) to the content files container. + * @param file - filename (extension is required) + */ + void addContentFile(const std::string& file); + void addGroundcoverFile(const std::string& file); + + /// Disable or enable all sounds + void setSoundUsage(bool soundUsage); + + /// Skip main menu and go directly into the game + /// + /// \param newGame Start a new game instead off dumping the player into the game + /// (ignored if !skipMenu). + void setSkipMenu(bool skipMenu, bool newGame); + + void setGrabMouse(bool grab) { mGrab = grab; } + + /// Initialise and enter main loop. + void go(); - /// Compile all scripts (excludign dialogue scripts) at startup? - void setCompileAll (bool all); + /// Compile all scripts (excludign dialogue scripts) at startup? + void setCompileAll(bool all); - /// Compile all dialogue scripts at startup? - void setCompileAllDialogue (bool all); + /// Compile all dialogue scripts at startup? + void setCompileAllDialogue(bool all); - /// Font encoding - void setEncoding(const ToUTF8::FromType& encoding); + /// Font encoding + void setEncoding(const ToUTF8::FromType& encoding); - /// Enable console-only script functionality - void setScriptConsoleMode (bool enabled); + /// Enable console-only script functionality + void setScriptConsoleMode(bool enabled); - /// Set path for a script that is run on startup in the console. - void setStartupScript (const std::string& path); + /// Set path for a script that is run on startup in the console. + void setStartupScript(const std::string& path); - /// Override the game setting specified activation distance. - void setActivationDistanceOverride (int distance); + /// Override the game setting specified activation distance. + void setActivationDistanceOverride(int distance); - void setWarningsMode (int mode); + void setWarningsMode(int mode); - void setScriptBlacklist (const std::vector& list); + void setScriptBlacklist(const std::vector& list); - void setScriptBlacklistUse (bool use); + void setScriptBlacklistUse(bool use); - /// Set the save game file to load after initialising the engine. - void setSaveGameFile(const std::filesystem::path &savegame); + /// Set the save game file to load after initialising the engine. + void setSaveGameFile(const std::filesystem::path& savegame); - void setRandomSeed(unsigned int seed); + void setRandomSeed(unsigned int seed); - private: - Files::ConfigurationManager& mCfgMgr; - class LuaWorker; - int mGlMaxTextureImageUnits; + private: + Files::ConfigurationManager& mCfgMgr; + class LuaWorker; + int mGlMaxTextureImageUnits; }; } diff --git a/apps/openmw/main.cpp b/apps/openmw/main.cpp index 9700142ab8..a2c096e2a0 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -1,10 +1,10 @@ -#include -#include +#include #include #include -#include +#include #include #include +#include #include "mwgui/debugwindow.hpp" @@ -27,7 +27,6 @@ extern "C" __declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x #include #endif - using namespace Fallback; /** @@ -39,7 +38,7 @@ using namespace Fallback; * \retval true - Everything goes OK * \retval false - Error */ -bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::ConfigurationManager& cfgMgr) +bool parseOptions(int argc, char** argv, OMW::Engine& engine, Files::ConfigurationManager& cfgMgr) { // Create a local alias for brevity namespace bpo = boost::program_options; @@ -51,17 +50,21 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat Files::parseArgs(argc, argv, variables, desc); bpo::notify(variables); - if (variables.count ("help")) + if (variables.count("help")) { getRawStdout() << desc << std::endl; return false; } - if (variables.count ("version")) + if (variables.count("version")) { cfgMgr.readConfiguration(variables, desc, true); - Version::Version v = Version::getOpenmwVersion(variables["resources"].as().u8string()); // This call to u8string is redundant, but required to build on MSVC 14.26 due to implementation bugs. + Version::Version v + = Version::getOpenmwVersion(variables["resources"] + .as() + .u8string()); // This call to u8string is redundant, but required to build + // on MSVC 14.26 due to implementation bugs. getRawStdout() << v.describe() << std::endl; return false; } @@ -72,7 +75,11 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat setupLogging(cfgMgr.getLogPath(), "OpenMW"); MWGui::DebugWindow::startLogRecording(); - Version::Version v = Version::getOpenmwVersion(variables["resources"].as().u8string()); // This call to u8string is redundant, but required to build on MSVC 14.26 due to implementation bugs. + Version::Version v + = Version::getOpenmwVersion(variables["resources"] + .as() + .u8string()); // This call to u8string is redundant, but required to build on + // MSVC 14.26 due to implementation bugs. Log(Debug::Info) << v.describe(); engine.setGrabMouse(!variables["no-grab"].as()); @@ -87,13 +94,19 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat Files::PathContainer dataDirs(asPathContainer(variables["data"].as())); - Files::PathContainer::value_type local(variables["data-local"].as().u8string()); // This call to u8string is redundant, but required to build on MSVC 14.26 due to implementation bugs. + Files::PathContainer::value_type local(variables["data-local"] + .as() + .u8string()); // This call to u8string is redundant, but required to + // build on MSVC 14.26 due to implementation bugs. if (!local.empty()) dataDirs.push_back(local); cfgMgr.filterOutNonExistingPaths(dataDirs); - engine.setResourceDir(variables["resources"].as().u8string()); // This call to u8string is redundant, but required to build on MSVC 14.26 due to implementation bugs. + engine.setResourceDir(variables["resources"] + .as() + .u8string()); // This call to u8string is redundant, but required to build on MSVC 14.26 + // due to implementation bugs. engine.setDataDirs(dataDirs); // fallback archives @@ -138,24 +151,24 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat // startup-settings engine.setCell(variables["start"].as()); - engine.setSkipMenu (variables["skip-menu"].as(), variables["new-game"].as()); + engine.setSkipMenu(variables["skip-menu"].as(), variables["new-game"].as()); if (!variables["skip-menu"].as() && variables["new-game"].as()) Log(Debug::Warning) << "Warning: new-game used without skip-menu -> ignoring it"; // scripts engine.setCompileAll(variables["script-all"].as()); engine.setCompileAllDialogue(variables["script-all-dialogue"].as()); - engine.setScriptConsoleMode (variables["script-console"].as()); - engine.setStartupScript (variables["script-run"].as()); - engine.setWarningsMode (variables["script-warn"].as()); - engine.setScriptBlacklist (variables["script-blacklist"].as()); - engine.setScriptBlacklistUse (variables["script-blacklist-use"].as()); - engine.setSaveGameFile (variables["load-savegame"].as().u8string()); + engine.setScriptConsoleMode(variables["script-console"].as()); + engine.setStartupScript(variables["script-run"].as()); + engine.setWarningsMode(variables["script-warn"].as()); + engine.setScriptBlacklist(variables["script-blacklist"].as()); + engine.setScriptBlacklistUse(variables["script-blacklist-use"].as()); + engine.setSaveGameFile(variables["load-savegame"].as().u8string()); // other settings Fallback::Map::init(variables["fallback"].as().mMap); engine.setSoundUsage(!variables["no-sound"].as()); - engine.setActivationDistanceOverride (variables["activate-dist"].as()); + engine.setActivationDistanceOverride(variables["activate-dist"].as()); engine.setRandomSeed(variables["random-seed"].as()); return true; @@ -175,21 +188,21 @@ namespace Debug::Level level; switch (severity) { - case osg::ALWAYS: - case osg::FATAL: - level = Debug::Error; - break; - case osg::WARN: - case osg::NOTICE: - level = Debug::Warning; - break; - case osg::INFO: - level = Debug::Info; - break; - case osg::DEBUG_INFO: - case osg::DEBUG_FP: - default: - level = Debug::Debug; + case osg::ALWAYS: + case osg::FATAL: + level = Debug::Error; + break; + case osg::WARN: + case osg::NOTICE: + level = Debug::Warning; + break; + case osg::INFO: + level = Debug::Info; + break; + case osg::DEBUG_INFO: + case osg::DEBUG_FP: + default: + level = Debug::Debug; } std::string_view s(msgCopy); if (s.size() < 1024) @@ -209,7 +222,7 @@ namespace }; } -int runApplication(int argc, char *argv[]) +int runApplication(int argc, char* argv[]) { Platform::init(); @@ -232,9 +245,9 @@ int runApplication(int argc, char *argv[]) } #ifdef ANDROID -extern "C" int SDL_main(int argc, char**argv) +extern "C" int SDL_main(int argc, char** argv) #else -int main(int argc, char**argv) +int main(int argc, char** argv) #endif { return wrapApplication(&runApplication, argc, argv, "OpenMW", false); diff --git a/apps/openmw/mwbase/dialoguemanager.hpp b/apps/openmw/mwbase/dialoguemanager.hpp index 94543ed955..889da6de71 100644 --- a/apps/openmw/mwbase/dialoguemanager.hpp +++ b/apps/openmw/mwbase/dialoguemanager.hpp @@ -1,10 +1,10 @@ #ifndef GAME_MWBASE_DIALOGUEMANAGER_H #define GAME_MWBASE_DIALOGUEMANAGER_H +#include #include #include #include -#include #include @@ -29,92 +29,91 @@ namespace MWBase /// \brief Interface for dialogue manager (implemented in MWDialogue) class DialogueManager { - DialogueManager (const DialogueManager&); - ///< not implemented + DialogueManager(const DialogueManager&); + ///< not implemented - DialogueManager& operator= (const DialogueManager&); - ///< not implemented + DialogueManager& operator=(const DialogueManager&); + ///< not implemented + public: + class ResponseCallback + { public: + virtual ~ResponseCallback() = default; + virtual void addResponse(const std::string& title, const std::string& text) = 0; + }; - class ResponseCallback - { - public: - virtual ~ResponseCallback() = default; - virtual void addResponse(const std::string& title, const std::string& text) = 0; - }; - - DialogueManager() {} + DialogueManager() {} - virtual void clear() = 0; + virtual void clear() = 0; - virtual ~DialogueManager() {} + virtual ~DialogueManager() {} - virtual bool isInChoice() const = 0; + virtual bool isInChoice() const = 0; - virtual bool startDialogue (const MWWorld::Ptr& actor, ResponseCallback* callback) = 0; + virtual bool startDialogue(const MWWorld::Ptr& actor, ResponseCallback* callback) = 0; - virtual bool inJournal (const std::string& topicId, const std::string& infoId) = 0; + virtual bool inJournal(const std::string& topicId, const std::string& infoId) = 0; - virtual void addTopic(std::string_view topic) = 0; + virtual void addTopic(std::string_view topic) = 0; - virtual void addChoice(std::string_view text,int choice) = 0; - virtual const std::vector >& getChoices() = 0; + virtual void addChoice(std::string_view text, int choice) = 0; + virtual const std::vector>& getChoices() = 0; - virtual bool isGoodbye() = 0; + virtual bool isGoodbye() = 0; - virtual void goodbye() = 0; + virtual void goodbye() = 0; - virtual void say(const MWWorld::Ptr &actor, const std::string &topic) = 0; + virtual void say(const MWWorld::Ptr& actor, const std::string& topic) = 0; - virtual void keywordSelected (const std::string& keyword, ResponseCallback* callback) = 0; - virtual void goodbyeSelected() = 0; - virtual void questionAnswered (int answer, ResponseCallback* callback) = 0; + virtual void keywordSelected(const std::string& keyword, ResponseCallback* callback) = 0; + virtual void goodbyeSelected() = 0; + virtual void questionAnswered(int answer, ResponseCallback* callback) = 0; - enum TopicType - { - Specific = 1, - Exhausted = 2 - }; + enum TopicType + { + Specific = 1, + Exhausted = 2 + }; - enum ServiceType - { - Any = -1, - Barter = 1, - Repair = 2, - Spells = 3, - Training = 4, - Travel = 5, - Spellmaking = 6, - Enchanting = 7 - }; + enum ServiceType + { + Any = -1, + Barter = 1, + Repair = 2, + Spells = 3, + Training = 4, + Travel = 5, + Spellmaking = 6, + Enchanting = 7 + }; - virtual std::list getAvailableTopics() = 0; - virtual int getTopicFlag(const std::string&) = 0; + virtual std::list getAvailableTopics() = 0; + virtual int getTopicFlag(const std::string&) = 0; - virtual bool checkServiceRefused (ResponseCallback* callback, ServiceType service = ServiceType::Any) = 0; + virtual bool checkServiceRefused(ResponseCallback* callback, ServiceType service = ServiceType::Any) = 0; - virtual void persuade (int type, ResponseCallback* callback) = 0; + virtual void persuade(int type, ResponseCallback* callback) = 0; - /// @note Controlled by an option, gets discarded when dialogue ends by default - virtual void applyBarterDispositionChange (int delta) = 0; + /// @note Controlled by an option, gets discarded when dialogue ends by default + virtual void applyBarterDispositionChange(int delta) = 0; - virtual int countSavedGameRecords() const = 0; + virtual int countSavedGameRecords() const = 0; - virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress) const = 0; + virtual void write(ESM::ESMWriter& writer, Loading::Listener& progress) const = 0; - virtual void readRecord (ESM::ESMReader& reader, uint32_t type) = 0; + virtual void readRecord(ESM::ESMReader& reader, uint32_t type) = 0; - /// Changes faction1's opinion of faction2 by \a diff. - virtual void modFactionReaction (std::string_view faction1, std::string_view faction2, int diff) = 0; + /// Changes faction1's opinion of faction2 by \a diff. + virtual void modFactionReaction(std::string_view faction1, std::string_view faction2, int diff) = 0; - virtual void setFactionReaction (std::string_view faction1, std::string_view faction2, int absolute) = 0; + virtual void setFactionReaction(std::string_view faction1, std::string_view faction2, int absolute) = 0; - /// @return faction1's opinion of faction2 - virtual int getFactionReaction (std::string_view faction1, std::string_view faction2) const = 0; + /// @return faction1's opinion of faction2 + virtual int getFactionReaction(std::string_view faction1, std::string_view faction2) const = 0; - /// Removes the last added topic response for the given actor from the journal - virtual void clearInfoActor (const MWWorld::Ptr& actor) const = 0; + /// Removes the last added topic response for the given actor from the journal + virtual void clearInfoActor(const MWWorld::Ptr& actor) const = 0; }; } diff --git a/apps/openmw/mwbase/environment.cpp b/apps/openmw/mwbase/environment.cpp index 6b0c891fa6..18b6589c9a 100644 --- a/apps/openmw/mwbase/environment.cpp +++ b/apps/openmw/mwbase/environment.cpp @@ -4,10 +4,10 @@ #include -#include "world.hpp" #include "mechanicsmanager.hpp" +#include "world.hpp" -MWBase::Environment *MWBase::Environment::sThis = nullptr; +MWBase::Environment* MWBase::Environment::sThis = nullptr; MWBase::Environment::Environment() { diff --git a/apps/openmw/mwbase/environment.hpp b/apps/openmw/mwbase/environment.hpp index 0c5d39425b..c2f4fd129c 100644 --- a/apps/openmw/mwbase/environment.hpp +++ b/apps/openmw/mwbase/environment.hpp @@ -34,92 +34,91 @@ namespace MWBase /// class Environment { - static Environment *sThis; + static Environment* sThis; - World* mWorld = nullptr; - SoundManager* mSoundManager = nullptr; - ScriptManager* mScriptManager = nullptr; - WindowManager* mWindowManager = nullptr; - MechanicsManager* mMechanicsManager = nullptr; - DialogueManager* mDialogueManager = nullptr; - Journal* mJournal = nullptr; - InputManager* mInputManager = nullptr; - StateManager* mStateManager = nullptr; - LuaManager* mLuaManager = nullptr; - Resource::ResourceSystem* mResourceSystem = nullptr; - float mFrameRateLimit = 0; - float mFrameDuration = 0; + World* mWorld = nullptr; + SoundManager* mSoundManager = nullptr; + ScriptManager* mScriptManager = nullptr; + WindowManager* mWindowManager = nullptr; + MechanicsManager* mMechanicsManager = nullptr; + DialogueManager* mDialogueManager = nullptr; + Journal* mJournal = nullptr; + InputManager* mInputManager = nullptr; + StateManager* mStateManager = nullptr; + LuaManager* mLuaManager = nullptr; + Resource::ResourceSystem* mResourceSystem = nullptr; + float mFrameRateLimit = 0; + float mFrameDuration = 0; - public: + public: + Environment(); - Environment(); + ~Environment(); - ~Environment(); + Environment(const Environment&) = delete; - Environment(const Environment&) = delete; + Environment& operator=(const Environment&) = delete; - Environment& operator=(const Environment&) = delete; + void setWorld(World& value) { mWorld = &value; } - void setWorld(World& value) { mWorld = &value; } + void setSoundManager(SoundManager& value) { mSoundManager = &value; } - void setSoundManager(SoundManager& value) { mSoundManager = &value; } + void setScriptManager(ScriptManager& value) { mScriptManager = &value; } - void setScriptManager(ScriptManager& value) { mScriptManager = &value; } + void setWindowManager(WindowManager& value) { mWindowManager = &value; } - void setWindowManager(WindowManager& value) { mWindowManager = &value; } + void setMechanicsManager(MechanicsManager& value) { mMechanicsManager = &value; } - void setMechanicsManager(MechanicsManager& value) { mMechanicsManager = &value; } + void setDialogueManager(DialogueManager& value) { mDialogueManager = &value; } - void setDialogueManager(DialogueManager& value) { mDialogueManager = &value; } + void setJournal(Journal& value) { mJournal = &value; } - void setJournal(Journal& value) { mJournal = &value; } + void setInputManager(InputManager& value) { mInputManager = &value; } - void setInputManager(InputManager& value) { mInputManager = &value; } + void setStateManager(StateManager& value) { mStateManager = &value; } - void setStateManager(StateManager& value) { mStateManager = &value; } + void setLuaManager(LuaManager& value) { mLuaManager = &value; } - void setLuaManager(LuaManager& value) { mLuaManager = &value; } + void setResourceSystem(Resource::ResourceSystem& value) { mResourceSystem = &value; } - void setResourceSystem(Resource::ResourceSystem& value) { mResourceSystem = &value; } + Misc::NotNullPtr getWorld() const { return mWorld; } - Misc::NotNullPtr getWorld() const { return mWorld; } + Misc::NotNullPtr getSoundManager() const { return mSoundManager; } - Misc::NotNullPtr getSoundManager() const { return mSoundManager; } + Misc::NotNullPtr getScriptManager() const { return mScriptManager; } - Misc::NotNullPtr getScriptManager() const { return mScriptManager; } + Misc::NotNullPtr getWindowManager() const { return mWindowManager; } - Misc::NotNullPtr getWindowManager() const { return mWindowManager; } + Misc::NotNullPtr getMechanicsManager() const { return mMechanicsManager; } - Misc::NotNullPtr getMechanicsManager() const { return mMechanicsManager; } + Misc::NotNullPtr getDialogueManager() const { return mDialogueManager; } - Misc::NotNullPtr getDialogueManager() const { return mDialogueManager; } + Misc::NotNullPtr getJournal() const { return mJournal; } - Misc::NotNullPtr getJournal() const { return mJournal; } + Misc::NotNullPtr getInputManager() const { return mInputManager; } - Misc::NotNullPtr getInputManager() const { return mInputManager; } + Misc::NotNullPtr getStateManager() const { return mStateManager; } - Misc::NotNullPtr getStateManager() const { return mStateManager; } + Misc::NotNullPtr getLuaManager() const { return mLuaManager; } - Misc::NotNullPtr getLuaManager() const { return mLuaManager; } + Misc::NotNullPtr getResourceSystem() const { return mResourceSystem; } - Misc::NotNullPtr getResourceSystem() const { return mResourceSystem; } + float getFrameRateLimit() const { return mFrameRateLimit; } - float getFrameRateLimit() const { return mFrameRateLimit; } + void setFrameRateLimit(float value) { mFrameRateLimit = value; } - void setFrameRateLimit(float value) { mFrameRateLimit = value; } + float getFrameDuration() const { return mFrameDuration; } - float getFrameDuration() const { return mFrameDuration; } + void setFrameDuration(float value) { mFrameDuration = value; } - void setFrameDuration(float value) { mFrameDuration = value; } + /// Return instance of this class. + static const Environment& get() + { + assert(sThis != nullptr); + return *sThis; + } - /// Return instance of this class. - static const Environment& get() - { - assert(sThis != nullptr); - return *sThis; - } - - void reportStats(unsigned int frameNumber, osg::Stats& stats) const; + void reportStats(unsigned int frameNumber, osg::Stats& stats) const; }; } diff --git a/apps/openmw/mwbase/inputmanager.hpp b/apps/openmw/mwbase/inputmanager.hpp index 14679ffd25..0e31f4f370 100644 --- a/apps/openmw/mwbase/inputmanager.hpp +++ b/apps/openmw/mwbase/inputmanager.hpp @@ -1,8 +1,8 @@ #ifndef GAME_MWBASE_INPUTMANAGER_H #define GAME_MWBASE_INPUTMANAGER_H -#include #include +#include #include #include @@ -24,70 +24,70 @@ namespace MWBase /// \brief Interface for input manager (implemented in MWInput) class InputManager { - InputManager (const InputManager&); - ///< not implemented - - InputManager& operator= (const InputManager&); - ///< not implemented + InputManager(const InputManager&); + ///< not implemented - public: + InputManager& operator=(const InputManager&); + ///< not implemented - InputManager() {} + public: + InputManager() {} - /// Clear all savegame-specific data - virtual void clear() = 0; + /// Clear all savegame-specific data + virtual void clear() = 0; - virtual ~InputManager() {} + virtual ~InputManager() {} - virtual void update(float dt, bool disableControls, bool disableEvents=false) = 0; + virtual void update(float dt, bool disableControls, bool disableEvents = false) = 0; - virtual void changeInputMode(bool guiMode) = 0; + virtual void changeInputMode(bool guiMode) = 0; - virtual void processChangedSettings(const std::set< std::pair >& changed) = 0; + virtual void processChangedSettings(const std::set>& changed) = 0; - virtual void setDragDrop(bool dragDrop) = 0; - virtual void setGamepadGuiCursorEnabled(bool enabled) = 0; - virtual void setAttemptJump(bool jumping) = 0; + virtual void setDragDrop(bool dragDrop) = 0; + virtual void setGamepadGuiCursorEnabled(bool enabled) = 0; + virtual void setAttemptJump(bool jumping) = 0; - virtual void toggleControlSwitch(std::string_view sw, bool value) = 0; - virtual bool getControlSwitch(std::string_view sw) = 0; + virtual void toggleControlSwitch(std::string_view sw, bool value) = 0; + virtual bool getControlSwitch(std::string_view sw) = 0; - virtual std::string_view getActionDescription(int action) const = 0; - virtual std::string getActionKeyBindingName (int action) const = 0; - virtual std::string getActionControllerBindingName (int action) const = 0; - virtual bool actionIsActive(int action) const = 0; + virtual std::string_view getActionDescription(int action) const = 0; + virtual std::string getActionKeyBindingName(int action) const = 0; + virtual std::string getActionControllerBindingName(int action) const = 0; + virtual bool actionIsActive(int action) const = 0; - virtual float getActionValue(int action) const = 0; // returns value in range [0, 1] - virtual bool isControllerButtonPressed(SDL_GameControllerButton button) const = 0; - virtual float getControllerAxisValue(SDL_GameControllerAxis axis) const = 0; // returns value in range [-1, 1] - virtual int getMouseMoveX() const = 0; - virtual int getMouseMoveY() const = 0; + virtual float getActionValue(int action) const = 0; // returns value in range [0, 1] + virtual bool isControllerButtonPressed(SDL_GameControllerButton button) const = 0; + virtual float getControllerAxisValue(SDL_GameControllerAxis axis) const = 0; // returns value in range [-1, 1] + virtual int getMouseMoveX() const = 0; + virtual int getMouseMoveY() const = 0; - ///Actions available for binding to keyboard buttons - virtual const std::initializer_list& getActionKeySorting() = 0; - ///Actions available for binding to controller buttons - virtual const std::initializer_list& getActionControllerSorting() = 0; - virtual int getNumActions() = 0; - ///If keyboard is true, only pay attention to keyboard events. If false, only pay attention to controller events (excluding esc) - virtual void enableDetectingBindingMode (int action, bool keyboard) = 0; - virtual void resetToDefaultKeyBindings() = 0; - virtual void resetToDefaultControllerBindings() = 0; + /// Actions available for binding to keyboard buttons + virtual const std::initializer_list& getActionKeySorting() = 0; + /// Actions available for binding to controller buttons + virtual const std::initializer_list& getActionControllerSorting() = 0; + virtual int getNumActions() = 0; + /// If keyboard is true, only pay attention to keyboard events. If false, only pay attention to controller + /// events (excluding esc) + virtual void enableDetectingBindingMode(int action, bool keyboard) = 0; + virtual void resetToDefaultKeyBindings() = 0; + virtual void resetToDefaultControllerBindings() = 0; - /// Returns if the last used input device was a joystick or a keyboard - /// @return true if joystick, false otherwise - virtual bool joystickLastUsed() = 0; - virtual void setJoystickLastUsed(bool enabled) = 0; + /// Returns if the last used input device was a joystick or a keyboard + /// @return true if joystick, false otherwise + virtual bool joystickLastUsed() = 0; + virtual void setJoystickLastUsed(bool enabled) = 0; - virtual int countSavedGameRecords() const = 0; - virtual void write(ESM::ESMWriter& writer, Loading::Listener& progress) = 0; - virtual void readRecord(ESM::ESMReader& reader, uint32_t type) = 0; + virtual int countSavedGameRecords() const = 0; + virtual void write(ESM::ESMWriter& writer, Loading::Listener& progress) = 0; + virtual void readRecord(ESM::ESMReader& reader, uint32_t type) = 0; - virtual void resetIdleTime() = 0; - virtual bool isIdle() const = 0; + virtual void resetIdleTime() = 0; + virtual bool isIdle() const = 0; - virtual void executeAction(int action) = 0; + virtual void executeAction(int action) = 0; - virtual bool controlsDisabled() = 0; + virtual bool controlsDisabled() = 0; }; } diff --git a/apps/openmw/mwbase/journal.hpp b/apps/openmw/mwbase/journal.hpp index acad5c8788..9956bcf236 100644 --- a/apps/openmw/mwbase/journal.hpp +++ b/apps/openmw/mwbase/journal.hpp @@ -1,16 +1,16 @@ #ifndef GAME_MWBASE_JOURNAL_H #define GAME_MWBASE_JOURNAL_H -#include -#include #include #include +#include +#include #include #include "../mwdialogue/journalentry.hpp" -#include "../mwdialogue/topic.hpp" #include "../mwdialogue/quest.hpp" +#include "../mwdialogue/topic.hpp" namespace Loading { @@ -28,73 +28,71 @@ namespace MWBase /// \brief Interface for the player's journal (implemented in MWDialogue) class Journal { - Journal (const Journal&); - ///< not implemented - - Journal& operator= (const Journal&); - ///< not implemented - - public: + Journal(const Journal&); + ///< not implemented - typedef std::deque TEntryContainer; - typedef TEntryContainer::const_iterator TEntryIter; - typedef std::map TQuestContainer; // topic, quest - typedef TQuestContainer::const_iterator TQuestIter; - typedef std::map TTopicContainer; // topic-id, topic-content - typedef TTopicContainer::const_iterator TTopicIter; + Journal& operator=(const Journal&); + ///< not implemented - public: + public: + typedef std::deque TEntryContainer; + typedef TEntryContainer::const_iterator TEntryIter; + typedef std::map TQuestContainer; // topic, quest + typedef TQuestContainer::const_iterator TQuestIter; + typedef std::map TTopicContainer; // topic-id, topic-content + typedef TTopicContainer::const_iterator TTopicIter; - Journal() {} + public: + Journal() {} - virtual void clear() = 0; + virtual void clear() = 0; - virtual ~Journal() {} + virtual ~Journal() {} - virtual void addEntry (const std::string& id, int index, const MWWorld::Ptr& actor) = 0; - ///< Add a journal entry. - /// @param actor Used as context for replacing of escape sequences (%name, etc). + virtual void addEntry(const std::string& id, int index, const MWWorld::Ptr& actor) = 0; + ///< Add a journal entry. + /// @param actor Used as context for replacing of escape sequences (%name, etc). - virtual void setJournalIndex (const std::string& id, int index) = 0; - ///< Set the journal index without adding an entry. + virtual void setJournalIndex(const std::string& id, int index) = 0; + ///< Set the journal index without adding an entry. - virtual int getJournalIndex (const std::string& id) const = 0; - ///< Get the journal index. + virtual int getJournalIndex(const std::string& id) const = 0; + ///< Get the journal index. - virtual void addTopic (const std::string& topicId, const std::string& infoId, const MWWorld::Ptr& actor) = 0; - /// \note topicId must be lowercase + virtual void addTopic(const std::string& topicId, const std::string& infoId, const MWWorld::Ptr& actor) = 0; + /// \note topicId must be lowercase - virtual void removeLastAddedTopicResponse(const std::string& topicId, std::string_view actorName) = 0; - ///< Removes the last topic response added for the given topicId and actor name. - /// \note topicId must be lowercase + virtual void removeLastAddedTopicResponse(const std::string& topicId, std::string_view actorName) = 0; + ///< Removes the last topic response added for the given topicId and actor name. + /// \note topicId must be lowercase - virtual TEntryIter begin() const = 0; - ///< Iterator pointing to the begin of the main journal. - /// - /// \note Iterators to main journal entries will never become invalid. + virtual TEntryIter begin() const = 0; + ///< Iterator pointing to the begin of the main journal. + /// + /// \note Iterators to main journal entries will never become invalid. - virtual TEntryIter end() const = 0; - ///< Iterator pointing past the end of the main journal. + virtual TEntryIter end() const = 0; + ///< Iterator pointing past the end of the main journal. - virtual TQuestIter questBegin() const = 0; - ///< Iterator pointing to the first quest (sorted by topic ID) + virtual TQuestIter questBegin() const = 0; + ///< Iterator pointing to the first quest (sorted by topic ID) - virtual TQuestIter questEnd() const = 0; - ///< Iterator pointing past the last quest. + virtual TQuestIter questEnd() const = 0; + ///< Iterator pointing past the last quest. - virtual TTopicIter topicBegin() const = 0; - ///< Iterator pointing to the first topic (sorted by topic ID) - /// - /// \note The topic ID is identical with the user-visible topic string. + virtual TTopicIter topicBegin() const = 0; + ///< Iterator pointing to the first topic (sorted by topic ID) + /// + /// \note The topic ID is identical with the user-visible topic string. - virtual TTopicIter topicEnd() const = 0; - ///< Iterator pointing past the last topic. + virtual TTopicIter topicEnd() const = 0; + ///< Iterator pointing past the last topic. - virtual int countSavedGameRecords() const = 0; + virtual int countSavedGameRecords() const = 0; - virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress) const = 0; + virtual void write(ESM::ESMWriter& writer, Loading::Listener& progress) const = 0; - virtual void readRecord (ESM::ESMReader& reader, uint32_t type) = 0; + virtual void readRecord(ESM::ESMReader& reader, uint32_t type) = 0; }; } diff --git a/apps/openmw/mwbase/luamanager.hpp b/apps/openmw/mwbase/luamanager.hpp index 84a8c8df40..bc0f16048a 100644 --- a/apps/openmw/mwbase/luamanager.hpp +++ b/apps/openmw/mwbase/luamanager.hpp @@ -1,9 +1,9 @@ #ifndef GAME_MWBASE_LUAMANAGER_H #define GAME_MWBASE_LUAMANAGER_H -#include -#include #include +#include +#include #include @@ -49,7 +49,8 @@ namespace MWBase struct InputEvent { - enum { + enum + { KeyPressed, KeyReleased, ControllerPressed, @@ -97,9 +98,11 @@ namespace MWBase // Drops script cache and reloads all scripts. Calls `onSave` and `onLoad` for every script. virtual void reloadAllScripts() = 0; - virtual void handleConsoleCommand(const std::string& consoleMode, const std::string& command, const MWWorld::Ptr& selectedPtr) = 0; + virtual void handleConsoleCommand( + const std::string& consoleMode, const std::string& command, const MWWorld::Ptr& selectedPtr) + = 0; }; } -#endif // GAME_MWBASE_LUAMANAGER_H +#endif // GAME_MWBASE_LUAMANAGER_H diff --git a/apps/openmw/mwbase/mechanicsmanager.hpp b/apps/openmw/mwbase/mechanicsmanager.hpp index 55f024e5b0..8a866a848f 100644 --- a/apps/openmw/mwbase/mechanicsmanager.hpp +++ b/apps/openmw/mwbase/mechanicsmanager.hpp @@ -1,12 +1,12 @@ #ifndef GAME_MWBASE_MECHANICSMANAGER_H #define GAME_MWBASE_MECHANICSMANAGER_H +#include +#include +#include #include #include #include -#include -#include -#include #include "../mwmechanics/greetingstate.hpp" @@ -43,237 +43,248 @@ namespace MWBase /// \brief Interface for game mechanics manager (implemented in MWMechanics) class MechanicsManager { - MechanicsManager (const MechanicsManager&); - ///< not implemented - - MechanicsManager& operator= (const MechanicsManager&); - ///< not implemented - - public: - - MechanicsManager() {} - - virtual ~MechanicsManager() {} - - virtual void add (const MWWorld::Ptr& ptr) = 0; - ///< Register an object for management - - virtual void remove (const MWWorld::Ptr& ptr, bool keepActive) = 0; - ///< Deregister an object for management - - virtual void updateCell(const MWWorld::Ptr &old, const MWWorld::Ptr &ptr) = 0; - ///< Moves an object to a new cell - - virtual void drop (const MWWorld::CellStore *cellStore) = 0; - ///< Deregister all objects in the given cell. - - virtual void setPlayerName (const std::string& name) = 0; - ///< Set player name. - - virtual void setPlayerRace (const std::string& id, bool male, const std::string &head, const std::string &hair) = 0; - ///< Set player race. - - virtual void setPlayerBirthsign (const std::string& id) = 0; - ///< Set player birthsign. - - virtual void setPlayerClass (const std::string& id) = 0; - ///< Set player class to stock class. - - virtual void setPlayerClass (const ESM::Class& class_) = 0; - ///< Set player class to custom class. - - virtual void restoreDynamicStats(const MWWorld::Ptr& actor, double hours, bool sleep) = 0; - - virtual void rest(double hours, bool sleep) = 0; - ///< If the player is sleeping or waiting, this should be called every hour. - /// @param sleep is the player sleeping or waiting? - - virtual int getHoursToRest() const = 0; - ///< Calculate how many hours the player needs to rest in order to be fully healed - - virtual int getBarterOffer(const MWWorld::Ptr& ptr,int basePrice, bool buying) = 0; - ///< This is used by every service to determine the price of objects given the trading skills of the player and NPC. - - virtual int getDerivedDisposition(const MWWorld::Ptr& ptr, bool clamp = true) = 0; - ///< Calculate the diposition of an NPC toward the player. - - virtual int countDeaths (const std::string& id) const = 0; - ///< Return the number of deaths for actors with the given ID. - - /// Check if \a observer is potentially aware of \a ptr. Does not do a line of sight check! - virtual bool awarenessCheck (const MWWorld::Ptr& ptr, const MWWorld::Ptr& observer) = 0; - - /// Makes \a ptr fight \a target. Also shouts a combat taunt. - virtual void startCombat (const MWWorld::Ptr& ptr, const MWWorld::Ptr& target) = 0; - - /// Removes an actor and its allies from combat with the actor's targets. - virtual void stopCombat(const MWWorld::Ptr& ptr) = 0; - - enum OffenseType - { - OT_Theft, // Taking items owned by an NPC or a faction you are not a member of - OT_Assault, // Attacking a peaceful NPC - OT_Murder, // Murdering a peaceful NPC - OT_Trespassing, // Picking the lock of an owned door/chest - OT_SleepingInOwnedBed, // Sleeping in a bed owned by an NPC or a faction you are not a member of - OT_Pickpocket // Entering pickpocket mode, leaving it, and being detected. Any items stolen are a separate crime (Theft) - }; - /** - * @note victim may be empty - * @param arg Depends on \a type, e.g. for Theft, the value of the item that was stolen. - * @param victimAware Is the victim already aware of the crime? - * If this parameter is false, it will be determined by a line-of-sight and awareness check. - * @return was the crime seen? - */ - virtual bool commitCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, OffenseType type, - const std::string& factionId="", int arg=0, bool victimAware=false) = 0; - /// @return false if the attack was considered a "friendly hit" and forgiven - virtual bool actorAttacked (const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker) = 0; - - /// Notify that actor was killed, add a murder bounty if applicable - /// @note No-op for non-player attackers - virtual void actorKilled (const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker) = 0; - - /// Utility to check if taking this item is illegal and calling commitCrime if so - /// @param container The container the item is in; may be empty for an item in the world - virtual void itemTaken (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, const MWWorld::Ptr& container, - int count, bool alarm = true) = 0; - /// Utility to check if unlocking this object is illegal and calling commitCrime if so - virtual void unlockAttempted (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item) = 0; - /// Attempt sleeping in a bed. If this is illegal, call commitCrime. - /// @return was it illegal, and someone saw you doing it? - virtual bool sleepInBed (const MWWorld::Ptr& ptr, const MWWorld::Ptr& bed) = 0; - - enum PersuasionType - { - PT_Admire, - PT_Intimidate, - PT_Taunt, - PT_Bribe10, - PT_Bribe100, - PT_Bribe1000 - }; - virtual void getPersuasionDispositionChange (const MWWorld::Ptr& npc, PersuasionType type, bool& success, int& tempChange, int& permChange) = 0; - ///< Perform a persuasion action on NPC - - virtual void forceStateUpdate(const MWWorld::Ptr &ptr) = 0; - ///< Forces an object to refresh its animation state. - - virtual bool playAnimationGroup(const MWWorld::Ptr& ptr, std::string_view groupName, int mode, int number=1, bool persist=false) = 0; - ///< Run animation for a MW-reference. Calls to this function for references that are currently not - /// in the scene should be ignored. - /// - /// \param mode 0 normal, 1 immediate start, 2 immediate loop - /// \param count How many times the animation should be run - /// \param persist Whether the animation state should be stored in saved games - /// and persist after cell unload. - /// \return Success or error - - virtual void skipAnimation(const MWWorld::Ptr& ptr) = 0; - ///< Skip the animation for the given MW-reference for one frame. Calls to this function for - /// references that are currently not in the scene should be ignored. - - virtual bool checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string& groupName) = 0; - - /// Save the current animation state of managed references to their RefData. - virtual void persistAnimationStates() = 0; - - /// Update magic effects for an actor. Usually done automatically once per frame, but if we're currently - /// paused we may want to do it manually (after equipping permanent enchantment) - virtual void updateMagicEffects (const MWWorld::Ptr& ptr) = 0; - - virtual bool toggleAI() = 0; - virtual bool isAIActive() = 0; - - virtual void getObjectsInRange (const osg::Vec3f& position, float radius, std::vector& objects) = 0; - virtual void getActorsInRange(const osg::Vec3f &position, float radius, std::vector &objects) = 0; - - /// Check if there are actors in selected range - virtual bool isAnyActorInRange(const osg::Vec3f &position, float radius) = 0; - - ///Returns the list of actors which are siding with the given actor in fights - /**ie AiFollow or AiEscort is active and the target is the actor **/ - virtual std::vector getActorsSidingWith(const MWWorld::Ptr& actor) = 0; - virtual std::vector getActorsFollowing(const MWWorld::Ptr& actor) = 0; - virtual std::vector getActorsFollowingIndices(const MWWorld::Ptr& actor) = 0; - virtual std::map getActorsFollowingByIndex(const MWWorld::Ptr& actor) = 0; - - ///Returns a list of actors who are fighting the given actor within the fAlarmDistance - /** ie AiCombat is active and the target is the actor **/ - virtual std::vector getActorsFighting(const MWWorld::Ptr& actor) = 0; + MechanicsManager(const MechanicsManager&); + ///< not implemented + + MechanicsManager& operator=(const MechanicsManager&); + ///< not implemented + + public: + MechanicsManager() {} + + virtual ~MechanicsManager() {} + + virtual void add(const MWWorld::Ptr& ptr) = 0; + ///< Register an object for management + + virtual void remove(const MWWorld::Ptr& ptr, bool keepActive) = 0; + ///< Deregister an object for management + + virtual void updateCell(const MWWorld::Ptr& old, const MWWorld::Ptr& ptr) = 0; + ///< Moves an object to a new cell + + virtual void drop(const MWWorld::CellStore* cellStore) = 0; + ///< Deregister all objects in the given cell. + + virtual void setPlayerName(const std::string& name) = 0; + ///< Set player name. + + virtual void setPlayerRace(const std::string& id, bool male, const std::string& head, const std::string& hair) + = 0; + ///< Set player race. + + virtual void setPlayerBirthsign(const std::string& id) = 0; + ///< Set player birthsign. + + virtual void setPlayerClass(const std::string& id) = 0; + ///< Set player class to stock class. + + virtual void setPlayerClass(const ESM::Class& class_) = 0; + ///< Set player class to custom class. + + virtual void restoreDynamicStats(const MWWorld::Ptr& actor, double hours, bool sleep) = 0; + + virtual void rest(double hours, bool sleep) = 0; + ///< If the player is sleeping or waiting, this should be called every hour. + /// @param sleep is the player sleeping or waiting? + + virtual int getHoursToRest() const = 0; + ///< Calculate how many hours the player needs to rest in order to be fully healed + + virtual int getBarterOffer(const MWWorld::Ptr& ptr, int basePrice, bool buying) = 0; + ///< This is used by every service to determine the price of objects given the trading skills of the player and + ///< NPC. + + virtual int getDerivedDisposition(const MWWorld::Ptr& ptr, bool clamp = true) = 0; + ///< Calculate the diposition of an NPC toward the player. + + virtual int countDeaths(const std::string& id) const = 0; + ///< Return the number of deaths for actors with the given ID. + + /// Check if \a observer is potentially aware of \a ptr. Does not do a line of sight check! + virtual bool awarenessCheck(const MWWorld::Ptr& ptr, const MWWorld::Ptr& observer) = 0; + + /// Makes \a ptr fight \a target. Also shouts a combat taunt. + virtual void startCombat(const MWWorld::Ptr& ptr, const MWWorld::Ptr& target) = 0; + + /// Removes an actor and its allies from combat with the actor's targets. + virtual void stopCombat(const MWWorld::Ptr& ptr) = 0; + + enum OffenseType + { + OT_Theft, // Taking items owned by an NPC or a faction you are not a member of + OT_Assault, // Attacking a peaceful NPC + OT_Murder, // Murdering a peaceful NPC + OT_Trespassing, // Picking the lock of an owned door/chest + OT_SleepingInOwnedBed, // Sleeping in a bed owned by an NPC or a faction you are not a member of + OT_Pickpocket // Entering pickpocket mode, leaving it, and being detected. Any items stolen are a separate + // crime (Theft) + }; + /** + * @note victim may be empty + * @param arg Depends on \a type, e.g. for Theft, the value of the item that was stolen. + * @param victimAware Is the victim already aware of the crime? + * If this parameter is false, it will be determined by a line-of-sight and awareness check. + * @return was the crime seen? + */ + virtual bool commitCrime(const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, OffenseType type, + const std::string& factionId = "", int arg = 0, bool victimAware = false) + = 0; + /// @return false if the attack was considered a "friendly hit" and forgiven + virtual bool actorAttacked(const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker) = 0; + + /// Notify that actor was killed, add a murder bounty if applicable + /// @note No-op for non-player attackers + virtual void actorKilled(const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker) = 0; + + /// Utility to check if taking this item is illegal and calling commitCrime if so + /// @param container The container the item is in; may be empty for an item in the world + virtual void itemTaken(const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, const MWWorld::Ptr& container, + int count, bool alarm = true) + = 0; + /// Utility to check if unlocking this object is illegal and calling commitCrime if so + virtual void unlockAttempted(const MWWorld::Ptr& ptr, const MWWorld::Ptr& item) = 0; + /// Attempt sleeping in a bed. If this is illegal, call commitCrime. + /// @return was it illegal, and someone saw you doing it? + virtual bool sleepInBed(const MWWorld::Ptr& ptr, const MWWorld::Ptr& bed) = 0; - virtual std::vector getEnemiesNearby(const MWWorld::Ptr& actor) = 0; + enum PersuasionType + { + PT_Admire, + PT_Intimidate, + PT_Taunt, + PT_Bribe10, + PT_Bribe100, + PT_Bribe1000 + }; + virtual void getPersuasionDispositionChange( + const MWWorld::Ptr& npc, PersuasionType type, bool& success, int& tempChange, int& permChange) + = 0; + ///< Perform a persuasion action on NPC - /// Recursive versions of above methods - virtual void getActorsFollowing(const MWWorld::Ptr& actor, std::set& out) = 0; - virtual void getActorsSidingWith(const MWWorld::Ptr& actor, std::set& out) = 0; + virtual void forceStateUpdate(const MWWorld::Ptr& ptr) = 0; + ///< Forces an object to refresh its animation state. - virtual void playerLoaded() = 0; - - virtual int countSavedGameRecords() const = 0; + virtual bool playAnimationGroup( + const MWWorld::Ptr& ptr, std::string_view groupName, int mode, int number = 1, bool persist = false) + = 0; + ///< Run animation for a MW-reference. Calls to this function for references that are currently not + /// in the scene should be ignored. + /// + /// \param mode 0 normal, 1 immediate start, 2 immediate loop + /// \param count How many times the animation should be run + /// \param persist Whether the animation state should be stored in saved games + /// and persist after cell unload. + /// \return Success or error + + virtual void skipAnimation(const MWWorld::Ptr& ptr) = 0; + ///< Skip the animation for the given MW-reference for one frame. Calls to this function for + /// references that are currently not in the scene should be ignored. - virtual void write (ESM::ESMWriter& writer, Loading::Listener& listener) const = 0; + virtual bool checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string& groupName) = 0; + + /// Save the current animation state of managed references to their RefData. + virtual void persistAnimationStates() = 0; + + /// Update magic effects for an actor. Usually done automatically once per frame, but if we're currently + /// paused we may want to do it manually (after equipping permanent enchantment) + virtual void updateMagicEffects(const MWWorld::Ptr& ptr) = 0; + + virtual bool toggleAI() = 0; + virtual bool isAIActive() = 0; + + virtual void getObjectsInRange(const osg::Vec3f& position, float radius, std::vector& objects) + = 0; + virtual void getActorsInRange(const osg::Vec3f& position, float radius, std::vector& objects) = 0; + + /// Check if there are actors in selected range + virtual bool isAnyActorInRange(const osg::Vec3f& position, float radius) = 0; + + /// Returns the list of actors which are siding with the given actor in fights + /**ie AiFollow or AiEscort is active and the target is the actor **/ + virtual std::vector getActorsSidingWith(const MWWorld::Ptr& actor) = 0; + virtual std::vector getActorsFollowing(const MWWorld::Ptr& actor) = 0; + virtual std::vector getActorsFollowingIndices(const MWWorld::Ptr& actor) = 0; + virtual std::map getActorsFollowingByIndex(const MWWorld::Ptr& actor) = 0; + + /// Returns a list of actors who are fighting the given actor within the fAlarmDistance + /** ie AiCombat is active and the target is the actor **/ + virtual std::vector getActorsFighting(const MWWorld::Ptr& actor) = 0; + + virtual std::vector getEnemiesNearby(const MWWorld::Ptr& actor) = 0; + + /// Recursive versions of above methods + virtual void getActorsFollowing(const MWWorld::Ptr& actor, std::set& out) = 0; + virtual void getActorsSidingWith(const MWWorld::Ptr& actor, std::set& out) = 0; + + virtual void playerLoaded() = 0; + + virtual int countSavedGameRecords() const = 0; + + virtual void write(ESM::ESMWriter& writer, Loading::Listener& listener) const = 0; - virtual void readRecord (ESM::ESMReader& reader, uint32_t type) = 0; + virtual void readRecord(ESM::ESMReader& reader, uint32_t type) = 0; - virtual void clear() = 0; + virtual void clear() = 0; - virtual bool isAggressive (const MWWorld::Ptr& ptr, const MWWorld::Ptr& target) = 0; + virtual bool isAggressive(const MWWorld::Ptr& ptr, const MWWorld::Ptr& target) = 0; - /// Resurrects the player if necessary - virtual void resurrect(const MWWorld::Ptr& ptr) = 0; + /// Resurrects the player if necessary + virtual void resurrect(const MWWorld::Ptr& ptr) = 0; - virtual bool isCastingSpell (const MWWorld::Ptr& ptr) const = 0; - virtual bool isReadyToBlock (const MWWorld::Ptr& ptr) const = 0; - virtual bool isAttackingOrSpell(const MWWorld::Ptr &ptr) const = 0; + virtual bool isCastingSpell(const MWWorld::Ptr& ptr) const = 0; + virtual bool isReadyToBlock(const MWWorld::Ptr& ptr) const = 0; + virtual bool isAttackingOrSpell(const MWWorld::Ptr& ptr) const = 0; - virtual void castSpell(const MWWorld::Ptr& ptr, const std::string& spellId, bool manualSpell) = 0; + virtual void castSpell(const MWWorld::Ptr& ptr, const std::string& spellId, bool manualSpell) = 0; - virtual void processChangedSettings (const std::set< std::pair >& settings) = 0; + virtual void processChangedSettings(const std::set>& settings) = 0; - virtual float getActorsProcessingRange() const = 0; + virtual float getActorsProcessingRange() const = 0; - virtual void notifyDied(const MWWorld::Ptr& actor) = 0; + virtual void notifyDied(const MWWorld::Ptr& actor) = 0; - virtual bool onOpen(const MWWorld::Ptr& ptr) = 0; - virtual void onClose(const MWWorld::Ptr& ptr) = 0; + virtual bool onOpen(const MWWorld::Ptr& ptr) = 0; + virtual void onClose(const MWWorld::Ptr& ptr) = 0; - /// Check if the target actor was detected by an observer - /// If the observer is a non-NPC, check all actors in AI processing distance as observers - virtual bool isActorDetected(const MWWorld::Ptr& actor, const MWWorld::Ptr& observer) = 0; + /// Check if the target actor was detected by an observer + /// If the observer is a non-NPC, check all actors in AI processing distance as observers + virtual bool isActorDetected(const MWWorld::Ptr& actor, const MWWorld::Ptr& observer) = 0; - virtual void confiscateStolenItems (const MWWorld::Ptr& player, const MWWorld::Ptr& targetContainer) = 0; + virtual void confiscateStolenItems(const MWWorld::Ptr& player, const MWWorld::Ptr& targetContainer) = 0; - /// List the owners that the player has stolen this item from (the owner can be an NPC or a faction). - /// - virtual std::vector > getStolenItemOwners(const std::string& itemid) = 0; + /// List the owners that the player has stolen this item from (the owner can be an NPC or a faction). + /// + virtual std::vector> getStolenItemOwners(const std::string& itemid) = 0; - /// Has the player stolen this item from the given owner? - virtual bool isItemStolenFrom(const std::string& itemid, const MWWorld::Ptr& ptr) = 0; + /// Has the player stolen this item from the given owner? + virtual bool isItemStolenFrom(const std::string& itemid, const MWWorld::Ptr& ptr) = 0; - virtual bool isBoundItem(const MWWorld::Ptr& item) = 0; - virtual bool isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::Ptr& target, MWWorld::Ptr& victim) = 0; + virtual bool isBoundItem(const MWWorld::Ptr& item) = 0; + virtual bool isAllowedToUse(const MWWorld::Ptr& ptr, const MWWorld::Ptr& target, MWWorld::Ptr& victim) = 0; - /// Turn actor into werewolf or normal form. - virtual void setWerewolf(const MWWorld::Ptr& actor, bool werewolf) = 0; + /// Turn actor into werewolf or normal form. + virtual void setWerewolf(const MWWorld::Ptr& actor, bool werewolf) = 0; - /// Sets the NPC's Acrobatics skill to match the fWerewolfAcrobatics GMST. - /// It only applies to the current form the NPC is in. - virtual void applyWerewolfAcrobatics(const MWWorld::Ptr& actor) = 0; + /// Sets the NPC's Acrobatics skill to match the fWerewolfAcrobatics GMST. + /// It only applies to the current form the NPC is in. + virtual void applyWerewolfAcrobatics(const MWWorld::Ptr& actor) = 0; - virtual void cleanupSummonedCreature(const MWWorld::Ptr& caster, int creatureActorId) = 0; + virtual void cleanupSummonedCreature(const MWWorld::Ptr& caster, int creatureActorId) = 0; - virtual void confiscateStolenItemToOwner(const MWWorld::Ptr &player, const MWWorld::Ptr &item, const MWWorld::Ptr& victim, int count) = 0; - virtual bool isAttackPreparing(const MWWorld::Ptr& ptr) = 0; - virtual bool isRunning(const MWWorld::Ptr& ptr) = 0; - virtual bool isSneaking(const MWWorld::Ptr& ptr) = 0; + virtual void confiscateStolenItemToOwner( + const MWWorld::Ptr& player, const MWWorld::Ptr& item, const MWWorld::Ptr& victim, int count) + = 0; + virtual bool isAttackPreparing(const MWWorld::Ptr& ptr) = 0; + virtual bool isRunning(const MWWorld::Ptr& ptr) = 0; + virtual bool isSneaking(const MWWorld::Ptr& ptr) = 0; - virtual void reportStats(unsigned int frameNumber, osg::Stats& stats) const = 0; + virtual void reportStats(unsigned int frameNumber, osg::Stats& stats) const = 0; - virtual int getGreetingTimer(const MWWorld::Ptr& ptr) const = 0; - virtual float getAngleToPlayer(const MWWorld::Ptr& ptr) const = 0; - virtual MWMechanics::GreetingState getGreetingState(const MWWorld::Ptr& ptr) const = 0; - virtual bool isTurningToPlayer(const MWWorld::Ptr& ptr) const = 0; + virtual int getGreetingTimer(const MWWorld::Ptr& ptr) const = 0; + virtual float getAngleToPlayer(const MWWorld::Ptr& ptr) const = 0; + virtual MWMechanics::GreetingState getGreetingState(const MWWorld::Ptr& ptr) const = 0; + virtual bool isTurningToPlayer(const MWWorld::Ptr& ptr) const = 0; }; } diff --git a/apps/openmw/mwbase/scriptmanager.hpp b/apps/openmw/mwbase/scriptmanager.hpp index be62722139..b727de87c2 100644 --- a/apps/openmw/mwbase/scriptmanager.hpp +++ b/apps/openmw/mwbase/scriptmanager.hpp @@ -24,38 +24,37 @@ namespace MWBase /// \brief Interface for script manager (implemented in MWScript) class ScriptManager { - ScriptManager (const ScriptManager&); - ///< not implemented + ScriptManager(const ScriptManager&); + ///< not implemented - ScriptManager& operator= (const ScriptManager&); - ///< not implemented + ScriptManager& operator=(const ScriptManager&); + ///< not implemented - public: + public: + ScriptManager() {} - ScriptManager() {} + virtual ~ScriptManager() {} - virtual ~ScriptManager() {} + virtual void clear() = 0; - virtual void clear() = 0; + virtual bool run(std::string_view name, Interpreter::Context& interpreterContext) = 0; + ///< Run the script with the given name (compile first, if not compiled yet) - virtual bool run(std::string_view name, Interpreter::Context& interpreterContext) = 0; - ///< Run the script with the given name (compile first, if not compiled yet) + virtual bool compile(std::string_view name) = 0; + ///< Compile script with the given namen + /// \return Success? - virtual bool compile(std::string_view name) = 0; - ///< Compile script with the given namen - /// \return Success? + virtual std::pair compileAll() = 0; + ///< Compile all scripts + /// \return count, success - virtual std::pair compileAll() = 0; - ///< Compile all scripts - /// \return count, success + virtual const Compiler::Locals& getLocals(std::string_view name) = 0; + ///< Return locals for script \a name. - virtual const Compiler::Locals& getLocals(std::string_view name) = 0; - ///< Return locals for script \a name. + virtual MWScript::GlobalScripts& getGlobalScripts() = 0; - virtual MWScript::GlobalScripts& getGlobalScripts() = 0; - - virtual const Compiler::Extensions& getExtensions() const = 0; - }; + virtual const Compiler::Extensions& getExtensions() const = 0; + }; } #endif diff --git a/apps/openmw/mwbase/soundmanager.hpp b/apps/openmw/mwbase/soundmanager.hpp index a60ed78154..4035a89abb 100644 --- a/apps/openmw/mwbase/soundmanager.hpp +++ b/apps/openmw/mwbase/soundmanager.hpp @@ -2,12 +2,12 @@ #define GAME_MWBASE_SOUNDMANAGER_H #include +#include #include #include -#include -#include "../mwworld/ptr.hpp" #include "../mwsound/type.hpp" +#include "../mwworld/ptr.hpp" namespace MWWorld { @@ -30,30 +30,43 @@ namespace MWSound typedef std::shared_ptr DecoderPtr; /* These must all fit together */ - enum class PlayMode { - Normal = 0, /* non-looping, affected by environment */ - Loop = 1<<0, /* Sound will continually loop until explicitly stopped */ - NoEnv = 1<<1, /* Do not apply environment effects (eg, underwater filters) */ - RemoveAtDistance = 1<<2, /* (3D only) If the listener gets further than 2000 units away - * from the sound source, the sound is removed. - * This is weird stuff but apparently how vanilla works for sounds - * played by the PlayLoopSound family of script functions. Perhaps - * we can make this cut off a more subtle fade later, but have to - * be careful to not change the overall volume of areas by too - * much. */ - NoPlayerLocal = 1<<3, /* (3D only) Don't play the sound local to the listener even if the - * player is making it. */ - NoScaling = 1<<4, /* Don't scale audio with simulation time */ + enum class PlayMode + { + Normal = 0, /* non-looping, affected by environment */ + Loop = 1 << 0, /* Sound will continually loop until explicitly stopped */ + NoEnv = 1 << 1, /* Do not apply environment effects (eg, underwater filters) */ + RemoveAtDistance = 1 << 2, /* (3D only) If the listener gets further than 2000 units away + * from the sound source, the sound is removed. + * This is weird stuff but apparently how vanilla works for sounds + * played by the PlayLoopSound family of script functions. Perhaps + * we can make this cut off a more subtle fade later, but have to + * be careful to not change the overall volume of areas by too + * much. */ + NoPlayerLocal = 1 << 3, /* (3D only) Don't play the sound local to the listener even if the + * player is making it. */ + NoScaling = 1 << 4, /* Don't scale audio with simulation time */ NoEnvNoScaling = NoEnv | NoScaling, LoopNoEnv = Loop | NoEnv, LoopRemoveAtDistance = Loop | RemoveAtDistance }; // Used for creating a type mask for SoundManager::pauseSounds and resumeSounds - inline int operator~(Type a) { return ~static_cast(a); } - inline int operator&(Type a, Type b) { return static_cast(a) & static_cast(b); } - inline int operator&(int a, Type b) { return a & static_cast(b); } - inline int operator|(Type a, Type b) { return static_cast(a) | static_cast(b); } + inline int operator~(Type a) + { + return ~static_cast(a); + } + inline int operator&(Type a, Type b) + { + return static_cast(a) & static_cast(b); + } + inline int operator&(int a, Type b) + { + return a & static_cast(b); + } + inline int operator|(Type a, Type b) + { + return static_cast(a) | static_cast(b); + } } namespace MWBase @@ -64,131 +77,135 @@ namespace MWBase /// \brief Interface for sound manager (implemented in MWSound) class SoundManager { - SoundManager (const SoundManager&); - ///< not implemented + SoundManager(const SoundManager&); + ///< not implemented - SoundManager& operator= (const SoundManager&); - ///< not implemented + SoundManager& operator=(const SoundManager&); + ///< not implemented - protected: - using PlayMode = MWSound::PlayMode; - using Type = MWSound::Type; + protected: + using PlayMode = MWSound::PlayMode; + using Type = MWSound::Type; - float mSimulationTimeScale = 1.0; + float mSimulationTimeScale = 1.0; - public: - SoundManager() {} - virtual ~SoundManager() {} + public: + SoundManager() {} + virtual ~SoundManager() {} - virtual void processChangedSettings(const std::set< std::pair >& settings) = 0; + virtual void processChangedSettings(const std::set>& settings) = 0; - virtual void stopMusic() = 0; - ///< Stops music if it's playing + virtual void stopMusic() = 0; + ///< Stops music if it's playing - virtual void streamMusic(const std::string& filename) = 0; - ///< Play a soundifle - /// \param filename name of a sound file in "Music/" in the data directory. + virtual void streamMusic(const std::string& filename) = 0; + ///< Play a soundifle + /// \param filename name of a sound file in "Music/" in the data directory. - virtual bool isMusicPlaying() = 0; - ///< Returns true if music is playing + virtual bool isMusicPlaying() = 0; + ///< Returns true if music is playing - virtual void playPlaylist(const std::string &playlist) = 0; - ///< Start playing music from the selected folder - /// \param name of the folder that contains the playlist + virtual void playPlaylist(const std::string& playlist) = 0; + ///< Start playing music from the selected folder + /// \param name of the folder that contains the playlist - virtual void playTitleMusic() = 0; - ///< Start playing title music + virtual void playTitleMusic() = 0; + ///< Start playing title music - virtual void say(const MWWorld::ConstPtr &reference, const std::string& filename) = 0; - ///< Make an actor say some text. - /// \param filename name of a sound file in "Sound/" in the data directory. + virtual void say(const MWWorld::ConstPtr& reference, const std::string& filename) = 0; + ///< Make an actor say some text. + /// \param filename name of a sound file in "Sound/" in the data directory. - virtual void say(const std::string& filename) = 0; - ///< Say some text, without an actor ref - /// \param filename name of a sound file in "Sound/" in the data directory. + virtual void say(const std::string& filename) = 0; + ///< Say some text, without an actor ref + /// \param filename name of a sound file in "Sound/" in the data directory. - virtual bool sayActive(const MWWorld::ConstPtr &reference=MWWorld::ConstPtr()) const = 0; - ///< Is actor not speaking? + virtual bool sayActive(const MWWorld::ConstPtr& reference = MWWorld::ConstPtr()) const = 0; + ///< Is actor not speaking? - virtual bool sayDone(const MWWorld::ConstPtr &reference=MWWorld::ConstPtr()) const = 0; - ///< For scripting backward compatibility + virtual bool sayDone(const MWWorld::ConstPtr& reference = MWWorld::ConstPtr()) const = 0; + ///< For scripting backward compatibility - virtual void stopSay(const MWWorld::ConstPtr &reference=MWWorld::ConstPtr()) = 0; - ///< Stop an actor speaking + virtual void stopSay(const MWWorld::ConstPtr& reference = MWWorld::ConstPtr()) = 0; + ///< Stop an actor speaking - virtual float getSaySoundLoudness(const MWWorld::ConstPtr& reference) const = 0; - ///< Check the currently playing say sound for this actor - /// and get an average loudness value (scale [0,1]) at the current time position. - /// If the actor is not saying anything, returns 0. + virtual float getSaySoundLoudness(const MWWorld::ConstPtr& reference) const = 0; + ///< Check the currently playing say sound for this actor + /// and get an average loudness value (scale [0,1]) at the current time position. + /// If the actor is not saying anything, returns 0. - virtual SoundStream *playTrack(const MWSound::DecoderPtr& decoder, Type type) = 0; - ///< Play a 2D audio track, using a custom decoder. The caller is expected to call - /// stopTrack with the returned handle when done. + virtual SoundStream* playTrack(const MWSound::DecoderPtr& decoder, Type type) = 0; + ///< Play a 2D audio track, using a custom decoder. The caller is expected to call + /// stopTrack with the returned handle when done. - virtual void stopTrack(SoundStream *stream) = 0; - ///< Stop the given audio track from playing + virtual void stopTrack(SoundStream* stream) = 0; + ///< Stop the given audio track from playing - virtual double getTrackTimeDelay(SoundStream *stream) = 0; - ///< Retives the time delay, in seconds, of the audio track (must be a sound - /// returned by \ref playTrack). Only intended to be called by the track - /// decoder's read method. + virtual double getTrackTimeDelay(SoundStream* stream) = 0; + ///< Retives the time delay, in seconds, of the audio track (must be a sound + /// returned by \ref playTrack). Only intended to be called by the track + /// decoder's read method. - virtual Sound *playSound(std::string_view soundId, float volume, float pitch, - Type type=Type::Sfx, PlayMode mode=PlayMode::Normal, - float offset=0) = 0; - ///< Play a sound, independently of 3D-position - ///< @param offset Number of seconds into the sound to start playback. + virtual Sound* playSound(std::string_view soundId, float volume, float pitch, Type type = Type::Sfx, + PlayMode mode = PlayMode::Normal, float offset = 0) + = 0; + ///< Play a sound, independently of 3D-position + ///< @param offset Number of seconds into the sound to start playback. - virtual Sound *playSound3D(const MWWorld::ConstPtr &reference, std::string_view soundId, - float volume, float pitch, Type type=Type::Sfx, - PlayMode mode=PlayMode::Normal, float offset=0) = 0; - ///< Play a 3D sound attached to an MWWorld::Ptr. Will be updated automatically with the Ptr's position, unless Play_NoTrack is specified. - ///< @param offset Number of seconds into the sound to start playback. + virtual Sound* playSound3D(const MWWorld::ConstPtr& reference, std::string_view soundId, float volume, + float pitch, Type type = Type::Sfx, PlayMode mode = PlayMode::Normal, float offset = 0) + = 0; + ///< Play a 3D sound attached to an MWWorld::Ptr. Will be updated automatically with the Ptr's position, unless + ///< Play_NoTrack is specified. + ///< @param offset Number of seconds into the sound to start playback. - virtual Sound *playSound3D(const osg::Vec3f& initialPos, std::string_view soundId, - float volume, float pitch, Type type=Type::Sfx, - PlayMode mode=PlayMode::Normal, float offset=0) = 0; - ///< Play a 3D sound at \a initialPos. If the sound should be moving, it must be updated using Sound::setPosition. + virtual Sound* playSound3D(const osg::Vec3f& initialPos, std::string_view soundId, float volume, float pitch, + Type type = Type::Sfx, PlayMode mode = PlayMode::Normal, float offset = 0) + = 0; + ///< Play a 3D sound at \a initialPos. If the sound should be moving, it must be updated using + ///< Sound::setPosition. - virtual void stopSound(Sound *sound) = 0; - ///< Stop the given sound from playing + virtual void stopSound(Sound* sound) = 0; + ///< Stop the given sound from playing - virtual void stopSound3D(const MWWorld::ConstPtr &reference, std::string_view soundId) = 0; - ///< Stop the given object from playing the given sound, + virtual void stopSound3D(const MWWorld::ConstPtr& reference, std::string_view soundId) = 0; + ///< Stop the given object from playing the given sound, - virtual void stopSound3D(const MWWorld::ConstPtr &reference) = 0; - ///< Stop the given object from playing all sounds. + virtual void stopSound3D(const MWWorld::ConstPtr& reference) = 0; + ///< Stop the given object from playing all sounds. - virtual void stopSound(const MWWorld::CellStore *cell) = 0; - ///< Stop all sounds for the given cell. + virtual void stopSound(const MWWorld::CellStore* cell) = 0; + ///< Stop all sounds for the given cell. - virtual void fadeOutSound3D(const MWWorld::ConstPtr &reference, std::string_view soundId, float duration) = 0; - ///< Fade out given sound (that is already playing) of given object - ///< @param reference Reference to object, whose sound is faded out - ///< @param soundId ID of the sound to fade out. - ///< @param duration Time until volume reaches 0. + virtual void fadeOutSound3D(const MWWorld::ConstPtr& reference, std::string_view soundId, float duration) = 0; + ///< Fade out given sound (that is already playing) of given object + ///< @param reference Reference to object, whose sound is faded out + ///< @param soundId ID of the sound to fade out. + ///< @param duration Time until volume reaches 0. - virtual bool getSoundPlaying(const MWWorld::ConstPtr &reference, std::string_view soundId) const = 0; - ///< Is the given sound currently playing on the given object? - /// If you want to check if sound played with playSound is playing, use empty Ptr + virtual bool getSoundPlaying(const MWWorld::ConstPtr& reference, std::string_view soundId) const = 0; + ///< Is the given sound currently playing on the given object? + /// If you want to check if sound played with playSound is playing, use empty Ptr - virtual void pauseSounds(MWSound::BlockerType blocker, int types=int(Type::Mask)) = 0; - ///< Pauses all currently playing sounds, including music. + virtual void pauseSounds(MWSound::BlockerType blocker, int types = int(Type::Mask)) = 0; + ///< Pauses all currently playing sounds, including music. - virtual void resumeSounds(MWSound::BlockerType blocker) = 0; - ///< Resumes all previously paused sounds. + virtual void resumeSounds(MWSound::BlockerType blocker) = 0; + ///< Resumes all previously paused sounds. - virtual void pausePlayback() = 0; - virtual void resumePlayback() = 0; + virtual void pausePlayback() = 0; + virtual void resumePlayback() = 0; - virtual void setListenerPosDir(const osg::Vec3f &pos, const osg::Vec3f &dir, const osg::Vec3f &up, bool underwater) = 0; + virtual void setListenerPosDir( + const osg::Vec3f& pos, const osg::Vec3f& dir, const osg::Vec3f& up, bool underwater) + = 0; - virtual void updatePtr(const MWWorld::ConstPtr& old, const MWWorld::ConstPtr& updated) = 0; + virtual void updatePtr(const MWWorld::ConstPtr& old, const MWWorld::ConstPtr& updated) = 0; - void setSimulationTimeScale(float scale) { mSimulationTimeScale = scale; } - float getSimulationTimeScale() const { return mSimulationTimeScale; } + void setSimulationTimeScale(float scale) { mSimulationTimeScale = scale; } + float getSimulationTimeScale() const { return mSimulationTimeScale; } - virtual void clear() = 0; + virtual void clear() = 0; }; } diff --git a/apps/openmw/mwbase/statemanager.hpp b/apps/openmw/mwbase/statemanager.hpp index df4df0943d..264549a82a 100644 --- a/apps/openmw/mwbase/statemanager.hpp +++ b/apps/openmw/mwbase/statemanager.hpp @@ -15,77 +15,74 @@ namespace MWBase /// \brief Interface for game state manager (implemented in MWState) class StateManager { - public: + public: + enum State + { + State_NoGame, + State_Ended, + State_Running + }; - enum State - { - State_NoGame, - State_Ended, - State_Running - }; + typedef std::list::const_iterator CharacterIterator; - typedef std::list::const_iterator CharacterIterator; + private: + StateManager(const StateManager&); + ///< not implemented - private: + StateManager& operator=(const StateManager&); + ///< not implemented - StateManager (const StateManager&); - ///< not implemented + public: + StateManager() {} - StateManager& operator= (const StateManager&); - ///< not implemented + virtual ~StateManager() {} - public: + virtual void requestQuit() = 0; - StateManager() {} + virtual bool hasQuitRequest() const = 0; - virtual ~StateManager() {} + virtual void askLoadRecent() = 0; - virtual void requestQuit() = 0; + virtual State getState() const = 0; - virtual bool hasQuitRequest() const = 0; + virtual void newGame(bool bypass = false) = 0; + ///< Start a new game. + /// + /// \param bypass Skip new game mechanics. - virtual void askLoadRecent() = 0; + virtual void resumeGame() = 0; - virtual State getState() const = 0; + virtual void deleteGame(const MWState::Character* character, const MWState::Slot* slot) = 0; - virtual void newGame (bool bypass = false) = 0; - ///< Start a new game. - /// - /// \param bypass Skip new game mechanics. + virtual void saveGame(const std::string& description, const MWState::Slot* slot = nullptr) = 0; + ///< Write a saved game to \a slot or create a new slot if \a slot == 0. + /// + /// \note Slot must belong to the current character. - virtual void resumeGame() = 0; + virtual void loadGame(const std::filesystem::path& filepath) = 0; + ///< Load a saved game directly from the given file path. This will search the CharacterManager + /// for a Character containing this save file, and set this Character current if one was found. + /// Otherwise, a new Character will be created. - virtual void deleteGame (const MWState::Character *character, const MWState::Slot *slot) = 0; + virtual void loadGame(const MWState::Character* character, const std::filesystem::path& filepath) = 0; + ///< Load a saved game file belonging to the given character. - virtual void saveGame (const std::string& description, const MWState::Slot *slot = nullptr) = 0; - ///< Write a saved game to \a slot or create a new slot if \a slot == 0. - /// - /// \note Slot must belong to the current character. + /// Simple saver, writes over the file if already existing + /** Used for quick save and autosave **/ + virtual void quickSave(std::string = "Quicksave") = 0; - virtual void loadGame (const std::filesystem::path &filepath) = 0; - ///< Load a saved game directly from the given file path. This will search the CharacterManager - /// for a Character containing this save file, and set this Character current if one was found. - /// Otherwise, a new Character will be created. + /// Simple loader, loads the last saved file + /** Used for quickload **/ + virtual void quickLoad() = 0; - virtual void loadGame (const MWState::Character *character, const std::filesystem::path &filepath) = 0; - ///< Load a saved game file belonging to the given character. + virtual MWState::Character* getCurrentCharacter() = 0; + ///< @note May return null. - ///Simple saver, writes over the file if already existing - /** Used for quick save and autosave **/ - virtual void quickSave(std::string = "Quicksave")=0; + virtual CharacterIterator characterBegin() = 0; + ///< Any call to SaveGame and getCurrentCharacter can invalidate the returned + /// iterator. - ///Simple loader, loads the last saved file - /** Used for quickload **/ - virtual void quickLoad()=0; - - virtual MWState::Character *getCurrentCharacter () = 0; - ///< @note May return null. - - virtual CharacterIterator characterBegin() = 0; - ///< Any call to SaveGame and getCurrentCharacter can invalidate the returned - /// iterator. - - virtual CharacterIterator characterEnd() = 0; + virtual CharacterIterator characterEnd() = 0; }; } diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index efca05d0cd..77d8de6c48 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -2,11 +2,11 @@ #define GAME_MWBASE_WINDOWMANAGER_H #include -#include -#include #include -#include #include +#include +#include +#include #include @@ -41,7 +41,7 @@ namespace ESM namespace MWMechanics { class AttributeValue; - template + template class DynamicStat; class SkillValue; } @@ -73,7 +73,8 @@ namespace MWGui class MessageBox; class PostProcessorHud; - enum ShowInDialogueMode { + enum ShowInDialogueMode + { ShowInDialogueMode_IfPossible, ShowInDialogueMode_Only, ShowInDialogueMode_Never @@ -92,282 +93,288 @@ namespace MWBase /// \brief Interface for widnow manager (implemented in MWGui) class WindowManager : public SDLUtil::WindowListener { - WindowManager (const WindowManager&); - ///< not implemented - - WindowManager& operator= (const WindowManager&); - ///< not implemented + WindowManager(const WindowManager&); + ///< not implemented - public: + WindowManager& operator=(const WindowManager&); + ///< not implemented - typedef std::vector SkillList; + public: + typedef std::vector SkillList; - WindowManager() {} + WindowManager() {} - virtual ~WindowManager() {} + virtual ~WindowManager() {} - /// @note This method will block until the video finishes playing - /// (and will continually update the window while doing so) - virtual void playVideo(std::string_view name, bool allowSkipping, bool overrideSounds = true) = 0; + /// @note This method will block until the video finishes playing + /// (and will continually update the window while doing so) + virtual void playVideo(std::string_view name, bool allowSkipping, bool overrideSounds = true) = 0; - virtual void setNewGame(bool newgame) = 0; + virtual void setNewGame(bool newgame) = 0; - virtual void pushGuiMode (MWGui::GuiMode mode, const MWWorld::Ptr& arg) = 0; - virtual void pushGuiMode (MWGui::GuiMode mode) = 0; - virtual void popGuiMode(bool noSound=false) = 0; + virtual void pushGuiMode(MWGui::GuiMode mode, const MWWorld::Ptr& arg) = 0; + virtual void pushGuiMode(MWGui::GuiMode mode) = 0; + virtual void popGuiMode(bool noSound = false) = 0; - virtual void removeGuiMode (MWGui::GuiMode mode, bool noSound=false) = 0; - ///< can be anywhere in the stack + virtual void removeGuiMode(MWGui::GuiMode mode, bool noSound = false) = 0; + ///< can be anywhere in the stack - virtual void goToJail(int days) = 0; + virtual void goToJail(int days) = 0; - virtual void updatePlayer() = 0; + virtual void updatePlayer() = 0; - virtual MWGui::GuiMode getMode() const = 0; - virtual bool containsMode(MWGui::GuiMode) const = 0; + virtual MWGui::GuiMode getMode() const = 0; + virtual bool containsMode(MWGui::GuiMode) const = 0; - virtual bool isGuiMode() const = 0; + virtual bool isGuiMode() const = 0; - virtual bool isConsoleMode() const = 0; + virtual bool isConsoleMode() const = 0; - virtual bool isPostProcessorHudVisible() const = 0; + virtual bool isPostProcessorHudVisible() const = 0; - virtual void toggleVisible (MWGui::GuiWindow wnd) = 0; + virtual void toggleVisible(MWGui::GuiWindow wnd) = 0; - virtual void forceHide(MWGui::GuiWindow wnd) = 0; - virtual void unsetForceHide(MWGui::GuiWindow wnd) = 0; + virtual void forceHide(MWGui::GuiWindow wnd) = 0; + virtual void unsetForceHide(MWGui::GuiWindow wnd) = 0; - /// Disallow all inventory mode windows - virtual void disallowAll() = 0; + /// Disallow all inventory mode windows + virtual void disallowAll() = 0; - /// Allow one or more windows - virtual void allow (MWGui::GuiWindow wnd) = 0; + /// Allow one or more windows + virtual void allow(MWGui::GuiWindow wnd) = 0; - virtual bool isAllowed (MWGui::GuiWindow wnd) const = 0; + virtual bool isAllowed(MWGui::GuiWindow wnd) const = 0; - /// \todo investigate, if we really need to expose every single lousy UI element to the outside world - virtual MWGui::InventoryWindow* getInventoryWindow() = 0; - virtual MWGui::CountDialog* getCountDialog() = 0; - virtual MWGui::ConfirmationDialog* getConfirmationDialog() = 0; - virtual MWGui::TradeWindow* getTradeWindow() = 0; - virtual const std::vector>& getActiveMessageBoxes() const = 0; - virtual MWGui::PostProcessorHud* getPostProcessorHud() = 0; + /// \todo investigate, if we really need to expose every single lousy UI element to the outside world + virtual MWGui::InventoryWindow* getInventoryWindow() = 0; + virtual MWGui::CountDialog* getCountDialog() = 0; + virtual MWGui::ConfirmationDialog* getConfirmationDialog() = 0; + virtual MWGui::TradeWindow* getTradeWindow() = 0; + virtual const std::vector>& getActiveMessageBoxes() const = 0; + virtual MWGui::PostProcessorHud* getPostProcessorHud() = 0; - /// Make the player use an item, while updating GUI state accordingly - virtual void useItem(const MWWorld::Ptr& item, bool force=false) = 0; + /// Make the player use an item, while updating GUI state accordingly + virtual void useItem(const MWWorld::Ptr& item, bool force = false) = 0; - virtual void updateSpellWindow() = 0; + virtual void updateSpellWindow() = 0; - virtual void setConsoleSelectedObject(const MWWorld::Ptr& object) = 0; - virtual void setConsoleMode(const std::string& mode) = 0; + virtual void setConsoleSelectedObject(const MWWorld::Ptr& object) = 0; + virtual void setConsoleMode(const std::string& mode) = 0; - static constexpr std::string_view sConsoleColor_Default = "#FFFFFF"; - static constexpr std::string_view sConsoleColor_Error = "#FF2222"; - static constexpr std::string_view sConsoleColor_Success = "#FF00FF"; - static constexpr std::string_view sConsoleColor_Info = "#AAAAAA"; - virtual void printToConsole(const std::string& msg, std::string_view color) = 0; + static constexpr std::string_view sConsoleColor_Default = "#FFFFFF"; + static constexpr std::string_view sConsoleColor_Error = "#FF2222"; + static constexpr std::string_view sConsoleColor_Success = "#FF00FF"; + static constexpr std::string_view sConsoleColor_Info = "#AAAAAA"; + virtual void printToConsole(const std::string& msg, std::string_view color) = 0; - /// Set time left for the player to start drowning (update the drowning bar) - /// @param time time left to start drowning - /// @param maxTime how long we can be underwater (in total) until drowning starts - virtual void setDrowningTimeLeft (float time, float maxTime) = 0; + /// Set time left for the player to start drowning (update the drowning bar) + /// @param time time left to start drowning + /// @param maxTime how long we can be underwater (in total) until drowning starts + virtual void setDrowningTimeLeft(float time, float maxTime) = 0; - virtual void changeCell(const MWWorld::CellStore* cell) = 0; - ///< change the active cell + virtual void changeCell(const MWWorld::CellStore* cell) = 0; + ///< change the active cell - virtual void setFocusObject(const MWWorld::Ptr& focus) = 0; - virtual void setFocusObjectScreenCoords(float min_x, float min_y, float max_x, float max_y) = 0; + virtual void setFocusObject(const MWWorld::Ptr& focus) = 0; + virtual void setFocusObjectScreenCoords(float min_x, float min_y, float max_x, float max_y) = 0; - virtual void setCursorVisible(bool visible) = 0; - virtual void setCursorActive(bool active) = 0; - virtual void getMousePosition(int &x, int &y) = 0; - virtual void getMousePosition(float &x, float &y) = 0; - virtual void setDragDrop(bool dragDrop) = 0; - virtual bool getWorldMouseOver() = 0; + virtual void setCursorVisible(bool visible) = 0; + virtual void setCursorActive(bool active) = 0; + virtual void getMousePosition(int& x, int& y) = 0; + virtual void getMousePosition(float& x, float& y) = 0; + virtual void setDragDrop(bool dragDrop) = 0; + virtual bool getWorldMouseOver() = 0; - virtual float getScalingFactor() const = 0; + virtual float getScalingFactor() const = 0; - virtual bool toggleFogOfWar() = 0; + virtual bool toggleFogOfWar() = 0; - virtual bool toggleFullHelp() = 0; - ///< show extra info in item tooltips (owner, script) + virtual bool toggleFullHelp() = 0; + ///< show extra info in item tooltips (owner, script) - virtual bool getFullHelp() const = 0; + virtual bool getFullHelp() const = 0; - virtual void setActiveMap(int x, int y, bool interior) = 0; - ///< set the indices of the map texture that should be used + virtual void setActiveMap(int x, int y, bool interior) = 0; + ///< set the indices of the map texture that should be used - /// sets the visibility of the drowning bar - virtual void setDrowningBarVisibility(bool visible) = 0; + /// sets the visibility of the drowning bar + virtual void setDrowningBarVisibility(bool visible) = 0; - /// sets the visibility of the hud health/magicka/stamina bars - virtual void setHMSVisibility(bool visible) = 0; + /// sets the visibility of the hud health/magicka/stamina bars + virtual void setHMSVisibility(bool visible) = 0; - /// sets the visibility of the hud minimap - virtual void setMinimapVisibility(bool visible) = 0; - virtual void setWeaponVisibility(bool visible) = 0; - virtual void setSpellVisibility(bool visible) = 0; - virtual void setSneakVisibility(bool visible) = 0; + /// sets the visibility of the hud minimap + virtual void setMinimapVisibility(bool visible) = 0; + virtual void setWeaponVisibility(bool visible) = 0; + virtual void setSpellVisibility(bool visible) = 0; + virtual void setSneakVisibility(bool visible) = 0; - /// activate selected quick key - virtual void activateQuickKey (int index) = 0; - /// update activated quick key state (if action executing was delayed for some reason) - virtual void updateActivatedQuickKey () = 0; + /// activate selected quick key + virtual void activateQuickKey(int index) = 0; + /// update activated quick key state (if action executing was delayed for some reason) + virtual void updateActivatedQuickKey() = 0; - virtual const std::string& getSelectedSpell() = 0; - virtual void setSelectedSpell(const std::string& spellId, int successChancePercent) = 0; - virtual void setSelectedEnchantItem(const MWWorld::Ptr& item) = 0; - virtual const MWWorld::Ptr& getSelectedEnchantItem() const = 0; - virtual void setSelectedWeapon(const MWWorld::Ptr& item) = 0; - virtual const MWWorld::Ptr& getSelectedWeapon() const = 0; - virtual int getFontHeight() const = 0; - virtual void unsetSelectedSpell() = 0; - virtual void unsetSelectedWeapon() = 0; + virtual const std::string& getSelectedSpell() = 0; + virtual void setSelectedSpell(const std::string& spellId, int successChancePercent) = 0; + virtual void setSelectedEnchantItem(const MWWorld::Ptr& item) = 0; + virtual const MWWorld::Ptr& getSelectedEnchantItem() const = 0; + virtual void setSelectedWeapon(const MWWorld::Ptr& item) = 0; + virtual const MWWorld::Ptr& getSelectedWeapon() const = 0; + virtual int getFontHeight() const = 0; + virtual void unsetSelectedSpell() = 0; + virtual void unsetSelectedWeapon() = 0; - virtual void showCrosshair(bool show) = 0; - virtual bool getSubtitlesEnabled() = 0; - virtual bool toggleHud() = 0; + virtual void showCrosshair(bool show) = 0; + virtual bool getSubtitlesEnabled() = 0; + virtual bool toggleHud() = 0; - virtual void disallowMouse() = 0; - virtual void allowMouse() = 0; - virtual void notifyInputActionBound() = 0; + virtual void disallowMouse() = 0; + virtual void allowMouse() = 0; + virtual void notifyInputActionBound() = 0; - virtual void addVisitedLocation(const std::string& name, int x, int y) = 0; + virtual void addVisitedLocation(const std::string& name, int x, int y) = 0; - /// Hides dialog and schedules dialog to be deleted. - virtual void removeDialog(std::unique_ptr&& dialog) = 0; + /// Hides dialog and schedules dialog to be deleted. + virtual void removeDialog(std::unique_ptr&& dialog) = 0; - ///Gracefully attempts to exit the topmost GUI mode - /** No guarantee of actually closing the window **/ - virtual void exitCurrentGuiMode() = 0; + /// Gracefully attempts to exit the topmost GUI mode + /** No guarantee of actually closing the window **/ + virtual void exitCurrentGuiMode() = 0; - virtual void messageBox(std::string_view message, enum MWGui::ShowInDialogueMode showInDialogueMode = MWGui::ShowInDialogueMode_IfPossible) = 0; - /// Puts message into a queue to show on the next update. Thread safe alternative for messageBox. - virtual void scheduleMessageBox(std::string message, enum MWGui::ShowInDialogueMode showInDialogueMode = MWGui::ShowInDialogueMode_IfPossible) = 0; - virtual void staticMessageBox(std::string_view message) = 0; - virtual void removeStaticMessageBox() = 0; - virtual void interactiveMessageBox(std::string_view message, const std::vector& buttons = {}, bool block = false) = 0; + virtual void messageBox(std::string_view message, + enum MWGui::ShowInDialogueMode showInDialogueMode = MWGui::ShowInDialogueMode_IfPossible) + = 0; + /// Puts message into a queue to show on the next update. Thread safe alternative for messageBox. + virtual void scheduleMessageBox(std::string message, + enum MWGui::ShowInDialogueMode showInDialogueMode = MWGui::ShowInDialogueMode_IfPossible) + = 0; + virtual void staticMessageBox(std::string_view message) = 0; + virtual void removeStaticMessageBox() = 0; + virtual void interactiveMessageBox( + std::string_view message, const std::vector& buttons = {}, bool block = false) + = 0; - /// returns the index of the pressed button or -1 if no button was pressed (->MessageBoxmanager->InteractiveMessageBox) - virtual int readPressedButton() = 0; + /// returns the index of the pressed button or -1 if no button was pressed + /// (->MessageBoxmanager->InteractiveMessageBox) + virtual int readPressedButton() = 0; - virtual void updateConsoleObjectPtr(const MWWorld::Ptr& currentPtr, const MWWorld::Ptr& newPtr) = 0; + virtual void updateConsoleObjectPtr(const MWWorld::Ptr& currentPtr, const MWWorld::Ptr& newPtr) = 0; - /** - * Fetches a GMST string from the store, if there is no setting with the given - * ID or it is not a string the default string is returned. - * - * @param id Identifier for the GMST setting, e.g. "aName" - * @param default Default value if the GMST setting cannot be used. - */ - virtual std::string_view getGameSettingString(std::string_view id, std::string_view default_) = 0; + /** + * Fetches a GMST string from the store, if there is no setting with the given + * ID or it is not a string the default string is returned. + * + * @param id Identifier for the GMST setting, e.g. "aName" + * @param default Default value if the GMST setting cannot be used. + */ + virtual std::string_view getGameSettingString(std::string_view id, std::string_view default_) = 0; - virtual void processChangedSettings(const std::set< std::pair >& changed) = 0; + virtual void processChangedSettings(const std::set>& changed) = 0; - virtual void executeInConsole (const std::string& path) = 0; + virtual void executeInConsole(const std::string& path) = 0; - virtual void enableRest() = 0; - virtual bool getRestEnabled() = 0; - virtual bool getJournalAllowed() = 0; + virtual void enableRest() = 0; + virtual bool getRestEnabled() = 0; + virtual bool getJournalAllowed() = 0; - virtual bool getPlayerSleeping() = 0; - virtual void wakeUpPlayer() = 0; + virtual bool getPlayerSleeping() = 0; + virtual void wakeUpPlayer() = 0; - virtual void showSoulgemDialog (MWWorld::Ptr item) = 0; + virtual void showSoulgemDialog(MWWorld::Ptr item) = 0; - virtual void changePointer (const std::string& name) = 0; + virtual void changePointer(const std::string& name) = 0; - virtual void setEnemy (const MWWorld::Ptr& enemy) = 0; + virtual void setEnemy(const MWWorld::Ptr& enemy) = 0; - virtual int getMessagesCount() const = 0; + virtual int getMessagesCount() const = 0; - virtual const Translation::Storage& getTranslationDataStorage() const = 0; + virtual const Translation::Storage& getTranslationDataStorage() const = 0; - /// Warning: do not use MyGUI::InputManager::setKeyFocusWidget directly. Instead use this. - virtual void setKeyFocusWidget (MyGUI::Widget* widget) = 0; + /// Warning: do not use MyGUI::InputManager::setKeyFocusWidget directly. Instead use this. + virtual void setKeyFocusWidget(MyGUI::Widget* widget) = 0; - virtual Loading::Listener* getLoadingScreen() = 0; + virtual Loading::Listener* getLoadingScreen() = 0; - /// Should the cursor be visible? - virtual bool getCursorVisible() = 0; + /// Should the cursor be visible? + virtual bool getCursorVisible() = 0; - /// Clear all savegame-specific data - virtual void clear() = 0; + /// Clear all savegame-specific data + virtual void clear() = 0; - virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress) = 0; - virtual void readRecord (ESM::ESMReader& reader, uint32_t type) = 0; - virtual int countSavedGameRecords() const = 0; + virtual void write(ESM::ESMWriter& writer, Loading::Listener& progress) = 0; + virtual void readRecord(ESM::ESMReader& reader, uint32_t type) = 0; + virtual int countSavedGameRecords() const = 0; - /// Does the current stack of GUI-windows permit saving? - virtual bool isSavingAllowed() const = 0; + /// Does the current stack of GUI-windows permit saving? + virtual bool isSavingAllowed() const = 0; - /// Send exit command to active Modal window - virtual void exitCurrentModal() = 0; + /// Send exit command to active Modal window + virtual void exitCurrentModal() = 0; - /// Sets the current Modal - /** Used to send exit command to active Modal when Esc is pressed **/ - virtual void addCurrentModal(MWGui::WindowModal* input) = 0; + /// Sets the current Modal + /** Used to send exit command to active Modal when Esc is pressed **/ + virtual void addCurrentModal(MWGui::WindowModal* input) = 0; - /// Removes the top Modal - /** Used when one Modal adds another Modal - \param input Pointer to the current modal, to ensure proper modal is removed **/ - virtual void removeCurrentModal(MWGui::WindowModal* input) = 0; + /// Removes the top Modal + /** Used when one Modal adds another Modal + \param input Pointer to the current modal, to ensure proper modal is removed **/ + virtual void removeCurrentModal(MWGui::WindowModal* input) = 0; - virtual void pinWindow (MWGui::GuiWindow window) = 0; - virtual void toggleMaximized(MWGui::Layout *layout) = 0; + virtual void pinWindow(MWGui::GuiWindow window) = 0; + virtual void toggleMaximized(MWGui::Layout* layout) = 0; - /// Fade the screen in, over \a time seconds - virtual void fadeScreenIn(const float time, bool clearQueue=true, float delay=0.f) = 0; - /// Fade the screen out to black, over \a time seconds - virtual void fadeScreenOut(const float time, bool clearQueue=true, float delay=0.f) = 0; - /// Fade the screen to a specified percentage of black, over \a time seconds - virtual void fadeScreenTo(const int percent, const float time, bool clearQueue=true, float delay=0.f) = 0; - /// Darken the screen to a specified percentage - virtual void setBlindness(const int percent) = 0; + /// Fade the screen in, over \a time seconds + virtual void fadeScreenIn(const float time, bool clearQueue = true, float delay = 0.f) = 0; + /// Fade the screen out to black, over \a time seconds + virtual void fadeScreenOut(const float time, bool clearQueue = true, float delay = 0.f) = 0; + /// Fade the screen to a specified percentage of black, over \a time seconds + virtual void fadeScreenTo(const int percent, const float time, bool clearQueue = true, float delay = 0.f) = 0; + /// Darken the screen to a specified percentage + virtual void setBlindness(const int percent) = 0; - virtual void activateHitOverlay(bool interrupt=true) = 0; - virtual void setWerewolfOverlay(bool set) = 0; + virtual void activateHitOverlay(bool interrupt = true) = 0; + virtual void setWerewolfOverlay(bool set) = 0; - virtual void toggleConsole() = 0; - virtual void toggleDebugWindow() = 0; - virtual void togglePostProcessorHud() = 0; + virtual void toggleConsole() = 0; + virtual void toggleDebugWindow() = 0; + virtual void togglePostProcessorHud() = 0; - /// Cycle to next or previous spell - virtual void cycleSpell(bool next) = 0; - /// Cycle to next or previous weapon - virtual void cycleWeapon(bool next) = 0; + /// Cycle to next or previous spell + virtual void cycleSpell(bool next) = 0; + /// Cycle to next or previous weapon + virtual void cycleWeapon(bool next) = 0; - virtual void playSound(std::string_view soundId, float volume = 1.f, float pitch = 1.f) = 0; + virtual void playSound(std::string_view soundId, float volume = 1.f, float pitch = 1.f) = 0; - virtual void addCell(MWWorld::CellStore* cell) = 0; - virtual void removeCell(MWWorld::CellStore* cell) = 0; - virtual void writeFog(MWWorld::CellStore* cell) = 0; + virtual void addCell(MWWorld::CellStore* cell) = 0; + virtual void removeCell(MWWorld::CellStore* cell) = 0; + virtual void writeFog(MWWorld::CellStore* cell) = 0; - virtual const MWGui::TextColours& getTextColours() = 0; + virtual const MWGui::TextColours& getTextColours() = 0; - virtual bool injectKeyPress(MyGUI::KeyCode key, unsigned int text, bool repeat) = 0; - virtual bool injectKeyRelease(MyGUI::KeyCode key) = 0; + virtual bool injectKeyPress(MyGUI::KeyCode key, unsigned int text, bool repeat) = 0; + virtual bool injectKeyRelease(MyGUI::KeyCode key) = 0; - void windowVisibilityChange(bool visible) override = 0; - void windowResized(int x, int y) override = 0; - void windowClosed() override = 0; - virtual bool isWindowVisible() = 0; + void windowVisibilityChange(bool visible) override = 0; + void windowResized(int x, int y) override = 0; + void windowClosed() override = 0; + virtual bool isWindowVisible() = 0; - virtual void watchActor(const MWWorld::Ptr& ptr) = 0; - virtual MWWorld::Ptr getWatchedActor() const = 0; + virtual void watchActor(const MWWorld::Ptr& ptr) = 0; + virtual MWWorld::Ptr getWatchedActor() const = 0; - virtual const std::string& getVersionDescription() const = 0; + virtual const std::string& getVersionDescription() const = 0; - virtual void onDeleteCustomData(const MWWorld::Ptr& ptr) = 0; - virtual void forceLootMode(const MWWorld::Ptr& ptr) = 0; + virtual void onDeleteCustomData(const MWWorld::Ptr& ptr) = 0; + virtual void forceLootMode(const MWWorld::Ptr& ptr) = 0; - virtual void asyncPrepareSaveMap() = 0; + virtual void asyncPrepareSaveMap() = 0; - /// Sets the cull masks for all applicable views - virtual void setCullMask(uint32_t mask) = 0; + /// Sets the cull masks for all applicable views + virtual void setCullMask(uint32_t mask) = 0; - /// Same as viewer->getCamera()->getCullMask(), provided for consistency. - virtual uint32_t getCullMask() = 0; + /// Same as viewer->getCamera()->getCullMask(), provided for consistency. + virtual uint32_t getCullMask() = 0; }; } diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index e6322dfda4..67e8b55db4 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -3,20 +3,20 @@ #include "rotationflags.hpp" -#include +#include #include #include -#include -#include #include +#include +#include #include #include #include -#include "../mwworld/ptr.hpp" #include "../mwworld/doorstate.hpp" +#include "../mwworld/ptr.hpp" #include "../mwworld/spellcaststate.hpp" #include "../mwrender/rendermode.hpp" @@ -92,7 +92,7 @@ namespace MWWorld class ESMStore; class RefData; - typedef std::vector > PtrMovementList; + typedef std::vector> PtrMovementList; } namespace MWBase @@ -100,580 +100,614 @@ namespace MWBase /// \brief Interface for the World (implemented in MWWorld) class World { - World (const World&); - ///< not implemented - - World& operator= (const World&); - ///< not implemented - - public: - - struct DoorMarker - { - std::string name; - float x, y; // world position - ESM::CellId dest; - }; - - World() {} - - virtual ~World() {} - - virtual void setRandomSeed(uint32_t seed) = 0; - ///< \param seed The seed used when starting a new game. - - virtual void startNewGame (bool bypass) = 0; - ///< \param bypass Bypass regular game start. - - virtual void clear() = 0; - - virtual int countSavedGameRecords() const = 0; - virtual int countSavedGameCells() const = 0; - - virtual void write (ESM::ESMWriter& writer, Loading::Listener& listener) const = 0; - - virtual void readRecord (ESM::ESMReader& reader, uint32_t type, - const std::map& contentFileMap) = 0; - - virtual MWWorld::CellStore *getExterior (int x, int y) = 0; - - virtual MWWorld::CellStore* getInterior(std::string_view name) = 0; - - virtual MWWorld::CellStore *getCell (const ESM::CellId& id) = 0; - - virtual bool isCellActive(MWWorld::CellStore* cell) const = 0; - - virtual void testExteriorCells() = 0; - virtual void testInteriorCells() = 0; - - virtual void useDeathCamera() = 0; - - virtual void setWaterHeight(const float height) = 0; - - virtual bool toggleWater() = 0; - virtual bool toggleWorld() = 0; - virtual bool toggleBorders() = 0; - - virtual MWWorld::Player& getPlayer() = 0; - virtual MWWorld::Ptr getPlayerPtr() = 0; - virtual MWWorld::ConstPtr getPlayerConstPtr() const = 0; - - virtual const MWWorld::ESMStore& getStore() const = 0; - - virtual const std::vector& getESMVersions() const = 0; - - virtual MWWorld::LocalScripts& getLocalScripts() = 0; - - virtual bool hasCellChanged() const = 0; - ///< Has the set of active cells changed, since the last frame? + World(const World&); + ///< not implemented - virtual bool isCellExterior() const = 0; + World& operator=(const World&); + ///< not implemented - virtual bool isCellQuasiExterior() const = 0; + public: + struct DoorMarker + { + std::string name; + float x, y; // world position + ESM::CellId dest; + }; - virtual osg::Vec2f getNorthVector (const MWWorld::CellStore* cell) = 0; - ///< get north vector for given interior cell + World() {} - virtual void getDoorMarkers (MWWorld::CellStore* cell, std::vector& out) = 0; - ///< get a list of teleport door markers for a given cell, to be displayed on the local map + virtual ~World() {} - virtual void setGlobalInt(std::string_view name, int value) = 0; - ///< Set value independently from real type. + virtual void setRandomSeed(uint32_t seed) = 0; + ///< \param seed The seed used when starting a new game. - virtual void setGlobalFloat(std::string_view name, float value) = 0; - ///< Set value independently from real type. + virtual void startNewGame(bool bypass) = 0; + ///< \param bypass Bypass regular game start. - virtual int getGlobalInt(std::string_view name) const = 0; - ///< Get value independently from real type. + virtual void clear() = 0; - virtual float getGlobalFloat(std::string_view name) const = 0; - ///< Get value independently from real type. + virtual int countSavedGameRecords() const = 0; + virtual int countSavedGameCells() const = 0; - virtual char getGlobalVariableType(std::string_view name) const = 0; - ///< Return ' ', if there is no global variable with this name. + virtual void write(ESM::ESMWriter& writer, Loading::Listener& listener) const = 0; - virtual std::string_view getCellName(const MWWorld::CellStore* cell = nullptr) const = 0; - ///< Return name of the cell. - /// - /// \note If cell==0, the cell the player is currently in will be used instead to - /// generate a name. - virtual std::string_view getCellName(const ESM::Cell* cell) const = 0; + virtual void readRecord(ESM::ESMReader& reader, uint32_t type, const std::map& contentFileMap) = 0; - virtual void removeRefScript (MWWorld::RefData *ref) = 0; - //< Remove the script attached to ref from mLocalScripts + virtual MWWorld::CellStore* getExterior(int x, int y) = 0; - virtual MWWorld::Ptr getPtr (std::string_view name, bool activeOnly) = 0; - ///< Return a pointer to a liveCellRef with the given name. - /// \param activeOnly do non search inactive cells. + virtual MWWorld::CellStore* getInterior(std::string_view name) = 0; - virtual MWWorld::Ptr searchPtr (std::string_view name, bool activeOnly, bool searchInContainers = true) = 0; - ///< Return a pointer to a liveCellRef with the given name. - /// \param activeOnly do non search inactive cells. + virtual MWWorld::CellStore* getCell(const ESM::CellId& id) = 0; - virtual MWWorld::Ptr searchPtrViaActorId (int actorId) = 0; - ///< Search is limited to the active cells. + virtual bool isCellActive(MWWorld::CellStore* cell) const = 0; - virtual MWWorld::Ptr searchPtrViaRefNum (const std::string& id, const ESM::RefNum& refNum) = 0; + virtual void testExteriorCells() = 0; + virtual void testInteriorCells() = 0; - virtual MWWorld::Ptr findContainer (const MWWorld::ConstPtr& ptr) = 0; - ///< Return a pointer to a liveCellRef which contains \a ptr. - /// \note Search is limited to the active cells. + virtual void useDeathCamera() = 0; - virtual void enable (const MWWorld::Ptr& ptr) = 0; + virtual void setWaterHeight(const float height) = 0; - virtual void disable (const MWWorld::Ptr& ptr) = 0; + virtual bool toggleWater() = 0; + virtual bool toggleWorld() = 0; + virtual bool toggleBorders() = 0; - virtual void advanceTime (double hours, bool incremental = false) = 0; - ///< Advance in-game time. + virtual MWWorld::Player& getPlayer() = 0; + virtual MWWorld::Ptr getPlayerPtr() = 0; + virtual MWWorld::ConstPtr getPlayerConstPtr() const = 0; - virtual std::string_view getMonthName(int month = -1) const = 0; - ///< Return name of month (-1: current month) + virtual const MWWorld::ESMStore& getStore() const = 0; - virtual MWWorld::TimeStamp getTimeStamp() const = 0; - ///< Return current in-game time and number of day since new game start. + virtual const std::vector& getESMVersions() const = 0; - virtual ESM::EpochTimeStamp getEpochTimeStamp() const = 0; - ///< Return current in-game date and time. + virtual MWWorld::LocalScripts& getLocalScripts() = 0; - virtual bool toggleSky() = 0; - ///< \return Resulting mode + virtual bool hasCellChanged() const = 0; + ///< Has the set of active cells changed, since the last frame? - virtual void changeWeather(std::string_view region, const unsigned int id) = 0; + virtual bool isCellExterior() const = 0; - virtual int getCurrentWeather() const = 0; + virtual bool isCellQuasiExterior() const = 0; - virtual int getNextWeather() const = 0; + virtual osg::Vec2f getNorthVector(const MWWorld::CellStore* cell) = 0; + ///< get north vector for given interior cell - virtual float getWeatherTransition() const = 0; + virtual void getDoorMarkers(MWWorld::CellStore* cell, std::vector& out) = 0; + ///< get a list of teleport door markers for a given cell, to be displayed on the local map - virtual unsigned int getNightDayMode() const = 0; + virtual void setGlobalInt(std::string_view name, int value) = 0; + ///< Set value independently from real type. - virtual int getMasserPhase() const = 0; + virtual void setGlobalFloat(std::string_view name, float value) = 0; + ///< Set value independently from real type. - virtual int getSecundaPhase() const = 0; + virtual int getGlobalInt(std::string_view name) const = 0; + ///< Get value independently from real type. - virtual void setMoonColour (bool red) = 0; + virtual float getGlobalFloat(std::string_view name) const = 0; + ///< Get value independently from real type. - virtual void modRegion(std::string_view regionid, const std::vector &chances) = 0; + virtual char getGlobalVariableType(std::string_view name) const = 0; + ///< Return ' ', if there is no global variable with this name. - virtual float getTimeScaleFactor() const = 0; + virtual std::string_view getCellName(const MWWorld::CellStore* cell = nullptr) const = 0; + ///< Return name of the cell. + /// + /// \note If cell==0, the cell the player is currently in will be used instead to + /// generate a name. + virtual std::string_view getCellName(const ESM::Cell* cell) const = 0; - virtual float getSimulationTimeScale() const = 0; + virtual void removeRefScript(MWWorld::RefData* ref) = 0; + //< Remove the script attached to ref from mLocalScripts - virtual void setSimulationTimeScale(float scale) = 0; + virtual MWWorld::Ptr getPtr(std::string_view name, bool activeOnly) = 0; + ///< Return a pointer to a liveCellRef with the given name. + /// \param activeOnly do non search inactive cells. - virtual void changeToInteriorCell (const std::string& cellName, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent=true) = 0; - ///< Move to interior cell. - ///< @param changeEvent If false, do not trigger cell change flag or detect worldspace changes + virtual MWWorld::Ptr searchPtr(std::string_view name, bool activeOnly, bool searchInContainers = true) = 0; + ///< Return a pointer to a liveCellRef with the given name. + /// \param activeOnly do non search inactive cells. - virtual void changeToExteriorCell (const ESM::Position& position, bool adjustPlayerPos, bool changeEvent=true) = 0; - ///< Move to exterior cell. - ///< @param changeEvent If false, do not trigger cell change flag or detect worldspace changes + virtual MWWorld::Ptr searchPtrViaActorId(int actorId) = 0; + ///< Search is limited to the active cells. - virtual void changeToCell (const ESM::CellId& cellId, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent=true) = 0; - ///< @param changeEvent If false, do not trigger cell change flag or detect worldspace changes + virtual MWWorld::Ptr searchPtrViaRefNum(const std::string& id, const ESM::RefNum& refNum) = 0; - virtual const ESM::Cell* getExterior(std::string_view cellName) const = 0; - ///< Return a cell matching the given name or a 0-pointer, if there is no such cell. + virtual MWWorld::Ptr findContainer(const MWWorld::ConstPtr& ptr) = 0; + ///< Return a pointer to a liveCellRef which contains \a ptr. + /// \note Search is limited to the active cells. - virtual void markCellAsUnchanged() = 0; + virtual void enable(const MWWorld::Ptr& ptr) = 0; - virtual MWWorld::Ptr getFacedObject() = 0; - ///< Return pointer to the object the player is looking at, if it is within activation range + virtual void disable(const MWWorld::Ptr& ptr) = 0; - virtual float getDistanceToFacedObject() = 0; + virtual void advanceTime(double hours, bool incremental = false) = 0; + ///< Advance in-game time. - virtual float getMaxActivationDistance() const = 0; + virtual std::string_view getMonthName(int month = -1) const = 0; + ///< Return name of month (-1: current month) - /// Returns a pointer to the object the provided object would hit (if within the - /// specified distance), and the point where the hit occurs. This will attempt to - /// use the "Head" node, or alternatively the "Bip01 Head" node as a basis. - virtual std::pair getHitContact(const MWWorld::ConstPtr &ptr, float distance, std::vector &targets) = 0; + virtual MWWorld::TimeStamp getTimeStamp() const = 0; + ///< Return current in-game time and number of day since new game start. - virtual void adjustPosition (const MWWorld::Ptr& ptr, bool force) = 0; - ///< Adjust position after load to be on ground. Must be called after model load. - /// @param force do this even if the ptr is flying + virtual ESM::EpochTimeStamp getEpochTimeStamp() const = 0; + ///< Return current in-game date and time. - virtual void fixPosition () = 0; - ///< Attempt to fix position so that the player is not stuck inside the geometry. + virtual bool toggleSky() = 0; + ///< \return Resulting mode - /// @note No-op for items in containers. Use ContainerStore::removeItem instead. - virtual void deleteObject (const MWWorld::Ptr& ptr) = 0; - virtual void undeleteObject (const MWWorld::Ptr& ptr) = 0; + virtual void changeWeather(std::string_view region, const unsigned int id) = 0; - virtual MWWorld::Ptr moveObject (const MWWorld::Ptr& ptr, const osg::Vec3f& position, bool movePhysics=true, bool moveToActive=false) = 0; - ///< @return an updated Ptr in case the Ptr's cell changes + virtual int getCurrentWeather() const = 0; - virtual MWWorld::Ptr moveObject(const MWWorld::Ptr &ptr, MWWorld::CellStore* newCell, const osg::Vec3f& position, bool movePhysics=true, bool keepActive=false) = 0; - ///< @return an updated Ptr + virtual int getNextWeather() const = 0; - virtual MWWorld::Ptr moveObjectBy(const MWWorld::Ptr &ptr, const osg::Vec3f& vec) = 0; - ///< @return an updated Ptr + virtual float getWeatherTransition() const = 0; - virtual void scaleObject (const MWWorld::Ptr& ptr, float scale, bool force = false) = 0; + virtual unsigned int getNightDayMode() const = 0; - virtual void rotateObject(const MWWorld::Ptr& ptr, const osg::Vec3f& rot, RotationFlags flags = RotationFlag_inverseOrder) = 0; + virtual int getMasserPhase() const = 0; - virtual MWWorld::Ptr placeObject(const MWWorld::ConstPtr& ptr, MWWorld::CellStore* cell, const ESM::Position& pos) = 0; - ///< Place an object. Makes a copy of the Ptr. + virtual int getSecundaPhase() const = 0; - virtual MWWorld::Ptr safePlaceObject (const MWWorld::ConstPtr& ptr, const MWWorld::ConstPtr& referenceObject, MWWorld::CellStore* referenceCell, int direction, float distance) = 0; - ///< Place an object in a safe place next to \a referenceObject. \a direction and \a distance specify the wanted placement - /// relative to \a referenceObject (but the object may be placed somewhere else if the wanted location is obstructed). + virtual void setMoonColour(bool red) = 0; - virtual void indexToPosition (int cellX, int cellY, float &x, float &y, bool centre = false) - const = 0; - ///< Convert cell numbers to position. + virtual void modRegion(std::string_view regionid, const std::vector& chances) = 0; - virtual void queueMovement(const MWWorld::Ptr &ptr, const osg::Vec3f &velocity) = 0; - ///< Queues movement for \a ptr (in local space), to be applied in the next call to - /// doPhysics. + virtual float getTimeScaleFactor() const = 0; - virtual void updateAnimatedCollisionShape(const MWWorld::Ptr &ptr) = 0; + virtual float getSimulationTimeScale() const = 0; - virtual const MWPhysics::RayCastingInterface* getRayCasting() const = 0; + virtual void setSimulationTimeScale(float scale) = 0; - virtual bool castRay (float x1, float y1, float z1, float x2, float y2, float z2, int mask) = 0; - ///< cast a Ray and return true if there is an object in the ray path. + virtual void changeToInteriorCell( + const std::string& cellName, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent = true) + = 0; + ///< Move to interior cell. + ///< @param changeEvent If false, do not trigger cell change flag or detect worldspace changes - virtual bool castRay (float x1, float y1, float z1, float x2, float y2, float z2) = 0; + virtual void changeToExteriorCell(const ESM::Position& position, bool adjustPlayerPos, bool changeEvent = true) + = 0; + ///< Move to exterior cell. + ///< @param changeEvent If false, do not trigger cell change flag or detect worldspace changes - virtual bool castRay(const osg::Vec3f& from, const osg::Vec3f& to, int mask, const MWWorld::ConstPtr& ignore) = 0; + virtual void changeToCell( + const ESM::CellId& cellId, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent = true) + = 0; + ///< @param changeEvent If false, do not trigger cell change flag or detect worldspace changes - virtual bool castRenderingRay(MWPhysics::RayCastingResult& res, const osg::Vec3f& from, const osg::Vec3f& to, - bool ignorePlayer, bool ignoreActors) = 0; + virtual const ESM::Cell* getExterior(std::string_view cellName) const = 0; + ///< Return a cell matching the given name or a 0-pointer, if there is no such cell. - virtual void setActorCollisionMode(const MWWorld::Ptr& ptr, bool internal, bool external) = 0; - virtual bool isActorCollisionEnabled(const MWWorld::Ptr& ptr) = 0; + virtual void markCellAsUnchanged() = 0; - virtual bool toggleCollisionMode() = 0; - ///< Toggle collision mode for player. If disabled player object should ignore - /// collisions and gravity. - /// \return Resulting mode + virtual MWWorld::Ptr getFacedObject() = 0; + ///< Return pointer to the object the player is looking at, if it is within activation range - virtual bool toggleRenderMode (MWRender::RenderMode mode) = 0; - ///< Toggle a render mode. - ///< \return Resulting mode + virtual float getDistanceToFacedObject() = 0; - virtual const ESM::Potion *createRecord (const ESM::Potion& record) = 0; - ///< Create a new record (of type potion) in the ESM store. - /// \return pointer to created record + virtual float getMaxActivationDistance() const = 0; - virtual const ESM::Spell *createRecord (const ESM::Spell& record) = 0; - ///< Create a new record (of type spell) in the ESM store. - /// \return pointer to created record + /// Returns a pointer to the object the provided object would hit (if within the + /// specified distance), and the point where the hit occurs. This will attempt to + /// use the "Head" node, or alternatively the "Bip01 Head" node as a basis. + virtual std::pair getHitContact( + const MWWorld::ConstPtr& ptr, float distance, std::vector& targets) + = 0; - virtual const ESM::Class *createRecord (const ESM::Class& record) = 0; - ///< Create a new record (of type class) in the ESM store. - /// \return pointer to created record + virtual void adjustPosition(const MWWorld::Ptr& ptr, bool force) = 0; + ///< Adjust position after load to be on ground. Must be called after model load. + /// @param force do this even if the ptr is flying - virtual const ESM::Cell *createRecord (const ESM::Cell& record) = 0; - ///< Create a new record (of type cell) in the ESM store. - /// \return pointer to created record + virtual void fixPosition() = 0; + ///< Attempt to fix position so that the player is not stuck inside the geometry. - virtual const ESM::NPC *createRecord(const ESM::NPC &record) = 0; - ///< Create a new record (of type npc) in the ESM store. - /// \return pointer to created record + /// @note No-op for items in containers. Use ContainerStore::removeItem instead. + virtual void deleteObject(const MWWorld::Ptr& ptr) = 0; + virtual void undeleteObject(const MWWorld::Ptr& ptr) = 0; - virtual const ESM::Armor *createRecord (const ESM::Armor& record) = 0; - ///< Create a new record (of type armor) in the ESM store. - /// \return pointer to created record + virtual MWWorld::Ptr moveObject( + const MWWorld::Ptr& ptr, const osg::Vec3f& position, bool movePhysics = true, bool moveToActive = false) + = 0; + ///< @return an updated Ptr in case the Ptr's cell changes - virtual const ESM::Weapon *createRecord (const ESM::Weapon& record) = 0; - ///< Create a new record (of type weapon) in the ESM store. - /// \return pointer to created record + virtual MWWorld::Ptr moveObject(const MWWorld::Ptr& ptr, MWWorld::CellStore* newCell, + const osg::Vec3f& position, bool movePhysics = true, bool keepActive = false) + = 0; + ///< @return an updated Ptr - virtual const ESM::Clothing *createRecord (const ESM::Clothing& record) = 0; - ///< Create a new record (of type clothing) in the ESM store. - /// \return pointer to created record + virtual MWWorld::Ptr moveObjectBy(const MWWorld::Ptr& ptr, const osg::Vec3f& vec) = 0; + ///< @return an updated Ptr - virtual const ESM::Enchantment *createRecord (const ESM::Enchantment& record) = 0; - ///< Create a new record (of type enchantment) in the ESM store. - /// \return pointer to created record + virtual void scaleObject(const MWWorld::Ptr& ptr, float scale, bool force = false) = 0; - virtual const ESM::Book *createRecord (const ESM::Book& record) = 0; - ///< Create a new record (of type book) in the ESM store. - /// \return pointer to created record + virtual void rotateObject( + const MWWorld::Ptr& ptr, const osg::Vec3f& rot, RotationFlags flags = RotationFlag_inverseOrder) + = 0; - virtual const ESM::CreatureLevList *createOverrideRecord (const ESM::CreatureLevList& record) = 0; - ///< Write this record to the ESM store, allowing it to override a pre-existing record with the same ID. - /// \return pointer to created record + virtual MWWorld::Ptr placeObject( + const MWWorld::ConstPtr& ptr, MWWorld::CellStore* cell, const ESM::Position& pos) + = 0; + ///< Place an object. Makes a copy of the Ptr. - virtual const ESM::ItemLevList *createOverrideRecord (const ESM::ItemLevList& record) = 0; - ///< Write this record to the ESM store, allowing it to override a pre-existing record with the same ID. - /// \return pointer to created record + virtual MWWorld::Ptr safePlaceObject(const MWWorld::ConstPtr& ptr, const MWWorld::ConstPtr& referenceObject, + MWWorld::CellStore* referenceCell, int direction, float distance) + = 0; + ///< Place an object in a safe place next to \a referenceObject. \a direction and \a distance specify the wanted + ///< placement + /// relative to \a referenceObject (but the object may be placed somewhere else if the wanted location is + /// obstructed). - virtual const ESM::Creature *createOverrideRecord (const ESM::Creature& record) = 0; - ///< Write this record to the ESM store, allowing it to override a pre-existing record with the same ID. - /// \return pointer to created record + virtual void indexToPosition(int cellX, int cellY, float& x, float& y, bool centre = false) const = 0; + ///< Convert cell numbers to position. - virtual const ESM::NPC *createOverrideRecord (const ESM::NPC& record) = 0; - ///< Write this record to the ESM store, allowing it to override a pre-existing record with the same ID. - /// \return pointer to created record - - virtual const ESM::Container *createOverrideRecord (const ESM::Container& record) = 0; - ///< Write this record to the ESM store, allowing it to override a pre-existing record with the same ID. - /// \return pointer to created record - - virtual MWWorld::Ptr placeObject (const MWWorld::ConstPtr& object, float cursorX, float cursorY, int amount) = 0; - ///< copy and place an object into the gameworld at the specified cursor position - /// @param object - /// @param cursor X (relative 0-1) - /// @param cursor Y (relative 0-1) - /// @param number of objects to place - - virtual MWWorld::Ptr dropObjectOnGround (const MWWorld::Ptr& actor, const MWWorld::ConstPtr& object, int amount) = 0; - ///< copy and place an object into the gameworld at the given actor's position - /// @param actor giving the dropped object position - /// @param object - /// @param number of objects to place - - virtual bool canPlaceObject (float cursorX, float cursorY) = 0; - ///< @return true if it is possible to place on object at specified cursor location - - virtual void processChangedSettings (const std::set< std::pair >& settings) = 0; - - virtual bool isFlying(const MWWorld::Ptr &ptr) const = 0; - virtual bool isSlowFalling(const MWWorld::Ptr &ptr) const = 0; - virtual bool isSwimming(const MWWorld::ConstPtr &object) const = 0; - virtual bool isWading(const MWWorld::ConstPtr &object) const = 0; - ///Is the head of the creature underwater? - virtual bool isSubmerged(const MWWorld::ConstPtr &object) const = 0; - virtual bool isUnderwater(const MWWorld::CellStore* cell, const osg::Vec3f &pos) const = 0; - virtual bool isUnderwater(const MWWorld::ConstPtr &object, const float heightRatio) const = 0; - virtual bool isWaterWalkingCastableOnTarget(const MWWorld::ConstPtr &target) const = 0; - virtual bool isOnGround(const MWWorld::Ptr &ptr) const = 0; - - virtual osg::Matrixf getActorHeadTransform(const MWWorld::ConstPtr& actor) const = 0; - - virtual MWRender::Camera* getCamera() = 0; - virtual void togglePOV(bool force = false) = 0; - virtual bool isFirstPerson() const = 0; - virtual bool isPreviewModeEnabled() const = 0; - virtual bool toggleVanityMode(bool enable) = 0; - virtual bool vanityRotateCamera(float * rot) = 0; - virtual void applyDeferredPreviewRotationToPlayer(float dt) = 0; - virtual void disableDeferredPreviewRotation() = 0; - - virtual void saveLoaded() = 0; - - virtual void setupPlayer() = 0; - virtual void renderPlayer() = 0; - - /// open or close a non-teleport door (depending on current state) - virtual void activateDoor(const MWWorld::Ptr& door) = 0; - /// update movement state of a non-teleport door as specified - /// @param state see MWClass::setDoorState - /// @note throws an exception when invoked on a teleport door - virtual void activateDoor(const MWWorld::Ptr& door, MWWorld::DoorState state) = 0; + virtual void queueMovement(const MWWorld::Ptr& ptr, const osg::Vec3f& velocity) = 0; + ///< Queues movement for \a ptr (in local space), to be applied in the next call to + /// doPhysics. - virtual void getActorsStandingOn (const MWWorld::ConstPtr& object, std::vector &actors) = 0; ///< get a list of actors standing on \a object - virtual bool getPlayerStandingOn (const MWWorld::ConstPtr& object) = 0; ///< @return true if the player is standing on \a object - virtual bool getActorStandingOn (const MWWorld::ConstPtr& object) = 0; ///< @return true if any actor is standing on \a object - virtual bool getPlayerCollidingWith(const MWWorld::ConstPtr& object) = 0; ///< @return true if the player is colliding with \a object - virtual bool getActorCollidingWith (const MWWorld::ConstPtr& object) = 0; ///< @return true if any actor is colliding with \a object - virtual void hurtStandingActors (const MWWorld::ConstPtr& object, float dmgPerSecond) = 0; - ///< Apply a health difference to any actors standing on \a object. - /// To hurt actors, healthPerSecond should be a positive value. For a negative value, actors will be healed. - virtual void hurtCollidingActors (const MWWorld::ConstPtr& object, float dmgPerSecond) = 0; - ///< Apply a health difference to any actors colliding with \a object. - /// To hurt actors, healthPerSecond should be a positive value. For a negative value, actors will be healed. - - virtual float getWindSpeed() = 0; - - virtual void getContainersOwnedBy (const MWWorld::ConstPtr& npc, std::vector& out) = 0; - ///< get all containers in active cells owned by this Npc - virtual void getItemsOwnedBy (const MWWorld::ConstPtr& npc, std::vector& out) = 0; - ///< get all items in active cells owned by this Npc - - virtual bool getLOS(const MWWorld::ConstPtr& actor,const MWWorld::ConstPtr& targetActor) = 0; - ///< get Line of Sight (morrowind stupid implementation) - - virtual float getDistToNearestRayHit(const osg::Vec3f& from, const osg::Vec3f& dir, float maxDist, bool includeWater = false) = 0; - - virtual void enableActorCollision(const MWWorld::Ptr& actor, bool enable) = 0; - - enum RestPermitted - { - Rest_Allowed = 0, - Rest_OnlyWaiting = 1, - Rest_PlayerIsInAir = 2, - Rest_PlayerIsUnderwater = 3, - Rest_EnemiesAreNearby = 4 - }; + virtual void updateAnimatedCollisionShape(const MWWorld::Ptr& ptr) = 0; - /// check if the player is allowed to rest - virtual RestPermitted canRest() const = 0; + virtual const MWPhysics::RayCastingInterface* getRayCasting() const = 0; - /// \todo Probably shouldn't be here - virtual MWRender::Animation* getAnimation(const MWWorld::Ptr &ptr) = 0; - virtual const MWRender::Animation* getAnimation(const MWWorld::ConstPtr &ptr) const = 0; - virtual void reattachPlayerCamera() = 0; + virtual bool castRay(float x1, float y1, float z1, float x2, float y2, float z2, int mask) = 0; + ///< cast a Ray and return true if there is an object in the ray path. - /// \todo this does not belong here - virtual void screenshot (osg::Image* image, int w, int h) = 0; - virtual bool screenshot360 (osg::Image* image) = 0; + virtual bool castRay(float x1, float y1, float z1, float x2, float y2, float z2) = 0; - /// Find default position inside exterior cell specified by name - /// \return false if exterior with given name not exists, true otherwise - virtual bool findExteriorPosition(std::string_view name, ESM::Position& pos) = 0; + virtual bool castRay(const osg::Vec3f& from, const osg::Vec3f& to, int mask, const MWWorld::ConstPtr& ignore) + = 0; - /// Find default position inside interior cell specified by name - /// \return false if interior with given name not exists, true otherwise - virtual bool findInteriorPosition(std::string_view name, ESM::Position &pos) = 0; + virtual bool castRenderingRay(MWPhysics::RayCastingResult& res, const osg::Vec3f& from, const osg::Vec3f& to, + bool ignorePlayer, bool ignoreActors) + = 0; + + virtual void setActorCollisionMode(const MWWorld::Ptr& ptr, bool internal, bool external) = 0; + virtual bool isActorCollisionEnabled(const MWWorld::Ptr& ptr) = 0; - /// Enables or disables use of teleport spell effects (recall, intervention, etc). - virtual void enableTeleporting(bool enable) = 0; + virtual bool toggleCollisionMode() = 0; + ///< Toggle collision mode for player. If disabled player object should ignore + /// collisions and gravity. + /// \return Resulting mode - /// Returns true if teleport spell effects are allowed. - virtual bool isTeleportingEnabled() const = 0; + virtual bool toggleRenderMode(MWRender::RenderMode mode) = 0; + ///< Toggle a render mode. + ///< \return Resulting mode + + virtual const ESM::Potion* createRecord(const ESM::Potion& record) = 0; + ///< Create a new record (of type potion) in the ESM store. + /// \return pointer to created record - /// Enables or disables use of levitation spell effect. - virtual void enableLevitation(bool enable) = 0; + virtual const ESM::Spell* createRecord(const ESM::Spell& record) = 0; + ///< Create a new record (of type spell) in the ESM store. + /// \return pointer to created record - /// Returns true if levitation spell effect is allowed. - virtual bool isLevitationEnabled() const = 0; + virtual const ESM::Class* createRecord(const ESM::Class& record) = 0; + ///< Create a new record (of type class) in the ESM store. + /// \return pointer to created record + + virtual const ESM::Cell* createRecord(const ESM::Cell& record) = 0; + ///< Create a new record (of type cell) in the ESM store. + /// \return pointer to created record + + virtual const ESM::NPC* createRecord(const ESM::NPC& record) = 0; + ///< Create a new record (of type npc) in the ESM store. + /// \return pointer to created record + + virtual const ESM::Armor* createRecord(const ESM::Armor& record) = 0; + ///< Create a new record (of type armor) in the ESM store. + /// \return pointer to created record + + virtual const ESM::Weapon* createRecord(const ESM::Weapon& record) = 0; + ///< Create a new record (of type weapon) in the ESM store. + /// \return pointer to created record + + virtual const ESM::Clothing* createRecord(const ESM::Clothing& record) = 0; + ///< Create a new record (of type clothing) in the ESM store. + /// \return pointer to created record + + virtual const ESM::Enchantment* createRecord(const ESM::Enchantment& record) = 0; + ///< Create a new record (of type enchantment) in the ESM store. + /// \return pointer to created record + + virtual const ESM::Book* createRecord(const ESM::Book& record) = 0; + ///< Create a new record (of type book) in the ESM store. + /// \return pointer to created record + + virtual const ESM::CreatureLevList* createOverrideRecord(const ESM::CreatureLevList& record) = 0; + ///< Write this record to the ESM store, allowing it to override a pre-existing record with the same ID. + /// \return pointer to created record + + virtual const ESM::ItemLevList* createOverrideRecord(const ESM::ItemLevList& record) = 0; + ///< Write this record to the ESM store, allowing it to override a pre-existing record with the same ID. + /// \return pointer to created record + + virtual const ESM::Creature* createOverrideRecord(const ESM::Creature& record) = 0; + ///< Write this record to the ESM store, allowing it to override a pre-existing record with the same ID. + /// \return pointer to created record + + virtual const ESM::NPC* createOverrideRecord(const ESM::NPC& record) = 0; + ///< Write this record to the ESM store, allowing it to override a pre-existing record with the same ID. + /// \return pointer to created record + + virtual const ESM::Container* createOverrideRecord(const ESM::Container& record) = 0; + ///< Write this record to the ESM store, allowing it to override a pre-existing record with the same ID. + /// \return pointer to created record + + virtual MWWorld::Ptr placeObject(const MWWorld::ConstPtr& object, float cursorX, float cursorY, int amount) = 0; + ///< copy and place an object into the gameworld at the specified cursor position + /// @param object + /// @param cursor X (relative 0-1) + /// @param cursor Y (relative 0-1) + /// @param number of objects to place + + virtual MWWorld::Ptr dropObjectOnGround(const MWWorld::Ptr& actor, const MWWorld::ConstPtr& object, int amount) + = 0; + ///< copy and place an object into the gameworld at the given actor's position + /// @param actor giving the dropped object position + /// @param object + /// @param number of objects to place + + virtual bool canPlaceObject(float cursorX, float cursorY) = 0; + ///< @return true if it is possible to place on object at specified cursor location + + virtual void processChangedSettings(const std::set>& settings) = 0; + + virtual bool isFlying(const MWWorld::Ptr& ptr) const = 0; + virtual bool isSlowFalling(const MWWorld::Ptr& ptr) const = 0; + virtual bool isSwimming(const MWWorld::ConstPtr& object) const = 0; + virtual bool isWading(const MWWorld::ConstPtr& object) const = 0; + /// Is the head of the creature underwater? + virtual bool isSubmerged(const MWWorld::ConstPtr& object) const = 0; + virtual bool isUnderwater(const MWWorld::CellStore* cell, const osg::Vec3f& pos) const = 0; + virtual bool isUnderwater(const MWWorld::ConstPtr& object, const float heightRatio) const = 0; + virtual bool isWaterWalkingCastableOnTarget(const MWWorld::ConstPtr& target) const = 0; + virtual bool isOnGround(const MWWorld::Ptr& ptr) const = 0; + + virtual osg::Matrixf getActorHeadTransform(const MWWorld::ConstPtr& actor) const = 0; + + virtual MWRender::Camera* getCamera() = 0; + virtual void togglePOV(bool force = false) = 0; + virtual bool isFirstPerson() const = 0; + virtual bool isPreviewModeEnabled() const = 0; + virtual bool toggleVanityMode(bool enable) = 0; + virtual bool vanityRotateCamera(float* rot) = 0; + virtual void applyDeferredPreviewRotationToPlayer(float dt) = 0; + virtual void disableDeferredPreviewRotation() = 0; + + virtual void saveLoaded() = 0; + + virtual void setupPlayer() = 0; + virtual void renderPlayer() = 0; + + /// open or close a non-teleport door (depending on current state) + virtual void activateDoor(const MWWorld::Ptr& door) = 0; + /// update movement state of a non-teleport door as specified + /// @param state see MWClass::setDoorState + /// @note throws an exception when invoked on a teleport door + virtual void activateDoor(const MWWorld::Ptr& door, MWWorld::DoorState state) = 0; + + virtual void getActorsStandingOn(const MWWorld::ConstPtr& object, std::vector& actors) + = 0; ///< get a list of actors standing on \a object + virtual bool getPlayerStandingOn(const MWWorld::ConstPtr& object) + = 0; ///< @return true if the player is standing on \a object + virtual bool getActorStandingOn(const MWWorld::ConstPtr& object) + = 0; ///< @return true if any actor is standing on \a object + virtual bool getPlayerCollidingWith(const MWWorld::ConstPtr& object) + = 0; ///< @return true if the player is colliding with \a object + virtual bool getActorCollidingWith(const MWWorld::ConstPtr& object) + = 0; ///< @return true if any actor is colliding with \a object + virtual void hurtStandingActors(const MWWorld::ConstPtr& object, float dmgPerSecond) = 0; + ///< Apply a health difference to any actors standing on \a object. + /// To hurt actors, healthPerSecond should be a positive value. For a negative value, actors will be healed. + virtual void hurtCollidingActors(const MWWorld::ConstPtr& object, float dmgPerSecond) = 0; + ///< Apply a health difference to any actors colliding with \a object. + /// To hurt actors, healthPerSecond should be a positive value. For a negative value, actors will be healed. + + virtual float getWindSpeed() = 0; + + virtual void getContainersOwnedBy(const MWWorld::ConstPtr& npc, std::vector& out) = 0; + ///< get all containers in active cells owned by this Npc + virtual void getItemsOwnedBy(const MWWorld::ConstPtr& npc, std::vector& out) = 0; + ///< get all items in active cells owned by this Npc + + virtual bool getLOS(const MWWorld::ConstPtr& actor, const MWWorld::ConstPtr& targetActor) = 0; + ///< get Line of Sight (morrowind stupid implementation) + + virtual float getDistToNearestRayHit( + const osg::Vec3f& from, const osg::Vec3f& dir, float maxDist, bool includeWater = false) + = 0; + + virtual void enableActorCollision(const MWWorld::Ptr& actor, bool enable) = 0; + + enum RestPermitted + { + Rest_Allowed = 0, + Rest_OnlyWaiting = 1, + Rest_PlayerIsInAir = 2, + Rest_PlayerIsUnderwater = 3, + Rest_EnemiesAreNearby = 4 + }; + + /// check if the player is allowed to rest + virtual RestPermitted canRest() const = 0; + + /// \todo Probably shouldn't be here + virtual MWRender::Animation* getAnimation(const MWWorld::Ptr& ptr) = 0; + virtual const MWRender::Animation* getAnimation(const MWWorld::ConstPtr& ptr) const = 0; + virtual void reattachPlayerCamera() = 0; + + /// \todo this does not belong here + virtual void screenshot(osg::Image* image, int w, int h) = 0; + virtual bool screenshot360(osg::Image* image) = 0; + + /// Find default position inside exterior cell specified by name + /// \return false if exterior with given name not exists, true otherwise + virtual bool findExteriorPosition(std::string_view name, ESM::Position& pos) = 0; + + /// Find default position inside interior cell specified by name + /// \return false if interior with given name not exists, true otherwise + virtual bool findInteriorPosition(std::string_view name, ESM::Position& pos) = 0; + + /// Enables or disables use of teleport spell effects (recall, intervention, etc). + virtual void enableTeleporting(bool enable) = 0; + + /// Returns true if teleport spell effects are allowed. + virtual bool isTeleportingEnabled() const = 0; + + /// Enables or disables use of levitation spell effect. + virtual void enableLevitation(bool enable) = 0; + + /// Returns true if levitation spell effect is allowed. + virtual bool isLevitationEnabled() const = 0; - virtual bool getGodModeState() const = 0; + virtual bool getGodModeState() const = 0; - virtual bool toggleGodMode() = 0; + virtual bool toggleGodMode() = 0; - virtual bool toggleScripts() = 0; - virtual bool getScriptsEnabled() const = 0; + virtual bool toggleScripts() = 0; + virtual bool getScriptsEnabled() const = 0; - /** - * @brief startSpellCast attempt to start casting a spell. Might fail immediately if conditions are not met. - * @param actor - * @return Success or the failure condition. - */ - virtual MWWorld::SpellCastState startSpellCast (const MWWorld::Ptr& actor) = 0; + /** + * @brief startSpellCast attempt to start casting a spell. Might fail immediately if conditions are not met. + * @param actor + * @return Success or the failure condition. + */ + virtual MWWorld::SpellCastState startSpellCast(const MWWorld::Ptr& actor) = 0; - virtual void castSpell (const MWWorld::Ptr& actor, bool manualSpell=false) = 0; + virtual void castSpell(const MWWorld::Ptr& actor, bool manualSpell = false) = 0; - virtual void launchMagicBolt (const std::string& spellId, const MWWorld::Ptr& caster, const osg::Vec3f& fallbackDirection, int slot) = 0; - virtual void launchProjectile (MWWorld::Ptr& actor, MWWorld::Ptr& projectile, - const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr& bow, float speed, float attackStrength) = 0; - virtual void updateProjectilesCasters() = 0; + virtual void launchMagicBolt( + const std::string& spellId, const MWWorld::Ptr& caster, const osg::Vec3f& fallbackDirection, int slot) + = 0; + virtual void launchProjectile(MWWorld::Ptr& actor, MWWorld::Ptr& projectile, const osg::Vec3f& worldPos, + const osg::Quat& orient, MWWorld::Ptr& bow, float speed, float attackStrength) + = 0; + virtual void updateProjectilesCasters() = 0; - virtual void applyLoopingParticles(const MWWorld::Ptr& ptr) const = 0; + virtual void applyLoopingParticles(const MWWorld::Ptr& ptr) const = 0; - virtual const std::vector& getContentFiles() const = 0; + virtual const std::vector& getContentFiles() const = 0; - virtual void breakInvisibility (const MWWorld::Ptr& actor) = 0; + virtual void breakInvisibility(const MWWorld::Ptr& actor) = 0; - // Allow NPCs to use torches? - virtual bool useTorches() const = 0; + // Allow NPCs to use torches? + virtual bool useTorches() const = 0; - virtual float getSunVisibility() const = 0; - virtual float getSunPercentage() const = 0; + virtual float getSunVisibility() const = 0; + virtual float getSunPercentage() const = 0; - virtual bool findInteriorPositionInWorldSpace(const MWWorld::CellStore* cell, osg::Vec3f& result) = 0; + virtual bool findInteriorPositionInWorldSpace(const MWWorld::CellStore* cell, osg::Vec3f& result) = 0; - /// Teleports \a ptr to the closest reference of \a id (e.g. DivineMarker, PrisonMarker, TempleMarker) - /// @note id must be lower case - virtual void teleportToClosestMarker(const MWWorld::Ptr& ptr, std::string_view id) = 0; + /// Teleports \a ptr to the closest reference of \a id (e.g. DivineMarker, PrisonMarker, TempleMarker) + /// @note id must be lower case + virtual void teleportToClosestMarker(const MWWorld::Ptr& ptr, std::string_view id) = 0; - enum DetectionType - { - Detect_Enchantment, - Detect_Key, - Detect_Creature - }; - /// List all references (filtered by \a type) detected by \a ptr. The range - /// is determined by the current magnitude of the "Detect X" magic effect belonging to \a type. - /// @note This also works for references in containers. - virtual void listDetectedReferences (const MWWorld::Ptr& ptr, std::vector& out, - DetectionType type) = 0; + enum DetectionType + { + Detect_Enchantment, + Detect_Key, + Detect_Creature + }; + /// List all references (filtered by \a type) detected by \a ptr. The range + /// is determined by the current magnitude of the "Detect X" magic effect belonging to \a type. + /// @note This also works for references in containers. + virtual void listDetectedReferences(const MWWorld::Ptr& ptr, std::vector& out, DetectionType type) + = 0; - /// Update the value of some globals according to the world state, which may be used by dialogue entries. - /// This should be called when initiating a dialogue. - virtual void updateDialogueGlobals() = 0; + /// Update the value of some globals according to the world state, which may be used by dialogue entries. + /// This should be called when initiating a dialogue. + virtual void updateDialogueGlobals() = 0; - /// Moves all stolen items from \a ptr to the closest evidence chest. - virtual void confiscateStolenItems(const MWWorld::Ptr& ptr) = 0; + /// Moves all stolen items from \a ptr to the closest evidence chest. + virtual void confiscateStolenItems(const MWWorld::Ptr& ptr) = 0; - virtual void goToJail () = 0; + virtual void goToJail() = 0; - /// Spawn a random creature from a levelled list next to the player - virtual void spawnRandomCreature(std::string_view creatureList) = 0; + /// Spawn a random creature from a levelled list next to the player + virtual void spawnRandomCreature(std::string_view creatureList) = 0; - /// Spawn a blood effect for \a ptr at \a worldPosition - virtual void spawnBloodEffect (const MWWorld::Ptr& ptr, const osg::Vec3f& worldPosition) = 0; + /// Spawn a blood effect for \a ptr at \a worldPosition + virtual void spawnBloodEffect(const MWWorld::Ptr& ptr, const osg::Vec3f& worldPosition) = 0; - virtual void spawnEffect (const std::string& model, const std::string& textureOverride, const osg::Vec3f& worldPos, float scale = 1.f, bool isMagicVFX = true) = 0; + virtual void spawnEffect(const std::string& model, const std::string& textureOverride, + const osg::Vec3f& worldPos, float scale = 1.f, bool isMagicVFX = true) + = 0; - virtual void activate (const MWWorld::Ptr& object, const MWWorld::Ptr& actor) = 0; + virtual void activate(const MWWorld::Ptr& object, const MWWorld::Ptr& actor) = 0; - /// @see MWWorld::WeatherManager::isInStorm - virtual bool isInStorm() const = 0; + /// @see MWWorld::WeatherManager::isInStorm + virtual bool isInStorm() const = 0; - /// @see MWWorld::WeatherManager::getStormDirection - virtual osg::Vec3f getStormDirection() const = 0; + /// @see MWWorld::WeatherManager::getStormDirection + virtual osg::Vec3f getStormDirection() const = 0; - /// Resets all actors in the current active cells to their original location within that cell. - virtual void resetActors() = 0; + /// Resets all actors in the current active cells to their original location within that cell. + virtual void resetActors() = 0; - virtual bool isWalkingOnWater (const MWWorld::ConstPtr& actor) const = 0; + virtual bool isWalkingOnWater(const MWWorld::ConstPtr& actor) const = 0; - /// Return a vector aiming the actor's weapon towards a target. - /// @note The length of the vector is the distance between actor and target. - virtual osg::Vec3f aimToTarget(const MWWorld::ConstPtr& actor, const MWWorld::ConstPtr& target, bool isRangedCombat) = 0; + /// Return a vector aiming the actor's weapon towards a target. + /// @note The length of the vector is the distance between actor and target. + virtual osg::Vec3f aimToTarget( + const MWWorld::ConstPtr& actor, const MWWorld::ConstPtr& target, bool isRangedCombat) + = 0; - /// Return the distance between actor's weapon and target's collision box. - virtual float getHitDistance(const MWWorld::ConstPtr& actor, const MWWorld::ConstPtr& target) = 0; + /// Return the distance between actor's weapon and target's collision box. + virtual float getHitDistance(const MWWorld::ConstPtr& actor, const MWWorld::ConstPtr& target) = 0; - virtual void addContainerScripts(const MWWorld::Ptr& reference, MWWorld::CellStore* cell) = 0; - virtual void removeContainerScripts(const MWWorld::Ptr& reference) = 0; + virtual void addContainerScripts(const MWWorld::Ptr& reference, MWWorld::CellStore* cell) = 0; + virtual void removeContainerScripts(const MWWorld::Ptr& reference) = 0; - virtual bool isPlayerInJail() const = 0; + virtual bool isPlayerInJail() const = 0; - virtual void rest(double hours) = 0; + virtual void rest(double hours) = 0; - virtual void setPlayerTraveling(bool traveling) = 0; - virtual bool isPlayerTraveling() const = 0; + virtual void setPlayerTraveling(bool traveling) = 0; + virtual bool isPlayerTraveling() const = 0; - virtual void rotateWorldObject (const MWWorld::Ptr& ptr, const osg::Quat& rotate) = 0; + virtual void rotateWorldObject(const MWWorld::Ptr& ptr, const osg::Quat& rotate) = 0; - /// Return terrain height at \a worldPos position. - virtual float getTerrainHeightAt(const osg::Vec3f& worldPos) const = 0; + /// Return terrain height at \a worldPos position. + virtual float getTerrainHeightAt(const osg::Vec3f& worldPos) const = 0; - /// Return physical or rendering half extents of the given actor. - virtual osg::Vec3f getHalfExtents(const MWWorld::ConstPtr& actor, bool rendering=false) const = 0; + /// Return physical or rendering half extents of the given actor. + virtual osg::Vec3f getHalfExtents(const MWWorld::ConstPtr& actor, bool rendering = false) const = 0; - /// Export scene graph to a file and return the filename. - /// \param ptr object to export scene graph for (if empty, export entire scene graph) - virtual std::filesystem::path exportSceneGraph(const MWWorld::Ptr& ptr) = 0; + /// Export scene graph to a file and return the filename. + /// \param ptr object to export scene graph for (if empty, export entire scene graph) + virtual std::filesystem::path exportSceneGraph(const MWWorld::Ptr& ptr) = 0; - /// Preload VFX associated with this effect list - virtual void preloadEffects(const ESM::EffectList* effectList) = 0; + /// Preload VFX associated with this effect list + virtual void preloadEffects(const ESM::EffectList* effectList) = 0; - virtual DetourNavigator::Navigator* getNavigator() const = 0; + virtual DetourNavigator::Navigator* getNavigator() const = 0; - virtual void updateActorPath(const MWWorld::ConstPtr& actor, const std::deque& path, - const DetourNavigator::AgentBounds& agentBounds, const osg::Vec3f& start, const osg::Vec3f& end) const = 0; + virtual void updateActorPath(const MWWorld::ConstPtr& actor, const std::deque& path, + const DetourNavigator::AgentBounds& agentBounds, const osg::Vec3f& start, const osg::Vec3f& end) const = 0; - virtual void removeActorPath(const MWWorld::ConstPtr& actor) const = 0; + virtual void removeActorPath(const MWWorld::ConstPtr& actor) const = 0; - virtual void setNavMeshNumberToRender(const std::size_t value) = 0; + virtual void setNavMeshNumberToRender(const std::size_t value) = 0; - virtual DetourNavigator::AgentBounds getPathfindingAgentBounds(const MWWorld::ConstPtr& actor) const = 0; + virtual DetourNavigator::AgentBounds getPathfindingAgentBounds(const MWWorld::ConstPtr& actor) const = 0; - virtual bool hasCollisionWithDoor(const MWWorld::ConstPtr& door, const osg::Vec3f& position, const osg::Vec3f& destination) const = 0; + virtual bool hasCollisionWithDoor( + const MWWorld::ConstPtr& door, const osg::Vec3f& position, const osg::Vec3f& destination) const = 0; - virtual bool isAreaOccupiedByOtherActor(const osg::Vec3f& position, const float radius, - std::span ignore, std::vector* occupyingActors = nullptr) const = 0; + virtual bool isAreaOccupiedByOtherActor(const osg::Vec3f& position, const float radius, + std::span ignore, std::vector* occupyingActors = nullptr) const = 0; - virtual void reportStats(unsigned int frameNumber, osg::Stats& stats) const = 0; + virtual void reportStats(unsigned int frameNumber, osg::Stats& stats) const = 0; - virtual std::vector getAll(const std::string& id) = 0; + virtual std::vector getAll(const std::string& id) = 0; - virtual Misc::Rng::Generator& getPrng() = 0; + virtual Misc::Rng::Generator& getPrng() = 0; - virtual MWRender::RenderingManager* getRenderingManager() = 0; + virtual MWRender::RenderingManager* getRenderingManager() = 0; - virtual MWRender::PostProcessor* getPostProcessor() = 0; + virtual MWRender::PostProcessor* getPostProcessor() = 0; - virtual void setActorActive(const MWWorld::Ptr& ptr, bool value) = 0; + virtual void setActorActive(const MWWorld::Ptr& ptr, bool value) = 0; }; } diff --git a/apps/openmw/mwclass/activator.cpp b/apps/openmw/mwclass/activator.cpp index a651a1f0b5..e12590b63b 100644 --- a/apps/openmw/mwclass/activator.cpp +++ b/apps/openmw/mwclass/activator.cpp @@ -3,23 +3,22 @@ #include #include +#include +#include +#include #include #include -#include -#include -#include -#include #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" #include "../mwbase/world.hpp" +#include "../mwworld/action.hpp" #include "../mwworld/cellstore.hpp" #include "../mwworld/esmstore.hpp" -#include "../mwworld/ptr.hpp" -#include "../mwworld/action.hpp" #include "../mwworld/failedaction.hpp" #include "../mwworld/nullaction.hpp" +#include "../mwworld/ptr.hpp" #include "../mwphysics/physicssystem.hpp" @@ -41,7 +40,8 @@ namespace MWClass { } - void Activator::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const + void Activator::insertObjectRendering( + const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const { if (!model.empty()) { @@ -50,17 +50,19 @@ namespace MWClass } } - void Activator::insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const + void Activator::insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, + MWPhysics::PhysicsSystem& physics) const { insertObjectPhysics(ptr, model, rotation, physics); } - void Activator::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const + void Activator::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, + MWPhysics::PhysicsSystem& physics) const { physics.addObject(ptr, model, rotation, MWPhysics::CollisionType_World); } - std::string Activator::getModel(const MWWorld::ConstPtr &ptr) const + std::string Activator::getModel(const MWWorld::ConstPtr& ptr) const { return getClassModel(ptr); } @@ -77,31 +79,31 @@ namespace MWClass std::string_view Activator::getName(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mName; } std::string_view Activator::getScript(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = - ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mScript; } - bool Activator::hasToolTip (const MWWorld::ConstPtr& ptr) const + bool Activator::hasToolTip(const MWWorld::ConstPtr& ptr) const { return !getName(ptr).empty(); } - MWGui::ToolTipInfo Activator::getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const + MWGui::ToolTipInfo Activator::getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); MWGui::ToolTipInfo info; std::string_view name = getName(ptr); - info.caption = MyGUI::TextIterator::toTagsString(MWGui::toUString(name)) + MWGui::ToolTips::getCountString(count); + info.caption + = MyGUI::TextIterator::toTagsString(MWGui::toUString(name)) + MWGui::ToolTips::getCountString(count); std::string text; if (MWBase::Environment::get().getWindowManager()->getFullHelp()) @@ -114,41 +116,42 @@ namespace MWClass return info; } - std::unique_ptr Activator::activate(const MWWorld::Ptr &ptr, const MWWorld::Ptr &actor) const + std::unique_ptr Activator::activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const { - if(actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf()) + if (actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf()) { - const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); auto& prng = MWBase::Environment::get().getWorld()->getPrng(); - const ESM::Sound *sound = store.get().searchRandom("WolfActivator", prng); + const ESM::Sound* sound = store.get().searchRandom("WolfActivator", prng); std::unique_ptr action = std::make_unique("#{sWerewolfRefusal}"); - if(sound) action->setSound(sound->mId); + if (sound) + action->setSound(sound->mId); return action; } return std::make_unique(); } - - MWWorld::Ptr Activator::copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const + MWWorld::Ptr Activator::copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return MWWorld::Ptr(cell.insert(ref), &cell); } std::string_view Activator::getSoundIdFromSndGen(const MWWorld::Ptr& ptr, std::string_view name) const { - const std::string model = getModel(ptr); // Assume it's not empty, since we wouldn't have gotten the soundgen otherwise - const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); + const std::string model + = getModel(ptr); // Assume it's not empty, since we wouldn't have gotten the soundgen otherwise + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); std::string_view creatureId; const VFS::Manager* const vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); - for (const ESM::Creature &iter : store.get()) + for (const ESM::Creature& iter : store.get()) { - if (!iter.mModel.empty() && Misc::StringUtils::ciEqual(model, - Misc::ResourceHelpers::correctMeshPath(iter.mModel, vfs))) + if (!iter.mModel.empty() + && Misc::StringUtils::ciEqual(model, Misc::ResourceHelpers::correctMeshPath(iter.mModel, vfs))) { creatureId = !iter.mOriginal.empty() ? iter.mOriginal : iter.mId; break; @@ -162,9 +165,11 @@ namespace MWClass if (!creatureId.empty()) { std::vector sounds; - for (auto sound = store.get().begin(); sound != store.get().end(); ++sound) + for (auto sound = store.get().begin(); sound != store.get().end(); + ++sound) { - if (type == sound->mType && !sound->mCreature.empty() && (Misc::StringUtils::ciEqual(creatureId, sound->mCreature))) + if (type == sound->mType && !sound->mCreature.empty() + && (Misc::StringUtils::ciEqual(creatureId, sound->mCreature))) sounds.push_back(&*sound); if (type == sound->mType && sound->mCreature.empty()) fallbacksounds.push_back(&*sound); @@ -178,7 +183,8 @@ namespace MWClass else { // The activator doesn't have a corresponding creature ID, but we can try to use the defaults - for (auto sound = store.get().begin(); sound != store.get().end(); ++sound) + for (auto sound = store.get().begin(); sound != store.get().end(); + ++sound) if (type == sound->mType && sound->mCreature.empty()) fallbacksounds.push_back(&*sound); diff --git a/apps/openmw/mwclass/activator.hpp b/apps/openmw/mwclass/activator.hpp index 12dce7a893..89478b5e80 100644 --- a/apps/openmw/mwclass/activator.hpp +++ b/apps/openmw/mwclass/activator.hpp @@ -7,45 +7,48 @@ namespace MWClass { class Activator final : public MWWorld::RegisteredClass { - friend MWWorld::RegisteredClass; + friend MWWorld::RegisteredClass; - Activator(); + Activator(); - MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const override; - static int getSndGenTypeFromName(std::string_view name); + static int getSndGenTypeFromName(std::string_view name); - public: - void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; - ///< Add reference into a cell for rendering + public: + void insertObjectRendering(const MWWorld::Ptr& ptr, const std::string& model, + MWRender::RenderingInterface& renderingInterface) const override; + ///< Add reference into a cell for rendering - void insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const override; + void insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, + MWPhysics::PhysicsSystem& physics) const override; - void insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const override; + void insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, + MWPhysics::PhysicsSystem& physics) const override; - std::string_view getName(const MWWorld::ConstPtr& ptr) const override; - ///< \return name or ID; can return an empty string. + std::string_view getName(const MWWorld::ConstPtr& ptr) const override; + ///< \return name or ID; can return an empty string. - bool hasToolTip (const MWWorld::ConstPtr& ptr) const override; - ///< @return true if this object has a tooltip when focused (default implementation: true) + bool hasToolTip(const MWWorld::ConstPtr& ptr) const override; + ///< @return true if this object has a tooltip when focused (default implementation: true) - MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const override; - ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + MWGui::ToolTipInfo getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const override; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. - std::string_view getScript(const MWWorld::ConstPtr& ptr) const override; - ///< Return name of the script attached to ptr + std::string_view getScript(const MWWorld::ConstPtr& ptr) const override; + ///< Return name of the script attached to ptr - std::unique_ptr activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const override; - ///< Generate action for activation + std::unique_ptr activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const override; + ///< Generate action for activation - std::string getModel(const MWWorld::ConstPtr &ptr) const override; + std::string getModel(const MWWorld::ConstPtr& ptr) const override; - bool useAnim() const override; - ///< Whether or not to use animated variant of model (default false) + bool useAnim() const override; + ///< Whether or not to use animated variant of model (default false) - bool isActivator() const override; + bool isActivator() const override; - std::string_view getSoundIdFromSndGen(const MWWorld::Ptr& ptr, std::string_view name) const override; + std::string_view getSoundIdFromSndGen(const MWWorld::Ptr& ptr, std::string_view name) const override; }; } diff --git a/apps/openmw/mwclass/actor.cpp b/apps/openmw/mwclass/actor.cpp index 8b291c5882..fec405b482 100644 --- a/apps/openmw/mwclass/actor.cpp +++ b/apps/openmw/mwclass/actor.cpp @@ -3,13 +3,13 @@ #include #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/soundmanager.hpp" +#include "../mwbase/world.hpp" #include "../mwmechanics/actorutil.hpp" #include "../mwmechanics/creaturestats.hpp" -#include "../mwmechanics/movement.hpp" #include "../mwmechanics/magiceffects.hpp" +#include "../mwmechanics/movement.hpp" #include "../mwphysics/physicssystem.hpp" @@ -22,7 +22,8 @@ namespace MWClass MWBase::Environment::get().getWorld()->adjustPosition(ptr, force); } - void Actor::insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const + void Actor::insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, + MWPhysics::PhysicsSystem& physics) const { physics.addActor(ptr, model); if (getCreatureStats(ptr).isDead() && getCreatureStats(ptr).isDeathAnimationFinished()) @@ -34,14 +35,14 @@ namespace MWClass return true; } - void Actor::block(const MWWorld::Ptr &ptr) const + void Actor::block(const MWWorld::Ptr& ptr) const { const MWWorld::InventoryStore& inv = getInventoryStore(ptr); MWWorld::ConstContainerStoreIterator shield = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); if (shield == inv.end()) return; - MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); + MWBase::SoundManager* sndMgr = MWBase::Environment::get().getSoundManager(); switch (shield->getClass().getEquipmentSkill(*shield)) { case ESM::Skill::LightArmor: @@ -60,7 +61,7 @@ namespace MWClass osg::Vec3f Actor::getRotationVector(const MWWorld::Ptr& ptr) const { - MWMechanics::Movement &movement = getMovementSettings(ptr); + MWMechanics::Movement& movement = getMovementSettings(ptr); osg::Vec3f vec(movement.mRotation[0], movement.mRotation[1], movement.mRotation[2]); movement.mRotation[0] = 0.0f; movement.mRotation[1] = 0.0f; @@ -78,7 +79,8 @@ namespace MWClass return (weight < 0) ? 0.0f : weight; } - bool Actor::allowTelekinesis(const MWWorld::ConstPtr &ptr) const { + bool Actor::allowTelekinesis(const MWWorld::ConstPtr& ptr) const + { return false; } diff --git a/apps/openmw/mwclass/actor.hpp b/apps/openmw/mwclass/actor.hpp index fca610bc41..fae31b8d20 100644 --- a/apps/openmw/mwclass/actor.hpp +++ b/apps/openmw/mwclass/actor.hpp @@ -19,30 +19,33 @@ namespace MWClass class Actor : public MWWorld::Class { protected: - - explicit Actor(unsigned type) : Class(type) {} + explicit Actor(unsigned type) + : Class(type) + { + } template - float getSwimSpeedImpl(const MWWorld::Ptr& ptr, const GMST& gmst, const MWMechanics::MagicEffects& mageffects, float baseSpeed) const + float getSwimSpeedImpl(const MWWorld::Ptr& ptr, const GMST& gmst, const MWMechanics::MagicEffects& mageffects, + float baseSpeed) const { - return baseSpeed - * (1.0f + 0.01f * mageffects.get(ESM::MagicEffect::SwiftSwim).getMagnitude()) + return baseSpeed * (1.0f + 0.01f * mageffects.get(ESM::MagicEffect::SwiftSwim).getMagnitude()) * (gmst.fSwimRunBase->mValue.getFloat() - + 0.01f * getSkill(ptr, ESM::Skill::Athletics) * gmst.fSwimRunAthleticsMult->mValue.getFloat()); + + 0.01f * getSkill(ptr, ESM::Skill::Athletics) * gmst.fSwimRunAthleticsMult->mValue.getFloat()); } public: - ~Actor() override = default; + ~Actor() override = default; void adjustPosition(const MWWorld::Ptr& ptr, bool force) const override; ///< Adjust position to stand on ground. Must be called post model load /// @param force do this even if the ptr is flying - void insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const override; + void insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, + MWPhysics::PhysicsSystem& physics) const override; bool useAnim() const override; - void block(const MWWorld::Ptr &ptr) const override; + void block(const MWWorld::Ptr& ptr) const override; osg::Vec3f getRotationVector(const MWWorld::Ptr& ptr) const override; ///< Return desired rotations, as euler angles. Sets getMovementSettings(ptr).mRotation to zero. @@ -58,10 +61,10 @@ namespace MWClass /// Return current movement speed. float getCurrentSpeed(const MWWorld::Ptr& ptr) const override; - + // not implemented Actor(const Actor&) = delete; - Actor& operator= (const Actor&) = delete; + Actor& operator=(const Actor&) = delete; }; } diff --git a/apps/openmw/mwclass/apparatus.cpp b/apps/openmw/mwclass/apparatus.cpp index 885fbb3bbc..aab3c2b583 100644 --- a/apps/openmw/mwclass/apparatus.cpp +++ b/apps/openmw/mwclass/apparatus.cpp @@ -2,14 +2,14 @@ #include -#include -#include #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" +#include +#include -#include "../mwworld/ptr.hpp" #include "../mwworld/actionalchemy.hpp" #include "../mwworld/cellstore.hpp" +#include "../mwworld/ptr.hpp" #include "../mwrender/objects.hpp" #include "../mwrender/renderinginterface.hpp" @@ -26,42 +26,43 @@ namespace MWClass { } - void Apparatus::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const + void Apparatus::insertObjectRendering( + const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const { - if (!model.empty()) { + if (!model.empty()) + { renderingInterface.getObjects().insertModel(ptr, model); } } - std::string Apparatus::getModel(const MWWorld::ConstPtr &ptr) const + std::string Apparatus::getModel(const MWWorld::ConstPtr& ptr) const { return getClassModel(ptr); } std::string_view Apparatus::getName(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); const std::string& name = ref->mBase->mName; return !name.empty() ? name : ref->mBase->mId; } - std::unique_ptr Apparatus::activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const + std::unique_ptr Apparatus::activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const { return defaultItemActivate(ptr, actor); } std::string_view Apparatus::getScript(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mScript; } - int Apparatus::getValue (const MWWorld::ConstPtr& ptr) const + int Apparatus::getValue(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mData.mValue; } @@ -78,18 +79,19 @@ namespace MWClass const std::string& Apparatus::getInventoryIcon(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mIcon; } - MWGui::ToolTipInfo Apparatus::getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const + MWGui::ToolTipInfo Apparatus::getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); MWGui::ToolTipInfo info; std::string_view name = getName(ptr); - info.caption = MyGUI::TextIterator::toTagsString(MWGui::toUString(name)) + MWGui::ToolTips::getCountString(count); + info.caption + = MyGUI::TextIterator::toTagsString(MWGui::toUString(name)) + MWGui::ToolTips::getCountString(count); info.icon = ref->mBase->mIcon; std::string text; @@ -107,26 +109,26 @@ namespace MWClass return info; } - std::unique_ptr Apparatus::use (const MWWorld::Ptr& ptr, bool force) const + std::unique_ptr Apparatus::use(const MWWorld::Ptr& ptr, bool force) const { return std::make_unique(force); } - MWWorld::Ptr Apparatus::copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const + MWWorld::Ptr Apparatus::copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return MWWorld::Ptr(cell.insert(ref), &cell); } - bool Apparatus::canSell (const MWWorld::ConstPtr& item, int npcServices) const + bool Apparatus::canSell(const MWWorld::ConstPtr& item, int npcServices) const { return (npcServices & ESM::NPC::Apparatus) != 0; } - float Apparatus::getWeight(const MWWorld::ConstPtr &ptr) const + float Apparatus::getWeight(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mData.mWeight; } } diff --git a/apps/openmw/mwclass/apparatus.hpp b/apps/openmw/mwclass/apparatus.hpp index 43e85a9be6..83036b512d 100644 --- a/apps/openmw/mwclass/apparatus.hpp +++ b/apps/openmw/mwclass/apparatus.hpp @@ -7,50 +7,49 @@ namespace MWClass { class Apparatus : public MWWorld::RegisteredClass { - friend MWWorld::RegisteredClass; + friend MWWorld::RegisteredClass; - Apparatus(); + Apparatus(); - MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const override; - public: + public: + float getWeight(const MWWorld::ConstPtr& ptr) const override; - float getWeight (const MWWorld::ConstPtr& ptr) const override; + void insertObjectRendering(const MWWorld::Ptr& ptr, const std::string& model, + MWRender::RenderingInterface& renderingInterface) const override; + ///< Add reference into a cell for rendering - void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; - ///< Add reference into a cell for rendering + std::string_view getName(const MWWorld::ConstPtr& ptr) const override; + ///< \return name or ID; can return an empty string. - std::string_view getName(const MWWorld::ConstPtr& ptr) const override; - ///< \return name or ID; can return an empty string. + std::unique_ptr activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const override; + ///< Generate action for activation - std::unique_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const override; - ///< Generate action for activation + std::string_view getScript(const MWWorld::ConstPtr& ptr) const override; + ///< Return name of the script attached to ptr - std::string_view getScript(const MWWorld::ConstPtr& ptr) const override; - ///< Return name of the script attached to ptr + int getValue(const MWWorld::ConstPtr& ptr) const override; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. - int getValue (const MWWorld::ConstPtr& ptr) const override; - ///< Return trade value of the object. Throws an exception, if the object can't be traded. + MWGui::ToolTipInfo getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const override; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. - MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const override; - ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + std::string_view getUpSoundId(const MWWorld::ConstPtr& ptr) const override; + ///< Return the pick up sound Id - std::string_view getUpSoundId(const MWWorld::ConstPtr& ptr) const override; - ///< Return the pick up sound Id + std::string_view getDownSoundId(const MWWorld::ConstPtr& ptr) const override; + ///< Return the put down sound Id - std::string_view getDownSoundId(const MWWorld::ConstPtr& ptr) const override; - ///< Return the put down sound Id + const std::string& getInventoryIcon(const MWWorld::ConstPtr& ptr) const override; + ///< Return name of inventory icon. - const std::string& getInventoryIcon(const MWWorld::ConstPtr& ptr) const override; - ///< Return name of inventory icon. + std::unique_ptr use(const MWWorld::Ptr& ptr, bool force = false) const override; + ///< Generate action for using via inventory menu - std::unique_ptr use (const MWWorld::Ptr& ptr, bool force=false) const override; - ///< Generate action for using via inventory menu + std::string getModel(const MWWorld::ConstPtr& ptr) const override; - std::string getModel(const MWWorld::ConstPtr &ptr) const override; - - bool canSell (const MWWorld::ConstPtr& item, int npcServices) const override; + bool canSell(const MWWorld::ConstPtr& item, int npcServices) const override; }; } diff --git a/apps/openmw/mwclass/armor.cpp b/apps/openmw/mwclass/armor.cpp index b4a9d73c5c..d118d37cd6 100644 --- a/apps/openmw/mwclass/armor.cpp +++ b/apps/openmw/mwclass/armor.cpp @@ -3,26 +3,26 @@ #include #include -#include #include -#include #include +#include +#include #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" -#include "../mwworld/ptr.hpp" #include "../mwworld/actionequip.hpp" -#include "../mwworld/inventorystore.hpp" #include "../mwworld/cellstore.hpp" -#include "../mwworld/esmstore.hpp" #include "../mwworld/containerstore.hpp" +#include "../mwworld/esmstore.hpp" +#include "../mwworld/inventorystore.hpp" +#include "../mwworld/ptr.hpp" -#include "../mwrender/objects.hpp" -#include "../mwrender/renderinginterface.hpp" #include "../mwmechanics/actorutil.hpp" #include "../mwmechanics/weapontype.hpp" +#include "../mwrender/objects.hpp" +#include "../mwrender/renderinginterface.hpp" #include "../mwgui/tooltips.hpp" #include "../mwgui/ustring.hpp" @@ -36,62 +36,61 @@ namespace MWClass { } - void Armor::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const + void Armor::insertObjectRendering( + const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const { - if (!model.empty()) { + if (!model.empty()) + { renderingInterface.getObjects().insertModel(ptr, model); } } - std::string Armor::getModel(const MWWorld::ConstPtr &ptr) const + std::string Armor::getModel(const MWWorld::ConstPtr& ptr) const { return getClassModel(ptr); } std::string_view Armor::getName(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); const std::string& name = ref->mBase->mName; return !name.empty() ? name : ref->mBase->mId; } - std::unique_ptr Armor::activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const + std::unique_ptr Armor::activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const { return defaultItemActivate(ptr, actor); } - bool Armor::hasItemHealth (const MWWorld::ConstPtr& ptr) const + bool Armor::hasItemHealth(const MWWorld::ConstPtr& ptr) const { return true; } - int Armor::getItemMaxHealth (const MWWorld::ConstPtr& ptr) const + int Armor::getItemMaxHealth(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mData.mHealth; } std::string_view Armor::getScript(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mScript; } - std::pair, bool> Armor::getEquipmentSlots (const MWWorld::ConstPtr& ptr) const + std::pair, bool> Armor::getEquipmentSlots(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); std::vector slots_; const int size = 11; - static const int sMapping[size][2] = - { - { ESM::Armor::Helmet, MWWorld::InventoryStore::Slot_Helmet }, + static const int sMapping[size][2] = { { ESM::Armor::Helmet, MWWorld::InventoryStore::Slot_Helmet }, { ESM::Armor::Cuirass, MWWorld::InventoryStore::Slot_Cuirass }, { ESM::Armor::LPauldron, MWWorld::InventoryStore::Slot_LeftPauldron }, { ESM::Armor::RPauldron, MWWorld::InventoryStore::Slot_RightPauldron }, @@ -101,63 +100,78 @@ namespace MWClass { ESM::Armor::RGauntlet, MWWorld::InventoryStore::Slot_RightGauntlet }, { ESM::Armor::Shield, MWWorld::InventoryStore::Slot_CarriedLeft }, { ESM::Armor::LBracer, MWWorld::InventoryStore::Slot_LeftGauntlet }, - { ESM::Armor::RBracer, MWWorld::InventoryStore::Slot_RightGauntlet } - }; + { ESM::Armor::RBracer, MWWorld::InventoryStore::Slot_RightGauntlet } }; - for (int i=0; imBase->mData.mType) + for (int i = 0; i < size; ++i) + if (sMapping[i][0] == ref->mBase->mData.mType) { - slots_.push_back (int (sMapping[i][1])); + slots_.push_back(int(sMapping[i][1])); break; } - return std::make_pair (slots_, false); + return std::make_pair(slots_, false); } - int Armor::getEquipmentSkill (const MWWorld::ConstPtr& ptr) const + int Armor::getEquipmentSkill(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); std::string_view typeGmst; switch (ref->mBase->mData.mType) { - case ESM::Armor::Helmet: typeGmst = "iHelmWeight"; break; - case ESM::Armor::Cuirass: typeGmst = "iCuirassWeight"; break; + case ESM::Armor::Helmet: + typeGmst = "iHelmWeight"; + break; + case ESM::Armor::Cuirass: + typeGmst = "iCuirassWeight"; + break; case ESM::Armor::LPauldron: - case ESM::Armor::RPauldron: typeGmst = "iPauldronWeight"; break; - case ESM::Armor::Greaves: typeGmst = "iGreavesWeight"; break; - case ESM::Armor::Boots: typeGmst = "iBootsWeight"; break; + case ESM::Armor::RPauldron: + typeGmst = "iPauldronWeight"; + break; + case ESM::Armor::Greaves: + typeGmst = "iGreavesWeight"; + break; + case ESM::Armor::Boots: + typeGmst = "iBootsWeight"; + break; case ESM::Armor::LGauntlet: - case ESM::Armor::RGauntlet: typeGmst = "iGauntletWeight"; break; - case ESM::Armor::Shield: typeGmst = "iShieldWeight"; break; + case ESM::Armor::RGauntlet: + typeGmst = "iGauntletWeight"; + break; + case ESM::Armor::Shield: + typeGmst = "iShieldWeight"; + break; case ESM::Armor::LBracer: - case ESM::Armor::RBracer: typeGmst = "iGauntletWeight"; break; + case ESM::Armor::RBracer: + typeGmst = "iGauntletWeight"; + break; } if (typeGmst.empty()) return -1; - const MWWorld::Store &gmst = - MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& gmst + = MWBase::Environment::get().getWorld()->getStore().get(); float iWeight = floor(gmst.find(typeGmst)->mValue.getFloat()); float epsilon = 0.0005f; - if (ref->mBase->mData.mWeight <= iWeight * gmst.find ("fLightMaxMod")->mValue.getFloat() + epsilon) + if (ref->mBase->mData.mWeight <= iWeight * gmst.find("fLightMaxMod")->mValue.getFloat() + epsilon) return ESM::Skill::LightArmor; - if (ref->mBase->mData.mWeight <= iWeight * gmst.find ("fMedMaxMod")->mValue.getFloat() + epsilon) + if (ref->mBase->mData.mWeight <= iWeight * gmst.find("fMedMaxMod")->mValue.getFloat() + epsilon) return ESM::Skill::MediumArmor; else return ESM::Skill::HeavyArmor; } - int Armor::getValue (const MWWorld::ConstPtr& ptr) const + int Armor::getValue(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mData.mValue; } @@ -186,18 +200,19 @@ namespace MWClass const std::string& Armor::getInventoryIcon(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mIcon; } - MWGui::ToolTipInfo Armor::getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const + MWGui::ToolTipInfo Armor::getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); MWGui::ToolTipInfo info; std::string_view name = getName(ptr); - info.caption = MyGUI::TextIterator::toTagsString(MWGui::toUString(name)) + MWGui::ToolTips::getCountString(count); + info.caption + = MyGUI::TextIterator::toTagsString(MWGui::toUString(name)) + MWGui::ToolTips::getCountString(count); info.icon = ref->mBase->mIcon; std::string text; @@ -210,7 +225,7 @@ namespace MWClass } else { - int armorType = getEquipmentSkill(ptr); + int armorType = getEquipmentSkill(ptr); if (armorType == ESM::Skill::LightArmor) typeText = "#{sLight}"; else if (armorType == ESM::Skill::MediumArmor) @@ -219,12 +234,12 @@ namespace MWClass typeText = "#{sHeavy}"; } - text += "\n#{sArmorRating}: " + MWGui::ToolTips::toString(static_cast(getEffectiveArmorRating(ptr, - MWMechanics::getPlayer()))); + text += "\n#{sArmorRating}: " + + MWGui::ToolTips::toString(static_cast(getEffectiveArmorRating(ptr, MWMechanics::getPlayer()))); int remainingHealth = getItemHealth(ptr); text += "\n#{sCondition}: " + MWGui::ToolTips::toString(remainingHealth) + "/" - + MWGui::ToolTips::toString(ref->mBase->mData.mHealth); + + MWGui::ToolTips::toString(ref->mBase->mData.mHealth); if (!typeText.empty()) { @@ -252,35 +267,36 @@ namespace MWClass std::string_view Armor::getEnchantment(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mEnchant; } - const std::string& Armor::applyEnchantment(const MWWorld::ConstPtr& ptr, const std::string& enchId, int enchCharge, const std::string& newName) const + const std::string& Armor::applyEnchantment( + const MWWorld::ConstPtr& ptr, const std::string& enchId, int enchCharge, const std::string& newName) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); ESM::Armor newItem = *ref->mBase; newItem.mId.clear(); - newItem.mName=newName; - newItem.mData.mEnchant=enchCharge; - newItem.mEnchant=enchId; - const ESM::Armor *record = MWBase::Environment::get().getWorld()->createRecord (newItem); + newItem.mName = newName; + newItem.mData.mEnchant = enchCharge; + newItem.mEnchant = enchId; + const ESM::Armor* record = MWBase::Environment::get().getWorld()->createRecord(newItem); return record->mId; } - float Armor::getEffectiveArmorRating(const MWWorld::ConstPtr &ptr, const MWWorld::Ptr &actor) const + float Armor::getEffectiveArmorRating(const MWWorld::ConstPtr& ptr, const MWWorld::Ptr& actor) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); int armorSkillType = getEquipmentSkill(ptr); float armorSkill = actor.getClass().getSkill(actor, armorSkillType); - const MWBase::World *world = MWBase::Environment::get().getWorld(); + const MWBase::World* world = MWBase::Environment::get().getWorld(); int iBaseArmorSkill = world->getStore().get().find("iBaseArmorSkill")->mValue.getInteger(); - if(ref->mBase->mData.mWeight == 0) + if (ref->mBase->mData.mWeight == 0) return ref->mBase->mData.mArmor; else return ref->mBase->mData.mArmor * armorSkill / static_cast(iBaseArmorSkill); @@ -291,13 +307,13 @@ namespace MWClass const MWWorld::InventoryStore& invStore = npc.getClass().getInventoryStore(npc); if (getItemHealth(ptr) == 0) - return {0, "#{sInventoryMessage1}"}; + return { 0, "#{sInventoryMessage1}" }; // slots that this item can be equipped in std::pair, bool> slots_ = getEquipmentSlots(ptr); if (slots_.first.empty()) - return {0, {}}; + return { 0, {} }; if (npc.getClass().isNpc()) { @@ -305,41 +321,41 @@ namespace MWClass // Beast races cannot equip shoes / boots, or full helms (head part vs hair part) const ESM::Race* race = MWBase::Environment::get().getWorld()->getStore().get().find(npcRace); - if(race->mData.mFlags & ESM::Race::Beast) + if (race->mData.mFlags & ESM::Race::Beast) { std::vector parts = ptr.get()->mBase->mParts.mParts; - for(std::vector::iterator itr = parts.begin(); itr != parts.end(); ++itr) + for (std::vector::iterator itr = parts.begin(); itr != parts.end(); ++itr) { - if((*itr).mPart == ESM::PRT_Head) - return {0, "#{sNotifyMessage13}"}; - if((*itr).mPart == ESM::PRT_LFoot || (*itr).mPart == ESM::PRT_RFoot) - return {0, "#{sNotifyMessage14}"}; + if ((*itr).mPart == ESM::PRT_Head) + return { 0, "#{sNotifyMessage13}" }; + if ((*itr).mPart == ESM::PRT_LFoot || (*itr).mPart == ESM::PRT_RFoot) + return { 0, "#{sNotifyMessage14}" }; } } } - for (std::vector::const_iterator slot=slots_.first.begin(); - slot!=slots_.first.end(); ++slot) + for (std::vector::const_iterator slot = slots_.first.begin(); slot != slots_.first.end(); ++slot) { // If equipping a shield, check if there's a twohanded weapon conflicting with it - if(*slot == MWWorld::InventoryStore::Slot_CarriedLeft) + if (*slot == MWWorld::InventoryStore::Slot_CarriedLeft) { - MWWorld::ConstContainerStoreIterator weapon = invStore.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); - if(weapon != invStore.end() && weapon->getType() == ESM::Weapon::sRecordId) + MWWorld::ConstContainerStoreIterator weapon + = invStore.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); + if (weapon != invStore.end() && weapon->getType() == ESM::Weapon::sRecordId) { - const MWWorld::LiveCellRef *ref = weapon->get(); + const MWWorld::LiveCellRef* ref = weapon->get(); if (MWMechanics::getWeaponType(ref->mBase->mData.mType)->mFlags & ESM::WeaponType::TwoHanded) - return {3, {}}; + return { 3, {} }; } - return {1, {}}; + return { 1, {} }; } } - return {1, {}}; + return { 1, {} }; } - std::unique_ptr Armor::use (const MWWorld::Ptr& ptr, bool force) const + std::unique_ptr Armor::use(const MWWorld::Ptr& ptr, bool force) const { std::unique_ptr action = std::make_unique(ptr, force); @@ -348,29 +364,29 @@ namespace MWClass return action; } - MWWorld::Ptr Armor::copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const + MWWorld::Ptr Armor::copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return MWWorld::Ptr(cell.insert(ref), &cell); } - int Armor::getEnchantmentPoints (const MWWorld::ConstPtr& ptr) const + int Armor::getEnchantmentPoints(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mData.mEnchant; } - bool Armor::canSell (const MWWorld::ConstPtr& item, int npcServices) const + bool Armor::canSell(const MWWorld::ConstPtr& item, int npcServices) const { return (npcServices & ESM::NPC::Armor) - || ((npcServices & ESM::NPC::MagicItems) && !getEnchantment(item).empty()); + || ((npcServices & ESM::NPC::MagicItems) && !getEnchantment(item).empty()); } - float Armor::getWeight(const MWWorld::ConstPtr &ptr) const + float Armor::getWeight(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mData.mWeight; } } diff --git a/apps/openmw/mwclass/armor.hpp b/apps/openmw/mwclass/armor.hpp index 5c9732f2ca..86b06715b1 100644 --- a/apps/openmw/mwclass/armor.hpp +++ b/apps/openmw/mwclass/armor.hpp @@ -7,79 +7,81 @@ namespace MWClass { class Armor : public MWWorld::RegisteredClass { - friend MWWorld::RegisteredClass; + friend MWWorld::RegisteredClass; - Armor(); + Armor(); - MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const override; - public: + public: + float getWeight(const MWWorld::ConstPtr& ptr) const override; - float getWeight (const MWWorld::ConstPtr& ptr) const override; + void insertObjectRendering(const MWWorld::Ptr& ptr, const std::string& model, + MWRender::RenderingInterface& renderingInterface) const override; + ///< Add reference into a cell for rendering - void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; - ///< Add reference into a cell for rendering + std::string_view getName(const MWWorld::ConstPtr& ptr) const override; + ///< \return name or ID; can return an empty string. - std::string_view getName(const MWWorld::ConstPtr& ptr) const override; - ///< \return name or ID; can return an empty string. + std::unique_ptr activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const override; + ///< Generate action for activation - std::unique_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const override; - ///< Generate action for activation + bool hasItemHealth(const MWWorld::ConstPtr& ptr) const override; + ///< \return Item health data available? - bool hasItemHealth (const MWWorld::ConstPtr& ptr) const override; - ///< \return Item health data available? + int getItemMaxHealth(const MWWorld::ConstPtr& ptr) const override; + ///< Return item max health or throw an exception, if class does not have item health - int getItemMaxHealth (const MWWorld::ConstPtr& ptr) const override; - ///< Return item max health or throw an exception, if class does not have item health + std::string_view getScript(const MWWorld::ConstPtr& ptr) const override; + ///< Return name of the script attached to ptr - std::string_view getScript(const MWWorld::ConstPtr& ptr) const override; - ///< Return name of the script attached to ptr + std::pair, bool> getEquipmentSlots(const MWWorld::ConstPtr& ptr) const override; + ///< \return first: Return IDs of the slot this object can be equipped in; second: can object + /// stay stacked when equipped? - std::pair, bool> getEquipmentSlots (const MWWorld::ConstPtr& ptr) const override; - ///< \return first: Return IDs of the slot this object can be equipped in; second: can object - /// stay stacked when equipped? + int getEquipmentSkill(const MWWorld::ConstPtr& ptr) const override; + /// Return the index of the skill this item corresponds to when equipped or -1, if there is + /// no such skill. - int getEquipmentSkill (const MWWorld::ConstPtr& ptr) const override; - /// Return the index of the skill this item corresponds to when equipped or -1, if there is - /// no such skill. + MWGui::ToolTipInfo getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const override; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. - MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const override; - ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + int getValue(const MWWorld::ConstPtr& ptr) const override; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. - int getValue (const MWWorld::ConstPtr& ptr) const override; - ///< Return trade value of the object. Throws an exception, if the object can't be traded. + std::string_view getUpSoundId(const MWWorld::ConstPtr& ptr) const override; + ///< Return the pick up sound Id - std::string_view getUpSoundId(const MWWorld::ConstPtr& ptr) const override; - ///< Return the pick up sound Id + std::string_view getDownSoundId(const MWWorld::ConstPtr& ptr) const override; + ///< Return the put down sound Id - std::string_view getDownSoundId(const MWWorld::ConstPtr& ptr) const override; - ///< Return the put down sound Id + const std::string& getInventoryIcon(const MWWorld::ConstPtr& ptr) const override; + ///< Return name of inventory icon. - const std::string& getInventoryIcon(const MWWorld::ConstPtr& ptr) const override; - ///< Return name of inventory icon. + std::string_view getEnchantment(const MWWorld::ConstPtr& ptr) const override; + ///< @return the enchantment ID if the object is enchanted, otherwise an empty string - std::string_view getEnchantment(const MWWorld::ConstPtr& ptr) const override; - ///< @return the enchantment ID if the object is enchanted, otherwise an empty string + const std::string& applyEnchantment(const MWWorld::ConstPtr& ptr, const std::string& enchId, int enchCharge, + const std::string& newName) const override; + ///< Creates a new record using \a ptr as template, with the given name and the given enchantment applied to it. - const std::string& applyEnchantment(const MWWorld::ConstPtr& ptr, const std::string& enchId, int enchCharge, const std::string& newName) const override; - ///< Creates a new record using \a ptr as template, with the given name and the given enchantment applied to it. + std::pair canBeEquipped( + const MWWorld::ConstPtr& ptr, const MWWorld::Ptr& npc) const override; + ///< Return 0 if player cannot equip item. 1 if can equip. 2 if it's twohanded weapon. 3 if twohanded weapon + ///< conflicts with that. \n + /// Second item in the pair specifies the error message - std::pair canBeEquipped(const MWWorld::ConstPtr& ptr, const MWWorld::Ptr& npc) const override; - ///< Return 0 if player cannot equip item. 1 if can equip. 2 if it's twohanded weapon. 3 if twohanded weapon conflicts with that. \n - /// Second item in the pair specifies the error message + std::unique_ptr use(const MWWorld::Ptr& ptr, bool force = false) const override; + ///< Generate action for using via inventory menu - std::unique_ptr use (const MWWorld::Ptr& ptr, bool force=false) const override; - ///< Generate action for using via inventory menu + std::string getModel(const MWWorld::ConstPtr& ptr) const override; - std::string getModel(const MWWorld::ConstPtr &ptr) const override; + int getEnchantmentPoints(const MWWorld::ConstPtr& ptr) const override; - int getEnchantmentPoints (const MWWorld::ConstPtr& ptr) const override; + bool canSell(const MWWorld::ConstPtr& item, int npcServices) const override; - bool canSell (const MWWorld::ConstPtr& item, int npcServices) const override; - - /// Get the effective armor rating, factoring in the actor's skills, for the given armor. - float getEffectiveArmorRating(const MWWorld::ConstPtr& armor, const MWWorld::Ptr& actor) const override; + /// Get the effective armor rating, factoring in the actor's skills, for the given armor. + float getEffectiveArmorRating(const MWWorld::ConstPtr& armor, const MWWorld::Ptr& actor) const override; }; } diff --git a/apps/openmw/mwclass/bodypart.cpp b/apps/openmw/mwclass/bodypart.cpp index 427203c383..431fb69652 100644 --- a/apps/openmw/mwclass/bodypart.cpp +++ b/apps/openmw/mwclass/bodypart.cpp @@ -2,8 +2,8 @@ #include -#include "../mwrender/renderinginterface.hpp" #include "../mwrender/objects.hpp" +#include "../mwrender/renderinginterface.hpp" #include "../mwworld/cellstore.hpp" @@ -16,21 +16,23 @@ namespace MWClass { } - MWWorld::Ptr BodyPart::copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const + MWWorld::Ptr BodyPart::copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return MWWorld::Ptr(cell.insert(ref), &cell); } - void BodyPart::insertObjectRendering(const MWWorld::Ptr &ptr, const std::string &model, MWRender::RenderingInterface &renderingInterface) const + void BodyPart::insertObjectRendering( + const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const { - if (!model.empty()) { + if (!model.empty()) + { renderingInterface.getObjects().insertModel(ptr, model); } } - std::string_view BodyPart::getName(const MWWorld::ConstPtr &ptr) const + std::string_view BodyPart::getName(const MWWorld::ConstPtr& ptr) const { return {}; } @@ -40,7 +42,7 @@ namespace MWClass return false; } - std::string BodyPart::getModel(const MWWorld::ConstPtr &ptr) const + std::string BodyPart::getModel(const MWWorld::ConstPtr& ptr) const { return getClassModel(ptr); } diff --git a/apps/openmw/mwclass/bodypart.hpp b/apps/openmw/mwclass/bodypart.hpp index 5491ccf8b6..4a2d9d3620 100644 --- a/apps/openmw/mwclass/bodypart.hpp +++ b/apps/openmw/mwclass/bodypart.hpp @@ -12,20 +12,20 @@ namespace MWClass BodyPart(); - MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const override; public: - - void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; + void insertObjectRendering(const MWWorld::Ptr& ptr, const std::string& model, + MWRender::RenderingInterface& renderingInterface) const override; ///< Add reference into a cell for rendering - std::string_view getName (const MWWorld::ConstPtr& ptr) const override; + std::string_view getName(const MWWorld::ConstPtr& ptr) const override; ///< \return name or ID; can return an empty string. - bool hasToolTip (const MWWorld::ConstPtr& ptr) const override; + bool hasToolTip(const MWWorld::ConstPtr& ptr) const override; ///< @return true if this object has a tooltip when focused (default implementation: true) - std::string getModel(const MWWorld::ConstPtr &ptr) const override; + std::string getModel(const MWWorld::ConstPtr& ptr) const override; }; } diff --git a/apps/openmw/mwclass/book.cpp b/apps/openmw/mwclass/book.cpp index c1734be946..6df4585deb 100644 --- a/apps/openmw/mwclass/book.cpp +++ b/apps/openmw/mwclass/book.cpp @@ -6,14 +6,14 @@ #include #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" -#include "../mwworld/ptr.hpp" #include "../mwworld/actionread.hpp" -#include "../mwworld/failedaction.hpp" #include "../mwworld/cellstore.hpp" #include "../mwworld/esmstore.hpp" +#include "../mwworld/failedaction.hpp" +#include "../mwworld/ptr.hpp" #include "../mwrender/objects.hpp" #include "../mwrender/renderinginterface.hpp" @@ -32,37 +32,39 @@ namespace MWClass { } - void Book::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const + void Book::insertObjectRendering( + const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const { - if (!model.empty()) { + if (!model.empty()) + { renderingInterface.getObjects().insertModel(ptr, model); } } - std::string Book::getModel(const MWWorld::ConstPtr &ptr) const + std::string Book::getModel(const MWWorld::ConstPtr& ptr) const { return getClassModel(ptr); } std::string_view Book::getName(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); const std::string& name = ref->mBase->mName; return !name.empty() ? name : ref->mBase->mId; } - std::unique_ptr Book::activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const + std::unique_ptr Book::activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const { - if(actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf()) + if (actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf()) { - const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); auto& prng = MWBase::Environment::get().getWorld()->getPrng(); - const ESM::Sound *sound = store.get().searchRandom("WolfItem", prng); + const ESM::Sound* sound = store.get().searchRandom("WolfItem", prng); std::unique_ptr action = std::make_unique("#{sWerewolfRefusal}"); - if(sound) action->setSound(sound->mId); + if (sound) + action->setSound(sound->mId); return action; } @@ -72,14 +74,14 @@ namespace MWClass std::string_view Book::getScript(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mScript; } - int Book::getValue (const MWWorld::ConstPtr& ptr) const + int Book::getValue(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mData.mValue; } @@ -96,18 +98,19 @@ namespace MWClass const std::string& Book::getInventoryIcon(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mIcon; } - MWGui::ToolTipInfo Book::getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const + MWGui::ToolTipInfo Book::getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); MWGui::ToolTipInfo info; std::string_view name = getName(ptr); - info.caption = MyGUI::TextIterator::toTagsString(MWGui::toUString(name)) + MWGui::ToolTips::getCountString(count); + info.caption + = MyGUI::TextIterator::toTagsString(MWGui::toUString(name)) + MWGui::ToolTips::getCountString(count); info.icon = ref->mBase->mIcon; std::string text; @@ -130,53 +133,54 @@ namespace MWClass std::string_view Book::getEnchantment(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mEnchant; } - const std::string& Book::applyEnchantment(const MWWorld::ConstPtr& ptr, const std::string& enchId, int enchCharge, const std::string& newName) const + const std::string& Book::applyEnchantment( + const MWWorld::ConstPtr& ptr, const std::string& enchId, int enchCharge, const std::string& newName) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); ESM::Book newItem = *ref->mBase; newItem.mId.clear(); - newItem.mName=newName; + newItem.mName = newName; newItem.mData.mIsScroll = 1; - newItem.mData.mEnchant=enchCharge; - newItem.mEnchant=enchId; - const ESM::Book *record = MWBase::Environment::get().getWorld()->createRecord (newItem); + newItem.mData.mEnchant = enchCharge; + newItem.mEnchant = enchId; + const ESM::Book* record = MWBase::Environment::get().getWorld()->createRecord(newItem); return record->mId; } - std::unique_ptr Book::use (const MWWorld::Ptr& ptr, bool force) const + std::unique_ptr Book::use(const MWWorld::Ptr& ptr, bool force) const { return std::make_unique(ptr); } - MWWorld::Ptr Book::copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const + MWWorld::Ptr Book::copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return MWWorld::Ptr(cell.insert(ref), &cell); } - int Book::getEnchantmentPoints (const MWWorld::ConstPtr& ptr) const + int Book::getEnchantmentPoints(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mData.mEnchant; } - bool Book::canSell (const MWWorld::ConstPtr& item, int npcServices) const + bool Book::canSell(const MWWorld::ConstPtr& item, int npcServices) const { return (npcServices & ESM::NPC::Books) - || ((npcServices & ESM::NPC::MagicItems) && !getEnchantment(item).empty()); + || ((npcServices & ESM::NPC::MagicItems) && !getEnchantment(item).empty()); } - float Book::getWeight(const MWWorld::ConstPtr &ptr) const + float Book::getWeight(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mData.mWeight; } } diff --git a/apps/openmw/mwclass/book.hpp b/apps/openmw/mwclass/book.hpp index 0cb6c48a59..7b9731c9f5 100644 --- a/apps/openmw/mwclass/book.hpp +++ b/apps/openmw/mwclass/book.hpp @@ -7,58 +7,58 @@ namespace MWClass { class Book : public MWWorld::RegisteredClass { - friend MWWorld::RegisteredClass; + friend MWWorld::RegisteredClass; - Book(); + Book(); - MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const override; - public: + public: + void insertObjectRendering(const MWWorld::Ptr& ptr, const std::string& model, + MWRender::RenderingInterface& renderingInterface) const override; + ///< Add reference into a cell for rendering - void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; - ///< Add reference into a cell for rendering + std::string_view getName(const MWWorld::ConstPtr& ptr) const override; + ///< \return name or ID; can return an empty string. - std::string_view getName(const MWWorld::ConstPtr& ptr) const override; - ///< \return name or ID; can return an empty string. + std::unique_ptr activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const override; + ///< Generate action for activation - std::unique_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const override; - ///< Generate action for activation + std::string_view getScript(const MWWorld::ConstPtr& ptr) const override; + ///< Return name of the script attached to ptr - std::string_view getScript(const MWWorld::ConstPtr& ptr) const override; - ///< Return name of the script attached to ptr + MWGui::ToolTipInfo getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const override; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. - MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const override; - ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + int getValue(const MWWorld::ConstPtr& ptr) const override; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. - int getValue (const MWWorld::ConstPtr& ptr) const override; - ///< Return trade value of the object. Throws an exception, if the object can't be traded. + std::string_view getUpSoundId(const MWWorld::ConstPtr& ptr) const override; + ///< Return the pick up sound Id - std::string_view getUpSoundId(const MWWorld::ConstPtr& ptr) const override; - ///< Return the pick up sound Id + std::string_view getDownSoundId(const MWWorld::ConstPtr& ptr) const override; + ///< Return the put down sound Id - std::string_view getDownSoundId(const MWWorld::ConstPtr& ptr) const override; - ///< Return the put down sound Id + const std::string& getInventoryIcon(const MWWorld::ConstPtr& ptr) const override; + ///< Return name of inventory icon. - const std::string& getInventoryIcon(const MWWorld::ConstPtr& ptr) const override; - ///< Return name of inventory icon. + std::string_view getEnchantment(const MWWorld::ConstPtr& ptr) const override; + ///< @return the enchantment ID if the object is enchanted, otherwise an empty string - std::string_view getEnchantment(const MWWorld::ConstPtr& ptr) const override; - ///< @return the enchantment ID if the object is enchanted, otherwise an empty string + const std::string& applyEnchantment(const MWWorld::ConstPtr& ptr, const std::string& enchId, int enchCharge, + const std::string& newName) const override; + ///< Creates a new record using \a ptr as template, with the given name and the given enchantment applied to it. - const std::string& applyEnchantment(const MWWorld::ConstPtr& ptr, const std::string& enchId, int enchCharge, const std::string& newName) const override; - ///< Creates a new record using \a ptr as template, with the given name and the given enchantment applied to it. + std::unique_ptr use(const MWWorld::Ptr& ptr, bool force = false) const override; + ///< Generate action for using via inventory menu - std::unique_ptr use (const MWWorld::Ptr& ptr, bool force=false) const override; - ///< Generate action for using via inventory menu + std::string getModel(const MWWorld::ConstPtr& ptr) const override; - std::string getModel(const MWWorld::ConstPtr &ptr) const override; + int getEnchantmentPoints(const MWWorld::ConstPtr& ptr) const override; - int getEnchantmentPoints (const MWWorld::ConstPtr& ptr) const override; + float getWeight(const MWWorld::ConstPtr& ptr) const override; - float getWeight (const MWWorld::ConstPtr& ptr) const override; - - bool canSell (const MWWorld::ConstPtr& item, int npcServices) const override; + bool canSell(const MWWorld::ConstPtr& item, int npcServices) const override; }; } diff --git a/apps/openmw/mwclass/classes.cpp b/apps/openmw/mwclass/classes.cpp index a552dfebf0..8303a3a74d 100644 --- a/apps/openmw/mwclass/classes.cpp +++ b/apps/openmw/mwclass/classes.cpp @@ -1,26 +1,26 @@ #include "classes.hpp" #include "activator.hpp" -#include "creature.hpp" -#include "npc.hpp" -#include "weapon.hpp" -#include "armor.hpp" -#include "potion.hpp" #include "apparatus.hpp" +#include "armor.hpp" +#include "bodypart.hpp" #include "book.hpp" #include "clothing.hpp" #include "container.hpp" +#include "creature.hpp" +#include "creaturelevlist.hpp" #include "door.hpp" #include "ingredient.hpp" -#include "creaturelevlist.hpp" #include "itemlevlist.hpp" #include "light.hpp" #include "lockpick.hpp" #include "misc.hpp" +#include "npc.hpp" +#include "potion.hpp" #include "probe.hpp" #include "repair.hpp" #include "static.hpp" -#include "bodypart.hpp" +#include "weapon.hpp" namespace MWClass { diff --git a/apps/openmw/mwclass/classmodel.hpp b/apps/openmw/mwclass/classmodel.hpp index 3f5997cf4d..5d1019ee1d 100644 --- a/apps/openmw/mwclass/classmodel.hpp +++ b/apps/openmw/mwclass/classmodel.hpp @@ -3,8 +3,8 @@ #include "../mwbase/environment.hpp" -#include "../mwworld/ptr.hpp" #include "../mwworld/livecellref.hpp" +#include "../mwworld/ptr.hpp" #include #include @@ -16,11 +16,11 @@ namespace MWClass template std::string getClassModel(const MWWorld::ConstPtr& ptr) { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); if (!ref->mBase->mModel.empty()) - return Misc::ResourceHelpers::correctMeshPath(ref->mBase->mModel, - MWBase::Environment::get().getResourceSystem()->getVFS()); + return Misc::ResourceHelpers::correctMeshPath( + ref->mBase->mModel, MWBase::Environment::get().getResourceSystem()->getVFS()); return {}; } diff --git a/apps/openmw/mwclass/clothing.cpp b/apps/openmw/mwclass/clothing.cpp index 3413c271ff..6a4353a5b6 100644 --- a/apps/openmw/mwclass/clothing.cpp +++ b/apps/openmw/mwclass/clothing.cpp @@ -3,18 +3,18 @@ #include #include -#include #include +#include #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" -#include "../mwworld/ptr.hpp" #include "../mwworld/actionequip.hpp" -#include "../mwworld/inventorystore.hpp" #include "../mwworld/cellstore.hpp" #include "../mwworld/esmstore.hpp" +#include "../mwworld/inventorystore.hpp" +#include "../mwworld/ptr.hpp" #include "../mwgui/tooltips.hpp" #include "../mwgui/ustring.hpp" @@ -31,57 +31,56 @@ namespace MWClass { } - void Clothing::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const + void Clothing::insertObjectRendering( + const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const { - if (!model.empty()) { + if (!model.empty()) + { renderingInterface.getObjects().insertModel(ptr, model); } } - std::string Clothing::getModel(const MWWorld::ConstPtr &ptr) const + std::string Clothing::getModel(const MWWorld::ConstPtr& ptr) const { return getClassModel(ptr); } std::string_view Clothing::getName(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); const std::string& name = ref->mBase->mName; return !name.empty() ? name : ref->mBase->mId; } - std::unique_ptr Clothing::activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const + std::unique_ptr Clothing::activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const { return defaultItemActivate(ptr, actor); } std::string_view Clothing::getScript(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mScript; } - std::pair, bool> Clothing::getEquipmentSlots (const MWWorld::ConstPtr& ptr) const + std::pair, bool> Clothing::getEquipmentSlots(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); std::vector slots_; - if (ref->mBase->mData.mType==ESM::Clothing::Ring) + if (ref->mBase->mData.mType == ESM::Clothing::Ring) { - slots_.push_back (int (MWWorld::InventoryStore::Slot_LeftRing)); - slots_.push_back (int (MWWorld::InventoryStore::Slot_RightRing)); + slots_.push_back(int(MWWorld::InventoryStore::Slot_LeftRing)); + slots_.push_back(int(MWWorld::InventoryStore::Slot_RightRing)); } else { const int size = 9; - static const int sMapping[size][2] = - { - { ESM::Clothing::Shirt, MWWorld::InventoryStore::Slot_Shirt }, + static const int sMapping[size][2] = { { ESM::Clothing::Shirt, MWWorld::InventoryStore::Slot_Shirt }, { ESM::Clothing::Belt, MWWorld::InventoryStore::Slot_Belt }, { ESM::Clothing::Robe, MWWorld::InventoryStore::Slot_Robe }, { ESM::Clothing::Pants, MWWorld::InventoryStore::Slot_Pants }, @@ -89,40 +88,39 @@ namespace MWClass { ESM::Clothing::LGlove, MWWorld::InventoryStore::Slot_LeftGauntlet }, { ESM::Clothing::RGlove, MWWorld::InventoryStore::Slot_RightGauntlet }, { ESM::Clothing::Skirt, MWWorld::InventoryStore::Slot_Skirt }, - { ESM::Clothing::Amulet, MWWorld::InventoryStore::Slot_Amulet } - }; + { ESM::Clothing::Amulet, MWWorld::InventoryStore::Slot_Amulet } }; - for (int i=0; imBase->mData.mType) + for (int i = 0; i < size; ++i) + if (sMapping[i][0] == ref->mBase->mData.mType) { - slots_.push_back (int (sMapping[i][1])); + slots_.push_back(int(sMapping[i][1])); break; } } - return std::make_pair (slots_, false); + return std::make_pair(slots_, false); } - int Clothing::getEquipmentSkill (const MWWorld::ConstPtr& ptr) const + int Clothing::getEquipmentSkill(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); - if (ref->mBase->mData.mType==ESM::Clothing::Shoes) + if (ref->mBase->mData.mType == ESM::Clothing::Shoes) return ESM::Skill::Unarmored; return -1; } - int Clothing::getValue (const MWWorld::ConstPtr& ptr) const + int Clothing::getValue(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mData.mValue; } std::string_view Clothing::getUpSoundId(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); if (ref->mBase->mData.mType == 8) { @@ -133,7 +131,7 @@ namespace MWClass std::string_view Clothing::getDownSoundId(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); if (ref->mBase->mData.mType == 8) { @@ -144,18 +142,19 @@ namespace MWClass const std::string& Clothing::getInventoryIcon(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mIcon; } - MWGui::ToolTipInfo Clothing::getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const + MWGui::ToolTipInfo Clothing::getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); MWGui::ToolTipInfo info; std::string_view name = getName(ptr); - info.caption = MyGUI::TextIterator::toTagsString(MWGui::toUString(name)) + MWGui::ToolTips::getCountString(count); + info.caption + = MyGUI::TextIterator::toTagsString(MWGui::toUString(name)) + MWGui::ToolTips::getCountString(count); info.icon = ref->mBase->mIcon; std::string text; @@ -180,31 +179,33 @@ namespace MWClass std::string_view Clothing::getEnchantment(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mEnchant; } - const std::string& Clothing::applyEnchantment(const MWWorld::ConstPtr& ptr, const std::string& enchId, int enchCharge, const std::string& newName) const + const std::string& Clothing::applyEnchantment( + const MWWorld::ConstPtr& ptr, const std::string& enchId, int enchCharge, const std::string& newName) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); ESM::Clothing newItem = *ref->mBase; newItem.mId.clear(); - newItem.mName=newName; - newItem.mData.mEnchant=enchCharge; - newItem.mEnchant=enchId; - const ESM::Clothing *record = MWBase::Environment::get().getWorld()->createRecord (newItem); + newItem.mName = newName; + newItem.mData.mEnchant = enchCharge; + newItem.mEnchant = enchId; + const ESM::Clothing* record = MWBase::Environment::get().getWorld()->createRecord(newItem); return record->mId; } - std::pair Clothing::canBeEquipped(const MWWorld::ConstPtr& ptr, const MWWorld::Ptr& npc) const + std::pair Clothing::canBeEquipped( + const MWWorld::ConstPtr& ptr, const MWWorld::Ptr& npc) const { // slots that this item can be equipped in std::pair, bool> slots_ = getEquipmentSlots(ptr); if (slots_.first.empty()) - return {0, {}}; + return { 0, {} }; if (npc.getClass().isNpc()) { @@ -212,24 +213,24 @@ namespace MWClass // Beast races cannot equip shoes / boots, or full helms (head part vs hair part) const ESM::Race* race = MWBase::Environment::get().getWorld()->getStore().get().find(npcRace); - if(race->mData.mFlags & ESM::Race::Beast) + if (race->mData.mFlags & ESM::Race::Beast) { std::vector parts = ptr.get()->mBase->mParts.mParts; - for(std::vector::iterator itr = parts.begin(); itr != parts.end(); ++itr) + for (std::vector::iterator itr = parts.begin(); itr != parts.end(); ++itr) { - if((*itr).mPart == ESM::PRT_Head) - return {0, "#{sNotifyMessage13}"}; - if((*itr).mPart == ESM::PRT_LFoot || (*itr).mPart == ESM::PRT_RFoot) - return {0, "#{sNotifyMessage15}"}; + if ((*itr).mPart == ESM::PRT_Head) + return { 0, "#{sNotifyMessage13}" }; + if ((*itr).mPart == ESM::PRT_LFoot || (*itr).mPart == ESM::PRT_RFoot) + return { 0, "#{sNotifyMessage15}" }; } } } - return {1, {}}; + return { 1, {} }; } - std::unique_ptr Clothing::use (const MWWorld::Ptr& ptr, bool force) const + std::unique_ptr Clothing::use(const MWWorld::Ptr& ptr, bool force) const { std::unique_ptr action = std::make_unique(ptr, force); @@ -238,29 +239,29 @@ namespace MWClass return action; } - MWWorld::Ptr Clothing::copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const + MWWorld::Ptr Clothing::copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return MWWorld::Ptr(cell.insert(ref), &cell); } - int Clothing::getEnchantmentPoints (const MWWorld::ConstPtr& ptr) const + int Clothing::getEnchantmentPoints(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mData.mEnchant; } - bool Clothing::canSell (const MWWorld::ConstPtr& item, int npcServices) const + bool Clothing::canSell(const MWWorld::ConstPtr& item, int npcServices) const { return (npcServices & ESM::NPC::Clothing) - || ((npcServices & ESM::NPC::MagicItems) && !getEnchantment(item).empty()); + || ((npcServices & ESM::NPC::MagicItems) && !getEnchantment(item).empty()); } - float Clothing::getWeight(const MWWorld::ConstPtr &ptr) const + float Clothing::getWeight(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mData.mWeight; } } diff --git a/apps/openmw/mwclass/clothing.hpp b/apps/openmw/mwclass/clothing.hpp index beca02f77a..bd6875b217 100644 --- a/apps/openmw/mwclass/clothing.hpp +++ b/apps/openmw/mwclass/clothing.hpp @@ -7,70 +7,72 @@ namespace MWClass { class Clothing : public MWWorld::RegisteredClass { - friend MWWorld::RegisteredClass; + friend MWWorld::RegisteredClass; - Clothing(); + Clothing(); - MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const override; - public: + public: + void insertObjectRendering(const MWWorld::Ptr& ptr, const std::string& model, + MWRender::RenderingInterface& renderingInterface) const override; + ///< Add reference into a cell for rendering - void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; - ///< Add reference into a cell for rendering + std::string_view getName(const MWWorld::ConstPtr& ptr) const override; + ///< \return name or ID; can return an empty string. - std::string_view getName(const MWWorld::ConstPtr& ptr) const override; - ///< \return name or ID; can return an empty string. + std::unique_ptr activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const override; + ///< Generate action for activation - std::unique_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const override; - ///< Generate action for activation + std::string_view getScript(const MWWorld::ConstPtr& ptr) const override; + ///< Return name of the script attached to ptr - std::string_view getScript(const MWWorld::ConstPtr& ptr) const override; - ///< Return name of the script attached to ptr + std::pair, bool> getEquipmentSlots(const MWWorld::ConstPtr& ptr) const override; + ///< \return first: Return IDs of the slot this object can be equipped in; second: can object + /// stay stacked when equipped? - std::pair, bool> getEquipmentSlots (const MWWorld::ConstPtr& ptr) const override; - ///< \return first: Return IDs of the slot this object can be equipped in; second: can object - /// stay stacked when equipped? + int getEquipmentSkill(const MWWorld::ConstPtr& ptr) const override; + /// Return the index of the skill this item corresponds to when equipped or -1, if there is + /// no such skill. - int getEquipmentSkill (const MWWorld::ConstPtr& ptr) const override; - /// Return the index of the skill this item corresponds to when equipped or -1, if there is - /// no such skill. + MWGui::ToolTipInfo getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const override; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. - MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const override; - ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + int getValue(const MWWorld::ConstPtr& ptr) const override; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. - int getValue (const MWWorld::ConstPtr& ptr) const override; - ///< Return trade value of the object. Throws an exception, if the object can't be traded. + std::string_view getUpSoundId(const MWWorld::ConstPtr& ptr) const override; + ///< Return the pick up sound Id - std::string_view getUpSoundId(const MWWorld::ConstPtr& ptr) const override; - ///< Return the pick up sound Id + std::string_view getDownSoundId(const MWWorld::ConstPtr& ptr) const override; + ///< Return the put down sound Id - std::string_view getDownSoundId(const MWWorld::ConstPtr& ptr) const override; - ///< Return the put down sound Id + const std::string& getInventoryIcon(const MWWorld::ConstPtr& ptr) const override; + ///< Return name of inventory icon. - const std::string& getInventoryIcon(const MWWorld::ConstPtr& ptr) const override; - ///< Return name of inventory icon. + std::string_view getEnchantment(const MWWorld::ConstPtr& ptr) const override; + ///< @return the enchantment ID if the object is enchanted, otherwise an empty string - std::string_view getEnchantment(const MWWorld::ConstPtr& ptr) const override; - ///< @return the enchantment ID if the object is enchanted, otherwise an empty string + const std::string& applyEnchantment(const MWWorld::ConstPtr& ptr, const std::string& enchId, int enchCharge, + const std::string& newName) const override; + ///< Creates a new record using \a ptr as template, with the given name and the given enchantment applied to it. - const std::string& applyEnchantment(const MWWorld::ConstPtr& ptr, const std::string& enchId, int enchCharge, const std::string& newName) const override; - ///< Creates a new record using \a ptr as template, with the given name and the given enchantment applied to it. + std::pair canBeEquipped( + const MWWorld::ConstPtr& ptr, const MWWorld::Ptr& npc) const override; + ///< Return 0 if player cannot equip item. 1 if can equip. 2 if it's twohanded weapon. 3 if twohanded weapon + ///< conflicts with that. + /// Second item in the pair specifies the error message - std::pair canBeEquipped(const MWWorld::ConstPtr& ptr, const MWWorld::Ptr& npc) const override; - ///< Return 0 if player cannot equip item. 1 if can equip. 2 if it's twohanded weapon. 3 if twohanded weapon conflicts with that. - /// Second item in the pair specifies the error message + std::unique_ptr use(const MWWorld::Ptr& ptr, bool force = false) const override; + ///< Generate action for using via inventory menu - std::unique_ptr use (const MWWorld::Ptr& ptr, bool force=false) const override; - ///< Generate action for using via inventory menu + std::string getModel(const MWWorld::ConstPtr& ptr) const override; - std::string getModel(const MWWorld::ConstPtr &ptr) const override; + int getEnchantmentPoints(const MWWorld::ConstPtr& ptr) const override; - int getEnchantmentPoints (const MWWorld::ConstPtr& ptr) const override; + float getWeight(const MWWorld::ConstPtr& ptr) const override; - float getWeight (const MWWorld::ConstPtr& ptr) const override; - - bool canSell (const MWWorld::ConstPtr& item, int npcServices) const override; + bool canSell(const MWWorld::ConstPtr& item, int npcServices) const override; }; } diff --git a/apps/openmw/mwclass/container.cpp b/apps/openmw/mwclass/container.cpp index a95c90d1b1..cd6805ab6c 100644 --- a/apps/openmw/mwclass/container.cpp +++ b/apps/openmw/mwclass/container.cpp @@ -2,25 +2,25 @@ #include -#include #include -#include +#include #include +#include #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" -#include "../mwbase/windowmanager.hpp" #include "../mwbase/soundmanager.hpp" +#include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" -#include "../mwworld/failedaction.hpp" -#include "../mwworld/nullaction.hpp" -#include "../mwworld/cellstore.hpp" -#include "../mwworld/esmstore.hpp" +#include "../mwphysics/physicssystem.hpp" #include "../mwworld/actionharvest.hpp" #include "../mwworld/actionopen.hpp" #include "../mwworld/actiontrap.hpp" -#include "../mwphysics/physicssystem.hpp" +#include "../mwworld/cellstore.hpp" +#include "../mwworld/esmstore.hpp" +#include "../mwworld/failedaction.hpp" #include "../mwworld/inventorystore.hpp" +#include "../mwworld/nullaction.hpp" #include "../mwgui/tooltips.hpp" #include "../mwgui/ustring.hpp" @@ -29,8 +29,8 @@ #include "../mwrender/objects.hpp" #include "../mwrender/renderinginterface.hpp" -#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/inventory.hpp" +#include "../mwmechanics/npcstats.hpp" #include "classmodel.hpp" @@ -65,14 +65,14 @@ namespace MWClass { } - void Container::ensureCustomData (const MWWorld::Ptr& ptr) const + void Container::ensureCustomData(const MWWorld::Ptr& ptr) const { if (!ptr.getRefData().getCustomData()) { - MWWorld::LiveCellRef *ref = ptr.get(); + MWWorld::LiveCellRef* ref = ptr.get(); // store - ptr.getRefData().setCustomData (std::make_unique(*ref->mBase, ptr.getCell())); + ptr.getRefData().setCustomData(std::make_unique(*ref->mBase, ptr.getCell())); MWBase::Environment::get().getWorld()->addContainerScripts(ptr, ptr.getCell()); } @@ -89,10 +89,9 @@ namespace MWClass return animation->canBeHarvested(); } - void Container::respawn(const MWWorld::Ptr &ptr) const + void Container::respawn(const MWWorld::Ptr& ptr) const { - MWWorld::LiveCellRef *ref = - ptr.get(); + MWWorld::LiveCellRef* ref = ptr.get(); if (ref->mBase->mFlags & ESM::Container::Respawn) { // Container was not touched, there is no need to modify its content. @@ -104,24 +103,28 @@ namespace MWClass } } - void Container::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const + void Container::insertObjectRendering( + const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const { - if (!model.empty()) { + if (!model.empty()) + { renderingInterface.getObjects().insertModel(ptr, model, true); } } - void Container::insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const + void Container::insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, + MWPhysics::PhysicsSystem& physics) const { insertObjectPhysics(ptr, model, rotation, physics); } - void Container::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const + void Container::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, + MWPhysics::PhysicsSystem& physics) const { physics.addObject(ptr, model, rotation, MWPhysics::CollisionType_World); } - std::string Container::getModel(const MWWorld::ConstPtr &ptr) const + std::string Container::getModel(const MWWorld::ConstPtr& ptr) const { return getClassModel(ptr); } @@ -131,20 +134,20 @@ namespace MWClass return true; } - std::unique_ptr Container::activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const + std::unique_ptr Container::activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const { if (!MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Inventory)) return std::make_unique(); - if(actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf()) + if (actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf()) { - const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); auto& prng = MWBase::Environment::get().getWorld()->getPrng(); - const ESM::Sound *sound = store.get().searchRandom("WolfContainer", prng); + const ESM::Sound* sound = store.get().searchRandom("WolfContainer", prng); std::unique_ptr action = std::make_unique("#{sWerewolfRefusal}"); - if(sound) action->setSound(sound->mId); + if (sound) + action->setSound(sound->mId); return action; } @@ -152,7 +155,7 @@ namespace MWClass const std::string_view lockedSound = "LockedChest"; const std::string_view trapActivationSound = "Disarm Trap Fail"; - MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWWorld::InventoryStore& invStore = player.getClass().getInventoryStore(player); bool isLocked = ptr.getCellRef().getLockLevel() > 0; @@ -173,10 +176,10 @@ namespace MWClass if (isLocked && hasKey) { - MWBase::Environment::get().getWindowManager ()->messageBox(std::string{keyName} + " #{sKeyUsed}"); + MWBase::Environment::get().getWindowManager()->messageBox(std::string{ keyName } + " #{sKeyUsed}"); ptr.getCellRef().unlock(); // using a key disarms the trap - if(isTrapped) + if (isTrapped) { ptr.getCellRef().setTrap(""); MWBase::Environment::get().getSoundManager()->playSound3D(ptr, "Disarm Trap", 1.0f, 1.0f); @@ -184,10 +187,9 @@ namespace MWClass } } - if (!isLocked || hasKey) { - if(!isTrapped) + if (!isTrapped) { if (canBeHarvested(ptr)) { @@ -199,7 +201,8 @@ namespace MWClass else { // Activate trap - std::unique_ptr action = std::make_unique(ptr.getCellRef().getTrap(), ptr); + std::unique_ptr action + = std::make_unique(ptr.getCellRef().getTrap(), ptr); action->setSound(trapActivationSound); return action; } @@ -214,15 +217,15 @@ namespace MWClass std::string_view Container::getName(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); const std::string& name = ref->mBase->mName; return !name.empty() ? name : ref->mBase->mId; } - MWWorld::ContainerStore& Container::getContainerStore (const MWWorld::Ptr& ptr) const + MWWorld::ContainerStore& Container::getContainerStore(const MWWorld::Ptr& ptr) const { - ensureCustomData (ptr); + ensureCustomData(ptr); auto& data = ptr.getRefData().getCustomData()->asContainerCustomData(); data.mStore.mPtr = ptr; return data.mStore; @@ -230,21 +233,21 @@ namespace MWClass std::string_view Container::getScript(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mScript; } - bool Container::hasToolTip (const MWWorld::ConstPtr& ptr) const + bool Container::hasToolTip(const MWWorld::ConstPtr& ptr) const { if (const MWWorld::CustomData* data = ptr.getRefData().getCustomData()) return !canBeHarvested(ptr) || data->asContainerCustomData().mStore.hasVisibleItems(); return true; } - MWGui::ToolTipInfo Container::getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const + MWGui::ToolTipInfo Container::getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); MWGui::ToolTipInfo info; std::string_view name = getName(ptr); @@ -260,7 +263,8 @@ namespace MWClass text += "\n#{sTrapped}"; if (MWBase::Environment::get().getWindowManager()->getFullHelp()) - { text += MWGui::ToolTips::getCellRefString(ptr.getCellRef()); + { + text += MWGui::ToolTips::getCellRefString(ptr.getCellRef()); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); if (Misc::StringUtils::ciEqual(ptr.getCellRef().getRefId(), "stolen_goods")) text += "\nYou can not use evidence chests"; @@ -271,22 +275,21 @@ namespace MWClass return info; } - float Container::getCapacity (const MWWorld::Ptr& ptr) const + float Container::getCapacity(const MWWorld::Ptr& ptr) const { - MWWorld::LiveCellRef *ref = - ptr.get(); + MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mWeight; } - float Container::getEncumbrance (const MWWorld::Ptr& ptr) const + float Container::getEncumbrance(const MWWorld::Ptr& ptr) const { - return getContainerStore (ptr).getWeight(); + return getContainerStore(ptr).getWeight(); } - bool Container::canLock(const MWWorld::ConstPtr &ptr) const + bool Container::canLock(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return !(ref->mBase->mFlags & ESM::Container::Organic); } @@ -295,14 +298,14 @@ namespace MWClass MWMechanics::modifyBaseInventory(containerId, itemId, amount); } - MWWorld::Ptr Container::copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const + MWWorld::Ptr Container::copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return MWWorld::Ptr(cell.insert(ref), &cell); } - void Container::readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state) const + void Container::readAdditionalState(const MWWorld::Ptr& ptr, const ESM::ObjectState& state) const { if (!state.mHasCustomState) return; @@ -311,7 +314,7 @@ namespace MWClass ptr.getRefData().setCustomData(std::make_unique(containerState.mInventory)); } - void Container::writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const + void Container::writeAdditionalState(const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const { if (!ptr.getRefData().getCustomData()) { @@ -327,6 +330,6 @@ namespace MWClass } ESM::ContainerState& containerState = state.asContainerState(); - customData.mStore.writeState (containerState.mInventory); + customData.mStore.writeState(containerState.mInventory); } } diff --git a/apps/openmw/mwclass/container.hpp b/apps/openmw/mwclass/container.hpp index b9573700d6..7126de3afa 100644 --- a/apps/openmw/mwclass/container.hpp +++ b/apps/openmw/mwclass/container.hpp @@ -1,9 +1,9 @@ #ifndef GAME_MWCLASS_CONTAINER_H #define GAME_MWCLASS_CONTAINER_H -#include "../mwworld/registeredclass.hpp" #include "../mwworld/containerstore.hpp" #include "../mwworld/customdata.hpp" +#include "../mwworld/registeredclass.hpp" namespace ESM { @@ -16,6 +16,7 @@ namespace MWClass class ContainerCustomData : public MWWorld::TypedCustomData { MWWorld::ContainerStore mStore; + public: ContainerCustomData(const ESM::Container& container, MWWorld::CellStore* cell); ContainerCustomData(const ESM::InventoryState& inventory); @@ -28,68 +29,69 @@ namespace MWClass class Container : public MWWorld::RegisteredClass { - friend MWWorld::RegisteredClass; + friend MWWorld::RegisteredClass; - const bool mHarvestEnabled; + const bool mHarvestEnabled; - Container(); + Container(); - void ensureCustomData (const MWWorld::Ptr& ptr) const; + void ensureCustomData(const MWWorld::Ptr& ptr) const; - MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const override; - bool canBeHarvested(const MWWorld::ConstPtr& ptr) const; + bool canBeHarvested(const MWWorld::ConstPtr& ptr) const; - public: - void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; - ///< Add reference into a cell for rendering + public: + void insertObjectRendering(const MWWorld::Ptr& ptr, const std::string& model, + MWRender::RenderingInterface& renderingInterface) const override; + ///< Add reference into a cell for rendering - void insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const override; - void insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const override; + void insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, + MWPhysics::PhysicsSystem& physics) const override; + void insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, + MWPhysics::PhysicsSystem& physics) const override; - std::string_view getName(const MWWorld::ConstPtr& ptr) const override; - ///< \return name or ID; can return an empty string. + std::string_view getName(const MWWorld::ConstPtr& ptr) const override; + ///< \return name or ID; can return an empty string. - std::unique_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const override; - ///< Generate action for activation + std::unique_ptr activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const override; + ///< Generate action for activation - bool hasToolTip (const MWWorld::ConstPtr& ptr) const override; - ///< @return true if this object has a tooltip when focused (default implementation: true) + bool hasToolTip(const MWWorld::ConstPtr& ptr) const override; + ///< @return true if this object has a tooltip when focused (default implementation: true) - MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const override; - ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + MWGui::ToolTipInfo getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const override; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. - MWWorld::ContainerStore& getContainerStore (const MWWorld::Ptr& ptr) const override; - ///< Return container store + MWWorld::ContainerStore& getContainerStore(const MWWorld::Ptr& ptr) const override; + ///< Return container store - std::string_view getScript(const MWWorld::ConstPtr& ptr) const override; - ///< Return name of the script attached to ptr + std::string_view getScript(const MWWorld::ConstPtr& ptr) const override; + ///< Return name of the script attached to ptr - float getCapacity (const MWWorld::Ptr& ptr) const override; - ///< Return total weight that fits into the object. Throws an exception, if the object can't - /// hold other objects. + float getCapacity(const MWWorld::Ptr& ptr) const override; + ///< Return total weight that fits into the object. Throws an exception, if the object can't + /// hold other objects. - float getEncumbrance (const MWWorld::Ptr& ptr) const override; - ///< Returns total weight of objects inside this object (including modifications from magic - /// effects). Throws an exception, if the object can't hold other objects. + float getEncumbrance(const MWWorld::Ptr& ptr) const override; + ///< Returns total weight of objects inside this object (including modifications from magic + /// effects). Throws an exception, if the object can't hold other objects. - bool canLock(const MWWorld::ConstPtr &ptr) const override; + bool canLock(const MWWorld::ConstPtr& ptr) const override; - void readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state) - const override; - ///< Read additional state from \a state into \a ptr. + void readAdditionalState(const MWWorld::Ptr& ptr, const ESM::ObjectState& state) const override; + ///< Read additional state from \a state into \a ptr. - void writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const override; - ///< Write additional state from \a ptr into \a state. + void writeAdditionalState(const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const override; + ///< Write additional state from \a ptr into \a state. - void respawn (const MWWorld::Ptr& ptr) const override; + void respawn(const MWWorld::Ptr& ptr) const override; - std::string getModel(const MWWorld::ConstPtr &ptr) const override; + std::string getModel(const MWWorld::ConstPtr& ptr) const override; - bool useAnim() const override; + bool useAnim() const override; - void modifyBaseInventory(std::string_view containerId, std::string_view itemId, int amount) const override; + void modifyBaseInventory(std::string_view containerId, std::string_view itemId, int amount) const override; }; } diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index a3d6ce8212..eacd4a15e9 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -1,46 +1,46 @@ #include "creature.hpp" -#include #include -#include #include -#include -#include -#include #include +#include +#include +#include +#include +#include +#include "../mwmechanics/actorutil.hpp" +#include "../mwmechanics/aisetting.hpp" +#include "../mwmechanics/combat.hpp" +#include "../mwmechanics/creaturecustomdataresetter.hpp" #include "../mwmechanics/creaturestats.hpp" +#include "../mwmechanics/difficultyscaling.hpp" +#include "../mwmechanics/disease.hpp" +#include "../mwmechanics/inventory.hpp" #include "../mwmechanics/magiceffects.hpp" #include "../mwmechanics/movement.hpp" -#include "../mwmechanics/disease.hpp" -#include "../mwmechanics/difficultyscaling.hpp" #include "../mwmechanics/npcstats.hpp" -#include "../mwmechanics/combat.hpp" -#include "../mwmechanics/actorutil.hpp" -#include "../mwmechanics/creaturecustomdataresetter.hpp" -#include "../mwmechanics/aisetting.hpp" -#include "../mwmechanics/inventory.hpp" #include "../mwmechanics/setbaseaisetting.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwbase/windowmanager.hpp" #include "../mwbase/world.hpp" -#include "../mwbase/soundmanager.hpp" -#include "../mwworld/ptr.hpp" -#include "../mwworld/actiontalk.hpp" #include "../mwworld/actionopen.hpp" -#include "../mwworld/failedaction.hpp" -#include "../mwworld/customdata.hpp" -#include "../mwworld/containerstore.hpp" +#include "../mwworld/actiontalk.hpp" #include "../mwworld/cellstore.hpp" -#include "../mwworld/localscripts.hpp" -#include "../mwworld/inventorystore.hpp" +#include "../mwworld/containerstore.hpp" +#include "../mwworld/customdata.hpp" #include "../mwworld/esmstore.hpp" +#include "../mwworld/failedaction.hpp" +#include "../mwworld/inventorystore.hpp" +#include "../mwworld/localscripts.hpp" +#include "../mwworld/ptr.hpp" -#include "../mwrender/renderinginterface.hpp" #include "../mwrender/objects.hpp" +#include "../mwrender/renderinginterface.hpp" #include "../mwgui/tooltips.hpp" #include "../mwgui/ustring.hpp" @@ -49,7 +49,7 @@ namespace { - bool isFlagBitSet(const MWWorld::ConstPtr &ptr, ESM::Creature::Flags bitMask) + bool isFlagBitSet(const MWWorld::ConstPtr& ptr, ESM::Creature::Flags bitMask) { return (ptr.get()->mBase->mFlags & bitMask) != 0; } @@ -69,20 +69,14 @@ namespace MWClass CreatureCustomData(const CreatureCustomData& other); CreatureCustomData(CreatureCustomData&& other) = default; - CreatureCustomData& asCreatureCustomData() override - { - return *this; - } - const CreatureCustomData& asCreatureCustomData() const override - { - return *this; - } + CreatureCustomData& asCreatureCustomData() override { return *this; } + const CreatureCustomData& asCreatureCustomData() const override { return *this; } }; CreatureCustomData::CreatureCustomData(const CreatureCustomData& other) - : mCreatureStats(other.mCreatureStats), - mContainerStore(other.mContainerStore->clone()), - mMovement(other.mMovement) + : mCreatureStats(other.mCreatureStats) + , mContainerStore(other.mContainerStore->clone()) + , mMovement(other.mMovement) { } @@ -93,12 +87,11 @@ namespace MWClass const Creature::GMST& Creature::getGmst() { - static const GMST staticGmst = [] - { + static const GMST staticGmst = [] { GMST gmst; - const MWBase::World *world = MWBase::Environment::get().getWorld(); - const MWWorld::Store &store = world->getStore().get(); + const MWBase::World* world = MWBase::Environment::get().getWorld(); + const MWWorld::Store& store = world->getStore().get(); gmst.fMinWalkSpeedCreature = store.find("fMinWalkSpeedCreature"); gmst.fMaxWalkSpeedCreature = store.find("fMaxWalkSpeedCreature"); @@ -115,20 +108,20 @@ namespace MWClass gmst.iKnockDownOddsBase = store.find("iKnockDownOddsBase"); return gmst; - } (); + }(); return staticGmst; } - void Creature::ensureCustomData (const MWWorld::Ptr& ptr) const + void Creature::ensureCustomData(const MWWorld::Ptr& ptr) const { if (!ptr.getRefData().getCustomData()) { auto tempData = std::make_unique(); CreatureCustomData* data = tempData.get(); - MWMechanics::CreatureCustomDataResetter resetter {ptr}; + MWMechanics::CreatureCustomDataResetter resetter{ ptr }; ptr.getRefData().setCustomData(std::move(tempData)); - MWWorld::LiveCellRef *ref = ptr.get(); + MWWorld::LiveCellRef* ref = ptr.get(); // creature stats data->mCreatureStats.setAttribute(ESM::Attribute::Strength, ref->mBase->mData.mStrength); @@ -180,18 +173,19 @@ namespace MWClass } } - void Creature::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const + void Creature::insertObjectRendering( + const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const { MWRender::Objects& objects = renderingInterface.getObjects(); objects.insertCreature(ptr, model, hasInventoryStore(ptr)); } - std::string Creature::getModel(const MWWorld::ConstPtr &ptr) const + std::string Creature::getModel(const MWWorld::ConstPtr& ptr) const { return getClassModel(ptr); } - void Creature::getModelsToPreload(const MWWorld::Ptr &ptr, std::vector &models) const + void Creature::getModelsToPreload(const MWWorld::Ptr& ptr, std::vector& models) const { std::string model = getModel(ptr); if (!model.empty()) @@ -216,15 +210,15 @@ namespace MWClass std::string_view Creature::getName(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); const std::string& name = ref->mBase->mName; return !name.empty() ? name : ref->mBase->mId; } - MWMechanics::CreatureStats& Creature::getCreatureStats (const MWWorld::Ptr& ptr) const + MWMechanics::CreatureStats& Creature::getCreatureStats(const MWWorld::Ptr& ptr) const { - ensureCustomData (ptr); + ensureCustomData(ptr); return ptr.getRefData().getCustomData()->asCreatureCustomData().mCreatureStats; } @@ -238,31 +232,33 @@ namespace MWClass MWWorld::Ptr weapon; if (hasInventoryStore(ptr)) { - MWWorld::InventoryStore &inv = getInventoryStore(ptr); + MWWorld::InventoryStore& inv = getInventoryStore(ptr); MWWorld::ContainerStoreIterator weaponslot = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); if (weaponslot != inv.end() && weaponslot->getType() == ESM::Weapon::sRecordId) weapon = *weaponslot; } - MWBase::World *world = MWBase::Environment::get().getWorld(); - const MWWorld::Store &store = world->getStore().get(); + MWBase::World* world = MWBase::Environment::get().getWorld(); + const MWWorld::Store& store = world->getStore().get(); float dist = store.find("fCombatDistance")->mValue.getFloat(); if (!weapon.isEmpty()) dist *= weapon.get()->mBase->mData.mReach; - // For AI actors, get combat targets to use in the ray cast. Only those targets will return a positive hit result. + // For AI actors, get combat targets to use in the ray cast. Only those targets will return a positive hit + // result. std::vector targetActors; getCreatureStats(ptr).getAiSequence().getCombatTargets(targetActors); - std::pair result = MWBase::Environment::get().getWorld()->getHitContact(ptr, dist, targetActors); + std::pair result + = MWBase::Environment::get().getWorld()->getHitContact(ptr, dist, targetActors); if (result.first.isEmpty()) // Didn't hit anything return true; - const MWWorld::Class &othercls = result.first.getClass(); + const MWWorld::Class& othercls = result.first.getClass(); if (!othercls.isActor()) // Can't hit non-actors return true; - MWMechanics::CreatureStats &otherstats = othercls.getCreatureStats(result.first); + MWMechanics::CreatureStats& otherstats = othercls.getCreatureStats(result.first); if (otherstats.isDead()) // Can't hit dead actors return true; @@ -275,9 +271,10 @@ namespace MWClass return Misc::Rng::roll0to99(world->getPrng()) < hitchance; } - void Creature::hit(const MWWorld::Ptr& ptr, float attackStrength, int type, const MWWorld::Ptr& victim, const osg::Vec3f& hitPosition, bool success) const + void Creature::hit(const MWWorld::Ptr& ptr, float attackStrength, int type, const MWWorld::Ptr& victim, + const osg::Vec3f& hitPosition, bool success) const { - MWMechanics::CreatureStats &stats = getCreatureStats(ptr); + MWMechanics::CreatureStats& stats = getCreatureStats(ptr); if (stats.getDrawState() != MWMechanics::DrawState::Weapon) return; @@ -285,7 +282,7 @@ namespace MWClass MWWorld::Ptr weapon; if (hasInventoryStore(ptr)) { - MWWorld::InventoryStore &inv = getInventoryStore(ptr); + MWWorld::InventoryStore& inv = getInventoryStore(ptr); MWWorld::ContainerStoreIterator weaponslot = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); if (weaponslot != inv.end() && weaponslot->getType() == ESM::Weapon::sRecordId) weapon = *weaponslot; @@ -296,8 +293,8 @@ namespace MWClass if (victim.isEmpty()) return; // Didn't hit anything - const MWWorld::Class &othercls = victim.getClass(); - MWMechanics::CreatureStats &otherstats = othercls.getCreatureStats(victim); + const MWWorld::Class& othercls = victim.getClass(); + MWMechanics::CreatureStats& otherstats = othercls.getCreatureStats(victim); if (otherstats.isDead()) // Can't hit dead actors return; @@ -308,39 +305,39 @@ namespace MWClass return; } - MWWorld::LiveCellRef *ref = ptr.get(); - int min,max; + MWWorld::LiveCellRef* ref = ptr.get(); + int min, max; switch (type) { - case 0: - min = ref->mBase->mData.mAttack[0]; - max = ref->mBase->mData.mAttack[1]; - break; - case 1: - min = ref->mBase->mData.mAttack[2]; - max = ref->mBase->mData.mAttack[3]; - break; - case 2: - default: - min = ref->mBase->mData.mAttack[4]; - max = ref->mBase->mData.mAttack[5]; - break; + case 0: + min = ref->mBase->mData.mAttack[0]; + max = ref->mBase->mData.mAttack[1]; + break; + case 1: + min = ref->mBase->mData.mAttack[2]; + max = ref->mBase->mData.mAttack[3]; + break; + case 2: + default: + min = ref->mBase->mData.mAttack[4]; + max = ref->mBase->mData.mAttack[5]; + break; } float damage = min + (max - min) * attackStrength; bool healthdmg = true; if (!weapon.isEmpty()) { - const unsigned char *attack = nullptr; - if(type == ESM::Weapon::AT_Chop) + const unsigned char* attack = nullptr; + if (type == ESM::Weapon::AT_Chop) attack = weapon.get()->mBase->mData.mChop; - else if(type == ESM::Weapon::AT_Slash) + else if (type == ESM::Weapon::AT_Slash) attack = weapon.get()->mBase->mData.mSlash; - else if(type == ESM::Weapon::AT_Thrust) + else if (type == ESM::Weapon::AT_Thrust) attack = weapon.get()->mBase->mData.mThrust; - if(attack) + if (attack) { - damage = attack[0] + ((attack[1]-attack[0])*attackStrength); + damage = attack[0] + ((attack[1] - attack[0]) * attackStrength); MWMechanics::adjustWeaponDamage(damage, weapon, ptr); MWMechanics::reduceWeaponCondition(damage, true, weapon, ptr); MWMechanics::resistNormalWeapon(victim, ptr, weapon, damage); @@ -364,17 +361,18 @@ namespace MWClass victim.getClass().onHit(victim, damage, healthdmg, weapon, ptr, hitPosition, true); } - void Creature::onHit(const MWWorld::Ptr &ptr, float damage, bool ishealth, const MWWorld::Ptr &object, const MWWorld::Ptr &attacker, const osg::Vec3f &hitPosition, bool successful) const + void Creature::onHit(const MWWorld::Ptr& ptr, float damage, bool ishealth, const MWWorld::Ptr& object, + const MWWorld::Ptr& attacker, const osg::Vec3f& hitPosition, bool successful) const { MWMechanics::CreatureStats& stats = getCreatureStats(ptr); - // NOTE: 'object' and/or 'attacker' may be empty. + // NOTE: 'object' and/or 'attacker' may be empty. if (!attacker.isEmpty() && attacker.getClass().isActor() && !stats.getAiSequence().isInCombat(attacker)) stats.setAttacked(true); // Self defense bool setOnPcHitMe = true; // Note OnPcHitMe is not set for friendly hits. - + // No retaliation for totally static creatures (they have no movement or attacks anyway) if (isMobile(ptr) && !attacker.isEmpty()) setOnPcHitMe = MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker); @@ -385,14 +383,12 @@ namespace MWClass MWMechanics::CreatureStats& statsAttacker = attacker.getClass().getCreatureStats(attacker); // First handle the attacked actor if ((stats.getHitAttemptActorId() == -1) - && (statsAttacker.getAiSequence().isInCombat(ptr) - || attacker == MWMechanics::getPlayer())) + && (statsAttacker.getAiSequence().isInCombat(ptr) || attacker == MWMechanics::getPlayer())) stats.setHitAttemptActorId(statsAttacker.getActorId()); // Next handle the attacking actor if ((statsAttacker.getHitAttemptActorId() == -1) - && (statsAttacker.getAiSequence().isInCombat(ptr) - || attacker == MWMechanics::getPlayer())) + && (statsAttacker.getAiSequence().isInCombat(ptr) || attacker == MWMechanics::getPlayer())) statsAttacker.setHitAttemptActorId(stats.getActorId()); } @@ -401,9 +397,9 @@ namespace MWClass if (setOnPcHitMe && !attacker.isEmpty() && attacker == MWMechanics::getPlayer()) { - const std::string &script = ptr.get()->mBase->mScript; + const std::string& script = ptr.get()->mBase->mScript; /* Set the OnPCHitMe script variable. The script is responsible for clearing it. */ - if(!script.empty()) + if (!script.empty()) ptr.getRefData().getLocals().setVarByInt(script, "onpchitme", 1); } @@ -426,9 +422,11 @@ namespace MWClass if (!attacker.isEmpty()) { // Check for knockdown - float agilityTerm = stats.getAttribute(ESM::Attribute::Agility).getModified() * getGmst().fKnockDownMult->mValue.getFloat(); + float agilityTerm = stats.getAttribute(ESM::Attribute::Agility).getModified() + * getGmst().fKnockDownMult->mValue.getFloat(); float knockdownTerm = stats.getAttribute(ESM::Attribute::Agility).getModified() - * getGmst().iKnockDownOddsMult->mValue.getInteger() * 0.01f + getGmst().iKnockDownOddsBase->mValue.getInteger(); + * getGmst().iKnockDownOddsMult->mValue.getInteger() * 0.01f + + getGmst().iKnockDownOddsBase->mValue.getInteger(); auto& prng = MWBase::Environment::get().getWorld()->getPrng(); if (ishealth && agilityTerm <= damage && knockdownTerm <= Misc::Rng::roll0to99(prng)) stats.setKnockedDown(true); @@ -436,7 +434,7 @@ namespace MWClass stats.setHitRecovery(true); // Is this supposed to always occur? } - if(ishealth) + if (ishealth) { damage *= damage / (damage + getArmorRating(ptr)); damage = std::max(1.f, damage); @@ -461,33 +459,33 @@ namespace MWClass } } - std::unique_ptr Creature::activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const + std::unique_ptr Creature::activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const { - if(actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf()) + if (actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf()) { - const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); auto& prng = MWBase::Environment::get().getWorld()->getPrng(); - const ESM::Sound *sound = store.get().searchRandom("WolfCreature", prng); + const ESM::Sound* sound = store.get().searchRandom("WolfCreature", prng); std::unique_ptr action = std::make_unique("#{sWerewolfRefusal}"); - if(sound) action->setSound(sound->mId); + if (sound) + action->setSound(sound->mId); return action; } const MWMechanics::CreatureStats& stats = getCreatureStats(ptr); - if(stats.isDead()) + if (stats.isDead()) { - bool canLoot = Settings::Manager::getBool ("can loot during death animation", "Game"); + bool canLoot = Settings::Manager::getBool("can loot during death animation", "Game"); // by default user can loot friendly actors during death animation if (canLoot && !stats.getAiSequence().isInCombat()) return std::make_unique(ptr); // otherwise wait until death animation - if(stats.isDeathAnimationFinished()) + if (stats.isDeathAnimationFinished()) return std::make_unique(ptr); } else if (!stats.getAiSequence().isInCombat() && !stats.getKnockedDown()) @@ -500,14 +498,14 @@ namespace MWClass return std::make_unique(); } - MWWorld::ContainerStore& Creature::getContainerStore (const MWWorld::Ptr& ptr) const + MWWorld::ContainerStore& Creature::getContainerStore(const MWWorld::Ptr& ptr) const { - ensureCustomData (ptr); + ensureCustomData(ptr); return *ptr.getRefData().getCustomData()->asCreatureCustomData().mContainerStore; } - MWWorld::InventoryStore& Creature::getInventoryStore(const MWWorld::Ptr &ptr) const + MWWorld::InventoryStore& Creature::getInventoryStore(const MWWorld::Ptr& ptr) const { if (hasInventoryStore(ptr)) return dynamic_cast(getContainerStore(ptr)); @@ -515,24 +513,24 @@ namespace MWClass throw std::runtime_error("this creature has no inventory store"); } - bool Creature::hasInventoryStore(const MWWorld::Ptr &ptr) const + bool Creature::hasInventoryStore(const MWWorld::Ptr& ptr) const { return isFlagBitSet(ptr, ESM::Creature::Weapon); } std::string_view Creature::getScript(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mScript; } - bool Creature::isEssential (const MWWorld::ConstPtr& ptr) const + bool Creature::isEssential(const MWWorld::ConstPtr& ptr) const { return isFlagBitSet(ptr, ESM::Creature::Essential); } - float Creature::getMaxSpeed(const MWWorld::Ptr &ptr) const + float Creature::getMaxSpeed(const MWWorld::Ptr& ptr) const { const MWMechanics::CreatureStats& stats = getCreatureStats(ptr); @@ -541,25 +539,27 @@ namespace MWClass const GMST& gmst = getGmst(); - const MWBase::World *world = MWBase::Environment::get().getWorld(); - const MWMechanics::MagicEffects &mageffects = stats.getMagicEffects(); + const MWBase::World* world = MWBase::Environment::get().getWorld(); + const MWMechanics::MagicEffects& mageffects = stats.getMagicEffects(); float moveSpeed; - if(getEncumbrance(ptr) > getCapacity(ptr)) + if (getEncumbrance(ptr) > getCapacity(ptr)) moveSpeed = 0.0f; - else if(canFly(ptr) || (mageffects.get(ESM::MagicEffect::Levitate).getMagnitude() > 0 && - world->isLevitationEnabled())) + else if (canFly(ptr) + || (mageffects.get(ESM::MagicEffect::Levitate).getMagnitude() > 0 && world->isLevitationEnabled())) { - float flySpeed = 0.01f*(stats.getAttribute(ESM::Attribute::Speed).getModified() + - mageffects.get(ESM::MagicEffect::Levitate).getMagnitude()); - flySpeed = gmst.fMinFlySpeed->mValue.getFloat() + flySpeed*(gmst.fMaxFlySpeed->mValue.getFloat() - gmst.fMinFlySpeed->mValue.getFloat()); + float flySpeed = 0.01f + * (stats.getAttribute(ESM::Attribute::Speed).getModified() + + mageffects.get(ESM::MagicEffect::Levitate).getMagnitude()); + flySpeed = gmst.fMinFlySpeed->mValue.getFloat() + + flySpeed * (gmst.fMaxFlySpeed->mValue.getFloat() - gmst.fMinFlySpeed->mValue.getFloat()); const float normalizedEncumbrance = getNormalizedEncumbrance(ptr); flySpeed *= 1.0f - gmst.fEncumberedMoveEffect->mValue.getFloat() * normalizedEncumbrance; flySpeed = std::max(0.0f, flySpeed); moveSpeed = flySpeed; } - else if(world->isSwimming(ptr)) + else if (world->isSwimming(ptr)) moveSpeed = getSwimSpeed(ptr); else moveSpeed = getWalkSpeed(ptr); @@ -567,9 +567,9 @@ namespace MWClass return moveSpeed; } - MWMechanics::Movement& Creature::getMovementSettings (const MWWorld::Ptr& ptr) const + MWMechanics::Movement& Creature::getMovementSettings(const MWWorld::Ptr& ptr) const { - ensureCustomData (ptr); + ensureCustomData(ptr); return ptr.getRefData().getCustomData()->asCreatureCustomData().mMovement; } @@ -587,9 +587,9 @@ namespace MWClass return !customData.mCreatureStats.getAiSequence().isInCombat(); } - MWGui::ToolTipInfo Creature::getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const + MWGui::ToolTipInfo Creature::getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); MWGui::ToolTipInfo info; std::string_view name = getName(ptr); @@ -603,24 +603,24 @@ namespace MWClass return info; } - float Creature::getArmorRating (const MWWorld::Ptr& ptr) const + float Creature::getArmorRating(const MWWorld::Ptr& ptr) const { // Equipment armor rating is deliberately ignored. return getCreatureStats(ptr).getMagicEffects().get(ESM::MagicEffect::Shield).getMagnitude(); } - float Creature::getCapacity (const MWWorld::Ptr& ptr) const + float Creature::getCapacity(const MWWorld::Ptr& ptr) const { - const MWMechanics::CreatureStats& stats = getCreatureStats (ptr); + const MWMechanics::CreatureStats& stats = getCreatureStats(ptr); return stats.getAttribute(ESM::Attribute::Strength).getModified() * 5; } - int Creature::getServices(const MWWorld::ConstPtr &actor) const + int Creature::getServices(const MWWorld::ConstPtr& actor) const { return actor.get()->mBase->mAiData.mServices; } - bool Creature::isPersistent(const MWWorld::ConstPtr &actor) const + bool Creature::isPersistent(const MWWorld::ConstPtr& actor) const { const MWWorld::LiveCellRef* ref = actor.get(); return (ref->mBase->mRecordFlags & ESM::FLAG_Persistent) != 0; @@ -637,13 +637,15 @@ namespace MWClass MWWorld::LiveCellRef* ref = ptr.get(); - const std::string& ourId = (ref->mBase->mOriginal.empty()) ? ptr.getCellRef().getRefId() : ref->mBase->mOriginal; + const std::string& ourId + = (ref->mBase->mOriginal.empty()) ? ptr.getCellRef().getRefId() : ref->mBase->mOriginal; - const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); auto sound = store.get().begin(); while (sound != store.get().end()) { - if (type == sound->mType && !sound->mCreature.empty() && Misc::StringUtils::ciEqual(ourId, sound->mCreature)) + if (type == sound->mType && !sound->mCreature.empty() + && Misc::StringUtils::ciEqual(ourId, sound->mCreature)) sounds.push_back(&*sound); if (type == sound->mType && sound->mCreature.empty()) fallbacksounds.push_back(&*sound); @@ -656,18 +658,18 @@ namespace MWClass if (!model.empty()) { const VFS::Manager* const vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); - for (const ESM::Creature &creature : store.get()) + for (const ESM::Creature& creature : store.get()) { if (creature.mId != ourId && creature.mOriginal != ourId && !creature.mModel.empty() - && Misc::StringUtils::ciEqual(model, - Misc::ResourceHelpers::correctMeshPath(creature.mModel, vfs))) + && Misc::StringUtils::ciEqual( + model, Misc::ResourceHelpers::correctMeshPath(creature.mModel, vfs))) { const std::string& fallbackId = !creature.mOriginal.empty() ? creature.mOriginal : creature.mId; sound = store.get().begin(); while (sound != store.get().end()) { if (type == sound->mType && !sound->mCreature.empty() - && Misc::StringUtils::ciEqual(fallbackId, sound->mCreature)) + && Misc::StringUtils::ciEqual(fallbackId, sound->mCreature)) sounds.push_back(&*sound); ++sound; } @@ -686,102 +688,100 @@ namespace MWClass return {}; } - MWWorld::Ptr Creature::copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const + MWWorld::Ptr Creature::copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return MWWorld::Ptr(cell.insert(ref), &cell); } - bool Creature::isBipedal(const MWWorld::ConstPtr &ptr) const + bool Creature::isBipedal(const MWWorld::ConstPtr& ptr) const { return isFlagBitSet(ptr, ESM::Creature::Bipedal); } - bool Creature::canFly(const MWWorld::ConstPtr &ptr) const + bool Creature::canFly(const MWWorld::ConstPtr& ptr) const { return isFlagBitSet(ptr, ESM::Creature::Flies); } - bool Creature::canSwim(const MWWorld::ConstPtr &ptr) const + bool Creature::canSwim(const MWWorld::ConstPtr& ptr) const { return isFlagBitSet(ptr, static_cast(ESM::Creature::Swims | ESM::Creature::Bipedal)); } - bool Creature::canWalk(const MWWorld::ConstPtr &ptr) const + bool Creature::canWalk(const MWWorld::ConstPtr& ptr) const { return isFlagBitSet(ptr, static_cast(ESM::Creature::Walks | ESM::Creature::Bipedal)); } int Creature::getSndGenTypeFromName(const MWWorld::Ptr& ptr, std::string_view name) { - if(name == "left") + if (name == "left") { - MWBase::World *world = MWBase::Environment::get().getWorld(); - if(world->isFlying(ptr)) + MWBase::World* world = MWBase::Environment::get().getWorld(); + if (world->isFlying(ptr)) return -1; osg::Vec3f pos(ptr.getRefData().getPosition().asVec3()); - if(world->isUnderwater(ptr.getCell(), pos) || world->isWalkingOnWater(ptr)) + if (world->isUnderwater(ptr.getCell(), pos) || world->isWalkingOnWater(ptr)) return ESM::SoundGenerator::SwimLeft; - if(world->isOnGround(ptr)) + if (world->isOnGround(ptr)) return ESM::SoundGenerator::LeftFoot; return -1; } - if(name == "right") + if (name == "right") { - MWBase::World *world = MWBase::Environment::get().getWorld(); - if(world->isFlying(ptr)) + MWBase::World* world = MWBase::Environment::get().getWorld(); + if (world->isFlying(ptr)) return -1; osg::Vec3f pos(ptr.getRefData().getPosition().asVec3()); - if(world->isUnderwater(ptr.getCell(), pos) || world->isWalkingOnWater(ptr)) + if (world->isUnderwater(ptr.getCell(), pos) || world->isWalkingOnWater(ptr)) return ESM::SoundGenerator::SwimRight; - if(world->isOnGround(ptr)) + if (world->isOnGround(ptr)) return ESM::SoundGenerator::RightFoot; return -1; } - if(name == "swimleft") + if (name == "swimleft") return ESM::SoundGenerator::SwimLeft; - if(name == "swimright") + if (name == "swimright") return ESM::SoundGenerator::SwimRight; - if(name == "moan") + if (name == "moan") return ESM::SoundGenerator::Moan; - if(name == "roar") + if (name == "roar") return ESM::SoundGenerator::Roar; - if(name == "scream") + if (name == "scream") return ESM::SoundGenerator::Scream; - if(name == "land") + if (name == "land") return ESM::SoundGenerator::Land; throw std::runtime_error("Unexpected soundgen type: " + std::string(name)); } - float Creature::getSkill(const MWWorld::Ptr &ptr, int skill) const + float Creature::getSkill(const MWWorld::Ptr& ptr, int skill) const { - MWWorld::LiveCellRef *ref = - ptr.get(); + MWWorld::LiveCellRef* ref = ptr.get(); const ESM::Skill* skillRecord = MWBase::Environment::get().getWorld()->getStore().get().find(skill); switch (skillRecord->mData.mSpecialization) { - case ESM::Class::Combat: - return ref->mBase->mData.mCombat; - case ESM::Class::Magic: - return ref->mBase->mData.mMagic; - case ESM::Class::Stealth: - return ref->mBase->mData.mStealth; - default: - throw std::runtime_error("invalid specialisation"); + case ESM::Class::Combat: + return ref->mBase->mData.mCombat; + case ESM::Class::Magic: + return ref->mBase->mData.mMagic; + case ESM::Class::Stealth: + return ref->mBase->mData.mStealth; + default: + throw std::runtime_error("invalid specialisation"); } } - int Creature::getBloodTexture(const MWWorld::ConstPtr &ptr) const + int Creature::getBloodTexture(const MWWorld::ConstPtr& ptr) const { return ptr.get()->mBase->mBloodType; } - void Creature::readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state) - const + void Creature::readAdditionalState(const MWWorld::Ptr& ptr, const ESM::ObjectState& state) const { if (!state.mHasCustomState) return; @@ -804,24 +804,24 @@ namespace MWClass else data->mContainerStore = std::make_unique(); - ptr.getRefData().setCustomData (std::move(data)); + ptr.getRefData().setCustomData(std::move(data)); } } } else - ensureCustomData(ptr); // in openmw 0.30 savegames not all state was saved yet, so need to load it regardless. + ensureCustomData( + ptr); // in openmw 0.30 savegames not all state was saved yet, so need to load it regardless. CreatureCustomData& customData = ptr.getRefData().getCustomData()->asCreatureCustomData(); - customData.mContainerStore->readState (creatureState.mInventory); + customData.mContainerStore->readState(creatureState.mInventory); bool spellsInitialised = customData.mCreatureStats.getSpells().setSpells(ptr.get()->mBase->mId); - if(spellsInitialised) + if (spellsInitialised) customData.mCreatureStats.getSpells().clear(); - customData.mCreatureStats.readState (creatureState.mCreatureStats); + customData.mCreatureStats.readState(creatureState.mCreatureStats); } - void Creature::writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) - const + void Creature::writeAdditionalState(const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const { if (!ptr.getRefData().getCustomData()) { @@ -830,15 +830,16 @@ namespace MWClass } const CreatureCustomData& customData = ptr.getRefData().getCustomData()->asCreatureCustomData(); - if (ptr.getRefData().getCount() <= 0 && (!isFlagBitSet(ptr, ESM::Creature::Respawn) || !customData.mCreatureStats.isDead())) + if (ptr.getRefData().getCount() <= 0 + && (!isFlagBitSet(ptr, ESM::Creature::Respawn) || !customData.mCreatureStats.isDead())) { state.mHasCustomState = false; return; } ESM::CreatureState& creatureState = state.asCreatureState(); - customData.mContainerStore->writeState (creatureState.mInventory); - customData.mCreatureStats.writeState (creatureState.mCreatureStats); + customData.mContainerStore->writeState(creatureState.mInventory); + customData.mCreatureStats.writeState(creatureState.mCreatureStats); } int Creature::getBaseGold(const MWWorld::ConstPtr& ptr) const @@ -846,7 +847,7 @@ namespace MWClass return ptr.get()->mBase->mData.mGold; } - void Creature::respawn(const MWWorld::Ptr &ptr) const + void Creature::respawn(const MWWorld::Ptr& ptr) const { const MWMechanics::CreatureStats& creatureStats = getCreatureStats(ptr); if (ptr.getRefData().getCount() > 0 && !creatureStats.isDead()) @@ -855,14 +856,16 @@ namespace MWClass if (!creatureStats.isDeathAnimationFinished()) return; - const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& gmst + = MWBase::Environment::get().getWorld()->getStore().get(); static const float fCorpseRespawnDelay = gmst.find("fCorpseRespawnDelay")->mValue.getFloat(); static const float fCorpseClearDelay = gmst.find("fCorpseClearDelay")->mValue.getFloat(); - float delay = ptr.getRefData().getCount() == 0 ? fCorpseClearDelay : std::min(fCorpseRespawnDelay, fCorpseClearDelay); + float delay + = ptr.getRefData().getCount() == 0 ? fCorpseClearDelay : std::min(fCorpseRespawnDelay, fCorpseClearDelay); if (isFlagBitSet(ptr, ESM::Creature::Respawn) - && creatureStats.getTimeOfDeath() + delay <= MWBase::Environment::get().getWorld()->getTimeStamp()) + && creatureStats.getTimeOfDeath() + delay <= MWBase::Environment::get().getWorld()->getTimeStamp()) { if (ptr.getCellRef().hasContentFile()) { @@ -870,7 +873,7 @@ namespace MWClass { ptr.getRefData().setCount(1); std::string_view script = getScript(ptr); - if(!script.empty()) + if (!script.empty()) MWBase::Environment::get().getWorld()->getLocalScripts().add(script, ptr); } @@ -880,20 +883,21 @@ namespace MWClass // Reset to original position MWBase::Environment::get().getWorld()->moveObject(ptr, ptr.getCellRef().getPosition().asVec3()); - MWBase::Environment::get().getWorld()->rotateObject(ptr, ptr.getCellRef().getPosition().asRotationVec3(), MWBase::RotationFlag_none); + MWBase::Environment::get().getWorld()->rotateObject( + ptr, ptr.getCellRef().getPosition().asRotationVec3(), MWBase::RotationFlag_none); } } } - int Creature::getBaseFightRating(const MWWorld::ConstPtr &ptr) const + int Creature::getBaseFightRating(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mAiData.mFight; } - void Creature::adjustScale(const MWWorld::ConstPtr &ptr, osg::Vec3f &scale, bool /* rendering */) const + void Creature::adjustScale(const MWWorld::ConstPtr& ptr, osg::Vec3f& scale, bool /* rendering */) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); scale *= ref->mBase->mScale; } @@ -913,8 +917,8 @@ namespace MWClass const GMST& gmst = getGmst(); return gmst.fMinWalkSpeedCreature->mValue.getFloat() - + 0.01f * stats.getAttribute(ESM::Attribute::Speed).getModified() - * (gmst.fMaxWalkSpeedCreature->mValue.getFloat() - gmst.fMinWalkSpeedCreature->mValue.getFloat()); + + 0.01f * stats.getAttribute(ESM::Attribute::Speed).getModified() + * (gmst.fMaxWalkSpeedCreature->mValue.getFloat() - gmst.fMinWalkSpeedCreature->mValue.getFloat()); } float Creature::getRunSpeed(const MWWorld::Ptr& ptr) const diff --git a/apps/openmw/mwclass/creature.hpp b/apps/openmw/mwclass/creature.hpp index 73b716d1ed..1951ce6093 100644 --- a/apps/openmw/mwclass/creature.hpp +++ b/apps/openmw/mwclass/creature.hpp @@ -16,135 +16,136 @@ namespace MWClass { class Creature : public MWWorld::RegisteredClass { - friend MWWorld::RegisteredClass; + friend MWWorld::RegisteredClass; - Creature(); + Creature(); - void ensureCustomData (const MWWorld::Ptr& ptr) const; + void ensureCustomData(const MWWorld::Ptr& ptr) const; - MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const override; - static int getSndGenTypeFromName(const MWWorld::Ptr& ptr, std::string_view name); + static int getSndGenTypeFromName(const MWWorld::Ptr& ptr, std::string_view name); - // cached GMSTs - struct GMST - { - const ESM::GameSetting *fMinWalkSpeedCreature; - const ESM::GameSetting *fMaxWalkSpeedCreature; - const ESM::GameSetting *fEncumberedMoveEffect; - const ESM::GameSetting *fSneakSpeedMultiplier; - const ESM::GameSetting *fAthleticsRunBonus; - const ESM::GameSetting *fBaseRunMultiplier; - const ESM::GameSetting *fMinFlySpeed; - const ESM::GameSetting *fMaxFlySpeed; - const ESM::GameSetting *fSwimRunBase; - const ESM::GameSetting *fSwimRunAthleticsMult; - const ESM::GameSetting *fKnockDownMult; - const ESM::GameSetting *iKnockDownOddsMult; - const ESM::GameSetting *iKnockDownOddsBase; - }; + // cached GMSTs + struct GMST + { + const ESM::GameSetting* fMinWalkSpeedCreature; + const ESM::GameSetting* fMaxWalkSpeedCreature; + const ESM::GameSetting* fEncumberedMoveEffect; + const ESM::GameSetting* fSneakSpeedMultiplier; + const ESM::GameSetting* fAthleticsRunBonus; + const ESM::GameSetting* fBaseRunMultiplier; + const ESM::GameSetting* fMinFlySpeed; + const ESM::GameSetting* fMaxFlySpeed; + const ESM::GameSetting* fSwimRunBase; + const ESM::GameSetting* fSwimRunAthleticsMult; + const ESM::GameSetting* fKnockDownMult; + const ESM::GameSetting* iKnockDownOddsMult; + const ESM::GameSetting* iKnockDownOddsBase; + }; - static const GMST& getGmst(); + static const GMST& getGmst(); - public: + public: + void insertObjectRendering(const MWWorld::Ptr& ptr, const std::string& model, + MWRender::RenderingInterface& renderingInterface) const override; + ///< Add reference into a cell for rendering - void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; - ///< Add reference into a cell for rendering + std::string_view getName(const MWWorld::ConstPtr& ptr) const override; + ///< \return name or ID; can return an empty string. - std::string_view getName(const MWWorld::ConstPtr& ptr) const override; - ///< \return name or ID; can return an empty string. + bool hasToolTip(const MWWorld::ConstPtr& ptr) const override; + ///< @return true if this object has a tooltip when focused (default implementation: true) - bool hasToolTip(const MWWorld::ConstPtr& ptr) const override; - ///< @return true if this object has a tooltip when focused (default implementation: true) + MWGui::ToolTipInfo getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const override; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. - MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const override; - ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + MWMechanics::CreatureStats& getCreatureStats(const MWWorld::Ptr& ptr) const override; + ///< Return creature stats - MWMechanics::CreatureStats& getCreatureStats (const MWWorld::Ptr& ptr) const override; - ///< Return creature stats + bool evaluateHit(const MWWorld::Ptr& ptr, MWWorld::Ptr& victim, osg::Vec3f& hitPosition) const override; - bool evaluateHit(const MWWorld::Ptr& ptr, MWWorld::Ptr& victim, osg::Vec3f& hitPosition) const override; + void hit(const MWWorld::Ptr& ptr, float attackStrength, int type, const MWWorld::Ptr& victim, + const osg::Vec3f& hitPosition, bool success) const override; - void hit(const MWWorld::Ptr& ptr, float attackStrength, int type, const MWWorld::Ptr& victim, const osg::Vec3f& hitPosition, bool success) const override; + void onHit(const MWWorld::Ptr& ptr, float damage, bool ishealth, const MWWorld::Ptr& object, + const MWWorld::Ptr& attacker, const osg::Vec3f& hitPosition, bool successful) const override; - void onHit(const MWWorld::Ptr &ptr, float damage, bool ishealth, const MWWorld::Ptr &object, const MWWorld::Ptr &attacker, const osg::Vec3f &hitPosition, bool successful) const override; + std::unique_ptr activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const override; + ///< Generate action for activation - std::unique_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const override; - ///< Generate action for activation + MWWorld::ContainerStore& getContainerStore(const MWWorld::Ptr& ptr) const override; + ///< Return container store - MWWorld::ContainerStore& getContainerStore ( - const MWWorld::Ptr& ptr) const override; - ///< Return container store + MWWorld::InventoryStore& getInventoryStore(const MWWorld::Ptr& ptr) const override; + ///< Return inventory store - MWWorld::InventoryStore& getInventoryStore (const MWWorld::Ptr& ptr) const override; - ///< Return inventory store + bool hasInventoryStore(const MWWorld::Ptr& ptr) const override; - bool hasInventoryStore (const MWWorld::Ptr &ptr) const override; + std::string_view getScript(const MWWorld::ConstPtr& ptr) const override; + ///< Return name of the script attached to ptr - std::string_view getScript(const MWWorld::ConstPtr& ptr) const override; - ///< Return name of the script attached to ptr + float getCapacity(const MWWorld::Ptr& ptr) const override; + ///< Return total weight that fits into the object. Throws an exception, if the object can't + /// hold other objects. - float getCapacity (const MWWorld::Ptr& ptr) const override; - ///< Return total weight that fits into the object. Throws an exception, if the object can't - /// hold other objects. + float getArmorRating(const MWWorld::Ptr& ptr) const override; + ///< @return combined armor rating of this actor - float getArmorRating (const MWWorld::Ptr& ptr) const override; - ///< @return combined armor rating of this actor + bool isEssential(const MWWorld::ConstPtr& ptr) const override; + ///< Is \a ptr essential? (i.e. may losing \a ptr make the game unwinnable) - bool isEssential (const MWWorld::ConstPtr& ptr) const override; - ///< Is \a ptr essential? (i.e. may losing \a ptr make the game unwinnable) + int getServices(const MWWorld::ConstPtr& actor) const override; - int getServices (const MWWorld::ConstPtr& actor) const override; + bool isPersistent(const MWWorld::ConstPtr& ptr) const override; - bool isPersistent (const MWWorld::ConstPtr& ptr) const override; + std::string_view getSoundIdFromSndGen(const MWWorld::Ptr& ptr, std::string_view name) const override; - std::string_view getSoundIdFromSndGen(const MWWorld::Ptr& ptr, std::string_view name) const override; + MWMechanics::Movement& getMovementSettings(const MWWorld::Ptr& ptr) const override; + ///< Return desired movement. - MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const override; - ///< Return desired movement. + float getMaxSpeed(const MWWorld::Ptr& ptr) const override; - float getMaxSpeed (const MWWorld::Ptr& ptr) const override; + std::string getModel(const MWWorld::ConstPtr& ptr) const override; - std::string getModel(const MWWorld::ConstPtr &ptr) const override; + void getModelsToPreload(const MWWorld::Ptr& ptr, std::vector& models) const override; + ///< Get a list of models to preload that this object may use (directly or indirectly). default implementation: + ///< list getModel(). - void getModelsToPreload(const MWWorld::Ptr& ptr, std::vector& models) const override; - ///< Get a list of models to preload that this object may use (directly or indirectly). default implementation: list getModel(). + bool isBipedal(const MWWorld::ConstPtr& ptr) const override; + bool canFly(const MWWorld::ConstPtr& ptr) const override; + bool canSwim(const MWWorld::ConstPtr& ptr) const override; + bool canWalk(const MWWorld::ConstPtr& ptr) const override; - bool isBipedal (const MWWorld::ConstPtr &ptr) const override; - bool canFly (const MWWorld::ConstPtr &ptr) const override; - bool canSwim (const MWWorld::ConstPtr &ptr) const override; - bool canWalk (const MWWorld::ConstPtr &ptr) const override; + float getSkill(const MWWorld::Ptr& ptr, int skill) const override; - float getSkill(const MWWorld::Ptr &ptr, int skill) const override; + /// Get a blood texture suitable for \a ptr (see Blood Texture 0-2 in Morrowind.ini) + int getBloodTexture(const MWWorld::ConstPtr& ptr) const override; - /// Get a blood texture suitable for \a ptr (see Blood Texture 0-2 in Morrowind.ini) - int getBloodTexture (const MWWorld::ConstPtr& ptr) const override; + void readAdditionalState(const MWWorld::Ptr& ptr, const ESM::ObjectState& state) const override; + ///< Read additional state from \a state into \a ptr. - void readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state) const override; - ///< Read additional state from \a state into \a ptr. + void writeAdditionalState(const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const override; + ///< Write additional state from \a ptr into \a state. - void writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const override; - ///< Write additional state from \a ptr into \a state. + int getBaseGold(const MWWorld::ConstPtr& ptr) const override; - int getBaseGold(const MWWorld::ConstPtr& ptr) const override; + void respawn(const MWWorld::Ptr& ptr) const override; - void respawn (const MWWorld::Ptr& ptr) const override; + int getBaseFightRating(const MWWorld::ConstPtr& ptr) const override; - int getBaseFightRating(const MWWorld::ConstPtr &ptr) const override; + void adjustScale(const MWWorld::ConstPtr& ptr, osg::Vec3f& scale, bool rendering) const override; + /// @param rendering Indicates if the scale to adjust is for the rendering mesh, or for the collision mesh - void adjustScale(const MWWorld::ConstPtr& ptr, osg::Vec3f& scale, bool rendering) const override; - /// @param rendering Indicates if the scale to adjust is for the rendering mesh, or for the collision mesh + void setBaseAISetting(const std::string& id, MWMechanics::AiSetting setting, int value) const override; - void setBaseAISetting(const std::string& id, MWMechanics::AiSetting setting, int value) const override; + void modifyBaseInventory(std::string_view actorId, std::string_view itemId, int amount) const override; - void modifyBaseInventory(std::string_view actorId, std::string_view itemId, int amount) const override; + float getWalkSpeed(const MWWorld::Ptr& ptr) const override; - float getWalkSpeed(const MWWorld::Ptr& ptr) const override; + float getRunSpeed(const MWWorld::Ptr& ptr) const override; - float getRunSpeed(const MWWorld::Ptr& ptr) const override; - - float getSwimSpeed(const MWWorld::Ptr& ptr) const override; + float getSwimSpeed(const MWWorld::Ptr& ptr) const override; }; } diff --git a/apps/openmw/mwclass/creaturelevlist.cpp b/apps/openmw/mwclass/creaturelevlist.cpp index 41d6b9b280..14ca13719b 100644 --- a/apps/openmw/mwclass/creaturelevlist.cpp +++ b/apps/openmw/mwclass/creaturelevlist.cpp @@ -1,7 +1,7 @@ #include "creaturelevlist.hpp" -#include #include +#include #include "../mwmechanics/levelledlist.hpp" @@ -24,14 +24,8 @@ namespace MWClass int mSpawnActorId; bool mSpawn; // Should a new creature be spawned? - CreatureLevListCustomData& asCreatureLevListCustomData() override - { - return *this; - } - const CreatureLevListCustomData& asCreatureLevListCustomData() const override - { - return *this; - } + CreatureLevListCustomData& asCreatureLevListCustomData() override { return *this; } + const CreatureLevListCustomData& asCreatureLevListCustomData() const override { return *this; } }; CreatureLevList::CreatureLevList() @@ -39,9 +33,9 @@ namespace MWClass { } - MWWorld::Ptr CreatureLevList::copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const + MWWorld::Ptr CreatureLevList::copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return MWWorld::Ptr(cell.insert(ref), &cell); } @@ -52,7 +46,9 @@ namespace MWClass return; CreatureLevListCustomData& customData = ptr.getRefData().getCustomData()->asCreatureLevListCustomData(); - MWWorld::Ptr creature = (customData.mSpawnActorId == -1) ? MWWorld::Ptr() : MWBase::Environment::get().getWorld()->searchPtrViaActorId(customData.mSpawnActorId); + MWWorld::Ptr creature = (customData.mSpawnActorId == -1) + ? MWWorld::Ptr() + : MWBase::Environment::get().getWorld()->searchPtrViaActorId(customData.mSpawnActorId); if (!creature.isEmpty()) MWBase::Environment::get().getWorld()->adjustPosition(creature, force); } @@ -67,7 +63,7 @@ namespace MWClass return false; } - void CreatureLevList::respawn(const MWWorld::Ptr &ptr) const + void CreatureLevList::respawn(const MWWorld::Ptr& ptr) const { ensureCustomData(ptr); @@ -76,10 +72,10 @@ namespace MWClass return; MWWorld::Ptr creature; - if(customData.mSpawnActorId != -1) + if (customData.mSpawnActorId != -1) { creature = MWBase::Environment::get().getWorld()->searchPtrViaActorId(customData.mSpawnActorId); - if(creature.isEmpty()) + if (creature.isEmpty()) creature = ptr.getCell()->getMovedActor(customData.mSpawnActorId); } if (!creature.isEmpty()) @@ -89,7 +85,8 @@ namespace MWClass customData.mSpawn = true; else if (creatureStats.isDead()) { - const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& gmst + = MWBase::Environment::get().getWorld()->getStore().get(); static const float fCorpseRespawnDelay = gmst.find("fCorpseRespawnDelay")->mValue.getFloat(); static const float fCorpseClearDelay = gmst.find("fCorpseClearDelay")->mValue.getFloat(); @@ -102,12 +99,13 @@ namespace MWClass customData.mSpawn = true; } - void CreatureLevList::getModelsToPreload(const MWWorld::Ptr &ptr, std::vector &models) const + void CreatureLevList::getModelsToPreload(const MWWorld::Ptr& ptr, std::vector& models) const { // disable for now, too many false positives /* const MWWorld::LiveCellRef *ref = ptr.get(); - for (std::vector::const_iterator it = ref->mBase->mList.begin(); it != ref->mBase->mList.end(); ++it) + for (std::vector::const_iterator it = ref->mBase->mList.begin(); it != + ref->mBase->mList.end(); ++it) { MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); if (it->mLevel > player.getClass().getCreatureStats(player).getLevel()) @@ -120,7 +118,8 @@ namespace MWClass */ } - void CreatureLevList::insertObjectRendering(const MWWorld::Ptr &ptr, const std::string& model, MWRender::RenderingInterface &renderingInterface) const + void CreatureLevList::insertObjectRendering( + const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const { ensureCustomData(ptr); @@ -128,8 +127,7 @@ namespace MWClass if (!customData.mSpawn) return; - MWWorld::LiveCellRef *ref = - ptr.get(); + MWWorld::LiveCellRef* ref = ptr.get(); auto& prng = MWBase::Environment::get().getWorld()->getPrng(); std::string_view id = MWMechanics::getLevelledItem(ref->mBase, true, prng); @@ -139,7 +137,8 @@ namespace MWClass // Delete the previous creature if (customData.mSpawnActorId != -1) { - MWWorld::Ptr creature = MWBase::Environment::get().getWorld()->searchPtrViaActorId(customData.mSpawnActorId); + MWWorld::Ptr creature + = MWBase::Environment::get().getWorld()->searchPtrViaActorId(customData.mSpawnActorId); if (!creature.isEmpty()) MWBase::Environment::get().getWorld()->deleteObject(creature); customData.mSpawnActorId = -1; @@ -149,7 +148,8 @@ namespace MWClass MWWorld::ManualRef manualRef(store, id); manualRef.getPtr().getCellRef().setPosition(ptr.getCellRef().getPosition()); manualRef.getPtr().getCellRef().setScale(ptr.getCellRef().getScale()); - MWWorld::Ptr placed = MWBase::Environment::get().getWorld()->placeObject(manualRef.getPtr(), ptr.getCell() , ptr.getCellRef().getPosition()); + MWWorld::Ptr placed = MWBase::Environment::get().getWorld()->placeObject( + manualRef.getPtr(), ptr.getCell(), ptr.getCellRef().getPosition()); customData.mSpawnActorId = placed.getClass().getCreatureStats(placed).getActorId(); customData.mSpawn = false; } @@ -157,7 +157,7 @@ namespace MWClass customData.mSpawn = false; } - void CreatureLevList::ensureCustomData(const MWWorld::Ptr &ptr) const + void CreatureLevList::ensureCustomData(const MWWorld::Ptr& ptr) const { if (!ptr.getRefData().getCustomData()) { @@ -169,8 +169,7 @@ namespace MWClass } } - void CreatureLevList::readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state) - const + void CreatureLevList::readAdditionalState(const MWWorld::Ptr& ptr, const ESM::ObjectState& state) const { if (!state.mHasCustomState) return; @@ -182,8 +181,7 @@ namespace MWClass customData.mSpawn = levListState.mSpawn; } - void CreatureLevList::writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) - const + void CreatureLevList::writeAdditionalState(const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const { if (!ptr.getRefData().getCustomData()) { diff --git a/apps/openmw/mwclass/creaturelevlist.hpp b/apps/openmw/mwclass/creaturelevlist.hpp index c8ee3b9b7a..d689d1770e 100644 --- a/apps/openmw/mwclass/creaturelevlist.hpp +++ b/apps/openmw/mwclass/creaturelevlist.hpp @@ -7,37 +7,38 @@ namespace MWClass { class CreatureLevList : public MWWorld::RegisteredClass { - friend MWWorld::RegisteredClass; + friend MWWorld::RegisteredClass; - CreatureLevList(); + CreatureLevList(); - void ensureCustomData (const MWWorld::Ptr& ptr) const; + void ensureCustomData(const MWWorld::Ptr& ptr) const; - public: + public: + std::string_view getName(const MWWorld::ConstPtr& ptr) const override; + ///< \return name or ID; can return an empty string. - std::string_view getName(const MWWorld::ConstPtr& ptr) const override; - ///< \return name or ID; can return an empty string. + bool hasToolTip(const MWWorld::ConstPtr& ptr) const override; + ///< @return true if this object has a tooltip when focused (default implementation: true) - bool hasToolTip (const MWWorld::ConstPtr& ptr) const override; - ///< @return true if this object has a tooltip when focused (default implementation: true) + void getModelsToPreload(const MWWorld::Ptr& ptr, std::vector& models) const override; + ///< Get a list of models to preload that this object may use (directly or indirectly). default implementation: + ///< list getModel(). - void getModelsToPreload(const MWWorld::Ptr& ptr, std::vector& models) const override; - ///< Get a list of models to preload that this object may use (directly or indirectly). default implementation: list getModel(). + void insertObjectRendering(const MWWorld::Ptr& ptr, const std::string& model, + MWRender::RenderingInterface& renderingInterface) const override; + ///< Add reference into a cell for rendering - void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; - ///< Add reference into a cell for rendering + void readAdditionalState(const MWWorld::Ptr& ptr, const ESM::ObjectState& state) const override; + ///< Read additional state from \a state into \a ptr. - void readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state) const override; - ///< Read additional state from \a state into \a ptr. + void writeAdditionalState(const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const override; + ///< Write additional state from \a ptr into \a state. - void writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const override; - ///< Write additional state from \a ptr into \a state. + void respawn(const MWWorld::Ptr& ptr) const override; - void respawn (const MWWorld::Ptr& ptr) const override; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const override; - MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; - - void adjustPosition(const MWWorld::Ptr& ptr, bool force) const override; + void adjustPosition(const MWWorld::Ptr& ptr, bool force) const override; }; } diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index 3faa42b288..8a300fc9e8 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -2,34 +2,34 @@ #include -#include #include +#include #include #include #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" -#include "../mwbase/windowmanager.hpp" #include "../mwbase/soundmanager.hpp" +#include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" -#include "../mwworld/ptr.hpp" -#include "../mwworld/failedaction.hpp" -#include "../mwworld/actionteleport.hpp" -#include "../mwworld/actiondoor.hpp" -#include "../mwworld/cellstore.hpp" -#include "../mwworld/esmstore.hpp" #include "../mwphysics/physicssystem.hpp" +#include "../mwworld/actiondoor.hpp" +#include "../mwworld/actionteleport.hpp" #include "../mwworld/actiontrap.hpp" -#include "../mwworld/customdata.hpp" +#include "../mwworld/cellstore.hpp" #include "../mwworld/cellutils.hpp" #include "../mwworld/containerstore.hpp" +#include "../mwworld/customdata.hpp" +#include "../mwworld/esmstore.hpp" +#include "../mwworld/failedaction.hpp" +#include "../mwworld/ptr.hpp" #include "../mwgui/tooltips.hpp" #include "../mwgui/ustring.hpp" +#include "../mwrender/animation.hpp" #include "../mwrender/objects.hpp" #include "../mwrender/renderinginterface.hpp" -#include "../mwrender/animation.hpp" #include "../mwrender/vismask.hpp" #include "../mwmechanics/actorutil.hpp" @@ -43,14 +43,8 @@ namespace MWClass public: MWWorld::DoorState mDoorState = MWWorld::DoorState::Idle; - DoorCustomData& asDoorCustomData() override - { - return *this; - } - const DoorCustomData& asDoorCustomData() const override - { - return *this; - } + DoorCustomData& asDoorCustomData() override { return *this; } + const DoorCustomData& asDoorCustomData() const override { return *this; } }; Door::Door() @@ -58,7 +52,8 @@ namespace MWClass { } - void Door::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const + void Door::insertObjectRendering( + const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const { if (!model.empty()) { @@ -67,7 +62,8 @@ namespace MWClass } } - void Door::insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const + void Door::insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, + MWPhysics::PhysicsSystem& physics) const { insertObjectPhysics(ptr, model, rotation, physics); @@ -82,7 +78,8 @@ namespace MWClass } } - void Door::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const + void Door::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, + MWPhysics::PhysicsSystem& physics) const { physics.addObject(ptr, model, rotation, MWPhysics::CollisionType_Door); } @@ -97,31 +94,30 @@ namespace MWClass return true; } - std::string Door::getModel(const MWWorld::ConstPtr &ptr) const + std::string Door::getModel(const MWWorld::ConstPtr& ptr) const { return getClassModel(ptr); } std::string_view Door::getName(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); const std::string& name = ref->mBase->mName; return !name.empty() ? name : ref->mBase->mId; } - std::unique_ptr Door::activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const + std::unique_ptr Door::activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const { - MWWorld::LiveCellRef *ref = ptr.get(); + MWWorld::LiveCellRef* ref = ptr.get(); - const std::string &openSound = ref->mBase->mOpenSound; - const std::string &closeSound = ref->mBase->mCloseSound; + const std::string& openSound = ref->mBase->mOpenSound; + const std::string& closeSound = ref->mBase->mCloseSound; const std::string_view lockedSound = "LockedDoor"; const std::string_view trapActivationSound = "Disarm Trap Fail"; - // FIXME: If NPC activate teleporting door, it can lead to crash due to iterator invalidation in the Actors update. - // Make such activation a no-op for now, like how it is in the vanilla game. + // FIXME: If NPC activate teleporting door, it can lead to crash due to iterator invalidation in the Actors + // update. Make such activation a no-op for now, like how it is in the vanilla game. if (actor != MWMechanics::getPlayer() && ptr.getCellRef().getTeleport()) { std::unique_ptr action = std::make_unique(std::string_view{}, ptr); @@ -130,22 +126,23 @@ namespace MWClass } // make door glow if player activates it with telekinesis - if (actor == MWMechanics::getPlayer() && - MWBase::Environment::get().getWorld()->getDistanceToFacedObject() > - MWBase::Environment::get().getWorld()->getMaxActivationDistance()) + if (actor == MWMechanics::getPlayer() + && MWBase::Environment::get().getWorld()->getDistanceToFacedObject() + > MWBase::Environment::get().getWorld()->getMaxActivationDistance()) { MWRender::Animation* animation = MWBase::Environment::get().getWorld()->getAnimation(ptr); - if(animation) + if (animation) { const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); int index = ESM::MagicEffect::effectStringToId("sEffectTelekinesis"); - const ESM::MagicEffect *effect = store.get().find(index); + const ESM::MagicEffect* effect = store.get().find(index); - animation->addSpellCastGlow(effect, 1); // 1 second glow to match the time taken for a door opening or closing + animation->addSpellCastGlow( + effect, 1); // 1 second glow to match the time taken for a door opening or closing } } - MWWorld::ContainerStore &invStore = actor.getClass().getContainerStore(actor); + MWWorld::ContainerStore& invStore = actor.getClass().getContainerStore(actor); bool isLocked = ptr.getCellRef().getLockLevel() > 0; bool isTrapped = !ptr.getCellRef().getTrap().empty(); @@ -164,11 +161,11 @@ namespace MWClass if (isLocked && hasKey) { - if(actor == MWMechanics::getPlayer()) - MWBase::Environment::get().getWindowManager()->messageBox(std::string{keyName} + " #{sKeyUsed}"); - ptr.getCellRef().unlock(); //Call the function here. because that makes sense. + if (actor == MWMechanics::getPlayer()) + MWBase::Environment::get().getWindowManager()->messageBox(std::string{ keyName } + " #{sKeyUsed}"); + ptr.getCellRef().unlock(); // Call the function here. because that makes sense. // using a key disarms the trap - if(isTrapped) + if (isTrapped) { ptr.getCellRef().setTrap(""); MWBase::Environment::get().getSoundManager()->playSound3D(ptr, "Disarm Trap", 1.0f, 1.0f); @@ -178,24 +175,28 @@ namespace MWClass if (!isLocked || hasKey) { - if(isTrapped) + if (isTrapped) { // Trap activation - std::unique_ptr action = std::make_unique(ptr.getCellRef().getTrap(), ptr); + std::unique_ptr action + = std::make_unique(ptr.getCellRef().getTrap(), ptr); action->setSound(trapActivationSound); return action; } if (ptr.getCellRef().getTeleport()) { - if (actor == MWMechanics::getPlayer() && MWBase::Environment::get().getWorld()->getDistanceToFacedObject() > MWBase::Environment::get().getWorld()->getMaxActivationDistance()) + if (actor == MWMechanics::getPlayer() + && MWBase::Environment::get().getWorld()->getDistanceToFacedObject() + > MWBase::Environment::get().getWorld()->getMaxActivationDistance()) { // player activated teleport door with telekinesis return std::make_unique(); } else { - std::unique_ptr action = std::make_unique(ptr.getCellRef().getDestCell(), ptr.getCellRef().getDoorDest(), true); + std::unique_ptr action = std::make_unique( + ptr.getCellRef().getDestCell(), ptr.getCellRef().getDoorDest(), true); action->setSound(openSound); return action; } @@ -214,19 +215,17 @@ namespace MWClass if (opening) { - MWBase::Environment::get().getSoundManager()->fadeOutSound3D(ptr, - closeSound, 0.5f); + MWBase::Environment::get().getSoundManager()->fadeOutSound3D(ptr, closeSound, 0.5f); // Doors rotate at 90 degrees per second, so start the sound at // where it would be at the current rotation. - float offset = doorRot/(osg::PI * 0.5f); + float offset = doorRot / (osg::PI * 0.5f); action->setSoundOffset(offset); action->setSound(openSound); } else { - MWBase::Environment::get().getSoundManager()->fadeOutSound3D(ptr, - openSound, 0.5f); - float offset = 1.0f - doorRot/(osg::PI * 0.5f); + MWBase::Environment::get().getSoundManager()->fadeOutSound3D(ptr, openSound, 0.5f); + float offset = 1.0f - doorRot / (osg::PI * 0.5f); action->setSoundOffset(std::max(offset, 0.0f)); action->setSound(closeSound); } @@ -243,14 +242,15 @@ namespace MWClass } } - bool Door::canLock(const MWWorld::ConstPtr &ptr) const + bool Door::canLock(const MWWorld::ConstPtr& ptr) const { return true; } - bool Door::allowTelekinesis(const MWWorld::ConstPtr &ptr) const + bool Door::allowTelekinesis(const MWWorld::ConstPtr& ptr) const { - if (ptr.getCellRef().getTeleport() && ptr.getCellRef().getLockLevel() <= 0 && ptr.getCellRef().getTrap().empty()) + if (ptr.getCellRef().getTeleport() && ptr.getCellRef().getLockLevel() <= 0 + && ptr.getCellRef().getTrap().empty()) return false; else return true; @@ -258,14 +258,14 @@ namespace MWClass std::string_view Door::getScript(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mScript; } - MWGui::ToolTipInfo Door::getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const + MWGui::ToolTipInfo Door::getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); MWGui::ToolTipInfo info; std::string_view name = getName(ptr); @@ -297,15 +297,15 @@ namespace MWClass return info; } - std::string Door::getDestination (const MWWorld::LiveCellRef& door) + std::string Door::getDestination(const MWWorld::LiveCellRef& door) { std::string dest = door.mRef.getDestCell(); if (dest.empty()) { // door leads to exterior, use cell name (if any), otherwise translated region name auto world = MWBase::Environment::get().getWorld(); - const osg::Vec2i index = MWWorld::positionToCellIndex(door.mRef.getDoorDest().pos[0], - door.mRef.getDoorDest().pos[1]); + const osg::Vec2i index + = MWWorld::positionToCellIndex(door.mRef.getDoorDest().pos[0], door.mRef.getDoorDest().pos[1]); const ESM::Cell* cell = world->getStore().get().search(index.x(), index.y()); dest = world->getCellName(cell); } @@ -313,14 +313,14 @@ namespace MWClass return "#{sCell=" + dest + "}"; } - MWWorld::Ptr Door::copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const + MWWorld::Ptr Door::copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return MWWorld::Ptr(cell.insert(ref), &cell); } - void Door::ensureCustomData(const MWWorld::Ptr &ptr) const + void Door::ensureCustomData(const MWWorld::Ptr& ptr) const { if (!ptr.getRefData().getCustomData()) { @@ -328,7 +328,7 @@ namespace MWClass } } - MWWorld::DoorState Door::getDoorState (const MWWorld::ConstPtr &ptr) const + MWWorld::DoorState Door::getDoorState(const MWWorld::ConstPtr& ptr) const { if (!ptr.getRefData().getCustomData()) return MWWorld::DoorState::Idle; @@ -336,7 +336,7 @@ namespace MWClass return customData.mDoorState; } - void Door::setDoorState (const MWWorld::Ptr &ptr, MWWorld::DoorState state) const + void Door::setDoorState(const MWWorld::Ptr& ptr, MWWorld::DoorState state) const { if (ptr.getCellRef().getTeleport()) throw std::runtime_error("load doors can't be moved"); @@ -346,7 +346,7 @@ namespace MWClass customData.mDoorState = state; } - void Door::readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state) const + void Door::readAdditionalState(const MWWorld::Ptr& ptr, const ESM::ObjectState& state) const { if (!state.mHasCustomState) return; @@ -357,7 +357,7 @@ namespace MWClass customData.mDoorState = MWWorld::DoorState(doorState.mDoorState); } - void Door::writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const + void Door::writeAdditionalState(const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const { if (!ptr.getRefData().getCustomData()) { diff --git a/apps/openmw/mwclass/door.hpp b/apps/openmw/mwclass/door.hpp index 4ffa2bd02e..dc6be431ed 100644 --- a/apps/openmw/mwclass/door.hpp +++ b/apps/openmw/mwclass/door.hpp @@ -9,59 +9,59 @@ namespace MWClass { class Door : public MWWorld::RegisteredClass { - friend MWWorld::RegisteredClass; + friend MWWorld::RegisteredClass; - Door(); + Door(); - void ensureCustomData (const MWWorld::Ptr& ptr) const; + void ensureCustomData(const MWWorld::Ptr& ptr) const; - MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const override; - public: + public: + void insertObjectRendering(const MWWorld::Ptr& ptr, const std::string& model, + MWRender::RenderingInterface& renderingInterface) const override; + ///< Add reference into a cell for rendering - void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; - ///< Add reference into a cell for rendering + void insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, + MWPhysics::PhysicsSystem& physics) const override; + void insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, + MWPhysics::PhysicsSystem& physics) const override; - void insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const override; - void insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const override; + bool isDoor() const override; - bool isDoor() const override; + bool useAnim() const override; - bool useAnim() const override; + std::string_view getName(const MWWorld::ConstPtr& ptr) const override; + ///< \return name or ID; can return an empty string. - std::string_view getName(const MWWorld::ConstPtr& ptr) const override; - ///< \return name or ID; can return an empty string. + std::unique_ptr activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const override; + ///< Generate action for activation - std::unique_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const override; - ///< Generate action for activation + MWGui::ToolTipInfo getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const override; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. - MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const override; - ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + static std::string getDestination(const MWWorld::LiveCellRef& door); + ///< @return destination cell name or token - static std::string getDestination (const MWWorld::LiveCellRef& door); - ///< @return destination cell name or token + bool canLock(const MWWorld::ConstPtr& ptr) const override; - bool canLock(const MWWorld::ConstPtr &ptr) const override; + bool allowTelekinesis(const MWWorld::ConstPtr& ptr) const override; + ///< Return whether this class of object can be activated with telekinesis - bool allowTelekinesis(const MWWorld::ConstPtr &ptr) const override; - ///< Return whether this class of object can be activated with telekinesis + std::string_view getScript(const MWWorld::ConstPtr& ptr) const override; + ///< Return name of the script attached to ptr - std::string_view getScript(const MWWorld::ConstPtr& ptr) const override; - ///< Return name of the script attached to ptr + std::string getModel(const MWWorld::ConstPtr& ptr) const override; - std::string getModel(const MWWorld::ConstPtr &ptr) const override; + MWWorld::DoorState getDoorState(const MWWorld::ConstPtr& ptr) const override; + /// This does not actually cause the door to move. Use World::activateDoor instead. + void setDoorState(const MWWorld::Ptr& ptr, MWWorld::DoorState state) const override; - MWWorld::DoorState getDoorState (const MWWorld::ConstPtr &ptr) const override; - /// This does not actually cause the door to move. Use World::activateDoor instead. - void setDoorState (const MWWorld::Ptr &ptr, MWWorld::DoorState state) const override; + void readAdditionalState(const MWWorld::Ptr& ptr, const ESM::ObjectState& state) const override; + ///< Read additional state from \a state into \a ptr. - - void readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state) const override; - ///< Read additional state from \a state into \a ptr. - - void writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const override; - ///< Write additional state from \a ptr into \a state. + void writeAdditionalState(const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const override; + ///< Write additional state from \a ptr into \a state. }; } diff --git a/apps/openmw/mwclass/ingredient.cpp b/apps/openmw/mwclass/ingredient.cpp index d7b313a4f9..575377a0e5 100644 --- a/apps/openmw/mwclass/ingredient.cpp +++ b/apps/openmw/mwclass/ingredient.cpp @@ -6,13 +6,13 @@ #include #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" -#include "../mwworld/ptr.hpp" +#include "../mwworld/actioneat.hpp" #include "../mwworld/cellstore.hpp" #include "../mwworld/esmstore.hpp" -#include "../mwworld/actioneat.hpp" +#include "../mwworld/ptr.hpp" #include "../mwgui/tooltips.hpp" #include "../mwgui/ustring.hpp" @@ -29,52 +29,52 @@ namespace MWClass { } - void Ingredient::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const + void Ingredient::insertObjectRendering( + const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const { - if (!model.empty()) { + if (!model.empty()) + { renderingInterface.getObjects().insertModel(ptr, model); } } - std::string Ingredient::getModel(const MWWorld::ConstPtr &ptr) const + std::string Ingredient::getModel(const MWWorld::ConstPtr& ptr) const { return getClassModel(ptr); } std::string_view Ingredient::getName(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); const std::string& name = ref->mBase->mName; return !name.empty() ? name : ref->mBase->mId; } - std::unique_ptr Ingredient::activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const + std::unique_ptr Ingredient::activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const { return defaultItemActivate(ptr, actor); } std::string_view Ingredient::getScript(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mScript; } - int Ingredient::getValue (const MWWorld::ConstPtr& ptr) const + int Ingredient::getValue(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mData.mValue; } - - std::unique_ptr Ingredient::use (const MWWorld::Ptr& ptr, bool force) const + std::unique_ptr Ingredient::use(const MWWorld::Ptr& ptr, bool force) const { std::unique_ptr action = std::make_unique(ptr); - action->setSound ("Swallow"); + action->setSound("Swallow"); return action; } @@ -91,18 +91,19 @@ namespace MWClass const std::string& Ingredient::getInventoryIcon(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mIcon; } - MWGui::ToolTipInfo Ingredient::getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const + MWGui::ToolTipInfo Ingredient::getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); MWGui::ToolTipInfo info; std::string_view name = getName(ptr); - info.caption = MyGUI::TextIterator::toTagsString(MWGui::toUString(name)) + MWGui::ToolTips::getCountString(count); + info.caption + = MyGUI::TextIterator::toTagsString(MWGui::toUString(name)) + MWGui::ToolTips::getCountString(count); info.icon = ref->mBase->mIcon; std::string text; @@ -110,19 +111,24 @@ namespace MWClass text += MWGui::ToolTips::getWeightString(ref->mBase->mData.mWeight, "#{sWeight}"); text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); - if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { + if (MWBase::Environment::get().getWindowManager()->getFullHelp()) + { text += MWGui::ToolTips::getCellRefString(ptr.getCellRef()); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); } - MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); float alchemySkill = player.getClass().getSkill(player, ESM::Skill::Alchemy); - static const float fWortChanceValue = - MWBase::Environment::get().getWorld()->getStore().get().find("fWortChanceValue")->mValue.getFloat(); + static const float fWortChanceValue = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fWortChanceValue") + ->mValue.getFloat(); MWGui::Widgets::SpellEffectList list; - for (int i=0; i<4; ++i) + for (int i = 0; i < 4; ++i) { if (ref->mBase->mData.mEffectID[i] < 0) continue; @@ -131,10 +137,9 @@ namespace MWClass params.mAttribute = ref->mBase->mData.mAttributes[i]; params.mSkill = ref->mBase->mData.mSkills[i]; - params.mKnown = ( (i == 0 && alchemySkill >= fWortChanceValue) - || (i == 1 && alchemySkill >= fWortChanceValue*2) - || (i == 2 && alchemySkill >= fWortChanceValue*3) - || (i == 3 && alchemySkill >= fWortChanceValue*4)); + params.mKnown = ((i == 0 && alchemySkill >= fWortChanceValue) + || (i == 1 && alchemySkill >= fWortChanceValue * 2) || (i == 2 && alchemySkill >= fWortChanceValue * 3) + || (i == 3 && alchemySkill >= fWortChanceValue * 4)); list.push_back(params); } @@ -146,22 +151,21 @@ namespace MWClass return info; } - MWWorld::Ptr Ingredient::copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const + MWWorld::Ptr Ingredient::copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return MWWorld::Ptr(cell.insert(ref), &cell); } - bool Ingredient::canSell (const MWWorld::ConstPtr& item, int npcServices) const + bool Ingredient::canSell(const MWWorld::ConstPtr& item, int npcServices) const { return (npcServices & ESM::NPC::Ingredients) != 0; } - - float Ingredient::getWeight(const MWWorld::ConstPtr &ptr) const + float Ingredient::getWeight(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mData.mWeight; } } diff --git a/apps/openmw/mwclass/ingredient.hpp b/apps/openmw/mwclass/ingredient.hpp index 11a6e56944..4527c67d98 100644 --- a/apps/openmw/mwclass/ingredient.hpp +++ b/apps/openmw/mwclass/ingredient.hpp @@ -7,50 +7,49 @@ namespace MWClass { class Ingredient : public MWWorld::RegisteredClass { - friend MWWorld::RegisteredClass; + friend MWWorld::RegisteredClass; - Ingredient(); + Ingredient(); - MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const override; - public: + public: + void insertObjectRendering(const MWWorld::Ptr& ptr, const std::string& model, + MWRender::RenderingInterface& renderingInterface) const override; + ///< Add reference into a cell for rendering - void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; - ///< Add reference into a cell for rendering + std::string_view getName(const MWWorld::ConstPtr& ptr) const override; + ///< \return name or ID; can return an empty string. - std::string_view getName(const MWWorld::ConstPtr& ptr) const override; - ///< \return name or ID; can return an empty string. + std::unique_ptr activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const override; + ///< Generate action for activation - std::unique_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const override; - ///< Generate action for activation + MWGui::ToolTipInfo getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const override; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. - MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const override; - ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + std::string_view getScript(const MWWorld::ConstPtr& ptr) const override; + ///< Return name of the script attached to ptr - std::string_view getScript(const MWWorld::ConstPtr& ptr) const override; - ///< Return name of the script attached to ptr + int getValue(const MWWorld::ConstPtr& ptr) const override; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. - int getValue (const MWWorld::ConstPtr& ptr) const override; - ///< Return trade value of the object. Throws an exception, if the object can't be traded. + std::unique_ptr use(const MWWorld::Ptr& ptr, bool force = false) const override; + ///< Generate action for using via inventory menu - std::unique_ptr use (const MWWorld::Ptr& ptr, bool force=false) const override; - ///< Generate action for using via inventory menu + std::string_view getUpSoundId(const MWWorld::ConstPtr& ptr) const override; + ///< Return the pick up sound Id - std::string_view getUpSoundId(const MWWorld::ConstPtr& ptr) const override; - ///< Return the pick up sound Id + std::string_view getDownSoundId(const MWWorld::ConstPtr& ptr) const override; + ///< Return the put down sound Id - std::string_view getDownSoundId(const MWWorld::ConstPtr& ptr) const override; - ///< Return the put down sound Id + const std::string& getInventoryIcon(const MWWorld::ConstPtr& ptr) const override; + ///< Return name of inventory icon. - const std::string& getInventoryIcon(const MWWorld::ConstPtr& ptr) const override; - ///< Return name of inventory icon. + std::string getModel(const MWWorld::ConstPtr& ptr) const override; - std::string getModel(const MWWorld::ConstPtr &ptr) const override; + float getWeight(const MWWorld::ConstPtr& ptr) const override; - float getWeight (const MWWorld::ConstPtr& ptr) const override; - - bool canSell (const MWWorld::ConstPtr& item, int npcServices) const override; + bool canSell(const MWWorld::ConstPtr& item, int npcServices) const override; }; } diff --git a/apps/openmw/mwclass/itemlevlist.hpp b/apps/openmw/mwclass/itemlevlist.hpp index dbaf6f54c4..56652c788b 100644 --- a/apps/openmw/mwclass/itemlevlist.hpp +++ b/apps/openmw/mwclass/itemlevlist.hpp @@ -7,17 +7,16 @@ namespace MWClass { class ItemLevList : public MWWorld::RegisteredClass { - friend MWWorld::RegisteredClass; + friend MWWorld::RegisteredClass; - ItemLevList(); + ItemLevList(); - public: + public: + std::string_view getName(const MWWorld::ConstPtr& ptr) const override; + ///< \return name or ID; can return an empty string. - std::string_view getName(const MWWorld::ConstPtr& ptr) const override; - ///< \return name or ID; can return an empty string. - - bool hasToolTip (const MWWorld::ConstPtr& ptr) const override; - ///< @return true if this object has a tooltip when focused (default implementation: true) + bool hasToolTip(const MWWorld::ConstPtr& ptr) const override; + ///< @return true if this object has a tooltip when focused (default implementation: true) }; } diff --git a/apps/openmw/mwclass/light.cpp b/apps/openmw/mwclass/light.cpp index 49974f9461..c3ac48ff81 100644 --- a/apps/openmw/mwclass/light.cpp +++ b/apps/openmw/mwclass/light.cpp @@ -11,13 +11,13 @@ #include "../mwbase/soundmanager.hpp" #include "../mwbase/windowmanager.hpp" -#include "../mwworld/ptr.hpp" +#include "../mwphysics/physicssystem.hpp" #include "../mwworld/actionequip.hpp" -#include "../mwworld/nullaction.hpp" +#include "../mwworld/cellstore.hpp" #include "../mwworld/failedaction.hpp" #include "../mwworld/inventorystore.hpp" -#include "../mwworld/cellstore.hpp" -#include "../mwphysics/physicssystem.hpp" +#include "../mwworld/nullaction.hpp" +#include "../mwworld/ptr.hpp" #include "../mwgui/tooltips.hpp" #include "../mwgui/ustring.hpp" @@ -34,30 +34,31 @@ namespace MWClass { } - void Light::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const + void Light::insertObjectRendering( + const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const { - MWWorld::LiveCellRef *ref = - ptr.get(); + MWWorld::LiveCellRef* ref = ptr.get(); // Insert even if model is empty, so that the light is added - renderingInterface.getObjects().insertModel(ptr, model, true, !(ref->mBase->mData.mFlags & ESM::Light::OffDefault)); + renderingInterface.getObjects().insertModel( + ptr, model, true, !(ref->mBase->mData.mFlags & ESM::Light::OffDefault)); } - void Light::insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const + void Light::insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, + MWPhysics::PhysicsSystem& physics) const { - MWWorld::LiveCellRef *ref = - ptr.get(); - assert (ref->mBase != nullptr); + MWWorld::LiveCellRef* ref = ptr.get(); + assert(ref->mBase != nullptr); insertObjectPhysics(ptr, model, rotation, physics); if (!ref->mBase->mSound.empty() && !(ref->mBase->mData.mFlags & ESM::Light::OffDefault)) - MWBase::Environment::get().getSoundManager()->playSound3D(ptr, ref->mBase->mSound, 1.0, 1.0, - MWSound::Type::Sfx, - MWSound::PlayMode::Loop); + MWBase::Environment::get().getSoundManager()->playSound3D( + ptr, ref->mBase->mSound, 1.0, 1.0, MWSound::Type::Sfx, MWSound::PlayMode::Loop); } - void Light::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const + void Light::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, + MWPhysics::PhysicsSystem& physics) const { // TODO: add option somewhere to enable collision for placeable objects if ((ptr.get()->mBase->mData.mFlags & ESM::Light::Carry) == 0) @@ -69,14 +70,14 @@ namespace MWClass return true; } - std::string Light::getModel(const MWWorld::ConstPtr &ptr) const + std::string Light::getModel(const MWWorld::ConstPtr& ptr) const { return getClassModel(ptr); } std::string_view Light::getName(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); if (ref->mBase->mModel.empty()) return {}; @@ -85,14 +86,13 @@ namespace MWClass return !name.empty() ? name : ref->mBase->mId; } - std::unique_ptr Light::activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const + std::unique_ptr Light::activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const { - if(!MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Inventory)) + if (!MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Inventory)) return std::make_unique(); - MWWorld::LiveCellRef *ref = ptr.get(); - if(!(ref->mBase->mData.mFlags&ESM::Light::Carry)) + MWWorld::LiveCellRef* ref = ptr.get(); + if (!(ref->mBase->mData.mFlags & ESM::Light::Carry)) return std::make_unique(); return defaultItemActivate(ptr, actor); @@ -100,26 +100,26 @@ namespace MWClass std::string_view Light::getScript(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mScript; } - std::pair, bool> Light::getEquipmentSlots (const MWWorld::ConstPtr& ptr) const + std::pair, bool> Light::getEquipmentSlots(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); std::vector slots_; if (ref->mBase->mData.mFlags & ESM::Light::Carry) - slots_.push_back (int (MWWorld::InventoryStore::Slot_CarriedLeft)); + slots_.push_back(int(MWWorld::InventoryStore::Slot_CarriedLeft)); - return std::make_pair (slots_, false); + return std::make_pair(slots_, false); } - int Light::getValue (const MWWorld::ConstPtr& ptr) const + int Light::getValue(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mData.mValue; } @@ -134,38 +134,40 @@ namespace MWClass return "Item Misc Down"; } - const std::string& Light::getInventoryIcon(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mIcon; } - bool Light::hasToolTip (const MWWorld::ConstPtr& ptr) const + bool Light::hasToolTip(const MWWorld::ConstPtr& ptr) const { return showsInInventory(ptr); } - MWGui::ToolTipInfo Light::getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const + MWGui::ToolTipInfo Light::getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); MWGui::ToolTipInfo info; std::string_view name = getName(ptr); - info.caption = MyGUI::TextIterator::toTagsString(MWGui::toUString(name)) + MWGui::ToolTips::getCountString(count); + info.caption + = MyGUI::TextIterator::toTagsString(MWGui::toUString(name)) + MWGui::ToolTips::getCountString(count); info.icon = ref->mBase->mIcon; std::string text; // Don't show duration for infinite light sources. - if (Settings::Manager::getBool("show effect duration","Game") && ptr.getClass().getRemainingUsageTime(ptr) != -1) + if (Settings::Manager::getBool("show effect duration", "Game") + && ptr.getClass().getRemainingUsageTime(ptr) != -1) text += MWGui::ToolTips::getDurationString(ptr.getClass().getRemainingUsageTime(ptr), "\n#{sDuration}"); text += MWGui::ToolTips::getWeightString(ref->mBase->mData.mWeight, "#{sWeight}"); text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); - if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { + if (MWBase::Environment::get().getWindowManager()->getFullHelp()) + { text += MWGui::ToolTips::getCellRefString(ptr.getCellRef()); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); } @@ -175,7 +177,7 @@ namespace MWClass return info; } - bool Light::showsInInventory (const MWWorld::ConstPtr& ptr) const + bool Light::showsInInventory(const MWWorld::ConstPtr& ptr) const { const ESM::Light* light = ptr.get()->mBase; @@ -185,7 +187,7 @@ namespace MWClass return Class::showsInInventory(ptr); } - std::unique_ptr Light::use (const MWWorld::Ptr& ptr, bool force) const + std::unique_ptr Light::use(const MWWorld::Ptr& ptr, bool force) const { std::unique_ptr action = std::make_unique(ptr, force); @@ -194,49 +196,49 @@ namespace MWClass return action; } - void Light::setRemainingUsageTime (const MWWorld::Ptr& ptr, float duration) const + void Light::setRemainingUsageTime(const MWWorld::Ptr& ptr, float duration) const { ptr.getCellRef().setChargeFloat(duration); } - float Light::getRemainingUsageTime (const MWWorld::ConstPtr& ptr) const + float Light::getRemainingUsageTime(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); if (ptr.getCellRef().getCharge() == -1) return static_cast(ref->mBase->mData.mTime); else return ptr.getCellRef().getChargeFloat(); } - MWWorld::Ptr Light::copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const + MWWorld::Ptr Light::copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return MWWorld::Ptr(cell.insert(ref), &cell); } - bool Light::canSell (const MWWorld::ConstPtr& item, int npcServices) const + bool Light::canSell(const MWWorld::ConstPtr& item, int npcServices) const { return (npcServices & ESM::NPC::Lights) != 0; } - float Light::getWeight(const MWWorld::ConstPtr &ptr) const + float Light::getWeight(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mData.mWeight; } std::pair Light::canBeEquipped(const MWWorld::ConstPtr& ptr, const MWWorld::Ptr& npc) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); if (!(ref->mBase->mData.mFlags & ESM::Light::Carry)) - return {0, {}}; + return { 0, {} }; - return {1, {}}; + return { 1, {} }; } std::string_view Light::getSound(const MWWorld::ConstPtr& ptr) const { - return ptr.get()->mBase->mSound; + return ptr.get()->mBase->mSound; } } diff --git a/apps/openmw/mwclass/light.hpp b/apps/openmw/mwclass/light.hpp index f803b523a3..41382df9b0 100644 --- a/apps/openmw/mwclass/light.hpp +++ b/apps/openmw/mwclass/light.hpp @@ -7,74 +7,76 @@ namespace MWClass { class Light : public MWWorld::RegisteredClass { - friend MWWorld::RegisteredClass; + friend MWWorld::RegisteredClass; - Light(); + Light(); - MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const override; - public: + public: + void insertObjectRendering(const MWWorld::Ptr& ptr, const std::string& model, + MWRender::RenderingInterface& renderingInterface) const override; + ///< Add reference into a cell for rendering - void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; - ///< Add reference into a cell for rendering + void insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, + MWPhysics::PhysicsSystem& physics) const override; + void insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, + MWPhysics::PhysicsSystem& physics) const override; - void insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const override; - void insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const override; + bool useAnim() const override; - bool useAnim() const override; + std::string_view getName(const MWWorld::ConstPtr& ptr) const override; + ///< \return name or ID; can return an empty string. - std::string_view getName(const MWWorld::ConstPtr& ptr) const override; - ///< \return name or ID; can return an empty string. + bool hasToolTip(const MWWorld::ConstPtr& ptr) const override; + ///< @return true if this object has a tooltip when focused (default implementation: true) - bool hasToolTip (const MWWorld::ConstPtr& ptr) const override; - ///< @return true if this object has a tooltip when focused (default implementation: true) + MWGui::ToolTipInfo getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const override; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. - MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const override; - ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + bool showsInInventory(const MWWorld::ConstPtr& ptr) const override; - bool showsInInventory (const MWWorld::ConstPtr& ptr) const override; + std::unique_ptr activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const override; + ///< Generate action for activation - std::unique_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const override; - ///< Generate action for activation + std::string_view getScript(const MWWorld::ConstPtr& ptr) const override; + ///< Return name of the script attached to ptr - std::string_view getScript(const MWWorld::ConstPtr& ptr) const override; - ///< Return name of the script attached to ptr + std::pair, bool> getEquipmentSlots(const MWWorld::ConstPtr& ptr) const override; + ///< \return first: Return IDs of the slot this object can be equipped in; second: can object + /// stay stacked when equipped? - std::pair, bool> getEquipmentSlots (const MWWorld::ConstPtr& ptr) const override; - ///< \return first: Return IDs of the slot this object can be equipped in; second: can object - /// stay stacked when equipped? + int getValue(const MWWorld::ConstPtr& ptr) const override; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. - int getValue (const MWWorld::ConstPtr& ptr) const override; - ///< Return trade value of the object. Throws an exception, if the object can't be traded. + std::string_view getUpSoundId(const MWWorld::ConstPtr& ptr) const override; + ///< Return the pick up sound Id - std::string_view getUpSoundId(const MWWorld::ConstPtr& ptr) const override; - ///< Return the pick up sound Id + std::string_view getDownSoundId(const MWWorld::ConstPtr& ptr) const override; + ///< Return the put down sound Id - std::string_view getDownSoundId(const MWWorld::ConstPtr& ptr) const override; - ///< Return the put down sound Id + const std::string& getInventoryIcon(const MWWorld::ConstPtr& ptr) const override; + ///< Return name of inventory icon. - const std::string& getInventoryIcon(const MWWorld::ConstPtr& ptr) const override; - ///< Return name of inventory icon. + std::unique_ptr use(const MWWorld::Ptr& ptr, bool force = false) const override; + ///< Generate action for using via inventory menu - std::unique_ptr use (const MWWorld::Ptr& ptr, bool force=false) const override; - ///< Generate action for using via inventory menu + void setRemainingUsageTime(const MWWorld::Ptr& ptr, float duration) const override; + ///< Sets the remaining duration of the object. - void setRemainingUsageTime (const MWWorld::Ptr& ptr, float duration) const override; - ///< Sets the remaining duration of the object. + float getRemainingUsageTime(const MWWorld::ConstPtr& ptr) const override; + ///< Returns the remaining duration of the object. - float getRemainingUsageTime (const MWWorld::ConstPtr& ptr) const override; - ///< Returns the remaining duration of the object. + std::string getModel(const MWWorld::ConstPtr& ptr) const override; - std::string getModel(const MWWorld::ConstPtr &ptr) const override; + float getWeight(const MWWorld::ConstPtr& ptr) const override; - float getWeight (const MWWorld::ConstPtr& ptr) const override; + bool canSell(const MWWorld::ConstPtr& item, int npcServices) const override; - bool canSell (const MWWorld::ConstPtr& item, int npcServices) const override; + std::pair canBeEquipped( + const MWWorld::ConstPtr& ptr, const MWWorld::Ptr& npc) const override; - std::pair canBeEquipped(const MWWorld::ConstPtr& ptr, const MWWorld::Ptr& npc) const override; - - std::string_view getSound(const MWWorld::ConstPtr& ptr) const override; + std::string_view getSound(const MWWorld::ConstPtr& ptr) const override; }; } diff --git a/apps/openmw/mwclass/lockpick.cpp b/apps/openmw/mwclass/lockpick.cpp index 0c09027d25..79b07a8154 100644 --- a/apps/openmw/mwclass/lockpick.cpp +++ b/apps/openmw/mwclass/lockpick.cpp @@ -9,10 +9,10 @@ #include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/windowmanager.hpp" -#include "../mwworld/ptr.hpp" #include "../mwworld/actionequip.hpp" -#include "../mwworld/inventorystore.hpp" #include "../mwworld/cellstore.hpp" +#include "../mwworld/inventorystore.hpp" +#include "../mwworld/ptr.hpp" #include "../mwgui/tooltips.hpp" #include "../mwgui/ustring.hpp" @@ -29,51 +29,52 @@ namespace MWClass { } - void Lockpick::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const + void Lockpick::insertObjectRendering( + const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const { - if (!model.empty()) { + if (!model.empty()) + { renderingInterface.getObjects().insertModel(ptr, model); } } - std::string Lockpick::getModel(const MWWorld::ConstPtr &ptr) const + std::string Lockpick::getModel(const MWWorld::ConstPtr& ptr) const { return getClassModel(ptr); } std::string_view Lockpick::getName(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); const std::string& name = ref->mBase->mName; return !name.empty() ? name : ref->mBase->mId; } - std::unique_ptr Lockpick::activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const + std::unique_ptr Lockpick::activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const { return defaultItemActivate(ptr, actor); } std::string_view Lockpick::getScript(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mScript; } - std::pair, bool> Lockpick::getEquipmentSlots (const MWWorld::ConstPtr& ptr) const + std::pair, bool> Lockpick::getEquipmentSlots(const MWWorld::ConstPtr& ptr) const { std::vector slots_; - slots_.push_back (int (MWWorld::InventoryStore::Slot_CarriedRight)); + slots_.push_back(int(MWWorld::InventoryStore::Slot_CarriedRight)); - return std::make_pair (slots_, false); + return std::make_pair(slots_, false); } - int Lockpick::getValue (const MWWorld::ConstPtr& ptr) const + int Lockpick::getValue(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mData.mValue; } @@ -90,18 +91,19 @@ namespace MWClass const std::string& Lockpick::getInventoryIcon(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mIcon; } - MWGui::ToolTipInfo Lockpick::getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const + MWGui::ToolTipInfo Lockpick::getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); MWGui::ToolTipInfo info; std::string_view name = getName(ptr); - info.caption = MyGUI::TextIterator::toTagsString(MWGui::toUString(name)) + MWGui::ToolTips::getCountString(count); + info.caption + = MyGUI::TextIterator::toTagsString(MWGui::toUString(name)) + MWGui::ToolTips::getCountString(count); info.icon = ref->mBase->mIcon; std::string text; @@ -113,7 +115,8 @@ namespace MWClass text += MWGui::ToolTips::getWeightString(ref->mBase->mData.mWeight, "#{sWeight}"); text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); - if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { + if (MWBase::Environment::get().getWindowManager()->getFullHelp()) + { text += MWGui::ToolTips::getCellRefString(ptr.getCellRef()); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); } @@ -123,7 +126,7 @@ namespace MWClass return info; } - std::unique_ptr Lockpick::use (const MWWorld::Ptr& ptr, bool force) const + std::unique_ptr Lockpick::use(const MWWorld::Ptr& ptr, bool force) const { std::unique_ptr action = std::make_unique(ptr, force); @@ -132,38 +135,39 @@ namespace MWClass return action; } - MWWorld::Ptr Lockpick::copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const + MWWorld::Ptr Lockpick::copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return MWWorld::Ptr(cell.insert(ref), &cell); } - std::pair Lockpick::canBeEquipped(const MWWorld::ConstPtr& ptr, const MWWorld::Ptr& npc) const + std::pair Lockpick::canBeEquipped( + const MWWorld::ConstPtr& ptr, const MWWorld::Ptr& npc) const { // Do not allow equip tools from inventory during attack if (MWBase::Environment::get().getMechanicsManager()->isAttackingOrSpell(npc) && MWBase::Environment::get().getWindowManager()->isGuiMode()) - return {0, "#{sCantEquipWeapWarning}"}; + return { 0, "#{sCantEquipWeapWarning}" }; - return {1, {}}; + return { 1, {} }; } - bool Lockpick::canSell (const MWWorld::ConstPtr& item, int npcServices) const + bool Lockpick::canSell(const MWWorld::ConstPtr& item, int npcServices) const { return (npcServices & ESM::NPC::Picks) != 0; } - int Lockpick::getItemMaxHealth (const MWWorld::ConstPtr& ptr) const + int Lockpick::getItemMaxHealth(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mData.mUses; } - float Lockpick::getWeight(const MWWorld::ConstPtr &ptr) const + float Lockpick::getWeight(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mData.mWeight; } } diff --git a/apps/openmw/mwclass/lockpick.hpp b/apps/openmw/mwclass/lockpick.hpp index f34579c38d..750549b4e3 100644 --- a/apps/openmw/mwclass/lockpick.hpp +++ b/apps/openmw/mwclass/lockpick.hpp @@ -7,62 +7,62 @@ namespace MWClass { class Lockpick : public MWWorld::RegisteredClass { - friend MWWorld::RegisteredClass; + friend MWWorld::RegisteredClass; - Lockpick(); + Lockpick(); - MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const override; - public: + public: + void insertObjectRendering(const MWWorld::Ptr& ptr, const std::string& model, + MWRender::RenderingInterface& renderingInterface) const override; + ///< Add reference into a cell for rendering - void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; - ///< Add reference into a cell for rendering + std::string_view getName(const MWWorld::ConstPtr& ptr) const override; + ///< \return name or ID; can return an empty string. - std::string_view getName(const MWWorld::ConstPtr& ptr) const override; - ///< \return name or ID; can return an empty string. + std::unique_ptr activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const override; + ///< Generate action for activation - std::unique_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const override; - ///< Generate action for activation + MWGui::ToolTipInfo getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const override; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. - MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const override; - ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + std::string_view getScript(const MWWorld::ConstPtr& ptr) const override; + ///< Return name of the script attached to ptr - std::string_view getScript(const MWWorld::ConstPtr& ptr) const override; - ///< Return name of the script attached to ptr + std::pair, bool> getEquipmentSlots(const MWWorld::ConstPtr& ptr) const override; + ///< \return first: Return IDs of the slot this object can be equipped in; second: can object + /// stay stacked when equipped? - std::pair, bool> getEquipmentSlots (const MWWorld::ConstPtr& ptr) const override; - ///< \return first: Return IDs of the slot this object can be equipped in; second: can object - /// stay stacked when equipped? + int getValue(const MWWorld::ConstPtr& ptr) const override; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. - int getValue (const MWWorld::ConstPtr& ptr) const override; - ///< Return trade value of the object. Throws an exception, if the object can't be traded. + std::string_view getUpSoundId(const MWWorld::ConstPtr& ptr) const override; + ///< Return the pick up sound Id - std::string_view getUpSoundId(const MWWorld::ConstPtr& ptr) const override; - ///< Return the pick up sound Id + std::string_view getDownSoundId(const MWWorld::ConstPtr& ptr) const override; + ///< Return the put down sound Id - std::string_view getDownSoundId(const MWWorld::ConstPtr& ptr) const override; - ///< Return the put down sound Id + const std::string& getInventoryIcon(const MWWorld::ConstPtr& ptr) const override; + ///< Return name of inventory icon. - const std::string& getInventoryIcon(const MWWorld::ConstPtr& ptr) const override; - ///< Return name of inventory icon. + std::pair canBeEquipped( + const MWWorld::ConstPtr& ptr, const MWWorld::Ptr& npc) const override; - std::pair canBeEquipped(const MWWorld::ConstPtr& ptr, const MWWorld::Ptr& npc) const override; + std::unique_ptr use(const MWWorld::Ptr& ptr, bool force = false) const override; + ///< Generate action for using via inventory menu - std::unique_ptr use (const MWWorld::Ptr& ptr, bool force=false) const override; - ///< Generate action for using via inventory menu + std::string getModel(const MWWorld::ConstPtr& ptr) const override; - std::string getModel(const MWWorld::ConstPtr &ptr) const override; + bool canSell(const MWWorld::ConstPtr& item, int npcServices) const override; - bool canSell (const MWWorld::ConstPtr& item, int npcServices) const override; + float getWeight(const MWWorld::ConstPtr& ptr) const override; - float getWeight (const MWWorld::ConstPtr& ptr) const override; + int getItemMaxHealth(const MWWorld::ConstPtr& ptr) const override; + ///< Return item max health or throw an exception, if class does not have item health - int getItemMaxHealth (const MWWorld::ConstPtr& ptr) const override; - ///< Return item max health or throw an exception, if class does not have item health - - bool hasItemHealth (const MWWorld::ConstPtr& ptr) const override { return true; } - ///< \return Item health data available? (default implementation: false) + bool hasItemHealth(const MWWorld::ConstPtr& ptr) const override { return true; } + ///< \return Item health data available? (default implementation: false) }; } diff --git a/apps/openmw/mwclass/misc.cpp b/apps/openmw/mwclass/misc.cpp index 0658212b84..8ddf6f6522 100644 --- a/apps/openmw/mwclass/misc.cpp +++ b/apps/openmw/mwclass/misc.cpp @@ -2,21 +2,21 @@ #include +#include #include #include -#include #include #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" +#include "../mwworld/actionsoulgem.hpp" #include "../mwworld/cellstore.hpp" #include "../mwworld/esmstore.hpp" #include "../mwworld/manualref.hpp" #include "../mwworld/nullaction.hpp" -#include "../mwworld/actionsoulgem.hpp" #include "../mwgui/tooltips.hpp" #include "../mwgui/ustring.hpp" @@ -33,51 +33,52 @@ namespace MWClass { } - bool Miscellaneous::isGold (const MWWorld::ConstPtr& ptr) const + bool Miscellaneous::isGold(const MWWorld::ConstPtr& ptr) const { return Misc::StringUtils::ciEqual(ptr.getCellRef().getRefId(), "gold_001") - || Misc::StringUtils::ciEqual(ptr.getCellRef().getRefId(), "gold_005") - || Misc::StringUtils::ciEqual(ptr.getCellRef().getRefId(), "gold_010") - || Misc::StringUtils::ciEqual(ptr.getCellRef().getRefId(), "gold_025") - || Misc::StringUtils::ciEqual(ptr.getCellRef().getRefId(), "gold_100"); + || Misc::StringUtils::ciEqual(ptr.getCellRef().getRefId(), "gold_005") + || Misc::StringUtils::ciEqual(ptr.getCellRef().getRefId(), "gold_010") + || Misc::StringUtils::ciEqual(ptr.getCellRef().getRefId(), "gold_025") + || Misc::StringUtils::ciEqual(ptr.getCellRef().getRefId(), "gold_100"); } - void Miscellaneous::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const + void Miscellaneous::insertObjectRendering( + const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const { - if (!model.empty()) { + if (!model.empty()) + { renderingInterface.getObjects().insertModel(ptr, model); } } - std::string Miscellaneous::getModel(const MWWorld::ConstPtr &ptr) const + std::string Miscellaneous::getModel(const MWWorld::ConstPtr& ptr) const { return getClassModel(ptr); } std::string_view Miscellaneous::getName(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); const std::string& name = ref->mBase->mName; return !name.empty() ? name : ref->mBase->mId; } - std::unique_ptr Miscellaneous::activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const + std::unique_ptr Miscellaneous::activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const { return defaultItemActivate(ptr, actor); } std::string_view Miscellaneous::getScript(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mScript; } - int Miscellaneous::getValue (const MWWorld::ConstPtr& ptr) const + int Miscellaneous::getValue(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); int value = ref->mBase->mData.mValue; if (ptr.getCellRef().getGoldValue() > 1 && ptr.getRefData().getCount() == 1) @@ -85,15 +86,16 @@ namespace MWClass if (!ptr.getCellRef().getSoul().empty()) { - const ESM::Creature *creature = MWBase::Environment::get().getWorld()->getStore().get().search(ref->mRef.getSoul()); + const ESM::Creature* creature + = MWBase::Environment::get().getWorld()->getStore().get().search(ref->mRef.getSoul()); if (creature) { int soul = creature->mData.mSoul; if (Settings::Manager::getBool("rebalance soul gem values", "Game")) { - // use the 'soul gem value rebalance' formula from the Morrowind Code Patch + // use the 'soul gem value rebalance' formula from the Morrowind Code Patch float soulValue = 0.0001 * pow(soul, 3) + 2 * soul; - + // for Azura's star add the unfilled value if (Misc::StringUtils::ciEqual(ptr.getCellRef().getRefId(), "Misc_SoulGem_Azura")) value += soulValue; @@ -124,14 +126,14 @@ namespace MWClass const std::string& Miscellaneous::getInventoryIcon(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mIcon; } - MWGui::ToolTipInfo Miscellaneous::getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const + MWGui::ToolTipInfo Miscellaneous::getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); MWGui::ToolTipInfo info; @@ -146,7 +148,8 @@ namespace MWClass countString = " (" + std::to_string(count) + ")"; std::string_view name = getName(ptr); - info.caption = MyGUI::TextIterator::toTagsString(MWGui::toUString(name)) + MWGui::ToolTips::getCountString(count) + MWGui::ToolTips::getSoulString(ptr.getCellRef()); + info.caption = MyGUI::TextIterator::toTagsString(MWGui::toUString(name)) + + MWGui::ToolTips::getCountString(count) + MWGui::ToolTips::getSoulString(ptr.getCellRef()); info.icon = ref->mBase->mIcon; std::string text; @@ -155,7 +158,8 @@ namespace MWClass if (!gold && !ref->mBase->mData.mIsKey) text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}"); - if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { + if (MWBase::Environment::get().getWindowManager()->getFullHelp()) + { text += MWGui::ToolTips::getCellRefString(ptr.getCellRef()); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); } @@ -165,14 +169,14 @@ namespace MWClass return info; } - MWWorld::Ptr Miscellaneous::copyToCell(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell, int count) const + MWWorld::Ptr Miscellaneous::copyToCell(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell, int count) const { MWWorld::Ptr newPtr; - const MWWorld::ESMStore &store = - MWBase::Environment::get().getWorld()->getStore(); + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); - if (isGold(ptr)) { + if (isGold(ptr)) + { int goldAmount = getValue(ptr) * count; std::string_view base = "Gold_001"; @@ -188,15 +192,15 @@ namespace MWClass // Really, I have no idea why moving ref out of conditional // scope causes list::push_back throwing std::bad_alloc MWWorld::ManualRef newRef(store, base); - const MWWorld::LiveCellRef *ref = - newRef.getPtr().get(); + const MWWorld::LiveCellRef* ref = newRef.getPtr().get(); newPtr = MWWorld::Ptr(cell.insert(ref), &cell); newPtr.getCellRef().setGoldValue(goldAmount); newPtr.getRefData().setCount(1); - } else { - const MWWorld::LiveCellRef *ref = - ptr.get(); + } + else + { + const MWWorld::LiveCellRef* ref = ptr.get(); newPtr = MWWorld::Ptr(cell.insert(ref), &cell); newPtr.getRefData().setCount(count); } @@ -205,7 +209,7 @@ namespace MWClass return newPtr; } - std::unique_ptr Miscellaneous::use (const MWWorld::Ptr& ptr, bool force) const + std::unique_ptr Miscellaneous::use(const MWWorld::Ptr& ptr, bool force) const { if (isSoulGem(ptr)) return std::make_unique(ptr); @@ -213,22 +217,22 @@ namespace MWClass return std::make_unique(); } - bool Miscellaneous::canSell (const MWWorld::ConstPtr& item, int npcServices) const + bool Miscellaneous::canSell(const MWWorld::ConstPtr& item, int npcServices) const { - const MWWorld::LiveCellRef *ref = item.get(); + const MWWorld::LiveCellRef* ref = item.get(); return !ref->mBase->mData.mIsKey && (npcServices & ESM::NPC::Misc) && !isGold(item); } - float Miscellaneous::getWeight(const MWWorld::ConstPtr &ptr) const + float Miscellaneous::getWeight(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mData.mWeight; } - bool Miscellaneous::isKey(const MWWorld::ConstPtr &ptr) const + bool Miscellaneous::isKey(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mData.mIsKey != 0; } diff --git a/apps/openmw/mwclass/misc.hpp b/apps/openmw/mwclass/misc.hpp index 55528855a7..1af2b772b8 100644 --- a/apps/openmw/mwclass/misc.hpp +++ b/apps/openmw/mwclass/misc.hpp @@ -7,56 +7,55 @@ namespace MWClass { class Miscellaneous : public MWWorld::RegisteredClass { - friend MWWorld::RegisteredClass; + friend MWWorld::RegisteredClass; - Miscellaneous(); + Miscellaneous(); - public: + public: + MWWorld::Ptr copyToCell(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell, int count) const override; - MWWorld::Ptr copyToCell(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell, int count) const override; + void insertObjectRendering(const MWWorld::Ptr& ptr, const std::string& model, + MWRender::RenderingInterface& renderingInterface) const override; + ///< Add reference into a cell for rendering - void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; - ///< Add reference into a cell for rendering + std::string_view getName(const MWWorld::ConstPtr& ptr) const override; + ///< \return name or ID; can return an empty string. - std::string_view getName(const MWWorld::ConstPtr& ptr) const override; - ///< \return name or ID; can return an empty string. + std::unique_ptr activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const override; + ///< Generate action for activation - std::unique_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const override; - ///< Generate action for activation + MWGui::ToolTipInfo getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const override; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. - MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const override; - ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + std::string_view getScript(const MWWorld::ConstPtr& ptr) const override; + ///< Return name of the script attached to ptr - std::string_view getScript(const MWWorld::ConstPtr& ptr) const override; - ///< Return name of the script attached to ptr + int getValue(const MWWorld::ConstPtr& ptr) const override; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. - int getValue (const MWWorld::ConstPtr& ptr) const override; - ///< Return trade value of the object. Throws an exception, if the object can't be traded. + std::string_view getUpSoundId(const MWWorld::ConstPtr& ptr) const override; + ///< Return the pick up sound Id - std::string_view getUpSoundId(const MWWorld::ConstPtr& ptr) const override; - ///< Return the pick up sound Id + std::string_view getDownSoundId(const MWWorld::ConstPtr& ptr) const override; + ///< Return the put down sound Id - std::string_view getDownSoundId(const MWWorld::ConstPtr& ptr) const override; - ///< Return the put down sound Id + const std::string& getInventoryIcon(const MWWorld::ConstPtr& ptr) const override; + ///< Return name of inventory icon. - const std::string& getInventoryIcon(const MWWorld::ConstPtr& ptr) const override; - ///< Return name of inventory icon. + std::string getModel(const MWWorld::ConstPtr& ptr) const override; - std::string getModel(const MWWorld::ConstPtr &ptr) const override; + std::unique_ptr use(const MWWorld::Ptr& ptr, bool force = false) const override; + ///< Generate action for using via inventory menu - std::unique_ptr use (const MWWorld::Ptr& ptr, bool force=false) const override; - ///< Generate action for using via inventory menu + float getWeight(const MWWorld::ConstPtr& ptr) const override; - float getWeight (const MWWorld::ConstPtr& ptr) const override; + bool canSell(const MWWorld::ConstPtr& item, int npcServices) const override; - bool canSell (const MWWorld::ConstPtr& item, int npcServices) const override; + bool isKey(const MWWorld::ConstPtr& ptr) const override; - bool isKey (const MWWorld::ConstPtr &ptr) const override; + bool isGold(const MWWorld::ConstPtr& ptr) const override; - bool isGold (const MWWorld::ConstPtr& ptr) const override; - - bool isSoulGem(const MWWorld::ConstPtr& ptr) const override; + bool isSoulGem(const MWWorld::ConstPtr& ptr) const override; }; } diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 6a0637576f..7d279084ec 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -5,56 +5,55 @@ #include #include -#include #include +#include #include +#include +#include #include #include -#include -#include #include -#include -#include #include -#include +#include +#include +#include "../mwbase/dialoguemanager.hpp" #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" +#include "../mwbase/luamanager.hpp" #include "../mwbase/mechanicsmanager.hpp" -#include "../mwbase/windowmanager.hpp" -#include "../mwbase/dialoguemanager.hpp" #include "../mwbase/soundmanager.hpp" -#include "../mwbase/luamanager.hpp" +#include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" -#include "../mwmechanics/creaturestats.hpp" -#include "../mwmechanics/npcstats.hpp" -#include "../mwmechanics/movement.hpp" -#include "../mwmechanics/spellcasting.hpp" -#include "../mwmechanics/disease.hpp" -#include "../mwmechanics/combat.hpp" -#include "../mwmechanics/autocalcspell.hpp" -#include "../mwmechanics/difficultyscaling.hpp" -#include "../mwmechanics/weapontype.hpp" #include "../mwmechanics/actorutil.hpp" +#include "../mwmechanics/aisetting.hpp" +#include "../mwmechanics/autocalcspell.hpp" +#include "../mwmechanics/combat.hpp" #include "../mwmechanics/creaturecustomdataresetter.hpp" +#include "../mwmechanics/creaturestats.hpp" +#include "../mwmechanics/difficultyscaling.hpp" +#include "../mwmechanics/disease.hpp" #include "../mwmechanics/inventory.hpp" -#include "../mwmechanics/aisetting.hpp" +#include "../mwmechanics/movement.hpp" +#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/setbaseaisetting.hpp" +#include "../mwmechanics/spellcasting.hpp" +#include "../mwmechanics/weapontype.hpp" -#include "../mwworld/ptr.hpp" -#include "../mwworld/actiontalk.hpp" #include "../mwworld/actionopen.hpp" +#include "../mwworld/actiontalk.hpp" +#include "../mwworld/cellstore.hpp" +#include "../mwworld/customdata.hpp" +#include "../mwworld/esmstore.hpp" #include "../mwworld/failedaction.hpp" #include "../mwworld/inventorystore.hpp" -#include "../mwworld/customdata.hpp" -#include "../mwworld/cellstore.hpp" #include "../mwworld/localscripts.hpp" -#include "../mwworld/esmstore.hpp" +#include "../mwworld/ptr.hpp" +#include "../mwrender/npcanimation.hpp" #include "../mwrender/objects.hpp" #include "../mwrender/renderinginterface.hpp" -#include "../mwrender/npcanimation.hpp" #include "../mwgui/tooltips.hpp" #include "../mwgui/ustring.hpp" @@ -62,59 +61,59 @@ namespace { - int is_even(double d) { + int is_even(double d) + { double int_part; modf(d / 2.0, &int_part); return 2.0 * int_part == d; } - int round_ieee_754(double d) { + int round_ieee_754(double d) + { double i = floor(d); d -= i; - if(d < 0.5) + if (d < 0.5) return static_cast(i); - if(d > 0.5) + if (d > 0.5) return static_cast(i) + 1; - if(is_even(i)) + if (is_even(i)) return static_cast(i); return static_cast(i) + 1; } - void autoCalculateAttributes (const ESM::NPC* npc, MWMechanics::CreatureStats& creatureStats) + void autoCalculateAttributes(const ESM::NPC* npc, MWMechanics::CreatureStats& creatureStats) { // race bonus - const ESM::Race *race = - MWBase::Environment::get().getWorld()->getStore().get().find(npc->mRace); + const ESM::Race* race = MWBase::Environment::get().getWorld()->getStore().get().find(npc->mRace); bool male = (npc->mFlags & ESM::NPC::Female) == 0; int level = creatureStats.getLevel(); - for (int i=0; imData.mAttributeValues[i]; creatureStats.setAttribute(i, male ? attribute.mMale : attribute.mFemale); } // class bonus - const ESM::Class *class_ = - MWBase::Environment::get().getWorld()->getStore().get().find(npc->mClass); + const ESM::Class* class_ + = MWBase::Environment::get().getWorld()->getStore().get().find(npc->mClass); - for (int i=0; i<2; ++i) + for (int i = 0; i < 2; ++i) { int attribute = class_->mData.mAttribute[i]; - if (attribute>=0 && attribute<8) + if (attribute >= 0 && attribute < 8) { - creatureStats.setAttribute(attribute, - creatureStats.getAttribute(attribute).getBase() + 10); + creatureStats.setAttribute(attribute, creatureStats.getAttribute(attribute).getBase() + 10); } } // skill bonus - for (int attribute=0; attribute < ESM::Attribute::Length; ++attribute) + for (int attribute = 0; attribute < ESM::Attribute::Length; ++attribute) { float modifierSum = 0; - for (int j=0; jgetStore().get().find(j); @@ -122,22 +121,22 @@ namespace continue; // is this a minor or major skill? - float add=0.2f; - for (int k=0; k<5; ++k) + float add = 0.2f; + for (int k = 0; k < 5; ++k) { if (class_->mData.mSkills[k][0] == j) - add=0.5; + add = 0.5; } - for (int k=0; k<5; ++k) + for (int k = 0; k < 5; ++k) { if (class_->mData.mSkills[k][1] == j) - add=1.0; + add = 1.0; } modifierSum += add; } - creatureStats.setAttribute(attribute, std::min( - round_ieee_754(creatureStats.getAttribute(attribute).getBase() - + (level-1) * modifierSum), 100) ); + creatureStats.setAttribute(attribute, + std::min( + round_ieee_754(creatureStats.getAttribute(attribute).getBase() + (level - 1) * modifierSum), 100)); } // initial health @@ -172,26 +171,26 @@ namespace * * and by adding class, race, specialization bonus. */ - void autoCalculateSkills(const ESM::NPC* npc, MWMechanics::NpcStats& npcStats, const MWWorld::Ptr& ptr, bool spellsInitialised) + void autoCalculateSkills( + const ESM::NPC* npc, MWMechanics::NpcStats& npcStats, const MWWorld::Ptr& ptr, bool spellsInitialised) { - const ESM::Class *class_ = - MWBase::Environment::get().getWorld()->getStore().get().find(npc->mClass); + const ESM::Class* class_ + = MWBase::Environment::get().getWorld()->getStore().get().find(npc->mClass); unsigned int level = npcStats.getLevel(); - const ESM::Race *race = MWBase::Environment::get().getWorld()->getStore().get().find(npc->mRace); - + const ESM::Race* race = MWBase::Environment::get().getWorld()->getStore().get().find(npc->mRace); for (int i = 0; i < 2; ++i) { - int bonus = (i==0) ? 10 : 25; + int bonus = (i == 0) ? 10 : 25; for (int i2 = 0; i2 < 5; ++i2) { int index = class_->mData.mSkills[i2][i]; if (index >= 0 && index < ESM::Skill::Length) { - npcStats.getSkill(index).setBase (npcStats.getSkill(index).getBase() + bonus); + npcStats.getSkill(index).setBase(npcStats.getSkill(index).getBase() + bonus); } } } @@ -224,29 +223,26 @@ namespace } // is this skill in the same Specialization as the class? - const ESM::Skill* skill = MWBase::Environment::get().getWorld()->getStore().get().find(skillIndex); + const ESM::Skill* skill + = MWBase::Environment::get().getWorld()->getStore().get().find(skillIndex); if (skill->mData.mSpecialization == class_->mData.mSpecialization) { specMultiplier = 0.5f; specBonus = 5; } - npcStats.getSkill(skillIndex).setBase( - std::min( - round_ieee_754( - npcStats.getSkill(skillIndex).getBase() - + 5 - + raceBonus - + specBonus - +(int(level)-1) * (majorMultiplier + specMultiplier)), 100)); // Must gracefully handle level 0 + npcStats.getSkill(skillIndex) + .setBase(std::min(round_ieee_754(npcStats.getSkill(skillIndex).getBase() + 5 + raceBonus + specBonus + + (int(level) - 1) * (majorMultiplier + specMultiplier)), + 100)); // Must gracefully handle level 0 } int skills[ESM::Skill::Length]; - for (int i=0; i &store = world->getStore().get(); + const MWBase::World* world = MWBase::Environment::get().getWorld(); + const MWWorld::Store& store = world->getStore().get(); gmst.fMinWalkSpeed = store.find("fMinWalkSpeed"); gmst.fMaxWalkSpeed = store.find("fMaxWalkSpeed"); @@ -312,32 +301,32 @@ namespace MWClass gmst.fCombatArmorMinMult = store.find("fCombatArmorMinMult"); return gmst; - } (); + }(); return staticGmst; } - void Npc::ensureCustomData (const MWWorld::Ptr& ptr) const + void Npc::ensureCustomData(const MWWorld::Ptr& ptr) const { if (!ptr.getRefData().getCustomData()) { bool recalculate = false; auto tempData = std::make_unique(); NpcCustomData* data = tempData.get(); - MWMechanics::CreatureCustomDataResetter resetter {ptr}; + MWMechanics::CreatureCustomDataResetter resetter{ ptr }; ptr.getRefData().setCustomData(std::move(tempData)); - MWWorld::LiveCellRef *ref = ptr.get(); + MWWorld::LiveCellRef* ref = ptr.get(); bool spellsInitialised = data->mNpcStats.getSpells().setSpells(ref->mBase->mId); // creature stats - int gold=0; - if(ref->mBase->mNpdtType != ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS) + int gold = 0; + if (ref->mBase->mNpdtType != ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS) { gold = ref->mBase->mNpdt.mGold; - for (unsigned int i=0; i< ESM::Skill::Length; ++i) - data->mNpcStats.getSkill (i).setBase (ref->mBase->mNpdt.mSkills[i]); + for (unsigned int i = 0; i < ESM::Skill::Length; ++i) + data->mNpcStats.getSkill(i).setBase(ref->mBase->mNpdt.mSkills[i]); data->mNpcStats.setAttribute(ESM::Attribute::Strength, ref->mBase->mNpdt.mStrength); data->mNpcStats.setAttribute(ESM::Attribute::Intelligence, ref->mBase->mNpdt.mIntelligence); @@ -348,9 +337,9 @@ namespace MWClass data->mNpcStats.setAttribute(ESM::Attribute::Personality, ref->mBase->mNpdt.mPersonality); data->mNpcStats.setAttribute(ESM::Attribute::Luck, ref->mBase->mNpdt.mLuck); - data->mNpcStats.setHealth (ref->mBase->mNpdt.mHealth); - data->mNpcStats.setMagicka (ref->mBase->mNpdt.mMana); - data->mNpcStats.setFatigue (ref->mBase->mNpdt.mFatigue); + data->mNpcStats.setHealth(ref->mBase->mNpdt.mHealth); + data->mNpcStats.setMagicka(ref->mBase->mNpdt.mMana); + data->mNpcStats.setFatigue(ref->mBase->mNpdt.mFatigue); data->mNpcStats.setLevel(ref->mBase->mNpdt.mLevel); data->mNpcStats.setBaseDisposition(ref->mBase->mNpdt.mDisposition); @@ -360,8 +349,8 @@ namespace MWClass { gold = ref->mBase->mNpdt.mGold; - for (int i=0; i<3; ++i) - data->mNpcStats.setDynamic (i, 10); + for (int i = 0; i < 3; ++i) + data->mNpcStats.setDynamic(i, 10); data->mNpcStats.setLevel(ref->mBase->mNpdt.mLevel); data->mNpcStats.setBaseDisposition(ref->mBase->mNpdt.mDisposition); @@ -378,18 +367,28 @@ namespace MWClass data->mNpcStats.setDeathAnimationFinished(isPersistent(ptr)); // race powers - const ESM::Race *race = MWBase::Environment::get().getWorld()->getStore().get().find(ref->mBase->mRace); + const ESM::Race* race + = MWBase::Environment::get().getWorld()->getStore().get().find(ref->mBase->mRace); data->mNpcStats.getSpells().addAllToInstance(race->mPowers.mList); if (!ref->mBase->mFaction.empty()) { - static const int iAutoRepFacMod = MWBase::Environment::get().getWorld()->getStore().get() - .find("iAutoRepFacMod")->mValue.getInteger(); - static const int iAutoRepLevMod = MWBase::Environment::get().getWorld()->getStore().get() - .find("iAutoRepLevMod")->mValue.getInteger(); + static const int iAutoRepFacMod = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("iAutoRepFacMod") + ->mValue.getInteger(); + static const int iAutoRepLevMod = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("iAutoRepLevMod") + ->mValue.getInteger(); int rank = ref->mBase->getFactionRank(); - data->mNpcStats.setReputation(iAutoRepFacMod * (rank+1) + iAutoRepLevMod * (data->mNpcStats.getLevel()-1)); + data->mNpcStats.setReputation( + iAutoRepFacMod * (rank + 1) + iAutoRepLevMod * (data->mNpcStats.getLevel() - 1)); } data->mNpcStats.getAiSequence().fill(ref->mBase->mAiPackage); @@ -407,7 +406,7 @@ namespace MWClass // store resetter.mPtr = {}; - if(recalculate) + if (recalculate) data->mNpcStats.recalculateMagicka(); // inventory @@ -419,34 +418,37 @@ namespace MWClass } } - void Npc::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const + void Npc::insertObjectRendering( + const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const { renderingInterface.getObjects().insertNPC(ptr); } - bool Npc::isPersistent(const MWWorld::ConstPtr &actor) const + bool Npc::isPersistent(const MWWorld::ConstPtr& actor) const { const MWWorld::LiveCellRef* ref = actor.get(); return (ref->mBase->mRecordFlags & ESM::FLAG_Persistent) != 0; } - std::string Npc::getModel(const MWWorld::ConstPtr &ptr) const + std::string Npc::getModel(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); std::string model = Settings::Manager::getString("baseanim", "Models"); - const ESM::Race* race = MWBase::Environment::get().getWorld()->getStore().get().find(ref->mBase->mRace); - if(race->mData.mFlags & ESM::Race::Beast) + const ESM::Race* race + = MWBase::Environment::get().getWorld()->getStore().get().find(ref->mBase->mRace); + if (race->mData.mFlags & ESM::Race::Beast) model = Settings::Manager::getString("baseanimkna", "Models"); return model; } - void Npc::getModelsToPreload(const MWWorld::Ptr &ptr, std::vector &models) const + void Npc::getModelsToPreload(const MWWorld::Ptr& ptr, std::vector& models) const { - const MWWorld::LiveCellRef *npc = ptr.get(); - const ESM::Race* race = MWBase::Environment::get().getWorld()->getStore().get().search(npc->mBase->mRace); - if(race && race->mData.mFlags & ESM::Race::Beast) + const MWWorld::LiveCellRef* npc = ptr.get(); + const ESM::Race* race + = MWBase::Environment::get().getWorld()->getStore().get().search(npc->mBase->mRace); + if (race && race->mData.mFlags & ESM::Race::Beast) models.emplace_back(Settings::Manager::getString("baseanimkna", "Models")); // keep these always loaded just in case @@ -461,13 +463,15 @@ namespace MWClass if (!npc->mBase->mHead.empty()) { - const ESM::BodyPart* head = MWBase::Environment::get().getWorld()->getStore().get().search(npc->mBase->mHead); + const ESM::BodyPart* head + = MWBase::Environment::get().getWorld()->getStore().get().search(npc->mBase->mHead); if (head) models.push_back(Misc::ResourceHelpers::correctMeshPath(head->mModel, vfs)); } if (!npc->mBase->mHair.empty()) { - const ESM::BodyPart* hair = MWBase::Environment::get().getWorld()->getStore().get().search(npc->mBase->mHair); + const ESM::BodyPart* hair + = MWBase::Environment::get().getWorld()->getStore().get().search(npc->mBase->mHair); if (hair) models.push_back(Misc::ResourceHelpers::correctMeshPath(hair->mModel, vfs)); } @@ -483,14 +487,14 @@ namespace MWClass if (equipped != invStore.end()) { std::vector parts; - if(equipped->getType() == ESM::Clothing::sRecordId) + if (equipped->getType() == ESM::Clothing::sRecordId) { - const ESM::Clothing *clothes = equipped->get()->mBase; + const ESM::Clothing* clothes = equipped->get()->mBase; parts = clothes->mParts.mParts; } - else if(equipped->getType() == ESM::Armor::sRecordId) + else if (equipped->getType() == ESM::Armor::sRecordId) { - const ESM::Armor *armor = equipped->get()->mBase; + const ESM::Armor* armor = equipped->get()->mBase; parts = armor->mParts.mParts; } else @@ -505,7 +509,8 @@ namespace MWClass std::string_view partname = female ? it->mFemale : it->mMale; if (partname.empty()) partname = female ? it->mMale : it->mFemale; - const ESM::BodyPart* part = MWBase::Environment::get().getWorld()->getStore().get().search(partname); + const ESM::BodyPart* part + = MWBase::Environment::get().getWorld()->getStore().get().search(partname); if (part && !part->mModel.empty()) models.push_back(Misc::ResourceHelpers::correctMeshPath(part->mModel, vfs)); } @@ -515,7 +520,8 @@ namespace MWClass // preload body parts if (race) { - const std::vector& parts = MWRender::NpcAnimation::getBodyParts(Misc::StringUtils::lowerCase(race->mId), female, false, false); + const std::vector& parts + = MWRender::NpcAnimation::getBodyParts(Misc::StringUtils::lowerCase(race->mId), female, false, false); for (std::vector::const_iterator it = parts.begin(); it != parts.end(); ++it) { const ESM::BodyPart* part = *it; @@ -523,60 +529,60 @@ namespace MWClass models.push_back(Misc::ResourceHelpers::correctMeshPath(part->mModel, vfs)); } } - } std::string_view Npc::getName(const MWWorld::ConstPtr& ptr) const { - if(ptr.getRefData().getCustomData() && ptr.getRefData().getCustomData()->asNpcCustomData().mNpcStats.isWerewolf()) + if (ptr.getRefData().getCustomData() + && ptr.getRefData().getCustomData()->asNpcCustomData().mNpcStats.isWerewolf()) { - const MWBase::World *world = MWBase::Environment::get().getWorld(); - const MWWorld::Store &store = world->getStore().get(); + const MWBase::World* world = MWBase::Environment::get().getWorld(); + const MWWorld::Store& store = world->getStore().get(); return store.find("sWerewolfPopup")->mValue.getString(); } - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); const std::string& name = ref->mBase->mName; return !name.empty() ? name : ref->mBase->mId; } - MWMechanics::CreatureStats& Npc::getCreatureStats (const MWWorld::Ptr& ptr) const + MWMechanics::CreatureStats& Npc::getCreatureStats(const MWWorld::Ptr& ptr) const { - ensureCustomData (ptr); + ensureCustomData(ptr); return ptr.getRefData().getCustomData()->asNpcCustomData().mNpcStats; } - MWMechanics::NpcStats& Npc::getNpcStats (const MWWorld::Ptr& ptr) const + MWMechanics::NpcStats& Npc::getNpcStats(const MWWorld::Ptr& ptr) const { - ensureCustomData (ptr); + ensureCustomData(ptr); return ptr.getRefData().getCustomData()->asNpcCustomData().mNpcStats; } - bool Npc::evaluateHit(const MWWorld::Ptr& ptr, MWWorld::Ptr& victim, osg::Vec3f& hitPosition) const { victim = MWWorld::Ptr(); hitPosition = osg::Vec3f(); // Get the weapon used (if hand-to-hand, weapon = inv.end()) - MWWorld::InventoryStore &inv = getInventoryStore(ptr); + MWWorld::InventoryStore& inv = getInventoryStore(ptr); MWWorld::ContainerStoreIterator weaponslot = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); MWWorld::Ptr weapon; if (weaponslot != inv.end() && weaponslot->getType() == ESM::Weapon::sRecordId) weapon = *weaponslot; - MWBase::World *world = MWBase::Environment::get().getWorld(); - const MWWorld::Store &store = world->getStore().get(); + MWBase::World* world = MWBase::Environment::get().getWorld(); + const MWWorld::Store& store = world->getStore().get(); const float fCombatDistance = store.find("fCombatDistance")->mValue.getFloat(); - float dist = fCombatDistance * (!weapon.isEmpty() ? - weapon.get()->mBase->mData.mReach : - store.find("fHandToHandReach")->mValue.getFloat()); + float dist = fCombatDistance + * (!weapon.isEmpty() ? weapon.get()->mBase->mData.mReach + : store.find("fHandToHandReach")->mValue.getFloat()); - // For AI actors, get combat targets to use in the ray cast. Only those targets will return a positive hit result. + // For AI actors, get combat targets to use in the ray cast. Only those targets will return a positive hit + // result. std::vector targetActors; if (ptr != MWMechanics::getPlayer()) getCreatureStats(ptr).getAiSequence().getCombatTargets(targetActors); @@ -586,11 +592,11 @@ namespace MWClass if (result.first.isEmpty()) // Didn't hit anything return true; - const MWWorld::Class &othercls = result.first.getClass(); + const MWWorld::Class& othercls = result.first.getClass(); if (!othercls.isActor()) // Can't hit non-actors return true; - MWMechanics::CreatureStats &otherstats = othercls.getCreatureStats(result.first); + MWMechanics::CreatureStats& otherstats = othercls.getCreatureStats(result.first); if (otherstats.isDead()) // Can't hit dead actors return true; @@ -608,9 +614,10 @@ namespace MWClass return Misc::Rng::roll0to99(world->getPrng()) < hitchance; } - void Npc::hit(const MWWorld::Ptr& ptr, float attackStrength, int type, const MWWorld::Ptr& victim, const osg::Vec3f& hitPosition, bool success) const + void Npc::hit(const MWWorld::Ptr& ptr, float attackStrength, int type, const MWWorld::Ptr& victim, + const osg::Vec3f& hitPosition, bool success) const { - MWWorld::InventoryStore &inv = getInventoryStore(ptr); + MWWorld::InventoryStore& inv = getInventoryStore(ptr); MWWorld::ContainerStoreIterator weaponslot = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); MWWorld::Ptr weapon; if (weaponslot != inv.end() && weaponslot->getType() == ESM::Weapon::sRecordId) @@ -618,15 +625,15 @@ namespace MWClass MWMechanics::applyFatigueLoss(ptr, weapon, attackStrength); - if(victim.isEmpty()) // Didn't hit anything + if (victim.isEmpty()) // Didn't hit anything return; - const MWWorld::Class &othercls = victim.getClass(); - MWMechanics::CreatureStats &otherstats = othercls.getCreatureStats(victim); + const MWWorld::Class& othercls = victim.getClass(); + MWMechanics::CreatureStats& otherstats = othercls.getCreatureStats(victim); if (otherstats.isDead()) // Can't hit dead actors return; - if(ptr == MWMechanics::getPlayer()) + if (ptr == MWMechanics::getPlayer()) MWBase::Environment::get().getWindowManager()->setEnemy(victim); if (!success) @@ -638,18 +645,18 @@ namespace MWClass bool healthdmg; float damage = 0.0f; - if(!weapon.isEmpty()) + if (!weapon.isEmpty()) { - const unsigned char *attack = nullptr; - if(type == ESM::Weapon::AT_Chop) + const unsigned char* attack = nullptr; + if (type == ESM::Weapon::AT_Chop) attack = weapon.get()->mBase->mData.mChop; - else if(type == ESM::Weapon::AT_Slash) + else if (type == ESM::Weapon::AT_Slash) attack = weapon.get()->mBase->mData.mSlash; - else if(type == ESM::Weapon::AT_Thrust) + else if (type == ESM::Weapon::AT_Thrust) attack = weapon.get()->mBase->mData.mThrust; - if(attack) + if (attack) { - damage = attack[0] + ((attack[1]-attack[0])*attackStrength); + damage = attack[0] + ((attack[1] - attack[0]) * attackStrength); } MWMechanics::adjustWeaponDamage(damage, weapon, ptr); MWMechanics::reduceWeaponCondition(damage, true, weapon, ptr); @@ -662,21 +669,21 @@ namespace MWClass MWMechanics::getHandToHandDamage(ptr, victim, damage, healthdmg, attackStrength); } - MWBase::World *world = MWBase::Environment::get().getWorld(); - const MWWorld::Store &store = world->getStore().get(); + MWBase::World* world = MWBase::Environment::get().getWorld(); + const MWWorld::Store& store = world->getStore().get(); - if(ptr == MWMechanics::getPlayer()) + if (ptr == MWMechanics::getPlayer()) { int weapskill = ESM::Skill::HandToHand; - if(!weapon.isEmpty()) + if (!weapon.isEmpty()) weapskill = weapon.getClass().getEquipmentSkill(weapon); skillUsageSucceeded(ptr, weapskill, 0); const MWMechanics::AiSequence& seq = victim.getClass().getCreatureStats(victim).getAiSequence(); - bool unaware = !seq.isInCombat() - && !MWBase::Environment::get().getMechanicsManager()->awarenessCheck(ptr, victim); - if(unaware) + bool unaware + = !seq.isInCombat() && !MWBase::Environment::get().getMechanicsManager()->awarenessCheck(ptr, victim); + if (unaware) { damage *= store.find("fCombatCriticalStrikeMult")->mValue.getFloat(); MWBase::Environment::get().getWindowManager()->messageBox("#{sTargetCriticalStrike}"); @@ -703,9 +710,10 @@ namespace MWClass othercls.onHit(victim, damage, healthdmg, weapon, ptr, hitPosition, true); } - void Npc::onHit(const MWWorld::Ptr &ptr, float damage, bool ishealth, const MWWorld::Ptr &object, const MWWorld::Ptr &attacker, const osg::Vec3f &hitPosition, bool successful) const + void Npc::onHit(const MWWorld::Ptr& ptr, float damage, bool ishealth, const MWWorld::Ptr& object, + const MWWorld::Ptr& attacker, const osg::Vec3f& hitPosition, bool successful) const { - MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); + MWBase::SoundManager* sndMgr = MWBase::Environment::get().getSoundManager(); MWMechanics::CreatureStats& stats = getCreatureStats(ptr); bool wasDead = stats.isDead(); @@ -725,14 +733,12 @@ namespace MWClass MWMechanics::CreatureStats& statsAttacker = attacker.getClass().getCreatureStats(attacker); // First handle the attacked actor if ((stats.getHitAttemptActorId() == -1) - && (statsAttacker.getAiSequence().isInCombat(ptr) - || attacker == MWMechanics::getPlayer())) + && (statsAttacker.getAiSequence().isInCombat(ptr) || attacker == MWMechanics::getPlayer())) stats.setHitAttemptActorId(statsAttacker.getActorId()); // Next handle the attacking actor if ((statsAttacker.getHitAttemptActorId() == -1) - && (statsAttacker.getAiSequence().isInCombat(ptr) - || attacker == MWMechanics::getPlayer())) + && (statsAttacker.getAiSequence().isInCombat(ptr) || attacker == MWMechanics::getPlayer())) statsAttacker.setHitAttemptActorId(stats.getActorId()); } @@ -743,7 +749,7 @@ namespace MWClass { std::string_view script = getScript(ptr); /* Set the OnPCHitMe script variable. The script is responsible for clearing it. */ - if(!script.empty()) + if (!script.empty()) ptr.getRefData().getLocals().setVarByInt(script, "onpchitme", 1); } @@ -758,7 +764,6 @@ namespace MWClass if (!object.isEmpty()) stats.setLastHitObject(object.getCellRef().getRefId()); - if (damage > 0.0f && !object.isEmpty()) MWMechanics::resistNormalWeapon(ptr, attacker, object, damage); @@ -775,18 +780,20 @@ namespace MWClass // 'ptr' is losing health. Play a 'hit' voiced dialog entry if not already saying // something, alert the character controller, scripts, etc. - const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); const GMST& gmst = getGmst(); - int chance = store.get().find("iVoiceHitOdds")->mValue.getInteger(); + int chance = store.get().find("iVoiceHitOdds")->mValue.getInteger(); auto& prng = MWBase::Environment::get().getWorld()->getPrng(); if (Misc::Rng::roll0to99(prng) < chance) MWBase::Environment::get().getDialogueManager()->say(ptr, "hit"); // Check for knockdown - float agilityTerm = stats.getAttribute(ESM::Attribute::Agility).getModified() * gmst.fKnockDownMult->mValue.getFloat(); + float agilityTerm + = stats.getAttribute(ESM::Attribute::Agility).getModified() * gmst.fKnockDownMult->mValue.getFloat(); float knockdownTerm = stats.getAttribute(ESM::Attribute::Agility).getModified() - * gmst.iKnockDownOddsMult->mValue.getInteger() * 0.01f + gmst.iKnockDownOddsBase->mValue.getInteger(); + * gmst.iKnockDownOddsMult->mValue.getInteger() * 0.01f + + gmst.iKnockDownOddsBase->mValue.getInteger(); if (ishealth && agilityTerm <= damage && knockdownTerm <= Misc::Rng::roll0to99(prng)) stats.setKnockedDown(true); else @@ -798,18 +805,17 @@ namespace MWClass // cuirass = 30% // shield, helmet, greaves, boots, pauldrons = 10% each // guantlets = 5% each - static const int hitslots[20] = { - MWWorld::InventoryStore::Slot_Cuirass, MWWorld::InventoryStore::Slot_Cuirass, - MWWorld::InventoryStore::Slot_Cuirass, MWWorld::InventoryStore::Slot_Cuirass, - MWWorld::InventoryStore::Slot_Cuirass, MWWorld::InventoryStore::Slot_Cuirass, - MWWorld::InventoryStore::Slot_CarriedLeft, MWWorld::InventoryStore::Slot_CarriedLeft, - MWWorld::InventoryStore::Slot_Helmet, MWWorld::InventoryStore::Slot_Helmet, - MWWorld::InventoryStore::Slot_Greaves, MWWorld::InventoryStore::Slot_Greaves, - MWWorld::InventoryStore::Slot_Boots, MWWorld::InventoryStore::Slot_Boots, - MWWorld::InventoryStore::Slot_LeftPauldron, MWWorld::InventoryStore::Slot_LeftPauldron, - MWWorld::InventoryStore::Slot_RightPauldron, MWWorld::InventoryStore::Slot_RightPauldron, - MWWorld::InventoryStore::Slot_LeftGauntlet, MWWorld::InventoryStore::Slot_RightGauntlet - }; + static const int hitslots[20] + = { MWWorld::InventoryStore::Slot_Cuirass, MWWorld::InventoryStore::Slot_Cuirass, + MWWorld::InventoryStore::Slot_Cuirass, MWWorld::InventoryStore::Slot_Cuirass, + MWWorld::InventoryStore::Slot_Cuirass, MWWorld::InventoryStore::Slot_Cuirass, + MWWorld::InventoryStore::Slot_CarriedLeft, MWWorld::InventoryStore::Slot_CarriedLeft, + MWWorld::InventoryStore::Slot_Helmet, MWWorld::InventoryStore::Slot_Helmet, + MWWorld::InventoryStore::Slot_Greaves, MWWorld::InventoryStore::Slot_Greaves, + MWWorld::InventoryStore::Slot_Boots, MWWorld::InventoryStore::Slot_Boots, + MWWorld::InventoryStore::Slot_LeftPauldron, MWWorld::InventoryStore::Slot_LeftPauldron, + MWWorld::InventoryStore::Slot_RightPauldron, MWWorld::InventoryStore::Slot_RightPauldron, + MWWorld::InventoryStore::Slot_LeftGauntlet, MWWorld::InventoryStore::Slot_RightGauntlet }; int hitslot = hitslots[Misc::Rng::rollDice(20, prng)]; float unmitigatedDamage = damage; @@ -819,7 +825,7 @@ namespace MWClass damage = std::max(1.f, damage); damageDiff = std::max(1, damageDiff); - MWWorld::InventoryStore &inv = getInventoryStore(ptr); + MWWorld::InventoryStore& inv = getInventoryStore(ptr); MWWorld::ContainerStoreIterator armorslot = inv.getSlot(hitslot); MWWorld::Ptr armor = ((armorslot != inv.end()) ? *armorslot : MWWorld::Ptr()); bool hasArmor = !armor.isEmpty() && armor.getType() == ESM::Armor::sRecordId; @@ -839,12 +845,12 @@ namespace MWClass } if (hasArmor) { - static const bool creatureDamage = Settings::Manager::getBool("unarmed creature attacks damage armor", "Game"); + static const bool creatureDamage + = Settings::Manager::getBool("unarmed creature attacks damage armor", "Game"); - if (!object.isEmpty() || - attacker.isEmpty() || - attacker.getClass().isNpc() || - creatureDamage) // Unarmed creature attacks don't affect armor condition unless it was explicitly requested. + if (!object.isEmpty() || attacker.isEmpty() || attacker.getClass().isNpc() + || creatureDamage) // Unarmed creature attacks don't affect armor condition unless it was + // explicitly requested. { int armorhealth = armor.getClass().getItemHealth(armor); armorhealth -= std::min(damageDiff, armorhealth); @@ -858,7 +864,7 @@ namespace MWClass if (ptr == MWMechanics::getPlayer()) skillUsageSucceeded(ptr, armor.getClass().getEquipmentSkill(armor), 0); - switch(armor.getClass().getEquipmentSkill(armor)) + switch (armor.getClass().getEquipmentSkill(armor)) { case ESM::Skill::LightArmor: sndMgr->playSound3D(ptr, "Light Armor Hit", 1.0f, 1.0f); @@ -871,7 +877,7 @@ namespace MWClass break; } } - else if(ptr == MWMechanics::getPlayer()) + else if (ptr == MWMechanics::getPlayer()) skillUsageSucceeded(ptr, ESM::Skill::Unarmored, 0); } } @@ -903,7 +909,8 @@ namespace MWClass if (!wasDead && getCreatureStats(ptr).isDead()) { // NPC was killed - if (!attacker.isEmpty() && attacker.getClass().isNpc() && attacker.getClass().getNpcStats(attacker).isWerewolf()) + if (!attacker.isEmpty() && attacker.getClass().isNpc() + && attacker.getClass().getNpcStats(attacker).isWerewolf()) { attacker.getClass().getNpcStats(attacker).addWerewolfKill(); } @@ -912,38 +919,38 @@ namespace MWClass } } - std::unique_ptr Npc::activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const + std::unique_ptr Npc::activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const { // player got activated by another NPC - if(ptr == MWMechanics::getPlayer()) + if (ptr == MWMechanics::getPlayer()) return std::make_unique(actor); // Werewolfs can't activate NPCs - if(actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf()) + if (actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf()) { - const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); auto& prng = MWBase::Environment::get().getWorld()->getPrng(); - const ESM::Sound *sound = store.get().searchRandom("WolfNPC", prng); + const ESM::Sound* sound = store.get().searchRandom("WolfNPC", prng); std::unique_ptr action = std::make_unique("#{sWerewolfRefusal}"); - if(sound) action->setSound(sound->mId); + if (sound) + action->setSound(sound->mId); return action; } const MWMechanics::CreatureStats& stats = getCreatureStats(ptr); - if(stats.isDead()) + if (stats.isDead()) { - bool canLoot = Settings::Manager::getBool ("can loot during death animation", "Game"); + bool canLoot = Settings::Manager::getBool("can loot during death animation", "Game"); // by default user can loot friendly actors during death animation if (canLoot && !stats.getAiSequence().isInCombat()) return std::make_unique(ptr); // otherwise wait until death animation - if(stats.isDeathAnimationFinished()) + if (stats.isDeathAnimationFinished()) return std::make_unique(ptr); } else if (!stats.getAiSequence().isInCombat()) @@ -957,7 +964,8 @@ namespace MWClass } else // In combat { - const bool stealingInCombat = Settings::Manager::getBool ("always allow stealing from knocked out actors", "Game"); + const bool stealingInCombat + = Settings::Manager::getBool("always allow stealing from knocked out actors", "Game"); if (stealingInCombat && stats.getKnockedDown()) return std::make_unique(ptr); // stealing } @@ -969,25 +977,23 @@ namespace MWClass return std::make_unique(); } - MWWorld::ContainerStore& Npc::getContainerStore (const MWWorld::Ptr& ptr) - const + MWWorld::ContainerStore& Npc::getContainerStore(const MWWorld::Ptr& ptr) const { - ensureCustomData (ptr); + ensureCustomData(ptr); return ptr.getRefData().getCustomData()->asNpcCustomData().mInventoryStore; } - MWWorld::InventoryStore& Npc::getInventoryStore (const MWWorld::Ptr& ptr) - const + MWWorld::InventoryStore& Npc::getInventoryStore(const MWWorld::Ptr& ptr) const { - ensureCustomData (ptr); + ensureCustomData(ptr); return ptr.getRefData().getCustomData()->asNpcCustomData().mInventoryStore; } std::string_view Npc::getScript(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mScript; } @@ -1001,10 +1007,10 @@ namespace MWClass if ((!godmode && stats.isParalyzed()) || stats.getKnockedDown() || stats.isDead()) return 0.f; - const MWBase::World *world = MWBase::Environment::get().getWorld(); + const MWBase::World* world = MWBase::Environment::get().getWorld(); const GMST& gmst = getGmst(); - const MWMechanics::MagicEffects &mageffects = stats.getMagicEffects(); + const MWMechanics::MagicEffects& mageffects = stats.getMagicEffects(); const float normalizedEncumbrance = getNormalizedEncumbrance(ptr); @@ -1015,14 +1021,15 @@ namespace MWClass running = running && (inair || MWBase::Environment::get().getMechanicsManager()->isRunning(ptr)); float moveSpeed; - if(getEncumbrance(ptr) > getCapacity(ptr)) + if (getEncumbrance(ptr) > getCapacity(ptr)) moveSpeed = 0.0f; - else if(mageffects.get(ESM::MagicEffect::Levitate).getMagnitude() > 0 && - world->isLevitationEnabled()) + else if (mageffects.get(ESM::MagicEffect::Levitate).getMagnitude() > 0 && world->isLevitationEnabled()) { - float flySpeed = 0.01f*(stats.getAttribute(ESM::Attribute::Speed).getModified() + - mageffects.get(ESM::MagicEffect::Levitate).getMagnitude()); - flySpeed = gmst.fMinFlySpeed->mValue.getFloat() + flySpeed*(gmst.fMaxFlySpeed->mValue.getFloat() - gmst.fMinFlySpeed->mValue.getFloat()); + float flySpeed = 0.01f + * (stats.getAttribute(ESM::Attribute::Speed).getModified() + + mageffects.get(ESM::MagicEffect::Levitate).getMagnitude()); + flySpeed = gmst.fMinFlySpeed->mValue.getFloat() + + flySpeed * (gmst.fMaxFlySpeed->mValue.getFloat() - gmst.fMinFlySpeed->mValue.getFloat()); flySpeed *= 1.0f - gmst.fEncumberedMoveEffect->mValue.getFloat() * normalizedEncumbrance; flySpeed = std::max(0.0f, flySpeed); moveSpeed = flySpeed; @@ -1034,15 +1041,15 @@ namespace MWClass else moveSpeed = getWalkSpeed(ptr); - if(stats.isWerewolf() && running && stats.getDrawState() == MWMechanics::DrawState::Nothing) + if (stats.isWerewolf() && running && stats.getDrawState() == MWMechanics::DrawState::Nothing) moveSpeed *= gmst.fWereWolfRunMult->mValue.getFloat(); return moveSpeed; } - float Npc::getJump(const MWWorld::Ptr &ptr) const + float Npc::getJump(const MWWorld::Ptr& ptr) const { - if(getEncumbrance(ptr) > getCapacity(ptr)) + if (getEncumbrance(ptr) > getCapacity(ptr)) return 0.f; const MWMechanics::NpcStats& stats = getNpcStats(ptr); @@ -1052,25 +1059,24 @@ namespace MWClass const GMST& gmst = getGmst(); const MWMechanics::MagicEffects& mageffects = stats.getMagicEffects(); - const float encumbranceTerm = gmst.fJumpEncumbranceBase->mValue.getFloat() + - gmst.fJumpEncumbranceMultiplier->mValue.getFloat() * - (1.0f - Npc::getNormalizedEncumbrance(ptr)); + const float encumbranceTerm = gmst.fJumpEncumbranceBase->mValue.getFloat() + + gmst.fJumpEncumbranceMultiplier->mValue.getFloat() * (1.0f - Npc::getNormalizedEncumbrance(ptr)); float a = getSkill(ptr, ESM::Skill::Acrobatics); float b = 0.0f; - if(a > 50.0f) + if (a > 50.0f) { b = a - 50.0f; a = 50.0f; } - float x = gmst.fJumpAcrobaticsBase->mValue.getFloat() + - std::pow(a / 15.0f, gmst.fJumpAcroMultiplier->mValue.getFloat()); + float x = gmst.fJumpAcrobaticsBase->mValue.getFloat() + + std::pow(a / 15.0f, gmst.fJumpAcroMultiplier->mValue.getFloat()); x += 3.0f * b * gmst.fJumpAcroMultiplier->mValue.getFloat(); x += mageffects.get(ESM::MagicEffect::Jump).getMagnitude() * 64; x *= encumbranceTerm; - if(stats.getStance(MWMechanics::CreatureStats::Stance_Run)) + if (stats.getStance(MWMechanics::CreatureStats::Stance_Run)) x *= gmst.fJumpRunMultiplier->mValue.getFloat(); x *= stats.getFatigueTerm(); x -= -Constants::GravityConst * Constants::UnitsPerMeter; @@ -1079,16 +1085,16 @@ namespace MWClass return x; } - MWMechanics::Movement& Npc::getMovementSettings (const MWWorld::Ptr& ptr) const + MWMechanics::Movement& Npc::getMovementSettings(const MWWorld::Ptr& ptr) const { - ensureCustomData (ptr); + ensureCustomData(ptr); return ptr.getRefData().getCustomData()->asNpcCustomData().mMovement; } - bool Npc::isEssential (const MWWorld::ConstPtr& ptr) const + bool Npc::isEssential(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return (ref->mBase->mFlags & ESM::NPC::Essential) != 0; } @@ -1106,43 +1112,50 @@ namespace MWClass if (!customData.mNpcStats.getAiSequence().isInCombat()) return true; - const bool stealingInCombat = Settings::Manager::getBool ("always allow stealing from knocked out actors", "Game"); + const bool stealingInCombat + = Settings::Manager::getBool("always allow stealing from knocked out actors", "Game"); if (stealingInCombat && customData.mNpcStats.getKnockedDown()) return true; return false; } - MWGui::ToolTipInfo Npc::getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const + MWGui::ToolTipInfo Npc::getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); bool fullHelp = MWBase::Environment::get().getWindowManager()->getFullHelp(); MWGui::ToolTipInfo info; std::string_view name = getName(ptr); info.caption = MyGUI::TextIterator::toTagsString(MWGui::toUString(name)); - if(fullHelp && !ref->mBase->mName.empty() && ptr.getRefData().getCustomData() && ptr.getRefData().getCustomData()->asNpcCustomData().mNpcStats.isWerewolf()) + if (fullHelp && !ref->mBase->mName.empty() && ptr.getRefData().getCustomData() + && ptr.getRefData().getCustomData()->asNpcCustomData().mNpcStats.isWerewolf()) { info.caption += " ("; info.caption += MyGUI::TextIterator::toTagsString(ref->mBase->mName); info.caption += ")"; } - if(fullHelp) + if (fullHelp) info.text = MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); return info; } - float Npc::getCapacity (const MWWorld::Ptr& ptr) const + float Npc::getCapacity(const MWWorld::Ptr& ptr) const { - const MWMechanics::CreatureStats& stats = getCreatureStats (ptr); - static const float fEncumbranceStrMult = MWBase::Environment::get().getWorld()->getStore().get().find("fEncumbranceStrMult")->mValue.getFloat(); - return stats.getAttribute(ESM::Attribute::Strength).getModified()*fEncumbranceStrMult; + const MWMechanics::CreatureStats& stats = getCreatureStats(ptr); + static const float fEncumbranceStrMult = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fEncumbranceStrMult") + ->mValue.getFloat(); + return stats.getAttribute(ESM::Attribute::Strength).getModified() * fEncumbranceStrMult; } - float Npc::getEncumbrance (const MWWorld::Ptr& ptr) const + float Npc::getEncumbrance(const MWWorld::Ptr& ptr) const { // According to UESP, inventory weight is ignored in werewolf form. Does that include // feather and burden effects? @@ -1159,37 +1172,35 @@ namespace MWClass return cast.cast(recordId); } - void Npc::skillUsageSucceeded (const MWWorld::Ptr& ptr, int skill, int usageType, float extraFactor) const + void Npc::skillUsageSucceeded(const MWWorld::Ptr& ptr, int skill, int usageType, float extraFactor) const { - MWMechanics::NpcStats& stats = getNpcStats (ptr); + MWMechanics::NpcStats& stats = getNpcStats(ptr); if (stats.isWerewolf()) return; - MWWorld::LiveCellRef *ref = ptr.get(); + MWWorld::LiveCellRef* ref = ptr.get(); - const ESM::Class *class_ = - MWBase::Environment::get().getWorld()->getStore().get().find ( - ref->mBase->mClass - ); + const ESM::Class* class_ + = MWBase::Environment::get().getWorld()->getStore().get().find(ref->mBase->mClass); - stats.useSkill (skill, *class_, usageType, extraFactor); + stats.useSkill(skill, *class_, usageType, extraFactor); } - float Npc::getArmorRating (const MWWorld::Ptr& ptr) const + float Npc::getArmorRating(const MWWorld::Ptr& ptr) const { - const MWBase::World *world = MWBase::Environment::get().getWorld(); - const MWWorld::Store &store = world->getStore().get(); + const MWBase::World* world = MWBase::Environment::get().getWorld(); + const MWWorld::Store& store = world->getStore().get(); - MWMechanics::NpcStats &stats = getNpcStats(ptr); - const MWWorld::InventoryStore &invStore = getInventoryStore(ptr); + MWMechanics::NpcStats& stats = getNpcStats(ptr); + const MWWorld::InventoryStore& invStore = getInventoryStore(ptr); float fUnarmoredBase1 = store.find("fUnarmoredBase1")->mValue.getFloat(); float fUnarmoredBase2 = store.find("fUnarmoredBase2")->mValue.getFloat(); float unarmoredSkill = getSkill(ptr, ESM::Skill::Unarmored); float ratings[MWWorld::InventoryStore::Slots]; - for(int i = 0;i < MWWorld::InventoryStore::Slots;i++) + for (int i = 0; i < MWWorld::InventoryStore::Slots; i++) { MWWorld::ConstContainerStoreIterator it = invStore.getSlot(i); if (it == invStore.end() || it->getType() != ESM::Armor::sRecordId) @@ -1213,27 +1224,30 @@ namespace MWClass float shield = stats.getMagicEffects().get(ESM::MagicEffect::Shield).getMagnitude(); return ratings[MWWorld::InventoryStore::Slot_Cuirass] * 0.3f - + (ratings[MWWorld::InventoryStore::Slot_CarriedLeft] + ratings[MWWorld::InventoryStore::Slot_Helmet] - + ratings[MWWorld::InventoryStore::Slot_Greaves] + ratings[MWWorld::InventoryStore::Slot_Boots] - + ratings[MWWorld::InventoryStore::Slot_LeftPauldron] + ratings[MWWorld::InventoryStore::Slot_RightPauldron] - ) * 0.1f - + (ratings[MWWorld::InventoryStore::Slot_LeftGauntlet] + ratings[MWWorld::InventoryStore::Slot_RightGauntlet]) - * 0.05f - + shield; + + (ratings[MWWorld::InventoryStore::Slot_CarriedLeft] + ratings[MWWorld::InventoryStore::Slot_Helmet] + + ratings[MWWorld::InventoryStore::Slot_Greaves] + ratings[MWWorld::InventoryStore::Slot_Boots] + + ratings[MWWorld::InventoryStore::Slot_LeftPauldron] + + ratings[MWWorld::InventoryStore::Slot_RightPauldron]) + * 0.1f + + (ratings[MWWorld::InventoryStore::Slot_LeftGauntlet] + + ratings[MWWorld::InventoryStore::Slot_RightGauntlet]) + * 0.05f + + shield; } - void Npc::adjustScale(const MWWorld::ConstPtr &ptr, osg::Vec3f&scale, bool rendering) const + void Npc::adjustScale(const MWWorld::ConstPtr& ptr, osg::Vec3f& scale, bool rendering) const { if (!rendering) return; // collision meshes are not scaled based on race height // having the same collision extents for all races makes the environments easier to test - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); - const ESM::Race* race = - MWBase::Environment::get().getWorld()->getStore().get().find(ref->mBase->mRace); + const ESM::Race* race + = MWBase::Environment::get().getWorld()->getStore().get().find(ref->mBase->mRace); - // Race weight should not affect 1st-person meshes, otherwise it will change hand proportions and can break aiming. + // Race weight should not affect 1st-person meshes, otherwise it will change hand proportions and can break + // aiming. if (ptr == MWMechanics::getPlayer() && ptr.isInCell() && MWBase::Environment::get().getWorld()->isFirstPerson()) { if (ref->mBase->isMale()) @@ -1258,28 +1272,27 @@ namespace MWClass } } - int Npc::getServices(const MWWorld::ConstPtr &actor) const + int Npc::getServices(const MWWorld::ConstPtr& actor) const { return actor.get()->mBase->mAiData.mServices; } - std::string_view Npc::getSoundIdFromSndGen(const MWWorld::Ptr& ptr, std::string_view name) const { - if(name == "left" || name == "right") + if (name == "left" || name == "right") { - MWBase::World *world = MWBase::Environment::get().getWorld(); - if(world->isFlying(ptr)) + MWBase::World* world = MWBase::Environment::get().getWorld(); + if (world->isFlying(ptr)) return {}; osg::Vec3f pos(ptr.getRefData().getPosition().asVec3()); - if(world->isSwimming(ptr)) + if (world->isSwimming(ptr)) return (name == "left") ? "Swim Left" : "Swim Right"; - if(world->isUnderwater(ptr.getCell(), pos) || world->isWalkingOnWater(ptr)) + if (world->isUnderwater(ptr.getCell(), pos) || world->isWalkingOnWater(ptr)) return (name == "left") ? "FootWaterLeft" : "FootWaterRight"; - if(world->isOnGround(ptr)) + if (world->isOnGround(ptr)) { if (getNpcStats(ptr).isWerewolf() - && getCreatureStats(ptr).getStance(MWMechanics::CreatureStats::Stance_Run)) + && getCreatureStats(ptr).getStance(MWMechanics::CreatureStats::Stance_Run)) { int weaponType = ESM::Weapon::None; MWMechanics::getActiveWeapon(ptr, &weaponType); @@ -1287,12 +1300,12 @@ namespace MWClass return {}; } - const MWWorld::InventoryStore &inv = Npc::getInventoryStore(ptr); + const MWWorld::InventoryStore& inv = Npc::getInventoryStore(ptr); MWWorld::ConstContainerStoreIterator boots = inv.getSlot(MWWorld::InventoryStore::Slot_Boots); - if(boots == inv.end() || boots->getType() != ESM::Armor::sRecordId) + if (boots == inv.end() || boots->getType() != ESM::Armor::sRecordId) return (name == "left") ? "FootBareLeft" : "FootBareRight"; - switch(boots->getClass().getEquipmentSkill(*boots)) + switch (boots->getClass().getEquipmentSkill(*boots)) { case ESM::Skill::LightArmor: return (name == "left") ? "FootLightLeft" : "FootLightRight"; @@ -1306,29 +1319,29 @@ namespace MWClass } // Morrowind ignores land soundgen for NPCs - if(name == "land") + if (name == "land") return {}; - if(name == "swimleft") + if (name == "swimleft") return "Swim Left"; - if(name == "swimright") + if (name == "swimright") return "Swim Right"; // TODO: I have no idea what these are supposed to do for NPCs since they use // voiced dialog for various conditions like health loss and combat taunts. Maybe // only for biped creatures? - if(name == "moan") + if (name == "moan") return {}; - if(name == "roar") + if (name == "roar") return {}; - if(name == "scream") + if (name == "scream") return {}; throw std::runtime_error("Unexpected soundgen type: " + std::string(name)); } - MWWorld::Ptr Npc::copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const + MWWorld::Ptr Npc::copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return MWWorld::Ptr(cell.insert(ref), &cell); } @@ -1338,13 +1351,12 @@ namespace MWClass return getNpcStats(ptr).getSkill(skill).getModified(); } - int Npc::getBloodTexture(const MWWorld::ConstPtr &ptr) const + int Npc::getBloodTexture(const MWWorld::ConstPtr& ptr) const { return ptr.get()->mBase->mBloodType; } - void Npc::readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state) - const + void Npc::readAdditionalState(const MWWorld::Ptr& ptr, const ESM::ObjectState& state) const { if (!state.mHasCustomState) return; @@ -1363,20 +1375,20 @@ namespace MWClass } } else - ensureCustomData(ptr); // in openmw 0.30 savegames not all state was saved yet, so need to load it regardless. + ensureCustomData( + ptr); // in openmw 0.30 savegames not all state was saved yet, so need to load it regardless. NpcCustomData& customData = ptr.getRefData().getCustomData()->asNpcCustomData(); - customData.mInventoryStore.readState (npcState.mInventory); - customData.mNpcStats.readState (npcState.mNpcStats); + customData.mInventoryStore.readState(npcState.mInventory); + customData.mNpcStats.readState(npcState.mNpcStats); bool spellsInitialised = customData.mNpcStats.getSpells().setSpells(ptr.get()->mBase->mId); - if(spellsInitialised) + if (spellsInitialised) customData.mNpcStats.getSpells().clear(); - customData.mNpcStats.readState (npcState.mCreatureStats); + customData.mNpcStats.readState(npcState.mCreatureStats); } - void Npc::writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) - const + void Npc::writeAdditionalState(const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const { if (!ptr.getRefData().getCustomData()) { @@ -1385,21 +1397,22 @@ namespace MWClass } const NpcCustomData& customData = ptr.getRefData().getCustomData()->asNpcCustomData(); - if (ptr.getRefData().getCount() <= 0 && (!(ptr.get()->mBase->mFlags & ESM::NPC::Respawn) || !customData.mNpcStats.isDead())) + if (ptr.getRefData().getCount() <= 0 + && (!(ptr.get()->mBase->mFlags & ESM::NPC::Respawn) || !customData.mNpcStats.isDead())) { state.mHasCustomState = false; return; } ESM::NpcState& npcState = state.asNpcState(); - customData.mInventoryStore.writeState (npcState.mInventory); - customData.mNpcStats.writeState (npcState.mNpcStats); - customData.mNpcStats.writeState (npcState.mCreatureStats); + customData.mInventoryStore.writeState(npcState.mInventory); + customData.mNpcStats.writeState(npcState.mNpcStats); + customData.mNpcStats.writeState(npcState.mCreatureStats); } int Npc::getBaseGold(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mNpdt.mGold; } @@ -1408,17 +1421,17 @@ namespace MWClass return Misc::StringUtils::ciEqual(ptr.get()->mBase->mClass, className); } - bool Npc::canSwim(const MWWorld::ConstPtr &ptr) const + bool Npc::canSwim(const MWWorld::ConstPtr& ptr) const { return true; } - bool Npc::canWalk(const MWWorld::ConstPtr &ptr) const + bool Npc::canWalk(const MWWorld::ConstPtr& ptr) const { return true; } - void Npc::respawn(const MWWorld::Ptr &ptr) const + void Npc::respawn(const MWWorld::Ptr& ptr) const { const MWMechanics::CreatureStats& creatureStats = getCreatureStats(ptr); if (ptr.getRefData().getCount() > 0 && !creatureStats.isDead()) @@ -1427,14 +1440,16 @@ namespace MWClass if (!creatureStats.isDeathAnimationFinished()) return; - const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& gmst + = MWBase::Environment::get().getWorld()->getStore().get(); static const float fCorpseRespawnDelay = gmst.find("fCorpseRespawnDelay")->mValue.getFloat(); static const float fCorpseClearDelay = gmst.find("fCorpseClearDelay")->mValue.getFloat(); - float delay = ptr.getRefData().getCount() == 0 ? fCorpseClearDelay : std::min(fCorpseRespawnDelay, fCorpseClearDelay); + float delay + = ptr.getRefData().getCount() == 0 ? fCorpseClearDelay : std::min(fCorpseRespawnDelay, fCorpseClearDelay); if (ptr.get()->mBase->mFlags & ESM::NPC::Respawn - && creatureStats.getTimeOfDeath() + delay <= MWBase::Environment::get().getWorld()->getTimeStamp()) + && creatureStats.getTimeOfDeath() + delay <= MWBase::Environment::get().getWorld()->getTimeStamp()) { if (ptr.getCellRef().hasContentFile()) { @@ -1452,32 +1467,33 @@ namespace MWClass // Reset to original position MWBase::Environment::get().getWorld()->moveObject(ptr, ptr.getCellRef().getPosition().asVec3()); - MWBase::Environment::get().getWorld()->rotateObject(ptr, ptr.getCellRef().getPosition().asRotationVec3(), MWBase::RotationFlag_none); + MWBase::Environment::get().getWorld()->rotateObject( + ptr, ptr.getCellRef().getPosition().asRotationVec3(), MWBase::RotationFlag_none); } } } - int Npc::getBaseFightRating (const MWWorld::ConstPtr& ptr) const + int Npc::getBaseFightRating(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mAiData.mFight; } - bool Npc::isBipedal(const MWWorld::ConstPtr &ptr) const + bool Npc::isBipedal(const MWWorld::ConstPtr& ptr) const { return true; } std::string_view Npc::getPrimaryFaction(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mFaction; } - int Npc::getPrimaryFactionRank (const MWWorld::ConstPtr& ptr) const + int Npc::getPrimaryFactionRank(const MWWorld::ConstPtr& ptr) const { std::string_view factionID = ptr.getClass().getPrimaryFaction(ptr); - if(factionID.empty()) + if (factionID.empty()) return -1; // Search in the NPC data first @@ -1489,7 +1505,7 @@ namespace MWClass } // Use base NPC record as a fallback - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->getFactionRank(); } @@ -1511,11 +1527,11 @@ namespace MWClass const bool sneaking = MWBase::Environment::get().getMechanicsManager()->isSneaking(ptr); float walkSpeed = gmst.fMinWalkSpeed->mValue.getFloat() - + 0.01f * stats.getAttribute(ESM::Attribute::Speed).getModified() + + 0.01f * stats.getAttribute(ESM::Attribute::Speed).getModified() * (gmst.fMaxWalkSpeed->mValue.getFloat() - gmst.fMinWalkSpeed->mValue.getFloat()); - walkSpeed *= 1.0f - gmst.fEncumberedMoveEffect->mValue.getFloat()*normalizedEncumbrance; + walkSpeed *= 1.0f - gmst.fEncumberedMoveEffect->mValue.getFloat() * normalizedEncumbrance; walkSpeed = std::max(0.0f, walkSpeed); - if(sneaking) + if (sneaking) walkSpeed *= gmst.fSneakSpeedMultiplier->mValue.getFloat(); return walkSpeed; @@ -1525,8 +1541,8 @@ namespace MWClass { const GMST& gmst = getGmst(); return getWalkSpeed(ptr) - * (0.01f * getSkill(ptr, ESM::Skill::Athletics) * gmst.fAthleticsRunBonus->mValue.getFloat() - + gmst.fBaseRunMultiplier->mValue.getFloat()); + * (0.01f * getSkill(ptr, ESM::Skill::Athletics) * gmst.fAthleticsRunBonus->mValue.getFloat() + + gmst.fBaseRunMultiplier->mValue.getFloat()); } float Npc::getSwimSpeed(const MWWorld::Ptr& ptr) const @@ -1537,7 +1553,7 @@ namespace MWClass const bool swimming = world->isSwimming(ptr); const bool inair = !world->isOnGround(ptr) && !swimming && !world->isFlying(ptr); const bool running = stats.getStance(MWMechanics::CreatureStats::Stance_Run) - && (inair || MWBase::Environment::get().getMechanicsManager()->isRunning(ptr)); + && (inair || MWBase::Environment::get().getMechanicsManager()->isRunning(ptr)); return getSwimSpeedImpl(ptr, getGmst(), mageffects, running ? getRunSpeed(ptr) : getWalkSpeed(ptr)); } diff --git a/apps/openmw/mwclass/npc.hpp b/apps/openmw/mwclass/npc.hpp index ebe9b03318..855d236c22 100644 --- a/apps/openmw/mwclass/npc.hpp +++ b/apps/openmw/mwclass/npc.hpp @@ -14,165 +14,165 @@ namespace MWClass { class Npc : public MWWorld::RegisteredClass { - friend MWWorld::RegisteredClass; + friend MWWorld::RegisteredClass; - Npc(); + Npc(); - void ensureCustomData (const MWWorld::Ptr& ptr) const; + void ensureCustomData(const MWWorld::Ptr& ptr) const; - MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const override; - struct GMST - { - const ESM::GameSetting *fMinWalkSpeed; - const ESM::GameSetting *fMaxWalkSpeed; - const ESM::GameSetting *fEncumberedMoveEffect; - const ESM::GameSetting *fSneakSpeedMultiplier; - const ESM::GameSetting *fAthleticsRunBonus; - const ESM::GameSetting *fBaseRunMultiplier; - const ESM::GameSetting *fMinFlySpeed; - const ESM::GameSetting *fMaxFlySpeed; - const ESM::GameSetting *fSwimRunBase; - const ESM::GameSetting *fSwimRunAthleticsMult; - const ESM::GameSetting *fJumpEncumbranceBase; - const ESM::GameSetting *fJumpEncumbranceMultiplier; - const ESM::GameSetting *fJumpAcrobaticsBase; - const ESM::GameSetting *fJumpAcroMultiplier; - const ESM::GameSetting *fJumpRunMultiplier; - const ESM::GameSetting *fWereWolfRunMult; - const ESM::GameSetting *fKnockDownMult; - const ESM::GameSetting *iKnockDownOddsMult; - const ESM::GameSetting *iKnockDownOddsBase; - const ESM::GameSetting *fCombatArmorMinMult; - }; + struct GMST + { + const ESM::GameSetting* fMinWalkSpeed; + const ESM::GameSetting* fMaxWalkSpeed; + const ESM::GameSetting* fEncumberedMoveEffect; + const ESM::GameSetting* fSneakSpeedMultiplier; + const ESM::GameSetting* fAthleticsRunBonus; + const ESM::GameSetting* fBaseRunMultiplier; + const ESM::GameSetting* fMinFlySpeed; + const ESM::GameSetting* fMaxFlySpeed; + const ESM::GameSetting* fSwimRunBase; + const ESM::GameSetting* fSwimRunAthleticsMult; + const ESM::GameSetting* fJumpEncumbranceBase; + const ESM::GameSetting* fJumpEncumbranceMultiplier; + const ESM::GameSetting* fJumpAcrobaticsBase; + const ESM::GameSetting* fJumpAcroMultiplier; + const ESM::GameSetting* fJumpRunMultiplier; + const ESM::GameSetting* fWereWolfRunMult; + const ESM::GameSetting* fKnockDownMult; + const ESM::GameSetting* iKnockDownOddsMult; + const ESM::GameSetting* iKnockDownOddsBase; + const ESM::GameSetting* fCombatArmorMinMult; + }; - static const GMST& getGmst(); + static const GMST& getGmst(); - public: + public: + void insertObjectRendering(const MWWorld::Ptr& ptr, const std::string& model, + MWRender::RenderingInterface& renderingInterface) const override; + ///< Add reference into a cell for rendering - void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; - ///< Add reference into a cell for rendering + std::string_view getName(const MWWorld::ConstPtr& ptr) const override; + ///< \return name or ID; can return an empty string. - std::string_view getName(const MWWorld::ConstPtr& ptr) const override; - ///< \return name or ID; can return an empty string. + MWMechanics::CreatureStats& getCreatureStats(const MWWorld::Ptr& ptr) const override; + ///< Return creature stats - MWMechanics::CreatureStats& getCreatureStats (const MWWorld::Ptr& ptr) const override; - ///< Return creature stats + MWMechanics::NpcStats& getNpcStats(const MWWorld::Ptr& ptr) const override; + ///< Return NPC stats - MWMechanics::NpcStats& getNpcStats (const MWWorld::Ptr& ptr) const override; - ///< Return NPC stats + MWWorld::ContainerStore& getContainerStore(const MWWorld::Ptr& ptr) const override; + ///< Return container store - MWWorld::ContainerStore& getContainerStore (const MWWorld::Ptr& ptr) const override; - ///< Return container store + bool hasToolTip(const MWWorld::ConstPtr& ptr) const override; + ///< @return true if this object has a tooltip when focused (default implementation: true) - bool hasToolTip(const MWWorld::ConstPtr& ptr) const override; - ///< @return true if this object has a tooltip when focused (default implementation: true) + MWGui::ToolTipInfo getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const override; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. - MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const override; - ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + MWWorld::InventoryStore& getInventoryStore(const MWWorld::Ptr& ptr) const override; + ///< Return inventory store - MWWorld::InventoryStore& getInventoryStore (const MWWorld::Ptr& ptr) const override; - ///< Return inventory store + bool hasInventoryStore(const MWWorld::Ptr& ptr) const override { return true; } - bool hasInventoryStore(const MWWorld::Ptr &ptr) const override { return true; } + bool evaluateHit(const MWWorld::Ptr& ptr, MWWorld::Ptr& victim, osg::Vec3f& hitPosition) const override; - bool evaluateHit(const MWWorld::Ptr& ptr, MWWorld::Ptr& victim, osg::Vec3f& hitPosition) const override; + void hit(const MWWorld::Ptr& ptr, float attackStrength, int type, const MWWorld::Ptr& victim, + const osg::Vec3f& hitPosition, bool success) const override; - void hit(const MWWorld::Ptr& ptr, float attackStrength, int type, const MWWorld::Ptr& victim, const osg::Vec3f& hitPosition, bool success) const override; + void onHit(const MWWorld::Ptr& ptr, float damage, bool ishealth, const MWWorld::Ptr& object, + const MWWorld::Ptr& attacker, const osg::Vec3f& hitPosition, bool successful) const override; - void onHit(const MWWorld::Ptr &ptr, float damage, bool ishealth, const MWWorld::Ptr &object, const MWWorld::Ptr &attacker, const osg::Vec3f &hitPosition, bool successful) const override; + void getModelsToPreload(const MWWorld::Ptr& ptr, std::vector& models) const override; + ///< Get a list of models to preload that this object may use (directly or indirectly). default implementation: + ///< list getModel(). - void getModelsToPreload(const MWWorld::Ptr& ptr, std::vector& models) const override; - ///< Get a list of models to preload that this object may use (directly or indirectly). default implementation: list getModel(). + std::unique_ptr activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const override; + ///< Generate action for activation - std::unique_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const override; - ///< Generate action for activation + std::string_view getScript(const MWWorld::ConstPtr& ptr) const override; + ///< Return name of the script attached to ptr - std::string_view getScript(const MWWorld::ConstPtr& ptr) const override; - ///< Return name of the script attached to ptr + float getMaxSpeed(const MWWorld::Ptr& ptr) const override; + ///< Return maximal movement speed. - float getMaxSpeed (const MWWorld::Ptr& ptr) const override; - ///< Return maximal movement speed. + float getJump(const MWWorld::Ptr& ptr) const override; + ///< Return jump velocity (not accounting for movement) - float getJump(const MWWorld::Ptr &ptr) const override; - ///< Return jump velocity (not accounting for movement) + MWMechanics::Movement& getMovementSettings(const MWWorld::Ptr& ptr) const override; + ///< Return desired movement. - MWMechanics::Movement& getMovementSettings (const MWWorld::Ptr& ptr) const override; - ///< Return desired movement. + float getCapacity(const MWWorld::Ptr& ptr) const override; + ///< Return total weight that fits into the object. Throws an exception, if the object can't + /// hold other objects. - float getCapacity (const MWWorld::Ptr& ptr) const override; - ///< Return total weight that fits into the object. Throws an exception, if the object can't - /// hold other objects. + float getEncumbrance(const MWWorld::Ptr& ptr) const override; + ///< Returns total weight of objects inside this object (including modifications from magic + /// effects). Throws an exception, if the object can't hold other objects. - float getEncumbrance (const MWWorld::Ptr& ptr) const override; - ///< Returns total weight of objects inside this object (including modifications from magic - /// effects). Throws an exception, if the object can't hold other objects. + float getArmorRating(const MWWorld::Ptr& ptr) const override; + ///< @return combined armor rating of this actor - float getArmorRating (const MWWorld::Ptr& ptr) const override; - ///< @return combined armor rating of this actor + bool consume(const MWWorld::Ptr& consumable, const MWWorld::Ptr& actor) const override; - bool consume(const MWWorld::Ptr& consumable, const MWWorld::Ptr& actor) const override; + void adjustScale(const MWWorld::ConstPtr& ptr, osg::Vec3f& scale, bool rendering) const override; + /// @param rendering Indicates if the scale to adjust is for the rendering mesh, or for the collision mesh - void adjustScale (const MWWorld::ConstPtr &ptr, osg::Vec3f &scale, bool rendering) const override; - /// @param rendering Indicates if the scale to adjust is for the rendering mesh, or for the collision mesh + void skillUsageSucceeded( + const MWWorld::Ptr& ptr, int skill, int usageType, float extraFactor = 1.f) const override; + ///< Inform actor \a ptr that a skill use has succeeded. - void skillUsageSucceeded (const MWWorld::Ptr& ptr, int skill, int usageType, float extraFactor=1.f) const override; - ///< Inform actor \a ptr that a skill use has succeeded. + bool isEssential(const MWWorld::ConstPtr& ptr) const override; + ///< Is \a ptr essential? (i.e. may losing \a ptr make the game unwinnable) - bool isEssential (const MWWorld::ConstPtr& ptr) const override; - ///< Is \a ptr essential? (i.e. may losing \a ptr make the game unwinnable) + int getServices(const MWWorld::ConstPtr& actor) const override; - int getServices (const MWWorld::ConstPtr& actor) const override; + bool isPersistent(const MWWorld::ConstPtr& ptr) const override; - bool isPersistent (const MWWorld::ConstPtr& ptr) const override; + std::string_view getSoundIdFromSndGen(const MWWorld::Ptr& ptr, std::string_view name) const override; - std::string_view getSoundIdFromSndGen(const MWWorld::Ptr& ptr, std::string_view name) const override; + std::string getModel(const MWWorld::ConstPtr& ptr) const override; - std::string getModel(const MWWorld::ConstPtr &ptr) const override; + float getSkill(const MWWorld::Ptr& ptr, int skill) const override; - float getSkill(const MWWorld::Ptr& ptr, int skill) const override; + /// Get a blood texture suitable for \a ptr (see Blood Texture 0-2 in Morrowind.ini) + int getBloodTexture(const MWWorld::ConstPtr& ptr) const override; - /// Get a blood texture suitable for \a ptr (see Blood Texture 0-2 in Morrowind.ini) - int getBloodTexture (const MWWorld::ConstPtr& ptr) const override; + bool isNpc() const override { return true; } - bool isNpc() const override - { - return true; - } + void readAdditionalState(const MWWorld::Ptr& ptr, const ESM::ObjectState& state) const override; + ///< Read additional state from \a state into \a ptr. - void readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state) const override; - ///< Read additional state from \a state into \a ptr. + void writeAdditionalState(const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const override; + ///< Write additional state from \a ptr into \a state. - void writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const override; - ///< Write additional state from \a ptr into \a state. + int getBaseGold(const MWWorld::ConstPtr& ptr) const override; - int getBaseGold(const MWWorld::ConstPtr& ptr) const override; + bool isClass(const MWWorld::ConstPtr& ptr, std::string_view className) const override; - bool isClass(const MWWorld::ConstPtr& ptr, std::string_view className) const override; + bool canSwim(const MWWorld::ConstPtr& ptr) const override; - bool canSwim (const MWWorld::ConstPtr &ptr) const override; + bool canWalk(const MWWorld::ConstPtr& ptr) const override; - bool canWalk (const MWWorld::ConstPtr &ptr) const override; + bool isBipedal(const MWWorld::ConstPtr& ptr) const override; - bool isBipedal (const MWWorld::ConstPtr &ptr) const override; + void respawn(const MWWorld::Ptr& ptr) const override; - void respawn (const MWWorld::Ptr& ptr) const override; + int getBaseFightRating(const MWWorld::ConstPtr& ptr) const override; - int getBaseFightRating (const MWWorld::ConstPtr& ptr) const override; + std::string_view getPrimaryFaction(const MWWorld::ConstPtr& ptr) const override; + int getPrimaryFactionRank(const MWWorld::ConstPtr& ptr) const override; - std::string_view getPrimaryFaction(const MWWorld::ConstPtr &ptr) const override; - int getPrimaryFactionRank(const MWWorld::ConstPtr &ptr) const override; + void setBaseAISetting(const std::string& id, MWMechanics::AiSetting setting, int value) const override; - void setBaseAISetting(const std::string& id, MWMechanics::AiSetting setting, int value) const override; + void modifyBaseInventory(std::string_view actorId, std::string_view itemId, int amount) const override; - void modifyBaseInventory(std::string_view actorId, std::string_view itemId, int amount) const override; + float getWalkSpeed(const MWWorld::Ptr& ptr) const override; - float getWalkSpeed(const MWWorld::Ptr& ptr) const override; + float getRunSpeed(const MWWorld::Ptr& ptr) const override; - float getRunSpeed(const MWWorld::Ptr& ptr) const override; - - float getSwimSpeed(const MWWorld::Ptr& ptr) const override; + float getSwimSpeed(const MWWorld::Ptr& ptr) const override; }; } diff --git a/apps/openmw/mwclass/potion.cpp b/apps/openmw/mwclass/potion.cpp index 874d33c598..499910bd77 100644 --- a/apps/openmw/mwclass/potion.cpp +++ b/apps/openmw/mwclass/potion.cpp @@ -2,15 +2,15 @@ #include -#include -#include #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" +#include +#include -#include "../mwworld/ptr.hpp" #include "../mwworld/actionapply.hpp" #include "../mwworld/cellstore.hpp" +#include "../mwworld/ptr.hpp" #include "../mwgui/tooltips.hpp" #include "../mwgui/ustring.hpp" @@ -29,43 +29,43 @@ namespace MWClass { } - void Potion::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const + void Potion::insertObjectRendering( + const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const { - if (!model.empty()) { + if (!model.empty()) + { renderingInterface.getObjects().insertModel(ptr, model); } } - std::string Potion::getModel(const MWWorld::ConstPtr &ptr) const + std::string Potion::getModel(const MWWorld::ConstPtr& ptr) const { return getClassModel(ptr); } std::string_view Potion::getName(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); const std::string& name = ref->mBase->mName; return !name.empty() ? name : ref->mBase->mId; } - std::unique_ptr Potion::activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const + std::unique_ptr Potion::activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const { return defaultItemActivate(ptr, actor); } std::string_view Potion::getScript(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = - ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mScript; } - int Potion::getValue (const MWWorld::ConstPtr& ptr) const + int Potion::getValue(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mData.mValue; } @@ -82,18 +82,19 @@ namespace MWClass const std::string& Potion::getInventoryIcon(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mIcon; } - MWGui::ToolTipInfo Potion::getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const + MWGui::ToolTipInfo Potion::getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); MWGui::ToolTipInfo info; std::string_view name = getName(ptr); - info.caption = MyGUI::TextIterator::toTagsString(MWGui::toUString(name)) + MWGui::ToolTips::getCountString(count); + info.caption + = MyGUI::TextIterator::toTagsString(MWGui::toUString(name)) + MWGui::ToolTips::getCountString(count); info.icon = ref->mBase->mIcon; std::string text; @@ -104,13 +105,14 @@ namespace MWClass info.effects = MWGui::Widgets::MWEffectList::effectListFromESM(&ref->mBase->mEffects); // hide effects the player doesn't know about - MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); - for (unsigned int i=0; igetPlayerPtr(); + for (unsigned int i = 0; i < info.effects.size(); ++i) info.effects[i].mKnown = MWMechanics::Alchemy::knownEffect(i, player); info.isPotion = true; - if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { + if (MWBase::Environment::get().getWindowManager()->getFullHelp()) + { text += MWGui::ToolTips::getCellRefString(ptr.getCellRef()); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); } @@ -120,33 +122,32 @@ namespace MWClass return info; } - std::unique_ptr Potion::use (const MWWorld::Ptr& ptr, bool force) const + std::unique_ptr Potion::use(const MWWorld::Ptr& ptr, bool force) const { - MWWorld::LiveCellRef *ref = - ptr.get(); + MWWorld::LiveCellRef* ref = ptr.get(); auto action = std::make_unique(ptr, ref->mBase->mId); - action->setSound ("Drink"); + action->setSound("Drink"); return action; } - MWWorld::Ptr Potion::copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const + MWWorld::Ptr Potion::copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return MWWorld::Ptr(cell.insert(ref), &cell); } - bool Potion::canSell (const MWWorld::ConstPtr& item, int npcServices) const + bool Potion::canSell(const MWWorld::ConstPtr& item, int npcServices) const { return (npcServices & ESM::NPC::Potions) != 0; } - float Potion::getWeight(const MWWorld::ConstPtr &ptr) const + float Potion::getWeight(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mData.mWeight; } } diff --git a/apps/openmw/mwclass/potion.hpp b/apps/openmw/mwclass/potion.hpp index 23fc2d1059..1bff256b0d 100644 --- a/apps/openmw/mwclass/potion.hpp +++ b/apps/openmw/mwclass/potion.hpp @@ -7,50 +7,49 @@ namespace MWClass { class Potion : public MWWorld::RegisteredClass { - friend MWWorld::RegisteredClass; + friend MWWorld::RegisteredClass; - Potion(); + Potion(); - MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const override; - public: + public: + void insertObjectRendering(const MWWorld::Ptr& ptr, const std::string& model, + MWRender::RenderingInterface& renderingInterface) const override; + ///< Add reference into a cell for rendering - void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; - ///< Add reference into a cell for rendering + std::string_view getName(const MWWorld::ConstPtr& ptr) const override; + ///< \return name or ID; can return an empty string. - std::string_view getName(const MWWorld::ConstPtr& ptr) const override; - ///< \return name or ID; can return an empty string. + std::unique_ptr activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const override; + ///< Generate action for activation - std::unique_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const override; - ///< Generate action for activation + MWGui::ToolTipInfo getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const override; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. - MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const override; - ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + std::string_view getScript(const MWWorld::ConstPtr& ptr) const override; + ///< Return name of the script attached to ptr - std::string_view getScript(const MWWorld::ConstPtr& ptr) const override; - ///< Return name of the script attached to ptr + int getValue(const MWWorld::ConstPtr& ptr) const override; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. - int getValue (const MWWorld::ConstPtr& ptr) const override; - ///< Return trade value of the object. Throws an exception, if the object can't be traded. + std::unique_ptr use(const MWWorld::Ptr& ptr, bool force = false) const override; + ///< Generate action for using via inventory menu - std::unique_ptr use (const MWWorld::Ptr& ptr, bool force=false) const override; - ///< Generate action for using via inventory menu + std::string_view getUpSoundId(const MWWorld::ConstPtr& ptr) const override; + ///< Return the pick up sound Id - std::string_view getUpSoundId(const MWWorld::ConstPtr& ptr) const override; - ///< Return the pick up sound Id + std::string_view getDownSoundId(const MWWorld::ConstPtr& ptr) const override; + ///< Return the put down sound Id - std::string_view getDownSoundId(const MWWorld::ConstPtr& ptr) const override; - ///< Return the put down sound Id + const std::string& getInventoryIcon(const MWWorld::ConstPtr& ptr) const override; + ///< Return name of inventory icon. - const std::string& getInventoryIcon(const MWWorld::ConstPtr& ptr) const override; - ///< Return name of inventory icon. + std::string getModel(const MWWorld::ConstPtr& ptr) const override; - std::string getModel(const MWWorld::ConstPtr &ptr) const override; + float getWeight(const MWWorld::ConstPtr& ptr) const override; - float getWeight (const MWWorld::ConstPtr& ptr) const override; - - bool canSell (const MWWorld::ConstPtr& item, int npcServices) const override; + bool canSell(const MWWorld::ConstPtr& item, int npcServices) const override; }; } diff --git a/apps/openmw/mwclass/probe.cpp b/apps/openmw/mwclass/probe.cpp index 94bb574b92..7feda8445e 100644 --- a/apps/openmw/mwclass/probe.cpp +++ b/apps/openmw/mwclass/probe.cpp @@ -2,17 +2,17 @@ #include -#include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/windowmanager.hpp" -#include "../mwworld/ptr.hpp" #include "../mwworld/actionequip.hpp" -#include "../mwworld/inventorystore.hpp" #include "../mwworld/cellstore.hpp" +#include "../mwworld/inventorystore.hpp" +#include "../mwworld/ptr.hpp" #include "../mwgui/tooltips.hpp" #include "../mwgui/ustring.hpp" @@ -29,51 +29,51 @@ namespace MWClass { } - void Probe::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const + void Probe::insertObjectRendering( + const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const { - if (!model.empty()) { + if (!model.empty()) + { renderingInterface.getObjects().insertModel(ptr, model); } } - std::string Probe::getModel(const MWWorld::ConstPtr &ptr) const + std::string Probe::getModel(const MWWorld::ConstPtr& ptr) const { return getClassModel(ptr); } std::string_view Probe::getName(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); const std::string& name = ref->mBase->mName; return !name.empty() ? name : ref->mBase->mId; } - std::unique_ptr Probe::activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const + std::unique_ptr Probe::activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const { return defaultItemActivate(ptr, actor); } std::string_view Probe::getScript(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = - ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mScript; } - std::pair, bool> Probe::getEquipmentSlots (const MWWorld::ConstPtr& ptr) const + std::pair, bool> Probe::getEquipmentSlots(const MWWorld::ConstPtr& ptr) const { std::vector slots_; - slots_.push_back (int (MWWorld::InventoryStore::Slot_CarriedRight)); + slots_.push_back(int(MWWorld::InventoryStore::Slot_CarriedRight)); - return std::make_pair (slots_, false); + return std::make_pair(slots_, false); } - int Probe::getValue (const MWWorld::ConstPtr& ptr) const + int Probe::getValue(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mData.mValue; } @@ -90,18 +90,19 @@ namespace MWClass const std::string& Probe::getInventoryIcon(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mIcon; } - MWGui::ToolTipInfo Probe::getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const + MWGui::ToolTipInfo Probe::getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); MWGui::ToolTipInfo info; std::string_view name = getName(ptr); - info.caption = MyGUI::TextIterator::toTagsString(MWGui::toUString(name)) + MWGui::ToolTips::getCountString(count); + info.caption + = MyGUI::TextIterator::toTagsString(MWGui::toUString(name)) + MWGui::ToolTips::getCountString(count); info.icon = ref->mBase->mIcon; std::string text; @@ -113,7 +114,8 @@ namespace MWClass text += MWGui::ToolTips::getWeightString(ref->mBase->mData.mWeight, "#{sWeight}"); text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); - if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { + if (MWBase::Environment::get().getWindowManager()->getFullHelp()) + { text += MWGui::ToolTips::getCellRefString(ptr.getCellRef()); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); } @@ -123,7 +125,7 @@ namespace MWClass return info; } - std::unique_ptr Probe::use (const MWWorld::Ptr& ptr, bool force) const + std::unique_ptr Probe::use(const MWWorld::Ptr& ptr, bool force) const { std::unique_ptr action = std::make_unique(ptr, force); @@ -132,9 +134,9 @@ namespace MWClass return action; } - MWWorld::Ptr Probe::copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const + MWWorld::Ptr Probe::copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return MWWorld::Ptr(cell.insert(ref), &cell); } @@ -144,26 +146,26 @@ namespace MWClass // Do not allow equip tools from inventory during attack if (MWBase::Environment::get().getMechanicsManager()->isAttackingOrSpell(npc) && MWBase::Environment::get().getWindowManager()->isGuiMode()) - return {0, "#{sCantEquipWeapWarning}"}; + return { 0, "#{sCantEquipWeapWarning}" }; - return {1, {}}; + return { 1, {} }; } - bool Probe::canSell (const MWWorld::ConstPtr& item, int npcServices) const + bool Probe::canSell(const MWWorld::ConstPtr& item, int npcServices) const { return (npcServices & ESM::NPC::Probes) != 0; } - int Probe::getItemMaxHealth (const MWWorld::ConstPtr& ptr) const + int Probe::getItemMaxHealth(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mData.mUses; } - float Probe::getWeight(const MWWorld::ConstPtr &ptr) const + float Probe::getWeight(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mData.mWeight; } } diff --git a/apps/openmw/mwclass/probe.hpp b/apps/openmw/mwclass/probe.hpp index 1583887960..3325c30e3b 100644 --- a/apps/openmw/mwclass/probe.hpp +++ b/apps/openmw/mwclass/probe.hpp @@ -7,62 +7,62 @@ namespace MWClass { class Probe : public MWWorld::RegisteredClass { - friend MWWorld::RegisteredClass; + friend MWWorld::RegisteredClass; - Probe(); + Probe(); - MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const override; - public: + public: + void insertObjectRendering(const MWWorld::Ptr& ptr, const std::string& model, + MWRender::RenderingInterface& renderingInterface) const override; + ///< Add reference into a cell for rendering - void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; - ///< Add reference into a cell for rendering + std::string_view getName(const MWWorld::ConstPtr& ptr) const override; + ///< \return name or ID; can return an empty string. - std::string_view getName(const MWWorld::ConstPtr& ptr) const override; - ///< \return name or ID; can return an empty string. + std::unique_ptr activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const override; + ///< Generate action for activation - std::unique_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const override; - ///< Generate action for activation + MWGui::ToolTipInfo getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const override; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. - MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const override; - ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + std::string_view getScript(const MWWorld::ConstPtr& ptr) const override; + ///< Return name of the script attached to ptr - std::string_view getScript(const MWWorld::ConstPtr& ptr) const override; - ///< Return name of the script attached to ptr + std::pair, bool> getEquipmentSlots(const MWWorld::ConstPtr& ptr) const override; + ///< \return first: Return IDs of the slot this object can be equipped in; second: can object + /// stay stacked when equipped? - std::pair, bool> getEquipmentSlots (const MWWorld::ConstPtr& ptr) const override; - ///< \return first: Return IDs of the slot this object can be equipped in; second: can object - /// stay stacked when equipped? + int getValue(const MWWorld::ConstPtr& ptr) const override; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. - int getValue (const MWWorld::ConstPtr& ptr) const override; - ///< Return trade value of the object. Throws an exception, if the object can't be traded. + std::string_view getUpSoundId(const MWWorld::ConstPtr& ptr) const override; + ///< Return the pick up sound Id - std::string_view getUpSoundId(const MWWorld::ConstPtr& ptr) const override; - ///< Return the pick up sound Id + std::string_view getDownSoundId(const MWWorld::ConstPtr& ptr) const override; + ///< Return the put down sound Id - std::string_view getDownSoundId(const MWWorld::ConstPtr& ptr) const override; - ///< Return the put down sound Id + const std::string& getInventoryIcon(const MWWorld::ConstPtr& ptr) const override; + ///< Return name of inventory icon. - const std::string& getInventoryIcon(const MWWorld::ConstPtr& ptr) const override; - ///< Return name of inventory icon. + std::pair canBeEquipped( + const MWWorld::ConstPtr& ptr, const MWWorld::Ptr& npc) const override; - std::pair canBeEquipped(const MWWorld::ConstPtr& ptr, const MWWorld::Ptr& npc) const override; + std::unique_ptr use(const MWWorld::Ptr& ptr, bool force = false) const override; + ///< Generate action for using via inventory menu - std::unique_ptr use (const MWWorld::Ptr& ptr, bool force=false) const override; - ///< Generate action for using via inventory menu + std::string getModel(const MWWorld::ConstPtr& ptr) const override; - std::string getModel(const MWWorld::ConstPtr &ptr) const override; + bool canSell(const MWWorld::ConstPtr& item, int npcServices) const override; - bool canSell (const MWWorld::ConstPtr& item, int npcServices) const override; + float getWeight(const MWWorld::ConstPtr& ptr) const override; - float getWeight (const MWWorld::ConstPtr& ptr) const override; + int getItemMaxHealth(const MWWorld::ConstPtr& ptr) const override; + ///< Return item max health or throw an exception, if class does not have item health - int getItemMaxHealth (const MWWorld::ConstPtr& ptr) const override; - ///< Return item max health or throw an exception, if class does not have item health - - bool hasItemHealth (const MWWorld::ConstPtr& ptr) const override { return true; } - ///< \return Item health data available? (default implementation: false) + bool hasItemHealth(const MWWorld::ConstPtr& ptr) const override { return true; } + ///< \return Item health data available? (default implementation: false) }; } diff --git a/apps/openmw/mwclass/repair.cpp b/apps/openmw/mwclass/repair.cpp index 85a014a1bf..899e0f14bd 100644 --- a/apps/openmw/mwclass/repair.cpp +++ b/apps/openmw/mwclass/repair.cpp @@ -2,15 +2,15 @@ #include -#include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" -#include "../mwworld/ptr.hpp" -#include "../mwworld/cellstore.hpp" #include "../mwworld/actionrepair.hpp" +#include "../mwworld/cellstore.hpp" +#include "../mwworld/ptr.hpp" #include "../mwgui/tooltips.hpp" #include "../mwgui/ustring.hpp" @@ -27,43 +27,43 @@ namespace MWClass { } - void Repair::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const + void Repair::insertObjectRendering( + const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const { - if (!model.empty()) { + if (!model.empty()) + { renderingInterface.getObjects().insertModel(ptr, model); } } - std::string Repair::getModel(const MWWorld::ConstPtr &ptr) const + std::string Repair::getModel(const MWWorld::ConstPtr& ptr) const { return getClassModel(ptr); } std::string_view Repair::getName(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); const std::string& name = ref->mBase->mName; return !name.empty() ? name : ref->mBase->mId; } - std::unique_ptr Repair::activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const + std::unique_ptr Repair::activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const { return defaultItemActivate(ptr, actor); } std::string_view Repair::getScript(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = - ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mScript; } - int Repair::getValue (const MWWorld::ConstPtr& ptr) const + int Repair::getValue(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mData.mValue; } @@ -80,30 +80,31 @@ namespace MWClass const std::string& Repair::getInventoryIcon(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mIcon; } - bool Repair::hasItemHealth (const MWWorld::ConstPtr& ptr) const + bool Repair::hasItemHealth(const MWWorld::ConstPtr& ptr) const { return true; } - int Repair::getItemMaxHealth (const MWWorld::ConstPtr& ptr) const + int Repair::getItemMaxHealth(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mData.mUses; } - MWGui::ToolTipInfo Repair::getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const + MWGui::ToolTipInfo Repair::getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); MWGui::ToolTipInfo info; std::string_view name = getName(ptr); - info.caption = MyGUI::TextIterator::toTagsString(MWGui::toUString(name)) + MWGui::ToolTips::getCountString(count); + info.caption + = MyGUI::TextIterator::toTagsString(MWGui::toUString(name)) + MWGui::ToolTips::getCountString(count); info.icon = ref->mBase->mIcon; std::string text; @@ -115,7 +116,8 @@ namespace MWClass text += MWGui::ToolTips::getWeightString(ref->mBase->mData.mWeight, "#{sWeight}"); text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); - if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { + if (MWBase::Environment::get().getWindowManager()->getFullHelp()) + { text += MWGui::ToolTips::getCellRefString(ptr.getCellRef()); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); } @@ -125,26 +127,26 @@ namespace MWClass return info; } - MWWorld::Ptr Repair::copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const + MWWorld::Ptr Repair::copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return MWWorld::Ptr(cell.insert(ref), &cell); } - std::unique_ptr Repair::use (const MWWorld::Ptr& ptr, bool force) const + std::unique_ptr Repair::use(const MWWorld::Ptr& ptr, bool force) const { return std::make_unique(ptr, force); } - bool Repair::canSell (const MWWorld::ConstPtr& item, int npcServices) const + bool Repair::canSell(const MWWorld::ConstPtr& item, int npcServices) const { return (npcServices & ESM::NPC::RepairItem) != 0; } - float Repair::getWeight(const MWWorld::ConstPtr &ptr) const + float Repair::getWeight(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mData.mWeight; } } diff --git a/apps/openmw/mwclass/repair.hpp b/apps/openmw/mwclass/repair.hpp index 6f84ecd854..02a69fdd0f 100644 --- a/apps/openmw/mwclass/repair.hpp +++ b/apps/openmw/mwclass/repair.hpp @@ -7,58 +7,57 @@ namespace MWClass { class Repair : public MWWorld::RegisteredClass { - friend MWWorld::RegisteredClass; + friend MWWorld::RegisteredClass; - Repair(); + Repair(); - MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const override; - public: + public: + void insertObjectRendering(const MWWorld::Ptr& ptr, const std::string& model, + MWRender::RenderingInterface& renderingInterface) const override; + ///< Add reference into a cell for rendering - void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; - ///< Add reference into a cell for rendering + std::string_view getName(const MWWorld::ConstPtr& ptr) const override; + ///< \return name or ID; can return an empty string. - std::string_view getName(const MWWorld::ConstPtr& ptr) const override; - ///< \return name or ID; can return an empty string. + std::unique_ptr activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const override; + ///< Generate action for activation - std::unique_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const override; - ///< Generate action for activation + MWGui::ToolTipInfo getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const override; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. - MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const override; - ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + std::string_view getScript(const MWWorld::ConstPtr& ptr) const override; + ///< Return name of the script attached to ptr - std::string_view getScript(const MWWorld::ConstPtr& ptr) const override; - ///< Return name of the script attached to ptr + int getValue(const MWWorld::ConstPtr& ptr) const override; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. - int getValue (const MWWorld::ConstPtr& ptr) const override; - ///< Return trade value of the object. Throws an exception, if the object can't be traded. + std::string_view getUpSoundId(const MWWorld::ConstPtr& ptr) const override; + ///< Return the pick up sound Id - std::string_view getUpSoundId(const MWWorld::ConstPtr& ptr) const override; - ///< Return the pick up sound Id + std::string_view getDownSoundId(const MWWorld::ConstPtr& ptr) const override; + ///< Return the put down sound Id - std::string_view getDownSoundId(const MWWorld::ConstPtr& ptr) const override; - ///< Return the put down sound Id + const std::string& getInventoryIcon(const MWWorld::ConstPtr& ptr) const override; + ///< Return name of inventory icon. - const std::string& getInventoryIcon(const MWWorld::ConstPtr& ptr) const override; - ///< Return name of inventory icon. + std::string getModel(const MWWorld::ConstPtr& ptr) const override; - std::string getModel(const MWWorld::ConstPtr &ptr) const override; + std::unique_ptr use(const MWWorld::Ptr& ptr, bool force = false) const override; + ///< Generate action for using via inventory menu (default implementation: return a + /// null action). - std::unique_ptr use (const MWWorld::Ptr& ptr, bool force=false) const override; - ///< Generate action for using via inventory menu (default implementation: return a - /// null action). + bool hasItemHealth(const MWWorld::ConstPtr& ptr) const override; + ///< \return Item health data available? (default implementation: false) - bool hasItemHealth (const MWWorld::ConstPtr& ptr) const override; - ///< \return Item health data available? (default implementation: false) + int getItemMaxHealth(const MWWorld::ConstPtr& ptr) const override; + ///< Return item max health or throw an exception, if class does not have item health + /// (default implementation: throw an exception) - int getItemMaxHealth (const MWWorld::ConstPtr& ptr) const override; - ///< Return item max health or throw an exception, if class does not have item health - /// (default implementation: throw an exception) + float getWeight(const MWWorld::ConstPtr& ptr) const override; - float getWeight (const MWWorld::ConstPtr& ptr) const override; - - bool canSell (const MWWorld::ConstPtr& item, int npcServices) const override; + bool canSell(const MWWorld::ConstPtr& item, int npcServices) const override; }; } diff --git a/apps/openmw/mwclass/static.cpp b/apps/openmw/mwclass/static.cpp index 1d1e45d7f7..c54e1088d3 100644 --- a/apps/openmw/mwclass/static.cpp +++ b/apps/openmw/mwclass/static.cpp @@ -3,9 +3,9 @@ #include #include -#include "../mwworld/ptr.hpp" #include "../mwphysics/physicssystem.hpp" #include "../mwworld/cellstore.hpp" +#include "../mwworld/ptr.hpp" #include "../mwrender/objects.hpp" #include "../mwrender/renderinginterface.hpp" @@ -20,7 +20,8 @@ namespace MWClass { } - void Static::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const + void Static::insertObjectRendering( + const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const { if (!model.empty()) { @@ -29,17 +30,19 @@ namespace MWClass } } - void Static::insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const + void Static::insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, + MWPhysics::PhysicsSystem& physics) const { insertObjectPhysics(ptr, model, rotation, physics); } - void Static::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const + void Static::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, + MWPhysics::PhysicsSystem& physics) const { physics.addObject(ptr, model, rotation, MWPhysics::CollisionType_World); } - std::string Static::getModel(const MWWorld::ConstPtr &ptr) const + std::string Static::getModel(const MWWorld::ConstPtr& ptr) const { return getClassModel(ptr); } @@ -54,9 +57,9 @@ namespace MWClass return false; } - MWWorld::Ptr Static::copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const + MWWorld::Ptr Static::copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return MWWorld::Ptr(cell.insert(ref), &cell); } diff --git a/apps/openmw/mwclass/static.hpp b/apps/openmw/mwclass/static.hpp index 88cf982d1c..c6b2c3e6f9 100644 --- a/apps/openmw/mwclass/static.hpp +++ b/apps/openmw/mwclass/static.hpp @@ -7,27 +7,29 @@ namespace MWClass { class Static : public MWWorld::RegisteredClass { - friend MWWorld::RegisteredClass; + friend MWWorld::RegisteredClass; - Static(); + Static(); - MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const override; - public: + public: + void insertObjectRendering(const MWWorld::Ptr& ptr, const std::string& model, + MWRender::RenderingInterface& renderingInterface) const override; + ///< Add reference into a cell for rendering - void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; - ///< Add reference into a cell for rendering + void insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, + MWPhysics::PhysicsSystem& physics) const override; + void insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, + MWPhysics::PhysicsSystem& physics) const override; - void insertObject(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const override; - void insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const override; + std::string_view getName(const MWWorld::ConstPtr& ptr) const override; + ///< \return name or ID; can return an empty string. - std::string_view getName(const MWWorld::ConstPtr& ptr) const override; - ///< \return name or ID; can return an empty string. + bool hasToolTip(const MWWorld::ConstPtr& ptr) const override; + ///< @return true if this object has a tooltip when focused (default implementation: true) - bool hasToolTip (const MWWorld::ConstPtr& ptr) const override; - ///< @return true if this object has a tooltip when focused (default implementation: true) - - std::string getModel(const MWWorld::ConstPtr &ptr) const override; + std::string getModel(const MWWorld::ConstPtr& ptr) const override; }; } diff --git a/apps/openmw/mwclass/weapon.cpp b/apps/openmw/mwclass/weapon.cpp index 3e58f68e7e..9c730953bc 100644 --- a/apps/openmw/mwclass/weapon.cpp +++ b/apps/openmw/mwclass/weapon.cpp @@ -2,21 +2,21 @@ #include -#include #include +#include #include #include #include "../mwbase/environment.hpp" #include "../mwbase/mechanicsmanager.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" -#include "../mwworld/ptr.hpp" #include "../mwworld/actionequip.hpp" -#include "../mwworld/inventorystore.hpp" #include "../mwworld/cellstore.hpp" #include "../mwworld/esmstore.hpp" +#include "../mwworld/inventorystore.hpp" +#include "../mwworld/ptr.hpp" #include "../mwmechanics/weapontype.hpp" @@ -35,58 +35,58 @@ namespace MWClass { } - void Weapon::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const + void Weapon::insertObjectRendering( + const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const { - if (!model.empty()) { + if (!model.empty()) + { renderingInterface.getObjects().insertModel(ptr, model); } } - std::string Weapon::getModel(const MWWorld::ConstPtr &ptr) const + std::string Weapon::getModel(const MWWorld::ConstPtr& ptr) const { return getClassModel(ptr); } std::string_view Weapon::getName(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); const std::string& name = ref->mBase->mName; return !name.empty() ? name : ref->mBase->mId; } - std::unique_ptr Weapon::activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const + std::unique_ptr Weapon::activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const { return defaultItemActivate(ptr, actor); } - bool Weapon::hasItemHealth (const MWWorld::ConstPtr& ptr) const + bool Weapon::hasItemHealth(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); int type = ref->mBase->mData.mType; return MWMechanics::getWeaponType(type)->mFlags & ESM::WeaponType::HasHealth; } - int Weapon::getItemMaxHealth (const MWWorld::ConstPtr& ptr) const + int Weapon::getItemMaxHealth(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mData.mHealth; } std::string_view Weapon::getScript(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = - ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mScript; } - std::pair, bool> Weapon::getEquipmentSlots (const MWWorld::ConstPtr& ptr) const + std::pair, bool> Weapon::getEquipmentSlots(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); ESM::WeaponType::Class weapClass = MWMechanics::getWeaponType(ref->mBase->mData.mType)->mWeaponClass; std::vector slots_; @@ -94,64 +94,65 @@ namespace MWClass if (weapClass == ESM::WeaponType::Ammo) { - slots_.push_back (int (MWWorld::InventoryStore::Slot_Ammunition)); + slots_.push_back(int(MWWorld::InventoryStore::Slot_Ammunition)); stack = true; } else if (weapClass == ESM::WeaponType::Thrown) { - slots_.push_back (int (MWWorld::InventoryStore::Slot_CarriedRight)); + slots_.push_back(int(MWWorld::InventoryStore::Slot_CarriedRight)); stack = true; } else - slots_.push_back (int (MWWorld::InventoryStore::Slot_CarriedRight)); + slots_.push_back(int(MWWorld::InventoryStore::Slot_CarriedRight)); - return std::make_pair (slots_, stack); + return std::make_pair(slots_, stack); } - int Weapon::getEquipmentSkill (const MWWorld::ConstPtr& ptr) const + int Weapon::getEquipmentSkill(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); int type = ref->mBase->mData.mType; return MWMechanics::getWeaponType(type)->mSkill; } - int Weapon::getValue (const MWWorld::ConstPtr& ptr) const + int Weapon::getValue(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mData.mValue; } std::string_view Weapon::getUpSoundId(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); int type = ref->mBase->mData.mType; return MWMechanics::getWeaponType(type)->mSoundIdUp; } std::string_view Weapon::getDownSoundId(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); int type = ref->mBase->mData.mType; return MWMechanics::getWeaponType(type)->mSoundIdDown; } const std::string& Weapon::getInventoryIcon(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mIcon; } - MWGui::ToolTipInfo Weapon::getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const + MWGui::ToolTipInfo Weapon::getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); const ESM::WeaponType* weaponType = MWMechanics::getWeaponType(ref->mBase->mData.mType); MWGui::ToolTipInfo info; std::string_view name = getName(ptr); - info.caption = MyGUI::TextIterator::toTagsString(MWGui::toUString(name)) + MWGui::ToolTips::getCountString(count); + info.caption + = MyGUI::TextIterator::toTagsString(MWGui::toUString(name)) + MWGui::ToolTips::getCountString(count); info.icon = ref->mBase->mIcon; const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); @@ -159,7 +160,8 @@ namespace MWClass std::string text; // weapon type & damage - if (weaponType->mWeaponClass != ESM::WeaponType::Ammo || Settings::Manager::getBool("show projectile damage", "Game")) + if (weaponType->mWeaponClass != ESM::WeaponType::Ammo + || Settings::Manager::getBool("show projectile damage", "Game")) { text += "\n#{sType} "; @@ -183,30 +185,25 @@ namespace MWClass { // Thrown weapons have 2x real damage applied // as they're both the weapon and the ammo - text += "\n#{sAttack}: " - + MWGui::ToolTips::toString(static_cast(ref->mBase->mData.mChop[0] * 2)) + text += "\n#{sAttack}: " + MWGui::ToolTips::toString(static_cast(ref->mBase->mData.mChop[0] * 2)) + " - " + MWGui::ToolTips::toString(static_cast(ref->mBase->mData.mChop[1] * 2)); } else if (weaponType->mWeaponClass == ESM::WeaponType::Melee) { // Chop - text += "\n#{sChop}: " - + MWGui::ToolTips::toString(static_cast(ref->mBase->mData.mChop[0])) - + " - " + MWGui::ToolTips::toString(static_cast(ref->mBase->mData.mChop[1])); + text += "\n#{sChop}: " + MWGui::ToolTips::toString(static_cast(ref->mBase->mData.mChop[0])) + " - " + + MWGui::ToolTips::toString(static_cast(ref->mBase->mData.mChop[1])); // Slash - text += "\n#{sSlash}: " - + MWGui::ToolTips::toString(static_cast(ref->mBase->mData.mSlash[0])) + text += "\n#{sSlash}: " + MWGui::ToolTips::toString(static_cast(ref->mBase->mData.mSlash[0])) + " - " + MWGui::ToolTips::toString(static_cast(ref->mBase->mData.mSlash[1])); // Thrust - text += "\n#{sThrust}: " - + MWGui::ToolTips::toString(static_cast(ref->mBase->mData.mThrust[0])) + text += "\n#{sThrust}: " + MWGui::ToolTips::toString(static_cast(ref->mBase->mData.mThrust[0])) + " - " + MWGui::ToolTips::toString(static_cast(ref->mBase->mData.mThrust[1])); } else { // marksman - text += "\n#{sAttack}: " - + MWGui::ToolTips::toString(static_cast(ref->mBase->mData.mChop[0])) + text += "\n#{sAttack}: " + MWGui::ToolTips::toString(static_cast(ref->mBase->mData.mChop[0])) + " - " + MWGui::ToolTips::toString(static_cast(ref->mBase->mData.mChop[1])); } } @@ -215,7 +212,7 @@ namespace MWClass { int remainingHealth = getItemHealth(ptr); text += "\n#{sCondition}: " + MWGui::ToolTips::toString(remainingHealth) + "/" - + MWGui::ToolTips::toString(ref->mBase->mData.mHealth); + + MWGui::ToolTips::toString(ref->mBase->mData.mHealth); } const bool verbose = Settings::Manager::getBool("show melee info", "Game"); @@ -223,7 +220,8 @@ namespace MWClass if (weaponType->mWeaponClass == ESM::WeaponType::Melee && verbose) { // display value in feet - const float combatDistance = store.get().find("fCombatDistance")->mValue.getFloat() * ref->mBase->mData.mReach; + const float combatDistance + = store.get().find("fCombatDistance")->mValue.getFloat() * ref->mBase->mData.mReach; text += MWGui::ToolTips::getWeightString(combatDistance / Constants::UnitsPerFoot, "#{sRange}"); text += " #{sFeet}"; } @@ -242,7 +240,8 @@ namespace MWClass if (!info.enchant.empty()) info.remainingEnchantCharge = static_cast(ptr.getCellRef().getEnchantmentCharge()); - if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { + if (MWBase::Environment::get().getWindowManager()->getFullHelp()) + { text += MWGui::ToolTips::getCellRefString(ptr.getCellRef()); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); } @@ -254,50 +253,51 @@ namespace MWClass std::string_view Weapon::getEnchantment(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mEnchant; } - const std::string& Weapon::applyEnchantment(const MWWorld::ConstPtr& ptr, const std::string& enchId, int enchCharge, const std::string& newName) const + const std::string& Weapon::applyEnchantment( + const MWWorld::ConstPtr& ptr, const std::string& enchId, int enchCharge, const std::string& newName) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); ESM::Weapon newItem = *ref->mBase; newItem.mId.clear(); - newItem.mName=newName; - newItem.mData.mEnchant=enchCharge; - newItem.mEnchant=enchId; + newItem.mName = newName; + newItem.mData.mEnchant = enchCharge; + newItem.mEnchant = enchId; newItem.mData.mFlags |= ESM::Weapon::Magical; - const ESM::Weapon *record = MWBase::Environment::get().getWorld()->createRecord (newItem); + const ESM::Weapon* record = MWBase::Environment::get().getWorld()->createRecord(newItem); return record->mId; } std::pair Weapon::canBeEquipped(const MWWorld::ConstPtr& ptr, const MWWorld::Ptr& npc) const { if (hasItemHealth(ptr) && getItemHealth(ptr) == 0) - return {0, "#{sInventoryMessage1}"}; + return { 0, "#{sInventoryMessage1}" }; // Do not allow equip weapons from inventory during attack if (MWBase::Environment::get().getMechanicsManager()->isAttackingOrSpell(npc) && MWBase::Environment::get().getWindowManager()->isGuiMode()) - return {0, "#{sCantEquipWeapWarning}"}; + return { 0, "#{sCantEquipWeapWarning}" }; std::pair, bool> slots_ = getEquipmentSlots(ptr); if (slots_.first.empty()) - return {0, {}}; + return { 0, {} }; int type = ptr.get()->mBase->mData.mType; - if(MWMechanics::getWeaponType(type)->mFlags & ESM::WeaponType::TwoHanded) + if (MWMechanics::getWeaponType(type)->mFlags & ESM::WeaponType::TwoHanded) { - return {2, {}}; + return { 2, {} }; } - return {1, {}}; + return { 1, {} }; } - std::unique_ptr Weapon::use (const MWWorld::Ptr& ptr, bool force) const + std::unique_ptr Weapon::use(const MWWorld::Ptr& ptr, bool force) const { std::unique_ptr action = std::make_unique(ptr, force); @@ -306,29 +306,29 @@ namespace MWClass return action; } - MWWorld::Ptr Weapon::copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const + MWWorld::Ptr Weapon::copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return MWWorld::Ptr(cell.insert(ref), &cell); } - int Weapon::getEnchantmentPoints (const MWWorld::ConstPtr& ptr) const + int Weapon::getEnchantmentPoints(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mData.mEnchant; } - bool Weapon::canSell (const MWWorld::ConstPtr& item, int npcServices) const + bool Weapon::canSell(const MWWorld::ConstPtr& item, int npcServices) const { return (npcServices & ESM::NPC::Weapon) - || ((npcServices & ESM::NPC::MagicItems) && !getEnchantment(item).empty()); + || ((npcServices & ESM::NPC::MagicItems) && !getEnchantment(item).empty()); } - float Weapon::getWeight(const MWWorld::ConstPtr &ptr) const + float Weapon::getWeight(const MWWorld::ConstPtr& ptr) const { - const MWWorld::LiveCellRef *ref = ptr.get(); + const MWWorld::LiveCellRef* ref = ptr.get(); return ref->mBase->mData.mWeight; } } diff --git a/apps/openmw/mwclass/weapon.hpp b/apps/openmw/mwclass/weapon.hpp index ec0d63a65e..9f07f5f6dd 100644 --- a/apps/openmw/mwclass/weapon.hpp +++ b/apps/openmw/mwclass/weapon.hpp @@ -7,76 +7,78 @@ namespace MWClass { class Weapon : public MWWorld::RegisteredClass { - friend MWWorld::RegisteredClass; + friend MWWorld::RegisteredClass; - MWWorld::Ptr - copyToCellImpl(const MWWorld::ConstPtr &ptr, MWWorld::CellStore &cell) const override; + MWWorld::Ptr copyToCellImpl(const MWWorld::ConstPtr& ptr, MWWorld::CellStore& cell) const override; - public: - Weapon(); + public: + Weapon(); - void insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const override; - ///< Add reference into a cell for rendering + void insertObjectRendering(const MWWorld::Ptr& ptr, const std::string& model, + MWRender::RenderingInterface& renderingInterface) const override; + ///< Add reference into a cell for rendering - std::string_view getName(const MWWorld::ConstPtr& ptr) const override; - ///< \return name or ID; can return an empty string. + std::string_view getName(const MWWorld::ConstPtr& ptr) const override; + ///< \return name or ID; can return an empty string. - std::unique_ptr activate (const MWWorld::Ptr& ptr, - const MWWorld::Ptr& actor) const override; - ///< Generate action for activation + std::unique_ptr activate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const override; + ///< Generate action for activation - MWGui::ToolTipInfo getToolTipInfo (const MWWorld::ConstPtr& ptr, int count) const override; - ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + MWGui::ToolTipInfo getToolTipInfo(const MWWorld::ConstPtr& ptr, int count) const override; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. - bool hasItemHealth (const MWWorld::ConstPtr& ptr) const override; - ///< \return Item health data available? + bool hasItemHealth(const MWWorld::ConstPtr& ptr) const override; + ///< \return Item health data available? - int getItemMaxHealth (const MWWorld::ConstPtr& ptr) const override; - ///< Return item max health or throw an exception, if class does not have item health + int getItemMaxHealth(const MWWorld::ConstPtr& ptr) const override; + ///< Return item max health or throw an exception, if class does not have item health - std::string_view getScript(const MWWorld::ConstPtr& ptr) const override; - ///< Return name of the script attached to ptr + std::string_view getScript(const MWWorld::ConstPtr& ptr) const override; + ///< Return name of the script attached to ptr - std::pair, bool> getEquipmentSlots (const MWWorld::ConstPtr& ptr) const override; - ///< \return first: Return IDs of the slot this object can be equipped in; second: can object - /// stay stacked when equipped? + std::pair, bool> getEquipmentSlots(const MWWorld::ConstPtr& ptr) const override; + ///< \return first: Return IDs of the slot this object can be equipped in; second: can object + /// stay stacked when equipped? - int getEquipmentSkill (const MWWorld::ConstPtr& ptr) const override; - /// Return the index of the skill this item corresponds to when equipped or -1, if there is - /// no such skill. + int getEquipmentSkill(const MWWorld::ConstPtr& ptr) const override; + /// Return the index of the skill this item corresponds to when equipped or -1, if there is + /// no such skill. - int getValue (const MWWorld::ConstPtr& ptr) const override; - ///< Return trade value of the object. Throws an exception, if the object can't be traded. + int getValue(const MWWorld::ConstPtr& ptr) const override; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. - std::string_view getUpSoundId(const MWWorld::ConstPtr& ptr) const override; - ///< Return the pick up sound Id + std::string_view getUpSoundId(const MWWorld::ConstPtr& ptr) const override; + ///< Return the pick up sound Id - std::string_view getDownSoundId(const MWWorld::ConstPtr& ptr) const override; - ///< Return the put down sound Id + std::string_view getDownSoundId(const MWWorld::ConstPtr& ptr) const override; + ///< Return the put down sound Id - const std::string& getInventoryIcon(const MWWorld::ConstPtr& ptr) const override; - ///< Return name of inventory icon. + const std::string& getInventoryIcon(const MWWorld::ConstPtr& ptr) const override; + ///< Return name of inventory icon. - std::string_view getEnchantment(const MWWorld::ConstPtr& ptr) const override; - ///< @return the enchantment ID if the object is enchanted, otherwise an empty string + std::string_view getEnchantment(const MWWorld::ConstPtr& ptr) const override; + ///< @return the enchantment ID if the object is enchanted, otherwise an empty string - const std::string& applyEnchantment(const MWWorld::ConstPtr& ptr, const std::string& enchId, int enchCharge, const std::string& newName) const override; - ///< Creates a new record using \a ptr as template, with the given name and the given enchantment applied to it. + const std::string& applyEnchantment(const MWWorld::ConstPtr& ptr, const std::string& enchId, int enchCharge, + const std::string& newName) const override; + ///< Creates a new record using \a ptr as template, with the given name and the given enchantment applied to it. - std::pair canBeEquipped(const MWWorld::ConstPtr& ptr, const MWWorld::Ptr& npc) const override; - ///< Return 0 if player cannot equip item. 1 if can equip. 2 if it's twohanded weapon. 3 if twohanded weapon conflicts with that. - /// Second item in the pair specifies the error message + std::pair canBeEquipped( + const MWWorld::ConstPtr& ptr, const MWWorld::Ptr& npc) const override; + ///< Return 0 if player cannot equip item. 1 if can equip. 2 if it's twohanded weapon. 3 if twohanded weapon + ///< conflicts with that. + /// Second item in the pair specifies the error message - std::unique_ptr use (const MWWorld::Ptr& ptr, bool force=false) const override; - ///< Generate action for using via inventory menu + std::unique_ptr use(const MWWorld::Ptr& ptr, bool force = false) const override; + ///< Generate action for using via inventory menu - std::string getModel(const MWWorld::ConstPtr &ptr) const override; + std::string getModel(const MWWorld::ConstPtr& ptr) const override; - bool canSell (const MWWorld::ConstPtr& item, int npcServices) const override; + bool canSell(const MWWorld::ConstPtr& item, int npcServices) const override; - float getWeight (const MWWorld::ConstPtr& ptr) const override; + float getWeight(const MWWorld::ConstPtr& ptr) const override; - int getEnchantmentPoints (const MWWorld::ConstPtr& ptr) const override; + int getEnchantmentPoints(const MWWorld::ConstPtr& ptr) const override; }; } diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index 1f076e6735..690f05d51f 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -6,62 +6,63 @@ #include -#include -#include #include #include +#include #include +#include -#include #include -#include +#include #include #include +#include #include -#include #include +#include #include #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/journal.hpp" -#include "../mwbase/scriptmanager.hpp" -#include "../mwbase/windowmanager.hpp" #include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/scriptmanager.hpp" #include "../mwbase/soundmanager.hpp" +#include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" #include "../mwworld/class.hpp" #include "../mwworld/containerstore.hpp" #include "../mwworld/esmstore.hpp" #include "../mwscript/compilercontext.hpp" -#include "../mwscript/interpretercontext.hpp" #include "../mwscript/extensions.hpp" +#include "../mwscript/interpretercontext.hpp" +#include "../mwmechanics/actorutil.hpp" #include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/npcstats.hpp" -#include "../mwmechanics/actorutil.hpp" #include "filter.hpp" #include "hypertextparser.hpp" namespace MWDialogue { - DialogueManager::DialogueManager (const Compiler::Extensions& extensions, Translation::Storage& translationDataStorage) : - mTranslationDataStorage(translationDataStorage) - , mCompilerContext (MWScript::CompilerContext::Type_Dialogue) - , mErrorHandler() - , mTalkedTo(false) - , mOriginalDisposition(0) - , mCurrentDisposition(0) - , mPermanentDispositionChange(0) + DialogueManager::DialogueManager( + const Compiler::Extensions& extensions, Translation::Storage& translationDataStorage) + : mTranslationDataStorage(translationDataStorage) + , mCompilerContext(MWScript::CompilerContext::Type_Dialogue) + , mErrorHandler() + , mTalkedTo(false) + , mOriginalDisposition(0) + , mCurrentDisposition(0) + , mPermanentDispositionChange(0) { mChoice = -1; mIsInChoice = false; mGoodbye = false; - mCompilerContext.setExtensions (&extensions); + mCompilerContext.setExtensions(&extensions); } void DialogueManager::clear() @@ -75,10 +76,10 @@ namespace MWDialogue void DialogueManager::addTopic(std::string_view topic) { - mKnownTopics.insert( Misc::StringUtils::lowerCase(topic) ); + mKnownTopics.insert(Misc::StringUtils::lowerCase(topic)); } - std::vector DialogueManager::parseTopicIdsFromText (const std::string& text) + std::vector DialogueManager::parseTopicIdsFromText(const std::string& text) { std::vector topicIdList; @@ -92,7 +93,7 @@ namespace MWDialogue { // calculation of standard form for all hyperlinks size_t asterisk_count = HyperTextParser::removePseudoAsterisks(topicId); - for(; asterisk_count > 0; --asterisk_count) + for (; asterisk_count > 0; --asterisk_count) topicId.append("*"); topicId = mTranslationDataStorage.topicStandardForm(topicId); @@ -104,24 +105,24 @@ namespace MWDialogue return topicIdList; } - void DialogueManager::addTopicsFromText (const std::string& text) + void DialogueManager::addTopicsFromText(const std::string& text) { updateActorKnownTopics(); for (const auto& topicId : parseTopicIdsFromText(text)) { - if (mActorKnownTopics.count( topicId )) - mKnownTopics.insert( topicId ); + if (mActorKnownTopics.count(topicId)) + mKnownTopics.insert(topicId); } } void DialogueManager::updateOriginalDisposition() { - if(mActor.getClass().isNpc()) + if (mActor.getClass().isNpc()) { const auto& stats = mActor.getClass().getNpcStats(mActor); // Disposition changed by script; discard our preconceived notions - if(stats.getBaseDisposition() != mCurrentDisposition) + if (stats.getBaseDisposition() != mCurrentDisposition) { mCurrentDisposition = stats.getBaseDisposition(); mOriginalDisposition = mCurrentDisposition; @@ -129,7 +130,7 @@ namespace MWDialogue } } - bool DialogueManager::startDialogue (const MWWorld::Ptr& actor, ResponseCallback* callback) + bool DialogueManager::startDialogue(const MWWorld::Ptr& actor, ResponseCallback* callback) { updateGlobals(); @@ -147,23 +148,23 @@ namespace MWDialogue mActor = actor; - MWMechanics::CreatureStats& creatureStats = actor.getClass().getCreatureStats (actor); + MWMechanics::CreatureStats& creatureStats = actor.getClass().getCreatureStats(actor); mTalkedTo = creatureStats.hasTalkedToPlayer(); mActorKnownTopics.clear(); - //greeting - const MWWorld::Store &dialogs = - MWBase::Environment::get().getWorld()->getStore().get(); + // greeting + const MWWorld::Store& dialogs + = MWBase::Environment::get().getWorld()->getStore().get(); - Filter filter (actor, mChoice, mTalkedTo); + Filter filter(actor, mChoice, mTalkedTo); for (MWWorld::Store::iterator it = dialogs.begin(); it != dialogs.end(); ++it) { - if(it->mType == ESM::Dialogue::Greeting) + if (it->mType == ESM::Dialogue::Greeting) { // Search a response (we do not accept a fallback to "Info refusal" here) - if (const ESM::DialInfo *info = filter.search (*it, false)) + if (const ESM::DialInfo* info = filter.search(*it, false)) { creatureStats.talkedToPlayer(); @@ -172,12 +173,12 @@ namespace MWDialogue // TODO play sound } - MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor); + MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(), mActor); callback->addResponse("", Interpreter::fixDefinesDialog(info->mResponse, interpreterContext)); - executeScript (info->mResultScript, mActor); + executeScript(info->mResultScript, mActor); mLastTopic = it->mId; - addTopicsFromText (info->mResponse); + addTopicsFromText(info->mResponse); return true; } @@ -186,7 +187,8 @@ namespace MWDialogue return false; } - bool DialogueManager::compile (const std::string& cmd, std::vector& code, const MWWorld::Ptr& actor) + bool DialogueManager::compile( + const std::string& cmd, std::vector& code, const MWWorld::Ptr& actor) { bool success = true; @@ -196,9 +198,9 @@ namespace MWDialogue mErrorHandler.setContext("[dialogue script]"); - std::istringstream input (cmd + "\n"); + std::istringstream input(cmd + "\n"); - Compiler::Scanner scanner (mErrorHandler, input, mCompilerContext.getExtensions()); + Compiler::Scanner scanner(mErrorHandler, input, mCompilerContext.getExtensions()); Compiler::Locals locals; @@ -207,18 +209,18 @@ namespace MWDialogue if (!actorScript.empty()) { // grab local variables from actor's script, if available. - locals = MWBase::Environment::get().getScriptManager()->getLocals (actorScript); + locals = MWBase::Environment::get().getScriptManager()->getLocals(actorScript); } - Compiler::ScriptParser parser(mErrorHandler,mCompilerContext, locals, false); + Compiler::ScriptParser parser(mErrorHandler, mCompilerContext, locals, false); - scanner.scan (parser); + scanner.scan(parser); if (!mErrorHandler.isGood()) success = false; if (success) - parser.getCode (code); + parser.getCode(code); } catch (const Compiler::SourceException& /* error */) { @@ -227,7 +229,7 @@ namespace MWDialogue } catch (const std::exception& error) { - Log(Debug::Error) << std::string ("Dialogue error: An exception has been thrown: ") + error.what(); + Log(Debug::Error) << std::string("Dialogue error: An exception has been thrown: ") + error.what(); success = false; } @@ -239,29 +241,29 @@ namespace MWDialogue return success; } - void DialogueManager::executeScript (const std::string& script, const MWWorld::Ptr& actor) + void DialogueManager::executeScript(const std::string& script, const MWWorld::Ptr& actor) { std::vector code; - if(compile(script, code, actor)) + if (compile(script, code, actor)) { try { MWScript::InterpreterContext interpreterContext(&actor.getRefData().getLocals(), actor); Interpreter::Interpreter interpreter; - MWScript::installOpcodes (interpreter); - interpreter.run (code.data(), code.size(), interpreterContext); + MWScript::installOpcodes(interpreter); + interpreter.run(code.data(), code.size(), interpreterContext); } catch (const std::exception& error) { - Log(Debug::Error) << std::string ("Dialogue error: An exception has been thrown: ") + error.what(); + Log(Debug::Error) << std::string("Dialogue error: An exception has been thrown: ") + error.what(); } } } - bool DialogueManager::inJournal (const std::string& topicId, const std::string& infoId) + bool DialogueManager::inJournal(const std::string& topicId, const std::string& infoId) { - const MWDialogue::Topic *topicHistory = nullptr; - MWBase::Journal *journal = MWBase::Environment::get().getJournal(); + const MWDialogue::Topic* topicHistory = nullptr; + MWBase::Journal* journal = MWBase::Environment::get().getJournal(); for (auto it = journal->topicBegin(); it != journal->topicEnd(); ++it) { if (it->first == topicId) @@ -274,7 +276,7 @@ namespace MWDialogue if (!topicHistory) return false; - for(const auto& topic : *topicHistory) + for (const auto& topic : *topicHistory) { if (topic.mInfoId == infoId) return true; @@ -282,52 +284,52 @@ namespace MWDialogue return false; } - void DialogueManager::executeTopic (const std::string& topic, ResponseCallback* callback) + void DialogueManager::executeTopic(const std::string& topic, ResponseCallback* callback) { - Filter filter (mActor, mChoice, mTalkedTo); + Filter filter(mActor, mChoice, mTalkedTo); + + const MWWorld::Store& dialogues + = MWBase::Environment::get().getWorld()->getStore().get(); - const MWWorld::Store &dialogues = - MWBase::Environment::get().getWorld()->getStore().get(); + const ESM::Dialogue& dialogue = *dialogues.find(topic); - const ESM::Dialogue& dialogue = *dialogues.find (topic); + const ESM::DialInfo* info = mChoice == -1 && mActorKnownTopics.count(topic) ? mActorKnownTopics[topic].mInfo + : filter.search(dialogue, true); - const ESM::DialInfo* info = - mChoice == -1 && mActorKnownTopics.count(topic) ? - mActorKnownTopics[topic].mInfo : filter.search(dialogue, true); - if (info) { std::string title; - if (dialogue.mType==ESM::Dialogue::Persuasion) + if (dialogue.mType == ESM::Dialogue::Persuasion) { // Determine GMST from dialogue topic. GMSTs are: // sAdmireSuccess, sAdmireFail, sIntimidateSuccess, sIntimidateFail, // sTauntSuccess, sTauntFail, sBribeSuccess, sBribeFail std::string modifiedTopic = "s" + topic; - modifiedTopic.erase (std::remove (modifiedTopic.begin(), modifiedTopic.end(), ' '), modifiedTopic.end()); + modifiedTopic.erase(std::remove(modifiedTopic.begin(), modifiedTopic.end(), ' '), modifiedTopic.end()); - const MWWorld::Store& gmsts = - MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& gmsts + = MWBase::Environment::get().getWorld()->getStore().get(); - title = gmsts.find (modifiedTopic)->mValue.getString(); + title = gmsts.find(modifiedTopic)->mValue.getString(); } else title = topic; - MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor); + MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(), mActor); callback->addResponse(title, Interpreter::fixDefinesDialog(info->mResponse, interpreterContext)); if (dialogue.mType == ESM::Dialogue::Topic) { - // Make sure the returned DialInfo is from the Dialogue we supplied. If could also be from the Info refusal group, - // in which case it should not be added to the journal. + // Make sure the returned DialInfo is from the Dialogue we supplied. If could also be from the Info + // refusal group, in which case it should not be added to the journal. for (ESM::Dialogue::InfoContainer::const_iterator iter = dialogue.mInfo.begin(); - iter!=dialogue.mInfo.end(); ++iter) + iter != dialogue.mInfo.end(); ++iter) { if (iter->mId == info->mId) { - MWBase::Environment::get().getJournal()->addTopic (Misc::StringUtils::lowerCase(topic), info->mId, mActor); + MWBase::Environment::get().getJournal()->addTopic( + Misc::StringUtils::lowerCase(topic), info->mId, mActor); break; } } @@ -335,13 +337,13 @@ namespace MWDialogue mLastTopic = topic; - executeScript (info->mResultScript, mActor); + executeScript(info->mResultScript, mActor); - addTopicsFromText (info->mResponse); + addTopicsFromText(info->mResponse); } } - const ESM::Dialogue *DialogueManager::searchDialogue(const std::string& id) + const ESM::Dialogue* DialogueManager::searchDialogue(const std::string& id) { return MWBase::Environment::get().getWorld()->getStore().get().search(id); } @@ -359,7 +361,7 @@ namespace MWDialogue const auto& dialogs = MWBase::Environment::get().getWorld()->getStore().get(); - Filter filter (mActor, -1, mTalkedTo); + Filter filter(mActor, -1, mTalkedTo); for (const auto& dialog : dialogs) { @@ -371,7 +373,7 @@ namespace MWDialogue if (answer != nullptr) { int topicFlags = 0; - if(!inJournal(topicId, answer->mId)) + if (!inJournal(topicId, answer->mId)) { // Does this dialogue contains some actor-specific answer? if (Misc::StringUtils::ciEqual(answer->mActor, mActor.getCellRef().getRefId())) @@ -379,9 +381,8 @@ namespace MWDialogue } else topicFlags |= MWBase::DialogueManager::TopicType::Exhausted; - mActorKnownTopics.insert (std::make_pair(dialog.mId, ActorKnownTopicInfo {topicFlags, answer})); + mActorKnownTopics.insert(std::make_pair(dialog.mId, ActorKnownTopicInfo{ topicFlags, answer })); } - } } @@ -392,13 +393,12 @@ namespace MWDialogue // If the topic is not marked as exhausted, we don't need to do anything about it. // If the topic will not be shown to the player, the flag actually does not matter. - if (!(topicInfo.mFlags & MWBase::DialogueManager::TopicType::Exhausted) || - !mKnownTopics.count(dialogId)) + if (!(topicInfo.mFlags & MWBase::DialogueManager::TopicType::Exhausted) || !mKnownTopics.count(dialogId)) continue; for (const auto& topicId : parseTopicIdsFromText(topicInfo.mInfo->mResponse)) { - if (mActorKnownTopics.count( topicId ) && !mKnownTopics.count( topicId )) + if (mActorKnownTopics.count(topicId) && !mKnownTopics.count(topicId)) { topicInfo.mFlags &= ~MWBase::DialogueManager::TopicType::Exhausted; break; @@ -415,7 +415,7 @@ namespace MWDialogue for (const auto& [topic, topicInfo] : mActorKnownTopics) { - //does the player know the topic? + // does the player know the topic? if (mKnownTopics.count(topic)) keywordList.push_back(topic); } @@ -430,14 +430,14 @@ namespace MWDialogue return mActorKnownTopics[topicId].mFlags; } - void DialogueManager::keywordSelected (const std::string& keyword, ResponseCallback* callback) + void DialogueManager::keywordSelected(const std::string& keyword, ResponseCallback* callback) { - if(!mIsInChoice) + if (!mIsInChoice) { const ESM::Dialogue* dialogue = searchDialogue(keyword); if (dialogue && dialogue->mType == ESM::Dialogue::Topic) { - executeTopic (keyword, callback); + executeTopic(keyword, callback); } } } @@ -454,7 +454,8 @@ namespace MWDialogue { updateOriginalDisposition(); MWMechanics::NpcStats& npcStats = mActor.getClass().getNpcStats(mActor); - // Clamp permanent disposition change so that final disposition doesn't go below 0 (could happen with intimidate) + // Clamp permanent disposition change so that final disposition doesn't go below 0 (could happen with + // intimidate) npcStats.setBaseDisposition(0); int zero = MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mActor, false); int disposition = std::clamp(mOriginalDisposition + mPermanentDispositionChange, -zero, 100 - zero); @@ -466,45 +467,46 @@ namespace MWDialogue mCurrentDisposition = 0; } - void DialogueManager::questionAnswered (int answer, ResponseCallback* callback) + void DialogueManager::questionAnswered(int answer, ResponseCallback* callback) { mChoice = answer; const ESM::Dialogue* dialogue = searchDialogue(mLastTopic); if (dialogue) { - Filter filter (mActor, mChoice, mTalkedTo); + Filter filter(mActor, mChoice, mTalkedTo); if (dialogue->mType == ESM::Dialogue::Topic || dialogue->mType == ESM::Dialogue::Greeting) { - if (const ESM::DialInfo *info = filter.search (*dialogue, true)) + if (const ESM::DialInfo* info = filter.search(*dialogue, true)) { std::string text = info->mResponse; - addTopicsFromText (text); + addTopicsFromText(text); mChoice = -1; mIsInChoice = false; mChoices.clear(); - MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor); + MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(), mActor); callback->addResponse("", Interpreter::fixDefinesDialog(text, interpreterContext)); if (dialogue->mType == ESM::Dialogue::Topic) { - // Make sure the returned DialInfo is from the Dialogue we supplied. If could also be from the Info refusal group, - // in which case it should not be added to the journal + // Make sure the returned DialInfo is from the Dialogue we supplied. If could also be from the + // Info refusal group, in which case it should not be added to the journal for (ESM::Dialogue::InfoContainer::const_iterator iter = dialogue->mInfo.begin(); - iter!=dialogue->mInfo.end(); ++iter) + iter != dialogue->mInfo.end(); ++iter) { if (iter->mId == info->mId) { - MWBase::Environment::get().getJournal()->addTopic (Misc::StringUtils::lowerCase(mLastTopic), info->mId, mActor); + MWBase::Environment::get().getJournal()->addTopic( + Misc::StringUtils::lowerCase(mLastTopic), info->mId, mActor); break; } } } - executeScript (info->mResultScript, mActor); + executeScript(info->mResultScript, mActor); } else { @@ -524,7 +526,7 @@ namespace MWDialogue mChoices.emplace_back(text, choice); } - const std::vector >& DialogueManager::getChoices() + const std::vector>& DialogueManager::getChoices() { return mChoices; } @@ -545,10 +547,9 @@ namespace MWDialogue bool success; int temp, perm; MWBase::Environment::get().getMechanicsManager()->getPersuasionDispositionChange( - mActor, MWBase::MechanicsManager::PersuasionType(type), - success, temp, perm); + mActor, MWBase::MechanicsManager::PersuasionType(type), success, temp, perm); updateOriginalDisposition(); - if(temp > 0 && perm > 0 && mOriginalDisposition + perm + mPermanentDispositionChange < 0) + if (temp > 0 && perm > 0 && mOriginalDisposition + perm + mPermanentDispositionChange < 0) perm = -(mOriginalDisposition + mPermanentDispositionChange); mCurrentDisposition += temp; mActor.getClass().getNpcStats(mActor).setBaseDisposition(mCurrentDisposition); @@ -559,7 +560,7 @@ namespace MWDialogue if (success) { - int gold=0; + int gold = 0; if (type == MWBase::MechanicsManager::PT_Bribe10) gold = 10; else if (type == MWBase::MechanicsManager::PT_Bribe100) @@ -582,16 +583,17 @@ namespace MWDialogue text = "Taunt"; else if (type == MWBase::MechanicsManager::PT_Intimidate) text = "Intimidate"; - else{ + else + { text = "Bribe"; } - executeTopic (text + (success ? " Success" : " Fail"), callback); + executeTopic(text + (success ? " Success" : " Fail"), callback); } void DialogueManager::applyBarterDispositionChange(int delta) { - if(mActor.getClass().isNpc()) + if (mActor.getClass().isNpc()) { updateOriginalDisposition(); mCurrentDisposition += delta; @@ -603,37 +605,38 @@ namespace MWDialogue bool DialogueManager::checkServiceRefused(ResponseCallback* callback, ServiceType service) { - Filter filter (mActor, service, mTalkedTo); + Filter filter(mActor, service, mTalkedTo); - const MWWorld::Store &dialogues = - MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& dialogues + = MWBase::Environment::get().getWorld()->getStore().get(); - const ESM::Dialogue& dialogue = *dialogues.find ("Service Refusal"); + const ESM::Dialogue& dialogue = *dialogues.find("Service Refusal"); - std::vector infos = filter.list (dialogue, false, false, true); + std::vector infos = filter.list(dialogue, false, false, true); if (!infos.empty()) { const ESM::DialInfo* info = infos[0]; - addTopicsFromText (info->mResponse); + addTopicsFromText(info->mResponse); - const MWWorld::Store& gmsts = - MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& gmsts + = MWBase::Environment::get().getWorld()->getStore().get(); - MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor); + MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(), mActor); - callback->addResponse(gmsts.find ("sServiceRefusal")->mValue.getString(), Interpreter::fixDefinesDialog(info->mResponse, interpreterContext)); + callback->addResponse(gmsts.find("sServiceRefusal")->mValue.getString(), + Interpreter::fixDefinesDialog(info->mResponse, interpreterContext)); - executeScript (info->mResultScript, mActor); + executeScript(info->mResultScript, mActor); return true; } return false; } - void DialogueManager::say(const MWWorld::Ptr &actor, const std::string &topic) + void DialogueManager::say(const MWWorld::Ptr& actor, const std::string& topic) { - MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); - if(sndMgr->sayActive(actor)) + MWBase::SoundManager* sndMgr = MWBase::Environment::get().getSoundManager(); + if (sndMgr->sayActive(actor)) { // Actor is already saying something. return; @@ -651,16 +654,16 @@ namespace MWDialogue return; } - const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); - const ESM::Dialogue *dial = store.get().find(topic); + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + const ESM::Dialogue* dial = store.get().find(topic); const MWMechanics::CreatureStats& creatureStats = actor.getClass().getCreatureStats(actor); Filter filter(actor, 0, creatureStats.hasTalkedToPlayer()); - const ESM::DialInfo *info = filter.search(*dial, false); - if(info != nullptr) + const ESM::DialInfo* info = filter.search(*dial, false); + if (info != nullptr) { - MWBase::WindowManager *winMgr = MWBase::Environment::get().getWindowManager(); - if(winMgr->getSubtitlesEnabled()) + MWBase::WindowManager* winMgr = MWBase::Environment::get().getWindowManager(); + if (winMgr->getSubtitlesEnabled()) winMgr->messageBox(info->mResponse); if (!info->mSound.empty()) sndMgr->say(actor, info->mSound); @@ -674,7 +677,7 @@ namespace MWDialogue return 1; // known topics } - void DialogueManager::write (ESM::ESMWriter& writer, Loading::Listener& progress) const + void DialogueManager::write(ESM::ESMWriter& writer, Loading::Listener& progress) const { ESM::DialogueState state; @@ -683,24 +686,24 @@ namespace MWDialogue state.mChangedFactionReaction = mChangedFactionReaction; - writer.startRecord (ESM::REC_DIAS); - state.save (writer); - writer.endRecord (ESM::REC_DIAS); + writer.startRecord(ESM::REC_DIAS); + state.save(writer); + writer.endRecord(ESM::REC_DIAS); } - void DialogueManager::readRecord (ESM::ESMReader& reader, uint32_t type) + void DialogueManager::readRecord(ESM::ESMReader& reader, uint32_t type) { - if (type==ESM::REC_DIAS) + if (type == ESM::REC_DIAS) { const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); ESM::DialogueState state; - state.load (reader); + state.load(reader); - for (std::vector::const_iterator iter (state.mKnownTopics.begin()); - iter!=state.mKnownTopics.end(); ++iter) - if (store.get().search (*iter)) - mKnownTopics.insert (*iter); + for (std::vector::const_iterator iter(state.mKnownTopics.begin()); + iter != state.mKnownTopics.end(); ++iter) + if (store.get().search(*iter)) + mKnownTopics.insert(*iter); mChangedFactionReaction = state.mChangedFactionReaction; } @@ -749,17 +752,17 @@ namespace MWDialogue for (; it != faction->mReactions.end(); ++it) { if (Misc::StringUtils::ciEqual(it->first, fact2)) - return it->second; + return it->second; } return 0; } - void DialogueManager::clearInfoActor(const MWWorld::Ptr &actor) const + void DialogueManager::clearInfoActor(const MWWorld::Ptr& actor) const { if (actor == mActor && !mLastTopic.empty()) { MWBase::Environment::get().getJournal()->removeLastAddedTopicResponse( - Misc::StringUtils::lowerCase(mLastTopic), actor.getClass().getName(actor)); + Misc::StringUtils::lowerCase(mLastTopic), actor.getClass().getName(actor)); } } } diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.hpp b/apps/openmw/mwdialogue/dialoguemanagerimp.hpp index 322c454c42..ae6824c57c 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.hpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.hpp @@ -8,9 +8,9 @@ #include #include -#include -#include #include +#include +#include #include "../mwworld/ptr.hpp" @@ -25,107 +25,106 @@ namespace MWDialogue { class DialogueManager : public MWBase::DialogueManager { - struct ActorKnownTopicInfo - { - int mFlags; - const ESM::DialInfo* mInfo; - }; - - std::set mKnownTopics;// Those are the topics the player knows. + struct ActorKnownTopicInfo + { + int mFlags; + const ESM::DialInfo* mInfo; + }; - // Modified faction reactions. > - typedef std::map > ModFactionReactionMap; - ModFactionReactionMap mChangedFactionReaction; + std::set mKnownTopics; // Those are the topics the player knows. - std::map mActorKnownTopics; + // Modified faction reactions. > + typedef std::map> ModFactionReactionMap; + ModFactionReactionMap mChangedFactionReaction; - Translation::Storage& mTranslationDataStorage; - MWScript::CompilerContext mCompilerContext; - Compiler::StreamErrorHandler mErrorHandler; + std::map mActorKnownTopics; - MWWorld::Ptr mActor; - bool mTalkedTo; + Translation::Storage& mTranslationDataStorage; + MWScript::CompilerContext mCompilerContext; + Compiler::StreamErrorHandler mErrorHandler; - int mChoice; - std::string mLastTopic; // last topic ID, lowercase - bool mIsInChoice; - bool mGoodbye; + MWWorld::Ptr mActor; + bool mTalkedTo; - std::vector > mChoices; + int mChoice; + std::string mLastTopic; // last topic ID, lowercase + bool mIsInChoice; + bool mGoodbye; - int mOriginalDisposition; - int mCurrentDisposition; - int mPermanentDispositionChange; + std::vector> mChoices; - std::vector parseTopicIdsFromText (const std::string& text); - void addTopicsFromText (const std::string& text); + int mOriginalDisposition; + int mCurrentDisposition; + int mPermanentDispositionChange; - void updateActorKnownTopics(); - void updateGlobals(); + std::vector parseTopicIdsFromText(const std::string& text); + void addTopicsFromText(const std::string& text); - bool compile (const std::string& cmd, std::vector& code, const MWWorld::Ptr& actor); - void executeScript (const std::string& script, const MWWorld::Ptr& actor); + void updateActorKnownTopics(); + void updateGlobals(); - void executeTopic (const std::string& topic, ResponseCallback* callback); + bool compile(const std::string& cmd, std::vector& code, const MWWorld::Ptr& actor); + void executeScript(const std::string& script, const MWWorld::Ptr& actor); - const ESM::Dialogue* searchDialogue(const std::string& id); + void executeTopic(const std::string& topic, ResponseCallback* callback); - void updateOriginalDisposition(); + const ESM::Dialogue* searchDialogue(const std::string& id); - public: + void updateOriginalDisposition(); - DialogueManager (const Compiler::Extensions& extensions, Translation::Storage& translationDataStorage); + public: + DialogueManager(const Compiler::Extensions& extensions, Translation::Storage& translationDataStorage); - void clear() override; + void clear() override; - bool isInChoice() const override; + bool isInChoice() const override; - bool startDialogue (const MWWorld::Ptr& actor, ResponseCallback* callback) override; + bool startDialogue(const MWWorld::Ptr& actor, ResponseCallback* callback) override; - std::list getAvailableTopics() override; - int getTopicFlag(const std::string& topicId) override; + std::list getAvailableTopics() override; + int getTopicFlag(const std::string& topicId) override; - bool inJournal (const std::string& topicId, const std::string& infoId) override; + bool inJournal(const std::string& topicId, const std::string& infoId) override; - void addTopic(std::string_view topic) override; + void addTopic(std::string_view topic) override; - void addChoice(std::string_view text,int choice) override; - const std::vector >& getChoices() override; + void addChoice(std::string_view text, int choice) override; + const std::vector>& getChoices() override; - bool isGoodbye() override; + bool isGoodbye() override; - void goodbye() override; + void goodbye() override; - bool checkServiceRefused (ResponseCallback* callback, ServiceType service = ServiceType::Any) override; + bool checkServiceRefused(ResponseCallback* callback, ServiceType service = ServiceType::Any) override; - void say(const MWWorld::Ptr &actor, const std::string &topic) override; + void say(const MWWorld::Ptr& actor, const std::string& topic) override; - //calbacks for the GUI - void keywordSelected (const std::string& keyword, ResponseCallback* callback) override; - void goodbyeSelected() override; - void questionAnswered (int answer, ResponseCallback* callback) override; + // calbacks for the GUI + void keywordSelected(const std::string& keyword, ResponseCallback* callback) override; + void goodbyeSelected() override; + void questionAnswered(int answer, ResponseCallback* callback) override; - void persuade (int type, ResponseCallback* callback) override; + void persuade(int type, ResponseCallback* callback) override; - /// @note Controlled by an option, gets discarded when dialogue ends by default - void applyBarterDispositionChange (int delta) override; + /// @note Controlled by an option, gets discarded when dialogue ends by default + void applyBarterDispositionChange(int delta) override; - int countSavedGameRecords() const override; + int countSavedGameRecords() const override; - void write (ESM::ESMWriter& writer, Loading::Listener& progress) const override; + void write(ESM::ESMWriter& writer, Loading::Listener& progress) const override; - void readRecord (ESM::ESMReader& reader, uint32_t type) override; + void readRecord(ESM::ESMReader& reader, uint32_t type) override; - /// Changes faction1's opinion of faction2 by \a diff. - void modFactionReaction (std::string_view faction1, std::string_view faction2, int diff) override; + /// Changes faction1's opinion of faction2 by \a diff. + void modFactionReaction(std::string_view faction1, std::string_view faction2, int diff) override; - void setFactionReaction (std::string_view faction1, std::string_view faction2, int absolute) override; + void setFactionReaction(std::string_view faction1, std::string_view faction2, int absolute) override; - /// @return faction1's opinion of faction2 - int getFactionReaction (std::string_view faction1, std::string_view faction2) const override; + /// @return faction1's opinion of faction2 + int getFactionReaction(std::string_view faction1, std::string_view faction2) const override; - /// Removes the last added topic response for the given actor from the journal - void clearInfoActor (const MWWorld::Ptr& actor) const override; + /// Removes the last added topic response for the given actor from the journal + void clearInfoActor(const MWWorld::Ptr& actor) const override; }; } diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index 54e853e12b..6ecff18205 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -1,37 +1,37 @@ #include "filter.hpp" #include -#include -#include #include +#include +#include +#include "../mwbase/dialoguemanager.hpp" #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/journal.hpp" #include "../mwbase/mechanicsmanager.hpp" -#include "../mwbase/dialoguemanager.hpp" #include "../mwbase/scriptmanager.hpp" +#include "../mwbase/world.hpp" -#include "../mwworld/class.hpp" -#include "../mwworld/inventorystore.hpp" #include "../mwworld/cellstore.hpp" +#include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" +#include "../mwworld/inventorystore.hpp" -#include "../mwmechanics/npcstats.hpp" +#include "../mwmechanics/actorutil.hpp" #include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/magiceffects.hpp" -#include "../mwmechanics/actorutil.hpp" +#include "../mwmechanics/npcstats.hpp" #include "selectwrapper.hpp" -bool MWDialogue::Filter::testActor (const ESM::DialInfo& info) const +bool MWDialogue::Filter::testActor(const ESM::DialInfo& info) const { bool isCreature = (mActor.getType() != ESM::NPC::sRecordId); // actor id if (!info.mActor.empty()) { - if ( !Misc::StringUtils::ciEqual(info.mActor, mActor.getCellRef().getRefId())) + if (!Misc::StringUtils::ciEqual(info.mActor, mActor.getCellRef().getRefId())) return false; } else if (isCreature) @@ -46,7 +46,7 @@ bool MWDialogue::Filter::testActor (const ESM::DialInfo& info) const if (isCreature) return true; - MWWorld::LiveCellRef *cellRef = mActor.get(); + MWWorld::LiveCellRef* cellRef = mActor.get(); if (!Misc::StringUtils::ciEqual(info.mRace, cellRef->mBase->mRace)) return false; @@ -58,9 +58,9 @@ bool MWDialogue::Filter::testActor (const ESM::DialInfo& info) const if (isCreature) return true; - MWWorld::LiveCellRef *cellRef = mActor.get(); + MWWorld::LiveCellRef* cellRef = mActor.get(); - if ( !Misc::StringUtils::ciEqual(info.mClass, cellRef->mBase->mClass)) + if (!Misc::StringUtils::ciEqual(info.mClass, cellRef->mBase->mClass)) return false; } @@ -100,24 +100,25 @@ bool MWDialogue::Filter::testActor (const ESM::DialInfo& info) const if (!isCreature) { MWWorld::LiveCellRef* npc = mActor.get(); - if (info.mData.mGender==(npc->mBase->mFlags & npc->mBase->Female ? 0 : 1)) + if (info.mData.mGender == (npc->mBase->mFlags & npc->mBase->Female ? 0 : 1)) return false; } return true; } -bool MWDialogue::Filter::testPlayer (const ESM::DialInfo& info) const +bool MWDialogue::Filter::testPlayer(const ESM::DialInfo& info) const { const MWWorld::Ptr player = MWMechanics::getPlayer(); - MWMechanics::NpcStats& stats = player.getClass().getNpcStats (player); + MWMechanics::NpcStats& stats = player.getClass().getNpcStats(player); // check player faction and rank if (!info.mPcFaction.empty()) { - std::map::const_iterator iter = stats.getFactionRanks().find (Misc::StringUtils::lowerCase (info.mPcFaction)); + std::map::const_iterator iter + = stats.getFactionRanks().find(Misc::StringUtils::lowerCase(info.mPcFaction)); - if(iter==stats.getFactionRanks().end()) + if (iter == stats.getFactionRanks().end()) return false; // check rank @@ -127,9 +128,10 @@ bool MWDialogue::Filter::testPlayer (const ESM::DialInfo& info) const else if (info.mData.mPCrank != -1) { // required PC faction is not specified but PC rank is; use speaker's faction - std::map::const_iterator iter = stats.getFactionRanks().find (Misc::StringUtils::lowerCase (mActor.getClass().getPrimaryFaction(mActor))); + std::map::const_iterator iter + = stats.getFactionRanks().find(Misc::StringUtils::lowerCase(mActor.getClass().getPrimaryFaction(mActor))); - if(iter==stats.getFactionRanks().end()) + if (iter == stats.getFactionRanks().end()) return false; // check rank @@ -142,8 +144,8 @@ bool MWDialogue::Filter::testPlayer (const ESM::DialInfo& info) const { // supports partial matches, just like getPcCell std::string_view playerCell = MWBase::Environment::get().getWorld()->getCellName(player.getCell()); - bool match = playerCell.length()>=info.mCell.length() && - Misc::StringUtils::ciEqual(playerCell.substr (0, info.mCell.length()), info.mCell); + bool match = playerCell.length() >= info.mCell.length() + && Misc::StringUtils::ciEqual(playerCell.substr(0, info.mCell.length()), info.mCell); if (!match) return false; } @@ -151,17 +153,17 @@ bool MWDialogue::Filter::testPlayer (const ESM::DialInfo& info) const return true; } -bool MWDialogue::Filter::testSelectStructs (const ESM::DialInfo& info) const +bool MWDialogue::Filter::testSelectStructs(const ESM::DialInfo& info) const { - for (std::vector::const_iterator iter (info.mSelects.begin()); - iter != info.mSelects.end(); ++iter) - if (!testSelectStruct (*iter)) + for (std::vector::const_iterator iter(info.mSelects.begin()); + iter != info.mSelects.end(); ++iter) + if (!testSelectStruct(*iter)) return false; return true; } -bool MWDialogue::Filter::testDisposition (const ESM::DialInfo& info, bool invert) const +bool MWDialogue::Filter::testDisposition(const ESM::DialInfo& info, bool invert) const { bool isCreature = (mActor.getType() != ESM::NPC::sRecordId); @@ -181,17 +183,16 @@ bool MWDialogue::Filter::testFunctionLocal(const MWDialogue::SelectWrapper& sele if (scriptName.empty()) return false; // no script - std::string name = Misc::StringUtils::lowerCase (select.getName()); + std::string name = Misc::StringUtils::lowerCase(select.getName()); - const Compiler::Locals& localDefs = - MWBase::Environment::get().getScriptManager()->getLocals (scriptName); + const Compiler::Locals& localDefs = MWBase::Environment::get().getScriptManager()->getLocals(scriptName); - char type = localDefs.getType (name); + char type = localDefs.getType(name); - if (type==' ') + if (type == ' ') return false; // script does not have a variable of this name. - int index = localDefs.getIndex (name); + int index = localDefs.getIndex(name); if (index < 0) return false; // shouldn't happen, we checked that variable has a type above, so must exist @@ -200,15 +201,18 @@ bool MWDialogue::Filter::testFunctionLocal(const MWDialogue::SelectWrapper& sele return select.selectCompare(0); switch (type) { - case 's': return select.selectCompare (static_cast (locals.mShorts[index])); - case 'l': return select.selectCompare (locals.mLongs[index]); - case 'f': return select.selectCompare (locals.mFloats[index]); + case 's': + return select.selectCompare(static_cast(locals.mShorts[index])); + case 'l': + return select.selectCompare(locals.mLongs[index]); + case 'f': + return select.selectCompare(locals.mFloats[index]); } - throw std::logic_error ("unknown local variable type in dialogue filter"); + throw std::logic_error("unknown local variable type in dialogue filter"); } -bool MWDialogue::Filter::testSelectStruct (const SelectWrapper& select) const +bool MWDialogue::Filter::testSelectStruct(const SelectWrapper& select) const { if (select.isNpcOnly() && (mActor.getType() != ESM::NPC::sRecordId)) // If the actor is a creature, we pass all conditions only applicable to NPCs. @@ -218,34 +222,41 @@ bool MWDialogue::Filter::testSelectStruct (const SelectWrapper& select) const // If not currently in a choice, we reject all conditions that test against choices. return false; - if (select.getFunction() == SelectWrapper::Function_Weather && !(MWBase::Environment::get().getWorld()->isCellExterior() || MWBase::Environment::get().getWorld()->isCellQuasiExterior())) + if (select.getFunction() == SelectWrapper::Function_Weather + && !(MWBase::Environment::get().getWorld()->isCellExterior() + || MWBase::Environment::get().getWorld()->isCellQuasiExterior())) // Reject weather conditions in interior cells - // Note that the original engine doesn't include the "|| isCellQuasiExterior()" check, which could be considered a bug. + // Note that the original engine doesn't include the "|| isCellQuasiExterior()" check, which could be considered + // a bug. return false; switch (select.getType()) { - case SelectWrapper::Type_None: return true; - case SelectWrapper::Type_Integer: return select.selectCompare (getSelectStructInteger (select)); - case SelectWrapper::Type_Numeric: return testSelectStructNumeric (select); - case SelectWrapper::Type_Boolean: return select.selectCompare (getSelectStructBoolean (select)); + case SelectWrapper::Type_None: + return true; + case SelectWrapper::Type_Integer: + return select.selectCompare(getSelectStructInteger(select)); + case SelectWrapper::Type_Numeric: + return testSelectStructNumeric(select); + case SelectWrapper::Type_Boolean: + return select.selectCompare(getSelectStructBoolean(select)); // We must not do the comparison for inverted functions (eg. Function_NotClass) - case SelectWrapper::Type_Inverted: return getSelectStructBoolean (select); + case SelectWrapper::Type_Inverted: + return getSelectStructBoolean(select); } return true; } -bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) const +bool MWDialogue::Filter::testSelectStructNumeric(const SelectWrapper& select) const { switch (select.getFunction()) { case SelectWrapper::Function_Global: // internally all globals are float :( - return select.selectCompare ( - MWBase::Environment::get().getWorld()->getGlobalFloat (select.getName())); + return select.selectCompare(MWBase::Environment::get().getWorld()->getGlobalFloat(select.getName())); case SelectWrapper::Function_Local: { @@ -260,31 +271,32 @@ bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) c case SelectWrapper::Function_PcHealthPercent: { MWWorld::Ptr player = MWMechanics::getPlayer(); - return select.selectCompare(static_cast(player.getClass().getCreatureStats(player).getHealth().getRatio() * 100)); + return select.selectCompare( + static_cast(player.getClass().getCreatureStats(player).getHealth().getRatio() * 100)); } case SelectWrapper::Function_PcDynamicStat: { MWWorld::Ptr player = MWMechanics::getPlayer(); - float value = player.getClass().getCreatureStats (player). - getDynamic (select.getArgument()).getCurrent(); + float value = player.getClass().getCreatureStats(player).getDynamic(select.getArgument()).getCurrent(); - return select.selectCompare (value); + return select.selectCompare(value); } case SelectWrapper::Function_HealthPercent: { - return select.selectCompare(static_cast(mActor.getClass().getCreatureStats(mActor).getHealth().getRatio() * 100)); + return select.selectCompare( + static_cast(mActor.getClass().getCreatureStats(mActor).getHealth().getRatio() * 100)); } default: - throw std::runtime_error ("unknown numeric select function"); + throw std::runtime_error("unknown numeric select function"); } } -int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) const +int MWDialogue::Filter::getSelectStructInteger(const SelectWrapper& select) const { MWWorld::Ptr player = MWMechanics::getPlayer(); @@ -292,18 +304,18 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con { case SelectWrapper::Function_Journal: - return MWBase::Environment::get().getJournal()->getJournalIndex (select.getName()); + return MWBase::Environment::get().getJournal()->getJournalIndex(select.getName()); case SelectWrapper::Function_Item: { - MWWorld::ContainerStore& store = player.getClass().getContainerStore (player); + MWWorld::ContainerStore& store = player.getClass().getContainerStore(player); return store.count(select.getName()); } case SelectWrapper::Function_Dead: - return MWBase::Environment::get().getMechanicsManager()->countDeaths (select.getName()); + return MWBase::Environment::get().getMechanicsManager()->countDeaths(select.getName()); case SelectWrapper::Function_Choice: @@ -311,29 +323,29 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con case SelectWrapper::Function_AiSetting: - return mActor.getClass().getCreatureStats (mActor).getAiSetting ( - (MWMechanics::AiSetting)select.getArgument()).getModified(false); + return mActor.getClass() + .getCreatureStats(mActor) + .getAiSetting((MWMechanics::AiSetting)select.getArgument()) + .getModified(false); case SelectWrapper::Function_PcAttribute: - return player.getClass().getCreatureStats (player). - getAttribute (select.getArgument()).getModified(); + return player.getClass().getCreatureStats(player).getAttribute(select.getArgument()).getModified(); case SelectWrapper::Function_PcSkill: - return static_cast (player.getClass(). - getNpcStats (player).getSkill (select.getArgument()).getModified()); + return static_cast(player.getClass().getNpcStats(player).getSkill(select.getArgument()).getModified()); case SelectWrapper::Function_FriendlyHit: { - int hits = mActor.getClass().getCreatureStats (mActor).getFriendlyHits(); + int hits = mActor.getClass().getCreatureStats(mActor).getFriendlyHits(); - return hits>4 ? 4 : hits; + return hits > 4 ? 4 : hits; } case SelectWrapper::Function_PcLevel: - return player.getClass().getCreatureStats (player).getLevel(); + return player.getClass().getCreatureStats(player).getLevel(); case SelectWrapper::Function_PcGender: @@ -341,16 +353,16 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con case SelectWrapper::Function_PcClothingModifier: { - const MWWorld::InventoryStore& store = player.getClass().getInventoryStore (player); + const MWWorld::InventoryStore& store = player.getClass().getInventoryStore(player); int value = 0; - for (int i=0; i<=15; ++i) // everything except things held in hands and ammunition + for (int i = 0; i <= 15; ++i) // everything except things held in hands and ammunition { - MWWorld::ConstContainerStoreIterator slot = store.getSlot (i); + MWWorld::ConstContainerStoreIterator slot = store.getSlot(i); - if (slot!=store.end()) - value += slot->getClass().getValue (*slot); + if (slot != store.end()) + value += slot->getClass().getValue(*slot); } return value; @@ -358,7 +370,7 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con case SelectWrapper::Function_PcCrimeLevel: - return player.getClass().getNpcStats (player).getBounty(); + return player.getClass().getNpcStats(player).getBounty(); case SelectWrapper::Function_RankRequirement: { @@ -366,17 +378,17 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con if (faction.empty()) return 0; - int rank = getFactionRank (player, faction); + int rank = getFactionRank(player, faction); - if (rank>=9) + if (rank >= 9) return 0; // max rank int result = 0; - if (hasFactionRankSkillRequirements (player, faction, rank+1)) + if (hasFactionRankSkillRequirements(player, faction, rank + 1)) result += 1; - if (hasFactionRankReputationRequirements (player, faction, rank+1)) + if (hasFactionRankReputationRequirements(player, faction, rank + 1)) result += 2; return result; @@ -384,11 +396,11 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con case SelectWrapper::Function_Level: - return mActor.getClass().getCreatureStats (mActor).getLevel(); + return mActor.getClass().getCreatureStats(mActor).getLevel(); case SelectWrapper::Function_PCReputation: - return player.getClass().getNpcStats (player).getReputation(); + return player.getClass().getNpcStats(player).getReputation(); case SelectWrapper::Function_Weather: @@ -396,7 +408,7 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con case SelectWrapper::Function_Reputation: - return mActor.getClass().getNpcStats (mActor).getReputation(); + return mActor.getClass().getNpcStats(mActor).getReputation(); case SelectWrapper::Function_FactionRankDiff: { @@ -405,19 +417,19 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con if (faction.empty()) return 0; - int rank = getFactionRank (player, faction); + int rank = getFactionRank(player, faction); int npcRank = mActor.getClass().getPrimaryFactionRank(mActor); - return rank-npcRank; + return rank - npcRank; } case SelectWrapper::Function_WerewolfKills: - return player.getClass().getNpcStats (player).getWerewolfKills(); + return player.getClass().getNpcStats(player).getWerewolfKills(); case SelectWrapper::Function_RankLow: case SelectWrapper::Function_RankHigh: { - bool low = select.getFunction()==SelectWrapper::Function_RankLow; + bool low = select.getFunction() == SelectWrapper::Function_RankLow; std::string_view factionId = mActor.getClass().getPrimaryFaction(mActor); @@ -426,12 +438,13 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con int value = 0; - MWMechanics::NpcStats& playerStats = player.getClass().getNpcStats (player); + MWMechanics::NpcStats& playerStats = player.getClass().getNpcStats(player); std::map::const_iterator playerFactionIt = playerStats.getFactionRanks().begin(); for (; playerFactionIt != playerStats.getFactionRanks().end(); ++playerFactionIt) { - int reaction = MWBase::Environment::get().getDialogueManager()->getFactionReaction(factionId, playerFactionIt->first); + int reaction = MWBase::Environment::get().getDialogueManager()->getFactionReaction( + factionId, playerFactionIt->first); if (low ? reaction < value : reaction > value) value = reaction; } @@ -441,26 +454,26 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con case SelectWrapper::Function_CreatureTargetted: + { + MWWorld::Ptr target; + mActor.getClass().getCreatureStats(mActor).getAiSequence().getCombatTarget(target); + if (target) { - MWWorld::Ptr target; - mActor.getClass().getCreatureStats(mActor).getAiSequence().getCombatTarget(target); - if (target) - { - if (target.getClass().isNpc() && target.getClass().getNpcStats(target).isWerewolf()) - return 2; - if (target.getType() == ESM::Creature::sRecordId) - return 1; - } + if (target.getClass().isNpc() && target.getClass().getNpcStats(target).isWerewolf()) + return 2; + if (target.getType() == ESM::Creature::sRecordId) + return 1; } + } return 0; default: - throw std::runtime_error ("unknown integer select function"); + throw std::runtime_error("unknown integer select function"); } } -bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) const +bool MWDialogue::Filter::getSelectStructBoolean(const SelectWrapper& select) const { MWWorld::Ptr player = MWMechanics::getPlayer(); @@ -487,36 +500,41 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co return !Misc::StringUtils::ciEqual(mActor.get()->mBase->mRace, select.getName()); case SelectWrapper::Function_NotCell: - { - std::string_view actorCell = MWBase::Environment::get().getWorld()->getCellName(mActor.getCell()); - return !(actorCell.length() >= select.getName().length() - && Misc::StringUtils::ciEqual(actorCell.substr(0, select.getName().length()), select.getName())); - } + { + std::string_view actorCell = MWBase::Environment::get().getWorld()->getCellName(mActor.getCell()); + return !(actorCell.length() >= select.getName().length() + && Misc::StringUtils::ciEqual(actorCell.substr(0, select.getName().length()), select.getName())); + } case SelectWrapper::Function_SameGender: - return (player.get()->mBase->mFlags & ESM::NPC::Female)== - (mActor.get()->mBase->mFlags & ESM::NPC::Female); + return (player.get()->mBase->mFlags & ESM::NPC::Female) + == (mActor.get()->mBase->mFlags & ESM::NPC::Female); case SelectWrapper::Function_SameRace: - return Misc::StringUtils::ciEqual(mActor.get()->mBase->mRace, player.get()->mBase->mRace); + return Misc::StringUtils::ciEqual( + mActor.get()->mBase->mRace, player.get()->mBase->mRace); case SelectWrapper::Function_SameFaction: - return player.getClass().getNpcStats (player).isInFaction(mActor.getClass().getPrimaryFaction(mActor)); + return player.getClass().getNpcStats(player).isInFaction(mActor.getClass().getPrimaryFaction(mActor)); case SelectWrapper::Function_PcCommonDisease: - return player.getClass().getCreatureStats (player).hasCommonDisease(); + return player.getClass().getCreatureStats(player).hasCommonDisease(); case SelectWrapper::Function_PcBlightDisease: - return player.getClass().getCreatureStats (player).hasBlightDisease(); + return player.getClass().getCreatureStats(player).hasBlightDisease(); case SelectWrapper::Function_PcCorprus: - return player.getClass().getCreatureStats (player). - getMagicEffects().get (ESM::MagicEffect::Corprus).getMagnitude()!=0; + return player.getClass() + .getCreatureStats(player) + .getMagicEffects() + .get(ESM::MagicEffect::Corprus) + .getMagnitude() + != 0; case SelectWrapper::Function_PcExpelled: { @@ -530,8 +548,12 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co case SelectWrapper::Function_PcVampire: - return player.getClass().getCreatureStats(player).getMagicEffects(). - get(ESM::MagicEffect::Vampirism).getMagnitude() > 0; + return player.getClass() + .getCreatureStats(player) + .getMagicEffects() + .get(ESM::MagicEffect::Vampirism) + .getMagnitude() + > 0; case SelectWrapper::Function_TalkedToPc: @@ -539,7 +561,7 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co case SelectWrapper::Function_Alarmed: - return mActor.getClass().getCreatureStats (mActor).isAlarmed(); + return mActor.getClass().getCreatureStats(mActor).isAlarmed(); case SelectWrapper::Function_Detected: @@ -547,66 +569,70 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co case SelectWrapper::Function_Attacked: - return mActor.getClass().getCreatureStats (mActor).getAttacked(); + return mActor.getClass().getCreatureStats(mActor).getAttacked(); case SelectWrapper::Function_ShouldAttack: - return MWBase::Environment::get().getMechanicsManager()->isAggressive(mActor, - MWMechanics::getPlayer()); + return MWBase::Environment::get().getMechanicsManager()->isAggressive(mActor, MWMechanics::getPlayer()); case SelectWrapper::Function_Werewolf: - return mActor.getClass().getNpcStats (mActor).isWerewolf(); + return mActor.getClass().getNpcStats(mActor).isWerewolf(); default: - throw std::runtime_error ("unknown boolean select function"); + throw std::runtime_error("unknown boolean select function"); } } -int MWDialogue::Filter::getFactionRank (const MWWorld::Ptr& actor, std::string_view factionId) const +int MWDialogue::Filter::getFactionRank(const MWWorld::Ptr& actor, std::string_view factionId) const { - MWMechanics::NpcStats& stats = actor.getClass().getNpcStats (actor); + MWMechanics::NpcStats& stats = actor.getClass().getNpcStats(actor); return stats.getFactionRank(factionId); } -bool MWDialogue::Filter::hasFactionRankSkillRequirements(const MWWorld::Ptr& actor, std::string_view factionId, int rank) const +bool MWDialogue::Filter::hasFactionRankSkillRequirements( + const MWWorld::Ptr& actor, std::string_view factionId, int rank) const { - if (rank<0 || rank>=10) - throw std::runtime_error ("rank index out of range"); + if (rank < 0 || rank >= 10) + throw std::runtime_error("rank index out of range"); - if (!actor.getClass().getNpcStats (actor).hasSkillsForRank (factionId, rank)) + if (!actor.getClass().getNpcStats(actor).hasSkillsForRank(factionId, rank)) return false; - const ESM::Faction& faction = - *MWBase::Environment::get().getWorld()->getStore().get().find (factionId); + const ESM::Faction& faction + = *MWBase::Environment::get().getWorld()->getStore().get().find(factionId); - MWMechanics::CreatureStats& stats = actor.getClass().getCreatureStats (actor); + MWMechanics::CreatureStats& stats = actor.getClass().getCreatureStats(actor); - return stats.getAttribute (faction.mData.mAttribute[0]).getBase()>=faction.mData.mRankData[rank].mAttribute1 && - stats.getAttribute (faction.mData.mAttribute[1]).getBase()>=faction.mData.mRankData[rank].mAttribute2; + return stats.getAttribute(faction.mData.mAttribute[0]).getBase() >= faction.mData.mRankData[rank].mAttribute1 + && stats.getAttribute(faction.mData.mAttribute[1]).getBase() >= faction.mData.mRankData[rank].mAttribute2; } -bool MWDialogue::Filter::hasFactionRankReputationRequirements(const MWWorld::Ptr& actor, std::string_view factionId, int rank) const +bool MWDialogue::Filter::hasFactionRankReputationRequirements( + const MWWorld::Ptr& actor, std::string_view factionId, int rank) const { - if (rank<0 || rank>=10) - throw std::runtime_error ("rank index out of range"); + if (rank < 0 || rank >= 10) + throw std::runtime_error("rank index out of range"); - MWMechanics::NpcStats& stats = actor.getClass().getNpcStats (actor); + MWMechanics::NpcStats& stats = actor.getClass().getNpcStats(actor); - const ESM::Faction& faction = - *MWBase::Environment::get().getWorld()->getStore().get().find (factionId); + const ESM::Faction& faction + = *MWBase::Environment::get().getWorld()->getStore().get().find(factionId); - return stats.getFactionReputation (factionId)>=faction.mData.mRankData[rank].mFactReaction; + return stats.getFactionReputation(factionId) >= faction.mData.mRankData[rank].mFactReaction; } -MWDialogue::Filter::Filter (const MWWorld::Ptr& actor, int choice, bool talkedToPlayer) -: mActor (actor), mChoice (choice), mTalkedToPlayer (talkedToPlayer) -{} +MWDialogue::Filter::Filter(const MWWorld::Ptr& actor, int choice, bool talkedToPlayer) + : mActor(actor) + , mChoice(choice) + , mTalkedToPlayer(talkedToPlayer) +{ +} -const ESM::DialInfo* MWDialogue::Filter::search (const ESM::Dialogue& dialogue, const bool fallbackToInfoRefusal) const +const ESM::DialInfo* MWDialogue::Filter::search(const ESM::Dialogue& dialogue, const bool fallbackToInfoRefusal) const { - std::vector suitableInfos = list (dialogue, fallbackToInfoRefusal, false); + std::vector suitableInfos = list(dialogue, fallbackToInfoRefusal, false); if (suitableInfos.empty()) return nullptr; @@ -614,31 +640,33 @@ const ESM::DialInfo* MWDialogue::Filter::search (const ESM::Dialogue& dialogue, return suitableInfos[0]; } -std::vector MWDialogue::Filter::listAll (const ESM::Dialogue& dialogue) const +std::vector MWDialogue::Filter::listAll(const ESM::Dialogue& dialogue) const { - std::vector infos; - for (ESM::Dialogue::InfoContainer::const_iterator iter = dialogue.mInfo.begin(); iter!=dialogue.mInfo.end(); ++iter) + std::vector infos; + for (ESM::Dialogue::InfoContainer::const_iterator iter = dialogue.mInfo.begin(); iter != dialogue.mInfo.end(); + ++iter) { - if (testActor (*iter)) + if (testActor(*iter)) infos.push_back(&*iter); } return infos; } -std::vector MWDialogue::Filter::list (const ESM::Dialogue& dialogue, - bool fallbackToInfoRefusal, bool searchAll, bool invertDisposition) const +std::vector MWDialogue::Filter::list( + const ESM::Dialogue& dialogue, bool fallbackToInfoRefusal, bool searchAll, bool invertDisposition) const { - std::vector infos; + std::vector infos; bool infoRefusal = false; // Iterate over topic responses to find a matching one - for (ESM::Dialogue::InfoContainer::const_iterator iter = dialogue.mInfo.begin(); - iter!=dialogue.mInfo.end(); ++iter) + for (ESM::Dialogue::InfoContainer::const_iterator iter = dialogue.mInfo.begin(); iter != dialogue.mInfo.end(); + ++iter) { - if (testActor (*iter) && testPlayer (*iter) && testSelectStructs (*iter)) + if (testActor(*iter) && testPlayer(*iter) && testSelectStructs(*iter)) { - if (testDisposition (*iter, invertDisposition)) { + if (testDisposition(*iter, invertDisposition)) + { infos.push_back(&*iter); if (!searchAll) break; @@ -653,14 +681,16 @@ std::vector MWDialogue::Filter::list (const ESM::Dialogue // No response is valid because of low NPC disposition, // search a response in the topic "Info Refusal" - const MWWorld::Store &dialogues = - MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& dialogues + = MWBase::Environment::get().getWorld()->getStore().get(); - const ESM::Dialogue& infoRefusalDialogue = *dialogues.find ("Info Refusal"); + const ESM::Dialogue& infoRefusalDialogue = *dialogues.find("Info Refusal"); for (ESM::Dialogue::InfoContainer::const_iterator iter = infoRefusalDialogue.mInfo.begin(); - iter!=infoRefusalDialogue.mInfo.end(); ++iter) - if (testActor (*iter) && testPlayer (*iter) && testSelectStructs (*iter) && testDisposition(*iter, invertDisposition)) { + iter != infoRefusalDialogue.mInfo.end(); ++iter) + if (testActor(*iter) && testPlayer(*iter) && testSelectStructs(*iter) + && testDisposition(*iter, invertDisposition)) + { infos.push_back(&*iter); if (!searchAll) break; diff --git a/apps/openmw/mwdialogue/filter.hpp b/apps/openmw/mwdialogue/filter.hpp index a9f78ebcb6..3db8a97790 100644 --- a/apps/openmw/mwdialogue/filter.hpp +++ b/apps/openmw/mwdialogue/filter.hpp @@ -17,53 +17,54 @@ namespace MWDialogue class Filter { - MWWorld::Ptr mActor; - int mChoice; - bool mTalkedToPlayer; + MWWorld::Ptr mActor; + int mChoice; + bool mTalkedToPlayer; - bool testActor (const ESM::DialInfo& info) const; - ///< Is this the right actor for this \a info? + bool testActor(const ESM::DialInfo& info) const; + ///< Is this the right actor for this \a info? - bool testPlayer (const ESM::DialInfo& info) const; - ///< Do the player and the cell the player is currently in match \a info? + bool testPlayer(const ESM::DialInfo& info) const; + ///< Do the player and the cell the player is currently in match \a info? - bool testSelectStructs (const ESM::DialInfo& info) const; - ///< Are all select structs matching? + bool testSelectStructs(const ESM::DialInfo& info) const; + ///< Are all select structs matching? - bool testDisposition (const ESM::DialInfo& info, bool invert=false) const; - ///< Is the actor disposition toward the player high enough (or low enough, if \a invert is true)? + bool testDisposition(const ESM::DialInfo& info, bool invert = false) const; + ///< Is the actor disposition toward the player high enough (or low enough, if \a invert is true)? - bool testFunctionLocal(const SelectWrapper& select) const; + bool testFunctionLocal(const SelectWrapper& select) const; - bool testSelectStruct (const SelectWrapper& select) const; + bool testSelectStruct(const SelectWrapper& select) const; - bool testSelectStructNumeric (const SelectWrapper& select) const; + bool testSelectStructNumeric(const SelectWrapper& select) const; - int getSelectStructInteger (const SelectWrapper& select) const; + int getSelectStructInteger(const SelectWrapper& select) const; - bool getSelectStructBoolean (const SelectWrapper& select) const; + bool getSelectStructBoolean(const SelectWrapper& select) const; - int getFactionRank(const MWWorld::Ptr& actor, std::string_view factionId) const; + int getFactionRank(const MWWorld::Ptr& actor, std::string_view factionId) const; - bool hasFactionRankSkillRequirements(const MWWorld::Ptr& actor, std::string_view factionId, int rank) const; + bool hasFactionRankSkillRequirements(const MWWorld::Ptr& actor, std::string_view factionId, int rank) const; - bool hasFactionRankReputationRequirements(const MWWorld::Ptr& actor, std::string_view factionId, int rank) const; + bool hasFactionRankReputationRequirements( + const MWWorld::Ptr& actor, std::string_view factionId, int rank) const; - public: + public: + Filter(const MWWorld::Ptr& actor, int choice, bool talkedToPlayer); - Filter (const MWWorld::Ptr& actor, int choice, bool talkedToPlayer); + std::vector list(const ESM::Dialogue& dialogue, bool fallbackToInfoRefusal, + bool searchAll, bool invertDisposition = false) const; + ///< List all infos that could be used on the given actor, using the current runtime state of the actor. + /// \note If fallbackToInfoRefusal is used, the returned DialInfo might not be from the supplied ESM::Dialogue. - std::vector list (const ESM::Dialogue& dialogue, - bool fallbackToInfoRefusal, bool searchAll, bool invertDisposition=false) const; - ///< List all infos that could be used on the given actor, using the current runtime state of the actor. - /// \note If fallbackToInfoRefusal is used, the returned DialInfo might not be from the supplied ESM::Dialogue. + std::vector listAll(const ESM::Dialogue& dialogue) const; + ///< List all infos that could possibly be used on the given actor, ignoring runtime state filters and ignoring + ///< player filters. - std::vector listAll (const ESM::Dialogue& dialogue) const; - ///< List all infos that could possibly be used on the given actor, ignoring runtime state filters and ignoring player filters. - - const ESM::DialInfo* search (const ESM::Dialogue& dialogue, const bool fallbackToInfoRefusal) const; - ///< Get a matching response for the requested dialogue. - /// Redirect to "Info Refusal" topic if a response fulfills all conditions but disposition. + const ESM::DialInfo* search(const ESM::Dialogue& dialogue, const bool fallbackToInfoRefusal) const; + ///< Get a matching response for the requested dialogue. + /// Redirect to "Info Refusal" topic if a response fulfills all conditions but disposition. }; } diff --git a/apps/openmw/mwdialogue/hypertextparser.cpp b/apps/openmw/mwdialogue/hypertextparser.cpp index 732cdb1f8f..bb05b5e798 100644 --- a/apps/openmw/mwdialogue/hypertextparser.cpp +++ b/apps/openmw/mwdialogue/hypertextparser.cpp @@ -3,8 +3,8 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" -#include "../mwworld/store.hpp" #include "../mwworld/esmstore.hpp" +#include "../mwworld/store.hpp" #include "keywordsearch.hpp" @@ -14,11 +14,11 @@ namespace MWDialogue { namespace HyperTextParser { - std::vector parseHyperText(const std::string & text) + std::vector parseHyperText(const std::string& text) { std::vector result; size_t pos_end = std::string::npos, iteration_pos = 0; - for(;;) + for (;;) { size_t pos_begin = text.find('@', iteration_pos); if (pos_begin != std::string::npos) @@ -45,30 +45,31 @@ namespace MWDialogue return result; } - void tokenizeKeywords(const std::string & text, std::vector & tokens) + void tokenizeKeywords(const std::string& text, std::vector& tokens) { - const auto& keywordSearch = - MWBase::Environment::get().getWorld()->getStore().get().getDialogIdKeywordSearch(); + const auto& keywordSearch + = MWBase::Environment::get().getWorld()->getStore().get().getDialogIdKeywordSearch(); std::vector::Match> matches; keywordSearch.highlightKeywords(text.begin(), text.end(), matches); - for (std::vector::Match>::const_iterator it = matches.begin(); it != matches.end(); ++it) + for (std::vector::Match>::const_iterator it = matches.begin(); + it != matches.end(); ++it) { tokens.emplace_back(std::string(it->mBeg, it->mEnd), Token::ImplicitKeyword); } } - size_t removePseudoAsterisks(std::string & phrase) + size_t removePseudoAsterisks(std::string& phrase) { size_t pseudoAsterisksCount = 0; - if( !phrase.empty() ) + if (!phrase.empty()) { std::string::reverse_iterator rit = phrase.rbegin(); const char specialPseudoAsteriskCharacter = 127; - while( rit != phrase.rend() && *rit == specialPseudoAsteriskCharacter ) + while (rit != phrase.rend() && *rit == specialPseudoAsteriskCharacter) { pseudoAsterisksCount++; ++rit; diff --git a/apps/openmw/mwdialogue/hypertextparser.hpp b/apps/openmw/mwdialogue/hypertextparser.hpp index 4ae0474c42..efd0982dee 100644 --- a/apps/openmw/mwdialogue/hypertextparser.hpp +++ b/apps/openmw/mwdialogue/hypertextparser.hpp @@ -16,7 +16,11 @@ namespace MWDialogue ImplicitKeyword }; - Token(const std::string & text, Type type) : mText(text), mType(type) {} + Token(const std::string& text, Type type) + : mText(text) + , mType(type) + { + } bool isExplicitLink() { return mType == ExplicitLink; } @@ -26,9 +30,9 @@ namespace MWDialogue // In translations (at least Russian) the links are marked with @#, so // it should be a function to parse it - std::vector parseHyperText(const std::string & text); - void tokenizeKeywords(const std::string & text, std::vector & tokens); - size_t removePseudoAsterisks(std::string & phrase); + std::vector parseHyperText(const std::string& text); + void tokenizeKeywords(const std::string& text, std::vector& tokens); + size_t removePseudoAsterisks(std::string& phrase); } } diff --git a/apps/openmw/mwdialogue/journalentry.cpp b/apps/openmw/mwdialogue/journalentry.cpp index 961977ca03..162ca214fe 100644 --- a/apps/openmw/mwdialogue/journalentry.cpp +++ b/apps/openmw/mwdialogue/journalentry.cpp @@ -13,17 +13,16 @@ #include "../mwscript/interpretercontext.hpp" - namespace MWDialogue { Entry::Entry(std::string_view topic, std::string_view infoId, const MWWorld::Ptr& actor) - : mInfoId (infoId) + : mInfoId(infoId) { - const ESM::Dialogue *dialogue = - MWBase::Environment::get().getWorld()->getStore().get().find (topic); + const ESM::Dialogue* dialogue + = MWBase::Environment::get().getWorld()->getStore().get().find(topic); - for (ESM::Dialogue::InfoContainer::const_iterator iter (dialogue->mInfo.begin()); - iter!=dialogue->mInfo.end(); ++iter) + for (ESM::Dialogue::InfoContainer::const_iterator iter(dialogue->mInfo.begin()); iter != dialogue->mInfo.end(); + ++iter) if (iter->mId == mInfoId) { if (actor.isEmpty()) @@ -33,83 +32,100 @@ namespace MWDialogue } else { - MWScript::InterpreterContext interpreterContext(&actor.getRefData().getLocals(),actor); + MWScript::InterpreterContext interpreterContext(&actor.getRefData().getLocals(), actor); mText = Interpreter::fixDefinesDialog(iter->mResponse, interpreterContext); } return; } - throw std::runtime_error ("unknown info ID " + mInfoId + " for topic " + std::string(topic)); + throw std::runtime_error("unknown info ID " + mInfoId + " for topic " + std::string(topic)); } - Entry::Entry (const ESM::JournalEntry& record) : mInfoId (record.mInfo), mText (record.mText), mActorName(record.mActorName) {} + Entry::Entry(const ESM::JournalEntry& record) + : mInfoId(record.mInfo) + , mText(record.mText) + , mActorName(record.mActorName) + { + } const std::string& Entry::getText() const { return mText; } - void Entry::write (ESM::JournalEntry& entry) const + void Entry::write(ESM::JournalEntry& entry) const { entry.mInfo = mInfoId; entry.mText = mText; entry.mActorName = mActorName; } - JournalEntry::JournalEntry(std::string_view topic, std::string_view infoId, const MWWorld::Ptr& actor) - : Entry (topic, infoId, actor), mTopic (topic) - {} + : Entry(topic, infoId, actor) + , mTopic(topic) + { + } - JournalEntry::JournalEntry (const ESM::JournalEntry& record) - : Entry (record), mTopic (record.mTopic) - {} + JournalEntry::JournalEntry(const ESM::JournalEntry& record) + : Entry(record) + , mTopic(record.mTopic) + { + } - void JournalEntry::write (ESM::JournalEntry& entry) const + void JournalEntry::write(ESM::JournalEntry& entry) const { - Entry::write (entry); + Entry::write(entry); entry.mTopic = mTopic; } JournalEntry JournalEntry::makeFromQuest(std::string_view topic, int index) { - return JournalEntry (topic, idFromIndex (topic, index), MWWorld::Ptr()); + return JournalEntry(topic, idFromIndex(topic, index), MWWorld::Ptr()); } - std::string_view JournalEntry::idFromIndex (std::string_view topic, int index) + std::string_view JournalEntry::idFromIndex(std::string_view topic, int index) { - const ESM::Dialogue *dialogue = - MWBase::Environment::get().getWorld()->getStore().get().find (topic); + const ESM::Dialogue* dialogue + = MWBase::Environment::get().getWorld()->getStore().get().find(topic); - for (ESM::Dialogue::InfoContainer::const_iterator iter (dialogue->mInfo.begin()); - iter!=dialogue->mInfo.end(); ++iter) - if (iter->mData.mJournalIndex==index) + for (ESM::Dialogue::InfoContainer::const_iterator iter(dialogue->mInfo.begin()); iter != dialogue->mInfo.end(); + ++iter) + if (iter->mData.mJournalIndex == index) { return iter->mId; } - throw std::runtime_error ("unknown journal index for topic " + std::string(topic)); + throw std::runtime_error("unknown journal index for topic " + std::string(topic)); } - StampedJournalEntry::StampedJournalEntry() - : mDay (0), mMonth (0), mDayOfMonth (0) - {} + : mDay(0) + , mMonth(0) + , mDayOfMonth(0) + { + } - StampedJournalEntry::StampedJournalEntry(std::string_view topic, std::string_view infoId, - int day, int month, int dayOfMonth, const MWWorld::Ptr& actor) - : JournalEntry (topic, infoId, actor), mDay (day), mMonth (month), mDayOfMonth (dayOfMonth) - {} + StampedJournalEntry::StampedJournalEntry( + std::string_view topic, std::string_view infoId, int day, int month, int dayOfMonth, const MWWorld::Ptr& actor) + : JournalEntry(topic, infoId, actor) + , mDay(day) + , mMonth(month) + , mDayOfMonth(dayOfMonth) + { + } - StampedJournalEntry::StampedJournalEntry (const ESM::JournalEntry& record) - : JournalEntry (record), mDay (record.mDay), mMonth (record.mMonth), - mDayOfMonth (record.mDayOfMonth) - {} + StampedJournalEntry::StampedJournalEntry(const ESM::JournalEntry& record) + : JournalEntry(record) + , mDay(record.mDay) + , mMonth(record.mMonth) + , mDayOfMonth(record.mDayOfMonth) + { + } - void StampedJournalEntry::write (ESM::JournalEntry& entry) const + void StampedJournalEntry::write(ESM::JournalEntry& entry) const { - JournalEntry::write (entry); + JournalEntry::write(entry); entry.mDay = mDay; entry.mMonth = mMonth; entry.mDayOfMonth = mDayOfMonth; @@ -117,10 +133,10 @@ namespace MWDialogue StampedJournalEntry StampedJournalEntry::makeFromQuest(std::string_view topic, int index, const MWWorld::Ptr& actor) { - int day = MWBase::Environment::get().getWorld()->getGlobalInt ("dayspassed"); - int month = MWBase::Environment::get().getWorld()->getGlobalInt ("month"); - int dayOfMonth = MWBase::Environment::get().getWorld()->getGlobalInt ("day"); + int day = MWBase::Environment::get().getWorld()->getGlobalInt("dayspassed"); + int month = MWBase::Environment::get().getWorld()->getGlobalInt("month"); + int dayOfMonth = MWBase::Environment::get().getWorld()->getGlobalInt("day"); - return StampedJournalEntry (topic, idFromIndex (topic, index), day, month, dayOfMonth, actor); + return StampedJournalEntry(topic, idFromIndex(topic, index), day, month, dayOfMonth, actor); } } diff --git a/apps/openmw/mwdialogue/journalentry.hpp b/apps/openmw/mwdialogue/journalentry.hpp index c4b93de7c4..4573981cb8 100644 --- a/apps/openmw/mwdialogue/journalentry.hpp +++ b/apps/openmw/mwdialogue/journalentry.hpp @@ -28,11 +28,11 @@ namespace MWDialogue /// actor is optional Entry(std::string_view topic, std::string_view infoId, const MWWorld::Ptr& actor); - Entry (const ESM::JournalEntry& record); + Entry(const ESM::JournalEntry& record); const std::string& getText() const; - void write (ESM::JournalEntry& entry) const; + void write(ESM::JournalEntry& entry) const; }; /// \brief A dialogue entry @@ -46,9 +46,9 @@ namespace MWDialogue JournalEntry(std::string_view topic, std::string_view infoId, const MWWorld::Ptr& actor); - JournalEntry (const ESM::JournalEntry& record); + JournalEntry(const ESM::JournalEntry& record); - void write (ESM::JournalEntry& entry) const; + void write(ESM::JournalEntry& entry) const; static JournalEntry makeFromQuest(std::string_view topic, int index); @@ -64,12 +64,12 @@ namespace MWDialogue StampedJournalEntry(); - StampedJournalEntry(std::string_view topic, std::string_view infoId, - int day, int month, int dayOfMonth, const MWWorld::Ptr& actor); + StampedJournalEntry(std::string_view topic, std::string_view infoId, int day, int month, int dayOfMonth, + const MWWorld::Ptr& actor); - StampedJournalEntry (const ESM::JournalEntry& record); + StampedJournalEntry(const ESM::JournalEntry& record); - void write (ESM::JournalEntry& entry) const; + void write(ESM::JournalEntry& entry) const; static StampedJournalEntry makeFromQuest(std::string_view topic, int index, const MWWorld::Ptr& actor); }; diff --git a/apps/openmw/mwdialogue/journalimp.cpp b/apps/openmw/mwdialogue/journalimp.cpp index 906ae97363..6a6348ed58 100644 --- a/apps/openmw/mwdialogue/journalimp.cpp +++ b/apps/openmw/mwdialogue/journalimp.cpp @@ -2,30 +2,29 @@ #include -#include #include -#include +#include #include +#include #include -#include "../mwworld/esmstore.hpp" #include "../mwworld/class.hpp" +#include "../mwworld/esmstore.hpp" #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" namespace MWDialogue { - Quest& Journal::getQuest (const std::string& id) + Quest& Journal::getQuest(const std::string& id) { - TQuestContainer::iterator iter = mQuests.find (id); + TQuestContainer::iterator iter = mQuests.find(id); - if (iter==mQuests.end()) + if (iter == mQuests.end()) { - std::pair result = - mQuests.insert (std::make_pair (id, Quest (id))); + std::pair result = mQuests.insert(std::make_pair(id, Quest(id))); iter = result.first; } @@ -33,14 +32,13 @@ namespace MWDialogue return iter->second; } - Topic& Journal::getTopic (const std::string& id) + Topic& Journal::getTopic(const std::string& id) { - TTopicContainer::iterator iter = mTopics.find (id); + TTopicContainer::iterator iter = mTopics.find(id); - if (iter==mTopics.end()) + if (iter == mTopics.end()) { - std::pair result - = mTopics.insert (std::make_pair (id, Topic (id))); + std::pair result = mTopics.insert(std::make_pair(id, Topic(id))); iter = result.first; } @@ -48,16 +46,16 @@ namespace MWDialogue return iter->second; } - bool Journal::isThere (const std::string& topicId, const std::string& infoId) const + bool Journal::isThere(const std::string& topicId, const std::string& infoId) const { - if (const ESM::Dialogue *dialogue = - MWBase::Environment::get().getWorld()->getStore().get().search (topicId)) + if (const ESM::Dialogue* dialogue + = MWBase::Environment::get().getWorld()->getStore().get().search(topicId)) { if (infoId.empty()) return true; - for (ESM::Dialogue::InfoContainer::const_iterator iter (dialogue->mInfo.begin()); - iter!=dialogue->mInfo.end(); ++iter) + for (ESM::Dialogue::InfoContainer::const_iterator iter(dialogue->mInfo.begin()); + iter != dialogue->mInfo.end(); ++iter) if (iter->mId == infoId) return true; } @@ -65,8 +63,7 @@ namespace MWDialogue return false; } - Journal::Journal() - {} + Journal::Journal() {} void Journal::clear() { @@ -75,31 +72,31 @@ namespace MWDialogue mTopics.clear(); } - void Journal::addEntry (const std::string& id, int index, const MWWorld::Ptr& actor) + void Journal::addEntry(const std::string& id, int index, const MWWorld::Ptr& actor) { // bail out if we already have heard this... std::string_view infoId = JournalEntry::idFromIndex(id, index); - for (TEntryIter i = mJournal.begin (); i != mJournal.end (); ++i) + for (TEntryIter i = mJournal.begin(); i != mJournal.end(); ++i) if (i->mTopic == id && i->mInfoId == infoId) { if (getJournalIndex(id) < index) { setJournalIndex(id, index); - MWBase::Environment::get().getWindowManager()->messageBox ("#{sJournalEntry}"); + MWBase::Environment::get().getWindowManager()->messageBox("#{sJournalEntry}"); } return; } - StampedJournalEntry entry = StampedJournalEntry::makeFromQuest (id, index, actor); + StampedJournalEntry entry = StampedJournalEntry::makeFromQuest(id, index, actor); - Quest& quest = getQuest (id); - if(quest.addEntry(entry)) // we are doing slicing on purpose here + Quest& quest = getQuest(id); + if (quest.addEntry(entry)) // we are doing slicing on purpose here { // Restart all "other" quests with the same name as well std::string_view name = quest.getName(); - for(auto& it : mQuests) + for (auto& it : mQuests) { - if(it.second.isFinished() && Misc::StringUtils::ciEqual(it.second.getName(), name)) + if (it.second.isFinished() && Misc::StringUtils::ciEqual(it.second.getName(), name)) it.second.setFinished(false); } } @@ -107,30 +104,30 @@ namespace MWDialogue // there is no need to show empty entries in journal if (!entry.getText().empty()) { - mJournal.push_back (entry); - MWBase::Environment::get().getWindowManager()->messageBox ("#{sJournalEntry}"); + mJournal.push_back(entry); + MWBase::Environment::get().getWindowManager()->messageBox("#{sJournalEntry}"); } } - void Journal::setJournalIndex (const std::string& id, int index) + void Journal::setJournalIndex(const std::string& id, int index) { - Quest& quest = getQuest (id); + Quest& quest = getQuest(id); - quest.setIndex (index); + quest.setIndex(index); } - void Journal::addTopic (const std::string& topicId, const std::string& infoId, const MWWorld::Ptr& actor) + void Journal::addTopic(const std::string& topicId, const std::string& infoId, const MWWorld::Ptr& actor) { - Topic& topic = getTopic (topicId); + Topic& topic = getTopic(topicId); JournalEntry entry(topicId, infoId, actor); entry.mActorName = actor.getClass().getName(actor); - topic.addEntry (entry); + topic.addEntry(entry); } - void Journal::removeLastAddedTopicResponse(const std::string &topicId, std::string_view actorName) + void Journal::removeLastAddedTopicResponse(const std::string& topicId, std::string_view actorName) { - Topic& topic = getTopic (topicId); + Topic& topic = getTopic(topicId); topic.removeLastAddedResponse(actorName); @@ -138,11 +135,11 @@ namespace MWDialogue mTopics.erase(mTopics.find(topicId)); // All responses removed -> remove topic } - int Journal::getJournalIndex (const std::string& id) const + int Journal::getJournalIndex(const std::string& id) const { - TQuestContainer::const_iterator iter = mQuests.find (id); + TQuestContainer::const_iterator iter = mQuests.find(id); - if (iter==mQuests.end()) + if (iter == mQuests.end()) return 0; return iter->second.getIndex(); @@ -180,104 +177,105 @@ namespace MWDialogue int Journal::countSavedGameRecords() const { - int count = static_cast (mQuests.size()); + int count = static_cast(mQuests.size()); - for (TQuestIter iter (mQuests.begin()); iter!=mQuests.end(); ++iter) - count += std::distance (iter->second.begin(), iter->second.end()); + for (TQuestIter iter(mQuests.begin()); iter != mQuests.end(); ++iter) + count += std::distance(iter->second.begin(), iter->second.end()); - count += std::distance (mJournal.begin(), mJournal.end()); + count += std::distance(mJournal.begin(), mJournal.end()); - for (TTopicIter iter (mTopics.begin()); iter!=mTopics.end(); ++iter) - count += std::distance (iter->second.begin(), iter->second.end()); + for (TTopicIter iter(mTopics.begin()); iter != mTopics.end(); ++iter) + count += std::distance(iter->second.begin(), iter->second.end()); return count; } - void Journal::write (ESM::ESMWriter& writer, Loading::Listener& progress) const + void Journal::write(ESM::ESMWriter& writer, Loading::Listener& progress) const { - for (TQuestIter iter (mQuests.begin()); iter!=mQuests.end(); ++iter) + for (TQuestIter iter(mQuests.begin()); iter != mQuests.end(); ++iter) { const Quest& quest = iter->second; ESM::QuestState state; - quest.write (state); - writer.startRecord (ESM::REC_QUES); - state.save (writer); - writer.endRecord (ESM::REC_QUES); + quest.write(state); + writer.startRecord(ESM::REC_QUES); + state.save(writer); + writer.endRecord(ESM::REC_QUES); - for (Topic::TEntryIter entryIter (quest.begin()); entryIter!=quest.end(); ++entryIter) + for (Topic::TEntryIter entryIter(quest.begin()); entryIter != quest.end(); ++entryIter) { ESM::JournalEntry entry; entry.mType = ESM::JournalEntry::Type_Quest; entry.mTopic = quest.getTopic(); - entryIter->write (entry); - writer.startRecord (ESM::REC_JOUR); - entry.save (writer); - writer.endRecord (ESM::REC_JOUR); + entryIter->write(entry); + writer.startRecord(ESM::REC_JOUR); + entry.save(writer); + writer.endRecord(ESM::REC_JOUR); } } - for (TEntryIter iter (mJournal.begin()); iter!=mJournal.end(); ++iter) + for (TEntryIter iter(mJournal.begin()); iter != mJournal.end(); ++iter) { ESM::JournalEntry entry; entry.mType = ESM::JournalEntry::Type_Journal; - iter->write (entry); - writer.startRecord (ESM::REC_JOUR); - entry.save (writer); - writer.endRecord (ESM::REC_JOUR); + iter->write(entry); + writer.startRecord(ESM::REC_JOUR); + entry.save(writer); + writer.endRecord(ESM::REC_JOUR); } - for (TTopicIter iter (mTopics.begin()); iter!=mTopics.end(); ++iter) + for (TTopicIter iter(mTopics.begin()); iter != mTopics.end(); ++iter) { const Topic& topic = iter->second; - for (Topic::TEntryIter entryIter (topic.begin()); entryIter!=topic.end(); ++entryIter) + for (Topic::TEntryIter entryIter(topic.begin()); entryIter != topic.end(); ++entryIter) { ESM::JournalEntry entry; entry.mType = ESM::JournalEntry::Type_Topic; entry.mTopic = topic.getTopic(); - entryIter->write (entry); - writer.startRecord (ESM::REC_JOUR); - entry.save (writer); - writer.endRecord (ESM::REC_JOUR); + entryIter->write(entry); + writer.startRecord(ESM::REC_JOUR); + entry.save(writer); + writer.endRecord(ESM::REC_JOUR); } } } - void Journal::readRecord (ESM::ESMReader& reader, uint32_t type) + void Journal::readRecord(ESM::ESMReader& reader, uint32_t type) { - if (type==ESM::REC_JOUR || type==ESM::REC_JOUR_LEGACY) + if (type == ESM::REC_JOUR || type == ESM::REC_JOUR_LEGACY) { ESM::JournalEntry record; - record.load (reader); + record.load(reader); - if (isThere (record.mTopic, record.mInfo)) + if (isThere(record.mTopic, record.mInfo)) switch (record.mType) { case ESM::JournalEntry::Type_Quest: - getQuest (record.mTopic).insertEntry (record); + getQuest(record.mTopic).insertEntry(record); break; case ESM::JournalEntry::Type_Journal: - mJournal.push_back (record); + mJournal.push_back(record); break; case ESM::JournalEntry::Type_Topic: - getTopic (record.mTopic).insertEntry (record); + getTopic(record.mTopic).insertEntry(record); break; } } - else if (type==ESM::REC_QUES) + else if (type == ESM::REC_QUES) { ESM::QuestState record; - record.load (reader); + record.load(reader); - if (isThere (record.mTopic)) + if (isThere(record.mTopic)) { - std::pair result = mQuests.insert (std::make_pair (record.mTopic, record)); + std::pair result + = mQuests.insert(std::make_pair(record.mTopic, record)); // reapply quest index, this is to handle users upgrading from only // Morrowind.esm (no quest states) to Morrowind.esm + Tribunal.esm result.first->second.setIndex(record.mState); diff --git a/apps/openmw/mwdialogue/journalimp.hpp b/apps/openmw/mwdialogue/journalimp.hpp index 18bbe8b2f2..52d92f333a 100644 --- a/apps/openmw/mwdialogue/journalimp.hpp +++ b/apps/openmw/mwdialogue/journalimp.hpp @@ -10,68 +10,66 @@ namespace MWDialogue /// \brief The player's journal class Journal : public MWBase::Journal { - TEntryContainer mJournal; - TQuestContainer mQuests; - TTopicContainer mTopics; + TEntryContainer mJournal; + TQuestContainer mQuests; + TTopicContainer mTopics; - private: + private: + Quest& getQuest(const std::string& id); - Quest& getQuest (const std::string& id); + Topic& getTopic(const std::string& id); - Topic& getTopic (const std::string& id); + bool isThere(const std::string& topicId, const std::string& infoId = "") const; - bool isThere (const std::string& topicId, const std::string& infoId = "") const; + public: + Journal(); - public: + void clear() override; - Journal(); + void addEntry(const std::string& id, int index, const MWWorld::Ptr& actor) override; + ///< Add a journal entry. + /// @param actor Used as context for replacing of escape sequences (%name, etc). - void clear() override; + void setJournalIndex(const std::string& id, int index) override; + ///< Set the journal index without adding an entry. - void addEntry (const std::string& id, int index, const MWWorld::Ptr& actor) override; - ///< Add a journal entry. - /// @param actor Used as context for replacing of escape sequences (%name, etc). + int getJournalIndex(const std::string& id) const override; + ///< Get the journal index. - void setJournalIndex (const std::string& id, int index) override; - ///< Set the journal index without adding an entry. + void addTopic(const std::string& topicId, const std::string& infoId, const MWWorld::Ptr& actor) override; + /// \note topicId must be lowercase - int getJournalIndex (const std::string& id) const override; - ///< Get the journal index. + void removeLastAddedTopicResponse(const std::string& topicId, std::string_view actorName) override; + ///< Removes the last topic response added for the given topicId and actor name. + /// \note topicId must be lowercase - void addTopic (const std::string& topicId, const std::string& infoId, const MWWorld::Ptr& actor) override; - /// \note topicId must be lowercase + TEntryIter begin() const override; + ///< Iterator pointing to the begin of the main journal. + /// + /// \note Iterators to main journal entries will never become invalid. - void removeLastAddedTopicResponse(const std::string& topicId, std::string_view actorName) override; - ///< Removes the last topic response added for the given topicId and actor name. - /// \note topicId must be lowercase + TEntryIter end() const override; + ///< Iterator pointing past the end of the main journal. - TEntryIter begin() const override; - ///< Iterator pointing to the begin of the main journal. - /// - /// \note Iterators to main journal entries will never become invalid. + TQuestIter questBegin() const override; + ///< Iterator pointing to the first quest (sorted by topic ID) - TEntryIter end() const override; - ///< Iterator pointing past the end of the main journal. + TQuestIter questEnd() const override; + ///< Iterator pointing past the last quest. - TQuestIter questBegin() const override; - ///< Iterator pointing to the first quest (sorted by topic ID) + TTopicIter topicBegin() const override; + ///< Iterator pointing to the first topic (sorted by topic ID) + /// + /// \note The topic ID is identical with the user-visible topic string. - TQuestIter questEnd() const override; - ///< Iterator pointing past the last quest. + TTopicIter topicEnd() const override; + ///< Iterator pointing past the last topic. - TTopicIter topicBegin() const override; - ///< Iterator pointing to the first topic (sorted by topic ID) - /// - /// \note The topic ID is identical with the user-visible topic string. + int countSavedGameRecords() const override; - TTopicIter topicEnd() const override; - ///< Iterator pointing past the last topic. + void write(ESM::ESMWriter& writer, Loading::Listener& progress) const override; - int countSavedGameRecords() const override; - - void write (ESM::ESMWriter& writer, Loading::Listener& progress) const override; - - void readRecord (ESM::ESMReader& reader, uint32_t type) override; + void readRecord(ESM::ESMReader& reader, uint32_t type) override; }; } diff --git a/apps/openmw/mwdialogue/keywordsearch.hpp b/apps/openmw/mwdialogue/keywordsearch.hpp index 8c02210121..e864533906 100644 --- a/apps/openmw/mwdialogue/keywordsearch.hpp +++ b/apps/openmw/mwdialogue/keywordsearch.hpp @@ -1,11 +1,11 @@ #ifndef GAME_MWDIALOGUE_KEYWORDSEARCH_H #define GAME_MWDIALOGUE_KEYWORDSEARCH_H +#include // std::reverse #include #include #include #include -#include // std::reverse #include #include @@ -13,235 +13,233 @@ namespace MWDialogue { -template -class KeywordSearch -{ -public: - - typedef typename string_t::const_iterator Point; - - struct Match + template + class KeywordSearch { - Point mBeg; - Point mEnd; - value_t mValue; - }; + public: + typedef typename string_t::const_iterator Point; - void seed (string_t keyword, value_t value) - { - if (keyword.empty()) - return; - seed_impl (std::move(keyword), std::move (value), 0, mRoot); - } - - void clear () - { - mRoot.mChildren.clear (); - mRoot.mKeyword.clear (); - } + struct Match + { + Point mBeg; + Point mEnd; + value_t mValue; + }; - bool containsKeyword (const string_t& keyword, value_t& value) - { - typename Entry::childen_t::iterator current; - typename Entry::childen_t::iterator next; + void seed(string_t keyword, value_t value) + { + if (keyword.empty()) + return; + seed_impl(std::move(keyword), std::move(value), 0, mRoot); + } - current = mRoot.mChildren.find (Misc::StringUtils::toLower (*keyword.begin())); - if (current == mRoot.mChildren.end()) - return false; - else if (current->second.mKeyword.size() && Misc::StringUtils::ciEqual(current->second.mKeyword, keyword)) + void clear() { - value = current->second.mValue; - return true; + mRoot.mChildren.clear(); + mRoot.mKeyword.clear(); } - for (Point i = ++keyword.begin(); i != keyword.end(); ++i) + bool containsKeyword(const string_t& keyword, value_t& value) { - next = current->second.mChildren.find(Misc::StringUtils::toLower (*i)); - if (next == current->second.mChildren.end()) + typename Entry::childen_t::iterator current; + typename Entry::childen_t::iterator next; + + current = mRoot.mChildren.find(Misc::StringUtils::toLower(*keyword.begin())); + if (current == mRoot.mChildren.end()) return false; - if (Misc::StringUtils::ciEqual(next->second.mKeyword, keyword)) + else if (current->second.mKeyword.size() && Misc::StringUtils::ciEqual(current->second.mKeyword, keyword)) { - value = next->second.mValue; + value = current->second.mValue; return true; } - current = next; - } - return false; - } + for (Point i = ++keyword.begin(); i != keyword.end(); ++i) + { + next = current->second.mChildren.find(Misc::StringUtils::toLower(*i)); + if (next == current->second.mChildren.end()) + return false; + if (Misc::StringUtils::ciEqual(next->second.mKeyword, keyword)) + { + value = next->second.mValue; + return true; + } + current = next; + } + return false; + } - static bool sortMatches(const Match& left, const Match& right) - { - return left.mBeg < right.mBeg; - } + static bool sortMatches(const Match& left, const Match& right) { return left.mBeg < right.mBeg; } - void highlightKeywords (Point beg, Point end, std::vector& out) const - { - std::vector matches; - for (Point i = beg; i != end; ++i) + void highlightKeywords(Point beg, Point end, std::vector& out) const { - // check first character - typename Entry::childen_t::const_iterator candidate = mRoot.mChildren.find (Misc::StringUtils::toLower (*i)); - - // no match, on to next character - if (candidate == mRoot.mChildren.end ()) - continue; + std::vector matches; + for (Point i = beg; i != end; ++i) + { + // check first character + typename Entry::childen_t::const_iterator candidate + = mRoot.mChildren.find(Misc::StringUtils::toLower(*i)); - // see how far the match goes - Point j = i; + // no match, on to next character + if (candidate == mRoot.mChildren.end()) + continue; - // some keywords might be longer variations of other keywords, so we definitely need a list of candidates - // the first element in the pair is length of the match, i.e. depth from the first character on - std::vector< typename std::pair > candidates; + // see how far the match goes + Point j = i; - while ((j + 1) != end) - { - typename Entry::childen_t::const_iterator next = candidate->second.mChildren.find (Misc::StringUtils::toLower (*++j)); + // some keywords might be longer variations of other keywords, so we definitely need a list of + // candidates the first element in the pair is length of the match, i.e. depth from the first character + // on + std::vector> candidates; - if (next == candidate->second.mChildren.end ()) + while ((j + 1) != end) { - if (candidate->second.mKeyword.size() > 0) - candidates.push_back(std::make_pair((j-i), candidate)); - break; - } + typename Entry::childen_t::const_iterator next + = candidate->second.mChildren.find(Misc::StringUtils::toLower(*++j)); - candidate = next; - - if (candidate->second.mKeyword.size() > 0) - candidates.push_back(std::make_pair((j-i), candidate)); - } + if (next == candidate->second.mChildren.end()) + { + if (candidate->second.mKeyword.size() > 0) + candidates.push_back(std::make_pair((j - i), candidate)); + break; + } - if (candidates.empty()) - continue; // didn't match enough to disambiguate, on to next character + candidate = next; - // shorter candidates will be added to the vector first. however, we want to check against longer candidates first - std::reverse(candidates.begin(), candidates.end()); + if (candidate->second.mKeyword.size() > 0) + candidates.push_back(std::make_pair((j - i), candidate)); + } - for (typename std::vector< std::pair >::iterator it = candidates.begin(); - it != candidates.end(); ++it) - { - candidate = it->second; - // try to match the rest of the keyword - Point k = i + it->first; - typename string_t::const_iterator t = candidate->second.mKeyword.begin () + (k - i); + if (candidates.empty()) + continue; // didn't match enough to disambiguate, on to next character + // shorter candidates will be added to the vector first. however, we want to check against longer + // candidates first + std::reverse(candidates.begin(), candidates.end()); - while (k != end && t != candidate->second.mKeyword.end ()) + for (typename std::vector>::iterator it + = candidates.begin(); + it != candidates.end(); ++it) { - if (Misc::StringUtils::toLower (*k) != Misc::StringUtils::toLower (*t)) - break; - - ++k, ++t; + candidate = it->second; + // try to match the rest of the keyword + Point k = i + it->first; + typename string_t::const_iterator t = candidate->second.mKeyword.begin() + (k - i); + + while (k != end && t != candidate->second.mKeyword.end()) + { + if (Misc::StringUtils::toLower(*k) != Misc::StringUtils::toLower(*t)) + break; + + ++k, ++t; + } + + // didn't match full keyword, try the next candidate + if (t != candidate->second.mKeyword.end()) + continue; + + // found a keyword, but there might still be longer keywords that start somewhere _within_ this + // keyword we will resolve these overlapping keywords later, choosing the longest one in case of + // conflict + Match match; + match.mValue = candidate->second.mValue; + match.mBeg = i; + match.mEnd = k; + matches.push_back(match); + break; } - - // didn't match full keyword, try the next candidate - if (t != candidate->second.mKeyword.end ()) - continue; - - // found a keyword, but there might still be longer keywords that start somewhere _within_ this keyword - // we will resolve these overlapping keywords later, choosing the longest one in case of conflict - Match match; - match.mValue = candidate->second.mValue; - match.mBeg = i; - match.mEnd = k; - matches.push_back(match); - break; } - } - // resolve overlapping keywords - while (!matches.empty()) - { - int longestKeywordSize = 0; - typename std::vector::iterator longestKeyword = matches.begin(); - for (typename std::vector::iterator it = matches.begin(); it != matches.end(); ++it) + // resolve overlapping keywords + while (!matches.empty()) { - int size = it->mEnd - it->mBeg; - if (size > longestKeywordSize) + int longestKeywordSize = 0; + typename std::vector::iterator longestKeyword = matches.begin(); + for (typename std::vector::iterator it = matches.begin(); it != matches.end(); ++it) { - longestKeywordSize = size; - longestKeyword = it; - } + int size = it->mEnd - it->mBeg; + if (size > longestKeywordSize) + { + longestKeywordSize = size; + longestKeyword = it; + } - typename std::vector::iterator next = it; - ++next; + typename std::vector::iterator next = it; + ++next; - if (next == matches.end()) - break; + if (next == matches.end()) + break; - if (it->mEnd <= next->mBeg) + if (it->mEnd <= next->mBeg) + { + break; // no overlap + } + } + + Match keyword = *longestKeyword; + matches.erase(longestKeyword); + out.push_back(keyword); + // erase anything that overlaps with the keyword we just added to the output + for (typename std::vector::iterator it = matches.begin(); it != matches.end();) { - break; // no overlap + if (it->mBeg < keyword.mEnd && it->mEnd > keyword.mBeg) + it = matches.erase(it); + else + ++it; } } - Match keyword = *longestKeyword; - matches.erase(longestKeyword); - out.push_back(keyword); - // erase anything that overlaps with the keyword we just added to the output - for (typename std::vector::iterator it = matches.begin(); it != matches.end();) - { - if (it->mBeg < keyword.mEnd && it->mEnd > keyword.mBeg) - it = matches.erase(it); - else - ++it; - } + std::sort(out.begin(), out.end(), sortMatches); } - std::sort(out.begin(), out.end(), sortMatches); - } - -private: - - struct Entry - { - typedef std::map childen_t; + private: + struct Entry + { + typedef std::map childen_t; - string_t mKeyword; - value_t mValue; - childen_t mChildren; - }; + string_t mKeyword; + value_t mValue; + childen_t mChildren; + }; - void seed_impl (string_t keyword, value_t value, size_t depth, Entry & entry) - { - int ch = Misc::StringUtils::toLower (keyword.at (depth)); + void seed_impl(string_t keyword, value_t value, size_t depth, Entry& entry) + { + int ch = Misc::StringUtils::toLower(keyword.at(depth)); - typename Entry::childen_t::iterator j = entry.mChildren.find (ch); + typename Entry::childen_t::iterator j = entry.mChildren.find(ch); - if (j == entry.mChildren.end ()) - { - entry.mChildren [ch].mValue = std::move (value); - entry.mChildren [ch].mKeyword = std::move (keyword); - } - else - { - if (j->second.mKeyword.size () > 0) + if (j == entry.mChildren.end()) + { + entry.mChildren[ch].mValue = std::move(value); + entry.mChildren[ch].mKeyword = std::move(keyword); + } + else { - if (keyword == j->second.mKeyword) - throw std::runtime_error ("duplicate keyword inserted"); + if (j->second.mKeyword.size() > 0) + { + if (keyword == j->second.mKeyword) + throw std::runtime_error("duplicate keyword inserted"); - value_t pushValue = j->second.mValue; - string_t pushKeyword = j->second.mKeyword; + value_t pushValue = j->second.mValue; + string_t pushKeyword = j->second.mKeyword; - if (depth >= pushKeyword.size ()) - throw std::runtime_error ("unexpected"); + if (depth >= pushKeyword.size()) + throw std::runtime_error("unexpected"); - if (depth+1 < pushKeyword.size()) - { - seed_impl (std::move (pushKeyword), std::move (pushValue), depth+1, j->second); - j->second.mKeyword.clear (); + if (depth + 1 < pushKeyword.size()) + { + seed_impl(std::move(pushKeyword), std::move(pushValue), depth + 1, j->second); + j->second.mKeyword.clear(); + } } + if (depth + 1 == keyword.size()) + j->second.mKeyword = value; + else // depth+1 < keyword.size() + seed_impl(std::move(keyword), std::move(value), depth + 1, j->second); } - if (depth+1 == keyword.size()) - j->second.mKeyword = value; - else // depth+1 < keyword.size() - seed_impl (std::move (keyword), std::move (value), depth+1, j->second); } - } - - Entry mRoot; -}; + Entry mRoot; + }; } diff --git a/apps/openmw/mwdialogue/quest.cpp b/apps/openmw/mwdialogue/quest.cpp index e9b0166f9f..ae29b0bca8 100644 --- a/apps/openmw/mwdialogue/quest.cpp +++ b/apps/openmw/mwdialogue/quest.cpp @@ -12,25 +12,34 @@ namespace MWDialogue { Quest::Quest() - : Topic(), mIndex (0), mFinished (false) - {} + : Topic() + , mIndex(0) + , mFinished(false) + { + } - Quest::Quest (const std::string& topic) - : Topic (topic), mIndex (0), mFinished (false) - {} + Quest::Quest(const std::string& topic) + : Topic(topic) + , mIndex(0) + , mFinished(false) + { + } - Quest::Quest (const ESM::QuestState& state) - : Topic (state.mTopic), mIndex (state.mState), mFinished (state.mFinished!=0) - {} + Quest::Quest(const ESM::QuestState& state) + : Topic(state.mTopic) + , mIndex(state.mState) + , mFinished(state.mFinished != 0) + { + } std::string_view Quest::getName() const { - const ESM::Dialogue *dialogue = - MWBase::Environment::get().getWorld()->getStore().get().find (mTopic); + const ESM::Dialogue* dialogue + = MWBase::Environment::get().getWorld()->getStore().get().find(mTopic); - for (ESM::Dialogue::InfoContainer::const_iterator iter (dialogue->mInfo.begin()); - iter!=dialogue->mInfo.end(); ++iter) - if (iter->mQuestStatus==ESM::DialInfo::QS_Name) + for (ESM::Dialogue::InfoContainer::const_iterator iter(dialogue->mInfo.begin()); iter != dialogue->mInfo.end(); + ++iter) + if (iter->mQuestStatus == ESM::DialInfo::QS_Name) return iter->mResponse; return {}; @@ -41,7 +50,7 @@ namespace MWDialogue return mIndex; } - void Quest::setIndex (int index) + void Quest::setIndex(int index) { // The index must be set even if no related journal entry was found mIndex = index; @@ -57,15 +66,16 @@ namespace MWDialogue mFinished = finished; } - bool Quest::addEntry (const JournalEntry& entry) + bool Quest::addEntry(const JournalEntry& entry) { - const ESM::Dialogue *dialogue = - MWBase::Environment::get().getWorld()->getStore().get().find (entry.mTopic); + const ESM::Dialogue* dialogue + = MWBase::Environment::get().getWorld()->getStore().get().find(entry.mTopic); - auto info = std::find_if(dialogue->mInfo.begin(), dialogue->mInfo.end(), [&](const auto& info) { return info.mId == entry.mInfoId; }); + auto info = std::find_if(dialogue->mInfo.begin(), dialogue->mInfo.end(), + [&](const auto& info) { return info.mId == entry.mInfoId; }); if (info == dialogue->mInfo.end() || info->mData.mJournalIndex == -1) - throw std::runtime_error ("unknown journal entry for topic " + mTopic); + throw std::runtime_error("unknown journal entry for topic " + mTopic); if (info->mQuestStatus == ESM::DialInfo::QS_Finished || info->mQuestStatus == ESM::DialInfo::QS_Restart) mFinished = info->mQuestStatus == ESM::DialInfo::QS_Finished; @@ -73,15 +83,15 @@ namespace MWDialogue if (info->mData.mJournalIndex > mIndex) mIndex = info->mData.mJournalIndex; - for (TEntryIter iter (mEntries.begin()); iter!=mEntries.end(); ++iter) - if (iter->mInfoId==entry.mInfoId) + for (TEntryIter iter(mEntries.begin()); iter != mEntries.end(); ++iter) + if (iter->mInfoId == entry.mInfoId) return info->mQuestStatus == ESM::DialInfo::QS_Restart; - mEntries.push_back (entry); // we want slicing here + mEntries.push_back(entry); // we want slicing here return info->mQuestStatus == ESM::DialInfo::QS_Restart; } - void Quest::write (ESM::QuestState& state) const + void Quest::write(ESM::QuestState& state) const { state.mTopic = getTopic(); state.mState = mIndex; diff --git a/apps/openmw/mwdialogue/quest.hpp b/apps/openmw/mwdialogue/quest.hpp index 17ed62b8c9..b1cf178bf5 100644 --- a/apps/openmw/mwdialogue/quest.hpp +++ b/apps/openmw/mwdialogue/quest.hpp @@ -13,34 +13,33 @@ namespace MWDialogue /// \brief A quest in progress or a completed quest class Quest : public Topic { - int mIndex; - bool mFinished; + int mIndex; + bool mFinished; - public: + public: + Quest(); - Quest(); + Quest(const std::string& topic); - Quest (const std::string& topic); + Quest(const ESM::QuestState& state); - Quest (const ESM::QuestState& state); + std::string_view getName() const override; + ///< May be an empty string - std::string_view getName() const override; - ///< May be an empty string + int getIndex() const; - int getIndex() const; + void setIndex(int index); + ///< Calling this function with a non-existent index will throw an exception. - void setIndex (int index); - ///< Calling this function with a non-existent index will throw an exception. + bool isFinished() const; + void setFinished(bool finished); - bool isFinished() const; - void setFinished(bool finished); + bool addEntry(const JournalEntry& entry) override; + ///< Add entry and adjust index accordingly. Returns true if the quest should be restarted. + /// + /// \note Redundant entries are ignored, but the index is still adjusted. - bool addEntry (const JournalEntry& entry) override; - ///< Add entry and adjust index accordingly. Returns true if the quest should be restarted. - /// - /// \note Redundant entries are ignored, but the index is still adjusted. - - void write (ESM::QuestState& state) const; + void write(ESM::QuestState& state) const; }; } diff --git a/apps/openmw/mwdialogue/scripttest.cpp b/apps/openmw/mwdialogue/scripttest.cpp index 3edcf077fc..be10479fdc 100644 --- a/apps/openmw/mwdialogue/scripttest.cpp +++ b/apps/openmw/mwdialogue/scripttest.cpp @@ -1,23 +1,23 @@ #include "scripttest.hpp" -#include "../mwworld/manualref.hpp" -#include "../mwworld/esmstore.hpp" #include "../mwworld/class.hpp" +#include "../mwworld/esmstore.hpp" +#include "../mwworld/manualref.hpp" #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/scriptmanager.hpp" +#include "../mwbase/world.hpp" #include "../mwscript/compilercontext.hpp" -#include #include -#include -#include #include +#include #include -#include +#include +#include #include +#include #include "filter.hpp" @@ -26,101 +26,106 @@ namespace { -void test(const MWWorld::Ptr& actor, int &compiled, int &total, const Compiler::Extensions* extensions, int warningsMode) -{ - MWDialogue::Filter filter(actor, 0, false); - - MWScript::CompilerContext compilerContext(MWScript::CompilerContext::Type_Dialogue); - compilerContext.setExtensions(extensions); - Compiler::StreamErrorHandler errorHandler; - errorHandler.setWarningsMode (warningsMode); - - const MWWorld::Store& dialogues = MWBase::Environment::get().getWorld()->getStore().get(); - for (MWWorld::Store::iterator it = dialogues.begin(); it != dialogues.end(); ++it) + void test( + const MWWorld::Ptr& actor, int& compiled, int& total, const Compiler::Extensions* extensions, int warningsMode) { - std::vector infos = filter.listAll(*it); + MWDialogue::Filter filter(actor, 0, false); - for (std::vector::iterator iter = infos.begin(); iter != infos.end(); ++iter) + MWScript::CompilerContext compilerContext(MWScript::CompilerContext::Type_Dialogue); + compilerContext.setExtensions(extensions); + Compiler::StreamErrorHandler errorHandler; + errorHandler.setWarningsMode(warningsMode); + + const MWWorld::Store& dialogues + = MWBase::Environment::get().getWorld()->getStore().get(); + for (MWWorld::Store::iterator it = dialogues.begin(); it != dialogues.end(); ++it) { - const ESM::DialInfo* info = *iter; - if (!info->mResultScript.empty()) + std::vector infos = filter.listAll(*it); + + for (std::vector::iterator iter = infos.begin(); iter != infos.end(); ++iter) { - bool success = true; - ++total; - try + const ESM::DialInfo* info = *iter; + if (!info->mResultScript.empty()) { - errorHandler.reset(); + bool success = true; + ++total; + try + { + errorHandler.reset(); - std::istringstream input (info->mResultScript + "\n"); + std::istringstream input(info->mResultScript + "\n"); - Compiler::Scanner scanner (errorHandler, input, extensions); + Compiler::Scanner scanner(errorHandler, input, extensions); - Compiler::Locals locals; + Compiler::Locals locals; - std::string_view actorScript = actor.getClass().getScript(actor); + std::string_view actorScript = actor.getClass().getScript(actor); - if (!actorScript.empty()) - { - // grab local variables from actor's script, if available. - locals = MWBase::Environment::get().getScriptManager()->getLocals (actorScript); - } + if (!actorScript.empty()) + { + // grab local variables from actor's script, if available. + locals = MWBase::Environment::get().getScriptManager()->getLocals(actorScript); + } - Compiler::ScriptParser parser(errorHandler, compilerContext, locals, false); + Compiler::ScriptParser parser(errorHandler, compilerContext, locals, false); - scanner.scan (parser); + scanner.scan(parser); - if (!errorHandler.isGood()) - success = false; + if (!errorHandler.isGood()) + success = false; - ++compiled; - } - catch (const Compiler::SourceException& /* error */) - { - // error has already been reported via error handler - success = false; - } - catch (const std::exception& error) - { - Log(Debug::Error) << std::string ("Dialogue error: An exception has been thrown: ") + error.what(); - success = false; - } + ++compiled; + } + catch (const Compiler::SourceException& /* error */) + { + // error has already been reported via error handler + success = false; + } + catch (const std::exception& error) + { + Log(Debug::Error) + << std::string("Dialogue error: An exception has been thrown: ") + error.what(); + success = false; + } - if (!success) - { - Log(Debug::Error) << "Error: compiling failed (dialogue script): \n" << info->mResultScript << "\n"; + if (!success) + { + Log(Debug::Error) << "Error: compiling failed (dialogue script): \n" + << info->mResultScript << "\n"; + } } } } } -} } namespace MWDialogue { -namespace ScriptTest -{ - - std::pair compileAll(const Compiler::Extensions *extensions, int warningsMode) + namespace ScriptTest { - int compiled = 0, total = 0; - const MWWorld::Store& npcs = MWBase::Environment::get().getWorld()->getStore().get(); - for (MWWorld::Store::iterator it = npcs.begin(); it != npcs.end(); ++it) - { - MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), it->mId); - test(ref.getPtr(), compiled, total, extensions, warningsMode); - } - const MWWorld::Store& creatures = MWBase::Environment::get().getWorld()->getStore().get(); - for (MWWorld::Store::iterator it = creatures.begin(); it != creatures.end(); ++it) + std::pair compileAll(const Compiler::Extensions* extensions, int warningsMode) { - MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), it->mId); - test(ref.getPtr(), compiled, total, extensions, warningsMode); + int compiled = 0, total = 0; + const MWWorld::Store& npcs = MWBase::Environment::get().getWorld()->getStore().get(); + for (MWWorld::Store::iterator it = npcs.begin(); it != npcs.end(); ++it) + { + MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), it->mId); + test(ref.getPtr(), compiled, total, extensions, warningsMode); + } + + const MWWorld::Store& creatures + = MWBase::Environment::get().getWorld()->getStore().get(); + for (MWWorld::Store::iterator it = creatures.begin(); it != creatures.end(); ++it) + { + MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), it->mId); + test(ref.getPtr(), compiled, total, extensions, warningsMode); + } + return std::make_pair(total, compiled); } - return std::make_pair(total, compiled); - } -} + } } diff --git a/apps/openmw/mwdialogue/scripttest.hpp b/apps/openmw/mwdialogue/scripttest.hpp index 0ac2597256..4b770ae12c 100644 --- a/apps/openmw/mwdialogue/scripttest.hpp +++ b/apps/openmw/mwdialogue/scripttest.hpp @@ -6,14 +6,14 @@ namespace MWDialogue { -namespace ScriptTest -{ + namespace ScriptTest + { -/// Attempt to compile all dialogue scripts, use for verification purposes -/// @return A pair containing -std::pair compileAll(const Compiler::Extensions* extensions, int warningsMode); + /// Attempt to compile all dialogue scripts, use for verification purposes + /// @return A pair containing + std::pair compileAll(const Compiler::Extensions* extensions, int warningsMode); -} + } } diff --git a/apps/openmw/mwdialogue/selectwrapper.cpp b/apps/openmw/mwdialogue/selectwrapper.cpp index 46f8824437..fa33dcb8e9 100644 --- a/apps/openmw/mwdialogue/selectwrapper.cpp +++ b/apps/openmw/mwdialogue/selectwrapper.cpp @@ -1,43 +1,48 @@ #include "selectwrapper.hpp" -#include -#include #include +#include +#include #include namespace { - template - bool selectCompareImp (char comp, T1 value1, T2 value2) + template + bool selectCompareImp(char comp, T1 value1, T2 value2) { switch (comp) { - case '0': return value1==value2; - case '1': return value1!=value2; - case '2': return value1>value2; - case '3': return value1>=value2; - case '4': return value1 value2; + case '3': + return value1 >= value2; + case '4': + return value1 < value2; + case '5': + return value1 <= value2; } - throw std::runtime_error ("unknown compare type in dialogue info select"); + throw std::runtime_error("unknown compare type in dialogue info select"); } - template - bool selectCompareImp (const ESM::DialInfo::SelectStruct& select, T value1) + template + bool selectCompareImp(const ESM::DialInfo::SelectStruct& select, T value1) { - if (select.mValue.getType()==ESM::VT_Int) + if (select.mValue.getType() == ESM::VT_Int) { - return selectCompareImp (select.mSelectRule[4], value1, select.mValue.getInteger()); + return selectCompareImp(select.mSelectRule[4], value1, select.mValue.getInteger()); } - else if (select.mValue.getType()==ESM::VT_Float) + else if (select.mValue.getType() == ESM::VT_Float) { - return selectCompareImp (select.mSelectRule[4], value1, select.mValue.getFloat()); + return selectCompareImp(select.mSelectRule[4], value1, select.mValue.getFloat()); } else - throw std::runtime_error ( - "unsupported variable type in dialogue info select"); + throw std::runtime_error("unsupported variable type in dialogue info select"); } } @@ -45,56 +50,131 @@ MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::decodeFunction() { int index = 0; - std::istringstream (mSelect.mSelectRule.substr(2,2)) >> index; + std::istringstream(mSelect.mSelectRule.substr(2, 2)) >> index; switch (index) { - case 0: return Function_RankLow; - case 1: return Function_RankHigh; - case 2: return Function_RankRequirement; - case 3: return Function_Reputation; - case 4: return Function_HealthPercent; - case 5: return Function_PCReputation; - case 6: return Function_PcLevel; - case 7: return Function_PcHealthPercent; - case 8: case 9: return Function_PcDynamicStat; - case 10: return Function_PcAttribute; - case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: - case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: case 30: - case 31: case 32: case 33: case 34: case 35: case 36: case 37: return Function_PcSkill; - case 38: return Function_PcGender; - case 39: return Function_PcExpelled; - case 40: return Function_PcCommonDisease; - case 41: return Function_PcBlightDisease; - case 42: return Function_PcClothingModifier; - case 43: return Function_PcCrimeLevel; - case 44: return Function_SameGender; - case 45: return Function_SameRace; - case 46: return Function_SameFaction; - case 47: return Function_FactionRankDiff; - case 48: return Function_Detected; - case 49: return Function_Alarmed; - case 50: return Function_Choice; - case 51: case 52: case 53: case 54: case 55: case 56: case 57: return Function_PcAttribute; - case 58: return Function_PcCorprus; - case 59: return Function_Weather; - case 60: return Function_PcVampire; - case 61: return Function_Level; - case 62: return Function_Attacked; - case 63: return Function_TalkedToPc; - case 64: return Function_PcDynamicStat; - case 65: return Function_CreatureTargetted; - case 66: return Function_FriendlyHit; - case 67: case 68: case 69: case 70: return Function_AiSetting; - case 71: return Function_ShouldAttack; - case 72: return Function_Werewolf; - case 73: return Function_WerewolfKills; + case 0: + return Function_RankLow; + case 1: + return Function_RankHigh; + case 2: + return Function_RankRequirement; + case 3: + return Function_Reputation; + case 4: + return Function_HealthPercent; + case 5: + return Function_PCReputation; + case 6: + return Function_PcLevel; + case 7: + return Function_PcHealthPercent; + case 8: + case 9: + return Function_PcDynamicStat; + case 10: + return Function_PcAttribute; + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + case 21: + case 22: + case 23: + case 24: + case 25: + case 26: + case 27: + case 28: + case 29: + case 30: + case 31: + case 32: + case 33: + case 34: + case 35: + case 36: + case 37: + return Function_PcSkill; + case 38: + return Function_PcGender; + case 39: + return Function_PcExpelled; + case 40: + return Function_PcCommonDisease; + case 41: + return Function_PcBlightDisease; + case 42: + return Function_PcClothingModifier; + case 43: + return Function_PcCrimeLevel; + case 44: + return Function_SameGender; + case 45: + return Function_SameRace; + case 46: + return Function_SameFaction; + case 47: + return Function_FactionRankDiff; + case 48: + return Function_Detected; + case 49: + return Function_Alarmed; + case 50: + return Function_Choice; + case 51: + case 52: + case 53: + case 54: + case 55: + case 56: + case 57: + return Function_PcAttribute; + case 58: + return Function_PcCorprus; + case 59: + return Function_Weather; + case 60: + return Function_PcVampire; + case 61: + return Function_Level; + case 62: + return Function_Attacked; + case 63: + return Function_TalkedToPc; + case 64: + return Function_PcDynamicStat; + case 65: + return Function_CreatureTargetted; + case 66: + return Function_FriendlyHit; + case 67: + case 68: + case 69: + case 70: + return Function_AiSetting; + case 71: + return Function_ShouldAttack; + case 72: + return Function_Werewolf; + case 73: + return Function_WerewolfKills; } return Function_False; } -MWDialogue::SelectWrapper::SelectWrapper (const ESM::DialInfo::SelectStruct& select) : mSelect (select) {} +MWDialogue::SelectWrapper::SelectWrapper(const ESM::DialInfo::SelectStruct& select) + : mSelect(select) +{ +} MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::getFunction() const { @@ -102,18 +182,30 @@ MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::getFunction() con switch (type) { - case '1': return decodeFunction(); - case '2': return Function_Global; - case '3': return Function_Local; - case '4': return Function_Journal; - case '5': return Function_Item; - case '6': return Function_Dead; - case '7': return Function_NotId; - case '8': return Function_NotFaction; - case '9': return Function_NotClass; - case 'A': return Function_NotRace; - case 'B': return Function_NotCell; - case 'C': return Function_NotLocal; + case '1': + return decodeFunction(); + case '2': + return Function_Global; + case '3': + return Function_Local; + case '4': + return Function_Journal; + case '5': + return Function_Item; + case '6': + return Function_Dead; + case '7': + return Function_NotId; + case '8': + return Function_NotFaction; + case '9': + return Function_NotClass; + case 'A': + return Function_NotRace; + case 'B': + return Function_NotCell; + case 'C': + return Function_NotLocal; } return Function_None; @@ -121,64 +213,106 @@ MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::getFunction() con int MWDialogue::SelectWrapper::getArgument() const { - if (mSelect.mSelectRule[1]!='1') + if (mSelect.mSelectRule[1] != '1') return 0; int index = 0; - std::istringstream (mSelect.mSelectRule.substr(2,2)) >> index; + std::istringstream(mSelect.mSelectRule.substr(2, 2)) >> index; switch (index) { // AI settings - case 67: return 1; - case 68: return 0; - case 69: return 3; - case 70: return 2; + case 67: + return 1; + case 68: + return 0; + case 69: + return 3; + case 70: + return 2; // attributes - case 10: return 0; - case 51: return 1; - case 52: return 2; - case 53: return 3; - case 54: return 4; - case 55: return 5; - case 56: return 6; - case 57: return 7; + case 10: + return 0; + case 51: + return 1; + case 52: + return 2; + case 53: + return 3; + case 54: + return 4; + case 55: + return 5; + case 56: + return 6; + case 57: + return 7; // skills - case 11: return 0; - case 12: return 1; - case 13: return 2; - case 14: return 3; - case 15: return 4; - case 16: return 5; - case 17: return 6; - case 18: return 7; - case 19: return 8; - case 20: return 9; - case 21: return 10; - case 22: return 11; - case 23: return 12; - case 24: return 13; - case 25: return 14; - case 26: return 15; - case 27: return 16; - case 28: return 17; - case 29: return 18; - case 30: return 19; - case 31: return 20; - case 32: return 21; - case 33: return 22; - case 34: return 23; - case 35: return 24; - case 36: return 25; - case 37: return 26; + case 11: + return 0; + case 12: + return 1; + case 13: + return 2; + case 14: + return 3; + case 15: + return 4; + case 16: + return 5; + case 17: + return 6; + case 18: + return 7; + case 19: + return 8; + case 20: + return 9; + case 21: + return 10; + case 22: + return 11; + case 23: + return 12; + case 24: + return 13; + case 25: + return 14; + case 26: + return 15; + case 27: + return 16; + case 28: + return 17; + case 29: + return 18; + case 30: + return 19; + case 31: + return 20; + case 32: + return 21; + case 33: + return 22; + case 34: + return 23; + case 35: + return 24; + case 36: + return 25; + case 37: + return 26; // dynamic stats - case 8: return 1; - case 9: return 2; - case 64: return 0; + case 8: + return 1; + case 9: + return 2; + case 64: + return 0; } return 0; @@ -186,73 +320,90 @@ int MWDialogue::SelectWrapper::getArgument() const MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const { - static const Function integerFunctions[] = - { - Function_Journal, Function_Item, Function_Dead, + static const Function integerFunctions[] = { + Function_Journal, + Function_Item, + Function_Dead, Function_Choice, Function_AiSetting, - Function_PcAttribute, Function_PcSkill, + Function_PcAttribute, + Function_PcSkill, Function_FriendlyHit, - Function_PcLevel, Function_PcGender, Function_PcClothingModifier, + Function_PcLevel, + Function_PcGender, + Function_PcClothingModifier, Function_PcCrimeLevel, Function_RankRequirement, - Function_Level, Function_PCReputation, + Function_Level, + Function_PCReputation, Function_Weather, - Function_Reputation, Function_FactionRankDiff, + Function_Reputation, + Function_FactionRankDiff, Function_WerewolfKills, - Function_RankLow, Function_RankHigh, + Function_RankLow, + Function_RankHigh, Function_CreatureTargetted, // end marker Function_None, }; - static const Function numericFunctions[] = - { - Function_Global, Function_Local, Function_NotLocal, - Function_PcDynamicStat, Function_PcHealthPercent, + static const Function numericFunctions[] = { + Function_Global, + Function_Local, + Function_NotLocal, + Function_PcDynamicStat, + Function_PcHealthPercent, Function_HealthPercent, // end marker Function_None, }; - static const Function booleanFunctions[] = - { + static const Function booleanFunctions[] = { Function_False, - Function_SameGender, Function_SameRace, Function_SameFaction, - Function_PcCommonDisease, Function_PcBlightDisease, Function_PcCorprus, + Function_SameGender, + Function_SameRace, + Function_SameFaction, + Function_PcCommonDisease, + Function_PcBlightDisease, + Function_PcCorprus, Function_PcExpelled, - Function_PcVampire, Function_TalkedToPc, - Function_Alarmed, Function_Detected, - Function_Attacked, Function_ShouldAttack, + Function_PcVampire, + Function_TalkedToPc, + Function_Alarmed, + Function_Detected, + Function_Attacked, + Function_ShouldAttack, Function_Werewolf, // end marker Function_None, }; - static const Function invertedBooleanFunctions[] = - { - Function_NotId, Function_NotFaction, Function_NotClass, - Function_NotRace, Function_NotCell, + static const Function invertedBooleanFunctions[] = { + Function_NotId, + Function_NotFaction, + Function_NotClass, + Function_NotRace, + Function_NotCell, // end marker Function_None, }; Function function = getFunction(); - for (int i=0; integerFunctions[i]!=Function_None; ++i) - if (integerFunctions[i]==function) + for (int i = 0; integerFunctions[i] != Function_None; ++i) + if (integerFunctions[i] == function) return Type_Integer; - for (int i=0; numericFunctions[i]!=Function_None; ++i) - if (numericFunctions[i]==function) + for (int i = 0; numericFunctions[i] != Function_None; ++i) + if (numericFunctions[i] == function) return Type_Numeric; - for (int i=0; booleanFunctions[i]!=Function_None; ++i) - if (booleanFunctions[i]==function) + for (int i = 0; booleanFunctions[i] != Function_None; ++i) + if (booleanFunctions[i] == function) return Type_Boolean; - for (int i=0; invertedBooleanFunctions[i]!=Function_None; ++i) - if (invertedBooleanFunctions[i]==function) + for (int i = 0; invertedBooleanFunctions[i] != Function_None; ++i) + if (invertedBooleanFunctions[i] == function) return Type_Inverted; return Type_None; @@ -260,40 +411,46 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const bool MWDialogue::SelectWrapper::isNpcOnly() const { - static const Function functions[] = - { - Function_NotFaction, Function_NotClass, Function_NotRace, - Function_SameGender, Function_SameRace, Function_SameFaction, + static const Function functions[] = { + Function_NotFaction, + Function_NotClass, + Function_NotRace, + Function_SameGender, + Function_SameRace, + Function_SameFaction, Function_RankRequirement, - Function_Reputation, Function_FactionRankDiff, - Function_Werewolf, Function_WerewolfKills, - Function_RankLow, Function_RankHigh, + Function_Reputation, + Function_FactionRankDiff, + Function_Werewolf, + Function_WerewolfKills, + Function_RankLow, + Function_RankHigh, // end marker Function_None, }; Function function = getFunction(); - for (int i=0; functions[i]!=Function_None; ++i) - if (functions[i]==function) + for (int i = 0; functions[i] != Function_None; ++i) + if (functions[i] == function) return true; return false; } -bool MWDialogue::SelectWrapper::selectCompare (int value) const +bool MWDialogue::SelectWrapper::selectCompare(int value) const { - return selectCompareImp (mSelect, value); + return selectCompareImp(mSelect, value); } -bool MWDialogue::SelectWrapper::selectCompare (float value) const +bool MWDialogue::SelectWrapper::selectCompare(float value) const { - return selectCompareImp (mSelect, value); + return selectCompareImp(mSelect, value); } -bool MWDialogue::SelectWrapper::selectCompare (bool value) const +bool MWDialogue::SelectWrapper::selectCompare(bool value) const { - return selectCompareImp (mSelect, static_cast (value)); + return selectCompareImp(mSelect, static_cast(value)); } std::string MWDialogue::SelectWrapper::getName() const diff --git a/apps/openmw/mwdialogue/selectwrapper.hpp b/apps/openmw/mwdialogue/selectwrapper.hpp index dff484562d..0d376d957c 100644 --- a/apps/openmw/mwdialogue/selectwrapper.hpp +++ b/apps/openmw/mwdialogue/selectwrapper.hpp @@ -7,79 +7,94 @@ namespace MWDialogue { class SelectWrapper { - const ESM::DialInfo::SelectStruct& mSelect; - - public: - - enum Function - { - Function_None, Function_False, - Function_Journal, - Function_Item, - Function_Dead, - Function_NotId, - Function_NotFaction, - Function_NotClass, - Function_NotRace, - Function_NotCell, - Function_NotLocal, - Function_Local, - Function_Global, - Function_SameGender, Function_SameRace, Function_SameFaction, - Function_Choice, - Function_PcCommonDisease, Function_PcBlightDisease, Function_PcCorprus, - Function_AiSetting, - Function_PcAttribute, Function_PcSkill, - Function_PcExpelled, - Function_PcVampire, - Function_FriendlyHit, - Function_TalkedToPc, - Function_PcLevel, Function_PcHealthPercent, Function_PcDynamicStat, - Function_PcGender, Function_PcClothingModifier, Function_PcCrimeLevel, - Function_RankRequirement, - Function_HealthPercent, Function_Level, Function_PCReputation, - Function_Weather, - Function_Reputation, Function_Alarmed, Function_FactionRankDiff, Function_Detected, - Function_Attacked, Function_ShouldAttack, - Function_CreatureTargetted, - Function_Werewolf, Function_WerewolfKills, - Function_RankLow, Function_RankHigh - }; - - enum Type - { - Type_None, - Type_Integer, - Type_Numeric, - Type_Boolean, - Type_Inverted - }; - - private: - - Function decodeFunction() const; - - public: - - SelectWrapper (const ESM::DialInfo::SelectStruct& select); - - Function getFunction() const; - - int getArgument() const; - - Type getType() const; - - bool isNpcOnly() const; - ///< \attention Do not call any of the select functions for this select struct! - - bool selectCompare (int value) const; - - bool selectCompare (float value) const; - - bool selectCompare (bool value) const; - - std::string getName() const; - ///< Return case-smashed name. + const ESM::DialInfo::SelectStruct& mSelect; + + public: + enum Function + { + Function_None, + Function_False, + Function_Journal, + Function_Item, + Function_Dead, + Function_NotId, + Function_NotFaction, + Function_NotClass, + Function_NotRace, + Function_NotCell, + Function_NotLocal, + Function_Local, + Function_Global, + Function_SameGender, + Function_SameRace, + Function_SameFaction, + Function_Choice, + Function_PcCommonDisease, + Function_PcBlightDisease, + Function_PcCorprus, + Function_AiSetting, + Function_PcAttribute, + Function_PcSkill, + Function_PcExpelled, + Function_PcVampire, + Function_FriendlyHit, + Function_TalkedToPc, + Function_PcLevel, + Function_PcHealthPercent, + Function_PcDynamicStat, + Function_PcGender, + Function_PcClothingModifier, + Function_PcCrimeLevel, + Function_RankRequirement, + Function_HealthPercent, + Function_Level, + Function_PCReputation, + Function_Weather, + Function_Reputation, + Function_Alarmed, + Function_FactionRankDiff, + Function_Detected, + Function_Attacked, + Function_ShouldAttack, + Function_CreatureTargetted, + Function_Werewolf, + Function_WerewolfKills, + Function_RankLow, + Function_RankHigh + }; + + enum Type + { + Type_None, + Type_Integer, + Type_Numeric, + Type_Boolean, + Type_Inverted + }; + + private: + Function decodeFunction() const; + + public: + SelectWrapper(const ESM::DialInfo::SelectStruct& select); + + Function getFunction() const; + + int getArgument() const; + + Type getType() const; + + bool isNpcOnly() const; + ///< \attention Do not call any of the select functions for this select struct! + + bool selectCompare(int value) const; + + bool selectCompare(float value) const; + + bool selectCompare(bool value) const; + + std::string getName() const; + ///< Return case-smashed name. }; } diff --git a/apps/openmw/mwdialogue/topic.cpp b/apps/openmw/mwdialogue/topic.cpp index 50316cfabf..fd6ca7d015 100644 --- a/apps/openmw/mwdialogue/topic.cpp +++ b/apps/openmw/mwdialogue/topic.cpp @@ -7,21 +7,20 @@ namespace MWDialogue { - Topic::Topic() - {} + Topic::Topic() {} - Topic::Topic (const std::string& topic) - : mTopic (topic), mName ( - MWBase::Environment::get().getWorld()->getStore().get().find (topic)->mId) - {} + Topic::Topic(const std::string& topic) + : mTopic(topic) + , mName(MWBase::Environment::get().getWorld()->getStore().get().find(topic)->mId) + { + } - Topic::~Topic() - {} + Topic::~Topic() {} - bool Topic::addEntry (const JournalEntry& entry) + bool Topic::addEntry(const JournalEntry& entry) { - if (entry.mTopic!=mTopic) - throw std::runtime_error ("topic does not match: " + mTopic); + if (entry.mTopic != mTopic) + throw std::runtime_error("topic does not match: " + mTopic); // bail out if we already have heard this for (Topic::TEntryIter it = mEntries.begin(); it != mEntries.end(); ++it) @@ -30,13 +29,13 @@ namespace MWDialogue return false; } - mEntries.push_back (entry); // we want slicing here + mEntries.push_back(entry); // we want slicing here return false; } - void Topic::insertEntry (const ESM::JournalEntry& entry) + void Topic::insertEntry(const ESM::JournalEntry& entry) { - mEntries.push_back (entry); + mEntries.push_back(entry); } std::string Topic::getTopic() const @@ -61,12 +60,11 @@ namespace MWDialogue void Topic::removeLastAddedResponse(std::string_view actorName) { - for (std::vector::reverse_iterator it = mEntries.rbegin(); - it != mEntries.rend(); ++it) + for (std::vector::reverse_iterator it = mEntries.rbegin(); it != mEntries.rend(); ++it) { if (it->mActorName == actorName) { - mEntries.erase( (++it).base() ); // erase doesn't take a reverse_iterator + mEntries.erase((++it).base()); // erase doesn't take a reverse_iterator return; } } diff --git a/apps/openmw/mwdialogue/topic.hpp b/apps/openmw/mwdialogue/topic.hpp index bf74b54e13..c45992a763 100644 --- a/apps/openmw/mwdialogue/topic.hpp +++ b/apps/openmw/mwdialogue/topic.hpp @@ -17,45 +17,42 @@ namespace MWDialogue /// \brief Collection of seen responses for a topic class Topic { - public: + public: + typedef std::vector TEntryContainer; + typedef TEntryContainer::const_iterator TEntryIter; - typedef std::vector TEntryContainer; - typedef TEntryContainer::const_iterator TEntryIter; + protected: + std::string mTopic; + std::string mName; + TEntryContainer mEntries; - protected: + public: + Topic(); - std::string mTopic; - std::string mName; - TEntryContainer mEntries; + Topic(const std::string& topic); - public: + virtual ~Topic(); - Topic(); + virtual bool addEntry(const JournalEntry& entry); + ///< Add entry + /// + /// \note Redundant entries are ignored. - Topic (const std::string& topic); + void insertEntry(const ESM::JournalEntry& entry); + ///< Add entry without checking for redundant entries or modifying the state of the + /// topic otherwise - virtual ~Topic(); + std::string getTopic() const; - virtual bool addEntry (const JournalEntry& entry); - ///< Add entry - /// - /// \note Redundant entries are ignored. + virtual std::string_view getName() const; - void insertEntry (const ESM::JournalEntry& entry); - ///< Add entry without checking for redundant entries or modifying the state of the - /// topic otherwise + void removeLastAddedResponse(std::string_view actorName); - std::string getTopic() const; + TEntryIter begin() const; + ///< Iterator pointing to the begin of the journal for this topic. - virtual std::string_view getName() const; - - void removeLastAddedResponse(std::string_view actorName); - - TEntryIter begin() const; - ///< Iterator pointing to the begin of the journal for this topic. - - TEntryIter end() const; - ///< Iterator pointing past the end of the journal for this topic. + TEntryIter end() const; + ///< Iterator pointing past the end of the journal for this topic. }; } diff --git a/apps/openmw/mwgui/alchemywindow.cpp b/apps/openmw/mwgui/alchemywindow.cpp index 67bee26710..238e8c3bc8 100644 --- a/apps/openmw/mwgui/alchemywindow.cpp +++ b/apps/openmw/mwgui/alchemywindow.cpp @@ -1,22 +1,22 @@ #include "alchemywindow.hpp" -#include #include -#include #include #include #include +#include +#include -#include #include +#include #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" -#include "../mwmechanics/magiceffects.hpp" -#include "../mwmechanics/alchemy.hpp" #include "../mwmechanics/actorutil.hpp" +#include "../mwmechanics/alchemy.hpp" +#include "../mwmechanics/magiceffects.hpp" #include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" @@ -24,9 +24,9 @@ #include #include "inventoryitemmodel.hpp" -#include "sortfilteritemmodel.hpp" #include "itemview.hpp" #include "itemwidget.hpp" +#include "sortfilteritemmodel.hpp" #include "ustring.hpp" #include "widgets.hpp" @@ -38,8 +38,8 @@ namespace MWGui , mModel(nullptr) , mSortModel(nullptr) , mAlchemy(std::make_unique()) - , mApparatus (4) - , mIngredients (4) + , mApparatus(4) + , mIngredients(4) { getWidget(mCreateButton, "CreateButton"); getWidget(mCancelButton, "CancelButton"); @@ -112,35 +112,36 @@ namespace MWGui void AlchemyWindow::createPotions(int count) { MWMechanics::Alchemy::Result result = mAlchemy->create(mNameEdit->getCaption(), count); - MWBase::WindowManager *winMgr = MWBase::Environment::get().getWindowManager(); + MWBase::WindowManager* winMgr = MWBase::Environment::get().getWindowManager(); switch (result) { - case MWMechanics::Alchemy::Result_NoName: - winMgr->messageBox("#{sNotifyMessage37}"); - break; - case MWMechanics::Alchemy::Result_NoMortarAndPestle: - winMgr->messageBox("#{sNotifyMessage45}"); - break; - case MWMechanics::Alchemy::Result_LessThanTwoIngredients: - winMgr->messageBox("#{sNotifyMessage6a}"); - break; - case MWMechanics::Alchemy::Result_Success: - winMgr->playSound("potion success"); - if (count == 1) - winMgr->messageBox("#{sPotionSuccess}"); - else - winMgr->messageBox("#{sPotionSuccess} "+mNameEdit->getCaption().asUTF8()+" ("+std::to_string(count)+")"); - break; - case MWMechanics::Alchemy::Result_NoEffects: - case MWMechanics::Alchemy::Result_RandomFailure: - winMgr->messageBox("#{sNotifyMessage8}"); - winMgr->playSound("potion fail"); - break; + case MWMechanics::Alchemy::Result_NoName: + winMgr->messageBox("#{sNotifyMessage37}"); + break; + case MWMechanics::Alchemy::Result_NoMortarAndPestle: + winMgr->messageBox("#{sNotifyMessage45}"); + break; + case MWMechanics::Alchemy::Result_LessThanTwoIngredients: + winMgr->messageBox("#{sNotifyMessage6a}"); + break; + case MWMechanics::Alchemy::Result_Success: + winMgr->playSound("potion success"); + if (count == 1) + winMgr->messageBox("#{sPotionSuccess}"); + else + winMgr->messageBox( + "#{sPotionSuccess} " + mNameEdit->getCaption().asUTF8() + " (" + std::to_string(count) + ")"); + break; + case MWMechanics::Alchemy::Result_NoEffects: + case MWMechanics::Alchemy::Result_RandomFailure: + winMgr->messageBox("#{sNotifyMessage8}"); + winMgr->playSound("potion fail"); + break; } // remove ingredient slots that have been fully used up - for (int i=0; i<4; ++i) + for (int i = 0; i < 4; ++i) if (mIngredients[i]->isUserString("ToolTipType")) { MWWorld::Ptr ingred = *mIngredients[i]->getUserData(); @@ -170,7 +171,7 @@ namespace MWGui { auto const& wm = MWBase::Environment::get().getWindowManager(); MyGUI::UString ingredient = toUString(wm->getGameSettingString("sIngredients", "Ingredients")); - auto *button = _sender->castType(); + auto* button = _sender->castType(); if (button->getCaption() == ingredient) { @@ -200,7 +201,7 @@ namespace MWGui itemNames.emplace(item.getClass().getName(item)); - MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); auto const alchemySkill = player.getClass().getSkill(player, ESM::Skill::Alchemy); auto const effects = MWMechanics::Alchemy::effectsDescription(item, alchemySkill); @@ -208,15 +209,18 @@ namespace MWGui } mFilterValue->removeAllItems(); - auto const addItems = [&](auto const& container) - { + auto const addItems = [&](auto const& container) { for (auto const& item : container) mFilterValue->addItem(item); }; switch (mCurrentFilter) { - case FilterType::ByName: addItems(itemNames); break; - case FilterType::ByEffect: addItems(itemEffects); break; + case FilterType::ByName: + addItems(itemNames); + break; + case FilterType::ByEffect: + addItems(itemEffects); + break; } } @@ -224,8 +228,12 @@ namespace MWGui { switch (mCurrentFilter) { - case FilterType::ByName: mSortModel->setNameFilter(filter); break; - case FilterType::ByEffect: mSortModel->setEffectFilter(filter); break; + case FilterType::ByName: + mSortModel->setNameFilter(filter); + break; + case FilterType::ByEffect: + mSortModel->setEffectFilter(filter); + break; } mItemView->update(); } @@ -246,7 +254,7 @@ namespace MWGui void AlchemyWindow::onOpen() { mAlchemy->clear(); - mAlchemy->setAlchemist (MWMechanics::getPlayer()); + mAlchemy->setAlchemist(MWMechanics::getPlayer()); auto model = std::make_unique(MWMechanics::getPlayer()); mModel = model.get(); @@ -260,15 +268,15 @@ namespace MWGui mBrewCountEdit->setValue(1); int index = 0; - for (MWMechanics::Alchemy::TToolsIterator iter (mAlchemy->beginTools()); - iter!=mAlchemy->endTools() && index (mApparatus.size()); ++iter, ++index) + for (MWMechanics::Alchemy::TToolsIterator iter(mAlchemy->beginTools()); + iter != mAlchemy->endTools() && index < static_cast(mApparatus.size()); ++iter, ++index) { - mApparatus.at (index)->setItem(*iter); - mApparatus.at (index)->clearUserStrings(); + mApparatus.at(index)->setItem(*iter); + mApparatus.at(index)->clearUserStrings(); if (!iter->isEmpty()) { - mApparatus.at (index)->setUserString ("ToolTipType", "ItemPtr"); - mApparatus.at (index)->setUserData (MWWorld::Ptr(*iter)); + mApparatus.at(index)->setUserString("ToolTipType", "ItemPtr"); + mApparatus.at(index)->setUserData(MWWorld::Ptr(*iter)); } } @@ -307,13 +315,13 @@ namespace MWGui mSortModel->clearDragItems(); - MWMechanics::Alchemy::TIngredientsIterator it = mAlchemy->beginIngredients (); - for (int i=0; i<4; ++i) + MWMechanics::Alchemy::TIngredientsIterator it = mAlchemy->beginIngredients(); + for (int i = 0; i < 4; ++i) { ItemWidget* ingredient = mIngredients[i]; MWWorld::Ptr item; - if (it != mAlchemy->endIngredients ()) + if (it != mAlchemy->endIngredients()) { item = *it; ++it; @@ -325,11 +333,11 @@ namespace MWGui if (ingredient->getChildCount()) MyGUI::Gui::getInstance().destroyWidget(ingredient->getChildAt(0)); - ingredient->clearUserStrings (); + ingredient->clearUserStrings(); ingredient->setItem(item); - if (item.isEmpty ()) + if (item.isEmpty()) continue; ingredient->setUserString("ToolTipType", "ItemPtr"); @@ -342,12 +350,13 @@ namespace MWGui std::set effectIds = mAlchemy->listEffects(); Widgets::SpellEffectList list; - unsigned int effectIndex=0; + unsigned int effectIndex = 0; for (const MWMechanics::EffectKey& effectKey : effectIds) { Widgets::SpellEffectParams params; params.mEffectID = effectKey.mId; - const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getWorld()->getStore().get().find(effectKey.mId); + const ESM::MagicEffect* magicEffect + = MWBase::Environment::get().getWorld()->getStore().get().find(effectKey.mId); if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetSkill) params.mSkill = effectKey.mArg; else if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetAttribute) @@ -366,8 +375,8 @@ namespace MWGui MyGUI::Gui::getInstance().destroyWidget(mEffectsBox->getChildAt(0)); MyGUI::IntCoord coord(0, 0, mEffectsBox->getWidth(), 24); - Widgets::MWEffectListPtr effectsWidget = mEffectsBox->createWidget - ("MW_StatName", coord, MyGUI::Align::Left | MyGUI::Align::Top); + Widgets::MWEffectListPtr effectsWidget = mEffectsBox->createWidget( + "MW_StatName", coord, MyGUI::Align::Left | MyGUI::Align::Top); effectsWidget->setEffectList(list); @@ -378,16 +387,17 @@ namespace MWGui void AlchemyWindow::removeIngredient(MyGUI::Widget* ingredient) { - for (int i=0; i<4; ++i) + for (int i = 0; i < 4; ++i) if (mIngredients[i] == ingredient) - mAlchemy->removeIngredient (i); + mAlchemy->removeIngredient(i); update(); } - void AlchemyWindow::addRepeatController(MyGUI::Widget *widget) + void AlchemyWindow::addRepeatController(MyGUI::Widget* widget) { - MyGUI::ControllerItem* item = MyGUI::ControllerManager::getInstance().createItem(MyGUI::ControllerRepeatClick::getClassTypeName()); + MyGUI::ControllerItem* item + = MyGUI::ControllerManager::getInstance().createItem(MyGUI::ControllerRepeatClick::getClassTypeName()); MyGUI::ControllerRepeatClick* controller = static_cast(item); controller->eventRepeatClick += newDelegate(this, &AlchemyWindow::onRepeatClick); MyGUI::ControllerManager::getInstance().addItem(widget, controller); @@ -413,7 +423,7 @@ namespace MWGui onDecreaseButtonTriggered(); } - void AlchemyWindow::onCountButtonReleased(MyGUI::Widget *_sender, int _left, int _top, MyGUI::MouseButton _id) + void AlchemyWindow::onCountButtonReleased(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) { MyGUI::ControllerManager::getInstance().removeItem(_sender); } @@ -431,13 +441,13 @@ namespace MWGui if (currentCount == std::numeric_limits::max()) return; - mBrewCountEdit->setValue(currentCount+1); + mBrewCountEdit->setValue(currentCount + 1); } void AlchemyWindow::onDecreaseButtonTriggered() { int currentCount = mBrewCountEdit->getValue(); if (currentCount > 1) - mBrewCountEdit->setValue(currentCount-1); + mBrewCountEdit->setValue(currentCount - 1); } } diff --git a/apps/openmw/mwgui/alchemywindow.hpp b/apps/openmw/mwgui/alchemywindow.hpp index afc00e2bfb..681de0e316 100644 --- a/apps/openmw/mwgui/alchemywindow.hpp +++ b/apps/openmw/mwgui/alchemywindow.hpp @@ -4,8 +4,8 @@ #include #include -#include #include +#include #include #include @@ -31,12 +31,15 @@ namespace MWGui void onResChange(int, int) override { center(); } private: - static const float sCountChangeInitialPause; // in seconds static const float sCountChangeInterval; // in seconds std::string mSuggestedPotionName; - enum class FilterType { ByName, ByEffect }; + enum class FilterType + { + ByName, + ByEffect + }; FilterType mCurrentFilter; ItemView* mItemView; diff --git a/apps/openmw/mwgui/backgroundimage.cpp b/apps/openmw/mwgui/backgroundimage.cpp index 55c825ebbd..e2e2c62cd1 100644 --- a/apps/openmw/mwgui/backgroundimage.cpp +++ b/apps/openmw/mwgui/backgroundimage.cpp @@ -5,59 +5,59 @@ namespace MWGui { -void BackgroundImage::setBackgroundImage (const std::string& image, bool fixedRatio, bool stretch) -{ - if (mChild) + void BackgroundImage::setBackgroundImage(const std::string& image, bool fixedRatio, bool stretch) { - MyGUI::Gui::getInstance().destroyWidget(mChild); - mChild = nullptr; + if (mChild) + { + MyGUI::Gui::getInstance().destroyWidget(mChild); + mChild = nullptr; + } + if (!stretch) + { + setImageTexture("black"); + + if (fixedRatio) + mAspect = 4.0 / 3.0; + else + mAspect = 0; // TODO + + mChild + = createWidgetReal("ImageBox", MyGUI::FloatCoord(0, 0, 1, 1), MyGUI::Align::Default); + mChild->setImageTexture(image); + + adjustSize(); + } + else + { + mAspect = 0; + setImageTexture(image); + } } - if (!stretch) + + void BackgroundImage::adjustSize() { - setImageTexture("black"); + if (mAspect == 0) + return; - if (fixedRatio) - mAspect = 4.0/3.0; - else - mAspect = 0; // TODO + MyGUI::IntSize screenSize = getSize(); - mChild = createWidgetReal("ImageBox", - MyGUI::FloatCoord(0,0,1,1), MyGUI::Align::Default); - mChild->setImageTexture(image); + int leftPadding = std::max(0, static_cast(screenSize.width - screenSize.height * mAspect) / 2); + int topPadding = std::max(0, static_cast(screenSize.height - screenSize.width / mAspect) / 2); - adjustSize(); + mChild->setCoord( + leftPadding, topPadding, screenSize.width - leftPadding * 2, screenSize.height - topPadding * 2); } - else + + void BackgroundImage::setSize(const MyGUI::IntSize& _value) { - mAspect = 0; - setImageTexture(image); + MyGUI::Widget::setSize(_value); + adjustSize(); } -} - -void BackgroundImage::adjustSize() -{ - if (mAspect == 0) - return; - - MyGUI::IntSize screenSize = getSize(); - - int leftPadding = std::max(0, static_cast(screenSize.width - screenSize.height * mAspect) / 2); - int topPadding = std::max(0, static_cast(screenSize.height - screenSize.width / mAspect) / 2); - - mChild->setCoord(leftPadding, topPadding, screenSize.width - leftPadding*2, screenSize.height - topPadding*2); -} - -void BackgroundImage::setSize (const MyGUI::IntSize& _value) -{ - MyGUI::Widget::setSize (_value); - adjustSize(); -} - -void BackgroundImage::setCoord (const MyGUI::IntCoord& _value) -{ - MyGUI::Widget::setCoord (_value); - adjustSize(); -} + void BackgroundImage::setCoord(const MyGUI::IntCoord& _value) + { + MyGUI::Widget::setCoord(_value); + adjustSize(); + } } diff --git a/apps/openmw/mwgui/backgroundimage.hpp b/apps/openmw/mwgui/backgroundimage.hpp index 32cdf1a657..b151a26e27 100644 --- a/apps/openmw/mwgui/backgroundimage.hpp +++ b/apps/openmw/mwgui/backgroundimage.hpp @@ -11,19 +11,23 @@ namespace MWGui */ class BackgroundImage final : public MyGUI::ImageBox { - MYGUI_RTTI_DERIVED(BackgroundImage) + MYGUI_RTTI_DERIVED(BackgroundImage) public: - BackgroundImage() : mChild(nullptr), mAspect(0) {} + BackgroundImage() + : mChild(nullptr) + , mAspect(0) + { + } /** * @param fixedRatio Use a fixed ratio of 4:3, regardless of the image dimensions * @param stretch Stretch to fill the whole screen, or add black bars? */ - void setBackgroundImage (const std::string& image, bool fixedRatio=true, bool stretch=true); + void setBackgroundImage(const std::string& image, bool fixedRatio = true, bool stretch = true); - void setSize (const MyGUI::IntSize &_value) override; - void setCoord (const MyGUI::IntCoord &_value) override; + void setSize(const MyGUI::IntSize& _value) override; + void setCoord(const MyGUI::IntCoord& _value) override; private: MyGUI::ImageBox* mChild; diff --git a/apps/openmw/mwgui/birth.cpp b/apps/openmw/mwgui/birth.cpp index 6686678983..5390705f93 100644 --- a/apps/openmw/mwgui/birth.cpp +++ b/apps/openmw/mwgui/birth.cpp @@ -1,18 +1,18 @@ #include "birth.hpp" -#include -#include #include +#include +#include #include -#include -#include #include #include +#include +#include #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" #include "../mwworld/esmstore.hpp" #include "../mwworld/player.hpp" @@ -23,9 +23,10 @@ namespace { - bool sortBirthSigns(const std::pair& left, const std::pair& right) + bool sortBirthSigns(const std::pair& left, + const std::pair& right) { - return left.second->mName.compare (right.second->mName) < 0; + return left.second->mName.compare(right.second->mName) < 0; } } @@ -34,7 +35,7 @@ namespace MWGui { BirthDialog::BirthDialog() - : WindowModal("openmw_chargen_birth.layout") + : WindowModal("openmw_chargen_birth.layout") { // Centre dialog center(); @@ -67,9 +68,11 @@ namespace MWGui getWidget(okButton, "OKButton"); if (shown) - okButton->setCaption(toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString("sNext", {}))); + okButton->setCaption( + toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString("sNext", {}))); else - okButton->setCaption(toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", {}))); + okButton->setCaption( + toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", {}))); } void BirthDialog::onOpen() @@ -80,14 +83,13 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mBirthList); // Show the current birthsign by default - const std::string &signId = - MWBase::Environment::get().getWorld()->getPlayer().getBirthSign(); + const std::string& signId = MWBase::Environment::get().getWorld()->getPlayer().getBirthSign(); if (!signId.empty()) setBirthId(signId); } - void BirthDialog::setBirthId(const std::string &birthId) + void BirthDialog::setBirthId(const std::string& birthId) { mCurrentBirthId = birthId; mBirthList->setIndexSelected(MyGUI::ITEM_NONE); @@ -108,15 +110,15 @@ namespace MWGui void BirthDialog::onOkClicked(MyGUI::Widget* _sender) { - if(mBirthList->getIndexSelected() == MyGUI::ITEM_NONE) + if (mBirthList->getIndexSelected() == MyGUI::ITEM_NONE) return; eventDone(this); } - void BirthDialog::onAccept(MyGUI::ListBox *_sender, size_t _index) + void BirthDialog::onAccept(MyGUI::ListBox* _sender, size_t _index) { onSelectBirth(_sender, _index); - if(mBirthList->getIndexSelected() == MyGUI::ITEM_NONE) + if (mBirthList->getIndexSelected() == MyGUI::ITEM_NONE) return; eventDone(this); } @@ -131,7 +133,7 @@ namespace MWGui if (_index == MyGUI::ITEM_NONE) return; - const std::string *birthId = mBirthList->getItemDataAt(_index); + const std::string* birthId = mBirthList->getItemDataAt(_index); if (Misc::StringUtils::ciEqual(mCurrentBirthId, *birthId)) return; @@ -145,11 +147,11 @@ namespace MWGui { mBirthList->removeAllItems(); - const MWWorld::Store &signs = - MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& signs + = MWBase::Environment::get().getWorld()->getStore().get(); // sort by name - std::vector < std::pair > birthSigns; + std::vector> birthSigns; for (const ESM::BirthSign& sign : signs) { @@ -190,14 +192,12 @@ namespace MWGui const int lineHeight = MWBase::Environment::get().getWindowManager()->getFontHeight() + 2; MyGUI::IntCoord coord(0, 0, mSpellArea->getWidth(), lineHeight); - const MWWorld::ESMStore &store = - MWBase::Environment::get().getWorld()->getStore(); + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); - const ESM::BirthSign *birth = - store.get().find(mCurrentBirthId); + const ESM::BirthSign* birth = store.get().find(mCurrentBirthId); - mBirthImage->setImageTexture(Misc::ResourceHelpers::correctTexturePath(birth->mTexture, - MWBase::Environment::get().getResourceSystem()->getVFS())); + mBirthImage->setImageTexture(Misc::ResourceHelpers::correctTexturePath( + birth->mTexture, MWBase::Environment::get().getResourceSystem()->getVFS())); std::vector abilities, powers, spells; @@ -205,8 +205,8 @@ namespace MWGui std::vector::const_iterator end = birth->mPowers.mList.end(); for (; it != end; ++it) { - const std::string &spellId = *it; - const ESM::Spell *spell = store.get().search(spellId); + const std::string& spellId = *it; + const ESM::Spell* spell = store.get().search(spellId); if (!spell) continue; // Skip spells which cannot be found ESM::Spell::SpellType type = static_cast(spell->mData.mType); @@ -223,38 +223,39 @@ namespace MWGui int i = 0; - struct { - const std::vector &spells; - const char *label; - } - categories[3] = { - {abilities, "sBirthsignmenu1"}, - {powers, "sPowers"}, - {spells, "sBirthsignmenu2"} - }; + struct + { + const std::vector& spells; + const char* label; + } categories[3] = { { abilities, "sBirthsignmenu1" }, { powers, "sPowers" }, { spells, "sBirthsignmenu2" } }; for (int category = 0; category < 3; ++category) { if (!categories[category].spells.empty()) { - MyGUI::TextBox* label = mSpellArea->createWidget("SandBrightText", coord, MyGUI::Align::Default, std::string("Label")); - label->setCaption(toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString(categories[category].label, {}))); + MyGUI::TextBox* label = mSpellArea->createWidget( + "SandBrightText", coord, MyGUI::Align::Default, std::string("Label")); + label->setCaption(toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString( + categories[category].label, {}))); mSpellItems.push_back(label); coord.top += lineHeight; end = categories[category].spells.end(); for (it = categories[category].spells.begin(); it != end; ++it) { - const std::string &spellId = *it; - spellWidget = mSpellArea->createWidget("MW_StatName", coord, MyGUI::Align::Default, std::string("Spell") + MyGUI::utility::toString(i)); + const std::string& spellId = *it; + spellWidget = mSpellArea->createWidget("MW_StatName", coord, + MyGUI::Align::Default, std::string("Spell") + MyGUI::utility::toString(i)); spellWidget->setSpellId(spellId); mSpellItems.push_back(spellWidget); coord.top += lineHeight; MyGUI::IntCoord spellCoord = coord; - spellCoord.height = 24; // TODO: This should be fetched from the skin somehow, or perhaps a widget in the layout as a template? - spellWidget->createEffectWidgets(mSpellItems, mSpellArea, spellCoord, (category == 0) ? Widgets::MWEffectList::EF_Constant : 0); + spellCoord.height = 24; // TODO: This should be fetched from the skin somehow, or perhaps a widget + // in the layout as a template? + spellWidget->createEffectWidgets( + mSpellItems, mSpellArea, spellCoord, (category == 0) ? Widgets::MWEffectList::EF_Constant : 0); coord.top = spellCoord.top; ++i; @@ -262,7 +263,8 @@ namespace MWGui } } - // Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden + // Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the + // scrollbar is hidden mSpellArea->setVisibleVScroll(false); mSpellArea->setCanvasSize(MyGUI::IntSize(mSpellArea->getWidth(), std::max(mSpellArea->getHeight(), coord.top))); mSpellArea->setVisibleVScroll(true); diff --git a/apps/openmw/mwgui/birth.hpp b/apps/openmw/mwgui/birth.hpp index 9f9d4332f1..edf2db2351 100644 --- a/apps/openmw/mwgui/birth.hpp +++ b/apps/openmw/mwgui/birth.hpp @@ -16,8 +16,8 @@ namespace MWGui GM_Female }; - const std::string &getBirthId() const { return mCurrentBirthId; } - void setBirthId(const std::string &raceId); + const std::string& getBirthId() const { return mCurrentBirthId; } + void setBirthId(const std::string& raceId); void setNextButtonShow(bool shown); void onOpen() override; diff --git a/apps/openmw/mwgui/bookpage.cpp b/apps/openmw/mwgui/bookpage.cpp index 7cc0f60b1d..9833dd5729 100644 --- a/apps/openmw/mwgui/bookpage.cpp +++ b/apps/openmw/mwgui/bookpage.cpp @@ -2,1406 +2,1404 @@ #include +#include "MyGUI_FactoryManager.h" +#include "MyGUI_FontManager.h" #include "MyGUI_RenderItem.h" #include "MyGUI_RenderManager.h" #include "MyGUI_TextureUtility.h" -#include "MyGUI_FactoryManager.h" -#include "MyGUI_FontManager.h" #include #include - namespace MWGui { -struct TypesetBookImpl; -class PageDisplay; -class BookPageImpl; + struct TypesetBookImpl; + class PageDisplay; + class BookPageImpl; -static bool ucsSpace (int codePoint); -static bool ucsLineBreak (int codePoint); -static bool ucsCarriageReturn (int codePoint); -static bool ucsBreakingSpace (int codePoint); + static bool ucsSpace(int codePoint); + static bool ucsLineBreak(int codePoint); + static bool ucsCarriageReturn(int codePoint); + static bool ucsBreakingSpace(int codePoint); -struct BookTypesetter::Style { virtual ~Style () {} }; - -struct TypesetBookImpl : TypesetBook -{ - typedef std::vector Content; - typedef std::list Contents; - typedef Utf8Stream::Point Utf8Point; - typedef std::pair Range; + struct BookTypesetter::Style + { + virtual ~Style() {} + }; - struct StyleImpl : BookTypesetter::Style + struct TypesetBookImpl : TypesetBook { - MyGUI::IFont* mFont; - MyGUI::Colour mHotColour; - MyGUI::Colour mActiveColour; - MyGUI::Colour mNormalColour; - InteractiveId mInteractiveId; - - bool match (MyGUI::IFont* tstFont, const MyGUI::Colour& tstHotColour, const MyGUI::Colour& tstActiveColour, - const MyGUI::Colour& tstNormalColour, intptr_t tstInteractiveId) - { - return (mFont == tstFont) && - partal_match (tstHotColour, tstActiveColour, tstNormalColour, tstInteractiveId); - } + typedef std::vector Content; + typedef std::list Contents; + typedef Utf8Stream::Point Utf8Point; + typedef std::pair Range; - bool match (char const * tstFont, const MyGUI::Colour& tstHotColour, const MyGUI::Colour& tstActiveColour, - const MyGUI::Colour& tstNormalColour, intptr_t tstInteractiveId) + struct StyleImpl : BookTypesetter::Style { - return (mFont->getResourceName () == tstFont) && - partal_match (tstHotColour, tstActiveColour, tstNormalColour, tstInteractiveId); - } + MyGUI::IFont* mFont; + MyGUI::Colour mHotColour; + MyGUI::Colour mActiveColour; + MyGUI::Colour mNormalColour; + InteractiveId mInteractiveId; + + bool match(MyGUI::IFont* tstFont, const MyGUI::Colour& tstHotColour, const MyGUI::Colour& tstActiveColour, + const MyGUI::Colour& tstNormalColour, intptr_t tstInteractiveId) + { + return (mFont == tstFont) + && partal_match(tstHotColour, tstActiveColour, tstNormalColour, tstInteractiveId); + } - bool partal_match (const MyGUI::Colour& tstHotColour, const MyGUI::Colour& tstActiveColour, - const MyGUI::Colour& tstNormalColour, intptr_t tstInteractiveId) - { - return - (mHotColour == tstHotColour ) && - (mActiveColour == tstActiveColour ) && - (mNormalColour == tstNormalColour ) && - (mInteractiveId == tstInteractiveId ) ; - } - }; + bool match(char const* tstFont, const MyGUI::Colour& tstHotColour, const MyGUI::Colour& tstActiveColour, + const MyGUI::Colour& tstNormalColour, intptr_t tstInteractiveId) + { + return (mFont->getResourceName() == tstFont) + && partal_match(tstHotColour, tstActiveColour, tstNormalColour, tstInteractiveId); + } - typedef std::list Styles; + bool partal_match(const MyGUI::Colour& tstHotColour, const MyGUI::Colour& tstActiveColour, + const MyGUI::Colour& tstNormalColour, intptr_t tstInteractiveId) + { + return (mHotColour == tstHotColour) && (mActiveColour == tstActiveColour) + && (mNormalColour == tstNormalColour) && (mInteractiveId == tstInteractiveId); + } + }; - struct Run - { - StyleImpl* mStyle; - Range mRange; - int mLeft, mRight; - int mPrintableChars; - }; + typedef std::list Styles; - typedef std::vector Runs; + struct Run + { + StyleImpl* mStyle; + Range mRange; + int mLeft, mRight; + int mPrintableChars; + }; - struct Line - { - Runs mRuns; - MyGUI::IntRect mRect; - }; + typedef std::vector Runs; - typedef std::vector Lines; + struct Line + { + Runs mRuns; + MyGUI::IntRect mRect; + }; - struct Section - { - Lines mLines; - MyGUI::IntRect mRect; - }; + typedef std::vector Lines; - typedef std::vector

        Sections; + struct Section + { + Lines mLines; + MyGUI::IntRect mRect; + }; - // Holds "top" and "bottom" vertical coordinates in the source text. - // A page is basically a "window" into a portion of the source text, similar to a ScrollView. - typedef std::pair Page; + typedef std::vector
        Sections; - typedef std::vector Pages; + // Holds "top" and "bottom" vertical coordinates in the source text. + // A page is basically a "window" into a portion of the source text, similar to a ScrollView. + typedef std::pair Page; - Pages mPages; - Sections mSections; - Contents mContents; - Styles mStyles; - MyGUI::IntRect mRect; + typedef std::vector Pages; - virtual ~TypesetBookImpl () {} + Pages mPages; + Sections mSections; + Contents mContents; + Styles mStyles; + MyGUI::IntRect mRect; - Range addContent (const BookTypesetter::Utf8Span &text) - { - Contents::iterator i = mContents.insert (mContents.end (), Content (text.first, text.second)); + virtual ~TypesetBookImpl() {} - if (i->empty()) - return Range (Utf8Point (nullptr), Utf8Point (nullptr)); + Range addContent(const BookTypesetter::Utf8Span& text) + { + Contents::iterator i = mContents.insert(mContents.end(), Content(text.first, text.second)); - return Range (i->data(), i->data() + i->size()); - } + if (i->empty()) + return Range(Utf8Point(nullptr), Utf8Point(nullptr)); - size_t pageCount () const override { return mPages.size (); } + return Range(i->data(), i->data() + i->size()); + } - std::pair getSize () const override - { - return std::make_pair (mRect.width (), mRect.height ()); - } + size_t pageCount() const override { return mPages.size(); } - template - void visitRuns (int top, int bottom, MyGUI::IFont* Font, Visitor const & visitor) const - { - for (Sections::const_iterator i = mSections.begin (); i != mSections.end (); ++i) + std::pair getSize() const override { - if (top >= mRect.bottom || bottom <= i->mRect.top) - continue; + return std::make_pair(mRect.width(), mRect.height()); + } - for (Lines::const_iterator j = i->mLines.begin (); j != i->mLines.end (); ++j) + template + void visitRuns(int top, int bottom, MyGUI::IFont* Font, Visitor const& visitor) const + { + for (Sections::const_iterator i = mSections.begin(); i != mSections.end(); ++i) { - if (top >= j->mRect.bottom || bottom <= j->mRect.top) + if (top >= mRect.bottom || bottom <= i->mRect.top) continue; - for (Runs::const_iterator k = j->mRuns.begin (); k != j->mRuns.end (); ++k) - if (!Font || k->mStyle->mFont == Font) - visitor (*i, *j, *k); + for (Lines::const_iterator j = i->mLines.begin(); j != i->mLines.end(); ++j) + { + if (top >= j->mRect.bottom || bottom <= j->mRect.top) + continue; + + for (Runs::const_iterator k = j->mRuns.begin(); k != j->mRuns.end(); ++k) + if (!Font || k->mStyle->mFont == Font) + visitor(*i, *j, *k); + } } } - } - template - void visitRuns (int top, int bottom, Visitor const & visitor) const - { - visitRuns (top, bottom, nullptr, visitor); - } - - /// hit test with a margin for error. only hits on interactive text fragments are reported. - StyleImpl * hitTestWithMargin (int left, int top) - { - StyleImpl * hit = hitTest(left, top); - if (hit && hit->mInteractiveId != 0) - return hit; + template + void visitRuns(int top, int bottom, Visitor const& visitor) const + { + visitRuns(top, bottom, nullptr, visitor); + } - const int maxMargin = 10; - for (int margin=1; margin < maxMargin; ++margin) + /// hit test with a margin for error. only hits on interactive text fragments are reported. + StyleImpl* hitTestWithMargin(int left, int top) { - for (int i=0; i<4; ++i) - { - if (i==0) - hit = hitTest(left, top-margin); - else if (i==1) - hit = hitTest(left, top+margin); - else if (i==2) - hit = hitTest(left-margin, top); - else - hit = hitTest(left+margin, top); + StyleImpl* hit = hitTest(left, top); + if (hit && hit->mInteractiveId != 0) + return hit; - if (hit && hit->mInteractiveId != 0) - return hit; + const int maxMargin = 10; + for (int margin = 1; margin < maxMargin; ++margin) + { + for (int i = 0; i < 4; ++i) + { + if (i == 0) + hit = hitTest(left, top - margin); + else if (i == 1) + hit = hitTest(left, top + margin); + else if (i == 2) + hit = hitTest(left - margin, top); + else + hit = hitTest(left + margin, top); + + if (hit && hit->mInteractiveId != 0) + return hit; + } } + return nullptr; } - return nullptr; - } - StyleImpl * hitTest (int left, int top) const - { - for (Sections::const_iterator i = mSections.begin (); i != mSections.end (); ++i) + StyleImpl* hitTest(int left, int top) const { - if (top < i->mRect.top || top >= i->mRect.bottom) - continue; - - int left1 = left - i->mRect.left; - - for (Lines::const_iterator j = i->mLines.begin (); j != i->mLines.end (); ++j) + for (Sections::const_iterator i = mSections.begin(); i != mSections.end(); ++i) { - if (top < j->mRect.top || top >= j->mRect.bottom) + if (top < i->mRect.top || top >= i->mRect.bottom) continue; - int left2 = left1 - j->mRect.left; + int left1 = left - i->mRect.left; - for (Runs::const_iterator k = j->mRuns.begin (); k != j->mRuns.end (); ++k) + for (Lines::const_iterator j = i->mLines.begin(); j != i->mLines.end(); ++j) { - if (left2 < k->mLeft || left2 >= k->mRight) + if (top < j->mRect.top || top >= j->mRect.bottom) continue; - return k->mStyle; + int left2 = left1 - j->mRect.left; + + for (Runs::const_iterator k = j->mRuns.begin(); k != j->mRuns.end(); ++k) + { + if (left2 < k->mLeft || left2 >= k->mRight) + continue; + + return k->mStyle; + } } } + + return nullptr; } - return nullptr; - } + MyGUI::IFont* affectedFont(StyleImpl* style) + { + for (Styles::iterator i = mStyles.begin(); i != mStyles.end(); ++i) + if (&*i == style) + return i->mFont; + return nullptr; + } - MyGUI::IFont* affectedFont (StyleImpl* style) - { - for (Styles::iterator i = mStyles.begin (); i != mStyles.end (); ++i) - if (&*i == style) - return i->mFont; - return nullptr; - } + struct Typesetter; + }; - struct Typesetter; -}; + struct TypesetBookImpl::Typesetter : BookTypesetter + { + struct PartialText + { + StyleImpl* mStyle; + Utf8Stream::Point mBegin; + Utf8Stream::Point mEnd; + int mWidth; + + PartialText(StyleImpl* style, Utf8Stream::Point begin, Utf8Stream::Point end, int width) + : mStyle(style) + , mBegin(begin) + , mEnd(end) + , mWidth(width) + { + } + }; + + typedef TypesetBookImpl Book; + typedef std::shared_ptr BookPtr; + typedef std::vector::const_iterator PartialTextConstIterator; + + int mPageWidth; + int mPageHeight; + + BookPtr mBook; + Section* mSection; + Line* mLine; + Run* mRun; + + std::vector mSectionAlignment; + std::vector mPartialWhitespace; + std::vector mPartialWord; + + Book::Content const* mCurrentContent; + Alignment mCurrentAlignment; + + Typesetter(size_t width, size_t height) + : mPageWidth(width) + , mPageHeight(height) + , mSection(nullptr) + , mLine(nullptr) + , mRun(nullptr) + , mCurrentContent(nullptr) + , mCurrentAlignment(AlignLeft) + { + mBook = std::make_shared(); + } -struct TypesetBookImpl::Typesetter : BookTypesetter -{ - struct PartialText { - StyleImpl *mStyle; - Utf8Stream::Point mBegin; - Utf8Stream::Point mEnd; - int mWidth; - - PartialText( StyleImpl *style, Utf8Stream::Point begin, Utf8Stream::Point end, int width) : - mStyle(style), mBegin(begin), mEnd(end), mWidth(width) - {} - }; + virtual ~Typesetter() {} - typedef TypesetBookImpl Book; - typedef std::shared_ptr BookPtr; - typedef std::vector::const_iterator PartialTextConstIterator; + Style* createStyle(const std::string& fontName, const Colour& fontColour, bool useBookFont) override + { + std::string fullFontName; + if (fontName.empty()) + fullFontName = MyGUI::FontManager::getInstance().getDefaultFont(); + else + fullFontName = fontName; - int mPageWidth; - int mPageHeight; + if (useBookFont) + fullFontName = "Journalbook " + fullFontName; - BookPtr mBook; - Section * mSection; - Line * mLine; - Run * mRun; + for (Styles::iterator i = mBook->mStyles.begin(); i != mBook->mStyles.end(); ++i) + if (i->match(fullFontName.c_str(), fontColour, fontColour, fontColour, 0)) + return &*i; - std::vector mSectionAlignment; - std::vector mPartialWhitespace; - std::vector mPartialWord; + MyGUI::IFont* font = MyGUI::FontManager::getInstance().getByName(fullFontName); + if (!font) + throw std::runtime_error(std::string("can't find font ") + fullFontName); - Book::Content const * mCurrentContent; - Alignment mCurrentAlignment; + StyleImpl& style = *mBook->mStyles.insert(mBook->mStyles.end(), StyleImpl()); + style.mFont = font; + style.mHotColour = fontColour; + style.mActiveColour = fontColour; + style.mNormalColour = fontColour; + style.mInteractiveId = 0; - Typesetter (size_t width, size_t height) : - mPageWidth (width), mPageHeight(height), - mSection (nullptr), mLine (nullptr), mRun (nullptr), - mCurrentContent (nullptr), - mCurrentAlignment (AlignLeft) - { - mBook = std::make_shared (); - } + return &style; + } - virtual ~Typesetter () - { - } + Style* createHotStyle(Style* baseStyle, const Colour& normalColour, const Colour& hoverColour, + const Colour& activeColour, InteractiveId id, bool unique) override + { + StyleImpl* BaseStyle = static_cast(baseStyle); - Style * createStyle (const std::string& fontName, const Colour& fontColour, bool useBookFont) override - { - std::string fullFontName; - if (fontName.empty()) - fullFontName = MyGUI::FontManager::getInstance().getDefaultFont(); - else - fullFontName = fontName; - - if (useBookFont) - fullFontName = "Journalbook " + fullFontName; - - for (Styles::iterator i = mBook->mStyles.begin (); i != mBook->mStyles.end (); ++i) - if (i->match (fullFontName.c_str(), fontColour, fontColour, fontColour, 0)) - return &*i; - - MyGUI::IFont* font = MyGUI::FontManager::getInstance().getByName(fullFontName); - if (!font) - throw std::runtime_error(std::string("can't find font ") + fullFontName); - - StyleImpl & style = *mBook->mStyles.insert (mBook->mStyles.end (), StyleImpl ()); - style.mFont = font; - style.mHotColour = fontColour; - style.mActiveColour = fontColour; - style.mNormalColour = fontColour; - style.mInteractiveId = 0; - - return &style; - } + if (!unique) + for (Styles::iterator i = mBook->mStyles.begin(); i != mBook->mStyles.end(); ++i) + if (i->match(BaseStyle->mFont, hoverColour, activeColour, normalColour, id)) + return &*i; - Style* createHotStyle (Style* baseStyle, const Colour& normalColour, const Colour& hoverColour, - const Colour& activeColour, InteractiveId id, bool unique) override - { - StyleImpl* BaseStyle = static_cast (baseStyle); + StyleImpl& style = *mBook->mStyles.insert(mBook->mStyles.end(), StyleImpl()); - if (!unique) - for (Styles::iterator i = mBook->mStyles.begin (); i != mBook->mStyles.end (); ++i) - if (i->match (BaseStyle->mFont, hoverColour, activeColour, normalColour, id)) - return &*i; + style.mFont = BaseStyle->mFont; + style.mHotColour = hoverColour; + style.mActiveColour = activeColour; + style.mNormalColour = normalColour; + style.mInteractiveId = id; - StyleImpl & style = *mBook->mStyles.insert (mBook->mStyles.end (), StyleImpl ()); + return &style; + } - style.mFont = BaseStyle->mFont; - style.mHotColour = hoverColour; - style.mActiveColour = activeColour; - style.mNormalColour = normalColour; - style.mInteractiveId = id; + void write(Style* style, Utf8Span text) override + { + Range range = mBook->addContent(text); - return &style; - } + writeImpl(static_cast(style), range.first, range.second); + } - void write (Style * style, Utf8Span text) override - { - Range range = mBook->addContent (text); + intptr_t addContent(Utf8Span text, bool select) override + { + add_partial_text(); - writeImpl (static_cast (style), range.first, range.second); - } + Contents::iterator i = mBook->mContents.insert(mBook->mContents.end(), Content(text.first, text.second)); - intptr_t addContent (Utf8Span text, bool select) override - { - add_partial_text(); + if (select) + mCurrentContent = &(*i); - Contents::iterator i = mBook->mContents.insert (mBook->mContents.end (), Content (text.first, text.second)); + return reinterpret_cast(&(*i)); + } - if (select) - mCurrentContent = &(*i); + void selectContent(intptr_t contentHandle) override + { + add_partial_text(); - return reinterpret_cast (&(*i)); - } + mCurrentContent = reinterpret_cast(contentHandle); + } - void selectContent (intptr_t contentHandle) override - { - add_partial_text(); + void write(Style* style, size_t begin, size_t end) override + { + assert(mCurrentContent != nullptr); + assert(end <= mCurrentContent->size()); + assert(begin <= mCurrentContent->size()); - mCurrentContent = reinterpret_cast (contentHandle); - } + Utf8Point begin_ = mCurrentContent->data() + begin; + Utf8Point end_ = mCurrentContent->data() + end; - void write (Style * style, size_t begin, size_t end) override - { - assert (mCurrentContent != nullptr); - assert (end <= mCurrentContent->size ()); - assert (begin <= mCurrentContent->size ()); + writeImpl(static_cast(style), begin_, end_); + } - Utf8Point begin_ = mCurrentContent->data() + begin; - Utf8Point end_ = mCurrentContent->data() + end; + void lineBreak(float margin) override + { + assert(margin == 0); // TODO: figure out proper behavior here... - writeImpl (static_cast (style), begin_, end_); - } + add_partial_text(); - void lineBreak (float margin) override - { - assert (margin == 0); //TODO: figure out proper behavior here... + mRun = nullptr; + mLine = nullptr; + } - add_partial_text(); + void sectionBreak(int margin) override + { + add_partial_text(); - mRun = nullptr; - mLine = nullptr; - } + if (mBook->mSections.size() > 0) + { + mRun = nullptr; + mLine = nullptr; + mSection = nullptr; - void sectionBreak (int margin) override - { - add_partial_text(); + if (mBook->mRect.bottom < (mBook->mSections.back().mRect.bottom + margin)) + mBook->mRect.bottom = (mBook->mSections.back().mRect.bottom + margin); + } + } - if (mBook->mSections.size () > 0) + void setSectionAlignment(Alignment sectionAlignment) override { - mRun = nullptr; - mLine = nullptr; - mSection = nullptr; + add_partial_text(); - if (mBook->mRect.bottom < (mBook->mSections.back ().mRect.bottom + margin)) - mBook->mRect.bottom = (mBook->mSections.back ().mRect.bottom + margin); + if (mSection != nullptr) + mSectionAlignment.back() = sectionAlignment; + mCurrentAlignment = sectionAlignment; } - } - void setSectionAlignment (Alignment sectionAlignment) override - { - add_partial_text(); + TypesetBook::Ptr complete() override + { + int curPageStart = 0; + int curPageStop = 0; - if (mSection != nullptr) - mSectionAlignment.back () = sectionAlignment; - mCurrentAlignment = sectionAlignment; - } + add_partial_text(); - TypesetBook::Ptr complete () override - { - int curPageStart = 0; - int curPageStop = 0; + std::vector::iterator sa = mSectionAlignment.begin(); + for (Sections::iterator i = mBook->mSections.begin(); i != mBook->mSections.end(); ++i, ++sa) + { + // apply alignment to individual lines... + for (Lines::iterator j = i->mLines.begin(); j != i->mLines.end(); ++j) + { + int width = j->mRect.width(); + int excess = mPageWidth - width; - add_partial_text(); + switch (*sa) + { + default: + case AlignLeft: + j->mRect.left = 0; + break; + case AlignCenter: + j->mRect.left = excess / 2; + break; + case AlignRight: + j->mRect.left = excess; + break; + } - std::vector ::iterator sa = mSectionAlignment.begin (); - for (Sections::iterator i = mBook->mSections.begin (); i != mBook->mSections.end (); ++i, ++sa) - { - // apply alignment to individual lines... - for (Lines::iterator j = i->mLines.begin (); j != i->mLines.end (); ++j) - { - int width = j->mRect.width (); - int excess = mPageWidth - width; + j->mRect.right = j->mRect.left + width; + } - switch (*sa) + if (curPageStop == curPageStart) { - default: - case AlignLeft: j->mRect.left = 0; break; - case AlignCenter: j->mRect.left = excess/2; break; - case AlignRight: j->mRect.left = excess; break; + curPageStart = i->mRect.top; + curPageStop = i->mRect.top; } - j->mRect.right = j->mRect.left + width; - } - - if (curPageStop == curPageStart) - { - curPageStart = i->mRect.top; - curPageStop = i->mRect.top; - } - - int spaceLeft = mPageHeight - (curPageStop - curPageStart); - int sectionHeight = i->mRect.height (); + int spaceLeft = mPageHeight - (curPageStop - curPageStart); + int sectionHeight = i->mRect.height(); - // This is NOT equal to i->mRect.height(), which doesn't account for section breaks. - int spaceRequired = (i->mRect.bottom - curPageStop); - if (curPageStart == curPageStop) // If this is a new page, the section break is not needed - spaceRequired = i->mRect.height(); + // This is NOT equal to i->mRect.height(), which doesn't account for section breaks. + int spaceRequired = (i->mRect.bottom - curPageStop); + if (curPageStart == curPageStop) // If this is a new page, the section break is not needed + spaceRequired = i->mRect.height(); - if (spaceRequired <= mPageHeight) - { - if (spaceRequired > spaceLeft) + if (spaceRequired <= mPageHeight) { - // The section won't completely fit on the current page. Finish the current page and start a new one. - assert (curPageStart != curPageStop); + if (spaceRequired > spaceLeft) + { + // The section won't completely fit on the current page. Finish the current page and start a new + // one. + assert(curPageStart != curPageStop); - mBook->mPages.push_back (Page (curPageStart, curPageStop)); + mBook->mPages.push_back(Page(curPageStart, curPageStop)); - curPageStart = i->mRect.top; - curPageStop = i->mRect.bottom; + curPageStart = i->mRect.top; + curPageStop = i->mRect.bottom; + } + else + curPageStop = i->mRect.bottom; } else - curPageStop = i->mRect.bottom; - } - else - { - // The section won't completely fit on the current page. Finish the current page and start a new one. - mBook->mPages.push_back (Page (curPageStart, curPageStop)); + { + // The section won't completely fit on the current page. Finish the current page and start a new + // one. + mBook->mPages.push_back(Page(curPageStart, curPageStop)); - curPageStart = i->mRect.top; - curPageStop = i->mRect.bottom; + curPageStart = i->mRect.top; + curPageStop = i->mRect.bottom; - //split section - int sectionHeightLeft = sectionHeight; - while (sectionHeightLeft >= mPageHeight) - { - // Adjust to the top of the first line that does not fit on the current page anymore - int splitPos = curPageStop; - for (Lines::iterator j = i->mLines.begin (); j != i->mLines.end (); ++j) + // split section + int sectionHeightLeft = sectionHeight; + while (sectionHeightLeft >= mPageHeight) { - if (j->mRect.bottom > curPageStart + mPageHeight) + // Adjust to the top of the first line that does not fit on the current page anymore + int splitPos = curPageStop; + for (Lines::iterator j = i->mLines.begin(); j != i->mLines.end(); ++j) { - splitPos = j->mRect.top; - break; + if (j->mRect.bottom > curPageStart + mPageHeight) + { + splitPos = j->mRect.top; + break; + } } - } - mBook->mPages.push_back (Page (curPageStart, splitPos)); - curPageStart = splitPos; - curPageStop = splitPos; + mBook->mPages.push_back(Page(curPageStart, splitPos)); + curPageStart = splitPos; + curPageStop = splitPos; - sectionHeightLeft = (i->mRect.bottom - splitPos); + sectionHeightLeft = (i->mRect.bottom - splitPos); + } + curPageStop = i->mRect.bottom; } - curPageStop = i->mRect.bottom; } - } - if (curPageStart != curPageStop) - mBook->mPages.push_back (Page (curPageStart, curPageStop)); + if (curPageStart != curPageStop) + mBook->mPages.push_back(Page(curPageStart, curPageStop)); - return mBook; - } - - void writeImpl (StyleImpl * style, Utf8Stream::Point _begin, Utf8Stream::Point _end) - { - Utf8Stream stream (_begin, _end); + return mBook; + } - while (!stream.eof ()) + void writeImpl(StyleImpl* style, Utf8Stream::Point _begin, Utf8Stream::Point _end) { - if (ucsLineBreak (stream.peek ())) + Utf8Stream stream(_begin, _end); + + while (!stream.eof()) { - add_partial_text(); - stream.consume (); - mLine = nullptr; - mRun = nullptr; - continue; - } + if (ucsLineBreak(stream.peek())) + { + add_partial_text(); + stream.consume(); + mLine = nullptr; + mRun = nullptr; + continue; + } - if (ucsBreakingSpace (stream.peek ()) && !mPartialWord.empty()) - add_partial_text(); + if (ucsBreakingSpace(stream.peek()) && !mPartialWord.empty()) + add_partial_text(); - int word_width = 0; - int space_width = 0; + int word_width = 0; + int space_width = 0; - Utf8Stream::Point lead = stream.current (); + Utf8Stream::Point lead = stream.current(); - while (!stream.eof () && !ucsLineBreak (stream.peek ()) && ucsBreakingSpace (stream.peek ())) - { - MWGui::GlyphInfo info = GlyphInfo(style->mFont, stream.peek()); - if (info.charFound) - space_width += static_cast(info.advance + info.bearingX); - stream.consume (); - } + while (!stream.eof() && !ucsLineBreak(stream.peek()) && ucsBreakingSpace(stream.peek())) + { + MWGui::GlyphInfo info = GlyphInfo(style->mFont, stream.peek()); + if (info.charFound) + space_width += static_cast(info.advance + info.bearingX); + stream.consume(); + } - Utf8Stream::Point origin = stream.current (); + Utf8Stream::Point origin = stream.current(); - while (!stream.eof () && !ucsLineBreak (stream.peek ()) && !ucsBreakingSpace (stream.peek ())) - { - MWGui::GlyphInfo info = GlyphInfo(style->mFont, stream.peek()); - if (info.charFound) - word_width += static_cast(info.advance + info.bearingX); - stream.consume (); - } + while (!stream.eof() && !ucsLineBreak(stream.peek()) && !ucsBreakingSpace(stream.peek())) + { + MWGui::GlyphInfo info = GlyphInfo(style->mFont, stream.peek()); + if (info.charFound) + word_width += static_cast(info.advance + info.bearingX); + stream.consume(); + } - Utf8Stream::Point extent = stream.current (); + Utf8Stream::Point extent = stream.current(); - if (lead == extent) - break; + if (lead == extent) + break; - if ( lead != origin ) - mPartialWhitespace.emplace_back(style, lead, origin, space_width); - if ( origin != extent ) - mPartialWord.emplace_back(style, origin, extent, word_width); + if (lead != origin) + mPartialWhitespace.emplace_back(style, lead, origin, space_width); + if (origin != extent) + mPartialWord.emplace_back(style, origin, extent, word_width); + } } - } - void add_partial_text () - { - if (mPartialWhitespace.empty() && mPartialWord.empty()) - return; + void add_partial_text() + { + if (mPartialWhitespace.empty() && mPartialWord.empty()) + return; - int fontHeight = MWBase::Environment::get().getWindowManager()->getFontHeight(); - int space_width = 0; - int word_width = 0; + int fontHeight = MWBase::Environment::get().getWindowManager()->getFontHeight(); + int space_width = 0; + int word_width = 0; - for (PartialTextConstIterator i = mPartialWhitespace.begin (); i != mPartialWhitespace.end (); ++i) - space_width += i->mWidth; - for (PartialTextConstIterator i = mPartialWord.begin (); i != mPartialWord.end (); ++i) - word_width += i->mWidth; + for (PartialTextConstIterator i = mPartialWhitespace.begin(); i != mPartialWhitespace.end(); ++i) + space_width += i->mWidth; + for (PartialTextConstIterator i = mPartialWord.begin(); i != mPartialWord.end(); ++i) + word_width += i->mWidth; - int left = mLine ? mLine->mRect.right : 0; + int left = mLine ? mLine->mRect.right : 0; - if (left + space_width + word_width > mPageWidth) - { - mLine = nullptr; - mRun = nullptr; - left = 0; - } - else - { - for (PartialTextConstIterator i = mPartialWhitespace.begin (); i != mPartialWhitespace.end (); ++i) + if (left + space_width + word_width > mPageWidth) { - int top = mLine ? mLine->mRect.top : mBook->mRect.bottom; + mLine = nullptr; + mRun = nullptr; + left = 0; + } + else + { + for (PartialTextConstIterator i = mPartialWhitespace.begin(); i != mPartialWhitespace.end(); ++i) + { + int top = mLine ? mLine->mRect.top : mBook->mRect.bottom; - append_run ( i->mStyle, i->mBegin, i->mEnd, 0, left + i->mWidth, top + fontHeight); + append_run(i->mStyle, i->mBegin, i->mEnd, 0, left + i->mWidth, top + fontHeight); - left = mLine->mRect.right; + left = mLine->mRect.right; + } } - } - for (PartialTextConstIterator i = mPartialWord.begin (); i != mPartialWord.end (); ++i) - { - int top = mLine ? mLine->mRect.top : mBook->mRect.bottom; - - append_run (i->mStyle, i->mBegin, i->mEnd, i->mEnd - i->mBegin, left + i->mWidth, top + fontHeight); + for (PartialTextConstIterator i = mPartialWord.begin(); i != mPartialWord.end(); ++i) + { + int top = mLine ? mLine->mRect.top : mBook->mRect.bottom; - left = mLine->mRect.right; - } + append_run(i->mStyle, i->mBegin, i->mEnd, i->mEnd - i->mBegin, left + i->mWidth, top + fontHeight); - mPartialWhitespace.clear(); - mPartialWord.clear(); - } + left = mLine->mRect.right; + } - void append_run (StyleImpl * style, Utf8Stream::Point begin, Utf8Stream::Point end, int pc, int right, int bottom) - { - if (mSection == nullptr) - { - mBook->mSections.push_back (Section ()); - mSection = &mBook->mSections.back (); - mSection->mRect = MyGUI::IntRect (0, mBook->mRect.bottom, 0, mBook->mRect.bottom); - mSectionAlignment.push_back (mCurrentAlignment); + mPartialWhitespace.clear(); + mPartialWord.clear(); } - if (mLine == nullptr) + void append_run(StyleImpl* style, Utf8Stream::Point begin, Utf8Stream::Point end, int pc, int right, int bottom) { - mSection->mLines.push_back (Line ()); - mLine = &mSection->mLines.back (); - mLine->mRect = MyGUI::IntRect (0, mSection->mRect.bottom, 0, mBook->mRect.bottom); - } + if (mSection == nullptr) + { + mBook->mSections.push_back(Section()); + mSection = &mBook->mSections.back(); + mSection->mRect = MyGUI::IntRect(0, mBook->mRect.bottom, 0, mBook->mRect.bottom); + mSectionAlignment.push_back(mCurrentAlignment); + } - if (mBook->mRect.right < right) - mBook->mRect.right = right; + if (mLine == nullptr) + { + mSection->mLines.push_back(Line()); + mLine = &mSection->mLines.back(); + mLine->mRect = MyGUI::IntRect(0, mSection->mRect.bottom, 0, mBook->mRect.bottom); + } - if (mBook->mRect.bottom < bottom) - mBook->mRect.bottom = bottom; + if (mBook->mRect.right < right) + mBook->mRect.right = right; - if (mSection->mRect.right < right) - mSection->mRect.right = right; + if (mBook->mRect.bottom < bottom) + mBook->mRect.bottom = bottom; - if (mSection->mRect.bottom < bottom) - mSection->mRect.bottom = bottom; + if (mSection->mRect.right < right) + mSection->mRect.right = right; - if (mLine->mRect.right < right) - mLine->mRect.right = right; + if (mSection->mRect.bottom < bottom) + mSection->mRect.bottom = bottom; - if (mLine->mRect.bottom < bottom) - mLine->mRect.bottom = bottom; + if (mLine->mRect.right < right) + mLine->mRect.right = right; - if (mRun == nullptr || mRun->mStyle != style || mRun->mRange.second != begin) - { - int left = mRun ? mRun->mRight : mLine->mRect.left; - - mLine->mRuns.push_back (Run ()); - mRun = &mLine->mRuns.back (); - mRun->mStyle = style; - mRun->mLeft = left; - mRun->mRight = right; - mRun->mRange.first = begin; - mRun->mRange.second = end; - mRun->mPrintableChars = pc; - //Run->Locale = Locale; - } - else - { - mRun->mRight = right; - mRun->mRange.second = end; - mRun->mPrintableChars += pc; - } - } -}; + if (mLine->mRect.bottom < bottom) + mLine->mRect.bottom = bottom; -BookTypesetter::Ptr BookTypesetter::create (int pageWidth, int pageHeight) -{ - return std::make_shared (pageWidth, pageHeight); -} + if (mRun == nullptr || mRun->mStyle != style || mRun->mRange.second != begin) + { + int left = mRun ? mRun->mRight : mLine->mRect.left; + + mLine->mRuns.push_back(Run()); + mRun = &mLine->mRuns.back(); + mRun->mStyle = style; + mRun->mLeft = left; + mRun->mRight = right; + mRun->mRange.first = begin; + mRun->mRange.second = end; + mRun->mPrintableChars = pc; + // Run->Locale = Locale; + } + else + { + mRun->mRight = right; + mRun->mRange.second = end; + mRun->mPrintableChars += pc; + } + } + }; -namespace -{ - struct RenderXform + BookTypesetter::Ptr BookTypesetter::create(int pageWidth, int pageHeight) { - public: - - float clipTop; - float clipLeft; - float clipRight; - float clipBottom; - - float absoluteLeft; - float absoluteTop; - float leftOffset; - float topOffset; - - float pixScaleX; - float pixScaleY; - float hOffset; - float vOffset; - - RenderXform (MyGUI::ICroppedRectangle* croppedParent, MyGUI::RenderTargetInfo const & renderTargetInfo) - { - clipTop = static_cast(croppedParent->_getMarginTop()); - clipLeft = static_cast(croppedParent->_getMarginLeft ()); - clipRight = static_cast(croppedParent->getWidth () - croppedParent->_getMarginRight ()); - clipBottom = static_cast(croppedParent->getHeight() - croppedParent->_getMarginBottom()); - - absoluteLeft = static_cast(croppedParent->getAbsoluteLeft()); - absoluteTop = static_cast(croppedParent->getAbsoluteTop()); - leftOffset = static_cast(renderTargetInfo.leftOffset); - topOffset = static_cast(renderTargetInfo.topOffset); - - pixScaleX = renderTargetInfo.pixScaleX; - pixScaleY = renderTargetInfo.pixScaleY; - hOffset = renderTargetInfo.hOffset; - vOffset = renderTargetInfo.vOffset; - } + return std::make_shared(pageWidth, pageHeight); + } - bool clip (MyGUI::FloatRect & vr, MyGUI::FloatRect & tr) + namespace + { + struct RenderXform { - if (vr.bottom <= clipTop || vr.right <= clipLeft || - vr.left >= clipRight || vr.top >= clipBottom ) - return false; - - if (vr.top < clipTop) + public: + float clipTop; + float clipLeft; + float clipRight; + float clipBottom; + + float absoluteLeft; + float absoluteTop; + float leftOffset; + float topOffset; + + float pixScaleX; + float pixScaleY; + float hOffset; + float vOffset; + + RenderXform(MyGUI::ICroppedRectangle* croppedParent, MyGUI::RenderTargetInfo const& renderTargetInfo) { - tr.top += tr.height () * (clipTop - vr.top) / vr.height (); - vr.top = clipTop; + clipTop = static_cast(croppedParent->_getMarginTop()); + clipLeft = static_cast(croppedParent->_getMarginLeft()); + clipRight = static_cast(croppedParent->getWidth() - croppedParent->_getMarginRight()); + clipBottom = static_cast(croppedParent->getHeight() - croppedParent->_getMarginBottom()); + + absoluteLeft = static_cast(croppedParent->getAbsoluteLeft()); + absoluteTop = static_cast(croppedParent->getAbsoluteTop()); + leftOffset = static_cast(renderTargetInfo.leftOffset); + topOffset = static_cast(renderTargetInfo.topOffset); + + pixScaleX = renderTargetInfo.pixScaleX; + pixScaleY = renderTargetInfo.pixScaleY; + hOffset = renderTargetInfo.hOffset; + vOffset = renderTargetInfo.vOffset; } - if (vr.left < clipLeft) + bool clip(MyGUI::FloatRect& vr, MyGUI::FloatRect& tr) { - tr.left += tr.width () * (clipLeft - vr.left) / vr.width (); - vr.left = clipLeft; - } + if (vr.bottom <= clipTop || vr.right <= clipLeft || vr.left >= clipRight || vr.top >= clipBottom) + return false; - if (vr.right > clipRight) - { - tr.right -= tr.width () * (vr.right - clipRight) / vr.width (); - vr.right = clipRight; - } + if (vr.top < clipTop) + { + tr.top += tr.height() * (clipTop - vr.top) / vr.height(); + vr.top = clipTop; + } - if (vr.bottom > clipBottom) - { - tr.bottom -= tr.height () * (vr.bottom - clipBottom) / vr.height (); - vr.bottom = clipBottom; - } + if (vr.left < clipLeft) + { + tr.left += tr.width() * (clipLeft - vr.left) / vr.width(); + vr.left = clipLeft; + } - return true; - } + if (vr.right > clipRight) + { + tr.right -= tr.width() * (vr.right - clipRight) / vr.width(); + vr.right = clipRight; + } - MyGUI::FloatPoint operator () (MyGUI::FloatPoint pt) - { - pt.left = absoluteLeft - leftOffset + pt.left; - pt.top = absoluteTop - topOffset + pt.top; + if (vr.bottom > clipBottom) + { + tr.bottom -= tr.height() * (vr.bottom - clipBottom) / vr.height(); + vr.bottom = clipBottom; + } - pt.left = +(((pixScaleX * pt.left + hOffset) * 2.0f) - 1.0f); - pt.top = -(((pixScaleY * pt.top + vOffset) * 2.0f) - 1.0f); + return true; + } - return pt; - } - }; + MyGUI::FloatPoint operator()(MyGUI::FloatPoint pt) + { + pt.left = absoluteLeft - leftOffset + pt.left; + pt.top = absoluteTop - topOffset + pt.top; - struct GlyphStream - { - float mZ; - uint32_t mC; - MyGUI::IFont* mFont; - MyGUI::FloatPoint mOrigin; - MyGUI::FloatPoint mCursor; - MyGUI::Vertex* mVertices; - RenderXform mRenderXform; - MyGUI::VertexColourType mVertexColourType; - - GlyphStream (MyGUI::IFont* font, float left, float top, float Z, - MyGUI::Vertex* vertices, RenderXform const & renderXform) : - mZ(Z), - mC(0), mFont (font), mOrigin (left, top), - mVertices (vertices), - mRenderXform (renderXform) - { - assert(font != nullptr); - mVertexColourType = MyGUI::RenderManager::getInstance().getVertexFormat(); - } + pt.left = +(((pixScaleX * pt.left + hOffset) * 2.0f) - 1.0f); + pt.top = -(((pixScaleY * pt.top + vOffset) * 2.0f) - 1.0f); - ~GlyphStream () = default; + return pt; + } + }; - MyGUI::Vertex* end () const { return mVertices; } + struct GlyphStream + { + float mZ; + uint32_t mC; + MyGUI::IFont* mFont; + MyGUI::FloatPoint mOrigin; + MyGUI::FloatPoint mCursor; + MyGUI::Vertex* mVertices; + RenderXform mRenderXform; + MyGUI::VertexColourType mVertexColourType; + + GlyphStream(MyGUI::IFont* font, float left, float top, float Z, MyGUI::Vertex* vertices, + RenderXform const& renderXform) + : mZ(Z) + , mC(0) + , mFont(font) + , mOrigin(left, top) + , mVertices(vertices) + , mRenderXform(renderXform) + { + assert(font != nullptr); + mVertexColourType = MyGUI::RenderManager::getInstance().getVertexFormat(); + } - void reset (float left, float top, MyGUI::Colour colour) - { - mC = MyGUI::texture_utility::toColourARGB(colour) | 0xFF000000; - MyGUI::texture_utility::convertColour(mC, mVertexColourType); + ~GlyphStream() = default; - mCursor.left = mOrigin.left + left; - mCursor.top = mOrigin.top + top; - } + MyGUI::Vertex* end() const { return mVertices; } - void emitGlyph (wchar_t ch) - { - MWGui::GlyphInfo info = GlyphInfo(mFont, ch); + void reset(float left, float top, MyGUI::Colour colour) + { + mC = MyGUI::texture_utility::toColourARGB(colour) | 0xFF000000; + MyGUI::texture_utility::convertColour(mC, mVertexColourType); - if (!info.charFound) - return; + mCursor.left = mOrigin.left + left; + mCursor.top = mOrigin.top + top; + } - MyGUI::FloatRect vr; + void emitGlyph(wchar_t ch) + { + MWGui::GlyphInfo info = GlyphInfo(mFont, ch); - vr.left = mCursor.left + info.bearingX; - vr.top = mCursor.top + info.bearingY; - vr.right = vr.left + info.width; - vr.bottom = vr.top + info.height; + if (!info.charFound) + return; - MyGUI::FloatRect tr = info.uvRect; + MyGUI::FloatRect vr; - if (mRenderXform.clip (vr, tr)) - quad (vr, tr); + vr.left = mCursor.left + info.bearingX; + vr.top = mCursor.top + info.bearingY; + vr.right = vr.left + info.width; + vr.bottom = vr.top + info.height; - mCursor.left += static_cast(info.bearingX + info.advance); - } + MyGUI::FloatRect tr = info.uvRect; - void emitSpace (wchar_t ch) - { - MWGui::GlyphInfo info = GlyphInfo(mFont, ch); + if (mRenderXform.clip(vr, tr)) + quad(vr, tr); - if (info.charFound) mCursor.left += static_cast(info.bearingX + info.advance); - } - - private: + } - void quad (const MyGUI::FloatRect& vr, const MyGUI::FloatRect& tr) - { - vertex (vr.left, vr.top, tr.left, tr.top); - vertex (vr.right, vr.top, tr.right, tr.top); - vertex (vr.left, vr.bottom, tr.left, tr.bottom); - vertex (vr.right, vr.top, tr.right, tr.top); - vertex (vr.left, vr.bottom, tr.left, tr.bottom); - vertex (vr.right, vr.bottom, tr.right, tr.bottom); - } + void emitSpace(wchar_t ch) + { + MWGui::GlyphInfo info = GlyphInfo(mFont, ch); - void vertex (float x, float y, float u, float v) - { - MyGUI::FloatPoint pt = mRenderXform (MyGUI::FloatPoint (x, y)); + if (info.charFound) + mCursor.left += static_cast(info.bearingX + info.advance); + } - mVertices->x = pt.left; - mVertices->y = pt.top ; - mVertices->z = mZ; - mVertices->u = u; - mVertices->v = v; - mVertices->colour = mC; + private: + void quad(const MyGUI::FloatRect& vr, const MyGUI::FloatRect& tr) + { + vertex(vr.left, vr.top, tr.left, tr.top); + vertex(vr.right, vr.top, tr.right, tr.top); + vertex(vr.left, vr.bottom, tr.left, tr.bottom); + vertex(vr.right, vr.top, tr.right, tr.top); + vertex(vr.left, vr.bottom, tr.left, tr.bottom); + vertex(vr.right, vr.bottom, tr.right, tr.bottom); + } - ++mVertices; - } - }; -} + void vertex(float x, float y, float u, float v) + { + MyGUI::FloatPoint pt = mRenderXform(MyGUI::FloatPoint(x, y)); -class PageDisplay final : public MyGUI::ISubWidgetText -{ - MYGUI_RTTI_DERIVED(PageDisplay) -protected: + mVertices->x = pt.left; + mVertices->y = pt.top; + mVertices->z = mZ; + mVertices->u = u; + mVertices->v = v; + mVertices->colour = mC; - typedef TypesetBookImpl::Section Section; - typedef TypesetBookImpl::Line Line; - typedef TypesetBookImpl::Run Run; - bool mIsPageReset; - size_t mPage; + ++mVertices; + } + }; + } - struct TextFormat : ISubWidget + class PageDisplay final : public MyGUI::ISubWidgetText { - typedef MyGUI::IFont* Id; - - Id mFont; - int mCountVertex; - MyGUI::ITexture* mTexture; - MyGUI::RenderItem* mRenderItem; - PageDisplay * mDisplay; - - TextFormat (MyGUI::IFont* id, PageDisplay * display) : - mFont (id), - mCountVertex (0), - mTexture (nullptr), - mRenderItem (nullptr), - mDisplay (display) - { - } - - void createDrawItem (MyGUI::ILayerNode* node) + MYGUI_RTTI_DERIVED(PageDisplay) + protected: + typedef TypesetBookImpl::Section Section; + typedef TypesetBookImpl::Line Line; + typedef TypesetBookImpl::Run Run; + bool mIsPageReset; + size_t mPage; + + struct TextFormat : ISubWidget { - assert (mRenderItem == nullptr); - - if (mTexture != nullptr) + typedef MyGUI::IFont* Id; + + Id mFont; + int mCountVertex; + MyGUI::ITexture* mTexture; + MyGUI::RenderItem* mRenderItem; + PageDisplay* mDisplay; + + TextFormat(MyGUI::IFont* id, PageDisplay* display) + : mFont(id) + , mCountVertex(0) + , mTexture(nullptr) + , mRenderItem(nullptr) + , mDisplay(display) { - mRenderItem = node->addToRenderItem(mTexture, false, false); - mRenderItem->addDrawItem(this, mCountVertex); } - } - void destroyDrawItem (MyGUI::ILayerNode* node) - { - assert (mTexture != nullptr ? mRenderItem != nullptr : mRenderItem == nullptr); - - if (mTexture != nullptr) + void createDrawItem(MyGUI::ILayerNode* node) { - mRenderItem->removeDrawItem (this); - mRenderItem = nullptr; + assert(mRenderItem == nullptr); + + if (mTexture != nullptr) + { + mRenderItem = node->addToRenderItem(mTexture, false, false); + mRenderItem->addDrawItem(this, mCountVertex); + } } - } - void doRender() override { mDisplay->doRender (*this); } + void destroyDrawItem(MyGUI::ILayerNode* node) + { + assert(mTexture != nullptr ? mRenderItem != nullptr : mRenderItem == nullptr); - // this isn't really a sub-widget, its just a "drawitem" which - // should have its own interface - void createDrawItem(MyGUI::ITexture* _texture, MyGUI::ILayerNode* _node) override {} - void destroyDrawItem() override {} - }; + if (mTexture != nullptr) + { + mRenderItem->removeDrawItem(this); + mRenderItem = nullptr; + } + } - void resetPage() - { - mIsPageReset = true; - mPage = 0; - } + void doRender() override { mDisplay->doRender(*this); } - void setPage(size_t page) - { - mIsPageReset = false; - mPage = page; - } + // this isn't really a sub-widget, its just a "drawitem" which + // should have its own interface + void createDrawItem(MyGUI::ITexture* _texture, MyGUI::ILayerNode* _node) override {} + void destroyDrawItem() override {} + }; - bool isPageDifferent(size_t page) - { - return mIsPageReset || (mPage != page); - } + void resetPage() + { + mIsPageReset = true; + mPage = 0; + } - std::optional getAdjustedPos(int left, int top, bool move = false) - { - if (!mBook) - return {}; + void setPage(size_t page) + { + mIsPageReset = false; + mPage = page; + } - if (mPage >= mBook->mPages.size()) - return {}; + bool isPageDifferent(size_t page) { return mIsPageReset || (mPage != page); } - MyGUI::IntPoint pos (left, top); - pos.left -= mCroppedParent->getAbsoluteLeft (); - pos.top -= mCroppedParent->getAbsoluteTop (); - pos.top += mViewTop; - return pos; - } + std::optional getAdjustedPos(int left, int top, bool move = false) + { + if (!mBook) + return {}; -public: + if (mPage >= mBook->mPages.size()) + return {}; - typedef TypesetBookImpl::StyleImpl Style; - typedef std::map > ActiveTextFormats; + MyGUI::IntPoint pos(left, top); + pos.left -= mCroppedParent->getAbsoluteLeft(); + pos.top -= mCroppedParent->getAbsoluteTop(); + pos.top += mViewTop; + return pos; + } - int mViewTop; - int mViewBottom; + public: + typedef TypesetBookImpl::StyleImpl Style; + typedef std::map> ActiveTextFormats; - Style* mFocusItem; - bool mItemActive; - MyGUI::MouseButton mLastDown; - std::function mLinkClicked; + int mViewTop; + int mViewBottom; + Style* mFocusItem; + bool mItemActive; + MyGUI::MouseButton mLastDown; + std::function mLinkClicked; - std::shared_ptr mBook; + std::shared_ptr mBook; - MyGUI::ILayerNode* mNode; - ActiveTextFormats mActiveTextFormats; + MyGUI::ILayerNode* mNode; + ActiveTextFormats mActiveTextFormats; - PageDisplay () - { - resetPage (); - mViewTop = 0; - mViewBottom = 0; - mFocusItem = nullptr; - mItemActive = false; - mNode = nullptr; - } + PageDisplay() + { + resetPage(); + mViewTop = 0; + mViewBottom = 0; + mFocusItem = nullptr; + mItemActive = false; + mNode = nullptr; + } - void dirtyFocusItem () - { - if (mFocusItem != nullptr) + void dirtyFocusItem() { - MyGUI::IFont* Font = mBook->affectedFont (mFocusItem); + if (mFocusItem != nullptr) + { + MyGUI::IFont* Font = mBook->affectedFont(mFocusItem); - ActiveTextFormats::iterator i = mActiveTextFormats.find (Font); + ActiveTextFormats::iterator i = mActiveTextFormats.find(Font); - if (mNode) - mNode->outOfDate (i->second->mRenderItem); + if (mNode) + mNode->outOfDate(i->second->mRenderItem); + } } - } - - void onMouseLostFocus () - { - if (!mBook) - return; - if (mPage >= mBook->mPages.size()) - return; + void onMouseLostFocus() + { + if (!mBook) + return; - dirtyFocusItem (); + if (mPage >= mBook->mPages.size()) + return; - mFocusItem = nullptr; - mItemActive = false; - } + dirtyFocusItem(); - void onMouseMove (int left, int top) - { - Style * hit = nullptr; - if(auto pos = getAdjustedPos(left, top, true)) - if(pos->top <= mViewBottom) - hit = mBook->hitTestWithMargin (pos->left, pos->top); + mFocusItem = nullptr; + mItemActive = false; + } - if (mLastDown == MyGUI::MouseButton::None) + void onMouseMove(int left, int top) { - if (hit != mFocusItem) + Style* hit = nullptr; + if (auto pos = getAdjustedPos(left, top, true)) + if (pos->top <= mViewBottom) + hit = mBook->hitTestWithMargin(pos->left, pos->top); + + if (mLastDown == MyGUI::MouseButton::None) { - dirtyFocusItem (); + if (hit != mFocusItem) + { + dirtyFocusItem(); - mFocusItem = hit; - mItemActive = false; + mFocusItem = hit; + mItemActive = false; - dirtyFocusItem (); + dirtyFocusItem(); + } } - } - else - if (mFocusItem != nullptr) - { - bool newItemActive = hit == mFocusItem; - - if (newItemActive != mItemActive) + else if (mFocusItem != nullptr) { - mItemActive = newItemActive; + bool newItemActive = hit == mFocusItem; + + if (newItemActive != mItemActive) + { + mItemActive = newItemActive; - dirtyFocusItem (); + dirtyFocusItem(); + } } } - } - - void onMouseButtonPressed (int left, int top, MyGUI::MouseButton id) - { - auto pos = getAdjustedPos(left, top); - if (pos && mLastDown == MyGUI::MouseButton::None) + void onMouseButtonPressed(int left, int top, MyGUI::MouseButton id) { - mFocusItem = pos->top <= mViewBottom ? mBook->hitTestWithMargin (pos->left, pos->top) : nullptr; - mItemActive = true; + auto pos = getAdjustedPos(left, top); - dirtyFocusItem (); + if (pos && mLastDown == MyGUI::MouseButton::None) + { + mFocusItem = pos->top <= mViewBottom ? mBook->hitTestWithMargin(pos->left, pos->top) : nullptr; + mItemActive = true; - mLastDown = id; - } - } + dirtyFocusItem(); - void onMouseButtonReleased(int left, int top, MyGUI::MouseButton id) - { - auto pos = getAdjustedPos(left, top); + mLastDown = id; + } + } - if (pos && mLastDown == id) + void onMouseButtonReleased(int left, int top, MyGUI::MouseButton id) { - Style * item = pos->top <= mViewBottom ? mBook->hitTestWithMargin (pos->left, pos->top) : nullptr; + auto pos = getAdjustedPos(left, top); - bool clicked = mFocusItem == item; + if (pos && mLastDown == id) + { + Style* item = pos->top <= mViewBottom ? mBook->hitTestWithMargin(pos->left, pos->top) : nullptr; - mItemActive = false; + bool clicked = mFocusItem == item; - dirtyFocusItem (); + mItemActive = false; - mLastDown = MyGUI::MouseButton::None; + dirtyFocusItem(); - if (clicked && mLinkClicked && item && item->mInteractiveId != 0) - mLinkClicked (item->mInteractiveId); - } - } + mLastDown = MyGUI::MouseButton::None; - void showPage (TypesetBook::Ptr book, size_t newPage) - { - std::shared_ptr newBook = std::dynamic_pointer_cast (book); + if (clicked && mLinkClicked && item && item->mInteractiveId != 0) + mLinkClicked(item->mInteractiveId); + } + } - if (mBook != newBook) + void showPage(TypesetBook::Ptr book, size_t newPage) { - mFocusItem = nullptr; - mItemActive = 0; + std::shared_ptr newBook = std::dynamic_pointer_cast(book); - for (ActiveTextFormats::iterator i = mActiveTextFormats.begin (); i != mActiveTextFormats.end (); ++i) + if (mBook != newBook) { - if (mNode != nullptr && i->second != nullptr) - i->second->destroyDrawItem (mNode); - i->second.reset(); - } + mFocusItem = nullptr; + mItemActive = 0; - mActiveTextFormats.clear (); - - if (newBook != nullptr) - { - createActiveFormats (newBook); + for (ActiveTextFormats::iterator i = mActiveTextFormats.begin(); i != mActiveTextFormats.end(); ++i) + { + if (mNode != nullptr && i->second != nullptr) + i->second->destroyDrawItem(mNode); + i->second.reset(); + } - mBook = newBook; - setPage (newPage); + mActiveTextFormats.clear(); - if (newPage < mBook->mPages.size ()) + if (newBook != nullptr) { - mViewTop = mBook->mPages [newPage].first; - mViewBottom = mBook->mPages [newPage].second; + createActiveFormats(newBook); + + mBook = newBook; + setPage(newPage); + + if (newPage < mBook->mPages.size()) + { + mViewTop = mBook->mPages[newPage].first; + mViewBottom = mBook->mPages[newPage].second; + } + else + { + mViewTop = 0; + mViewBottom = 0; + } } else { + mBook.reset(); + resetPage(); mViewTop = 0; mViewBottom = 0; } } - else + else if (mBook && isPageDifferent(newPage)) { - mBook.reset (); - resetPage (); - mViewTop = 0; - mViewBottom = 0; - } - } - else - if (mBook && isPageDifferent (newPage)) - { - if (mNode != nullptr) - for (ActiveTextFormats::iterator i = mActiveTextFormats.begin (); i != mActiveTextFormats.end (); ++i) - mNode->outOfDate(i->second->mRenderItem); + if (mNode != nullptr) + for (ActiveTextFormats::iterator i = mActiveTextFormats.begin(); i != mActiveTextFormats.end(); ++i) + mNode->outOfDate(i->second->mRenderItem); - setPage (newPage); + setPage(newPage); - if (newPage < mBook->mPages.size ()) - { - mViewTop = mBook->mPages [newPage].first; - mViewBottom = mBook->mPages [newPage].second; - } - else - { - mViewTop = 0; - mViewBottom = 0; + if (newPage < mBook->mPages.size()) + { + mViewTop = mBook->mPages[newPage].first; + mViewBottom = mBook->mPages[newPage].second; + } + else + { + mViewTop = 0; + mViewBottom = 0; + } } } - } - struct CreateActiveFormat - { - PageDisplay * this_; - - CreateActiveFormat (PageDisplay * this_) : this_ (this_) {} - - void operator () (Section const & section, Line const & line, Run const & run) const + struct CreateActiveFormat { - MyGUI::IFont* Font = run.mStyle->mFont; - - ActiveTextFormats::iterator j = this_->mActiveTextFormats.find (Font); + PageDisplay* this_; - if (j == this_->mActiveTextFormats.end ()) + CreateActiveFormat(PageDisplay* this_) + : this_(this_) { - auto textFormat = std::make_unique(Font, this_); - - textFormat->mTexture = Font->getTextureFont (); - - j = this_->mActiveTextFormats.insert (std::make_pair (Font, std::move(textFormat))).first; } - j->second->mCountVertex += run.mPrintableChars * 6; - } - }; + void operator()(Section const& section, Line const& line, Run const& run) const + { + MyGUI::IFont* Font = run.mStyle->mFont; - void createActiveFormats (std::shared_ptr newBook) - { - newBook->visitRuns (0, 0x7FFFFFFF, CreateActiveFormat (this)); + ActiveTextFormats::iterator j = this_->mActiveTextFormats.find(Font); - if (mNode != nullptr) - for (ActiveTextFormats::iterator i = mActiveTextFormats.begin (); i != mActiveTextFormats.end (); ++i) - i->second->createDrawItem (mNode); - } + if (j == this_->mActiveTextFormats.end()) + { + auto textFormat = std::make_unique(Font, this_); - void setVisible (bool newVisible) override - { - if (mVisible == newVisible) - return; + textFormat->mTexture = Font->getTextureFont(); - mVisible = newVisible; + j = this_->mActiveTextFormats.insert(std::make_pair(Font, std::move(textFormat))).first; + } - if (mVisible) - { - // reset input state - mLastDown = MyGUI::MouseButton::None; - mFocusItem = nullptr; - mItemActive = 0; - } + j->second->mCountVertex += run.mPrintableChars * 6; + } + }; - if (nullptr != mNode) + void createActiveFormats(std::shared_ptr newBook) { - for (ActiveTextFormats::iterator i = mActiveTextFormats.begin (); i != mActiveTextFormats.end (); ++i) - mNode->outOfDate(i->second->mRenderItem); + newBook->visitRuns(0, 0x7FFFFFFF, CreateActiveFormat(this)); + + if (mNode != nullptr) + for (ActiveTextFormats::iterator i = mActiveTextFormats.begin(); i != mActiveTextFormats.end(); ++i) + i->second->createDrawItem(mNode); } - } - void createDrawItem(MyGUI::ITexture* texture, MyGUI::ILayerNode* node) override - { - mNode = node; + void setVisible(bool newVisible) override + { + if (mVisible == newVisible) + return; - for (ActiveTextFormats::iterator i = mActiveTextFormats.begin (); i != mActiveTextFormats.end (); ++i) - i->second->createDrawItem (node); - } + mVisible = newVisible; - struct RenderRun - { - PageDisplay * this_; - GlyphStream &glyphStream; + if (mVisible) + { + // reset input state + mLastDown = MyGUI::MouseButton::None; + mFocusItem = nullptr; + mItemActive = 0; + } - RenderRun (PageDisplay * this_, GlyphStream &glyphStream) : - this_(this_), glyphStream (glyphStream) - { + if (nullptr != mNode) + { + for (ActiveTextFormats::iterator i = mActiveTextFormats.begin(); i != mActiveTextFormats.end(); ++i) + mNode->outOfDate(i->second->mRenderItem); + } } - void operator () (Section const & section, Line const & line, Run const & run) const + void createDrawItem(MyGUI::ITexture* texture, MyGUI::ILayerNode* node) override { - bool isActive = run.mStyle->mInteractiveId && (run.mStyle == this_->mFocusItem); + mNode = node; - MyGUI::Colour colour = isActive ? (this_->mItemActive ? run.mStyle->mActiveColour: run.mStyle->mHotColour) : run.mStyle->mNormalColour; + for (ActiveTextFormats::iterator i = mActiveTextFormats.begin(); i != mActiveTextFormats.end(); ++i) + i->second->createDrawItem(node); + } - glyphStream.reset(static_cast(section.mRect.left + line.mRect.left + run.mLeft), static_cast(line.mRect.top), colour); + struct RenderRun + { + PageDisplay* this_; + GlyphStream& glyphStream; - Utf8Stream stream (run.mRange); + RenderRun(PageDisplay* this_, GlyphStream& glyphStream) + : this_(this_) + , glyphStream(glyphStream) + { + } - while (!stream.eof ()) + void operator()(Section const& section, Line const& line, Run const& run) const { - Utf8Stream::UnicodeChar code_point = stream.consume (); + bool isActive = run.mStyle->mInteractiveId && (run.mStyle == this_->mFocusItem); - if (ucsCarriageReturn (code_point)) - continue; + MyGUI::Colour colour = isActive + ? (this_->mItemActive ? run.mStyle->mActiveColour : run.mStyle->mHotColour) + : run.mStyle->mNormalColour; - if (!ucsSpace (code_point)) - glyphStream.emitGlyph (code_point); - else - glyphStream.emitSpace (code_point); - } - } - }; + glyphStream.reset(static_cast(section.mRect.left + line.mRect.left + run.mLeft), + static_cast(line.mRect.top), colour); - /* - queue up rendering operations for this text format - */ - void doRender(TextFormat & textFormat) - { - if (!mVisible) - return; + Utf8Stream stream(run.mRange); - MyGUI::Vertex* vertices = textFormat.mRenderItem->getCurrentVertexBuffer(); + while (!stream.eof()) + { + Utf8Stream::UnicodeChar code_point = stream.consume(); - RenderXform renderXform (mCroppedParent, textFormat.mRenderItem->getRenderTarget()->getInfo()); + if (ucsCarriageReturn(code_point)) + continue; - float z = SceneUtil::AutoDepth::isReversed() ? 1.f : -1.f; + if (!ucsSpace(code_point)) + glyphStream.emitGlyph(code_point); + else + glyphStream.emitSpace(code_point); + } + } + }; - GlyphStream glyphStream(textFormat.mFont, static_cast(mCoord.left), static_cast(mCoord.top - mViewTop), - z /*mNode->getNodeDepth()*/, vertices, renderXform); + /* + queue up rendering operations for this text format + */ + void doRender(TextFormat& textFormat) + { + if (!mVisible) + return; - int visit_top = (std::max) (mViewTop, mViewTop + int (renderXform.clipTop )); - int visit_bottom = (std::min) (mViewBottom, mViewTop + int (renderXform.clipBottom)); + MyGUI::Vertex* vertices = textFormat.mRenderItem->getCurrentVertexBuffer(); - mBook->visitRuns (visit_top, visit_bottom, textFormat.mFont, RenderRun (this, glyphStream)); + RenderXform renderXform(mCroppedParent, textFormat.mRenderItem->getRenderTarget()->getInfo()); - textFormat.mRenderItem->setLastVertexCount(glyphStream.end () - vertices); - } + float z = SceneUtil::AutoDepth::isReversed() ? 1.f : -1.f; - // ISubWidget should not necessarily be a drawitem - // in this case, it is not... - void doRender() override { } + GlyphStream glyphStream(textFormat.mFont, static_cast(mCoord.left), + static_cast(mCoord.top - mViewTop), z /*mNode->getNodeDepth()*/, vertices, renderXform); - void _updateView () override - { - _checkMargin(); + int visit_top = (std::max)(mViewTop, mViewTop + int(renderXform.clipTop)); + int visit_bottom = (std::min)(mViewBottom, mViewTop + int(renderXform.clipBottom)); - if (mNode != nullptr) - for (ActiveTextFormats::iterator i = mActiveTextFormats.begin (); i != mActiveTextFormats.end (); ++i) - mNode->outOfDate (i->second->mRenderItem); - } + mBook->visitRuns(visit_top, visit_bottom, textFormat.mFont, RenderRun(this, glyphStream)); - void _correctView() override - { - _checkMargin (); + textFormat.mRenderItem->setLastVertexCount(glyphStream.end() - vertices); + } - if (mNode != nullptr) - for (ActiveTextFormats::iterator i = mActiveTextFormats.begin (); i != mActiveTextFormats.end (); ++i) - mNode->outOfDate (i->second->mRenderItem); + // ISubWidget should not necessarily be a drawitem + // in this case, it is not... + void doRender() override {} - } + void _updateView() override + { + _checkMargin(); - void destroyDrawItem() override - { - for (ActiveTextFormats::iterator i = mActiveTextFormats.begin (); i != mActiveTextFormats.end (); ++i) - i->second->destroyDrawItem (mNode); + if (mNode != nullptr) + for (ActiveTextFormats::iterator i = mActiveTextFormats.begin(); i != mActiveTextFormats.end(); ++i) + mNode->outOfDate(i->second->mRenderItem); + } - mNode = nullptr; - } -}; + void _correctView() override + { + _checkMargin(); + if (mNode != nullptr) + for (ActiveTextFormats::iterator i = mActiveTextFormats.begin(); i != mActiveTextFormats.end(); ++i) + mNode->outOfDate(i->second->mRenderItem); + } -class BookPageImpl final : public BookPage -{ -MYGUI_RTTI_DERIVED(BookPage) -public: + void destroyDrawItem() override + { + for (ActiveTextFormats::iterator i = mActiveTextFormats.begin(); i != mActiveTextFormats.end(); ++i) + i->second->destroyDrawItem(mNode); - BookPageImpl() - : mPageDisplay(nullptr) - { - } + mNode = nullptr; + } + }; - void showPage (TypesetBook::Ptr book, size_t page) override + class BookPageImpl final : public BookPage { - mPageDisplay->showPage (book, page); - } + MYGUI_RTTI_DERIVED(BookPage) + public: + BookPageImpl() + : mPageDisplay(nullptr) + { + } - void adviseLinkClicked (std::function linkClicked) override - { - mPageDisplay->mLinkClicked = linkClicked; - } + void showPage(TypesetBook::Ptr book, size_t page) override { mPageDisplay->showPage(book, page); } - void unadviseLinkClicked () override - { - mPageDisplay->mLinkClicked = std::function (); - } + void adviseLinkClicked(std::function linkClicked) override + { + mPageDisplay->mLinkClicked = linkClicked; + } -protected: + void unadviseLinkClicked() override { mPageDisplay->mLinkClicked = std::function(); } - void initialiseOverride() override - { - Base::initialiseOverride(); + protected: + void initialiseOverride() override + { + Base::initialiseOverride(); + + if (getSubWidgetText()) + { + mPageDisplay = getSubWidgetText()->castType(); + } + else + { + throw std::runtime_error("BookPage unable to find page display sub widget"); + } + } - if (getSubWidgetText()) + void onMouseLostFocus(Widget* _new) override { - mPageDisplay = getSubWidgetText()->castType(); + // NOTE: MyGUI also fires eventMouseLostFocus for widgets that are about to be destroyed (if they had + // focus). Child widgets may already be destroyed! So be careful. + mPageDisplay->onMouseLostFocus(); } - else + + void onMouseMove(int left, int top) override { mPageDisplay->onMouseMove(left, top); } + + void onMouseButtonPressed(int left, int top, MyGUI::MouseButton id) override { - throw std::runtime_error("BookPage unable to find page display sub widget"); + mPageDisplay->onMouseButtonPressed(left, top, id); } - } - void onMouseLostFocus(Widget* _new) override - { - // NOTE: MyGUI also fires eventMouseLostFocus for widgets that are about to be destroyed (if they had focus). - // Child widgets may already be destroyed! So be careful. - mPageDisplay->onMouseLostFocus (); - } + void onMouseButtonReleased(int left, int top, MyGUI::MouseButton id) override + { + mPageDisplay->onMouseButtonReleased(left, top, id); + } - void onMouseMove(int left, int top) override + PageDisplay* mPageDisplay; + }; + + void BookPage::registerMyGUIComponents() { - mPageDisplay->onMouseMove (left, top); + MyGUI::FactoryManager& factory = MyGUI::FactoryManager::getInstance(); + + factory.registerFactory("Widget"); + factory.registerFactory("BasisSkin"); } - void onMouseButtonPressed (int left, int top, MyGUI::MouseButton id) override + static bool ucsLineBreak(int codePoint) { - mPageDisplay->onMouseButtonPressed (left, top, id); + return codePoint == '\n'; } - void onMouseButtonReleased(int left, int top, MyGUI::MouseButton id) override + static bool ucsCarriageReturn(int codePoint) { - mPageDisplay->onMouseButtonReleased (left, top, id); + return codePoint == '\r'; } - PageDisplay* mPageDisplay; -}; - -void BookPage::registerMyGUIComponents () -{ - MyGUI::FactoryManager & factory = MyGUI::FactoryManager::getInstance(); - - factory.registerFactory("Widget"); - factory.registerFactory("BasisSkin"); -} - -static bool ucsLineBreak (int codePoint) -{ - return codePoint == '\n'; -} - -static bool ucsCarriageReturn (int codePoint) -{ - return codePoint == '\r'; -} - -static bool ucsSpace (int codePoint) -{ - switch (codePoint) + static bool ucsSpace(int codePoint) { - case 0x0020: // SPACE - case 0x00A0: // NO-BREAK SPACE - case 0x1680: // OGHAM SPACE MARK - case 0x180E: // MONGOLIAN VOWEL SEPARATOR - case 0x2000: // EN QUAD - case 0x2001: // EM QUAD - case 0x2002: // EN SPACE - case 0x2003: // EM SPACE - case 0x2004: // THREE-PER-EM SPACE - case 0x2005: // FOUR-PER-EM SPACE - case 0x2006: // SIX-PER-EM SPACE - case 0x2007: // FIGURE SPACE - case 0x2008: // PUNCTUATION SPACE - case 0x2009: // THIN SPACE - case 0x200A: // HAIR SPACE - case 0x200B: // ZERO WIDTH SPACE - case 0x202F: // NARROW NO-BREAK SPACE - case 0x205F: // MEDIUM MATHEMATICAL SPACE - case 0x3000: // IDEOGRAPHIC SPACE - case 0xFEFF: // ZERO WIDTH NO-BREAK SPACE - return true; - default: - return false; + switch (codePoint) + { + case 0x0020: // SPACE + case 0x00A0: // NO-BREAK SPACE + case 0x1680: // OGHAM SPACE MARK + case 0x180E: // MONGOLIAN VOWEL SEPARATOR + case 0x2000: // EN QUAD + case 0x2001: // EM QUAD + case 0x2002: // EN SPACE + case 0x2003: // EM SPACE + case 0x2004: // THREE-PER-EM SPACE + case 0x2005: // FOUR-PER-EM SPACE + case 0x2006: // SIX-PER-EM SPACE + case 0x2007: // FIGURE SPACE + case 0x2008: // PUNCTUATION SPACE + case 0x2009: // THIN SPACE + case 0x200A: // HAIR SPACE + case 0x200B: // ZERO WIDTH SPACE + case 0x202F: // NARROW NO-BREAK SPACE + case 0x205F: // MEDIUM MATHEMATICAL SPACE + case 0x3000: // IDEOGRAPHIC SPACE + case 0xFEFF: // ZERO WIDTH NO-BREAK SPACE + return true; + default: + return false; + } } -} -static bool ucsBreakingSpace (int codePoint) -{ - switch (codePoint) + static bool ucsBreakingSpace(int codePoint) { - case 0x0020: // SPACE - //case 0x00A0: // NO-BREAK SPACE - case 0x1680: // OGHAM SPACE MARK - case 0x180E: // MONGOLIAN VOWEL SEPARATOR - case 0x2000: // EN QUAD - case 0x2001: // EM QUAD - case 0x2002: // EN SPACE - case 0x2003: // EM SPACE - case 0x2004: // THREE-PER-EM SPACE - case 0x2005: // FOUR-PER-EM SPACE - case 0x2006: // SIX-PER-EM SPACE - case 0x2007: // FIGURE SPACE - case 0x2008: // PUNCTUATION SPACE - case 0x2009: // THIN SPACE - case 0x200A: // HAIR SPACE - case 0x200B: // ZERO WIDTH SPACE - case 0x202F: // NARROW NO-BREAK SPACE - case 0x205F: // MEDIUM MATHEMATICAL SPACE - case 0x3000: // IDEOGRAPHIC SPACE - //case 0xFEFF: // ZERO WIDTH NO-BREAK SPACE - return true; - default: - return false; + switch (codePoint) + { + case 0x0020: // SPACE + // case 0x00A0: // NO-BREAK SPACE + case 0x1680: // OGHAM SPACE MARK + case 0x180E: // MONGOLIAN VOWEL SEPARATOR + case 0x2000: // EN QUAD + case 0x2001: // EM QUAD + case 0x2002: // EN SPACE + case 0x2003: // EM SPACE + case 0x2004: // THREE-PER-EM SPACE + case 0x2005: // FOUR-PER-EM SPACE + case 0x2006: // SIX-PER-EM SPACE + case 0x2007: // FIGURE SPACE + case 0x2008: // PUNCTUATION SPACE + case 0x2009: // THIN SPACE + case 0x200A: // HAIR SPACE + case 0x200B: // ZERO WIDTH SPACE + case 0x202F: // NARROW NO-BREAK SPACE + case 0x205F: // MEDIUM MATHEMATICAL SPACE + case 0x3000: // IDEOGRAPHIC SPACE + // case 0xFEFF: // ZERO WIDTH NO-BREAK SPACE + return true; + default: + return false; + } } -} } diff --git a/apps/openmw/mwgui/bookpage.hpp b/apps/openmw/mwgui/bookpage.hpp index 05bbd3af82..af6d33ff2b 100644 --- a/apps/openmw/mwgui/bookpage.hpp +++ b/apps/openmw/mwgui/bookpage.hpp @@ -2,12 +2,12 @@ #define MWGUI_BOOKPAGE_HPP #include "MyGUI_Colour.h" -#include "MyGUI_Widget.h" #include "MyGUI_IFont.h" +#include "MyGUI_Widget.h" +#include #include #include -#include #include @@ -20,11 +20,11 @@ namespace MWGui /// the book page widget. struct TypesetBook { - typedef std::shared_ptr Ptr; + typedef std::shared_ptr Ptr; typedef intptr_t InteractiveId; /// Returns the number of pages in the document. - virtual size_t pageCount () const = 0; + virtual size_t pageCount() const = 0; /// Return the area covered by the document. The first /// integer is the maximum with of any line. This is not @@ -32,7 +32,7 @@ namespace MWGui /// it is the largest distance from the left edge to the /// right edge. The second integer is the height of all /// text combined prior to pagination. - virtual std::pair getSize () const = 0; + virtual std::pair getSize() const = 0; virtual ~TypesetBook() = default; }; @@ -55,14 +55,14 @@ namespace MWGui const MyGUI::GlyphInfo* gi = font->getGlyphInfo(ch); if (gi) { - const float scale = font->getDefaultHeight() / (float) fontHeight; + const float scale = font->getDefaultHeight() / (float)fontHeight; codePoint = gi->codePoint; - bearingX = (int) gi->bearingX / scale; - bearingY = (int) gi->bearingY / scale; - width = (int) gi->width / scale; - height = (int) gi->height / scale; - advance = (int) gi->advance / scale; + bearingX = (int)gi->bearingX / scale; + bearingY = (int)gi->bearingY / scale; + width = (int)gi->width / scale; + height = (int)gi->height / scale; + advance = (int)gi->advance / scale; uvRect = gi->uvRect; charFound = true; } @@ -82,18 +82,19 @@ namespace MWGui /// A factory class for creating a typeset book instance. struct BookTypesetter { - typedef std::shared_ptr Ptr; + typedef std::shared_ptr Ptr; typedef TypesetBook::InteractiveId InteractiveId; typedef MyGUI::Colour Colour; - typedef uint8_t const * Utf8Point; - typedef std::pair Utf8Span; + typedef uint8_t const* Utf8Point; + typedef std::pair Utf8Span; virtual ~BookTypesetter() = default; - enum Alignment { - AlignLeft = -1, + enum Alignment + { + AlignLeft = -1, AlignCenter = 0, - AlignRight = +1 + AlignRight = +1 }; /// Styles are used to control the character level formatting @@ -103,71 +104,71 @@ namespace MWGui struct Style; /// A factory function for creating the default implementation of a book typesetter - static Ptr create (int pageWidth, int pageHeight); + static Ptr create(int pageWidth, int pageHeight); /// Create a simple text style consisting of a font and a text color. - virtual Style* createStyle (const std::string& fontName, const Colour& colour, bool useBookFont=true) = 0; + virtual Style* createStyle(const std::string& fontName, const Colour& colour, bool useBookFont = true) = 0; /// Create a hyper-link style with a user-defined identifier based on an /// existing style. The unique flag forces a new instance of this style /// to be created even if an existing instance is present. - virtual Style* createHotStyle (Style * BaseStyle, const Colour& NormalColour, const Colour& HoverColour, - const Colour& ActiveColour, InteractiveId Id, bool Unique = true) = 0; + virtual Style* createHotStyle(Style* BaseStyle, const Colour& NormalColour, const Colour& HoverColour, + const Colour& ActiveColour, InteractiveId Id, bool Unique = true) + = 0; /// Insert a line break into the document. Newline characters in the input /// text have the same affect. The margin parameter adds additional space /// before the next line of text. - virtual void lineBreak (float margin = 0) = 0; + virtual void lineBreak(float margin = 0) = 0; /// Insert a section break into the document. This causes a new section /// to begin when additional text is inserted. Pagination attempts to keep /// sections together on a single page. The margin parameter adds additional space /// before the next line of text. - virtual void sectionBreak (int margin = 0) = 0; + virtual void sectionBreak(int margin = 0) = 0; /// Changes the alignment for the current section of text. - virtual void setSectionAlignment (Alignment sectionAlignment) = 0; + virtual void setSectionAlignment(Alignment sectionAlignment) = 0; // Layout a block of text with the specified style into the document. - virtual void write (Style * Style, Utf8Span Text) = 0; + virtual void write(Style* Style, Utf8Span Text) = 0; /// Adds a content block to the document without laying it out. An /// identifier is returned that can be used to refer to it. If select /// is true, the block is activated to be references by future writes. - virtual intptr_t addContent (Utf8Span Text, bool Select = true) = 0; + virtual intptr_t addContent(Utf8Span Text, bool Select = true) = 0; /// Select a previously created content block for future writes. - virtual void selectContent (intptr_t contentHandle) = 0; + virtual void selectContent(intptr_t contentHandle) = 0; /// Layout a span of the selected content block into the document /// using the specified style. - virtual void write (Style * Style, size_t Begin, size_t End) = 0; + virtual void write(Style* Style, size_t Begin, size_t End) = 0; /// Finalize the document layout, and return a pointer to it. - virtual TypesetBook::Ptr complete () = 0; + virtual TypesetBook::Ptr complete() = 0; }; /// An interface to the BookPage widget. class BookPage : public MyGUI::Widget { - MYGUI_RTTI_DERIVED(BookPage) + MYGUI_RTTI_DERIVED(BookPage) public: - typedef TypesetBook::InteractiveId InteractiveId; - typedef std::function ClickCallback; + typedef std::function ClickCallback; /// Make the widget display the specified page from the specified book. - virtual void showPage (TypesetBook::Ptr Book, size_t Page) = 0; + virtual void showPage(TypesetBook::Ptr Book, size_t Page) = 0; /// Set the callback for a clicking a hyper-link in the document. - virtual void adviseLinkClicked (ClickCallback callback) = 0; + virtual void adviseLinkClicked(ClickCallback callback) = 0; /// Clear the hyper-link click callback. - virtual void unadviseLinkClicked () = 0; + virtual void unadviseLinkClicked() = 0; /// Register the widget and associated sub-widget with MyGUI. Should be /// called once near the beginning of the program. - static void registerMyGUIComponents (); + static void registerMyGUIComponents(); }; } diff --git a/apps/openmw/mwgui/bookwindow.cpp b/apps/openmw/mwgui/bookwindow.cpp index 8dbb90ca6d..56b76836e2 100644 --- a/apps/openmw/mwgui/bookwindow.cpp +++ b/apps/openmw/mwgui/bookwindow.cpp @@ -1,13 +1,13 @@ #include "bookwindow.hpp" -#include #include +#include #include #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" #include "../mwmechanics/actorutil.hpp" @@ -19,7 +19,7 @@ namespace MWGui { - BookWindow::BookWindow () + BookWindow::BookWindow() : BookWindowBase("openmw_book.layout") , mCurrentPage(0) , mTakeButtonShow(true) @@ -61,14 +61,15 @@ namespace MWGui if (mNextPageButton->getSize().width == 64) { // english button has a 7 pixel wide strip of garbage on its right edge - mNextPageButton->setSize(64-7, mNextPageButton->getSize().height); - mNextPageButton->setImageCoord(MyGUI::IntCoord(0,0,(64-7)*scale,mNextPageButton->getSize().height*scale)); + mNextPageButton->setSize(64 - 7, mNextPageButton->getSize().height); + mNextPageButton->setImageCoord( + MyGUI::IntCoord(0, 0, (64 - 7) * scale, mNextPageButton->getSize().height * scale)); } center(); } - void BookWindow::onMouseWheel(MyGUI::Widget *_sender, int _rel) + void BookWindow::onMouseWheel(MyGUI::Widget* _sender, int _rel) { if (_rel < 0) nextPage(); @@ -81,7 +82,7 @@ namespace MWGui mPages.clear(); } - void BookWindow::setPtr (const MWWorld::Ptr& book) + void BookWindow::setPtr(const MWWorld::Ptr& book) { mBook = book; @@ -91,7 +92,7 @@ namespace MWGui clearPages(); mCurrentPage = 0; - MWWorld::LiveCellRef *ref = mBook.get(); + MWWorld::LiveCellRef* ref = mBook.get(); Formatting::BookFormatter formatter; mPages = formatter.markupToWidget(mLeftPage, ref->mBase->mText); @@ -110,7 +111,7 @@ namespace MWGui mTakeButton->setVisible(mTakeButtonShow && mTakeButtonAllowed); } - void BookWindow::onKeyButtonPressed(MyGUI::Widget *sender, MyGUI::KeyCode key, MyGUI::Char character) + void BookWindow::onKeyButtonPressed(MyGUI::Widget* sender, MyGUI::KeyCode key, MyGUI::Char character) { if (key == MyGUI::KeyCode::ArrowUp) prevPage(); @@ -124,38 +125,38 @@ namespace MWGui mTakeButton->setVisible(mTakeButtonShow && mTakeButtonAllowed); } - void BookWindow::onCloseButtonClicked (MyGUI::Widget* sender) + void BookWindow::onCloseButtonClicked(MyGUI::Widget* sender) { MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Book); } - void BookWindow::onTakeButtonClicked (MyGUI::Widget* sender) + void BookWindow::onTakeButtonClicked(MyGUI::Widget* sender) { MWBase::Environment::get().getWindowManager()->playSound("Item Book Up"); MWWorld::ActionTake take(mBook); - take.execute (MWMechanics::getPlayer()); + take.execute(MWMechanics::getPlayer()); MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Book); } - void BookWindow::onNextPageButtonClicked (MyGUI::Widget* sender) + void BookWindow::onNextPageButtonClicked(MyGUI::Widget* sender) { nextPage(); } - void BookWindow::onPrevPageButtonClicked (MyGUI::Widget* sender) + void BookWindow::onPrevPageButtonClicked(MyGUI::Widget* sender) { prevPage(); } void BookWindow::updatePages() { - mLeftPageNumber->setCaption( MyGUI::utility::toString(mCurrentPage*2 + 1) ); - mRightPageNumber->setCaption( MyGUI::utility::toString(mCurrentPage*2 + 2) ); + mLeftPageNumber->setCaption(MyGUI::utility::toString(mCurrentPage * 2 + 1)); + mRightPageNumber->setCaption(MyGUI::utility::toString(mCurrentPage * 2 + 2)); MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget(); - bool nextPageVisible = (mCurrentPage+1)*2 < mPages.size(); + bool nextPageVisible = (mCurrentPage + 1) * 2 < mPages.size(); mNextPageButton->setVisible(nextPageVisible); bool prevPageVisible = mCurrentPage != 0; mPrevPageButton->setVisible(prevPageVisible); @@ -168,17 +169,17 @@ namespace MWGui if (mPages.empty()) return; - MyGUI::Widget * paper; + MyGUI::Widget* paper; paper = mLeftPage->getChildAt(0); - paper->setCoord(paper->getPosition().left, -mPages[mCurrentPage*2].first, - paper->getWidth(), mPages[mCurrentPage*2].second); + paper->setCoord(paper->getPosition().left, -mPages[mCurrentPage * 2].first, paper->getWidth(), + mPages[mCurrentPage * 2].second); paper = mRightPage->getChildAt(0); - if ((mCurrentPage+1)*2 <= mPages.size()) + if ((mCurrentPage + 1) * 2 <= mPages.size()) { - paper->setCoord(paper->getPosition().left, -mPages[mCurrentPage*2+1].first, - paper->getWidth(), mPages[mCurrentPage*2+1].second); + paper->setCoord(paper->getPosition().left, -mPages[mCurrentPage * 2 + 1].first, paper->getWidth(), + mPages[mCurrentPage * 2 + 1].second); paper->setVisible(true); } else @@ -189,7 +190,7 @@ namespace MWGui void BookWindow::nextPage() { - if ((mCurrentPage+1)*2 < mPages.size()) + if ((mCurrentPage + 1) * 2 < mPages.size()) { MWBase::Environment::get().getWindowManager()->playSound("book page2"); diff --git a/apps/openmw/mwgui/bookwindow.hpp b/apps/openmw/mwgui/bookwindow.hpp index 116437f22e..bf210c0b12 100644 --- a/apps/openmw/mwgui/bookwindow.hpp +++ b/apps/openmw/mwgui/bookwindow.hpp @@ -11,51 +11,51 @@ namespace MWGui { class BookWindow : public BookWindowBase { - public: - BookWindow(); + public: + BookWindow(); - void setPtr(const MWWorld::Ptr& book) override; - void setInventoryAllowed(bool allowed); + void setPtr(const MWWorld::Ptr& book) override; + void setInventoryAllowed(bool allowed); - void onResChange(int, int) override { center(); } + void onResChange(int, int) override { center(); } - protected: - void onNextPageButtonClicked (MyGUI::Widget* sender); - void onPrevPageButtonClicked (MyGUI::Widget* sender); - void onCloseButtonClicked (MyGUI::Widget* sender); - void onTakeButtonClicked (MyGUI::Widget* sender); - void onMouseWheel(MyGUI::Widget* _sender, int _rel); - void setTakeButtonShow(bool show); + protected: + void onNextPageButtonClicked(MyGUI::Widget* sender); + void onPrevPageButtonClicked(MyGUI::Widget* sender); + void onCloseButtonClicked(MyGUI::Widget* sender); + void onTakeButtonClicked(MyGUI::Widget* sender); + void onMouseWheel(MyGUI::Widget* _sender, int _rel); + void setTakeButtonShow(bool show); - void onKeyButtonPressed(MyGUI::Widget* sender, MyGUI::KeyCode key, MyGUI::Char character); + void onKeyButtonPressed(MyGUI::Widget* sender, MyGUI::KeyCode key, MyGUI::Char character); - void nextPage(); - void prevPage(); + void nextPage(); + void prevPage(); - void updatePages(); - void clearPages(); + void updatePages(); + void clearPages(); - private: - typedef std::pair Page; - typedef std::vector Pages; + private: + typedef std::pair Page; + typedef std::vector Pages; - Gui::ImageButton* mCloseButton; - Gui::ImageButton* mTakeButton; - Gui::ImageButton* mNextPageButton; - Gui::ImageButton* mPrevPageButton; + Gui::ImageButton* mCloseButton; + Gui::ImageButton* mTakeButton; + Gui::ImageButton* mNextPageButton; + Gui::ImageButton* mPrevPageButton; - MyGUI::TextBox* mLeftPageNumber; - MyGUI::TextBox* mRightPageNumber; - MyGUI::Widget* mLeftPage; - MyGUI::Widget* mRightPage; + MyGUI::TextBox* mLeftPageNumber; + MyGUI::TextBox* mRightPageNumber; + MyGUI::Widget* mLeftPage; + MyGUI::Widget* mRightPage; - unsigned int mCurrentPage; // 0 is first page - Pages mPages; + unsigned int mCurrentPage; // 0 is first page + Pages mPages; - MWWorld::Ptr mBook; + MWWorld::Ptr mBook; - bool mTakeButtonShow; - bool mTakeButtonAllowed; + bool mTakeButtonShow; + bool mTakeButtonAllowed; }; } diff --git a/apps/openmw/mwgui/charactercreation.cpp b/apps/openmw/mwgui/charactercreation.cpp index 9a620ae3d5..de71aed1f6 100644 --- a/apps/openmw/mwgui/charactercreation.cpp +++ b/apps/openmw/mwgui/charactercreation.cpp @@ -7,24 +7,24 @@ #include #include "../mwbase/environment.hpp" -#include "../mwbase/soundmanager.hpp" #include "../mwbase/mechanicsmanager.hpp" -#include "../mwbase/world.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" -#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/actorutil.hpp" +#include "../mwmechanics/npcstats.hpp" #include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" #include "../mwworld/player.hpp" -#include "textinput.hpp" -#include "race.hpp" -#include "class.hpp" #include "birth.hpp" -#include "review.hpp" +#include "class.hpp" #include "inventorywindow.hpp" +#include "race.hpp" +#include "review.hpp" +#include "textinput.hpp" namespace { @@ -45,15 +45,16 @@ namespace { number++; - std::string question{Fallback::Map::getString("Question_" + MyGUI::utility::toString(number) + "_Question")}; - std::string answer0{Fallback::Map::getString("Question_" + MyGUI::utility::toString(number) + "_AnswerOne")}; - std::string answer1{Fallback::Map::getString("Question_" + MyGUI::utility::toString(number) + "_AnswerTwo")}; - std::string answer2{Fallback::Map::getString("Question_" + MyGUI::utility::toString(number) + "_AnswerThree")}; + std::string question{ Fallback::Map::getString("Question_" + MyGUI::utility::toString(number) + "_Question") }; + std::string answer0{ Fallback::Map::getString("Question_" + MyGUI::utility::toString(number) + "_AnswerOne") }; + std::string answer1{ Fallback::Map::getString("Question_" + MyGUI::utility::toString(number) + "_AnswerTwo") }; + std::string answer2{ Fallback::Map::getString( + "Question_" + MyGUI::utility::toString(number) + "_AnswerThree") }; std::string sound = "vo\\misc\\chargen qa" + MyGUI::utility::toString(number) + ".wav"; - Response r0 = {answer0, ESM::Class::Combat}; - Response r1 = {answer1, ESM::Class::Magic}; - Response r2 = {answer2, ESM::Class::Stealth}; + Response r0 = { answer0, ESM::Class::Combat }; + Response r1 = { answer1, ESM::Class::Magic }; + Response r2 = { answer2, ESM::Class::Stealth }; // randomize order in which responses are displayed int order = Misc::Rng::rollDice(6); @@ -61,17 +62,17 @@ namespace switch (order) { case 0: - return {question, {r0, r1, r2}, sound}; + return { question, { r0, r1, r2 }, sound }; case 1: - return {question, {r0, r2, r1}, sound}; + return { question, { r0, r2, r1 }, sound }; case 2: - return {question, {r1, r0, r2}, sound}; + return { question, { r1, r0, r2 }, sound }; case 3: - return {question, {r1, r2, r0}, sound}; + return { question, { r1, r2, r0 }, sound }; case 4: - return {question, {r2, r0, r1}, sound}; + return { question, { r2, r0, r1 }, sound }; default: - return {question, {r2, r1, r0}, sound}; + return { question, { r2, r1, r0 }, sound }; } } } @@ -100,17 +101,23 @@ namespace MWGui mPlayerSkillValues.emplace(ESM::Skill::sSkillIds[i], MWMechanics::SkillValue()); } - void CharacterCreation::setValue (const std::string& id, const MWMechanics::AttributeValue& value) - { - static const char *ids[] = - { - "AttribVal1", "AttribVal2", "AttribVal3", "AttribVal4", - "AttribVal5", "AttribVal6", "AttribVal7", "AttribVal8", nullptr, + void CharacterCreation::setValue(const std::string& id, const MWMechanics::AttributeValue& value) + { + static const char* ids[] = { + "AttribVal1", + "AttribVal2", + "AttribVal3", + "AttribVal4", + "AttribVal5", + "AttribVal6", + "AttribVal7", + "AttribVal8", + nullptr, }; - for (int i=0; ids[i]; ++i) + for (int i = 0; ids[i]; ++i) { - if (ids[i]==id) + if (ids[i] == id) { mPlayerAttributes[static_cast(i)] = value; if (mReviewDialog) @@ -121,21 +128,21 @@ namespace MWGui } } - void CharacterCreation::setValue (const std::string& id, const MWMechanics::DynamicStat& value) + void CharacterCreation::setValue(const std::string& id, const MWMechanics::DynamicStat& value) { if (mReviewDialog) { if (id == "HBar") { - mReviewDialog->setHealth (value); + mReviewDialog->setHealth(value); } else if (id == "MBar") { - mReviewDialog->setMagicka (value); + mReviewDialog->setMagicka(value); } else if (id == "FBar") { - mReviewDialog->setFatigue (value); + mReviewDialog->setFatigue(value); } } } @@ -147,7 +154,7 @@ namespace MWGui mReviewDialog->setSkillValue(parSkill, value); } - void CharacterCreation::configureSkills (const SkillList& major, const SkillList& minor) + void CharacterCreation::configureSkills(const SkillList& major, const SkillList& minor) { if (mReviewDialog) mReviewDialog->configureSkills(major, minor); @@ -171,7 +178,8 @@ namespace MWGui case GM_Name: MWBase::Environment::get().getWindowManager()->removeDialog(std::move(mNameDialog)); mNameDialog = std::make_unique(); - mNameDialog->setTextLabel(MWBase::Environment::get().getWindowManager()->getGameSettingString("sName", "Name")); + mNameDialog->setTextLabel( + MWBase::Environment::get().getWindowManager()->getGameSettingString("sName", "Name")); mNameDialog->setTextInput(mPlayerName); mNameDialog->setNextButtonShow(mCreationStage >= CSE_NameChosen); mNameDialog->eventDone += MyGUI::newDelegate(this, &CharacterCreation::onNameDialogDone); @@ -193,7 +201,8 @@ namespace MWGui case GM_Class: MWBase::Environment::get().getWindowManager()->removeDialog(std::move(mClassChoiceDialog)); mClassChoiceDialog = std::make_unique(); - mClassChoiceDialog->eventButtonSelected += MyGUI::newDelegate(this, &CharacterCreation::onClassChoice); + mClassChoiceDialog->eventButtonSelected + += MyGUI::newDelegate(this, &CharacterCreation::onClassChoice); mClassChoiceDialog->setVisible(true); if (mCreationStage < CSE_RaceChosen) mCreationStage = CSE_RaceChosen; @@ -227,8 +236,10 @@ namespace MWGui if (mCreateClassDialog == nullptr) { mCreateClassDialog = std::make_unique(); - mCreateClassDialog->eventDone += MyGUI::newDelegate(this, &CharacterCreation::onCreateClassDialogDone); - mCreateClassDialog->eventBack += MyGUI::newDelegate(this, &CharacterCreation::onCreateClassDialogBack); + mCreateClassDialog->eventDone + += MyGUI::newDelegate(this, &CharacterCreation::onCreateClassDialogDone); + mCreateClassDialog->eventBack + += MyGUI::newDelegate(this, &CharacterCreation::onCreateClassDialogBack); } mCreateClassDialog->setNextButtonShow(mCreationStage >= CSE_ClassChosen); mCreateClassDialog->setVisible(true); @@ -249,13 +260,13 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->removeDialog(std::move(mReviewDialog)); mReviewDialog = std::make_unique(); - MWBase::World *world = MWBase::Environment::get().getWorld(); + MWBase::World* world = MWBase::Environment::get().getWorld(); - const ESM::NPC *playerNpc = world->getPlayerPtr().get()->mBase; + const ESM::NPC* playerNpc = world->getPlayerPtr().get()->mBase; const MWWorld::Player player = world->getPlayer(); - const ESM::Class *playerClass = world->getStore().get().find(playerNpc->mClass); + const ESM::Class* playerClass = world->getStore().get().find(playerNpc->mClass); mReviewDialog->setPlayerName(playerNpc->mName); mReviewDialog->setRace(playerNpc->mRace); @@ -270,17 +281,20 @@ namespace MWGui mReviewDialog->setFatigue(stats.getFatigue()); for (auto& attributePair : mPlayerAttributes) { - mReviewDialog->setAttribute(static_cast (attributePair.first), attributePair.second); + mReviewDialog->setAttribute( + static_cast(attributePair.first), attributePair.second); } for (auto& skillPair : mPlayerSkillValues) { - mReviewDialog->setSkillValue(static_cast (skillPair.first), skillPair.second); + mReviewDialog->setSkillValue( + static_cast(skillPair.first), skillPair.second); } mReviewDialog->configureSkills(mPlayerMajorSkills, mPlayerMinorSkills); mReviewDialog->eventDone += MyGUI::newDelegate(this, &CharacterCreation::onReviewDialogDone); mReviewDialog->eventBack += MyGUI::newDelegate(this, &CharacterCreation::onReviewDialogBack); - mReviewDialog->eventActivateDialog += MyGUI::newDelegate(this, &CharacterCreation::onReviewActivateDialog); + mReviewDialog->eventActivateDialog + += MyGUI::newDelegate(this, &CharacterCreation::onReviewActivateDialog); mReviewDialog->setVisible(true); if (mCreationStage < CSE_BirthSignChosen) mCreationStage = CSE_BirthSignChosen; @@ -315,7 +329,7 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->popGuiMode(); - switch(parDialog) + switch (parDialog) { case ReviewDialog::NAME_DIALOG: MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Name); @@ -335,12 +349,11 @@ namespace MWGui { if (mPickClassDialog) { - const std::string &classId = mPickClassDialog->getClassId(); + const std::string& classId = mPickClassDialog->getClassId(); if (!classId.empty()) MWBase::Environment::get().getMechanicsManager()->setPlayerClass(classId); - const ESM::Class *klass = - MWBase::Environment::get().getWorld()->getStore().get().find(classId); + const ESM::Class* klass = MWBase::Environment::get().getWorld()->getStore().get().find(classId); if (klass) { mPlayerClass = *klass; @@ -370,7 +383,7 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->popGuiMode(); - switch(_index) + switch (_index) { case ClassChoiceDialog::Class_Generate: MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_ClassGenerate); @@ -384,7 +397,6 @@ namespace MWGui case ClassChoiceDialog::Class_Back: MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Race); break; - }; } @@ -404,15 +416,12 @@ namespace MWGui { if (mRaceDialog) { - const ESM::NPC &data = mRaceDialog->getResult(); + const ESM::NPC& data = mRaceDialog->getResult(); mPlayerRaceId = data.mRace; - if (!mPlayerRaceId.empty()) { + if (!mPlayerRaceId.empty()) + { MWBase::Environment::get().getMechanicsManager()->setPlayerRace( - data.mRace, - data.isMale(), - data.mHead, - data.mHair - ); + data.mRace, data.isMale(), data.mHead, data.mHair); } MWBase::Environment::get().getWindowManager()->getInventoryWindow()->rebuildAvatar(); @@ -479,9 +488,9 @@ namespace MWGui std::vector majorSkills = mCreateClassDialog->getMajorSkills(); std::vector minorSkills = mCreateClassDialog->getMinorSkills(); - assert(majorSkills.size() >= sizeof(klass.mData.mSkills)/sizeof(klass.mData.mSkills[0])); - assert(minorSkills.size() >= sizeof(klass.mData.mSkills)/sizeof(klass.mData.mSkills[0])); - for (size_t i = 0; i < sizeof(klass.mData.mSkills)/sizeof(klass.mData.mSkills[0]); ++i) + assert(majorSkills.size() >= sizeof(klass.mData.mSkills) / sizeof(klass.mData.mSkills[0])); + assert(minorSkills.size() >= sizeof(klass.mData.mSkills) / sizeof(klass.mData.mSkills[0])); + for (size_t i = 0; i < sizeof(klass.mData.mSkills) / sizeof(klass.mData.mSkills[0]); ++i) { klass.mData.mSkills[i][1] = majorSkills[i]; klass.mData.mSkills[i][0] = minorSkills[i]; @@ -664,7 +673,8 @@ namespace MWGui buttons.push_back(step.mResponses[1].mText); buttons.push_back(step.mResponses[2].mText); mGenerateClassQuestionDialog->setButtons(buttons); - mGenerateClassQuestionDialog->eventButtonSelected += MyGUI::newDelegate(this, &CharacterCreation::onClassQuestionChosen); + mGenerateClassQuestionDialog->eventButtonSelected + += MyGUI::newDelegate(this, &CharacterCreation::onClassQuestionChosen); mGenerateClassQuestionDialog->setVisible(true); MWBase::Environment::get().getSoundManager()->say(step.mSound); @@ -676,8 +686,8 @@ namespace MWGui MWBase::Environment::get().getMechanicsManager()->setPlayerClass(mGenerateClass); - const ESM::Class *klass = - MWBase::Environment::get().getWorld()->getStore().get().find(mGenerateClass); + const ESM::Class* klass + = MWBase::Environment::get().getWorld()->getStore().get().find(mGenerateClass); mPlayerClass = *klass; } diff --git a/apps/openmw/mwgui/charactercreation.hpp b/apps/openmw/mwgui/charactercreation.hpp index e9c21fc212..3780efbd6b 100644 --- a/apps/openmw/mwgui/charactercreation.hpp +++ b/apps/openmw/mwgui/charactercreation.hpp @@ -4,8 +4,8 @@ #include #include -#include #include +#include #include "statswatcher.hpp" @@ -38,99 +38,100 @@ namespace MWGui class CharacterCreation : public StatsListener { public: - typedef std::vector SkillList; + typedef std::vector SkillList; - CharacterCreation(osg::Group* parent, Resource::ResourceSystem* resourceSystem); - virtual ~CharacterCreation(); + CharacterCreation(osg::Group* parent, Resource::ResourceSystem* resourceSystem); + virtual ~CharacterCreation(); - //Show a dialog - void spawnDialog(const char id); + // Show a dialog + void spawnDialog(const char id); - void setValue (const std::string& id, const MWMechanics::AttributeValue& value) override; - void setValue (const std::string& id, const MWMechanics::DynamicStat& value) override; - void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::SkillValue& value) override; - void configureSkills(const SkillList& major, const SkillList& minor) override; + void setValue(const std::string& id, const MWMechanics::AttributeValue& value) override; + void setValue(const std::string& id, const MWMechanics::DynamicStat& value) override; + void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::SkillValue& value) override; + void configureSkills(const SkillList& major, const SkillList& minor) override; - void onFrame(float duration); + void onFrame(float duration); private: - osg::Group* mParent; - Resource::ResourceSystem* mResourceSystem; - - SkillList mPlayerMajorSkills, mPlayerMinorSkills; - std::map mPlayerAttributes; - std::map mPlayerSkillValues; - - //Dialogs - std::unique_ptr mNameDialog; - std::unique_ptr mRaceDialog; - std::unique_ptr mClassChoiceDialog; - std::unique_ptr mGenerateClassQuestionDialog; - std::unique_ptr mGenerateClassResultDialog; - std::unique_ptr mPickClassDialog; - std::unique_ptr mCreateClassDialog; - std::unique_ptr mBirthSignDialog; - std::unique_ptr mReviewDialog; - - //Player data - std::string mPlayerName; - std::string mPlayerRaceId; - std::string mPlayerBirthSignId; - ESM::Class mPlayerClass; - - //Class generation vars - unsigned mGenerateClassStep; // Keeps track of current step in Generate Class dialog - ESM::Class::Specialization mGenerateClassResponses[3]; - unsigned mGenerateClassSpecializations[3]; // A counter for each specialization which is increased when an answer is chosen - std::string mGenerateClass; // In order: Combat, Magic, Stealth - - ////Dialog events - //Name dialog - void onNameDialogDone(WindowBase* parWindow); - - //Race dialog - void onRaceDialogDone(WindowBase* parWindow); - void onRaceDialogBack(); - void selectRace(); - - //Class dialogs - void onClassChoice(int _index); - void onPickClassDialogDone(WindowBase* parWindow); - void onPickClassDialogBack(); - void onCreateClassDialogDone(WindowBase* parWindow); - void onCreateClassDialogBack(); - void showClassQuestionDialog(); - void onClassQuestionChosen(int _index); - void onGenerateClassBack(); - void onGenerateClassDone(WindowBase* parWindow); - void selectGeneratedClass(); - void selectCreatedClass(); - void selectPickedClass(); - - //Birthsign dialog - void onBirthSignDialogDone(WindowBase* parWindow); - void onBirthSignDialogBack(); - void selectBirthSign(); - - //Review dialog - void onReviewDialogDone(WindowBase* parWindow); - void onReviewDialogBack(); - void onReviewActivateDialog(int parDialog); - - enum CSE //Creation Stage Enum - { - CSE_NotStarted, - CSE_NameChosen, - CSE_RaceChosen, - CSE_ClassChosen, - CSE_BirthSignChosen, - CSE_ReviewBack, - CSE_ReviewNext - }; - - CSE mCreationStage; // Which state the character creating is in, controls back/next/ok buttons - - void handleDialogDone(CSE currentStage, int nextMode); + osg::Group* mParent; + Resource::ResourceSystem* mResourceSystem; + + SkillList mPlayerMajorSkills, mPlayerMinorSkills; + std::map mPlayerAttributes; + std::map mPlayerSkillValues; + + // Dialogs + std::unique_ptr mNameDialog; + std::unique_ptr mRaceDialog; + std::unique_ptr mClassChoiceDialog; + std::unique_ptr mGenerateClassQuestionDialog; + std::unique_ptr mGenerateClassResultDialog; + std::unique_ptr mPickClassDialog; + std::unique_ptr mCreateClassDialog; + std::unique_ptr mBirthSignDialog; + std::unique_ptr mReviewDialog; + + // Player data + std::string mPlayerName; + std::string mPlayerRaceId; + std::string mPlayerBirthSignId; + ESM::Class mPlayerClass; + + // Class generation vars + unsigned mGenerateClassStep; // Keeps track of current step in Generate Class dialog + ESM::Class::Specialization mGenerateClassResponses[3]; + unsigned mGenerateClassSpecializations[3]; // A counter for each specialization which is increased when an + // answer is chosen + std::string mGenerateClass; // In order: Combat, Magic, Stealth + + ////Dialog events + // Name dialog + void onNameDialogDone(WindowBase* parWindow); + + // Race dialog + void onRaceDialogDone(WindowBase* parWindow); + void onRaceDialogBack(); + void selectRace(); + + // Class dialogs + void onClassChoice(int _index); + void onPickClassDialogDone(WindowBase* parWindow); + void onPickClassDialogBack(); + void onCreateClassDialogDone(WindowBase* parWindow); + void onCreateClassDialogBack(); + void showClassQuestionDialog(); + void onClassQuestionChosen(int _index); + void onGenerateClassBack(); + void onGenerateClassDone(WindowBase* parWindow); + void selectGeneratedClass(); + void selectCreatedClass(); + void selectPickedClass(); + + // Birthsign dialog + void onBirthSignDialogDone(WindowBase* parWindow); + void onBirthSignDialogBack(); + void selectBirthSign(); + + // Review dialog + void onReviewDialogDone(WindowBase* parWindow); + void onReviewDialogBack(); + void onReviewActivateDialog(int parDialog); + + enum CSE // Creation Stage Enum + { + CSE_NotStarted, + CSE_NameChosen, + CSE_RaceChosen, + CSE_ClassChosen, + CSE_BirthSignChosen, + CSE_ReviewBack, + CSE_ReviewNext + }; + + CSE mCreationStage; // Which state the character creating is in, controls back/next/ok buttons + + void handleDialogDone(CSE currentStage, int nextMode); }; } diff --git a/apps/openmw/mwgui/class.cpp b/apps/openmw/mwgui/class.cpp index a54435d67f..ec5ec75eef 100644 --- a/apps/openmw/mwgui/class.cpp +++ b/apps/openmw/mwgui/class.cpp @@ -1,22 +1,22 @@ #include "class.hpp" +#include #include #include -#include #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" #include "../mwmechanics/actorutil.hpp" #include "../mwworld/esmstore.hpp" #include -#include +#include #include +#include #include -#include #include "tooltips.hpp" #include "ustring.hpp" @@ -37,9 +37,10 @@ namespace MWGui /* GenerateClassResultDialog */ GenerateClassResultDialog::GenerateClassResultDialog() - : WindowModal("openmw_chargen_generate_class_result.layout") + : WindowModal("openmw_chargen_generate_class_result.layout") { - setText("ReflectT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sMessageQuestionAnswer1", {})); + setText("ReflectT", + MWBase::Environment::get().getWindowManager()->getGameSettingString("sMessageQuestionAnswer1", {})); getWidget(mClassImage, "ClassImage"); getWidget(mClassName, "ClassName"); @@ -57,13 +58,14 @@ namespace MWGui center(); } - void GenerateClassResultDialog::setClassId(const std::string &classId) + void GenerateClassResultDialog::setClassId(const std::string& classId) { mCurrentClassId = classId; setClassImage(mClassImage, mCurrentClassId); - mClassName->setCaption(MWBase::Environment::get().getWorld()->getStore().get().find(mCurrentClassId)->mName); + mClassName->setCaption( + MWBase::Environment::get().getWorld()->getStore().get().find(mCurrentClassId)->mName); center(); } @@ -83,7 +85,7 @@ namespace MWGui /* PickClassDialog */ PickClassDialog::PickClassDialog() - : WindowModal("openmw_chargen_class.layout") + : WindowModal("openmw_chargen_class.layout") { // Centre dialog center(); @@ -93,9 +95,9 @@ namespace MWGui getWidget(mFavoriteAttribute[0], "FavoriteAttribute0"); getWidget(mFavoriteAttribute[1], "FavoriteAttribute1"); - for(int i = 0; i < 5; i++) + for (int i = 0; i < 5; i++) { - char theIndex = '0'+i; + char theIndex = '0' + i; getWidget(mMajorSkill[i], std::string("MajorSkill").append(1, theIndex)); getWidget(mMinorSkill[i], std::string("MinorSkill").append(1, theIndex)); } @@ -125,14 +127,16 @@ namespace MWGui getWidget(okButton, "OKButton"); if (shown) - okButton->setCaption(toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString("sNext", {}))); + okButton->setCaption( + toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString("sNext", {}))); else - okButton->setCaption(toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", {}))); + okButton->setCaption( + toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", {}))); } void PickClassDialog::onOpen() { - WindowModal::onOpen (); + WindowModal::onOpen(); updateClasses(); updateStats(); MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mClassList); @@ -140,14 +144,13 @@ namespace MWGui // Show the current class by default MWWorld::Ptr player = MWMechanics::getPlayer(); - const std::string &classId = - player.get()->mBase->mClass; + const std::string& classId = player.get()->mBase->mClass; if (!classId.empty()) setClassId(classId); } - void PickClassDialog::setClassId(const std::string &classId) + void PickClassDialog::setClassId(const std::string& classId) { mCurrentClassId = classId; mClassList->setIndexSelected(MyGUI::ITEM_NONE); @@ -168,7 +171,7 @@ namespace MWGui void PickClassDialog::onOkClicked(MyGUI::Widget* _sender) { - if(mClassList->getIndexSelected() == MyGUI::ITEM_NONE) + if (mClassList->getIndexSelected() == MyGUI::ITEM_NONE) return; eventDone(this); } @@ -181,7 +184,7 @@ namespace MWGui void PickClassDialog::onAccept(MyGUI::ListBox* _sender, size_t _index) { onSelectClass(_sender, _index); - if(mClassList->getIndexSelected() == MyGUI::ITEM_NONE) + if (mClassList->getIndexSelected() == MyGUI::ITEM_NONE) return; eventDone(this); } @@ -191,7 +194,7 @@ namespace MWGui if (_index == MyGUI::ITEM_NONE) return; - const std::string *classId = mClassList->getItemDataAt(_index); + const std::string* classId = mClassList->getItemDataAt(_index); if (Misc::StringUtils::ciEqual(mCurrentClassId, *classId)) return; @@ -205,9 +208,9 @@ namespace MWGui { mClassList->removeAllItems(); - const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); - std::vector > items; // class id, class name + std::vector> items; // class id, class name for (const ESM::Class& classInfo : store.get()) { bool playable = (classInfo.mData.mIsPlayable != 0); @@ -224,7 +227,7 @@ namespace MWGui int index = 0; for (auto& itemPair : items) { - const std::string &id = itemPair.first; + const std::string& id = itemPair.first; mClassList->addItem(itemPair.second, id); if (mCurrentClassId.empty()) { @@ -243,19 +246,18 @@ namespace MWGui { if (mCurrentClassId.empty()) return; - const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); - const ESM::Class *klass = store.get().search(mCurrentClassId); + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + const ESM::Class* klass = store.get().search(mCurrentClassId); if (!klass) return; - ESM::Class::Specialization specialization = static_cast(klass->mData.mSpecialization); + ESM::Class::Specialization specialization + = static_cast(klass->mData.mSpecialization); - static const std::string_view specIds[3] = { - "sSpecializationCombat", - "sSpecializationMagic", - "sSpecializationStealth" - }; - std::string specName{MWBase::Environment::get().getWindowManager()->getGameSettingString(specIds[specialization], specIds[specialization])}; + static const std::string_view specIds[3] + = { "sSpecializationCombat", "sSpecializationMagic", "sSpecializationStealth" }; + std::string specName{ MWBase::Environment::get().getWindowManager()->getGameSettingString( + specIds[specialization], specIds[specialization]) }; mSpecializationName->setCaption(specName); ToolTips::createSpecializationToolTip(mSpecializationName, specName, specialization); @@ -303,7 +305,7 @@ namespace MWGui width = std::max(width, child->getWidth()); pos += child->getHeight() + margin; } - width += margin*2; + width += margin * 2; widget->setSize(width, pos); } @@ -318,7 +320,7 @@ namespace MWGui center(); } - void InfoBoxDialog::setText(const std::string &str) + void InfoBoxDialog::setText(const std::string& str) { mText->setCaption(str); mTextBox->setVisible(!str.empty()); @@ -330,7 +332,7 @@ namespace MWGui return mText->getCaption(); } - void InfoBoxDialog::setButtons(ButtonList &buttons) + void InfoBoxDialog::setButtons(ButtonList& buttons) { for (MyGUI::Button* button : this->mButtons) { @@ -341,9 +343,10 @@ namespace MWGui // TODO: The buttons should be generated from a template in the layout file, ie. cloning an existing widget MyGUI::Button* button; MyGUI::IntCoord coord = MyGUI::IntCoord(0, 0, mButtonBar->getWidth(), 10); - for (const std::string &text : buttons) + for (const std::string& text : buttons) { - button = mButtonBar->createWidget("MW_Button", coord, MyGUI::Align::Top | MyGUI::Align::HCenter, ""); + button = mButtonBar->createWidget( + "MW_Button", coord, MyGUI::Align::Top | MyGUI::Align::HCenter, ""); button->getSubWidgetText()->setWordWrap(true); button->setCaption(text); fitToText(button); @@ -385,9 +388,12 @@ namespace MWGui { setText(""); ButtonList buttons; - buttons.emplace_back(MWBase::Environment::get().getWindowManager()->getGameSettingString("sClassChoiceMenu1", {})); - buttons.emplace_back(MWBase::Environment::get().getWindowManager()->getGameSettingString("sClassChoiceMenu2", {})); - buttons.emplace_back(MWBase::Environment::get().getWindowManager()->getGameSettingString("sClassChoiceMenu3", {})); + buttons.emplace_back( + MWBase::Environment::get().getWindowManager()->getGameSettingString("sClassChoiceMenu1", {})); + buttons.emplace_back( + MWBase::Environment::get().getWindowManager()->getGameSettingString("sClassChoiceMenu2", {})); + buttons.emplace_back( + MWBase::Environment::get().getWindowManager()->getGameSettingString("sClassChoiceMenu3", {})); buttons.emplace_back(MWBase::Environment::get().getWindowManager()->getGameSettingString("sBack", {})); setButtons(buttons); } @@ -395,28 +401,34 @@ namespace MWGui /* CreateClassDialog */ CreateClassDialog::CreateClassDialog() - : WindowModal("openmw_chargen_create_class.layout") - , mAffectedAttribute(nullptr) - , mAffectedSkill(nullptr) + : WindowModal("openmw_chargen_create_class.layout") + , mAffectedAttribute(nullptr) + , mAffectedSkill(nullptr) { // Centre dialog center(); - setText("SpecializationT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sChooseClassMenu1", "Specialization")); + setText("SpecializationT", + MWBase::Environment::get().getWindowManager()->getGameSettingString("sChooseClassMenu1", "Specialization")); getWidget(mSpecializationName, "SpecializationName"); - mSpecializationName->eventMouseButtonClick += MyGUI::newDelegate(this, &CreateClassDialog::onSpecializationClicked); + mSpecializationName->eventMouseButtonClick + += MyGUI::newDelegate(this, &CreateClassDialog::onSpecializationClicked); - setText("FavoriteAttributesT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sChooseClassMenu2", "Favorite Attributes:")); + setText("FavoriteAttributesT", + MWBase::Environment::get().getWindowManager()->getGameSettingString( + "sChooseClassMenu2", "Favorite Attributes:")); getWidget(mFavoriteAttribute0, "FavoriteAttribute0"); getWidget(mFavoriteAttribute1, "FavoriteAttribute1"); mFavoriteAttribute0->eventClicked += MyGUI::newDelegate(this, &CreateClassDialog::onAttributeClicked); mFavoriteAttribute1->eventClicked += MyGUI::newDelegate(this, &CreateClassDialog::onAttributeClicked); - setText("MajorSkillT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sSkillClassMajor", {})); - setText("MinorSkillT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sSkillClassMinor", {})); - for(int i = 0; i < 5; i++) + setText( + "MajorSkillT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sSkillClassMajor", {})); + setText( + "MinorSkillT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sSkillClassMinor", {})); + for (int i = 0; i < 5; i++) { - char theIndex = '0'+i; + char theIndex = '0' + i; getWidget(mMajorSkill[i], std::string("MajorSkill").append(1, theIndex)); getWidget(mMinorSkill[i], std::string("MinorSkill").append(1, theIndex)); mSkills.push_back(mMajorSkill[i]); @@ -508,7 +520,7 @@ namespace MWGui { std::vector v; v.reserve(5); - for(int i = 0; i < 5; i++) + for (int i = 0; i < 5; i++) { v.push_back(mMajorSkill[i]->getSkillId()); } @@ -519,7 +531,7 @@ namespace MWGui { std::vector v; v.reserve(5); - for(int i=0; i < 5; i++) + for (int i = 0; i < 5; i++) { v.push_back(mMinorSkill[i]->getSkillId()); } @@ -532,9 +544,11 @@ namespace MWGui getWidget(okButton, "OKButton"); if (shown) - okButton->setCaption(toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString("sNext", {}))); + okButton->setCaption( + toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString("sNext", {}))); else - okButton->setCaption(toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", {}))); + okButton->setCaption( + toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", {}))); } // widget controls @@ -565,13 +579,11 @@ namespace MWGui void CreateClassDialog::setSpecialization(int id) { - mSpecializationId = (ESM::Class::Specialization) id; - static const std::string_view specIds[3] = { - "sSpecializationCombat", - "sSpecializationMagic", - "sSpecializationStealth" - }; - std::string specName{MWBase::Environment::get().getWindowManager()->getGameSettingString(specIds[mSpecializationId], specIds[mSpecializationId])}; + mSpecializationId = (ESM::Class::Specialization)id; + static const std::string_view specIds[3] + = { "sSpecializationCombat", "sSpecializationMagic", "sSpecializationStealth" }; + std::string specName{ MWBase::Environment::get().getWindowManager()->getGameSettingString( + specIds[mSpecializationId], specIds[mSpecializationId]) }; mSpecializationName->setCaption(specName); ToolTips::createSpecializationToolTip(mSpecializationName, specName, mSpecializationId); } @@ -650,7 +662,7 @@ namespace MWGui void CreateClassDialog::onOkClicked(MyGUI::Widget* _sender) { - if(getName().size() <= 0) + if (getName().size() <= 0) return; eventDone(this); } @@ -663,7 +675,7 @@ namespace MWGui /* SelectSpecializationDialog */ SelectSpecializationDialog::SelectSpecializationDialog() - : WindowModal("openmw_chargen_select_specialization.layout") + : WindowModal("openmw_chargen_select_specialization.layout") { // Centre dialog center(); @@ -671,16 +683,22 @@ namespace MWGui getWidget(mSpecialization0, "Specialization0"); getWidget(mSpecialization1, "Specialization1"); getWidget(mSpecialization2, "Specialization2"); - std::string combat{MWBase::Environment::get().getWindowManager()->getGameSettingString(ESM::Class::sGmstSpecializationIds[ESM::Class::Combat], {})}; - std::string magic{MWBase::Environment::get().getWindowManager()->getGameSettingString(ESM::Class::sGmstSpecializationIds[ESM::Class::Magic], {})}; - std::string stealth{MWBase::Environment::get().getWindowManager()->getGameSettingString(ESM::Class::sGmstSpecializationIds[ESM::Class::Stealth], {})}; + std::string combat{ MWBase::Environment::get().getWindowManager()->getGameSettingString( + ESM::Class::sGmstSpecializationIds[ESM::Class::Combat], {}) }; + std::string magic{ MWBase::Environment::get().getWindowManager()->getGameSettingString( + ESM::Class::sGmstSpecializationIds[ESM::Class::Magic], {}) }; + std::string stealth{ MWBase::Environment::get().getWindowManager()->getGameSettingString( + ESM::Class::sGmstSpecializationIds[ESM::Class::Stealth], {}) }; mSpecialization0->setCaption(combat); - mSpecialization0->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked); + mSpecialization0->eventMouseButtonClick + += MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked); mSpecialization1->setCaption(magic); - mSpecialization1->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked); + mSpecialization1->eventMouseButtonClick + += MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked); mSpecialization2->setCaption(stealth); - mSpecialization2->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked); + mSpecialization2->eventMouseButtonClick + += MyGUI::newDelegate(this, &SelectSpecializationDialog::onSpecializationClicked); mSpecializationId = ESM::Class::Combat; ToolTips::createSpecializationToolTip(mSpecialization0, combat, ESM::Class::Combat); @@ -692,9 +710,7 @@ namespace MWGui cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSpecializationDialog::onCancelClicked); } - SelectSpecializationDialog::~SelectSpecializationDialog() - { - } + SelectSpecializationDialog::~SelectSpecializationDialog() {} // widget controls @@ -726,8 +742,8 @@ namespace MWGui /* SelectAttributeDialog */ SelectAttributeDialog::SelectAttributeDialog() - : WindowModal("openmw_chargen_select_attribute.layout") - , mAttributeId(ESM::Attribute::Strength) + : WindowModal("openmw_chargen_select_attribute.layout") + , mAttributeId(ESM::Attribute::Strength) { // Centre dialog center(); @@ -735,9 +751,9 @@ namespace MWGui for (int i = 0; i < 8; ++i) { Widgets::MWAttributePtr attribute; - char theIndex = '0'+i; + char theIndex = '0' + i; - getWidget(attribute, std::string("Attribute").append(1, theIndex)); + getWidget(attribute, std::string("Attribute").append(1, theIndex)); attribute->setAttributeId(ESM::Attribute::sAttributeIds[i]); attribute->eventClicked += MyGUI::newDelegate(this, &SelectAttributeDialog::onAttributeClicked); ToolTips::createAttributeToolTip(attribute, attribute->getAttributeId()); @@ -748,9 +764,7 @@ namespace MWGui cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectAttributeDialog::onCancelClicked); } - SelectAttributeDialog::~SelectAttributeDialog() - { - } + SelectAttributeDialog::~SelectAttributeDialog() {} // widget controls @@ -772,59 +786,43 @@ namespace MWGui return true; } - /* SelectSkillDialog */ SelectSkillDialog::SelectSkillDialog() - : WindowModal("openmw_chargen_select_skill.layout") - , mSkillId(ESM::Skill::Block) + : WindowModal("openmw_chargen_select_skill.layout") + , mSkillId(ESM::Skill::Block) { // Centre dialog center(); - for(int i = 0; i < 9; i++) + for (int i = 0; i < 9; i++) { - char theIndex = '0'+i; - getWidget(mCombatSkill[i], std::string("CombatSkill").append(1, theIndex)); - getWidget(mMagicSkill[i], std::string("MagicSkill").append(1, theIndex)); + char theIndex = '0' + i; + getWidget(mCombatSkill[i], std::string("CombatSkill").append(1, theIndex)); + getWidget(mMagicSkill[i], std::string("MagicSkill").append(1, theIndex)); getWidget(mStealthSkill[i], std::string("StealthSkill").append(1, theIndex)); } - struct {Widgets::MWSkillPtr widget; ESM::Skill::SkillEnum skillId;} mSkills[3][9] = { - { - {mCombatSkill[0], ESM::Skill::Block}, - {mCombatSkill[1], ESM::Skill::Armorer}, - {mCombatSkill[2], ESM::Skill::MediumArmor}, - {mCombatSkill[3], ESM::Skill::HeavyArmor}, - {mCombatSkill[4], ESM::Skill::BluntWeapon}, - {mCombatSkill[5], ESM::Skill::LongBlade}, - {mCombatSkill[6], ESM::Skill::Axe}, - {mCombatSkill[7], ESM::Skill::Spear}, - {mCombatSkill[8], ESM::Skill::Athletics} - }, - { - {mMagicSkill[0], ESM::Skill::Enchant}, - {mMagicSkill[1], ESM::Skill::Destruction}, - {mMagicSkill[2], ESM::Skill::Alteration}, - {mMagicSkill[3], ESM::Skill::Illusion}, - {mMagicSkill[4], ESM::Skill::Conjuration}, - {mMagicSkill[5], ESM::Skill::Mysticism}, - {mMagicSkill[6], ESM::Skill::Restoration}, - {mMagicSkill[7], ESM::Skill::Alchemy}, - {mMagicSkill[8], ESM::Skill::Unarmored} - }, - { - {mStealthSkill[0], ESM::Skill::Security}, - {mStealthSkill[1], ESM::Skill::Sneak}, - {mStealthSkill[2], ESM::Skill::Acrobatics}, - {mStealthSkill[3], ESM::Skill::LightArmor}, - {mStealthSkill[4], ESM::Skill::ShortBlade}, - {mStealthSkill[5] ,ESM::Skill::Marksman}, - {mStealthSkill[6] ,ESM::Skill::Mercantile}, - {mStealthSkill[7] ,ESM::Skill::Speechcraft}, - {mStealthSkill[8] ,ESM::Skill::HandToHand} - } - }; + struct + { + Widgets::MWSkillPtr widget; + ESM::Skill::SkillEnum skillId; + } mSkills[3][9] + = { { { mCombatSkill[0], ESM::Skill::Block }, { mCombatSkill[1], ESM::Skill::Armorer }, + { mCombatSkill[2], ESM::Skill::MediumArmor }, { mCombatSkill[3], ESM::Skill::HeavyArmor }, + { mCombatSkill[4], ESM::Skill::BluntWeapon }, { mCombatSkill[5], ESM::Skill::LongBlade }, + { mCombatSkill[6], ESM::Skill::Axe }, { mCombatSkill[7], ESM::Skill::Spear }, + { mCombatSkill[8], ESM::Skill::Athletics } }, + { { mMagicSkill[0], ESM::Skill::Enchant }, { mMagicSkill[1], ESM::Skill::Destruction }, + { mMagicSkill[2], ESM::Skill::Alteration }, { mMagicSkill[3], ESM::Skill::Illusion }, + { mMagicSkill[4], ESM::Skill::Conjuration }, { mMagicSkill[5], ESM::Skill::Mysticism }, + { mMagicSkill[6], ESM::Skill::Restoration }, { mMagicSkill[7], ESM::Skill::Alchemy }, + { mMagicSkill[8], ESM::Skill::Unarmored } }, + { { mStealthSkill[0], ESM::Skill::Security }, { mStealthSkill[1], ESM::Skill::Sneak }, + { mStealthSkill[2], ESM::Skill::Acrobatics }, { mStealthSkill[3], ESM::Skill::LightArmor }, + { mStealthSkill[4], ESM::Skill::ShortBlade }, { mStealthSkill[5], ESM::Skill::Marksman }, + { mStealthSkill[6], ESM::Skill::Mercantile }, { mStealthSkill[7], ESM::Skill::Speechcraft }, + { mStealthSkill[8], ESM::Skill::HandToHand } } }; for (int spec = 0; spec < 3; ++spec) { @@ -841,9 +839,7 @@ namespace MWGui cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSkillDialog::onCancelClicked); } - SelectSkillDialog::~SelectSkillDialog() - { - } + SelectSkillDialog::~SelectSkillDialog() {} // widget controls @@ -867,7 +863,7 @@ namespace MWGui /* DescriptionDialog */ DescriptionDialog::DescriptionDialog() - : WindowModal("openmw_chargen_class_description.layout") + : WindowModal("openmw_chargen_class_description.layout") { // Centre dialog center(); @@ -877,15 +873,14 @@ namespace MWGui MyGUI::Button* okButton; getWidget(okButton, "OKButton"); okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &DescriptionDialog::onOkClicked); - okButton->setCaption(toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString("sInputMenu1", {}))); + okButton->setCaption( + toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString("sInputMenu1", {}))); // Make sure the edit box has focus MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mTextEdit); } - DescriptionDialog::~DescriptionDialog() - { - } + DescriptionDialog::~DescriptionDialog() {} // widget controls @@ -894,10 +889,11 @@ namespace MWGui eventDone(this); } - void setClassImage(MyGUI::ImageBox* imageBox, const std::string &classId) + void setClassImage(MyGUI::ImageBox* imageBox, const std::string& classId) { const VFS::Manager* const vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); - std::string classImage = Misc::ResourceHelpers::correctTexturePath("textures\\levelup\\" + classId + ".dds", vfs); + std::string classImage + = Misc::ResourceHelpers::correctTexturePath("textures\\levelup\\" + classId + ".dds", vfs); if (!vfs->exists(classImage)) { Log(Debug::Warning) << "No class image for " << classId << ", falling back to default"; diff --git a/apps/openmw/mwgui/class.hpp b/apps/openmw/mwgui/class.hpp index 6f45459ad7..b88d51b15f 100644 --- a/apps/openmw/mwgui/class.hpp +++ b/apps/openmw/mwgui/class.hpp @@ -22,9 +22,9 @@ namespace MWGui typedef std::vector ButtonList; - void setText(const std::string &str); + void setText(const std::string& str); std::string getText() const; - void setButtons(ButtonList &buttons); + void setButtons(ButtonList& buttons); void onOpen() override; @@ -42,7 +42,6 @@ namespace MWGui void onButtonClicked(MyGUI::Widget* _sender); private: - void fitToText(MyGUI::TextBox* widget); void layoutVertically(MyGUI::Widget* widget, int margin); MyGUI::Widget* mTextBox; @@ -71,7 +70,7 @@ namespace MWGui public: GenerateClassResultDialog(); - void setClassId(const std::string &classId); + void setClassId(const std::string& classId); bool exit() override { return false; } @@ -94,7 +93,7 @@ namespace MWGui private: MyGUI::ImageBox* mClassImage; - MyGUI::TextBox* mClassName; + MyGUI::TextBox* mClassName; std::string mCurrentClassId; }; @@ -104,8 +103,8 @@ namespace MWGui public: PickClassDialog(); - const std::string &getClassId() const { return mCurrentClassId; } - void setClassId(const std::string &classId); + const std::string& getClassId() const { return mCurrentClassId; } + void setClassId(const std::string& classId); void setNextButtonShow(bool shown); void onOpen() override; @@ -137,11 +136,11 @@ namespace MWGui void updateStats(); MyGUI::ImageBox* mClassImage; - MyGUI::ListBox* mClassList; - MyGUI::TextBox* mSpecializationName; + MyGUI::ListBox* mClassList; + MyGUI::TextBox* mSpecializationName; Widgets::MWAttributePtr mFavoriteAttribute[2]; - Widgets::MWSkillPtr mMajorSkill[5]; - Widgets::MWSkillPtr mMinorSkill[5]; + Widgets::MWSkillPtr mMajorSkill[5]; + Widgets::MWSkillPtr mMinorSkill[5]; std::string mCurrentClassId; }; @@ -252,7 +251,7 @@ namespace MWGui ~DescriptionDialog(); std::string getTextInput() const { return mTextEdit->getCaption(); } - void setTextInput(const std::string &text) { mTextEdit->setCaption(text); } + void setTextInput(const std::string& text) { mTextEdit->setCaption(text); } /** Event : Dialog finished, OK button clicked.\n signature : void method()\n @@ -315,23 +314,23 @@ namespace MWGui void update(); private: - MyGUI::EditBox* mEditName; - MyGUI::TextBox* mSpecializationName; - Widgets::MWAttributePtr mFavoriteAttribute0, mFavoriteAttribute1; - Widgets::MWSkillPtr mMajorSkill[5]; - Widgets::MWSkillPtr mMinorSkill[5]; + MyGUI::EditBox* mEditName; + MyGUI::TextBox* mSpecializationName; + Widgets::MWAttributePtr mFavoriteAttribute0, mFavoriteAttribute1; + Widgets::MWSkillPtr mMajorSkill[5]; + Widgets::MWSkillPtr mMinorSkill[5]; std::vector mSkills; - std::string mDescription; + std::string mDescription; std::unique_ptr mSpecDialog; std::unique_ptr mAttribDialog; std::unique_ptr mSkillDialog; std::unique_ptr mDescDialog; - ESM::Class::Specialization mSpecializationId; + ESM::Class::Specialization mSpecializationId; - Widgets::MWAttributePtr mAffectedAttribute; - Widgets::MWSkillPtr mAffectedSkill; + Widgets::MWAttributePtr mAffectedAttribute; + Widgets::MWSkillPtr mAffectedSkill; }; } #endif diff --git a/apps/openmw/mwgui/companionitemmodel.cpp b/apps/openmw/mwgui/companionitemmodel.cpp index 4e065da8b5..1f3f7558ed 100644 --- a/apps/openmw/mwgui/companionitemmodel.cpp +++ b/apps/openmw/mwgui/companionitemmodel.cpp @@ -20,12 +20,12 @@ namespace namespace MWGui { - CompanionItemModel::CompanionItemModel(const MWWorld::Ptr &actor) + CompanionItemModel::CompanionItemModel(const MWWorld::Ptr& actor) : InventoryItemModel(actor) { } - MWWorld::Ptr CompanionItemModel::copyItem (const ItemStack& item, size_t count, bool allowAutoEquip) + MWWorld::Ptr CompanionItemModel::copyItem(const ItemStack& item, size_t count, bool allowAutoEquip) { if (hasProfit(mActor)) modifyProfit(mActor, item.mBase.getClass().getValue(item.mBase) * count); @@ -33,7 +33,7 @@ namespace MWGui return InventoryItemModel::copyItem(item, count, allowAutoEquip); } - void CompanionItemModel::removeItem (const ItemStack& item, size_t count) + void CompanionItemModel::removeItem(const ItemStack& item, size_t count) { if (hasProfit(mActor)) modifyProfit(mActor, -item.mBase.getClass().getValue(item.mBase) * count); @@ -41,7 +41,7 @@ namespace MWGui InventoryItemModel::removeItem(item, count); } - bool CompanionItemModel::hasProfit(const MWWorld::Ptr &actor) + bool CompanionItemModel::hasProfit(const MWWorld::Ptr& actor) { std::string_view script = actor.getClass().getScript(actor); if (script.empty()) diff --git a/apps/openmw/mwgui/companionitemmodel.hpp b/apps/openmw/mwgui/companionitemmodel.hpp index 1872dd1569..0a9491c348 100644 --- a/apps/openmw/mwgui/companionitemmodel.hpp +++ b/apps/openmw/mwgui/companionitemmodel.hpp @@ -11,10 +11,10 @@ namespace MWGui class CompanionItemModel : public InventoryItemModel { public: - CompanionItemModel (const MWWorld::Ptr& actor); + CompanionItemModel(const MWWorld::Ptr& actor); - MWWorld::Ptr copyItem (const ItemStack& item, size_t count, bool allowAutoEquip = true) override; - void removeItem (const ItemStack& item, size_t count) override; + MWWorld::Ptr copyItem(const ItemStack& item, size_t count, bool allowAutoEquip = true) override; + void removeItem(const ItemStack& item, size_t count) override; bool hasProfit(const MWWorld::Ptr& actor); }; diff --git a/apps/openmw/mwgui/companionwindow.cpp b/apps/openmw/mwgui/companionwindow.cpp index 99ed2d995c..d8b71b2ee9 100644 --- a/apps/openmw/mwgui/companionwindow.cpp +++ b/apps/openmw/mwgui/companionwindow.cpp @@ -3,22 +3,22 @@ #include #include -#include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" #include "../mwworld/class.hpp" -#include "messagebox.hpp" -#include "itemview.hpp" -#include "sortfilteritemmodel.hpp" #include "companionitemmodel.hpp" -#include "draganddrop.hpp" #include "countdialog.hpp" -#include "widgets.hpp" +#include "draganddrop.hpp" +#include "itemview.hpp" +#include "messagebox.hpp" +#include "sortfilteritemmodel.hpp" #include "tooltips.hpp" +#include "widgets.hpp" namespace { @@ -38,166 +38,166 @@ namespace namespace MWGui { -CompanionWindow::CompanionWindow(DragAndDrop *dragAndDrop, MessageBoxManager* manager) - : WindowBase("openmw_companion_window.layout") - , mSortModel(nullptr) - , mModel(nullptr) - , mSelectedItem(-1) - , mDragAndDrop(dragAndDrop) - , mMessageBoxManager(manager) -{ - getWidget(mCloseButton, "CloseButton"); - getWidget(mProfitLabel, "ProfitLabel"); - getWidget(mEncumbranceBar, "EncumbranceBar"); - getWidget(mFilterEdit, "FilterEdit"); - getWidget(mItemView, "ItemView"); - mItemView->eventBackgroundClicked += MyGUI::newDelegate(this, &CompanionWindow::onBackgroundSelected); - mItemView->eventItemClicked += MyGUI::newDelegate(this, &CompanionWindow::onItemSelected); - mFilterEdit->eventEditTextChange += MyGUI::newDelegate(this, &CompanionWindow::onNameFilterChanged); - - mCloseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CompanionWindow::onCloseButtonClicked); - - setCoord(200,0,600,300); -} - -void CompanionWindow::onItemSelected(int index) -{ - if (mDragAndDrop->mIsOnDragAndDrop) + CompanionWindow::CompanionWindow(DragAndDrop* dragAndDrop, MessageBoxManager* manager) + : WindowBase("openmw_companion_window.layout") + , mSortModel(nullptr) + , mModel(nullptr) + , mSelectedItem(-1) + , mDragAndDrop(dragAndDrop) + , mMessageBoxManager(manager) { - mDragAndDrop->drop(mModel, mItemView); - updateEncumbranceBar(); - return; + getWidget(mCloseButton, "CloseButton"); + getWidget(mProfitLabel, "ProfitLabel"); + getWidget(mEncumbranceBar, "EncumbranceBar"); + getWidget(mFilterEdit, "FilterEdit"); + getWidget(mItemView, "ItemView"); + mItemView->eventBackgroundClicked += MyGUI::newDelegate(this, &CompanionWindow::onBackgroundSelected); + mItemView->eventItemClicked += MyGUI::newDelegate(this, &CompanionWindow::onItemSelected); + mFilterEdit->eventEditTextChange += MyGUI::newDelegate(this, &CompanionWindow::onNameFilterChanged); + + mCloseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CompanionWindow::onCloseButtonClicked); + + setCoord(200, 0, 600, 300); } - const ItemStack& item = mSortModel->getItem(index); - - // We can't take conjured items from a companion NPC - if (item.mFlags & ItemStack::Flag_Bound) + void CompanionWindow::onItemSelected(int index) { - MWBase::Environment::get().getWindowManager()->messageBox("#{sBarterDialog12}"); - return; - } + if (mDragAndDrop->mIsOnDragAndDrop) + { + mDragAndDrop->drop(mModel, mItemView); + updateEncumbranceBar(); + return; + } - MWWorld::Ptr object = item.mBase; - int count = item.mCount; - bool shift = MyGUI::InputManager::getInstance().isShiftPressed(); - if (MyGUI::InputManager::getInstance().isControlPressed()) - count = 1; + const ItemStack& item = mSortModel->getItem(index); - mSelectedItem = mSortModel->mapToSource(index); + // We can't take conjured items from a companion NPC + if (item.mFlags & ItemStack::Flag_Bound) + { + MWBase::Environment::get().getWindowManager()->messageBox("#{sBarterDialog12}"); + return; + } - if (count > 1 && !shift) - { - CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog(); - std::string name{object.getClass().getName(object)}; - name += MWGui::ToolTips::getSoulString(object.getCellRef()); - dialog->openCountDialog(name, "#{sTake}", count); - dialog->eventOkClicked.clear(); - dialog->eventOkClicked += MyGUI::newDelegate(this, &CompanionWindow::dragItem); + MWWorld::Ptr object = item.mBase; + int count = item.mCount; + bool shift = MyGUI::InputManager::getInstance().isShiftPressed(); + if (MyGUI::InputManager::getInstance().isControlPressed()) + count = 1; + + mSelectedItem = mSortModel->mapToSource(index); + + if (count > 1 && !shift) + { + CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog(); + std::string name{ object.getClass().getName(object) }; + name += MWGui::ToolTips::getSoulString(object.getCellRef()); + dialog->openCountDialog(name, "#{sTake}", count); + dialog->eventOkClicked.clear(); + dialog->eventOkClicked += MyGUI::newDelegate(this, &CompanionWindow::dragItem); + } + else + dragItem(nullptr, count); } - else - dragItem (nullptr, count); -} -void CompanionWindow::onNameFilterChanged(MyGUI::EditBox* _sender) + void CompanionWindow::onNameFilterChanged(MyGUI::EditBox* _sender) { mSortModel->setNameFilter(_sender->getCaption()); mItemView->update(); } -void CompanionWindow::dragItem(MyGUI::Widget* sender, int count) -{ - mDragAndDrop->startDrag(mSelectedItem, mSortModel, mModel, mItemView, count); -} + void CompanionWindow::dragItem(MyGUI::Widget* sender, int count) + { + mDragAndDrop->startDrag(mSelectedItem, mSortModel, mModel, mItemView, count); + } -void CompanionWindow::onBackgroundSelected() -{ - if (mDragAndDrop->mIsOnDragAndDrop) + void CompanionWindow::onBackgroundSelected() + { + if (mDragAndDrop->mIsOnDragAndDrop) + { + mDragAndDrop->drop(mModel, mItemView); + updateEncumbranceBar(); + } + } + + void CompanionWindow::setPtr(const MWWorld::Ptr& npc) { - mDragAndDrop->drop(mModel, mItemView); + mPtr = npc; updateEncumbranceBar(); + auto model = std::make_unique(npc); + mModel = model.get(); + auto sortModel = std::make_unique(std::move(model)); + mSortModel = sortModel.get(); + mFilterEdit->setCaption({}); + mItemView->setModel(std::move(sortModel)); + mItemView->resetScrollBars(); + + setTitle(npc.getClass().getName(npc)); } -} -void CompanionWindow::setPtr(const MWWorld::Ptr& npc) -{ - mPtr = npc; - updateEncumbranceBar(); - auto model = std::make_unique(npc); - mModel = model.get(); - auto sortModel = std::make_unique(std::move(model)); - mSortModel = sortModel.get(); - mFilterEdit->setCaption({}); - mItemView->setModel(std::move(sortModel)); - mItemView->resetScrollBars(); - - setTitle(npc.getClass().getName(npc)); -} + void CompanionWindow::onFrame(float dt) + { + checkReferenceAvailable(); + updateEncumbranceBar(); + } -void CompanionWindow::onFrame(float dt) -{ - checkReferenceAvailable(); - updateEncumbranceBar(); -} + void CompanionWindow::updateEncumbranceBar() + { + if (mPtr.isEmpty()) + return; + float capacity = mPtr.getClass().getCapacity(mPtr); + float encumbrance = mPtr.getClass().getEncumbrance(mPtr); + mEncumbranceBar->setValue(std::ceil(encumbrance), static_cast(capacity)); -void CompanionWindow::updateEncumbranceBar() -{ - if (mPtr.isEmpty()) - return; - float capacity = mPtr.getClass().getCapacity(mPtr); - float encumbrance = mPtr.getClass().getEncumbrance(mPtr); - mEncumbranceBar->setValue(std::ceil(encumbrance), static_cast(capacity)); + if (mModel && mModel->hasProfit(mPtr)) + { + mProfitLabel->setCaptionWithReplacing("#{sProfitValue} " + MyGUI::utility::toString(getProfit(mPtr))); + } + else + mProfitLabel->setCaption(""); + } - if (mModel && mModel->hasProfit(mPtr)) + void CompanionWindow::onCloseButtonClicked(MyGUI::Widget* _sender) { - mProfitLabel->setCaptionWithReplacing("#{sProfitValue} " + MyGUI::utility::toString(getProfit(mPtr))); + if (exit()) + MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Companion); } - else - mProfitLabel->setCaption(""); -} -void CompanionWindow::onCloseButtonClicked(MyGUI::Widget* _sender) -{ - if (exit()) - MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Companion); -} + bool CompanionWindow::exit() + { + if (mModel && mModel->hasProfit(mPtr) && getProfit(mPtr) < 0) + { + std::vector buttons; + buttons.emplace_back("#{sCompanionWarningButtonOne}"); + buttons.emplace_back("#{sCompanionWarningButtonTwo}"); + mMessageBoxManager->createInteractiveMessageBox("#{sCompanionWarningMessage}", buttons); + mMessageBoxManager->eventButtonPressed + += MyGUI::newDelegate(this, &CompanionWindow::onMessageBoxButtonClicked); + return false; + } + return true; + } -bool CompanionWindow::exit() -{ - if (mModel && mModel->hasProfit(mPtr) && getProfit(mPtr) < 0) + void CompanionWindow::onMessageBoxButtonClicked(int button) { - std::vector buttons; - buttons.emplace_back("#{sCompanionWarningButtonOne}"); - buttons.emplace_back("#{sCompanionWarningButtonTwo}"); - mMessageBoxManager->createInteractiveMessageBox("#{sCompanionWarningMessage}", buttons); - mMessageBoxManager->eventButtonPressed += MyGUI::newDelegate(this, &CompanionWindow::onMessageBoxButtonClicked); - return false; + if (button == 0) + { + MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Companion); + // Important for Calvus' contract script to work properly + MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode(); + } } - return true; -} -void CompanionWindow::onMessageBoxButtonClicked(int button) -{ - if (button == 0) + void CompanionWindow::onReferenceUnavailable() { MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Companion); - // Important for Calvus' contract script to work properly - MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode(); } -} - -void CompanionWindow::onReferenceUnavailable() -{ - MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Companion); -} - -void CompanionWindow::resetReference() -{ - ReferenceInterface::resetReference(); - mItemView->setModel(nullptr); - mModel = nullptr; - mSortModel = nullptr; -} + void CompanionWindow::resetReference() + { + ReferenceInterface::resetReference(); + mItemView->setModel(nullptr); + mModel = nullptr; + mSortModel = nullptr; + } } diff --git a/apps/openmw/mwgui/companionwindow.hpp b/apps/openmw/mwgui/companionwindow.hpp index 7a7c92e3dc..40fac26eb5 100644 --- a/apps/openmw/mwgui/companionwindow.hpp +++ b/apps/openmw/mwgui/companionwindow.hpp @@ -1,8 +1,8 @@ #ifndef OPENMW_MWGUI_COMPANIONWINDOW_H #define OPENMW_MWGUI_COMPANIONWINDOW_H -#include "windowbase.hpp" #include "referenceinterface.hpp" +#include "windowbase.hpp" namespace MWGui { @@ -27,7 +27,7 @@ namespace MWGui void resetReference() override; void setPtr(const MWWorld::Ptr& npc) override; - void onFrame (float dt) override; + void onFrame(float dt) override; void clear() override { resetReference(); } private: diff --git a/apps/openmw/mwgui/confirmationdialog.cpp b/apps/openmw/mwgui/confirmationdialog.cpp index 9ebaf3919f..48b209f17e 100644 --- a/apps/openmw/mwgui/confirmationdialog.cpp +++ b/apps/openmw/mwgui/confirmationdialog.cpp @@ -8,8 +8,8 @@ namespace MWGui { - ConfirmationDialog::ConfirmationDialog() : - WindowModal("openmw_confirmation_dialog.layout") + ConfirmationDialog::ConfirmationDialog() + : WindowModal("openmw_confirmation_dialog.layout") { getWidget(mMessage, "Message"); getWidget(mOkButton, "OkButton"); diff --git a/apps/openmw/mwgui/confirmationdialog.hpp b/apps/openmw/mwgui/confirmationdialog.hpp index 2acefd54c1..649e8ba1eb 100644 --- a/apps/openmw/mwgui/confirmationdialog.hpp +++ b/apps/openmw/mwgui/confirmationdialog.hpp @@ -7,26 +7,26 @@ namespace MWGui { class ConfirmationDialog : public WindowModal { - public: - ConfirmationDialog(); - void askForConfirmation(const std::string& message); - bool exit() override; - - typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void; - - /** Event : Ok button was clicked.\n - signature : void method()\n - */ - EventHandle_Void eventOkClicked; - EventHandle_Void eventCancelClicked; - - private: - MyGUI::EditBox* mMessage; - MyGUI::Button* mOkButton; - MyGUI::Button* mCancelButton; - - void onCancelButtonClicked(MyGUI::Widget* _sender); - void onOkButtonClicked(MyGUI::Widget* _sender); + public: + ConfirmationDialog(); + void askForConfirmation(const std::string& message); + bool exit() override; + + typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void; + + /** Event : Ok button was clicked.\n + signature : void method()\n + */ + EventHandle_Void eventOkClicked; + EventHandle_Void eventCancelClicked; + + private: + MyGUI::EditBox* mMessage; + MyGUI::Button* mOkButton; + MyGUI::Button* mCancelButton; + + void onCancelButtonClicked(MyGUI::Widget* _sender); + void onOkButtonClicked(MyGUI::Widget* _sender); }; } diff --git a/apps/openmw/mwgui/console.cpp b/apps/openmw/mwgui/console.cpp index 65ac17cea2..7a89227030 100644 --- a/apps/openmw/mwgui/console.cpp +++ b/apps/openmw/mwgui/console.cpp @@ -10,61 +10,59 @@ #include #include #include -#include #include +#include #include #include "../mwscript/extensions.hpp" #include "../mwscript/interpretercontext.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/luamanager.hpp" #include "../mwbase/scriptmanager.hpp" #include "../mwbase/windowmanager.hpp" #include "../mwbase/world.hpp" -#include "../mwbase/luamanager.hpp" -#include "../mwworld/esmstore.hpp" #include "../mwworld/class.hpp" +#include "../mwworld/esmstore.hpp" namespace MWGui { class ConsoleInterpreterContext : public MWScript::InterpreterContext { - Console& mConsole; - - public: + Console& mConsole; - ConsoleInterpreterContext (Console& console, MWWorld::Ptr reference); + public: + ConsoleInterpreterContext(Console& console, MWWorld::Ptr reference); - void report (const std::string& message) override; + void report(const std::string& message) override; }; - ConsoleInterpreterContext::ConsoleInterpreterContext (Console& console, - MWWorld::Ptr reference) - : MWScript::InterpreterContext ( - reference.isEmpty() ? nullptr : &reference.getRefData().getLocals(), reference), - mConsole (console) - {} + ConsoleInterpreterContext::ConsoleInterpreterContext(Console& console, MWWorld::Ptr reference) + : MWScript::InterpreterContext(reference.isEmpty() ? nullptr : &reference.getRefData().getLocals(), reference) + , mConsole(console) + { + } - void ConsoleInterpreterContext::report (const std::string& message) + void ConsoleInterpreterContext::report(const std::string& message) { - mConsole.printOK (message); + mConsole.printOK(message); } - bool Console::compile (const std::string& cmd, Compiler::Output& output) + bool Console::compile(const std::string& cmd, Compiler::Output& output) { try { ErrorHandler::reset(); - std::istringstream input (cmd + '\n'); + std::istringstream input(cmd + '\n'); - Compiler::Scanner scanner (*this, input, mCompilerContext.getExtensions()); + Compiler::Scanner scanner(*this, input, mCompilerContext.getExtensions()); - Compiler::LineParser parser (*this, mCompilerContext, output.getLocals(), - output.getLiterals(), output.getCode(), true); + Compiler::LineParser parser( + *this, mCompilerContext, output.getLocals(), output.getLiterals(), output.getCode(), true); - scanner.scan (parser); + scanner.scan(parser); return isGood(); } @@ -74,24 +72,24 @@ namespace MWGui } catch (const std::exception& error) { - printError (std::string ("Error: ") + error.what()); + printError(std::string("Error: ") + error.what()); } return false; } - void Console::report (const std::string& message, const Compiler::TokenLoc& loc, Type type) + void Console::report(const std::string& message, const Compiler::TokenLoc& loc, Type type) { std::ostringstream error; error << "column " << loc.mColumn << " (" << loc.mLiteral << "):"; - printError (error.str()); - printError ((type==ErrorMessage ? "error: " : "warning: ") + message); + printError(error.str()); + printError((type == ErrorMessage ? "error: " : "warning: ") + message); } - void Console::report (const std::string& message, Type type) + void Console::report(const std::string& message, Type type) { - printError ((type==ErrorMessage ? "error: " : "warning: ") + message); + printError((type == ErrorMessage ? "error: " : "warning: ") + message); } void Console::listNames() @@ -99,19 +97,18 @@ namespace MWGui if (mNames.empty()) { // keywords - std::istringstream input (""); + std::istringstream input(""); - Compiler::Scanner scanner (*this, input, mCompilerContext.getExtensions()); + Compiler::Scanner scanner(*this, input, mCompilerContext.getExtensions()); - scanner.listKeywords (mNames); + scanner.listKeywords(mNames); // identifier - const MWWorld::ESMStore& store = - MWBase::Environment::get().getWorld()->getStore(); + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); for (MWWorld::ESMStore::iterator it = store.begin(); it != store.end(); ++it) { - (*it)->listIdentifier (mNames); + (*it)->listIdentifier(mNames); } // exterior cell names aren't technically identifiers, but since the COC function accepts them, @@ -124,35 +121,33 @@ namespace MWGui } // sort - std::sort (mNames.begin(), mNames.end()); + std::sort(mNames.begin(), mNames.end()); // remove duplicates - mNames.erase( std::unique( mNames.begin(), mNames.end() ), mNames.end() ); + mNames.erase(std::unique(mNames.begin(), mNames.end()), mNames.end()); } } Console::Console(int w, int h, bool consoleOnlyScripts) - : WindowBase("openmw_console.layout"), - mCompilerContext (MWScript::CompilerContext::Type_Console), - mConsoleOnlyScripts (consoleOnlyScripts) + : WindowBase("openmw_console.layout") + , mCompilerContext(MWScript::CompilerContext::Type_Console) + , mConsoleOnlyScripts(consoleOnlyScripts) { - setCoord(10,10, w-10, h/2); + setCoord(10, 10, w - 10, h / 2); getWidget(mCommandLine, "edit_Command"); getWidget(mHistory, "list_History"); // Set up the command line box - mCommandLine->eventEditSelectAccept += - newDelegate(this, &Console::acceptCommand); - mCommandLine->eventKeyButtonPressed += - newDelegate(this, &Console::keyPress); + mCommandLine->eventEditSelectAccept += newDelegate(this, &Console::acceptCommand); + mCommandLine->eventKeyButtonPressed += newDelegate(this, &Console::keyPress); // Set up the log window mHistory->setOverflowToTheLeft(true); // compiler - Compiler::registerExtensions (mExtensions, mConsoleOnlyScripts); - mCompilerContext.setExtensions (&mExtensions); + Compiler::registerExtensions(mExtensions, mConsoleOnlyScripts); + mCompilerContext.setExtensions(&mExtensions); } void Console::onOpen() @@ -163,22 +158,22 @@ namespace MWGui MyGUI::LayerManager::getInstance().upLayerItem(mMainWidget); } - void Console::print(const std::string &msg, std::string_view color) + void Console::print(const std::string& msg, std::string_view color) { mHistory->addText(std::string(color) + MyGUI::TextIterator::toTagsString(msg)); } - void Console::printOK(const std::string &msg) + void Console::printOK(const std::string& msg) { print(msg + "\n", MWBase::WindowManager::sConsoleColor_Success); } - void Console::printError(const std::string &msg) + void Console::printError(const std::string& msg) { print(msg + "\n", MWBase::WindowManager::sConsoleColor_Error); } - void Console::execute (const std::string& command) + void Console::execute(const std::string& command) { // Log the command if (mConsoleMode.empty()) @@ -199,38 +194,38 @@ namespace MWGui if (!script.empty()) locals = MWBase::Environment::get().getScriptManager()->getLocals(script); } - Compiler::Output output (locals); + Compiler::Output output(locals); - if (compile (command + "\n", output)) + if (compile(command + "\n", output)) { try { - ConsoleInterpreterContext interpreterContext (*this, mPtr); + ConsoleInterpreterContext interpreterContext(*this, mPtr); Interpreter::Interpreter interpreter; - MWScript::installOpcodes (interpreter, mConsoleOnlyScripts); + MWScript::installOpcodes(interpreter, mConsoleOnlyScripts); std::vector code; - output.getCode (code); - interpreter.run (code.data(), code.size(), interpreterContext); + output.getCode(code); + interpreter.run(code.data(), code.size(), interpreterContext); } catch (const std::exception& error) { - printError (std::string ("Error: ") + error.what()); + printError(std::string("Error: ") + error.what()); } } } - void Console::executeFile (const std::string& path) + void Console::executeFile(const std::string& path) { - std::ifstream stream ((std::filesystem::path(path))); + std::ifstream stream((std::filesystem::path(path))); if (!stream.is_open()) - printError ("failed to open file: " + path); + printError("failed to open file: " + path); else { std::string line; - while (std::getline (stream, line)) - execute (line); + while (std::getline(stream, line)) + execute(line); } } @@ -244,24 +239,22 @@ namespace MWGui return c == ' ' || c == '\t'; } - void Console::keyPress(MyGUI::Widget* _sender, - MyGUI::KeyCode key, - MyGUI::Char _char) + void Console::keyPress(MyGUI::Widget* _sender, MyGUI::KeyCode key, MyGUI::Char _char) { - if(MyGUI::InputManager::getInstance().isControlPressed()) + if (MyGUI::InputManager::getInstance().isControlPressed()) { - if(key == MyGUI::KeyCode::W) + if (key == MyGUI::KeyCode::W) { const auto& caption = mCommandLine->getCaption(); - if(caption.empty()) + if (caption.empty()) return; size_t max = mCommandLine->getTextCursor(); - while(max > 0 && (isWhitespace(caption[max - 1]) || caption[max - 1] == '>')) + while (max > 0 && (isWhitespace(caption[max - 1]) || caption[max - 1] == '>')) max--; - while(max > 0 && !isWhitespace(caption[max - 1]) && caption[max - 1] != '>') + while (max > 0 && !isWhitespace(caption[max - 1]) && caption[max - 1] != '>') max--; size_t length = mCommandLine->getTextCursor() - max; - if(length > 0) + if (length > 0) { auto text = caption; text.erase(max, length); @@ -269,9 +262,9 @@ namespace MWGui mCommandLine->setTextCursor(max); } } - else if(key == MyGUI::KeyCode::U) + else if (key == MyGUI::KeyCode::U) { - if(mCommandLine->getTextCursor() > 0) + if (mCommandLine->getTextCursor() > 0) { auto text = mCommandLine->getCaption(); text.erase(0, mCommandLine->getTextCursor()); @@ -280,12 +273,12 @@ namespace MWGui } } } - else if(key == MyGUI::KeyCode::Tab && mConsoleMode.empty()) + else if (key == MyGUI::KeyCode::Tab && mConsoleMode.empty()) { std::vector matches; listNames(); std::string oldCaption = mCommandLine->getCaption(); - std::string newCaption = complete( mCommandLine->getOnlyText(), matches ); + std::string newCaption = complete(mCommandLine->getOnlyText(), matches); mCommandLine->setCaption(newCaption); // List candidates if repeatedly pressing tab @@ -293,9 +286,9 @@ namespace MWGui { int i = 0; printOK(""); - for(std::string& match : matches) + for (std::string& match : matches) { - if(i == 50) + if (i == 50) break; printOK(match); @@ -304,28 +297,29 @@ namespace MWGui } } - if(mCommandHistory.empty()) return; + if (mCommandHistory.empty()) + return; // Traverse history with up and down arrows - if(key == MyGUI::KeyCode::ArrowUp) + if (key == MyGUI::KeyCode::ArrowUp) { // If the user was editing a string, store it for later - if(mCurrent == mCommandHistory.end()) + if (mCurrent == mCommandHistory.end()) mEditString = mCommandLine->getOnlyText(); - if(mCurrent != mCommandHistory.begin()) + if (mCurrent != mCommandHistory.begin()) { --mCurrent; mCommandLine->setCaption(*mCurrent); } } - else if(key == MyGUI::KeyCode::ArrowDown) + else if (key == MyGUI::KeyCode::ArrowDown) { - if(mCurrent != mCommandHistory.end()) + if (mCurrent != mCommandHistory.end()) { ++mCurrent; - if(mCurrent != mCommandHistory.end()) + if (mCurrent != mCommandHistory.end()) mCommandLine->setCaption(*mCurrent); else // Restore the edit string @@ -336,8 +330,9 @@ namespace MWGui void Console::acceptCommand(MyGUI::EditBox* _sender) { - const std::string &cm = mCommandLine->getOnlyText(); - if(cm.empty()) return; + const std::string& cm = mCommandLine->getOnlyText(); + if (cm.empty()) + return; // Add the command to the history, and set the current pointer to // the end of the list @@ -348,14 +343,14 @@ namespace MWGui mHistory->setTextCursor(mHistory->getTextLength()); // Reset the command line before the command execution. - // It prevents the re-triggering of the acceptCommand() event for the same command + // It prevents the re-triggering of the acceptCommand() event for the same command // during the actual command execution mCommandLine->setCaption(""); - execute (cm); + execute(cm); } - std::string Console::complete( std::string input, std::vector &matches ) + std::string Console::complete(std::string input, std::vector& matches) { std::string output = input; std::string tmp = input; @@ -367,73 +362,87 @@ namespace MWGui size_t explicitPos = tmp.find("->"); if (explicitPos != std::string::npos) { - tmp.erase(0, explicitPos+2); + tmp.erase(0, explicitPos + 2); } /* Are there quotation marks? */ - if( tmp.find('"') != std::string::npos ) { - int numquotes=0; - for(std::string::iterator it=tmp.begin(); it < tmp.end(); ++it) { - if( *it == '"' ) + if (tmp.find('"') != std::string::npos) + { + int numquotes = 0; + for (std::string::iterator it = tmp.begin(); it < tmp.end(); ++it) + { + if (*it == '"') numquotes++; } /* Is it terminated?*/ - if( numquotes % 2 ) { - tmp.erase( 0, tmp.rfind('"')+1 ); + if (numquotes % 2) + { + tmp.erase(0, tmp.rfind('"') + 1); has_front_quote = true; } - else { + else + { size_t pos; - if( ( ((pos = tmp.rfind(' ')) != std::string::npos ) ) && ( pos > tmp.rfind('"') ) ) { - tmp.erase( 0, tmp.rfind(' ')+1); + if ((((pos = tmp.rfind(' ')) != std::string::npos)) && (pos > tmp.rfind('"'))) + { + tmp.erase(0, tmp.rfind(' ') + 1); } - else { + else + { tmp.clear(); } has_front_quote = false; } } /* No quotation marks. Are there spaces?*/ - else { + else + { size_t rpos; - if( (rpos=tmp.rfind(' ')) != std::string::npos ) { - if( rpos == 0 ) { + if ((rpos = tmp.rfind(' ')) != std::string::npos) + { + if (rpos == 0) + { tmp.clear(); } - else { - tmp.erase(0, rpos+1); + else + { + tmp.erase(0, rpos + 1); } } } /* Erase the input from the output string so we can easily append the completed form later. */ - output.erase(output.end()-tmp.length(), output.end()); + output.erase(output.end() - tmp.length(), output.end()); - /* Is there still something in the input string? If not just display all commands and return the unchanged input. */ - if( tmp.length() == 0 ) { - matches=mNames; + /* Is there still something in the input string? If not just display all commands and return the unchanged + * input. */ + if (tmp.length() == 0) + { + matches = mNames; return input; } /* Iterate through the vector. */ - for(std::string& name : mNames) + for (std::string& name : mNames) { - bool string_different=false; + bool string_different = false; /* Is the string shorter than the input string? If yes skip it. */ - if(name.length() < tmp.length()) + if (name.length() < tmp.length()) continue; /* Is the beginning of the string different from the input string? If yes skip it. */ - for( std::string::iterator iter=tmp.begin(), iter2=name.begin(); iter < tmp.end();++iter, ++iter2) { - if( Misc::StringUtils::toLower(*iter) != Misc::StringUtils::toLower(*iter2) ) { - string_different=true; + for (std::string::iterator iter = tmp.begin(), iter2 = name.begin(); iter < tmp.end(); ++iter, ++iter2) + { + if (Misc::StringUtils::toLower(*iter) != Misc::StringUtils::toLower(*iter2)) + { + string_different = true; break; } } - if( string_different ) + if (string_different) continue; /* The beginning of the string matches the input string, save it for the next test. */ @@ -441,23 +450,27 @@ namespace MWGui } /* There are no matches. Return the unchanged input. */ - if( matches.empty() ) + if (matches.empty()) { return input; } /* Only one match. We're done. */ - if( matches.size() == 1 ) { + if (matches.size() == 1) + { /* Adding quotation marks when the input string started with a quotation mark or has spaces in it*/ - if( ( matches.front().find(' ') != std::string::npos ) ) { - if( !has_front_quote ) + if ((matches.front().find(' ') != std::string::npos)) + { + if (!has_front_quote) output.append(std::string("\"")); return output.append(matches.front() + std::string("\" ")); } - else if( has_front_quote ) { - return output.append(matches.front() + std::string("\" ")); + else if (has_front_quote) + { + return output.append(matches.front() + std::string("\" ")); } - else { + else + { return output.append(matches.front() + std::string(" ")); } } @@ -465,11 +478,12 @@ namespace MWGui /* Check if all matching strings match further than input. If yes complete to this match. */ int i = tmp.length(); - for(std::string::iterator iter=matches.front().begin()+tmp.length(); iter < matches.front().end(); ++iter, ++i) + for (std::string::iterator iter = matches.front().begin() + tmp.length(); iter < matches.front().end(); + ++iter, ++i) { - for(std::string& match : matches) + for (std::string& match : matches) { - if(Misc::StringUtils::toLower(match[i]) != Misc::StringUtils::toLower(*iter)) + if (Misc::StringUtils::toLower(match[i]) != Misc::StringUtils::toLower(*iter)) { /* Append the longest match to the end of the output string*/ output.append(matches.front().substr(0, i)); @@ -484,7 +498,7 @@ namespace MWGui void Console::onResChange(int width, int height) { - setCoord(10, 10, width-10, height/2); + setCoord(10, 10, width - 10, height / 2); } void Console::updateSelectedObjectPtr(const MWWorld::Ptr& currentPtr, const MWWorld::Ptr& newPtr) diff --git a/apps/openmw/mwgui/console.hpp b/apps/openmw/mwgui/console.hpp index d90308d4e7..97c4c3e749 100644 --- a/apps/openmw/mwgui/console.hpp +++ b/apps/openmw/mwgui/console.hpp @@ -6,8 +6,8 @@ #include #include -#include #include +#include #include "../mwbase/windowmanager.hpp" @@ -20,86 +20,82 @@ namespace MWGui { class Console : public WindowBase, private Compiler::ErrorHandler, public ReferenceInterface { - public: - /// Set the implicit object for script execution - void setSelectedObject(const MWWorld::Ptr& object); - - MyGUI::EditBox* mCommandLine; - MyGUI::EditBox* mHistory; - - typedef std::list StringList; + public: + /// Set the implicit object for script execution + void setSelectedObject(const MWWorld::Ptr& object); - // History of previous entered commands - StringList mCommandHistory; - StringList::iterator mCurrent; - std::string mEditString; + MyGUI::EditBox* mCommandLine; + MyGUI::EditBox* mHistory; - Console(int w, int h, bool consoleOnlyScripts); + typedef std::list StringList; - void onOpen() override; + // History of previous entered commands + StringList mCommandHistory; + StringList::iterator mCurrent; + std::string mEditString; - void onResChange(int width, int height) override; + Console(int w, int h, bool consoleOnlyScripts); - // Print a message to the console, in specified color. - void print(const std::string &msg, std::string_view color = MWBase::WindowManager::sConsoleColor_Default); + void onOpen() override; - // These are pre-colored versions that you should use. + void onResChange(int width, int height) override; - /// Output from successful console command - void printOK(const std::string &msg); + // Print a message to the console, in specified color. + void print(const std::string& msg, std::string_view color = MWBase::WindowManager::sConsoleColor_Default); - /// Error message - void printError(const std::string &msg); + // These are pre-colored versions that you should use. - void execute (const std::string& command); + /// Output from successful console command + void printOK(const std::string& msg); - void executeFile (const std::string& path); + /// Error message + void printError(const std::string& msg); - void updateSelectedObjectPtr(const MWWorld::Ptr& currentPtr, const MWWorld::Ptr& newPtr); + void execute(const std::string& command); - void clear() override; + void executeFile(const std::string& path); - void resetReference () override; + void updateSelectedObjectPtr(const MWWorld::Ptr& currentPtr, const MWWorld::Ptr& newPtr); - const std::string& getConsoleMode() const { return mConsoleMode; } - void setConsoleMode(std::string_view mode); + void clear() override; - protected: + void resetReference() override; - void onReferenceUnavailable() override; + const std::string& getConsoleMode() const { return mConsoleMode; } + void setConsoleMode(std::string_view mode); - private: + protected: + void onReferenceUnavailable() override; - std::string mConsoleMode; + private: + std::string mConsoleMode; - void updateConsoleTitle(); + void updateConsoleTitle(); - void keyPress(MyGUI::Widget* _sender, - MyGUI::KeyCode key, - MyGUI::Char _char); + void keyPress(MyGUI::Widget* _sender, MyGUI::KeyCode key, MyGUI::Char _char); - void acceptCommand(MyGUI::EditBox* _sender); + void acceptCommand(MyGUI::EditBox* _sender); - std::string complete( std::string input, std::vector &matches ); + std::string complete(std::string input, std::vector& matches); - Compiler::Extensions mExtensions; - MWScript::CompilerContext mCompilerContext; - std::vector mNames; - bool mConsoleOnlyScripts; + Compiler::Extensions mExtensions; + MWScript::CompilerContext mCompilerContext; + std::vector mNames; + bool mConsoleOnlyScripts; - bool compile (const std::string& cmd, Compiler::Output& output); + bool compile(const std::string& cmd, Compiler::Output& output); - /// Report error to the user. - void report (const std::string& message, const Compiler::TokenLoc& loc, Type type) override; + /// Report error to the user. + void report(const std::string& message, const Compiler::TokenLoc& loc, Type type) override; - /// Report a file related error - void report (const std::string& message, Type type) override; + /// Report a file related error + void report(const std::string& message, Type type) override; - /// Write all valid identifiers and keywords into mNames and sort them. - /// \note If mNames is not empty, this function is a no-op. - /// \note The list may contain duplicates (if a name is a keyword and an identifier at the same - /// time). - void listNames(); - }; + /// Write all valid identifiers and keywords into mNames and sort them. + /// \note If mNames is not empty, this function is a no-op. + /// \note The list may contain duplicates (if a name is a keyword and an identifier at the same + /// time). + void listNames(); + }; } #endif diff --git a/apps/openmw/mwgui/container.cpp b/apps/openmw/mwgui/container.cpp index ad23af4711..ecfadf3675 100644 --- a/apps/openmw/mwgui/container.cpp +++ b/apps/openmw/mwgui/container.cpp @@ -1,13 +1,13 @@ #include "container.hpp" -#include #include +#include #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" -#include "../mwbase/windowmanager.hpp" #include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/scriptmanager.hpp" +#include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" #include "../mwworld/class.hpp" #include "../mwworld/inventorystore.hpp" @@ -21,12 +21,12 @@ #include "countdialog.hpp" #include "inventorywindow.hpp" -#include "itemview.hpp" -#include "inventoryitemmodel.hpp" #include "containeritemmodel.hpp" -#include "sortfilteritemmodel.hpp" -#include "pickpocketitemmodel.hpp" #include "draganddrop.hpp" +#include "inventoryitemmodel.hpp" +#include "itemview.hpp" +#include "pickpocketitemmodel.hpp" +#include "sortfilteritemmodel.hpp" #include "tooltips.hpp" namespace MWGui @@ -48,11 +48,12 @@ namespace MWGui mItemView->eventBackgroundClicked += MyGUI::newDelegate(this, &ContainerWindow::onBackgroundSelected); mItemView->eventItemClicked += MyGUI::newDelegate(this, &ContainerWindow::onItemSelected); - mDisposeCorpseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onDisposeCorpseButtonClicked); + mDisposeCorpseButton->eventMouseButtonClick + += MyGUI::newDelegate(this, &ContainerWindow::onDisposeCorpseButtonClicked); mCloseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onCloseButtonClicked); mTakeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ContainerWindow::onTakeAllButtonClicked); - setCoord(200,0,600,300); + setCoord(200, 0, 600, 300); } void ContainerWindow::onItemSelected(int index) @@ -83,14 +84,14 @@ namespace MWGui if (count > 1 && !shift) { CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog(); - std::string name{object.getClass().getName(object)}; + std::string name{ object.getClass().getName(object) }; name += MWGui::ToolTips::getSoulString(object.getCellRef()); dialog->openCountDialog(name, "#{sTake}", count); dialog->eventOkClicked.clear(); dialog->eventOkClicked += MyGUI::newDelegate(this, &ContainerWindow::dragItem); } else - dragItem (nullptr, count); + dragItem(nullptr, count); } void ContainerWindow::dragItem(MyGUI::Widget* sender, int count) @@ -136,7 +137,7 @@ namespace MWGui { // we are stealing stuff model = std::make_unique(mPtr, std::make_unique(container), - !mPtr.getClass().getCreatureStats(mPtr).getKnockedDown()); + !mPtr.getClass().getCreatureStats(mPtr).getKnockedDown()); } else model = std::make_unique(container); @@ -190,7 +191,7 @@ namespace MWGui void ContainerWindow::onTakeAllButtonClicked(MyGUI::Widget* _sender) { - if(mDragAndDrop != nullptr && mDragAndDrop->mIsOnDragAndDrop) + if (mDragAndDrop != nullptr && mDragAndDrop->mIsOnDragAndDrop) return; MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCloseButton); @@ -204,7 +205,7 @@ namespace MWGui if (mPtr.getClass().hasInventoryStore(mPtr)) { MWWorld::InventoryStore& invStore = mPtr.getClass().getInventoryStore(mPtr); - for (size_t i=0; igetItemCount(); ++i) + for (size_t i = 0; i < mModel->getItemCount(); ++i) { const ItemStack& item = mModel->getItem(i); if (invStore.isEquipped(item.mBase) == false) @@ -216,9 +217,9 @@ namespace MWGui mModel->update(); - for (size_t i=0; igetItemCount(); ++i) + for (size_t i = 0; i < mModel->getItemCount(); ++i) { - if (i==0) + if (i == 0) { // play the sound of the first object MWWorld::Ptr item = mModel->getItem(i).mBase; @@ -237,9 +238,9 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container); } - void ContainerWindow::onDisposeCorpseButtonClicked(MyGUI::Widget *sender) + void ContainerWindow::onDisposeCorpseButtonClicked(MyGUI::Widget* sender) { - if(mDragAndDrop == nullptr || !mDragAndDrop->mIsOnDragAndDrop) + if (mDragAndDrop == nullptr || !mDragAndDrop->mIsOnDragAndDrop) { MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCloseButton); @@ -263,7 +264,7 @@ namespace MWGui std::string_view script = ptr.getClass().getScript(ptr); if (!script.empty() && MWBase::Environment::get().getWorld()->getScriptsEnabled()) { - MWScript::InterpreterContext interpreterContext (&ptr.getRefData().getLocals(), ptr); + MWScript::InterpreterContext interpreterContext(&ptr.getRefData().getLocals(), ptr); MWBase::Environment::get().getScriptManager()->run(script, interpreterContext); } @@ -274,14 +275,15 @@ namespace MWGui creatureMap.clear(); // Check if we are a summon and inform our master we've bit the dust - for(const auto& package : creatureStats.getAiSequence()) + for (const auto& package : creatureStats.getAiSequence()) { - if(package->followTargetThroughDoors() && !package->getTarget().isEmpty()) + if (package->followTargetThroughDoors() && !package->getTarget().isEmpty()) { const auto& summoner = package->getTarget(); auto& summons = summoner.getClass().getCreatureStats(summoner).getSummonedCreatureMap(); - auto it = std::find_if(summons.begin(), summons.end(), [&] (const auto& entry) { return entry.second == creatureStats.getActorId(); }); - if(it != summons.end()) + auto it = std::find_if(summons.begin(), summons.end(), + [&](const auto& entry) { return entry.second == creatureStats.getActorId(); }); + if (it != summons.end()) { auto summon = *it; summons.erase(it); @@ -304,14 +306,14 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container); } - bool ContainerWindow::onTakeItem(const ItemStack &item, int count) + bool ContainerWindow::onTakeItem(const ItemStack& item, int count) { return mModel->onTakeItem(item.mBase, count); } void ContainerWindow::onDeleteCustomData(const MWWorld::Ptr& ptr) { - if(mModel && mModel->usesContainer(ptr)) + if (mModel && mModel->usesContainer(ptr)) MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Container); } } diff --git a/apps/openmw/mwgui/container.hpp b/apps/openmw/mwgui/container.hpp index 66a20e7ef5..7c625c488f 100644 --- a/apps/openmw/mwgui/container.hpp +++ b/apps/openmw/mwgui/container.hpp @@ -1,8 +1,8 @@ #ifndef MGUI_CONTAINER_H #define MGUI_CONTAINER_H -#include "windowbase.hpp" #include "referenceinterface.hpp" +#include "windowbase.hpp" #include "itemmodel.hpp" @@ -19,7 +19,6 @@ namespace MWGui class SortFilterItemModel; } - namespace MWGui { class ContainerWindow : public WindowBase, public ReferenceInterface @@ -38,6 +37,7 @@ namespace MWGui void onDeleteCustomData(const MWWorld::Ptr& ptr) override; void treatNextOpenAsLoot() { mTreatNextOpenAsLoot = true; }; + private: DragAndDrop* mDragAndDrop; diff --git a/apps/openmw/mwgui/containeritemmodel.cpp b/apps/openmw/mwgui/containeritemmodel.cpp index 9f202108a2..73a8d2bc2c 100644 --- a/apps/openmw/mwgui/containeritemmodel.cpp +++ b/apps/openmw/mwgui/containeritemmodel.cpp @@ -2,11 +2,11 @@ #include -#include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/actorutil.hpp" +#include "../mwmechanics/creaturestats.hpp" -#include "../mwworld/containerstore.hpp" #include "../mwworld/class.hpp" +#include "../mwworld/containerstore.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/mechanicsmanager.hpp" @@ -16,15 +16,14 @@ namespace { - bool stacks (const MWWorld::Ptr& left, const MWWorld::Ptr& right) + bool stacks(const MWWorld::Ptr& left, const MWWorld::Ptr& right) { if (left == right) return true; // If one of the items is in an inventory and currently equipped, we need to check stacking both ways to be sure if (left.getContainerStore() && right.getContainerStore()) - return left.getContainerStore()->stacks(left, right) - && right.getContainerStore()->stacks(left, right); + return left.getContainerStore()->stacks(left, right) && right.getContainerStore()->stacks(left, right); if (left.getContainerStore()) return left.getContainerStore()->stacks(left, right); @@ -39,134 +38,158 @@ namespace namespace MWGui { -ContainerItemModel::ContainerItemModel(const std::vector& itemSources, const std::vector& worldItems) - : mWorldItems(worldItems) - , mTrading(true) -{ - assert (!itemSources.empty()); - // Tie resolution lifetimes to the ItemModel - mItemSources.reserve(itemSources.size()); - for(const MWWorld::Ptr& source : itemSources) + ContainerItemModel::ContainerItemModel( + const std::vector& itemSources, const std::vector& worldItems) + : mWorldItems(worldItems) + , mTrading(true) + { + assert(!itemSources.empty()); + // Tie resolution lifetimes to the ItemModel + mItemSources.reserve(itemSources.size()); + for (const MWWorld::Ptr& source : itemSources) + { + MWWorld::ContainerStore& store = source.getClass().getContainerStore(source); + mItemSources.emplace_back(source, store.resolveTemporarily()); + } + } + + ContainerItemModel::ContainerItemModel(const MWWorld::Ptr& source) + : mTrading(false) { MWWorld::ContainerStore& store = source.getClass().getContainerStore(source); mItemSources.emplace_back(source, store.resolveTemporarily()); } -} - -ContainerItemModel::ContainerItemModel (const MWWorld::Ptr& source) : mTrading(false) -{ - MWWorld::ContainerStore& store = source.getClass().getContainerStore(source); - mItemSources.emplace_back(source, store.resolveTemporarily()); -} - -bool ContainerItemModel::allowedToUseItems() const -{ - if (mItemSources.empty()) - return true; - - MWWorld::Ptr ptr = MWMechanics::getPlayer(); - MWWorld::Ptr victim; - // Check if the player is allowed to use items from opened container - MWBase::MechanicsManager* mm = MWBase::Environment::get().getMechanicsManager(); - return mm->isAllowedToUse(ptr, mItemSources[0].first, victim); -} + bool ContainerItemModel::allowedToUseItems() const + { + if (mItemSources.empty()) + return true; -ItemStack ContainerItemModel::getItem (ModelIndex index) -{ - if (index < 0) - throw std::runtime_error("Invalid index supplied"); - if (mItems.size() <= static_cast(index)) - throw std::runtime_error("Item index out of range"); - return mItems[index]; -} + MWWorld::Ptr ptr = MWMechanics::getPlayer(); + MWWorld::Ptr victim; -size_t ContainerItemModel::getItemCount() -{ - return mItems.size(); -} + // Check if the player is allowed to use items from opened container + MWBase::MechanicsManager* mm = MWBase::Environment::get().getMechanicsManager(); + return mm->isAllowedToUse(ptr, mItemSources[0].first, victim); + } -ItemModel::ModelIndex ContainerItemModel::getIndex (const ItemStack& item) -{ - size_t i = 0; - for (ItemStack& itemStack : mItems) + ItemStack ContainerItemModel::getItem(ModelIndex index) { - if (itemStack == item) - return i; - ++i; + if (index < 0) + throw std::runtime_error("Invalid index supplied"); + if (mItems.size() <= static_cast(index)) + throw std::runtime_error("Item index out of range"); + return mItems[index]; } - return -1; -} -MWWorld::Ptr ContainerItemModel::copyItem (const ItemStack& item, size_t count, bool allowAutoEquip) -{ - auto& source = mItemSources[0]; - MWWorld::ContainerStore& store = source.first.getClass().getContainerStore(source.first); - if (item.mBase.getContainerStore() == &store) - throw std::runtime_error("Item to copy needs to be from a different container!"); - return *store.add(item.mBase, count, source.first, allowAutoEquip); -} + size_t ContainerItemModel::getItemCount() + { + return mItems.size(); + } -void ContainerItemModel::removeItem (const ItemStack& item, size_t count) -{ - int toRemove = count; + ItemModel::ModelIndex ContainerItemModel::getIndex(const ItemStack& item) + { + size_t i = 0; + for (ItemStack& itemStack : mItems) + { + if (itemStack == item) + return i; + ++i; + } + return -1; + } - for (auto& source : mItemSources) + MWWorld::Ptr ContainerItemModel::copyItem(const ItemStack& item, size_t count, bool allowAutoEquip) { + auto& source = mItemSources[0]; MWWorld::ContainerStore& store = source.first.getClass().getContainerStore(source.first); + if (item.mBase.getContainerStore() == &store) + throw std::runtime_error("Item to copy needs to be from a different container!"); + return *store.add(item.mBase, count, source.first, allowAutoEquip); + } + + void ContainerItemModel::removeItem(const ItemStack& item, size_t count) + { + int toRemove = count; + + for (auto& source : mItemSources) + { + MWWorld::ContainerStore& store = source.first.getClass().getContainerStore(source.first); - for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it) + for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it) + { + if (stacks(*it, item.mBase)) + { + int quantity = it->mRef->mData.getCount(false); + // If this is a restocking quantity, just don't remove it + if (quantity < 0 && mTrading) + toRemove += quantity; + else + toRemove -= store.remove(*it, toRemove, source.first); + if (toRemove <= 0) + return; + } + } + } + for (MWWorld::Ptr& source : mWorldItems) { - if (stacks(*it, item.mBase)) + if (stacks(source, item.mBase)) { - int quantity = it->mRef->mData.getCount(false); - // If this is a restocking quantity, just don't remove it - if(quantity < 0 && mTrading) - toRemove += quantity; + int refCount = source.getRefData().getCount(); + if (refCount - toRemove <= 0) + MWBase::Environment::get().getWorld()->deleteObject(source); else - toRemove -= store.remove(*it, toRemove, source.first); + source.getRefData().setCount(std::max(0, refCount - toRemove)); + toRemove -= refCount; if (toRemove <= 0) return; } } + + throw std::runtime_error("Not enough items to remove could be found"); } - for (MWWorld::Ptr& source : mWorldItems) + + void ContainerItemModel::update() { - if (stacks(source, item.mBase)) + mItems.clear(); + for (auto& source : mItemSources) { - int refCount = source.getRefData().getCount(); - if (refCount - toRemove <= 0) - MWBase::Environment::get().getWorld()->deleteObject(source); - else - source.getRefData().setCount(std::max(0, refCount - toRemove)); - toRemove -= refCount; - if (toRemove <= 0) - return; - } - } + MWWorld::ContainerStore& store = source.first.getClass().getContainerStore(source.first); - throw std::runtime_error("Not enough items to remove could be found"); -} + for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it) + { + if (!(*it).getClass().showsInInventory(*it)) + continue; -void ContainerItemModel::update() -{ - mItems.clear(); - for (auto& source : mItemSources) - { - MWWorld::ContainerStore& store = source.first.getClass().getContainerStore(source.first); + bool found = false; + for (ItemStack& itemStack : mItems) + { + if (stacks(*it, itemStack.mBase)) + { + // we already have an item stack of this kind, add to it + itemStack.mCount += it->getRefData().getCount(); + found = true; + break; + } + } - for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it) + if (!found) + { + // no stack yet, create one + ItemStack newItem(*it, this, it->getRefData().getCount()); + mItems.push_back(newItem); + } + } + } + for (MWWorld::Ptr& source : mWorldItems) { - if (!(*it).getClass().showsInInventory(*it)) - continue; - bool found = false; for (ItemStack& itemStack : mItems) { - if (stacks(*it, itemStack.mBase)) + if (stacks(source, itemStack.mBase)) { // we already have an item stack of this kind, add to it - itemStack.mCount += it->getRefData().getCount(); + itemStack.mCount += source.getRefData().getCount(); found = true; break; } @@ -175,88 +198,65 @@ void ContainerItemModel::update() if (!found) { // no stack yet, create one - ItemStack newItem (*it, this, it->getRefData().getCount()); + ItemStack newItem(source, this, source.getRefData().getCount()); mItems.push_back(newItem); } } } - for (MWWorld::Ptr& source : mWorldItems) + bool ContainerItemModel::onDropItem(const MWWorld::Ptr& item, int count) { - bool found = false; - for (ItemStack& itemStack : mItems) + if (mItemSources.empty()) + return false; + + MWWorld::Ptr target = mItemSources[0].first; + + if (target.getType() != ESM::Container::sRecordId) + return true; + + // check container organic flag + MWWorld::LiveCellRef* ref = target.get(); + if (ref->mBase->mFlags & ESM::Container::Organic) { - if (stacks(source, itemStack.mBase)) - { - // we already have an item stack of this kind, add to it - itemStack.mCount += source.getRefData().getCount(); - found = true; - break; - } + MWBase::Environment::get().getWindowManager()->messageBox("#{sContentsMessage2}"); + return false; } - if (!found) + // check that we don't exceed container capacity + float weight = item.getClass().getWeight(item) * count; + if (target.getClass().getCapacity(target) < target.getClass().getEncumbrance(target) + weight) { - // no stack yet, create one - ItemStack newItem (source, this, source.getRefData().getCount()); - mItems.push_back(newItem); + MWBase::Environment::get().getWindowManager()->messageBox("#{sContentsMessage3}"); + return false; } - } -} -bool ContainerItemModel::onDropItem(const MWWorld::Ptr &item, int count) -{ - if (mItemSources.empty()) - return false; - MWWorld::Ptr target = mItemSources[0].first; - - if (target.getType() != ESM::Container::sRecordId) return true; - - // check container organic flag - MWWorld::LiveCellRef* ref = target.get(); - if (ref->mBase->mFlags & ESM::Container::Organic) - { - MWBase::Environment::get().getWindowManager()-> - messageBox("#{sContentsMessage2}"); - return false; } - // check that we don't exceed container capacity - float weight = item.getClass().getWeight(item) * count; - if (target.getClass().getCapacity(target) < target.getClass().getEncumbrance(target) + weight) + bool ContainerItemModel::onTakeItem(const MWWorld::Ptr& item, int count) { - MWBase::Environment::get().getWindowManager()->messageBox("#{sContentsMessage3}"); - return false; - } + if (mItemSources.empty()) + return false; - return true; -} + MWWorld::Ptr target = mItemSources[0].first; -bool ContainerItemModel::onTakeItem(const MWWorld::Ptr &item, int count) -{ - if (mItemSources.empty()) - return false; + // Looting a dead corpse is considered OK + if (target.getClass().isActor() && target.getClass().getCreatureStats(target).isDead()) + return true; - MWWorld::Ptr target = mItemSources[0].first; + MWWorld::Ptr player = MWMechanics::getPlayer(); + MWBase::Environment::get().getMechanicsManager()->itemTaken(player, item, target, count); - // Looting a dead corpse is considered OK - if (target.getClass().isActor() && target.getClass().getCreatureStats(target).isDead()) return true; + } - MWWorld::Ptr player = MWMechanics::getPlayer(); - MWBase::Environment::get().getMechanicsManager()->itemTaken(player, item, target, count); - - return true; -} - -bool ContainerItemModel::usesContainer(const MWWorld::Ptr& container) -{ - for(const auto& source : mItemSources) + bool ContainerItemModel::usesContainer(const MWWorld::Ptr& container) { - if(source.first == container) - return true; + for (const auto& source : mItemSources) + { + if (source.first == container) + return true; + } + return false; } - return false; -} } diff --git a/apps/openmw/mwgui/containeritemmodel.hpp b/apps/openmw/mwgui/containeritemmodel.hpp index 11fed06913..1bdcec90f9 100644 --- a/apps/openmw/mwgui/containeritemmodel.hpp +++ b/apps/openmw/mwgui/containeritemmodel.hpp @@ -16,23 +16,24 @@ namespace MWGui class ContainerItemModel : public ItemModel { public: - ContainerItemModel (const std::vector& itemSources, const std::vector& worldItems); - ///< @note The order of elements \a itemSources matters here. The first element has the highest priority for removal, + ContainerItemModel(const std::vector& itemSources, const std::vector& worldItems); + ///< @note The order of elements \a itemSources matters here. The first element has the highest priority for + ///< removal, /// while the last element will be used to add new items to. - ContainerItemModel (const MWWorld::Ptr& source); + ContainerItemModel(const MWWorld::Ptr& source); bool allowedToUseItems() const override; - bool onDropItem(const MWWorld::Ptr &item, int count) override; - bool onTakeItem(const MWWorld::Ptr &item, int count) override; + bool onDropItem(const MWWorld::Ptr& item, int count) override; + bool onTakeItem(const MWWorld::Ptr& item, int count) override; - ItemStack getItem (ModelIndex index) override; - ModelIndex getIndex (const ItemStack &item) override; + ItemStack getItem(ModelIndex index) override; + ModelIndex getIndex(const ItemStack& item) override; size_t getItemCount() override; - MWWorld::Ptr copyItem (const ItemStack& item, size_t count, bool allowAutoEquip = true) override; - void removeItem (const ItemStack& item, size_t count) override; + MWWorld::Ptr copyItem(const ItemStack& item, size_t count, bool allowAutoEquip = true) override; + void removeItem(const ItemStack& item, size_t count) override; void update() override; diff --git a/apps/openmw/mwgui/controllers.cpp b/apps/openmw/mwgui/controllers.cpp index f3932d3ce6..f024def39b 100644 --- a/apps/openmw/mwgui/controllers.cpp +++ b/apps/openmw/mwgui/controllers.cpp @@ -7,11 +7,9 @@ namespace MWGui { namespace Controllers { - void ControllerFollowMouse::prepareItem(MyGUI::Widget *_widget) - { - } + void ControllerFollowMouse::prepareItem(MyGUI::Widget* _widget) {} - bool ControllerFollowMouse::addTime(MyGUI::Widget *_widget, float _time) + bool ControllerFollowMouse::addTime(MyGUI::Widget* _widget, float _time) { _widget->setPosition(MyGUI::InputManager::getInstance().getMousePosition()); return true; diff --git a/apps/openmw/mwgui/controllers.hpp b/apps/openmw/mwgui/controllers.hpp index 416f104d9a..a9e5565187 100644 --- a/apps/openmw/mwgui/controllers.hpp +++ b/apps/openmw/mwgui/controllers.hpp @@ -1,8 +1,8 @@ #ifndef MWGUI_CONTROLLERS_H #define MWGUI_CONTROLLERS_H -#include #include +#include namespace MyGUI { @@ -10,16 +10,16 @@ namespace MyGUI } namespace MWGui::Controllers +{ + /// Automatically positions a widget below the mouse cursor. + class ControllerFollowMouse final : public MyGUI::ControllerItem { - /// Automatically positions a widget below the mouse cursor. - class ControllerFollowMouse final : public MyGUI::ControllerItem - { - MYGUI_RTTI_DERIVED( ControllerFollowMouse ) + MYGUI_RTTI_DERIVED(ControllerFollowMouse) - private: - bool addTime(MyGUI::Widget* _widget, float _time) override; - void prepareItem(MyGUI::Widget* _widget) override; - }; - } + private: + bool addTime(MyGUI::Widget* _widget, float _time) override; + void prepareItem(MyGUI::Widget* _widget) override; + }; +} #endif diff --git a/apps/openmw/mwgui/countdialog.cpp b/apps/openmw/mwgui/countdialog.cpp index baf3a43abd..86d6402c88 100644 --- a/apps/openmw/mwgui/countdialog.cpp +++ b/apps/openmw/mwgui/countdialog.cpp @@ -1,8 +1,8 @@ #include "countdialog.hpp" #include -#include #include +#include #include @@ -11,8 +11,8 @@ namespace MWGui { - CountDialog::CountDialog() : - WindowModal("openmw_count_window.layout") + CountDialog::CountDialog() + : WindowModal("openmw_count_window.layout") { getWidget(mSlider, "CountSlider"); getWidget(mItemEdit, "ItemEdit"); @@ -41,15 +41,13 @@ namespace MWGui mItemText->setCaption(item); int width = std::max(mItemText->getTextSize().width + 128, 320); - setCoord(viewSize.width/2 - width/2, - viewSize.height/2 - mMainWidget->getHeight()/2, - width, - mMainWidget->getHeight()); + setCoord(viewSize.width / 2 - width / 2, viewSize.height / 2 - mMainWidget->getHeight() / 2, width, + mMainWidget->getHeight()); // by default, the text edit field has the focus of the keyboard MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mItemEdit); - mSlider->setScrollPosition(maxCount-1); + mSlider->setScrollPosition(maxCount - 1); mItemEdit->setMinValue(1); mItemEdit->setMaxValue(maxCount); @@ -63,7 +61,7 @@ namespace MWGui void CountDialog::onOkButtonClicked(MyGUI::Widget* _sender) { - eventOkClicked(nullptr, mSlider->getScrollPosition()+1); + eventOkClicked(nullptr, mSlider->getScrollPosition() + 1); setVisible(false); } @@ -72,7 +70,7 @@ namespace MWGui // Enter key void CountDialog::onEnterKeyPressed(MyGUI::EditBox* _sender) { - eventOkClicked(nullptr, mSlider->getScrollPosition()+1); + eventOkClicked(nullptr, mSlider->getScrollPosition() + 1); setVisible(false); // To do not spam onEnterKeyPressed() again and again @@ -81,11 +79,11 @@ namespace MWGui void CountDialog::onEditValueChanged(int value) { - mSlider->setScrollPosition(value-1); + mSlider->setScrollPosition(value - 1); } void CountDialog::onSliderMoved(MyGUI::ScrollBar* _sender, size_t _position) { - mItemEdit->setValue(_position+1); + mItemEdit->setValue(_position + 1); } } diff --git a/apps/openmw/mwgui/countdialog.hpp b/apps/openmw/mwgui/countdialog.hpp index 766612f681..bbc6ed90ff 100644 --- a/apps/openmw/mwgui/countdialog.hpp +++ b/apps/openmw/mwgui/countdialog.hpp @@ -12,30 +12,30 @@ namespace MWGui { class CountDialog : public WindowModal { - public: - CountDialog(); - void openCountDialog(const std::string& item, const std::string& message, const int maxCount); - - typedef MyGUI::delegates::CMultiDelegate2 EventHandle_WidgetInt; - - /** Event : Ok button was clicked.\n - signature : void method(MyGUI::Widget* _sender, int _count)\n - */ - EventHandle_WidgetInt eventOkClicked; - - private: - MyGUI::ScrollBar* mSlider; - Gui::NumericEditBox* mItemEdit; - MyGUI::TextBox* mItemText; - MyGUI::TextBox* mLabelText; - MyGUI::Button* mOkButton; - MyGUI::Button* mCancelButton; - - void onCancelButtonClicked(MyGUI::Widget* _sender); - void onOkButtonClicked(MyGUI::Widget* _sender); - void onEditValueChanged(int value); - void onSliderMoved(MyGUI::ScrollBar* _sender, size_t _position); - void onEnterKeyPressed(MyGUI::EditBox* _sender); + public: + CountDialog(); + void openCountDialog(const std::string& item, const std::string& message, const int maxCount); + + typedef MyGUI::delegates::CMultiDelegate2 EventHandle_WidgetInt; + + /** Event : Ok button was clicked.\n + signature : void method(MyGUI::Widget* _sender, int _count)\n + */ + EventHandle_WidgetInt eventOkClicked; + + private: + MyGUI::ScrollBar* mSlider; + Gui::NumericEditBox* mItemEdit; + MyGUI::TextBox* mItemText; + MyGUI::TextBox* mLabelText; + MyGUI::Button* mOkButton; + MyGUI::Button* mCancelButton; + + void onCancelButtonClicked(MyGUI::Widget* _sender); + void onOkButtonClicked(MyGUI::Widget* _sender); + void onEditValueChanged(int value); + void onSliderMoved(MyGUI::ScrollBar* _sender, size_t _position); + void onEnterKeyPressed(MyGUI::EditBox* _sender); }; } diff --git a/apps/openmw/mwgui/cursor.cpp b/apps/openmw/mwgui/cursor.cpp index ed8a76eb87..7c95e2fd11 100644 --- a/apps/openmw/mwgui/cursor.cpp +++ b/apps/openmw/mwgui/cursor.cpp @@ -1,23 +1,20 @@ #include "cursor.hpp" -#include +#include #include +#include #include -#include namespace MWGui { - ResourceImageSetPointerFix::ResourceImageSetPointerFix() : mImageSet(nullptr) , mRotation(0) { } - ResourceImageSetPointerFix::~ResourceImageSetPointerFix() - { - } + ResourceImageSetPointerFix::~ResourceImageSetPointerFix() {} void ResourceImageSetPointerFix::deserialization(MyGUI::xml::ElementPtr _node, MyGUI::Version _version) { @@ -56,7 +53,7 @@ namespace MWGui _image->setCoord(_point.left - mPoint.left, _point.top - mPoint.top, mSize.width, mSize.height); } - MyGUI::ResourceImageSetPtr ResourceImageSetPointerFix:: getImageSet() + MyGUI::ResourceImageSetPtr ResourceImageSetPointerFix::getImageSet() { return mImageSet; } diff --git a/apps/openmw/mwgui/cursor.hpp b/apps/openmw/mwgui/cursor.hpp index 7e1f9adba9..b25db0ce06 100644 --- a/apps/openmw/mwgui/cursor.hpp +++ b/apps/openmw/mwgui/cursor.hpp @@ -9,12 +9,12 @@ namespace MWGui /// \brief Allows us to get the members of /// ResourceImageSetPointer that we need. - /// \example MyGUI::FactoryManager::getInstance().registerFactory("Resource", "ResourceImageSetPointer"); + /// \example MyGUI::FactoryManager::getInstance().registerFactory("Resource", + /// "ResourceImageSetPointer"); /// MyGUI::ResourceManager::getInstance().load("core.xml"); - class ResourceImageSetPointerFix final : - public MyGUI::IPointer + class ResourceImageSetPointerFix final : public MyGUI::IPointer { - MYGUI_RTTI_DERIVED( ResourceImageSetPointerFix ) + MYGUI_RTTI_DERIVED(ResourceImageSetPointerFix) public: ResourceImageSetPointerFix(); @@ -25,8 +25,8 @@ namespace MWGui void setImage(MyGUI::ImageBox* _image) override; void setPosition(MyGUI::ImageBox* _image, const MyGUI::IntPoint& _point) override; - //and now for the whole point of this class, allow us to get - //the hot spot, the image and the size of the cursor. + // and now for the whole point of this class, allow us to get + // the hot spot, the image and the size of the cursor. MyGUI::ResourceImageSetPtr getImageSet(); MyGUI::IntPoint getHotSpot(); MyGUI::IntSize getSize(); diff --git a/apps/openmw/mwgui/debugwindow.cpp b/apps/openmw/mwgui/debugwindow.cpp index 93f5fdb076..e02e3032f4 100644 --- a/apps/openmw/mwgui/debugwindow.cpp +++ b/apps/openmw/mwgui/debugwindow.cpp @@ -1,8 +1,8 @@ #include "debugwindow.hpp" +#include #include #include -#include #include #include @@ -20,47 +20,56 @@ namespace if (pit->Is_Done()) return; - float accumulated_time=0,parent_time = pit->Is_Root() ? CProfileManager::Get_Time_Since_Reset() : pit->Get_Current_Parent_Total_Time(); - int i,j; + float accumulated_time = 0, + parent_time + = pit->Is_Root() ? CProfileManager::Get_Time_Since_Reset() : pit->Get_Current_Parent_Total_Time(); + int i, j; int frames_since_reset = CProfileManager::Get_Frame_Count_Since_Reset(); - for (i=0;iGet_Current_Parent_Name())+" (total running time: "+MyGUI::utility::toString(parent_time,3)+" ms) ---\n"; + for (i = 0; i < spacing; i++) + os << "."; + std::string s = "Profiling: " + std::string(pit->Get_Current_Parent_Name()) + + " (total running time: " + MyGUI::utility::toString(parent_time, 3) + " ms) ---\n"; os << s; - //float totalTime = 0.f; + // float totalTime = 0.f; int numChildren = 0; - for (i = 0; !pit->Is_Done(); i++,pit->Next()) + for (i = 0; !pit->Is_Done(); i++, pit->Next()) { numChildren++; float current_total_time = pit->Get_Current_Total_Time(); accumulated_time += current_total_time; float fraction = parent_time > SIMD_EPSILON ? (current_total_time / parent_time) * 100 : 0.f; - for (j=0;jGet_Current_Name()+" ("+MyGUI::utility::toString(fraction,2)+" %) :: "+MyGUI::utility::toString(ms,3)+" ms / frame ("+MyGUI::utility::toString(pit->Get_Current_Total_Calls())+" calls)\n"; + s = MyGUI::utility::toString(i) + " -- " + pit->Get_Current_Name() + " (" + + MyGUI::utility::toString(fraction, 2) + " %) :: " + MyGUI::utility::toString(ms, 3) + " ms / frame (" + + MyGUI::utility::toString(pit->Get_Current_Total_Calls()) + " calls)\n"; os << s; - //totalTime += current_total_time; - //recurse into children + // totalTime += current_total_time; + // recurse into children } if (parent_time < accumulated_time) { os << "what's wrong\n"; } - for (i=0;i SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f; - s = "Unaccounted: ("+MyGUI::utility::toString(unaccounted,3)+" %) :: "+MyGUI::utility::toString(parent_time - accumulated_time,3)+" ms\n"; + for (i = 0; i < spacing; i++) + os << "."; + double unaccounted = parent_time > SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f; + s = "Unaccounted: (" + MyGUI::utility::toString(unaccounted, 3) + + " %) :: " + MyGUI::utility::toString(parent_time - accumulated_time, 3) + " ms\n"; os << s; - for (i=0;iEnter_Child(i); - bulletDumpRecursive(pit, spacing+3, os); + bulletDumpRecursive(pit, spacing + 3, os); pit->Enter_Parent(); } } @@ -93,15 +102,15 @@ namespace MWGui MyGUI::TabItem* itemLV = mTabControl->addItem("Log Viewer"); itemLV->setCaptionWithReplacing(" #{DebugMenu:LogViewer} "); - mLogView = itemLV->createWidgetReal - ("LogEdit", MyGUI::FloatCoord(0,0,1,1), MyGUI::Align::Stretch); + mLogView + = itemLV->createWidgetReal("LogEdit", MyGUI::FloatCoord(0, 0, 1, 1), MyGUI::Align::Stretch); mLogView->setEditReadOnly(true); #ifndef BT_NO_PROFILE MyGUI::TabItem* item = mTabControl->addItem("Physics Profiler"); item->setCaptionWithReplacing(" #{DebugMenu:PhysicsProfiler} "); - mBulletProfilerEdit = item->createWidgetReal - ("LogEdit", MyGUI::FloatCoord(0,0,1,1), MyGUI::Align::Stretch); + mBulletProfilerEdit + = item->createWidgetReal("LogEdit", MyGUI::FloatCoord(0, 0, 1, 1), MyGUI::Align::Stretch); #else mBulletProfilerEdit = nullptr; #endif @@ -115,32 +124,38 @@ namespace MWGui void DebugWindow::startLogRecording() { sLogCircularBuffer.resize(std::max(0, Settings::Manager::getInt64("log buffer size", "General"))); - Debug::setLogListener([](Debug::Level level, std::string_view prefix, std::string_view msg) - { + Debug::setLogListener([](Debug::Level level, std::string_view prefix, std::string_view msg) { if (sLogCircularBuffer.empty()) - return; // Log viewer is disabled. + return; // Log viewer is disabled. std::string_view color; switch (level) { - case Debug::Error: color = "#FF0000"; break; - case Debug::Warning: color = "#FFFF00"; break; - case Debug::Info: color = "#FFFFFF"; break; + case Debug::Error: + color = "#FF0000"; + break; + case Debug::Warning: + color = "#FFFF00"; + break; + case Debug::Info: + color = "#FFFFFF"; + break; case Debug::Verbose: - case Debug::Debug: color = "#666666"; break; - default: color = "#FFFFFF"; + case Debug::Debug: + color = "#666666"; + break; + default: + color = "#FFFFFF"; } bool bufferOverflow = false; std::lock_guard lock(sBufferMutex); const int64_t bufSize = sLogCircularBuffer.size(); - auto addChar = [&](char c) - { + auto addChar = [&](char c) { sLogCircularBuffer[sLogEndIndex++] = c; if (sLogEndIndex == bufSize) sLogEndIndex = 0; bufferOverflow = bufferOverflow || sLogEndIndex == sLogStartIndex; }; - auto addShieldedStr = [&](std::string_view s) - { + auto addShieldedStr = [&](std::string_view s) { for (char c : s) { addChar(c); @@ -164,7 +179,7 @@ namespace MWGui if (!mLogView || sLogCircularBuffer.empty() || sLogStartIndex == sLogEndIndex) return; if (mLogView->isTextSelection()) - return; // Don't change text while player is trying to copy something + return; // Don't change text while player is trying to copy something std::string addition; const int64_t bufSize = sLogCircularBuffer.size(); @@ -180,7 +195,7 @@ namespace MWGui } size_t scrollPos = mLogView->getVScrollPosition(); - bool scrolledToTheEnd = scrollPos+1 >= mLogView->getVScrollRange(); + bool scrolledToTheEnd = scrollPos + 1 >= mLogView->getVScrollRange(); int64_t newSizeEstimation = mLogView->getTextLength() + addition.size(); if (newSizeEstimation > bufSize) mLogView->eraseText(0, newSizeEstimation - bufSize); @@ -202,7 +217,7 @@ namespace MWGui size_t previousPos = mBulletProfilerEdit->getVScrollPosition(); mBulletProfilerEdit->setCaption(stream.str()); - mBulletProfilerEdit->setVScrollPosition(std::min(previousPos, mBulletProfilerEdit->getVScrollRange()-1)); + mBulletProfilerEdit->setVScrollPosition(std::min(previousPos, mBulletProfilerEdit->getVScrollRange() - 1)); #endif } diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index 03cd234fed..1b36e42992 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -1,30 +1,30 @@ #include "dialogue.hpp" +#include #include -#include #include #include -#include +#include #include -#include -#include -#include #include #include +#include +#include +#include +#include "../mwbase/dialoguemanager.hpp" #include "../mwbase/environment.hpp" -#include "../mwbase/windowmanager.hpp" #include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/windowmanager.hpp" #include "../mwbase/world.hpp" -#include "../mwbase/dialoguemanager.hpp" #include "../mwworld/class.hpp" #include "../mwworld/containerstore.hpp" #include "../mwworld/esmstore.hpp" -#include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/actorutil.hpp" +#include "../mwmechanics/creaturestats.hpp" #include "bookpage.hpp" #include "textcolours.hpp" @@ -96,17 +96,20 @@ namespace MWGui totalHeight += lineHeight; } - void PersuasionDialog::onCancel(MyGUI::Widget *sender) + void PersuasionDialog::onCancel(MyGUI::Widget* sender) { setVisible(false); } - void PersuasionDialog::onPersuade(MyGUI::Widget *sender) + void PersuasionDialog::onPersuade(MyGUI::Widget* sender) { MWBase::MechanicsManager::PersuasionType type; - if (sender == mAdmireButton) type = MWBase::MechanicsManager::PT_Admire; - else if (sender == mIntimidateButton) type = MWBase::MechanicsManager::PT_Intimidate; - else if (sender == mTauntButton) type = MWBase::MechanicsManager::PT_Taunt; + if (sender == mAdmireButton) + type = MWBase::MechanicsManager::PT_Admire; + else if (sender == mIntimidateButton) + type = MWBase::MechanicsManager::PT_Intimidate; + else if (sender == mTauntButton) + type = MWBase::MechanicsManager::PT_Taunt; else if (sender == mBribe10Button) type = MWBase::MechanicsManager::PT_Bribe10; else if (sender == mBribe100Button) @@ -127,9 +130,9 @@ namespace MWGui MWWorld::Ptr player = MWMechanics::getPlayer(); int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId); - mBribe10Button->setEnabled (playerGold >= 10); - mBribe100Button->setEnabled (playerGold >= 100); - mBribe1000Button->setEnabled (playerGold >= 1000); + mBribe10Button->setEnabled(playerGold >= 10); + mBribe100Button->setEnabled(playerGold >= 100); + mBribe1000Button->setEnabled(playerGold >= 1000); mGoldLabel->setCaptionWithReplacing("#{sGold}: " + MyGUI::utility::toString(playerGold)); @@ -149,13 +152,15 @@ namespace MWGui // -------------------------------------------------------------------------------------------------- - Response::Response(const std::string &text, const std::string &title, bool needMargin) - : mTitle(title), mNeedMargin(needMargin) + Response::Response(const std::string& text, const std::string& title, bool needMargin) + : mTitle(title) + , mNeedMargin(needMargin) { mText = text; } - void Response::write(BookTypesetter::Ptr typesetter, KeywordSearchT* keywordSearch, std::map>& topicLinks) const + void Response::write(BookTypesetter::Ptr typesetter, KeywordSearchT* keywordSearch, + std::map>& topicLinks) const { typesetter->sectionBreak(mNeedMargin ? 9 : 0); auto windowManager = MWBase::Environment::get().getWindowManager(); @@ -175,7 +180,7 @@ namespace MWGui std::string text = mText; size_t pos_end = std::string::npos; - for(;;) + for (;;) { size_t pos_begin = text.find('@'); if (pos_begin != std::string::npos) @@ -186,16 +191,18 @@ namespace MWGui std::string link = text.substr(pos_begin + 1, pos_end - pos_begin - 1); const char specialPseudoAsteriskCharacter = 127; std::replace(link.begin(), link.end(), specialPseudoAsteriskCharacter, '*'); - std::string topicName = Misc::StringUtils::lowerCase(windowManager->getTranslationDataStorage().topicStandardForm(link)); + std::string topicName + = Misc::StringUtils::lowerCase(windowManager->getTranslationDataStorage().topicStandardForm(link)); std::string displayName = link; - while (displayName[displayName.size()-1] == '*') - displayName.erase(displayName.size()-1, 1); + while (displayName[displayName.size() - 1] == '*') + displayName.erase(displayName.size() - 1, 1); - text.replace(pos_begin, pos_end+1-pos_begin, displayName); + text.replace(pos_begin, pos_end + 1 - pos_begin, displayName); if (topicLinks.find(topicName) != topicLinks.end()) - hyperLinks[std::make_pair(pos_begin, pos_begin+displayName.size())] = intptr_t(topicLinks[topicName].get()); + hyperLinks[std::make_pair(pos_begin, pos_begin + displayName.size())] + = intptr_t(topicLinks[topicName].get()); } else break; @@ -203,7 +210,8 @@ namespace MWGui typesetter->addContent(to_utf8_span(text.c_str())); - if (hyperLinks.size() && MWBase::Environment::get().getWindowManager()->getTranslationDataStorage().hasTranslation()) + if (hyperLinks.size() + && MWBase::Environment::get().getWindowManager()->getTranslationDataStorage().hasTranslation()) { const TextColours& textColours = MWBase::Environment::get().getWindowManager()->getTextColours(); @@ -212,9 +220,8 @@ namespace MWGui for (auto& hyperLink : hyperLinks) { intptr_t topicId = hyperLink.second; - BookTypesetter::Style* hotStyle = typesetter->createHotStyle (style, textColours.link, - textColours.linkOver, textColours.linkPressed, - topicId); + BookTypesetter::Style* hotStyle = typesetter->createHotStyle( + style, textColours.link, textColours.linkOver, textColours.linkPressed, topicId); if (formatted < hyperLink.first.first) typesetter->write(style, formatted, hyperLink.first.first); typesetter->write(hotStyle, hyperLink.first.first, hyperLink.first.second); @@ -228,18 +235,18 @@ namespace MWGui std::vector matches; keywordSearch->highlightKeywords(text.begin(), text.end(), matches); - std::string::const_iterator i = text.begin (); + std::string::const_iterator i = text.begin(); for (KeywordSearchT::Match& match : matches) { if (i != match.mBeg) - addTopicLink (typesetter, 0, i - text.begin (), match.mBeg - text.begin ()); + addTopicLink(typesetter, 0, i - text.begin(), match.mBeg - text.begin()); - addTopicLink (typesetter, match.mValue, match.mBeg - text.begin (), match.mEnd - text.begin ()); + addTopicLink(typesetter, match.mValue, match.mBeg - text.begin(), match.mEnd - text.begin()); i = match.mEnd; } - if (i != text.end ()) - addTopicLink (typesetter, 0, i - text.begin (), text.size ()); + if (i != text.end()) + addTopicLink(typesetter, 0, i - text.begin(), text.size()); } } @@ -249,10 +256,10 @@ namespace MWGui BookTypesetter::Style* style = typesetter->createStyle("", textColours.normal, false); - if (topicId) - style = typesetter->createHotStyle (style, textColours.link, textColours.linkOver, textColours.linkPressed, topicId); - typesetter->write (style, begin, end); + style = typesetter->createHotStyle( + style, textColours.link, textColours.linkOver, textColours.linkPressed, topicId); + typesetter->write(style, begin, end); } Message::Message(const std::string& text) @@ -260,7 +267,8 @@ namespace MWGui mText = text; } - void Message::write(BookTypesetter::Ptr typesetter, KeywordSearchT* keywordSearch, std::map>& topicLinks) const + void Message::write(BookTypesetter::Ptr typesetter, KeywordSearchT* keywordSearch, + std::map>& topicLinks) const { const MyGUI::Colour& textColour = MWBase::Environment::get().getWindowManager()->getTextColours().notify; BookTypesetter::Style* title = typesetter->createStyle("", textColour, false); @@ -303,10 +311,10 @@ namespace MWGui mPersuasionDialog.setVisible(false); - //History view + // History view getWidget(mHistory, "History"); - //Topics list + // Topics list getWidget(mTopicsList, "TopicsList"); mTopicsList->eventItemSelected += MyGUI::newDelegate(this, &DialogueWindow::onSelectListItem); @@ -314,16 +322,17 @@ namespace MWGui mGoodbyeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &DialogueWindow::onByeClicked); getWidget(mDispositionBar, "Disposition"); - getWidget(mDispositionText,"DispositionText"); + getWidget(mDispositionText, "DispositionText"); getWidget(mScrollBar, "VScroll"); mScrollBar->eventScrollChangePosition += MyGUI::newDelegate(this, &DialogueWindow::onScrollbarMoved); mHistory->eventMouseWheel += MyGUI::newDelegate(this, &DialogueWindow::onMouseWheel); - BookPage::ClickCallback callback = std::bind (&DialogueWindow::notifyLinkClicked, this, std::placeholders::_1); + BookPage::ClickCallback callback = std::bind(&DialogueWindow::notifyLinkClicked, this, std::placeholders::_1); mHistory->adviseLinkClicked(callback); - mMainWidget->castType()->eventWindowChangeCoord += MyGUI::newDelegate(this, &DialogueWindow::onWindowResize); + mMainWidget->castType()->eventWindowChangeCoord + += MyGUI::newDelegate(this, &DialogueWindow::onWindowResize); } void DialogueWindow::onTradeComplete() @@ -349,7 +358,8 @@ namespace MWGui void DialogueWindow::onWindowResize(MyGUI::Window* _sender) { // if the window has only been moved, not resized, we don't need to update - if (mCurrentWindowSize == _sender->getSize()) return; + if (mCurrentWindowSize == _sender->getSize()) + return; mTopicsList->adjustSize(); updateHistory(); @@ -361,7 +371,8 @@ namespace MWGui { if (!mScrollBar->getVisible()) return; - mScrollBar->setScrollPosition(std::clamp(mScrollBar->getScrollPosition() - _rel*0.3, 0, mScrollBar->getScrollRange() - 1)); + mScrollBar->setScrollPosition( + std::clamp(mScrollBar->getScrollPosition() - _rel * 0.3, 0, mScrollBar->getScrollRange() - 1)); onScrollbarMoved(mScrollBar, mScrollBar->getScrollPosition()); } @@ -380,7 +391,8 @@ namespace MWGui if (mGoodbye || dialogueManager->isInChoice()) return; - const MWWorld::Store &gmst = MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& gmst + = MWBase::Environment::get().getWorld()->getStore().get(); const std::string& sPersuasion = gmst.find("sPersuasion")->mValue.getString(); const std::string& sCompanionShare = gmst.find("sCompanionShare")->mValue.getString(); @@ -392,9 +404,9 @@ namespace MWGui const std::string& sServiceTrainingTitle = gmst.find("sServiceTrainingTitle")->mValue.getString(); const std::string& sRepair = gmst.find("sRepair")->mValue.getString(); - if (topic != sPersuasion && topic != sCompanionShare && topic != sBarter - && topic != sSpells && topic != sTravel && topic != sSpellMakingMenuTitle - && topic != sEnchanting && topic != sServiceTrainingTitle && topic != sRepair) + if (topic != sPersuasion && topic != sCompanionShare && topic != sBarter && topic != sSpells && topic != sTravel + && topic != sSpellMakingMenuTitle && topic != sEnchanting && topic != sServiceTrainingTitle + && topic != sRepair) { onTopicActivated(topic); if (mGoodbyeButton->getEnabled()) @@ -406,19 +418,26 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Companion, mPtr); else if (!dialogueManager->checkServiceRefused(mCallback.get())) { - if (topic == sBarter && !dialogueManager->checkServiceRefused(mCallback.get(), MWBase::DialogueManager::Barter)) + if (topic == sBarter + && !dialogueManager->checkServiceRefused(mCallback.get(), MWBase::DialogueManager::Barter)) MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Barter, mPtr); - else if (topic == sSpells && !dialogueManager->checkServiceRefused(mCallback.get(), MWBase::DialogueManager::Spells)) + else if (topic == sSpells + && !dialogueManager->checkServiceRefused(mCallback.get(), MWBase::DialogueManager::Spells)) MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_SpellBuying, mPtr); - else if (topic == sTravel && !dialogueManager->checkServiceRefused(mCallback.get(), MWBase::DialogueManager::Travel)) + else if (topic == sTravel + && !dialogueManager->checkServiceRefused(mCallback.get(), MWBase::DialogueManager::Travel)) MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Travel, mPtr); - else if (topic == sSpellMakingMenuTitle && !dialogueManager->checkServiceRefused(mCallback.get(), MWBase::DialogueManager::Spellmaking)) + else if (topic == sSpellMakingMenuTitle + && !dialogueManager->checkServiceRefused(mCallback.get(), MWBase::DialogueManager::Spellmaking)) MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_SpellCreation, mPtr); - else if (topic == sEnchanting && !dialogueManager->checkServiceRefused(mCallback.get(), MWBase::DialogueManager::Enchanting)) + else if (topic == sEnchanting + && !dialogueManager->checkServiceRefused(mCallback.get(), MWBase::DialogueManager::Enchanting)) MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Enchanting, mPtr); - else if (topic == sServiceTrainingTitle && !dialogueManager->checkServiceRefused(mCallback.get(), MWBase::DialogueManager::Training)) + else if (topic == sServiceTrainingTitle + && !dialogueManager->checkServiceRefused(mCallback.get(), MWBase::DialogueManager::Training)) MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Training, mPtr); - else if (topic == sRepair && !dialogueManager->checkServiceRefused(mCallback.get(), MWBase::DialogueManager::Repair)) + else if (topic == sRepair + && !dialogueManager->checkServiceRefused(mCallback.get(), MWBase::DialogueManager::Repair)) MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_MerchantRepair, mPtr); } else @@ -440,7 +459,8 @@ namespace MWGui mKeywords.clear(); mTopicsList->clear(); for (auto& link : mLinks) - mDeleteLater.push_back(std::move(link)); // Links are not deleted right away to prevent issues with event handlers + mDeleteLater.push_back( + std::move(link)); // Links are not deleted right away to prevent issues with event handlers mLinks.clear(); } @@ -472,8 +492,13 @@ namespace MWGui void DialogueWindow::restock() { - MWMechanics::CreatureStats &sellerStats = mPtr.getClass().getCreatureStats(mPtr); - float delay = MWBase::Environment::get().getWorld()->getStore().get().find("fBarterGoldResetDelay")->mValue.getFloat(); + MWMechanics::CreatureStats& sellerStats = mPtr.getClass().getCreatureStats(mPtr); + float delay = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fBarterGoldResetDelay") + ->mValue.getFloat(); // Gold is restocked every 24h if (MWBase::Environment::get().getWorld()->getTimeStamp() >= sellerStats.getLastRestockTime() + delay) @@ -518,10 +543,11 @@ namespace MWGui int services = mPtr.getClass().getServices(mPtr); bool travel = (mPtr.getType() == ESM::NPC::sRecordId && !mPtr.get()->mBase->getTransport().empty()) - || (mPtr.getType() == ESM::Creature::sRecordId && !mPtr.get()->mBase->getTransport().empty()); + || (mPtr.getType() == ESM::Creature::sRecordId + && !mPtr.get()->mBase->getTransport().empty()); - const MWWorld::Store &gmst = - MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& gmst + = MWBase::Environment::get().getWorld()->getStore().get(); if (mPtr.getType() == ESM::NPC::sRecordId) mTopicsList->addItem(gmst.find("sPersuasion")->mValue.getString()); @@ -553,8 +579,7 @@ namespace MWGui if (mTopicsList->getItemCount() > 0) mTopicsList->addSeparator(); - - for(const auto& keyword : mKeywords) + for (const auto& keyword : mKeywords) { std::string topicId = Misc::StringUtils::lowerCase(keyword); mTopicsList->addItem(keyword); @@ -575,16 +600,16 @@ namespace MWGui { if (!scrollbar && mScrollBar->getVisible()) { - mHistory->setSize(mHistory->getSize()+MyGUI::IntSize(mScrollBar->getWidth(),0)); + mHistory->setSize(mHistory->getSize() + MyGUI::IntSize(mScrollBar->getWidth(), 0)); mScrollBar->setVisible(false); } if (scrollbar && !mScrollBar->getVisible()) { - mHistory->setSize(mHistory->getSize()-MyGUI::IntSize(mScrollBar->getWidth(),0)); + mHistory->setSize(mHistory->getSize() - MyGUI::IntSize(mScrollBar->getWidth(), 0)); mScrollBar->setVisible(true); } - BookTypesetter::Ptr typesetter = BookTypesetter::create (mHistory->getWidth(), std::numeric_limits::max()); + BookTypesetter::Ptr typesetter = BookTypesetter::create(mHistory->getWidth(), std::numeric_limits::max()); for (const auto& text : mHistoryContents) text->write(typesetter, &mKeywordSearch, mTopicLinks); @@ -603,8 +628,8 @@ namespace MWGui mLinks.push_back(std::move(link)); typesetter->lineBreak(); - BookTypesetter::Style* questionStyle = typesetter->createHotStyle(body, textColours.answer, textColours.answerOver, - textColours.answerPressed, interactiveId); + BookTypesetter::Style* questionStyle = typesetter->createHotStyle( + body, textColours.answer, textColours.answerOver, textColours.answerPressed, interactiveId); typesetter->write(questionStyle, to_utf8_span(choice.first.c_str())); } @@ -615,9 +640,14 @@ namespace MWGui link->eventActivated += MyGUI::newDelegate(this, &DialogueWindow::onGoodbyeActivated); auto interactiveId = TypesetBook::InteractiveId(link.get()); mLinks.push_back(std::move(link)); - const std::string& goodbye = MWBase::Environment::get().getWorld()->getStore().get().find("sGoodbye")->mValue.getString(); - BookTypesetter::Style* questionStyle = typesetter->createHotStyle(body, textColours.answer, textColours.answerOver, - textColours.answerPressed, interactiveId); + const std::string& goodbye = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("sGoodbye") + ->mValue.getString(); + BookTypesetter::Style* questionStyle = typesetter->createHotStyle( + body, textColours.answer, textColours.answerOver, textColours.answerPressed, interactiveId); typesetter->lineBreak(); typesetter->write(questionStyle, to_utf8_span(goodbye.c_str())); } @@ -632,9 +662,10 @@ namespace MWGui mHistory->setSize(MyGUI::IntSize(mHistory->getWidth(), book->getSize().second)); size_t range = book->getSize().second - viewHeight; mScrollBar->setScrollRange(range); - mScrollBar->setScrollPosition(range-1); - mScrollBar->setTrackSize(static_cast(viewHeight / static_cast(book->getSize().second) * mScrollBar->getLineSize())); - onScrollbarMoved(mScrollBar, range-1); + mScrollBar->setScrollPosition(range - 1); + mScrollBar->setTrackSize( + static_cast(viewHeight / static_cast(book->getSize().second) * mScrollBar->getLineSize())); + onScrollbarMoved(mScrollBar, range - 1); } else { @@ -652,12 +683,12 @@ namespace MWGui mTopicsList->setEnabled(topicsEnabled); } - void DialogueWindow::notifyLinkClicked (TypesetBook::InteractiveId link) + void DialogueWindow::notifyLinkClicked(TypesetBook::InteractiveId link) { reinterpret_cast(link)->activated(); } - void DialogueWindow::onTopicActivated(const std::string &topicId) + void DialogueWindow::onTopicActivated(const std::string& topicId) { if (mGoodbye) return; @@ -684,12 +715,12 @@ namespace MWGui resetReference(); } - void DialogueWindow::onScrollbarMoved(MyGUI::ScrollBar *sender, size_t pos) + void DialogueWindow::onScrollbarMoved(MyGUI::ScrollBar* sender, size_t pos) { mHistory->setPosition(0, static_cast(pos) * -1); } - void DialogueWindow::addResponse(const std::string &title, const std::string &text, bool needMargin) + void DialogueWindow::addResponse(const std::string& title, const std::string& text, bool needMargin) { mHistoryContents.push_back(std::make_unique(text, title, needMargin)); updateHistory(); @@ -708,8 +739,11 @@ namespace MWGui { dispositionVisible = true; mDispositionBar->setProgressRange(100); - mDispositionBar->setProgressPosition(MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mPtr)); - mDispositionText->setCaption(MyGUI::utility::toString(MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mPtr))+std::string("/100")); + mDispositionBar->setProgressPosition( + MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mPtr)); + mDispositionText->setCaption( + MyGUI::utility::toString(MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mPtr)) + + std::string("/100")); } bool dispositionWasVisible = mDispositionBar->getVisible(); @@ -717,15 +751,15 @@ namespace MWGui if (dispositionVisible && !dispositionWasVisible) { mDispositionBar->setVisible(true); - int offset = mDispositionBar->getHeight()+5; - mTopicsList->setCoord(mTopicsList->getCoord() + MyGUI::IntCoord(0,offset,0,-offset)); + int offset = mDispositionBar->getHeight() + 5; + mTopicsList->setCoord(mTopicsList->getCoord() + MyGUI::IntCoord(0, offset, 0, -offset)); mTopicsList->adjustSize(); } else if (!dispositionVisible && dispositionWasVisible) { mDispositionBar->setVisible(false); - int offset = mDispositionBar->getHeight()+5; - mTopicsList->setCoord(mTopicsList->getCoord() - MyGUI::IntCoord(0,offset,0,-offset)); + int offset = mDispositionBar->getHeight() + 5; + mTopicsList->setCoord(mTopicsList->getCoord() - MyGUI::IntCoord(0, offset, 0, -offset)); mTopicsList->adjustSize(); } } @@ -745,7 +779,7 @@ namespace MWGui deleteLater(); if (mChoices != MWBase::Environment::get().getDialogueManager()->getChoices() - || mGoodbye != MWBase::Environment::get().getDialogueManager()->isGoodbye()) + || mGoodbye != MWBase::Environment::get().getDialogueManager()->isGoodbye()) updateHistory(); } @@ -787,7 +821,7 @@ namespace MWGui return false; return !actor.getClass().getScript(actor).empty() - && actor.getRefData().getLocals().getIntVar(actor.getClass().getScript(actor), "companion"); + && actor.getRefData().getLocals().getIntVar(actor.getClass().getScript(actor), "companion"); } } diff --git a/apps/openmw/mwgui/dialogue.hpp b/apps/openmw/mwgui/dialogue.hpp index 27547ca046..632fd9ea09 100644 --- a/apps/openmw/mwgui/dialogue.hpp +++ b/apps/openmw/mwgui/dialogue.hpp @@ -3,8 +3,8 @@ #include -#include "windowbase.hpp" #include "referenceinterface.hpp" +#include "windowbase.hpp" #include "bookpage.hpp" @@ -27,10 +27,13 @@ namespace MWGui { DialogueWindow* mWindow; bool mNeedMargin; - + public: - ResponseCallback(DialogueWindow* win, bool needMargin = true) : mWindow(win), mNeedMargin(needMargin) - {} + ResponseCallback(DialogueWindow* win, bool needMargin = true) + : mWindow(win) + , mNeedMargin(needMargin) + { + } void addResponse(const std::string& title, const std::string& text) override; @@ -64,56 +67,63 @@ namespace MWGui void adjustAction(MyGUI::Widget* action, int& totalHeight); - void onCancel (MyGUI::Widget* sender); - void onPersuade (MyGUI::Widget* sender); + void onCancel(MyGUI::Widget* sender); + void onPersuade(MyGUI::Widget* sender); }; - struct Link { virtual ~Link() {} - virtual void activated () = 0; + virtual void activated() = 0; }; struct Topic : Link { typedef MyGUI::delegates::CMultiDelegate1 EventHandle_TopicId; EventHandle_TopicId eventTopicActivated; - Topic(const std::string& id) : mTopicId(id) {} + Topic(const std::string& id) + : mTopicId(id) + { + } std::string mTopicId; - void activated () override; + void activated() override; }; struct Choice : Link { typedef MyGUI::delegates::CMultiDelegate1 EventHandle_ChoiceId; EventHandle_ChoiceId eventChoiceActivated; - Choice(int id) : mChoiceId(id) {} + Choice(int id) + : mChoiceId(id) + { + } int mChoiceId; - void activated () override; + void activated() override; }; struct Goodbye : Link { typedef MyGUI::delegates::CMultiDelegate0 Event_Activated; Event_Activated eventActivated; - void activated () override; + void activated() override; }; - typedef MWDialogue::KeywordSearch KeywordSearchT; + typedef MWDialogue::KeywordSearch KeywordSearchT; struct DialogueText { virtual ~DialogueText() {} - virtual void write(BookTypesetter::Ptr typesetter, KeywordSearchT* keywordSearch, std::map>& topicLinks) const = 0; + virtual void write(BookTypesetter::Ptr typesetter, KeywordSearchT* keywordSearch, + std::map>& topicLinks) const = 0; std::string mText; }; struct Response : DialogueText { Response(const std::string& text, const std::string& title = "", bool needMargin = true); - void write(BookTypesetter::Ptr typesetter, KeywordSearchT* keywordSearch, std::map>& topicLinks) const override; - void addTopicLink (BookTypesetter::Ptr typesetter, intptr_t topicId, size_t begin, size_t end) const; + void write(BookTypesetter::Ptr typesetter, KeywordSearchT* keywordSearch, + std::map>& topicLinks) const override; + void addTopicLink(BookTypesetter::Ptr typesetter, intptr_t topicId, size_t begin, size_t end) const; std::string mTitle; bool mNeedMargin; }; @@ -121,10 +131,11 @@ namespace MWGui struct Message : DialogueText { Message(const std::string& text); - void write(BookTypesetter::Ptr typesetter, KeywordSearchT* keywordSearch, std::map>& topicLinks) const override; + void write(BookTypesetter::Ptr typesetter, KeywordSearchT* keywordSearch, + std::map>& topicLinks) const override; }; - class DialogueWindow: public WindowBase, public ReferenceInterface + class DialogueWindow : public WindowBase, public ReferenceInterface { public: DialogueWindow(); @@ -136,14 +147,14 @@ namespace MWGui // Events typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void; - void notifyLinkClicked (TypesetBook::InteractiveId link); + void notifyLinkClicked(TypesetBook::InteractiveId link); void setPtr(const MWWorld::Ptr& actor) override; /// @return true if stale keywords were updated successfully bool setKeywords(const std::list& keyWord); - void addResponse (const std::string& title, const std::string& text, bool needMargin = true); + void addResponse(const std::string& title, const std::string& text, bool needMargin = true); void addMessageBox(const std::string& text); @@ -167,9 +178,9 @@ namespace MWGui void onChoiceActivated(int id); void onGoodbyeActivated(); - void onScrollbarMoved (MyGUI::ScrollBar* sender, size_t pos); + void onScrollbarMoved(MyGUI::ScrollBar* sender, size_t pos); - void updateHistory(bool scrollbar=false); + void updateHistory(bool scrollbar = false); void onReferenceUnavailable() override; @@ -182,7 +193,7 @@ namespace MWGui std::list mKeywords; std::vector> mHistoryContents; - std::vector > mChoices; + std::vector> mChoices; bool mGoodbye; std::vector> mLinks; @@ -193,10 +204,10 @@ namespace MWGui KeywordSearchT mKeywordSearch; BookPage* mHistory; - Gui::MWList* mTopicsList; + Gui::MWList* mTopicsList; MyGUI::ScrollBar* mScrollBar; MyGUI::ProgressBar* mDispositionBar; - MyGUI::TextBox* mDispositionText; + MyGUI::TextBox* mDispositionText; MyGUI::Button* mGoodbyeButton; PersuasionDialog mPersuasionDialog; diff --git a/apps/openmw/mwgui/draganddrop.cpp b/apps/openmw/mwgui/draganddrop.cpp index 543c7f9e1a..a8c63337c2 100644 --- a/apps/openmw/mwgui/draganddrop.cpp +++ b/apps/openmw/mwgui/draganddrop.cpp @@ -1,142 +1,145 @@ #include "draganddrop.hpp" -#include #include +#include -#include "../mwbase/windowmanager.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/windowmanager.hpp" #include "../mwworld/class.hpp" -#include "sortfilteritemmodel.hpp" +#include "controllers.hpp" #include "inventorywindow.hpp" -#include "itemwidget.hpp" #include "itemview.hpp" -#include "controllers.hpp" +#include "itemwidget.hpp" +#include "sortfilteritemmodel.hpp" namespace MWGui { + DragAndDrop::DragAndDrop() + : mIsOnDragAndDrop(false) + , mDraggedWidget(nullptr) + , mSourceModel(nullptr) + , mSourceView(nullptr) + , mSourceSortModel(nullptr) + , mDraggedCount(0) + { + } -DragAndDrop::DragAndDrop() - : mIsOnDragAndDrop(false) - , mDraggedWidget(nullptr) - , mSourceModel(nullptr) - , mSourceView(nullptr) - , mSourceSortModel(nullptr) - , mDraggedCount(0) -{ -} - -void DragAndDrop::startDrag (int index, SortFilterItemModel* sortModel, ItemModel* sourceModel, ItemView* sourceView, int count) -{ - mItem = sourceModel->getItem(index); - mDraggedCount = count; - mSourceModel = sourceModel; - mSourceView = sourceView; - mSourceSortModel = sortModel; - - // If picking up an item that isn't from the player's inventory, the item gets added to player inventory backend - // immediately, even though it's still floating beneath the mouse cursor. A bit counterintuitive, - // but this is how it works in vanilla, and not doing so would break quests (BM_beasts for instance). - ItemModel* playerModel = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getModel(); - if (mSourceModel != playerModel) + void DragAndDrop::startDrag( + int index, SortFilterItemModel* sortModel, ItemModel* sourceModel, ItemView* sourceView, int count) { - MWWorld::Ptr item = mSourceModel->moveItem(mItem, mDraggedCount, playerModel); + mItem = sourceModel->getItem(index); + mDraggedCount = count; + mSourceModel = sourceModel; + mSourceView = sourceView; + mSourceSortModel = sortModel; + + // If picking up an item that isn't from the player's inventory, the item gets added to player inventory backend + // immediately, even though it's still floating beneath the mouse cursor. A bit counterintuitive, + // but this is how it works in vanilla, and not doing so would break quests (BM_beasts for instance). + ItemModel* playerModel = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getModel(); + if (mSourceModel != playerModel) + { + MWWorld::Ptr item = mSourceModel->moveItem(mItem, mDraggedCount, playerModel); - playerModel->update(); + playerModel->update(); - ItemModel::ModelIndex newIndex = -1; - for (unsigned int i=0; igetItemCount(); ++i) - { - if (playerModel->getItem(i).mBase == item) + ItemModel::ModelIndex newIndex = -1; + for (unsigned int i = 0; i < playerModel->getItemCount(); ++i) { - newIndex = i; - break; + if (playerModel->getItem(i).mBase == item) + { + newIndex = i; + break; + } } + mItem = playerModel->getItem(newIndex); + mSourceModel = playerModel; + + SortFilterItemModel* playerFilterModel + = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getSortFilterModel(); + mSourceSortModel = playerFilterModel; } - mItem = playerModel->getItem(newIndex); - mSourceModel = playerModel; - SortFilterItemModel* playerFilterModel = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getSortFilterModel(); - mSourceSortModel = playerFilterModel; - } + std::string_view sound = mItem.mBase.getClass().getUpSoundId(mItem.mBase); + MWBase::Environment::get().getWindowManager()->playSound(sound); - std::string_view sound = mItem.mBase.getClass().getUpSoundId(mItem.mBase); - MWBase::Environment::get().getWindowManager()->playSound (sound); + if (mSourceSortModel) + { + mSourceSortModel->clearDragItems(); + mSourceSortModel->addDragItem(mItem.mBase, count); + } - if (mSourceSortModel) - { - mSourceSortModel->clearDragItems(); - mSourceSortModel->addDragItem(mItem.mBase, count); - } + ItemWidget* baseWidget = MyGUI::Gui::getInstance().createWidget( + "MW_ItemIcon", 0, 0, 42, 42, MyGUI::Align::Default, "DragAndDrop"); - ItemWidget* baseWidget = MyGUI::Gui::getInstance().createWidget("MW_ItemIcon", 0, 0, 42, 42, MyGUI::Align::Default, "DragAndDrop"); + Controllers::ControllerFollowMouse* controller + = MyGUI::ControllerManager::getInstance() + .createItem(Controllers::ControllerFollowMouse::getClassTypeName()) + ->castType(); + MyGUI::ControllerManager::getInstance().addItem(baseWidget, controller); - Controllers::ControllerFollowMouse* controller = - MyGUI::ControllerManager::getInstance().createItem(Controllers::ControllerFollowMouse::getClassTypeName()) - ->castType(); - MyGUI::ControllerManager::getInstance().addItem(baseWidget, controller); + mDraggedWidget = baseWidget; + baseWidget->setItem(mItem.mBase); + baseWidget->setNeedMouseFocus(false); + baseWidget->setCount(count); - mDraggedWidget = baseWidget; - baseWidget->setItem(mItem.mBase); - baseWidget->setNeedMouseFocus(false); - baseWidget->setCount(count); + sourceView->update(); - sourceView->update(); + MWBase::Environment::get().getWindowManager()->setDragDrop(true); - MWBase::Environment::get().getWindowManager()->setDragDrop(true); + mIsOnDragAndDrop = true; + } - mIsOnDragAndDrop = true; -} + void DragAndDrop::drop(ItemModel* targetModel, ItemView* targetView) + { + std::string_view sound = mItem.mBase.getClass().getDownSoundId(mItem.mBase); + MWBase::Environment::get().getWindowManager()->playSound(sound); -void DragAndDrop::drop(ItemModel *targetModel, ItemView *targetView) -{ - std::string_view sound = mItem.mBase.getClass().getDownSoundId(mItem.mBase); - MWBase::Environment::get().getWindowManager()->playSound(sound); + // We can't drop a conjured item to the ground; the target container should always be the source container + if (mItem.mFlags & ItemStack::Flag_Bound && targetModel != mSourceModel) + { + MWBase::Environment::get().getWindowManager()->messageBox("#{sBarterDialog12}"); + return; + } - // We can't drop a conjured item to the ground; the target container should always be the source container - if (mItem.mFlags & ItemStack::Flag_Bound && targetModel != mSourceModel) - { - MWBase::Environment::get().getWindowManager()->messageBox("#{sBarterDialog12}"); - return; - } + // If item is dropped where it was taken from, we don't need to do anything - + // otherwise, do the transfer + if (targetModel != mSourceModel) + { + mSourceModel->moveItem(mItem, mDraggedCount, targetModel); + } - // If item is dropped where it was taken from, we don't need to do anything - - // otherwise, do the transfer - if (targetModel != mSourceModel) - { - mSourceModel->moveItem(mItem, mDraggedCount, targetModel); - } + mSourceModel->update(); - mSourceModel->update(); + finish(); + if (targetView) + targetView->update(); - finish(); - if (targetView) - targetView->update(); + MWBase::Environment::get().getWindowManager()->getInventoryWindow()->updateItemView(); - MWBase::Environment::get().getWindowManager()->getInventoryWindow()->updateItemView(); + // We need to update the view since an other item could be auto-equipped. + mSourceView->update(); + } - // We need to update the view since an other item could be auto-equipped. - mSourceView->update(); -} + void DragAndDrop::onFrame() + { + if (mIsOnDragAndDrop && mItem.mBase.getRefData().getCount() == 0) + finish(); + } -void DragAndDrop::onFrame() -{ - if (mIsOnDragAndDrop && mItem.mBase.getRefData().getCount() == 0) - finish(); -} + void DragAndDrop::finish() + { + mIsOnDragAndDrop = false; + mSourceSortModel->clearDragItems(); + // since mSourceView doesn't get updated in drag() + MWBase::Environment::get().getWindowManager()->getInventoryWindow()->updateItemView(); -void DragAndDrop::finish() -{ - mIsOnDragAndDrop = false; - mSourceSortModel->clearDragItems(); - // since mSourceView doesn't get updated in drag() - MWBase::Environment::get().getWindowManager()->getInventoryWindow()->updateItemView(); - - MyGUI::Gui::getInstance().destroyWidget(mDraggedWidget); - mDraggedWidget = nullptr; - MWBase::Environment::get().getWindowManager()->setDragDrop(false); -} + MyGUI::Gui::getInstance().destroyWidget(mDraggedWidget); + mDraggedWidget = nullptr; + MWBase::Environment::get().getWindowManager()->setDragDrop(false); + } } diff --git a/apps/openmw/mwgui/draganddrop.hpp b/apps/openmw/mwgui/draganddrop.hpp index dff8cd73c0..fab7f30d75 100644 --- a/apps/openmw/mwgui/draganddrop.hpp +++ b/apps/openmw/mwgui/draganddrop.hpp @@ -27,8 +27,9 @@ namespace MWGui DragAndDrop(); - void startDrag (int index, SortFilterItemModel* sortModel, ItemModel* sourceModel, ItemView* sourceView, int count); - void drop (ItemModel* targetModel, ItemView* targetView); + void startDrag( + int index, SortFilterItemModel* sortModel, ItemModel* sourceModel, ItemView* sourceView, int count); + void drop(ItemModel* targetModel, ItemView* targetView); void onFrame(); void finish(); diff --git a/apps/openmw/mwgui/enchantingdialog.cpp b/apps/openmw/mwgui/enchantingdialog.cpp index 1e340b4a99..d12f1ce6ab 100644 --- a/apps/openmw/mwgui/enchantingdialog.cpp +++ b/apps/openmw/mwgui/enchantingdialog.cpp @@ -3,19 +3,19 @@ #include #include -#include #include +#include -#include #include #include +#include #include #include "../mwbase/environment.hpp" #include "../mwbase/mechanicsmanager.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" #include "../mwworld/class.hpp" #include "../mwworld/containerstore.hpp" @@ -32,7 +32,6 @@ namespace MWGui { - EnchantingDialog::EnchantingDialog() : WindowBase("openmw_enchanting_dialog.layout") , EffectEditorBase(EffectEditorBase::Enchanting) @@ -69,7 +68,7 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mName); } - void EnchantingDialog::setSoulGem(const MWWorld::Ptr &gem) + void EnchantingDialog::setSoulGem(const MWWorld::Ptr& gem) { if (gem.isEmpty()) { @@ -80,13 +79,13 @@ namespace MWGui else { mSoulBox->setItem(gem); - mSoulBox->setUserString ("ToolTipType", "ItemPtr"); + mSoulBox->setUserString("ToolTipType", "ItemPtr"); mSoulBox->setUserData(MWWorld::Ptr(gem)); mEnchanting.setSoulGem(gem); } } - void EnchantingDialog::setItem(const MWWorld::Ptr &item) + void EnchantingDialog::setItem(const MWWorld::Ptr& item) { if (item.isEmpty()) { @@ -99,7 +98,7 @@ namespace MWGui std::string_view name = item.getClass().getName(item); mName->setCaption(toUString(name)); mItemBox->setItem(item); - mItemBox->setUserString ("ToolTipType", "ItemPtr"); + mItemBox->setUserString("ToolTipType", "ItemPtr"); mItemBox->setUserData(MWWorld::Ptr(item)); mEnchanting.setOldItem(item); } @@ -107,34 +106,39 @@ namespace MWGui void EnchantingDialog::updateLabels() { - mEnchantmentPoints->setCaption(std::to_string(static_cast(mEnchanting.getEnchantPoints(false))) + " / " + std::to_string(mEnchanting.getMaxEnchantValue())); + mEnchantmentPoints->setCaption(std::to_string(static_cast(mEnchanting.getEnchantPoints(false))) + " / " + + std::to_string(mEnchanting.getMaxEnchantValue())); mCharge->setCaption(std::to_string(mEnchanting.getGemCharge())); mSuccessChance->setCaption(std::to_string(std::clamp(mEnchanting.getEnchantChance(), 0, 100))); mCastCost->setCaption(std::to_string(mEnchanting.getEffectiveCastCost())); mPrice->setCaption(std::to_string(mEnchanting.getEnchantPrice())); - switch(mEnchanting.getCastStyle()) + switch (mEnchanting.getCastStyle()) { case ESM::Enchantment::CastOnce: - mTypeButton->setCaption(toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString("sItemCastOnce", "Cast Once"))); + mTypeButton->setCaption(toUString( + MWBase::Environment::get().getWindowManager()->getGameSettingString("sItemCastOnce", "Cast Once"))); setConstantEffect(false); break; case ESM::Enchantment::WhenStrikes: - mTypeButton->setCaption(toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString("sItemCastWhenStrikes", "When Strikes"))); + mTypeButton->setCaption(toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString( + "sItemCastWhenStrikes", "When Strikes"))); setConstantEffect(false); break; case ESM::Enchantment::WhenUsed: - mTypeButton->setCaption(toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString("sItemCastWhenUsed", "When Used"))); + mTypeButton->setCaption(toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString( + "sItemCastWhenUsed", "When Used"))); setConstantEffect(false); break; case ESM::Enchantment::ConstantEffect: - mTypeButton->setCaption(toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString("sItemCastConstant", "Cast Constant"))); + mTypeButton->setCaption(toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString( + "sItemCastConstant", "Cast Constant"))); setConstantEffect(true); break; } } - void EnchantingDialog::setPtr (const MWWorld::Ptr& ptr) + void EnchantingDialog::setPtr(const MWWorld::Ptr& ptr) { mName->setCaption(""); @@ -154,7 +158,7 @@ namespace MWGui mEnchanting.setSelfEnchanting(true); mEnchanting.setEnchanter(MWMechanics::getPlayer()); mBuyButton->setCaptionWithReplacing("#{sCreate}"); - bool enabled = Settings::Manager::getBool("show enchant chance","Game"); + bool enabled = Settings::Manager::getBool("show enchant chance", "Game"); mChanceLayout->setVisible(enabled); mPtr = MWMechanics::getPlayer(); setSoulGem(ptr); @@ -163,13 +167,13 @@ namespace MWGui } setItem(MWWorld::Ptr()); - startEditing (); + startEditing(); updateLabels(); } - void EnchantingDialog::onReferenceUnavailable () + void EnchantingDialog::onReferenceUnavailable() { - MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_Enchanting); + MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Enchanting); resetReference(); } @@ -187,7 +191,7 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Enchanting); } - void EnchantingDialog::onSelectItem(MyGUI::Widget *sender) + void EnchantingDialog::onSelectItem(MyGUI::Widget* sender) { if (mEnchanting.getOldItem().isEmpty()) { @@ -225,9 +229,9 @@ namespace MWGui mItemSelectionDialog->setVisible(false); mEnchanting.setSoulGem(item); - if(mEnchanting.getGemCharge()==0) + if (mEnchanting.getGemCharge() == 0) { - MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage32}"); + MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage32}"); return; } @@ -241,7 +245,7 @@ namespace MWGui mItemSelectionDialog->setVisible(false); } - void EnchantingDialog::onSelectSoul(MyGUI::Widget *sender) + void EnchantingDialog::onSelectSoul(MyGUI::Widget* sender) { if (mEnchanting.getGem().isEmpty()) { @@ -252,7 +256,7 @@ namespace MWGui mItemSelectionDialog->openContainer(MWMechanics::getPlayer()); mItemSelectionDialog->setFilter(SortFilterItemModel::Filter_OnlyChargedSoulstones); - //MWBase::Environment::get().getWindowManager()->messageBox("#{sInventorySelectNoSoul}"); + // MWBase::Environment::get().getWindowManager()->messageBox("#{sInventorySelectNoSoul}"); } else { @@ -263,7 +267,7 @@ namespace MWGui } } - void EnchantingDialog::notifyEffectsChanged () + void EnchantingDialog::notifyEffectsChanged() { mEffectList.mList = mEffects; mEnchanting.setEffect(mEffectList); @@ -277,7 +281,7 @@ namespace MWGui updateEffectsView(); } - void EnchantingDialog::onAccept(MyGUI::EditBox *sender) + void EnchantingDialog::onAccept(MyGUI::EditBox* sender) { onBuyButtonClicked(sender); @@ -289,31 +293,31 @@ namespace MWGui { if (mEffects.size() <= 0) { - MWBase::Environment::get().getWindowManager()->messageBox ("#{sEnchantmentMenu11}"); + MWBase::Environment::get().getWindowManager()->messageBox("#{sEnchantmentMenu11}"); return; } - if (mName->getCaption ().empty()) + if (mName->getCaption().empty()) { - MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage10}"); + MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage10}"); return; } if (mEnchanting.soulEmpty()) { - MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage52}"); + MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage52}"); return; } if (mEnchanting.itemEmpty()) { - MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage11}"); + MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage11}"); return; } if (static_cast(mEnchanting.getEnchantPoints(false)) > mEnchanting.getMaxEnchantValue()) { - MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage29}"); + MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage29}"); return; } @@ -324,25 +328,32 @@ namespace MWGui int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId); if (mPtr != player && mEnchanting.getEnchantPrice() > playerGold) { - MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage18}"); + MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage18}"); return; } // check if the player is attempting to use a soulstone or item that was stolen from this actor if (mPtr != player) { - for (int i=0; i<2; ++i) + for (int i = 0; i < 2; ++i) { MWWorld::Ptr item = (i == 0) ? mEnchanting.getOldItem() : mEnchanting.getGem(); - if (MWBase::Environment::get().getMechanicsManager()->isItemStolenFrom(item.getCellRef().getRefId(), mPtr)) + if (MWBase::Environment::get().getMechanicsManager()->isItemStolenFrom( + item.getCellRef().getRefId(), mPtr)) { - std::string msg = MWBase::Environment::get().getWorld()->getStore().get().find("sNotifyMessage49")->mValue.getString(); + std::string msg = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("sNotifyMessage49") + ->mValue.getString(); msg = Misc::StringUtils::format(msg, item.getClass().getName(item)); MWBase::Environment::get().getWindowManager()->messageBox(msg); - MWBase::Environment::get().getMechanicsManager()->confiscateStolenItemToOwner(player, item, mPtr, 1); + MWBase::Environment::get().getMechanicsManager()->confiscateStolenItemToOwner( + player, item, mPtr, 1); - MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_Enchanting); + MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Enchanting); MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode(); return; } @@ -351,16 +362,16 @@ namespace MWGui int result = mEnchanting.create(); - if(result==1) + if (result == 1) { MWBase::Environment::get().getWindowManager()->playSound("enchant success"); - MWBase::Environment::get().getWindowManager()->messageBox ("#{sEnchantmentMenu12}"); - MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_Enchanting); + MWBase::Environment::get().getWindowManager()->messageBox("#{sEnchantmentMenu12}"); + MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Enchanting); } else { MWBase::Environment::get().getWindowManager()->playSound("enchant fail"); - MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage34}"); + MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage34}"); if (!mEnchanting.getGem().isEmpty() && !mEnchanting.getGem().getRefData().getCount()) { setSoulGem(MWWorld::Ptr()); diff --git a/apps/openmw/mwgui/enchantingdialog.hpp b/apps/openmw/mwgui/enchantingdialog.hpp index 14157d800e..f9d891b2dc 100644 --- a/apps/openmw/mwgui/enchantingdialog.hpp +++ b/apps/openmw/mwgui/enchantingdialog.hpp @@ -24,8 +24,8 @@ namespace MWGui void onFrame(float dt) override { checkReferenceAvailable(); } void clear() override { resetReference(); } - void setSoulGem (const MWWorld::Ptr& gem); - void setItem (const MWWorld::Ptr& item); + void setSoulGem(const MWWorld::Ptr& gem); + void setItem(const MWWorld::Ptr& item); /// Actor Ptr: buy enchantment from this actor /// Soulgem Ptr: player self-enchant @@ -38,8 +38,8 @@ namespace MWGui void notifyEffectsChanged() override; void onCancelButtonClicked(MyGUI::Widget* sender); - void onSelectItem (MyGUI::Widget* sender); - void onSelectSoul (MyGUI::Widget* sender); + void onSelectItem(MyGUI::Widget* sender); + void onSelectSoul(MyGUI::Widget* sender); void onItemSelected(MWWorld::Ptr item); void onItemCancel(); diff --git a/apps/openmw/mwgui/exposedwindow.cpp b/apps/openmw/mwgui/exposedwindow.cpp index 90cfa09d34..36b47d98f2 100644 --- a/apps/openmw/mwgui/exposedwindow.cpp +++ b/apps/openmw/mwgui/exposedwindow.cpp @@ -2,18 +2,18 @@ namespace MWGui { - MyGUI::VectorWidgetPtr Window::getSkinWidgetsByName (const std::string &name) + MyGUI::VectorWidgetPtr Window::getSkinWidgetsByName(const std::string& name) { - return MyGUI::Widget::getSkinWidgetsByName (name); + return MyGUI::Widget::getSkinWidgetsByName(name); } - MyGUI::Widget* Window::getSkinWidget(const std::string & _name, bool _throw) + MyGUI::Widget* Window::getSkinWidget(const std::string& _name, bool _throw) { - MyGUI::VectorWidgetPtr widgets = getSkinWidgetsByName (_name); + MyGUI::VectorWidgetPtr widgets = getSkinWidgetsByName(_name); if (widgets.empty()) { - MYGUI_ASSERT( ! _throw, "widget name '" << _name << "' not found in skin of layout '" << getName() << "'"); + MYGUI_ASSERT(!_throw, "widget name '" << _name << "' not found in skin of layout '" << getName() << "'"); return nullptr; } else diff --git a/apps/openmw/mwgui/exposedwindow.hpp b/apps/openmw/mwgui/exposedwindow.hpp index f1f5d3c2f8..d192a3db01 100644 --- a/apps/openmw/mwgui/exposedwindow.hpp +++ b/apps/openmw/mwgui/exposedwindow.hpp @@ -14,13 +14,12 @@ namespace MWGui MYGUI_RTTI_DERIVED(Window) public: - MyGUI::VectorWidgetPtr getSkinWidgetsByName (const std::string &name); + MyGUI::VectorWidgetPtr getSkinWidgetsByName(const std::string& name); - MyGUI::Widget* getSkinWidget(const std::string & _name, bool _throw = true); + MyGUI::Widget* getSkinWidget(const std::string& _name, bool _throw = true); ///< Get a widget defined in the inner skin of this window. }; } #endif - diff --git a/apps/openmw/mwgui/formatting.cpp b/apps/openmw/mwgui/formatting.cpp index cc3c125552..474615ab2d 100644 --- a/apps/openmw/mwgui/formatting.cpp +++ b/apps/openmw/mwgui/formatting.cpp @@ -1,493 +1,501 @@ #include "formatting.hpp" +#include #include #include -#include #include #include +#include #include +#include +#include #include #include -#include -#include -#include #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" #include "../mwscript/interpretercontext.hpp" namespace MWGui::Formatting +{ + /* BookTextParser */ + BookTextParser::BookTextParser(const std::string& text) + : mIndex(0) + , mText(text) + , mIgnoreNewlineTags(true) + , mIgnoreLineEndings(true) + , mClosingTag(false) { - /* BookTextParser */ - BookTextParser::BookTextParser(const std::string & text) - : mIndex(0), mText(text), mIgnoreNewlineTags(true), mIgnoreLineEndings(true), mClosingTag(false) + MWScript::InterpreterContext interpreterContext( + nullptr, MWWorld::Ptr()); // empty arguments, because there is no locals or actor + mText = Interpreter::fixDefinesBook(mText, interpreterContext); + + Misc::StringUtils::replaceAll(mText, "\r", ""); + + // vanilla game does not show any text after the last EOL tag. + const std::string lowerText = Misc::StringUtils::lowerCase(mText); + size_t brIndex = lowerText.rfind("
        "); + size_t pIndex = lowerText.rfind("

        "); + mPlainTextEnd = 0; + if (brIndex != pIndex) { - MWScript::InterpreterContext interpreterContext(nullptr, MWWorld::Ptr()); // empty arguments, because there is no locals or actor - mText = Interpreter::fixDefinesBook(mText, interpreterContext); - - Misc::StringUtils::replaceAll(mText, "\r", ""); - - // vanilla game does not show any text after the last EOL tag. - const std::string lowerText = Misc::StringUtils::lowerCase(mText); - size_t brIndex = lowerText.rfind("
        "); - size_t pIndex = lowerText.rfind("

        "); - mPlainTextEnd = 0; - if (brIndex != pIndex) - { - if (brIndex != std::string::npos && pIndex != std::string::npos) - mPlainTextEnd = std::max(brIndex, pIndex); - else if (brIndex != std::string::npos) - mPlainTextEnd = brIndex; - else - mPlainTextEnd = pIndex; - } - - registerTag("br", Event_BrTag); - registerTag("p", Event_PTag); - registerTag("img", Event_ImgTag); - registerTag("div", Event_DivTag); - registerTag("font", Event_FontTag); + if (brIndex != std::string::npos && pIndex != std::string::npos) + mPlainTextEnd = std::max(brIndex, pIndex); + else if (brIndex != std::string::npos) + mPlainTextEnd = brIndex; + else + mPlainTextEnd = pIndex; } - void BookTextParser::registerTag(const std::string & tag, BookTextParser::Events type) - { - mTagTypes[tag] = type; - } + registerTag("br", Event_BrTag); + registerTag("p", Event_PTag); + registerTag("img", Event_ImgTag); + registerTag("div", Event_DivTag); + registerTag("font", Event_FontTag); + } - std::string BookTextParser::getReadyText() const - { - return mReadyText; - } + void BookTextParser::registerTag(const std::string& tag, BookTextParser::Events type) + { + mTagTypes[tag] = type; + } + + std::string BookTextParser::getReadyText() const + { + return mReadyText; + } - BookTextParser::Events BookTextParser::next() + BookTextParser::Events BookTextParser::next() + { + while (mIndex < mText.size()) { - while (mIndex < mText.size()) + char ch = mText[mIndex]; + if (ch == '<') { - char ch = mText[mIndex]; - if (ch == '<') + const size_t tagStart = mIndex + 1; + const size_t tagEnd = mText.find('>', tagStart); + if (tagEnd == std::string::npos) + throw std::runtime_error("BookTextParser Error: Tag is not terminated"); + parseTag(mText.substr(tagStart, tagEnd - tagStart)); + mIndex = tagEnd; + + if (mTagTypes.find(mTag) != mTagTypes.end()) { - const size_t tagStart = mIndex + 1; - const size_t tagEnd = mText.find('>', tagStart); - if (tagEnd == std::string::npos) - throw std::runtime_error("BookTextParser Error: Tag is not terminated"); - parseTag(mText.substr(tagStart, tagEnd - tagStart)); - mIndex = tagEnd; - - if (mTagTypes.find(mTag) != mTagTypes.end()) - { - Events type = mTagTypes.at(mTag); + Events type = mTagTypes.at(mTag); - if (type == Event_BrTag || type == Event_PTag) + if (type == Event_BrTag || type == Event_PTag) + { + if (!mIgnoreNewlineTags) { - if (!mIgnoreNewlineTags) + if (type == Event_BrTag) + mBuffer.push_back('\n'); + else { - if (type == Event_BrTag) - mBuffer.push_back('\n'); - else - { - mBuffer.append("\n\n"); - } + mBuffer.append("\n\n"); } - mIgnoreLineEndings = true; - } - else - flushBuffer(); - - if (type == Event_ImgTag) - { - mIgnoreNewlineTags = false; } - - ++mIndex; - return type; + mIgnoreLineEndings = true; } - } - else - { - if (!mIgnoreLineEndings || ch != '\n') + else + flushBuffer(); + + if (type == Event_ImgTag) { - if (mIndex < mPlainTextEnd) - mBuffer.push_back(ch); - mIgnoreLineEndings = false; mIgnoreNewlineTags = false; } - } - ++mIndex; + ++mIndex; + return type; + } + } + else + { + if (!mIgnoreLineEndings || ch != '\n') + { + if (mIndex < mPlainTextEnd) + mBuffer.push_back(ch); + mIgnoreLineEndings = false; + mIgnoreNewlineTags = false; + } } - flushBuffer(); - return Event_EOF; + ++mIndex; } - void BookTextParser::flushBuffer() - { - mReadyText = mBuffer; - mBuffer.clear(); - } + flushBuffer(); + return Event_EOF; + } - const BookTextParser::Attributes & BookTextParser::getAttributes() const - { - return mAttributes; - } + void BookTextParser::flushBuffer() + { + mReadyText = mBuffer; + mBuffer.clear(); + } + + const BookTextParser::Attributes& BookTextParser::getAttributes() const + { + return mAttributes; + } - bool BookTextParser::isClosingTag() const + bool BookTextParser::isClosingTag() const + { + return mClosingTag; + } + + void BookTextParser::parseTag(std::string tag) + { + size_t tagNameEndPos = tag.find(' '); + mAttributes.clear(); + mTag = tag.substr(0, tagNameEndPos); + Misc::StringUtils::lowerCaseInPlace(mTag); + if (mTag.empty()) + return; + + mClosingTag = (mTag[0] == '/'); + if (mClosingTag) { - return mClosingTag; + mTag.erase(mTag.begin()); + return; } - void BookTextParser::parseTag(std::string tag) + if (tagNameEndPos == std::string::npos) + return; + tag.erase(0, tagNameEndPos + 1); + + while (!tag.empty()) { - size_t tagNameEndPos = tag.find(' '); - mAttributes.clear(); - mTag = tag.substr(0, tagNameEndPos); - Misc::StringUtils::lowerCaseInPlace(mTag); - if (mTag.empty()) + size_t sepPos = tag.find('='); + if (sepPos == std::string::npos) return; - mClosingTag = (mTag[0] == '/'); - if (mClosingTag) - { - mTag.erase(mTag.begin()); - return; - } + std::string key = tag.substr(0, sepPos); + Misc::StringUtils::lowerCaseInPlace(key); + tag.erase(0, sepPos + 1); + + std::string value; - if (tagNameEndPos == std::string::npos) + if (tag.empty()) return; - tag.erase(0, tagNameEndPos+1); - while (!tag.empty()) + if (tag[0] == '"') { - size_t sepPos = tag.find('='); - if (sepPos == std::string::npos) - return; - - std::string key = tag.substr(0, sepPos); - Misc::StringUtils::lowerCaseInPlace(key); - tag.erase(0, sepPos+1); - - std::string value; - - if (tag.empty()) - return; - - if (tag[0] == '"') + size_t quoteEndPos = tag.find('"', 1); + if (quoteEndPos == std::string::npos) + throw std::runtime_error("BookTextParser Error: Missing end quote in tag"); + value = tag.substr(1, quoteEndPos - 1); + tag.erase(0, quoteEndPos + 2); + } + else + { + size_t valEndPos = tag.find(' '); + if (valEndPos == std::string::npos) { - size_t quoteEndPos = tag.find('"', 1); - if (quoteEndPos == std::string::npos) - throw std::runtime_error("BookTextParser Error: Missing end quote in tag"); - value = tag.substr(1, quoteEndPos-1); - tag.erase(0, quoteEndPos+2); + value = tag; + tag.erase(); } else { - size_t valEndPos = tag.find(' '); - if (valEndPos == std::string::npos) - { - value = tag; - tag.erase(); - } - else - { - value = tag.substr(0, valEndPos); - tag.erase(0, valEndPos+1); - } + value = tag.substr(0, valEndPos); + tag.erase(0, valEndPos + 1); } - - mAttributes[key] = value; } + + mAttributes[key] = value; } + } - /* BookFormatter */ - Paginator::Pages BookFormatter::markupToWidget(MyGUI::Widget * parent, const std::string & markup, const int pageWidth, const int pageHeight) - { - Paginator pag(pageWidth, pageHeight); + /* BookFormatter */ + Paginator::Pages BookFormatter::markupToWidget( + MyGUI::Widget* parent, const std::string& markup, const int pageWidth, const int pageHeight) + { + Paginator pag(pageWidth, pageHeight); - while (parent->getChildCount()) - { - MyGUI::Gui::getInstance().destroyWidget(parent->getChildAt(0)); - } + while (parent->getChildCount()) + { + MyGUI::Gui::getInstance().destroyWidget(parent->getChildAt(0)); + } - mTextStyle = TextStyle(); - mBlockStyle = BlockStyle(); + mTextStyle = TextStyle(); + mBlockStyle = BlockStyle(); - MyGUI::Widget * paper = parent->createWidget("Widget", MyGUI::IntCoord(0, 0, pag.getPageWidth(), pag.getPageHeight()), MyGUI::Align::Left | MyGUI::Align::Top); - paper->setNeedMouseFocus(false); + MyGUI::Widget* paper = parent->createWidget("Widget", + MyGUI::IntCoord(0, 0, pag.getPageWidth(), pag.getPageHeight()), MyGUI::Align::Left | MyGUI::Align::Top); + paper->setNeedMouseFocus(false); - BookTextParser parser(markup); + BookTextParser parser(markup); - bool brBeforeLastTag = false; - bool isPrevImg = false; - for (;;) - { - BookTextParser::Events event = parser.next(); - if (event == BookTextParser::Event_BrTag || event == BookTextParser::Event_PTag) - continue; + bool brBeforeLastTag = false; + bool isPrevImg = false; + for (;;) + { + BookTextParser::Events event = parser.next(); + if (event == BookTextParser::Event_BrTag || event == BookTextParser::Event_PTag) + continue; - std::string plainText = parser.getReadyText(); + std::string plainText = parser.getReadyText(); - // for cases when linebreaks are used to cause a shift to the next page - // if the split text block ends in an empty line, proceeding text block(s) should have leading empty lines removed - if (pag.getIgnoreLeadingEmptyLines()) + // for cases when linebreaks are used to cause a shift to the next page + // if the split text block ends in an empty line, proceeding text block(s) should have leading empty lines + // removed + if (pag.getIgnoreLeadingEmptyLines()) + { + while (!plainText.empty()) { - while (!plainText.empty()) + if (plainText[0] == '\n') + plainText.erase(plainText.begin()); + else { - if (plainText[0] == '\n') - plainText.erase(plainText.begin()); - else - { - pag.setIgnoreLeadingEmptyLines(false); - break; - } + pag.setIgnoreLeadingEmptyLines(false); + break; } } + } - if (plainText.empty()) - brBeforeLastTag = true; - else - { - // Each block of text (between two tags / boundary and tag) will be displayed in a separate editbox widget, - // which means an additional linebreak will be created between them. - // ^ This is not what vanilla MW assumes, so we must deal with line breaks around tags appropriately. - bool brAtStart = (plainText[0] == '\n'); - bool brAtEnd = (plainText[plainText.size()-1] == '\n'); - - if (brAtStart && !brBeforeLastTag && !isPrevImg) - plainText.erase(plainText.begin()); + if (plainText.empty()) + brBeforeLastTag = true; + else + { + // Each block of text (between two tags / boundary and tag) will be displayed in a separate editbox + // widget, which means an additional linebreak will be created between them. ^ This is not what vanilla + // MW assumes, so we must deal with line breaks around tags appropriately. + bool brAtStart = (plainText[0] == '\n'); + bool brAtEnd = (plainText[plainText.size() - 1] == '\n'); - if (plainText.size() && brAtEnd) - plainText.erase(plainText.end()-1); + if (brAtStart && !brBeforeLastTag && !isPrevImg) + plainText.erase(plainText.begin()); - if (!plainText.empty() || brBeforeLastTag || isPrevImg) - { - TextElement elem(paper, pag, mBlockStyle, - mTextStyle, plainText); - elem.paginate(); - } + if (plainText.size() && brAtEnd) + plainText.erase(plainText.end() - 1); - brBeforeLastTag = brAtEnd; + if (!plainText.empty() || brBeforeLastTag || isPrevImg) + { + TextElement elem(paper, pag, mBlockStyle, mTextStyle, plainText); + elem.paginate(); } - if (event == BookTextParser::Event_EOF) - break; - - isPrevImg = (event == BookTextParser::Event_ImgTag); + brBeforeLastTag = brAtEnd; + } - switch (event) - { - case BookTextParser::Event_ImgTag: - { - const BookTextParser::Attributes & attr = parser.getAttributes(); + if (event == BookTextParser::Event_EOF) + break; - if (attr.find("src") == attr.end() || attr.find("width") == attr.end() || attr.find("height") == attr.end()) - continue; + isPrevImg = (event == BookTextParser::Event_ImgTag); - std::string src = attr.at("src"); - int width = MyGUI::utility::parseInt(attr.at("width")); - int height = MyGUI::utility::parseInt(attr.at("height")); + switch (event) + { + case BookTextParser::Event_ImgTag: + { + const BookTextParser::Attributes& attr = parser.getAttributes(); - auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); - std::string correctedSrc = Misc::ResourceHelpers::correctBookartPath(src, width, height, vfs); - bool exists = vfs->exists(correctedSrc); + if (attr.find("src") == attr.end() || attr.find("width") == attr.end() + || attr.find("height") == attr.end()) + continue; - if (!exists) - { - Log(Debug::Warning) << "Warning: Could not find \"" << src << "\" referenced by an tag."; - break; - } + std::string src = attr.at("src"); + int width = MyGUI::utility::parseInt(attr.at("width")); + int height = MyGUI::utility::parseInt(attr.at("height")); - pag.setIgnoreLeadingEmptyLines(false); + auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); + std::string correctedSrc = Misc::ResourceHelpers::correctBookartPath(src, width, height, vfs); + bool exists = vfs->exists(correctedSrc); - ImageElement elem(paper, pag, mBlockStyle, correctedSrc, width, height); - elem.paginate(); + if (!exists) + { + Log(Debug::Warning) << "Warning: Could not find \"" << src << "\" referenced by an tag."; break; } - case BookTextParser::Event_FontTag: - if (parser.isClosingTag()) - resetFontProperties(); - else - handleFont(parser.getAttributes()); - break; - case BookTextParser::Event_DivTag: - handleDiv(parser.getAttributes()); - break; - default: - break; + + pag.setIgnoreLeadingEmptyLines(false); + + ImageElement elem(paper, pag, mBlockStyle, correctedSrc, width, height); + elem.paginate(); + break; } + case BookTextParser::Event_FontTag: + if (parser.isClosingTag()) + resetFontProperties(); + else + handleFont(parser.getAttributes()); + break; + case BookTextParser::Event_DivTag: + handleDiv(parser.getAttributes()); + break; + default: + break; } + } - // insert last page - if (pag.getStartTop() != pag.getCurrentTop()) - pag << Paginator::Page(pag.getStartTop(), pag.getStartTop() + pag.getPageHeight()); + // insert last page + if (pag.getStartTop() != pag.getCurrentTop()) + pag << Paginator::Page(pag.getStartTop(), pag.getStartTop() + pag.getPageHeight()); - paper->setSize(paper->getWidth(), pag.getCurrentTop()); + paper->setSize(paper->getWidth(), pag.getCurrentTop()); - return pag.getPages(); - } + return pag.getPages(); + } - Paginator::Pages BookFormatter::markupToWidget(MyGUI::Widget * parent, const std::string & markup) - { - return markupToWidget(parent, markup, parent->getWidth(), parent->getHeight()); - } + Paginator::Pages BookFormatter::markupToWidget(MyGUI::Widget* parent, const std::string& markup) + { + return markupToWidget(parent, markup, parent->getWidth(), parent->getHeight()); + } - void BookFormatter::resetFontProperties() - { - mTextStyle = TextStyle(); - } + void BookFormatter::resetFontProperties() + { + mTextStyle = TextStyle(); + } - void BookFormatter::handleDiv(const BookTextParser::Attributes & attr) - { - if (attr.find("align") == attr.end()) - return; + void BookFormatter::handleDiv(const BookTextParser::Attributes& attr) + { + if (attr.find("align") == attr.end()) + return; - std::string align = attr.at("align"); + std::string align = attr.at("align"); - if (Misc::StringUtils::ciEqual(align, "center")) - mBlockStyle.mAlign = MyGUI::Align::HCenter; - else if (Misc::StringUtils::ciEqual(align, "left")) - mBlockStyle.mAlign = MyGUI::Align::Left; - else if (Misc::StringUtils::ciEqual(align, "right")) - mBlockStyle.mAlign = MyGUI::Align::Right; - } + if (Misc::StringUtils::ciEqual(align, "center")) + mBlockStyle.mAlign = MyGUI::Align::HCenter; + else if (Misc::StringUtils::ciEqual(align, "left")) + mBlockStyle.mAlign = MyGUI::Align::Left; + else if (Misc::StringUtils::ciEqual(align, "right")) + mBlockStyle.mAlign = MyGUI::Align::Right; + } - void BookFormatter::handleFont(const BookTextParser::Attributes & attr) + void BookFormatter::handleFont(const BookTextParser::Attributes& attr) + { + if (attr.find("color") != attr.end()) { - if (attr.find("color") != attr.end()) - { - unsigned int color; - std::stringstream ss; - ss << attr.at("color"); - ss >> std::hex >> color; - - mTextStyle.mColour = MyGUI::Colour( - (color>>16 & 0xFF) / 255.f, - (color>>8 & 0xFF) / 255.f, - (color & 0xFF) / 255.f); - } - if (attr.find("face") != attr.end()) - { - std::string face = attr.at("face"); - std::string name = Gui::FontLoader::getFontForFace(face); - - mTextStyle.mFont = "Journalbook "+name; - } - if (attr.find("size") != attr.end()) - { - /// \todo - } - } + unsigned int color; + std::stringstream ss; + ss << attr.at("color"); + ss >> std::hex >> color; - /* GraphicElement */ - GraphicElement::GraphicElement(MyGUI::Widget * parent, Paginator & pag, const BlockStyle & blockStyle) - : mParent(parent), mPaginator(pag), mBlockStyle(blockStyle) - { + mTextStyle.mColour + = MyGUI::Colour((color >> 16 & 0xFF) / 255.f, (color >> 8 & 0xFF) / 255.f, (color & 0xFF) / 255.f); } - - void GraphicElement::paginate() + if (attr.find("face") != attr.end()) { - int newTop = mPaginator.getCurrentTop() + getHeight(); - while (newTop-mPaginator.getStartTop() > mPaginator.getPageHeight()) - { - int newStartTop = pageSplit(); - mPaginator << Paginator::Page(mPaginator.getStartTop(), newStartTop); - mPaginator.setStartTop(newStartTop); - } + std::string face = attr.at("face"); + std::string name = Gui::FontLoader::getFontForFace(face); - mPaginator.setCurrentTop(newTop); + mTextStyle.mFont = "Journalbook " + name; } - - int GraphicElement::pageSplit() + if (attr.find("size") != attr.end()) { - return mPaginator.getStartTop() + mPaginator.getPageHeight(); + /// \todo } + } - /* TextElement */ - TextElement::TextElement(MyGUI::Widget * parent, Paginator & pag, const BlockStyle & blockStyle, - const TextStyle & textStyle, const std::string & text) - : GraphicElement(parent, pag, blockStyle), - mTextStyle(textStyle) - { - Gui::EditBox* box = parent->createWidget("NormalText", - MyGUI::IntCoord(0, pag.getCurrentTop(), pag.getPageWidth(), 0), MyGUI::Align::Left | MyGUI::Align::Top, - parent->getName() + MyGUI::utility::toString(parent->getChildCount())); - box->setEditStatic(true); - box->setEditMultiLine(true); - box->setEditWordWrap(true); - box->setNeedMouseFocus(false); - box->setNeedKeyFocus(false); - box->setMaxTextLength(text.size()); - box->setTextAlign(mBlockStyle.mAlign); - box->setTextColour(mTextStyle.mColour); - box->setFontName(mTextStyle.mFont); - box->setCaption(MyGUI::TextIterator::toTagsString(text)); - box->setSize(box->getSize().width, box->getTextSize().height); - mEditBox = box; - } + /* GraphicElement */ + GraphicElement::GraphicElement(MyGUI::Widget* parent, Paginator& pag, const BlockStyle& blockStyle) + : mParent(parent) + , mPaginator(pag) + , mBlockStyle(blockStyle) + { + } - int TextElement::getHeight() + void GraphicElement::paginate() + { + int newTop = mPaginator.getCurrentTop() + getHeight(); + while (newTop - mPaginator.getStartTop() > mPaginator.getPageHeight()) { - return mEditBox->getTextSize().height; + int newStartTop = pageSplit(); + mPaginator << Paginator::Page(mPaginator.getStartTop(), newStartTop); + mPaginator.setStartTop(newStartTop); } - int TextElement::pageSplit() + mPaginator.setCurrentTop(newTop); + } + + int GraphicElement::pageSplit() + { + return mPaginator.getStartTop() + mPaginator.getPageHeight(); + } + + /* TextElement */ + TextElement::TextElement(MyGUI::Widget* parent, Paginator& pag, const BlockStyle& blockStyle, + const TextStyle& textStyle, const std::string& text) + : GraphicElement(parent, pag, blockStyle) + , mTextStyle(textStyle) + { + Gui::EditBox* box = parent->createWidget("NormalText", + MyGUI::IntCoord(0, pag.getCurrentTop(), pag.getPageWidth(), 0), MyGUI::Align::Left | MyGUI::Align::Top, + parent->getName() + MyGUI::utility::toString(parent->getChildCount())); + box->setEditStatic(true); + box->setEditMultiLine(true); + box->setEditWordWrap(true); + box->setNeedMouseFocus(false); + box->setNeedKeyFocus(false); + box->setMaxTextLength(text.size()); + box->setTextAlign(mBlockStyle.mAlign); + box->setTextColour(mTextStyle.mColour); + box->setFontName(mTextStyle.mFont); + box->setCaption(MyGUI::TextIterator::toTagsString(text)); + box->setSize(box->getSize().width, box->getTextSize().height); + mEditBox = box; + } + + int TextElement::getHeight() + { + return mEditBox->getTextSize().height; + } + + int TextElement::pageSplit() + { + // split lines + const int lineHeight = MWBase::Environment::get().getWindowManager()->getFontHeight(); + unsigned int lastLine = (mPaginator.getStartTop() + mPaginator.getPageHeight() - mPaginator.getCurrentTop()); + if (lineHeight > 0) + lastLine /= lineHeight; + int ret = mPaginator.getCurrentTop() + lastLine * lineHeight; + + // first empty lines that would go to the next page should be ignored + mPaginator.setIgnoreLeadingEmptyLines(true); + + const MyGUI::VectorLineInfo& lines = mEditBox->getSubWidgetText()->castType()->getLineInfo(); + for (unsigned int i = lastLine; i < lines.size(); ++i) { - // split lines - const int lineHeight = MWBase::Environment::get().getWindowManager()->getFontHeight(); - unsigned int lastLine = (mPaginator.getStartTop() + mPaginator.getPageHeight() - mPaginator.getCurrentTop()); - if (lineHeight > 0) - lastLine /= lineHeight; - int ret = mPaginator.getCurrentTop() + lastLine * lineHeight; - - // first empty lines that would go to the next page should be ignored - mPaginator.setIgnoreLeadingEmptyLines(true); - - const MyGUI::VectorLineInfo & lines = mEditBox->getSubWidgetText()->castType()->getLineInfo(); - for (unsigned int i = lastLine; i < lines.size(); ++i) + if (lines[i].width == 0) + ret += lineHeight; + else { - if (lines[i].width == 0) - ret += lineHeight; - else - { - mPaginator.setIgnoreLeadingEmptyLines(false); - break; - } + mPaginator.setIgnoreLeadingEmptyLines(false); + break; } - return ret; } + return ret; + } - /* ImageElement */ - ImageElement::ImageElement(MyGUI::Widget * parent, Paginator & pag, const BlockStyle & blockStyle, - const std::string & src, int width, int height) - : GraphicElement(parent, pag, blockStyle), - mImageHeight(height) - { - int left = 0; - if (mBlockStyle.mAlign.isHCenter()) - left += (pag.getPageWidth() - width) / 2; - else if (mBlockStyle.mAlign.isLeft()) - left = 0; - else if (mBlockStyle.mAlign.isRight()) - left += pag.getPageWidth() - width; - - mImageBox = parent->createWidget ("ImageBox", - MyGUI::IntCoord(left, pag.getCurrentTop(), width, mImageHeight), MyGUI::Align::Left | MyGUI::Align::Top, - parent->getName() + MyGUI::utility::toString(parent->getChildCount())); - - mImageBox->setImageTexture(src); - mImageBox->setProperty("NeedMouse", "false"); - } + /* ImageElement */ + ImageElement::ImageElement(MyGUI::Widget* parent, Paginator& pag, const BlockStyle& blockStyle, + const std::string& src, int width, int height) + : GraphicElement(parent, pag, blockStyle) + , mImageHeight(height) + { + int left = 0; + if (mBlockStyle.mAlign.isHCenter()) + left += (pag.getPageWidth() - width) / 2; + else if (mBlockStyle.mAlign.isLeft()) + left = 0; + else if (mBlockStyle.mAlign.isRight()) + left += pag.getPageWidth() - width; + + mImageBox = parent->createWidget("ImageBox", + MyGUI::IntCoord(left, pag.getCurrentTop(), width, mImageHeight), MyGUI::Align::Left | MyGUI::Align::Top, + parent->getName() + MyGUI::utility::toString(parent->getChildCount())); + + mImageBox->setImageTexture(src); + mImageBox->setProperty("NeedMouse", "false"); + } - int ImageElement::getHeight() - { - return mImageHeight; - } + int ImageElement::getHeight() + { + return mImageHeight; + } - int ImageElement::pageSplit() - { - // if the image is larger than the page, fall back to the default pageSplit implementation - if (mImageHeight > mPaginator.getPageHeight()) - return GraphicElement::pageSplit(); - return mPaginator.getCurrentTop(); - } + int ImageElement::pageSplit() + { + // if the image is larger than the page, fall back to the default pageSplit implementation + if (mImageHeight > mPaginator.getPageHeight()) + return GraphicElement::pageSplit(); + return mPaginator.getCurrentTop(); } +} diff --git a/apps/openmw/mwgui/formatting.hpp b/apps/openmw/mwgui/formatting.hpp index 387acd58c8..421bda6f1d 100644 --- a/apps/openmw/mwgui/formatting.hpp +++ b/apps/openmw/mwgui/formatting.hpp @@ -12,8 +12,8 @@ namespace MWGui { struct TextStyle { - TextStyle() : - mColour(0,0,0) + TextStyle() + : mColour(0, 0, 0) , mFont("Journalbook DefaultFont") , mTextSize(16) { @@ -26,8 +26,8 @@ namespace MWGui struct BlockStyle { - BlockStyle() : - mAlign(MyGUI::Align::Left | MyGUI::Align::Top) + BlockStyle() + : mAlign(MyGUI::Align::Left | MyGUI::Align::Top) { } @@ -36,140 +36,144 @@ namespace MWGui class BookTextParser { - public: - typedef std::map Attributes; - enum Events - { - Event_None = -2, - Event_EOF = -1, - Event_BrTag, - Event_PTag, - Event_ImgTag, - Event_DivTag, - Event_FontTag - }; - - BookTextParser(const std::string & text); - - Events next(); - - const Attributes & getAttributes() const; - std::string getReadyText() const; - bool isClosingTag() const; - - private: - void registerTag(const std::string & tag, Events type); - void flushBuffer(); - void parseTag(std::string tag); - - size_t mIndex; - std::string mText; - std::string mReadyText; - - bool mIgnoreNewlineTags; - bool mIgnoreLineEndings; - Attributes mAttributes; - std::string mTag; - bool mClosingTag; - std::map mTagTypes; - std::string mBuffer; - - size_t mPlainTextEnd; + public: + typedef std::map Attributes; + enum Events + { + Event_None = -2, + Event_EOF = -1, + Event_BrTag, + Event_PTag, + Event_ImgTag, + Event_DivTag, + Event_FontTag + }; + + BookTextParser(const std::string& text); + + Events next(); + + const Attributes& getAttributes() const; + std::string getReadyText() const; + bool isClosingTag() const; + + private: + void registerTag(const std::string& tag, Events type); + void flushBuffer(); + void parseTag(std::string tag); + + size_t mIndex; + std::string mText; + std::string mReadyText; + + bool mIgnoreNewlineTags; + bool mIgnoreLineEndings; + Attributes mAttributes; + std::string mTag; + bool mClosingTag; + std::map mTagTypes; + std::string mBuffer; + + size_t mPlainTextEnd; }; class Paginator { - public: - typedef std::pair Page; - typedef std::vector Pages; - - Paginator(int pageWidth, int pageHeight) - : mStartTop(0), mCurrentTop(0), - mPageWidth(pageWidth), mPageHeight(pageHeight), - mIgnoreLeadingEmptyLines(false) - { - } - - int getStartTop() const { return mStartTop; } - int getCurrentTop() const { return mCurrentTop; } - int getPageWidth() const { return mPageWidth; } - int getPageHeight() const { return mPageHeight; } - bool getIgnoreLeadingEmptyLines() const { return mIgnoreLeadingEmptyLines; } - Pages getPages() const { return mPages; } - - void setStartTop(int top) { mStartTop = top; } - void setCurrentTop(int top) { mCurrentTop = top; } - void setIgnoreLeadingEmptyLines(bool ignore) { mIgnoreLeadingEmptyLines = ignore; } - - Paginator & operator<<(const Page & page) - { - mPages.push_back(page); - return *this; - } - - private: - int mStartTop, mCurrentTop; - int mPageWidth, mPageHeight; - bool mIgnoreLeadingEmptyLines; - Pages mPages; + public: + typedef std::pair Page; + typedef std::vector Pages; + + Paginator(int pageWidth, int pageHeight) + : mStartTop(0) + , mCurrentTop(0) + , mPageWidth(pageWidth) + , mPageHeight(pageHeight) + , mIgnoreLeadingEmptyLines(false) + { + } + + int getStartTop() const { return mStartTop; } + int getCurrentTop() const { return mCurrentTop; } + int getPageWidth() const { return mPageWidth; } + int getPageHeight() const { return mPageHeight; } + bool getIgnoreLeadingEmptyLines() const { return mIgnoreLeadingEmptyLines; } + Pages getPages() const { return mPages; } + + void setStartTop(int top) { mStartTop = top; } + void setCurrentTop(int top) { mCurrentTop = top; } + void setIgnoreLeadingEmptyLines(bool ignore) { mIgnoreLeadingEmptyLines = ignore; } + + Paginator& operator<<(const Page& page) + { + mPages.push_back(page); + return *this; + } + + private: + int mStartTop, mCurrentTop; + int mPageWidth, mPageHeight; + bool mIgnoreLeadingEmptyLines; + Pages mPages; }; /// \brief utilities for parsing book/scroll text as mygui widgets class BookFormatter { - public: - Paginator::Pages markupToWidget(MyGUI::Widget * parent, const std::string & markup, const int pageWidth, const int pageHeight); - Paginator::Pages markupToWidget(MyGUI::Widget * parent, const std::string & markup); + public: + Paginator::Pages markupToWidget( + MyGUI::Widget* parent, const std::string& markup, const int pageWidth, const int pageHeight); + Paginator::Pages markupToWidget(MyGUI::Widget* parent, const std::string& markup); - private: - void resetFontProperties(); + private: + void resetFontProperties(); - void handleDiv(const BookTextParser::Attributes & attr); - void handleFont(const BookTextParser::Attributes & attr); + void handleDiv(const BookTextParser::Attributes& attr); + void handleFont(const BookTextParser::Attributes& attr); - TextStyle mTextStyle; - BlockStyle mBlockStyle; + TextStyle mTextStyle; + BlockStyle mBlockStyle; }; class GraphicElement { - public: - GraphicElement(MyGUI::Widget * parent, Paginator & pag, const BlockStyle & blockStyle); - virtual int getHeight() = 0; - virtual void paginate(); - virtual int pageSplit(); - - protected: - virtual ~GraphicElement() {} - MyGUI::Widget * mParent; - Paginator & mPaginator; - BlockStyle mBlockStyle; + public: + GraphicElement(MyGUI::Widget* parent, Paginator& pag, const BlockStyle& blockStyle); + virtual int getHeight() = 0; + virtual void paginate(); + virtual int pageSplit(); + + protected: + virtual ~GraphicElement() {} + MyGUI::Widget* mParent; + Paginator& mPaginator; + BlockStyle mBlockStyle; }; class TextElement : public GraphicElement { - public: - TextElement(MyGUI::Widget * parent, Paginator & pag, const BlockStyle & blockStyle, - const TextStyle & textStyle, const std::string & text); - int getHeight() override; - int pageSplit() override; - private: - int currentFontHeight() const; - TextStyle mTextStyle; - Gui::EditBox * mEditBox; + public: + TextElement(MyGUI::Widget* parent, Paginator& pag, const BlockStyle& blockStyle, const TextStyle& textStyle, + const std::string& text); + int getHeight() override; + int pageSplit() override; + + private: + int currentFontHeight() const; + TextStyle mTextStyle; + Gui::EditBox* mEditBox; }; class ImageElement : public GraphicElement { - public: - ImageElement(MyGUI::Widget * parent, Paginator & pag, const BlockStyle & blockStyle, - const std::string & src, int width, int height); - int getHeight() override; - int pageSplit() override; - - private: - int mImageHeight; - MyGUI::ImageBox * mImageBox; + public: + ImageElement(MyGUI::Widget* parent, Paginator& pag, const BlockStyle& blockStyle, const std::string& src, + int width, int height); + int getHeight() override; + int pageSplit() override; + + private: + int mImageHeight; + MyGUI::ImageBox* mImageBox; }; } } diff --git a/apps/openmw/mwgui/hud.cpp b/apps/openmw/mwgui/hud.cpp index d2a2b8f320..0b33668920 100644 --- a/apps/openmw/mwgui/hud.cpp +++ b/apps/openmw/mwgui/hud.cpp @@ -1,17 +1,17 @@ #include "hud.hpp" -#include -#include #include -#include #include +#include +#include +#include #include -#include -#include -#include #include #include +#include +#include +#include #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" @@ -20,13 +20,13 @@ #include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" -#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/actorutil.hpp" +#include "../mwmechanics/npcstats.hpp" +#include "draganddrop.hpp" #include "inventorywindow.hpp" -#include "spellicons.hpp" #include "itemmodel.hpp" -#include "draganddrop.hpp" +#include "spellicons.hpp" #include "itemwidget.hpp" @@ -39,9 +39,13 @@ namespace MWGui class WorldItemModel : public ItemModel { public: - WorldItemModel(float left, float top) : mLeft(left), mTop(top) {} + WorldItemModel(float left, float top) + : mLeft(left) + , mTop(top) + { + } virtual ~WorldItemModel() override {} - MWWorld::Ptr copyItem (const ItemStack& item, size_t count, bool /*allowAutoEquip*/) override + MWWorld::Ptr copyItem(const ItemStack& item, size_t count, bool /*allowAutoEquip*/) override { MWBase::World* world = MWBase::Environment::get().getWorld(); @@ -55,11 +59,14 @@ namespace MWGui return dropped; } - void removeItem (const ItemStack& item, size_t count) override { throw std::runtime_error("removeItem not implemented"); } - ModelIndex getIndex (const ItemStack &item) override { throw std::runtime_error("getIndex not implemented"); } + void removeItem(const ItemStack& item, size_t count) override + { + throw std::runtime_error("removeItem not implemented"); + } + ModelIndex getIndex(const ItemStack& item) override { throw std::runtime_error("getIndex not implemented"); } void update() override {} size_t getItemCount() override { return 0; } - ItemStack getItem (ModelIndex index) override { throw std::runtime_error("getItem not implemented"); } + ItemStack getItem(ModelIndex index) override { throw std::runtime_error("getItem not implemented"); } bool usesContainer(const MWWorld::Ptr&) override { return false; } private: @@ -68,8 +75,7 @@ namespace MWGui float mTop; }; - - HUD::HUD(CustomMarkerCollection &customMarkers, DragAndDrop* dragAndDrop, MWRender::LocalMap* localMapRender) + HUD::HUD(CustomMarkerCollection& customMarkers, DragAndDrop* dragAndDrop, MWRender::LocalMap* localMapRender) : WindowBase("openmw_hud.layout") , LocalMapBase(customMarkers, localMapRender, Settings::Manager::getBool("local map hud fog of war", "Map")) , mHealth(nullptr) @@ -119,7 +125,7 @@ namespace MWGui magickaFrame->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onHMSClicked); fatigueFrame->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onHMSClicked); - //Drowning bar + // Drowning bar getWidget(mDrowningBar, "DrowningBar"); getWidget(mDrowningFrame, "DrowningFrame"); getWidget(mDrowning, "Drowning"); @@ -229,22 +235,21 @@ namespace MWGui void HUD::onWorldClicked(MyGUI::Widget* _sender) { - if (!MWBase::Environment::get().getWindowManager ()->isGuiMode ()) + if (!MWBase::Environment::get().getWindowManager()->isGuiMode()) return; - MWBase::WindowManager *winMgr = MWBase::Environment::get().getWindowManager(); + MWBase::WindowManager* winMgr = MWBase::Environment::get().getWindowManager(); if (mDragAndDrop->mIsOnDragAndDrop) { // drop item into the gameworld - MWBase::Environment::get().getWorld()->breakInvisibility( - MWMechanics::getPlayer()); + MWBase::Environment::get().getWorld()->breakInvisibility(MWMechanics::getPlayer()); MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize(); MyGUI::IntPoint cursorPosition = MyGUI::InputManager::getInstance().getMousePosition(); float mouseX = cursorPosition.left / float(viewSize.width); float mouseY = cursorPosition.top / float(viewSize.height); - WorldItemModel drop (mouseX, mouseY); + WorldItemModel drop(mouseX, mouseY); mDragAndDrop->drop(&drop, nullptr); winMgr->changePointer("arrow"); @@ -260,7 +265,7 @@ namespace MWGui if (winMgr->isConsoleMode()) winMgr->setConsoleSelectedObject(object); - else //if ((mode == GM_Container) || (mode == GM_Inventory)) + else // if ((mode == GM_Container) || (mode == GM_Inventory)) { // pick up object if (!object.isEmpty()) @@ -289,7 +294,6 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->changePointer("drop_ground"); else MWBase::Environment::get().getWindowManager()->changePointer("arrow"); - } else { @@ -365,7 +369,7 @@ namespace MWGui if (mEnemyHealth->getVisible() && mEnemyHealthTimer < 0) { mEnemyHealth->setVisible(false); - mWeaponSpellBox->setPosition(mWeaponSpellBox->getPosition() + MyGUI::IntPoint(0,20)); + mWeaponSpellBox->setPosition(mWeaponSpellBox->getPosition() + MyGUI::IntPoint(0, 20)); } mSpellIcons->updateWidgets(mEffectBox, true); @@ -376,11 +380,12 @@ namespace MWGui } if (mDrowningBar->getVisible()) - mDrowningBar->setPosition(mMainWidget->getWidth()/2 - mDrowningFrame->getWidth()/2, mMainWidget->getTop()); + mDrowningBar->setPosition( + mMainWidget->getWidth() / 2 - mDrowningFrame->getWidth() / 2, mMainWidget->getTop()); if (mIsDrowning) { - mDrowningFlashTheta += dt * osg::PI*2; + mDrowningFlashTheta += dt * osg::PI * 2; float intensity = (cos(mDrowningFlashTheta) + 2.0f) / 3.0f; @@ -390,8 +395,7 @@ namespace MWGui void HUD::setSelectedSpell(const std::string& spellId, int successChancePercent) { - const ESM::Spell* spell = - MWBase::Environment::get().getWorld()->getStore().get().find(spellId); + const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get().find(spellId); const std::string& spellName = spell->mName; if (spellName != mSpellName && mSpellVisible) @@ -409,12 +413,12 @@ namespace MWGui mSpellBox->setUserString("Spell", spellId); // use the icon of the first effect - const ESM::MagicEffect* effect = - MWBase::Environment::get().getWorld()->getStore().get().find(spell->mEffects.mList.front().mEffectID); + const ESM::MagicEffect* effect = MWBase::Environment::get().getWorld()->getStore().get().find( + spell->mEffects.mList.front().mEffectID); std::string icon = effect->mIcon; int slashPos = icon.rfind('\\'); - icon.insert(slashPos+1, "b_"); + icon.insert(slashPos + 1, "b_"); icon = Misc::ResourceHelpers::correctIconPath(icon, MWBase::Environment::get().getResourceSystem()->getVFS()); mSpellImage->setSpellIcon(icon); @@ -492,11 +496,12 @@ namespace MWGui mWeapStatus->setProgressRange(100); mWeapStatus->setProgressPosition(0); - MWBase::World *world = MWBase::Environment::get().getWorld(); + MWBase::World* world = MWBase::Environment::get().getWorld(); MWWorld::Ptr player = world->getPlayerPtr(); mWeapImage->setItem(MWWorld::Ptr()); - std::string icon = (player.getClass().getNpcStats(player).isWerewolf()) ? "icons\\k\\tx_werewolf_hand.dds" : "icons\\k\\stealth_handtohand.dds"; + std::string icon = (player.getClass().getNpcStats(player).isWerewolf()) ? "icons\\k\\tx_werewolf_hand.dds" + : "icons\\k\\stealth_handtohand.dds"; mWeapImage->setIcon(icon); mWeapBox->clearUserStrings(); @@ -508,12 +513,12 @@ namespace MWGui void HUD::setCrosshairVisible(bool visible) { - mCrosshair->setVisible (visible); + mCrosshair->setVisible(visible); } - + void HUD::setCrosshairOwned(bool owned) { - if(owned) + if (owned) { mCrosshair->changeWidgetSkin("HUD_Crosshair_Owned"); } @@ -522,7 +527,7 @@ namespace MWGui mCrosshair->changeWidgetSkin("HUD_Crosshair"); } } - + void HUD::setHmsVisible(bool visible) { mHealth->setVisible(visible); @@ -551,13 +556,13 @@ namespace MWGui void HUD::setEffectVisible(bool visible) { - mEffectBox->setVisible (visible); + mEffectBox->setVisible(visible); updatePositions(); } void HUD::setMinimapVisible(bool visible) { - mMinimapBox->setVisible (visible); + mMinimapBox->setVisible(visible); updatePositions(); } @@ -589,14 +594,15 @@ namespace MWGui // effect box can have variable width -> variable left coordinate int effectsDx = 0; - if (!mMinimapBox->getVisible ()) + if (!mMinimapBox->getVisible()) effectsDx = mEffectBoxBaseRight - mMinimapBoxBaseRight; - mMapVisible = mMinimapBox->getVisible (); + mMapVisible = mMinimapBox->getVisible(); if (!mMapVisible) mCellNameBox->setVisible(false); - mEffectBox->setPosition((viewSize.width - mEffectBoxBaseRight) - mEffectBox->getWidth() + effectsDx, mEffectBox->getTop()); + mEffectBox->setPosition( + (viewSize.width - mEffectBoxBaseRight) - mEffectBox->getWidth() + effectsDx, mEffectBox->getTop()); } void HUD::updateEnemyHealthBar() @@ -610,18 +616,27 @@ namespace MWGui // Therefore any value < 1 should show as an empty health bar. We do the same in statswindow :) mEnemyHealth->setProgressPosition(static_cast(stats.getHealth().getRatio() * 100)); - static const float fNPCHealthBarFade = MWBase::Environment::get().getWorld()->getStore().get().find("fNPCHealthBarFade")->mValue.getFloat(); + static const float fNPCHealthBarFade = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fNPCHealthBarFade") + ->mValue.getFloat(); if (fNPCHealthBarFade > 0.f) mEnemyHealth->setAlpha(std::clamp(mEnemyHealthTimer / fNPCHealthBarFade, 0.f, 1.f)); - } - void HUD::setEnemy(const MWWorld::Ptr &enemy) + void HUD::setEnemy(const MWWorld::Ptr& enemy) { mEnemyActorId = enemy.getClass().getCreatureStats(enemy).getActorId(); - mEnemyHealthTimer = MWBase::Environment::get().getWorld()->getStore().get().find("fNPCHealthBarTime")->mValue.getFloat(); + mEnemyHealthTimer = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fNPCHealthBarTime") + ->mValue.getFloat(); if (!mEnemyHealth->getVisible()) - mWeaponSpellBox->setPosition(mWeaponSpellBox->getPosition() - MyGUI::IntPoint(0,20)); + mWeaponSpellBox->setPosition(mWeaponSpellBox->getPosition() - MyGUI::IntPoint(0, 20)); mEnemyHealth->setVisible(true); updateEnemyHealthBar(); } @@ -639,12 +654,12 @@ namespace MWGui resetEnemy(); } - void HUD::customMarkerCreated(MyGUI::Widget *marker) + void HUD::customMarkerCreated(MyGUI::Widget* marker) { marker->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMapClicked); } - void HUD::doorMarkerCreated(MyGUI::Widget *marker) + void HUD::doorMarkerCreated(MyGUI::Widget* marker) { marker->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMapClicked); } diff --git a/apps/openmw/mwgui/hud.hpp b/apps/openmw/mwgui/hud.hpp index aacca60a52..3285aa307f 100644 --- a/apps/openmw/mwgui/hud.hpp +++ b/apps/openmw/mwgui/hud.hpp @@ -23,7 +23,7 @@ namespace MWGui public: HUD(CustomMarkerCollection& customMarkers, DragAndDrop* dragAndDrop, MWRender::LocalMap* localMapRender); virtual ~HUD(); - void setValue (const std::string& id, const MWMechanics::DynamicStat& value) override; + void setValue(const std::string& id, const MWMechanics::DynamicStat& value) override; /// Set time left for the player to start drowning /// @param time time left to start drowning @@ -66,8 +66,8 @@ namespace MWGui MyGUI::ProgressBar *mHealth, *mMagicka, *mStamina, *mEnemyHealth, *mDrowning; MyGUI::Widget* mHealthFrame; MyGUI::Widget *mWeapBox, *mSpellBox, *mSneakBox; - ItemWidget *mWeapImage; - SpellWidget *mSpellImage; + ItemWidget* mWeapImage; + SpellWidget* mSpellImage; MyGUI::ProgressBar *mWeapStatus, *mSpellStatus; MyGUI::Widget *mEffectBox, *mMinimapBox; MyGUI::Button* mMinimapButton; @@ -102,7 +102,7 @@ namespace MWGui int mEnemyActorId; float mEnemyHealthTimer; - bool mIsDrowning; + bool mIsDrowning; float mDrowningFlashTheta; void onWorldClicked(MyGUI::Widget* _sender); diff --git a/apps/openmw/mwgui/inventoryitemmodel.cpp b/apps/openmw/mwgui/inventoryitemmodel.cpp index f96cfd865e..77799d4278 100644 --- a/apps/openmw/mwgui/inventoryitemmodel.cpp +++ b/apps/openmw/mwgui/inventoryitemmodel.cpp @@ -5,8 +5,8 @@ #include "../mwmechanics/actorutil.hpp" #include "../mwmechanics/npcstats.hpp" -#include "../mwworld/containerstore.hpp" #include "../mwworld/class.hpp" +#include "../mwworld/containerstore.hpp" #include "../mwworld/inventorystore.hpp" #include "../mwbase/environment.hpp" @@ -15,125 +15,127 @@ namespace MWGui { -InventoryItemModel::InventoryItemModel(const MWWorld::Ptr &actor) - : mActor(actor) -{ -} - -ItemStack InventoryItemModel::getItem (ModelIndex index) -{ - if (index < 0) - throw std::runtime_error("Invalid index supplied"); - if (mItems.size() <= static_cast(index)) - throw std::runtime_error("Item index out of range"); - return mItems[index]; -} - -size_t InventoryItemModel::getItemCount() -{ - return mItems.size(); -} - -ItemModel::ModelIndex InventoryItemModel::getIndex (const ItemStack& item) -{ - size_t i = 0; - for (ItemStack& itemStack : mItems) + InventoryItemModel::InventoryItemModel(const MWWorld::Ptr& actor) + : mActor(actor) { - if (itemStack == item) - return i; - ++i; } - return -1; -} - -MWWorld::Ptr InventoryItemModel::copyItem (const ItemStack& item, size_t count, bool allowAutoEquip) -{ - if (item.mBase.getContainerStore() == &mActor.getClass().getContainerStore(mActor)) - throw std::runtime_error("Item to copy needs to be from a different container!"); - return *mActor.getClass().getContainerStore(mActor).add(item.mBase, count, mActor, allowAutoEquip); -} -void InventoryItemModel::removeItem (const ItemStack& item, size_t count) -{ - int removed = 0; - // Re-equipping makes sense only if a target has inventory - if (mActor.getClass().hasInventoryStore(mActor)) + ItemStack InventoryItemModel::getItem(ModelIndex index) { - MWWorld::InventoryStore& store = mActor.getClass().getInventoryStore(mActor); - removed = store.remove(item.mBase, count, mActor, true); + if (index < 0) + throw std::runtime_error("Invalid index supplied"); + if (mItems.size() <= static_cast(index)) + throw std::runtime_error("Item index out of range"); + return mItems[index]; } - else + + size_t InventoryItemModel::getItemCount() { - MWWorld::ContainerStore& store = mActor.getClass().getContainerStore(mActor); - removed = store.remove(item.mBase, count, mActor); + return mItems.size(); } - std::stringstream error; - - if (removed == 0) + ItemModel::ModelIndex InventoryItemModel::getIndex(const ItemStack& item) { - error << "Item '" << item.mBase.getCellRef().getRefId() << "' was not found in container store to remove"; - throw std::runtime_error(error.str()); + size_t i = 0; + for (ItemStack& itemStack : mItems) + { + if (itemStack == item) + return i; + ++i; + } + return -1; } - else if (removed < static_cast(count)) + + MWWorld::Ptr InventoryItemModel::copyItem(const ItemStack& item, size_t count, bool allowAutoEquip) { - error << "Not enough items '" << item.mBase.getCellRef().getRefId() << "' in the stack to remove (" << static_cast(count) << " requested, " << removed << " found)"; - throw std::runtime_error(error.str()); + if (item.mBase.getContainerStore() == &mActor.getClass().getContainerStore(mActor)) + throw std::runtime_error("Item to copy needs to be from a different container!"); + return *mActor.getClass().getContainerStore(mActor).add(item.mBase, count, mActor, allowAutoEquip); } -} - -MWWorld::Ptr InventoryItemModel::moveItem(const ItemStack &item, size_t count, ItemModel *otherModel) -{ - // Can't move conjured items: This is a general fix that also takes care of issues with taking conjured items via the 'Take All' button. - if (item.mFlags & ItemStack::Flag_Bound) - return MWWorld::Ptr(); - MWWorld::Ptr ret = otherModel->copyItem(item, count); - removeItem(item, count); - return ret; -} + void InventoryItemModel::removeItem(const ItemStack& item, size_t count) + { + int removed = 0; + // Re-equipping makes sense only if a target has inventory + if (mActor.getClass().hasInventoryStore(mActor)) + { + MWWorld::InventoryStore& store = mActor.getClass().getInventoryStore(mActor); + removed = store.remove(item.mBase, count, mActor, true); + } + else + { + MWWorld::ContainerStore& store = mActor.getClass().getContainerStore(mActor); + removed = store.remove(item.mBase, count, mActor); + } -void InventoryItemModel::update() -{ - MWWorld::ContainerStore& store = mActor.getClass().getContainerStore(mActor); + std::stringstream error; - mItems.clear(); + if (removed == 0) + { + error << "Item '" << item.mBase.getCellRef().getRefId() << "' was not found in container store to remove"; + throw std::runtime_error(error.str()); + } + else if (removed < static_cast(count)) + { + error << "Not enough items '" << item.mBase.getCellRef().getRefId() << "' in the stack to remove (" + << static_cast(count) << " requested, " << removed << " found)"; + throw std::runtime_error(error.str()); + } + } - for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it) + MWWorld::Ptr InventoryItemModel::moveItem(const ItemStack& item, size_t count, ItemModel* otherModel) { - MWWorld::Ptr item = *it; + // Can't move conjured items: This is a general fix that also takes care of issues with taking conjured items + // via the 'Take All' button. + if (item.mFlags & ItemStack::Flag_Bound) + return MWWorld::Ptr(); + + MWWorld::Ptr ret = otherModel->copyItem(item, count); + removeItem(item, count); + return ret; + } - if (!item.getClass().showsInInventory(item)) - continue; + void InventoryItemModel::update() + { + MWWorld::ContainerStore& store = mActor.getClass().getContainerStore(mActor); - ItemStack newItem (item, this, item.getRefData().getCount()); + mItems.clear(); - if (mActor.getClass().hasInventoryStore(mActor)) + for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it) { - MWWorld::InventoryStore& invStore = mActor.getClass().getInventoryStore(mActor); - if (invStore.isEquipped(newItem.mBase)) - newItem.mType = ItemStack::Type_Equipped; - } + MWWorld::Ptr item = *it; + + if (!item.getClass().showsInInventory(item)) + continue; - mItems.push_back(newItem); + ItemStack newItem(item, this, item.getRefData().getCount()); + + if (mActor.getClass().hasInventoryStore(mActor)) + { + MWWorld::InventoryStore& invStore = mActor.getClass().getInventoryStore(mActor); + if (invStore.isEquipped(newItem.mBase)) + newItem.mType = ItemStack::Type_Equipped; + } + + mItems.push_back(newItem); + } } -} -bool InventoryItemModel::onTakeItem(const MWWorld::Ptr &item, int count) -{ - // Looting a dead corpse is considered OK - if (mActor.getClass().isActor() && mActor.getClass().getCreatureStats(mActor).isDead()) - return true; + bool InventoryItemModel::onTakeItem(const MWWorld::Ptr& item, int count) + { + // Looting a dead corpse is considered OK + if (mActor.getClass().isActor() && mActor.getClass().getCreatureStats(mActor).isDead()) + return true; - MWWorld::Ptr player = MWMechanics::getPlayer(); - MWBase::Environment::get().getMechanicsManager()->itemTaken(player, item, mActor, count); + MWWorld::Ptr player = MWMechanics::getPlayer(); + MWBase::Environment::get().getMechanicsManager()->itemTaken(player, item, mActor, count); - return true; -} + return true; + } -bool InventoryItemModel::usesContainer(const MWWorld::Ptr& container) -{ - return mActor == container; -} + bool InventoryItemModel::usesContainer(const MWWorld::Ptr& container) + { + return mActor == container; + } } diff --git a/apps/openmw/mwgui/inventoryitemmodel.hpp b/apps/openmw/mwgui/inventoryitemmodel.hpp index 87d874c946..b99bfc544d 100644 --- a/apps/openmw/mwgui/inventoryitemmodel.hpp +++ b/apps/openmw/mwgui/inventoryitemmodel.hpp @@ -9,19 +9,19 @@ namespace MWGui class InventoryItemModel : public ItemModel { public: - InventoryItemModel (const MWWorld::Ptr& actor); + InventoryItemModel(const MWWorld::Ptr& actor); - ItemStack getItem (ModelIndex index) override; - ModelIndex getIndex (const ItemStack &item) override; + ItemStack getItem(ModelIndex index) override; + ModelIndex getIndex(const ItemStack& item) override; size_t getItemCount() override; - bool onTakeItem(const MWWorld::Ptr &item, int count) override; + bool onTakeItem(const MWWorld::Ptr& item, int count) override; - MWWorld::Ptr copyItem (const ItemStack& item, size_t count, bool allowAutoEquip = true) override; - void removeItem (const ItemStack& item, size_t count) override; + MWWorld::Ptr copyItem(const ItemStack& item, size_t count, bool allowAutoEquip = true) override; + void removeItem(const ItemStack& item, size_t count) override; /// Move items from this model to \a otherModel. - MWWorld::Ptr moveItem (const ItemStack& item, size_t count, ItemModel* otherModel) override; + MWWorld::Ptr moveItem(const ItemStack& item, size_t count, ItemModel* otherModel) override; void update() override; @@ -29,6 +29,7 @@ namespace MWGui protected: MWWorld::Ptr mActor; + private: std::vector mItems; }; diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index 8a3a72d2b0..7deb91455c 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -3,12 +3,12 @@ #include #include -#include -#include -#include -#include #include #include +#include +#include +#include +#include #include @@ -18,26 +18,26 @@ #include -#include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" -#include "../mwbase/windowmanager.hpp" #include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" -#include "../mwworld/inventorystore.hpp" -#include "../mwworld/class.hpp" #include "../mwworld/actionequip.hpp" +#include "../mwworld/class.hpp" +#include "../mwworld/inventorystore.hpp" -#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/actorutil.hpp" +#include "../mwmechanics/npcstats.hpp" -#include "itemview.hpp" +#include "countdialog.hpp" +#include "draganddrop.hpp" #include "inventoryitemmodel.hpp" +#include "itemview.hpp" #include "sortfilteritemmodel.hpp" +#include "tooltips.hpp" #include "tradeitemmodel.hpp" -#include "countdialog.hpp" #include "tradewindow.hpp" -#include "draganddrop.hpp" -#include "tooltips.hpp" namespace { @@ -55,7 +55,8 @@ namespace namespace MWGui { - InventoryWindow::InventoryWindow(DragAndDrop* dragAndDrop, osg::Group* parent, Resource::ResourceSystem* resourceSystem) + InventoryWindow::InventoryWindow( + DragAndDrop* dragAndDrop, osg::Group* parent, Resource::ResourceSystem* resourceSystem) : WindowPinnableBase("openmw_inventory_window.layout") , mDragAndDrop(dragAndDrop) , mSelectedItem(-1) @@ -68,10 +69,12 @@ namespace MWGui , mTrading(false) , mUpdateTimer(0.f) { - mPreviewTexture = std::make_unique(mPreview->getTexture(), mPreview->getTextureStateSet()); + mPreviewTexture + = std::make_unique(mPreview->getTexture(), mPreview->getTextureStateSet()); mPreview->rebuild(); - mMainWidget->castType()->eventWindowChangeCoord += MyGUI::newDelegate(this, &InventoryWindow::onWindowResize); + mMainWidget->castType()->eventWindowChangeCoord + += MyGUI::newDelegate(this, &InventoryWindow::onWindowResize); getWidget(mAvatar, "Avatar"); getWidget(mAvatarImage, "AvatarImage"); @@ -112,16 +115,14 @@ namespace MWGui { const float aspect = 0.5; // fixed aspect ratio for the avatar image int leftPaneWidth = static_cast((mMainWidget->getSize().height - 44 - mArmorRating->getHeight()) * aspect); - mLeftPane->setSize( leftPaneWidth, mMainWidget->getSize().height-44 ); - mRightPane->setCoord( mLeftPane->getPosition().left + leftPaneWidth + 4, - mRightPane->getPosition().top, - mMainWidget->getSize().width - 12 - leftPaneWidth - 15, - mMainWidget->getSize().height-44 ); + mLeftPane->setSize(leftPaneWidth, mMainWidget->getSize().height - 44); + mRightPane->setCoord(mLeftPane->getPosition().left + leftPaneWidth + 4, mRightPane->getPosition().top, + mMainWidget->getSize().width - 12 - leftPaneWidth - 15, mMainWidget->getSize().height - 44); } void InventoryWindow::updatePlayer() { - mPtr = MWBase::Environment::get().getWorld ()->getPlayerPtr(); + mPtr = MWBase::Environment::get().getWorld()->getPlayerPtr(); auto tradeModel = std::make_unique(std::make_unique(mPtr), MWWorld::Ptr()); mTradeModel = tradeModel.get(); @@ -199,9 +200,9 @@ namespace MWGui MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize(); MyGUI::IntPoint pos(static_cast(Settings::Manager::getFloat(setting + " x", "Windows") * viewSize.width), - static_cast(Settings::Manager::getFloat(setting + " y", "Windows") * viewSize.height)); + static_cast(Settings::Manager::getFloat(setting + " y", "Windows") * viewSize.height)); MyGUI::IntSize size(static_cast(Settings::Manager::getFloat(setting + " w", "Windows") * viewSize.width), - static_cast(Settings::Manager::getFloat(setting + " h", "Windows") * viewSize.height)); + static_cast(Settings::Manager::getFloat(setting + " h", "Windows") * viewSize.height)); bool needUpdate = (size.width != mMainWidget->getWidth() || size.height != mMainWidget->getHeight()); @@ -235,12 +236,12 @@ namespace MWGui mDragAndDrop->drop(mTradeModel, mItemView); } - void InventoryWindow::onItemSelected (int index) + void InventoryWindow::onItemSelected(int index) { - onItemSelectedFromSourceModel (mSortModel->mapToSource(index)); + onItemSelectedFromSourceModel(mSortModel->mapToSource(index)); } - void InventoryWindow::onItemSelectedFromSourceModel (int index) + void InventoryWindow::onItemSelectedFromSourceModel(int index) { if (mDragAndDrop->mIsOnDragAndDrop) { @@ -273,8 +274,7 @@ namespace MWGui if (!object.getClass().canSell(object, services)) { MWBase::Environment::get().getWindowManager()->playSound(sound); - MWBase::Environment::get().getWindowManager()-> - messageBox("#{sBarterDialog4}"); + MWBase::Environment::get().getWindowManager()->messageBox("#{sBarterDialog4}"); return; } } @@ -296,7 +296,7 @@ namespace MWGui { CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog(); std::string message = mTrading ? "#{sQuanityMenuMessage01}" : "#{sTake}"; - std::string name{object.getClass().getName(object)}; + std::string name{ object.getClass().getName(object) }; name += MWGui::ToolTips::getSoulString(object.getCellRef()); dialog->openCountDialog(name, message, count); dialog->eventOkClicked.clear(); @@ -310,9 +310,9 @@ namespace MWGui { mSelectedItem = index; if (mTrading) - sellItem (nullptr, count); + sellItem(nullptr, count); else - dragItem (nullptr, count); + dragItem(nullptr, count); } } @@ -328,11 +328,11 @@ namespace MWGui // since the item pointed does not exist anymore. if (item.mBase != newStack) { - updateItemView(); // Unequipping can produce a new stack, not yet in the window... + updateItemView(); // Unequipping can produce a new stack, not yet in the window... // newIndex will store the index of the ItemStack the item was stacked on int newIndex = -1; - for (size_t i=0; i < mTradeModel->getItemCount(); ++i) + for (size_t i = 0; i < mTradeModel->getItemCount(); ++i) { if (mTradeModel->getItem(i).mBase == newStack) { @@ -408,7 +408,7 @@ namespace MWGui std::string InventoryWindow::getModeSetting() const { std::string setting = "inventory"; - switch(mGuiMode) + switch (mGuiMode) { case GM_Container: setting += " container"; @@ -456,18 +456,20 @@ namespace MWGui void InventoryWindow::updateArmorRating() { - mArmorRating->setCaptionWithReplacing ("#{sArmor}: " - + MyGUI::utility::toString(static_cast(mPtr.getClass().getArmorRating(mPtr)))); + mArmorRating->setCaptionWithReplacing( + "#{sArmor}: " + MyGUI::utility::toString(static_cast(mPtr.getClass().getArmorRating(mPtr)))); if (mArmorRating->getTextSize().width > mArmorRating->getSize().width) - mArmorRating->setCaptionWithReplacing (MyGUI::utility::toString(static_cast(mPtr.getClass().getArmorRating(mPtr)))); + mArmorRating->setCaptionWithReplacing( + MyGUI::utility::toString(static_cast(mPtr.getClass().getArmorRating(mPtr)))); } void InventoryWindow::updatePreviewSize() { const MyGUI::IntSize viewport = getPreviewViewportSize(); mPreview->setViewport(viewport.width, viewport.height); - mAvatarImage->getSubWidgetMain()->_setUVSet(MyGUI::FloatRect(0.f, 0.f, - viewport.width / float(mPreview->getTextureWidth()), viewport.height / float(mPreview->getTextureHeight()))); + mAvatarImage->getSubWidgetMain()->_setUVSet( + MyGUI::FloatRect(0.f, 0.f, viewport.width / float(mPreview->getTextureWidth()), + viewport.height / float(mPreview->getTextureHeight()))); } void InventoryWindow::onNameFilterChanged(MyGUI::EditBox* _sender) @@ -514,7 +516,7 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->toggleVisible(GW_Inventory); } - void InventoryWindow::useItem(const MWWorld::Ptr &ptr, bool force) + void InventoryWindow::useItem(const MWWorld::Ptr& ptr, bool force) { std::string_view script = ptr.getClass().getScript(ptr); if (!script.empty()) @@ -530,7 +532,8 @@ namespace MWGui MWWorld::Ptr player = MWMechanics::getPlayer(); - // early-out for items that need to be equipped, but can't be equipped: we don't want to set OnPcEquip in that case + // early-out for items that need to be equipped, but can't be equipped: we don't want to set OnPcEquip in that + // case if (!ptr.getClass().getEquipmentSlots(ptr).first.empty()) { if (ptr.getClass().hasItemHealth(ptr) && ptr.getCellRef().getCharge() == 0) @@ -589,14 +592,15 @@ namespace MWGui if (mDragAndDrop->mSourceModel != mTradeModel) { // Move item to the player's inventory - ptr = mDragAndDrop->mSourceModel->moveItem(mDragAndDrop->mItem, mDragAndDrop->mDraggedCount, mTradeModel); + ptr = mDragAndDrop->mSourceModel->moveItem( + mDragAndDrop->mItem, mDragAndDrop->mDraggedCount, mTradeModel); } useItem(ptr); - // If item is ingredient or potion don't stop drag and drop to simplify action of taking more than one 1 item - if ((ptr.getType() == ESM::Potion::sRecordId || - ptr.getType() == ESM::Ingredient::sRecordId) + // If item is ingredient or potion don't stop drag and drop to simplify action of taking more than one 1 + // item + if ((ptr.getType() == ESM::Potion::sRecordId || ptr.getType() == ESM::Ingredient::sRecordId) && mDragAndDrop->mDraggedCount > 1) { // Item can be provided from other window for example container. @@ -607,14 +611,15 @@ namespace MWGui } else { - MyGUI::IntPoint mousePos = MyGUI::InputManager::getInstance ().getLastPressedPosition (MyGUI::MouseButton::Left); - MyGUI::IntPoint relPos = mousePos - mAvatarImage->getAbsolutePosition (); + MyGUI::IntPoint mousePos + = MyGUI::InputManager::getInstance().getLastPressedPosition(MyGUI::MouseButton::Left); + MyGUI::IntPoint relPos = mousePos - mAvatarImage->getAbsolutePosition(); - MWWorld::Ptr itemSelected = getAvatarSelectedItem (relPos.left, relPos.top); - if (itemSelected.isEmpty ()) + MWWorld::Ptr itemSelected = getAvatarSelectedItem(relPos.left, relPos.top); + if (itemSelected.isEmpty()) return; - for (size_t i=0; i < mTradeModel->getItemCount (); ++i) + for (size_t i = 0; i < mTradeModel->getItemCount(); ++i) { if (mTradeModel->getItem(i).mBase == itemSelected) { @@ -635,7 +640,7 @@ namespace MWGui return MWWorld::Ptr(); MWWorld::InventoryStore& invStore = mPtr.getClass().getInventoryStore(mPtr); - if(invStore.getSlot(slot) != invStore.end()) + if (invStore.getSlot(slot) != invStore.end()) { MWWorld::Ptr item = *invStore.getSlot(slot); if (!item.getClass().showsInInventory(item)) @@ -694,31 +699,23 @@ namespace MWGui // update the spell window just in case new enchanted items were added to inventory MWBase::Environment::get().getWindowManager()->updateSpellWindow(); - MWBase::Environment::get().getMechanicsManager()->updateMagicEffects( - MWMechanics::getPlayer()); + MWBase::Environment::get().getMechanicsManager()->updateMagicEffects(MWMechanics::getPlayer()); dirtyPreview(); } - void InventoryWindow::pickUpObject (MWWorld::Ptr object) + void InventoryWindow::pickUpObject(MWWorld::Ptr object) { // If the inventory is not yet enabled, don't pick anything up if (!MWBase::Environment::get().getWindowManager()->isAllowed(GW_Inventory)) return; // make sure the object is of a type that can be picked up auto type = object.getType(); - if ( (type != ESM::Apparatus::sRecordId) - && (type != ESM::Armor::sRecordId) - && (type != ESM::Book::sRecordId) - && (type != ESM::Clothing::sRecordId) - && (type != ESM::Ingredient::sRecordId) - && (type != ESM::Light::sRecordId) - && (type != ESM::Miscellaneous::sRecordId) - && (type != ESM::Lockpick::sRecordId) - && (type != ESM::Probe::sRecordId) - && (type != ESM::Repair::sRecordId) - && (type != ESM::Weapon::sRecordId) - && (type != ESM::Potion::sRecordId)) + if ((type != ESM::Apparatus::sRecordId) && (type != ESM::Armor::sRecordId) && (type != ESM::Book::sRecordId) + && (type != ESM::Clothing::sRecordId) && (type != ESM::Ingredient::sRecordId) + && (type != ESM::Light::sRecordId) && (type != ESM::Miscellaneous::sRecordId) + && (type != ESM::Lockpick::sRecordId) && (type != ESM::Probe::sRecordId) && (type != ESM::Repair::sRecordId) + && (type != ESM::Weapon::sRecordId) && (type != ESM::Potion::sRecordId)) return; // An object that can be picked up must have a tooltip. @@ -731,7 +728,7 @@ namespace MWGui MWWorld::Ptr player = MWMechanics::getPlayer(); MWBase::Environment::get().getWorld()->breakInvisibility(player); - + if (!object.getRefData().activate()) return; @@ -745,15 +742,16 @@ namespace MWGui // add to player inventory // can't use ActionTake here because we need an MWWorld::Ptr to the newly inserted object - MWWorld::Ptr newObject = *player.getClass().getContainerStore (player).add (object, object.getRefData().getCount(), player); + MWWorld::Ptr newObject + = *player.getClass().getContainerStore(player).add(object, object.getRefData().getCount(), player); // remove from world - MWBase::Environment::get().getWorld()->deleteObject (object); + MWBase::Environment::get().getWorld()->deleteObject(object); // get ModelIndex to the item mTradeModel->update(); - size_t i=0; - for (; igetItemCount(); ++i) + size_t i = 0; + for (; i < mTradeModel->getItemCount(); ++i) { if (mTradeModel->getItem(i).mBase == newObject) break; @@ -772,7 +770,7 @@ namespace MWGui if (MWBase::Environment::get().getMechanicsManager()->isAttackingOrSpell(player)) return; - const MWMechanics::CreatureStats &stats = player.getClass().getCreatureStats(player); + const MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player); bool godmode = MWBase::Environment::get().getWorld()->getGodModeState(); if ((!godmode && stats.isParalyzed()) || stats.getKnockedDown() || stats.isDead() || stats.getHitRecovery()) return; @@ -785,7 +783,7 @@ namespace MWGui if (model.getItemCount() == 0) return; - for (ItemModel::ModelIndex i=0; igetScalingFactor(); return MyGUI::IntSize(std::min(mPreview->getTextureWidth(), previewWindowSize.width * scale), - std::min(mPreview->getTextureHeight(), previewWindowSize.height * scale)); + std::min(mPreview->getTextureHeight(), previewWindowSize.height * scale)); } osg::Vec2f InventoryWindow::mapPreviewWindowToViewport(int x, int y) const @@ -847,9 +845,6 @@ namespace MWGui const float normalisedY = y / std::max(1.0f, previewWindowSize.height); const MyGUI::IntSize viewport = getPreviewViewportSize(); - return osg::Vec2f( - normalisedX * float(viewport.width - 1), - (1.0 - normalisedY) * float(viewport.height - 1) - ); + return osg::Vec2f(normalisedX * float(viewport.width - 1), (1.0 - normalisedY) * float(viewport.height - 1)); } } diff --git a/apps/openmw/mwgui/inventorywindow.hpp b/apps/openmw/mwgui/inventorywindow.hpp index a89e9a945f..be331297ed 100644 --- a/apps/openmw/mwgui/inventorywindow.hpp +++ b/apps/openmw/mwgui/inventorywindow.hpp @@ -1,11 +1,11 @@ #ifndef MGUI_Inventory_H #define MGUI_Inventory_H -#include "windowpinnablebase.hpp" #include "mode.hpp" +#include "windowpinnablebase.hpp" -#include "../mwworld/ptr.hpp" #include "../mwrender/characterpreview.hpp" +#include "../mwworld/ptr.hpp" namespace osg { @@ -32,111 +32,112 @@ namespace MWGui class InventoryWindow : public WindowPinnableBase { - public: - InventoryWindow(DragAndDrop* dragAndDrop, osg::Group* parent, Resource::ResourceSystem* resourceSystem); + public: + InventoryWindow(DragAndDrop* dragAndDrop, osg::Group* parent, Resource::ResourceSystem* resourceSystem); + + void onOpen() override; - void onOpen() override; + /// start trading, disables item drag&drop + void setTrading(bool trading); - /// start trading, disables item drag&drop - void setTrading(bool trading); + void onFrame(float dt) override; - void onFrame(float dt) override; + void pickUpObject(MWWorld::Ptr object); - void pickUpObject (MWWorld::Ptr object); + MWWorld::Ptr getAvatarSelectedItem(int x, int y); - MWWorld::Ptr getAvatarSelectedItem(int x, int y); + void rebuildAvatar(); - void rebuildAvatar(); + SortFilterItemModel* getSortFilterModel(); + TradeItemModel* getTradeModel(); + ItemModel* getModel(); - SortFilterItemModel* getSortFilterModel(); - TradeItemModel* getTradeModel(); - ItemModel* getModel(); + void updateItemView(); - void updateItemView(); + void updatePlayer(); - void updatePlayer(); + void clear() override; - void clear() override; + void useItem(const MWWorld::Ptr& ptr, bool force = false); - void useItem(const MWWorld::Ptr& ptr, bool force=false); + void setGuiMode(GuiMode mode); - void setGuiMode(GuiMode mode); + /// Cycle to previous/next weapon + void cycle(bool next); - /// Cycle to previous/next weapon - void cycle(bool next); + protected: + void onTitleDoubleClicked() override; - protected: - void onTitleDoubleClicked() override; + private: + DragAndDrop* mDragAndDrop; - private: - DragAndDrop* mDragAndDrop; + int mSelectedItem; - int mSelectedItem; + MWWorld::Ptr mPtr; - MWWorld::Ptr mPtr; + MWGui::ItemView* mItemView; + SortFilterItemModel* mSortModel; + TradeItemModel* mTradeModel; - MWGui::ItemView* mItemView; - SortFilterItemModel* mSortModel; - TradeItemModel* mTradeModel; + MyGUI::Widget* mAvatar; + MyGUI::ImageBox* mAvatarImage; + MyGUI::TextBox* mArmorRating; + Widgets::MWDynamicStat* mEncumbranceBar; - MyGUI::Widget* mAvatar; - MyGUI::ImageBox* mAvatarImage; - MyGUI::TextBox* mArmorRating; - Widgets::MWDynamicStat* mEncumbranceBar; + MyGUI::Widget* mLeftPane; + MyGUI::Widget* mRightPane; - MyGUI::Widget* mLeftPane; - MyGUI::Widget* mRightPane; + MyGUI::Button* mFilterAll; + MyGUI::Button* mFilterWeapon; + MyGUI::Button* mFilterApparel; + MyGUI::Button* mFilterMagic; + MyGUI::Button* mFilterMisc; - MyGUI::Button* mFilterAll; - MyGUI::Button* mFilterWeapon; - MyGUI::Button* mFilterApparel; - MyGUI::Button* mFilterMagic; - MyGUI::Button* mFilterMisc; - - MyGUI::EditBox* mFilterEdit; + MyGUI::EditBox* mFilterEdit; - GuiMode mGuiMode; + GuiMode mGuiMode; - int mLastXSize; - int mLastYSize; + int mLastXSize; + int mLastYSize; - std::unique_ptr mPreviewTexture; - std::unique_ptr mPreview; + std::unique_ptr mPreviewTexture; + std::unique_ptr mPreview; - bool mTrading; - float mUpdateTimer; + bool mTrading; + float mUpdateTimer; - void toggleMaximized(); + void toggleMaximized(); - void onItemSelected(int index); - void onItemSelectedFromSourceModel(int index); + void onItemSelected(int index); + void onItemSelectedFromSourceModel(int index); - void onBackgroundSelected(); + void onBackgroundSelected(); - std::string getModeSetting() const; + std::string getModeSetting() const; - void sellItem(MyGUI::Widget* sender, int count); - void dragItem(MyGUI::Widget* sender, int count); + void sellItem(MyGUI::Widget* sender, int count); + void dragItem(MyGUI::Widget* sender, int count); - void onWindowResize(MyGUI::Window* _sender); - void onFilterChanged(MyGUI::Widget* _sender); - void onNameFilterChanged(MyGUI::EditBox* _sender); - void onAvatarClicked(MyGUI::Widget* _sender); - void onPinToggled() override; + void onWindowResize(MyGUI::Window* _sender); + void onFilterChanged(MyGUI::Widget* _sender); + void onNameFilterChanged(MyGUI::EditBox* _sender); + void onAvatarClicked(MyGUI::Widget* _sender); + void onPinToggled() override; - void updateEncumbranceBar(); - void notifyContentChanged(); - void dirtyPreview(); - void updatePreviewSize(); - void updateArmorRating(); + void updateEncumbranceBar(); + void notifyContentChanged(); + void dirtyPreview(); + void updatePreviewSize(); + void updateArmorRating(); - MyGUI::IntSize getPreviewViewportSize() const; - osg::Vec2f mapPreviewWindowToViewport(int x, int y) const; + MyGUI::IntSize getPreviewViewportSize() const; + osg::Vec2f mapPreviewWindowToViewport(int x, int y) const; - void adjustPanes(); + void adjustPanes(); - /// Unequips count items from mSelectedItem, if it is equipped, and then updates mSelectedItem in case the items were re-stacked - void ensureSelectedItemUnequipped(int count); + /// Unequips count items from mSelectedItem, if it is equipped, and then updates mSelectedItem in case the items + /// were re-stacked + void ensureSelectedItemUnequipped(int count); }; } diff --git a/apps/openmw/mwgui/itemchargeview.cpp b/apps/openmw/mwgui/itemchargeview.cpp index e2745003e7..b7dc441b49 100644 --- a/apps/openmw/mwgui/itemchargeview.cpp +++ b/apps/openmw/mwgui/itemchargeview.cpp @@ -2,10 +2,10 @@ #include +#include #include -#include #include -#include +#include #include @@ -22,8 +22,8 @@ namespace MWGui { ItemChargeView::ItemChargeView() - : mScrollView(nullptr), - mDisplayMode(DisplayMode_Health) + : mScrollView(nullptr) + , mDisplayMode(DisplayMode_Health) { } @@ -92,17 +92,20 @@ namespace MWGui Line line; line.mItemPtr = stack.mBase; - line.mText = mScrollView->createWidget("SandText", MyGUI::IntCoord(), MyGUI::Align::Default); + line.mText + = mScrollView->createWidget("SandText", MyGUI::IntCoord(), MyGUI::Align::Default); line.mText->setNeedMouseFocus(false); - line.mIcon = mScrollView->createWidget("MW_ItemIconSmall", MyGUI::IntCoord(), MyGUI::Align::Default); + line.mIcon = mScrollView->createWidget( + "MW_ItemIconSmall", MyGUI::IntCoord(), MyGUI::Align::Default); line.mIcon->setItem(line.mItemPtr); line.mIcon->setUserString("ToolTipType", "ItemPtr"); line.mIcon->setUserData(MWWorld::Ptr(line.mItemPtr)); line.mIcon->eventMouseButtonClick += MyGUI::newDelegate(this, &ItemChargeView::onIconClicked); line.mIcon->eventMouseWheel += MyGUI::newDelegate(this, &ItemChargeView::onMouseWheelMoved); - line.mCharge = mScrollView->createWidget("MW_ChargeBar", MyGUI::IntCoord(), MyGUI::Align::Default); + line.mCharge = mScrollView->createWidget( + "MW_ChargeBar", MyGUI::IntCoord(), MyGUI::Align::Default); line.mCharge->setNeedMouseFocus(false); updateLine(line); @@ -133,17 +136,19 @@ namespace MWGui for (Line& line : mLines) { - line.mText->setCoord(8, currentY, mScrollView->getWidth()-8, 18); + line.mText->setCoord(8, currentY, mScrollView->getWidth() - 8, 18); currentY += 19; line.mIcon->setCoord(16, currentY, 32, 32); - line.mCharge->setCoord(72, currentY+2, std::max(199, mScrollView->getWidth()-72-38), 20); + line.mCharge->setCoord(72, currentY + 2, std::max(199, mScrollView->getWidth() - 72 - 38), 20); currentY += 32 + 4; } - // Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden + // Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the + // scrollbar is hidden mScrollView->setVisibleVScroll(false); - mScrollView->setCanvasSize(MyGUI::IntSize(mScrollView->getWidth(), std::max(mScrollView->getHeight(), currentY))); + mScrollView->setCanvasSize( + MyGUI::IntSize(mScrollView->getWidth(), std::max(mScrollView->getHeight(), currentY))); mScrollView->setVisibleVScroll(true); } @@ -182,19 +187,20 @@ namespace MWGui line.mCharge->setVisible(true); line.mCharge->setValue(line.mItemPtr.getClass().getItemHealth(line.mItemPtr), - line.mItemPtr.getClass().getItemMaxHealth(line.mItemPtr)); + line.mItemPtr.getClass().getItemMaxHealth(line.mItemPtr)); break; case DisplayMode_EnchantmentCharge: std::string_view enchId = line.mItemPtr.getClass().getEnchantment(line.mItemPtr); if (enchId.empty()) break; - const ESM::Enchantment* ench = MWBase::Environment::get().getWorld()->getStore().get().search(enchId); + const ESM::Enchantment* ench + = MWBase::Environment::get().getWorld()->getStore().get().search(enchId); if (!ench) break; line.mCharge->setVisible(true); - line.mCharge->setValue(static_cast(line.mItemPtr.getCellRef().getEnchantmentCharge()), - ench->mData.mCharge); + line.mCharge->setValue( + static_cast(line.mItemPtr.getCellRef().getEnchantmentCharge()), ench->mData.mCharge); break; } } @@ -206,9 +212,10 @@ namespace MWGui void ItemChargeView::onMouseWheelMoved(MyGUI::Widget* /*sender*/, int rel) { - if (mScrollView->getViewOffset().top + rel*0.3f > 0) + if (mScrollView->getViewOffset().top + rel * 0.3f > 0) mScrollView->setViewOffset(MyGUI::IntPoint(0, 0)); else - mScrollView->setViewOffset(MyGUI::IntPoint(0, static_cast(mScrollView->getViewOffset().top + rel*0.3f))); + mScrollView->setViewOffset( + MyGUI::IntPoint(0, static_cast(mScrollView->getViewOffset().top + rel * 0.3f))); } } diff --git a/apps/openmw/mwgui/itemchargeview.hpp b/apps/openmw/mwgui/itemchargeview.hpp index 039dcaf4e6..8c266c4a26 100644 --- a/apps/openmw/mwgui/itemchargeview.hpp +++ b/apps/openmw/mwgui/itemchargeview.hpp @@ -1,8 +1,8 @@ #ifndef MWGUI_ITEMCHARGEVIEW_H #define MWGUI_ITEMCHARGEVIEW_H -#include #include +#include #include @@ -24,54 +24,54 @@ namespace MWGui class ItemChargeView final : public MyGUI::Widget { MYGUI_RTTI_DERIVED(ItemChargeView) - public: - enum DisplayMode - { - DisplayMode_Health, - DisplayMode_EnchantmentCharge - }; + public: + enum DisplayMode + { + DisplayMode_Health, + DisplayMode_EnchantmentCharge + }; - ItemChargeView(); + ItemChargeView(); - /// Register needed components with MyGUI's factory manager - static void registerComponents(); + /// Register needed components with MyGUI's factory manager + static void registerComponents(); - void initialiseOverride() override; + void initialiseOverride() override; - /// Takes ownership of \a model - void setModel(ItemModel* model); + /// Takes ownership of \a model + void setModel(ItemModel* model); - void setDisplayMode(DisplayMode type); + void setDisplayMode(DisplayMode type); - void update(); - void layoutWidgets(); - void resetScrollbars(); + void update(); + void layoutWidgets(); + void resetScrollbars(); - void setSize(const MyGUI::IntSize& value) override; - void setCoord(const MyGUI::IntCoord& value) override; + void setSize(const MyGUI::IntSize& value) override; + void setCoord(const MyGUI::IntCoord& value) override; - MyGUI::delegates::CMultiDelegate2 eventItemClicked; + MyGUI::delegates::CMultiDelegate2 eventItemClicked; - private: - struct Line - { - MWWorld::Ptr mItemPtr; - MyGUI::TextBox* mText; - ItemWidget* mIcon; - Widgets::MWDynamicStatPtr mCharge; - }; + private: + struct Line + { + MWWorld::Ptr mItemPtr; + MyGUI::TextBox* mText; + ItemWidget* mIcon; + Widgets::MWDynamicStatPtr mCharge; + }; - void updateLine(const Line& line); + void updateLine(const Line& line); - void onIconClicked(MyGUI::Widget* sender); - void onMouseWheelMoved(MyGUI::Widget* sender, int rel); + void onIconClicked(MyGUI::Widget* sender); + void onMouseWheelMoved(MyGUI::Widget* sender, int rel); - typedef std::vector Lines; - Lines mLines; + typedef std::vector Lines; + Lines mLines; - std::unique_ptr mModel; - MyGUI::ScrollView* mScrollView; - DisplayMode mDisplayMode; + std::unique_ptr mModel; + MyGUI::ScrollView* mScrollView; + DisplayMode mDisplayMode; }; } diff --git a/apps/openmw/mwgui/itemmodel.cpp b/apps/openmw/mwgui/itemmodel.cpp index 55b2994199..810c8944dd 100644 --- a/apps/openmw/mwgui/itemmodel.cpp +++ b/apps/openmw/mwgui/itemmodel.cpp @@ -9,7 +9,7 @@ namespace MWGui { - ItemStack::ItemStack(const MWWorld::Ptr &base, ItemModel *creator, size_t count) + ItemStack::ItemStack(const MWWorld::Ptr& base, ItemModel* creator, size_t count) : mType(Type_Normal) , mFlags(0) , mCreator(creator) @@ -31,18 +31,18 @@ namespace MWGui { } - bool operator == (const ItemStack& left, const ItemStack& right) + bool operator==(const ItemStack& left, const ItemStack& right) { if (left.mType != right.mType) return false; - if(left.mBase == right.mBase) + if (left.mBase == right.mBase) return true; // If one of the items is in an inventory and currently equipped, we need to check stacking both ways to be sure if (left.mBase.getContainerStore() && right.mBase.getContainerStore()) return left.mBase.getContainerStore()->stacks(left.mBase, right.mBase) - && right.mBase.getContainerStore()->stacks(left.mBase, right.mBase); + && right.mBase.getContainerStore()->stacks(left.mBase, right.mBase); if (left.mBase.getContainerStore()) return left.mBase.getContainerStore()->stacks(left.mBase, right.mBase); @@ -53,11 +53,9 @@ namespace MWGui return store.stacks(left.mBase, right.mBase); } - ItemModel::ItemModel() - { - } + ItemModel::ItemModel() {} - MWWorld::Ptr ItemModel::moveItem(const ItemStack &item, size_t count, ItemModel *otherModel) + MWWorld::Ptr ItemModel::moveItem(const ItemStack& item, size_t count, ItemModel* otherModel) { MWWorld::Ptr ret = otherModel->copyItem(item, count); removeItem(item, count); @@ -69,12 +67,12 @@ namespace MWGui return true; } - bool ItemModel::onDropItem(const MWWorld::Ptr &item, int count) + bool ItemModel::onDropItem(const MWWorld::Ptr& item, int count) { return true; } - bool ItemModel::onTakeItem(const MWWorld::Ptr &item, int count) + bool ItemModel::onTakeItem(const MWWorld::Ptr& item, int count) { return true; } @@ -84,20 +82,20 @@ namespace MWGui return mSourceModel->allowedToUseItems(); } - MWWorld::Ptr ProxyItemModel::copyItem (const ItemStack& item, size_t count, bool allowAutoEquip) + MWWorld::Ptr ProxyItemModel::copyItem(const ItemStack& item, size_t count, bool allowAutoEquip) { - return mSourceModel->copyItem (item, count, allowAutoEquip); + return mSourceModel->copyItem(item, count, allowAutoEquip); } - void ProxyItemModel::removeItem (const ItemStack& item, size_t count) + void ProxyItemModel::removeItem(const ItemStack& item, size_t count) { - mSourceModel->removeItem (item, count); + mSourceModel->removeItem(item, count); } - ItemModel::ModelIndex ProxyItemModel::mapToSource (ModelIndex index) + ItemModel::ModelIndex ProxyItemModel::mapToSource(ModelIndex index) { const ItemStack& itemToSearch = getItem(index); - for (size_t i=0; igetItemCount(); ++i) + for (size_t i = 0; i < mSourceModel->getItemCount(); ++i) { const ItemStack& item = mSourceModel->getItem(i); if (item.mBase == itemToSearch.mBase) @@ -106,10 +104,10 @@ namespace MWGui return -1; } - ItemModel::ModelIndex ProxyItemModel::mapFromSource (ModelIndex index) + ItemModel::ModelIndex ProxyItemModel::mapFromSource(ModelIndex index) { const ItemStack& itemToSearch = mSourceModel->getItem(index); - for (size_t i=0; igetIndex(item); } @@ -133,12 +131,12 @@ namespace MWGui mSourceModel->onClose(); } - bool ProxyItemModel::onDropItem(const MWWorld::Ptr &item, int count) + bool ProxyItemModel::onDropItem(const MWWorld::Ptr& item, int count) { return mSourceModel->onDropItem(item, count); } - bool ProxyItemModel::onTakeItem(const MWWorld::Ptr &item, int count) + bool ProxyItemModel::onTakeItem(const MWWorld::Ptr& item, int count) { return mSourceModel->onTakeItem(item, count); } diff --git a/apps/openmw/mwgui/itemmodel.hpp b/apps/openmw/mwgui/itemmodel.hpp index 9ddcaffc50..c7143b4b91 100644 --- a/apps/openmw/mwgui/itemmodel.hpp +++ b/apps/openmw/mwgui/itemmodel.hpp @@ -13,7 +13,7 @@ namespace MWGui /// @brief A single item stack managed by an item model struct ItemStack { - ItemStack (const MWWorld::Ptr& base, ItemModel* creator, size_t count); + ItemStack(const MWWorld::Ptr& base, ItemModel* creator, size_t count); ItemStack(); ///< like operator==, only without checking mType @@ -27,8 +27,8 @@ namespace MWGui enum Flags { - Flag_Enchanted = (1<<0), - Flag_Bound = (1<<1) + Flag_Enchanted = (1 << 0), + Flag_Bound = (1 << 1) }; int mFlags; @@ -37,8 +37,7 @@ namespace MWGui MWWorld::Ptr mBase; }; - bool operator == (const ItemStack& left, const ItemStack& right); - + bool operator==(const ItemStack& left, const ItemStack& right); /// @brief The base class that all item models should derive from. class ItemModel @@ -50,32 +49,30 @@ namespace MWGui typedef int ModelIndex; // -1 means invalid index /// Throws for invalid index or out of range index - virtual ItemStack getItem (ModelIndex index) = 0; + virtual ItemStack getItem(ModelIndex index) = 0; /// The number of items in the model, this specifies the range of indices you can pass to /// the getItem function (but this range is only valid until the next call to update()) virtual size_t getItemCount() = 0; /// Returns an invalid index if the item was not found - virtual ModelIndex getIndex (const ItemStack &item) = 0; + virtual ModelIndex getIndex(const ItemStack& item) = 0; /// Rebuild the item model, this will invalidate existing model indices virtual void update() = 0; /// Move items from this model to \a otherModel. /// @note Derived implementations may return an empty Ptr if the move was unsuccessful. - virtual MWWorld::Ptr moveItem (const ItemStack& item, size_t count, ItemModel* otherModel); + virtual MWWorld::Ptr moveItem(const ItemStack& item, size_t count, ItemModel* otherModel); - virtual MWWorld::Ptr copyItem (const ItemStack& item, size_t count, bool allowAutoEquip = true) = 0; - virtual void removeItem (const ItemStack& item, size_t count) = 0; + virtual MWWorld::Ptr copyItem(const ItemStack& item, size_t count, bool allowAutoEquip = true) = 0; + virtual void removeItem(const ItemStack& item, size_t count) = 0; /// Is the player allowed to use items from this item model? (default true) virtual bool allowedToUseItems() const; - virtual void onClose() - { - } - virtual bool onDropItem(const MWWorld::Ptr &item, int count); - virtual bool onTakeItem(const MWWorld::Ptr &item, int count); + virtual void onClose() {} + virtual bool onDropItem(const MWWorld::Ptr& item, int count); + virtual bool onTakeItem(const MWWorld::Ptr& item, int count); virtual bool usesContainer(const MWWorld::Ptr& container) = 0; @@ -84,8 +81,8 @@ namespace MWGui ItemModel& operator=(const ItemModel&); }; - /// @brief A proxy item model can be used to filter or rearrange items from a source model (or even add new items to it). - /// The neat thing is that this does not actually alter the source model. + /// @brief A proxy item model can be used to filter or rearrange items from a source model (or even add new items to + /// it). The neat thing is that this does not actually alter the source model. class ProxyItemModel : public ItemModel { public: @@ -95,20 +92,21 @@ namespace MWGui bool allowedToUseItems() const override; void onClose() override; - bool onDropItem(const MWWorld::Ptr &item, int count) override; - bool onTakeItem(const MWWorld::Ptr &item, int count) override; + bool onDropItem(const MWWorld::Ptr& item, int count) override; + bool onTakeItem(const MWWorld::Ptr& item, int count) override; - MWWorld::Ptr copyItem (const ItemStack& item, size_t count, bool allowAutoEquip = true) override; - void removeItem (const ItemStack& item, size_t count) override; - ModelIndex getIndex (const ItemStack &item) override; + MWWorld::Ptr copyItem(const ItemStack& item, size_t count, bool allowAutoEquip = true) override; + void removeItem(const ItemStack& item, size_t count) override; + ModelIndex getIndex(const ItemStack& item) override; /// @note Takes ownership of the passed pointer. void setSourceModel(std::unique_ptr sourceModel); - ModelIndex mapToSource (ModelIndex index); - ModelIndex mapFromSource (ModelIndex index); + ModelIndex mapToSource(ModelIndex index); + ModelIndex mapFromSource(ModelIndex index); bool usesContainer(const MWWorld::Ptr& container) override; + protected: std::unique_ptr mSourceModel; }; diff --git a/apps/openmw/mwgui/itemselection.cpp b/apps/openmw/mwgui/itemselection.cpp index 1a34f5d623..4fe40ce693 100644 --- a/apps/openmw/mwgui/itemselection.cpp +++ b/apps/openmw/mwgui/itemselection.cpp @@ -1,16 +1,16 @@ #include "itemselection.hpp" -#include #include +#include -#include "itemview.hpp" #include "inventoryitemmodel.hpp" +#include "itemview.hpp" #include "sortfilteritemmodel.hpp" namespace MWGui { - ItemSelectionDialog::ItemSelectionDialog(const std::string &label) + ItemSelectionDialog::ItemSelectionDialog(const std::string& label) : WindowModal("openmw_itemselection_dialog.layout") , mSortModel(nullptr) { @@ -19,7 +19,7 @@ namespace MWGui MyGUI::TextBox* l; getWidget(l, "Label"); - l->setCaptionWithReplacing (label); + l->setCaptionWithReplacing(label); MyGUI::Button* cancelButton; getWidget(cancelButton, "CancelButton"); diff --git a/apps/openmw/mwgui/itemselection.hpp b/apps/openmw/mwgui/itemselection.hpp index 27eed8ea51..d418f5dbd6 100644 --- a/apps/openmw/mwgui/itemselection.hpp +++ b/apps/openmw/mwgui/itemselection.hpp @@ -28,7 +28,7 @@ namespace MWGui EventHandle_Item eventItemSelected; EventHandle_Void eventDialogCanceled; - void openContainer (const MWWorld::Ptr& container); + void openContainer(const MWWorld::Ptr& container); void setCategory(int category); void setFilter(int filter); diff --git a/apps/openmw/mwgui/itemview.cpp b/apps/openmw/mwgui/itemview.cpp index ba12d622c5..760fc650d6 100644 --- a/apps/openmw/mwgui/itemview.cpp +++ b/apps/openmw/mwgui/itemview.cpp @@ -15,154 +15,156 @@ namespace MWGui { -ItemView::ItemView() - : mScrollView(nullptr) -{ -} + ItemView::ItemView() + : mScrollView(nullptr) + { + } -void ItemView::setModel(std::unique_ptr model) -{ - mModel = std::move(model); + void ItemView::setModel(std::unique_ptr model) + { + mModel = std::move(model); - update(); -} + update(); + } -void ItemView::initialiseOverride() -{ - Base::initialiseOverride(); + void ItemView::initialiseOverride() + { + Base::initialiseOverride(); - assignWidget(mScrollView, "ScrollView"); - if (mScrollView == nullptr) - throw std::runtime_error("Item view needs a scroll view"); + assignWidget(mScrollView, "ScrollView"); + if (mScrollView == nullptr) + throw std::runtime_error("Item view needs a scroll view"); - mScrollView->setCanvasAlign(MyGUI::Align::Left | MyGUI::Align::Top); -} + mScrollView->setCanvasAlign(MyGUI::Align::Left | MyGUI::Align::Top); + } -void ItemView::layoutWidgets() -{ - if (!mScrollView->getChildCount()) - return; + void ItemView::layoutWidgets() + { + if (!mScrollView->getChildCount()) + return; - int x = 0; - int y = 0; - MyGUI::Widget* dragArea = mScrollView->getChildAt(0); - int maxHeight = mScrollView->getHeight(); + int x = 0; + int y = 0; + MyGUI::Widget* dragArea = mScrollView->getChildAt(0); + int maxHeight = mScrollView->getHeight(); - int rows = maxHeight/42; - rows = std::max(rows, 1); - bool showScrollbar = int(std::ceil(dragArea->getChildCount()/float(rows))) > mScrollView->getWidth()/42; - if (showScrollbar) - maxHeight -= 18; + int rows = maxHeight / 42; + rows = std::max(rows, 1); + bool showScrollbar = int(std::ceil(dragArea->getChildCount() / float(rows))) > mScrollView->getWidth() / 42; + if (showScrollbar) + maxHeight -= 18; - for (unsigned int i=0; igetChildCount(); ++i) - { - MyGUI::Widget* w = dragArea->getChildAt(i); + for (unsigned int i = 0; i < dragArea->getChildCount(); ++i) + { + MyGUI::Widget* w = dragArea->getChildAt(i); - w->setPosition(x, y); + w->setPosition(x, y); - y += 42; + y += 42; - if (y > maxHeight-42 && i < dragArea->getChildCount()-1) - { - x += 42; - y = 0; + if (y > maxHeight - 42 && i < dragArea->getChildCount() - 1) + { + x += 42; + y = 0; + } } + x += 42; + + MyGUI::IntSize size = MyGUI::IntSize(std::max(mScrollView->getSize().width, x), mScrollView->getSize().height); + + // Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the + // scrollbar is hidden + mScrollView->setVisibleVScroll(false); + mScrollView->setVisibleHScroll(false); + mScrollView->setCanvasSize(size); + mScrollView->setVisibleVScroll(true); + mScrollView->setVisibleHScroll(true); + dragArea->setSize(size); } - x += 42; - MyGUI::IntSize size = MyGUI::IntSize(std::max(mScrollView->getSize().width, x), mScrollView->getSize().height); + void ItemView::update() + { + while (mScrollView->getChildCount()) + MyGUI::Gui::getInstance().destroyWidget(mScrollView->getChildAt(0)); - // Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden - mScrollView->setVisibleVScroll(false); - mScrollView->setVisibleHScroll(false); - mScrollView->setCanvasSize(size); - mScrollView->setVisibleVScroll(true); - mScrollView->setVisibleHScroll(true); - dragArea->setSize(size); -} + if (!mModel) + return; -void ItemView::update() -{ - while (mScrollView->getChildCount()) - MyGUI::Gui::getInstance().destroyWidget(mScrollView->getChildAt(0)); + mModel->update(); - if (!mModel) - return; + MyGUI::Widget* dragArea = mScrollView->createWidget( + "", 0, 0, mScrollView->getWidth(), mScrollView->getHeight(), MyGUI::Align::Stretch); + dragArea->setNeedMouseFocus(true); + dragArea->eventMouseButtonClick += MyGUI::newDelegate(this, &ItemView::onSelectedBackground); + dragArea->eventMouseWheel += MyGUI::newDelegate(this, &ItemView::onMouseWheelMoved); - mModel->update(); + for (ItemModel::ModelIndex i = 0; i < static_cast(mModel->getItemCount()); ++i) + { + const ItemStack& item = mModel->getItem(i); + + ItemWidget* itemWidget = dragArea->createWidget( + "MW_ItemIcon", MyGUI::IntCoord(0, 0, 42, 42), MyGUI::Align::Default); + itemWidget->setUserString("ToolTipType", "ItemModelIndex"); + itemWidget->setUserData(std::make_pair(i, mModel.get())); + ItemWidget::ItemState state = ItemWidget::None; + if (item.mType == ItemStack::Type_Barter) + state = ItemWidget::Barter; + if (item.mType == ItemStack::Type_Equipped) + state = ItemWidget::Equip; + itemWidget->setItem(item.mBase, state); + itemWidget->setCount(item.mCount); + + itemWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &ItemView::onSelectedItem); + itemWidget->eventMouseWheel += MyGUI::newDelegate(this, &ItemView::onMouseWheelMoved); + } - MyGUI::Widget* dragArea = mScrollView->createWidget("",0,0,mScrollView->getWidth(),mScrollView->getHeight(), - MyGUI::Align::Stretch); - dragArea->setNeedMouseFocus(true); - dragArea->eventMouseButtonClick += MyGUI::newDelegate(this, &ItemView::onSelectedBackground); - dragArea->eventMouseWheel += MyGUI::newDelegate(this, &ItemView::onMouseWheelMoved); + layoutWidgets(); + } - for (ItemModel::ModelIndex i=0; i(mModel->getItemCount()); ++i) + void ItemView::resetScrollBars() { - const ItemStack& item = mModel->getItem(i); - - ItemWidget* itemWidget = dragArea->createWidget("MW_ItemIcon", - MyGUI::IntCoord(0, 0, 42, 42), MyGUI::Align::Default); - itemWidget->setUserString("ToolTipType", "ItemModelIndex"); - itemWidget->setUserData(std::make_pair(i, mModel.get())); - ItemWidget::ItemState state = ItemWidget::None; - if (item.mType == ItemStack::Type_Barter) - state = ItemWidget::Barter; - if (item.mType == ItemStack::Type_Equipped) - state = ItemWidget::Equip; - itemWidget->setItem(item.mBase, state); - itemWidget->setCount(item.mCount); - - itemWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &ItemView::onSelectedItem); - itemWidget->eventMouseWheel += MyGUI::newDelegate(this, &ItemView::onMouseWheelMoved); + mScrollView->setViewOffset(MyGUI::IntPoint(0, 0)); } - layoutWidgets(); -} - -void ItemView::resetScrollBars() -{ - mScrollView->setViewOffset(MyGUI::IntPoint(0, 0)); -} - -void ItemView::onSelectedItem(MyGUI::Widget *sender) -{ - ItemModel::ModelIndex index = (*sender->getUserData >()).first; - eventItemClicked(index); -} + void ItemView::onSelectedItem(MyGUI::Widget* sender) + { + ItemModel::ModelIndex index = (*sender->getUserData>()).first; + eventItemClicked(index); + } -void ItemView::onSelectedBackground(MyGUI::Widget *sender) -{ - eventBackgroundClicked(); -} + void ItemView::onSelectedBackground(MyGUI::Widget* sender) + { + eventBackgroundClicked(); + } -void ItemView::onMouseWheelMoved(MyGUI::Widget *_sender, int _rel) -{ - if (mScrollView->getViewOffset().left + _rel*0.3f > 0) - mScrollView->setViewOffset(MyGUI::IntPoint(0, 0)); - else - mScrollView->setViewOffset(MyGUI::IntPoint(static_cast(mScrollView->getViewOffset().left + _rel*0.3f), 0)); -} + void ItemView::onMouseWheelMoved(MyGUI::Widget* _sender, int _rel) + { + if (mScrollView->getViewOffset().left + _rel * 0.3f > 0) + mScrollView->setViewOffset(MyGUI::IntPoint(0, 0)); + else + mScrollView->setViewOffset( + MyGUI::IntPoint(static_cast(mScrollView->getViewOffset().left + _rel * 0.3f), 0)); + } -void ItemView::setSize(const MyGUI::IntSize &_value) -{ - bool changed = (_value.width != getWidth() || _value.height != getHeight()); - Base::setSize(_value); - if (changed) - layoutWidgets(); -} + void ItemView::setSize(const MyGUI::IntSize& _value) + { + bool changed = (_value.width != getWidth() || _value.height != getHeight()); + Base::setSize(_value); + if (changed) + layoutWidgets(); + } -void ItemView::setCoord(const MyGUI::IntCoord &_value) -{ - bool changed = (_value.width != getWidth() || _value.height != getHeight()); - Base::setCoord(_value); - if (changed) - layoutWidgets(); -} + void ItemView::setCoord(const MyGUI::IntCoord& _value) + { + bool changed = (_value.width != getWidth() || _value.height != getHeight()); + Base::setCoord(_value); + if (changed) + layoutWidgets(); + } -void ItemView::registerComponents() -{ - MyGUI::FactoryManager::getInstance().registerFactory("Widget"); -} + void ItemView::registerComponents() + { + MyGUI::FactoryManager::getInstance().registerFactory("Widget"); + } } diff --git a/apps/openmw/mwgui/itemview.hpp b/apps/openmw/mwgui/itemview.hpp index e2f882e618..7fb242f51e 100644 --- a/apps/openmw/mwgui/itemview.hpp +++ b/apps/openmw/mwgui/itemview.hpp @@ -10,12 +10,12 @@ namespace MWGui class ItemView final : public MyGUI::Widget { - MYGUI_RTTI_DERIVED(ItemView) + MYGUI_RTTI_DERIVED(ItemView) public: ItemView(); /// Register needed components with MyGUI's factory manager - static void registerComponents (); + static void registerComponents(); /// Takes ownership of \a model void setModel(std::unique_ptr model); @@ -39,13 +39,12 @@ namespace MWGui void setSize(const MyGUI::IntSize& _value) override; void setCoord(const MyGUI::IntCoord& _value) override; - void onSelectedItem (MyGUI::Widget* sender); - void onSelectedBackground (MyGUI::Widget* sender); + void onSelectedItem(MyGUI::Widget* sender); + void onSelectedBackground(MyGUI::Widget* sender); void onMouseWheelMoved(MyGUI::Widget* _sender, int _rel); std::unique_ptr mModel; MyGUI::ScrollView* mScrollView; - }; } diff --git a/apps/openmw/mwgui/itemwidget.cpp b/apps/openmw/mwgui/itemwidget.cpp index a7e6cb8bef..a2877e8b1e 100644 --- a/apps/openmw/mwgui/itemwidget.cpp +++ b/apps/openmw/mwgui/itemwidget.cpp @@ -7,9 +7,9 @@ #include // correctIconPath +#include #include #include -#include #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" @@ -29,25 +29,25 @@ namespace if (fontHeight > 16) { if (count > 999999999) - return MyGUI::utility::toString(count/1000000000) + "b"; + return MyGUI::utility::toString(count / 1000000000) + "b"; else if (count > 9999999) return ">9m"; else if (count > 999999) - return MyGUI::utility::toString(count/1000000) + "m"; + return MyGUI::utility::toString(count / 1000000) + "m"; else if (count > 9999) return ">9k"; else if (count > 999) - return MyGUI::utility::toString(count/1000) + "k"; + return MyGUI::utility::toString(count / 1000) + "k"; else return MyGUI::utility::toString(count); } if (count > 999999999) - return MyGUI::utility::toString(count/1000000000) + "b"; + return MyGUI::utility::toString(count / 1000000000) + "b"; else if (count > 999999) - return MyGUI::utility::toString(count/1000000) + "m"; + return MyGUI::utility::toString(count / 1000000) + "m"; else if (count > 9999) - return MyGUI::utility::toString(count/1000) + "k"; + return MyGUI::utility::toString(count / 1000) + "k"; else return MyGUI::utility::toString(count); } @@ -63,7 +63,6 @@ namespace MWGui , mFrame(nullptr) , mText(nullptr) { - } void ItemWidget::registerComponents() @@ -97,7 +96,7 @@ namespace MWGui mText->setCaption(getCountString(count)); } - void ItemWidget::setIcon(const std::string &icon) + void ItemWidget::setIcon(const std::string& icon) { if (mCurrentIcon != icon) { @@ -110,7 +109,7 @@ namespace MWGui } } - void ItemWidget::setFrame(const std::string &frame, const MyGUI::IntCoord &coord) + void ItemWidget::setFrame(const std::string& frame, const MyGUI::IntCoord& coord) { if (mFrame) { @@ -125,7 +124,7 @@ namespace MWGui } } - void ItemWidget::setIcon(const MWWorld::Ptr &ptr) + void ItemWidget::setIcon(const MWWorld::Ptr& ptr) { std::string_view icon = ptr.getClass().getInventoryIcon(ptr); if (icon.empty()) @@ -134,14 +133,14 @@ namespace MWGui std::string invIcon = Misc::ResourceHelpers::correctIconPath(icon, vfs); if (!vfs->exists(invIcon)) { - Log(Debug::Error) << "Failed to open image: '" << invIcon << "' not found, falling back to 'default-icon.tga'"; + Log(Debug::Error) << "Failed to open image: '" << invIcon + << "' not found, falling back to 'default-icon.tga'"; invIcon = Misc::ResourceHelpers::correctIconPath("default icon.tga", vfs); } setIcon(invIcon); } - - void ItemWidget::setItem(const MWWorld::Ptr &ptr, ItemState state) + void ItemWidget::setItem(const MWWorld::Ptr& ptr, ItemState state) { if (!mItem) return; @@ -199,9 +198,9 @@ namespace MWGui } if (state == Barter && !isMagic) - setFrame(backgroundTex, MyGUI::IntCoord(2*scale,2*scale,44*scale,44*scale)); + setFrame(backgroundTex, MyGUI::IntCoord(2 * scale, 2 * scale, 44 * scale, 44 * scale)); else - setFrame(backgroundTex, MyGUI::IntCoord(0,0,44*scale,44*scale)); + setFrame(backgroundTex, MyGUI::IntCoord(0, 0, 44 * scale, 44 * scale)); setIcon(ptr); } diff --git a/apps/openmw/mwgui/itemwidget.hpp b/apps/openmw/mwgui/itemwidget.hpp index 550d736433..29b0063203 100644 --- a/apps/openmw/mwgui/itemwidget.hpp +++ b/apps/openmw/mwgui/itemwidget.hpp @@ -14,12 +14,12 @@ namespace MWGui /// @brief A widget that shows an icon for an MWWorld::Ptr class ItemWidget : public MyGUI::Widget { - MYGUI_RTTI_DERIVED(ItemWidget) + MYGUI_RTTI_DERIVED(ItemWidget) public: ItemWidget(); /// Register needed components with MyGUI's factory manager - static void registerComponents (); + static void registerComponents(); enum ItemState { @@ -33,12 +33,12 @@ namespace MWGui void setCount(int count); /// \a ptr may be empty - void setItem (const MWWorld::Ptr& ptr, ItemState state = None); + void setItem(const MWWorld::Ptr& ptr, ItemState state = None); // Set icon and frame manually - void setIcon (const std::string& icon); - void setIcon (const MWWorld::Ptr& ptr); - void setFrame (const std::string& frame, const MyGUI::IntCoord& coord); + void setIcon(const std::string& icon); + void setIcon(const MWWorld::Ptr& ptr); + void setFrame(const std::string& frame, const MyGUI::IntCoord& coord); protected: void initialiseOverride() override; @@ -56,10 +56,9 @@ namespace MWGui class SpellWidget : public ItemWidget { - MYGUI_RTTI_DERIVED(SpellWidget) + MYGUI_RTTI_DERIVED(SpellWidget) public: - - void setSpellIcon (const std::string& icon); + void setSpellIcon(const std::string& icon); }; } diff --git a/apps/openmw/mwgui/jailscreen.cpp b/apps/openmw/mwgui/jailscreen.cpp index b77d484445..7d791afc08 100644 --- a/apps/openmw/mwgui/jailscreen.cpp +++ b/apps/openmw/mwgui/jailscreen.cpp @@ -3,27 +3,27 @@ #include #include -#include "../mwbase/windowmanager.hpp" +#include "../mwbase/environment.hpp" #include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/windowmanager.hpp" #include "../mwbase/world.hpp" -#include "../mwbase/environment.hpp" -#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/actorutil.hpp" +#include "../mwmechanics/npcstats.hpp" +#include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" #include "../mwworld/store.hpp" -#include "../mwworld/class.hpp" #include "jailscreen.hpp" namespace MWGui { JailScreen::JailScreen() - : WindowBase("openmw_jail_screen.layout"), - mDays(1), - mFadeTimeRemaining(0), - mTimeAdvancer(0.01f) + : WindowBase("openmw_jail_screen.layout") + , mDays(1) + , mFadeTimeRemaining(0) + , mTimeAdvancer(0.01f) { getWidget(mProgressBar, "ProgressBar"); @@ -41,7 +41,7 @@ namespace MWGui mFadeTimeRemaining = 0.5; setVisible(false); - mProgressBar->setScrollRange(100+1); + mProgressBar->setScrollRange(100 + 1); mProgressBar->setScrollPosition(0); mProgressBar->setTrackSize(0); } @@ -59,7 +59,8 @@ namespace MWGui { MWWorld::Ptr player = MWMechanics::getPlayer(); MWBase::Environment::get().getWorld()->teleportToClosestMarker(player, "prisonmarker"); - MWBase::Environment::get().getWindowManager()->fadeScreenOut(0.f); // override fade-in caused by cell transition + MWBase::Environment::get().getWindowManager()->fadeScreenOut( + 0.f); // override fade-in caused by cell transition setVisible(true); mTimeAdvancer.run(100); @@ -69,7 +70,8 @@ namespace MWGui void JailScreen::onJailProgressChanged(int cur, int /*total*/) { mProgressBar->setScrollPosition(0); - mProgressBar->setTrackSize(static_cast(cur / (float)(mProgressBar->getScrollRange()) * mProgressBar->getLineSize())); + mProgressBar->setTrackSize( + static_cast(cur / (float)(mProgressBar->getScrollRange()) * mProgressBar->getLineSize())); } void JailScreen::onJailFinished() @@ -86,7 +88,7 @@ namespace MWGui player.getClass().getCreatureStats(player).getActiveSpells().skipWorsenings(mDays * 24); std::set skills; - for (int day=0; daygetPrng(); int skill = Misc::Rng::rollDice(ESM::Skill::Length, prng); @@ -94,12 +96,13 @@ namespace MWGui MWMechanics::SkillValue& value = player.getClass().getNpcStats(player).getSkill(skill); if (skill == ESM::Skill::Security || skill == ESM::Skill::Sneak) - value.setBase(std::min(100.f, value.getBase()+1)); + value.setBase(std::min(100.f, value.getBase() + 1)); else - value.setBase(std::max(0.f, value.getBase()-1)); + value.setBase(std::max(0.f, value.getBase() - 1)); } - const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& gmst + = MWBase::Environment::get().getWorld()->getStore().get(); std::string message; if (mDays == 1) diff --git a/apps/openmw/mwgui/jailscreen.hpp b/apps/openmw/mwgui/jailscreen.hpp index 871a861d77..42a70abf44 100644 --- a/apps/openmw/mwgui/jailscreen.hpp +++ b/apps/openmw/mwgui/jailscreen.hpp @@ -1,32 +1,32 @@ #ifndef MWGUI_JAILSCREEN_H #define MWGUI_JAILSCREEN_H -#include "windowbase.hpp" #include "timeadvancer.hpp" +#include "windowbase.hpp" namespace MWGui { class JailScreen : public WindowBase { - public: - JailScreen(); - void goToJail(int days); + public: + JailScreen(); + void goToJail(int days); - void onFrame(float dt) override; + void onFrame(float dt) override; - bool exit() override { return false; } + bool exit() override { return false; } - private: - int mDays; + private: + int mDays; - float mFadeTimeRemaining; + float mFadeTimeRemaining; - MyGUI::ScrollBar* mProgressBar; + MyGUI::ScrollBar* mProgressBar; - void onJailProgressChanged(int cur, int total); - void onJailFinished(); + void onJailProgressChanged(int cur, int total); + void onJailFinished(); - TimeAdvancer mTimeAdvancer; + TimeAdvancer mTimeAdvancer; }; } diff --git a/apps/openmw/mwgui/journalbooks.cpp b/apps/openmw/mwgui/journalbooks.cpp index 40053b3c8a..f16491f2d5 100644 --- a/apps/openmw/mwgui/journalbooks.cpp +++ b/apps/openmw/mwgui/journalbooks.cpp @@ -15,29 +15,30 @@ namespace MWGui::BookTypesetter::Ptr mTypesetter; MWGui::BookTypesetter::Style* mBodyStyle; - AddContent (MWGui::BookTypesetter::Ptr typesetter, MWGui::BookTypesetter::Style* body_style) : - mTypesetter (typesetter), mBodyStyle (body_style) + AddContent(MWGui::BookTypesetter::Ptr typesetter, MWGui::BookTypesetter::Style* body_style) + : mTypesetter(typesetter) + , mBodyStyle(body_style) { } }; struct AddSpan : AddContent { - AddSpan (MWGui::BookTypesetter::Ptr typesetter, MWGui::BookTypesetter::Style* body_style) : - AddContent (typesetter, body_style) + AddSpan(MWGui::BookTypesetter::Ptr typesetter, MWGui::BookTypesetter::Style* body_style) + : AddContent(typesetter, body_style) { } - void operator () (intptr_t topicId, size_t begin, size_t end) + void operator()(intptr_t topicId, size_t begin, size_t end) { MWGui::BookTypesetter::Style* style = mBodyStyle; const MWGui::TextColours& textColours = MWBase::Environment::get().getWindowManager()->getTextColours(); if (topicId) - style = mTypesetter->createHotStyle (mBodyStyle, textColours.journalLink, textColours.journalLinkOver, - textColours.journalLinkPressed, topicId); + style = mTypesetter->createHotStyle(mBodyStyle, textColours.journalLink, textColours.journalLinkOver, + textColours.journalLinkPressed, topicId); - mTypesetter->write (style, begin, end); + mTypesetter->write(style, begin, end); } }; @@ -46,16 +47,17 @@ namespace MWGui::BookTypesetter::Ptr mTypesetter; MWGui::BookTypesetter::Style* mBodyStyle; - AddEntry (MWGui::BookTypesetter::Ptr typesetter, MWGui::BookTypesetter::Style* body_style) : - mTypesetter (typesetter), mBodyStyle (body_style) + AddEntry(MWGui::BookTypesetter::Ptr typesetter, MWGui::BookTypesetter::Style* body_style) + : mTypesetter(typesetter) + , mBodyStyle(body_style) { } - void operator () (MWGui::JournalViewModel::Entry const & entry) + void operator()(MWGui::JournalViewModel::Entry const& entry) { - mTypesetter->addContent (entry.body ()); + mTypesetter->addContent(entry.body()); - entry.visitSpans (AddSpan (mTypesetter, mBodyStyle)); + entry.visitSpans(AddSpan(mTypesetter, mBodyStyle)); } }; @@ -64,25 +66,25 @@ namespace bool mAddHeader; MWGui::BookTypesetter::Style* mHeaderStyle; - AddJournalEntry (MWGui::BookTypesetter::Ptr typesetter, MWGui::BookTypesetter::Style* body_style, - MWGui::BookTypesetter::Style* header_style, bool add_header) : - AddEntry (typesetter, body_style), - mAddHeader (add_header), - mHeaderStyle (header_style) + AddJournalEntry(MWGui::BookTypesetter::Ptr typesetter, MWGui::BookTypesetter::Style* body_style, + MWGui::BookTypesetter::Style* header_style, bool add_header) + : AddEntry(typesetter, body_style) + , mAddHeader(add_header) + , mHeaderStyle(header_style) { } - void operator () (MWGui::JournalViewModel::JournalEntry const & entry) + void operator()(MWGui::JournalViewModel::JournalEntry const& entry) { if (mAddHeader) { - mTypesetter->write (mHeaderStyle, entry.timestamp ()); - mTypesetter->lineBreak (); + mTypesetter->write(mHeaderStyle, entry.timestamp()); + mTypesetter->lineBreak(); } - AddEntry::operator () (entry); + AddEntry::operator()(entry); - mTypesetter->sectionBreak (30); + mTypesetter->sectionBreak(30); } }; @@ -91,51 +93,53 @@ namespace intptr_t mContentId; MWGui::BookTypesetter::Style* mHeaderStyle; - AddTopicEntry (MWGui::BookTypesetter::Ptr typesetter, MWGui::BookTypesetter::Style* body_style, - MWGui::BookTypesetter::Style* header_style, intptr_t contentId) : - AddEntry (typesetter, body_style), mContentId (contentId), mHeaderStyle (header_style) + AddTopicEntry(MWGui::BookTypesetter::Ptr typesetter, MWGui::BookTypesetter::Style* body_style, + MWGui::BookTypesetter::Style* header_style, intptr_t contentId) + : AddEntry(typesetter, body_style) + , mContentId(contentId) + , mHeaderStyle(header_style) { } - void operator () (MWGui::JournalViewModel::TopicEntry const & entry) + void operator()(MWGui::JournalViewModel::TopicEntry const& entry) { - mTypesetter->write (mBodyStyle, entry.source ()); - mTypesetter->write (mBodyStyle, 0, 3);// begin + mTypesetter->write(mBodyStyle, entry.source()); + mTypesetter->write(mBodyStyle, 0, 3); // begin - AddEntry::operator() (entry); + AddEntry::operator()(entry); - mTypesetter->selectContent (mContentId); - mTypesetter->write (mBodyStyle, 2, 3);// end quote + mTypesetter->selectContent(mContentId); + mTypesetter->write(mBodyStyle, 2, 3); // end quote - mTypesetter->sectionBreak (30); + mTypesetter->sectionBreak(30); } }; struct AddTopicName : AddContent { - AddTopicName (MWGui::BookTypesetter::Ptr typesetter, MWGui::BookTypesetter::Style* style) : - AddContent (typesetter, style) + AddTopicName(MWGui::BookTypesetter::Ptr typesetter, MWGui::BookTypesetter::Style* style) + : AddContent(typesetter, style) { } - void operator () (MWGui::JournalViewModel::Utf8Span topicName) + void operator()(MWGui::JournalViewModel::Utf8Span topicName) { - mTypesetter->write (mBodyStyle, topicName); - mTypesetter->sectionBreak (); + mTypesetter->write(mBodyStyle, topicName); + mTypesetter->sectionBreak(); } }; struct AddQuestName : AddContent { - AddQuestName (MWGui::BookTypesetter::Ptr typesetter, MWGui::BookTypesetter::Style* style) : - AddContent (typesetter, style) + AddQuestName(MWGui::BookTypesetter::Ptr typesetter, MWGui::BookTypesetter::Style* style) + : AddContent(typesetter, style) { } - void operator () (MWGui::JournalViewModel::Utf8Span topicName) + void operator()(MWGui::JournalViewModel::Utf8Span topicName) { - mTypesetter->write (mBodyStyle, topicName); - mTypesetter->sectionBreak (); + mTypesetter->write(mBodyStyle, topicName); + mTypesetter->sectionBreak(); } }; } @@ -143,176 +147,178 @@ namespace namespace MWGui { -MWGui::BookTypesetter::Utf8Span to_utf8_span (char const * text) -{ - typedef MWGui::BookTypesetter::Utf8Point point; + MWGui::BookTypesetter::Utf8Span to_utf8_span(char const* text) + { + typedef MWGui::BookTypesetter::Utf8Point point; - point begin = reinterpret_cast (text); + point begin = reinterpret_cast(text); - return MWGui::BookTypesetter::Utf8Span (begin, begin + strlen (text)); -} + return MWGui::BookTypesetter::Utf8Span(begin, begin + strlen(text)); + } -typedef TypesetBook::Ptr book; + typedef TypesetBook::Ptr book; -JournalBooks::JournalBooks (JournalViewModel::Ptr model, ToUTF8::FromType encoding) : - mModel (model), mEncoding(encoding), mIndexPagesCount(0) -{ -} + JournalBooks::JournalBooks(JournalViewModel::Ptr model, ToUTF8::FromType encoding) + : mModel(model) + , mEncoding(encoding) + , mIndexPagesCount(0) + { + } -book JournalBooks::createEmptyJournalBook () -{ - BookTypesetter::Ptr typesetter = createTypesetter (); + book JournalBooks::createEmptyJournalBook() + { + BookTypesetter::Ptr typesetter = createTypesetter(); - BookTypesetter::Style* header = typesetter->createStyle ("", MyGUI::Colour (0.60f, 0.00f, 0.00f)); - BookTypesetter::Style* body = typesetter->createStyle ("", MyGUI::Colour::Black); + BookTypesetter::Style* header = typesetter->createStyle("", MyGUI::Colour(0.60f, 0.00f, 0.00f)); + BookTypesetter::Style* body = typesetter->createStyle("", MyGUI::Colour::Black); - typesetter->write (header, to_utf8_span ("You have no journal entries!")); - typesetter->lineBreak (); - typesetter->write (body, to_utf8_span ("You should have gone though the starting quest and got an initial quest.")); + typesetter->write(header, to_utf8_span("You have no journal entries!")); + typesetter->lineBreak(); + typesetter->write( + body, to_utf8_span("You should have gone though the starting quest and got an initial quest.")); - return typesetter->complete (); -} + return typesetter->complete(); + } -book JournalBooks::createJournalBook () -{ - BookTypesetter::Ptr typesetter = createTypesetter (); + book JournalBooks::createJournalBook() + { + BookTypesetter::Ptr typesetter = createTypesetter(); - BookTypesetter::Style* header = typesetter->createStyle ("", MyGUI::Colour (0.60f, 0.00f, 0.00f)); - BookTypesetter::Style* body = typesetter->createStyle ("", MyGUI::Colour::Black); + BookTypesetter::Style* header = typesetter->createStyle("", MyGUI::Colour(0.60f, 0.00f, 0.00f)); + BookTypesetter::Style* body = typesetter->createStyle("", MyGUI::Colour::Black); - mModel->visitJournalEntries ("", AddJournalEntry (typesetter, body, header, true)); + mModel->visitJournalEntries("", AddJournalEntry(typesetter, body, header, true)); - return typesetter->complete (); -} + return typesetter->complete(); + } -book JournalBooks::createTopicBook (uintptr_t topicId) -{ - BookTypesetter::Ptr typesetter = createTypesetter (); + book JournalBooks::createTopicBook(uintptr_t topicId) + { + BookTypesetter::Ptr typesetter = createTypesetter(); - BookTypesetter::Style* header = typesetter->createStyle ("", MyGUI::Colour (0.60f, 0.00f, 0.00f)); - BookTypesetter::Style* body = typesetter->createStyle ("", MyGUI::Colour::Black); + BookTypesetter::Style* header = typesetter->createStyle("", MyGUI::Colour(0.60f, 0.00f, 0.00f)); + BookTypesetter::Style* body = typesetter->createStyle("", MyGUI::Colour::Black); - mModel->visitTopicName (topicId, AddTopicName (typesetter, header)); + mModel->visitTopicName(topicId, AddTopicName(typesetter, header)); - intptr_t contentId = typesetter->addContent (to_utf8_span (", \"")); + intptr_t contentId = typesetter->addContent(to_utf8_span(", \"")); - mModel->visitTopicEntries (topicId, AddTopicEntry (typesetter, body, header, contentId)); + mModel->visitTopicEntries(topicId, AddTopicEntry(typesetter, body, header, contentId)); - return typesetter->complete (); -} + return typesetter->complete(); + } -book JournalBooks::createQuestBook (const std::string& questName) -{ - BookTypesetter::Ptr typesetter = createTypesetter (); + book JournalBooks::createQuestBook(const std::string& questName) + { + BookTypesetter::Ptr typesetter = createTypesetter(); - BookTypesetter::Style* header = typesetter->createStyle ("", MyGUI::Colour (0.60f, 0.00f, 0.00f)); - BookTypesetter::Style* body = typesetter->createStyle ("", MyGUI::Colour::Black); + BookTypesetter::Style* header = typesetter->createStyle("", MyGUI::Colour(0.60f, 0.00f, 0.00f)); + BookTypesetter::Style* body = typesetter->createStyle("", MyGUI::Colour::Black); - AddQuestName addName (typesetter, header); - addName(to_utf8_span(questName.c_str())); + AddQuestName addName(typesetter, header); + addName(to_utf8_span(questName.c_str())); - mModel->visitJournalEntries (questName, AddJournalEntry (typesetter, body, header, false)); + mModel->visitJournalEntries(questName, AddJournalEntry(typesetter, body, header, false)); - return typesetter->complete (); -} + return typesetter->complete(); + } -book JournalBooks::createTopicIndexBook () -{ - bool isRussian = (mEncoding == ToUTF8::WINDOWS_1251); + book JournalBooks::createTopicIndexBook() + { + bool isRussian = (mEncoding == ToUTF8::WINDOWS_1251); - BookTypesetter::Ptr typesetter = isRussian ? createCyrillicJournalIndex() : createLatinJournalIndex(); + BookTypesetter::Ptr typesetter = isRussian ? createCyrillicJournalIndex() : createLatinJournalIndex(); - return typesetter->complete (); -} + return typesetter->complete(); + } -BookTypesetter::Ptr JournalBooks::createLatinJournalIndex () -{ - BookTypesetter::Ptr typesetter = BookTypesetter::create (92, 260); + BookTypesetter::Ptr JournalBooks::createLatinJournalIndex() + { + BookTypesetter::Ptr typesetter = BookTypesetter::create(92, 260); - typesetter->setSectionAlignment (BookTypesetter::AlignCenter); + typesetter->setSectionAlignment(BookTypesetter::AlignCenter); - // Latin journal index always has two columns for now. - mIndexPagesCount = 2; + // Latin journal index always has two columns for now. + mIndexPagesCount = 2; - char ch = 'A'; + char ch = 'A'; - BookTypesetter::Style* body = typesetter->createStyle ("", MyGUI::Colour::Black); - for (int i = 0; i < 26; ++i) - { - char buffer [32]; - sprintf (buffer, "( %c )", ch); + BookTypesetter::Style* body = typesetter->createStyle("", MyGUI::Colour::Black); + for (int i = 0; i < 26; ++i) + { + char buffer[32]; + sprintf(buffer, "( %c )", ch); + + const MWGui::TextColours& textColours = MWBase::Environment::get().getWindowManager()->getTextColours(); + BookTypesetter::Style* style = typesetter->createHotStyle(body, textColours.journalTopic, + textColours.journalTopicOver, textColours.journalTopicPressed, (Utf8Stream::UnicodeChar)ch); - const MWGui::TextColours& textColours = MWBase::Environment::get().getWindowManager()->getTextColours(); - BookTypesetter::Style* style = typesetter->createHotStyle (body, textColours.journalTopic, - textColours.journalTopicOver, - textColours.journalTopicPressed, (Utf8Stream::UnicodeChar) ch); + if (i == 13) + typesetter->sectionBreak(); - if (i == 13) - typesetter->sectionBreak (); + typesetter->write(style, to_utf8_span(buffer)); + typesetter->lineBreak(); - typesetter->write (style, to_utf8_span (buffer)); - typesetter->lineBreak (); + ch++; + } - ch++; + return typesetter; } - return typesetter; -} + BookTypesetter::Ptr JournalBooks::createCyrillicJournalIndex() + { + BookTypesetter::Ptr typesetter = BookTypesetter::create(92, 260); -BookTypesetter::Ptr JournalBooks::createCyrillicJournalIndex () -{ - BookTypesetter::Ptr typesetter = BookTypesetter::create (92, 260); + typesetter->setSectionAlignment(BookTypesetter::AlignCenter); - typesetter->setSectionAlignment (BookTypesetter::AlignCenter); + BookTypesetter::Style* body = typesetter->createStyle("", MyGUI::Colour::Black); - BookTypesetter::Style* body = typesetter->createStyle ("", MyGUI::Colour::Black); + int fontHeight = MWBase::Environment::get().getWindowManager()->getFontHeight(); - int fontHeight = MWBase::Environment::get().getWindowManager()->getFontHeight(); + // for small font size split alphabet to two columns (2x15 characers), for big font size split it to three + // colums (3x10 characters). + int sectionBreak = 10; + mIndexPagesCount = 3; + if (fontHeight < 18) + { + sectionBreak = 15; + mIndexPagesCount = 2; + } - // for small font size split alphabet to two columns (2x15 characers), for big font size split it to three colums (3x10 characters). - int sectionBreak = 10; - mIndexPagesCount = 3; - if (fontHeight < 18) - { - sectionBreak = 15; - mIndexPagesCount = 2; - } + unsigned char ch[3] = { 0xd0, 0x90, 0x00 }; // CYRILLIC CAPITAL A is a 0xd090 in UTF-8 - unsigned char ch[3] = {0xd0, 0x90, 0x00}; // CYRILLIC CAPITAL A is a 0xd090 in UTF-8 + for (int i = 0; i < 32; ++i) + { + char buffer[32]; + sprintf(buffer, "( %c%c )", ch[0], ch[1]); - for (int i = 0; i < 32; ++i) - { - char buffer [32]; - sprintf(buffer, "( %c%c )", ch[0], ch[1]); + Utf8Stream stream((char*)ch); + Utf8Stream::UnicodeChar first = stream.peek(); - Utf8Stream stream ((char*) ch); - Utf8Stream::UnicodeChar first = stream.peek(); + const MWGui::TextColours& textColours = MWBase::Environment::get().getWindowManager()->getTextColours(); + BookTypesetter::Style* style = typesetter->createHotStyle( + body, textColours.journalTopic, textColours.journalTopicOver, textColours.journalTopicPressed, first); - const MWGui::TextColours& textColours = MWBase::Environment::get().getWindowManager()->getTextColours(); - BookTypesetter::Style* style = typesetter->createHotStyle (body, textColours.journalTopic, - textColours.journalTopicOver, - textColours.journalTopicPressed, first); + ch[1]++; - ch[1]++; + // Words can not be started with these characters + if (i == 26 || i == 28) + continue; - // Words can not be started with these characters - if (i == 26 || i == 28) - continue; + if (i % sectionBreak == 0) + typesetter->sectionBreak(); - if (i % sectionBreak == 0) - typesetter->sectionBreak (); + typesetter->write(style, to_utf8_span(buffer)); + typesetter->lineBreak(); + } - typesetter->write (style, to_utf8_span (buffer)); - typesetter->lineBreak (); + return typesetter; } - return typesetter; -} - -BookTypesetter::Ptr JournalBooks::createTypesetter () -{ - //TODO: determine page size from layout... - return BookTypesetter::create (240, 320); -} + BookTypesetter::Ptr JournalBooks::createTypesetter() + { + // TODO: determine page size from layout... + return BookTypesetter::create(240, 320); + } } diff --git a/apps/openmw/mwgui/journalbooks.hpp b/apps/openmw/mwgui/journalbooks.hpp index 05eda6e222..1045b81ed9 100644 --- a/apps/openmw/mwgui/journalbooks.hpp +++ b/apps/openmw/mwgui/journalbooks.hpp @@ -8,29 +8,29 @@ namespace MWGui { - MWGui::BookTypesetter::Utf8Span to_utf8_span (char const * text); + MWGui::BookTypesetter::Utf8Span to_utf8_span(char const* text); struct JournalBooks { typedef TypesetBook::Ptr Book; JournalViewModel::Ptr mModel; - JournalBooks (JournalViewModel::Ptr model, ToUTF8::FromType encoding); + JournalBooks(JournalViewModel::Ptr model, ToUTF8::FromType encoding); - Book createEmptyJournalBook (); - Book createJournalBook (); - Book createTopicBook (uintptr_t topicId); - Book createTopicBook (const std::string& topicId); - Book createQuestBook (const std::string& questName); - Book createTopicIndexBook (); + Book createEmptyJournalBook(); + Book createJournalBook(); + Book createTopicBook(uintptr_t topicId); + Book createTopicBook(const std::string& topicId); + Book createQuestBook(const std::string& questName); + Book createTopicIndexBook(); ToUTF8::FromType mEncoding; int mIndexPagesCount; private: - BookTypesetter::Ptr createTypesetter (); - BookTypesetter::Ptr createLatinJournalIndex (); - BookTypesetter::Ptr createCyrillicJournalIndex (); + BookTypesetter::Ptr createTypesetter(); + BookTypesetter::Ptr createLatinJournalIndex(); + BookTypesetter::Ptr createCyrillicJournalIndex(); }; } diff --git a/apps/openmw/mwgui/journalviewmodel.cpp b/apps/openmw/mwgui/journalviewmodel.cpp index 7e0832bb47..80e58a784a 100644 --- a/apps/openmw/mwgui/journalviewmodel.cpp +++ b/apps/openmw/mwgui/journalviewmodel.cpp @@ -4,357 +4,353 @@ #include -#include #include +#include -#include "../mwbase/world.hpp" -#include "../mwbase/journal.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/journal.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" #include "../mwdialogue/keywordsearch.hpp" -namespace MWGui { - -struct JournalViewModelImpl; - -struct JournalViewModelImpl : JournalViewModel +namespace MWGui { - typedef MWDialogue::KeywordSearch KeywordSearchT; - mutable bool mKeywordSearchLoaded; - mutable KeywordSearchT mKeywordSearch; + struct JournalViewModelImpl; - JournalViewModelImpl () + struct JournalViewModelImpl : JournalViewModel { - mKeywordSearchLoaded = false; - } + typedef MWDialogue::KeywordSearch KeywordSearchT; - virtual ~JournalViewModelImpl () - { - } + mutable bool mKeywordSearchLoaded; + mutable KeywordSearchT mKeywordSearch; - /// \todo replace this nasty BS - static Utf8Span toUtf8Span(std::string_view str) - { - if (str.size () == 0) - return Utf8Span (Utf8Point (nullptr), Utf8Point (nullptr)); + JournalViewModelImpl() { mKeywordSearchLoaded = false; } - Utf8Point point = reinterpret_cast(str.data()); + virtual ~JournalViewModelImpl() {} - return Utf8Span (point, point + str.size ()); - } + /// \todo replace this nasty BS + static Utf8Span toUtf8Span(std::string_view str) + { + if (str.size() == 0) + return Utf8Span(Utf8Point(nullptr), Utf8Point(nullptr)); - void load () override - { - } + Utf8Point point = reinterpret_cast(str.data()); - void unload () override - { - mKeywordSearch.clear (); - mKeywordSearchLoaded = false; - } + return Utf8Span(point, point + str.size()); + } - void ensureKeyWordSearchLoaded () const - { - if (!mKeywordSearchLoaded) + void load() override {} + + void unload() override + { + mKeywordSearch.clear(); + mKeywordSearchLoaded = false; + } + + void ensureKeyWordSearchLoaded() const { - MWBase::Journal * journal = MWBase::Environment::get().getJournal(); + if (!mKeywordSearchLoaded) + { + MWBase::Journal* journal = MWBase::Environment::get().getJournal(); - for(MWBase::Journal::TTopicIter i = journal->topicBegin(); i != journal->topicEnd (); ++i) - mKeywordSearch.seed (i->first, intptr_t (&i->second)); + for (MWBase::Journal::TTopicIter i = journal->topicBegin(); i != journal->topicEnd(); ++i) + mKeywordSearch.seed(i->first, intptr_t(&i->second)); - mKeywordSearchLoaded = true; + mKeywordSearchLoaded = true; + } } - } - bool isEmpty () const override - { - MWBase::Journal * journal = MWBase::Environment::get().getJournal(); + bool isEmpty() const override + { + MWBase::Journal* journal = MWBase::Environment::get().getJournal(); - return journal->begin () == journal->end (); - } + return journal->begin() == journal->end(); + } - template - struct BaseEntry : Interface - { - typedef t_iterator iterator_t; + template + struct BaseEntry : Interface + { + typedef t_iterator iterator_t; - iterator_t itr; - JournalViewModelImpl const * mModel; + iterator_t itr; + JournalViewModelImpl const* mModel; - BaseEntry (JournalViewModelImpl const * model, iterator_t itr) : - itr (itr), mModel (model), loaded (false) - {} + BaseEntry(JournalViewModelImpl const* model, iterator_t itr) + : itr(itr) + , mModel(model) + , loaded(false) + { + } - virtual ~BaseEntry () {} + virtual ~BaseEntry() {} - mutable bool loaded; - mutable std::string utf8text; + mutable bool loaded; + mutable std::string utf8text; - typedef std::pair Range; + typedef std::pair Range; - // hyperlinks in @link# notation - mutable std::map mHyperLinks; + // hyperlinks in @link# notation + mutable std::map mHyperLinks; - virtual std::string getText () const = 0; + virtual std::string getText() const = 0; - void ensureLoaded () const - { - if (!loaded) + void ensureLoaded() const { - mModel->ensureKeyWordSearchLoaded (); - - utf8text = getText (); - - size_t pos_end = 0; - for(;;) + if (!loaded) { - size_t pos_begin = utf8text.find('@'); - if (pos_begin != std::string::npos) - pos_end = utf8text.find('#', pos_begin); - - if (pos_begin != std::string::npos && pos_end != std::string::npos) - { - std::string link = utf8text.substr(pos_begin + 1, pos_end - pos_begin - 1); - const char specialPseudoAsteriskCharacter = 127; - std::replace(link.begin(), link.end(), specialPseudoAsteriskCharacter, '*'); - std::string topicName = MWBase::Environment::get().getWindowManager()-> - getTranslationDataStorage().topicStandardForm(link); + mModel->ensureKeyWordSearchLoaded(); - std::string displayName = link; - while (displayName[displayName.size()-1] == '*') - displayName.erase(displayName.size()-1, 1); + utf8text = getText(); - utf8text.replace(pos_begin, pos_end+1-pos_begin, displayName); - - intptr_t value = 0; - if (mModel->mKeywordSearch.containsKeyword(topicName, value)) - mHyperLinks[std::make_pair(pos_begin, pos_begin+displayName.size())] = value; + size_t pos_end = 0; + for (;;) + { + size_t pos_begin = utf8text.find('@'); + if (pos_begin != std::string::npos) + pos_end = utf8text.find('#', pos_begin); + + if (pos_begin != std::string::npos && pos_end != std::string::npos) + { + std::string link = utf8text.substr(pos_begin + 1, pos_end - pos_begin - 1); + const char specialPseudoAsteriskCharacter = 127; + std::replace(link.begin(), link.end(), specialPseudoAsteriskCharacter, '*'); + std::string topicName = MWBase::Environment::get() + .getWindowManager() + ->getTranslationDataStorage() + .topicStandardForm(link); + + std::string displayName = link; + while (displayName[displayName.size() - 1] == '*') + displayName.erase(displayName.size() - 1, 1); + + utf8text.replace(pos_begin, pos_end + 1 - pos_begin, displayName); + + intptr_t value = 0; + if (mModel->mKeywordSearch.containsKeyword(topicName, value)) + mHyperLinks[std::make_pair(pos_begin, pos_begin + displayName.size())] = value; + } + else + break; } - else - break; - } - loaded = true; + loaded = true; + } } - } - - Utf8Span body () const override - { - ensureLoaded (); - return toUtf8Span (utf8text); - } + Utf8Span body() const override + { + ensureLoaded(); - void visitSpans (std::function < void (TopicId, size_t, size_t)> visitor) const override - { - ensureLoaded (); - mModel->ensureKeyWordSearchLoaded (); + return toUtf8Span(utf8text); + } - if (mHyperLinks.size() && MWBase::Environment::get().getWindowManager()->getTranslationDataStorage().hasTranslation()) + void visitSpans(std::function visitor) const override { - size_t formatted = 0; // points to the first character that is not laid out yet - for (std::map::const_iterator it = mHyperLinks.begin(); it != mHyperLinks.end(); ++it) + ensureLoaded(); + mModel->ensureKeyWordSearchLoaded(); + + if (mHyperLinks.size() + && MWBase::Environment::get().getWindowManager()->getTranslationDataStorage().hasTranslation()) { - intptr_t topicId = it->second; - if (formatted < it->first.first) - visitor (0, formatted, it->first.first); - visitor (topicId, it->first.first, it->first.second); - formatted = it->first.second; + size_t formatted = 0; // points to the first character that is not laid out yet + for (std::map::const_iterator it = mHyperLinks.begin(); it != mHyperLinks.end(); + ++it) + { + intptr_t topicId = it->second; + if (formatted < it->first.first) + visitor(0, formatted, it->first.first); + visitor(topicId, it->first.first, it->first.second); + formatted = it->first.second; + } + if (formatted < utf8text.size()) + visitor(0, formatted, utf8text.size()); } - if (formatted < utf8text.size()) - visitor (0, formatted, utf8text.size()); - } - else - { - std::vector matches; - mModel->mKeywordSearch.highlightKeywords(utf8text.begin(), utf8text.end(), matches); - - std::string::const_iterator i = utf8text.begin (); - for (std::vector::const_iterator it = matches.begin(); it != matches.end(); ++it) + else { - const KeywordSearchT::Match& match = *it; - - if (i != match.mBeg) - visitor (0, i - utf8text.begin (), match.mBeg - utf8text.begin ()); - - visitor (match.mValue, match.mBeg - utf8text.begin (), match.mEnd - utf8text.begin ()); + std::vector matches; + mModel->mKeywordSearch.highlightKeywords(utf8text.begin(), utf8text.end(), matches); - i = match.mEnd; - } + std::string::const_iterator i = utf8text.begin(); + for (std::vector::const_iterator it = matches.begin(); it != matches.end(); + ++it) + { + const KeywordSearchT::Match& match = *it; - if (i != utf8text.end ()) - visitor (0, i - utf8text.begin (), utf8text.size ()); - } - } + if (i != match.mBeg) + visitor(0, i - utf8text.begin(), match.mBeg - utf8text.begin()); - }; + visitor(match.mValue, match.mBeg - utf8text.begin(), match.mEnd - utf8text.begin()); - void visitQuestNames(bool active_only, std::function visitor) const override - { - MWBase::Journal * journal = MWBase::Environment::get ().getJournal (); + i = match.mEnd; + } - std::set> visitedQuests; + if (i != utf8text.end()) + visitor(0, i - utf8text.begin(), utf8text.size()); + } + } + }; - // Note that for purposes of the journal GUI, quests are identified by the name, not the ID, so several - // different quest IDs can end up in the same quest log. A quest log should be considered finished - // when any quest ID in that log is finished. - for (MWBase::Journal::TQuestIter i = journal->questBegin (); i != journal->questEnd (); ++i) + void visitQuestNames(bool active_only, std::function visitor) const override { - const MWDialogue::Quest& quest = i->second; + MWBase::Journal* journal = MWBase::Environment::get().getJournal(); + + std::set> visitedQuests; - bool isFinished = false; - for (MWBase::Journal::TQuestIter j = journal->questBegin (); j != journal->questEnd (); ++j) + // Note that for purposes of the journal GUI, quests are identified by the name, not the ID, so several + // different quest IDs can end up in the same quest log. A quest log should be considered finished + // when any quest ID in that log is finished. + for (MWBase::Journal::TQuestIter i = journal->questBegin(); i != journal->questEnd(); ++i) { - if (quest.getName() == j->second.getName() && j->second.isFinished()) - isFinished = true; - } + const MWDialogue::Quest& quest = i->second; - if (active_only && isFinished) - continue; + bool isFinished = false; + for (MWBase::Journal::TQuestIter j = journal->questBegin(); j != journal->questEnd(); ++j) + { + if (quest.getName() == j->second.getName() && j->second.isFinished()) + isFinished = true; + } - // Unfortunately Morrowind.esm has no quest names, since the quest book was added with tribunal. - // Note that even with Tribunal, some quests still don't have quest names. I'm assuming those are not supposed - // to appear in the quest book. - if (!quest.getName().empty()) - { - // Don't list the same quest name twice - if (visitedQuests.find(quest.getName()) != visitedQuests.end()) + if (active_only && isFinished) continue; - visitor (quest.getName(), isFinished); + // Unfortunately Morrowind.esm has no quest names, since the quest book was added with tribunal. + // Note that even with Tribunal, some quests still don't have quest names. I'm assuming those are not + // supposed to appear in the quest book. + if (!quest.getName().empty()) + { + // Don't list the same quest name twice + if (visitedQuests.find(quest.getName()) != visitedQuests.end()) + continue; + + visitor(quest.getName(), isFinished); - visitedQuests.emplace(quest.getName()); + visitedQuests.emplace(quest.getName()); + } } } - } - template - struct JournalEntryImpl : BaseEntry - { - using BaseEntry ::itr; + template + struct JournalEntryImpl : BaseEntry + { + using BaseEntry::itr; - mutable std::string timestamp_buffer; + mutable std::string timestamp_buffer; - JournalEntryImpl (JournalViewModelImpl const * model, iterator_t itr) : - BaseEntry (model, itr) - {} + JournalEntryImpl(JournalViewModelImpl const* model, iterator_t itr) + : BaseEntry(model, itr) + { + } - std::string getText () const override - { - return itr->getText(); - } + std::string getText() const override { return itr->getText(); } - Utf8Span timestamp () const override - { - if (timestamp_buffer.empty ()) + Utf8Span timestamp() const override { - std::string dayStr = MyGUI::LanguageManager::getInstance().replaceTags("#{sDay}"); - - std::ostringstream os; + if (timestamp_buffer.empty()) + { + std::string dayStr = MyGUI::LanguageManager::getInstance().replaceTags("#{sDay}"); - os - << itr->mDayOfMonth << ' ' - << MWBase::Environment::get().getWorld()->getMonthName (itr->mMonth) - << " (" << dayStr << " " << (itr->mDay) << ')'; + std::ostringstream os; - timestamp_buffer = os.str (); - } + os << itr->mDayOfMonth << ' ' << MWBase::Environment::get().getWorld()->getMonthName(itr->mMonth) + << " (" << dayStr << " " << (itr->mDay) << ')'; - return toUtf8Span (timestamp_buffer); - } - }; + timestamp_buffer = os.str(); + } - void visitJournalEntries (const std::string& questName, std::function visitor) const override - { - MWBase::Journal * journal = MWBase::Environment::get().getJournal(); + return toUtf8Span(timestamp_buffer); + } + }; - if (!questName.empty()) + void visitJournalEntries( + const std::string& questName, std::function visitor) const override { - std::vector quests; - for (MWBase::Journal::TQuestIter questIt = journal->questBegin(); questIt != journal->questEnd(); ++questIt) - { - if (Misc::StringUtils::ciEqual(questIt->second.getName(), questName)) - quests.push_back(&questIt->second); - } + MWBase::Journal* journal = MWBase::Environment::get().getJournal(); - for(MWBase::Journal::TEntryIter i = journal->begin(); i != journal->end (); ++i) + if (!questName.empty()) { - for (std::vector::iterator questIt = quests.begin(); questIt != quests.end(); ++questIt) + std::vector quests; + for (MWBase::Journal::TQuestIter questIt = journal->questBegin(); questIt != journal->questEnd(); + ++questIt) + { + if (Misc::StringUtils::ciEqual(questIt->second.getName(), questName)) + quests.push_back(&questIt->second); + } + + for (MWBase::Journal::TEntryIter i = journal->begin(); i != journal->end(); ++i) { - MWDialogue::Quest const* quest = *questIt; - for (MWDialogue::Topic::TEntryIter j = quest->begin (); j != quest->end (); ++j) + for (std::vector::iterator questIt = quests.begin(); + questIt != quests.end(); ++questIt) { - if (i->mInfoId == j->mInfoId) - visitor (JournalEntryImpl (this, i)); + MWDialogue::Quest const* quest = *questIt; + for (MWDialogue::Topic::TEntryIter j = quest->begin(); j != quest->end(); ++j) + { + if (i->mInfoId == j->mInfoId) + visitor(JournalEntryImpl(this, i)); + } } } } + else + { + for (MWBase::Journal::TEntryIter i = journal->begin(); i != journal->end(); ++i) + visitor(JournalEntryImpl(this, i)); + } } - else + + void visitTopicName(TopicId topicId, std::function visitor) const override { - for(MWBase::Journal::TEntryIter i = journal->begin(); i != journal->end (); ++i) - visitor (JournalEntryImpl (this, i)); + MWDialogue::Topic const& topic = *reinterpret_cast(topicId); + visitor(toUtf8Span(topic.getName())); } - } - - void visitTopicName (TopicId topicId, std::function visitor) const override - { - MWDialogue::Topic const & topic = * reinterpret_cast (topicId); - visitor (toUtf8Span (topic.getName())); - } - - void visitTopicNamesStartingWith(Utf8Stream::UnicodeChar character, std::function < void (std::string_view) > visitor) const override - { - MWBase::Journal * journal = MWBase::Environment::get().getJournal(); - for (MWBase::Journal::TTopicIter i = journal->topicBegin (); i != journal->topicEnd (); ++i) + void visitTopicNamesStartingWith( + Utf8Stream::UnicodeChar character, std::function visitor) const override { - Utf8Stream stream (i->first.c_str()); - Utf8Stream::UnicodeChar first = Utf8Stream::toLowerUtf8(stream.peek()); + MWBase::Journal* journal = MWBase::Environment::get().getJournal(); - if (first != Utf8Stream::toLowerUtf8(character)) - continue; + for (MWBase::Journal::TTopicIter i = journal->topicBegin(); i != journal->topicEnd(); ++i) + { + Utf8Stream stream(i->first.c_str()); + Utf8Stream::UnicodeChar first = Utf8Stream::toLowerUtf8(stream.peek()); + + if (first != Utf8Stream::toLowerUtf8(character)) + continue; - visitor (i->second.getName()); + visitor(i->second.getName()); + } } - } - struct TopicEntryImpl : BaseEntry - { - MWDialogue::Topic const & mTopic; + struct TopicEntryImpl : BaseEntry + { + MWDialogue::Topic const& mTopic; + + TopicEntryImpl(JournalViewModelImpl const* model, MWDialogue::Topic const& topic, iterator_t itr) + : BaseEntry(model, itr) + , mTopic(topic) + { + } - TopicEntryImpl (JournalViewModelImpl const * model, MWDialogue::Topic const & topic, iterator_t itr) : - BaseEntry (model, itr), mTopic (topic) - {} + std::string getText() const override { return itr->getText(); } - std::string getText () const override - { - return itr->getText(); - } + Utf8Span source() const override { return toUtf8Span(itr->mActorName); } + }; - Utf8Span source () const override + void visitTopicEntries(TopicId topicId, std::function visitor) const override { - return toUtf8Span (itr->mActorName); - } + typedef MWDialogue::Topic::TEntryIter iterator_t; + + MWDialogue::Topic const& topic = *reinterpret_cast(topicId); + for (iterator_t i = topic.begin(); i != topic.end(); ++i) + visitor(TopicEntryImpl(this, topic, i)); + } }; - void visitTopicEntries (TopicId topicId, std::function visitor) const override + JournalViewModel::Ptr JournalViewModel::create() { - typedef MWDialogue::Topic::TEntryIter iterator_t; - - MWDialogue::Topic const & topic = * reinterpret_cast (topicId); - - for (iterator_t i = topic.begin (); i != topic.end (); ++i) - visitor (TopicEntryImpl (this, topic, i)); + return std::make_shared(); } -}; - -JournalViewModel::Ptr JournalViewModel::create () -{ - return std::make_shared (); -} } diff --git a/apps/openmw/mwgui/journalviewmodel.hpp b/apps/openmw/mwgui/journalviewmodel.hpp index c49ccf3e20..125706aabb 100644 --- a/apps/openmw/mwgui/journalviewmodel.hpp +++ b/apps/openmw/mwgui/journalviewmodel.hpp @@ -1,10 +1,10 @@ #ifndef MWGUI_JOURNALVIEWMODEL_HPP #define MWGUI_JOURNALVIEWMODEL_HPP -#include -#include -#include #include +#include +#include +#include #include @@ -18,12 +18,12 @@ namespace MWGui /// game data store. struct JournalViewModel { - typedef std::shared_ptr Ptr; + typedef std::shared_ptr Ptr; typedef intptr_t QuestId; typedef intptr_t TopicId; - typedef uint8_t const * Utf8Point; - typedef std::pair Utf8Span; + typedef uint8_t const* Utf8Point; + typedef std::pair Utf8Span; /// The base interface for both journal entries and topics. struct Entry @@ -33,12 +33,12 @@ namespace MWGui /// This function returns a borrowed reference to the body of the /// journal entry. The returned reference becomes invalid when the /// entry is destroyed. - virtual Utf8Span body () const = 0; + virtual Utf8Span body() const = 0; /// Visits each subset of text in the body, delivering the beginning /// and end of the span relative to the body, and a valid topic ID if /// the span represents a keyword, or zero if not. - virtual void visitSpans (std::function visitor) const = 0; + virtual void visitSpans(std::function visitor) const = 0; virtual ~Entry() = default; }; @@ -48,7 +48,7 @@ namespace MWGui { /// Returns a pre-formatted span of UTF8 encoded text representing /// the name of the NPC this portion of dialog was heard from. - virtual Utf8Span source () const = 0; + virtual Utf8Span source() const = 0; virtual ~TopicEntry() = default; }; @@ -58,38 +58,40 @@ namespace MWGui { /// Returns a pre-formatted span of UTF8 encoded text representing /// the in-game date this entry was added to the journal. - virtual Utf8Span timestamp () const = 0; + virtual Utf8Span timestamp() const = 0; virtual ~JournalEntry() = default; }; /// called prior to journal opening - virtual void load () = 0; + virtual void load() = 0; /// called prior to journal closing - virtual void unload () = 0; + virtual void unload() = 0; /// returns true if their are no journal entries to display - virtual bool isEmpty () const = 0; + virtual bool isEmpty() const = 0; /// walks the active and optionally completed, quests providing the name and completed status - virtual void visitQuestNames(bool active_only, std::function visitor) const = 0; + virtual void visitQuestNames(bool active_only, std::function visitor) const = 0; /// walks over the journal entries related to all quests with the given name /// If \a questName is empty, simply visits all journal entries - virtual void visitJournalEntries (const std::string& questName, std::function visitor) const = 0; + virtual void visitJournalEntries( + const std::string& questName, std::function visitor) const = 0; /// provides the name of the topic specified by its id - virtual void visitTopicName (TopicId topicId, std::function visitor) const = 0; + virtual void visitTopicName(TopicId topicId, std::function visitor) const = 0; /// walks over the topics whose names start with the character - virtual void visitTopicNamesStartingWith(Utf8Stream::UnicodeChar character, std::function < void (std::string_view) > visitor) const = 0; + virtual void visitTopicNamesStartingWith( + Utf8Stream::UnicodeChar character, std::function visitor) const = 0; /// walks over the topic entries for the topic specified by its identifier - virtual void visitTopicEntries (TopicId topicId, std::function visitor) const = 0; + virtual void visitTopicEntries(TopicId topicId, std::function visitor) const = 0; // create an instance of the default journal view model implementation - static Ptr create (); + static Ptr create(); virtual ~JournalViewModel() = default; }; diff --git a/apps/openmw/mwgui/journalwindow.cpp b/apps/openmw/mwgui/journalwindow.cpp index 7009e66110..729e29edf3 100644 --- a/apps/openmw/mwgui/journalwindow.cpp +++ b/apps/openmw/mwgui/journalwindow.cpp @@ -5,45 +5,45 @@ #include #include -#include #include #include +#include #include #include #include #include "../mwbase/environment.hpp" -#include "../mwbase/windowmanager.hpp" #include "../mwbase/journal.hpp" +#include "../mwbase/windowmanager.hpp" #include "bookpage.hpp" -#include "windowbase.hpp" -#include "journalviewmodel.hpp" #include "journalbooks.hpp" +#include "journalviewmodel.hpp" +#include "windowbase.hpp" namespace { - static char const OptionsOverlay [] = "OptionsOverlay"; - static char const OptionsBTN [] = "OptionsBTN"; - static char const PrevPageBTN [] = "PrevPageBTN"; - static char const NextPageBTN [] = "NextPageBTN"; - static char const CloseBTN [] = "CloseBTN"; - static char const JournalBTN [] = "JournalBTN"; - static char const TopicsBTN [] = "TopicsBTN"; - static char const QuestsBTN [] = "QuestsBTN"; - static char const CancelBTN [] = "CancelBTN"; - static char const ShowAllBTN [] = "ShowAllBTN"; - static char const ShowActiveBTN [] = "ShowActiveBTN"; - static char const PageOneNum [] = "PageOneNum"; - static char const PageTwoNum [] = "PageTwoNum"; - static char const TopicsList [] = "TopicsList"; - static char const QuestsList [] = "QuestsList"; - static char const LeftBookPage [] = "LeftBookPage"; - static char const RightBookPage [] = "RightBookPage"; - static char const LeftTopicIndex [] = "LeftTopicIndex"; - static char const CenterTopicIndex [] = "CenterTopicIndex"; - static char const RightTopicIndex [] = "RightTopicIndex"; + static char const OptionsOverlay[] = "OptionsOverlay"; + static char const OptionsBTN[] = "OptionsBTN"; + static char const PrevPageBTN[] = "PrevPageBTN"; + static char const NextPageBTN[] = "NextPageBTN"; + static char const CloseBTN[] = "CloseBTN"; + static char const JournalBTN[] = "JournalBTN"; + static char const TopicsBTN[] = "TopicsBTN"; + static char const QuestsBTN[] = "QuestsBTN"; + static char const CancelBTN[] = "CancelBTN"; + static char const ShowAllBTN[] = "ShowAllBTN"; + static char const ShowActiveBTN[] = "ShowActiveBTN"; + static char const PageOneNum[] = "PageOneNum"; + static char const PageTwoNum[] = "PageTwoNum"; + static char const TopicsList[] = "TopicsList"; + static char const QuestsList[] = "QuestsList"; + static char const LeftBookPage[] = "LeftBookPage"; + static char const RightBookPage[] = "RightBookPage"; + static char const LeftTopicIndex[] = "LeftTopicIndex"; + static char const CenterTopicIndex[] = "CenterTopicIndex"; + static char const RightTopicIndex[] = "RightTopicIndex"; struct JournalWindowImpl : MWGui::JournalBooks, MWGui::JournalWindow { @@ -53,7 +53,7 @@ namespace Book mBook; }; - typedef std::stack DisplayStateStack; + typedef std::stack DisplayStateStack; DisplayStateStack mStates; Book mTopicIndexBook; @@ -63,66 +63,58 @@ namespace bool mAllQuests; template - T * getWidget (char const * name) + T* getWidget(char const* name) { - T * widget; - WindowBase::getWidget (widget, name); + T* widget; + WindowBase::getWidget(widget, name); return widget; } template - void setText (char const * name, value_type const & value) + void setText(char const* name, value_type const& value) { - getWidget (name) -> - setCaption (MyGUI::utility::toString (value)); + getWidget(name)->setCaption(MyGUI::utility::toString(value)); } - void setVisible (char const * name, bool visible) - { - getWidget (name) -> - setVisible (visible); - } + void setVisible(char const* name, bool visible) { getWidget(name)->setVisible(visible); } - void adviseButtonClick (char const * name, void (JournalWindowImpl::*handler)(MyGUI::Widget*)) + void adviseButtonClick(char const* name, void (JournalWindowImpl::*handler)(MyGUI::Widget*)) { - getWidget (name) -> - eventMouseButtonClick += newDelegate(this, handler); + getWidget(name)->eventMouseButtonClick += newDelegate(this, handler); } - void adviseKeyPress (char const * name, void (JournalWindowImpl::*handler)(MyGUI::Widget*, MyGUI::KeyCode, MyGUI::Char)) + void adviseKeyPress( + char const* name, void (JournalWindowImpl::*handler)(MyGUI::Widget*, MyGUI::KeyCode, MyGUI::Char)) { - getWidget (name) -> - eventKeyButtonPressed += newDelegate(this, handler); + getWidget(name)->eventKeyButtonPressed += newDelegate(this, handler); } - MWGui::BookPage* getPage (char const * name) - { - return getWidget (name); - } + MWGui::BookPage* getPage(char const* name) { return getWidget(name); } - JournalWindowImpl (MWGui::JournalViewModel::Ptr Model, bool questList, ToUTF8::FromType encoding) - : JournalBooks (Model, encoding), JournalWindow() + JournalWindowImpl(MWGui::JournalViewModel::Ptr Model, bool questList, ToUTF8::FromType encoding) + : JournalBooks(Model, encoding) + , JournalWindow() { center(); - adviseButtonClick (OptionsBTN, &JournalWindowImpl::notifyOptions ); - adviseButtonClick (PrevPageBTN, &JournalWindowImpl::notifyPrevPage ); - adviseButtonClick (NextPageBTN, &JournalWindowImpl::notifyNextPage ); - adviseButtonClick (CloseBTN, &JournalWindowImpl::notifyClose ); - adviseButtonClick (JournalBTN, &JournalWindowImpl::notifyJournal ); + adviseButtonClick(OptionsBTN, &JournalWindowImpl::notifyOptions); + adviseButtonClick(PrevPageBTN, &JournalWindowImpl::notifyPrevPage); + adviseButtonClick(NextPageBTN, &JournalWindowImpl::notifyNextPage); + adviseButtonClick(CloseBTN, &JournalWindowImpl::notifyClose); + adviseButtonClick(JournalBTN, &JournalWindowImpl::notifyJournal); - adviseButtonClick (TopicsBTN, &JournalWindowImpl::notifyTopics ); - adviseButtonClick (QuestsBTN, &JournalWindowImpl::notifyQuests ); - adviseButtonClick (CancelBTN, &JournalWindowImpl::notifyCancel ); + adviseButtonClick(TopicsBTN, &JournalWindowImpl::notifyTopics); + adviseButtonClick(QuestsBTN, &JournalWindowImpl::notifyQuests); + adviseButtonClick(CancelBTN, &JournalWindowImpl::notifyCancel); - adviseButtonClick (ShowAllBTN, &JournalWindowImpl::notifyShowAll ); - adviseButtonClick (ShowActiveBTN, &JournalWindowImpl::notifyShowActive); + adviseButtonClick(ShowAllBTN, &JournalWindowImpl::notifyShowAll); + adviseButtonClick(ShowActiveBTN, &JournalWindowImpl::notifyShowActive); - adviseKeyPress (OptionsBTN, &JournalWindowImpl::notifyKeyPress); - adviseKeyPress (PrevPageBTN, &JournalWindowImpl::notifyKeyPress); - adviseKeyPress (NextPageBTN, &JournalWindowImpl::notifyKeyPress); - adviseKeyPress (CloseBTN, &JournalWindowImpl::notifyKeyPress); - adviseKeyPress (JournalBTN, &JournalWindowImpl::notifyKeyPress); + adviseKeyPress(OptionsBTN, &JournalWindowImpl::notifyKeyPress); + adviseKeyPress(PrevPageBTN, &JournalWindowImpl::notifyKeyPress); + adviseKeyPress(NextPageBTN, &JournalWindowImpl::notifyKeyPress); + adviseKeyPress(CloseBTN, &JournalWindowImpl::notifyKeyPress); + adviseKeyPress(JournalBTN, &JournalWindowImpl::notifyKeyPress); Gui::MWList* list = getWidget(QuestsList); list->eventItemSelected += MyGUI::newDelegate(this, &JournalWindowImpl::notifyQuestClicked); @@ -132,24 +124,26 @@ namespace { MWGui::BookPage::ClickCallback callback; - - callback = std::bind (&JournalWindowImpl::notifyTopicClicked, this, std::placeholders::_1); - getPage (LeftBookPage)->adviseLinkClicked (callback); - getPage (RightBookPage)->adviseLinkClicked (callback); + callback = std::bind(&JournalWindowImpl::notifyTopicClicked, this, std::placeholders::_1); + + getPage(LeftBookPage)->adviseLinkClicked(callback); + getPage(RightBookPage)->adviseLinkClicked(callback); - getPage (LeftBookPage)->eventMouseWheel += MyGUI::newDelegate(this, &JournalWindowImpl::notifyMouseWheel); - getPage (RightBookPage)->eventMouseWheel += MyGUI::newDelegate(this, &JournalWindowImpl::notifyMouseWheel); + getPage(LeftBookPage)->eventMouseWheel + += MyGUI::newDelegate(this, &JournalWindowImpl::notifyMouseWheel); + getPage(RightBookPage)->eventMouseWheel + += MyGUI::newDelegate(this, &JournalWindowImpl::notifyMouseWheel); } { MWGui::BookPage::ClickCallback callback; - + callback = std::bind(&JournalWindowImpl::notifyIndexLinkClicked, this, std::placeholders::_1); - getPage (LeftTopicIndex)->adviseLinkClicked (callback); - getPage (CenterTopicIndex)->adviseLinkClicked (callback); - getPage (RightTopicIndex)->adviseLinkClicked (callback); + getPage(LeftTopicIndex)->adviseLinkClicked(callback); + getPage(CenterTopicIndex)->adviseLinkClicked(callback); + getPage(RightTopicIndex)->adviseLinkClicked(callback); } adjustButton(PrevPageBTN); @@ -167,8 +161,9 @@ namespace if (nextButton->getSize().width == 64) { // english button has a 7 pixel wide strip of garbage on its right edge - nextButton->setSize(64-7, nextButton->getSize().height); - nextButton->setImageCoord(MyGUI::IntCoord(0,0,(64-7)*nextButtonScale,nextButton->getSize().height*nextButtonScale)); + nextButton->setSize(64 - 7, nextButton->getSize().height); + nextButton->setImageCoord( + MyGUI::IntCoord(0, 0, (64 - 7) * nextButtonScale, nextButton->getSize().height * nextButtonScale)); } if (!questList) @@ -203,20 +198,26 @@ namespace adjustButton(TopicsBTN); int topicsWidth = getWidget(TopicsBTN)->getSize().width; int cancelLeft = getWidget(CancelBTN)->getPosition().left; - int cancelRight = getWidget(CancelBTN)->getPosition().left + getWidget(CancelBTN)->getSize().width; + int cancelRight = getWidget(CancelBTN)->getPosition().left + + getWidget(CancelBTN)->getSize().width; - getWidget(QuestsBTN)->setPosition(cancelRight, getWidget(QuestsBTN)->getPosition().top); + getWidget(QuestsBTN)->setPosition( + cancelRight, getWidget(QuestsBTN)->getPosition().top); - // Usually Topics, Quests, and Cancel buttons have the 64px width, so we can place the Topics left-up from the Cancel button, and the Quests right-up from the Cancel button. - // But in some installations, e.g. German one, the Topics button has the 128px width, so we should place it exactly left from the Quests button. + // Usually Topics, Quests, and Cancel buttons have the 64px width, so we can place the Topics left-up + // from the Cancel button, and the Quests right-up from the Cancel button. But in some installations, + // e.g. German one, the Topics button has the 128px width, so we should place it exactly left from the + // Quests button. if (topicsWidth == 64) { - getWidget(TopicsBTN)->setPosition(cancelLeft - topicsWidth, getWidget(TopicsBTN)->getPosition().top); + getWidget(TopicsBTN)->setPosition( + cancelLeft - topicsWidth, getWidget(TopicsBTN)->getPosition().top); } else { int questLeft = getWidget(QuestsBTN)->getPosition().left; - getWidget(TopicsBTN)->setPosition(questLeft - topicsWidth, getWidget(TopicsBTN)->getPosition().top); + getWidget(TopicsBTN)->setPosition( + questLeft - topicsWidth, getWidget(TopicsBTN)->getPosition().top); } } @@ -228,28 +229,28 @@ namespace void onOpen() override { - if (!MWBase::Environment::get().getWindowManager ()->getJournalAllowed ()) + if (!MWBase::Environment::get().getWindowManager()->getJournalAllowed()) { - MWBase::Environment::get().getWindowManager()->popGuiMode (); + MWBase::Environment::get().getWindowManager()->popGuiMode(); } - mModel->load (); + mModel->load(); - setBookMode (); + setBookMode(); Book journalBook; - if (mModel->isEmpty ()) - journalBook = createEmptyJournalBook (); + if (mModel->isEmpty()) + journalBook = createEmptyJournalBook(); else - journalBook = createJournalBook (); + journalBook = createJournalBook(); - pushBook (journalBook, 0); + pushBook(journalBook, 0); // fast forward to the last page - if (!mStates.empty ()) + if (!mStates.empty()) { - unsigned int & page = mStates.top ().mPage; - page = mStates.top().mBook->pageCount()-1; - if (page%2) + unsigned int& page = mStates.top().mPage; + page = mStates.top().mBook->pageCount() - 1; + if (page % 2) --page; } updateShowingPages(); @@ -259,57 +260,54 @@ namespace void onClose() override { - mModel->unload (); + mModel->unload(); - getPage (LeftBookPage)->showPage (Book (), 0); - getPage (RightBookPage)->showPage (Book (), 0); + getPage(LeftBookPage)->showPage(Book(), 0); + getPage(RightBookPage)->showPage(Book(), 0); - while (!mStates.empty ()) - mStates.pop (); + while (!mStates.empty()) + mStates.pop(); - mTopicIndexBook.reset (); + mTopicIndexBook.reset(); } - void setVisible (bool newValue) override - { - WindowBase::setVisible (newValue); - } + void setVisible(bool newValue) override { WindowBase::setVisible(newValue); } - void setBookMode () + void setBookMode() { mOptionsMode = false; mTopicsMode = false; - setVisible (OptionsBTN, true); - setVisible (OptionsOverlay, false); + setVisible(OptionsBTN, true); + setVisible(OptionsOverlay, false); - updateShowingPages (); - updateCloseJournalButton (); + updateShowingPages(); + updateCloseJournalButton(); } - void setOptionsMode () + void setOptionsMode() { mOptionsMode = true; mTopicsMode = false; - setVisible (OptionsBTN, false); - setVisible (OptionsOverlay, true); + setVisible(OptionsBTN, false); + setVisible(OptionsOverlay, true); - setVisible (PrevPageBTN, false); - setVisible (NextPageBTN, false); - setVisible (CloseBTN, false); - setVisible (JournalBTN, false); + setVisible(PrevPageBTN, false); + setVisible(NextPageBTN, false); + setVisible(CloseBTN, false); + setVisible(JournalBTN, false); - setVisible (TopicsList, false); - setVisible (QuestsList, mQuestMode); - setVisible (LeftTopicIndex, !mQuestMode); - setVisible (CenterTopicIndex, !mQuestMode); - setVisible (RightTopicIndex, !mQuestMode); - setVisible (ShowAllBTN, mQuestMode && !mAllQuests); - setVisible (ShowActiveBTN, mQuestMode && mAllQuests); + setVisible(TopicsList, false); + setVisible(QuestsList, mQuestMode); + setVisible(LeftTopicIndex, !mQuestMode); + setVisible(CenterTopicIndex, !mQuestMode); + setVisible(RightTopicIndex, !mQuestMode); + setVisible(ShowAllBTN, mQuestMode && !mAllQuests); + setVisible(ShowActiveBTN, mQuestMode && mAllQuests); - //TODO: figure out how to make "options" page overlay book page - // correctly, so that text may show underneath - getPage (RightBookPage)->showPage (Book (), 0); + // TODO: figure out how to make "options" page overlay book page + // correctly, so that text may show underneath + getPage(RightBookPage)->showPage(Book(), 0); // If in quest mode, ensure the quest list is updated if (mQuestMode) @@ -318,48 +316,48 @@ namespace notifyTopics(getWidget(TopicsList)); } - void pushBook (Book book, unsigned int page) + void pushBook(Book book, unsigned int page) { DisplayState bs; bs.mPage = page; bs.mBook = book; - mStates.push (bs); - updateShowingPages (); - updateCloseJournalButton (); + mStates.push(bs); + updateShowingPages(); + updateCloseJournalButton(); } - void replaceBook (Book book, unsigned int page) + void replaceBook(Book book, unsigned int page) { - assert (!mStates.empty ()); - mStates.top ().mBook = book; - mStates.top ().mPage = page; - updateShowingPages (); + assert(!mStates.empty()); + mStates.top().mBook = book; + mStates.top().mPage = page; + updateShowingPages(); } - void popBook () + void popBook() { - mStates.pop (); - updateShowingPages (); - updateCloseJournalButton (); + mStates.pop(); + updateShowingPages(); + updateCloseJournalButton(); } - void updateCloseJournalButton () + void updateCloseJournalButton() { - setVisible (CloseBTN, mStates.size () < 2); - setVisible (JournalBTN, mStates.size () >= 2); + setVisible(CloseBTN, mStates.size() < 2); + setVisible(JournalBTN, mStates.size() >= 2); } - void updateShowingPages () + void updateShowingPages() { Book book; unsigned int page; unsigned int relPages; - if (!mStates.empty ()) + if (!mStates.empty()) { - book = mStates.top ().mBook; - page = mStates.top ().mPage; - relPages = book->pageCount () - page; + book = mStates.top().mBook; + page = mStates.top().mPage; + relPages = book->pageCount() - page; } else { @@ -381,14 +379,14 @@ namespace else if (focus == prevPageBtn && !prevPageVisible && nextPageVisible) MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(nextPageBtn); - setVisible (PageOneNum, relPages > 0); - setVisible (PageTwoNum, relPages > 1); + setVisible(PageOneNum, relPages > 0); + setVisible(PageTwoNum, relPages > 1); - getPage (LeftBookPage)->showPage ((relPages > 0) ? book : Book (), page+0); - getPage (RightBookPage)->showPage ((relPages > 0) ? book : Book (), page+1); + getPage(LeftBookPage)->showPage((relPages > 0) ? book : Book(), page + 0); + getPage(RightBookPage)->showPage((relPages > 0) ? book : Book(), page + 1); - setText (PageOneNum, page + 1); - setText (PageTwoNum, page + 2); + setText(PageOneNum, page + 1); + setText(PageTwoNum, page + 2); } void notifyKeyPress(MyGUI::Widget* sender, MyGUI::KeyCode key, MyGUI::Char character) @@ -399,18 +397,18 @@ namespace notifyNextPage(sender); } - void notifyTopicClicked (intptr_t linkId) + void notifyTopicClicked(intptr_t linkId) { - Book topicBook = createTopicBook (linkId); + Book topicBook = createTopicBook(linkId); - if (mStates.size () > 1) - replaceBook (topicBook, 0); + if (mStates.size() > 1) + replaceBook(topicBook, 0); else - pushBook (topicBook, 0); + pushBook(topicBook, 0); - setVisible (OptionsOverlay, false); - setVisible (OptionsBTN, true); - setVisible (JournalBTN, true); + setVisible(OptionsOverlay, false); + setVisible(OptionsBTN, true); + setVisible(JournalBTN, true); mOptionsMode = false; mTopicsMode = false; @@ -418,31 +416,31 @@ namespace MWBase::Environment::get().getWindowManager()->playSound("book page"); } - void notifyTopicSelected (const std::string& topic, int id) + void notifyTopicSelected(const std::string& topic, int id) { const MWBase::Journal* journal = MWBase::Environment::get().getJournal(); intptr_t topicId = 0; /// \todo get rid of intptr ids - for(MWBase::Journal::TTopicIter i = journal->topicBegin(); i != journal->topicEnd (); ++i) + for (MWBase::Journal::TTopicIter i = journal->topicBegin(); i != journal->topicEnd(); ++i) { if (Misc::StringUtils::ciEqual(i->first, topic)) - topicId = intptr_t (&i->second); + topicId = intptr_t(&i->second); } notifyTopicClicked(topicId); } - void notifyQuestClicked (const std::string& name, int id) + void notifyQuestClicked(const std::string& name, int id) { - Book book = createQuestBook (name); + Book book = createQuestBook(name); - if (mStates.size () > 1) - replaceBook (book, 0); + if (mStates.size() > 1) + replaceBook(book, 0); else - pushBook (book, 0); + pushBook(book, 0); - setVisible (OptionsOverlay, false); - setVisible (OptionsBTN, true); - setVisible (JournalBTN, true); + setVisible(OptionsOverlay, false); + setVisible(OptionsBTN, true); + setVisible(JournalBTN, true); mOptionsMode = false; @@ -451,38 +449,38 @@ namespace void notifyOptions(MyGUI::Widget* _sender) { - setOptionsMode (); + setOptionsMode(); if (!mTopicIndexBook) - mTopicIndexBook = createTopicIndexBook (); + mTopicIndexBook = createTopicIndexBook(); if (mIndexPagesCount == 3) { - getPage (LeftTopicIndex)->showPage (mTopicIndexBook, 0); - getPage (CenterTopicIndex)->showPage (mTopicIndexBook, 1); - getPage (RightTopicIndex)->showPage (mTopicIndexBook, 2); + getPage(LeftTopicIndex)->showPage(mTopicIndexBook, 0); + getPage(CenterTopicIndex)->showPage(mTopicIndexBook, 1); + getPage(RightTopicIndex)->showPage(mTopicIndexBook, 2); } else { - getPage (LeftTopicIndex)->showPage (mTopicIndexBook, 0); - getPage (RightTopicIndex)->showPage (mTopicIndexBook, 1); + getPage(LeftTopicIndex)->showPage(mTopicIndexBook, 0); + getPage(RightTopicIndex)->showPage(mTopicIndexBook, 1); } } void notifyJournal(MyGUI::Widget* _sender) { - assert (mStates.size () > 1); - popBook (); + assert(mStates.size() > 1); + popBook(); MWBase::Environment::get().getWindowManager()->playSound("book page"); } - void notifyIndexLinkClicked (MWGui::TypesetBook::InteractiveId index) + void notifyIndexLinkClicked(MWGui::TypesetBook::InteractiveId index) { - setVisible (LeftTopicIndex, false); - setVisible (CenterTopicIndex, false); - setVisible (RightTopicIndex, false); - setVisible (TopicsList, true); + setVisible(LeftTopicIndex, false); + setVisible(CenterTopicIndex, false); + setVisible(RightTopicIndex, false); + setVisible(TopicsList, true); mTopicsMode = true; @@ -502,33 +500,36 @@ namespace { mQuestMode = false; mTopicsMode = false; - setVisible (LeftTopicIndex, true); - setVisible (CenterTopicIndex, true); - setVisible (RightTopicIndex, true); - setVisible (TopicsList, false); - setVisible (QuestsList, false); - setVisible (ShowAllBTN, false); - setVisible (ShowActiveBTN, false); + setVisible(LeftTopicIndex, true); + setVisible(CenterTopicIndex, true); + setVisible(RightTopicIndex, true); + setVisible(TopicsList, false); + setVisible(QuestsList, false); + setVisible(ShowAllBTN, false); + setVisible(ShowActiveBTN, false); MWBase::Environment::get().getWindowManager()->playSound("book page"); } struct AddNamesToList { - AddNamesToList(Gui::MWList* list) : mList(list) {} - - Gui::MWList* mList; - void operator() (std::string_view name, bool finished = false) + AddNamesToList(Gui::MWList* list) + : mList(list) { - mList->addItem(name); } + + Gui::MWList* mList; + void operator()(std::string_view name, bool finished = false) { mList->addItem(name); } }; struct SetNamesInactive { - SetNamesInactive(Gui::MWList* list) : mList(list) {} + SetNamesInactive(Gui::MWList* list) + : mList(list) + { + } Gui::MWList* mList; - void operator() (std::string_view name, bool finished) + void operator()(std::string_view name, bool finished) { if (finished) { @@ -541,13 +542,13 @@ namespace { mQuestMode = true; - setVisible (LeftTopicIndex, false); - setVisible (CenterTopicIndex, false); - setVisible (RightTopicIndex, false); - setVisible (TopicsList, false); - setVisible (QuestsList, true); - setVisible (ShowAllBTN, !mAllQuests); - setVisible (ShowActiveBTN, mAllQuests); + setVisible(LeftTopicIndex, false); + setVisible(CenterTopicIndex, false); + setVisible(RightTopicIndex, false); + setVisible(TopicsList, false); + setVisible(QuestsList, true); + setVisible(ShowAllBTN, !mAllQuests); + setVisible(ShowActiveBTN, mAllQuests); Gui::MWList* list = getWidget(QuestsList); list->clear(); @@ -590,12 +591,11 @@ namespace setBookMode(); MWBase::Environment::get().getWindowManager()->playSound("book page"); } - } void notifyClose(MyGUI::Widget* _sender) { - MWBase::WindowManager *winMgr = MWBase::Environment::get().getWindowManager(); + MWBase::WindowManager* winMgr = MWBase::Environment::get().getWindowManager(); winMgr->playSound("book close"); winMgr->popGuiMode(); } @@ -612,17 +612,17 @@ namespace { if (mOptionsMode) return; - if (!mStates.empty ()) + if (!mStates.empty()) { - unsigned int & page = mStates.top ().mPage; - Book book = mStates.top ().mBook; + unsigned int& page = mStates.top().mPage; + Book book = mStates.top().mBook; - if (page+2 < book->pageCount()) + if (page + 2 < book->pageCount()) { MWBase::Environment::get().getWindowManager()->playSound("book page"); page += 2; - updateShowingPages (); + updateShowingPages(); } } } @@ -631,16 +631,16 @@ namespace { if (mOptionsMode) return; - if (!mStates.empty ()) + if (!mStates.empty()) { - unsigned int & page = mStates.top ().mPage; + unsigned int& page = mStates.top().mPage; - if(page >= 2) + if (page >= 2) { MWBase::Environment::get().getWindowManager()->playSound("book page"); page -= 2; - updateShowingPages (); + updateShowingPages(); } } } @@ -648,7 +648,8 @@ namespace } // glue the implementation to the interface -std::unique_ptr MWGui::JournalWindow::create(JournalViewModel::Ptr Model, bool questList, ToUTF8::FromType encoding) +std::unique_ptr MWGui::JournalWindow::create( + JournalViewModel::Ptr Model, bool questList, ToUTF8::FromType encoding) { return std::make_unique(Model, questList, encoding); } @@ -656,5 +657,4 @@ std::unique_ptr MWGui::JournalWindow::create(JournalViewMo MWGui::JournalWindow::JournalWindow() : BookWindowBase("openmw_journal.layout") { - } diff --git a/apps/openmw/mwgui/journalwindow.hpp b/apps/openmw/mwgui/journalwindow.hpp index 0f3071f113..1c73e37a34 100644 --- a/apps/openmw/mwgui/journalwindow.hpp +++ b/apps/openmw/mwgui/journalwindow.hpp @@ -7,7 +7,10 @@ #include -namespace MWBase { class WindowManager; } +namespace MWBase +{ + class WindowManager; +} namespace MWGui { @@ -18,13 +21,14 @@ namespace MWGui JournalWindow(); /// construct a new instance of the one JournalWindow implementation - static std::unique_ptr create(std::shared_ptr Model, bool questList, ToUTF8::FromType encoding); + static std::unique_ptr create( + std::shared_ptr Model, bool questList, ToUTF8::FromType encoding); /// destroy this instance of the JournalWindow implementation - virtual ~JournalWindow () {} + virtual ~JournalWindow() {} /// show/hide the journal window - void setVisible (bool newValue) override = 0; + void setVisible(bool newValue) override = 0; }; } diff --git a/apps/openmw/mwgui/keyboardnavigation.cpp b/apps/openmw/mwgui/keyboardnavigation.cpp index 37b64f276c..a8fb52c95e 100644 --- a/apps/openmw/mwgui/keyboardnavigation.cpp +++ b/apps/openmw/mwgui/keyboardnavigation.cpp @@ -1,300 +1,301 @@ #include "keyboardnavigation.hpp" +#include #include #include -#include #include #include -#include "../mwbase/windowmanager.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/windowmanager.hpp" namespace MWGui { -bool shouldAcceptKeyFocus(MyGUI::Widget* w) -{ - return w && !w->castType(false) && w->getInheritedEnabled() && w->getInheritedVisible() && w->getVisible() && w->getEnabled(); -} - -/// Recursively get all child widgets that accept keyboard input -void getKeyFocusWidgets(MyGUI::Widget* parent, std::vector& results) -{ - assert(parent != nullptr); - - if (!parent->getVisible() || !parent->getEnabled()) - return; - - MyGUI::EnumeratorWidgetPtr enumerator = parent->getEnumerator(); - while (enumerator.next()) + bool shouldAcceptKeyFocus(MyGUI::Widget* w) { - MyGUI::Widget* w = enumerator.current(); - if (!w->getVisible() || !w->getEnabled()) - continue; - if (w->getNeedKeyFocus() && shouldAcceptKeyFocus(w)) - results.push_back(w); - else - getKeyFocusWidgets(w, results); + return w && !w->castType(false) && w->getInheritedEnabled() && w->getInheritedVisible() + && w->getVisible() && w->getEnabled(); } -} -KeyboardNavigation::KeyboardNavigation() - : mCurrentFocus(nullptr) - , mModalWindow(nullptr) - , mEnabled(true) -{ - MyGUI::WidgetManager::getInstance().registerUnlinker(this); -} - -KeyboardNavigation::~KeyboardNavigation() -{ - try + /// Recursively get all child widgets that accept keyboard input + void getKeyFocusWidgets(MyGUI::Widget* parent, std::vector& results) { - MyGUI::WidgetManager::getInstance().unregisterUnlinker(this); + assert(parent != nullptr); + + if (!parent->getVisible() || !parent->getEnabled()) + return; + + MyGUI::EnumeratorWidgetPtr enumerator = parent->getEnumerator(); + while (enumerator.next()) + { + MyGUI::Widget* w = enumerator.current(); + if (!w->getVisible() || !w->getEnabled()) + continue; + if (w->getNeedKeyFocus() && shouldAcceptKeyFocus(w)) + results.push_back(w); + else + getKeyFocusWidgets(w, results); + } } - catch(const MyGUI::Exception& e) + + KeyboardNavigation::KeyboardNavigation() + : mCurrentFocus(nullptr) + , mModalWindow(nullptr) + , mEnabled(true) { - Log(Debug::Error) << "Error in the destructor: " << e.what(); + MyGUI::WidgetManager::getInstance().registerUnlinker(this); } -} -void KeyboardNavigation::saveFocus(int mode) -{ - MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget(); - if (shouldAcceptKeyFocus(focus)) + KeyboardNavigation::~KeyboardNavigation() { - mKeyFocus[mode] = focus; + try + { + MyGUI::WidgetManager::getInstance().unregisterUnlinker(this); + } + catch (const MyGUI::Exception& e) + { + Log(Debug::Error) << "Error in the destructor: " << e.what(); + } } - else if(shouldAcceptKeyFocus(mCurrentFocus)) + + void KeyboardNavigation::saveFocus(int mode) { - mKeyFocus[mode] = mCurrentFocus; + MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget(); + if (shouldAcceptKeyFocus(focus)) + { + mKeyFocus[mode] = focus; + } + else if (shouldAcceptKeyFocus(mCurrentFocus)) + { + mKeyFocus[mode] = mCurrentFocus; + } } -} -void KeyboardNavigation::restoreFocus(int mode) -{ - std::map::const_iterator found = mKeyFocus.find(mode); - if (found != mKeyFocus.end()) + void KeyboardNavigation::restoreFocus(int mode) { - MyGUI::Widget* w = found->second; - if (w && w->getVisible() && w->getEnabled() && w->getInheritedVisible() && w->getInheritedEnabled()) - MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(found->second); + std::map::const_iterator found = mKeyFocus.find(mode); + if (found != mKeyFocus.end()) + { + MyGUI::Widget* w = found->second; + if (w && w->getVisible() && w->getEnabled() && w->getInheritedVisible() && w->getInheritedEnabled()) + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(found->second); + } } -} -void KeyboardNavigation::_unlinkWidget(MyGUI::Widget *widget) -{ - for (std::pair& w : mKeyFocus) - if (w.second == widget) - w.second = nullptr; - if (widget == mCurrentFocus) - mCurrentFocus = nullptr; -} - -bool isRootParent(MyGUI::Widget* widget, MyGUI::Widget* root) -{ - while (widget && widget->getParent()) - widget = widget->getParent(); - return widget == root; -} - -void KeyboardNavigation::onFrame() -{ - if (!mEnabled) - return; - - if (!MWBase::Environment::get().getWindowManager()->isGuiMode()) + void KeyboardNavigation::_unlinkWidget(MyGUI::Widget* widget) { - MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(nullptr); - return; + for (std::pair& w : mKeyFocus) + if (w.second == widget) + w.second = nullptr; + if (widget == mCurrentFocus) + mCurrentFocus = nullptr; } - MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget(); - - if (focus == mCurrentFocus) + bool isRootParent(MyGUI::Widget* widget, MyGUI::Widget* root) { - return; + while (widget && widget->getParent()) + widget = widget->getParent(); + return widget == root; } - // workaround incorrect key focus resets (fix in MyGUI TBD) - if (!shouldAcceptKeyFocus(focus) && shouldAcceptKeyFocus(mCurrentFocus) && (!mModalWindow || isRootParent(mCurrentFocus, mModalWindow))) + void KeyboardNavigation::onFrame() { - MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCurrentFocus); - focus = mCurrentFocus; + if (!mEnabled) + return; + + if (!MWBase::Environment::get().getWindowManager()->isGuiMode()) + { + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(nullptr); + return; + } + + MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget(); + + if (focus == mCurrentFocus) + { + return; + } + + // workaround incorrect key focus resets (fix in MyGUI TBD) + if (!shouldAcceptKeyFocus(focus) && shouldAcceptKeyFocus(mCurrentFocus) + && (!mModalWindow || isRootParent(mCurrentFocus, mModalWindow))) + { + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCurrentFocus); + focus = mCurrentFocus; + } + + if (focus != mCurrentFocus) + { + mCurrentFocus = focus; + } } - if (focus != mCurrentFocus) + void KeyboardNavigation::setDefaultFocus(MyGUI::Widget* window, MyGUI::Widget* defaultFocus) { - mCurrentFocus = focus; + MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget(); + if (!focus || !shouldAcceptKeyFocus(focus)) + { + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(defaultFocus); + } + else + { + if (!isRootParent(focus, window)) + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(defaultFocus); + } } -} -void KeyboardNavigation::setDefaultFocus(MyGUI::Widget *window, MyGUI::Widget *defaultFocus) -{ - MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget(); - if (!focus || !shouldAcceptKeyFocus(focus)) + void KeyboardNavigation::setModalWindow(MyGUI::Widget* window) { - MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(defaultFocus); + mModalWindow = window; } - else + + void KeyboardNavigation::setEnabled(bool enabled) { - if (!isRootParent(focus, window)) - MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(defaultFocus); + mEnabled = enabled; } -} - -void KeyboardNavigation::setModalWindow(MyGUI::Widget *window) -{ - mModalWindow = window; -} - -void KeyboardNavigation::setEnabled(bool enabled) -{ - mEnabled = enabled; -} - -enum Direction -{ - D_Left, - D_Up, - D_Right, - D_Down, - D_Next, - D_Prev -}; - -bool KeyboardNavigation::injectKeyPress(MyGUI::KeyCode key, unsigned int text, bool repeat) -{ - if (!mEnabled) - return false; - switch (key.getValue()) + enum Direction { - case MyGUI::KeyCode::ArrowLeft: - return switchFocus(D_Left, false); - case MyGUI::KeyCode::ArrowRight: - return switchFocus(D_Right, false); - case MyGUI::KeyCode::ArrowUp: - return switchFocus(D_Up, false); - case MyGUI::KeyCode::ArrowDown: - return switchFocus(D_Down, false); - case MyGUI::KeyCode::Tab: - return switchFocus(MyGUI::InputManager::getInstance().isShiftPressed() ? D_Prev : D_Next, true); - case MyGUI::KeyCode::Return: - case MyGUI::KeyCode::NumpadEnter: - case MyGUI::KeyCode::Space: + D_Left, + D_Up, + D_Right, + D_Down, + D_Next, + D_Prev + }; + + bool KeyboardNavigation::injectKeyPress(MyGUI::KeyCode key, unsigned int text, bool repeat) { - // We should disable repeating for activation keys - MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::None); - if (repeat) - return true; + if (!mEnabled) + return false; - return accept(); - } - default: - return false; + switch (key.getValue()) + { + case MyGUI::KeyCode::ArrowLeft: + return switchFocus(D_Left, false); + case MyGUI::KeyCode::ArrowRight: + return switchFocus(D_Right, false); + case MyGUI::KeyCode::ArrowUp: + return switchFocus(D_Up, false); + case MyGUI::KeyCode::ArrowDown: + return switchFocus(D_Down, false); + case MyGUI::KeyCode::Tab: + return switchFocus(MyGUI::InputManager::getInstance().isShiftPressed() ? D_Prev : D_Next, true); + case MyGUI::KeyCode::Return: + case MyGUI::KeyCode::NumpadEnter: + case MyGUI::KeyCode::Space: + { + // We should disable repeating for activation keys + MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::None); + if (repeat) + return true; + + return accept(); + } + default: + return false; + } } -} - -bool KeyboardNavigation::switchFocus(int direction, bool wrap) -{ - if (!MWBase::Environment::get().getWindowManager()->isGuiMode()) - return false; - - MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget(); - bool isCycle = (direction == D_Prev || direction == D_Next); - - if ((focus && focus->getTypeName().find("Button") == std::string::npos) && !isCycle) - return false; + bool KeyboardNavigation::switchFocus(int direction, bool wrap) + { + if (!MWBase::Environment::get().getWindowManager()->isGuiMode()) + return false; - if (focus && isCycle && focus->getUserString("AcceptTab") == "true") - return false; + MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget(); - if ((!focus || !focus->getNeedKeyFocus()) && isCycle) - { - // if nothing is selected, select the first widget - return selectFirstWidget(); - } - if (!focus) - return false; + bool isCycle = (direction == D_Prev || direction == D_Next); - MyGUI::Widget* window = focus; - while (window && window->getParent()) - window = window->getParent(); - MyGUI::VectorWidgetPtr keyFocusList; - getKeyFocusWidgets(window, keyFocusList); + if ((focus && focus->getTypeName().find("Button") == std::string::npos) && !isCycle) + return false; - if (keyFocusList.empty()) - return false; + if (focus && isCycle && focus->getUserString("AcceptTab") == "true") + return false; - MyGUI::VectorWidgetPtr::iterator found = std::find(keyFocusList.begin(), keyFocusList.end(), focus); - if (found == keyFocusList.end()) - { - if (isCycle) + if ((!focus || !focus->getNeedKeyFocus()) && isCycle) + { + // if nothing is selected, select the first widget return selectFirstWidget(); - else + } + if (!focus) return false; - } - bool forward = (direction == D_Next || direction == D_Right || direction == D_Down); + MyGUI::Widget* window = focus; + while (window && window->getParent()) + window = window->getParent(); + MyGUI::VectorWidgetPtr keyFocusList; + getKeyFocusWidgets(window, keyFocusList); - int index = found - keyFocusList.begin(); - index = forward ? (index+1) : (index-1); - if (wrap) - index = (index + keyFocusList.size())%keyFocusList.size(); - else - index = std::clamp(index, 0, keyFocusList.size() - 1); + if (keyFocusList.empty()) + return false; - MyGUI::Widget* next = keyFocusList[index]; - int vertdiff = next->getTop() - focus->getTop(); - int horizdiff = next->getLeft() - focus->getLeft(); - bool isVertical = std::abs(vertdiff) > std::abs(horizdiff); - if (direction == D_Right && (horizdiff <= 0 || isVertical)) - return false; - else if (direction == D_Left && (horizdiff >= 0 || isVertical)) - return false; - else if (direction == D_Down && (vertdiff <= 0 || !isVertical)) - return false; - else if (direction == D_Up && (vertdiff >= 0 || !isVertical)) - return false; + MyGUI::VectorWidgetPtr::iterator found = std::find(keyFocusList.begin(), keyFocusList.end(), focus); + if (found == keyFocusList.end()) + { + if (isCycle) + return selectFirstWidget(); + else + return false; + } + + bool forward = (direction == D_Next || direction == D_Right || direction == D_Down); + + int index = found - keyFocusList.begin(); + index = forward ? (index + 1) : (index - 1); + if (wrap) + index = (index + keyFocusList.size()) % keyFocusList.size(); + else + index = std::clamp(index, 0, keyFocusList.size() - 1); - MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(keyFocusList[index]); - return true; -} + MyGUI::Widget* next = keyFocusList[index]; + int vertdiff = next->getTop() - focus->getTop(); + int horizdiff = next->getLeft() - focus->getLeft(); + bool isVertical = std::abs(vertdiff) > std::abs(horizdiff); + if (direction == D_Right && (horizdiff <= 0 || isVertical)) + return false; + else if (direction == D_Left && (horizdiff >= 0 || isVertical)) + return false; + else if (direction == D_Down && (vertdiff <= 0 || !isVertical)) + return false; + else if (direction == D_Up && (vertdiff >= 0 || !isVertical)) + return false; -bool KeyboardNavigation::selectFirstWidget() -{ - MyGUI::VectorWidgetPtr keyFocusList; - MyGUI::EnumeratorWidgetPtr enumerator = MyGUI::Gui::getInstance().getEnumerator(); - if (mModalWindow) - enumerator = mModalWindow->getEnumerator(); - while (enumerator.next()) - getKeyFocusWidgets(enumerator.current(), keyFocusList); - - if (!keyFocusList.empty()) - { - MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(keyFocusList[0]); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(keyFocusList[index]); return true; } - return false; -} -bool KeyboardNavigation::accept() -{ - MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget(); - if (!focus) - return false; - //MyGUI::Button* button = focus->castType(false); - //if (button && button->getEnabled()) - if (focus->getTypeName().find("Button") != std::string::npos && focus->getEnabled()) + bool KeyboardNavigation::selectFirstWidget() { - focus->eventMouseButtonClick(focus); - return true; + MyGUI::VectorWidgetPtr keyFocusList; + MyGUI::EnumeratorWidgetPtr enumerator = MyGUI::Gui::getInstance().getEnumerator(); + if (mModalWindow) + enumerator = mModalWindow->getEnumerator(); + while (enumerator.next()) + getKeyFocusWidgets(enumerator.current(), keyFocusList); + + if (!keyFocusList.empty()) + { + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(keyFocusList[0]); + return true; + } + return false; } - return false; -} + bool KeyboardNavigation::accept() + { + MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget(); + if (!focus) + return false; + // MyGUI::Button* button = focus->castType(false); + // if (button && button->getEnabled()) + if (focus->getTypeName().find("Button") != std::string::npos && focus->getEnabled()) + { + focus->eventMouseButtonClick(focus); + return true; + } + return false; + } } diff --git a/apps/openmw/mwgui/keyboardnavigation.hpp b/apps/openmw/mwgui/keyboardnavigation.hpp index d5159c24a0..e37fe9088b 100644 --- a/apps/openmw/mwgui/keyboardnavigation.hpp +++ b/apps/openmw/mwgui/keyboardnavigation.hpp @@ -1,8 +1,8 @@ #ifndef OPENMW_MWGUI_KEYBOARDNAVIGATION_H #define OPENMW_MWGUI_KEYBOARDNAVIGATION_H -#include #include +#include namespace MWGui { diff --git a/apps/openmw/mwgui/layout.cpp b/apps/openmw/mwgui/layout.cpp index 2f763b6552..fb0fb5e1c5 100644 --- a/apps/openmw/mwgui/layout.cpp +++ b/apps/openmw/mwgui/layout.cpp @@ -1,9 +1,9 @@ #include "layout.hpp" -#include -#include #include +#include #include +#include #include #include "ustring.hpp" @@ -27,7 +27,8 @@ namespace MWGui // Force the alignment to update immediately widget->_setAlign(widget->getSize(), widget->getParentSize()); } - MYGUI_ASSERT(mMainWidget, "root widget name '" << MAIN_WINDOW << "' in layout '" << mLayoutName << "' not found."); + MYGUI_ASSERT( + mMainWidget, "root widget name '" << MAIN_WINDOW << "' in layout '" << mLayoutName << "' not found."); } void Layout::shutdown() @@ -39,7 +40,7 @@ namespace MWGui void Layout::setCoord(int x, int y, int w, int h) { - mMainWidget->setCoord(x,y,w,h); + mMainWidget->setCoord(x, y, w, h); } void Layout::setVisible(bool b) diff --git a/apps/openmw/mwgui/layout.hpp b/apps/openmw/mwgui/layout.hpp index 7239f6a80c..07a3d1e66b 100644 --- a/apps/openmw/mwgui/layout.hpp +++ b/apps/openmw/mwgui/layout.hpp @@ -10,69 +10,69 @@ namespace MWGui { - /** The Layout class is an utility class used to load MyGUI layouts - from xml files, and to manipulate member widgets. - */ - class Layout - { - public: - Layout(std::string_view layout) : mMainWidget(nullptr) + /** The Layout class is an utility class used to load MyGUI layouts + from xml files, and to manipulate member widgets. + */ + class Layout { - initialise(layout); - assert(mMainWidget); - } - - virtual ~Layout() - { - try + public: + Layout(std::string_view layout) + : mMainWidget(nullptr) { - shutdown(); + initialise(layout); + assert(mMainWidget); } - catch(const MyGUI::Exception& e) + + virtual ~Layout() { - Log(Debug::Error) << "Error in the destructor: " << e.what(); + try + { + shutdown(); + } + catch (const MyGUI::Exception& e) + { + Log(Debug::Error) << "Error in the destructor: " << e.what(); + } } - } - MyGUI::Widget* getWidget(std::string_view name); + MyGUI::Widget* getWidget(std::string_view name); - template - void getWidget(T * & _widget, std::string_view _name) - { - MyGUI::Widget* w = getWidget(_name); - T* cast = w->castType(false); - if (!cast) + template + void getWidget(T*& _widget, std::string_view _name) { - MYGUI_EXCEPT("Error cast : dest type = '" << T::getClassTypeName() - << "' source name = '" << w->getName() - << "' source type = '" << w->getTypeName() << "' in layout '" << mLayoutName << "'"); + MyGUI::Widget* w = getWidget(_name); + T* cast = w->castType(false); + if (!cast) + { + MYGUI_EXCEPT("Error cast : dest type = '" << T::getClassTypeName() << "' source name = '" + << w->getName() << "' source type = '" << w->getTypeName() + << "' in layout '" << mLayoutName << "'"); + } + else + _widget = cast; } - else - _widget = cast; - } - - private: - void initialise(std::string_view layout); - void shutdown(); + private: + void initialise(std::string_view layout); - public: - void setCoord(int x, int y, int w, int h); + void shutdown(); - virtual void setVisible(bool b); + public: + void setCoord(int x, int y, int w, int h); - void setText(std::string_view name, std::string_view caption); + virtual void setVisible(bool b); - // NOTE: this assume that mMainWidget is of type Window. - void setTitle(std::string_view title); + void setText(std::string_view name, std::string_view caption); - MyGUI::Widget* mMainWidget; + // NOTE: this assume that mMainWidget is of type Window. + void setTitle(std::string_view title); - protected: + MyGUI::Widget* mMainWidget; - std::string mPrefix; - std::string mLayoutName; - MyGUI::VectorWidgetPtr mListWindowRoot; - }; + protected: + std::string mPrefix; + std::string mLayoutName; + MyGUI::VectorWidgetPtr mListWindowRoot; + }; } #endif diff --git a/apps/openmw/mwgui/levelupdialog.cpp b/apps/openmw/mwgui/levelupdialog.cpp index a4609ec16a..7c41c8865f 100644 --- a/apps/openmw/mwgui/levelupdialog.cpp +++ b/apps/openmw/mwgui/levelupdialog.cpp @@ -1,21 +1,21 @@ #include "levelupdialog.hpp" #include -#include #include +#include #include -#include "../mwbase/windowmanager.hpp" #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/soundmanager.hpp" +#include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" #include "../mwworld/class.hpp" +#include "../mwmechanics/actorutil.hpp" #include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/npcstats.hpp" -#include "../mwmechanics/actorutil.hpp" #include "class.hpp" #include "ustring.hpp" @@ -24,8 +24,8 @@ namespace MWGui { const unsigned int LevelupDialog::sMaxCoins = 3; LevelupDialog::LevelupDialog() - : WindowBase("openmw_levelup_dialog.layout"), - mCoinCount(sMaxCoins) + : WindowBase("openmw_levelup_dialog.layout") + , mCoinCount(sMaxCoins) { getWidget(mOkButton, "OkButton"); getWidget(mClassImage, "ClassImage"); @@ -36,7 +36,7 @@ namespace MWGui mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &LevelupDialog::onOkButtonClicked); - for (int i=1; i<9; ++i) + for (int i = 1; i < 9; ++i) { MyGUI::TextBox* t; getWidget(t, "AttribVal" + MyGUI::utility::toString(i)); @@ -44,7 +44,7 @@ namespace MWGui MyGUI::Button* b; getWidget(b, "Attrib" + MyGUI::utility::toString(i)); - b->setUserData (i-1); + b->setUserData(i - 1); b->eventMouseButtonClick += MyGUI::newDelegate(this, &LevelupDialog::onAttributeClicked); mAttributes.push_back(b); @@ -54,8 +54,9 @@ namespace MWGui for (unsigned int i = 0; i < mCoinCount; ++i) { - MyGUI::ImageBox* image = mCoinBox->createWidget("ImageBox", MyGUI::IntCoord(0,0,16,16), MyGUI::Align::Default); - image->setImageTexture ("icons\\tx_goldicon.dds"); + MyGUI::ImageBox* image = mCoinBox->createWidget( + "ImageBox", MyGUI::IntCoord(0, 0, 16, 16), MyGUI::Align::Default); + image->setImageTexture("icons\\tx_goldicon.dds"); mCoins.push_back(image); } @@ -64,9 +65,9 @@ namespace MWGui void LevelupDialog::setAttributeValues() { - MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWMechanics::CreatureStats& creatureStats = player.getClass().getCreatureStats(player); - MWMechanics::NpcStats& pcStats = player.getClass().getNpcStats (player); + MWMechanics::NpcStats& pcStats = player.getClass().getNpcStats(player); for (int i = 0; i < 8; ++i) { @@ -83,12 +84,11 @@ namespace MWGui } } - void LevelupDialog::resetCoins() { const int coinSpacing = 33; - int curX = mCoinBox->getWidth()/2 - (coinSpacing*(mCoinCount - 1) + 16*mCoinCount)/2; - for (unsigned int i=0; igetWidth() / 2 - (coinSpacing * (mCoinCount - 1) + 16 * mCoinCount) / 2; + for (unsigned int i = 0; i < sMaxCoins; ++i) { MyGUI::ImageBox* image = mCoins[i]; image->detachFromWidget(); @@ -96,8 +96,8 @@ namespace MWGui if (i < mCoinCount) { mCoins[i]->setVisible(true); - image->setCoord(MyGUI::IntCoord(curX,0,16,16)); - curX += 16+coinSpacing; + image->setCoord(MyGUI::IntCoord(curX, 0, 16, 16)); + curX += 16 + coinSpacing; } else mCoins[i]->setVisible(false); @@ -107,7 +107,7 @@ namespace MWGui void LevelupDialog::assignCoins() { resetCoins(); - for (unsigned int i=0; idetachFromWidget(); @@ -117,8 +117,9 @@ namespace MWGui int xdiff = mAttributeMultipliers[attribute]->getCaption() == "" ? 0 : 20; - MyGUI::IntPoint pos = mAttributes[attribute]->getAbsolutePosition() - mAssignWidget->getAbsolutePosition() - MyGUI::IntPoint(22+xdiff,0); - pos.top += (mAttributes[attribute]->getHeight() - image->getHeight())/2; + MyGUI::IntPoint pos = mAttributes[attribute]->getAbsolutePosition() - mAssignWidget->getAbsolutePosition() + - MyGUI::IntPoint(22 + xdiff, 0); + pos.top += (mAttributes[attribute]->getHeight() - image->getHeight()) / 2; image->setPosition(pos); } @@ -127,20 +128,20 @@ namespace MWGui void LevelupDialog::onOpen() { - MWBase::World *world = MWBase::Environment::get().getWorld(); + MWBase::World* world = MWBase::Environment::get().getWorld(); MWWorld::Ptr player = world->getPlayerPtr(); MWMechanics::CreatureStats& creatureStats = player.getClass().getCreatureStats(player); MWMechanics::NpcStats& pcStats = player.getClass().getNpcStats(player); - setClassImage(mClassImage, getLevelupClassImage(pcStats.getSkillIncreasesForSpecialization(0), - pcStats.getSkillIncreasesForSpecialization(1), - pcStats.getSkillIncreasesForSpecialization(2))); + setClassImage(mClassImage, + getLevelupClassImage(pcStats.getSkillIncreasesForSpecialization(0), + pcStats.getSkillIncreasesForSpecialization(1), pcStats.getSkillIncreasesForSpecialization(2))); - int level = creatureStats.getLevel ()+1; + int level = creatureStats.getLevel() + 1; mLevelText->setCaptionWithReplacing("#{sLevelUpMenu1} " + MyGUI::utility::toString(level)); std::string_view levelupdescription; - levelupdescription = Fallback::Map::getString("Level_Up_Level"+MyGUI::utility::toString(level)); + levelupdescription = Fallback::Map::getString("Level_Up_Level" + MyGUI::utility::toString(level)); if (levelupdescription.empty()) levelupdescription = Fallback::Map::getString("Level_Up_Default"); @@ -157,8 +158,8 @@ namespace MWGui mAttributeValues[i]->setEnabled(true); availableAttributes++; - float mult = pcStats.getLevelupAttributeMultiplier (i); - mult = std::min(mult, 100-pcStats.getAttribute(i).getBase()); + float mult = pcStats.getLevelupAttributeMultiplier(i); + mult = std::min(mult, 100 - pcStats.getAttribute(i).getBase()); text->setCaption(mult <= 1 ? "" : "x" + MyGUI::utility::toString(mult)); } else @@ -186,7 +187,7 @@ namespace MWGui void LevelupDialog::onOkButtonClicked(MyGUI::Widget* sender) { MWWorld::Ptr player = MWMechanics::getPlayer(); - MWMechanics::NpcStats& pcStats = player.getClass().getNpcStats (player); + MWMechanics::NpcStats& pcStats = player.getClass().getNpcStats(player); if (mSpentAttributes.size() < mCoinCount) MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage36}"); @@ -207,10 +208,9 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Levelup); } - } - void LevelupDialog::onAttributeClicked(MyGUI::Widget *sender) + void LevelupDialog::onAttributeClicked(MyGUI::Widget* sender) { int attribute = *sender->getUserData(); @@ -227,7 +227,8 @@ namespace MWGui assignCoins(); } - std::string LevelupDialog::getLevelupClassImage(const int combatIncreases, const int magicIncreases, const int stealthIncreases) + std::string LevelupDialog::getLevelupClassImage( + const int combatIncreases, const int magicIncreases, const int stealthIncreases) { std::string ret = "acrobat"; diff --git a/apps/openmw/mwgui/levelupdialog.hpp b/apps/openmw/mwgui/levelupdialog.hpp index 6c9182609e..2f7bf84089 100644 --- a/apps/openmw/mwgui/levelupdialog.hpp +++ b/apps/openmw/mwgui/levelupdialog.hpp @@ -40,7 +40,8 @@ namespace MWGui void setAttributeValues(); - std::string getLevelupClassImage(const int combatIncreases, const int magicIncreases, const int stealthIncreases); + std::string getLevelupClassImage( + const int combatIncreases, const int magicIncreases, const int stealthIncreases); }; } diff --git a/apps/openmw/mwgui/loadingscreen.cpp b/apps/openmw/mwgui/loadingscreen.cpp index f80b24cccd..a91ce61ba7 100644 --- a/apps/openmw/mwgui/loadingscreen.cpp +++ b/apps/openmw/mwgui/loadingscreen.cpp @@ -6,22 +6,22 @@ #include -#include #include +#include #include +#include #include #include -#include #include +#include #include #include -#include #include "../mwbase/environment.hpp" +#include "../mwbase/inputmanager.hpp" #include "../mwbase/statemanager.hpp" #include "../mwbase/windowmanager.hpp" -#include "../mwbase/inputmanager.hpp" #include "backgroundimage.hpp" @@ -53,15 +53,16 @@ namespace MWGui findSplashScreens(); } - LoadingScreen::~LoadingScreen() - { - } + LoadingScreen::~LoadingScreen() {} void LoadingScreen::findSplashScreens() { auto isSupportedExtension = [](const std::string_view& ext) { - static const std::array supported_extensions{ {"tga", "dds", "ktx", "png", "bmp", "jpeg", "jpg"} }; - return !ext.empty() && std::find(supported_extensions.begin(), supported_extensions.end(), ext) != supported_extensions.end(); + static const std::array supported_extensions{ { "tga", "dds", "ktx", "png", "bmp", "jpeg", + "jpg" } }; + return !ext.empty() + && std::find(supported_extensions.begin(), supported_extensions.end(), ext) + != supported_extensions.end(); }; for (const auto& name : mResourceSystem->getVFS()->getRecursiveDirectoryIterator("Splash/")) @@ -73,20 +74,22 @@ namespace MWGui Log(Debug::Warning) << "Warning: no splash screens found!"; } - void LoadingScreen::setLabel(const std::string &label, bool important) + void LoadingScreen::setLabel(const std::string& label, bool important) { mImportantLabel = important; mLoadingText->setCaptionWithReplacing(label); int padding = mLoadingBox->getWidth() - mLoadingText->getWidth(); - MyGUI::IntSize size(mLoadingText->getTextSize().width+padding, mLoadingBox->getHeight()); + MyGUI::IntSize size(mLoadingText->getTextSize().width + padding, mLoadingBox->getHeight()); size.width = std::max(300, size.width); mLoadingBox->setSize(size); if (MWBase::Environment::get().getWindowManager()->getMessagesCount() > 0) - mLoadingBox->setPosition(mMainWidget->getWidth()/2 - mLoadingBox->getWidth()/2, mMainWidget->getHeight()/2 - mLoadingBox->getHeight()/2); + mLoadingBox->setPosition(mMainWidget->getWidth() / 2 - mLoadingBox->getWidth() / 2, + mMainWidget->getHeight() / 2 - mLoadingBox->getHeight() / 2); else - mLoadingBox->setPosition(mMainWidget->getWidth()/2 - mLoadingBox->getWidth()/2, mMainWidget->getHeight() - mLoadingBox->getHeight() - 8); + mLoadingBox->setPosition(mMainWidget->getWidth() / 2 - mLoadingBox->getWidth() / 2, + mMainWidget->getHeight() - mLoadingBox->getHeight() - 8); } void LoadingScreen::setVisible(bool visible) @@ -114,7 +117,7 @@ namespace MWGui { } - void operator () (osg::RenderInfo& renderInfo) const override + void operator()(osg::RenderInfo& renderInfo) const override { int w = renderInfo.getCurrentCamera()->getViewport()->width(); int h = renderInfo.getCurrentCamera()->getViewport()->height(); @@ -123,10 +126,7 @@ namespace MWGui mOneshot = false; } - void reset() - { - mOneshot = true; - } + void reset() { mOneshot = true; } private: mutable bool mOneshot; @@ -147,11 +147,13 @@ namespace MWGui mLoadingOnTime = mTimer.time_m(); - // Assign dummy bounding sphere callback to avoid the bounding sphere of the entire scene being recomputed after each frame of loading - // We are already using node masks to avoid the scene from being updated/rendered, but node masks don't work for computeBound() + // Assign dummy bounding sphere callback to avoid the bounding sphere of the entire scene being recomputed after + // each frame of loading We are already using node masks to avoid the scene from being updated/rendered, but + // node masks don't work for computeBound() mViewer->getSceneData()->setComputeBoundingSphereCallback(new DontComputeBoundCallback); - if (const osgUtil::IncrementalCompileOperation* ico = mViewer->getIncrementalCompileOperation()) { + if (const osgUtil::IncrementalCompileOperation* ico = mViewer->getIncrementalCompileOperation()) + { mOldIcoMin = ico->getMinimumTimeAvailableForGLCompileAndDeletePerFrame(); mOldIcoMax = ico->getMaximumNumOfObjectsToCompilePerFrame(); } @@ -181,7 +183,7 @@ namespace MWGui { if (--mNestedLoadingCount > 0) return; - mLoadingBox->setVisible(true); // restore + mLoadingBox->setVisible(true); // restore if (mLastRenderTime < mLoadingOnTime) { @@ -211,14 +213,15 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_LoadingWallpaper); } - void LoadingScreen::changeWallpaper () + void LoadingScreen::changeWallpaper() { if (!mSplashScreens.empty()) { - std::string const & randomSplash = mSplashScreens.at(Misc::Rng::rollDice(mSplashScreens.size())); + std::string const& randomSplash = mSplashScreens.at(Misc::Rng::rollDice(mSplashScreens.size())); // TODO: add option (filename pattern?) to use image aspect ratio instead of 4:3 - // we can't do this by default, because the Morrowind splash screens are 1024x1024, but should be displayed as 4:3 + // we can't do this by default, because the Morrowind splash screens are 1024x1024, but should be displayed + // as 4:3 bool stretch = Settings::Manager::getBool("stretch menu background", "GUI"); mSplashImage->setVisible(true); mSplashImage->setBackgroundImage(randomSplash, true, stretch); @@ -227,39 +230,42 @@ namespace MWGui mSceneImage->setVisible(false); } - void LoadingScreen::setProgressRange (size_t range) + void LoadingScreen::setProgressRange(size_t range) { - mProgressBar->setScrollRange(range+1); + mProgressBar->setScrollRange(range + 1); mProgressBar->setScrollPosition(0); mProgressBar->setTrackSize(0); mProgress = 0; } - void LoadingScreen::setProgress (size_t value) + void LoadingScreen::setProgress(size_t value) { // skip expensive update if there isn't enough visible progress - if (mProgressBar->getWidth() <= 0 || value - mProgress < mProgressBar->getScrollRange()/mProgressBar->getWidth()) + if (mProgressBar->getWidth() <= 0 + || value - mProgress < mProgressBar->getScrollRange() / mProgressBar->getWidth()) return; - value = std::min(value, mProgressBar->getScrollRange()-1); + value = std::min(value, mProgressBar->getScrollRange() - 1); mProgress = value; mProgressBar->setScrollPosition(0); - mProgressBar->setTrackSize(static_cast(value / (float)(mProgressBar->getScrollRange()) * mProgressBar->getLineSize())); + mProgressBar->setTrackSize( + static_cast(value / (float)(mProgressBar->getScrollRange()) * mProgressBar->getLineSize())); draw(); } - void LoadingScreen::increaseProgress (size_t increase) + void LoadingScreen::increaseProgress(size_t increase) { mProgressBar->setScrollPosition(0); size_t value = mProgress + increase; - value = std::min(value, mProgressBar->getScrollRange()-1); + value = std::min(value, mProgressBar->getScrollRange() - 1); mProgress = value; - mProgressBar->setTrackSize(static_cast(value / (float)(mProgressBar->getScrollRange()) * mProgressBar->getLineSize())); + mProgressBar->setTrackSize( + static_cast(value / (float)(mProgressBar->getScrollRange()) * mProgressBar->getLineSize())); draw(); } bool LoadingScreen::needToDrawLoadingScreen() { - if ( mTimer.time_m() <= mLastRenderTime + (1.0/getTargetFrameRate()) * 1000.0) + if (mTimer.time_m() <= mLastRenderTime + (1.0 / getTargetFrameRate()) * 1000.0) return false; // the minimal delay before a loading screen shows @@ -275,7 +281,7 @@ namespace MWGui diff -= mProgress / static_cast(mProgressBar->getScrollRange()) * 100.f; } - if (!mShowWallpaper && diff < initialDelay*1000) + if (!mShowWallpaper && diff < initialDelay * 1000) return false; return true; } @@ -320,7 +326,7 @@ namespace MWGui if (mVisible && !needToDrawLoadingScreen()) return; - if (mShowWallpaper && mTimer.time_m() > mLastWallpaperChangeTime + 5000*1) + if (mShowWallpaper && mTimer.time_m() > mLastWallpaperChangeTime + 5000 * 1) { mLastWallpaperChangeTime = mTimer.time_m(); changeWallpaper(); @@ -336,7 +342,7 @@ namespace MWGui mResourceSystem->reportStats(mViewer->getFrameStamp()->getFrameNumber(), mViewer->getViewerStats()); if (osgUtil::IncrementalCompileOperation* ico = mViewer->getIncrementalCompileOperation()) { - ico->setMinimumTimeAvailableForGLCompileAndDeletePerFrame(1.f/getTargetFrameRate()); + ico->setMinimumTimeAvailableForGLCompileAndDeletePerFrame(1.f / getTargetFrameRate()); ico->setMaximumNumOfObjectsToCompilePerFrame(1000); } diff --git a/apps/openmw/mwgui/loadingscreen.hpp b/apps/openmw/mwgui/loadingscreen.hpp index cfa97ed762..2cd3f73576 100644 --- a/apps/openmw/mwgui/loadingscreen.hpp +++ b/apps/openmw/mwgui/loadingscreen.hpp @@ -37,12 +37,12 @@ namespace MWGui virtual ~LoadingScreen(); /// Overridden from Loading::Listener, see the Loading::Listener documentation for usage details - void setLabel (const std::string& label, bool important) override; - void loadingOn(bool visible=true) override; + void setLabel(const std::string& label, bool important) override; + void loadingOn(bool visible = true) override; void loadingOff() override; - void setProgressRange (size_t range) override; - void setProgress (size_t value) override; - void increaseProgress (size_t increase=1) override; + void setProgressRange(size_t range) override; + void setProgress(size_t value) override; + void increaseProgress(size_t increase = 1) override; void setVisible(bool visible) override; @@ -95,5 +95,4 @@ namespace MWGui } - #endif diff --git a/apps/openmw/mwgui/mainmenu.cpp b/apps/openmw/mwgui/mainmenu.cpp index f178576f12..850acf8090 100644 --- a/apps/openmw/mwgui/mainmenu.cpp +++ b/apps/openmw/mwgui/mainmenu.cpp @@ -1,21 +1,21 @@ #include "mainmenu.hpp" -#include #include #include +#include -#include #include #include +#include #include "../mwbase/environment.hpp" +#include "../mwbase/statemanager.hpp" #include "../mwbase/windowmanager.hpp" #include "../mwbase/world.hpp" -#include "../mwbase/statemanager.hpp" -#include "savegamedialog.hpp" -#include "confirmationdialog.hpp" #include "backgroundimage.hpp" +#include "confirmationdialog.hpp" +#include "savegamedialog.hpp" #include "videowidget.hpp" namespace MWGui @@ -23,8 +23,10 @@ namespace MWGui MainMenu::MainMenu(int w, int h, const VFS::Manager* vfs, const std::string& versionDescription) : WindowBase("openmw_mainmenu.layout") - , mWidth (w), mHeight (h) - , mVFS(vfs), mButtonBox(nullptr) + , mWidth(w) + , mHeight(h) + , mVFS(vfs) + , mButtonBox(nullptr) , mBackground(nullptr) , mVideoBackground(nullptr) , mVideo(nullptr) @@ -45,14 +47,13 @@ namespace MWGui updateMenu(); } - void MainMenu::setVisible (bool visible) + void MainMenu::setVisible(bool visible) { if (visible) updateMenu(); - bool isMainMenu = - MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_MainMenu) && - MWBase::Environment::get().getStateManager()->getState() == MWBase::StateManager::State_NoGame; + bool isMainMenu = MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_MainMenu) + && MWBase::Environment::get().getStateManager()->getState() == MWBase::StateManager::State_NoGame; showBackground(isMainMenu); @@ -69,12 +70,12 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mButtons["return"]); } - Layout::setVisible (visible); + Layout::setVisible(visible); } void MainMenu::onNewGameConfirmed() { - MWBase::Environment::get().getWindowManager()->removeGuiMode (MWGui::GM_MainMenu); + MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_MainMenu); MWBase::Environment::get().getStateManager()->newGame(); } @@ -83,18 +84,18 @@ namespace MWGui MWBase::Environment::get().getStateManager()->requestQuit(); } - void MainMenu::onButtonClicked(MyGUI::Widget *sender) + void MainMenu::onButtonClicked(MyGUI::Widget* sender) { - MWBase::WindowManager *winMgr = MWBase::Environment::get().getWindowManager(); + MWBase::WindowManager* winMgr = MWBase::Environment::get().getWindowManager(); const std::string& name = *sender->getUserData(); winMgr->playSound("Menu Click"); if (name == "return") { - winMgr->removeGuiMode (GM_MainMenu); + winMgr->removeGuiMode(GM_MainMenu); } else if (name == "options") - winMgr->pushGuiMode (GM_Settings); + winMgr->pushGuiMode(GM_Settings); else if (name == "credits") winMgr->playVideo("mw_credits.bik", true); else if (name == "exitgame") @@ -160,12 +161,12 @@ namespace MWGui if (!mVideo) { // Use black background to correct aspect ratio - mVideoBackground = MyGUI::Gui::getInstance().createWidgetReal("ImageBox", 0,0,1,1, - MyGUI::Align::Default, "MainMenuBackground"); + mVideoBackground = MyGUI::Gui::getInstance().createWidgetReal( + "ImageBox", 0, 0, 1, 1, MyGUI::Align::Default, "MainMenuBackground"); mVideoBackground->setImageTexture("black"); - mVideo = mVideoBackground->createWidget("ImageBox", 0,0,1,1, - MyGUI::Align::Stretch, "MainMenuBackground"); + mVideo = mVideoBackground->createWidget( + "ImageBox", 0, 0, 1, 1, MyGUI::Align::Stretch, "MainMenuBackground"); mVideo->setVFS(mVFS); mVideo->playVideo("video\\menu_background.bik"); @@ -184,8 +185,8 @@ namespace MWGui { if (!mBackground) { - mBackground = MyGUI::Gui::getInstance().createWidgetReal("ImageBox", 0,0,1,1, - MyGUI::Align::Stretch, "MainMenuBackground"); + mBackground = MyGUI::Gui::getInstance().createWidgetReal( + "ImageBox", 0, 0, 1, 1, MyGUI::Align::Stretch, "MainMenuBackground"); mBackground->setBackgroundImage("textures\\menu_morrowind.dds", true, stretch); } mBackground->setVisible(true); @@ -211,10 +212,11 @@ namespace MWGui void MainMenu::updateMenu() { - setCoord(0,0, mWidth, mHeight); + setCoord(0, 0, mWidth, mHeight); if (!mButtonBox) - mButtonBox = mMainWidget->createWidget("", MyGUI::IntCoord(0, 0, 0, 0), MyGUI::Align::Default); + mButtonBox + = mMainWidget->createWidget("", MyGUI::IntCoord(0, 0, 0, 0), MyGUI::Align::Default); int curH = 0; @@ -224,35 +226,36 @@ namespace MWGui std::vector buttons; - if (state==MWBase::StateManager::State_Running) + if (state == MWBase::StateManager::State_Running) buttons.emplace_back("return"); buttons.emplace_back("newgame"); - if (state==MWBase::StateManager::State_Running && - MWBase::Environment::get().getWorld()->getGlobalInt ("chargenstate")==-1 && - MWBase::Environment::get().getWindowManager()->isSavingAllowed()) + if (state == MWBase::StateManager::State_Running + && MWBase::Environment::get().getWorld()->getGlobalInt("chargenstate") == -1 + && MWBase::Environment::get().getWindowManager()->isSavingAllowed()) buttons.emplace_back("savegame"); - if (MWBase::Environment::get().getStateManager()->characterBegin()!= - MWBase::Environment::get().getStateManager()->characterEnd()) + if (MWBase::Environment::get().getStateManager()->characterBegin() + != MWBase::Environment::get().getStateManager()->characterEnd()) buttons.emplace_back("loadgame"); buttons.emplace_back("options"); - if (state==MWBase::StateManager::State_NoGame) + if (state == MWBase::StateManager::State_NoGame) buttons.emplace_back("credits"); buttons.emplace_back("exitgame"); // Create new buttons if needed - std::vector allButtons { "return", "newgame", "savegame", "loadgame", "options", "credits", "exitgame"}; + std::vector allButtons{ "return", "newgame", "savegame", "loadgame", "options", "credits", + "exitgame" }; for (std::string& buttonId : allButtons) { if (mButtons.find(buttonId) == mButtons.end()) { - Gui::ImageButton* button = mButtonBox->createWidget - ("ImageBox", MyGUI::IntCoord(0, curH, 0, 0), MyGUI::Align::Default); + Gui::ImageButton* button = mButtonBox->createWidget( + "ImageBox", MyGUI::IntCoord(0, curH, 0, 0), MyGUI::Align::Default); button->setProperty("ImageHighlighted", "textures\\menu_" + buttonId + "_over.dds"); button->setProperty("ImageNormal", "textures\\menu_" + buttonId + ".dds"); button->setProperty("ImagePushed", "textures\\menu_" + buttonId + "_pressed.dds"); @@ -288,19 +291,19 @@ namespace MWGui // Trim off some of the excessive padding // TODO: perhaps do this within ImageButton? int height = requested.height; - button->setImageTile(MyGUI::IntSize(requested.width, requested.height-16*scale)); - button->setCoord((maxwidth-requested.width/scale) / 2, curH, requested.width/scale, height/scale-16); - curH += height/scale-16; + button->setImageTile(MyGUI::IntSize(requested.width, requested.height - 16 * scale)); + button->setCoord( + (maxwidth - requested.width / scale) / 2, curH, requested.width / scale, height / scale - 16); + curH += height / scale - 16; } if (state == MWBase::StateManager::State_NoGame) { // Align with the background image - int bottomPadding=24; - mButtonBox->setCoord (mWidth/2 - maxwidth/2, mHeight - curH - bottomPadding, maxwidth, curH); + int bottomPadding = 24; + mButtonBox->setCoord(mWidth / 2 - maxwidth / 2, mHeight - curH - bottomPadding, maxwidth, curH); } else - mButtonBox->setCoord (mWidth/2 - maxwidth/2, mHeight/2 - curH/2, maxwidth, curH); - + mButtonBox->setCoord(mWidth / 2 - maxwidth / 2, mHeight / 2 - curH / 2, maxwidth, curH); } } diff --git a/apps/openmw/mwgui/mainmenu.hpp b/apps/openmw/mwgui/mainmenu.hpp index 2ca3844f37..710a246653 100644 --- a/apps/openmw/mwgui/mainmenu.hpp +++ b/apps/openmw/mwgui/mainmenu.hpp @@ -24,45 +24,44 @@ namespace MWGui class MainMenu : public WindowBase { - int mWidth; - int mHeight; + int mWidth; + int mHeight; - bool mHasAnimatedMenu; + bool mHasAnimatedMenu; - public: + public: + MainMenu(int w, int h, const VFS::Manager* vfs, const std::string& versionDescription); - MainMenu(int w, int h, const VFS::Manager* vfs, const std::string& versionDescription); + void onResChange(int w, int h) override; - void onResChange(int w, int h) override; + void setVisible(bool visible) override; - void setVisible (bool visible) override; + void onFrame(float dt) override; - void onFrame(float dt) override; + bool exit() override; - bool exit() override; + private: + const VFS::Manager* mVFS; - private: - const VFS::Manager* mVFS; + MyGUI::Widget* mButtonBox; + MyGUI::TextBox* mVersionText; - MyGUI::Widget* mButtonBox; - MyGUI::TextBox* mVersionText; + BackgroundImage* mBackground; - BackgroundImage* mBackground; + MyGUI::ImageBox* mVideoBackground; + VideoWidget* mVideo; // For animated main menus - MyGUI::ImageBox* mVideoBackground; - VideoWidget* mVideo; // For animated main menus + std::map mButtons; - std::map mButtons; + void onButtonClicked(MyGUI::Widget* sender); + void onNewGameConfirmed(); + void onExitConfirmed(); - void onButtonClicked (MyGUI::Widget* sender); - void onNewGameConfirmed(); - void onExitConfirmed(); + void showBackground(bool show); - void showBackground(bool show); + void updateMenu(); - void updateMenu(); - - std::unique_ptr mSaveGameDialog; + std::unique_ptr mSaveGameDialog; }; } diff --git a/apps/openmw/mwgui/mapwindow.cpp b/apps/openmw/mwgui/mapwindow.cpp index c52d1f0660..e963fef05e 100644 --- a/apps/openmw/mwgui/mapwindow.cpp +++ b/apps/openmw/mwgui/mapwindow.cpp @@ -2,30 +2,30 @@ #include -#include -#include -#include +#include +#include #include -#include +#include #include +#include +#include #include -#include +#include #include -#include -#include #include -#include +#include #include +#include +#include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" #include "../mwbase/world.hpp" -#include "../mwbase/environment.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/cellstore.hpp" -#include "../mwworld/esmstore.hpp" #include "../mwworld/cellutils.hpp" +#include "../mwworld/esmstore.hpp" +#include "../mwworld/player.hpp" #include "../mwrender/globalmap.hpp" #include "../mwrender/localmap.hpp" @@ -39,7 +39,7 @@ namespace { const int cellSize = Constants::CellSizeInUnits; - constexpr float speed = 1.08f; //the zoom speed, it should be greater than 1 + constexpr float speed = 1.08f; // the zoom speed, it should be greater than 1 enum LocalMapWidgetDepth { @@ -58,7 +58,6 @@ namespace Global_MapLayer = 3 }; - /// @brief A widget that changes its color when hovered. class MarkerWidget final : public MyGUI::Widget { @@ -71,24 +70,15 @@ namespace setColour(colour); } - void setHoverColour(const MyGUI::Colour& colour) - { - mHoverColour = colour; - } + void setHoverColour(const MyGUI::Colour& colour) { mHoverColour = colour; } private: MyGUI::Colour mNormalColour; MyGUI::Colour mHoverColour; - void onMouseLostFocus(MyGUI::Widget* _new) override - { - setColour(mNormalColour); - } + void onMouseLostFocus(MyGUI::Widget* _new) override { setColour(mNormalColour); } - void onMouseSetFocus(MyGUI::Widget* _old) override - { - setColour(mHoverColour); - } + void onMouseSetFocus(MyGUI::Widget* _old) override { setColour(mHoverColour); } }; MyGUI::IntRect createRect(const MyGUI::IntPoint& center, int radius) @@ -102,8 +92,10 @@ namespace return Constants::CellGridRadius; if (!Settings::Manager::getBool("distant terrain", "Terrain")) return Constants::CellGridRadius; - const int maxLocalViewingDistance = std::max(Settings::Manager::getInt("max local viewing distance", "Map"), Constants::CellGridRadius); - const int viewingDistanceInCells = Settings::Manager::getFloat("viewing distance", "Camera") / Constants::CellSizeInUnits; + const int maxLocalViewingDistance + = std::max(Settings::Manager::getInt("max local viewing distance", "Map"), Constants::CellGridRadius); + const int viewingDistanceInCells + = Settings::Manager::getFloat("viewing distance", "Camera") / Constants::CellSizeInUnits; return std::clamp(viewingDistanceInCells, Constants::CellGridRadius, maxLocalViewingDistance); } } @@ -111,14 +103,14 @@ namespace namespace MWGui { - void CustomMarkerCollection::addMarker(const ESM::CustomMarker &marker, bool triggerEvent) + void CustomMarkerCollection::addMarker(const ESM::CustomMarker& marker, bool triggerEvent) { mMarkers.insert(std::make_pair(marker.mCell, marker)); if (triggerEvent) eventMarkersChanged(); } - void CustomMarkerCollection::deleteMarker(const ESM::CustomMarker &marker) + void CustomMarkerCollection::deleteMarker(const ESM::CustomMarker& marker) { std::pair range = mMarkers.equal_range(marker.mCell); @@ -134,7 +126,7 @@ namespace MWGui throw std::runtime_error("can't find marker to delete"); } - void CustomMarkerCollection::updateMarker(const ESM::CustomMarker &marker, const std::string &newNote) + void CustomMarkerCollection::updateMarker(const ESM::CustomMarker& marker, const std::string& newNote) { std::pair range = mMarkers.equal_range(marker.mCell); @@ -166,7 +158,7 @@ namespace MWGui return mMarkers.end(); } - CustomMarkerCollection::RangeType CustomMarkerCollection::getMarkers(const ESM::CellId &cellId) const + CustomMarkerCollection::RangeType CustomMarkerCollection::getMarkers(const ESM::CellId& cellId) const { return mMarkers.equal_range(cellId); } @@ -178,7 +170,8 @@ namespace MWGui // ------------------------------------------------------ - LocalMapBase::LocalMapBase(CustomMarkerCollection &markers, MWRender::LocalMap* localMapRender, bool fogOfWarEnabled) + LocalMapBase::LocalMapBase( + CustomMarkerCollection& markers, MWRender::LocalMap* localMapRender, bool fogOfWarEnabled) : mLocalMapRender(localMapRender) , mCurX(0) , mCurY(0) @@ -213,22 +206,22 @@ namespace MWGui mCellDistance = cellDistance; mNumCells = mCellDistance * 2 + 1; - mLocalMap->setCanvasSize(mMapWidgetSize*mNumCells, mMapWidgetSize*mNumCells); + mLocalMap->setCanvasSize(mMapWidgetSize * mNumCells, mMapWidgetSize * mNumCells); mCompass->setDepth(Local_CompassLayer); mCompass->setNeedMouseFocus(false); - for (int mx=0; mxcreateWidget("ImageBox", - MyGUI::IntCoord(mx*mMapWidgetSize, my*mMapWidgetSize, mMapWidgetSize, mMapWidgetSize), + MyGUI::IntCoord(mx * mMapWidgetSize, my * mMapWidgetSize, mMapWidgetSize, mMapWidgetSize), MyGUI::Align::Top | MyGUI::Align::Left); map->setDepth(Local_MapLayer); MyGUI::ImageBox* fog = mLocalMap->createWidget("ImageBox", - MyGUI::IntCoord(mx*mMapWidgetSize, my*mMapWidgetSize, mMapWidgetSize, mMapWidgetSize), + MyGUI::IntCoord(mx * mMapWidgetSize, my * mMapWidgetSize, mMapWidgetSize, mMapWidgetSize), MyGUI::Align::Top | MyGUI::Align::Left); fog->setDepth(Local_FogLayer); fog->setColour(MyGUI::Colour(0, 0, 0)); @@ -272,17 +265,15 @@ namespace MWGui { // normalized cell coordinates auto mapWidgetSize = getWidgetSize(); - return MyGUI::IntPoint( - std::round(nX * mapWidgetSize + (mCellDistance + (cellX - mCurX)) * mapWidgetSize), - std::round(nY * mapWidgetSize + (mCellDistance - (cellY - mCurY)) * mapWidgetSize) - ); + return MyGUI::IntPoint(std::round(nX * mapWidgetSize + (mCellDistance + (cellX - mCurX)) * mapWidgetSize), + std::round(nY * mapWidgetSize + (mCellDistance - (cellY - mCurY)) * mapWidgetSize)); } MyGUI::IntPoint LocalMapBase::getMarkerPosition(float worldX, float worldY, MarkerUserData& markerPos) const { osg::Vec2i cellIndex; // normalized cell coordinates - float nX,nY; + float nX, nY; if (!mInterior) { @@ -301,22 +292,26 @@ namespace MWGui return getPosition(markerPos.cellX, markerPos.cellY, markerPos.nX, markerPos.nY); } - MyGUI::IntCoord LocalMapBase::getMarkerCoordinates(float worldX, float worldY, MarkerUserData& markerPos, size_t markerSize) const + MyGUI::IntCoord LocalMapBase::getMarkerCoordinates( + float worldX, float worldY, MarkerUserData& markerPos, size_t markerSize) const { int halfMarkerSize = markerSize / 2; auto position = getMarkerPosition(worldX, worldY, markerPos); return MyGUI::IntCoord(position.left - halfMarkerSize, position.top - halfMarkerSize, markerSize, markerSize); } - MyGUI::Widget* LocalMapBase::createDoorMarker(const std::string& name, const MyGUI::VectorString& notes, float x, float y) const + MyGUI::Widget* LocalMapBase::createDoorMarker( + const std::string& name, const MyGUI::VectorString& notes, float x, float y) const { MarkerUserData data(mLocalMapRender); data.notes = notes; data.caption = name; - MarkerWidget* markerWidget = mLocalMap->createWidget("MarkerButton", - getMarkerCoordinates(x, y, data, 8), MyGUI::Align::Default); - markerWidget->setNormalColour(MyGUI::Colour::parse(MyGUI::LanguageManager::getInstance().replaceTags("#{fontcolour=normal}"))); - markerWidget->setHoverColour(MyGUI::Colour::parse(MyGUI::LanguageManager::getInstance().replaceTags("#{fontcolour=normal_over}"))); + MarkerWidget* markerWidget = mLocalMap->createWidget( + "MarkerButton", getMarkerCoordinates(x, y, data, 8), MyGUI::Align::Default); + markerWidget->setNormalColour( + MyGUI::Colour::parse(MyGUI::LanguageManager::getInstance().replaceTags("#{fontcolour=normal}"))); + markerWidget->setHoverColour( + MyGUI::Colour::parse(MyGUI::LanguageManager::getInstance().replaceTags("#{fontcolour=normal_over}"))); markerWidget->setDepth(Local_MarkerLayer); markerWidget->setNeedMouseFocus(true); // Used by tooltips to not show the tooltip if marker is hidden by fog of war @@ -354,20 +349,21 @@ namespace MWGui for (int dX = -mCellDistance; dX <= mCellDistance; ++dX) { - for (int dY =-mCellDistance; dY <= mCellDistance; ++dY) + for (int dY = -mCellDistance; dY <= mCellDistance; ++dY) { ESM::CellId cellId; cellId.mPaged = !mInterior; cellId.mWorldspace = (mInterior ? mPrefix : ESM::CellId::sDefaultWorldspace); - cellId.mIndex.mX = mCurX+dX; - cellId.mIndex.mY = mCurY+dY; + cellId.mIndex.mX = mCurX + dX; + cellId.mIndex.mY = mCurY + dY; CustomMarkerCollection::RangeType markers = mCustomMarkers.getMarkers(cellId); - for (CustomMarkerCollection::ContainerType::const_iterator it = markers.first; it != markers.second; ++it) + for (CustomMarkerCollection::ContainerType::const_iterator it = markers.first; it != markers.second; + ++it) { const ESM::CustomMarker& marker = it->second; - MarkerUserData markerPos (mLocalMapRender); + MarkerUserData markerPos(mLocalMapRender); MarkerWidget* markerWidget = mLocalMap->createWidget("CustomMarkerButton", getMarkerCoordinates(marker.mWorldX, marker.mWorldY, markerPos, 16), MyGUI::Align::Default); markerWidget->setDepth(Local_MarkerAboveFogLayer); @@ -389,15 +385,14 @@ namespace MWGui void LocalMapBase::setActiveCell(const int x, const int y, bool interior) { - if (x==mCurX && y==mCurY && mInterior==interior && !mChanged) + if (x == mCurX && y == mCurY && mInterior == interior && !mChanged) return; // don't do anything if we're still in the same cell if (!interior && !(x == mCurX && y == mCurY)) { - const MyGUI::IntRect intersection = { - std::max(x, mCurX) - mCellDistance, std::max(y, mCurY) - mCellDistance, - std::min(x, mCurX) + mCellDistance, std::min(y, mCurY) + mCellDistance - }; + const MyGUI::IntRect intersection + = { std::max(x, mCurX) - mCellDistance, std::max(y, mCurY) - mCellDistance, + std::min(x, mCurX) + mCellDistance, std::min(y, mCurY) + mCellDistance }; const MyGUI::IntRect activeGrid = createRect({ x, y }, Constants::CellGridRadius); const MyGUI::IntRect currentView = createRect({ x, y }, mCellDistance); @@ -405,7 +400,8 @@ namespace MWGui mExteriorDoorMarkerWidgets.clear(); for (auto& [coord, doors] : mExteriorDoorsByCell) { - if (!mHasALastActiveCell || !currentView.inside({ coord.first, coord.second }) || activeGrid.inside({ coord.first, coord.second })) + if (!mHasALastActiveCell || !currentView.inside({ coord.first, coord.second }) + || activeGrid.inside({ coord.first, coord.second })) { mDoorMarkersToRecycle.insert(mDoorMarkersToRecycle.end(), doors.begin(), doors.end()); doors.clear(); @@ -429,11 +425,11 @@ namespace MWGui mInterior = interior; mChanged = false; - for (int mx=0; mxsetRenderItemTexture(nullptr); entry.mFogWidget->setRenderItemTexture(nullptr); entry.mMapTexture.reset(); @@ -458,7 +454,7 @@ namespace MWGui updateCustomMarkers(); } - void LocalMapBase::requestMapRender(const MWWorld::CellStore *cell) + void LocalMapBase::requestMapRender(const MWWorld::CellStore* cell) { mLocalMapRender->requestMap(cell); } @@ -480,7 +476,7 @@ namespace MWGui if (pos != mCompass->getPosition()) { - notifyPlayerUpdate (); + notifyPlayerUpdate(); mCompass->setPosition(pos); } @@ -497,12 +493,12 @@ namespace MWGui if (x == mLastDirectionX && y == mLastDirectionY) return; - notifyPlayerUpdate (); + notifyPlayerUpdate(); MyGUI::ISubWidget* main = mCompass->getSubWidgetMain(); MyGUI::RotatingSkin* rotatingSubskin = main->castType(); - rotatingSubskin->setCenter(MyGUI::IntPoint(16,16)); - float angle = std::atan2(x,y); + rotatingSubskin->setCenter(MyGUI::IntPoint(16, 16)); + float angle = std::atan2(x, y); rotatingSubskin->setAngle(angle); mLastDirectionX = x; @@ -513,9 +509,7 @@ namespace MWGui { std::vector markers; MWBase::World* world = MWBase::Environment::get().getWorld(); - world->listDetectedReferences( - world->getPlayerPtr(), - markers, MWBase::World::DetectionType(type)); + world->listDetectedReferences(world->getPlayerPtr(), markers, MWBase::World::DetectionType(type)); if (markers.empty()) return; @@ -536,12 +530,12 @@ namespace MWGui for (const MWWorld::Ptr& ptr : markers) { const ESM::Position& worldPos = ptr.getRefData().getPosition(); - MarkerUserData markerPos (mLocalMapRender); + MarkerUserData markerPos(mLocalMapRender); MyGUI::ImageBox* markerWidget = mLocalMap->createWidget("ImageBox", getMarkerCoordinates(worldPos.pos[0], worldPos.pos[1], markerPos, 8), MyGUI::Align::Default); markerWidget->setDepth(Local_MarkerAboveFogLayer); markerWidget->setImageTexture(markerTexture); - markerWidget->setImageCoord(MyGUI::IntCoord(0,0,8,8)); + markerWidget->setImageCoord(MyGUI::IntCoord(0, 0, 8, 8)); markerWidget->setNeedMouseFocus(false); markerWidget->setUserData(markerPos); mMagicMarkerWidgets.push_back(markerWidget); @@ -593,7 +587,7 @@ namespace MWGui if (!entry.mMapTexture) { if (!mInterior) - requestMapRender(MWBase::Environment::get().getWorld()->getExterior (entry.mCellX, entry.mCellY)); + requestMapRender(MWBase::Environment::get().getWorld()->getExterior(entry.mCellX, entry.mCellY)); osg::ref_ptr texture = mLocalMapRender->getMapTexture(entry.mCellX, entry.mCellY); if (texture) @@ -632,7 +626,8 @@ namespace MWGui std::vector doors; MWBase::World* world = MWBase::Environment::get().getWorld(); - mDoorMarkersToRecycle.insert(mDoorMarkersToRecycle.end(), mInteriorDoorMarkerWidgets.begin(), mInteriorDoorMarkerWidgets.end()); + mDoorMarkersToRecycle.insert( + mDoorMarkersToRecycle.end(), mInteriorDoorMarkerWidgets.begin(), mInteriorDoorMarkerWidgets.end()); mInteriorDoorMarkerWidgets.clear(); if (mInterior) @@ -640,7 +635,7 @@ namespace MWGui for (MyGUI::Widget* widget : mExteriorDoorMarkerWidgets) widget->setVisible(false); - MWWorld::CellStore* cell = world->getInterior (mPrefix); + MWWorld::CellStore* cell = world->getInterior(mPrefix); world->getDoorMarkers(cell, doors); } else @@ -659,7 +654,8 @@ namespace MWGui { std::vector destNotes; CustomMarkerCollection::RangeType markers = mCustomMarkers.getMarkers(marker.dest); - for (CustomMarkerCollection::ContainerType::const_iterator iter = markers.first; iter != markers.second; ++iter) + for (CustomMarkerCollection::ContainerType::const_iterator iter = markers.first; iter != markers.second; + ++iter) destNotes.push_back(iter->second.mNote); MyGUI::Widget* markerWidget = nullptr; @@ -684,7 +680,7 @@ namespace MWGui currentDoorMarkersWidgets().push_back(markerWidget); if (!mInterior) - mExteriorDoorsByCell[{data->cellX, data->cellY}].push_back(markerWidget); + mExteriorDoorsByCell[{ data->cellX, data->cellY }].push_back(markerWidget); } for (auto& widget : mDoorMarkersToRecycle) @@ -707,11 +703,12 @@ namespace MWGui ESM::Position markedPosition; MWBase::Environment::get().getWorld()->getPlayer().getMarkedPosition(markedCell, markedPosition); if (markedCell && markedCell->isExterior() == !mInterior - && (!mInterior || Misc::StringUtils::ciEqual(markedCell->getCell()->mName, mPrefix))) + && (!mInterior || Misc::StringUtils::ciEqual(markedCell->getCell()->mName, mPrefix))) { - MarkerUserData markerPos (mLocalMapRender); + MarkerUserData markerPos(mLocalMapRender); MyGUI::ImageBox* markerWidget = mLocalMap->createWidget("ImageBox", - getMarkerCoordinates(markedPosition.pos[0], markedPosition.pos[1], markerPos, 8), MyGUI::Align::Default); + getMarkerCoordinates(markedPosition.pos[0], markedPosition.pos[1], markerPos, 8), + MyGUI::Align::Default); markerWidget->setDepth(Local_MarkerAboveFogLayer); markerWidget->setImageTexture("textures\\menu_map_smark.dds"); markerWidget->setNeedMouseFocus(false); @@ -750,7 +747,8 @@ namespace MWGui } // ------------------------------------------------------------------------------------------ - MapWindow::MapWindow(CustomMarkerCollection &customMarkers, DragAndDrop* drag, MWRender::LocalMap* localMapRender, SceneUtil::WorkQueue* workQueue) + MapWindow::MapWindow(CustomMarkerCollection& customMarkers, DragAndDrop* drag, MWRender::LocalMap* localMapRender, + SceneUtil::WorkQueue* workQueue) #ifdef USE_OPENXR : WindowPinnableBase("openmw_map_window_vr.layout") #else @@ -778,7 +776,7 @@ namespace MWGui mEditNoteDialog.eventOkClicked += MyGUI::newDelegate(this, &MapWindow::onNoteEditOk); mEditNoteDialog.eventDeleteClicked += MyGUI::newDelegate(this, &MapWindow::onNoteEditDelete); - setCoord(500,0,320,300); + setCoord(500, 0, 320, 300); getWidget(mLocalMap, "LocalMap"); getWidget(mGlobalMap, "GlobalMap"); @@ -795,17 +793,17 @@ namespace MWGui mLastScrollWindowCoordinates = mLocalMap->getCoord(); mLocalMap->eventChangeCoord += MyGUI::newDelegate(this, &MapWindow::onChangeScrollWindowCoord); - mGlobalMap->setVisible (false); + mGlobalMap->setVisible(false); getWidget(mButton, "WorldButton"); mButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MapWindow::onWorldButtonClicked); - mButton->setCaptionWithReplacing( mGlobal ? "#{sLocal}" : "#{sWorld}"); + mButton->setCaptionWithReplacing(mGlobal ? "#{sLocal}" : "#{sWorld}"); getWidget(mEventBoxGlobal, "EventBoxGlobal"); mEventBoxGlobal->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag); mEventBoxGlobal->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart); const bool allowZooming = Settings::Manager::getBool("allow zooming", "Map"); - if(allowZooming) + if (allowZooming) mEventBoxGlobal->eventMouseWheel += MyGUI::newDelegate(this, &MapWindow::onMapZoomed); mEventBoxGlobal->setDepth(Global_ExploreOverlayLayer); @@ -851,7 +849,7 @@ namespace MWGui mEditNoteDialog.setVisible(false); } - void MapWindow::onCustomMarkerDoubleClicked(MyGUI::Widget *sender) + void MapWindow::onCustomMarkerDoubleClicked(MyGUI::Widget* sender) { mEditingMarker = *sender->getUserData(); mEditNoteDialog.setText(mEditingMarker.mNote); @@ -859,16 +857,16 @@ namespace MWGui mEditNoteDialog.setVisible(true); } - void MapWindow::onMapDoubleClicked(MyGUI::Widget *sender) + void MapWindow::onMapDoubleClicked(MyGUI::Widget* sender) { MyGUI::IntPoint clickedPos = MyGUI::InputManager::getInstance().getMousePosition(); MyGUI::IntPoint widgetPos = clickedPos - mEventBoxLocal->getAbsolutePosition(); auto mapWidgetSize = getWidgetSize(); - int x = int(widgetPos.left/float(mapWidgetSize))-mCellDistance; - int y = (int(widgetPos.top/float(mapWidgetSize))-mCellDistance)*-1; - float nX = widgetPos.left/float(mapWidgetSize) - int(widgetPos.left/float(mapWidgetSize)); - float nY = widgetPos.top/float(mapWidgetSize) - int(widgetPos.top/float(mapWidgetSize)); + int x = int(widgetPos.left / float(mapWidgetSize)) - mCellDistance; + int y = (int(widgetPos.top / float(mapWidgetSize)) - mCellDistance) * -1; + float nX = widgetPos.left / float(mapWidgetSize) - int(widgetPos.left / float(mapWidgetSize)); + float nY = widgetPos.top / float(mapWidgetSize) - int(widgetPos.top / float(mapWidgetSize)); x += mCurX; y += mCurY; @@ -880,7 +878,7 @@ namespace MWGui else { worldPos.x() = (x + nX) * cellSize; - worldPos.y() = (y + (1.0f-nY)) * cellSize; + worldPos.y() = (y + (1.0f - nY)) * cellSize; } mEditingMarker.mWorldX = worldPos.x(); @@ -911,19 +909,15 @@ namespace MWGui const double speedDiff = zoomOut ? 1.0 / speed : speed; const float localMapSizeInUnits = localWidgetSize * mNumCells; - const float currentMinLocalMapZoom = std::max({ - (float(globalCellSize) * 4.f) / float(localWidgetSize), - float(mLocalMap->getWidth()) / localMapSizeInUnits, - float(mLocalMap->getHeight()) / localMapSizeInUnits - }); + const float currentMinLocalMapZoom = std::max({ (float(globalCellSize) * 4.f) / float(localWidgetSize), + float(mLocalMap->getWidth()) / localMapSizeInUnits, float(mLocalMap->getHeight()) / localMapSizeInUnits }); if (mGlobal) { const float currentGlobalZoom = mGlobalMapZoom; - const float currentMinGlobalMapZoom = std::min( - float(mGlobalMap->getWidth()) / float(mGlobalMapRender->getWidth()), - float(mGlobalMap->getHeight()) / float(mGlobalMapRender->getHeight()) - ); + const float currentMinGlobalMapZoom + = std::min(float(mGlobalMap->getWidth()) / float(mGlobalMapRender->getWidth()), + float(mGlobalMap->getHeight()) / float(mGlobalMapRender->getHeight())); mGlobalMapZoom *= speedDiff; @@ -933,13 +927,13 @@ namespace MWGui mLocalMapZoom = currentMinLocalMapZoom; onWorldButtonClicked(nullptr); updateLocalMap(); - return; //the zoom in is too big + return; // the zoom in is too big } if (zoomOut && mGlobalMapZoom < currentMinGlobalMapZoom) { mGlobalMapZoom = currentGlobalZoom; - return; //the zoom out is too big, we have reach the borders of the widget + return; // the zoom out is too big, we have reach the borders of the widget } } else @@ -950,19 +944,19 @@ namespace MWGui if (zoomIn && mLocalMapZoom > 4.0f) { mLocalMapZoom = currentLocalZoom; - return; //the zoom in is too big + return; // the zoom in is too big } if (zoomOut && mLocalMapZoom < currentMinLocalMapZoom) { mLocalMapZoom = currentLocalZoom; - float zoomRatio = 4.f/ mGlobalMapZoom; + float zoomRatio = 4.f / mGlobalMapZoom; mGlobalMapZoom = 4.f; onWorldButtonClicked(nullptr); zoomOnCursor(zoomRatio); - return; //the zoom out is too big, we switch to the global map + return; // the zoom out is too big, we switch to the global map } if (zoomOut) @@ -977,12 +971,10 @@ namespace MWGui auto cursor = MyGUI::InputManager::getInstance().getMousePosition() - map->getAbsolutePosition(); auto centerView = map->getViewOffset() - cursor; - mGlobal? updateGlobalMap() : updateLocalMap(); + mGlobal ? updateGlobalMap() : updateLocalMap(); - map->setViewOffset(MyGUI::IntPoint( - std::round(centerView.left * speedDiff) + cursor.left, - std::round(centerView.top * speedDiff) + cursor.top - )); + map->setViewOffset(MyGUI::IntPoint(std::round(centerView.left * speedDiff) + cursor.left, + std::round(centerView.top * speedDiff) + cursor.top)); } void MapWindow::updateGlobalMap() @@ -1009,8 +1001,10 @@ namespace MWGui { MyGUI::IntCoord currentCoordinates = sender->getCoord(); - MyGUI::IntPoint currentViewPortCenter = MyGUI::IntPoint(currentCoordinates.width / 2, currentCoordinates.height / 2); - MyGUI::IntPoint lastViewPortCenter = MyGUI::IntPoint(mLastScrollWindowCoordinates.width / 2, mLastScrollWindowCoordinates.height / 2); + MyGUI::IntPoint currentViewPortCenter + = MyGUI::IntPoint(currentCoordinates.width / 2, currentCoordinates.height / 2); + MyGUI::IntPoint lastViewPortCenter + = MyGUI::IntPoint(mLastScrollWindowCoordinates.width / 2, mLastScrollWindowCoordinates.height / 2); MyGUI::IntPoint viewPortCenterDiff = currentViewPortCenter - lastViewPortCenter; mLocalMap->setViewOffset(mLocalMap->getViewOffset() + viewPortCenterDiff); @@ -1031,9 +1025,7 @@ namespace MWGui resizeGlobalMap(); } - MapWindow::~MapWindow() - { - } + MapWindow::~MapWindow() {} void MapWindow::setCellName(const std::string& cellName) { @@ -1043,20 +1035,19 @@ namespace MWGui MyGUI::IntCoord MapWindow::createMarkerCoords(float x, float y, float agregatedWeight) const { float worldX, worldY; - worldPosToGlobalMapImageSpace((x + 0.5f) * Constants::CellSizeInUnits, (y + 0.5f)* Constants::CellSizeInUnits, worldX, worldY); + worldPosToGlobalMapImageSpace( + (x + 0.5f) * Constants::CellSizeInUnits, (y + 0.5f) * Constants::CellSizeInUnits, worldX, worldY); const float markerSize = getMarkerSize(agregatedWeight); const float halfMarkerSize = markerSize / 2.0f; - return MyGUI::IntCoord( - static_cast(worldX - halfMarkerSize), - static_cast(worldY - halfMarkerSize), + return MyGUI::IntCoord(static_cast(worldX - halfMarkerSize), static_cast(worldY - halfMarkerSize), markerSize, markerSize); } MyGUI::Widget* MapWindow::createMarker(const std::string& name, float x, float y, float agregatedWeight) { - MyGUI::Widget* markerWidget = mGlobalMap->createWidget("MarkerButton", - createMarkerCoords(x, y, agregatedWeight), MyGUI::Align::Default); + MyGUI::Widget* markerWidget = mGlobalMap->createWidget( + "MarkerButton", createMarkerCoords(x, y, agregatedWeight), MyGUI::Align::Default); markerWidget->setVisible(markerWidget->getHeight() >= 6.0); markerWidget->setUserString("Caption_TextOneLine", "#{sCell=" + name + "}"); setGlobalMapMarkerTooltip(markerWidget, x, y); @@ -1064,7 +1055,8 @@ namespace MWGui markerWidget->setUserString("ToolTipLayout", "TextToolTipOneLine"); markerWidget->setNeedMouseFocus(true); - markerWidget->setColour(MyGUI::Colour::parse(MyGUI::LanguageManager::getInstance().replaceTags("#{fontcolour=normal}"))); + markerWidget->setColour( + MyGUI::Colour::parse(MyGUI::LanguageManager::getInstance().replaceTags("#{fontcolour=normal}"))); markerWidget->setDepth(Global_MarkerLayer); markerWidget->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag); markerWidget->eventMouseWheel += MyGUI::newDelegate(this, &MapWindow::onMapZoomed); @@ -1087,7 +1079,7 @@ namespace MWGui auto& entry = mGlobalMapMarkersByName[name_]; if (!entry.widget) { - entry = { osg::Vec2f(x, y), entry.widget }; //update the coords + entry = { osg::Vec2f(x, y), entry.widget }; // update the coords entry.widget = createMarker(name_, entry.position.x(), entry.position.y(), 1); mGlobalMapMarkers.emplace(entry, std::vector{ entry }); @@ -1099,10 +1091,11 @@ namespace MWGui auto& elements = it->second; elements.emplace_back(mapMarkerWidget); - //we compute the barycenter of the entry elements => it will be the place on the world map for the agregated widget - marker.position = std::accumulate(elements.begin(), elements.end(), osg::Vec2f(0.f, 0.f), [](const auto& left, const auto& right) { - return left + right.position; - }) / float(elements.size()); + // we compute the barycenter of the entry elements => it will be the place on the world map for the + // agregated widget + marker.position = std::accumulate(elements.begin(), elements.end(), osg::Vec2f(0.f, 0.f), + [](const auto& left, const auto& right) { return left + right.position; }) + / float(elements.size()); marker.widget->setCoord(createMarkerCoords(marker.position.x(), marker.position.y(), elements.size())); marker.widget->setVisible(marker.widget->getHeight() >= 6); @@ -1136,7 +1129,7 @@ namespace MWGui if (!destNotes.empty()) { - MarkerUserData data (nullptr); + MarkerUserData data(nullptr); data.notes = destNotes; data.caption = markerWidget->getUserString("Caption_TextOneLine"); markerWidget->setUserData(data); @@ -1152,14 +1145,16 @@ namespace MWGui { float markerSize = 12.f * mGlobalMapZoom; if (mGlobalMapZoom < 1) - return markerSize * std::sqrt(agregatedWeight); //we want to see agregated object - return agregatedWeight ? 0 : markerSize; //we want to see only original markers (i.e. non agregated) + return markerSize * std::sqrt(agregatedWeight); // we want to see agregated object + return agregatedWeight ? 0 : markerSize; // we want to see only original markers (i.e. non agregated) } void MapWindow::resizeGlobalMap() { - mGlobalMap->setCanvasSize(mGlobalMapRender->getWidth() * mGlobalMapZoom, mGlobalMapRender->getHeight() * mGlobalMapZoom); - mGlobalMapImage->setSize(mGlobalMapRender->getWidth() * mGlobalMapZoom, mGlobalMapRender->getHeight() * mGlobalMapZoom); + mGlobalMap->setCanvasSize( + mGlobalMapRender->getWidth() * mGlobalMapZoom, mGlobalMapRender->getHeight() * mGlobalMapZoom); + mGlobalMapImage->setSize( + mGlobalMapRender->getWidth() * mGlobalMapZoom, mGlobalMapRender->getHeight() * mGlobalMapZoom); } void MapWindow::worldPosToGlobalMapImageSpace(float x, float y, float& imageX, float& imageY) const @@ -1173,29 +1168,31 @@ namespace MWGui { LocalMapBase::updateCustomMarkers(); - for (auto& [widgetPair, ignore]: mGlobalMapMarkers) + for (auto& [widgetPair, ignore] : mGlobalMapMarkers) setGlobalMapMarkerTooltip(widgetPair.widget, widgetPair.position.x(), widgetPair.position.y()); } void MapWindow::onDragStart(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) { - if (_id!=MyGUI::MouseButton::Left) return; + if (_id != MyGUI::MouseButton::Left) + return; mLastDragPos = MyGUI::IntPoint(_left, _top); } void MapWindow::onMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) { - if (_id!=MyGUI::MouseButton::Left) return; + if (_id != MyGUI::MouseButton::Left) + return; MyGUI::IntPoint diff = MyGUI::IntPoint(_left, _top) - mLastDragPos; if (!mGlobal) { mNeedDoorMarkersUpdate = true; - mLocalMap->setViewOffset( mLocalMap->getViewOffset() + diff ); + mLocalMap->setViewOffset(mLocalMap->getViewOffset() + diff); } else - mGlobalMap->setViewOffset( mGlobalMap->getViewOffset() + diff ); + mGlobalMap->setViewOffset(mGlobalMap->getViewOffset() + diff); mLastDragPos = MyGUI::IntPoint(_left, _top); } @@ -1208,8 +1205,7 @@ namespace MWGui Settings::Manager::setBool("global", "Map", mGlobal); - mButton->setCaptionWithReplacing( mGlobal ? "#{sLocal}" : - "#{sWorld}"); + mButton->setCaptionWithReplacing(mGlobal ? "#{sLocal}" : "#{sWorld}"); } void MapWindow::onPinToggled() @@ -1234,19 +1230,19 @@ namespace MWGui globalMapUpdatePlayer(); } - void MapWindow::globalMapUpdatePlayer () + void MapWindow::globalMapUpdatePlayer() { // For interiors, position is set by WindowManager via setGlobalMapPlayerPosition - if (MWBase::Environment::get().getWorld ()->isCellExterior ()) + if (MWBase::Environment::get().getWorld()->isCellExterior()) { - osg::Vec3f pos = MWBase::Environment::get().getWorld ()->getPlayerPtr().getRefData().getPosition().asVec3(); + osg::Vec3f pos = MWBase::Environment::get().getWorld()->getPlayerPtr().getRefData().getPosition().asVec3(); setGlobalMapPlayerPosition(pos.x(), pos.y()); } } - void MapWindow::notifyPlayerUpdate () + void MapWindow::notifyPlayerUpdate() { - globalMapUpdatePlayer (); + globalMapUpdatePlayer(); setGlobalMapPlayerDir(mLastDirectionX, mLastDirectionY); } @@ -1256,8 +1252,9 @@ namespace MWGui LocalMapBase::centerView(); // set the view offset so that player is in the center MyGUI::IntSize viewsize = mGlobalMap->getSize(); - MyGUI::IntPoint pos = mPlayerArrowGlobal->getPosition() + MyGUI::IntPoint{ 16,16 }; - MyGUI::IntPoint viewoffs(static_cast(viewsize.width * 0.5f - pos.left), static_cast(viewsize.height * 0.5f - pos.top)); + MyGUI::IntPoint pos = mPlayerArrowGlobal->getPosition() + MyGUI::IntPoint{ 16, 16 }; + MyGUI::IntPoint viewoffs( + static_cast(viewsize.width * 0.5f - pos.left), static_cast(viewsize.height * 0.5f - pos.top)); mGlobalMap->setViewOffset(viewoffs); } @@ -1272,8 +1269,8 @@ namespace MWGui { MyGUI::ISubWidget* main = mPlayerArrowGlobal->getSubWidgetMain(); MyGUI::RotatingSkin* rotatingSubskin = main->castType(); - rotatingSubskin->setCenter(MyGUI::IntPoint(16,16)); - float angle = std::atan2(x,y); + rotatingSubskin->setCenter(MyGUI::IntPoint(16, 16)); + float angle = std::atan2(x, y); rotatingSubskin->setAngle(angle); } @@ -1307,7 +1304,7 @@ namespace MWGui mGlobalMapMarkersByName.clear(); } - void MapWindow::write(ESM::ESMWriter &writer, Loading::Listener& progress) + void MapWindow::write(ESM::ESMWriter& writer, Loading::Listener& progress) { ESM::GlobalMap map; mGlobalMapRender->write(map); @@ -1319,7 +1316,7 @@ namespace MWGui writer.endRecord(ESM::REC_GMAP); } - void MapWindow::readRecord(ESM::ESMReader &reader, uint32_t type) + void MapWindow::readRecord(ESM::ESMReader& reader, uint32_t type) { if (type == ESM::REC_GMAP) { @@ -1330,7 +1327,8 @@ namespace MWGui for (const ESM::GlobalMap::CellId& cellId : map.mMarkers) { - const ESM::Cell* cell = MWBase::Environment::get().getWorld()->getStore().get().search(cellId.first, cellId.second); + const ESM::Cell* cell = MWBase::Environment::get().getWorld()->getStore().get().search( + cellId.first, cellId.second); if (cell && !cell->mName.empty()) addVisitedLocation(cell->mName, cellId.first, cellId.second); } @@ -1346,7 +1344,7 @@ namespace MWGui entry.mMapWidget->setVisible(alpha == 1); } - void MapWindow::customMarkerCreated(MyGUI::Widget *marker) + void MapWindow::customMarkerCreated(MyGUI::Widget* marker) { marker->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag); marker->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart); @@ -1354,7 +1352,7 @@ namespace MWGui marker->eventMouseWheel += MyGUI::newDelegate(this, &MapWindow::onMapZoomed); } - void MapWindow::doorMarkerCreated(MyGUI::Widget *marker) + void MapWindow::doorMarkerCreated(MyGUI::Widget* marker) { marker->eventMouseDrag += MyGUI::newDelegate(this, &MapWindow::onMouseDrag); marker->eventMouseButtonPressed += MyGUI::newDelegate(this, &MapWindow::onDragStart); @@ -1391,7 +1389,7 @@ namespace MWGui return mDeleteButton->getVisible(); } - void EditNoteDialog::setText(const std::string &text) + void EditNoteDialog::setText(const std::string& text) { mTextEdit->setCaption(MyGUI::TextIterator::toTagsString(text)); } @@ -1408,17 +1406,17 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mTextEdit); } - void EditNoteDialog::onCancelButtonClicked(MyGUI::Widget *sender) + void EditNoteDialog::onCancelButtonClicked(MyGUI::Widget* sender) { setVisible(false); } - void EditNoteDialog::onOkButtonClicked(MyGUI::Widget *sender) + void EditNoteDialog::onOkButtonClicked(MyGUI::Widget* sender) { eventOkClicked(); } - void EditNoteDialog::onDeleteButtonClicked(MyGUI::Widget *sender) + void EditNoteDialog::onDeleteButtonClicked(MyGUI::Widget* sender) { eventDeleteClicked(); } diff --git a/apps/openmw/mwgui/mapwindow.hpp b/apps/openmw/mwgui/mapwindow.hpp index 37c971cd19..10dd9dbe0c 100644 --- a/apps/openmw/mwgui/mapwindow.hpp +++ b/apps/openmw/mwgui/mapwindow.hpp @@ -48,8 +48,8 @@ namespace MWGui class CustomMarkerCollection { public: - void addMarker(const ESM::CustomMarker& marker, bool triggerEvent=true); - void deleteMarker (const ESM::CustomMarker& marker); + void addMarker(const ESM::CustomMarker& marker, bool triggerEvent = true); + void deleteMarker(const ESM::CustomMarker& marker); void updateMarker(const ESM::CustomMarker& marker, const std::string& newNote); void clear(); @@ -80,7 +80,7 @@ namespace MWGui void init(MyGUI::ScrollView* widget, MyGUI::ImageBox* compass, int cellDistance = Constants::CellGridRadius); void setCellPrefix(const std::string& prefix); - void setActiveCell(const int x, const int y, bool interior=false); + void setActiveCell(const int x, const int y, bool interior = false); void requestMapRender(const MWWorld::CellStore* cell); void setPlayerDir(const float x, const float y); void setPlayerPos(int cellX, int cellY, const float nx, const float ny); @@ -117,9 +117,9 @@ namespace MWGui float mLocalMapZoom = 1.f; MWRender::LocalMap* mLocalMapRender; - int mCurX, mCurY; //the position of the active cell on the global map (in cell coords) + int mCurX, mCurY; // the position of the active cell on the global map (in cell coords) bool mHasALastActiveCell = false; - osg::Vec2f mCurPos; //the position of the player in the world (in cell coords) + osg::Vec2f mCurPos; // the position of the player in the world (in cell coords) bool mInterior; MyGUI::ScrollView* mLocalMap; @@ -140,7 +140,12 @@ namespace MWGui struct MapEntry { MapEntry(MyGUI::ImageBox* mapWidget, MyGUI::ImageBox* fogWidget) - : mMapWidget(mapWidget), mFogWidget(fogWidget), mCellX(0), mCellY(0) {} + : mMapWidget(mapWidget) + , mFogWidget(fogWidget) + , mCellX(0) + , mCellY(0) + { + } MyGUI::ImageBox* mMapWidget; MyGUI::ImageBox* mFogWidget; @@ -166,9 +171,11 @@ namespace MWGui void applyFogOfWar(); MyGUI::IntPoint getPosition(int cellX, int cellY, float nx, float ny) const; - MyGUI::IntPoint getMarkerPosition (float worldX, float worldY, MarkerUserData& markerPos) const; - MyGUI::IntCoord getMarkerCoordinates(float worldX, float worldY, MarkerUserData& markerPos, size_t markerSize) const; - MyGUI::Widget* createDoorMarker(const std::string& name, const MyGUI::VectorString& notes, float x, float y) const; + MyGUI::IntPoint getMarkerPosition(float worldX, float worldY, MarkerUserData& markerPos) const; + MyGUI::IntCoord getMarkerCoordinates( + float worldX, float worldY, MarkerUserData& markerPos, size_t markerSize) const; + MyGUI::Widget* createDoorMarker( + const std::string& name, const MyGUI::VectorString& notes, float x, float y) const; MyGUI::IntCoord getMarkerCoordinates(MyGUI::Widget* widget, size_t markerSize) const; virtual void notifyPlayerUpdate() {} @@ -228,7 +235,8 @@ namespace MWGui class MapWindow : public MWGui::WindowPinnableBase, public LocalMapBase, public NoDrop { public: - MapWindow(CustomMarkerCollection& customMarkers, DragAndDrop* drag, MWRender::LocalMap* localMapRender, SceneUtil::WorkQueue* workQueue); + MapWindow(CustomMarkerCollection& customMarkers, DragAndDrop* drag, MWRender::LocalMap* localMapRender, + SceneUtil::WorkQueue* workQueue); virtual ~MapWindow(); void setCellName(const std::string& cellName); @@ -245,7 +253,7 @@ namespace MWGui // reveals this cell's map on the global map void cellExplored(int x, int y); - void setGlobalMapPlayerPosition (float worldX, float worldY); + void setGlobalMapPlayerPosition(float worldX, float worldY); void setGlobalMapPlayerDir(const float x, const float y); void ensureGlobalMapLoaded(); @@ -259,8 +267,8 @@ namespace MWGui /// Clear all savegame-specific data void clear() override; - void write (ESM::ESMWriter& writer, Loading::Listener& progress); - void readRecord (ESM::ESMReader& reader, uint32_t type); + void write(ESM::ESMWriter& writer, Loading::Listener& progress); + void readRecord(ESM::ESMReader& reader, uint32_t type); void asyncPrepareSaveMap(); @@ -286,7 +294,6 @@ namespace MWGui MyGUI::IntCoord createMarkerCoords(float x, float y, float agregatedWeight) const; MyGUI::Widget* createMarker(const std::string& name, float x, float y, float agregatedWeight); - MyGUI::ScrollView* mGlobalMap; std::unique_ptr mGlobalMapTexture; std::unique_ptr mGlobalMapOverlayTexture; @@ -315,9 +322,7 @@ namespace MWGui osg::Vec2f position; MyGUI::Widget* widget = nullptr; - bool operator<(const MapMarkerType& right) const { - return widget < right.widget; - } + bool operator<(const MapMarkerType& right) const { return widget < right.widget; } }; std::map mGlobalMapMarkersByName; @@ -330,7 +335,7 @@ namespace MWGui void onTitleDoubleClicked() override; void doorMarkerCreated(MyGUI::Widget* marker) override; - void customMarkerCreated(MyGUI::Widget *marker) override; + void customMarkerCreated(MyGUI::Widget* marker) override; void notifyPlayerUpdate() override; diff --git a/apps/openmw/mwgui/merchantrepair.cpp b/apps/openmw/mwgui/merchantrepair.cpp index 169dfe0de7..208127a606 100644 --- a/apps/openmw/mwgui/merchantrepair.cpp +++ b/apps/openmw/mwgui/merchantrepair.cpp @@ -3,16 +3,16 @@ #include #include -#include #include +#include -#include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" -#include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/actorutil.hpp" +#include "../mwmechanics/creaturestats.hpp" #include "../mwworld/class.hpp" #include "../mwworld/containerstore.hpp" @@ -20,130 +20,134 @@ namespace MWGui { -MerchantRepair::MerchantRepair() - : WindowBase("openmw_merchantrepair.layout") -{ - getWidget(mList, "RepairView"); - getWidget(mOkButton, "OkButton"); - getWidget(mGoldLabel, "PlayerGold"); + MerchantRepair::MerchantRepair() + : WindowBase("openmw_merchantrepair.layout") + { + getWidget(mList, "RepairView"); + getWidget(mOkButton, "OkButton"); + getWidget(mGoldLabel, "PlayerGold"); - mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MerchantRepair::onOkButtonClick); -} + mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &MerchantRepair::onOkButtonClick); + } -void MerchantRepair::setPtr(const MWWorld::Ptr &actor) -{ - mActor = actor; + void MerchantRepair::setPtr(const MWWorld::Ptr& actor) + { + mActor = actor; - while (mList->getChildCount()) - MyGUI::Gui::getInstance().destroyWidget(mList->getChildAt(0)); + while (mList->getChildCount()) + MyGUI::Gui::getInstance().destroyWidget(mList->getChildAt(0)); - int lineHeight = MWBase::Environment::get().getWindowManager()->getFontHeight() + 2; - int currentY = 0; + int lineHeight = MWBase::Environment::get().getWindowManager()->getFontHeight() + 2; + int currentY = 0; - MWWorld::Ptr player = MWMechanics::getPlayer(); - int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId); + MWWorld::Ptr player = MWMechanics::getPlayer(); + int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId); - MWWorld::ContainerStore& store = player.getClass().getContainerStore(player); - int categories = MWWorld::ContainerStore::Type_Weapon | MWWorld::ContainerStore::Type_Armor; - for (MWWorld::ContainerStoreIterator iter (store.begin(categories)); iter!=store.end(); ++iter) - { - if (iter->getClass().hasItemHealth(*iter)) + MWWorld::ContainerStore& store = player.getClass().getContainerStore(player); + int categories = MWWorld::ContainerStore::Type_Weapon | MWWorld::ContainerStore::Type_Armor; + for (MWWorld::ContainerStoreIterator iter(store.begin(categories)); iter != store.end(); ++iter) { - int maxDurability = iter->getClass().getItemMaxHealth(*iter); - int durability = iter->getClass().getItemHealth(*iter); - if (maxDurability == durability || maxDurability == 0) - continue; - - int basePrice = iter->getClass().getValue(*iter); - float fRepairMult = MWBase::Environment::get().getWorld()->getStore().get() - .find("fRepairMult")->mValue.getFloat(); - - float p = static_cast(std::max(1, basePrice)); - float r = static_cast(std::max(1, static_cast(maxDurability / p))); - - int x = static_cast((maxDurability - durability) / r); - x = static_cast(fRepairMult * x); - x = std::max(1, x); - - int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mActor, x, true); - - std::string name{iter->getClass().getName(*iter)}; - name += " - " + MyGUI::utility::toString(price) - + MWBase::Environment::get().getWorld()->getStore().get() - .find("sgp")->mValue.getString(); - - MyGUI::Button* button = - mList->createWidget(price <= playerGold ? "SandTextButton" : "SandTextButtonDisabled", // can't use setEnabled since that removes tooltip - 0, - currentY, - 0, - lineHeight, - MyGUI::Align::Default - ); - - currentY += lineHeight; - - button->setUserString("Price", MyGUI::utility::toString(price)); - button->setUserData(MWWorld::Ptr(*iter)); - button->setCaptionWithReplacing(name); - button->setSize(mList->getWidth(), lineHeight); - button->eventMouseWheel += MyGUI::newDelegate(this, &MerchantRepair::onMouseWheel); - button->setUserString("ToolTipType", "ItemPtr"); - button->eventMouseButtonClick += MyGUI::newDelegate(this, &MerchantRepair::onRepairButtonClick); + if (iter->getClass().hasItemHealth(*iter)) + { + int maxDurability = iter->getClass().getItemMaxHealth(*iter); + int durability = iter->getClass().getItemHealth(*iter); + if (maxDurability == durability || maxDurability == 0) + continue; + + int basePrice = iter->getClass().getValue(*iter); + float fRepairMult = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fRepairMult") + ->mValue.getFloat(); + + float p = static_cast(std::max(1, basePrice)); + float r = static_cast(std::max(1, static_cast(maxDurability / p))); + + int x = static_cast((maxDurability - durability) / r); + x = static_cast(fRepairMult * x); + x = std::max(1, x); + + int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mActor, x, true); + + std::string name{ iter->getClass().getName(*iter) }; + name += " - " + MyGUI::utility::toString(price) + + MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("sgp") + ->mValue.getString(); + + MyGUI::Button* button = mList->createWidget(price <= playerGold + ? "SandTextButton" + : "SandTextButtonDisabled", // can't use setEnabled since that removes tooltip + 0, currentY, 0, lineHeight, MyGUI::Align::Default); + + currentY += lineHeight; + + button->setUserString("Price", MyGUI::utility::toString(price)); + button->setUserData(MWWorld::Ptr(*iter)); + button->setCaptionWithReplacing(name); + button->setSize(mList->getWidth(), lineHeight); + button->eventMouseWheel += MyGUI::newDelegate(this, &MerchantRepair::onMouseWheel); + button->setUserString("ToolTipType", "ItemPtr"); + button->eventMouseButtonClick += MyGUI::newDelegate(this, &MerchantRepair::onRepairButtonClick); + } } + // Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the + // scrollbar is hidden + mList->setVisibleVScroll(false); + mList->setCanvasSize(MyGUI::IntSize(mList->getWidth(), std::max(mList->getHeight(), currentY))); + mList->setVisibleVScroll(true); + + mGoldLabel->setCaptionWithReplacing("#{sGold}: " + MyGUI::utility::toString(playerGold)); } - // Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden - mList->setVisibleVScroll(false); - mList->setCanvasSize (MyGUI::IntSize(mList->getWidth(), std::max(mList->getHeight(), currentY))); - mList->setVisibleVScroll(true); - mGoldLabel->setCaptionWithReplacing("#{sGold}: " - + MyGUI::utility::toString(playerGold)); -} + void MerchantRepair::onMouseWheel(MyGUI::Widget* _sender, int _rel) + { + if (mList->getViewOffset().top + _rel * 0.3f > 0) + mList->setViewOffset(MyGUI::IntPoint(0, 0)); + else + mList->setViewOffset(MyGUI::IntPoint(0, static_cast(mList->getViewOffset().top + _rel * 0.3f))); + } -void MerchantRepair::onMouseWheel(MyGUI::Widget* _sender, int _rel) -{ - if (mList->getViewOffset().top + _rel*0.3f > 0) + void MerchantRepair::onOpen() + { + center(); + // Reset scrollbars mList->setViewOffset(MyGUI::IntPoint(0, 0)); - else - mList->setViewOffset(MyGUI::IntPoint(0, static_cast(mList->getViewOffset().top + _rel*0.3f))); -} - -void MerchantRepair::onOpen() -{ - center(); - // Reset scrollbars - mList->setViewOffset(MyGUI::IntPoint(0, 0)); -} + } -void MerchantRepair::onRepairButtonClick(MyGUI::Widget *sender) -{ - MWWorld::Ptr player = MWMechanics::getPlayer(); + void MerchantRepair::onRepairButtonClick(MyGUI::Widget* sender) + { + MWWorld::Ptr player = MWMechanics::getPlayer(); - int price = MyGUI::utility::parseInt(sender->getUserString("Price")); - if (price > player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId)) - return; + int price = MyGUI::utility::parseInt(sender->getUserString("Price")); + if (price > player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId)) + return; - // repair - MWWorld::Ptr item = *sender->getUserData(); - item.getCellRef().setCharge(item.getClass().getItemMaxHealth(item)); + // repair + MWWorld::Ptr item = *sender->getUserData(); + item.getCellRef().setCharge(item.getClass().getItemMaxHealth(item)); - player.getClass().getContainerStore(player).restack(item); + player.getClass().getContainerStore(player).restack(item); - MWBase::Environment::get().getWindowManager()->playSound("Repair"); + MWBase::Environment::get().getWindowManager()->playSound("Repair"); - player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, price, player); + player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, price, player); - // add gold to NPC trading gold pool - MWMechanics::CreatureStats& actorStats = mActor.getClass().getCreatureStats(mActor); - actorStats.setGoldPool(actorStats.getGoldPool() + price); + // add gold to NPC trading gold pool + MWMechanics::CreatureStats& actorStats = mActor.getClass().getCreatureStats(mActor); + actorStats.setGoldPool(actorStats.getGoldPool() + price); - setPtr(mActor); -} + setPtr(mActor); + } -void MerchantRepair::onOkButtonClick(MyGUI::Widget *sender) -{ - MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_MerchantRepair); -} + void MerchantRepair::onOkButtonClick(MyGUI::Widget* sender) + { + MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_MerchantRepair); + } } diff --git a/apps/openmw/mwgui/merchantrepair.hpp b/apps/openmw/mwgui/merchantrepair.hpp index f5276d7f6e..c2fa1cc28a 100644 --- a/apps/openmw/mwgui/merchantrepair.hpp +++ b/apps/openmw/mwgui/merchantrepair.hpp @@ -1,33 +1,33 @@ #ifndef OPENMW_MWGUI_MERCHANTREPAIR_H #define OPENMW_MWGUI_MERCHANTREPAIR_H -#include "windowbase.hpp" #include "../mwworld/ptr.hpp" +#include "windowbase.hpp" namespace MWGui { -class MerchantRepair : public WindowBase -{ -public: - MerchantRepair(); + class MerchantRepair : public WindowBase + { + public: + MerchantRepair(); - void onOpen() override; + void onOpen() override; - void setPtr(const MWWorld::Ptr& actor) override; + void setPtr(const MWWorld::Ptr& actor) override; -private: - MyGUI::ScrollView* mList; - MyGUI::Button* mOkButton; - MyGUI::TextBox* mGoldLabel; + private: + MyGUI::ScrollView* mList; + MyGUI::Button* mOkButton; + MyGUI::TextBox* mGoldLabel; - MWWorld::Ptr mActor; + MWWorld::Ptr mActor; -protected: - void onMouseWheel(MyGUI::Widget* _sender, int _rel); - void onRepairButtonClick(MyGUI::Widget* sender); - void onOkButtonClick(MyGUI::Widget* sender); -}; + protected: + void onMouseWheel(MyGUI::Widget* _sender, int _rel); + void onRepairButtonClick(MyGUI::Widget* sender); + void onOkButtonClick(MyGUI::Widget* sender); + }; } diff --git a/apps/openmw/mwgui/messagebox.cpp b/apps/openmw/mwgui/messagebox.cpp index 4e163f7d37..1b8fa8b1f8 100644 --- a/apps/openmw/mwgui/messagebox.cpp +++ b/apps/openmw/mwgui/messagebox.cpp @@ -1,29 +1,29 @@ #include "messagebox.hpp" -#include +#include #include +#include #include -#include #include #include #include "../mwbase/environment.hpp" -#include "../mwbase/soundmanager.hpp" #include "../mwbase/inputmanager.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwbase/windowmanager.hpp" namespace MWGui { - MessageBoxManager::MessageBoxManager (float timePerChar) + MessageBoxManager::MessageBoxManager(float timePerChar) { mStaticMessageBox = nullptr; mLastButtonPressed = -1; mMessageBoxSpeed = timePerChar; } - MessageBoxManager::~MessageBoxManager () + MessageBoxManager::~MessageBoxManager() { MessageBoxManager::clear(); } @@ -47,12 +47,12 @@ namespace MWGui mLastButtonPressed = -1; } - void MessageBoxManager::onFrame (float frameDuration) + void MessageBoxManager::onFrame(float frameDuration) { - for(auto it = mMessageBoxes.begin(); it != mMessageBoxes.end();) + for (auto it = mMessageBoxes.begin(); it != mMessageBoxes.end();) { (*it)->mCurrentTime += frameDuration; - if((*it)->mCurrentTime >= (*it)->mMaxTime && it->get() != mStaticMessageBox) + if ((*it)->mCurrentTime >= (*it)->mMaxTime && it->get() != mStaticMessageBox) { it = mMessageBoxes.erase(it); } @@ -62,19 +62,20 @@ namespace MWGui float height = 0; auto it = mMessageBoxes.begin(); - while(it != mMessageBoxes.end()) + while (it != mMessageBoxes.end()) { (*it)->update(static_cast(height)); height += (*it)->getHeight(); ++it; } - if(mInterMessageBoxe != nullptr && mInterMessageBoxe->mMarkedToDelete) { + if (mInterMessageBoxe != nullptr && mInterMessageBoxe->mMarkedToDelete) + { mLastButtonPressed = mInterMessageBoxe->readPressedButton(); mInterMessageBoxe->setVisible(false); mInterMessageBoxe.reset(); MWBase::Environment::get().getInputManager()->changeInputMode( - MWBase::Environment::get().getWindowManager()->isGuiMode()); + MWBase::Environment::get().getWindowManager()->isGuiMode()); } } @@ -82,17 +83,18 @@ namespace MWGui { auto box = std::make_unique(*this, message); box->mCurrentTime = 0; - auto realMessage = MyGUI::LanguageManager::getInstance().replaceTags({message.data(), message.size()}); - box->mMaxTime = realMessage.length()*mMessageBoxSpeed; + auto realMessage = MyGUI::LanguageManager::getInstance().replaceTags({ message.data(), message.size() }); + box->mMaxTime = realMessage.length() * mMessageBoxSpeed; - if(stat) + if (stat) mStaticMessageBox = box.get(); box->setVisible(mVisible); mMessageBoxes.push_back(std::move(box)); - if(mMessageBoxes.size() > 3) { + if (mMessageBoxes.size() > 3) + { mMessageBoxes.erase(mMessageBoxes.begin()); } @@ -104,13 +106,14 @@ namespace MWGui } } - void MessageBoxManager::removeStaticMessageBox () + void MessageBoxManager::removeStaticMessageBox() { removeMessageBox(mStaticMessageBox); mStaticMessageBox = nullptr; } - bool MessageBoxManager::createInteractiveMessageBox(std::string_view message, const std::vector& buttons) + bool MessageBoxManager::createInteractiveMessageBox( + std::string_view message, const std::vector& buttons) { if (mInterMessageBoxe != nullptr) { @@ -118,22 +121,22 @@ namespace MWGui mInterMessageBoxe->setVisible(false); } - mInterMessageBoxe = std::make_unique(*this, std::string{message}, buttons); + mInterMessageBoxe = std::make_unique(*this, std::string{ message }, buttons); mLastButtonPressed = -1; return true; } - bool MessageBoxManager::isInteractiveMessageBox () + bool MessageBoxManager::isInteractiveMessageBox() { return mInterMessageBoxe != nullptr; } - bool MessageBoxManager::removeMessageBox (MessageBox *msgbox) + bool MessageBoxManager::removeMessageBox(MessageBox* msgbox) { - for(auto it = mMessageBoxes.begin(); it != mMessageBoxes.end(); ++it) + for (auto it = mMessageBoxes.begin(); it != mMessageBoxes.end(); ++it) { - if(it->get() == msgbox) + if (it->get() == msgbox) { mMessageBoxes.erase(it); return true; @@ -147,7 +150,7 @@ namespace MWGui return mMessageBoxes; } - int MessageBoxManager::readPressedButton (bool reset) + int MessageBoxManager::readPressedButton(bool reset) { int pressed = mLastButtonPressed; if (reset) @@ -163,11 +166,11 @@ namespace MWGui } MessageBox::MessageBox(MessageBoxManager& parMessageBoxManager, std::string_view message) - : Layout("openmw_messagebox.layout") - , mCurrentTime(0) - , mMaxTime(0) - , mMessageBoxManager(parMessageBoxManager) - , mMessage(message) + : Layout("openmw_messagebox.layout") + , mCurrentTime(0) + , mMaxTime(0) + , mMessageBoxManager(parMessageBoxManager) + , mMessage(message) { // defines mBottomPadding = 48; @@ -178,19 +181,19 @@ namespace MWGui mMessageWidget->setCaptionWithReplacing(mMessage); } - void MessageBox::update (int height) + void MessageBox::update(int height) { MyGUI::IntSize gameWindowSize = MyGUI::RenderManager::getInstance().getViewSize(); MyGUI::IntPoint pos; - pos.left = (gameWindowSize.width - mMainWidget->getWidth())/2; + pos.left = (gameWindowSize.width - mMainWidget->getWidth()) / 2; pos.top = (gameWindowSize.height - mMainWidget->getHeight() - height - mBottomPadding); mMainWidget->setPosition(pos); } - int MessageBox::getHeight () + int MessageBox::getHeight() { - return mMainWidget->getHeight()+mNextBoxPadding; + return mMainWidget->getHeight() + mNextBoxPadding; } void MessageBox::setVisible(bool value) @@ -198,10 +201,13 @@ namespace MWGui mMainWidget->setVisible(value); } - InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxManager, const std::string& message, const std::vector& buttons) - : WindowModal(MWBase::Environment::get().getWindowManager()->isGuiMode() ? "openmw_interactive_messagebox_notransp.layout" : "openmw_interactive_messagebox.layout") - , mMessageBoxManager(parMessageBoxManager) - , mButtonPressed(-1) + InteractiveMessageBox::InteractiveMessageBox( + MessageBoxManager& parMessageBoxManager, const std::string& message, const std::vector& buttons) + : WindowModal(MWBase::Environment::get().getWindowManager()->isGuiMode() + ? "openmw_interactive_messagebox_notransp.layout" + : "openmw_interactive_messagebox.layout") + , mMessageBoxManager(parMessageBoxManager) + , mButtonPressed(-1) { int textPadding = 10; // padding between text-widget and main-widget int textButtonPadding = 10; // padding between the text-widget und the button-widget @@ -213,7 +219,6 @@ namespace MWGui mMarkedToDelete = false; - getWidget(mMessageWidget, "message"); getWidget(mButtonsWidget, "buttons"); @@ -230,13 +235,10 @@ namespace MWGui int buttonHeight = 0; MyGUI::IntCoord dummyCoord(0, 0, 0, 0); - for(const std::string& buttonId : buttons) + for (const std::string& buttonId : buttons) { MyGUI::Button* button = mButtonsWidget->createWidget( - MyGUI::WidgetStyle::Child, - std::string("MW_Button"), - dummyCoord, - MyGUI::Align::Default); + MyGUI::WidgetStyle::Child, std::string("MW_Button"), dummyCoord, MyGUI::Align::Default); button->setCaptionWithReplacing(buttonId); button->eventMouseButtonClick += MyGUI::newDelegate(this, &InteractiveMessageBox::mousePressed); @@ -246,41 +248,42 @@ namespace MWGui if (buttonsWidth != 0) buttonsWidth += buttonLeftPadding; - int buttonWidth = button->getTextSize().width + 2*buttonLabelLeftPadding; + int buttonWidth = button->getTextSize().width + 2 * buttonLabelLeftPadding; buttonsWidth += buttonWidth; - buttonHeight = button->getTextSize().height + 2*buttonLabelTopPadding; + buttonHeight = button->getTextSize().height + 2 * buttonLabelTopPadding; if (buttonsHeight != 0) buttonsHeight += buttonTopPadding; buttonsHeight += buttonHeight; - if(buttonWidth > biggestButtonWidth) + if (buttonWidth > biggestButtonWidth) { biggestButtonWidth = buttonWidth; } } MyGUI::IntSize mainWidgetSize; - if(buttonsWidth < textSize.width) + if (buttonsWidth < textSize.width) { // on one line - mainWidgetSize.width = textSize.width + 3*textPadding; - mainWidgetSize.height = textPadding + textSize.height + textButtonPadding + buttonHeight + buttonMainPadding; + mainWidgetSize.width = textSize.width + 3 * textPadding; + mainWidgetSize.height + = textPadding + textSize.height + textButtonPadding + buttonHeight + buttonMainPadding; MyGUI::IntSize realSize = mainWidgetSize + - // To account for borders - (mMainWidget->getSize() - mMainWidget->getClientWidget()->getSize()); + // To account for borders + (mMainWidget->getSize() - mMainWidget->getClientWidget()->getSize()); MyGUI::IntPoint absPos; - absPos.left = (gameWindowSize.width - realSize.width)/2; - absPos.top = (gameWindowSize.height - realSize.height)/2; + absPos.left = (gameWindowSize.width - realSize.width) / 2; + absPos.top = (gameWindowSize.height - realSize.height) / 2; mMainWidget->setPosition(absPos); mMainWidget->setSize(realSize); MyGUI::IntCoord messageWidgetCoord; - messageWidgetCoord.left = (mainWidgetSize.width - textSize.width)/2; + messageWidgetCoord.left = (mainWidgetSize.width - textSize.width) / 2; messageWidgetCoord.top = textPadding; mMessageWidget->setCoord(messageWidgetCoord); @@ -288,15 +291,15 @@ namespace MWGui MyGUI::IntCoord buttonCord; MyGUI::IntSize buttonSize(0, buttonHeight); - int left = (mainWidgetSize.width - buttonsWidth)/2; + int left = (mainWidgetSize.width - buttonsWidth) / 2; - for(MyGUI::Button* button : mButtons) + for (MyGUI::Button* button : mButtons) { buttonCord.left = left; buttonCord.top = messageWidgetCoord.top + textSize.height + textButtonPadding; - buttonSize.width = button->getTextSize().width + 2*buttonLabelLeftPadding; - buttonSize.height = button->getTextSize().height + 2*buttonLabelTopPadding; + buttonSize.width = button->getTextSize().width + 2 * buttonLabelLeftPadding; + buttonSize.height = button->getTextSize().height + 2 * buttonLabelTopPadding; button->setCoord(buttonCord); button->setSize(buttonSize); @@ -307,11 +310,13 @@ namespace MWGui else { // among each other - if(biggestButtonWidth > textSize.width) { - mainWidgetSize.width = biggestButtonWidth + buttonTopPadding*2; + if (biggestButtonWidth > textSize.width) + { + mainWidgetSize.width = biggestButtonWidth + buttonTopPadding * 2; } - else { - mainWidgetSize.width = textSize.width + 3*textPadding; + else + { + mainWidgetSize.width = textSize.width + 3 * textPadding; } MyGUI::IntCoord buttonCord; @@ -319,13 +324,13 @@ namespace MWGui int top = textPadding + textSize.height + textButtonPadding; - for(MyGUI::Button* button : mButtons) + for (MyGUI::Button* button : mButtons) { - buttonSize.width = button->getTextSize().width + buttonLabelLeftPadding*2; - buttonSize.height = button->getTextSize().height + buttonLabelTopPadding*2; + buttonSize.width = button->getTextSize().width + buttonLabelLeftPadding * 2; + buttonSize.height = button->getTextSize().height + buttonLabelTopPadding * 2; buttonCord.top = top; - buttonCord.left = (mainWidgetSize.width - buttonSize.width)/2; + buttonCord.left = (mainWidgetSize.width - buttonSize.width) / 2; button->setCoord(buttonCord); button->setSize(buttonSize); @@ -333,19 +338,20 @@ namespace MWGui top += buttonSize.height + buttonTopPadding; } - mainWidgetSize.height = textPadding + textSize.height + textButtonPadding + buttonsHeight + buttonMainPadding; + mainWidgetSize.height + = textPadding + textSize.height + textButtonPadding + buttonsHeight + buttonMainPadding; mMainWidget->setSize(mainWidgetSize + - // To account for borders - (mMainWidget->getSize() - mMainWidget->getClientWidget()->getSize())); + // To account for borders + (mMainWidget->getSize() - mMainWidget->getClientWidget()->getSize())); MyGUI::IntPoint absPos; - absPos.left = (gameWindowSize.width - mainWidgetSize.width)/2; - absPos.top = (gameWindowSize.height - mainWidgetSize.height)/2; + absPos.left = (gameWindowSize.width - mainWidgetSize.width) / 2; + absPos.top = (gameWindowSize.height - mainWidgetSize.height) / 2; mMainWidget->setPosition(absPos); MyGUI::IntCoord messageWidgetCoord; - messageWidgetCoord.left = (mainWidgetSize.width - textSize.width)/2; + messageWidgetCoord.left = (mainWidgetSize.width - textSize.width) / 2; messageWidgetCoord.top = textPadding; messageWidgetCoord.width = textSize.width; messageWidgetCoord.height = textSize.height; @@ -357,8 +363,8 @@ namespace MWGui MyGUI::Widget* InteractiveMessageBox::getDefaultKeyFocus() { - std::vector keywords { "sOk", "sYes" }; - for(MyGUI::Button* button : mButtons) + std::vector keywords{ "sOk", "sYes" }; + for (MyGUI::Button* button : mButtons) { for (const std::string& keyword : keywords) { @@ -373,18 +379,18 @@ namespace MWGui return nullptr; } - void InteractiveMessageBox::mousePressed (MyGUI::Widget* pressed) + void InteractiveMessageBox::mousePressed(MyGUI::Widget* pressed) { - buttonActivated (pressed); + buttonActivated(pressed); } - void InteractiveMessageBox::buttonActivated (MyGUI::Widget* pressed) + void InteractiveMessageBox::buttonActivated(MyGUI::Widget* pressed) { mMarkedToDelete = true; int index = 0; - for(const MyGUI::Button* button : mButtons) + for (const MyGUI::Button* button : mButtons) { - if(button == pressed) + if (button == pressed) { mButtonPressed = index; mMessageBoxManager.onButtonPressed(mButtonPressed); @@ -394,7 +400,7 @@ namespace MWGui } } - int InteractiveMessageBox::readPressedButton () + int InteractiveMessageBox::readPressedButton() { return mButtonPressed; } diff --git a/apps/openmw/mwgui/messagebox.hpp b/apps/openmw/mwgui/messagebox.hpp index 3fec60caee..78f3df0d84 100644 --- a/apps/openmw/mwgui/messagebox.hpp +++ b/apps/openmw/mwgui/messagebox.hpp @@ -19,89 +19,94 @@ namespace MWGui class MessageBox; class MessageBoxManager { - public: - MessageBoxManager (float timePerChar); - ~MessageBoxManager (); - void onFrame (float frameDuration); - void createMessageBox(std::string_view message, bool stat = false); - void removeStaticMessageBox (); - bool createInteractiveMessageBox(std::string_view message, const std::vector& buttons); - bool isInteractiveMessageBox (); + public: + MessageBoxManager(float timePerChar); + ~MessageBoxManager(); + void onFrame(float frameDuration); + void createMessageBox(std::string_view message, bool stat = false); + void removeStaticMessageBox(); + bool createInteractiveMessageBox(std::string_view message, const std::vector& buttons); + bool isInteractiveMessageBox(); - int getMessagesCount(); + int getMessagesCount(); - const InteractiveMessageBox* getInteractiveMessageBox() const { return mInterMessageBoxe.get(); } + const InteractiveMessageBox* getInteractiveMessageBox() const { return mInterMessageBoxe.get(); } - /// Remove all message boxes - void clear(); + /// Remove all message boxes + void clear(); - bool removeMessageBox (MessageBox *msgbox); + bool removeMessageBox(MessageBox* msgbox); - /// @param reset Reset the pressed button to -1 after reading it. - int readPressedButton (bool reset=true); + /// @param reset Reset the pressed button to -1 after reading it. + int readPressedButton(bool reset = true); - typedef MyGUI::delegates::CMultiDelegate1 EventHandle_Int; + typedef MyGUI::delegates::CMultiDelegate1 EventHandle_Int; - // Note: this delegate unassigns itself after it was fired, i.e. works once. - EventHandle_Int eventButtonPressed; + // Note: this delegate unassigns itself after it was fired, i.e. works once. + EventHandle_Int eventButtonPressed; - void onButtonPressed(int button) { eventButtonPressed(button); eventButtonPressed.clear(); } + void onButtonPressed(int button) + { + eventButtonPressed(button); + eventButtonPressed.clear(); + } - void setVisible(bool value); + void setVisible(bool value); - const std::vector>& getActiveMessageBoxes() const; + const std::vector>& getActiveMessageBoxes() const; - private: - std::vector> mMessageBoxes; - std::unique_ptr mInterMessageBoxe; - MessageBox* mStaticMessageBox; - float mMessageBoxSpeed; - int mLastButtonPressed; - bool mVisible = true; + private: + std::vector> mMessageBoxes; + std::unique_ptr mInterMessageBoxe; + MessageBox* mStaticMessageBox; + float mMessageBoxSpeed; + int mLastButtonPressed; + bool mVisible = true; }; class MessageBox : public Layout { - public: - MessageBox (MessageBoxManager& parMessageBoxManager, std::string_view message); - const std::string& getMessage() { return mMessage; }; - int getHeight (); - void update (int height); - void setVisible(bool value); - - float mCurrentTime; - float mMaxTime; - - protected: - MessageBoxManager& mMessageBoxManager; - std::string mMessage; - MyGUI::EditBox* mMessageWidget; - int mBottomPadding; - int mNextBoxPadding; + public: + MessageBox(MessageBoxManager& parMessageBoxManager, std::string_view message); + const std::string& getMessage() { return mMessage; }; + int getHeight(); + void update(int height); + void setVisible(bool value); + + float mCurrentTime; + float mMaxTime; + + protected: + MessageBoxManager& mMessageBoxManager; + std::string mMessage; + MyGUI::EditBox* mMessageWidget; + int mBottomPadding; + int mNextBoxPadding; }; class InteractiveMessageBox : public WindowModal { - public: - InteractiveMessageBox (MessageBoxManager& parMessageBoxManager, const std::string& message, const std::vector& buttons); - void mousePressed (MyGUI::Widget* _widget); - int readPressedButton (); + public: + InteractiveMessageBox(MessageBoxManager& parMessageBoxManager, const std::string& message, + const std::vector& buttons); + void mousePressed(MyGUI::Widget* _widget); + int readPressedButton(); - MyGUI::Widget* getDefaultKeyFocus() override; + MyGUI::Widget* getDefaultKeyFocus() override; - bool exit() override { return false; } + bool exit() override { return false; } - bool mMarkedToDelete; + bool mMarkedToDelete; - private: - void buttonActivated (MyGUI::Widget* _widget); + private: + void buttonActivated(MyGUI::Widget* _widget); - MessageBoxManager& mMessageBoxManager; - MyGUI::EditBox* mMessageWidget; - MyGUI::Widget* mButtonsWidget; - std::vector mButtons; + MessageBoxManager& mMessageBoxManager; + MyGUI::EditBox* mMessageWidget; + MyGUI::Widget* mButtonsWidget; + std::vector mButtons; - int mButtonPressed; + int mButtonPressed; }; } diff --git a/apps/openmw/mwgui/mode.hpp b/apps/openmw/mwgui/mode.hpp index 62d7396577..63f81e8b47 100644 --- a/apps/openmw/mwgui/mode.hpp +++ b/apps/openmw/mwgui/mode.hpp @@ -3,63 +3,63 @@ namespace MWGui { - enum GuiMode + enum GuiMode { - GM_None, - GM_Settings, // Settings window - GM_Inventory, // Inventory mode - GM_Container, - GM_Companion, - GM_MainMenu, // Main menu mode + GM_None, + GM_Settings, // Settings window + GM_Inventory, // Inventory mode + GM_Container, + GM_Companion, + GM_MainMenu, // Main menu mode - GM_Journal, // Journal mode + GM_Journal, // Journal mode - GM_Scroll, // Read scroll - GM_Book, // Read book - GM_Alchemy, // Make potions - GM_Repair, + GM_Scroll, // Read scroll + GM_Book, // Read book + GM_Alchemy, // Make potions + GM_Repair, - GM_Dialogue, // NPC interaction - GM_Barter, - GM_Rest, - GM_SpellBuying, - GM_Travel, - GM_SpellCreation, - GM_Enchanting, - GM_Recharge, - GM_Training, - GM_MerchantRepair, + GM_Dialogue, // NPC interaction + GM_Barter, + GM_Rest, + GM_SpellBuying, + GM_Travel, + GM_SpellCreation, + GM_Enchanting, + GM_Recharge, + GM_Training, + GM_MerchantRepair, - GM_Levelup, + GM_Levelup, - // Startup character creation dialogs - GM_Name, - GM_Race, - GM_Birth, - GM_Class, - GM_ClassGenerate, - GM_ClassPick, - GM_ClassCreate, - GM_Review, - - GM_Loading, - GM_LoadingWallpaper, - GM_Jail, + // Startup character creation dialogs + GM_Name, + GM_Race, + GM_Birth, + GM_Class, + GM_ClassGenerate, + GM_ClassPick, + GM_ClassCreate, + GM_Review, - GM_QuickKeysMenu + GM_Loading, + GM_LoadingWallpaper, + GM_Jail, + + GM_QuickKeysMenu }; - // Windows shown in inventory mode - enum GuiWindow + // Windows shown in inventory mode + enum GuiWindow { - GW_None = 0, + GW_None = 0, - GW_Map = 0x01, - GW_Inventory = 0x02, - GW_Magic = 0x04, - GW_Stats = 0x08, + GW_Map = 0x01, + GW_Inventory = 0x02, + GW_Magic = 0x04, + GW_Stats = 0x08, - GW_ALL = 0xFF + GW_ALL = 0xFF }; } diff --git a/apps/openmw/mwgui/pickpocketitemmodel.cpp b/apps/openmw/mwgui/pickpocketitemmodel.cpp index aca1b7392b..cfa832fd7f 100644 --- a/apps/openmw/mwgui/pickpocketitemmodel.cpp +++ b/apps/openmw/mwgui/pickpocketitemmodel.cpp @@ -1,7 +1,7 @@ #include "pickpocketitemmodel.hpp" -#include #include +#include #include "../mwmechanics/actorutil.hpp" #include "../mwmechanics/creaturestats.hpp" @@ -17,8 +17,10 @@ namespace MWGui { - PickpocketItemModel::PickpocketItemModel(const MWWorld::Ptr& actor, std::unique_ptr sourceModel, bool hideItems) - : mActor(actor), mPickpocketDetected(false) + PickpocketItemModel::PickpocketItemModel( + const MWWorld::Ptr& actor, std::unique_ptr sourceModel, bool hideItems) + : mActor(actor) + , mPickpocketDetected(false) { MWWorld::Ptr player = MWMechanics::getPlayer(); mSourceModel = std::move(sourceModel); @@ -29,7 +31,7 @@ namespace MWGui if (hideItems) { auto& prng = MWBase::Environment::get().getWorld()->getPrng(); - for (size_t i = 0; igetItemCount(); ++i) + for (size_t i = 0; i < mSourceModel->getItemCount(); ++i) { if (Misc::Rng::roll0to99(prng) > chance) mHiddenItems.push_back(mSourceModel->getItem(i)); @@ -42,7 +44,7 @@ namespace MWGui return false; } - ItemStack PickpocketItemModel::getItem (ModelIndex index) + ItemStack PickpocketItemModel::getItem(ModelIndex index) { if (index < 0) throw std::runtime_error("Invalid index supplied"); @@ -60,7 +62,7 @@ namespace MWGui { mSourceModel->update(); mItems.clear(); - for (size_t i = 0; igetItemCount(); ++i) + for (size_t i = 0; i < mSourceModel->getItemCount(); ++i) { const ItemStack& item = mSourceModel->getItem(i); @@ -69,17 +71,17 @@ namespace MWGui continue; if (std::find(mHiddenItems.begin(), mHiddenItems.end(), item) == mHiddenItems.end() - && item.mType != ItemStack::Type_Equipped) + && item.mType != ItemStack::Type_Equipped) mItems.push_back(item); } } - void PickpocketItemModel::removeItem (const ItemStack &item, size_t count) + void PickpocketItemModel::removeItem(const ItemStack& item, size_t count) { ProxyItemModel::removeItem(item, count); } - bool PickpocketItemModel::onDropItem(const MWWorld::Ptr &item, int count) + bool PickpocketItemModel::onDropItem(const MWWorld::Ptr& item, int count) { // don't allow "reverse pickpocket" (it will be handled by scripts after 1.0) return false; @@ -89,8 +91,8 @@ namespace MWGui { // Make sure we were actually closed, rather than just temporarily hidden (e.g. console or main menu opened) if (MWBase::Environment::get().getWindowManager()->containsMode(GM_Container) - // If it was already detected while taking an item, no need to check now - || mPickpocketDetected) + // If it was already detected while taking an item, no need to check now + || mPickpocketDetected) return; MWWorld::Ptr player = MWMechanics::getPlayer(); @@ -98,13 +100,13 @@ namespace MWGui if (pickpocket.finish()) { MWBase::Environment::get().getMechanicsManager()->commitCrime( - player, mActor, MWBase::MechanicsManager::OT_Pickpocket, std::string(), 0, true); + player, mActor, MWBase::MechanicsManager::OT_Pickpocket, std::string(), 0, true); MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Container); mPickpocketDetected = true; } } - bool PickpocketItemModel::onTakeItem(const MWWorld::Ptr &item, int count) + bool PickpocketItemModel::onTakeItem(const MWWorld::Ptr& item, int count) { if (mActor.getClass().getCreatureStats(mActor).getKnockedDown()) return mSourceModel->onTakeItem(item, count); @@ -119,14 +121,14 @@ namespace MWGui return success; } - bool PickpocketItemModel::stealItem(const MWWorld::Ptr &item, int count) + bool PickpocketItemModel::stealItem(const MWWorld::Ptr& item, int count) { MWWorld::Ptr player = MWMechanics::getPlayer(); MWMechanics::Pickpocket pickpocket(player, mActor); if (pickpocket.pick(item, count)) { MWBase::Environment::get().getMechanicsManager()->commitCrime( - player, mActor, MWBase::MechanicsManager::OT_Pickpocket, std::string(), 0, true); + player, mActor, MWBase::MechanicsManager::OT_Pickpocket, std::string(), 0, true); MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Container); mPickpocketDetected = true; return false; diff --git a/apps/openmw/mwgui/pickpocketitemmodel.hpp b/apps/openmw/mwgui/pickpocketitemmodel.hpp index ec18f13609..3ed1786d82 100644 --- a/apps/openmw/mwgui/pickpocketitemmodel.hpp +++ b/apps/openmw/mwgui/pickpocketitemmodel.hpp @@ -6,25 +6,26 @@ namespace MWGui { - /// @brief The pickpocket item model randomly hides item stacks based on a specified chance. Equipped items are always hidden. + /// @brief The pickpocket item model randomly hides item stacks based on a specified chance. Equipped items are + /// always hidden. class PickpocketItemModel : public ProxyItemModel { public: PickpocketItemModel(const MWWorld::Ptr& thief, std::unique_ptr sourceModel, bool hideItems = true); bool allowedToUseItems() const override; - ItemStack getItem (ModelIndex index) override; + ItemStack getItem(ModelIndex index) override; size_t getItemCount() override; void update() override; - void removeItem (const ItemStack& item, size_t count) override; + void removeItem(const ItemStack& item, size_t count) override; void onClose() override; - bool onDropItem(const MWWorld::Ptr &item, int count) override; - bool onTakeItem(const MWWorld::Ptr &item, int count) override; + bool onDropItem(const MWWorld::Ptr& item, int count) override; + bool onTakeItem(const MWWorld::Ptr& item, int count) override; protected: MWWorld::Ptr mActor; bool mPickpocketDetected; - bool stealItem(const MWWorld::Ptr &item, int count); + bool stealItem(const MWWorld::Ptr& item, int count); private: std::vector mHiddenItems; diff --git a/apps/openmw/mwgui/postprocessorhud.cpp b/apps/openmw/mwgui/postprocessorhud.cpp index b7a25405b2..bd54bbf2c2 100644 --- a/apps/openmw/mwgui/postprocessorhud.cpp +++ b/apps/openmw/mwgui/postprocessorhud.cpp @@ -1,27 +1,28 @@ #include "postprocessorhud.hpp" -#include #include -#include -#include #include +#include +#include +#include -#include #include +#include #include #include "../mwrender/postprocessor.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" namespace MWGui { void PostProcessorHud::ListWrapper::onKeyButtonPressed(MyGUI::KeyCode key, MyGUI::Char ch) { - if (MyGUI::InputManager::getInstance().isShiftPressed() && (key == MyGUI::KeyCode::ArrowUp || key == MyGUI::KeyCode::ArrowDown)) + if (MyGUI::InputManager::getInstance().isShiftPressed() + && (key == MyGUI::KeyCode::ArrowUp || key == MyGUI::KeyCode::ArrowDown)) return; MyGUI::ListBox::onKeyButtonPressed(key, ch); @@ -41,7 +42,8 @@ namespace MWGui getWidget(mButtonDown, "ButtonDown"); mButtonActivate->eventMouseButtonClick += MyGUI::newDelegate(this, &PostProcessorHud::notifyActivatePressed); - mButtonDeactivate->eventMouseButtonClick += MyGUI::newDelegate(this, &PostProcessorHud::notifyDeactivatePressed); + mButtonDeactivate->eventMouseButtonClick + += MyGUI::newDelegate(this, &PostProcessorHud::notifyDeactivatePressed); mButtonUp->eventMouseButtonClick += MyGUI::newDelegate(this, &PostProcessorHud::notifyShaderUpPressed); mButtonDown->eventMouseButtonClick += MyGUI::newDelegate(this, &PostProcessorHud::notifyShaderDownPressed); @@ -53,7 +55,8 @@ namespace MWGui mFilter->eventEditTextChange += MyGUI::newDelegate(this, &PostProcessorHud::notifyFilterChanged); - mMainWidget->castType()->eventWindowChangeCoord += MyGUI::newDelegate(this, &PostProcessorHud::notifyWindowResize); + mMainWidget->castType()->eventWindowChangeCoord + += MyGUI::newDelegate(this, &PostProcessorHud::notifyWindowResize); mShaderInfo = mConfigLayout->createWidget("HeaderText", {}, MyGUI::Align::Default); mShaderInfo->setUserString("VStretch", "true"); @@ -203,7 +206,8 @@ namespace MWGui select(mActiveList, 0); } } - else if (list == mActiveList && MyGUI::InputManager::getInstance().isShiftPressed() && (key == MyGUI::KeyCode::ArrowUp || key == MyGUI::KeyCode::ArrowDown)) + else if (list == mActiveList && MyGUI::InputManager::getInstance().isShiftPressed() + && (key == MyGUI::KeyCode::ArrowUp || key == MyGUI::KeyCode::ArrowDown)) { moveShader(key == MyGUI::KeyCode::ArrowUp ? Direction::Up : Direction::Down); } @@ -224,19 +228,21 @@ namespace MWGui { constexpr int padding = 12; constexpr int padding2 = padding * 2; - mShaderInfo->setCoord(padding, padding, mConfigLayout->getSize().width - padding2 - padding, mShaderInfo->getTextSize().height); + mShaderInfo->setCoord( + padding, padding, mConfigLayout->getSize().width - padding2 - padding, mShaderInfo->getTextSize().height); int totalHeight = mShaderInfo->getTop() + mShaderInfo->getTextSize().height + padding; - mConfigArea->setCoord({padding, totalHeight, mShaderInfo->getSize().width, mConfigLayout->getHeight()}); + mConfigArea->setCoord({ padding, totalHeight, mShaderInfo->getSize().width, mConfigLayout->getHeight() }); int childHeights = 0; - MyGUI::EnumeratorWidgetPtr enumerator = mConfigArea->getEnumerator(); - while (enumerator.next()) - { - enumerator.current()->setCoord(padding, childHeights + padding, mShaderInfo->getSize().width - padding2, enumerator.current()->getHeight()); + MyGUI::EnumeratorWidgetPtr enumerator = mConfigArea->getEnumerator(); + while (enumerator.next()) + { + enumerator.current()->setCoord(padding, childHeights + padding, mShaderInfo->getSize().width - padding2, + enumerator.current()->getHeight()); childHeights += enumerator.current()->getHeight() + padding; - } + } totalHeight += childHeights; mConfigArea->setSize(mConfigArea->getWidth(), childHeights); @@ -245,7 +251,7 @@ namespace MWGui mConfigLayout->setSize(mConfigLayout->getWidth(), mConfigLayout->getParentSize().height - padding2); } - void PostProcessorHud::notifyMouseWheel(MyGUI::Widget *sender, int rel) + void PostProcessorHud::notifyMouseWheel(MyGUI::Widget* sender, int rel) { int offset = mConfigLayout->getViewOffset().top + rel * 0.3; if (offset > 0) @@ -298,9 +304,7 @@ namespace MWGui std::string_view version = technique->getVersion().empty() ? NA : technique->getVersion(); std::string_view description = technique->getDescription().empty() ? NA : technique->getDescription(); - auto serializeBool = [](bool value) { - return value ? "#{sYes}" : "#{sNo}"; - }; + auto serializeBool = [](bool value) { return value ? "#{sYes}" : "#{sNo}"; }; const auto flags = technique->getFlags(); @@ -315,19 +319,34 @@ namespace MWGui case fx::Technique::Status::Uncompiled: { if (technique->getDynamic()) - ss << "#{fontcolourhtml=header}#{PostProcessing:ShaderLocked}: #{fontcolourhtml=normal} #{PostProcessing:ShaderLockedDescription}" << endl << endl; - ss << "#{fontcolourhtml=header}#{PostProcessing:Author}: #{fontcolourhtml=normal} " << author << endl << endl - << "#{fontcolourhtml=header}#{PostProcessing:Version}: #{fontcolourhtml=normal} " << version << endl << endl - << "#{fontcolourhtml=header}#{PostProcessing:Description}: #{fontcolourhtml=normal} " << description << endl << endl - << "#{fontcolourhtml=header}#{PostProcessing:InInteriors}: #{fontcolourhtml=normal} " << flag_interior - << "#{fontcolourhtml=header} #{PostProcessing:InExteriors}: #{fontcolourhtml=normal} " << flag_exterior - << "#{fontcolourhtml=header} #{PostProcessing:Underwater}: #{fontcolourhtml=normal} " << flag_underwater - << "#{fontcolourhtml=header} #{PostProcessing:Abovewater}: #{fontcolourhtml=normal} " << flag_abovewater; + ss << "#{fontcolourhtml=header}#{PostProcessing:ShaderLocked}: #{fontcolourhtml=normal} " + "#{PostProcessing:ShaderLockedDescription}" + << endl + << endl; + ss << "#{fontcolourhtml=header}#{PostProcessing:Author}: #{fontcolourhtml=normal} " << author + << endl + << endl + << "#{fontcolourhtml=header}#{PostProcessing:Version}: #{fontcolourhtml=normal} " << version + << endl + << endl + << "#{fontcolourhtml=header}#{PostProcessing:Description}: #{fontcolourhtml=normal} " << description + << endl + << endl + << "#{fontcolourhtml=header}#{PostProcessing:InInteriors}: #{fontcolourhtml=normal} " + << flag_interior + << "#{fontcolourhtml=header} #{PostProcessing:InExteriors}: #{fontcolourhtml=normal} " + << flag_exterior + << "#{fontcolourhtml=header} #{PostProcessing:Underwater}: #{fontcolourhtml=normal} " + << flag_underwater + << "#{fontcolourhtml=header} #{PostProcessing:Abovewater}: #{fontcolourhtml=normal} " + << flag_abovewater; break; } case fx::Technique::Status::Parse_Error: - ss << "#{fontcolourhtml=negative}Shader Compile Error: #{fontcolourhtml=normal} <" << std::string(technique->getName()) << "> failed to compile." << endl << endl - << technique->getLastError(); + ss << "#{fontcolourhtml=negative}Shader Compile Error: #{fontcolourhtml=normal} <" + << std::string(technique->getName()) << "> failed to compile." << endl + << endl + << technique->getLastError(); break; case fx::Technique::Status::File_Not_exists: break; @@ -339,11 +358,13 @@ namespace MWGui { if (technique->getUniformMap().size() > 0) { - MyGUI::Button* resetButton = mConfigArea->createWidget("MW_Button", {0,0,0,24}, MyGUI::Align::Default); + MyGUI::Button* resetButton + = mConfigArea->createWidget("MW_Button", { 0, 0, 0, 24 }, MyGUI::Align::Default); resetButton->setCaptionWithReplacing("#{PostProcessing:ResetShader}"); resetButton->setTextAlign(MyGUI::Align::Center); resetButton->eventMouseWheel += MyGUI::newDelegate(this, &PostProcessorHud::notifyMouseWheel); - resetButton->eventMouseButtonClick += MyGUI::newDelegate(this, &PostProcessorHud::notifyResetButtonClicked); + resetButton->eventMouseButtonClick + += MyGUI::newDelegate(this, &PostProcessorHud::notifyResetButtonClicked); } for (const auto& uniform : technique->getUniformMap()) @@ -353,12 +374,14 @@ namespace MWGui if (!uniform->mHeader.empty()) { - Gui::AutoSizedTextBox* divider = mConfigArea->createWidget("MW_UniformGroup", {0,0,0,34}, MyGUI::Align::Default); + Gui::AutoSizedTextBox* divider = mConfigArea->createWidget( + "MW_UniformGroup", { 0, 0, 0, 34 }, MyGUI::Align::Default); divider->setNeedMouseFocus(false); divider->setCaptionWithReplacing(uniform->mHeader); } - fx::Widgets::UniformBase* uwidget = mConfigArea->createWidget("MW_UniformEdit", {0,0,0,22}, MyGUI::Align::Default); + fx::Widgets::UniformBase* uwidget = mConfigArea->createWidget( + "MW_UniformEdit", { 0, 0, 0, 22 }, MyGUI::Align::Default); uwidget->init(uniform); uwidget->getLabel()->eventMouseWheel += MyGUI::newDelegate(this, &PostProcessorHud::notifyMouseWheel); } @@ -397,7 +420,8 @@ namespace MWGui if (!technique) continue; - if (!technique->getHidden() && !processor->isTechniqueEnabled(technique) && name.find(mFilter->getCaption()) != std::string::npos) + if (!technique->getHidden() && !processor->isTechniqueEnabled(technique) + && name.find(mFilter->getCaption()) != std::string::npos) mInactiveList->addItem(name, technique); } @@ -407,8 +431,7 @@ namespace MWGui mActiveList->addItem(technique->getName(), technique); } - auto tryFocus = [this](ListWrapper* widget, const std::string& hint) - { + auto tryFocus = [this](ListWrapper* widget, const std::string& hint) { size_t index = widget->findItemIndexWith(hint); if (index != MyGUI::ITEM_NONE) diff --git a/apps/openmw/mwgui/postprocessorhud.hpp b/apps/openmw/mwgui/postprocessorhud.hpp index 7473cfcfa5..54e95e7986 100644 --- a/apps/openmw/mwgui/postprocessorhud.hpp +++ b/apps/openmw/mwgui/postprocessorhud.hpp @@ -44,7 +44,6 @@ namespace MWGui static void registerMyGUIComponents(); private: - void notifyWindowResize(MyGUI::Window* sender); void notifyFilterChanged(MyGUI::EditBox* sender); @@ -65,7 +64,7 @@ namespace MWGui void notifyShaderDownPressed(MyGUI::Widget* sender); - void notifyMouseWheel(MyGUI::Widget *sender, int rel); + void notifyMouseWheel(MyGUI::Widget* sender, int rel); enum class Direction { diff --git a/apps/openmw/mwgui/quickkeysmenu.cpp b/apps/openmw/mwgui/quickkeysmenu.cpp index c218d60726..4b7bcb58ff 100644 --- a/apps/openmw/mwgui/quickkeysmenu.cpp +++ b/apps/openmw/mwgui/quickkeysmenu.cpp @@ -1,36 +1,35 @@ #include "quickkeysmenu.hpp" -#include #include +#include #include #include #include #include +#include #include -#include #include -#include +#include -#include "../mwworld/inventorystore.hpp" #include "../mwworld/class.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/esmstore.hpp" +#include "../mwworld/inventorystore.hpp" +#include "../mwworld/player.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/mechanicsmanager.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" -#include "../mwmechanics/spellutil.hpp" -#include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/actorutil.hpp" +#include "../mwmechanics/creaturestats.hpp" +#include "../mwmechanics/spellutil.hpp" #include "itemselection.hpp" -#include "spellview.hpp" #include "itemwidget.hpp" #include "sortfilteritemmodel.hpp" - +#include "spellview.hpp" namespace MWGui { @@ -46,16 +45,15 @@ namespace MWGui getWidget(mInstructionLabel, "InstructionLabel"); mMainWidget->setSize(mMainWidget->getWidth(), - mMainWidget->getHeight() + - (mInstructionLabel->getTextSize().height - mInstructionLabel->getHeight())); + mMainWidget->getHeight() + (mInstructionLabel->getTextSize().height - mInstructionLabel->getHeight())); mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &QuickKeysMenu::onOkButtonClicked); center(); for (int i = 0; i < 10; ++i) { - mKey[i].index = i+1; - getWidget(mKey[i].button, "QuickKey" + MyGUI::utility::toString(i+1)); + mKey[i].index = i + 1; + getWidget(mKey[i].button, "QuickKey" + MyGUI::utility::toString(i + 1)); mKey[i].button->eventMouseButtonClick += MyGUI::newDelegate(this, &QuickKeysMenu::onQuickKeyButtonClicked); unassign(&mKey[i]); @@ -66,7 +64,7 @@ namespace MWGui { mActivated = nullptr; - for (int i=0; i<10; ++i) + for (int i = 0; i < 10; ++i) { unassign(&mKey[i]); } @@ -87,9 +85,8 @@ namespace MWGui { MWWorld::Ptr item = *mKey[index].button->getUserData(); // Make sure the item is available and is not broken - if (!item || item.getRefData().getCount() < 1 || - (item.getClass().hasItemHealth(item) && - item.getClass().getItemHealth(item) <= 0)) + if (!item || item.getRefData().getCount() < 1 + || (item.getClass().hasItemHealth(item) && item.getClass().getItemHealth(item) <= 0)) { // Try searching for a compatible replacement item = store.findReplacement(mKey[index].id); @@ -138,8 +135,8 @@ namespace MWGui { key->type = Type_HandToHand; - MyGUI::ImageBox* image = key->button->createWidget("ImageBox", - MyGUI::IntCoord(14, 13, 32, 32), MyGUI::Align::Default); + MyGUI::ImageBox* image = key->button->createWidget( + "ImageBox", MyGUI::IntCoord(14, 13, 32, 32), MyGUI::Align::Default); image->setImageTexture("icons\\k\\stealth_handtohand.dds"); image->setNeedMouseFocus(false); @@ -150,8 +147,8 @@ namespace MWGui key->id.clear(); key->name.clear(); - MyGUI::TextBox* textBox = key->button->createWidgetReal("SandText", - MyGUI::FloatCoord(0,0,1,1), MyGUI::Align::Default); + MyGUI::TextBox* textBox = key->button->createWidgetReal( + "SandText", MyGUI::FloatCoord(0, 0, 1, 1), MyGUI::Align::Default); textBox->setTextAlign(MyGUI::Align::Center); textBox->setCaption(MyGUI::utility::toString(key->index)); @@ -180,7 +177,7 @@ namespace MWGui mSelected = &mKey[index]; // prevent reallocation of zero key from Type_HandToHand - if(mSelected->index == 10) + if (mSelected->index == 10) return; // open assign dialog @@ -190,7 +187,7 @@ namespace MWGui mAssignDialog->setVisible(true); } - void QuickKeysMenu::onOkButtonClicked (MyGUI::Widget *sender) + void QuickKeysMenu::onOkButtonClicked(MyGUI::Widget* sender) { MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_QuickKeysMenu); } @@ -268,11 +265,13 @@ namespace MWGui mSelected->name = item.getClass().getName(item); float scale = 1.f; - MyGUI::ITexture* texture = MyGUI::RenderManager::getInstance().getTexture("textures\\menu_icon_select_magic_magic.dds"); + MyGUI::ITexture* texture + = MyGUI::RenderManager::getInstance().getTexture("textures\\menu_icon_select_magic_magic.dds"); if (texture) scale = texture->getHeight() / 64.f; - mSelected->button->setFrame("textures\\menu_icon_select_magic_magic.dds", MyGUI::IntCoord(0, 0, 44*scale, 44*scale)); + mSelected->button->setFrame( + "textures\\menu_icon_select_magic_magic.dds", MyGUI::IntCoord(0, 0, 44 * scale, 44 * scale)); mSelected->button->setIcon(item); mSelected->button->setUserString("ToolTipType", "ItemPtr"); @@ -288,7 +287,7 @@ namespace MWGui while (mSelected->button->getChildCount()) // Destroy number label MyGUI::Gui::getInstance().destroyWidget(mSelected->button->getChildAt(0)); - const MWWorld::ESMStore &esmStore = MWBase::Environment::get().getWorld()->getStore(); + const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); const ESM::Spell* spell = esmStore.get().find(spellId); mSelected->type = Type_Magic; @@ -304,15 +303,17 @@ namespace MWGui std::string path = effect->mIcon; int slashPos = path.rfind('\\'); - path.insert(slashPos+1, "b_"); + path.insert(slashPos + 1, "b_"); path = Misc::ResourceHelpers::correctIconPath(path, MWBase::Environment::get().getResourceSystem()->getVFS()); float scale = 1.f; - MyGUI::ITexture* texture = MyGUI::RenderManager::getInstance().getTexture("textures\\menu_icon_select_magic.dds"); + MyGUI::ITexture* texture + = MyGUI::RenderManager::getInstance().getTexture("textures\\menu_icon_select_magic.dds"); if (texture) scale = texture->getHeight() / 64.f; - mSelected->button->setFrame("textures\\menu_icon_select_magic.dds", MyGUI::IntCoord(0, 0, 44*scale, 44*scale)); + mSelected->button->setFrame( + "textures\\menu_icon_select_magic.dds", MyGUI::IntCoord(0, 0, 44 * scale, 44 * scale)); mSelected->button->setIcon(path); if (mMagicSelectionDialog) @@ -337,19 +338,18 @@ namespace MWGui { assert(index >= 1 && index <= 10); - keyData *key = &mKey[index-1]; - + keyData* key = &mKey[index - 1]; + MWWorld::Ptr player = MWMechanics::getPlayer(); MWWorld::InventoryStore& store = player.getClass().getInventoryStore(player); - const MWMechanics::CreatureStats &playerStats = player.getClass().getCreatureStats(player); + const MWMechanics::CreatureStats& playerStats = player.getClass().getCreatureStats(player); - validate(index-1); + validate(index - 1); // Delay action executing, // if player is busy for now (casting a spell, attacking someone, etc.) bool isDelayNeeded = MWBase::Environment::get().getMechanicsManager()->isAttackingOrSpell(player) - || playerStats.getKnockedDown() - || playerStats.getHitRecovery(); + || playerStats.getKnockedDown() || playerStats.getHitRecovery(); bool godmode = MWBase::Environment::get().getWorld()->getGodModeState(); bool isReturnNeeded = (!godmode && playerStats.isParalyzed()) || playerStats.isDead(); @@ -382,15 +382,14 @@ namespace MWGui item = nullptr; // check the item is available and not broken - if (!item || item.getRefData().getCount() < 1 || - (item.getClass().hasItemHealth(item) && item.getClass().getItemHealth(item) <= 0)) + if (!item || item.getRefData().getCount() < 1 + || (item.getClass().hasItemHealth(item) && item.getClass().getItemHealth(item) <= 0)) { item = store.findReplacement(key->id); if (!item || item.getRefData().getCount() < 1) { - MWBase::Environment::get().getWindowManager()->messageBox( - "#{sQuickMenu5} " + key->name); + MWBase::Environment::get().getWindowManager()->messageBox("#{sQuickMenu5} " + key->name); return; } @@ -400,7 +399,8 @@ namespace MWGui { if (!store.isEquipped(item)) MWBase::Environment::get().getWindowManager()->useItem(item); - MWWorld::ConstContainerStoreIterator rightHand = store.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); + MWWorld::ConstContainerStoreIterator rightHand + = store.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); // change draw state only if the item is in player's right hand if (rightHand != store.end() && item == *rightHand) { @@ -438,8 +438,8 @@ namespace MWGui } store.setSelectedEnchantItem(store.end()); - MWBase::Environment::get().getWindowManager() - ->setSelectedSpell(spellId, int(MWMechanics::getSpellSuccessChance(spellId, player))); + MWBase::Environment::get().getWindowManager()->setSelectedSpell( + spellId, int(MWMechanics::getSpellSuccessChance(spellId, player))); MWBase::Environment::get().getWorld()->getPlayer().setDrawState(MWMechanics::DrawState::Spell); } else if (key->type == Type_HandToHand) @@ -451,7 +451,7 @@ namespace MWGui // --------------------------------------------------------------------------------------------------------- - QuickKeysMenuAssign::QuickKeysMenuAssign (QuickKeysMenu* parent) + QuickKeysMenuAssign::QuickKeysMenuAssign(QuickKeysMenu* parent) : WindowModal("openmw_quickkeys_menu_assign.layout") , mParent(parent) { @@ -466,44 +466,35 @@ namespace MWGui mUnassignButton->eventMouseButtonClick += MyGUI::newDelegate(mParent, &QuickKeysMenu::onUnassignButtonClicked); mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(mParent, &QuickKeysMenu::onCancelButtonClicked); - - int maxWidth = mLabel->getTextSize ().width + 24; - maxWidth = std::max(maxWidth, mItemButton->getTextSize ().width + 24); - maxWidth = std::max(maxWidth, mMagicButton->getTextSize ().width + 24); - maxWidth = std::max(maxWidth, mUnassignButton->getTextSize ().width + 24); - maxWidth = std::max(maxWidth, mCancelButton->getTextSize ().width + 24); + int maxWidth = mLabel->getTextSize().width + 24; + maxWidth = std::max(maxWidth, mItemButton->getTextSize().width + 24); + maxWidth = std::max(maxWidth, mMagicButton->getTextSize().width + 24); + maxWidth = std::max(maxWidth, mUnassignButton->getTextSize().width + 24); + maxWidth = std::max(maxWidth, mCancelButton->getTextSize().width + 24); mMainWidget->setSize(maxWidth + 24, mMainWidget->getHeight()); mLabel->setSize(maxWidth, mLabel->getHeight()); - mItemButton->setCoord((maxWidth - mItemButton->getTextSize().width-24)/2 + 8, - mItemButton->getTop(), - mItemButton->getTextSize().width + 24, - mItemButton->getHeight()); - mMagicButton->setCoord((maxWidth - mMagicButton->getTextSize().width-24)/2 + 8, - mMagicButton->getTop(), - mMagicButton->getTextSize().width + 24, - mMagicButton->getHeight()); - mUnassignButton->setCoord((maxWidth - mUnassignButton->getTextSize().width-24)/2 + 8, - mUnassignButton->getTop(), - mUnassignButton->getTextSize().width + 24, - mUnassignButton->getHeight()); - mCancelButton->setCoord((maxWidth - mCancelButton->getTextSize().width-24)/2 + 8, - mCancelButton->getTop(), - mCancelButton->getTextSize().width + 24, - mCancelButton->getHeight()); + mItemButton->setCoord((maxWidth - mItemButton->getTextSize().width - 24) / 2 + 8, mItemButton->getTop(), + mItemButton->getTextSize().width + 24, mItemButton->getHeight()); + mMagicButton->setCoord((maxWidth - mMagicButton->getTextSize().width - 24) / 2 + 8, mMagicButton->getTop(), + mMagicButton->getTextSize().width + 24, mMagicButton->getHeight()); + mUnassignButton->setCoord((maxWidth - mUnassignButton->getTextSize().width - 24) / 2 + 8, + mUnassignButton->getTop(), mUnassignButton->getTextSize().width + 24, mUnassignButton->getHeight()); + mCancelButton->setCoord((maxWidth - mCancelButton->getTextSize().width - 24) / 2 + 8, mCancelButton->getTop(), + mCancelButton->getTextSize().width + 24, mCancelButton->getHeight()); center(); } - void QuickKeysMenu::write(ESM::ESMWriter &writer) + void QuickKeysMenu::write(ESM::ESMWriter& writer) { writer.startRecord(ESM::REC_KEYS); ESM::QuickKeys keys; // NB: The quick key with index 9 always has Hand-to-Hand type and must not be saved - for (int i=0; i<9; ++i) + for (int i = 0; i < 9; ++i) { ItemWidget* button = mKey[i].button; @@ -537,7 +528,7 @@ namespace MWGui writer.endRecord(ESM::REC_KEYS); } - void QuickKeysMenu::readRecord(ESM::ESMReader &reader, uint32_t type) + void QuickKeysMenu::readRecord(ESM::ESMReader& reader, uint32_t type) { if (type != ESM::REC_KEYS) return; @@ -548,7 +539,7 @@ namespace MWGui MWWorld::Ptr player = MWMechanics::getPlayer(); MWWorld::InventoryStore& store = player.getClass().getInventoryStore(player); - int i=0; + int i = 0; for (ESM::QuickKeys::QuickKey& quickKey : keys.mKeys) { // NB: The quick key with index 9 always has Hand-to-Hand type and must not be loaded @@ -559,32 +550,32 @@ namespace MWGui switch (quickKey.mType) { - case Type_Magic: - if (MWBase::Environment::get().getWorld()->getStore().get().search(quickKey.mId)) - onAssignMagic(quickKey.mId); - break; - case Type_Item: - case Type_MagicItem: - { - // Find the item by id - MWWorld::Ptr item = store.findReplacement(quickKey.mId); - - if (item.isEmpty()) - unassign(mSelected); - else + case Type_Magic: + if (MWBase::Environment::get().getWorld()->getStore().get().search(quickKey.mId)) + onAssignMagic(quickKey.mId); + break; + case Type_Item: + case Type_MagicItem: { - if (quickKey.mType == Type_Item) - onAssignItem(item); - else // if (quickKey.mType == Type_MagicItem) - onAssignMagicItem(item); - } + // Find the item by id + MWWorld::Ptr item = store.findReplacement(quickKey.mId); + + if (item.isEmpty()) + unassign(mSelected); + else + { + if (quickKey.mType == Type_Item) + onAssignItem(item); + else // if (quickKey.mType == Type_MagicItem) + onAssignMagicItem(item); + } - break; - } - case Type_Unassigned: - case Type_HandToHand: - unassign(mSelected); - break; + break; + } + case Type_Unassigned: + case Type_HandToHand: + unassign(mSelected); + break; } ++i; @@ -608,7 +599,7 @@ namespace MWGui center(); } - void MagicSelectionDialog::onCancelButtonClicked (MyGUI::Widget *sender) + void MagicSelectionDialog::onCancelButtonClicked(MyGUI::Widget* sender) { exit(); } @@ -619,7 +610,7 @@ namespace MWGui return true; } - void MagicSelectionDialog::onOpen () + void MagicSelectionDialog::onOpen() { WindowModal::onOpen(); diff --git a/apps/openmw/mwgui/quickkeysmenu.hpp b/apps/openmw/mwgui/quickkeysmenu.hpp index 2c28bfee61..affffd5bd4 100644 --- a/apps/openmw/mwgui/quickkeysmenu.hpp +++ b/apps/openmw/mwgui/quickkeysmenu.hpp @@ -27,11 +27,11 @@ namespace MWGui void onUnassignButtonClicked(MyGUI::Widget* sender); void onCancelButtonClicked(MyGUI::Widget* sender); - void onAssignItem (MWWorld::Ptr item); - void onAssignItemCancel (); - void onAssignMagicItem (MWWorld::Ptr item); - void onAssignMagic (const std::string& spellId); - void onAssignMagicCancel (); + void onAssignItem(MWWorld::Ptr item); + void onAssignItemCancel(); + void onAssignMagicItem(MWWorld::Ptr item); + void onAssignMagic(const std::string& spellId); + void onAssignMagicCancel(); void onOpen() override; void onClose() override; @@ -48,20 +48,26 @@ namespace MWGui Type_HandToHand }; - void write (ESM::ESMWriter& writer); - void readRecord (ESM::ESMReader& reader, uint32_t type); + void write(ESM::ESMWriter& writer); + void readRecord(ESM::ESMReader& reader, uint32_t type); void clear() override; - private: - - struct keyData { + struct keyData + { int index; ItemWidget* button; QuickKeysMenu::QuickKeyType type; std::string id; std::string name; - keyData(): index(-1), button(nullptr), type(Type_Unassigned), id(""), name("") {} + keyData() + : index(-1) + , button(nullptr) + , type(Type_Unassigned) + , id("") + , name("") + { + } }; std::vector mKey; @@ -111,10 +117,9 @@ namespace MWGui QuickKeysMenu* mParent; - void onCancelButtonClicked (MyGUI::Widget* sender); + void onCancelButtonClicked(MyGUI::Widget* sender); void onModelIndexSelected(SpellModel::ModelIndex index); }; } - #endif diff --git a/apps/openmw/mwgui/race.cpp b/apps/openmw/mwgui/race.cpp index f9d261a272..e52161d442 100644 --- a/apps/openmw/mwgui/race.cpp +++ b/apps/openmw/mwgui/race.cpp @@ -1,8 +1,8 @@ #include "race.hpp" -#include -#include #include +#include +#include #include #include @@ -13,11 +13,11 @@ #include #include -#include "../mwworld/esmstore.hpp" #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" #include "../mwrender/characterpreview.hpp" +#include "../mwworld/esmstore.hpp" #include "tooltips.hpp" #include "ustring.hpp" @@ -45,19 +45,20 @@ namespace MWGui { RaceDialog::RaceDialog(osg::Group* parent, Resource::ResourceSystem* resourceSystem) - : WindowModal("openmw_chargen_race.layout") - , mParent(parent) - , mResourceSystem(resourceSystem) - , mGenderIndex(0) - , mFaceIndex(0) - , mHairIndex(0) - , mCurrentAngle(0) - , mPreviewDirty(true) + : WindowModal("openmw_chargen_race.layout") + , mParent(parent) + , mResourceSystem(resourceSystem) + , mGenderIndex(0) + , mFaceIndex(0) + , mHairIndex(0) + , mCurrentAngle(0) + , mPreviewDirty(true) { // Centre dialog center(); - setText("AppearanceT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sRaceMenu1", "Appearance")); + setText("AppearanceT", + MWBase::Environment::get().getWindowManager()->getGameSettingString("sRaceMenu1", "Appearance")); getWidget(mPreviewImage, "PreviewImage"); mPreviewImage->eventMouseWheel += MyGUI::newDelegate(this, &RaceDialog::onPreviewScroll); @@ -74,19 +75,22 @@ namespace MWGui // Set up next/previous buttons MyGUI::Button *prevButton, *nextButton; - setText("GenderChoiceT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sRaceMenu2", "Change Sex")); + setText("GenderChoiceT", + MWBase::Environment::get().getWindowManager()->getGameSettingString("sRaceMenu2", "Change Sex")); getWidget(prevButton, "PrevGenderButton"); getWidget(nextButton, "NextGenderButton"); prevButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousGender); nextButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectNextGender); - setText("FaceChoiceT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sRaceMenu3", "Change Face")); + setText("FaceChoiceT", + MWBase::Environment::get().getWindowManager()->getGameSettingString("sRaceMenu3", "Change Face")); getWidget(prevButton, "PrevFaceButton"); getWidget(nextButton, "NextFaceButton"); prevButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousFace); nextButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectNextFace); - setText("HairChoiceT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sRaceMenu4", "Change Hair")); + setText("HairChoiceT", + MWBase::Environment::get().getWindowManager()->getGameSettingString("sRaceMenu4", "Change Hair")); getWidget(prevButton, "PrevHairButton"); getWidget(nextButton, "NextHairButton"); prevButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousHair); @@ -98,9 +102,11 @@ namespace MWGui mRaceList->eventListSelectAccept += MyGUI::newDelegate(this, &RaceDialog::onAccept); mRaceList->eventListChangePosition += MyGUI::newDelegate(this, &RaceDialog::onSelectRace); - setText("SkillsT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sBonusSkillTitle", "Skill Bonus")); + setText("SkillsT", + MWBase::Environment::get().getWindowManager()->getGameSettingString("sBonusSkillTitle", "Skill Bonus")); getWidget(mSkillList, "SkillList"); - setText("SpellPowerT", MWBase::Environment::get().getWindowManager()->getGameSettingString("sRaceMenu7", "Specials")); + setText("SpellPowerT", + MWBase::Environment::get().getWindowManager()->getGameSettingString("sRaceMenu7", "Specials")); getWidget(mSpellPowerList, "SpellPowerList"); MyGUI::Button* backButton; @@ -123,9 +129,11 @@ namespace MWGui getWidget(okButton, "OKButton"); if (shown) - okButton->setCaption(toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString("sNext", {}))); + okButton->setCaption( + toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString("sNext", {}))); else - okButton->setCaption(toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", {}))); + okButton->setCaption( + toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", {}))); } void RaceDialog::onOpen() @@ -143,9 +151,10 @@ namespace MWGui mPreview = std::make_unique(mParent, mResourceSystem); mPreview->rebuild(); - mPreview->setAngle (mCurrentAngle); + mPreview->setAngle(mCurrentAngle); - mPreviewTexture = std::make_unique(mPreview->getTexture(), mPreview->getTextureStateSet()); + mPreviewTexture + = std::make_unique(mPreview->getTexture(), mPreview->getTextureStateSet()); mPreviewImage->setRenderItemTexture(mPreviewTexture.get()); mPreviewImage->getSubWidgetMain()->_setUVSet(MyGUI::FloatRect(0.f, 0.f, 1.f, 1.f)); @@ -154,13 +163,13 @@ namespace MWGui setGender(proto.isMale() ? GM_Male : GM_Female); recountParts(); - for (unsigned int i=0; igetScrollRange()/2+mHeadRotate->getScrollRange()/10; + size_t initialPos = mHeadRotate->getScrollRange() / 2 + mHeadRotate->getScrollRange() / 10; mHeadRotate->setScrollPosition(initialPos); onHeadRotate(mHeadRotate, initialPos); MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mRaceList); } - void RaceDialog::setRaceId(const std::string &raceId) + void RaceDialog::setRaceId(const std::string& raceId) { mCurrentRaceId = raceId; mRaceList->setIndexSelected(MyGUI::ITEM_NONE); @@ -207,7 +216,7 @@ namespace MWGui void RaceDialog::onOkClicked(MyGUI::Widget* _sender) { - if(mRaceList->getIndexSelected() == MyGUI::ITEM_NONE) + if (mRaceList->getIndexSelected() == MyGUI::ITEM_NONE) return; eventDone(this); } @@ -232,8 +241,8 @@ namespace MWGui void RaceDialog::onHeadRotate(MyGUI::ScrollBar* scroll, size_t _position) { - float angle = (float(_position) / (scroll->getScrollRange()-1) - 0.5f) * osg::PI * 2; - mPreview->setAngle (angle); + float angle = (float(_position) / (scroll->getScrollRange() - 1) - 0.5f) * osg::PI * 2; + mPreview->setAngle(angle); mCurrentAngle = angle; } @@ -283,7 +292,7 @@ namespace MWGui if (_index == MyGUI::ITEM_NONE) return; - const std::string *raceId = mRaceList->getItemDataAt(_index); + const std::string* raceId = mRaceList->getItemDataAt(_index); if (Misc::StringUtils::ciEqual(mCurrentRaceId, *raceId)) return; @@ -296,19 +305,19 @@ namespace MWGui updateSpellPowers(); } - void RaceDialog::onAccept(MyGUI::ListBox *_sender, size_t _index) + void RaceDialog::onAccept(MyGUI::ListBox* _sender, size_t _index) { onSelectRace(_sender, _index); - if(mRaceList->getIndexSelected() == MyGUI::ITEM_NONE) + if (mRaceList->getIndexSelected() == MyGUI::ITEM_NONE) return; eventDone(this); } - void RaceDialog::getBodyParts (int part, std::vector& out) + void RaceDialog::getBodyParts(int part, std::vector& out) { out.clear(); - const MWWorld::Store &store = - MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& store + = MWBase::Environment::get().getWorld()->getStore().get(); for (const ESM::BodyPart& bodypart : store) { @@ -320,10 +329,8 @@ namespace MWGui continue; if (mGenderIndex != (bodypart.mData.mFlags & ESM::BodyPart::BPF_Female)) continue; - bool firstPerson = (bodypart.mId.size() >= 3) - && bodypart.mId[bodypart.mId.size()-3] == '1' - && bodypart.mId[bodypart.mId.size()-2] == 's' - && bodypart.mId[bodypart.mId.size()-1] == 't'; + bool firstPerson = (bodypart.mId.size() >= 3) && bodypart.mId[bodypart.mId.size() - 3] == '1' + && bodypart.mId[bodypart.mId.size() - 2] == 's' && bodypart.mId[bodypart.mId.size() - 1] == 't'; if (firstPerson) continue; if (Misc::StringUtils::ciEqual(bodypart.mRace, mCurrentRaceId)) @@ -368,10 +375,9 @@ namespace MWGui { mRaceList->removeAllItems(); - const MWWorld::Store &races = - MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& races = MWBase::Environment::get().getWorld()->getStore().get(); - std::vector > items; // ID, name + std::vector> items; // ID, name for (const ESM::Race& race : races) { bool playable = race.mData.mFlags & ESM::Race::Playable; @@ -407,22 +413,23 @@ namespace MWGui const int lineHeight = MWBase::Environment::get().getWindowManager()->getFontHeight() + 2; MyGUI::IntCoord coord1(0, 0, mSkillList->getWidth(), 18); - const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); - const ESM::Race *race = store.get().find(mCurrentRaceId); - int count = sizeof(race->mData.mBonus)/sizeof(race->mData.mBonus[0]); // TODO: Find a portable macro for this ARRAYSIZE? + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + const ESM::Race* race = store.get().find(mCurrentRaceId); + int count = sizeof(race->mData.mBonus) + / sizeof(race->mData.mBonus[0]); // TODO: Find a portable macro for this ARRAYSIZE? for (int i = 0; i < count; ++i) { int skillId = race->mData.mBonus[i].mSkill; if (skillId < 0 || skillId > ESM::Skill::Length) // Skip unknown skill indexes continue; - skillWidget = mSkillList->createWidget("MW_StatNameValue", coord1, MyGUI::Align::Default, - std::string("Skill") + MyGUI::utility::toString(i)); + skillWidget = mSkillList->createWidget( + "MW_StatNameValue", coord1, MyGUI::Align::Default, std::string("Skill") + MyGUI::utility::toString(i)); skillWidget->setSkillNumber(skillId); - skillWidget->setSkillValue(Widgets::MWSkill::SkillValue(static_cast(race->mData.mBonus[i].mBonus), 0.f)); + skillWidget->setSkillValue( + Widgets::MWSkill::SkillValue(static_cast(race->mData.mBonus[i].mBonus), 0.f)); ToolTips::createSkillToolTip(skillWidget, skillId); - mSkillItems.push_back(skillWidget); coord1.top += lineHeight; @@ -443,13 +450,14 @@ namespace MWGui const int lineHeight = MWBase::Environment::get().getWindowManager()->getFontHeight() + 2; MyGUI::IntCoord coord(0, 0, mSpellPowerList->getWidth(), lineHeight); - const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); - const ESM::Race *race = store.get().find(mCurrentRaceId); + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + const ESM::Race* race = store.get().find(mCurrentRaceId); int i = 0; for (const std::string& spellpower : race->mPowers.mList) { - Widgets::MWSpellPtr spellPowerWidget = mSpellPowerList->createWidget("MW_StatName", coord, MyGUI::Align::Default, std::string("SpellPower") + MyGUI::utility::toString(i)); + Widgets::MWSpellPtr spellPowerWidget = mSpellPowerList->createWidget( + "MW_StatName", coord, MyGUI::Align::Default, std::string("SpellPower") + MyGUI::utility::toString(i)); spellPowerWidget->setSpellId(spellpower); spellPowerWidget->setUserString("ToolTipType", "Spell"); spellPowerWidget->setUserString("Spell", spellpower); diff --git a/apps/openmw/mwgui/race.hpp b/apps/openmw/mwgui/race.hpp index e48ca28162..3a6966cb7c 100644 --- a/apps/openmw/mwgui/race.hpp +++ b/apps/openmw/mwgui/race.hpp @@ -5,7 +5,6 @@ #include "windowbase.hpp" - namespace MWRender { class RaceSelectionPreview; @@ -39,11 +38,11 @@ namespace MWGui GM_Female }; - const ESM::NPC &getResult() const; - const std::string &getRaceId() const { return mCurrentRaceId; } + const ESM::NPC& getResult() const; + const std::string& getRaceId() const { return mCurrentRaceId; } Gender getGender() const { return mGenderIndex == 0 ? GM_Male : GM_Female; } - void setRaceId(const std::string &raceId); + void setRaceId(const std::string& raceId); void setGender(Gender gender) { mGenderIndex = gender == GM_Male ? 0 : 1; } void setNextButtonShow(bool shown); @@ -91,7 +90,7 @@ namespace MWGui void updatePreview(); void recountParts(); - void getBodyParts (int part, std::vector& out); + void getBodyParts(int part, std::vector& out); osg::Group* mParent; Resource::ResourceSystem* mResourceSystem; @@ -99,8 +98,8 @@ namespace MWGui std::vector mAvailableHeads; std::vector mAvailableHairs; - MyGUI::ImageBox* mPreviewImage; - MyGUI::ListBox* mRaceList; + MyGUI::ImageBox* mPreviewImage; + MyGUI::ListBox* mRaceList; MyGUI::ScrollBar* mHeadRotate; MyGUI::Widget* mSkillList; diff --git a/apps/openmw/mwgui/recharge.cpp b/apps/openmw/mwgui/recharge.cpp index 46fb64780e..8fc0328a0b 100644 --- a/apps/openmw/mwgui/recharge.cpp +++ b/apps/openmw/mwgui/recharge.cpp @@ -8,132 +8,134 @@ #include -#include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" -#include "../mwworld/containerstore.hpp" #include "../mwworld/class.hpp" +#include "../mwworld/containerstore.hpp" #include "../mwworld/esmstore.hpp" #include "../mwmechanics/actorutil.hpp" #include "../mwmechanics/recharge.hpp" +#include "inventoryitemmodel.hpp" +#include "itemchargeview.hpp" #include "itemselection.hpp" #include "itemwidget.hpp" -#include "itemchargeview.hpp" #include "sortfilteritemmodel.hpp" -#include "inventoryitemmodel.hpp" namespace MWGui { -Recharge::Recharge() - : WindowBase("openmw_recharge_dialog.layout") -{ - getWidget(mBox, "Box"); - getWidget(mGemBox, "GemBox"); - getWidget(mGemIcon, "GemIcon"); - getWidget(mChargeLabel, "ChargeLabel"); - getWidget(mCancelButton, "CancelButton"); + Recharge::Recharge() + : WindowBase("openmw_recharge_dialog.layout") + { + getWidget(mBox, "Box"); + getWidget(mGemBox, "GemBox"); + getWidget(mGemIcon, "GemIcon"); + getWidget(mChargeLabel, "ChargeLabel"); + getWidget(mCancelButton, "CancelButton"); - mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &Recharge::onCancel); - mBox->eventItemClicked += MyGUI::newDelegate(this, &Recharge::onItemClicked); + mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &Recharge::onCancel); + mBox->eventItemClicked += MyGUI::newDelegate(this, &Recharge::onItemClicked); - mBox->setDisplayMode(ItemChargeView::DisplayMode_EnchantmentCharge); + mBox->setDisplayMode(ItemChargeView::DisplayMode_EnchantmentCharge); - mGemIcon->eventMouseButtonClick += MyGUI::newDelegate(this, &Recharge::onSelectItem); -} + mGemIcon->eventMouseButtonClick += MyGUI::newDelegate(this, &Recharge::onSelectItem); + } -void Recharge::onOpen() -{ - center(); + void Recharge::onOpen() + { + center(); - SortFilterItemModel * model = new SortFilterItemModel(std::make_unique(MWMechanics::getPlayer())); - model->setFilter(SortFilterItemModel::Filter_OnlyRechargable); - mBox->setModel(model); + SortFilterItemModel* model + = new SortFilterItemModel(std::make_unique(MWMechanics::getPlayer())); + model->setFilter(SortFilterItemModel::Filter_OnlyRechargable); + mBox->setModel(model); - // Reset scrollbars - mBox->resetScrollbars(); -} + // Reset scrollbars + mBox->resetScrollbars(); + } -void Recharge::setPtr (const MWWorld::Ptr &item) -{ - mGemIcon->setItem(item); - mGemIcon->setUserString("ToolTipType", "ItemPtr"); - mGemIcon->setUserData(MWWorld::Ptr(item)); + void Recharge::setPtr(const MWWorld::Ptr& item) + { + mGemIcon->setItem(item); + mGemIcon->setUserString("ToolTipType", "ItemPtr"); + mGemIcon->setUserData(MWWorld::Ptr(item)); - updateView(); -} + updateView(); + } -void Recharge::updateView() -{ - MWWorld::Ptr gem = *mGemIcon->getUserData(); + void Recharge::updateView() + { + MWWorld::Ptr gem = *mGemIcon->getUserData(); - const std::string& soul = gem.getCellRef().getSoul(); - const ESM::Creature *creature = MWBase::Environment::get().getWorld()->getStore().get().find(soul); + const std::string& soul = gem.getCellRef().getSoul(); + const ESM::Creature* creature + = MWBase::Environment::get().getWorld()->getStore().get().find(soul); - mChargeLabel->setCaptionWithReplacing("#{sCharges} " + MyGUI::utility::toString(creature->mData.mSoul)); + mChargeLabel->setCaptionWithReplacing("#{sCharges} " + MyGUI::utility::toString(creature->mData.mSoul)); - bool toolBoxVisible = (gem.getRefData().getCount() != 0); - mGemBox->setVisible(toolBoxVisible); - mGemBox->setUserString("Hidden", toolBoxVisible ? "false" : "true"); + bool toolBoxVisible = (gem.getRefData().getCount() != 0); + mGemBox->setVisible(toolBoxVisible); + mGemBox->setUserString("Hidden", toolBoxVisible ? "false" : "true"); - if (!toolBoxVisible) - { - mGemIcon->setItem(MWWorld::Ptr()); - mGemIcon->clearUserStrings(); - } + if (!toolBoxVisible) + { + mGemIcon->setItem(MWWorld::Ptr()); + mGemIcon->clearUserStrings(); + } - mBox->update(); + mBox->update(); - Gui::Box* box = dynamic_cast(mMainWidget); - if (box == nullptr) - throw std::runtime_error("main widget must be a box"); + Gui::Box* box = dynamic_cast(mMainWidget); + if (box == nullptr) + throw std::runtime_error("main widget must be a box"); - box->notifyChildrenSizeChanged(); - center(); -} + box->notifyChildrenSizeChanged(); + center(); + } -void Recharge::onCancel(MyGUI::Widget *sender) -{ - MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Recharge); -} + void Recharge::onCancel(MyGUI::Widget* sender) + { + MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Recharge); + } -void Recharge::onSelectItem(MyGUI::Widget *sender) -{ - mItemSelectionDialog = std::make_unique("#{sSoulGemsWithSouls}"); - mItemSelectionDialog->eventItemSelected += MyGUI::newDelegate(this, &Recharge::onItemSelected); - mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &Recharge::onItemCancel); - mItemSelectionDialog->setVisible(true); - mItemSelectionDialog->openContainer(MWMechanics::getPlayer()); - mItemSelectionDialog->setFilter(SortFilterItemModel::Filter_OnlyChargedSoulstones); -} + void Recharge::onSelectItem(MyGUI::Widget* sender) + { + mItemSelectionDialog = std::make_unique("#{sSoulGemsWithSouls}"); + mItemSelectionDialog->eventItemSelected += MyGUI::newDelegate(this, &Recharge::onItemSelected); + mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &Recharge::onItemCancel); + mItemSelectionDialog->setVisible(true); + mItemSelectionDialog->openContainer(MWMechanics::getPlayer()); + mItemSelectionDialog->setFilter(SortFilterItemModel::Filter_OnlyChargedSoulstones); + } -void Recharge::onItemSelected(MWWorld::Ptr item) -{ - mItemSelectionDialog->setVisible(false); + void Recharge::onItemSelected(MWWorld::Ptr item) + { + mItemSelectionDialog->setVisible(false); - mGemIcon->setItem(item); - mGemIcon->setUserString ("ToolTipType", "ItemPtr"); - mGemIcon->setUserData(item); + mGemIcon->setItem(item); + mGemIcon->setUserString("ToolTipType", "ItemPtr"); + mGemIcon->setUserData(item); - MWBase::Environment::get().getWindowManager()->playSound(item.getClass().getDownSoundId(item)); - updateView(); -} + MWBase::Environment::get().getWindowManager()->playSound(item.getClass().getDownSoundId(item)); + updateView(); + } -void Recharge::onItemCancel() -{ - mItemSelectionDialog->setVisible(false); -} + void Recharge::onItemCancel() + { + mItemSelectionDialog->setVisible(false); + } -void Recharge::onItemClicked(MyGUI::Widget *sender, const MWWorld::Ptr& item) -{ - MWWorld::Ptr gem = *mGemIcon->getUserData(); - if (!MWMechanics::rechargeItem(item, gem)) - return; + void Recharge::onItemClicked(MyGUI::Widget* sender, const MWWorld::Ptr& item) + { + MWWorld::Ptr gem = *mGemIcon->getUserData(); + if (!MWMechanics::rechargeItem(item, gem)) + return; - updateView(); -} + updateView(); + } } diff --git a/apps/openmw/mwgui/recharge.hpp b/apps/openmw/mwgui/recharge.hpp index 76852f3052..f7afde4571 100644 --- a/apps/openmw/mwgui/recharge.hpp +++ b/apps/openmw/mwgui/recharge.hpp @@ -13,44 +13,43 @@ namespace MWWorld namespace MWGui { -class ItemSelectionDialog; -class ItemWidget; -class ItemChargeView; + class ItemSelectionDialog; + class ItemWidget; + class ItemChargeView; -class Recharge : public WindowBase -{ -public: - Recharge(); - - void onOpen() override; + class Recharge : public WindowBase + { + public: + Recharge(); - void setPtr (const MWWorld::Ptr& gem) override; + void onOpen() override; -protected: - ItemChargeView* mBox; + void setPtr(const MWWorld::Ptr& gem) override; - MyGUI::Widget* mGemBox; + protected: + ItemChargeView* mBox; - ItemWidget* mGemIcon; + MyGUI::Widget* mGemBox; - std::unique_ptr mItemSelectionDialog; + ItemWidget* mGemIcon; - MyGUI::TextBox* mChargeLabel; + std::unique_ptr mItemSelectionDialog; - MyGUI::Button* mCancelButton; + MyGUI::TextBox* mChargeLabel; - void updateView(); + MyGUI::Button* mCancelButton; - void onSelectItem(MyGUI::Widget* sender); + void updateView(); - void onItemSelected(MWWorld::Ptr item); - void onItemCancel(); + void onSelectItem(MyGUI::Widget* sender); - void onItemClicked (MyGUI::Widget* sender, const MWWorld::Ptr& item); - void onCancel (MyGUI::Widget* sender); - void onMouseWheel(MyGUI::Widget* _sender, int _rel); + void onItemSelected(MWWorld::Ptr item); + void onItemCancel(); -}; + void onItemClicked(MyGUI::Widget* sender, const MWWorld::Ptr& item); + void onCancel(MyGUI::Widget* sender); + void onMouseWheel(MyGUI::Widget* _sender, int _rel); + }; } diff --git a/apps/openmw/mwgui/referenceinterface.cpp b/apps/openmw/mwgui/referenceinterface.cpp index 83221c4f4b..de7c93d862 100644 --- a/apps/openmw/mwgui/referenceinterface.cpp +++ b/apps/openmw/mwgui/referenceinterface.cpp @@ -2,13 +2,9 @@ namespace MWGui { - ReferenceInterface::ReferenceInterface() - { - } + ReferenceInterface::ReferenceInterface() {} - ReferenceInterface::~ReferenceInterface() - { - } + ReferenceInterface::~ReferenceInterface() {} void ReferenceInterface::checkReferenceAvailable() { diff --git a/apps/openmw/mwgui/referenceinterface.hpp b/apps/openmw/mwgui/referenceinterface.hpp index 6428a5b540..e8b60693e4 100644 --- a/apps/openmw/mwgui/referenceinterface.hpp +++ b/apps/openmw/mwgui/referenceinterface.hpp @@ -8,7 +8,8 @@ namespace MWGui /// \brief this class is intended for GUI interfaces that access an MW-Reference /// for example dialogue window accesses an NPC, or Container window accesses a Container /// these classes have to be automatically closed if the reference becomes unavailable - /// make sure that checkReferenceAvailable() is called every frame and that onReferenceUnavailable() has been overridden + /// make sure that checkReferenceAvailable() is called every frame and that onReferenceUnavailable() has been + /// overridden class ReferenceInterface { public: diff --git a/apps/openmw/mwgui/repair.cpp b/apps/openmw/mwgui/repair.cpp index 9917e03f9b..e91435b0d1 100644 --- a/apps/openmw/mwgui/repair.cpp +++ b/apps/openmw/mwgui/repair.cpp @@ -6,146 +6,146 @@ #include -#include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" #include "../mwmechanics/actorutil.hpp" -#include "../mwworld/containerstore.hpp" #include "../mwworld/class.hpp" +#include "../mwworld/containerstore.hpp" +#include "inventoryitemmodel.hpp" +#include "itemchargeview.hpp" #include "itemselection.hpp" #include "itemwidget.hpp" -#include "itemchargeview.hpp" #include "sortfilteritemmodel.hpp" -#include "inventoryitemmodel.hpp" namespace MWGui { -Repair::Repair() - : WindowBase("openmw_repair.layout") -{ - getWidget(mRepairBox, "RepairBox"); - getWidget(mToolBox, "ToolBox"); - getWidget(mToolIcon, "ToolIcon"); - getWidget(mUsesLabel, "UsesLabel"); - getWidget(mQualityLabel, "QualityLabel"); - getWidget(mCancelButton, "CancelButton"); + Repair::Repair() + : WindowBase("openmw_repair.layout") + { + getWidget(mRepairBox, "RepairBox"); + getWidget(mToolBox, "ToolBox"); + getWidget(mToolIcon, "ToolIcon"); + getWidget(mUsesLabel, "UsesLabel"); + getWidget(mQualityLabel, "QualityLabel"); + getWidget(mCancelButton, "CancelButton"); - mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &Repair::onCancel); + mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &Repair::onCancel); - mRepairBox->eventItemClicked += MyGUI::newDelegate(this, &Repair::onRepairItem); - mRepairBox->setDisplayMode(ItemChargeView::DisplayMode_Health); + mRepairBox->eventItemClicked += MyGUI::newDelegate(this, &Repair::onRepairItem); + mRepairBox->setDisplayMode(ItemChargeView::DisplayMode_Health); - mToolIcon->eventMouseButtonClick += MyGUI::newDelegate(this, &Repair::onSelectItem); -} + mToolIcon->eventMouseButtonClick += MyGUI::newDelegate(this, &Repair::onSelectItem); + } -void Repair::onOpen() -{ - center(); + void Repair::onOpen() + { + center(); - SortFilterItemModel * model = new SortFilterItemModel(std::make_unique(MWMechanics::getPlayer())); - model->setFilter(SortFilterItemModel::Filter_OnlyRepairable); - mRepairBox->setModel(model); + SortFilterItemModel* model + = new SortFilterItemModel(std::make_unique(MWMechanics::getPlayer())); + model->setFilter(SortFilterItemModel::Filter_OnlyRepairable); + mRepairBox->setModel(model); - // Reset scrollbars - mRepairBox->resetScrollbars(); -} + // Reset scrollbars + mRepairBox->resetScrollbars(); + } -void Repair::setPtr(const MWWorld::Ptr &item) -{ - MWBase::Environment::get().getWindowManager()->playSound("Item Repair Up"); + void Repair::setPtr(const MWWorld::Ptr& item) + { + MWBase::Environment::get().getWindowManager()->playSound("Item Repair Up"); - mRepair.setTool(item); + mRepair.setTool(item); - mToolIcon->setItem(item); - mToolIcon->setUserString("ToolTipType", "ItemPtr"); - mToolIcon->setUserData(MWWorld::Ptr(item)); + mToolIcon->setItem(item); + mToolIcon->setUserString("ToolTipType", "ItemPtr"); + mToolIcon->setUserData(MWWorld::Ptr(item)); - updateRepairView(); -} + updateRepairView(); + } -void Repair::updateRepairView() -{ - MWWorld::LiveCellRef *ref = - mRepair.getTool().get(); + void Repair::updateRepairView() + { + MWWorld::LiveCellRef* ref = mRepair.getTool().get(); - int uses = mRepair.getTool().getClass().getItemHealth(mRepair.getTool()); + int uses = mRepair.getTool().getClass().getItemHealth(mRepair.getTool()); - float quality = ref->mBase->mData.mQuality; + float quality = ref->mBase->mData.mQuality; - mToolIcon->setUserData(mRepair.getTool()); + mToolIcon->setUserData(mRepair.getTool()); - std::stringstream qualityStr; - qualityStr << std::setprecision(3) << quality; + std::stringstream qualityStr; + qualityStr << std::setprecision(3) << quality; - mUsesLabel->setCaptionWithReplacing("#{sUses} " + MyGUI::utility::toString(uses)); - mQualityLabel->setCaptionWithReplacing("#{sQuality} " + qualityStr.str()); + mUsesLabel->setCaptionWithReplacing("#{sUses} " + MyGUI::utility::toString(uses)); + mQualityLabel->setCaptionWithReplacing("#{sQuality} " + qualityStr.str()); - bool toolBoxVisible = (mRepair.getTool().getRefData().getCount() != 0); - mToolBox->setVisible(toolBoxVisible); - mToolBox->setUserString("Hidden", toolBoxVisible ? "false" : "true"); + bool toolBoxVisible = (mRepair.getTool().getRefData().getCount() != 0); + mToolBox->setVisible(toolBoxVisible); + mToolBox->setUserString("Hidden", toolBoxVisible ? "false" : "true"); - if (!toolBoxVisible) - { - mToolIcon->setItem(MWWorld::Ptr()); - mToolIcon->clearUserStrings(); - } + if (!toolBoxVisible) + { + mToolIcon->setItem(MWWorld::Ptr()); + mToolIcon->clearUserStrings(); + } - mRepairBox->update(); + mRepairBox->update(); - Gui::Box* box = dynamic_cast(mMainWidget); - if (box == nullptr) - throw std::runtime_error("main widget must be a box"); + Gui::Box* box = dynamic_cast(mMainWidget); + if (box == nullptr) + throw std::runtime_error("main widget must be a box"); - box->notifyChildrenSizeChanged(); - center(); -} + box->notifyChildrenSizeChanged(); + center(); + } -void Repair::onSelectItem(MyGUI::Widget *sender) -{ - mItemSelectionDialog = std::make_unique("#{sRepair}"); - mItemSelectionDialog->eventItemSelected += MyGUI::newDelegate(this, &Repair::onItemSelected); - mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &Repair::onItemCancel); - mItemSelectionDialog->setVisible(true); - mItemSelectionDialog->openContainer(MWMechanics::getPlayer()); - mItemSelectionDialog->setFilter(SortFilterItemModel::Filter_OnlyRepairTools); -} + void Repair::onSelectItem(MyGUI::Widget* sender) + { + mItemSelectionDialog = std::make_unique("#{sRepair}"); + mItemSelectionDialog->eventItemSelected += MyGUI::newDelegate(this, &Repair::onItemSelected); + mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &Repair::onItemCancel); + mItemSelectionDialog->setVisible(true); + mItemSelectionDialog->openContainer(MWMechanics::getPlayer()); + mItemSelectionDialog->setFilter(SortFilterItemModel::Filter_OnlyRepairTools); + } -void Repair::onItemSelected(MWWorld::Ptr item) -{ - mItemSelectionDialog->setVisible(false); + void Repair::onItemSelected(MWWorld::Ptr item) + { + mItemSelectionDialog->setVisible(false); - mToolIcon->setItem(item); - mToolIcon->setUserString ("ToolTipType", "ItemPtr"); - mToolIcon->setUserData(item); + mToolIcon->setItem(item); + mToolIcon->setUserString("ToolTipType", "ItemPtr"); + mToolIcon->setUserData(item); - mRepair.setTool(item); + mRepair.setTool(item); - MWBase::Environment::get().getWindowManager()->playSound(item.getClass().getDownSoundId(item)); - updateRepairView(); -} + MWBase::Environment::get().getWindowManager()->playSound(item.getClass().getDownSoundId(item)); + updateRepairView(); + } -void Repair::onItemCancel() -{ - mItemSelectionDialog->setVisible(false); -} + void Repair::onItemCancel() + { + mItemSelectionDialog->setVisible(false); + } -void Repair::onCancel(MyGUI::Widget* /*sender*/) -{ - MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Repair); -} + void Repair::onCancel(MyGUI::Widget* /*sender*/) + { + MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Repair); + } -void Repair::onRepairItem(MyGUI::Widget* /*sender*/, const MWWorld::Ptr& ptr) -{ - if (!mRepair.getTool().getRefData().getCount()) - return; + void Repair::onRepairItem(MyGUI::Widget* /*sender*/, const MWWorld::Ptr& ptr) + { + if (!mRepair.getTool().getRefData().getCount()) + return; - mRepair.repair(ptr); + mRepair.repair(ptr); - updateRepairView(); -} + updateRepairView(); + } } diff --git a/apps/openmw/mwgui/repair.hpp b/apps/openmw/mwgui/repair.hpp index 7d992939fc..db608d9b8b 100644 --- a/apps/openmw/mwgui/repair.hpp +++ b/apps/openmw/mwgui/repair.hpp @@ -10,46 +10,45 @@ namespace MWGui { -class ItemSelectionDialog; -class ItemWidget; -class ItemChargeView; + class ItemSelectionDialog; + class ItemWidget; + class ItemChargeView; -class Repair : public WindowBase -{ -public: - Repair(); - - void onOpen() override; + class Repair : public WindowBase + { + public: + Repair(); - void setPtr (const MWWorld::Ptr& item) override; + void onOpen() override; -protected: - ItemChargeView* mRepairBox; + void setPtr(const MWWorld::Ptr& item) override; - MyGUI::Widget* mToolBox; + protected: + ItemChargeView* mRepairBox; - ItemWidget* mToolIcon; + MyGUI::Widget* mToolBox; - std::unique_ptr mItemSelectionDialog; + ItemWidget* mToolIcon; - MyGUI::TextBox* mUsesLabel; - MyGUI::TextBox* mQualityLabel; + std::unique_ptr mItemSelectionDialog; - MyGUI::Button* mCancelButton; + MyGUI::TextBox* mUsesLabel; + MyGUI::TextBox* mQualityLabel; - MWMechanics::Repair mRepair; + MyGUI::Button* mCancelButton; - void updateRepairView(); + MWMechanics::Repair mRepair; - void onSelectItem(MyGUI::Widget* sender); + void updateRepairView(); - void onItemSelected(MWWorld::Ptr item); - void onItemCancel(); + void onSelectItem(MyGUI::Widget* sender); - void onRepairItem(MyGUI::Widget* sender, const MWWorld::Ptr& ptr); - void onCancel(MyGUI::Widget* sender); + void onItemSelected(MWWorld::Ptr item); + void onItemCancel(); -}; + void onRepairItem(MyGUI::Widget* sender, const MWWorld::Ptr& ptr); + void onCancel(MyGUI::Widget* sender); + }; } diff --git a/apps/openmw/mwgui/resourceskin.cpp b/apps/openmw/mwgui/resourceskin.cpp index f549241a62..b71355c3e6 100644 --- a/apps/openmw/mwgui/resourceskin.cpp +++ b/apps/openmw/mwgui/resourceskin.cpp @@ -23,7 +23,7 @@ namespace MWGui MyGUI::IntCoord coord(0, 0, texture->getWidth(), texture->getHeight()); MyGUI::xml::ElementEnumerator basis = _node->getElementEnumerator(); - const std::string textureSize = std::to_string(coord.width) + " " + std::to_string(coord.height); + const std::string textureSize = std::to_string(coord.width) + " " + std::to_string(coord.height); _node->addAttribute("size", textureSize); while (basis.next()) { diff --git a/apps/openmw/mwgui/resourceskin.hpp b/apps/openmw/mwgui/resourceskin.hpp index fd1977e660..1b66c22fb2 100644 --- a/apps/openmw/mwgui/resourceskin.hpp +++ b/apps/openmw/mwgui/resourceskin.hpp @@ -7,7 +7,7 @@ namespace MWGui { class AutoSizedResourceSkin final : public MyGUI::ResourceSkin { - MYGUI_RTTI_DERIVED( AutoSizedResourceSkin ) + MYGUI_RTTI_DERIVED(AutoSizedResourceSkin) public: void deserialization(MyGUI::xml::ElementPtr _node, MyGUI::Version _version) override; diff --git a/apps/openmw/mwgui/review.cpp b/apps/openmw/mwgui/review.cpp index 737efba65c..541c07287f 100644 --- a/apps/openmw/mwgui/review.cpp +++ b/apps/openmw/mwgui/review.cpp @@ -3,26 +3,26 @@ #include #include -#include -#include #include +#include +#include #include #include #include #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" -#include "../mwworld/esmstore.hpp" +#include "../mwbase/world.hpp" #include "../mwmechanics/autocalcspell.hpp" +#include "../mwworld/esmstore.hpp" #include "tooltips.hpp" #include "ustring.hpp" namespace { - void adjustButtonSize(MyGUI::Button *button) + void adjustButtonSize(MyGUI::Button* button) { // adjust size of button to fit its text MyGUI::IntSize size = button->getTextSize(); @@ -33,8 +33,8 @@ namespace namespace MWGui { ReviewDialog::ReviewDialog() - : WindowModal("openmw_chargen_review.layout"), - mUpdateSkillArea(false) + : WindowModal("openmw_chargen_review.layout") + , mUpdateSkillArea(false) { // Centre dialog center(); @@ -92,7 +92,7 @@ namespace MWGui for (int i = 0; i < ESM::Skill::Length; ++i) { mSkillValues.insert(std::make_pair(i, MWMechanics::SkillValue())); - mSkillWidgetMap.insert(std::make_pair(i, static_cast (nullptr))); + mSkillWidgetMap.insert(std::make_pair(i, static_cast(nullptr))); } MyGUI::Button* backButton; @@ -119,17 +119,16 @@ namespace MWGui } } - void ReviewDialog::setPlayerName(const std::string &name) + void ReviewDialog::setPlayerName(const std::string& name) { mNameWidget->setCaption(name); } - void ReviewDialog::setRace(const std::string &raceId) + void ReviewDialog::setRace(const std::string& raceId) { mRaceId = raceId; - const ESM::Race *race = - MWBase::Environment::get().getWorld()->getStore().get().search(mRaceId); + const ESM::Race* race = MWBase::Environment::get().getWorld()->getStore().get().search(mRaceId); if (race) { ToolTips::createRaceToolTip(mRaceWidget, race); @@ -150,8 +149,8 @@ namespace MWGui { mBirthSignId = signId; - const ESM::BirthSign *sign = - MWBase::Environment::get().getWorld()->getStore().get().search(mBirthSignId); + const ESM::BirthSign* sign + = MWBase::Environment::get().getWorld()->getStore().get().search(mBirthSignId); if (sign) { mBirthSignWidget->setCaption(sign->mName); @@ -167,7 +166,7 @@ namespace MWGui int modified = static_cast(value.getModified()); mHealth->setValue(current, modified); - std::string valStr = MyGUI::utility::toString(current) + " / " + MyGUI::utility::toString(modified); + std::string valStr = MyGUI::utility::toString(current) + " / " + MyGUI::utility::toString(modified); mHealth->setUserString("Caption_HealthDescription", "#{sHealthDesc}\n" + valStr); } @@ -177,7 +176,7 @@ namespace MWGui int modified = static_cast(value.getModified()); mMagicka->setValue(current, modified); - std::string valStr = MyGUI::utility::toString(current) + " / " + MyGUI::utility::toString(modified); + std::string valStr = MyGUI::utility::toString(current) + " / " + MyGUI::utility::toString(modified); mMagicka->setUserString("Caption_HealthDescription", "#{sMagDesc}\n" + valStr); } @@ -187,7 +186,7 @@ namespace MWGui int modified = static_cast(value.getModified()); mFatigue->setValue(current, modified); - std::string valStr = MyGUI::utility::toString(current) + " / " + MyGUI::utility::toString(modified); + std::string valStr = MyGUI::utility::toString(current) + " / " + MyGUI::utility::toString(modified); mFatigue->setUserString("Caption_HealthDescription", "#{sFatDesc}\n" + valStr); } @@ -244,9 +243,10 @@ namespace MWGui mUpdateSkillArea = true; } - void ReviewDialog::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) + void ReviewDialog::addSeparator(MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2) { - MyGUI::ImageBox* separator = mSkillView->createWidget("MW_HLine", MyGUI::IntCoord(10, coord1.top, coord1.width + coord2.width - 4, 18), MyGUI::Align::Default); + MyGUI::ImageBox* separator = mSkillView->createWidget( + "MW_HLine", MyGUI::IntCoord(10, coord1.top, coord1.width + coord2.width - 4, 18), MyGUI::Align::Default); separator->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel); mSkillWidgets.push_back(separator); @@ -257,7 +257,8 @@ namespace MWGui void ReviewDialog::addGroup(std::string_view label, MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2) { - MyGUI::TextBox* groupWidget = mSkillView->createWidget("SandBrightText", MyGUI::IntCoord(0, coord1.top, coord1.width + coord2.width, coord1.height), MyGUI::Align::Default); + MyGUI::TextBox* groupWidget = mSkillView->createWidget("SandBrightText", + MyGUI::IntCoord(0, coord1.top, coord1.width + coord2.width, coord1.height), MyGUI::Align::Default); groupWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel); groupWidget->setCaption(toUString(label)); mSkillWidgets.push_back(groupWidget); @@ -267,7 +268,8 @@ namespace MWGui coord2.top += lineHeight; } - MyGUI::TextBox* ReviewDialog::addValueItem(std::string_view text, const std::string& value, const std::string& state, MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2) + MyGUI::TextBox* ReviewDialog::addValueItem(std::string_view text, const std::string& value, + const std::string& state, MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2) { MyGUI::TextBox* skillNameWidget; MyGUI::TextBox* skillValueWidget; @@ -291,11 +293,12 @@ namespace MWGui return skillValueWidget; } - void ReviewDialog::addItem(const std::string& text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) + void ReviewDialog::addItem(const std::string& text, MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2) { MyGUI::TextBox* skillNameWidget; - skillNameWidget = mSkillView->createWidget("SandText", coord1 + MyGUI::IntSize(coord2.width, 0), MyGUI::Align::Default); + skillNameWidget = mSkillView->createWidget( + "SandText", coord1 + MyGUI::IntSize(coord2.width, 0), MyGUI::Align::Default); skillNameWidget->setCaption(text); skillNameWidget->eventMouseWheel += MyGUI::newDelegate(this, &ReviewDialog::onMouseWheel); @@ -308,7 +311,8 @@ namespace MWGui void ReviewDialog::addItem(const ESM::Spell* spell, MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2) { - Widgets::MWSpellPtr widget = mSkillView->createWidget("MW_StatName", coord1 + MyGUI::IntSize(coord2.width, 0), MyGUI::Align::Default); + Widgets::MWSpellPtr widget = mSkillView->createWidget( + "MW_StatName", coord1 + MyGUI::IntSize(coord2.width, 0), MyGUI::Align::Default); widget->setSpellId(spell->mId); widget->setUserString("ToolTipType", "Spell"); widget->setUserString("Spell", spell->mId); @@ -321,7 +325,8 @@ namespace MWGui coord2.top += lineHeight; } - void ReviewDialog::addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) + void ReviewDialog::addSkills(const SkillList& skills, const std::string& titleId, const std::string& titleDefault, + MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2) { // Add a line separator if there are items above if (!mSkillWidgets.empty()) @@ -329,15 +334,16 @@ namespace MWGui addSeparator(coord1, coord2); } - addGroup(MWBase::Environment::get().getWindowManager()->getGameSettingString(titleId, titleDefault), coord1, coord2); + addGroup( + MWBase::Environment::get().getWindowManager()->getGameSettingString(titleId, titleDefault), coord1, coord2); for (const int& skillId : skills) { if (skillId < 0 || skillId >= ESM::Skill::Length) // Skip unknown skill indexes continue; assert(skillId >= 0 && skillId < ESM::Skill::Length); - const std::string &skillNameId = ESM::Skill::sSkillNameIds[skillId]; - const MWMechanics::SkillValue &stat = mSkillValues.find(skillId)->second; + const std::string& skillNameId = ESM::Skill::sSkillNameIds[skillId]; + const MWMechanics::SkillValue& stat = mSkillValues.find(skillId)->second; int base = stat.getBase(); int modified = stat.getModified(); @@ -346,11 +352,13 @@ namespace MWGui state = "increased"; else if (modified < base) state = "decreased"; - MyGUI::TextBox* widget = addValueItem(MWBase::Environment::get().getWindowManager()->getGameSettingString(skillNameId, skillNameId), MyGUI::utility::toString(static_cast(modified)), state, coord1, coord2); + MyGUI::TextBox* widget = addValueItem( + MWBase::Environment::get().getWindowManager()->getGameSettingString(skillNameId, skillNameId), + MyGUI::utility::toString(static_cast(modified)), state, coord1, coord2); - for (int i=0; i<2; ++i) + for (int i = 0; i < 2; ++i) { - ToolTips::createSkillToolTip(mSkillWidgets[mSkillWidgets.size()-1-i], skillId); + ToolTips::createSkillToolTip(mSkillWidgets[mSkillWidgets.size() - 1 - i], skillId); } mSkillWidgetMap[skillId] = widget; @@ -386,11 +394,11 @@ namespace MWGui race = MWBase::Environment::get().getWorld()->getStore().get().find(mRaceId); int skills[ESM::Skill::Length]; - for (int i=0; isecond.getBase(); int attributes[ESM::Attribute::Length]; - for (int i=0; igetAttributeValue().getBase(); std::vector selectedSpells = MWMechanics::autoCalcPlayerSpells(skills, attributes, race); @@ -413,7 +421,8 @@ namespace MWGui if (!mBirthSignId.empty()) { - const ESM::BirthSign* sign = MWBase::Environment::get().getWorld()->getStore().get().find(mBirthSignId); + const ESM::BirthSign* sign + = MWBase::Environment::get().getWorld()->getStore().get().find(mBirthSignId); for (const std::string& spellId : sign->mPowers.mList) { std::string lower = Misc::StringUtils::lowerCase(spellId); @@ -424,7 +433,8 @@ namespace MWGui if (!mSkillWidgets.empty()) addSeparator(coord1, coord2); - addGroup(MWBase::Environment::get().getWindowManager()->getGameSettingString("sTypeAbility", "Abilities"), coord1, coord2); + addGroup(MWBase::Environment::get().getWindowManager()->getGameSettingString("sTypeAbility", "Abilities"), + coord1, coord2); for (std::string& spellId : spells) { const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get().find(spellId); @@ -433,7 +443,8 @@ namespace MWGui } addSeparator(coord1, coord2); - addGroup(MWBase::Environment::get().getWindowManager()->getGameSettingString("sTypePower", "Powers"), coord1, coord2); + addGroup(MWBase::Environment::get().getWindowManager()->getGameSettingString("sTypePower", "Powers"), coord1, + coord2); for (std::string& spellId : spells) { const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get().find(spellId); @@ -442,7 +453,8 @@ namespace MWGui } addSeparator(coord1, coord2); - addGroup(MWBase::Environment::get().getWindowManager()->getGameSettingString("sTypeSpell", "Spells"), coord1, coord2); + addGroup(MWBase::Environment::get().getWindowManager()->getGameSettingString("sTypeSpell", "Spells"), coord1, + coord2); for (std::string& spellId : spells) { const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get().find(spellId); @@ -450,9 +462,10 @@ namespace MWGui addItem(spell, coord1, coord2); } - // Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden + // Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the + // scrollbar is hidden mSkillView->setVisibleVScroll(false); - mSkillView->setCanvasSize (mSkillView->getWidth(), std::max(mSkillView->getHeight(), coord1.top)); + mSkillView->setCanvasSize(mSkillView->getWidth(), std::max(mSkillView->getHeight(), coord1.top)); mSkillView->setVisibleVScroll(true); } @@ -490,10 +503,11 @@ namespace MWGui void ReviewDialog::onMouseWheel(MyGUI::Widget* _sender, int _rel) { - if (mSkillView->getViewOffset().top + _rel*0.3 > 0) + if (mSkillView->getViewOffset().top + _rel * 0.3 > 0) mSkillView->setViewOffset(MyGUI::IntPoint(0, 0)); else - mSkillView->setViewOffset(MyGUI::IntPoint(0, static_cast(mSkillView->getViewOffset().top + _rel*0.3))); + mSkillView->setViewOffset( + MyGUI::IntPoint(0, static_cast(mSkillView->getViewOffset().top + _rel * 0.3))); } } diff --git a/apps/openmw/mwgui/review.hpp b/apps/openmw/mwgui/review.hpp index 59a5daecac..913c825217 100644 --- a/apps/openmw/mwgui/review.hpp +++ b/apps/openmw/mwgui/review.hpp @@ -1,10 +1,10 @@ #ifndef MWGUI_REVIEW_H #define MWGUI_REVIEW_H +#include "widgets.hpp" +#include "windowbase.hpp" #include #include -#include "windowbase.hpp" -#include "widgets.hpp" namespace ESM { @@ -16,7 +16,8 @@ namespace MWGui class ReviewDialog : public WindowModal { public: - enum Dialogs { + enum Dialogs + { NAME_DIALOG, RACE_DIALOG, CLASS_DIALOG, @@ -28,10 +29,10 @@ namespace MWGui bool exit() override { return false; } - void setPlayerName(const std::string &name); - void setRace(const std::string &raceId); + void setPlayerName(const std::string& name); + void setRace(const std::string& raceId); void setClass(const ESM::Class& class_); - void setBirthSign (const std::string &signId); + void setBirthSign(const std::string& signId); void setHealth(const MWMechanics::DynamicStat& value); void setMagicka(const MWMechanics::DynamicStat& value); @@ -74,12 +75,14 @@ namespace MWGui void onMouseWheel(MyGUI::Widget* _sender, int _rel); private: - void addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); - void addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); + void addSkills(const SkillList& skills, const std::string& titleId, const std::string& titleDefault, + MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2); + void addSeparator(MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2); void addGroup(std::string_view label, MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2); - MyGUI::TextBox* addValueItem(std::string_view text, const std::string& value, const std::string& state, MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2); - void addItem(const std::string& text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); - void addItem(const ESM::Spell* spell, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); + MyGUI::TextBox* addValueItem(std::string_view text, const std::string& value, const std::string& state, + MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2); + void addItem(const std::string& text, MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2); + void addItem(const ESM::Spell* spell, MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2); void updateSkillArea(); MyGUI::TextBox *mNameWidget, *mRaceWidget, *mClassWidget, *mBirthSignWidget; @@ -90,7 +93,7 @@ namespace MWGui std::map mAttributeWidgets; SkillList mMajorSkills, mMinorSkills, mMiscSkills; - std::map mSkillValues; + std::map mSkillValues; std::map mSkillWidgetMap; std::string mName, mRaceId, mBirthSignId; ESM::Class mKlass; diff --git a/apps/openmw/mwgui/savegamedialog.cpp b/apps/openmw/mwgui/savegamedialog.cpp index 8da5047efd..c2bfbf682e 100644 --- a/apps/openmw/mwgui/savegamedialog.cpp +++ b/apps/openmw/mwgui/savegamedialog.cpp @@ -1,15 +1,15 @@ #include "savegamedialog.hpp" -#include #include +#include #include #include #include #include -#include #include +#include #include @@ -19,16 +19,16 @@ #include +#include #include #include -#include #include -#include "../mwbase/statemanager.hpp" #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" +#include "../mwbase/statemanager.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" #include "../mwworld/esmstore.hpp" #include "../mwstate/character.hpp" @@ -68,7 +68,7 @@ namespace MWGui mDeleteButton->setNeedKeyFocus(false); } - void SaveGameDialog::onSlotActivated(MyGUI::ListBox *sender, size_t pos) + void SaveGameDialog::onSlotActivated(MyGUI::ListBox* sender, size_t pos) { onSlotSelected(sender, pos); accept(); @@ -94,7 +94,7 @@ namespace MWGui void SaveGameDialog::onDeleteSlotConfirmed() { - MWBase::Environment::get().getStateManager()->deleteGame (mCurrentCharacter, mCurrentSlot); + MWBase::Environment::get().getStateManager()->deleteGame(mCurrentCharacter, mCurrentSlot); mSaveList->removeItemAt(mSaveList->getIndexSelected()); onSlotSelected(mSaveList, mSaveList->getIndexSelected()); MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mSaveList); @@ -106,7 +106,7 @@ namespace MWGui mCharacterSelection->removeItemAt(previousIndex); if (mCharacterSelection->getItemCount()) { - size_t nextCharacter = std::min(previousIndex, mCharacterSelection->getItemCount()-1); + size_t nextCharacter = std::min(previousIndex, mCharacterSelection->getItemCount() - 1); mCharacterSelection->setIndexSelected(nextCharacter); onCharacterSelected(mCharacterSelection, nextCharacter); } @@ -120,14 +120,14 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mSaveList); } - void SaveGameDialog::onSaveNameChanged(MyGUI::EditBox *sender) + void SaveGameDialog::onSaveNameChanged(MyGUI::EditBox* sender) { // This might have previously been a save slot from the list. If so, that is no longer the case mSaveList->setIndexSelected(MyGUI::ITEM_NONE); onSlotSelected(mSaveList, MyGUI::ITEM_NONE); } - void SaveGameDialog::onEditSelectAccept(MyGUI::EditBox *sender) + void SaveGameDialog::onEditSelectAccept(MyGUI::EditBox* sender) { accept(); @@ -146,7 +146,7 @@ namespace MWGui { WindowModal::onOpen(); - mSaveNameEdit->setCaption (""); + mSaveNameEdit->setCaption(""); if (mSaving) MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mSaveNameEdit); else @@ -167,14 +167,13 @@ namespace MWGui mCurrentCharacter = mgr->getCurrentCharacter(); - std::string directory = - Misc::StringUtils::lowerCase (Settings::Manager::getString ("character", "Saves")); + std::string directory = Misc::StringUtils::lowerCase(Settings::Manager::getString("character", "Saves")); size_t selectedIndex = MyGUI::ITEM_NONE; for (MWBase::StateManager::CharacterIterator it = mgr->characterBegin(); it != mgr->characterEnd(); ++it) { - if (it->begin()!=it->end()) + if (it->begin() != it->end()) { const ESM::SavedGame& signature = it->getSignature(); @@ -189,24 +188,28 @@ namespace MWGui else { // Find the localised name for this class from the store - const ESM::Class* class_ = MWBase::Environment::get().getWorld()->getStore().get() - .search(signature.mPlayerClassId); + const ESM::Class* class_ + = MWBase::Environment::get().getWorld()->getStore().get().search( + signature.mPlayerClassId); if (class_) className = class_->mName; else className = "?"; // From an older savegame format that did not support custom classes properly. } - title << " (#{sLevel} " << signature.mPlayerLevel << " " << MyGUI::TextIterator::toTagsString(toUString(className)) << ")"; + title << " (#{sLevel} " << signature.mPlayerLevel << " " + << MyGUI::TextIterator::toTagsString(toUString(className)) << ")"; - mCharacterSelection->addItem (MyGUI::LanguageManager::getInstance().replaceTags(title.str())); + mCharacterSelection->addItem(MyGUI::LanguageManager::getInstance().replaceTags(title.str())); - if (mCurrentCharacter == &*it || - (!mCurrentCharacter && !mSaving && directory==Misc::StringUtils::lowerCase ( - Files::pathToUnicodeString(it->begin()->mPath.parent_path().filename())))) + if (mCurrentCharacter == &*it + || (!mCurrentCharacter && !mSaving + && directory + == Misc::StringUtils::lowerCase( + Files::pathToUnicodeString(it->begin()->mPath.parent_path().filename())))) { mCurrentCharacter = &*it; - selectedIndex = mCharacterSelection->getItemCount()-1; + selectedIndex = mCharacterSelection->getItemCount() - 1; } } } @@ -216,7 +219,6 @@ namespace MWGui mCharacterSelection->setCaptionWithReplacing("#{SavegameMenu:SelectCharacter}"); fillSaveList(); - } void SaveGameDialog::setLoadOrSave(bool load) @@ -237,12 +239,12 @@ namespace MWGui center(); } - void SaveGameDialog::onCancelButtonClicked(MyGUI::Widget *sender) + void SaveGameDialog::onCancelButtonClicked(MyGUI::Widget* sender) { setVisible(false); } - void SaveGameDialog::onDeleteButtonClicked(MyGUI::Widget *sender) + void SaveGameDialog::onDeleteButtonClicked(MyGUI::Widget* sender) { if (mCurrentSlot) confirmDeleteSave(); @@ -297,16 +299,16 @@ namespace MWGui } setVisible(false); - MWBase::Environment::get().getWindowManager()->removeGuiMode (MWGui::GM_MainMenu); + MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_MainMenu); if (mSaving) { - MWBase::Environment::get().getStateManager()->saveGame (mSaveNameEdit->getCaption(), mCurrentSlot); + MWBase::Environment::get().getStateManager()->saveGame(mSaveNameEdit->getCaption(), mCurrentSlot); } else { - assert (mCurrentCharacter && mCurrentSlot); - MWBase::Environment::get().getStateManager()->loadGame (mCurrentCharacter, mCurrentSlot->mPath); + assert(mCurrentCharacter && mCurrentSlot); + MWBase::Environment::get().getStateManager()->loadGame(mCurrentCharacter, mCurrentSlot->mPath); } } @@ -316,16 +318,16 @@ namespace MWGui confirmDeleteSave(); } - void SaveGameDialog::onOkButtonClicked(MyGUI::Widget *sender) + void SaveGameDialog::onOkButtonClicked(MyGUI::Widget* sender) { accept(); } - void SaveGameDialog::onCharacterSelected(MyGUI::ComboBox *sender, size_t pos) + void SaveGameDialog::onCharacterSelected(MyGUI::ComboBox* sender, size_t pos) { MWBase::StateManager* mgr = MWBase::Environment::get().getStateManager(); - unsigned int i=0; + unsigned int i = 0; const MWState::Character* character = nullptr; for (MWBase::StateManager::CharacterIterator it = mgr->characterBegin(); it != mgr->characterEnd(); ++it, ++i) { @@ -380,7 +382,7 @@ namespace MWGui return stream.str(); } - void SaveGameDialog::onSlotSelected(MyGUI::ListBox *sender, size_t pos) + void SaveGameDialog::onSlotSelected(MyGUI::ListBox* sender, size_t pos) { mOkButton->setEnabled(pos != MyGUI::ITEM_NONE || mSaving); mDeleteButton->setEnabled(pos != MyGUI::ITEM_NONE); @@ -397,8 +399,9 @@ namespace MWGui mSaveNameEdit->setCaption(sender->getItemNameAt(pos)); mCurrentSlot = nullptr; - unsigned int i=0; - for (MWState::Character::SlotIterator it = mCurrentCharacter->begin(); it != mCurrentCharacter->end(); ++it, ++i) + unsigned int i = 0; + for (MWState::Character::SlotIterator it = mCurrentCharacter->begin(); it != mCurrentCharacter->end(); + ++it, ++i) { if (i == pos) mCurrentSlot = &*it; @@ -418,17 +421,19 @@ namespace MWGui int hour = int(mCurrentSlot->mProfile.mInGameTime.mGameHour); bool pm = hour >= 12; - if (hour >= 13) hour -= 12; - if (hour == 0) hour = 12; + if (hour >= 13) + hour -= 12; + if (hour == 0) + hour = 12; - text - << mCurrentSlot->mProfile.mInGameTime.mDay << " " - << MWBase::Environment::get().getWorld()->getMonthName(mCurrentSlot->mProfile.mInGameTime.mMonth) - << " " << hour << " " << (pm ? "#{sSaveMenuHelp05}" : "#{sSaveMenuHelp04}"); + text << mCurrentSlot->mProfile.mInGameTime.mDay << " " + << MWBase::Environment::get().getWorld()->getMonthName(mCurrentSlot->mProfile.mInGameTime.mMonth) << " " + << hour << " " << (pm ? "#{sSaveMenuHelp05}" : "#{sSaveMenuHelp04}"); - if (Settings::Manager::getBool("timeplayed","Saves")) + if (Settings::Manager::getBool("timeplayed", "Saves")) { - text << "\n" << "#{SavegameMenu:TimePlayed}: " << formatTimeplayed(mCurrentSlot->mProfile.mTimePlayed); + text << "\n" + << "#{SavegameMenu:TimePlayed}: " << formatTimeplayed(mCurrentSlot->mProfile.mTimePlayed); } mInfoText->setCaptionWithReplacing(text.str()); @@ -442,11 +447,12 @@ namespace MWGui const std::vector& data = mCurrentSlot->mProfile.mScreenshot; if (!data.size()) { - Log(Debug::Warning) << "Selected save file '" << Files::pathToUnicodeString(mCurrentSlot->mPath.filename()) << "' has no savegame screenshot"; + Log(Debug::Warning) << "Selected save file '" << Files::pathToUnicodeString(mCurrentSlot->mPath.filename()) + << "' has no savegame screenshot"; return; } - Files::IMemStream instream (data.data(), data.size()); + Files::IMemStream instream(data.data(), data.size()); osgDB::ReaderWriter* readerwriter = osgDB::Registry::instance()->getReaderWriterForExtension("jpg"); if (!readerwriter) @@ -458,11 +464,12 @@ namespace MWGui osgDB::ReaderWriter::ReadResult result = readerwriter->readImage(instream); if (!result.success()) { - Log(Debug::Error) << "Failed to read savegame screenshot: " << result.message() << " code " << result.status(); + Log(Debug::Error) << "Failed to read savegame screenshot: " << result.message() << " code " + << result.status(); return; } - osg::ref_ptr texture (new osg::Texture2D); + osg::ref_ptr texture(new osg::Texture2D); texture->setImage(result.getImage()); texture->setInternalFormat(GL_RGB); texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE); diff --git a/apps/openmw/mwgui/savegamedialog.hpp b/apps/openmw/mwgui/savegamedialog.hpp index 86d4ade8ac..35e65fbed0 100644 --- a/apps/openmw/mwgui/savegamedialog.hpp +++ b/apps/openmw/mwgui/savegamedialog.hpp @@ -28,27 +28,27 @@ namespace MWGui void confirmDeleteSave(); void onKeyButtonPressed(MyGUI::Widget* _sender, MyGUI::KeyCode key, MyGUI::Char character); - void onCancelButtonClicked (MyGUI::Widget* sender); - void onOkButtonClicked (MyGUI::Widget* sender); - void onDeleteButtonClicked (MyGUI::Widget* sender); - void onCharacterSelected (MyGUI::ComboBox* sender, size_t pos); + void onCancelButtonClicked(MyGUI::Widget* sender); + void onOkButtonClicked(MyGUI::Widget* sender); + void onDeleteButtonClicked(MyGUI::Widget* sender); + void onCharacterSelected(MyGUI::ComboBox* sender, size_t pos); void onCharacterAccept(MyGUI::ComboBox* sender, size_t pos); // Slot selected (mouse click or arrow keys) - void onSlotSelected (MyGUI::ListBox* sender, size_t pos); + void onSlotSelected(MyGUI::ListBox* sender, size_t pos); // Slot activated (double click or enter key) - void onSlotActivated (MyGUI::ListBox* sender, size_t pos); + void onSlotActivated(MyGUI::ListBox* sender, size_t pos); // Slot clicked with mouse void onSlotMouseClick(MyGUI::ListBox* sender, size_t pos); void onDeleteSlotConfirmed(); void onDeleteSlotCancel(); - void onEditSelectAccept (MyGUI::EditBox* sender); - void onSaveNameChanged (MyGUI::EditBox* sender); + void onEditSelectAccept(MyGUI::EditBox* sender); + void onSaveNameChanged(MyGUI::EditBox* sender); void onConfirmationGiven(); void onConfirmationCancel(); - void accept(bool reallySure=false); + void accept(bool reallySure = false); void fillSaveList(); @@ -66,7 +66,6 @@ namespace MWGui const MWState::Character* mCurrentCharacter; const MWState::Slot* mCurrentSlot; - }; } diff --git a/apps/openmw/mwgui/screenfader.cpp b/apps/openmw/mwgui/screenfader.cpp index aa47d0821c..e22517a360 100644 --- a/apps/openmw/mwgui/screenfader.cpp +++ b/apps/openmw/mwgui/screenfader.cpp @@ -1,19 +1,19 @@ #include "screenfader.hpp" -#include #include +#include namespace MWGui { - FadeOp::FadeOp(ScreenFader * fader, float time, float targetAlpha, float delay) - : mFader(fader), - mRemainingTime(time+delay), - mTargetTime(time), - mTargetAlpha(targetAlpha), - mStartAlpha(0.f), - mDelay(delay), - mRunning(false) + FadeOp::FadeOp(ScreenFader* fader, float time, float targetAlpha, float delay) + : mFader(fader) + , mRemainingTime(time + delay) + , mTargetTime(time) + , mTargetAlpha(targetAlpha) + , mStartAlpha(0.f) + , mDelay(delay) + , mRunning(false) { } @@ -60,13 +60,13 @@ namespace MWGui float currentAlpha = mFader->getCurrentAlpha(); if (mStartAlpha > mTargetAlpha) { - currentAlpha -= dt/mTargetTime * (mStartAlpha-mTargetAlpha); + currentAlpha -= dt / mTargetTime * (mStartAlpha - mTargetAlpha); if (currentAlpha < mTargetAlpha) currentAlpha = mTargetAlpha; } else { - currentAlpha += dt/mTargetTime * (mTargetAlpha-mStartAlpha); + currentAlpha += dt / mTargetTime * (mTargetAlpha - mStartAlpha); if (currentAlpha > mTargetAlpha) currentAlpha = mTargetAlpha; } @@ -82,7 +82,8 @@ namespace MWGui mFader->notifyOperationFinished(); } - ScreenFader::ScreenFader(const std::string & texturePath, const std::string& layout, const MyGUI::FloatCoord& texCoordOverride) + ScreenFader::ScreenFader( + const std::string& texturePath, const std::string& layout, const MyGUI::FloatCoord& texCoordOverride) : WindowBase(layout) , mCurrentAlpha(0.f) , mFactor(1.f) @@ -95,10 +96,9 @@ namespace MWGui { imageBox->setImageTexture(texturePath); const MyGUI::IntSize imageSize = imageBox->getImageSize(); - imageBox->setImageCoord(MyGUI::IntCoord(texCoordOverride.left * imageSize.width, - texCoordOverride.top * imageSize.height, - texCoordOverride.width * imageSize.width, - texCoordOverride.height * imageSize.height)); + imageBox->setImageCoord( + MyGUI::IntCoord(texCoordOverride.left * imageSize.width, texCoordOverride.top * imageSize.height, + texCoordOverride.width * imageSize.width, texCoordOverride.height * imageSize.height)); } } @@ -108,7 +108,7 @@ namespace MWGui { MyGUI::Gui::getInstance().eventFrameStart -= MyGUI::newDelegate(this, &ScreenFader::onFrameStart); } - catch(const MyGUI::Exception& e) + catch (const MyGUI::Exception& e) { Log(Debug::Error) << "Error in the destructor: " << e.what(); } @@ -127,7 +127,7 @@ namespace MWGui void ScreenFader::applyAlpha() { setVisible(true); - mMainWidget->setAlpha(1.f-((1.f-mCurrentAlpha) * mFactor)); + mMainWidget->setAlpha(1.f - ((1.f - mCurrentAlpha) * mFactor)); } void ScreenFader::fadeIn(float time, float delay) @@ -142,7 +142,7 @@ namespace MWGui void ScreenFader::fadeTo(const int percent, const float time, float delay) { - queue(time, percent/100.f, delay); + queue(time, percent / 100.f, delay); } void ScreenFader::clear() @@ -194,7 +194,7 @@ namespace MWGui mCurrentAlpha = alpha; - if (1.f-((1.f-mCurrentAlpha) * mFactor) == 0.f) + if (1.f - ((1.f - mCurrentAlpha) * mFactor) == 0.f) mMainWidget->setVisible(false); else applyAlpha(); diff --git a/apps/openmw/mwgui/screenfader.hpp b/apps/openmw/mwgui/screenfader.hpp index 8eb8a68591..4ef1ae2f43 100644 --- a/apps/openmw/mwgui/screenfader.hpp +++ b/apps/openmw/mwgui/screenfader.hpp @@ -15,7 +15,7 @@ namespace MWGui public: typedef std::shared_ptr Ptr; - FadeOp(ScreenFader * fader, float time, float targetAlpha, float delay); + FadeOp(ScreenFader* fader, float time, float targetAlpha, float delay); bool isRunning(); @@ -24,7 +24,7 @@ namespace MWGui void finish(); private: - ScreenFader * mFader; + ScreenFader* mFader; float mRemainingTime; float mTargetTime; float mTargetAlpha; @@ -36,18 +36,19 @@ namespace MWGui class ScreenFader : public WindowBase { public: - ScreenFader(const std::string & texturePath, const std::string& layout = "openmw_screen_fader.layout", const MyGUI::FloatCoord& texCoordOverride = MyGUI::FloatCoord(0,0,1,1)); + ScreenFader(const std::string& texturePath, const std::string& layout = "openmw_screen_fader.layout", + const MyGUI::FloatCoord& texCoordOverride = MyGUI::FloatCoord(0, 0, 1, 1)); ~ScreenFader(); void onFrameStart(float dt); - void fadeIn(const float time, float delay=0); - void fadeOut(const float time, float delay=0); - void fadeTo(const int percent, const float time, float delay=0); + void fadeIn(const float time, float delay = 0); + void fadeOut(const float time, float delay = 0); + void fadeTo(const int percent, const float time, float delay = 0); void clear() override; - void setFactor (float factor); + void setFactor(float factor); void setRepeat(bool repeat); void queue(float time, float targetAlpha, float delay); diff --git a/apps/openmw/mwgui/scrollwindow.cpp b/apps/openmw/mwgui/scrollwindow.cpp index df703dcb61..99cec7eb1c 100644 --- a/apps/openmw/mwgui/scrollwindow.cpp +++ b/apps/openmw/mwgui/scrollwindow.cpp @@ -6,8 +6,8 @@ #include #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" #include "../mwmechanics/actorutil.hpp" @@ -19,7 +19,7 @@ namespace MWGui { - ScrollWindow::ScrollWindow () + ScrollWindow::ScrollWindow() : BookWindowBase("openmw_scroll.layout") , mTakeButtonShow(true) , mTakeButtonAllowed(true) @@ -41,20 +41,21 @@ namespace MWGui center(); } - void ScrollWindow::setPtr (const MWWorld::Ptr& scroll) + void ScrollWindow::setPtr(const MWWorld::Ptr& scroll) { mScroll = scroll; MWWorld::Ptr player = MWMechanics::getPlayer(); bool showTakeButton = scroll.getContainerStore() != &player.getClass().getContainerStore(player); - MWWorld::LiveCellRef *ref = mScroll.get(); + MWWorld::LiveCellRef* ref = mScroll.get(); Formatting::BookFormatter formatter; formatter.markupToWidget(mTextView, ref->mBase->mText, 390, mTextView->getHeight()); MyGUI::IntSize size = mTextView->getChildAt(0)->getSize(); - // Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden + // Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the + // scrollbar is hidden mTextView->setVisibleVScroll(false); if (size.height > mTextView->getSize().height) mTextView->setCanvasSize(mTextView->getWidth(), size.height); @@ -62,14 +63,14 @@ namespace MWGui mTextView->setCanvasSize(mTextView->getWidth(), mTextView->getSize().height); mTextView->setVisibleVScroll(true); - mTextView->setViewOffset(MyGUI::IntPoint(0,0)); + mTextView->setViewOffset(MyGUI::IntPoint(0, 0)); setTakeButtonShow(showTakeButton); MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mCloseButton); } - void ScrollWindow::onKeyButtonPressed(MyGUI::Widget *sender, MyGUI::KeyCode key, MyGUI::Char character) + void ScrollWindow::onKeyButtonPressed(MyGUI::Widget* sender, MyGUI::KeyCode key, MyGUI::Char character) { int scroll = 0; if (key == MyGUI::KeyCode::ArrowUp) @@ -93,17 +94,17 @@ namespace MWGui mTakeButton->setVisible(mTakeButtonShow && mTakeButtonAllowed); } - void ScrollWindow::onCloseButtonClicked (MyGUI::Widget* _sender) + void ScrollWindow::onCloseButtonClicked(MyGUI::Widget* _sender) { MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Scroll); } - void ScrollWindow::onTakeButtonClicked (MyGUI::Widget* _sender) + void ScrollWindow::onTakeButtonClicked(MyGUI::Widget* _sender) { MWBase::Environment::get().getWindowManager()->playSound("Item Book Up"); MWWorld::ActionTake take(mScroll); - take.execute (MWMechanics::getPlayer()); + take.execute(MWMechanics::getPlayer()); MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Scroll, true); } diff --git a/apps/openmw/mwgui/scrollwindow.hpp b/apps/openmw/mwgui/scrollwindow.hpp index 8a1e323ab1..a8d22a64b0 100644 --- a/apps/openmw/mwgui/scrollwindow.hpp +++ b/apps/openmw/mwgui/scrollwindow.hpp @@ -14,30 +14,29 @@ namespace MWGui { class ScrollWindow : public BookWindowBase { - public: - ScrollWindow (); + public: + ScrollWindow(); - void setPtr (const MWWorld::Ptr& scroll) override; - void setInventoryAllowed(bool allowed); + void setPtr(const MWWorld::Ptr& scroll) override; + void setInventoryAllowed(bool allowed); - void onResChange(int, int) override { center(); } + void onResChange(int, int) override { center(); } - protected: - void onCloseButtonClicked (MyGUI::Widget* _sender); - void onTakeButtonClicked (MyGUI::Widget* _sender); - void setTakeButtonShow(bool show); - void onKeyButtonPressed(MyGUI::Widget* sender, MyGUI::KeyCode key, MyGUI::Char character); + protected: + void onCloseButtonClicked(MyGUI::Widget* _sender); + void onTakeButtonClicked(MyGUI::Widget* _sender); + void setTakeButtonShow(bool show); + void onKeyButtonPressed(MyGUI::Widget* sender, MyGUI::KeyCode key, MyGUI::Char character); - private: - Gui::ImageButton* mCloseButton; - Gui::ImageButton* mTakeButton; - MyGUI::ScrollView* mTextView; + private: + Gui::ImageButton* mCloseButton; + Gui::ImageButton* mTakeButton; + MyGUI::ScrollView* mTextView; - MWWorld::Ptr mScroll; - - bool mTakeButtonShow; - bool mTakeButtonAllowed; + MWWorld::Ptr mScroll; + bool mTakeButtonShow; + bool mTakeButtonAllowed; }; } diff --git a/apps/openmw/mwgui/settingswindow.cpp b/apps/openmw/mwgui/settingswindow.cpp index a249f1e203..bc2d9a2d78 100644 --- a/apps/openmw/mwgui/settingswindow.cpp +++ b/apps/openmw/mwgui/settingswindow.cpp @@ -1,41 +1,41 @@ #include "settingswindow.hpp" -#include +#include #include #include -#include +#include #include -#include -#include #include -#include #include -#include #include +#include +#include +#include +#include #include #include -#include -#include +#include #include #include -#include -#include +#include +#include #include #include #include -#include +#include #include +#include #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" -#include "../mwbase/soundmanager.hpp" #include "../mwbase/inputmanager.hpp" #include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" #include "confirmationdialog.hpp" #include "ustring.hpp" @@ -44,11 +44,14 @@ namespace { std::string textureMipmappingToStr(const std::string& val) { - if (val == "linear") return "#{SettingsMenu:TextureFilteringTrilinear}"; - if (val == "nearest") return "#{SettingsMenu:TextureFilteringBilinear}"; - if (val == "none") return "#{SettingsMenu:TextureFilteringDisabled}"; - - Log(Debug::Warning) << "Warning: Invalid texture mipmap option: "<< val; + if (val == "linear") + return "#{SettingsMenu:TextureFilteringTrilinear}"; + if (val == "nearest") + return "#{SettingsMenu:TextureFilteringBilinear}"; + if (val == "none") + return "#{SettingsMenu:TextureFilteringDisabled}"; + + Log(Debug::Warning) << "Warning: Invalid texture mipmap option: " << val; return "#{SettingsMenu:TextureFilteringOther}"; } @@ -57,42 +60,42 @@ namespace std::string result; switch (method) { - case SceneUtil::LightingMethod::FFP: - result = "#{SettingsMenu:LightingMethodLegacy}"; - break; - case SceneUtil::LightingMethod::PerObjectUniform: - result = "#{SettingsMenu:LightingMethodShadersCompatibility}"; - break; - case SceneUtil::LightingMethod::SingleUBO: - default: - result = "#{SettingsMenu:LightingMethodShaders}"; - break; + case SceneUtil::LightingMethod::FFP: + result = "#{SettingsMenu:LightingMethodLegacy}"; + break; + case SceneUtil::LightingMethod::PerObjectUniform: + result = "#{SettingsMenu:LightingMethodShadersCompatibility}"; + break; + case SceneUtil::LightingMethod::SingleUBO: + default: + result = "#{SettingsMenu:LightingMethodShaders}"; + break; } return MyGUI::LanguageManager::getInstance().replaceTags(result); } - void parseResolution (int &x, int &y, const std::string& str) + void parseResolution(int& x, int& y, const std::string& str) { std::vector split; - Misc::StringUtils::split (str, split, "@(x"); - assert (split.size() >= 2); + Misc::StringUtils::split(str, split, "@(x"); + assert(split.size() >= 2); Misc::StringUtils::trim(split[0]); Misc::StringUtils::trim(split[1]); - x = MyGUI::utility::parseInt (split[0]); - y = MyGUI::utility::parseInt (split[1]); + x = MyGUI::utility::parseInt(split[0]); + y = MyGUI::utility::parseInt(split[1]); } - bool sortResolutions (std::pair left, std::pair right) + bool sortResolutions(std::pair left, std::pair right) { if (left.first == right.first) return left.second > right.second; return left.first > right.first; } - std::string getAspect (int x, int y) + std::string getAspect(int x, int y) { - int gcd = std::gcd (x, y); + int gcd = std::gcd(x, y); if (gcd == 0) return std::string(); @@ -147,7 +150,7 @@ namespace int maxLights = Settings::Manager::getInt("max lights", "Shaders"); // show increments of 8 in dropdown if (maxLights >= min && maxLights <= max && !(maxLights % increment)) - box->setIndexSelected((maxLights / increment)-1); + box->setIndexSelected((maxLights / increment) - 1); else box->setIndexSelected(MyGUI::ITEM_NONE); } @@ -165,9 +168,9 @@ namespace MWGui std::string type = getSettingType(current); if (type == checkButtonType) { - std::string initialValue = Settings::Manager::getBool(getSettingName(current), - getSettingCategory(current)) - ? "#{sOn}" : "#{sOff}"; + std::string initialValue + = Settings::Manager::getBool(getSettingName(current), getSettingCategory(current)) ? "#{sOn}" + : "#{sOff}"; current->castType()->setCaptionWithReplacing(initialValue); if (init) current->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); @@ -180,14 +183,14 @@ namespace MWGui if (valueType == "Float" || valueType == "Integer" || valueType == "Cell") { // TODO: ScrollBar isn't meant for this. should probably use a dedicated FloatSlider widget - float min,max; + float min, max; getSettingMinMax(scroll, min, max); float value = Settings::Manager::getFloat(getSettingName(current), getSettingCategory(current)); if (valueType == "Cell") { std::stringstream ss; - ss << std::fixed << std::setprecision(2) << value/Constants::CellSizeInUnits; + ss << std::fixed << std::setprecision(2) << value / Constants::CellSizeInUnits; valueStr = ss.str(); } else if (valueType == "Float") @@ -200,7 +203,7 @@ namespace MWGui valueStr = MyGUI::utility::toString(int(value)); value = std::clamp(value, min, max); - value = (value-min)/(max-min); + value = (value - min) / (max - min); scroll->setScrollPosition(static_cast(value * (scroll->getScrollRange() - 1))); } @@ -211,7 +214,8 @@ namespace MWGui scroll->setScrollPosition(value); } if (init) - scroll->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); + scroll->eventScrollChangePosition + += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); if (scroll->getVisible()) updateSliderLabel(scroll, valueStr); } @@ -220,7 +224,7 @@ namespace MWGui } } - void SettingsWindow::updateSliderLabel(MyGUI::ScrollBar *scroller, const std::string& value) + void SettingsWindow::updateSliderLabel(MyGUI::ScrollBar* scroller, const std::string& value) { std::string labelWidgetName = scroller->getUserString("SettingLabelWidget"); if (!labelWidgetName.empty()) @@ -233,7 +237,8 @@ namespace MWGui } } - SettingsWindow::SettingsWindow() : WindowBase("openmw_settings_window.layout") + SettingsWindow::SettingsWindow() + : WindowBase("openmw_settings_window.layout") , mKeyboardMode(true) , mCurrentPage(-1) { @@ -274,10 +279,10 @@ namespace MWGui #ifndef WIN32 // hide gamma controls since it currently does not work under Linux - MyGUI::ScrollBar *gammaSlider; + MyGUI::ScrollBar* gammaSlider; getWidget(gammaSlider, "GammaSlider"); gammaSlider->setVisible(false); - MyGUI::TextBox *textBox; + MyGUI::TextBox* textBox; getWidget(textBox, "GammaText"); textBox->setVisible(false); getWidget(textBox, "GammaTextDark"); @@ -286,39 +291,50 @@ namespace MWGui textBox->setVisible(false); #endif - mMainWidget->castType()->eventWindowChangeCoord += MyGUI::newDelegate(this, &SettingsWindow::onWindowResize); + mMainWidget->castType()->eventWindowChangeCoord + += MyGUI::newDelegate(this, &SettingsWindow::onWindowResize); mSettingsTab->eventTabChangeSelect += MyGUI::newDelegate(this, &SettingsWindow::onTabChanged); mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onOkButtonClicked); - mTextureFilteringButton->eventComboChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onTextureFilteringChanged); + mTextureFilteringButton->eventComboChangePosition + += MyGUI::newDelegate(this, &SettingsWindow::onTextureFilteringChanged); mResolutionList->eventListChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onResolutionSelected); - mWaterTextureSize->eventComboChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onWaterTextureSizeChanged); - mWaterReflectionDetail->eventComboChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onWaterReflectionDetailChanged); - mWaterRainRippleDetail->eventComboChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onWaterRainRippleDetailChanged); - - mLightingMethodButton->eventComboChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onLightingMethodButtonChanged); - mLightsResetButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onLightsResetButtonClicked); + mWaterTextureSize->eventComboChangePosition + += MyGUI::newDelegate(this, &SettingsWindow::onWaterTextureSizeChanged); + mWaterReflectionDetail->eventComboChangePosition + += MyGUI::newDelegate(this, &SettingsWindow::onWaterReflectionDetailChanged); + mWaterRainRippleDetail->eventComboChangePosition + += MyGUI::newDelegate(this, &SettingsWindow::onWaterRainRippleDetailChanged); + + mLightingMethodButton->eventComboChangePosition + += MyGUI::newDelegate(this, &SettingsWindow::onLightingMethodButtonChanged); + mLightsResetButton->eventMouseButtonClick + += MyGUI::newDelegate(this, &SettingsWindow::onLightsResetButtonClicked); mMaxLights->eventComboChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onMaxLightsChanged); mWindowModeList->eventComboChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onWindowModeChanged); mKeyboardSwitch->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onKeyboardSwitchClicked); - mControllerSwitch->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onControllerSwitchClicked); + mControllerSwitch->eventMouseButtonClick + += MyGUI::newDelegate(this, &SettingsWindow::onControllerSwitchClicked); - mPrimaryLanguage->eventComboChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onPrimaryLanguageChanged); - mSecondaryLanguage->eventComboChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSecondaryLanguageChanged); + mPrimaryLanguage->eventComboChangePosition + += MyGUI::newDelegate(this, &SettingsWindow::onPrimaryLanguageChanged); + mSecondaryLanguage->eventComboChangePosition + += MyGUI::newDelegate(this, &SettingsWindow::onSecondaryLanguageChanged); computeMinimumWindowSize(); center(); - mResetControlsButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onResetDefaultBindings); + mResetControlsButton->eventMouseButtonClick + += MyGUI::newDelegate(this, &SettingsWindow::onResetDefaultBindings); // fill resolution list int screen = Settings::Manager::getInt("screen", "Video"); int numDisplayModes = SDL_GetNumDisplayModes(screen); - std::vector < std::pair > resolutions; + std::vector> resolutions; for (int i = 0; i < numDisplayModes; i++) { SDL_DisplayMode mode; @@ -328,10 +344,11 @@ namespace MWGui std::sort(resolutions.begin(), resolutions.end(), sortResolutions); for (std::pair& resolution : resolutions) { - std::string str = MyGUI::utility::toString(resolution.first) + " x " + MyGUI::utility::toString(resolution.second); + std::string str + = MyGUI::utility::toString(resolution.first) + " x " + MyGUI::utility::toString(resolution.second); std::string aspect = getAspect(resolution.first, resolution.second); if (!aspect.empty()) - str = str + " (" + aspect + ")"; + str = str + " (" + aspect + ")"; if (mResolutionList->findItemIndexWith(str) == MyGUI::ITEM_NONE) mResolutionList->addItem(str); @@ -357,8 +374,10 @@ namespace MWGui updateMaxLightsComboBox(mMaxLights); - Settings::WindowMode windowMode = static_cast(Settings::Manager::getInt("window mode", "Video")); - mWindowBorderButton->setEnabled(windowMode != Settings::WindowMode::Fullscreen && windowMode != Settings::WindowMode::WindowedFullscreen); + Settings::WindowMode windowMode + = static_cast(Settings::Manager::getInt("window mode", "Video")); + mWindowBorderButton->setEnabled( + windowMode != Settings::WindowMode::Fullscreen && windowMode != Settings::WindowMode::WindowedFullscreen); mKeyboardSwitch->setStateSelected(true); mControllerSwitch->setStateSelected(false); @@ -373,12 +392,13 @@ namespace MWGui if (Misc::getFileExtension(path) == "yaml") { std::string localeName(Misc::stemFile(path)); - if (std::find(availableLanguages.begin(), availableLanguages.end(), localeName) == availableLanguages.end()) - availableLanguages.push_back(localeName); + if (std::find(availableLanguages.begin(), availableLanguages.end(), localeName) + == availableLanguages.end()) + availableLanguages.push_back(localeName); } } - std::sort (availableLanguages.begin(), availableLanguages.end()); + std::sort(availableLanguages.begin(), availableLanguages.end()); std::vector currentLocales = Settings::Manager::getStringArray("preferred locales", "General"); if (currentLocales.empty()) @@ -442,7 +462,7 @@ namespace MWGui { std::string resStr = mResolutionList->getItemNameAt(mResolutionList->getIndexSelected()); int resX, resY; - parseResolution (resX, resY, resStr); + parseResolution(resX, resY, resStr); Settings::Manager::setInt("resolution x", "Video", resX); Settings::Manager::setInt("resolution y", "Video", resY); @@ -462,10 +482,10 @@ namespace MWGui int currentX = Settings::Manager::getInt("resolution x", "Video"); int currentY = Settings::Manager::getInt("resolution y", "Video"); - for (size_t i=0; igetItemCount(); ++i) + for (size_t i = 0; i < mResolutionList->getItemCount(); ++i) { int resX, resY; - parseResolution (resX, resY, mResolutionList->getItemNameAt(i)); + parseResolution(resX, resY, mResolutionList->getItemNameAt(i)); if (resX == currentX && resY == currentY) { @@ -509,7 +529,8 @@ namespace MWGui _sender->setCaptionWithReplacing(_sender->getItemNameAt(_sender->getIndexSelected())); - MWBase::Environment::get().getWindowManager()->interactiveMessageBox("#{SettingsMenu:ChangeRequiresRestart}", {"#{sOK}"}, true); + MWBase::Environment::get().getWindowManager()->interactiveMessageBox( + "#{SettingsMenu:ChangeRequiresRestart}", { "#{sOK}" }, true); Settings::Manager::setString("lighting method", "Shaders", *_sender->getItemDataAt(pos)); apply(); @@ -522,7 +543,8 @@ namespace MWGui _sender->setCaptionWithReplacing(_sender->getItemNameAt(_sender->getIndexSelected())); - MWBase::Environment::get().getWindowManager()->interactiveMessageBox("#{SettingsMenu:ChangeRequiresRestart}", {"#{sOK}"}, true); + MWBase::Environment::get().getWindowManager()->interactiveMessageBox( + "#{SettingsMenu:ChangeRequiresRestart}", { "#{sOK}" }, true); std::vector currentLocales = Settings::Manager::getStringArray("preferred locales", "General"); if (currentLocales.size() <= langPriority) @@ -557,8 +579,9 @@ namespace MWGui void SettingsWindow::onLightsResetButtonClicked(MyGUI::Widget* _sender) { - std::vector buttons = {"#{sYes}", "#{sNo}"}; - MWBase::Environment::get().getWindowManager()->interactiveMessageBox("#{SettingsMenu:LightingResetToDefaults}", buttons, true); + std::vector buttons = { "#{sYes}", "#{sNo}" }; + MWBase::Environment::get().getWindowManager()->interactiveMessageBox( + "#{SettingsMenu:LightingResetToDefaults}", buttons, true); int selectedButton = MWBase::Environment::get().getWindowManager()->readPressedButton(); if (selectedButton == 1 || selectedButton == -1) return; @@ -572,9 +595,11 @@ namespace MWGui "lighting method", }; for (const auto& setting : settings) - Settings::Manager::setString(setting, "Shaders", Settings::Manager::mDefaultSettings[{"Shaders", setting}]); + Settings::Manager::setString( + setting, "Shaders", Settings::Manager::mDefaultSettings[{ "Shaders", setting }]); - auto lightingMethod = SceneUtil::LightManager::getLightingMethodFromString(Settings::Manager::mDefaultSettings[{"Shaders", "lighting method"}]); + auto lightingMethod = SceneUtil::LightManager::getLightingMethodFromString( + Settings::Manager::mDefaultSettings[{ "Shaders", "lighting method" }]); auto lightIndex = mLightingMethodButton->findItemIndexWith(lightingMethodToStr(lightingMethod)); mLightingMethodButton->setIndexSelected(lightIndex); updateMaxLightsComboBox(mMaxLights); @@ -589,7 +614,8 @@ namespace MWGui bool newState; if (_sender->castType()->getCaption() == on) { - MyGUI::UString off = toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOff", "Off")); + MyGUI::UString off + = toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOff", "Off")); _sender->castType()->setCaption(off); newState = false; } @@ -609,9 +635,9 @@ namespace MWGui void SettingsWindow::onTextureFilteringChanged(MyGUI::ComboBox* _sender, size_t pos) { - if(pos == 0) + if (pos == 0) Settings::Manager::setString("texture mipmap", "General", "nearest"); - else if(pos == 1) + else if (pos == 1) Settings::Manager::setString("texture mipmap", "General", "linear"); else Log(Debug::Warning) << "Unexpected option pos " << pos; @@ -626,11 +652,11 @@ namespace MWGui std::string valueType = getSettingValueType(scroller); if (valueType == "Float" || valueType == "Integer" || valueType == "Cell") { - float value = pos / float(scroller->getScrollRange()-1); + float value = pos / float(scroller->getScrollRange() - 1); - float min,max; + float min, max; getSettingMinMax(scroller, min, max); - value = min + (max-min) * value; + value = min + (max - min) * value; if (valueType == "Float") Settings::Manager::setFloat(getSettingName(scroller), getSettingCategory(scroller), value); else @@ -639,7 +665,7 @@ namespace MWGui if (valueType == "Cell") { std::stringstream ss; - ss << std::fixed << std::setprecision(2) << value/Constants::CellSizeInUnits; + ss << std::fixed << std::setprecision(2) << value / Constants::CellSizeInUnits; valueStr = ss.str(); } else if (valueType == "Float") @@ -675,7 +701,7 @@ namespace MWGui void SettingsWindow::onKeyboardSwitchClicked(MyGUI::Widget* _sender) { - if(mKeyboardMode) + if (mKeyboardMode) return; mKeyboardMode = true; mKeyboardSwitch->setStateSelected(true); @@ -686,7 +712,7 @@ namespace MWGui void SettingsWindow::onControllerSwitchClicked(MyGUI::Widget* _sender) { - if(!mKeyboardMode) + if (!mKeyboardMode) return; mKeyboardMode = false; mKeyboardSwitch->setStateSelected(false); @@ -702,26 +728,29 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->removeStaticMessageBox(); const auto inputManager = MWBase::Environment::get().getInputManager(); - const auto& actions = mKeyboardMode ? inputManager->getActionKeySorting() : inputManager->getActionControllerSorting(); + const auto& actions + = mKeyboardMode ? inputManager->getActionKeySorting() : inputManager->getActionControllerSorting(); for (const int& action : actions) { - std::string desc{inputManager->getActionDescription(action)}; + std::string desc{ inputManager->getActionDescription(action) }; if (desc.empty()) continue; std::string binding; - if(mKeyboardMode) + if (mKeyboardMode) binding = inputManager->getActionKeyBindingName(action); else binding = inputManager->getActionControllerBindingName(action); - Gui::SharedStateButton* leftText = mControlsBox->createWidget("SandTextButton", MyGUI::IntCoord(), MyGUI::Align::Default); + Gui::SharedStateButton* leftText = mControlsBox->createWidget( + "SandTextButton", MyGUI::IntCoord(), MyGUI::Align::Default); leftText->setCaptionWithReplacing(desc); - Gui::SharedStateButton* rightText = mControlsBox->createWidget("SandTextButton", MyGUI::IntCoord(), MyGUI::Align::Default); + Gui::SharedStateButton* rightText = mControlsBox->createWidget( + "SandTextButton", MyGUI::IntCoord(), MyGUI::Align::Default); rightText->setCaptionWithReplacing(binding); - rightText->setTextAlign (MyGUI::Align::Right); + rightText->setTextAlign(MyGUI::Align::Right); rightText->setUserData(action); // save the action id for callbacks rightText->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onRebindAction); rightText->eventMouseWheel += MyGUI::newDelegate(this, &SettingsWindow::onInputTabMouseWheel); @@ -753,7 +782,8 @@ namespace MWGui if (!MWBase::Environment::get().getResourceSystem()->getSceneManager()->isSupportedLightingMethod(method)) continue; - mLightingMethodButton->addItem(lightingMethodToStr(method), SceneUtil::LightManager::getLightingMethodString(method)); + mLightingMethodButton->addItem( + lightingMethodToStr(method), SceneUtil::LightManager::getLightingMethodString(method)); } mLightingMethodButton->setIndexSelected(mLightingMethodButton->findItemIndexWith(lightingMethodStr)); } @@ -774,18 +804,18 @@ namespace MWGui { std::string resStr = mResolutionList->getItemNameAt(mResolutionList->getIndexSelected()); int resX, resY; - parseResolution (resX, resY, resStr); + parseResolution(resX, resY, resStr); Settings::Manager::setInt("resolution x", "Video", resX); Settings::Manager::setInt("resolution y", "Video", resY); } bool supported = false; int fallbackX = 0, fallbackY = 0; - for (unsigned int i=0; igetItemCount(); ++i) + for (unsigned int i = 0; i < mResolutionList->getItemCount(); ++i) { std::string resStr = mResolutionList->getItemNameAt(i); int resX, resY; - parseResolution (resX, resY, resStr); + parseResolution(resX, resY, resStr); if (i == 0) { @@ -794,7 +824,7 @@ namespace MWGui } if (resX == Settings::Manager::getInt("resolution x", "Video") - && resY == Settings::Manager::getInt("resolution y", "Video")) + && resY == Settings::Manager::getInt("resolution y", "Video")) supported = true; } @@ -820,13 +850,14 @@ namespace MWGui for (size_t i = 0; i < mControlsBox->getChildCount(); i++) { - MyGUI::Widget * widget = mControlsBox->getChildAt(i); + MyGUI::Widget* widget = mControlsBox->getChildAt(i); widget->setCoord(0, i / noWidgetsInRow * h, w, h); } - // Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden + // Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the + // scrollbar is hidden mControlsBox->setVisibleVScroll(false); - mControlsBox->setCanvasSize (mControlsBox->getWidth(), std::max(totalH, mControlsBox->getHeight())); + mControlsBox->setCanvasSize(mControlsBox->getWidth(), std::max(totalH, mControlsBox->getHeight())); mControlsBox->setVisibleVScroll(true); } @@ -871,9 +902,10 @@ namespace MWGui mScriptAdapter->detach(); mScriptList->removeAllItems(); - mScriptView->setCanvasSize({0, 0}); + mScriptView->setCanvasSize({ 0, 0 }); - struct WeightedPage { + struct WeightedPage + { size_t mIndex; std::string mName; double mNameWeight; @@ -933,19 +965,19 @@ namespace MWGui _sender->castType()->setCaptionWithReplacing("#{sNone}"); - MWBase::Environment::get().getWindowManager ()->staticMessageBox ("#{sControlsMenu3}"); - MWBase::Environment::get().getWindowManager ()->disallowMouse(); - - MWBase::Environment::get().getInputManager ()->enableDetectingBindingMode (actionId, mKeyboardMode); + MWBase::Environment::get().getWindowManager()->staticMessageBox("#{sControlsMenu3}"); + MWBase::Environment::get().getWindowManager()->disallowMouse(); + MWBase::Environment::get().getInputManager()->enableDetectingBindingMode(actionId, mKeyboardMode); } void SettingsWindow::onInputTabMouseWheel(MyGUI::Widget* _sender, int _rel) { - if (mControlsBox->getViewOffset().top + _rel*0.3f > 0) + if (mControlsBox->getViewOffset().top + _rel * 0.3f > 0) mControlsBox->setViewOffset(MyGUI::IntPoint(0, 0)); else - mControlsBox->setViewOffset(MyGUI::IntPoint(0, static_cast(mControlsBox->getViewOffset().top + _rel*0.3f))); + mControlsBox->setViewOffset( + MyGUI::IntPoint(0, static_cast(mControlsBox->getViewOffset().top + _rel * 0.3f))); } void SettingsWindow::onResetDefaultBindings(MyGUI::Widget* _sender) @@ -959,11 +991,11 @@ namespace MWGui void SettingsWindow::onResetDefaultBindingsAccept() { - if(mKeyboardMode) - MWBase::Environment::get().getInputManager ()->resetToDefaultKeyBindings (); + if (mKeyboardMode) + MWBase::Environment::get().getInputManager()->resetToDefaultKeyBindings(); else MWBase::Environment::get().getInputManager()->resetToDefaultControllerBindings(); - updateControlsBox (); + updateControlsBox(); } void SettingsWindow::onOpen() @@ -977,7 +1009,7 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mOkButton); } - void SettingsWindow::onWindowResize(MyGUI::Window *_sender) + void SettingsWindow::onWindowResize(MyGUI::Window* _sender) { layoutControlsBox(); } diff --git a/apps/openmw/mwgui/settingswindow.hpp b/apps/openmw/mwgui/settingswindow.hpp index 5851457e9c..576ba2c627 100644 --- a/apps/openmw/mwgui/settingswindow.hpp +++ b/apps/openmw/mwgui/settingswindow.hpp @@ -9,103 +9,103 @@ namespace MWGui { class SettingsWindow : public WindowBase { - public: - SettingsWindow(); + public: + SettingsWindow(); - void onOpen() override; + void onOpen() override; - void updateControlsBox(); + void updateControlsBox(); - void updateLightSettings(); + void updateLightSettings(); - void updateWindowModeSettings(); + void updateWindowModeSettings(); - void onResChange(int, int) override { center(); } + void onResChange(int, int) override { center(); } protected: - MyGUI::TabControl* mSettingsTab; - MyGUI::Button* mOkButton; - - // graphics - MyGUI::ListBox* mResolutionList; - MyGUI::ComboBox* mWindowModeList; - MyGUI::Button* mWindowBorderButton; - MyGUI::ComboBox* mTextureFilteringButton; - - MyGUI::ComboBox* mWaterTextureSize; - MyGUI::ComboBox* mWaterReflectionDetail; - MyGUI::ComboBox* mWaterRainRippleDetail; - - MyGUI::ComboBox* mMaxLights; - MyGUI::ComboBox* mLightingMethodButton; - MyGUI::Button* mLightsResetButton; - - MyGUI::ComboBox* mPrimaryLanguage; - MyGUI::ComboBox* mSecondaryLanguage; - - // controls - MyGUI::ScrollView* mControlsBox; - MyGUI::Button* mResetControlsButton; - MyGUI::Button* mKeyboardSwitch; - MyGUI::Button* mControllerSwitch; - bool mKeyboardMode; //if true, setting up the keyboard. Otherwise, it's controller - - MyGUI::EditBox* mScriptFilter; - MyGUI::ListBox* mScriptList; - MyGUI::Widget* mScriptBox; - MyGUI::Widget* mScriptDisabled; - MyGUI::ScrollView* mScriptView; - LuaUi::LuaAdapter* mScriptAdapter; - int mCurrentPage; - - void onTabChanged(MyGUI::TabControl* _sender, size_t index); - void onOkButtonClicked(MyGUI::Widget* _sender); - void onTextureFilteringChanged(MyGUI::ComboBox* _sender, size_t pos); - void onSliderChangePosition(MyGUI::ScrollBar* scroller, size_t pos); - void onButtonToggled(MyGUI::Widget* _sender); - void onResolutionSelected(MyGUI::ListBox* _sender, size_t index); - void onResolutionAccept(); - void onResolutionCancel(); - void highlightCurrentResolution(); - - void onWaterTextureSizeChanged(MyGUI::ComboBox* _sender, size_t pos); - void onWaterReflectionDetailChanged(MyGUI::ComboBox* _sender, size_t pos); - void onWaterRainRippleDetailChanged(MyGUI::ComboBox* _sender, size_t pos); - - void onLightingMethodButtonChanged(MyGUI::ComboBox* _sender, size_t pos); - void onLightsResetButtonClicked(MyGUI::Widget* _sender); - void onMaxLightsChanged(MyGUI::ComboBox* _sender, size_t pos); - - void onPrimaryLanguageChanged(MyGUI::ComboBox* _sender, size_t pos) { onLanguageChanged(0, _sender, pos); } - void onSecondaryLanguageChanged(MyGUI::ComboBox* _sender, size_t pos) { onLanguageChanged(1, _sender, pos); } - void onLanguageChanged(size_t langPriority, MyGUI::ComboBox* _sender, size_t pos); - - void onWindowModeChanged(MyGUI::ComboBox* _sender, size_t pos); - - void onRebindAction(MyGUI::Widget* _sender); - void onInputTabMouseWheel(MyGUI::Widget* _sender, int _rel); - void onResetDefaultBindings(MyGUI::Widget* _sender); - void onResetDefaultBindingsAccept (); - void onKeyboardSwitchClicked(MyGUI::Widget* _sender); - void onControllerSwitchClicked(MyGUI::Widget* _sender); - - void onWindowResize(MyGUI::Window* _sender); - - void onScriptFilterChange(MyGUI::EditBox*); - void onScriptListSelection(MyGUI::ListBox*, size_t index); - - void apply(); - - void configureWidgets(MyGUI::Widget* widget, bool init); - void updateSliderLabel(MyGUI::ScrollBar* scroller, const std::string& value); - - void layoutControlsBox(); - void renderScriptSettings(); - - void computeMinimumWindowSize(); - - private: - void resetScrollbars(); + MyGUI::TabControl* mSettingsTab; + MyGUI::Button* mOkButton; + + // graphics + MyGUI::ListBox* mResolutionList; + MyGUI::ComboBox* mWindowModeList; + MyGUI::Button* mWindowBorderButton; + MyGUI::ComboBox* mTextureFilteringButton; + + MyGUI::ComboBox* mWaterTextureSize; + MyGUI::ComboBox* mWaterReflectionDetail; + MyGUI::ComboBox* mWaterRainRippleDetail; + + MyGUI::ComboBox* mMaxLights; + MyGUI::ComboBox* mLightingMethodButton; + MyGUI::Button* mLightsResetButton; + + MyGUI::ComboBox* mPrimaryLanguage; + MyGUI::ComboBox* mSecondaryLanguage; + + // controls + MyGUI::ScrollView* mControlsBox; + MyGUI::Button* mResetControlsButton; + MyGUI::Button* mKeyboardSwitch; + MyGUI::Button* mControllerSwitch; + bool mKeyboardMode; // if true, setting up the keyboard. Otherwise, it's controller + + MyGUI::EditBox* mScriptFilter; + MyGUI::ListBox* mScriptList; + MyGUI::Widget* mScriptBox; + MyGUI::Widget* mScriptDisabled; + MyGUI::ScrollView* mScriptView; + LuaUi::LuaAdapter* mScriptAdapter; + int mCurrentPage; + + void onTabChanged(MyGUI::TabControl* _sender, size_t index); + void onOkButtonClicked(MyGUI::Widget* _sender); + void onTextureFilteringChanged(MyGUI::ComboBox* _sender, size_t pos); + void onSliderChangePosition(MyGUI::ScrollBar* scroller, size_t pos); + void onButtonToggled(MyGUI::Widget* _sender); + void onResolutionSelected(MyGUI::ListBox* _sender, size_t index); + void onResolutionAccept(); + void onResolutionCancel(); + void highlightCurrentResolution(); + + void onWaterTextureSizeChanged(MyGUI::ComboBox* _sender, size_t pos); + void onWaterReflectionDetailChanged(MyGUI::ComboBox* _sender, size_t pos); + void onWaterRainRippleDetailChanged(MyGUI::ComboBox* _sender, size_t pos); + + void onLightingMethodButtonChanged(MyGUI::ComboBox* _sender, size_t pos); + void onLightsResetButtonClicked(MyGUI::Widget* _sender); + void onMaxLightsChanged(MyGUI::ComboBox* _sender, size_t pos); + + void onPrimaryLanguageChanged(MyGUI::ComboBox* _sender, size_t pos) { onLanguageChanged(0, _sender, pos); } + void onSecondaryLanguageChanged(MyGUI::ComboBox* _sender, size_t pos) { onLanguageChanged(1, _sender, pos); } + void onLanguageChanged(size_t langPriority, MyGUI::ComboBox* _sender, size_t pos); + + void onWindowModeChanged(MyGUI::ComboBox* _sender, size_t pos); + + void onRebindAction(MyGUI::Widget* _sender); + void onInputTabMouseWheel(MyGUI::Widget* _sender, int _rel); + void onResetDefaultBindings(MyGUI::Widget* _sender); + void onResetDefaultBindingsAccept(); + void onKeyboardSwitchClicked(MyGUI::Widget* _sender); + void onControllerSwitchClicked(MyGUI::Widget* _sender); + + void onWindowResize(MyGUI::Window* _sender); + + void onScriptFilterChange(MyGUI::EditBox*); + void onScriptListSelection(MyGUI::ListBox*, size_t index); + + void apply(); + + void configureWidgets(MyGUI::Widget* widget, bool init); + void updateSliderLabel(MyGUI::ScrollBar* scroller, const std::string& value); + + void layoutControlsBox(); + void renderScriptSettings(); + + void computeMinimumWindowSize(); + + private: + void resetScrollbars(); }; } diff --git a/apps/openmw/mwgui/sortfilteritemmodel.cpp b/apps/openmw/mwgui/sortfilteritemmodel.cpp index f3239f0186..35a9d792e0 100644 --- a/apps/openmw/mwgui/sortfilteritemmodel.cpp +++ b/apps/openmw/mwgui/sortfilteritemmodel.cpp @@ -1,27 +1,27 @@ #include "sortfilteritemmodel.hpp" -#include +#include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" #include #include #include #include #include #include +#include +#include #include -#include #include +#include #include #include #include #include -#include -#include -#include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" +#include #include "../mwworld/class.hpp" -#include "../mwworld/nullaction.hpp" #include "../mwworld/esmstore.hpp" +#include "../mwworld/nullaction.hpp" #include "../mwmechanics/alchemy.hpp" @@ -31,18 +31,30 @@ namespace { switch (type) { - case ESM::Weapon::sRecordId: return 0; - case ESM::Armor::sRecordId: return 1; - case ESM::Clothing::sRecordId: return 2; - case ESM::Potion::sRecordId: return 3; - case ESM::Ingredient::sRecordId: return 4; - case ESM::Apparatus::sRecordId: return 5; - case ESM::Book::sRecordId: return 6; - case ESM::Light::sRecordId: return 7; - case ESM::Miscellaneous::sRecordId: return 8; - case ESM::Lockpick::sRecordId: return 9; - case ESM::Repair::sRecordId: return 10; - case ESM::Probe::sRecordId: return 11; + case ESM::Weapon::sRecordId: + return 0; + case ESM::Armor::sRecordId: + return 1; + case ESM::Clothing::sRecordId: + return 2; + case ESM::Potion::sRecordId: + return 3; + case ESM::Ingredient::sRecordId: + return 4; + case ESM::Apparatus::sRecordId: + return 5; + case ESM::Book::sRecordId: + return 6; + case ESM::Light::sRecordId: + return 7; + case ESM::Miscellaneous::sRecordId: + return 8; + case ESM::Lockpick::sRecordId: + return 9; + case ESM::Repair::sRecordId: + return 10; + case ESM::Probe::sRecordId: + return 11; } assert(false && "Invalid type value"); return std::numeric_limits::max(); @@ -56,8 +68,11 @@ namespace struct Compare { bool mSortByType; - Compare() : mSortByType(true) {} - bool operator() (const MWGui::ItemStack& left, const MWGui::ItemStack& right) + Compare() + : mSortByType(true) + { + } + bool operator()(const MWGui::ItemStack& left, const MWGui::ItemStack& right) { if (mSortByType && left.mType != right.mType) return left.mType < right.mType; @@ -90,25 +105,29 @@ namespace if (!leftName.empty()) { - const ESM::Enchantment* ench = MWBase::Environment::get().getWorld()->getStore().get().search(leftName); + const ESM::Enchantment* ench + = MWBase::Environment::get().getWorld()->getStore().get().search(leftName); if (ench) { if (ench->mData.mType == ESM::Enchantment::ConstantEffect) leftChargePercent = 101; else - leftChargePercent = static_cast(left.mBase.getCellRef().getNormalizedEnchantmentCharge(ench->mData.mCharge) * 100); + leftChargePercent = static_cast( + left.mBase.getCellRef().getNormalizedEnchantmentCharge(ench->mData.mCharge) * 100); } } if (!rightName.empty()) { - const ESM::Enchantment* ench = MWBase::Environment::get().getWorld()->getStore().get().search(rightName); + const ESM::Enchantment* ench + = MWBase::Environment::get().getWorld()->getStore().get().search(rightName); if (ench) { if (ench->mData.mType == ESM::Enchantment::ConstantEffect) rightChargePercent = 101; else - rightChargePercent = static_cast(right.mBase.getCellRef().getNormalizedEnchantmentCharge(ench->mData.mCharge) * 100); + rightChargePercent = static_cast( + right.mBase.getCellRef().getNormalizedEnchantmentCharge(ench->mData.mCharge) * 100); } } @@ -119,13 +138,15 @@ namespace // compare items by condition if (left.mBase.getClass().hasItemHealth(left.mBase) && right.mBase.getClass().hasItemHealth(right.mBase)) { - result = left.mBase.getClass().getItemHealth(left.mBase) - right.mBase.getClass().getItemHealth(right.mBase); + result = left.mBase.getClass().getItemHealth(left.mBase) + - right.mBase.getClass().getItemHealth(right.mBase); if (result != 0) return result > 0; } // compare items by remaining usage time - result = left.mBase.getClass().getRemainingUsageTime(left.mBase) - right.mBase.getClass().getRemainingUsageTime(right.mBase); + result = left.mBase.getClass().getRemainingUsageTime(left.mBase) + - right.mBase.getClass().getRemainingUsageTime(right.mBase); if (result != 0) return result > 0; @@ -165,7 +186,7 @@ namespace MWGui return mSourceModel->allowedToUseItems(); } - void SortFilterItemModel::addDragItem (const MWWorld::Ptr& dragItem, size_t count) + void SortFilterItemModel::addDragItem(const MWWorld::Ptr& dragItem, size_t count) { mDragItems.emplace_back(dragItem, count); } @@ -175,7 +196,7 @@ namespace MWGui mDragItems.clear(); } - bool SortFilterItemModel::filterAccepts (const ItemStack& item) + bool SortFilterItemModel::filterAccepts(const ItemStack& item) { MWWorld::Ptr base = item.mBase; @@ -226,7 +247,7 @@ namespace MWGui if (!mEffectFilter.empty()) { - MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); const auto alchemySkill = player.getClass().getSkill(player, ESM::Skill::Alchemy); const auto effects = MWMechanics::Alchemy::effectsDescription(base, alchemySkill); @@ -245,19 +266,20 @@ namespace MWGui if ((mFilter & Filter_OnlyEnchanted) && !(item.mFlags & ItemStack::Flag_Enchanted)) return false; - if ((mFilter & Filter_OnlyChargedSoulstones) && (base.getType() != ESM::Miscellaneous::sRecordId - || base.getCellRef().getSoul() == "" || !MWBase::Environment::get().getWorld()->getStore().get().search(base.getCellRef().getSoul()))) + if ((mFilter & Filter_OnlyChargedSoulstones) + && (base.getType() != ESM::Miscellaneous::sRecordId || base.getCellRef().getSoul() == "" + || !MWBase::Environment::get().getWorld()->getStore().get().search( + base.getCellRef().getSoul()))) return false; if ((mFilter & Filter_OnlyRepairTools) && (base.getType() != ESM::Repair::sRecordId)) return false; - if ((mFilter & Filter_OnlyEnchantable) && (item.mFlags & ItemStack::Flag_Enchanted - || (base.getType() != ESM::Armor::sRecordId - && base.getType() != ESM::Clothing::sRecordId - && base.getType() != ESM::Weapon::sRecordId - && base.getType() != ESM::Book::sRecordId))) + if ((mFilter & Filter_OnlyEnchantable) + && (item.mFlags & ItemStack::Flag_Enchanted + || (base.getType() != ESM::Armor::sRecordId && base.getType() != ESM::Clothing::sRecordId + && base.getType() != ESM::Weapon::sRecordId && base.getType() != ESM::Book::sRecordId))) return false; if ((mFilter & Filter_OnlyEnchantable) && base.getType() == ESM::Book::sRecordId - && !base.get()->mBase->mData.mIsScroll) + && !base.get()->mBase->mData.mIsScroll) return false; if ((mFilter & Filter_OnlyUsableItems) && base.getClass().getScript(base).empty()) @@ -267,11 +289,10 @@ namespace MWGui return false; } - if ((mFilter & Filter_OnlyRepairable) && ( - !base.getClass().hasItemHealth(base) - || (base.getClass().getItemHealth(base) == base.getClass().getItemMaxHealth(base)) - || (base.getType() != ESM::Weapon::sRecordId - && base.getType() != ESM::Armor::sRecordId))) + if ((mFilter & Filter_OnlyRepairable) + && (!base.getClass().hasItemHealth(base) + || (base.getClass().getItemHealth(base) == base.getClass().getItemMaxHealth(base)) + || (base.getType() != ESM::Weapon::sRecordId && base.getType() != ESM::Armor::sRecordId))) return false; if (mFilter & Filter_OnlyRechargable) @@ -280,26 +301,28 @@ namespace MWGui return false; std::string_view enchId = base.getClass().getEnchantment(base); - const ESM::Enchantment* ench = MWBase::Environment::get().getWorld()->getStore().get().search(enchId); + const ESM::Enchantment* ench + = MWBase::Environment::get().getWorld()->getStore().get().search(enchId); if (!ench) { - Log(Debug::Warning) << "Warning: Can't find enchantment '" << enchId << "' on item " << base.getCellRef().getRefId(); + Log(Debug::Warning) << "Warning: Can't find enchantment '" << enchId << "' on item " + << base.getCellRef().getRefId(); return false; } if (base.getCellRef().getEnchantmentCharge() >= ench->mData.mCharge - || base.getCellRef().getEnchantmentCharge() == -1) + || base.getCellRef().getEnchantmentCharge() == -1) return false; } std::string compare = Utf8Stream::lowerCaseUtf8(item.mBase.getClass().getName(item.mBase)); - if(compare.find(mNameFilter) == std::string::npos) + if (compare.find(mNameFilter) == std::string::npos) return false; return true; } - ItemStack SortFilterItemModel::getItem (ModelIndex index) + ItemStack SortFilterItemModel::getItem(ModelIndex index) { if (index < 0) throw std::runtime_error("Invalid index supplied"); @@ -313,22 +336,22 @@ namespace MWGui return mItems.size(); } - void SortFilterItemModel::setCategory (int category) + void SortFilterItemModel::setCategory(int category) { mCategory = category; } - void SortFilterItemModel::setFilter (int filter) + void SortFilterItemModel::setFilter(int filter) { mFilter = filter; } - void SortFilterItemModel::setNameFilter (const std::string& filter) + void SortFilterItemModel::setNameFilter(const std::string& filter) { mNameFilter = Utf8Stream::lowerCaseUtf8(filter); } - void SortFilterItemModel::setEffectFilter (const std::string& filter) + void SortFilterItemModel::setEffectFilter(const std::string& filter) { mEffectFilter = Utf8Stream::lowerCaseUtf8(filter); } @@ -340,11 +363,12 @@ namespace MWGui size_t count = mSourceModel->getItemCount(); mItems.clear(); - for (size_t i=0; igetItem(i); - for (std::vector >::iterator it = mDragItems.begin(); it != mDragItems.end(); ++it) + for (std::vector>::iterator it = mDragItems.begin(); it != mDragItems.end(); + ++it) { if (item.mBase == it->first) { @@ -368,12 +392,12 @@ namespace MWGui mSourceModel->onClose(); } - bool SortFilterItemModel::onDropItem(const MWWorld::Ptr &item, int count) + bool SortFilterItemModel::onDropItem(const MWWorld::Ptr& item, int count) { return mSourceModel->onDropItem(item, count); } - bool SortFilterItemModel::onTakeItem(const MWWorld::Ptr &item, int count) + bool SortFilterItemModel::onTakeItem(const MWWorld::Ptr& item, int count) { return mSourceModel->onTakeItem(item, count); } diff --git a/apps/openmw/mwgui/sortfilteritemmodel.hpp b/apps/openmw/mwgui/sortfilteritemmodel.hpp index 2640737a89..66a22b3afa 100644 --- a/apps/openmw/mwgui/sortfilteritemmodel.hpp +++ b/apps/openmw/mwgui/sortfilteritemmodel.hpp @@ -13,48 +13,47 @@ namespace MWGui void update() override; - bool filterAccepts (const ItemStack& item); + bool filterAccepts(const ItemStack& item); bool allowedToUseItems() const override; - ItemStack getItem (ModelIndex index) override; + ItemStack getItem(ModelIndex index) override; size_t getItemCount() override; /// Dragged items are not displayed. - void addDragItem (const MWWorld::Ptr& dragItem, size_t count); + void addDragItem(const MWWorld::Ptr& dragItem, size_t count); void clearDragItems(); - void setCategory (int category); - void setFilter (int filter); - void setNameFilter (const std::string& filter); - void setEffectFilter (const std::string& filter); + void setCategory(int category); + void setFilter(int filter); + void setNameFilter(const std::string& filter); + void setEffectFilter(const std::string& filter); /// Use ItemStack::Type for sorting? void setSortByType(bool sort) { mSortByType = sort; } void onClose() override; - bool onDropItem(const MWWorld::Ptr &item, int count) override; - bool onTakeItem(const MWWorld::Ptr &item, int count) override; + bool onDropItem(const MWWorld::Ptr& item, int count) override; + bool onTakeItem(const MWWorld::Ptr& item, int count) override; - static constexpr int Category_Weapon = (1<<1); - static constexpr int Category_Apparel = (1<<2); - static constexpr int Category_Misc = (1<<3); - static constexpr int Category_Magic = (1<<4); + static constexpr int Category_Weapon = (1 << 1); + static constexpr int Category_Apparel = (1 << 2); + static constexpr int Category_Misc = (1 << 3); + static constexpr int Category_Magic = (1 << 4); static constexpr int Category_All = 255; - static constexpr int Filter_OnlyIngredients = (1<<0); - static constexpr int Filter_OnlyEnchanted = (1<<1); - static constexpr int Filter_OnlyEnchantable = (1<<2); - static constexpr int Filter_OnlyChargedSoulstones = (1<<3); - static constexpr int Filter_OnlyUsableItems = (1<<4); // Only items with a Use action - static constexpr int Filter_OnlyRepairable = (1<<5); - static constexpr int Filter_OnlyRechargable = (1<<6); - static constexpr int Filter_OnlyRepairTools = (1<<7); - + static constexpr int Filter_OnlyIngredients = (1 << 0); + static constexpr int Filter_OnlyEnchanted = (1 << 1); + static constexpr int Filter_OnlyEnchantable = (1 << 2); + static constexpr int Filter_OnlyChargedSoulstones = (1 << 3); + static constexpr int Filter_OnlyUsableItems = (1 << 4); // Only items with a Use action + static constexpr int Filter_OnlyRepairable = (1 << 5); + static constexpr int Filter_OnlyRechargable = (1 << 6); + static constexpr int Filter_OnlyRepairTools = (1 << 7); private: std::vector mItems; - std::vector > mDragItems; + std::vector> mDragItems; int mCategory; int mFilter; diff --git a/apps/openmw/mwgui/soulgemdialog.cpp b/apps/openmw/mwgui/soulgemdialog.cpp index 345c8b7221..8aaf182159 100644 --- a/apps/openmw/mwgui/soulgemdialog.cpp +++ b/apps/openmw/mwgui/soulgemdialog.cpp @@ -8,7 +8,7 @@ namespace MWGui { - void SoulgemDialog::show(const MWWorld::Ptr &soulgem) + void SoulgemDialog::show(const MWWorld::Ptr& soulgem) { mSoulgem = soulgem; std::vector buttons; diff --git a/apps/openmw/mwgui/soulgemdialog.hpp b/apps/openmw/mwgui/soulgemdialog.hpp index 9aea1f3393..775378f763 100644 --- a/apps/openmw/mwgui/soulgemdialog.hpp +++ b/apps/openmw/mwgui/soulgemdialog.hpp @@ -11,10 +11,12 @@ namespace MWGui class SoulgemDialog { public: - SoulgemDialog (MessageBoxManager* manager) - : mManager(manager) {} + SoulgemDialog(MessageBoxManager* manager) + : mManager(manager) + { + } - void show (const MWWorld::Ptr& soulgem); + void show(const MWWorld::Ptr& soulgem); void onButtonPressed(int button); diff --git a/apps/openmw/mwgui/spellbuyingwindow.cpp b/apps/openmw/mwgui/spellbuyingwindow.cpp index 0894e9e1f2..b0a58ddc02 100644 --- a/apps/openmw/mwgui/spellbuyingwindow.cpp +++ b/apps/openmw/mwgui/spellbuyingwindow.cpp @@ -1,32 +1,31 @@ #include "spellbuyingwindow.hpp" -#include #include +#include #include #include -#include #include - +#include #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" -#include "../mwbase/windowmanager.hpp" #include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" #include "../mwworld/class.hpp" #include "../mwworld/containerstore.hpp" #include "../mwworld/esmstore.hpp" #include "../mwmechanics/actorutil.hpp" -#include "../mwmechanics/spells.hpp" #include "../mwmechanics/creaturestats.hpp" +#include "../mwmechanics/spells.hpp" namespace MWGui { - SpellBuyingWindow::SpellBuyingWindow() : - WindowBase("openmw_spell_buying_window.layout") + SpellBuyingWindow::SpellBuyingWindow() + : WindowBase("openmw_spell_buying_window.layout") , mCurrentY(0) { getWidget(mCancelButton, "CancelButton"); @@ -36,18 +35,19 @@ namespace MWGui mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellBuyingWindow::onCancelButtonClicked); } - bool SpellBuyingWindow::sortSpells (const ESM::Spell* left, const ESM::Spell* right) + bool SpellBuyingWindow::sortSpells(const ESM::Spell* left, const ESM::Spell* right) { return Misc::StringUtils::ciLess(left->mName, right->mName); } void SpellBuyingWindow::addSpell(const ESM::Spell& spell) { - const MWWorld::ESMStore &store = - MWBase::Environment::get().getWorld()->getStore(); + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); - int price = std::max(1, static_cast(spell.mData.mCost*store.get().find("fSpellValueMult")->mValue.getFloat())); - price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr,price,true); + int price = std::max(1, + static_cast( + spell.mData.mCost * store.get().find("fSpellValueMult")->mValue.getFloat())); + price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, price, true); MWWorld::Ptr player = MWMechanics::getPlayer(); int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId); @@ -56,39 +56,34 @@ namespace MWGui int lineHeight = MWBase::Environment::get().getWindowManager()->getFontHeight() + 2; - MyGUI::Button* toAdd = - mSpellsView->createWidget( - price <= playerGold ? "SandTextButton" : "SandTextButtonDisabled", // can't use setEnabled since that removes tooltip - 0, - mCurrentY, - 200, - lineHeight, - MyGUI::Align::Default - ); + MyGUI::Button* toAdd = mSpellsView->createWidget(price <= playerGold + ? "SandTextButton" + : "SandTextButtonDisabled", // can't use setEnabled since that removes tooltip + 0, mCurrentY, 200, lineHeight, MyGUI::Align::Default); mCurrentY += lineHeight; toAdd->setUserData(price); - toAdd->setCaptionWithReplacing(spell.mName+" - "+MyGUI::utility::toString(price)+"#{sgp}"); + toAdd->setCaptionWithReplacing(spell.mName + " - " + MyGUI::utility::toString(price) + "#{sgp}"); toAdd->setSize(mSpellsView->getWidth(), lineHeight); toAdd->eventMouseWheel += MyGUI::newDelegate(this, &SpellBuyingWindow::onMouseWheel); toAdd->setUserString("ToolTipType", "Spell"); toAdd->setUserString("Spell", spell.mId); toAdd->setUserString("SpellCost", std::to_string(spell.mData.mCost)); toAdd->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellBuyingWindow::onSpellButtonClick); - mSpellsWidgetMap.insert(std::make_pair (toAdd, spell.mId)); + mSpellsWidgetMap.insert(std::make_pair(toAdd, spell.mId)); } void SpellBuyingWindow::clearSpells() { - mSpellsView->setViewOffset(MyGUI::IntPoint(0,0)); + mSpellsView->setViewOffset(MyGUI::IntPoint(0, 0)); mCurrentY = 0; while (mSpellsView->getChildCount()) MyGUI::Gui::getInstance().destroyWidget(mSpellsView->getChildAt(0)); mSpellsWidgetMap.clear(); } - void SpellBuyingWindow::setPtr(const MWWorld::Ptr &actor) + void SpellBuyingWindow::setPtr(const MWWorld::Ptr& actor) { setPtr(actor, 0); } @@ -99,20 +94,19 @@ namespace MWGui mPtr = actor; clearSpells(); - MWMechanics::Spells& merchantSpells = actor.getClass().getCreatureStats (actor).getSpells(); + MWMechanics::Spells& merchantSpells = actor.getClass().getCreatureStats(actor).getSpells(); std::vector spellsToSort; for (const ESM::Spell* spell : merchantSpells) { - if (spell->mData.mType!=ESM::Spell::ST_Spell) + if (spell->mData.mType != ESM::Spell::ST_Spell) continue; // don't try to sell diseases, curses or powers if (actor.getClass().isNpc()) { - const ESM::Race* race = - MWBase::Environment::get().getWorld()->getStore().get().find( - actor.get()->mBase->mRace); + const ESM::Race* race = MWBase::Environment::get().getWorld()->getStore().get().find( + actor.get()->mBase->mRace); if (race->mPowers.exists(spell->mId)) continue; } @@ -134,14 +128,16 @@ namespace MWGui updateLabels(); - // Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden + // Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the + // scrollbar is hidden mSpellsView->setVisibleVScroll(false); - mSpellsView->setCanvasSize (MyGUI::IntSize(mSpellsView->getWidth(), std::max(mSpellsView->getHeight(), mCurrentY))); + mSpellsView->setCanvasSize( + MyGUI::IntSize(mSpellsView->getWidth(), std::max(mSpellsView->getHeight(), mCurrentY))); mSpellsView->setVisibleVScroll(true); mSpellsView->setViewOffset(MyGUI::IntPoint(0, startOffset)); } - bool SpellBuyingWindow::playerHasSpell(const std::string &id) + bool SpellBuyingWindow::playerHasSpell(const std::string& id) { MWWorld::Ptr player = MWMechanics::getPlayer(); return player.getClass().getCreatureStats(player).getSpells().hasSpell(id); @@ -157,7 +153,7 @@ namespace MWGui MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player); MWMechanics::Spells& spells = stats.getSpells(); - spells.add (mSpellsWidgetMap.find(_sender)->second); + spells.add(mSpellsWidgetMap.find(_sender)->second); player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, price, player); // add gold to NPC trading gold pool @@ -171,7 +167,7 @@ namespace MWGui void SpellBuyingWindow::onCancelButtonClicked(MyGUI::Widget* _sender) { - MWBase::Environment::get().getWindowManager()->removeGuiMode (MWGui::GM_SpellBuying); + MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_SpellBuying); } void SpellBuyingWindow::updateLabels() @@ -180,25 +176,23 @@ namespace MWGui int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId); mPlayerGold->setCaptionWithReplacing("#{sGold}: " + MyGUI::utility::toString(playerGold)); - mPlayerGold->setCoord(8, - mPlayerGold->getTop(), - mPlayerGold->getTextSize().width, - mPlayerGold->getHeight()); + mPlayerGold->setCoord(8, mPlayerGold->getTop(), mPlayerGold->getTextSize().width, mPlayerGold->getHeight()); } void SpellBuyingWindow::onReferenceUnavailable() { - // remove both Spells and Dialogue (since you always trade with the NPC/creature that you have previously talked to) + // remove both Spells and Dialogue (since you always trade with the NPC/creature that you have previously talked + // to) MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_SpellBuying); MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode(); } void SpellBuyingWindow::onMouseWheel(MyGUI::Widget* _sender, int _rel) { - if (mSpellsView->getViewOffset().top + _rel*0.3 > 0) + if (mSpellsView->getViewOffset().top + _rel * 0.3 > 0) mSpellsView->setViewOffset(MyGUI::IntPoint(0, 0)); else - mSpellsView->setViewOffset(MyGUI::IntPoint(0, static_cast(mSpellsView->getViewOffset().top + _rel*0.3f))); + mSpellsView->setViewOffset( + MyGUI::IntPoint(0, static_cast(mSpellsView->getViewOffset().top + _rel * 0.3f))); } } - diff --git a/apps/openmw/mwgui/spellbuyingwindow.hpp b/apps/openmw/mwgui/spellbuyingwindow.hpp index f46c437963..17c49eb68c 100644 --- a/apps/openmw/mwgui/spellbuyingwindow.hpp +++ b/apps/openmw/mwgui/spellbuyingwindow.hpp @@ -1,8 +1,8 @@ #ifndef MWGUI_SpellBuyingWINDOW_H #define MWGUI_SpellBuyingWINDOW_H -#include "windowbase.hpp" #include "referenceinterface.hpp" +#include "windowbase.hpp" namespace ESM { @@ -11,48 +11,48 @@ namespace ESM namespace MyGUI { - class Gui; - class Widget; + class Gui; + class Widget; } namespace MWGui { class SpellBuyingWindow : public ReferenceInterface, public WindowBase { - public: - SpellBuyingWindow(); + public: + SpellBuyingWindow(); - void setPtr(const MWWorld::Ptr& actor) override; - void setPtr(const MWWorld::Ptr& actor, int startOffset); + void setPtr(const MWWorld::Ptr& actor) override; + void setPtr(const MWWorld::Ptr& actor, int startOffset); - void onFrame(float dt) override { checkReferenceAvailable(); } - void clear() override { resetReference(); } + void onFrame(float dt) override { checkReferenceAvailable(); } + void clear() override { resetReference(); } - void onResChange(int, int) override { center(); } + void onResChange(int, int) override { center(); } - protected: - MyGUI::Button* mCancelButton; - MyGUI::TextBox* mPlayerGold; + protected: + MyGUI::Button* mCancelButton; + MyGUI::TextBox* mPlayerGold; - MyGUI::ScrollView* mSpellsView; + MyGUI::ScrollView* mSpellsView; - std::map mSpellsWidgetMap; + std::map mSpellsWidgetMap; - void onCancelButtonClicked(MyGUI::Widget* _sender); - void onSpellButtonClick(MyGUI::Widget* _sender); - void onMouseWheel(MyGUI::Widget* _sender, int _rel); - void addSpell(const ESM::Spell& spell); - void clearSpells(); - int mCurrentY; + void onCancelButtonClicked(MyGUI::Widget* _sender); + void onSpellButtonClick(MyGUI::Widget* _sender); + void onMouseWheel(MyGUI::Widget* _sender, int _rel); + void addSpell(const ESM::Spell& spell); + void clearSpells(); + int mCurrentY; - void updateLabels(); + void updateLabels(); - void onReferenceUnavailable() override; + void onReferenceUnavailable() override; - bool playerHasSpell (const std::string& id); + bool playerHasSpell(const std::string& id); - private: - static bool sortSpells (const ESM::Spell* left, const ESM::Spell* right); + private: + static bool sortSpells(const ESM::Spell* left, const ESM::Spell* right); }; } diff --git a/apps/openmw/mwgui/spellcreationdialog.cpp b/apps/openmw/mwgui/spellcreationdialog.cpp index 43024a3db3..e57246b009 100644 --- a/apps/openmw/mwgui/spellcreationdialog.cpp +++ b/apps/openmw/mwgui/spellcreationdialog.cpp @@ -1,44 +1,44 @@ #include "spellcreationdialog.hpp" #include -#include #include +#include #include -#include #include #include +#include #include -#include "../mwbase/windowmanager.hpp" -#include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/windowmanager.hpp" #include "../mwbase/world.hpp" -#include "../mwworld/containerstore.hpp" #include "../mwworld/class.hpp" -#include "../mwworld/store.hpp" +#include "../mwworld/containerstore.hpp" #include "../mwworld/esmstore.hpp" +#include "../mwworld/store.hpp" -#include "../mwmechanics/spellutil.hpp" #include "../mwmechanics/actorutil.hpp" #include "../mwmechanics/creaturestats.hpp" +#include "../mwmechanics/spellutil.hpp" -#include "tooltips.hpp" #include "class.hpp" +#include "tooltips.hpp" #include "widgets.hpp" namespace { - bool sortMagicEffects (short id1, short id2) + bool sortMagicEffects(short id1, short id2) { - const MWWorld::Store &gmst = - MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& gmst + = MWBase::Environment::get().getWorld()->getStore().get(); - return gmst.find(ESM::MagicEffect::effectIdToString (id1))->mValue.getString() - < gmst.find(ESM::MagicEffect::effectIdToString (id2))->mValue.getString(); + return gmst.find(ESM::MagicEffect::effectIdToString(id1))->mValue.getString() + < gmst.find(ESM::MagicEffect::effectIdToString(id2))->mValue.getString(); } void init(ESM::ENAMstruct& effect) @@ -90,8 +90,10 @@ namespace MWGui mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &EditEffectDialog::onCancelButtonClicked); mDeleteButton->eventMouseButtonClick += MyGUI::newDelegate(this, &EditEffectDialog::onDeleteButtonClicked); - mMagnitudeMinSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &EditEffectDialog::onMagnitudeMinChanged); - mMagnitudeMaxSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &EditEffectDialog::onMagnitudeMaxChanged); + mMagnitudeMinSlider->eventScrollChangePosition + += MyGUI::newDelegate(this, &EditEffectDialog::onMagnitudeMinChanged); + mMagnitudeMaxSlider->eventScrollChangePosition + += MyGUI::newDelegate(this, &EditEffectDialog::onMagnitudeMaxChanged); mDurationSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &EditEffectDialog::onDurationChanged); mAreaSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &EditEffectDialog::onAreaChanged); } @@ -109,14 +111,14 @@ namespace MWGui bool EditEffectDialog::exit() { - if(mEditing) + if (mEditing) eventEffectModified(mOldEffect); else eventEffectRemoved(mEffect); return true; } - void EditEffectDialog::newEffect (const ESM::MagicEffect *effect) + void EditEffectDialog::newEffect(const ESM::MagicEffect* effect) { bool allowSelf = (effect->mData.mFlags & ESM::MagicEffect::CastSelf) != 0; bool allowTouch = (effect->mData.mFlags & ESM::MagicEffect::CastTouch) && !mConstantEffect; @@ -124,7 +126,7 @@ namespace MWGui setMagicEffect(effect); mEditing = false; - mDeleteButton->setVisible (false); + mDeleteButton->setVisible(false); mEffect.mRange = ESM::RT_Self; if (!allowSelf) @@ -141,14 +143,14 @@ namespace MWGui onRangeButtonClicked(mRangeButton); - mMagnitudeMinSlider->setScrollPosition (0); - mMagnitudeMaxSlider->setScrollPosition (0); - mAreaSlider->setScrollPosition (0); - mDurationSlider->setScrollPosition (0); + mMagnitudeMinSlider->setScrollPosition(0); + mMagnitudeMaxSlider->setScrollPosition(0); + mAreaSlider->setScrollPosition(0); + mDurationSlider->setScrollPosition(0); mDurationValue->setCaption("1"); mMagnitudeMinValue->setCaption("1"); - const std::string to{MWBase::Environment::get().getWindowManager()->getGameSettingString("sTo", "-")}; + const std::string to{ MWBase::Environment::get().getWindowManager()->getGameSettingString("sTo", "-") }; mMagnitudeMaxValue->setCaption(to + " 1"); mAreaValue->setCaption("0"); @@ -156,45 +158,45 @@ namespace MWGui setVisible(true); } - void EditEffectDialog::editEffect (ESM::ENAMstruct effect) + void EditEffectDialog::editEffect(ESM::ENAMstruct effect) { - const ESM::MagicEffect* magicEffect = - MWBase::Environment::get().getWorld()->getStore().get().find(effect.mEffectID); + const ESM::MagicEffect* magicEffect + = MWBase::Environment::get().getWorld()->getStore().get().find(effect.mEffectID); setMagicEffect(magicEffect); mOldEffect = effect; mEffect = effect; mEditing = true; - mDeleteButton->setVisible (true); + mDeleteButton->setVisible(true); - mMagnitudeMinSlider->setScrollPosition (effect.mMagnMin-1); - mMagnitudeMaxSlider->setScrollPosition (effect.mMagnMax-1); - mAreaSlider->setScrollPosition (effect.mArea); - mDurationSlider->setScrollPosition (effect.mDuration-1); + mMagnitudeMinSlider->setScrollPosition(effect.mMagnMin - 1); + mMagnitudeMaxSlider->setScrollPosition(effect.mMagnMax - 1); + mAreaSlider->setScrollPosition(effect.mArea); + mDurationSlider->setScrollPosition(effect.mDuration - 1); if (mEffect.mRange == ESM::RT_Self) - mRangeButton->setCaptionWithReplacing ("#{sRangeSelf}"); + mRangeButton->setCaptionWithReplacing("#{sRangeSelf}"); else if (mEffect.mRange == ESM::RT_Target) - mRangeButton->setCaptionWithReplacing ("#{sRangeTarget}"); + mRangeButton->setCaptionWithReplacing("#{sRangeTarget}"); else if (mEffect.mRange == ESM::RT_Touch) - mRangeButton->setCaptionWithReplacing ("#{sRangeTouch}"); + mRangeButton->setCaptionWithReplacing("#{sRangeTouch}"); - onMagnitudeMinChanged (mMagnitudeMinSlider, effect.mMagnMin-1); - onMagnitudeMaxChanged (mMagnitudeMinSlider, effect.mMagnMax-1); - onAreaChanged (mAreaSlider, effect.mArea); - onDurationChanged (mDurationSlider, effect.mDuration-1); + onMagnitudeMinChanged(mMagnitudeMinSlider, effect.mMagnMin - 1); + onMagnitudeMaxChanged(mMagnitudeMinSlider, effect.mMagnMax - 1); + onAreaChanged(mAreaSlider, effect.mArea); + onDurationChanged(mDurationSlider, effect.mDuration - 1); eventEffectModified(mEffect); updateBoxes(); } - void EditEffectDialog::setMagicEffect (const ESM::MagicEffect *effect) + void EditEffectDialog::setMagicEffect(const ESM::MagicEffect* effect) { - mEffectImage->setImageTexture(Misc::ResourceHelpers::correctIconPath(effect->mIcon, - MWBase::Environment::get().getResourceSystem()->getVFS())); + mEffectImage->setImageTexture(Misc::ResourceHelpers::correctIconPath( + effect->mIcon, MWBase::Environment::get().getResourceSystem()->getVFS())); - mEffectName->setCaptionWithReplacing("#{"+ESM::MagicEffect::effectIdToString (effect->mIndex)+"}"); + mEffectName->setCaptionWithReplacing("#{" + ESM::MagicEffect::effectIdToString(effect->mIndex) + "}"); mEffect.mEffectID = effect->mIndex; @@ -208,129 +210,131 @@ namespace MWGui static int startY = mMagnitudeBox->getPosition().top; int curY = startY; - mMagnitudeBox->setVisible (false); - mDurationBox->setVisible (false); - mAreaBox->setVisible (false); + mMagnitudeBox->setVisible(false); + mDurationBox->setVisible(false); + mAreaBox->setVisible(false); if (!(mMagicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude)) { mMagnitudeBox->setPosition(mMagnitudeBox->getPosition().left, curY); - mMagnitudeBox->setVisible (true); + mMagnitudeBox->setVisible(true); curY += mMagnitudeBox->getSize().height; } - if (!(mMagicEffect->mData.mFlags & ESM::MagicEffect::NoDuration)&&mConstantEffect==false) + if (!(mMagicEffect->mData.mFlags & ESM::MagicEffect::NoDuration) && mConstantEffect == false) { mDurationBox->setPosition(mDurationBox->getPosition().left, curY); - mDurationBox->setVisible (true); + mDurationBox->setVisible(true); curY += mDurationBox->getSize().height; } if (mEffect.mRange != ESM::RT_Self) { mAreaBox->setPosition(mAreaBox->getPosition().left, curY); - mAreaBox->setVisible (true); - //curY += mAreaBox->getSize().height; + mAreaBox->setVisible(true); + // curY += mAreaBox->getSize().height; } } - void EditEffectDialog::onRangeButtonClicked (MyGUI::Widget* sender) + void EditEffectDialog::onRangeButtonClicked(MyGUI::Widget* sender) { - mEffect.mRange = (mEffect.mRange+1)%3; + mEffect.mRange = (mEffect.mRange + 1) % 3; // cycle through range types until we find something that's allowed - // does not handle the case where nothing is allowed (this should be prevented before opening the Add Effect dialog) + // does not handle the case where nothing is allowed (this should be prevented before opening the Add Effect + // dialog) bool allowSelf = (mMagicEffect->mData.mFlags & ESM::MagicEffect::CastSelf) != 0; bool allowTouch = (mMagicEffect->mData.mFlags & ESM::MagicEffect::CastTouch) && !mConstantEffect; bool allowTarget = (mMagicEffect->mData.mFlags & ESM::MagicEffect::CastTarget) && !mConstantEffect; if (mEffect.mRange == ESM::RT_Self && !allowSelf) - mEffect.mRange = (mEffect.mRange+1)%3; + mEffect.mRange = (mEffect.mRange + 1) % 3; if (mEffect.mRange == ESM::RT_Touch && !allowTouch) - mEffect.mRange = (mEffect.mRange+1)%3; + mEffect.mRange = (mEffect.mRange + 1) % 3; if (mEffect.mRange == ESM::RT_Target && !allowTarget) - mEffect.mRange = (mEffect.mRange+1)%3; + mEffect.mRange = (mEffect.mRange + 1) % 3; - if(mEffect.mRange == ESM::RT_Self) + if (mEffect.mRange == ESM::RT_Self) { mAreaSlider->setScrollPosition(0); - onAreaChanged(mAreaSlider,0); + onAreaChanged(mAreaSlider, 0); } if (mEffect.mRange == ESM::RT_Self) - mRangeButton->setCaptionWithReplacing ("#{sRangeSelf}"); + mRangeButton->setCaptionWithReplacing("#{sRangeSelf}"); else if (mEffect.mRange == ESM::RT_Target) - mRangeButton->setCaptionWithReplacing ("#{sRangeTarget}"); + mRangeButton->setCaptionWithReplacing("#{sRangeTarget}"); else if (mEffect.mRange == ESM::RT_Touch) - mRangeButton->setCaptionWithReplacing ("#{sRangeTouch}"); + mRangeButton->setCaptionWithReplacing("#{sRangeTouch}"); updateBoxes(); eventEffectModified(mEffect); } - void EditEffectDialog::onDeleteButtonClicked (MyGUI::Widget* sender) + void EditEffectDialog::onDeleteButtonClicked(MyGUI::Widget* sender) { setVisible(false); eventEffectRemoved(mEffect); } - void EditEffectDialog::onOkButtonClicked (MyGUI::Widget* sender) + void EditEffectDialog::onOkButtonClicked(MyGUI::Widget* sender) { setVisible(false); } - void EditEffectDialog::onCancelButtonClicked (MyGUI::Widget* sender) + void EditEffectDialog::onCancelButtonClicked(MyGUI::Widget* sender) { setVisible(false); exit(); } - void EditEffectDialog::setSkill (int skill) + void EditEffectDialog::setSkill(int skill) { mEffect.mSkill = skill; eventEffectModified(mEffect); } - void EditEffectDialog::setAttribute (int attribute) + void EditEffectDialog::setAttribute(int attribute) { mEffect.mAttribute = attribute; eventEffectModified(mEffect); } - void EditEffectDialog::onMagnitudeMinChanged (MyGUI::ScrollBar* sender, size_t pos) + void EditEffectDialog::onMagnitudeMinChanged(MyGUI::ScrollBar* sender, size_t pos) { - mMagnitudeMinValue->setCaption(MyGUI::utility::toString(pos+1)); - mEffect.mMagnMin = pos+1; + mMagnitudeMinValue->setCaption(MyGUI::utility::toString(pos + 1)); + mEffect.mMagnMin = pos + 1; // trigger the check again (see below) - onMagnitudeMaxChanged(mMagnitudeMaxSlider, mMagnitudeMaxSlider->getScrollPosition ()); + onMagnitudeMaxChanged(mMagnitudeMaxSlider, mMagnitudeMaxSlider->getScrollPosition()); eventEffectModified(mEffect); } - void EditEffectDialog::onMagnitudeMaxChanged (MyGUI::ScrollBar* sender, size_t pos) + void EditEffectDialog::onMagnitudeMaxChanged(MyGUI::ScrollBar* sender, size_t pos) { // make sure the max value is actually larger or equal than the min value - size_t magnMin = std::abs(mEffect.mMagnMin); // should never be < 0, this is just here to avoid the compiler warning - if (pos+1 < magnMin) + size_t magnMin + = std::abs(mEffect.mMagnMin); // should never be < 0, this is just here to avoid the compiler warning + if (pos + 1 < magnMin) { - pos = mEffect.mMagnMin-1; - sender->setScrollPosition (pos); + pos = mEffect.mMagnMin - 1; + sender->setScrollPosition(pos); } - mEffect.mMagnMax = pos+1; - const std::string to{MWBase::Environment::get().getWindowManager()->getGameSettingString("sTo", "-")}; + mEffect.mMagnMax = pos + 1; + const std::string to{ MWBase::Environment::get().getWindowManager()->getGameSettingString("sTo", "-") }; - mMagnitudeMaxValue->setCaption(to + " " + MyGUI::utility::toString(pos+1)); + mMagnitudeMaxValue->setCaption(to + " " + MyGUI::utility::toString(pos + 1)); eventEffectModified(mEffect); } - void EditEffectDialog::onDurationChanged (MyGUI::ScrollBar* sender, size_t pos) + void EditEffectDialog::onDurationChanged(MyGUI::ScrollBar* sender, size_t pos) { - mDurationValue->setCaption(MyGUI::utility::toString(pos+1)); - mEffect.mDuration = pos+1; + mDurationValue->setCaption(MyGUI::utility::toString(pos + 1)); + mEffect.mDuration = pos + 1; eventEffectModified(mEffect); } - void EditEffectDialog::onAreaChanged (MyGUI::ScrollBar* sender, size_t pos) + void EditEffectDialog::onAreaChanged(MyGUI::ScrollBar* sender, size_t pos) { mAreaValue->setCaption(MyGUI::utility::toString(pos)); mEffect.mArea = pos; @@ -359,7 +363,7 @@ namespace MWGui setWidgets(mAvailableEffectsList, mUsedEffectsView); } - void SpellCreationDialog::setPtr (const MWWorld::Ptr& actor) + void SpellCreationDialog::setPtr(const MWWorld::Ptr& actor) { mPtr = actor; mNameEdit->setCaption(""); @@ -367,28 +371,28 @@ namespace MWGui startEditing(); } - void SpellCreationDialog::onCancelButtonClicked (MyGUI::Widget* sender) + void SpellCreationDialog::onCancelButtonClicked(MyGUI::Widget* sender) { - MWBase::Environment::get().getWindowManager()->removeGuiMode (MWGui::GM_SpellCreation); + MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_SpellCreation); } - void SpellCreationDialog::onBuyButtonClicked (MyGUI::Widget* sender) + void SpellCreationDialog::onBuyButtonClicked(MyGUI::Widget* sender) { if (mEffects.size() <= 0) { - MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage30}"); + MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage30}"); return; } - if (mNameEdit->getCaption () == "") + if (mNameEdit->getCaption() == "") { - MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage10}"); + MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage10}"); return; } if (mMagickaCost->getCaption() == "0") { - MWBase::Environment::get().getWindowManager()->messageBox ("#{sEnchantmentMenu8}"); + MWBase::Environment::get().getWindowManager()->messageBox("#{sEnchantmentMenu8}"); return; } @@ -398,7 +402,7 @@ namespace MWGui int price = MyGUI::utility::parseInt(mPriceLabel->getCaption()); if (price > playerGold) { - MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage18}"); + MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage18}"); return; } @@ -410,18 +414,18 @@ namespace MWGui MWMechanics::CreatureStats& npcStats = mPtr.getClass().getCreatureStats(mPtr); npcStats.setGoldPool(npcStats.getGoldPool() + price); - MWBase::Environment::get().getWindowManager()->playSound ("Mysticism Hit"); + MWBase::Environment::get().getWindowManager()->playSound("Mysticism Hit"); const ESM::Spell* spell = MWBase::Environment::get().getWorld()->createRecord(mSpell); MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player); MWMechanics::Spells& spells = stats.getSpells(); - spells.add (spell->mId); + spells.add(spell->mId); - MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_SpellCreation); + MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_SpellCreation); } - void SpellCreationDialog::onAccept(MyGUI::EditBox *sender) + void SpellCreationDialog::onAccept(MyGUI::EditBox* sender) { onBuyButtonClicked(sender); @@ -435,13 +439,13 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mNameEdit); } - void SpellCreationDialog::onReferenceUnavailable () + void SpellCreationDialog::onReferenceUnavailable() { - MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_Dialogue); - MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_SpellCreation); + MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Dialogue); + MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_SpellCreation); } - void SpellCreationDialog::notifyEffectsChanged () + void SpellCreationDialog::notifyEffectsChanged() { if (mEffects.empty()) { @@ -453,12 +457,12 @@ namespace MWGui float y = 0; - const MWWorld::ESMStore &store = - MWBase::Environment::get().getWorld()->getStore(); + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); for (const ESM::ENAMstruct& effect : mEffects) { - y += std::max(1.f, MWMechanics::calcEffectCost(effect, nullptr, MWMechanics::EffectCostMethod::PlayerSpell)); + y += std::max( + 1.f, MWMechanics::calcEffectCost(effect, nullptr, MWMechanics::EffectCostMethod::PlayerSpell)); if (effect.mRange == ESM::RT_Target) y *= 1.5; @@ -473,8 +477,7 @@ namespace MWGui mMagickaCost->setCaption(MyGUI::utility::toString(int(y))); - float fSpellMakingValueMult = - store.get().find("fSpellMakingValueMult")->mValue.getFloat(); + float fSpellMakingValueMult = store.get().find("fSpellMakingValueMult")->mValue.getFloat(); int price = std::max(1, static_cast(y * fSpellMakingValueMult)); price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, price, true); @@ -489,7 +492,6 @@ namespace MWGui // ------------------------------------------------------------------------------------------------ - EffectEditorBase::EffectEditorBase(Type type) : mAvailableEffectsList(nullptr) , mUsedEffectsView(nullptr) @@ -503,14 +505,12 @@ namespace MWGui mAddEffectDialog.eventEffectModified += MyGUI::newDelegate(this, &EffectEditorBase::onEffectModified); mAddEffectDialog.eventEffectRemoved += MyGUI::newDelegate(this, &EffectEditorBase::onEffectRemoved); - mAddEffectDialog.setVisible (false); + mAddEffectDialog.setVisible(false); } - EffectEditorBase::~EffectEditorBase() - { - } + EffectEditorBase::~EffectEditorBase() {} - void EffectEditorBase::startEditing () + void EffectEditorBase::startEditing() { // get the list of magic effects that are known to the player @@ -528,10 +528,13 @@ namespace MWGui for (const ESM::ENAMstruct& effectInfo : spell->mEffects.mList) { - const ESM::MagicEffect * effect = MWBase::Environment::get().getWorld()->getStore().get().find(effectInfo.mEffectID); + const ESM::MagicEffect* effect + = MWBase::Environment::get().getWorld()->getStore().get().find( + effectInfo.mEffectID); // skip effects that do not allow spellmaking/enchanting - int requiredFlags = (mType == Spellmaking) ? ESM::MagicEffect::AllowSpellmaking : ESM::MagicEffect::AllowEnchanting; + int requiredFlags + = (mType == Spellmaking) ? ESM::MagicEffect::AllowSpellmaking : ESM::MagicEffect::AllowEnchanting; if (!(effect->mData.mFlags & requiredFlags)) continue; @@ -542,61 +545,70 @@ namespace MWGui std::sort(knownEffects.begin(), knownEffects.end(), sortMagicEffects); - mAvailableEffectsList->clear (); + mAvailableEffectsList->clear(); - int i=0; + int i = 0; for (const short effectId : knownEffects) { - mAvailableEffectsList->addItem(MWBase::Environment::get().getWorld ()->getStore ().get().find( - ESM::MagicEffect::effectIdToString(effectId))->mValue.getString()); + mAvailableEffectsList->addItem(MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find(ESM::MagicEffect::effectIdToString(effectId)) + ->mValue.getString()); mButtonMapping[i] = effectId; ++i; } - mAvailableEffectsList->adjustSize (); + mAvailableEffectsList->adjustSize(); mAvailableEffectsList->scrollToTop(); for (const short effectId : knownEffects) { - const std::string& name = MWBase::Environment::get().getWorld ()->getStore ().get().find( - ESM::MagicEffect::effectIdToString(effectId))->mValue.getString(); + const std::string& name = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find(ESM::MagicEffect::effectIdToString(effectId)) + ->mValue.getString(); MyGUI::Widget* w = mAvailableEffectsList->getItemWidget(name); - ToolTips::createMagicEffectToolTip (w, effectId); + ToolTips::createMagicEffectToolTip(w, effectId); } mEffects.clear(); - updateEffectsView (); + updateEffectsView(); } - void EffectEditorBase::setWidgets (Gui::MWList *availableEffectsList, MyGUI::ScrollView *usedEffectsView) + void EffectEditorBase::setWidgets(Gui::MWList* availableEffectsList, MyGUI::ScrollView* usedEffectsView) { mAvailableEffectsList = availableEffectsList; mUsedEffectsView = usedEffectsView; - mAvailableEffectsList->eventWidgetSelected += MyGUI::newDelegate(this, &EffectEditorBase::onAvailableEffectClicked); + mAvailableEffectsList->eventWidgetSelected + += MyGUI::newDelegate(this, &EffectEditorBase::onAvailableEffectClicked); } - void EffectEditorBase::onSelectAttribute () + void EffectEditorBase::onSelectAttribute() { - const ESM::MagicEffect* effect = - MWBase::Environment::get().getWorld()->getStore().get().find(mSelectedKnownEffectId); + const ESM::MagicEffect* effect + = MWBase::Environment::get().getWorld()->getStore().get().find(mSelectedKnownEffectId); mAddEffectDialog.newEffect(effect); - mAddEffectDialog.setAttribute (mSelectAttributeDialog->getAttributeId()); + mAddEffectDialog.setAttribute(mSelectAttributeDialog->getAttributeId()); MWBase::Environment::get().getWindowManager()->removeDialog(std::move(mSelectAttributeDialog)); } - void EffectEditorBase::onSelectSkill () + void EffectEditorBase::onSelectSkill() { - const ESM::MagicEffect* effect = - MWBase::Environment::get().getWorld()->getStore().get().find(mSelectedKnownEffectId); + const ESM::MagicEffect* effect + = MWBase::Environment::get().getWorld()->getStore().get().find(mSelectedKnownEffectId); mAddEffectDialog.newEffect(effect); - mAddEffectDialog.setSkill (mSelectSkillDialog->getSkillId()); + mAddEffectDialog.setSkill(mSelectSkillDialog->getSkillId()); MWBase::Environment::get().getWindowManager()->removeDialog(std::move(mSelectSkillDialog)); } - void EffectEditorBase::onAttributeOrSkillCancel () + void EffectEditorBase::onAttributeOrSkillCancel() { if (mSelectSkillDialog != nullptr) MWBase::Environment::get().getWindowManager()->removeDialog(std::move(mSelectSkillDialog)); @@ -604,7 +616,7 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->removeDialog(std::move(mSelectAttributeDialog)); } - void EffectEditorBase::onAvailableEffectClicked (MyGUI::Widget* sender) + void EffectEditorBase::onAvailableEffectClicked(MyGUI::Widget* sender) { if (mEffects.size() >= 8) { @@ -615,8 +627,8 @@ namespace MWGui int buttonId = *sender->getUserData(); mSelectedKnownEffectId = mButtonMapping[buttonId]; - const ESM::MagicEffect* effect = - MWBase::Environment::get().getWorld()->getStore().get().find(mSelectedKnownEffectId); + const ESM::MagicEffect* effect + = MWBase::Environment::get().getWorld()->getStore().get().find(mSelectedKnownEffectId); bool allowSelf = (effect->mData.mFlags & ESM::MagicEffect::CastSelf) != 0; bool allowTouch = (effect->mData.mFlags & ESM::MagicEffect::CastTouch) && !mConstantEffect; @@ -630,14 +642,16 @@ namespace MWGui mSelectSkillDialog = std::make_unique(); mSelectSkillDialog->eventCancel += MyGUI::newDelegate(this, &SpellCreationDialog::onAttributeOrSkillCancel); mSelectSkillDialog->eventItemSelected += MyGUI::newDelegate(this, &SpellCreationDialog::onSelectSkill); - mSelectSkillDialog->setVisible (true); + mSelectSkillDialog->setVisible(true); } else if (effect->mData.mFlags & ESM::MagicEffect::TargetAttribute) { mSelectAttributeDialog = std::make_unique(); - mSelectAttributeDialog->eventCancel += MyGUI::newDelegate(this, &SpellCreationDialog::onAttributeOrSkillCancel); - mSelectAttributeDialog->eventItemSelected += MyGUI::newDelegate(this, &SpellCreationDialog::onSelectAttribute); - mSelectAttributeDialog->setVisible (true); + mSelectAttributeDialog->eventCancel + += MyGUI::newDelegate(this, &SpellCreationDialog::onAttributeOrSkillCancel); + mSelectAttributeDialog->eventItemSelected + += MyGUI::newDelegate(this, &SpellCreationDialog::onSelectAttribute); + mSelectAttributeDialog->setVisible(true); } else { @@ -645,7 +659,7 @@ namespace MWGui { if (effectInfo.mEffectID == mSelectedKnownEffectId) { - MWBase::Environment::get().getWindowManager()->messageBox ("#{sOnetypeEffectMessage}"); + MWBase::Environment::get().getWindowManager()->messageBox("#{sOnetypeEffectMessage}"); return; } } @@ -654,25 +668,25 @@ namespace MWGui } } - void EffectEditorBase::onEffectModified (ESM::ENAMstruct effect) + void EffectEditorBase::onEffectModified(ESM::ENAMstruct effect) { mEffects[mSelectedEffect] = effect; updateEffectsView(); } - void EffectEditorBase::onEffectRemoved (ESM::ENAMstruct effect) + void EffectEditorBase::onEffectRemoved(ESM::ENAMstruct effect) { mEffects.erase(mEffects.begin() + mSelectedEffect); updateEffectsView(); } - void EffectEditorBase::updateEffectsView () + void EffectEditorBase::updateEffectsView() { - MyGUI::EnumeratorWidgetPtr oldWidgets = mUsedEffectsView->getEnumerator (); - MyGUI::Gui::getInstance ().destroyWidgets (oldWidgets); + MyGUI::EnumeratorWidgetPtr oldWidgets = mUsedEffectsView->getEnumerator(); + MyGUI::Gui::getInstance().destroyWidgets(oldWidgets); - MyGUI::IntSize size(0,0); + MyGUI::IntSize size(0, 0); int i = 0; for (const ESM::ENAMstruct& effectInfo : mEffects) @@ -688,25 +702,28 @@ namespace MWGui params.mArea = effectInfo.mArea; params.mIsConstant = mConstantEffect; - MyGUI::Button* button = mUsedEffectsView->createWidget("", MyGUI::IntCoord(0, size.height, 0, 24), MyGUI::Align::Default); + MyGUI::Button* button = mUsedEffectsView->createWidget( + "", MyGUI::IntCoord(0, size.height, 0, 24), MyGUI::Align::Default); button->setUserData(i); button->eventMouseButtonClick += MyGUI::newDelegate(this, &SpellCreationDialog::onEditEffect); - button->setNeedMouseFocus (true); + button->setNeedMouseFocus(true); - Widgets::MWSpellEffectPtr effect = button->createWidget("MW_EffectImage", MyGUI::IntCoord(0,0,0,24), MyGUI::Align::Default); + Widgets::MWSpellEffectPtr effect = button->createWidget( + "MW_EffectImage", MyGUI::IntCoord(0, 0, 0, 24), MyGUI::Align::Default); - effect->setNeedMouseFocus (false); - effect->setSpellEffect (params); + effect->setNeedMouseFocus(false); + effect->setSpellEffect(params); - effect->setSize(effect->getRequestedWidth (), 24); - button->setSize(effect->getRequestedWidth (), 24); + effect->setSize(effect->getRequestedWidth(), 24); + button->setSize(effect->getRequestedWidth(), 24); - size.width = std::max(size.width, effect->getRequestedWidth ()); + size.width = std::max(size.width, effect->getRequestedWidth()); size.height += 24; ++i; } - // Canvas size must be expressed with HScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden + // Canvas size must be expressed with HScroll disabled, otherwise MyGUI would expand the scroll area when the + // scrollbar is hidden mUsedEffectsView->setVisibleHScroll(false); mUsedEffectsView->setCanvasSize(size); mUsedEffectsView->setVisibleHScroll(true); @@ -714,22 +731,22 @@ namespace MWGui notifyEffectsChanged(); } - void EffectEditorBase::onEffectAdded (ESM::ENAMstruct effect) + void EffectEditorBase::onEffectAdded(ESM::ENAMstruct effect) { mEffects.push_back(effect); - mSelectedEffect=mEffects.size()-1; + mSelectedEffect = mEffects.size() - 1; updateEffectsView(); } - void EffectEditorBase::onEditEffect (MyGUI::Widget *sender) + void EffectEditorBase::onEditEffect(MyGUI::Widget* sender) { int id = *sender->getUserData(); mSelectedEffect = id; - mAddEffectDialog.editEffect (mEffects[id]); - mAddEffectDialog.setVisible (true); + mAddEffectDialog.editEffect(mEffects[id]); + mAddEffectDialog.setVisible(true); } void EffectEditorBase::setConstantEffect(bool constant) diff --git a/apps/openmw/mwgui/spellcreationdialog.hpp b/apps/openmw/mwgui/spellcreationdialog.hpp index 683455d557..d79494dae2 100644 --- a/apps/openmw/mwgui/spellcreationdialog.hpp +++ b/apps/openmw/mwgui/spellcreationdialog.hpp @@ -6,8 +6,8 @@ #include #include -#include "windowbase.hpp" #include "referenceinterface.hpp" +#include "windowbase.hpp" namespace Gui { @@ -33,8 +33,8 @@ namespace MWGui void setSkill(int skill); void setAttribute(int attribute); - void newEffect (const ESM::MagicEffect* effect); - void editEffect (ESM::ENAMstruct effect); + void newEffect(const ESM::MagicEffect* effect); + void editEffect(ESM::ENAMstruct effect); typedef MyGUI::delegates::CMultiDelegate1 EventHandle_Effect; EventHandle_Effect eventEffectAdded; @@ -70,15 +70,15 @@ namespace MWGui bool mEditing; protected: - void onRangeButtonClicked (MyGUI::Widget* sender); - void onDeleteButtonClicked (MyGUI::Widget* sender); - void onOkButtonClicked (MyGUI::Widget* sender); - void onCancelButtonClicked (MyGUI::Widget* sender); - - void onMagnitudeMinChanged (MyGUI::ScrollBar* sender, size_t pos); - void onMagnitudeMaxChanged (MyGUI::ScrollBar* sender, size_t pos); - void onDurationChanged (MyGUI::ScrollBar* sender, size_t pos); - void onAreaChanged (MyGUI::ScrollBar* sender, size_t pos); + void onRangeButtonClicked(MyGUI::Widget* sender); + void onDeleteButtonClicked(MyGUI::Widget* sender); + void onOkButtonClicked(MyGUI::Widget* sender); + void onCancelButtonClicked(MyGUI::Widget* sender); + + void onMagnitudeMinChanged(MyGUI::ScrollBar* sender, size_t pos); + void onMagnitudeMaxChanged(MyGUI::ScrollBar* sender, size_t pos); + void onDurationChanged(MyGUI::ScrollBar* sender, size_t pos); + void onAreaChanged(MyGUI::ScrollBar* sender, size_t pos); void setMagicEffect(const ESM::MagicEffect* effect); void updateBoxes(); @@ -92,7 +92,6 @@ namespace MWGui bool mConstantEffect; }; - class EffectEditorBase { public: @@ -128,7 +127,7 @@ namespace MWGui void onEffectModified(ESM::ENAMstruct effect); void onEffectRemoved(ESM::ENAMstruct effect); - void onAvailableEffectClicked (MyGUI::Widget* sender); + void onAvailableEffectClicked(MyGUI::Widget* sender); void onAttributeOrSkillCancel(); void onSelectAttribute(); @@ -139,9 +138,9 @@ namespace MWGui void updateEffectsView(); void startEditing(); - void setWidgets (Gui::MWList* availableEffectsList, MyGUI::ScrollView* usedEffectsView); + void setWidgets(Gui::MWList* availableEffectsList, MyGUI::ScrollView* usedEffectsView); - virtual void notifyEffectsChanged () {} + virtual void notifyEffectsChanged() {} private: Type mType; @@ -162,8 +161,8 @@ namespace MWGui protected: void onReferenceUnavailable() override; - void onCancelButtonClicked (MyGUI::Widget* sender); - void onBuyButtonClicked (MyGUI::Widget* sender); + void onCancelButtonClicked(MyGUI::Widget* sender); + void onBuyButtonClicked(MyGUI::Widget* sender); void onAccept(MyGUI::EditBox* sender); void notifyEffectsChanged() override; @@ -176,7 +175,6 @@ namespace MWGui MyGUI::TextBox* mPriceLabel; ESM::Spell mSpell; - }; } diff --git a/apps/openmw/mwgui/spellicons.cpp b/apps/openmw/mwgui/spellicons.cpp index 60ea47683b..be59dfb171 100644 --- a/apps/openmw/mwgui/spellicons.cpp +++ b/apps/openmw/mwgui/spellicons.cpp @@ -1,42 +1,41 @@ #include "spellicons.hpp" -#include #include +#include #include #include -#include #include #include +#include -#include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" #include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" #include "../mwworld/inventorystore.hpp" -#include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/actorutil.hpp" +#include "../mwmechanics/creaturestats.hpp" #include "tooltips.hpp" - namespace MWGui { - void SpellIcons::updateWidgets(MyGUI::Widget *parent, bool adjustSize) + void SpellIcons::updateWidgets(MyGUI::Widget* parent, bool adjustSize) { MWWorld::Ptr player = MWMechanics::getPlayer(); const MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player); std::map> effects; - for(const auto& params : stats.getActiveSpells()) + for (const auto& params : stats.getActiveSpells()) { - for(const auto& effect : params.getEffects()) + for (const auto& effect : params.getEffects()) { - if(!(effect.mFlags & ESM::ActiveEffect::Flag_Applied)) + if (!(effect.mFlags & ESM::ActiveEffect::Flag_Applied)) continue; MagicEffectInfo newEffectSource; newEffectSource.mKey = MWMechanics::EffectKey(effect.mEffectId, effect.mArg); @@ -49,19 +48,24 @@ namespace MWGui } } - int w=2; + int w = 2; for (const auto& [effectId, effectInfos] : effects) { - const ESM::MagicEffect* effect = - MWBase::Environment::get().getWorld ()->getStore ().get().find(effectId); + const ESM::MagicEffect* effect + = MWBase::Environment::get().getWorld()->getStore().get().find(effectId); float remainingDuration = 0; float totalDuration = 0; std::string sourcesDescription; - static const float fadeTime = MWBase::Environment::get().getWorld()->getStore().get().find("fMagicStartIconBlink")->mValue.getFloat(); + static const float fadeTime = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fMagicStartIconBlink") + ->mValue.getFloat(); bool addNewLine = false; for (const MagicEffectInfo& effectInfo : effectInfos) @@ -86,53 +90,64 @@ namespace MWGui if (effect->mData.mFlags & ESM::MagicEffect::TargetSkill) { sourcesDescription += " ("; - sourcesDescription += MWBase::Environment::get().getWindowManager()->getGameSettingString(ESM::Skill::sSkillNameIds[effectInfo.mKey.mArg], {}); + sourcesDescription += MWBase::Environment::get().getWindowManager()->getGameSettingString( + ESM::Skill::sSkillNameIds[effectInfo.mKey.mArg], {}); sourcesDescription += ')'; } if (effect->mData.mFlags & ESM::MagicEffect::TargetAttribute) { sourcesDescription += " ("; - sourcesDescription += MWBase::Environment::get().getWindowManager()->getGameSettingString(ESM::Attribute::sGmstAttributeIds[effectInfo.mKey.mArg], {}); + sourcesDescription += MWBase::Environment::get().getWindowManager()->getGameSettingString( + ESM::Attribute::sGmstAttributeIds[effectInfo.mKey.mArg], {}); sourcesDescription += ')'; } ESM::MagicEffect::MagnitudeDisplayType displayType = effect->getMagnitudeDisplayType(); if (displayType == ESM::MagicEffect::MDT_TimesInt) { - std::string_view timesInt = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimesINT", {}); + std::string_view timesInt + = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimesINT", {}); std::stringstream formatter; - formatter << std::fixed << std::setprecision(1) << " " << (effectInfo.mMagnitude / 10.0f) << timesInt; + formatter << std::fixed << std::setprecision(1) << " " << (effectInfo.mMagnitude / 10.0f) + << timesInt; sourcesDescription += formatter.str(); } - else if ( displayType != ESM::MagicEffect::MDT_None ) + else if (displayType != ESM::MagicEffect::MDT_None) { sourcesDescription += ": " + MyGUI::utility::toString(effectInfo.mMagnitude); - if ( displayType == ESM::MagicEffect::MDT_Percentage ) - sourcesDescription += MWBase::Environment::get().getWindowManager()->getGameSettingString("spercent", {}); - else if ( displayType == ESM::MagicEffect::MDT_Feet ) + if (displayType == ESM::MagicEffect::MDT_Percentage) + sourcesDescription + += MWBase::Environment::get().getWindowManager()->getGameSettingString("spercent", {}); + else if (displayType == ESM::MagicEffect::MDT_Feet) { sourcesDescription += ' '; - sourcesDescription += MWBase::Environment::get().getWindowManager()->getGameSettingString("sfeet", {}); + sourcesDescription + += MWBase::Environment::get().getWindowManager()->getGameSettingString("sfeet", {}); } - else if ( displayType == ESM::MagicEffect::MDT_Level ) + else if (displayType == ESM::MagicEffect::MDT_Level) { sourcesDescription += ' '; if (effectInfo.mMagnitude > 1) - sourcesDescription += MWBase::Environment::get().getWindowManager()->getGameSettingString("sLevels", {}); + sourcesDescription + += MWBase::Environment::get().getWindowManager()->getGameSettingString("sLevels", {}); else - sourcesDescription += MWBase::Environment::get().getWindowManager()->getGameSettingString("sLevel", {}); + sourcesDescription + += MWBase::Environment::get().getWindowManager()->getGameSettingString("sLevel", {}); } else // ESM::MagicEffect::MDT_Points { sourcesDescription += ' '; if (effectInfo.mMagnitude > 1) - sourcesDescription += MWBase::Environment::get().getWindowManager()->getGameSettingString("spoints", {}); + sourcesDescription + += MWBase::Environment::get().getWindowManager()->getGameSettingString("spoints", {}); else - sourcesDescription += MWBase::Environment::get().getWindowManager()->getGameSettingString("spoint", {}); + sourcesDescription + += MWBase::Environment::get().getWindowManager()->getGameSettingString("spoint", {}); } } - if (effectInfo.mRemainingTime > -1 && Settings::Manager::getBool("show effect duration","Game")) - sourcesDescription += MWGui::ToolTips::getDurationString(effectInfo.mRemainingTime, " #{sDuration}"); + if (effectInfo.mRemainingTime > -1 && Settings::Manager::getBool("show effect duration", "Game")) + sourcesDescription + += MWGui::ToolTips::getDurationString(effectInfo.mRemainingTime, " #{sDuration}"); addNewLine = true; } @@ -142,12 +157,12 @@ namespace MWGui MyGUI::ImageBox* image; if (mWidgetMap.find(effectId) == mWidgetMap.end()) { - image = parent->createWidget - ("ImageBox", MyGUI::IntCoord(w,2,16,16), MyGUI::Align::Default); + image = parent->createWidget( + "ImageBox", MyGUI::IntCoord(w, 2, 16, 16), MyGUI::Align::Default); mWidgetMap[effectId] = image; - image->setImageTexture(Misc::ResourceHelpers::correctIconPath(effect->mIcon, - MWBase::Environment::get().getResourceSystem()->getVFS())); + image->setImageTexture(Misc::ResourceHelpers::correctIconPath( + effect->mIcon, MWBase::Environment::get().getResourceSystem()->getVFS())); const std::string& name = ESM::MagicEffect::effectIdToString(effectId); @@ -163,7 +178,7 @@ namespace MWGui else image = mWidgetMap[effectId]; - image->setPosition(w,2); + image->setPosition(w, 2); image->setVisible(true); w += 16; @@ -172,7 +187,7 @@ namespace MWGui // Fade out if (totalDuration >= fadeTime && fadeTime > 0.f) - image->setAlpha(std::min(remainingDuration/fadeTime, 1.f)); + image->setAlpha(std::min(remainingDuration / fadeTime, 1.f)); } else if (mWidgetMap.find(effectId) != mWidgetMap.end()) { @@ -189,7 +204,7 @@ namespace MWGui s = 0; int diff = parent->getWidth() - s; parent->setSize(s, parent->getHeight()); - parent->setPosition(parent->getLeft()+diff, parent->getTop()); + parent->setPosition(parent->getLeft() + diff, parent->getTop()); } // hide inactive effects diff --git a/apps/openmw/mwgui/spellicons.hpp b/apps/openmw/mwgui/spellicons.hpp index 9825162a33..e53fa98284 100644 --- a/apps/openmw/mwgui/spellicons.hpp +++ b/apps/openmw/mwgui/spellicons.hpp @@ -28,7 +28,8 @@ namespace MWGui , mRemainingTime(0.f) , mTotalTime(0.f) , mPermanent(false) - {} + { + } std::string mSource; // display name for effect source (e.g. potion name) MWMechanics::EffectKey mKey; int mMagnitude; @@ -43,7 +44,6 @@ namespace MWGui void updateWidgets(MyGUI::Widget* parent, bool adjustSize); private: - std::map mWidgetMap; }; diff --git a/apps/openmw/mwgui/spellmodel.cpp b/apps/openmw/mwgui/spellmodel.cpp index a6972b90e4..af428587f7 100644 --- a/apps/openmw/mwgui/spellmodel.cpp +++ b/apps/openmw/mwgui/spellmodel.cpp @@ -3,19 +3,19 @@ #include #include -#include #include +#include #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" #include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/spellutil.hpp" +#include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" #include "../mwworld/inventorystore.hpp" -#include "../mwworld/class.hpp" namespace { @@ -32,21 +32,21 @@ namespace namespace MWGui { - SpellModel::SpellModel(const MWWorld::Ptr &actor, const std::string& filter) - : mActor(actor), mFilter(filter) + SpellModel::SpellModel(const MWWorld::Ptr& actor, const std::string& filter) + : mActor(actor) + , mFilter(filter) { } - SpellModel::SpellModel(const MWWorld::Ptr &actor) + SpellModel::SpellModel(const MWWorld::Ptr& actor) : mActor(actor) { } - bool SpellModel::matchingEffectExists(std::string filter, const ESM::EffectList &effects) + bool SpellModel::matchingEffectExists(std::string filter, const ESM::EffectList& effects) { auto wm = MWBase::Environment::get().getWindowManager(); - const MWWorld::ESMStore &store = - MWBase::Environment::get().getWorld()->getStore(); + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); for (const auto& effect : effects.mList) { @@ -54,10 +54,9 @@ namespace MWGui if (effectId != -1) { - const ESM::MagicEffect *magicEffect = - store.get().find(effectId); + const ESM::MagicEffect* magicEffect = store.get().find(effectId); const std::string& effectIDStr = ESM::MagicEffect::effectIdToString(effectId); - std::string fullEffectName{wm->getGameSettingString(effectIDStr, {})}; + std::string fullEffectName{ wm->getGameSettingString(effectIDStr, {}) }; if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetSkill && effect.mSkill != -1) { @@ -68,7 +67,8 @@ namespace MWGui if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetAttribute && effect.mAttribute != -1) { fullEffectName += ' '; - fullEffectName += wm->getGameSettingString(ESM::Attribute::sGmstAttributeIds[effect.mAttribute], {}); + fullEffectName + += wm->getGameSettingString(ESM::Attribute::sGmstAttributeIds[effect.mAttribute], {}); } std::string convert = Utf8Stream::lowerCaseUtf8(fullEffectName); @@ -89,8 +89,7 @@ namespace MWGui MWMechanics::CreatureStats& stats = mActor.getClass().getCreatureStats(mActor); const MWMechanics::Spells& spells = stats.getSpells(); - const MWWorld::ESMStore &esmStore = - MWBase::Environment::get().getWorld()->getStore(); + const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); std::string filter = Utf8Stream::lowerCaseUtf8(mFilter); @@ -100,9 +99,8 @@ namespace MWGui continue; std::string name = Utf8Stream::lowerCaseUtf8(spell->mName); - - if (name.find(filter) == std::string::npos - && !matchingEffectExists(filter, spell->mEffects)) + + if (name.find(filter) == std::string::npos && !matchingEffectExists(filter, spell->mEffects)) continue; Spell newSpell; @@ -134,17 +132,18 @@ namespace MWGui const ESM::Enchantment* enchant = esmStore.get().search(enchantId); if (!enchant) { - Log(Debug::Warning) << "Warning: Can't find enchantment '" << enchantId << "' on item " << item.getCellRef().getRefId(); + Log(Debug::Warning) << "Warning: Can't find enchantment '" << enchantId << "' on item " + << item.getCellRef().getRefId(); continue; } - if (enchant->mData.mType != ESM::Enchantment::WhenUsed && enchant->mData.mType != ESM::Enchantment::CastOnce) + if (enchant->mData.mType != ESM::Enchantment::WhenUsed + && enchant->mData.mType != ESM::Enchantment::CastOnce) continue; std::string name = Utf8Stream::lowerCaseUtf8(item.getClass().getName(item)); - if (name.find(filter) == std::string::npos - && !matchingEffectExists(filter, enchant->mEffects)) + if (name.find(filter) == std::string::npos && !matchingEffectExists(filter, enchant->mEffects)) continue; Spell newSpell; @@ -164,14 +163,15 @@ namespace MWGui else { if (!item.getClass().getEquipmentSlots(item).first.empty() - && item.getClass().canBeEquipped(item, mActor).first == 0) + && item.getClass().canBeEquipped(item, mActor).first == 0) continue; - int castCost = MWMechanics::getEffectiveEnchantmentCastCost(static_cast(enchant->mData.mCost), mActor); + int castCost + = MWMechanics::getEffectiveEnchantmentCastCost(static_cast(enchant->mData.mCost), mActor); std::string cost = std::to_string(castCost); int currentCharge = int(item.getCellRef().getEnchantmentCharge()); - if (currentCharge == -1) + if (currentCharge == -1) currentCharge = enchant->mData.mCharge; std::string charge = std::to_string(currentCharge); newSpell.mCostColumn = cost + "/" + charge; @@ -192,9 +192,10 @@ namespace MWGui SpellModel::ModelIndex SpellModel::getSelectedIndex() const { ModelIndex selected = -1; - for (SpellModel::ModelIndex i = 0; i -#include -#include #include +#include +#include #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" -#include #include +#include #include "tooltips.hpp" @@ -18,12 +18,12 @@ namespace MWGui const char* SpellView::sSpellModelIndex = "SpellModelIndex"; - SpellView::LineInfo::LineInfo(MyGUI::Widget* leftWidget, MyGUI::Widget* rightWidget, SpellModel::ModelIndex spellIndex) + SpellView::LineInfo::LineInfo( + MyGUI::Widget* leftWidget, MyGUI::Widget* rightWidget, SpellModel::ModelIndex spellIndex) : mLeftWidget(leftWidget) , mRightWidget(rightWidget) , mSpellIndex(spellIndex) { - } SpellView::SpellView() @@ -49,7 +49,7 @@ namespace MWGui MyGUI::FactoryManager::getInstance().registerFactory("Widget"); } - void SpellView::setModel(SpellModel *model) + void SpellView::setModel(SpellModel* model) { mModel.reset(model); update(); @@ -94,7 +94,7 @@ namespace MWGui while (mScrollView->getChildCount()) MyGUI::Gui::getInstance().destroyWidget(mScrollView->getChildAt(0)); - for (SpellModel::ModelIndex i = 0; igetItemCount()); ++i) + for (SpellModel::ModelIndex i = 0; i < int(mModel->getItemCount()); ++i) { const Spell& spell = mModel->getItem(i); if (curType != spell.mType) @@ -111,8 +111,8 @@ namespace MWGui const std::string skin = spell.mActive ? "SandTextButton" : "SpellTextUnequipped"; const std::string captionSuffix = MWGui::ToolTips::getCountString(spell.mCount); - Gui::SharedStateButton* t = mScrollView->createWidget(skin, - MyGUI::IntCoord(0, 0, 0, spellHeight), MyGUI::Align::Left | MyGUI::Align::Top); + Gui::SharedStateButton* t = mScrollView->createWidget( + skin, MyGUI::IntCoord(0, 0, 0, spellHeight), MyGUI::Align::Left | MyGUI::Align::Top); t->setNeedKeyFocus(true); t->setCaption(spell.mName + captionSuffix); t->setTextAlign(MyGUI::Align::Left); @@ -120,8 +120,8 @@ namespace MWGui if (!spell.mCostColumn.empty() && mShowCostColumn) { - Gui::SharedStateButton* costChance = mScrollView->createWidget(skin, - MyGUI::IntCoord(0, 0, 0, spellHeight), MyGUI::Align::Left | MyGUI::Align::Top); + Gui::SharedStateButton* costChance = mScrollView->createWidget( + skin, MyGUI::IntCoord(0, 0, 0, spellHeight), MyGUI::Align::Left | MyGUI::Align::Top); costChance->setCaption(spell.mCostColumn); costChance->setTextAlign(MyGUI::Align::Right); adjustSpellWidget(spell, i, costChance); @@ -190,14 +190,12 @@ namespace MWGui // special case, look for spells added to model that are beyond last updatable item SpellModel::ModelIndex topSpellIndex = mModel->getItemCount() - 1; - if (fullUpdateRequired || - ((0 <= topSpellIndex) && (maxSpellIndexFound < topSpellIndex))) + if (fullUpdateRequired || ((0 <= topSpellIndex) && (maxSpellIndexFound < topSpellIndex))) { update(); } } - void SpellView::layoutWidgets() { int height = 0; @@ -225,26 +223,25 @@ namespace MWGui height += lineHeight; } - // Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden + // Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the + // scrollbar is hidden mScrollView->setVisibleVScroll(false); mScrollView->setCanvasSize(mScrollView->getWidth(), std::max(mScrollView->getHeight(), height)); mScrollView->setVisibleVScroll(true); } - void SpellView::addGroup(const std::string &label, const std::string& label2) + void SpellView::addGroup(const std::string& label, const std::string& label2) { if (mScrollView->getChildCount() > 0) { - MyGUI::ImageBox* separator = mScrollView->createWidget("MW_HLine", - MyGUI::IntCoord(0, 0, mScrollView->getWidth(), 18), - MyGUI::Align::Left | MyGUI::Align::Top); + MyGUI::ImageBox* separator = mScrollView->createWidget( + "MW_HLine", MyGUI::IntCoord(0, 0, mScrollView->getWidth(), 18), MyGUI::Align::Left | MyGUI::Align::Top); separator->setNeedMouseFocus(false); mLines.emplace_back(separator, (MyGUI::Widget*)nullptr, NoSpellIndex); } MyGUI::TextBox* groupWidget = mScrollView->createWidget("SandBrightText", - MyGUI::IntCoord(0, 0, mScrollView->getWidth(), 24), - MyGUI::Align::Left | MyGUI::Align::Top); + MyGUI::IntCoord(0, 0, mScrollView->getWidth(), 24), MyGUI::Align::Left | MyGUI::Align::Top); groupWidget->setCaptionWithReplacing(label); groupWidget->setTextAlign(MyGUI::Align::Left); groupWidget->setNeedMouseFocus(false); @@ -252,8 +249,7 @@ namespace MWGui if (label2 != "") { MyGUI::TextBox* groupWidget2 = mScrollView->createWidget("SandBrightText", - MyGUI::IntCoord(0, 0, mScrollView->getWidth(), 24), - MyGUI::Align::Left | MyGUI::Align::Top); + MyGUI::IntCoord(0, 0, mScrollView->getWidth(), 24), MyGUI::Align::Left | MyGUI::Align::Top); groupWidget2->setCaptionWithReplacing(label2); groupWidget2->setTextAlign(MyGUI::Align::Right); groupWidget2->setNeedMouseFocus(false); @@ -264,8 +260,7 @@ namespace MWGui mLines.emplace_back(groupWidget, (MyGUI::Widget*)nullptr, NoSpellIndex); } - - void SpellView::setSize(const MyGUI::IntSize &_value) + void SpellView::setSize(const MyGUI::IntSize& _value) { bool changed = (_value.width != getWidth() || _value.height != getHeight()); Base::setSize(_value); @@ -273,7 +268,7 @@ namespace MWGui layoutWidgets(); } - void SpellView::setCoord(const MyGUI::IntCoord &_value) + void SpellView::setCoord(const MyGUI::IntCoord& _value) { bool changed = (_value.width != getWidth() || _value.height != getHeight()); Base::setCoord(_value); @@ -281,7 +276,7 @@ namespace MWGui layoutWidgets(); } - void SpellView::adjustSpellWidget(const Spell &spell, SpellModel::ModelIndex index, MyGUI::Widget *widget) + void SpellView::adjustSpellWidget(const Spell& spell, SpellModel::ModelIndex index, MyGUI::Widget* widget) { if (spell.mType == Spell::Type_EnchantedItem) { @@ -312,10 +307,11 @@ namespace MWGui void SpellView::onMouseWheelMoved(MyGUI::Widget* _sender, int _rel) { - if (mScrollView->getViewOffset().top + _rel*0.3f > 0) + if (mScrollView->getViewOffset().top + _rel * 0.3f > 0) mScrollView->setViewOffset(MyGUI::IntPoint(0, 0)); else - mScrollView->setViewOffset(MyGUI::IntPoint(0, static_cast(mScrollView->getViewOffset().top + _rel*0.3f))); + mScrollView->setViewOffset( + MyGUI::IntPoint(0, static_cast(mScrollView->getViewOffset().top + _rel * 0.3f))); } void SpellView::resetScrollbars() diff --git a/apps/openmw/mwgui/spellview.hpp b/apps/openmw/mwgui/spellview.hpp index 6b3effc453..8805aaf2ab 100644 --- a/apps/openmw/mwgui/spellview.hpp +++ b/apps/openmw/mwgui/spellview.hpp @@ -26,7 +26,7 @@ namespace MWGui SpellView(); /// Register needed components with MyGUI's factory manager - static void registerComponents (); + static void registerComponents(); /// Should the cost/chance column be shown? void setShowCostColumn(bool show); @@ -34,7 +34,7 @@ namespace MWGui void setHighlightSelected(bool highlight); /// Takes ownership of \a model - void setModel (SpellModel* model); + void setModel(SpellModel* model); SpellModel* getModel(); @@ -75,9 +75,12 @@ namespace MWGui }; /// magic number indicating LineInfo does not correspond to an item in mModel - enum { NoSpellIndex = -1 }; + enum + { + NoSpellIndex = -1 + }; - std::vector< LineInfo > mLines; + std::vector mLines; bool mShowCostColumn; bool mHighlightSelected; diff --git a/apps/openmw/mwgui/spellwindow.cpp b/apps/openmw/mwgui/spellwindow.cpp index f35d435f0c..59312a33af 100644 --- a/apps/openmw/mwgui/spellwindow.cpp +++ b/apps/openmw/mwgui/spellwindow.cpp @@ -3,28 +3,28 @@ #include #include -#include -#include -#include #include +#include +#include +#include -#include "../mwbase/windowmanager.hpp" #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" -#include "../mwworld/inventorystore.hpp" #include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" +#include "../mwworld/inventorystore.hpp" #include "../mwworld/player.hpp" -#include "../mwmechanics/spellutil.hpp" -#include "../mwmechanics/spells.hpp" -#include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/actorutil.hpp" +#include "../mwmechanics/creaturestats.hpp" +#include "../mwmechanics/spells.hpp" +#include "../mwmechanics/spellutil.hpp" -#include "spellicons.hpp" #include "confirmationdialog.hpp" +#include "spellicons.hpp" #include "spellview.hpp" namespace MWGui @@ -81,7 +81,7 @@ namespace MWGui updateSpells(); } - void SpellWindow::onFrame(float dt) + void SpellWindow::onFrame(float dt) { NoDrop::onFrame(dt); mUpdateTimer += dt; @@ -121,8 +121,7 @@ namespace MWGui throw std::runtime_error("can't find selected item"); // equip, if it can be equipped and is not already equipped - if (!alreadyEquipped - && !item.getClass().getEquipmentSlots(item).first.empty()) + if (!alreadyEquipped && !item.getClass().getEquipmentSlots(item).first.empty()) { MWBase::Environment::get().getWindowManager()->useItem(item); // make sure that item was successfully equipped @@ -137,11 +136,10 @@ namespace MWGui updateSpells(); } - void SpellWindow::askDeleteSpell(const std::string &spellId) + void SpellWindow::askDeleteSpell(const std::string& spellId) { // delete spell, if allowed - const ESM::Spell* spell = - MWBase::Environment::get().getWorld()->getStore().get().find(spellId); + const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get().find(spellId); MWWorld::Ptr player = MWMechanics::getPlayer(); const std::string& raceId = player.get()->mBase->mRace; @@ -151,7 +149,8 @@ namespace MWGui const std::string& signId = MWBase::Environment::get().getWorld()->getPlayer().getBirthSign(); if (!isInherent && !signId.empty()) { - const ESM::BirthSign* sign = MWBase::Environment::get().getWorld()->getStore().get().find(signId); + const ESM::BirthSign* sign + = MWBase::Environment::get().getWorld()->getStore().get().find(signId); isInherent = sign->mPowers.exists(spell->mId); } @@ -165,7 +164,7 @@ namespace MWGui // ask for confirmation mSpellToDelete = spellId; ConfirmationDialog* dialog = windowManager->getConfirmationDialog(); - std::string question{windowManager->getGameSettingString("sQuestionDeleteSpell", "Delete %s?")}; + std::string question{ windowManager->getGameSettingString("sQuestionDeleteSpell", "Delete %s?") }; question = Misc::StringUtils::format(question, spell->mName); dialog->askForConfirmation(question); dialog->eventOkClicked.clear(); @@ -190,12 +189,12 @@ namespace MWGui } } - void SpellWindow::onFilterChanged(MyGUI::EditBox *sender) + void SpellWindow::onFilterChanged(MyGUI::EditBox* sender) { mSpellView->setModel(new SpellModel(MWMechanics::getPlayer(), sender->getCaption())); } - void SpellWindow::onDeleteClicked(MyGUI::Widget *widget) + void SpellWindow::onDeleteClicked(MyGUI::Widget* widget) { SpellModel::ModelIndex selected = mSpellView->getModel()->getSelectedIndex(); if (selected < 0) @@ -211,7 +210,8 @@ namespace MWGui MWWorld::Ptr player = MWMechanics::getPlayer(); MWWorld::InventoryStore& store = player.getClass().getInventoryStore(player); store.setSelectedEnchantItem(store.end()); - MWBase::Environment::get().getWindowManager()->setSelectedSpell(spellId, int(MWMechanics::getSpellSuccessChance(spellId, player))); + MWBase::Environment::get().getWindowManager()->setSelectedSpell( + spellId, int(MWMechanics::getSpellSuccessChance(spellId, player))); updateSpells(); } @@ -238,7 +238,7 @@ namespace MWGui return; bool godmode = MWBase::Environment::get().getWorld()->getGodModeState(); - const MWMechanics::CreatureStats &stats = player.getClass().getCreatureStats(player); + const MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player); if ((!godmode && stats.isParalyzed()) || stats.getKnockedDown() || stats.isDead() || stats.getHitRecovery()) return; diff --git a/apps/openmw/mwgui/spellwindow.hpp b/apps/openmw/mwgui/spellwindow.hpp index f7176bebd6..7e2e7e267f 100644 --- a/apps/openmw/mwgui/spellwindow.hpp +++ b/apps/openmw/mwgui/spellwindow.hpp @@ -31,8 +31,8 @@ namespace MWGui void onEnchantedItemSelected(MWWorld::Ptr item, bool alreadyEquipped); void onSpellSelected(const std::string& spellId); void onModelIndexSelected(SpellModel::ModelIndex index); - void onFilterChanged(MyGUI::EditBox *sender); - void onDeleteClicked(MyGUI::Widget *widget); + void onFilterChanged(MyGUI::EditBox* sender); + void onDeleteClicked(MyGUI::Widget* widget); void onDeleteSpellAccept(); void askDeleteSpell(const std::string& spellId); diff --git a/apps/openmw/mwgui/statswatcher.cpp b/apps/openmw/mwgui/statswatcher.cpp index 46be15542a..1318173a60 100644 --- a/apps/openmw/mwgui/statswatcher.cpp +++ b/apps/openmw/mwgui/statswatcher.cpp @@ -1,7 +1,7 @@ #include "statswatcher.hpp" -#include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" @@ -21,7 +21,9 @@ namespace MWGui // mWatchedTimeToStartDrowning = -1 for correct drowning state check, // if stats.getTimeToStartDrowning() == 0 already on game start StatsWatcher::StatsWatcher() - : mWatchedLevel(-1), mWatchedTimeToStartDrowning(-1), mWatchedStatsEmpty(true) + : mWatchedLevel(-1) + , mWatchedTimeToStartDrowning(-1) + , mWatchedStatsEmpty(true) { } @@ -35,9 +37,9 @@ namespace MWGui if (mWatched.isEmpty()) return; - MWBase::WindowManager *winMgr = MWBase::Environment::get().getWindowManager(); - const MWMechanics::NpcStats &stats = mWatched.getClass().getNpcStats(mWatched); - for (int i = 0;i < ESM::Attribute::Length;++i) + MWBase::WindowManager* winMgr = MWBase::Environment::get().getWindowManager(); + const MWMechanics::NpcStats& stats = mWatched.getClass().getNpcStats(mWatched); + for (int i = 0; i < ESM::Attribute::Length; ++i) { if (stats.getAttribute(i) != mWatchedAttributes[i] || mWatchedStatsEmpty) { @@ -69,12 +71,16 @@ namespace MWGui if (timeToDrown != mWatchedTimeToStartDrowning) { - static const float fHoldBreathTime = MWBase::Environment::get().getWorld()->getStore().get() - .find("fHoldBreathTime")->mValue.getFloat(); + static const float fHoldBreathTime = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fHoldBreathTime") + ->mValue.getFloat(); mWatchedTimeToStartDrowning = timeToDrown; - if(timeToDrown >= fHoldBreathTime || timeToDrown == -1.0) // -1.0 is a special value during initialization + if (timeToDrown >= fHoldBreathTime || timeToDrown == -1.0) // -1.0 is a special value during initialization winMgr->setDrowningBarVisibility(false); else { @@ -83,10 +89,10 @@ namespace MWGui } } - //Loop over ESM::Skill::SkillEnum + // Loop over ESM::Skill::SkillEnum for (int i = 0; i < ESM::Skill::Length; ++i) { - if(stats.getSkill(i) != mWatchedSkills[i] || mWatchedStatsEmpty) + if (stats.getSkill(i) != mWatchedSkills[i] || mWatchedStatsEmpty) { mWatchedSkills[i] = stats.getSkill(i); setValue((ESM::Skill::SkillEnum)i, stats.getSkill(i)); @@ -101,7 +107,7 @@ namespace MWGui if (mWatched.getClass().isNpc()) { - const ESM::NPC *watchedRecord = mWatched.get()->mBase; + const ESM::NPC* watchedRecord = mWatched.get()->mBase; if (watchedRecord->mName != mWatchedName || mWatchedStatsEmpty) { @@ -112,22 +118,22 @@ namespace MWGui if (watchedRecord->mRace != mWatchedRace || mWatchedStatsEmpty) { mWatchedRace = watchedRecord->mRace; - const ESM::Race *race = MWBase::Environment::get().getWorld()->getStore() - .get().find(watchedRecord->mRace); + const ESM::Race* race + = MWBase::Environment::get().getWorld()->getStore().get().find(watchedRecord->mRace); setValue("race", race->mName); } if (watchedRecord->mClass != mWatchedClass || mWatchedStatsEmpty) { mWatchedClass = watchedRecord->mClass; - const ESM::Class *cls = MWBase::Environment::get().getWorld()->getStore() - .get().find(watchedRecord->mClass); + const ESM::Class* cls + = MWBase::Environment::get().getWorld()->getStore().get().find(watchedRecord->mClass); setValue("class", cls->mName); - MWBase::WindowManager::SkillList majorSkills (5); - MWBase::WindowManager::SkillList minorSkills (5); + MWBase::WindowManager::SkillList majorSkills(5); + MWBase::WindowManager::SkillList minorSkills(5); - for (int i=0; i<5; ++i) + for (int i = 0; i < 5; ++i) { minorSkills[i] = cls->mData.mSkills[i][0]; majorSkills[i] = cls->mData.mSkills[i][1]; diff --git a/apps/openmw/mwgui/statswindow.cpp b/apps/openmw/mwgui/statswindow.cpp index e957b5d192..988577613c 100644 --- a/apps/openmw/mwgui/statswindow.cpp +++ b/apps/openmw/mwgui/statswindow.cpp @@ -1,75 +1,67 @@ #include "statswindow.hpp" -#include -#include -#include +#include #include #include #include +#include +#include #include -#include +#include -#include -#include -#include #include #include +#include +#include #include +#include #include #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" #include "../mwworld/class.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/esmstore.hpp" +#include "../mwworld/player.hpp" -#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/actorutil.hpp" +#include "../mwmechanics/npcstats.hpp" #include "tooltips.hpp" #include "ustring.hpp" namespace MWGui { - StatsWindow::StatsWindow (DragAndDrop* drag) - : WindowPinnableBase("openmw_stats_window.layout") - , NoDrop(drag, mMainWidget) - , mSkillView(nullptr) - , mMajorSkills() - , mMinorSkills() - , mMiscSkills() - , mSkillValues() - , mSkillWidgetMap() - , mFactionWidgetMap() - , mFactions() - , mBirthSignId() - , mReputation(0) - , mBounty(0) - , mSkillWidgets() - , mChanged(true) - , mMinFullWidth(mMainWidget->getSize().width) + StatsWindow::StatsWindow(DragAndDrop* drag) + : WindowPinnableBase("openmw_stats_window.layout") + , NoDrop(drag, mMainWidget) + , mSkillView(nullptr) + , mMajorSkills() + , mMinorSkills() + , mMiscSkills() + , mSkillValues() + , mSkillWidgetMap() + , mFactionWidgetMap() + , mFactions() + , mBirthSignId() + , mReputation(0) + , mBounty(0) + , mSkillWidgets() + , mChanged(true) + , mMinFullWidth(mMainWidget->getSize().width) { - const char *names[][2] = - { - { "Attrib1", "sAttributeStrength" }, - { "Attrib2", "sAttributeIntelligence" }, - { "Attrib3", "sAttributeWillpower" }, - { "Attrib4", "sAttributeAgility" }, - { "Attrib5", "sAttributeSpeed" }, - { "Attrib6", "sAttributeEndurance" }, - { "Attrib7", "sAttributePersonality" }, - { "Attrib8", "sAttributeLuck" }, - { 0, 0 } - }; + const char* names[][2] = { { "Attrib1", "sAttributeStrength" }, { "Attrib2", "sAttributeIntelligence" }, + { "Attrib3", "sAttributeWillpower" }, { "Attrib4", "sAttributeAgility" }, { "Attrib5", "sAttributeSpeed" }, + { "Attrib6", "sAttributeEndurance" }, { "Attrib7", "sAttributePersonality" }, + { "Attrib8", "sAttributeLuck" }, { 0, 0 } }; - const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); - for (int i=0; names[i][0]; ++i) + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + for (int i = 0; names[i][0]; ++i) { - setText (names[i][0], store.get().find (names[i][1])->mValue.getString()); + setText(names[i][0], store.get().find(names[i][1])->mValue.getString()); } getWidget(mSkillView, "SkillView"); @@ -79,7 +71,8 @@ namespace MWGui for (int i = 0; i < ESM::Skill::Length; ++i) { mSkillValues.insert(std::make_pair(i, MWMechanics::SkillValue())); - mSkillWidgetMap.insert(std::make_pair(i, std::make_pair((MyGUI::TextBox*)nullptr, (MyGUI::TextBox*)nullptr))); + mSkillWidgetMap.insert( + std::make_pair(i, std::make_pair((MyGUI::TextBox*)nullptr, (MyGUI::TextBox*)nullptr))); } MyGUI::Window* t = mMainWidget->castType(); @@ -90,10 +83,11 @@ namespace MWGui void StatsWindow::onMouseWheel(MyGUI::Widget* _sender, int _rel) { - if (mSkillView->getViewOffset().top + _rel*0.3 > 0) + if (mSkillView->getViewOffset().top + _rel * 0.3 > 0) mSkillView->setViewOffset(MyGUI::IntPoint(0, 0)); else - mSkillView->setViewOffset(MyGUI::IntPoint(0, static_cast(mSkillView->getViewOffset().top + _rel*0.3))); + mSkillView->setViewOffset( + MyGUI::IntPoint(0, static_cast(mSkillView->getViewOffset().top + _rel * 0.3))); } void StatsWindow::onWindowResize(MyGUI::Window* window) @@ -101,7 +95,8 @@ namespace MWGui int windowWidth = window->getSize().width; int windowHeight = window->getSize().height; - //initial values defined in openmw_stats_window.layout, if custom options are not present in .layout, a default is loaded + // initial values defined in openmw_stats_window.layout, if custom options are not present in .layout, a default + // is loaded float leftPaneRatio = 0.44f; if (mLeftPane->isUserString("LeftPaneRatio")) leftPaneRatio = MyGUI::utility::parseFloat(mLeftPane->getUserString("LeftPaneRatio")); @@ -114,28 +109,30 @@ namespace MWGui int minLeftWidth = static_cast(mMinFullWidth * leftPaneRatio); int minLeftOffsetWidth = minLeftWidth + leftOffsetWidth; - //if there's no space for right pane + // if there's no space for right pane mRightPane->setVisible(windowWidth >= minLeftOffsetWidth); if (!mRightPane->getVisible()) { mLeftPane->setCoord(MyGUI::IntCoord(0, 0, windowWidth - leftOffsetWidth, windowHeight)); } - //if there's some space for right pane + // if there's some space for right pane else if (windowWidth < mMinFullWidth) { mLeftPane->setCoord(MyGUI::IntCoord(0, 0, minLeftWidth, windowHeight)); mRightPane->setCoord(MyGUI::IntCoord(minLeftWidth, 0, windowWidth - minLeftWidth, windowHeight)); } - //if there's enough space for both panes + // if there's enough space for both panes else { - mLeftPane->setCoord(MyGUI::IntCoord(0, 0, static_cast(leftPaneRatio*windowWidth), windowHeight)); - mRightPane->setCoord(MyGUI::IntCoord(static_cast(leftPaneRatio*windowWidth), 0, static_cast(rightPaneRatio*windowWidth), windowHeight)); + mLeftPane->setCoord(MyGUI::IntCoord(0, 0, static_cast(leftPaneRatio * windowWidth), windowHeight)); + mRightPane->setCoord(MyGUI::IntCoord(static_cast(leftPaneRatio * windowWidth), 0, + static_cast(rightPaneRatio * windowWidth), windowHeight)); } - // Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden + // Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the + // scrollbar is hidden mSkillView->setVisibleVScroll(false); - mSkillView->setCanvasSize (mSkillView->getWidth(), mSkillView->getCanvasSize().height); + mSkillView->setCanvasSize(mSkillView->getWidth(), mSkillView->getCanvasSize().height); mSkillView->setVisibleVScroll(true); } @@ -157,26 +154,31 @@ namespace MWGui mMainWidget->castType()->setCaption(playerName); } - void StatsWindow::setValue (const std::string& id, const MWMechanics::AttributeValue& value) + void StatsWindow::setValue(const std::string& id, const MWMechanics::AttributeValue& value) { - static const char *ids[] = - { - "AttribVal1", "AttribVal2", "AttribVal3", "AttribVal4", "AttribVal5", - "AttribVal6", "AttribVal7", "AttribVal8", + static const char* ids[] = { + "AttribVal1", + "AttribVal2", + "AttribVal3", + "AttribVal4", + "AttribVal5", + "AttribVal6", + "AttribVal7", + "AttribVal8", nullptr, }; - for (int i=0; ids[i]; ++i) - if (ids[i]==id) + for (int i = 0; ids[i]; ++i) + if (ids[i] == id) { - setText (id, std::to_string(static_cast(value.getModified()))); + setText(id, std::to_string(static_cast(value.getModified()))); MyGUI::TextBox* box; getWidget(box, id); - if (value.getModified()>value.getBase()) + if (value.getModified() > value.getBase()) box->_setWidgetState("increased"); - else if (value.getModified()_setWidgetState("decreased"); else box->_setWidgetState("normal"); @@ -185,7 +187,7 @@ namespace MWGui } } - void StatsWindow::setValue (const std::string& id, const MWMechanics::DynamicStat& value) + void StatsWindow::setValue(const std::string& id, const MWMechanics::DynamicStat& value) { int current = static_cast(value.getCurrent()); int modified = static_cast(value.getModified(false)); @@ -194,11 +196,11 @@ namespace MWGui if (id != "FBar") current = std::max(0, current); - setBar (id, id + "T", current, modified); + setBar(id, id + "T", current, modified); // health, magicka, fatigue tooltip MyGUI::Widget* w; - std::string valStr = MyGUI::utility::toString(current) + " / " + MyGUI::utility::toString(modified); + std::string valStr = MyGUI::utility::toString(current) + " / " + MyGUI::utility::toString(modified); if (id == "HBar") { getWidget(w, "Health"); @@ -216,19 +218,19 @@ namespace MWGui } } - void StatsWindow::setValue (const std::string& id, const std::string& value) + void StatsWindow::setValue(const std::string& id, const std::string& value) { - if (id=="name") - setPlayerName (value); - else if (id=="race") - setText ("RaceText", value); - else if (id=="class") - setText ("ClassText", value); + if (id == "name") + setPlayerName(value); + else if (id == "race") + setText("RaceText", value); + else if (id == "class") + setText("ClassText", value); } - void StatsWindow::setValue (const std::string& id, int value) + void StatsWindow::setValue(const std::string& id, int value) { - if (id=="level") + if (id == "level") { std::ostringstream text; text << value; @@ -239,11 +241,10 @@ namespace MWGui void setSkillProgress(MyGUI::Widget* w, float progress, int skillId) { MWWorld::Ptr player = MWMechanics::getPlayer(); - const MWWorld::ESMStore &esmStore = - MWBase::Environment::get().getWorld()->getStore(); + const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); - float progressRequirement = player.getClass().getNpcStats(player).getSkillProgressRequirement(skillId, - *esmStore.get().find(player.get()->mBase->mClass)); + float progressRequirement = player.getClass().getNpcStats(player).getSkillProgressRequirement( + skillId, *esmStore.get().find(player.get()->mBase->mClass)); // This is how vanilla MW displays the progress bar (I think). Note it's slightly inaccurate, // due to the int casting in the skill levelup logic. Also the progress label could in rare cases @@ -251,7 +252,7 @@ namespace MWGui // Leaving the original display logic for now, for consistency with ess-imported savegames. int progressPercent = int(float(progress) / float(progressRequirement) * 100.f + 0.5f); - w->setUserString("Caption_SkillProgressText", MyGUI::utility::toString(progressPercent)+"/100"); + w->setUserString("Caption_SkillProgressText", MyGUI::utility::toString(progressPercent) + "/100"); w->setUserString("RangePosition_SkillProgress", MyGUI::utility::toString(progressPercent)); } @@ -279,8 +280,9 @@ namespace MWGui int widthAfter = valueWidget->getTextSize().width; if (widthBefore != widthAfter) { - valueWidget->setCoord(valueWidget->getLeft() - (widthAfter-widthBefore), valueWidget->getTop(), valueWidget->getWidth() + (widthAfter-widthBefore), valueWidget->getHeight()); - nameWidget->setSize(nameWidget->getWidth() - (widthAfter-widthBefore), nameWidget->getHeight()); + valueWidget->setCoord(valueWidget->getLeft() - (widthAfter - widthBefore), valueWidget->getTop(), + valueWidget->getWidth() + (widthAfter - widthBefore), valueWidget->getHeight()); + nameWidget->setSize(nameWidget->getWidth() - (widthAfter - widthBefore), nameWidget->getHeight()); } if (value.getBase() < 100) @@ -313,7 +315,7 @@ namespace MWGui } } - void StatsWindow::configureSkills (const std::vector& major, const std::vector& minor) + void StatsWindow::configureSkills(const std::vector& major, const std::vector& minor) { mMajorSkills = major; mMinorSkills = minor; @@ -332,12 +334,12 @@ namespace MWGui updateSkillArea(); } - void StatsWindow::onFrame (float dt) + void StatsWindow::onFrame(float dt) { NoDrop::onFrame(dt); MWWorld::Ptr player = MWMechanics::getPlayer(); - const MWMechanics::NpcStats &PCstats = player.getClass().getNpcStats(player); + const MWMechanics::NpcStats& PCstats = player.getClass().getNpcStats(player); std::string detailText; std::stringstream detail; @@ -347,40 +349,45 @@ namespace MWGui mult = std::min(mult, 100 - PCstats.getAttribute(attribute).getBase()); if (mult > 1) detail << (detail.str().empty() ? "" : "\n") << "#{" - << MyGUI::TextIterator::toTagsString(ESM::Attribute::sGmstAttributeIds[attribute]) - << "} x" << MyGUI::utility::toString(mult); + << MyGUI::TextIterator::toTagsString(ESM::Attribute::sGmstAttributeIds[attribute]) << "} x" + << MyGUI::utility::toString(mult); } detailText = MyGUI::LanguageManager::getInstance().replaceTags(detail.str()); // level progress MyGUI::Widget* levelWidget; - for (int i=0; i<2; ++i) + for (int i = 0; i < 2; ++i) { - int max = MWBase::Environment::get().getWorld()->getStore().get().find("iLevelUpTotal")->mValue.getInteger(); - getWidget(levelWidget, i==0 ? "Level_str" : "LevelText"); - - levelWidget->setUserString("RangePosition_LevelProgress", MyGUI::utility::toString(PCstats.getLevelProgress())); + int max = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("iLevelUpTotal") + ->mValue.getInteger(); + getWidget(levelWidget, i == 0 ? "Level_str" : "LevelText"); + + levelWidget->setUserString( + "RangePosition_LevelProgress", MyGUI::utility::toString(PCstats.getLevelProgress())); levelWidget->setUserString("Range_LevelProgress", MyGUI::utility::toString(max)); - levelWidget->setUserString("Caption_LevelProgressText", MyGUI::utility::toString(PCstats.getLevelProgress()) + "/" - + MyGUI::utility::toString(max)); + levelWidget->setUserString("Caption_LevelProgressText", + MyGUI::utility::toString(PCstats.getLevelProgress()) + "/" + MyGUI::utility::toString(max)); levelWidget->setUserString("Caption_LevelDetailText", detailText); } setFactions(PCstats.getFactionRanks()); - setExpelled(PCstats.getExpelled ()); + setExpelled(PCstats.getExpelled()); - const std::string &signId = - MWBase::Environment::get().getWorld()->getPlayer().getBirthSign(); + const std::string& signId = MWBase::Environment::get().getWorld()->getPlayer().getBirthSign(); setBirthSign(signId); - setReputation (PCstats.getReputation ()); - setBounty (PCstats.getBounty ()); + setReputation(PCstats.getReputation()); + setBounty(PCstats.getBounty()); if (mChanged) updateSkillArea(); } - void StatsWindow::setFactions (const FactionList& factions) + void StatsWindow::setFactions(const FactionList& factions) { if (mFactions != factions) { @@ -389,7 +396,7 @@ namespace MWGui } } - void StatsWindow::setExpelled (const std::set& expelled) + void StatsWindow::setExpelled(const std::set& expelled) { if (mExpelled != expelled) { @@ -398,7 +405,7 @@ namespace MWGui } } - void StatsWindow::setBirthSign (const std::string& signId) + void StatsWindow::setBirthSign(const std::string& signId) { if (signId != mBirthSignId) { @@ -407,7 +414,7 @@ namespace MWGui } } - void StatsWindow::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) + void StatsWindow::addSeparator(MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2) { MyGUI::ImageBox* separator = mSkillView->createWidget("MW_HLine", MyGUI::IntCoord(10, coord1.top, coord1.width + coord2.width - 4, 18), @@ -433,22 +440,26 @@ namespace MWGui coord2.top += lineHeight; } - std::pair StatsWindow::addValueItem(std::string_view text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) + std::pair StatsWindow::addValueItem(std::string_view text, + const std::string& value, const std::string& state, MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2) { MyGUI::TextBox *skillNameWidget, *skillValueWidget; - skillNameWidget = mSkillView->createWidget("SandText", coord1, MyGUI::Align::Left | MyGUI::Align::Top | MyGUI::Align::HStretch); + skillNameWidget = mSkillView->createWidget( + "SandText", coord1, MyGUI::Align::Left | MyGUI::Align::Top | MyGUI::Align::HStretch); skillNameWidget->setCaption(toUString(text)); skillNameWidget->eventMouseWheel += MyGUI::newDelegate(this, &StatsWindow::onMouseWheel); - skillValueWidget = mSkillView->createWidget("SandTextRight", coord2, MyGUI::Align::Right | MyGUI::Align::Top); + skillValueWidget = mSkillView->createWidget( + "SandTextRight", coord2, MyGUI::Align::Right | MyGUI::Align::Top); skillValueWidget->setCaption(value); skillValueWidget->_setWidgetState(state); skillValueWidget->eventMouseWheel += MyGUI::newDelegate(this, &StatsWindow::onMouseWheel); // resize dynamically according to text size int textWidthPlusMargin = skillValueWidget->getTextSize().width + 12; - skillValueWidget->setCoord(coord2.left + coord2.width - textWidthPlusMargin, coord2.top, textWidthPlusMargin, coord2.height); + skillValueWidget->setCoord( + coord2.left + coord2.width - textWidthPlusMargin, coord2.top, textWidthPlusMargin, coord2.height); skillNameWidget->setSize(skillNameWidget->getSize() + MyGUI::IntSize(coord2.width - textWidthPlusMargin, 0)); mSkillWidgets.push_back(skillNameWidget); @@ -461,7 +472,7 @@ namespace MWGui return std::make_pair(skillNameWidget, skillValueWidget); } - MyGUI::Widget* StatsWindow::addItem(const std::string& text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) + MyGUI::Widget* StatsWindow::addItem(const std::string& text, MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2) { MyGUI::TextBox* skillNameWidget; @@ -482,7 +493,8 @@ namespace MWGui return skillNameWidget; } - void StatsWindow::addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) + void StatsWindow::addSkills(const SkillList& skills, const std::string& titleId, const std::string& titleDefault, + MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2) { // Add a line separator if there are items above if (!mSkillWidgets.empty()) @@ -490,37 +502,40 @@ namespace MWGui addSeparator(coord1, coord2); } - addGroup(MWBase::Environment::get().getWindowManager()->getGameSettingString(titleId, titleDefault), coord1, coord2); + addGroup( + MWBase::Environment::get().getWindowManager()->getGameSettingString(titleId, titleDefault), coord1, coord2); for (const int skillId : skills) { if (skillId < 0 || skillId >= ESM::Skill::Length) // Skip unknown skill indexes continue; - const std::string &skillNameId = ESM::Skill::sSkillNameIds[skillId]; + const std::string& skillNameId = ESM::Skill::sSkillNameIds[skillId]; - const MWWorld::ESMStore &esmStore = - MWBase::Environment::get().getWorld()->getStore(); + const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); const ESM::Skill* skill = esmStore.get().find(skillId); std::string icon = "icons\\k\\" + ESM::Skill::sIconNames[skillId]; - const ESM::Attribute* attr = - esmStore.get().find(skill->mData.mAttribute); + const ESM::Attribute* attr = esmStore.get().find(skill->mData.mAttribute); - std::pair widgets = addValueItem(MWBase::Environment::get().getWindowManager()->getGameSettingString(skillNameId, skillNameId), - {}, "normal", coord1, coord2); + std::pair widgets = addValueItem( + MWBase::Environment::get().getWindowManager()->getGameSettingString(skillNameId, skillNameId), {}, + "normal", coord1, coord2); mSkillWidgetMap[skillId] = widgets; - for (int i=0; i<2; ++i) + for (int i = 0; i < 2; ++i) { - mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("ToolTipType", "Layout"); - mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("ToolTipLayout", "SkillToolTip"); - mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("Caption_SkillName", "#{"+skillNameId+"}"); - mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("Caption_SkillDescription", skill->mDescription); - mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("Caption_SkillAttribute", "#{sGoverningAttribute}: #{" + attr->mName + "}"); - mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("ImageTexture_SkillImage", icon); - mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("Range_SkillProgress", "100"); + mSkillWidgets[mSkillWidgets.size() - 1 - i]->setUserString("ToolTipType", "Layout"); + mSkillWidgets[mSkillWidgets.size() - 1 - i]->setUserString("ToolTipLayout", "SkillToolTip"); + mSkillWidgets[mSkillWidgets.size() - 1 - i]->setUserString( + "Caption_SkillName", "#{" + skillNameId + "}"); + mSkillWidgets[mSkillWidgets.size() - 1 - i]->setUserString( + "Caption_SkillDescription", skill->mDescription); + mSkillWidgets[mSkillWidgets.size() - 1 - i]->setUserString( + "Caption_SkillAttribute", "#{sGoverningAttribute}: #{" + attr->mName + "}"); + mSkillWidgets[mSkillWidgets.size() - 1 - i]->setUserString("ImageTexture_SkillImage", icon); + mSkillWidgets[mSkillWidgets.size() - 1 - i]->setUserString("Range_SkillProgress", "100"); } setValue(static_cast(skillId), mSkillValues.find(skillId)->second); @@ -550,10 +565,9 @@ namespace MWGui if (!mMiscSkills.empty()) addSkills(mMiscSkills, "sSkillClassMisc", "Misc Skills", coord1, coord2); - MWBase::World *world = MWBase::Environment::get().getWorld(); - const MWWorld::ESMStore &store = world->getStore(); - const ESM::NPC *player = - world->getPlayerPtr().get()->mBase; + MWBase::World* world = MWBase::Environment::get().getWorld(); + const MWWorld::ESMStore& store = world->getStore(); + const ESM::NPC* player = world->getPlayerPtr().get()->mBase; // race tooltip const ESM::Race* playerRace = store.get().find(player->mRace); @@ -567,8 +581,7 @@ namespace MWGui // class tooltip MyGUI::Widget* classWidget; - const ESM::Class *playerClass = - store.get().find(player->mClass); + const ESM::Class* playerClass = store.get().find(player->mClass); getWidget(classWidget, "ClassText"); ToolTips::createClassToolTip(classWidget, *playerClass); @@ -578,15 +591,14 @@ namespace MWGui if (!mFactions.empty()) { MWWorld::Ptr playerPtr = MWMechanics::getPlayer(); - const MWMechanics::NpcStats &PCstats = playerPtr.getClass().getNpcStats(playerPtr); - const std::set &expelled = PCstats.getExpelled(); + const MWMechanics::NpcStats& PCstats = playerPtr.getClass().getNpcStats(playerPtr); + const std::set& expelled = PCstats.getExpelled(); - bool firstFaction=true; + bool firstFaction = true; for (auto& factionPair : mFactions) { const std::string& factionId = factionPair.first; - const ESM::Faction *faction = - store.get().find(factionId); + const ESM::Faction* faction = store.get().find(factionId); if (faction->mData.mIsHidden == 1) continue; @@ -596,7 +608,8 @@ namespace MWGui if (!mSkillWidgets.empty()) addSeparator(coord1, coord2); - addGroup(MWBase::Environment::get().getWindowManager()->getGameSettingString("sFaction", "Faction"), coord1, coord2); + addGroup(MWBase::Environment::get().getWindowManager()->getGameSettingString("sFaction", "Faction"), + coord1, coord2); firstFaction = false; } @@ -617,19 +630,20 @@ namespace MWGui if (rank < 9) { // player doesn't have max rank yet - text += std::string("\n\n#{fontcolourhtml=header}#{sNextRank} ") + faction->mRanks[rank+1]; + text += std::string("\n\n#{fontcolourhtml=header}#{sNextRank} ") + faction->mRanks[rank + 1]; - ESM::RankData rankData = faction->mData.mRankData[rank+1]; + ESM::RankData rankData = faction->mData.mRankData[rank + 1]; const ESM::Attribute* attr1 = store.get().find(faction->mData.mAttribute[0]); const ESM::Attribute* attr2 = store.get().find(faction->mData.mAttribute[1]); - text += "\n#{fontcolourhtml=normal}#{" + attr1->mName + "}: " + MyGUI::utility::toString(rankData.mAttribute1) - + ", #{" + attr2->mName + "}: " + MyGUI::utility::toString(rankData.mAttribute2); + text += "\n#{fontcolourhtml=normal}#{" + attr1->mName + + "}: " + MyGUI::utility::toString(rankData.mAttribute1) + ", #{" + attr2->mName + + "}: " + MyGUI::utility::toString(rankData.mAttribute2); text += "\n\n#{fontcolourhtml=header}#{sFavoriteSkills}"; text += "\n#{fontcolourhtml=normal}"; bool firstSkill = true; - for (int i=0; i<7; ++i) + for (int i = 0; i < 7; ++i) { if (faction->mData.mSkills[i] != -1) { @@ -638,7 +652,7 @@ namespace MWGui firstSkill = false; - text += "#{"+ESM::Skill::sSkillNameIds[faction->mData.mSkills[i]]+"}"; + text += "#{" + ESM::Skill::sSkillNameIds[faction->mData.mSkills[i]] + "}"; } } @@ -663,9 +677,9 @@ namespace MWGui if (!mSkillWidgets.empty()) addSeparator(coord1, coord2); - addGroup(MWBase::Environment::get().getWindowManager()->getGameSettingString("sBirthSign", "Sign"), coord1, coord2); - const ESM::BirthSign *sign = - store.get().find(mBirthSignId); + addGroup(MWBase::Environment::get().getWindowManager()->getGameSettingString("sBirthSign", "Sign"), coord1, + coord2); + const ESM::BirthSign* sign = store.get().find(mBirthSignId); MyGUI::Widget* w = addItem(sign->mName, coord1, coord2); ToolTips::createBirthsignToolTip(w, mBirthSignId); @@ -676,28 +690,29 @@ namespace MWGui addSeparator(coord1, coord2); addValueItem(MWBase::Environment::get().getWindowManager()->getGameSettingString("sReputation", "Reputation"), - MyGUI::utility::toString(static_cast(mReputation)), "normal", coord1, coord2); + MyGUI::utility::toString(static_cast(mReputation)), "normal", coord1, coord2); - for (int i=0; i<2; ++i) + for (int i = 0; i < 2; ++i) { - mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("ToolTipType", "Layout"); - mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("ToolTipLayout", "TextToolTip"); - mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("Caption_Text", "#{sSkillsMenuReputationHelp}"); + mSkillWidgets[mSkillWidgets.size() - 1 - i]->setUserString("ToolTipType", "Layout"); + mSkillWidgets[mSkillWidgets.size() - 1 - i]->setUserString("ToolTipLayout", "TextToolTip"); + mSkillWidgets[mSkillWidgets.size() - 1 - i]->setUserString("Caption_Text", "#{sSkillsMenuReputationHelp}"); } addValueItem(MWBase::Environment::get().getWindowManager()->getGameSettingString("sBounty", "Bounty"), - MyGUI::utility::toString(static_cast(mBounty)), "normal", coord1, coord2); + MyGUI::utility::toString(static_cast(mBounty)), "normal", coord1, coord2); - for (int i=0; i<2; ++i) + for (int i = 0; i < 2; ++i) { - mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("ToolTipType", "Layout"); - mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("ToolTipLayout", "TextToolTip"); - mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("Caption_Text", "#{sCrimeHelp}"); + mSkillWidgets[mSkillWidgets.size() - 1 - i]->setUserString("ToolTipType", "Layout"); + mSkillWidgets[mSkillWidgets.size() - 1 - i]->setUserString("ToolTipLayout", "TextToolTip"); + mSkillWidgets[mSkillWidgets.size() - 1 - i]->setUserString("Caption_Text", "#{sCrimeHelp}"); } - // Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden + // Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the + // scrollbar is hidden mSkillView->setVisibleVScroll(false); - mSkillView->setCanvasSize (mSkillView->getWidth(), std::max(mSkillView->getHeight(), coord1.top)); + mSkillView->setCanvasSize(mSkillView->getWidth(), std::max(mSkillView->getHeight(), coord1.top)); mSkillView->setVisibleVScroll(true); } diff --git a/apps/openmw/mwgui/statswindow.hpp b/apps/openmw/mwgui/statswindow.hpp index cc87ea9523..c7d887903d 100644 --- a/apps/openmw/mwgui/statswindow.hpp +++ b/apps/openmw/mwgui/statswindow.hpp @@ -8,68 +8,80 @@ namespace MWGui { class StatsWindow : public WindowPinnableBase, public NoDrop, public StatsListener { - public: - typedef std::map FactionList; - - typedef std::vector SkillList; - - StatsWindow(DragAndDrop* drag); - - /// automatically updates all the data in the stats window, but only if it has changed. - void onFrame(float dt) override; - - void setBar(const std::string& name, const std::string& tname, int val, int max); - void setPlayerName(const std::string& playerName); - - /// Set value for the given ID. - void setValue (const std::string& id, const MWMechanics::AttributeValue& value) override; - void setValue (const std::string& id, const MWMechanics::DynamicStat& value) override; - void setValue (const std::string& id, const std::string& value) override; - void setValue (const std::string& id, int value) override; - void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::SkillValue& value) override; - void configureSkills(const SkillList& major, const SkillList& minor) override; - - void setReputation (int reputation) { if (reputation != mReputation) mChanged = true; this->mReputation = reputation; } - void setBounty (int bounty) { if (bounty != mBounty) mChanged = true; this->mBounty = bounty; } - void updateSkillArea(); - - void onOpen() override { onWindowResize(mMainWidget->castType()); } - - private: - void addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); - void addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); - void addGroup(std::string_view label, MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2); - std::pair addValueItem(std::string_view text, const std::string &value, const std::string& state, MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2); - MyGUI::Widget* addItem(const std::string& text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); - - void setFactions (const FactionList& factions); - void setExpelled (const std::set& expelled); - void setBirthSign (const std::string &signId); - - void onWindowResize(MyGUI::Window* window); - void onMouseWheel(MyGUI::Widget* _sender, int _rel); - - MyGUI::Widget* mLeftPane; - MyGUI::Widget* mRightPane; - - MyGUI::ScrollView* mSkillView; - - SkillList mMajorSkills, mMinorSkills, mMiscSkills; - std::map mSkillValues; - std::map > mSkillWidgetMap; - std::map mFactionWidgetMap; - FactionList mFactions; ///< Stores a list of factions and the current rank - std::string mBirthSignId; - int mReputation, mBounty; - std::vector mSkillWidgets; //< Skills and other information - std::set mExpelled; - - bool mChanged; - const int mMinFullWidth; - - protected: - void onPinToggled() override; - void onTitleDoubleClicked() override; + public: + typedef std::map FactionList; + + typedef std::vector SkillList; + + StatsWindow(DragAndDrop* drag); + + /// automatically updates all the data in the stats window, but only if it has changed. + void onFrame(float dt) override; + + void setBar(const std::string& name, const std::string& tname, int val, int max); + void setPlayerName(const std::string& playerName); + + /// Set value for the given ID. + void setValue(const std::string& id, const MWMechanics::AttributeValue& value) override; + void setValue(const std::string& id, const MWMechanics::DynamicStat& value) override; + void setValue(const std::string& id, const std::string& value) override; + void setValue(const std::string& id, int value) override; + void setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::SkillValue& value) override; + void configureSkills(const SkillList& major, const SkillList& minor) override; + + void setReputation(int reputation) + { + if (reputation != mReputation) + mChanged = true; + this->mReputation = reputation; + } + void setBounty(int bounty) + { + if (bounty != mBounty) + mChanged = true; + this->mBounty = bounty; + } + void updateSkillArea(); + + void onOpen() override { onWindowResize(mMainWidget->castType()); } + + private: + void addSkills(const SkillList& skills, const std::string& titleId, const std::string& titleDefault, + MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2); + void addSeparator(MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2); + void addGroup(std::string_view label, MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2); + std::pair addValueItem(std::string_view text, const std::string& value, + const std::string& state, MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2); + MyGUI::Widget* addItem(const std::string& text, MyGUI::IntCoord& coord1, MyGUI::IntCoord& coord2); + + void setFactions(const FactionList& factions); + void setExpelled(const std::set& expelled); + void setBirthSign(const std::string& signId); + + void onWindowResize(MyGUI::Window* window); + void onMouseWheel(MyGUI::Widget* _sender, int _rel); + + MyGUI::Widget* mLeftPane; + MyGUI::Widget* mRightPane; + + MyGUI::ScrollView* mSkillView; + + SkillList mMajorSkills, mMinorSkills, mMiscSkills; + std::map mSkillValues; + std::map> mSkillWidgetMap; + std::map mFactionWidgetMap; + FactionList mFactions; ///< Stores a list of factions and the current rank + std::string mBirthSignId; + int mReputation, mBounty; + std::vector mSkillWidgets; //< Skills and other information + std::set mExpelled; + + bool mChanged; + const int mMinFullWidth; + + protected: + void onPinToggled() override; + void onTitleDoubleClicked() override; }; } #endif diff --git a/apps/openmw/mwgui/textinput.cpp b/apps/openmw/mwgui/textinput.cpp index 016e84ecf0..6ff4e5304a 100644 --- a/apps/openmw/mwgui/textinput.cpp +++ b/apps/openmw/mwgui/textinput.cpp @@ -1,10 +1,10 @@ #include "textinput.hpp" -#include "../mwbase/windowmanager.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/windowmanager.hpp" -#include #include +#include #include "ustring.hpp" @@ -12,7 +12,7 @@ namespace MWGui { TextInputDialog::TextInputDialog() - : WindowModal("openmw_text_input.layout") + : WindowModal("openmw_text_input.layout") { // Centre dialog center(); @@ -34,9 +34,11 @@ namespace MWGui getWidget(okButton, "OKButton"); if (shown) - okButton->setCaption(toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString("sNext", {}))); + okButton->setCaption( + toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString("sNext", {}))); else - okButton->setCaption(toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", {}))); + okButton->setCaption( + toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString("sOK", {}))); } void TextInputDialog::setTextLabel(std::string_view label) @@ -57,8 +59,8 @@ namespace MWGui { if (mTextEdit->getCaption().empty()) { - MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage37}"); - MWBase::Environment::get().getWindowManager()->setKeyFocusWidget (mTextEdit); + MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage37}"); + MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mTextEdit); } else eventDone(this); @@ -77,10 +79,9 @@ namespace MWGui return mTextEdit->getCaption(); } - void TextInputDialog::setTextInput(const std::string &text) + void TextInputDialog::setTextInput(const std::string& text) { mTextEdit->setCaption(text); } - } diff --git a/apps/openmw/mwgui/textinput.hpp b/apps/openmw/mwgui/textinput.hpp index 3914d5119f..0e616305cb 100644 --- a/apps/openmw/mwgui/textinput.hpp +++ b/apps/openmw/mwgui/textinput.hpp @@ -11,7 +11,7 @@ namespace MWGui TextInputDialog(); std::string getTextInput() const; - void setTextInput(const std::string &text); + void setTextInput(const std::string& text); void setNextButtonShow(bool shown); void setTextLabel(std::string_view label); diff --git a/apps/openmw/mwgui/timeadvancer.cpp b/apps/openmw/mwgui/timeadvancer.cpp index c38094ae45..2cdab127b9 100644 --- a/apps/openmw/mwgui/timeadvancer.cpp +++ b/apps/openmw/mwgui/timeadvancer.cpp @@ -3,12 +3,12 @@ namespace MWGui { TimeAdvancer::TimeAdvancer(float delay) - : mRunning(false), - mCurHour(0), - mHours(1), - mInterruptAt(-1), - mDelay(delay), - mRemainingTime(delay) + : mRunning(false) + , mCurHour(0) + , mHours(1) + , mInterruptAt(-1) + , mDelay(delay) + , mRemainingTime(delay) { } @@ -54,7 +54,6 @@ namespace MWGui eventFinished(); return; } - } } diff --git a/apps/openmw/mwgui/timeadvancer.hpp b/apps/openmw/mwgui/timeadvancer.hpp index 40fce978b9..56a190a3e3 100644 --- a/apps/openmw/mwgui/timeadvancer.hpp +++ b/apps/openmw/mwgui/timeadvancer.hpp @@ -7,33 +7,33 @@ namespace MWGui { class TimeAdvancer { - public: - TimeAdvancer(float delay); + public: + TimeAdvancer(float delay); - void run(int hours, int interruptAt=-1); - void stop(); - void onFrame(float dt); + void run(int hours, int interruptAt = -1); + void stop(); + void onFrame(float dt); - int getHours() const; - bool isRunning() const; + int getHours() const; + bool isRunning() const; - // signals - typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void; - typedef MyGUI::delegates::CMultiDelegate2 EventHandle_IntInt; + // signals + typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void; + typedef MyGUI::delegates::CMultiDelegate2 EventHandle_IntInt; - EventHandle_IntInt eventProgressChanged; - EventHandle_Void eventInterrupted; - EventHandle_Void eventFinished; + EventHandle_IntInt eventProgressChanged; + EventHandle_Void eventInterrupted; + EventHandle_Void eventFinished; - private: - bool mRunning; + private: + bool mRunning; - int mCurHour; - int mHours; - int mInterruptAt; + int mCurHour; + int mHours; + int mInterruptAt; - float mDelay; - float mRemainingTime; + float mDelay; + float mRemainingTime; }; } diff --git a/apps/openmw/mwgui/tooltips.cpp b/apps/openmw/mwgui/tooltips.cpp index 2bd4ea8e61..de22f2a38a 100644 --- a/apps/openmw/mwgui/tooltips.cpp +++ b/apps/openmw/mwgui/tooltips.cpp @@ -3,36 +3,37 @@ #include #include -#include -#include #include +#include +#include +#include +#include #include #include -#include -#include -#include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" -#include "../mwbase/windowmanager.hpp" #include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" +#include "../mwmechanics/actorutil.hpp" +#include "../mwmechanics/spellutil.hpp" #include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" -#include "../mwmechanics/spellutil.hpp" -#include "../mwmechanics/actorutil.hpp" -#include "mapwindow.hpp" #include "inventorywindow.hpp" +#include "mapwindow.hpp" #include "itemmodel.hpp" namespace MWGui { - std::string ToolTips::sSchoolNames[] = {"#{sSchoolAlteration}", "#{sSchoolConjuration}", "#{sSchoolDestruction}", "#{sSchoolIllusion}", "#{sSchoolMysticism}", "#{sSchoolRestoration}"}; + std::string ToolTips::sSchoolNames[] = { "#{sSchoolAlteration}", "#{sSchoolConjuration}", "#{sSchoolDestruction}", + "#{sSchoolIllusion}", "#{sSchoolMysticism}", "#{sSchoolRestoration}" }; - ToolTips::ToolTips() : - Layout("openmw_tooltips.layout") + ToolTips::ToolTips() + : Layout("openmw_tooltips.layout") , mFocusToolTipX(0.0) , mFocusToolTipY(0.0) , mHorizontalScrollIndex(0) @@ -57,11 +58,11 @@ namespace MWGui mDelay = Settings::Manager::getFloat("tooltip delay", "GUI"); mRemainingDelay = mDelay; - for (unsigned int i=0; i < mMainWidget->getChildCount(); ++i) + for (unsigned int i = 0; i < mMainWidget->getChildCount(); ++i) { mMainWidget->getChildAt(i)->setVisible(false); } - + mShowOwned = Settings::Manager::getInt("show owned", "Game"); } @@ -84,19 +85,19 @@ namespace MWGui } // start by hiding everything - for (unsigned int i=0; i < mMainWidget->getChildCount(); ++i) + for (unsigned int i = 0; i < mMainWidget->getChildCount(); ++i) { mMainWidget->getChildAt(i)->setVisible(false); } - const MyGUI::IntSize &viewSize = MyGUI::RenderManager::getInstance().getViewSize(); + const MyGUI::IntSize& viewSize = MyGUI::RenderManager::getInstance().getViewSize(); if (!mEnabled) { return; } - MWBase::WindowManager *winMgr = MWBase::Environment::get().getWindowManager(); + MWBase::WindowManager* winMgr = MWBase::Environment::get().getWindowManager(); bool guiMode = winMgr->isGuiMode(); if (guiMode) @@ -105,12 +106,11 @@ namespace MWGui return; const MyGUI::IntPoint& mousePos = MyGUI::InputManager::getInstance().getMousePosition(); - if (winMgr->getWorldMouseOver() && - (winMgr->isConsoleMode() || - (winMgr->getMode() == GM_Container) || - (winMgr->getMode() == GM_Inventory))) + if (winMgr->getWorldMouseOver() + && (winMgr->isConsoleMode() || (winMgr->getMode() == GM_Container) + || (winMgr->getMode() == GM_Inventory))) { - if (mFocusObject.isEmpty ()) + if (mFocusObject.isEmpty()) return; const MWWorld::Class& objectclass = mFocusObject.getClass(); @@ -123,7 +123,7 @@ namespace MWGui ToolTipInfo info; info.caption = mFocusObject.getClass().getName(mFocusObject); if (info.caption.empty()) - info.caption=mFocusObject.getCellRef().getRefId(); + info.caption = mFocusObject.getCellRef().getRefId(); info.icon.clear(); tooltipSize = createToolTip(info, checkOwned()); } @@ -150,7 +150,6 @@ namespace MWGui mLastMouseX = mousePos.left; mLastMouseY = mousePos.top; - if (mRemainingDelay > 0) return; @@ -176,7 +175,6 @@ namespace MWGui return; } - // special handling for markers on the local map: the tooltip should only be visible // if the marker is not hidden due to the fog of war. if (type == "MapMarker") @@ -201,7 +199,8 @@ namespace MWGui } else if (type == "ItemModelIndex") { - std::pair pair = *focus->getUserData >(); + std::pair pair + = *focus->getUserData>(); mFocusObject = pair.second->getItem(pair.first).mBase; bool isAllowedToUse = pair.second->allowedToUseItems(); tooltipSize = getToolTipViaPtr(pair.second->getItem(pair.first).mCount, false, !isAllowedToUse); @@ -213,19 +212,21 @@ namespace MWGui else if (type == "AvatarItemSelection") { MyGUI::IntCoord avatarPos = focus->getAbsoluteCoord(); - MyGUI::IntPoint relMousePos = MyGUI::InputManager::getInstance ().getMousePosition () - MyGUI::IntPoint(avatarPos.left, avatarPos.top); - MWWorld::Ptr item = winMgr->getInventoryWindow ()->getAvatarSelectedItem (relMousePos.left, relMousePos.top); + MyGUI::IntPoint relMousePos = MyGUI::InputManager::getInstance().getMousePosition() + - MyGUI::IntPoint(avatarPos.left, avatarPos.top); + MWWorld::Ptr item + = winMgr->getInventoryWindow()->getAvatarSelectedItem(relMousePos.left, relMousePos.top); mFocusObject = item; - if (!mFocusObject.isEmpty ()) + if (!mFocusObject.isEmpty()) tooltipSize = getToolTipViaPtr(mFocusObject.getRefData().getCount(), false); } else if (type == "Spell") { ToolTipInfo info; - const ESM::Spell *spell = - MWBase::Environment::get().getWorld()->getStore().get().find(focus->getUserString("Spell")); + const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get().find( + focus->getUserString("Spell")); info.caption = spell->mName; Widgets::SpellEffectList effects; for (const ESM::ENAMstruct& spellEffect : spell->mEffects.mList) @@ -243,7 +244,8 @@ namespace MWGui params.mNoTarget = false; effects.push_back(params); } - if (MWMechanics::spellIncreasesSkill(spell)) // display school of spells that contribute to skill progress + if (MWMechanics::spellIncreasesSkill( + spell)) // display school of spells that contribute to skill progress { MWWorld::Ptr player = MWMechanics::getPlayer(); int school = MWMechanics::getSpellSchool(spell, player); @@ -251,7 +253,8 @@ namespace MWGui } std::string cost = focus->getUserString("SpellCost"); if (cost != "" && cost != "0") - info.text += MWGui::ToolTips::getValueString(MWMechanics::calcSpellCost(*spell), "#{sCastCost}"); + info.text + += MWGui::ToolTips::getValueString(MWMechanics::calcSpellCost(*spell), "#{sCastCost}"); info.effects = effects; tooltipSize = createToolTip(info); } @@ -270,7 +273,8 @@ namespace MWGui if (underscorePos == std::string::npos) continue; std::string key = userStringPair.first.substr(0, underscorePos); - std::string widgetName = userStringPair.first.substr(underscorePos+1, userStringPair.first.size()-(underscorePos+1)); + std::string widgetName = userStringPair.first.substr( + underscorePos + 1, userStringPair.first.size() - (underscorePos + 1)); type = "Property"; size_t caretPos = key.find('^'); @@ -293,7 +297,7 @@ namespace MWGui tooltip->setCoord(0, 0, tooltipSize.width, tooltipSize.height); } else - throw std::runtime_error ("unknown tooltip type"); + throw std::runtime_error("unknown tooltip type"); MyGUI::IntPoint tooltipPosition = MyGUI::InputManager::getInstance().getMousePosition(); @@ -308,10 +312,9 @@ namespace MWGui { MyGUI::IntSize tooltipSize = getToolTipViaPtr(mFocusObject.getRefData().getCount(), true, checkOwned()); - setCoord(viewSize.width/2 - tooltipSize.width/2, - std::max(0, int(mFocusToolTipY*viewSize.height - tooltipSize.height)), - tooltipSize.width, - tooltipSize.height); + setCoord(viewSize.width / 2 - tooltipSize.width / 2, + std::max(0, int(mFocusToolTipY * viewSize.height - tooltipSize.height)), tooltipSize.width, + tooltipSize.height); mDynamicToolTipBox->setVisible(true); } @@ -321,7 +324,9 @@ namespace MWGui void ToolTips::position(MyGUI::IntPoint& position, MyGUI::IntSize size, MyGUI::IntSize viewportSize) { position += MyGUI::IntPoint(0, 32) - - MyGUI::IntPoint(static_cast(MyGUI::InputManager::getInstance().getMousePosition().left / float(viewportSize.width) * size.width), 0); + - MyGUI::IntPoint(static_cast(MyGUI::InputManager::getInstance().getMousePosition().left + / float(viewportSize.width) * size.width), + 0); if ((position.left + size.width) > viewportSize.width) { @@ -342,7 +347,7 @@ namespace MWGui MyGUI::Gui::getInstance().destroyWidget(mDynamicToolTipBox->getChildAt(0)); } - for (unsigned int i=0; i < mMainWidget->getChildCount(); ++i) + for (unsigned int i = 0; i < mMainWidget->getChildCount(); ++i) { mMainWidget->getChildAt(i)->setVisible(false); } @@ -355,7 +360,7 @@ namespace MWGui update(mFrameDuration); } - MyGUI::IntSize ToolTips::getToolTipViaPtr (int count, bool image, bool isOwned) + MyGUI::IntSize ToolTips::getToolTipViaPtr(int count, bool image, bool isOwned) { // this the maximum width of the tooltip before it starts word-wrapping setCoord(0, 0, 300, 300); @@ -379,10 +384,10 @@ namespace MWGui return tooltipSize; } - + bool ToolTips::checkOwned() { - if(mFocusObject.isEmpty()) + if (mFocusObject.isEmpty()) return false; MWWorld::Ptr ptr = MWMechanics::getPlayer(); @@ -395,11 +400,14 @@ namespace MWGui MyGUI::IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info, bool isOwned) { mDynamicToolTipBox->setVisible(true); - - if((mShowOwned == 1 || mShowOwned == 3) && isOwned) - mDynamicToolTipBox->changeWidgetSkin(MWBase::Environment::get().getWindowManager()->isGuiMode() ? "HUD_Box_NoTransp_Owned" : "HUD_Box_Owned"); + + if ((mShowOwned == 1 || mShowOwned == 3) && isOwned) + mDynamicToolTipBox->changeWidgetSkin(MWBase::Environment::get().getWindowManager()->isGuiMode() + ? "HUD_Box_NoTransp_Owned" + : "HUD_Box_Owned"); else - mDynamicToolTipBox->changeWidgetSkin(MWBase::Environment::get().getWindowManager()->isGuiMode() ? "HUD_Box_NoTransp" : "HUD_Box"); + mDynamicToolTipBox->changeWidgetSkin( + MWBase::Environment::get().getWindowManager()->isGuiMode() ? "HUD_Box_NoTransp" : "HUD_Box"); const std::string& caption = info.caption; const std::string& image = info.icon; @@ -438,10 +446,11 @@ namespace MWGui const int maximumWidth = MyGUI::RenderManager::getInstance().getViewSize().width - imageCaptionHPadding * 2; - const std::string realImage = Misc::ResourceHelpers::correctIconPath(image, - MWBase::Environment::get().getResourceSystem()->getVFS()); + const std::string realImage + = Misc::ResourceHelpers::correctIconPath(image, MWBase::Environment::get().getResourceSystem()->getVFS()); - Gui::EditBox* captionWidget = mDynamicToolTipBox->createWidget("NormalText", MyGUI::IntCoord(0, 0, 300, 300), MyGUI::Align::Left | MyGUI::Align::Top, "ToolTipCaption"); + Gui::EditBox* captionWidget = mDynamicToolTipBox->createWidget( + "NormalText", MyGUI::IntCoord(0, 0, 300, 300), MyGUI::Align::Left | MyGUI::Align::Top, "ToolTipCaption"); captionWidget->setEditStatic(true); captionWidget->setNeedKeyFocus(false); captionWidget->setCaptionWithReplacing(caption); @@ -449,7 +458,9 @@ namespace MWGui int captionHeight = std::max(!caption.empty() ? captionSize.height : 0, imageSize); - Gui::EditBox* textWidget = mDynamicToolTipBox->createWidget("SandText", MyGUI::IntCoord(0, captionHeight+imageCaptionVPadding, 300, 300-captionHeight-imageCaptionVPadding), MyGUI::Align::Stretch, "ToolTipText"); + Gui::EditBox* textWidget = mDynamicToolTipBox->createWidget("SandText", + MyGUI::IntCoord(0, captionHeight + imageCaptionVPadding, 300, 300 - captionHeight - imageCaptionVPadding), + MyGUI::Align::Stretch, "ToolTipText"); textWidget->setEditStatic(true); textWidget->setEditMultiLine(true); textWidget->setEditWordWrap(info.wordWrap); @@ -459,63 +470,68 @@ namespace MWGui MyGUI::IntSize textSize = textWidget->getTextSize(); captionSize += MyGUI::IntSize(imageSize, 0); // adjust for image - MyGUI::IntSize totalSize = MyGUI::IntSize( std::min(std::max(textSize.width,captionSize.width + ((!image.empty()) ? imageCaptionHPadding : 0)),maximumWidth), - (!text.empty() ? textSize.height + imageCaptionVPadding : 0) + captionHeight ); + MyGUI::IntSize totalSize = MyGUI::IntSize( + std::min(std::max(textSize.width, captionSize.width + ((!image.empty()) ? imageCaptionHPadding : 0)), + maximumWidth), + (!text.empty() ? textSize.height + imageCaptionVPadding : 0) + captionHeight); for (const std::string& note : info.notes) { MyGUI::ImageBox* icon = mDynamicToolTipBox->createWidget("MarkerButton", - MyGUI::IntCoord(padding.left, totalSize.height+padding.top, 8, 8), MyGUI::Align::Default); + MyGUI::IntCoord(padding.left, totalSize.height + padding.top, 8, 8), MyGUI::Align::Default); icon->setColour(MyGUI::Colour(1.0f, 0.3f, 0.3f)); Gui::EditBox* edit = mDynamicToolTipBox->createWidget("SandText", - MyGUI::IntCoord(padding.left+8+4, totalSize.height+padding.top, 300-padding.left-8-4, 300-totalSize.height), - MyGUI::Align::Default); + MyGUI::IntCoord(padding.left + 8 + 4, totalSize.height + padding.top, 300 - padding.left - 8 - 4, + 300 - totalSize.height), + MyGUI::Align::Default); edit->setEditMultiLine(true); edit->setEditWordWrap(true); edit->setCaption(note); edit->setSize(edit->getWidth(), edit->getTextSize().height); - icon->setPosition(icon->getLeft(),(edit->getTop()+edit->getBottom())/2-icon->getHeight()/2); + icon->setPosition(icon->getLeft(), (edit->getTop() + edit->getBottom()) / 2 - icon->getHeight() / 2); totalSize.height += std::max(edit->getHeight(), icon->getHeight()); - totalSize.width = std::max(totalSize.width, edit->getWidth()+8+4); + totalSize.width = std::max(totalSize.width, edit->getWidth() + 8 + 4); } if (!info.effects.empty()) { MyGUI::Widget* effectArea = mDynamicToolTipBox->createWidget("", - MyGUI::IntCoord(padding.left, totalSize.height, 300-padding.left, 300-totalSize.height), + MyGUI::IntCoord(padding.left, totalSize.height, 300 - padding.left, 300 - totalSize.height), MyGUI::Align::Stretch); MyGUI::IntCoord coord(0, 6, totalSize.width, 24); - Widgets::MWEffectListPtr effectsWidget = effectArea->createWidget - ("MW_StatName", coord, MyGUI::Align::Default); + Widgets::MWEffectListPtr effectsWidget + = effectArea->createWidget("MW_StatName", coord, MyGUI::Align::Default); effectsWidget->setEffectList(info.effects); std::vector effectItems; int flag = info.isPotion ? Widgets::MWEffectList::EF_NoTarget : 0; flag |= info.isIngredient ? Widgets::MWEffectList::EF_NoMagnitude : 0; flag |= info.isIngredient ? Widgets::MWEffectList::EF_Constant : 0; - effectsWidget->createEffectWidgets(effectItems, effectArea, coord, info.isPotion || info.isIngredient, flag); - totalSize.height += coord.top-6; + effectsWidget->createEffectWidgets( + effectItems, effectArea, coord, info.isPotion || info.isIngredient, flag); + totalSize.height += coord.top - 6; totalSize.width = std::max(totalSize.width, coord.width); } if (enchant) { MyGUI::Widget* enchantArea = mDynamicToolTipBox->createWidget("", - MyGUI::IntCoord(padding.left, totalSize.height, 300-padding.left, 300-totalSize.height), + MyGUI::IntCoord(padding.left, totalSize.height, 300 - padding.left, 300 - totalSize.height), MyGUI::Align::Stretch); MyGUI::IntCoord coord(0, 6, totalSize.width, 24); - Widgets::MWEffectListPtr enchantWidget = enchantArea->createWidget - ("MW_StatName", coord, MyGUI::Align::Default); + Widgets::MWEffectListPtr enchantWidget + = enchantArea->createWidget("MW_StatName", coord, MyGUI::Align::Default); enchantWidget->setEffectList(Widgets::MWEffectList::effectListFromESM(&enchant->mEffects)); std::vector enchantEffectItems; - int flag = (enchant->mData.mType == ESM::Enchantment::ConstantEffect) ? Widgets::MWEffectList::EF_Constant : 0; + int flag + = (enchant->mData.mType == ESM::Enchantment::ConstantEffect) ? Widgets::MWEffectList::EF_Constant : 0; enchantWidget->createEffectWidgets(enchantEffectItems, enchantArea, coord, false, flag); - totalSize.height += coord.top-6; + totalSize.height += coord.top - 6; totalSize.width = std::max(totalSize.width, coord.width); if (enchant->mData.mType == ESM::Enchantment::WhenStrikes @@ -526,7 +542,8 @@ namespace MWGui const int chargeWidth = 204; - MyGUI::TextBox* chargeText = enchantArea->createWidget("SandText", MyGUI::IntCoord(0, 0, 10, 18), MyGUI::Align::Default, "ToolTipEnchantChargeText"); + MyGUI::TextBox* chargeText = enchantArea->createWidget( + "SandText", MyGUI::IntCoord(0, 0, 10, 18), MyGUI::Align::Default, "ToolTipEnchantChargeText"); chargeText->setCaptionWithReplacing("#{sCharges}"); const int chargeTextWidth = chargeText->getTextSize().width + 5; @@ -535,60 +552,69 @@ namespace MWGui totalSize.width = std::max(totalSize.width, chargeAndTextWidth); - chargeText->setCoord((totalSize.width - chargeAndTextWidth)/2, coord.top+6, chargeTextWidth, 18); + chargeText->setCoord((totalSize.width - chargeAndTextWidth) / 2, coord.top + 6, chargeTextWidth, 18); MyGUI::IntCoord chargeCoord; if (totalSize.width < chargeWidth) { totalSize.width = chargeWidth; - chargeCoord = MyGUI::IntCoord(0, coord.top+6, chargeWidth, 18); + chargeCoord = MyGUI::IntCoord(0, coord.top + 6, chargeWidth, 18); } else { - chargeCoord = MyGUI::IntCoord((totalSize.width - chargeAndTextWidth)/2 + chargeTextWidth, coord.top+6, chargeWidth, 18); + chargeCoord = MyGUI::IntCoord( + (totalSize.width - chargeAndTextWidth) / 2 + chargeTextWidth, coord.top + 6, chargeWidth, 18); } - Widgets::MWDynamicStatPtr chargeWidget = enchantArea->createWidget - ("MW_ChargeBar", chargeCoord, MyGUI::Align::Default); + Widgets::MWDynamicStatPtr chargeWidget = enchantArea->createWidget( + "MW_ChargeBar", chargeCoord, MyGUI::Align::Default); chargeWidget->setValue(charge, maxCharge); totalSize.height += 24; } } - captionWidget->setCoord( (totalSize.width - captionSize.width)/2 + imageSize, - (captionHeight-captionSize.height)/2, - captionSize.width-imageSize, - captionSize.height); + captionWidget->setCoord((totalSize.width - captionSize.width) / 2 + imageSize, + (captionHeight - captionSize.height) / 2, captionSize.width - imageSize, captionSize.height); - //if its too long we do hscroll with the caption + // if its too long we do hscroll with the caption if (captionSize.width > maximumWidth) { mHorizontalScrollIndex = mHorizontalScrollIndex + 2; - if (mHorizontalScrollIndex > captionSize.width){ + if (mHorizontalScrollIndex > captionSize.width) + { mHorizontalScrollIndex = -totalSize.width; } int horizontal_scroll = mHorizontalScrollIndex; - if (horizontal_scroll < 40){ + if (horizontal_scroll < 40) + { horizontal_scroll = 40; - }else{ + } + else + { horizontal_scroll = 80 - mHorizontalScrollIndex; } - captionWidget->setPosition (MyGUI::IntPoint(horizontal_scroll, captionWidget->getPosition().top + padding.top)); - } else { - captionWidget->setPosition (captionWidget->getPosition() + padding); + captionWidget->setPosition( + MyGUI::IntPoint(horizontal_scroll, captionWidget->getPosition().top + padding.top)); + } + else + { + captionWidget->setPosition(captionWidget->getPosition() + padding); } - textWidget->setPosition (textWidget->getPosition() + MyGUI::IntPoint(0, padding.top)); // only apply vertical padding, the horizontal works automatically due to Align::HCenter + textWidget->setPosition(textWidget->getPosition() + + MyGUI::IntPoint(0, + padding.top)); // only apply vertical padding, the horizontal works automatically due to Align::HCenter if (!image.empty()) { MyGUI::ImageBox* imageWidget = mDynamicToolTipBox->createWidget("ImageBox", - MyGUI::IntCoord((totalSize.width - captionSize.width - imageCaptionHPadding)/2, 0, imageSize, imageSize), + MyGUI::IntCoord( + (totalSize.width - captionSize.width - imageCaptionHPadding) / 2, 0, imageSize, imageSize), MyGUI::Align::Left | MyGUI::Align::Top); imageWidget->setImageTexture(realImage); - imageWidget->setPosition (imageWidget->getPosition() + padding); + imageWidget->setPosition(imageWidget->getPosition() + padding); } - totalSize += MyGUI::IntSize(padding.left*2, padding.top*2); + totalSize += MyGUI::IntSize(padding.left * 2, padding.top * 2); return totalSize; } @@ -622,7 +648,7 @@ namespace MWGui if (value == 0) return {}; else - return "\n" + prefix + ": " + toString(value*100) +"%"; + return "\n" + prefix + ": " + toString(value * 100) + "%"; } std::string ToolTips::getValueString(const int value, const std::string& prefix) @@ -654,8 +680,8 @@ namespace MWGui const std::string& soul = cellref.getSoul(); if (soul.empty()) return {}; - const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); - const ESM::Creature *creature = store.get().search(soul); + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + const ESM::Creature* creature = store.get().search(soul); if (!creature) return {}; if (creature->mName.empty()) @@ -670,8 +696,8 @@ namespace MWGui const std::string& factionId = cellref.getFaction(); if (!factionId.empty()) { - const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); - const ESM::Faction *fact = store.get().search(factionId); + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + const ESM::Faction* fact = store.get().search(factionId); if (fact != nullptr) { ret += getMiscString(fact->mName.empty() ? factionId : fact->mName, "Owner Faction"); @@ -687,8 +713,8 @@ namespace MWGui } } - std::vector > itemOwners = - MWBase::Environment::get().getMechanicsManager()->getStolenItemOwners(cellref.getRefId()); + std::vector> itemOwners + = MWBase::Environment::get().getMechanicsManager()->getStolenItemOwners(cellref.getRefId()); for (std::pair& owner : itemOwners) { @@ -722,7 +748,8 @@ namespace MWGui int units = 0; int years = fullDuration / secondsPerYear; int months = fullDuration % secondsPerYear / secondsPerMonth; - int days = fullDuration % secondsPerYear % secondsPerMonth / secondsPerDay; // Because a year is not exactly 12 "months" + int days = fullDuration % secondsPerYear % secondsPerMonth + / secondsPerDay; // Because a year is not exactly 12 "months" int hours = fullDuration % secondsPerDay / secondsPerHour; int minutes = fullDuration % secondsPerHour / secondsPerMinute; int seconds = fullDuration % secondsPerMinute; @@ -778,21 +805,19 @@ namespace MWGui if (skillId == -1) return; - const MWWorld::ESMStore &store = - MWBase::Environment::get().getWorld()->getStore(); + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); - const std::string &skillNameId = ESM::Skill::sSkillNameIds[skillId]; + const std::string& skillNameId = ESM::Skill::sSkillNameIds[skillId]; const ESM::Skill* skill = store.get().find(skillId); assert(skill); - const ESM::Attribute* attr = - store.get().find(skill->mData.mAttribute); + const ESM::Attribute* attr = store.get().find(skill->mData.mAttribute); assert(attr); std::string icon = "icons\\k\\" + ESM::Skill::sIconNames[skillId]; widget->setUserString("ToolTipType", "Layout"); widget->setUserString("ToolTipLayout", "SkillNoProgressToolTip"); - widget->setUserString("Caption_SkillNoProgressName", "#{"+skillNameId+"}"); + widget->setUserString("Caption_SkillNoProgressName", "#{" + skillNameId + "}"); widget->setUserString("Caption_SkillNoProgressDescription", skill->mDescription); widget->setUserString("Caption_SkillNoProgressAttribute", "#{sGoverningAttribute}: #{" + attr->mName + "}"); widget->setUserString("ImageTexture_SkillNoProgressImage", icon); @@ -809,8 +834,8 @@ namespace MWGui widget->setUserString("ToolTipType", "Layout"); widget->setUserString("ToolTipLayout", "AttributeToolTip"); - widget->setUserString("Caption_AttributeName", "#{"+name+"}"); - widget->setUserString("Caption_AttributeDescription", "#{"+desc+"}"); + widget->setUserString("Caption_AttributeName", "#{" + name + "}"); + widget->setUserString("Caption_AttributeDescription", "#{" + desc + "}"); widget->setUserString("ImageTexture_AttributeImage", icon); } @@ -819,8 +844,7 @@ namespace MWGui widget->setUserString("Caption_Caption", name); std::string specText; // get all skills of this specialisation - const MWWorld::Store &skills = - MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& skills = MWBase::Environment::get().getWorld()->getStore().get(); bool isFirst = true; for (auto& skillPair : skills) @@ -842,22 +866,22 @@ namespace MWGui void ToolTips::createBirthsignToolTip(MyGUI::Widget* widget, const std::string& birthsignId) { - const MWWorld::ESMStore &store = - MWBase::Environment::get().getWorld()->getStore(); + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); - const ESM::BirthSign *sign = store.get().find(birthsignId); + const ESM::BirthSign* sign = store.get().find(birthsignId); const VFS::Manager* const vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); widget->setUserString("ToolTipType", "Layout"); widget->setUserString("ToolTipLayout", "BirthSignToolTip"); - widget->setUserString("ImageTexture_BirthSignImage", Misc::ResourceHelpers::correctTexturePath(sign->mTexture, vfs)); + widget->setUserString( + "ImageTexture_BirthSignImage", Misc::ResourceHelpers::correctTexturePath(sign->mTexture, vfs)); std::string text = sign->mName + "\n#{fontcolourhtml=normal}" + sign->mDescription; std::vector abilities, powers, spells; for (const std::string& spellId : sign->mPowers.mList) { - const ESM::Spell *spell = store.get().search(spellId); + const ESM::Spell* spell = store.get().search(spellId); if (!spell) continue; // Skip spells which cannot be found ESM::Spell::SpellType type = static_cast(spell->mData.mType); @@ -873,7 +897,8 @@ namespace MWGui } using Category = std::pair&, std::string_view>; - for (const auto&[category, label] : std::initializer_list{{abilities, "sBirthsignmenu1"}, {powers, "sPowers"}, {spells, "sBirthsignmenu2"}}) + for (const auto& [category, label] : std::initializer_list{ + { abilities, "sBirthsignmenu1" }, { powers, "sPowers" }, { spells, "sBirthsignmenu2" } }) { bool addHeader = true; for (const ESM::Spell* spell : category) @@ -924,13 +949,13 @@ namespace MWGui void ToolTips::createMagicEffectToolTip(MyGUI::Widget* widget, short id) { - const ESM::MagicEffect* effect = - MWBase::Environment::get().getWorld ()->getStore ().get().find(id); - const std::string &name = ESM::MagicEffect::effectIdToString (id); + const ESM::MagicEffect* effect + = MWBase::Environment::get().getWorld()->getStore().get().find(id); + const std::string& name = ESM::MagicEffect::effectIdToString(id); std::string icon = effect->mIcon; int slashPos = icon.rfind('\\'); - icon.insert(slashPos+1, "b_"); + icon.insert(slashPos + 1, "b_"); icon = Misc::ResourceHelpers::correctIconPath(icon, MWBase::Environment::get().getResourceSystem()->getVFS()); widget->setUserString("ToolTipType", "Layout"); diff --git a/apps/openmw/mwgui/tooltips.hpp b/apps/openmw/mwgui/tooltips.hpp index d7bb87bdb0..1c2c434070 100644 --- a/apps/openmw/mwgui/tooltips.hpp +++ b/apps/openmw/mwgui/tooltips.hpp @@ -1,8 +1,8 @@ #ifndef MWGUI_TOOLTIPS_H #define MWGUI_TOOLTIPS_H -#include "layout.hpp" #include "../mwworld/ptr.hpp" +#include "layout.hpp" #include "widgets.hpp" @@ -24,7 +24,8 @@ namespace MWGui , isPotion(false) , isIngredient(false) , wordWrap(true) - {} + { + } std::string caption; std::string text; @@ -87,7 +88,7 @@ namespace MWGui static std::string getCellRefString(const MWWorld::CellRef& cellref); ///< Returns a string containing debug tooltip information about the given cellref. - static std::string getDurationString (float duration, const std::string& prefix); + static std::string getDurationString(float duration, const std::string& prefix); ///< Returns duration as two largest time units, rounded down. Note: not localized; no line break. // these do not create an actual tooltip, but they fill in the data that is required so the tooltip @@ -99,16 +100,16 @@ namespace MWGui static void createRaceToolTip(MyGUI::Widget* widget, const ESM::Race* playerRace); static void createClassToolTip(MyGUI::Widget* widget, const ESM::Class& playerClass); static void createMagicEffectToolTip(MyGUI::Widget* widget, short id); - + bool checkOwned(); /// Returns True if taking mFocusObject would be crime - + private: MyGUI::Widget* mDynamicToolTipBox; MWWorld::Ptr mFocusObject; - MyGUI::IntSize getToolTipViaPtr (int count, bool image = true, bool isOwned = false); + MyGUI::IntSize getToolTipViaPtr(int count, bool image = true, bool isOwned = false); ///< @return requested tooltip size MyGUI::IntSize createToolTip(const ToolTipInfo& info, bool isOwned = false); @@ -125,7 +126,6 @@ namespace MWGui int mHorizontalScrollIndex; - float mDelay; float mRemainingDelay; // remaining time until tooltip will show @@ -135,7 +135,7 @@ namespace MWGui bool mEnabled; bool mFullHelp; - + int mShowOwned; float mFrameDuration; diff --git a/apps/openmw/mwgui/tradeitemmodel.cpp b/apps/openmw/mwgui/tradeitemmodel.cpp index 22973ee91a..b3202c112a 100644 --- a/apps/openmw/mwgui/tradeitemmodel.cpp +++ b/apps/openmw/mwgui/tradeitemmodel.cpp @@ -21,7 +21,7 @@ namespace MWGui return true; } - ItemStack TradeItemModel::getItem (ModelIndex index) + ItemStack TradeItemModel::getItem(ModelIndex index) { if (index < 0) throw std::runtime_error("Invalid index supplied"); @@ -35,7 +35,7 @@ namespace MWGui return mItems.size(); } - void TradeItemModel::borrowImpl(const ItemStack &item, std::vector &out) + void TradeItemModel::borrowImpl(const ItemStack& item, std::vector& out) { bool found = false; for (ItemStack& itemStack : out) @@ -51,7 +51,7 @@ namespace MWGui out.push_back(item); } - void TradeItemModel::unborrowImpl(const ItemStack &item, size_t count, std::vector &out) + void TradeItemModel::unborrowImpl(const ItemStack& item, size_t count, std::vector& out) { std::vector::iterator it = out.begin(); bool found = false; @@ -72,33 +72,33 @@ namespace MWGui throw std::runtime_error("Can't find borrowed item to return"); } - void TradeItemModel::borrowItemFromUs (ModelIndex itemIndex, size_t count) + void TradeItemModel::borrowItemFromUs(ModelIndex itemIndex, size_t count) { ItemStack item = getItem(itemIndex); item.mCount = count; borrowImpl(item, mBorrowedFromUs); } - void TradeItemModel::borrowItemToUs (ModelIndex itemIndex, ItemModel* source, size_t count) + void TradeItemModel::borrowItemToUs(ModelIndex itemIndex, ItemModel* source, size_t count) { ItemStack item = source->getItem(itemIndex); item.mCount = count; borrowImpl(item, mBorrowedToUs); } - void TradeItemModel::returnItemBorrowedToUs (ModelIndex itemIndex, size_t count) + void TradeItemModel::returnItemBorrowedToUs(ModelIndex itemIndex, size_t count) { ItemStack item = getItem(itemIndex); unborrowImpl(item, count, mBorrowedToUs); } - void TradeItemModel::returnItemBorrowedFromUs (ModelIndex itemIndex, ItemModel* source, size_t count) + void TradeItemModel::returnItemBorrowedFromUs(ModelIndex itemIndex, ItemModel* source, size_t count) { ItemStack item = source->getItem(itemIndex); unborrowImpl(item, count, mBorrowedFromUs); } - void TradeItemModel::adjustEncumbrance(float &encumbrance) + void TradeItemModel::adjustEncumbrance(float& encumbrance) { for (ItemStack& itemStack : mBorrowedToUs) { @@ -130,8 +130,8 @@ namespace MWGui { // get index in the source model ItemModel* sourceModel = itemStack.mCreator; - size_t i=0; - for (; igetItemCount(); ++i) + size_t i = 0; + for (; i < sourceModel->getItemCount(); ++i) { if (itemStack.mBase == sourceModel->getItem(i).mBase) break; @@ -160,19 +160,19 @@ namespace MWGui mItems.clear(); // add regular items - for (size_t i=0; igetItemCount(); ++i) + for (size_t i = 0; i < mSourceModel->getItemCount(); ++i) { ItemStack item = mSourceModel->getItem(i); - if(!mMerchant.isEmpty()) + if (!mMerchant.isEmpty()) { MWWorld::Ptr base = item.mBase; - if(Misc::StringUtils::ciEqual(base.getCellRef().getRefId(), MWWorld::ContainerStore::sGoldId)) + if (Misc::StringUtils::ciEqual(base.getCellRef().getRefId(), MWWorld::ContainerStore::sGoldId)) continue; if (!base.getClass().showsInInventory(base)) return; - if(!base.getClass().canSell(base, services)) + if (!base.getClass().canSell(base, services)) continue; // Bound items may not be bought @@ -180,7 +180,7 @@ namespace MWGui continue; // don't show equipped items - if(mMerchant.getClass().hasInventoryStore(mMerchant)) + if (mMerchant.getClass().hasInventoryStore(mMerchant)) { MWWorld::InventoryStore& store = mMerchant.getClass().getInventoryStore(mMerchant); if (store.isEquipped(base)) diff --git a/apps/openmw/mwgui/tradeitemmodel.hpp b/apps/openmw/mwgui/tradeitemmodel.hpp index 5a22bab8d3..d395744d2a 100644 --- a/apps/openmw/mwgui/tradeitemmodel.hpp +++ b/apps/openmw/mwgui/tradeitemmodel.hpp @@ -17,28 +17,28 @@ namespace MWGui bool allowedToUseItems() const override; - ItemStack getItem (ModelIndex index) override; + ItemStack getItem(ModelIndex index) override; size_t getItemCount() override; void update() override; - void borrowItemFromUs (ModelIndex itemIndex, size_t count); + void borrowItemFromUs(ModelIndex itemIndex, size_t count); - void borrowItemToUs (ModelIndex itemIndex, ItemModel* source, size_t count); + void borrowItemToUs(ModelIndex itemIndex, ItemModel* source, size_t count); ///< @note itemIndex points to an item in \a source - void returnItemBorrowedToUs (ModelIndex itemIndex, size_t count); + void returnItemBorrowedToUs(ModelIndex itemIndex, size_t count); - void returnItemBorrowedFromUs (ModelIndex itemIndex, ItemModel* source, size_t count); + void returnItemBorrowedFromUs(ModelIndex itemIndex, ItemModel* source, size_t count); /// Permanently transfers items that were borrowed to us from another model to this model - void transferItems (); + void transferItems(); /// Aborts trade void abort(); /// Adjusts the given encumbrance by adding weight for items that have been lent to us, /// and removing weight for items we've lent to someone else. - void adjustEncumbrance (float& encumbrance); + void adjustEncumbrance(float& encumbrance); const std::vector getItemsBorrowedToUs() const; diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index 3abe10a6fb..60e0374ff2 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -1,18 +1,18 @@ #include "tradewindow.hpp" #include -#include #include #include +#include -#include #include +#include +#include "../mwbase/dialoguemanager.hpp" #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" -#include "../mwbase/windowmanager.hpp" #include "../mwbase/mechanicsmanager.hpp" -#include "../mwbase/dialoguemanager.hpp" +#include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" #include "../mwworld/class.hpp" #include "../mwworld/containerstore.hpp" @@ -21,18 +21,18 @@ #include "../mwmechanics/actorutil.hpp" #include "../mwmechanics/creaturestats.hpp" +#include "containeritemmodel.hpp" +#include "countdialog.hpp" #include "inventorywindow.hpp" #include "itemview.hpp" #include "sortfilteritemmodel.hpp" -#include "containeritemmodel.hpp" -#include "tradeitemmodel.hpp" -#include "countdialog.hpp" #include "tooltips.hpp" +#include "tradeitemmodel.hpp" namespace { - int getEffectiveValue (MWWorld::Ptr item, int count) + int getEffectiveValue(MWWorld::Ptr item, int count) { float price = static_cast(item.getClass().getValue(item)); if (item.getClass().hasItemHealth(item)) @@ -94,7 +94,8 @@ namespace MWGui mTotalBalance->eventValueChanged += MyGUI::newDelegate(this, &TradeWindow::onBalanceValueChanged); mTotalBalance->eventEditSelectAccept += MyGUI::newDelegate(this, &TradeWindow::onAccept); - mTotalBalance->setMinValue(std::numeric_limits::min()+1); // disallow INT_MIN since abs(INT_MIN) is undefined + mTotalBalance->setMinValue( + std::numeric_limits::min() + 1); // disallow INT_MIN since abs(INT_MIN) is undefined setCoord(400, 0, 400, 300); } @@ -114,7 +115,8 @@ namespace MWGui std::vector worldItems; MWBase::Environment::get().getWorld()->getItemsOwnedBy(actor, worldItems); - auto tradeModel = std::make_unique(std::make_unique(itemSources, worldItems), mPtr); + auto tradeModel + = std::make_unique(std::make_unique(itemSources, worldItems), mPtr); mTradeModel = tradeModel.get(); auto sortModel = std::make_unique(std::move(tradeModel)); mSortModel = sortModel.get(); @@ -176,7 +178,7 @@ namespace MWGui return true; } - void TradeWindow::onItemSelected (int index) + void TradeWindow::onItemSelected(int index) { const ItemStack& item = mSortModel->getItem(index); @@ -190,7 +192,7 @@ namespace MWGui { CountDialog* dialog = MWBase::Environment::get().getWindowManager()->getCountDialog(); std::string message = "#{sQuanityMenuMessage02}"; - std::string name{object.getClass().getName(object)}; + std::string name{ object.getClass().getName(object) }; name += MWGui::ToolTips::getSoulString(object.getCellRef()); dialog->openCountDialog(name, message, count); dialog->eventOkClicked.clear(); @@ -200,7 +202,7 @@ namespace MWGui else { mItemToSell = mSortModel->mapToSource(index); - sellItem (nullptr, count); + sellItem(nullptr, count); } } @@ -210,7 +212,8 @@ namespace MWGui std::string_view sound = item.mBase.getClass().getUpSoundId(item.mBase); MWBase::Environment::get().getWindowManager()->playSound(sound); - TradeItemModel* playerTradeModel = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getTradeModel(); + TradeItemModel* playerTradeModel + = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getTradeModel(); if (item.mType == ItemStack::Type_Barter) { @@ -231,17 +234,19 @@ namespace MWGui mItemView->update(); } - void TradeWindow::borrowItem (int index, size_t count) + void TradeWindow::borrowItem(int index, size_t count) { - TradeItemModel* playerTradeModel = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getTradeModel(); + TradeItemModel* playerTradeModel + = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getTradeModel(); mTradeModel->borrowItemToUs(index, playerTradeModel, count); mItemView->update(); sellToNpc(playerTradeModel->getItem(index).mBase, count, false); } - void TradeWindow::returnItem (int index, size_t count) + void TradeWindow::returnItem(int index, size_t count) { - TradeItemModel* playerTradeModel = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getTradeModel(); + TradeItemModel* playerTradeModel + = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getTradeModel(); const ItemStack& item = playerTradeModel->getItem(index); mTradeModel->returnItemBorrowedFromUs(index, playerTradeModel, count); mItemView->update(); @@ -258,18 +263,20 @@ namespace MWGui } else { - store.remove(MWWorld::ContainerStore::sGoldId, - amount, actor); + store.remove(MWWorld::ContainerStore::sGoldId, -amount, actor); } } void TradeWindow::onOfferButtonClicked(MyGUI::Widget* _sender) { - TradeItemModel* playerItemModel = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getTradeModel(); + TradeItemModel* playerItemModel + = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getTradeModel(); - const MWWorld::Store &gmst = - MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& gmst + = MWBase::Environment::get().getWorld()->getStore().get(); - if (mTotalBalance->getValue() == 0) mCurrentBalance = 0; + if (mTotalBalance->getValue() == 0) + mCurrentBalance = 0; // were there any items traded at all? const std::vector& playerBought = playerItemModel->getItemsBorrowedToUs(); @@ -277,8 +284,7 @@ namespace MWGui if (playerBought.empty() && merchantBought.empty()) { // user notification - MWBase::Environment::get().getWindowManager()-> - messageBox("#{sBarterDialog11}"); + MWBase::Environment::get().getWindowManager()->messageBox("#{sBarterDialog11}"); return; } @@ -289,8 +295,7 @@ namespace MWGui if (mCurrentBalance < 0 && playerGold < std::abs(mCurrentBalance)) { // user notification - MWBase::Environment::get().getWindowManager()-> - messageBox("#{sBarterDialog1}"); + MWBase::Environment::get().getWindowManager()->messageBox("#{sBarterDialog1}"); return; } @@ -298,21 +303,22 @@ namespace MWGui if (mCurrentBalance > 0 && getMerchantGold() < mCurrentBalance) { // user notification - MWBase::Environment::get().getWindowManager()-> - messageBox("#{sBarterDialog2}"); + MWBase::Environment::get().getWindowManager()->messageBox("#{sBarterDialog2}"); return; } // check if the player is attempting to sell back an item stolen from this actor for (const ItemStack& itemStack : merchantBought) { - if (MWBase::Environment::get().getMechanicsManager()->isItemStolenFrom(itemStack.mBase.getCellRef().getRefId(), mPtr)) + if (MWBase::Environment::get().getMechanicsManager()->isItemStolenFrom( + itemStack.mBase.getCellRef().getRefId(), mPtr)) { std::string msg = gmst.find("sNotifyMessage49")->mValue.getString(); msg = Misc::StringUtils::format(msg, itemStack.mBase.getClass().getName(itemStack.mBase)); MWBase::Environment::get().getWindowManager()->messageBox(msg); - MWBase::Environment::get().getMechanicsManager()->confiscateStolenItemToOwner(player, itemStack.mBase, mPtr, itemStack.mCount); + MWBase::Environment::get().getMechanicsManager()->confiscateStolenItemToOwner( + player, itemStack.mBase, mPtr, itemStack.mCount); onCancelButtonClicked(mCancelButton); MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode(); @@ -323,18 +329,18 @@ namespace MWGui bool offerAccepted = mTrading.haggle(player, mPtr, mCurrentBalance, mCurrentMerchantOffer); // apply disposition change if merchant is NPC - if ( mPtr.getClass().isNpc() ) { - int dispositionDelta = offerAccepted - ? gmst.find("iBarterSuccessDisposition")->mValue.getInteger() - : gmst.find("iBarterFailDisposition")->mValue.getInteger(); + if (mPtr.getClass().isNpc()) + { + int dispositionDelta = offerAccepted ? gmst.find("iBarterSuccessDisposition")->mValue.getInteger() + : gmst.find("iBarterFailDisposition")->mValue.getInteger(); MWBase::Environment::get().getDialogueManager()->applyBarterDispositionChange(dispositionDelta); } // display message on haggle failure - if ( !offerAccepted ) { - MWBase::Environment::get().getWindowManager()-> - messageBox("#{sNotifyMessage9}"); + if (!offerAccepted) + { + MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage9}"); return; } @@ -347,7 +353,7 @@ namespace MWGui { addOrRemoveGold(mCurrentBalance, player); mPtr.getClass().getCreatureStats(mPtr).setGoldPool( - mPtr.getClass().getCreatureStats(mPtr).getGoldPool() - mCurrentBalance ); + mPtr.getClass().getCreatureStats(mPtr).getGoldPool() - mCurrentBalance); } eventTradeDone(); @@ -356,7 +362,7 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Barter); } - void TradeWindow::onAccept(MyGUI::EditBox *sender) + void TradeWindow::onAccept(MyGUI::EditBox* sender) { onOfferButtonClicked(sender); @@ -376,9 +382,10 @@ namespace MWGui updateLabels(); } - void TradeWindow::addRepeatController(MyGUI::Widget *widget) + void TradeWindow::addRepeatController(MyGUI::Widget* widget) { - MyGUI::ControllerItem* item = MyGUI::ControllerManager::getInstance().createItem(MyGUI::ControllerRepeatClick::getClassTypeName()); + MyGUI::ControllerItem* item + = MyGUI::ControllerManager::getInstance().createItem(MyGUI::ControllerRepeatClick::getClassTypeName()); MyGUI::ControllerRepeatClick* controller = static_cast(item); controller->eventRepeatClick += newDelegate(this, &TradeWindow::onRepeatClick); MyGUI::ControllerManager::getInstance().addItem(widget, controller); @@ -404,7 +411,7 @@ namespace MWGui onDecreaseButtonTriggered(); } - void TradeWindow::onBalanceButtonReleased(MyGUI::Widget *_sender, int _left, int _top, MyGUI::MouseButton _id) + void TradeWindow::onBalanceButtonReleased(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) { MyGUI::ControllerManager::getInstance().removeItem(_sender); } @@ -427,19 +434,26 @@ namespace MWGui void TradeWindow::onIncreaseButtonTriggered() { // prevent overflows, and prevent entering INT_MIN since abs(INT_MIN) is undefined - if (mCurrentBalance == std::numeric_limits::max() || mCurrentBalance == std::numeric_limits::min()+1) + if (mCurrentBalance == std::numeric_limits::max() + || mCurrentBalance == std::numeric_limits::min() + 1) return; - if (mTotalBalance->getValue() == 0) mCurrentBalance = 0; - if (mCurrentBalance < 0) mCurrentBalance -= 1; - else mCurrentBalance += 1; + if (mTotalBalance->getValue() == 0) + mCurrentBalance = 0; + if (mCurrentBalance < 0) + mCurrentBalance -= 1; + else + mCurrentBalance += 1; updateLabels(); } void TradeWindow::onDecreaseButtonTriggered() { - if (mTotalBalance->getValue() == 0) mCurrentBalance = 0; - if (mCurrentBalance < 0) mCurrentBalance += 1; - else mCurrentBalance -= 1; + if (mTotalBalance->getValue() == 0) + mCurrentBalance = 0; + if (mCurrentBalance < 0) + mCurrentBalance += 1; + else + mCurrentBalance -= 1; updateLabels(); } @@ -449,7 +463,8 @@ namespace MWGui int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId); mPlayerGold->setCaptionWithReplacing("#{sYourGold} " + MyGUI::utility::toString(playerGold)); - TradeItemModel* playerTradeModel = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getTradeModel(); + TradeItemModel* playerTradeModel + = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getTradeModel(); const std::vector& playerBorrowed = playerTradeModel->getItemsBorrowedToUs(); const std::vector& merchantBorrowed = mTradeModel->getItemsBorrowedToUs(); @@ -474,7 +489,8 @@ namespace MWGui void TradeWindow::updateOffer() { - TradeItemModel* playerTradeModel = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getTradeModel(); + TradeItemModel* playerTradeModel + = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getTradeModel(); int merchantOffer = 0; @@ -486,8 +502,10 @@ namespace MWGui for (const ItemStack& itemStack : playerBorrowed) { const int basePrice = getEffectiveValue(itemStack.mBase, itemStack.mCount); - const int cap = static_cast(std::max(1.f, 0.75f * basePrice)); // Minimum buying price -- 75% of the base - const int buyingPrice = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, basePrice, true); + const int cap + = static_cast(std::max(1.f, 0.75f * basePrice)); // Minimum buying price -- 75% of the base + const int buyingPrice + = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, basePrice, true); merchantOffer -= std::max(cap, buyingPrice); } @@ -495,8 +513,10 @@ namespace MWGui for (const ItemStack& itemStack : merchantBorrowed) { const int basePrice = getEffectiveValue(itemStack.mBase, itemStack.mCount); - const int cap = static_cast(std::max(1.f, 0.75f * basePrice)); // Maximum selling price -- 75% of the base - const int sellingPrice = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, basePrice, false); + const int cap + = static_cast(std::max(1.f, 0.75f * basePrice)); // Maximum selling price -- 75% of the base + const int sellingPrice + = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, basePrice, false); merchantOffer += mPtr.getClass().isNpc() ? std::min(cap, sellingPrice) : sellingPrice; } @@ -518,7 +538,8 @@ namespace MWGui void TradeWindow::onReferenceUnavailable() { - // remove both Trade and Dialogue (since you always trade with the NPC/creature that you have previously talked to) + // remove both Trade and Dialogue (since you always trade with the NPC/creature that you have previously talked + // to) MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Barter); MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode(); } @@ -547,7 +568,7 @@ namespace MWGui void TradeWindow::onDeleteCustomData(const MWWorld::Ptr& ptr) { - if(mTradeModel && mTradeModel->usesContainer(ptr)) + if (mTradeModel && mTradeModel->usesContainer(ptr)) MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Barter); } } diff --git a/apps/openmw/mwgui/tradewindow.hpp b/apps/openmw/mwgui/tradewindow.hpp index 5ace09e8e2..62a51be0dd 100644 --- a/apps/openmw/mwgui/tradewindow.hpp +++ b/apps/openmw/mwgui/tradewindow.hpp @@ -24,96 +24,98 @@ namespace MWGui class TradeWindow : public WindowBase, public ReferenceInterface { - public: - TradeWindow(); + public: + TradeWindow(); - void setPtr(const MWWorld::Ptr& actor) override; + void setPtr(const MWWorld::Ptr& actor) override; - void onClose() override; - void onFrame(float dt) override; - void clear() override { resetReference(); } + void onClose() override; + void onFrame(float dt) override; + void clear() override { resetReference(); } - void borrowItem (int index, size_t count); - void returnItem (int index, size_t count); + void borrowItem(int index, size_t count); + void returnItem(int index, size_t count); - int getMerchantServices(); + int getMerchantServices(); - bool exit() override; + bool exit() override; - void resetReference() override; + void resetReference() override; - void onDeleteCustomData(const MWWorld::Ptr& ptr) override; + void onDeleteCustomData(const MWWorld::Ptr& ptr) override; - typedef MyGUI::delegates::CMultiDelegate0 EventHandle_TradeDone; - EventHandle_TradeDone eventTradeDone; + typedef MyGUI::delegates::CMultiDelegate0 EventHandle_TradeDone; + EventHandle_TradeDone eventTradeDone; - private: - ItemView* mItemView; - SortFilterItemModel* mSortModel; - TradeItemModel* mTradeModel; - MWMechanics::Trading mTrading; + private: + ItemView* mItemView; + SortFilterItemModel* mSortModel; + TradeItemModel* mTradeModel; + MWMechanics::Trading mTrading; - static const float sBalanceChangeInitialPause; // in seconds - static const float sBalanceChangeInterval; // in seconds + static const float sBalanceChangeInitialPause; // in seconds + static const float sBalanceChangeInterval; // in seconds - MyGUI::Button* mFilterAll; - MyGUI::Button* mFilterWeapon; - MyGUI::Button* mFilterApparel; - MyGUI::Button* mFilterMagic; - MyGUI::Button* mFilterMisc; + MyGUI::Button* mFilterAll; + MyGUI::Button* mFilterWeapon; + MyGUI::Button* mFilterApparel; + MyGUI::Button* mFilterMagic; + MyGUI::Button* mFilterMisc; - MyGUI::EditBox* mFilterEdit; + MyGUI::EditBox* mFilterEdit; - MyGUI::Button* mIncreaseButton; - MyGUI::Button* mDecreaseButton; - MyGUI::TextBox* mTotalBalanceLabel; - Gui::NumericEditBox* mTotalBalance; + MyGUI::Button* mIncreaseButton; + MyGUI::Button* mDecreaseButton; + MyGUI::TextBox* mTotalBalanceLabel; + Gui::NumericEditBox* mTotalBalance; - MyGUI::Widget* mBottomPane; + MyGUI::Widget* mBottomPane; - MyGUI::Button* mMaxSaleButton; - MyGUI::Button* mCancelButton; - MyGUI::Button* mOfferButton; - MyGUI::TextBox* mPlayerGold; - MyGUI::TextBox* mMerchantGold; + MyGUI::Button* mMaxSaleButton; + MyGUI::Button* mCancelButton; + MyGUI::Button* mOfferButton; + MyGUI::TextBox* mPlayerGold; + MyGUI::TextBox* mMerchantGold; - int mItemToSell; + int mItemToSell; - int mCurrentBalance; - int mCurrentMerchantOffer; + int mCurrentBalance; + int mCurrentMerchantOffer; - void sellToNpc(const MWWorld::Ptr& item, int count, bool boughtItem); ///< only used for adjusting the gold balance - void buyFromNpc(const MWWorld::Ptr& item, int count, bool soldItem); ///< only used for adjusting the gold balance + void sellToNpc( + const MWWorld::Ptr& item, int count, bool boughtItem); ///< only used for adjusting the gold balance + void buyFromNpc( + const MWWorld::Ptr& item, int count, bool soldItem); ///< only used for adjusting the gold balance - void updateOffer(); + void updateOffer(); - void onItemSelected (int index); - void sellItem (MyGUI::Widget* sender, int count); + void onItemSelected(int index); + void sellItem(MyGUI::Widget* sender, int count); - void onFilterChanged(MyGUI::Widget* _sender); - void onNameFilterChanged(MyGUI::EditBox* _sender); - void onOfferButtonClicked(MyGUI::Widget* _sender); - void onAccept(MyGUI::EditBox* sender); - void onCancelButtonClicked(MyGUI::Widget* _sender); - void onMaxSaleButtonClicked(MyGUI::Widget* _sender); - void onIncreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); - void onDecreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); - void onBalanceButtonReleased(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); - void onBalanceValueChanged(int value); - void onRepeatClick(MyGUI::Widget* widget, MyGUI::ControllerItem* controller); + void onFilterChanged(MyGUI::Widget* _sender); + void onNameFilterChanged(MyGUI::EditBox* _sender); + void onOfferButtonClicked(MyGUI::Widget* _sender); + void onAccept(MyGUI::EditBox* sender); + void onCancelButtonClicked(MyGUI::Widget* _sender); + void onMaxSaleButtonClicked(MyGUI::Widget* _sender); + void onIncreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); + void onDecreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); + void onBalanceButtonReleased(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); + void onBalanceValueChanged(int value); + void onRepeatClick(MyGUI::Widget* widget, MyGUI::ControllerItem* controller); - void addRepeatController(MyGUI::Widget* widget); + void addRepeatController(MyGUI::Widget* widget); - void onIncreaseButtonTriggered(); - void onDecreaseButtonTriggered(); + void onIncreaseButtonTriggered(); + void onDecreaseButtonTriggered(); - void addOrRemoveGold(int gold, const MWWorld::Ptr& actor); + void addOrRemoveGold(int gold, const MWWorld::Ptr& actor); - void updateLabels(); + void updateLabels(); - void onReferenceUnavailable() override; + void onReferenceUnavailable() override; - int getMerchantGold(); + int getMerchantGold(); }; } diff --git a/apps/openmw/mwgui/trainingwindow.cpp b/apps/openmw/mwgui/trainingwindow.cpp index 1955a79426..f8549d70fa 100644 --- a/apps/openmw/mwgui/trainingwindow.cpp +++ b/apps/openmw/mwgui/trainingwindow.cpp @@ -3,39 +3,39 @@ #include #include -#include "../mwbase/windowmanager.hpp" #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" #include "../mwworld/class.hpp" #include "../mwworld/containerstore.hpp" #include "../mwworld/esmstore.hpp" -#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/actorutil.hpp" +#include "../mwmechanics/npcstats.hpp" -#include #include +#include #include "tooltips.hpp" namespace { -// Sorts a container descending by skill value. If skill value is equal, sorts ascending by skill ID. -// pair -bool sortSkills (const std::pair& left, const std::pair& right) -{ - if (left == right) - return false; + // Sorts a container descending by skill value. If skill value is equal, sorts ascending by skill ID. + // pair + bool sortSkills(const std::pair& left, const std::pair& right) + { + if (left == right) + return false; - if (left.second > right.second) - return true; - else if (left.second < right.second) - return false; + if (left.second > right.second) + return true; + else if (left.second < right.second) + return false; - return left.first < right.first; -} + return left.first < right.first; + } } namespace MWGui @@ -44,7 +44,8 @@ namespace MWGui TrainingWindow::TrainingWindow() : WindowBase("openmw_trainingwindow.layout") , mTimeAdvancer(0.05f) - , mTrainingSkillBasedOnBaseSkill(Settings::Manager::getBool("trainers training skills based on base skill", "Game")) + , mTrainingSkillBasedOnBaseSkill( + Settings::Manager::getBool("trainers training skills based on base skill", "Game")) { getWidget(mTrainingOptions, "TrainingOptions"); getWidget(mCancelButton, "CancelButton"); @@ -69,7 +70,7 @@ namespace MWGui center(); } - void TrainingWindow::setPtr (const MWWorld::Ptr& actor) + void TrainingWindow::setPtr(const MWWorld::Ptr& actor) { mPtr = actor; @@ -79,10 +80,10 @@ namespace MWGui mPlayerGold->setCaptionWithReplacing("#{sGold}: " + MyGUI::utility::toString(playerGold)); // NPC can train you in his best 3 skills - std::vector< std::pair > skills; + std::vector> skills; MWMechanics::NpcStats const& actorStats(actor.getClass().getNpcStats(actor)); - for (int i=0; igetEnumerator (); - MyGUI::Gui::getInstance ().destroyWidgets (widgets); + MyGUI::EnumeratorWidgetPtr widgets = mTrainingOptions->getEnumerator(); + MyGUI::Gui::getInstance().destroyWidgets(widgets); - MWMechanics::NpcStats& pcStats = player.getClass().getNpcStats (player); + MWMechanics::NpcStats& pcStats = player.getClass().getNpcStats(player); - const MWWorld::Store &gmst = - MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& gmst + = MWBase::Environment::get().getWorld()->getStore().get(); const int lineHeight = MWBase::Environment::get().getWindowManager()->getFontHeight() + 2; - for (int i=0; i<3; ++i) + for (int i = 0; i < 3; ++i) { - int price = static_cast(pcStats.getSkill (skills[i].first).getBase() * gmst.find("iTrainingMod")->mValue.getInteger()); + int price = static_cast( + pcStats.getSkill(skills[i].first).getBase() * gmst.find("iTrainingMod")->mValue.getInteger()); price = std::max(1, price); price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, price, true); - MyGUI::Button* button = mTrainingOptions->createWidget(price <= playerGold ? "SandTextButton" : "SandTextButtonDisabled", // can't use setEnabled since that removes tooltip - MyGUI::IntCoord(5, 5+i*lineHeight, mTrainingOptions->getWidth()-10, lineHeight), MyGUI::Align::Default); + MyGUI::Button* button = mTrainingOptions->createWidget(price <= playerGold + ? "SandTextButton" + : "SandTextButtonDisabled", // can't use setEnabled since that removes tooltip + MyGUI::IntCoord(5, 5 + i * lineHeight, mTrainingOptions->getWidth() - 10, lineHeight), + MyGUI::Align::Default); button->setUserData(skills[i].first); button->eventMouseButtonClick += MyGUI::newDelegate(this, &TrainingWindow::onTrainingSelected); - button->setCaptionWithReplacing("#{" + ESM::Skill::sSkillNameIds[skills[i].first] + "} - " + MyGUI::utility::toString(price)); + button->setCaptionWithReplacing( + "#{" + ESM::Skill::sSkillNameIds[skills[i].first] + "} - " + MyGUI::utility::toString(price)); - button->setSize(button->getTextSize ().width+12, button->getSize().height); + button->setSize(button->getTextSize().width + 12, button->getSize().height); - ToolTips::createSkillToolTip (button, skills[i].first); + ToolTips::createSkillToolTip(button, skills[i].first); } center(); } - void TrainingWindow::onReferenceUnavailable () + void TrainingWindow::onReferenceUnavailable() { MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Training); } - void TrainingWindow::onCancelButtonClicked (MyGUI::Widget *sender) + void TrainingWindow::onCancelButtonClicked(MyGUI::Widget* sender) { MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Training); } - void TrainingWindow::onTrainingSelected (MyGUI::Widget *sender) + void TrainingWindow::onTrainingSelected(MyGUI::Widget* sender) { int skillId = *sender->getUserData(); - MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); - MWMechanics::NpcStats& pcStats = player.getClass().getNpcStats (player); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); + MWMechanics::NpcStats& pcStats = player.getClass().getNpcStats(player); - const MWWorld::ESMStore &store = - MWBase::Environment::get().getWorld()->getStore(); + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); - int price = pcStats.getSkill (skillId).getBase() * store.get().find("iTrainingMod")->mValue.getInteger(); - price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr,price,true); + int price = pcStats.getSkill(skillId).getBase() + * store.get().find("iTrainingMod")->mValue.getInteger(); + price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, price, true); if (price > player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId)) return; if (getSkillForTraining(mPtr.getClass().getNpcStats(mPtr), skillId) <= pcStats.getSkill(skillId).getBase()) { - MWBase::Environment::get().getWindowManager()->messageBox ("#{sServiceTrainingWords}"); + MWBase::Environment::get().getWindowManager()->messageBox("#{sServiceTrainingWords}"); return; } @@ -159,16 +165,15 @@ namespace MWGui const ESM::Skill* skill = MWBase::Environment::get().getWorld()->getStore().get().find(skillId); if (pcStats.getSkill(skillId).getBase() >= pcStats.getAttribute(skill->mData.mAttribute).getBase()) { - MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage17}"); + MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage17}"); return; } // increase skill - MWWorld::LiveCellRef *playerRef = player.get(); + MWWorld::LiveCellRef* playerRef = player.get(); - const ESM::Class *class_ = - store.get().find(playerRef->mBase->mClass); - pcStats.increaseSkill (skillId, *class_, true); + const ESM::Class* class_ = store.get().find(playerRef->mBase->mClass); + pcStats.increaseSkill(skillId, *class_, true); // remove gold player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, price, player); @@ -179,7 +184,7 @@ namespace MWGui // advance time MWBase::Environment::get().getMechanicsManager()->rest(2, false); - MWBase::Environment::get().getWorld ()->advanceTime (2); + MWBase::Environment::get().getWorld()->advanceTime(2); setVisible(false); mProgressBar.setVisible(true); @@ -200,7 +205,7 @@ namespace MWGui mProgressBar.setVisible(false); // go back to game mode - MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_Training); + MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Training); MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode(); } diff --git a/apps/openmw/mwgui/trainingwindow.hpp b/apps/openmw/mwgui/trainingwindow.hpp index 57fdd323a4..145c326150 100644 --- a/apps/openmw/mwgui/trainingwindow.hpp +++ b/apps/openmw/mwgui/trainingwindow.hpp @@ -1,10 +1,10 @@ #ifndef MWGUI_TRAININGWINDOW_H #define MWGUI_TRAININGWINDOW_H -#include "windowbase.hpp" #include "referenceinterface.hpp" #include "timeadvancer.hpp" #include "waitdialog.hpp" +#include "windowbase.hpp" namespace MWMechanics { @@ -34,7 +34,7 @@ namespace MWGui protected: void onReferenceUnavailable() override; - void onCancelButtonClicked (MyGUI::Widget* sender); + void onCancelButtonClicked(MyGUI::Widget* sender); void onTrainingSelected(MyGUI::Widget* sender); void onTrainingProgressChanged(int cur, int total); @@ -50,7 +50,7 @@ namespace MWGui WaitDialogProgressBar mProgressBar; TimeAdvancer mTimeAdvancer; - bool mTrainingSkillBasedOnBaseSkill; //corresponds to the setting 'training skills based on base skill' + bool mTrainingSkillBasedOnBaseSkill; // corresponds to the setting 'training skills based on base skill' }; } diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp index 9533e00375..506c2123db 100644 --- a/apps/openmw/mwgui/travelwindow.cpp +++ b/apps/openmw/mwgui/travelwindow.cpp @@ -1,33 +1,33 @@ #include "travelwindow.hpp" #include -#include #include +#include -#include -#include #include +#include +#include #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" -#include "../mwbase/windowmanager.hpp" #include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" -#include "../mwworld/class.hpp" -#include "../mwworld/containerstore.hpp" #include "../mwworld/actionteleport.hpp" #include "../mwworld/cellstore.hpp" #include "../mwworld/cellutils.hpp" -#include "../mwworld/store.hpp" +#include "../mwworld/class.hpp" +#include "../mwworld/containerstore.hpp" #include "../mwworld/esmstore.hpp" +#include "../mwworld/store.hpp" #include "../mwmechanics/actorutil.hpp" #include "../mwmechanics/creaturestats.hpp" namespace MWGui { - TravelWindow::TravelWindow() : - WindowBase("openmw_travel_window.layout") + TravelWindow::TravelWindow() + : WindowBase("openmw_travel_window.layout") , mCurrentY(0) { getWidget(mCancelButton, "CancelButton"); @@ -38,24 +38,19 @@ namespace MWGui mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TravelWindow::onCancelButtonClicked); - mDestinations->setCoord(450/2-mDestinations->getTextSize().width/2, - mDestinations->getTop(), - mDestinations->getTextSize().width, - mDestinations->getHeight()); - mSelect->setCoord(8, - mSelect->getTop(), - mSelect->getTextSize().width, - mSelect->getHeight()); + mDestinations->setCoord(450 / 2 - mDestinations->getTextSize().width / 2, mDestinations->getTop(), + mDestinations->getTextSize().width, mDestinations->getHeight()); + mSelect->setCoord(8, mSelect->getTop(), mSelect->getTextSize().width, mSelect->getHeight()); } - void TravelWindow::addDestination(const std::string& name, const ESM::Position &pos, bool interior) + void TravelWindow::addDestination(const std::string& name, const ESM::Position& pos, bool interior) { int price; - const MWWorld::Store &gmst = - MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& gmst + = MWBase::Environment::get().getWorld()->getStore().get(); - MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId); if (!mPtr.getCell()->isExterior()) @@ -65,7 +60,8 @@ namespace MWGui else { ESM::Position PlayerPos = player.getRefData().getPosition(); - float d = sqrt(pow(pos.pos[0] - PlayerPos.pos[0], 2) + pow(pos.pos[1] - PlayerPos.pos[1], 2) + pow(pos.pos[2] - PlayerPos.pos[2], 2)); + float d = sqrt(pow(pos.pos[0] - PlayerPos.pos[0], 2) + pow(pos.pos[1] - PlayerPos.pos[1], 2) + + pow(pos.pos[2] - PlayerPos.pos[2], 2)); float fTravelMult = gmst.find("fTravelMult")->mValue.getFloat(); if (fTravelMult != 0) price = static_cast(d / fTravelMult); @@ -85,17 +81,18 @@ namespace MWGui int lineHeight = MWBase::Environment::get().getWindowManager()->getFontHeight() + 2; - MyGUI::Button* toAdd = mDestinationsView->createWidget("SandTextButton", 0, mCurrentY, 200, lineHeight, MyGUI::Align::Default); + MyGUI::Button* toAdd = mDestinationsView->createWidget( + "SandTextButton", 0, mCurrentY, 200, lineHeight, MyGUI::Align::Default); toAdd->setEnabled(price <= playerGold); mCurrentY += lineHeight; - if(interior) - toAdd->setUserString("interior","y"); + if (interior) + toAdd->setUserString("interior", "y"); else - toAdd->setUserString("interior","n"); + toAdd->setUserString("interior", "n"); toAdd->setUserString("price", std::to_string(price)); - toAdd->setCaptionWithReplacing("#{sCell=" + name + "} - " + MyGUI::utility::toString(price)+"#{sgp}"); - toAdd->setSize(mDestinationsView->getWidth(),lineHeight); + toAdd->setCaptionWithReplacing("#{sCell=" + name + "} - " + MyGUI::utility::toString(price) + "#{sgp}"); + toAdd->setSize(mDestinationsView->getWidth(), lineHeight); toAdd->eventMouseWheel += MyGUI::newDelegate(this, &TravelWindow::onMouseWheel); toAdd->setUserString("Destination", name); toAdd->setUserData(pos); @@ -104,7 +101,7 @@ namespace MWGui void TravelWindow::clearDestinations() { - mDestinationsView->setViewOffset(MyGUI::IntPoint(0,0)); + mDestinationsView->setViewOffset(MyGUI::IntPoint(0, 0)); mCurrentY = 0; while (mDestinationsView->getChildCount()) MyGUI::Gui::getInstance().destroyWidget(mDestinationsView->getChildAt(0)); @@ -122,24 +119,28 @@ namespace MWGui else if (mPtr.getType() == ESM::Creature::sRecordId) transport = mPtr.get()->mBase->getTransport(); - for(unsigned int i = 0;igetExterior(cellIndex.x(), cellIndex.y()); + MWWorld::CellStore* cell + = MWBase::Environment::get().getWorld()->getExterior(cellIndex.x(), cellIndex.y()); cellname = MWBase::Environment::get().getWorld()->getCellName(cell); interior = false; } - addDestination(cellname,transport[i].mPos,interior); + addDestination(cellname, transport[i].mPos, interior); } updateLabels(); - // Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the scrollbar is hidden + // Canvas size must be expressed with VScroll disabled, otherwise MyGUI would expand the scroll area when the + // scrollbar is hidden mDestinationsView->setVisibleVScroll(false); - mDestinationsView->setCanvasSize (MyGUI::IntSize(mDestinationsView->getWidth(), std::max(mDestinationsView->getHeight(), mCurrentY))); + mDestinationsView->setCanvasSize( + MyGUI::IntSize(mDestinationsView->getWidth(), std::max(mDestinationsView->getHeight(), mCurrentY))); mDestinationsView->setVisibleVScroll(true); } @@ -152,7 +153,7 @@ namespace MWGui MWWorld::Ptr player = MWMechanics::getPlayer(); int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId); - if (playerGoldisExterior()) { ESM::Position playerPos = player.getRefData().getPosition(); - float d = (osg::Vec3f(pos.pos[0], pos.pos[1], 0) - osg::Vec3f(playerPos.pos[0], playerPos.pos[1], 0)).length(); - int hours = static_cast(d /MWBase::Environment::get().getWorld()->getStore().get().find("fTravelTimeMult")->mValue.getFloat()); - MWBase::Environment::get().getMechanicsManager ()->rest (hours, true); + float d + = (osg::Vec3f(pos.pos[0], pos.pos[1], 0) - osg::Vec3f(playerPos.pos[0], playerPos.pos[1], 0)).length(); + int hours = static_cast(d + / MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fTravelTimeMult") + ->mValue.getFloat()); + MWBase::Environment::get().getMechanicsManager()->rest(hours, true); MWBase::Environment::get().getWorld()->advanceTime(hours); } @@ -202,14 +210,11 @@ namespace MWGui void TravelWindow::updateLabels() { - MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId); mPlayerGold->setCaptionWithReplacing("#{sGold}: " + MyGUI::utility::toString(playerGold)); - mPlayerGold->setCoord(8, - mPlayerGold->getTop(), - mPlayerGold->getTextSize().width, - mPlayerGold->getHeight()); + mPlayerGold->setCoord(8, mPlayerGold->getTop(), mPlayerGold->getTextSize().width, mPlayerGold->getHeight()); } void TravelWindow::onReferenceUnavailable() @@ -220,10 +225,10 @@ namespace MWGui void TravelWindow::onMouseWheel(MyGUI::Widget* _sender, int _rel) { - if (mDestinationsView->getViewOffset().top + _rel*0.3f > 0) + if (mDestinationsView->getViewOffset().top + _rel * 0.3f > 0) mDestinationsView->setViewOffset(MyGUI::IntPoint(0, 0)); else - mDestinationsView->setViewOffset(MyGUI::IntPoint(0, static_cast(mDestinationsView->getViewOffset().top + _rel*0.3f))); + mDestinationsView->setViewOffset( + MyGUI::IntPoint(0, static_cast(mDestinationsView->getViewOffset().top + _rel * 0.3f))); } } - diff --git a/apps/openmw/mwgui/travelwindow.hpp b/apps/openmw/mwgui/travelwindow.hpp index dd970ee10e..75aa7a580f 100644 --- a/apps/openmw/mwgui/travelwindow.hpp +++ b/apps/openmw/mwgui/travelwindow.hpp @@ -1,43 +1,42 @@ #ifndef MWGUI_TravelWINDOW_H #define MWGUI_TravelWINDOW_H - -#include "windowbase.hpp" #include "referenceinterface.hpp" +#include "windowbase.hpp" namespace MyGUI { - class Gui; - class Widget; + class Gui; + class Widget; } namespace MWGui { class TravelWindow : public ReferenceInterface, public WindowBase { - public: - TravelWindow(); + public: + TravelWindow(); - void setPtr (const MWWorld::Ptr& actor) override; + void setPtr(const MWWorld::Ptr& actor) override; - protected: - MyGUI::Button* mCancelButton; - MyGUI::TextBox* mPlayerGold; - MyGUI::TextBox* mDestinations; - MyGUI::TextBox* mSelect; + protected: + MyGUI::Button* mCancelButton; + MyGUI::TextBox* mPlayerGold; + MyGUI::TextBox* mDestinations; + MyGUI::TextBox* mSelect; - MyGUI::ScrollView* mDestinationsView; + MyGUI::ScrollView* mDestinationsView; - void onCancelButtonClicked(MyGUI::Widget* _sender); - void onTravelButtonClick(MyGUI::Widget* _sender); - void onMouseWheel(MyGUI::Widget* _sender, int _rel); - void addDestination(const std::string& name, const ESM::Position& pos, bool interior); - void clearDestinations(); - int mCurrentY; + void onCancelButtonClicked(MyGUI::Widget* _sender); + void onTravelButtonClick(MyGUI::Widget* _sender); + void onMouseWheel(MyGUI::Widget* _sender, int _rel); + void addDestination(const std::string& name, const ESM::Position& pos, bool interior); + void clearDestinations(); + int mCurrentY; - void updateLabels(); + void updateLabels(); - void onReferenceUnavailable() override; + void onReferenceUnavailable() override; }; } diff --git a/apps/openmw/mwgui/ustring.hpp b/apps/openmw/mwgui/ustring.hpp index 1d8ec3ba13..5a6c30312a 100644 --- a/apps/openmw/mwgui/ustring.hpp +++ b/apps/openmw/mwgui/ustring.hpp @@ -8,7 +8,7 @@ namespace MWGui // FIXME: Remove once we get a version of MyGUI that supports string_view inline MyGUI::UString toUString(std::string_view string) { - return {string.data(), string.size()}; + return { string.data(), string.size() }; } } diff --git a/apps/openmw/mwgui/videowidget.cpp b/apps/openmw/mwgui/videowidget.cpp index a973db3a61..a82d8ce67f 100644 --- a/apps/openmw/mwgui/videowidget.cpp +++ b/apps/openmw/mwgui/videowidget.cpp @@ -7,113 +7,112 @@ #include #include -#include #include +#include #include "../mwsound/movieaudiofactory.hpp" namespace MWGui { -VideoWidget::VideoWidget() - : mVFS(nullptr) -{ - mPlayer = std::make_unique(); - setNeedKeyFocus(true); -} - -VideoWidget::~VideoWidget() = default; - -void VideoWidget::setVFS(const VFS::Manager *vfs) -{ - mVFS = vfs; -} + VideoWidget::VideoWidget() + : mVFS(nullptr) + { + mPlayer = std::make_unique(); + setNeedKeyFocus(true); + } -void VideoWidget::playVideo(const std::string &video) -{ - mPlayer->setAudioFactory(new MWSound::MovieAudioFactory()); + VideoWidget::~VideoWidget() = default; - Files::IStreamPtr videoStream; - try + void VideoWidget::setVFS(const VFS::Manager* vfs) { - videoStream = mVFS->get(video); + mVFS = vfs; } - catch (std::exception& e) + + void VideoWidget::playVideo(const std::string& video) { - Log(Debug::Error) << "Failed to open video: " << e.what(); - return; - } + mPlayer->setAudioFactory(new MWSound::MovieAudioFactory()); - mPlayer->playVideo(std::move(videoStream), video); + Files::IStreamPtr videoStream; + try + { + videoStream = mVFS->get(video); + } + catch (std::exception& e) + { + Log(Debug::Error) << "Failed to open video: " << e.what(); + return; + } - osg::ref_ptr texture = mPlayer->getVideoTexture(); - if (!texture) - return; + mPlayer->playVideo(std::move(videoStream), video); - mTexture = std::make_unique(texture); + osg::ref_ptr texture = mPlayer->getVideoTexture(); + if (!texture) + return; - setRenderItemTexture(mTexture.get()); - getSubWidgetMain()->_setUVSet(MyGUI::FloatRect(0.f, 1.f, 1.f, 0.f)); -} + mTexture = std::make_unique(texture); -int VideoWidget::getVideoWidth() -{ - return mPlayer->getVideoWidth(); -} + setRenderItemTexture(mTexture.get()); + getSubWidgetMain()->_setUVSet(MyGUI::FloatRect(0.f, 1.f, 1.f, 0.f)); + } -int VideoWidget::getVideoHeight() -{ - return mPlayer->getVideoHeight(); -} + int VideoWidget::getVideoWidth() + { + return mPlayer->getVideoWidth(); + } -bool VideoWidget::update() -{ - return mPlayer->update(); -} + int VideoWidget::getVideoHeight() + { + return mPlayer->getVideoHeight(); + } -void VideoWidget::stop() -{ - mPlayer->close(); -} + bool VideoWidget::update() + { + return mPlayer->update(); + } -void VideoWidget::pause() -{ - mPlayer->pause(); -} + void VideoWidget::stop() + { + mPlayer->close(); + } -void VideoWidget::resume() -{ - mPlayer->play(); -} + void VideoWidget::pause() + { + mPlayer->pause(); + } -bool VideoWidget::isPaused() const -{ - return mPlayer->isPaused(); -} + void VideoWidget::resume() + { + mPlayer->play(); + } -bool VideoWidget::hasAudioStream() -{ - return mPlayer->hasAudioStream(); -} + bool VideoWidget::isPaused() const + { + return mPlayer->isPaused(); + } -void VideoWidget::autoResize(bool stretch) -{ - MyGUI::IntSize screenSize = MyGUI::RenderManager::getInstance().getViewSize(); - if (getParent()) - screenSize = getParent()->getSize(); + bool VideoWidget::hasAudioStream() + { + return mPlayer->hasAudioStream(); + } - if (getVideoHeight() > 0 && !stretch) + void VideoWidget::autoResize(bool stretch) { - double imageaspect = static_cast(getVideoWidth())/getVideoHeight(); + MyGUI::IntSize screenSize = MyGUI::RenderManager::getInstance().getViewSize(); + if (getParent()) + screenSize = getParent()->getSize(); + + if (getVideoHeight() > 0 && !stretch) + { + double imageaspect = static_cast(getVideoWidth()) / getVideoHeight(); - int leftPadding = std::max(0, static_cast(screenSize.width - screenSize.height * imageaspect) / 2); - int topPadding = std::max(0, static_cast(screenSize.height - screenSize.width / imageaspect) / 2); + int leftPadding = std::max(0, static_cast(screenSize.width - screenSize.height * imageaspect) / 2); + int topPadding = std::max(0, static_cast(screenSize.height - screenSize.width / imageaspect) / 2); - setCoord(leftPadding, topPadding, - screenSize.width - leftPadding*2, screenSize.height - topPadding*2); + setCoord(leftPadding, topPadding, screenSize.width - leftPadding * 2, screenSize.height - topPadding * 2); + } + else + setCoord(0, 0, screenSize.width, screenSize.height); } - else - setCoord(0,0,screenSize.width,screenSize.height); -} } diff --git a/apps/openmw/mwgui/videowidget.hpp b/apps/openmw/mwgui/videowidget.hpp index 814b9ca73a..f6f70068e3 100644 --- a/apps/openmw/mwgui/videowidget.hpp +++ b/apps/openmw/mwgui/videowidget.hpp @@ -27,13 +27,13 @@ namespace MWGui MYGUI_RTTI_DERIVED(VideoWidget) VideoWidget(); - + ~VideoWidget(); /// Set the VFS (virtual file system) to find the videos on. void setVFS(const VFS::Manager* vfs); - void playVideo (const std::string& video); + void playVideo(const std::string& video); int getVideoWidth(); int getVideoHeight(); @@ -55,7 +55,7 @@ namespace MWGui /// based on the dimensions of the playing video. /// @param stretch Stretch the video to fill the whole screen? If false, /// black bars may be added to fix the aspect ratio. - void autoResize (bool stretch); + void autoResize(bool stretch); private: const VFS::Manager* mVFS; diff --git a/apps/openmw/mwgui/waitdialog.cpp b/apps/openmw/mwgui/waitdialog.cpp index c8abf87fcb..54a78d99bc 100644 --- a/apps/openmw/mwgui/waitdialog.cpp +++ b/apps/openmw/mwgui/waitdialog.cpp @@ -1,29 +1,29 @@ #include "waitdialog.hpp" -#include #include +#include #include #include -#include -#include -#include #include +#include +#include +#include -#include "../mwbase/windowmanager.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/statemanager.hpp" +#include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" -#include "../mwworld/class.hpp" #include "../mwworld/cellstore.hpp" +#include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" +#include "../mwmechanics/actorutil.hpp" #include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/npcstats.hpp" -#include "../mwmechanics/actorutil.hpp" namespace MWGui { @@ -40,10 +40,10 @@ namespace MWGui center(); } - void WaitDialogProgressBar::setProgress (int cur, int total) + void WaitDialogProgressBar::setProgress(int cur, int total) { - mProgressBar->setProgressRange (total); - mProgressBar->setProgressPosition (cur); + mProgressBar->setProgressRange(total); + mProgressBar->setProgressPosition(cur); mProgressText->setCaption(MyGUI::utility::toString(cur) + "/" + MyGUI::utility::toString(total)); } @@ -81,17 +81,17 @@ namespace MWGui mTimeAdvancer.eventFinished += MyGUI::newDelegate(this, &WaitDialog::onWaitingFinished); } - void WaitDialog::setPtr(const MWWorld::Ptr &ptr) + void WaitDialog::setPtr(const MWWorld::Ptr& ptr) { - setCanRest(!ptr.isEmpty() || MWBase::Environment::get().getWorld ()->canRest () == MWBase::World::Rest_Allowed); + setCanRest(!ptr.isEmpty() || MWBase::Environment::get().getWorld()->canRest() == MWBase::World::Rest_Allowed); - if (ptr.isEmpty() && MWBase::Environment::get().getWorld ()->canRest() == MWBase::World::Rest_PlayerIsInAir) + if (ptr.isEmpty() && MWBase::Environment::get().getWorld()->canRest() == MWBase::World::Rest_PlayerIsInAir) { // Resting in air is not allowed unless you're using a bed - MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage1}"); + MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage1}"); MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Rest); } - + if (mUntilHealedButton->getVisible()) MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mUntilHealedButton); else @@ -132,39 +132,43 @@ namespace MWGui mProgressBar.setVisible(false); } - if (!MWBase::Environment::get().getWindowManager ()->getRestEnabled ()) + if (!MWBase::Environment::get().getWindowManager()->getRestEnabled()) { - MWBase::Environment::get().getWindowManager()->popGuiMode (); + MWBase::Environment::get().getWindowManager()->popGuiMode(); } - MWBase::World::RestPermitted canRest = MWBase::Environment::get().getWorld ()->canRest (); + MWBase::World::RestPermitted canRest = MWBase::Environment::get().getWorld()->canRest(); if (canRest == MWBase::World::Rest_EnemiesAreNearby) { MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage2}"); - MWBase::Environment::get().getWindowManager()->popGuiMode (); + MWBase::Environment::get().getWindowManager()->popGuiMode(); } else if (canRest == MWBase::World::Rest_PlayerIsUnderwater) { // resting underwater not allowed - MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage1}"); - MWBase::Environment::get().getWindowManager()->popGuiMode (); + MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage1}"); + MWBase::Environment::get().getWindowManager()->popGuiMode(); } onHourSliderChangedPosition(mHourSlider, 0); - mHourSlider->setScrollPosition (0); + mHourSlider->setScrollPosition(0); - std::string_view month = MWBase::Environment::get().getWorld ()->getMonthName(); + std::string_view month = MWBase::Environment::get().getWorld()->getMonthName(); int hour = static_cast(MWBase::Environment::get().getWorld()->getTimeStamp().getHour()); bool pm = hour >= 12; - if (hour >= 13) hour -= 12; - if (hour == 0) hour = 12; + if (hour >= 13) + hour -= 12; + if (hour == 0) + hour = 12; ESM::EpochTimeStamp currentDate = MWBase::Environment::get().getWorld()->getEpochTimeStamp(); - std::string daysPassed = Misc::StringUtils::format("(#{sDay} %i)", MWBase::Environment::get().getWorld()->getTimeStamp().getDay()); + std::string daysPassed + = Misc::StringUtils::format("(#{sDay} %i)", MWBase::Environment::get().getWorld()->getTimeStamp().getDay()); std::string_view formattedHour(pm ? "#{sSaveMenuHelp05}" : "#{sSaveMenuHelp04}"); - std::string dateTimeText = Misc::StringUtils::format("%i %s %s %i %s", currentDate.mDay, month, daysPassed, hour, formattedHour); - mDateTimeText->setCaptionWithReplacing (dateTimeText); + std::string dateTimeText + = Misc::StringUtils::format("%i %s %s %i %s", currentDate.mDay, month, daysPassed, hour, formattedHour); + mDateTimeText->setCaptionWithReplacing(dateTimeText); } void WaitDialog::onUntilHealedButtonClicked(MyGUI::Widget* sender) @@ -181,7 +185,7 @@ namespace MWGui void WaitDialog::startWaiting(int hoursToWait) { - if(Settings::Manager::getBool("autosave","Saves")) //autosaves when enabled + if (Settings::Manager::getBool("autosave", "Saves")) // autosaves when enabled MWBase::Environment::get().getStateManager()->quickSave("Autosave"); MWBase::World* world = MWBase::Environment::get().getWorld(); @@ -199,15 +203,17 @@ namespace MWGui const std::string& regionstr = player.getCell()->getCell()->mRegion; if (!regionstr.empty()) { - const ESM::Region *region = world->getStore().get().find (regionstr); + const ESM::Region* region = world->getStore().get().find(regionstr); if (!region->mSleepList.empty()) { // figure out if player will be woken while sleeping int x = Misc::Rng::rollDice(hoursToWait, world->getPrng()); - float fSleepRandMod = world->getStore().get().find("fSleepRandMod")->mValue.getFloat(); + float fSleepRandMod + = world->getStore().get().find("fSleepRandMod")->mValue.getFloat(); if (x < fSleepRandMod * hoursToWait) { - float fSleepRestMod = world->getStore().get().find("fSleepRestMod")->mValue.getFloat(); + float fSleepRestMod + = world->getStore().get().find("fSleepRestMod")->mValue.getFloat(); int interruptAtHoursRemaining = int(fSleepRestMod * hoursToWait); if (interruptAtHoursRemaining != 0) { @@ -219,7 +225,7 @@ namespace MWGui } } - mProgressBar.setProgress (0, hoursToWait); + mProgressBar.setProgress(0, hoursToWait); } void WaitDialog::onCancelButtonClicked(MyGUI::Widget* sender) @@ -229,17 +235,18 @@ namespace MWGui void WaitDialog::onHourSliderChangedPosition(MyGUI::ScrollBar* sender, size_t position) { - mHourText->setCaptionWithReplacing (MyGUI::utility::toString(position+1) + " #{sRestMenu2}"); - mManualHours = position+1; + mHourText->setCaptionWithReplacing(MyGUI::utility::toString(position + 1) + " #{sRestMenu2}"); + mManualHours = position + 1; MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mWaitButton); } - void WaitDialog::onKeyButtonPressed(MyGUI::Widget *sender, MyGUI::KeyCode key, MyGUI::Char character) + void WaitDialog::onKeyButtonPressed(MyGUI::Widget* sender, MyGUI::KeyCode key, MyGUI::Char character) { if (key == MyGUI::KeyCode::ArrowUp) - mHourSlider->setScrollPosition(std::min(mHourSlider->getScrollPosition()+1, mHourSlider->getScrollRange()-1)); + mHourSlider->setScrollPosition( + std::min(mHourSlider->getScrollPosition() + 1, mHourSlider->getScrollRange() - 1)); else if (key == MyGUI::KeyCode::ArrowDown) - mHourSlider->setScrollPosition(std::max(static_cast(mHourSlider->getScrollPosition())-1, 0)); + mHourSlider->setScrollPosition(std::max(static_cast(mHourSlider->getScrollPosition()) - 1, 0)); else return; onHourSliderChangedPosition(mHourSlider, mHourSlider->getScrollPosition()); @@ -268,31 +275,30 @@ namespace MWGui stopWaiting(); MWWorld::Ptr player = MWMechanics::getPlayer(); - const MWMechanics::NpcStats &pcstats = player.getClass().getNpcStats(player); + const MWMechanics::NpcStats& pcstats = player.getClass().getNpcStats(player); // trigger levelup if possible - const MWWorld::Store &gmst = - MWBase::Environment::get().getWorld()->getStore().get(); - if (mSleeping && pcstats.getLevelProgress () >= gmst.find("iLevelUpTotal")->mValue.getInteger()) + const MWWorld::Store& gmst + = MWBase::Environment::get().getWorld()->getStore().get(); + if (mSleeping && pcstats.getLevelProgress() >= gmst.find("iLevelUpTotal")->mValue.getInteger()) { - MWBase::Environment::get().getWindowManager()->pushGuiMode (GM_Levelup); + MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Levelup); } } - void WaitDialog::setCanRest (bool canRest) + void WaitDialog::setCanRest(bool canRest) { MWWorld::Ptr player = MWMechanics::getPlayer(); MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player); bool full = (stats.getHealth().getCurrent() >= stats.getHealth().getModified()) - && (stats.getMagicka().getCurrent() >= stats.getMagicka().getModified()); + && (stats.getMagicka().getCurrent() >= stats.getMagicka().getModified()); MWMechanics::NpcStats& npcstats = player.getClass().getNpcStats(player); bool werewolf = npcstats.isWerewolf(); mUntilHealedButton->setVisible(canRest && !full); - mWaitButton->setCaptionWithReplacing (canRest ? "#{sRest}" : "#{sWait}"); - mRestText->setCaptionWithReplacing (canRest ? "#{sRestMenu3}" - : (werewolf ? "#{sWerewolfRestMessage}" - : "#{sRestIllegal}")); + mWaitButton->setCaptionWithReplacing(canRest ? "#{sRest}" : "#{sWait}"); + mRestText->setCaptionWithReplacing( + canRest ? "#{sRestMenu3}" : (werewolf ? "#{sWerewolfRestMessage}" : "#{sRestIllegal}")); mSleeping = canRest; @@ -319,16 +325,15 @@ namespace MWGui } } - void WaitDialog::stopWaiting () + void WaitDialog::stopWaiting() { MWBase::Environment::get().getWindowManager()->fadeScreenIn(0.2f); - mProgressBar.setVisible (false); - MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_Rest); + mProgressBar.setVisible(false); + MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Rest); mTimeAdvancer.stop(); } - - void WaitDialog::wakeUp () + void WaitDialog::wakeUp() { mSleeping = false; if (mInterruptAt != -1) diff --git a/apps/openmw/mwgui/waitdialog.hpp b/apps/openmw/mwgui/waitdialog.hpp index bf84e7e819..cff0d66bf8 100644 --- a/apps/openmw/mwgui/waitdialog.hpp +++ b/apps/openmw/mwgui/waitdialog.hpp @@ -27,7 +27,7 @@ namespace MWGui public: WaitDialog(); - void setPtr(const MWWorld::Ptr &ptr) override; + void setPtr(const MWWorld::Ptr& ptr) override; void onOpen() override; diff --git a/apps/openmw/mwgui/widgets.cpp b/apps/openmw/mwgui/widgets.cpp index aa88d58c4f..a6a5299289 100644 --- a/apps/openmw/mwgui/widgets.cpp +++ b/apps/openmw/mwgui/widgets.cpp @@ -3,19 +3,19 @@ #include #include -#include -#include #include +#include +#include -#include -#include -#include -#include #include +#include +#include +#include +#include #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" #include "../mwworld/esmstore.hpp" @@ -23,541 +23,535 @@ #include "ustring.hpp" namespace MWGui::Widgets - { - /* MWSkill */ +{ + /* MWSkill */ - MWSkill::MWSkill() - : mSkillId(ESM::Skill::Length) - , mSkillNameWidget(nullptr) - , mSkillValueWidget(nullptr) - { - } + MWSkill::MWSkill() + : mSkillId(ESM::Skill::Length) + , mSkillNameWidget(nullptr) + , mSkillValueWidget(nullptr) + { + } - void MWSkill::setSkillId(ESM::Skill::SkillEnum skill) - { - mSkillId = skill; - updateWidgets(); - } + void MWSkill::setSkillId(ESM::Skill::SkillEnum skill) + { + mSkillId = skill; + updateWidgets(); + } - void MWSkill::setSkillNumber(int skill) - { - if (skill < 0) - setSkillId(ESM::Skill::Length); - else if (skill < ESM::Skill::Length) - setSkillId(static_cast(skill)); - else - throw std::runtime_error("Skill number out of range"); - } + void MWSkill::setSkillNumber(int skill) + { + if (skill < 0) + setSkillId(ESM::Skill::Length); + else if (skill < ESM::Skill::Length) + setSkillId(static_cast(skill)); + else + throw std::runtime_error("Skill number out of range"); + } - void MWSkill::setSkillValue(const SkillValue& value) - { - mValue = value; - updateWidgets(); - } + void MWSkill::setSkillValue(const SkillValue& value) + { + mValue = value; + updateWidgets(); + } - void MWSkill::updateWidgets() + void MWSkill::updateWidgets() + { + if (mSkillNameWidget) { - if (mSkillNameWidget) + if (mSkillId == ESM::Skill::Length) { - if (mSkillId == ESM::Skill::Length) - { - mSkillNameWidget->setCaption(""); - } - else - { - MyGUI::UString name = toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString(ESM::Skill::sSkillNameIds[mSkillId], {})); - mSkillNameWidget->setCaption(name); - } + mSkillNameWidget->setCaption(""); } - if (mSkillValueWidget) + else { - SkillValue::Type modified = mValue.getModified(), base = mValue.getBase(); - mSkillValueWidget->setCaption(MyGUI::utility::toString(modified)); - if (modified > base) - mSkillValueWidget->_setWidgetState("increased"); - else if (modified < base) - mSkillValueWidget->_setWidgetState("decreased"); - else - mSkillValueWidget->_setWidgetState("normal"); + MyGUI::UString name = toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString( + ESM::Skill::sSkillNameIds[mSkillId], {})); + mSkillNameWidget->setCaption(name); } } - - void MWSkill::onClicked(MyGUI::Widget* _sender) - { - eventClicked(this); - } - - MWSkill::~MWSkill() + if (mSkillValueWidget) { + SkillValue::Type modified = mValue.getModified(), base = mValue.getBase(); + mSkillValueWidget->setCaption(MyGUI::utility::toString(modified)); + if (modified > base) + mSkillValueWidget->_setWidgetState("increased"); + else if (modified < base) + mSkillValueWidget->_setWidgetState("decreased"); + else + mSkillValueWidget->_setWidgetState("normal"); } + } - void MWSkill::initialiseOverride() - { - Base::initialiseOverride(); + void MWSkill::onClicked(MyGUI::Widget* _sender) + { + eventClicked(this); + } - assignWidget(mSkillNameWidget, "StatName"); - assignWidget(mSkillValueWidget, "StatValue"); + MWSkill::~MWSkill() {} - MyGUI::Button* button; - assignWidget(button, "StatNameButton"); - if (button) - { - mSkillNameWidget = button; - button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWSkill::onClicked); - } - - button = nullptr; - assignWidget(button, "StatValueButton"); - if (button) - { - mSkillValueWidget = button; - button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWSkill::onClicked); - } - } + void MWSkill::initialiseOverride() + { + Base::initialiseOverride(); - /* MWAttribute */ + assignWidget(mSkillNameWidget, "StatName"); + assignWidget(mSkillValueWidget, "StatValue"); - MWAttribute::MWAttribute() - : mId(-1) - , mAttributeNameWidget(nullptr) - , mAttributeValueWidget(nullptr) + MyGUI::Button* button; + assignWidget(button, "StatNameButton"); + if (button) { + mSkillNameWidget = button; + button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWSkill::onClicked); } - void MWAttribute::setAttributeId(int attributeId) + button = nullptr; + assignWidget(button, "StatValueButton"); + if (button) { - mId = attributeId; - updateWidgets(); + mSkillValueWidget = button; + button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWSkill::onClicked); } + } - void MWAttribute::setAttributeValue(const AttributeValue& value) - { - mValue = value; - updateWidgets(); - } + /* MWAttribute */ - void MWAttribute::onClicked(MyGUI::Widget* _sender) - { - eventClicked(this); - } + MWAttribute::MWAttribute() + : mId(-1) + , mAttributeNameWidget(nullptr) + , mAttributeValueWidget(nullptr) + { + } + + void MWAttribute::setAttributeId(int attributeId) + { + mId = attributeId; + updateWidgets(); + } - void MWAttribute::updateWidgets() + void MWAttribute::setAttributeValue(const AttributeValue& value) + { + mValue = value; + updateWidgets(); + } + + void MWAttribute::onClicked(MyGUI::Widget* _sender) + { + eventClicked(this); + } + + void MWAttribute::updateWidgets() + { + if (mAttributeNameWidget) { - if (mAttributeNameWidget) + if (mId < 0 || mId >= 8) { - if (mId < 0 || mId >= 8) - { - mAttributeNameWidget->setCaption(""); - } - else - { - static const std::string_view attributes[8] = { - "sAttributeStrength", - "sAttributeIntelligence", - "sAttributeWillpower", - "sAttributeAgility", - "sAttributeSpeed", - "sAttributeEndurance", - "sAttributePersonality", - "sAttributeLuck" - }; - MyGUI::UString name = toUString(MWBase::Environment::get().getWindowManager()->getGameSettingString(attributes[mId], {})); - mAttributeNameWidget->setCaption(name); - } + mAttributeNameWidget->setCaption(""); } - if (mAttributeValueWidget) + else { - int modified = mValue.getModified(), base = mValue.getBase(); - mAttributeValueWidget->setCaption(MyGUI::utility::toString(modified)); - if (modified > base) - mAttributeValueWidget->_setWidgetState("increased"); - else if (modified < base) - mAttributeValueWidget->_setWidgetState("decreased"); - else - mAttributeValueWidget->_setWidgetState("normal"); + static const std::string_view attributes[8] + = { "sAttributeStrength", "sAttributeIntelligence", "sAttributeWillpower", "sAttributeAgility", + "sAttributeSpeed", "sAttributeEndurance", "sAttributePersonality", "sAttributeLuck" }; + MyGUI::UString name = toUString( + MWBase::Environment::get().getWindowManager()->getGameSettingString(attributes[mId], {})); + mAttributeNameWidget->setCaption(name); } } - - MWAttribute::~MWAttribute() + if (mAttributeValueWidget) { + int modified = mValue.getModified(), base = mValue.getBase(); + mAttributeValueWidget->setCaption(MyGUI::utility::toString(modified)); + if (modified > base) + mAttributeValueWidget->_setWidgetState("increased"); + else if (modified < base) + mAttributeValueWidget->_setWidgetState("decreased"); + else + mAttributeValueWidget->_setWidgetState("normal"); } + } - void MWAttribute::initialiseOverride() - { - Base::initialiseOverride(); - - assignWidget(mAttributeNameWidget, "StatName"); - assignWidget(mAttributeValueWidget, "StatValue"); - - MyGUI::Button* button; - assignWidget(button, "StatNameButton"); - if (button) - { - mAttributeNameWidget = button; - button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWAttribute::onClicked); - } + MWAttribute::~MWAttribute() {} - button = nullptr; - assignWidget(button, "StatValueButton"); - if (button) - { - mAttributeValueWidget = button; - button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWAttribute::onClicked); - } - } + void MWAttribute::initialiseOverride() + { + Base::initialiseOverride(); - /* MWSpell */ + assignWidget(mAttributeNameWidget, "StatName"); + assignWidget(mAttributeValueWidget, "StatValue"); - MWSpell::MWSpell() - : mSpellNameWidget(nullptr) + MyGUI::Button* button; + assignWidget(button, "StatNameButton"); + if (button) { + mAttributeNameWidget = button; + button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWAttribute::onClicked); } - void MWSpell::setSpellId(const std::string &spellId) + button = nullptr; + assignWidget(button, "StatValueButton"); + if (button) { - mId = spellId; - updateWidgets(); + mAttributeValueWidget = button; + button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWAttribute::onClicked); } + } - void MWSpell::createEffectWidgets(std::vector &effects, MyGUI::Widget* creator, MyGUI::IntCoord &coord, int flags) - { - const MWWorld::ESMStore &store = - MWBase::Environment::get().getWorld()->getStore(); + /* MWSpell */ - const ESM::Spell *spell = store.get().search(mId); - MYGUI_ASSERT(spell, "spell with id '" << mId << "' not found"); + MWSpell::MWSpell() + : mSpellNameWidget(nullptr) + { + } - for (const ESM::ENAMstruct& effectInfo : spell->mEffects.mList) - { - MWSpellEffectPtr effect = creator->createWidget("MW_EffectImage", coord, MyGUI::Align::Default); - SpellEffectParams params; - params.mEffectID = effectInfo.mEffectID; - params.mSkill = effectInfo.mSkill; - params.mAttribute = effectInfo.mAttribute; - params.mDuration = effectInfo.mDuration; - params.mMagnMin = effectInfo.mMagnMin; - params.mMagnMax = effectInfo.mMagnMax; - params.mRange = effectInfo.mRange; - params.mIsConstant = (flags & MWEffectList::EF_Constant) != 0; - params.mNoTarget = (flags & MWEffectList::EF_NoTarget); - params.mNoMagnitude = (flags & MWEffectList::EF_NoMagnitude); - effect->setSpellEffect(params); - effects.push_back(effect); - coord.top += effect->getHeight(); - coord.width = std::max(coord.width, effect->getRequestedWidth()); - } - } + void MWSpell::setSpellId(const std::string& spellId) + { + mId = spellId; + updateWidgets(); + } - void MWSpell::updateWidgets() - { - if (mSpellNameWidget && MWBase::Environment::get().getWindowManager()) - { - const MWWorld::ESMStore &store = - MWBase::Environment::get().getWorld()->getStore(); - - const ESM::Spell *spell = store.get().search(mId); - if (spell) - mSpellNameWidget->setCaption(spell->mName); - else - mSpellNameWidget->setCaption(""); - } + void MWSpell::createEffectWidgets( + std::vector& effects, MyGUI::Widget* creator, MyGUI::IntCoord& coord, int flags) + { + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + + const ESM::Spell* spell = store.get().search(mId); + MYGUI_ASSERT(spell, "spell with id '" << mId << "' not found"); + + for (const ESM::ENAMstruct& effectInfo : spell->mEffects.mList) + { + MWSpellEffectPtr effect + = creator->createWidget("MW_EffectImage", coord, MyGUI::Align::Default); + SpellEffectParams params; + params.mEffectID = effectInfo.mEffectID; + params.mSkill = effectInfo.mSkill; + params.mAttribute = effectInfo.mAttribute; + params.mDuration = effectInfo.mDuration; + params.mMagnMin = effectInfo.mMagnMin; + params.mMagnMax = effectInfo.mMagnMax; + params.mRange = effectInfo.mRange; + params.mIsConstant = (flags & MWEffectList::EF_Constant) != 0; + params.mNoTarget = (flags & MWEffectList::EF_NoTarget); + params.mNoMagnitude = (flags & MWEffectList::EF_NoMagnitude); + effect->setSpellEffect(params); + effects.push_back(effect); + coord.top += effect->getHeight(); + coord.width = std::max(coord.width, effect->getRequestedWidth()); } + } - void MWSpell::initialiseOverride() + void MWSpell::updateWidgets() + { + if (mSpellNameWidget && MWBase::Environment::get().getWindowManager()) { - Base::initialiseOverride(); + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); - assignWidget(mSpellNameWidget, "StatName"); + const ESM::Spell* spell = store.get().search(mId); + if (spell) + mSpellNameWidget->setCaption(spell->mName); + else + mSpellNameWidget->setCaption(""); } + } - MWSpell::~MWSpell() - { - } + void MWSpell::initialiseOverride() + { + Base::initialiseOverride(); + + assignWidget(mSpellNameWidget, "StatName"); + } - /* MWEffectList */ + MWSpell::~MWSpell() {} - MWEffectList::MWEffectList() - : mEffectList(0) - { - } + /* MWEffectList */ + + MWEffectList::MWEffectList() + : mEffectList(0) + { + } + + void MWEffectList::setEffectList(const SpellEffectList& list) + { + mEffectList = list; + updateWidgets(); + } + + void MWEffectList::createEffectWidgets( + std::vector& effects, MyGUI::Widget* creator, MyGUI::IntCoord& coord, bool center, int flags) + { + // We don't know the width of all the elements beforehand, so we do it in + // 2 steps: first, create all widgets and check their width.... + MWSpellEffectPtr effect = nullptr; + int maxwidth = coord.width; - void MWEffectList::setEffectList(const SpellEffectList& list) + for (auto& effectInfo : mEffectList) { - mEffectList = list; - updateWidgets(); + effect = creator->createWidget("MW_EffectImage", coord, MyGUI::Align::Default); + effectInfo.mIsConstant = (flags & EF_Constant) || effectInfo.mIsConstant; + effectInfo.mNoTarget = (flags & EF_NoTarget) || effectInfo.mNoTarget; + effectInfo.mNoMagnitude = (flags & EF_NoMagnitude) || effectInfo.mNoMagnitude; + effect->setSpellEffect(effectInfo); + effects.push_back(effect); + if (effect->getRequestedWidth() > maxwidth) + maxwidth = effect->getRequestedWidth(); + + coord.top += effect->getHeight(); } - void MWEffectList::createEffectWidgets(std::vector &effects, MyGUI::Widget* creator, MyGUI::IntCoord &coord, bool center, int flags) + // ... then adjust the size for all widgets + for (MyGUI::Widget* effectWidget : effects) { - // We don't know the width of all the elements beforehand, so we do it in - // 2 steps: first, create all widgets and check their width.... - MWSpellEffectPtr effect = nullptr; - int maxwidth = coord.width; - - for (auto& effectInfo : mEffectList) + effect = effectWidget->castType(); + bool needcenter = center && (maxwidth > effect->getRequestedWidth()); + int diff = maxwidth - effect->getRequestedWidth(); + if (needcenter) { - effect = creator->createWidget("MW_EffectImage", coord, MyGUI::Align::Default); - effectInfo.mIsConstant = (flags & EF_Constant) || effectInfo.mIsConstant; - effectInfo.mNoTarget = (flags & EF_NoTarget) || effectInfo.mNoTarget; - effectInfo.mNoMagnitude = (flags & EF_NoMagnitude) || effectInfo.mNoMagnitude; - effect->setSpellEffect(effectInfo); - effects.push_back(effect); - if (effect->getRequestedWidth() > maxwidth) - maxwidth = effect->getRequestedWidth(); - - coord.top += effect->getHeight(); + effect->setCoord( + diff / 2, effect->getCoord().top, effect->getRequestedWidth(), effect->getCoord().height); } - - // ... then adjust the size for all widgets - for (MyGUI::Widget* effectWidget : effects) + else { - effect = effectWidget->castType(); - bool needcenter = center && (maxwidth > effect->getRequestedWidth()); - int diff = maxwidth - effect->getRequestedWidth(); - if (needcenter) - { - effect->setCoord(diff/2, effect->getCoord().top, effect->getRequestedWidth(), effect->getCoord().height); - } - else - { - effect->setCoord(0, effect->getCoord().top, effect->getRequestedWidth(), effect->getCoord().height); - } + effect->setCoord(0, effect->getCoord().top, effect->getRequestedWidth(), effect->getCoord().height); } - - // inform the parent about width - coord.width = maxwidth; } - void MWEffectList::updateWidgets() - { - } + // inform the parent about width + coord.width = maxwidth; + } - void MWEffectList::initialiseOverride() - { - Base::initialiseOverride(); - } + void MWEffectList::updateWidgets() {} - MWEffectList::~MWEffectList() - { - } + void MWEffectList::initialiseOverride() + { + Base::initialiseOverride(); + } - SpellEffectList MWEffectList::effectListFromESM(const ESM::EffectList* effects) - { - SpellEffectList result; - for (const ESM::ENAMstruct& effectInfo : effects->mList) - { - SpellEffectParams params; - params.mEffectID = effectInfo.mEffectID; - params.mSkill = effectInfo.mSkill; - params.mAttribute = effectInfo.mAttribute; - params.mDuration = effectInfo.mDuration; - params.mMagnMin = effectInfo.mMagnMin; - params.mMagnMax = effectInfo.mMagnMax; - params.mRange = effectInfo.mRange; - params.mArea = effectInfo.mArea; - result.push_back(params); - } - return result; - } + MWEffectList::~MWEffectList() {} + + SpellEffectList MWEffectList::effectListFromESM(const ESM::EffectList* effects) + { + SpellEffectList result; + for (const ESM::ENAMstruct& effectInfo : effects->mList) + { + SpellEffectParams params; + params.mEffectID = effectInfo.mEffectID; + params.mSkill = effectInfo.mSkill; + params.mAttribute = effectInfo.mAttribute; + params.mDuration = effectInfo.mDuration; + params.mMagnMin = effectInfo.mMagnMin; + params.mMagnMax = effectInfo.mMagnMax; + params.mRange = effectInfo.mRange; + params.mArea = effectInfo.mArea; + result.push_back(params); + } + return result; + } - /* MWSpellEffect */ + /* MWSpellEffect */ - MWSpellEffect::MWSpellEffect() - : mImageWidget(nullptr) - , mTextWidget(nullptr) - , mRequestedWidth(0) - { - } + MWSpellEffect::MWSpellEffect() + : mImageWidget(nullptr) + , mTextWidget(nullptr) + , mRequestedWidth(0) + { + } - void MWSpellEffect::setSpellEffect(const SpellEffectParams& params) + void MWSpellEffect::setSpellEffect(const SpellEffectParams& params) + { + mEffectParams = params; + updateWidgets(); + } + + void MWSpellEffect::updateWidgets() + { + if (!mEffectParams.mKnown) { - mEffectParams = params; - updateWidgets(); + mTextWidget->setCaption("?"); + mTextWidget->setCoord(sIconOffset / 2, mTextWidget->getCoord().top, mTextWidget->getCoord().width, + mTextWidget->getCoord().height); // Compensates for the missing image when effect is not known + mRequestedWidth = mTextWidget->getTextSize().width + sIconOffset; + mImageWidget->setImageTexture(""); + return; } - void MWSpellEffect::updateWidgets() - { - if (!mEffectParams.mKnown) - { - mTextWidget->setCaption ("?"); - mTextWidget->setCoord(sIconOffset / 2, mTextWidget->getCoord().top, mTextWidget->getCoord().width, mTextWidget->getCoord().height); // Compensates for the missing image when effect is not known - mRequestedWidth = mTextWidget->getTextSize().width + sIconOffset; - mImageWidget->setImageTexture (""); - return; - } + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); - const MWWorld::ESMStore &store = - MWBase::Environment::get().getWorld()->getStore(); + const ESM::MagicEffect* magicEffect = store.get().search(mEffectParams.mEffectID); - const ESM::MagicEffect *magicEffect = - store.get().search(mEffectParams.mEffectID); + assert(magicEffect); - assert(magicEffect); + std::string_view pt = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoint", {}); + std::string_view pts = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoints", {}); + std::string_view pct = MWBase::Environment::get().getWindowManager()->getGameSettingString("spercent", {}); + std::string_view ft = MWBase::Environment::get().getWindowManager()->getGameSettingString("sfeet", {}); + std::string_view lvl = MWBase::Environment::get().getWindowManager()->getGameSettingString("sLevel", {}); + std::string_view lvls = MWBase::Environment::get().getWindowManager()->getGameSettingString("sLevels", {}); + std::string to + = " " + std::string{ MWBase::Environment::get().getWindowManager()->getGameSettingString("sTo", {}) } + " "; + std::string sec + = " " + std::string{ MWBase::Environment::get().getWindowManager()->getGameSettingString("ssecond", {}) }; + std::string secs + = " " + std::string{ MWBase::Environment::get().getWindowManager()->getGameSettingString("sseconds", {}) }; - std::string_view pt = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoint", {}); - std::string_view pts = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoints", {}); - std::string_view pct = MWBase::Environment::get().getWindowManager()->getGameSettingString("spercent", {}); - std::string_view ft = MWBase::Environment::get().getWindowManager()->getGameSettingString("sfeet", {}); - std::string_view lvl = MWBase::Environment::get().getWindowManager()->getGameSettingString("sLevel", {}); - std::string_view lvls = MWBase::Environment::get().getWindowManager()->getGameSettingString("sLevels", {}); - std::string to = " " + std::string{MWBase::Environment::get().getWindowManager()->getGameSettingString("sTo", {})} + " "; - std::string sec = " " + std::string{MWBase::Environment::get().getWindowManager()->getGameSettingString("ssecond", {})}; - std::string secs = " " + std::string{MWBase::Environment::get().getWindowManager()->getGameSettingString("sseconds", {})}; + const std::string& effectIDStr = ESM::MagicEffect::effectIdToString(mEffectParams.mEffectID); + std::string spellLine{ MWBase::Environment::get().getWindowManager()->getGameSettingString(effectIDStr, {}) }; - const std::string& effectIDStr = ESM::MagicEffect::effectIdToString(mEffectParams.mEffectID); - std::string spellLine{MWBase::Environment::get().getWindowManager()->getGameSettingString(effectIDStr, {})}; + if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetSkill && mEffectParams.mSkill != -1) + { + spellLine += ' '; + spellLine += MWBase::Environment::get().getWindowManager()->getGameSettingString( + ESM::Skill::sSkillNameIds[mEffectParams.mSkill], {}); + } + if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetAttribute && mEffectParams.mAttribute != -1) + { + spellLine += ' '; + spellLine += MWBase::Environment::get().getWindowManager()->getGameSettingString( + ESM::Attribute::sGmstAttributeIds[mEffectParams.mAttribute], {}); + } - if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetSkill && mEffectParams.mSkill != -1) - { - spellLine += ' '; - spellLine += MWBase::Environment::get().getWindowManager()->getGameSettingString(ESM::Skill::sSkillNameIds[mEffectParams.mSkill], {}); - } - if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetAttribute && mEffectParams.mAttribute != -1) + if (mEffectParams.mMagnMin || mEffectParams.mMagnMax) + { + ESM::MagicEffect::MagnitudeDisplayType displayType = magicEffect->getMagnitudeDisplayType(); + if (displayType == ESM::MagicEffect::MDT_TimesInt) { - spellLine += ' '; - spellLine += MWBase::Environment::get().getWindowManager()->getGameSettingString(ESM::Attribute::sGmstAttributeIds[mEffectParams.mAttribute], {}); - } + std::string_view timesInt + = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimesINT", {}); + std::stringstream formatter; - if (mEffectParams.mMagnMin || mEffectParams.mMagnMax) { - ESM::MagicEffect::MagnitudeDisplayType displayType = magicEffect->getMagnitudeDisplayType(); - if ( displayType == ESM::MagicEffect::MDT_TimesInt ) { - std::string_view timesInt = MWBase::Environment::get().getWindowManager()->getGameSettingString("sXTimesINT", {}); - std::stringstream formatter; + formatter << std::fixed << std::setprecision(1) << " " << (mEffectParams.mMagnMin / 10.0f); + if (mEffectParams.mMagnMin != mEffectParams.mMagnMax) + formatter << to << (mEffectParams.mMagnMax / 10.0f); + formatter << timesInt; - formatter << std::fixed << std::setprecision(1) << " " << (mEffectParams.mMagnMin / 10.0f); - if (mEffectParams.mMagnMin != mEffectParams.mMagnMax) - formatter << to << (mEffectParams.mMagnMax / 10.0f); - formatter << timesInt; - - spellLine += formatter.str(); - } - else if ( displayType != ESM::MagicEffect::MDT_None && !mEffectParams.mNoMagnitude) { - spellLine += " " + MyGUI::utility::toString(mEffectParams.mMagnMin); - if (mEffectParams.mMagnMin != mEffectParams.mMagnMax) - spellLine += to + MyGUI::utility::toString(mEffectParams.mMagnMax); - - if ( displayType == ESM::MagicEffect::MDT_Percentage ) - spellLine += pct; - else if ( displayType == ESM::MagicEffect::MDT_Feet ) - { - spellLine += ' '; - spellLine += ft; - } - else if ( displayType == ESM::MagicEffect::MDT_Level ) - { - spellLine += ' '; - if (mEffectParams.mMagnMin == mEffectParams.mMagnMax && std::abs(mEffectParams.mMagnMin) == 1) - spellLine += lvl; - else - spellLine += lvls; - } - else // ESM::MagicEffect::MDT_Points - { - spellLine += ' '; - if (mEffectParams.mMagnMin == mEffectParams.mMagnMax && std::abs(mEffectParams.mMagnMin) == 1) - spellLine += pt; - else - spellLine += pts; - } - } + spellLine += formatter.str(); } - - // constant effects have no duration and no target - if (!mEffectParams.mIsConstant) + else if (displayType != ESM::MagicEffect::MDT_None && !mEffectParams.mNoMagnitude) { - if (!(magicEffect->mData.mFlags & ESM::MagicEffect::AppliedOnce)) - mEffectParams.mDuration = std::max(1, mEffectParams.mDuration); + spellLine += " " + MyGUI::utility::toString(mEffectParams.mMagnMin); + if (mEffectParams.mMagnMin != mEffectParams.mMagnMax) + spellLine += to + MyGUI::utility::toString(mEffectParams.mMagnMax); - if (mEffectParams.mDuration > 0 && !(magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration)) + if (displayType == ESM::MagicEffect::MDT_Percentage) + spellLine += pct; + else if (displayType == ESM::MagicEffect::MDT_Feet) { spellLine += ' '; - spellLine += MWBase::Environment::get().getWindowManager()->getGameSettingString("sfor", {}); - spellLine += ' ' + MyGUI::utility::toString(mEffectParams.mDuration) + ((mEffectParams.mDuration == 1) ? sec : secs); + spellLine += ft; } - - if (mEffectParams.mArea > 0) + else if (displayType == ESM::MagicEffect::MDT_Level) { - spellLine += " #{sin} " + MyGUI::utility::toString(mEffectParams.mArea) + " #{sfootarea}"; + spellLine += ' '; + if (mEffectParams.mMagnMin == mEffectParams.mMagnMax && std::abs(mEffectParams.mMagnMin) == 1) + spellLine += lvl; + else + spellLine += lvls; } - - // potions have no target - if (!mEffectParams.mNoTarget) + else // ESM::MagicEffect::MDT_Points { spellLine += ' '; - spellLine += MWBase::Environment::get().getWindowManager()->getGameSettingString("sonword", {}); - spellLine += ' '; - if (mEffectParams.mRange == ESM::RT_Self) - spellLine += MWBase::Environment::get().getWindowManager()->getGameSettingString("sRangeSelf", {}); - else if (mEffectParams.mRange == ESM::RT_Touch) - spellLine += MWBase::Environment::get().getWindowManager()->getGameSettingString("sRangeTouch", {}); - else if (mEffectParams.mRange == ESM::RT_Target) - spellLine += MWBase::Environment::get().getWindowManager()->getGameSettingString("sRangeTarget", {}); + if (mEffectParams.mMagnMin == mEffectParams.mMagnMax && std::abs(mEffectParams.mMagnMin) == 1) + spellLine += pt; + else + spellLine += pts; } } - - mTextWidget->setCaptionWithReplacing(spellLine); - mRequestedWidth = mTextWidget->getTextSize().width + sIconOffset; - - mImageWidget->setImageTexture(Misc::ResourceHelpers::correctIconPath(magicEffect->mIcon, MWBase::Environment::get().getResourceSystem()->getVFS())); } - MWSpellEffect::~MWSpellEffect() + // constant effects have no duration and no target + if (!mEffectParams.mIsConstant) { - } + if (!(magicEffect->mData.mFlags & ESM::MagicEffect::AppliedOnce)) + mEffectParams.mDuration = std::max(1, mEffectParams.mDuration); - void MWSpellEffect::initialiseOverride() - { - Base::initialiseOverride(); + if (mEffectParams.mDuration > 0 && !(magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration)) + { + spellLine += ' '; + spellLine += MWBase::Environment::get().getWindowManager()->getGameSettingString("sfor", {}); + spellLine += ' ' + MyGUI::utility::toString(mEffectParams.mDuration) + + ((mEffectParams.mDuration == 1) ? sec : secs); + } - assignWidget(mTextWidget, "Text"); - assignWidget(mImageWidget, "Image"); + if (mEffectParams.mArea > 0) + { + spellLine += " #{sin} " + MyGUI::utility::toString(mEffectParams.mArea) + " #{sfootarea}"; + } + + // potions have no target + if (!mEffectParams.mNoTarget) + { + spellLine += ' '; + spellLine += MWBase::Environment::get().getWindowManager()->getGameSettingString("sonword", {}); + spellLine += ' '; + if (mEffectParams.mRange == ESM::RT_Self) + spellLine += MWBase::Environment::get().getWindowManager()->getGameSettingString("sRangeSelf", {}); + else if (mEffectParams.mRange == ESM::RT_Touch) + spellLine += MWBase::Environment::get().getWindowManager()->getGameSettingString("sRangeTouch", {}); + else if (mEffectParams.mRange == ESM::RT_Target) + spellLine + += MWBase::Environment::get().getWindowManager()->getGameSettingString("sRangeTarget", {}); + } } - /* MWDynamicStat */ + mTextWidget->setCaptionWithReplacing(spellLine); + mRequestedWidth = mTextWidget->getTextSize().width + sIconOffset; - MWDynamicStat::MWDynamicStat() + mImageWidget->setImageTexture(Misc::ResourceHelpers::correctIconPath( + magicEffect->mIcon, MWBase::Environment::get().getResourceSystem()->getVFS())); + } + + MWSpellEffect::~MWSpellEffect() {} + + void MWSpellEffect::initialiseOverride() + { + Base::initialiseOverride(); + + assignWidget(mTextWidget, "Text"); + assignWidget(mImageWidget, "Image"); + } + + /* MWDynamicStat */ + + MWDynamicStat::MWDynamicStat() : mValue(0) , mMax(1) , mTextWidget(nullptr) , mBarWidget(nullptr) , mBarTextWidget(nullptr) - { - } - - void MWDynamicStat::setValue(int cur, int max) - { - mValue = cur; - mMax = max; + { + } - if (mBarWidget) - { - mBarWidget->setProgressRange(std::max(0, mMax)); - mBarWidget->setProgressPosition(std::max(0, mValue)); - } + void MWDynamicStat::setValue(int cur, int max) + { + mValue = cur; + mMax = max; - if (mBarTextWidget) - { - std::stringstream out; - out << mValue << "/" << mMax; - mBarTextWidget->setCaption(out.str().c_str()); - } - } - void MWDynamicStat::setTitle(std::string_view text) + if (mBarWidget) { - if (mTextWidget) - mTextWidget->setCaption(toUString(text)); + mBarWidget->setProgressRange(std::max(0, mMax)); + mBarWidget->setProgressPosition(std::max(0, mValue)); } - MWDynamicStat::~MWDynamicStat() + if (mBarTextWidget) { + std::stringstream out; + out << mValue << "/" << mMax; + mBarTextWidget->setCaption(out.str().c_str()); } + } + void MWDynamicStat::setTitle(std::string_view text) + { + if (mTextWidget) + mTextWidget->setCaption(toUString(text)); + } - void MWDynamicStat::initialiseOverride() - { - Base::initialiseOverride(); + MWDynamicStat::~MWDynamicStat() {} - assignWidget(mTextWidget, "Text"); - assignWidget(mBarWidget, "Bar"); - assignWidget(mBarTextWidget, "BarText"); - } + void MWDynamicStat::initialiseOverride() + { + Base::initialiseOverride(); + + assignWidget(mTextWidget, "Text"); + assignWidget(mBarWidget, "Bar"); + assignWidget(mBarTextWidget, "BarText"); } +} diff --git a/apps/openmw/mwgui/widgets.hpp b/apps/openmw/mwgui/widgets.hpp index af83daf34c..b3b4f2ec82 100644 --- a/apps/openmw/mwgui/widgets.hpp +++ b/apps/openmw/mwgui/widgets.hpp @@ -31,7 +31,7 @@ namespace MWGui { class MWEffectList; - void fixTexturePath(std::string &path); + void fixTexturePath(std::string& path); struct SpellEffectParams { @@ -71,20 +71,21 @@ namespace MWGui bool operator==(const SpellEffectParams& other) const { - if (mEffectID != other.mEffectID) + if (mEffectID != other.mEffectID) return false; bool involvesAttribute = (mEffectID == 74 // restore attribute - || mEffectID == 85 // absorb attribute - || mEffectID == 17 // drain attribute - || mEffectID == 79 // fortify attribute - || mEffectID == 22); // damage attribute + || mEffectID == 85 // absorb attribute + || mEffectID == 17 // drain attribute + || mEffectID == 79 // fortify attribute + || mEffectID == 22); // damage attribute bool involvesSkill = (mEffectID == 78 // restore skill - || mEffectID == 89 // absorb skill - || mEffectID == 21 // drain skill - || mEffectID == 83 // fortify skill - || mEffectID == 26); // damage skill - return ((other.mSkill == mSkill) || !involvesSkill) && ((other.mAttribute == mAttribute) && !involvesAttribute) && (other.mArea == mArea); + || mEffectID == 89 // absorb skill + || mEffectID == 21 // drain skill + || mEffectID == 83 // fortify skill + || mEffectID == 26); // damage skill + return ((other.mSkill == mSkill) || !involvesSkill) + && ((other.mAttribute == mAttribute) && !involvesAttribute) && (other.mArea == mArea); } }; @@ -92,7 +93,7 @@ namespace MWGui class MWSkill final : public MyGUI::Widget { - MYGUI_RTTI_DERIVED( MWSkill ) + MYGUI_RTTI_DERIVED(MWSkill) public: MWSkill(); @@ -121,7 +122,6 @@ namespace MWGui void onClicked(MyGUI::Widget* _sender); private: - void updateWidgets(); ESM::Skill::SkillEnum mSkillId; @@ -133,7 +133,7 @@ namespace MWGui class MWAttribute final : public MyGUI::Widget { - MYGUI_RTTI_DERIVED( MWAttribute ) + MYGUI_RTTI_DERIVED(MWAttribute) public: MWAttribute(); @@ -161,7 +161,6 @@ namespace MWGui void onClicked(MyGUI::Widget* _sender); private: - void updateWidgets(); int mId; @@ -177,22 +176,24 @@ namespace MWGui class MWSpellEffect; class MWSpell final : public MyGUI::Widget { - MYGUI_RTTI_DERIVED( MWSpell ) + MYGUI_RTTI_DERIVED(MWSpell) public: MWSpell(); - void setSpellId(const std::string &id); + void setSpellId(const std::string& id); /** * @param vector to store the created effect widgets * @param parent widget * @param coordinates to use, will be expanded if more space is needed - * @param spell category, if this is 0, this means the spell effects are permanent and won't display e.g. duration + * @param spell category, if this is 0, this means the spell effects are permanent and won't display e.g. + * duration * @param various flags, see MWEffectList::EffectFlags */ - void createEffectWidgets(std::vector &effects, MyGUI::Widget* creator, MyGUI::IntCoord &coord, int flags); + void createEffectWidgets( + std::vector& effects, MyGUI::Widget* creator, MyGUI::IntCoord& coord, int flags); - const std::string &getSpellId() const { return mId; } + const std::string& getSpellId() const { return mId; } protected: virtual ~MWSpell(); @@ -209,7 +210,7 @@ namespace MWGui class MWEffectList final : public MyGUI::Widget { - MYGUI_RTTI_DERIVED( MWEffectList ) + MYGUI_RTTI_DERIVED(MWEffectList) public: MWEffectList(); @@ -232,7 +233,8 @@ namespace MWGui * @param center the effect widgets horizontally * @param various flags, see MWEffectList::EffectFlags */ - void createEffectWidgets(std::vector &effects, MyGUI::Widget* creator, MyGUI::IntCoord &coord, bool center, int flags); + void createEffectWidgets(std::vector& effects, MyGUI::Widget* creator, + MyGUI::IntCoord& coord, bool center, int flags); protected: virtual ~MWEffectList(); @@ -248,7 +250,7 @@ namespace MWGui class MWSpellEffect final : public MyGUI::Widget { - MYGUI_RTTI_DERIVED( MWSpellEffect ) + MYGUI_RTTI_DERIVED(MWSpellEffect) public: MWSpellEffect(); @@ -265,7 +267,7 @@ namespace MWGui private: static constexpr int sIconOffset = 24; - + void updateWidgets(); SpellEffectParams mEffectParams; @@ -277,7 +279,7 @@ namespace MWGui class MWDynamicStat final : public MyGUI::Widget { - MYGUI_RTTI_DERIVED( MWDynamicStat ) + MYGUI_RTTI_DERIVED(MWDynamicStat) public: MWDynamicStat(); @@ -293,7 +295,6 @@ namespace MWGui void initialiseOverride() override; private: - int mValue, mMax; MyGUI::TextBox* mTextWidget; MyGUI::ProgressBar* mBarWidget; diff --git a/apps/openmw/mwgui/windowbase.cpp b/apps/openmw/mwgui/windowbase.cpp index 9e476e4dab..d072efb677 100644 --- a/apps/openmw/mwgui/windowbase.cpp +++ b/apps/openmw/mwgui/windowbase.cpp @@ -4,8 +4,8 @@ #include #include -#include "../mwbase/windowmanager.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/windowmanager.hpp" #include @@ -15,7 +15,7 @@ using namespace MWGui; WindowBase::WindowBase(std::string_view parLayout) - : Layout(parLayout) + : Layout(parLayout) { mMainWidget->setVisible(false); @@ -41,7 +41,7 @@ void WindowBase::onTitleDoubleClicked() MWBase::Environment::get().getWindowManager()->toggleMaximized(this); } -void WindowBase::onDoubleClick(MyGUI::Widget *_sender) +void WindowBase::onDoubleClick(MyGUI::Widget* _sender) { onTitleDoubleClicked(); } @@ -71,8 +71,8 @@ void WindowBase::center() layerSize = mMainWidget->getLayer()->getSize(); MyGUI::IntCoord coord = mMainWidget->getCoord(); - coord.left = (layerSize.width - coord.width)/2; - coord.top = (layerSize.height - coord.height)/2; + coord.left = (layerSize.width - coord.width) / 2; + coord.top = (layerSize.height - coord.height) / 2; mMainWidget->setCoord(coord); } @@ -83,10 +83,10 @@ WindowModal::WindowModal(const std::string& parLayout) void WindowModal::onOpen() { - MWBase::Environment::get().getWindowManager()->addCurrentModal(this); //Set so we can escape it if needed + MWBase::Environment::get().getWindowManager()->addCurrentModal(this); // Set so we can escape it if needed MyGUI::Widget* focus = MyGUI::InputManager::getInstance().getKeyFocusWidget(); - MyGUI::InputManager::getInstance ().addWidgetModal (mMainWidget); + MyGUI::InputManager::getInstance().addWidgetModal(mMainWidget); MyGUI::InputManager::getInstance().setKeyFocusWidget(focus); } @@ -94,11 +94,13 @@ void WindowModal::onClose() { MWBase::Environment::get().getWindowManager()->removeCurrentModal(this); - MyGUI::InputManager::getInstance ().removeWidgetModal (mMainWidget); + MyGUI::InputManager::getInstance().removeWidgetModal(mMainWidget); } -NoDrop::NoDrop(DragAndDrop *drag, MyGUI::Widget *widget) - : mWidget(widget), mDrag(drag), mTransparent(false) +NoDrop::NoDrop(DragAndDrop* drag, MyGUI::Widget* widget) + : mWidget(widget) + , mDrag(drag) + , mTransparent(false) { } @@ -124,12 +126,12 @@ void NoDrop::onFrame(float dt) if (mTransparent) { mWidget->setNeedMouseFocus(false); // Allow click-through - setAlpha(std::max(0.13f, mWidget->getAlpha() - dt*5)); + setAlpha(std::max(0.13f, mWidget->getAlpha() - dt * 5)); } else { mWidget->setNeedMouseFocus(true); - setAlpha(std::min(1.0f, mWidget->getAlpha() + dt*5)); + setAlpha(std::min(1.0f, mWidget->getAlpha() + dt * 5)); } } @@ -140,14 +142,14 @@ void NoDrop::setAlpha(float alpha) } BookWindowBase::BookWindowBase(std::string_view parLayout) - : WindowBase(parLayout) + : WindowBase(parLayout) { } float BookWindowBase::adjustButton(std::string_view name) { Gui::ImageButton* button; - WindowBase::getWidget (button, name); + WindowBase::getWidget(button, name); MyGUI::IntSize requested = button->getRequestedSize(); float scale = float(requested.height) / button->getSize().height; MyGUI::IntSize newSize = requested; @@ -160,7 +162,7 @@ float BookWindowBase::adjustButton(std::string_view name) MyGUI::IntSize diff = (button->getSize() - requested); diff.width /= scale; diff.height /= scale; - button->setPosition(button->getPosition() + MyGUI::IntPoint(diff.width,0)); + button->setPosition(button->getPosition() + MyGUI::IntPoint(diff.width, 0)); } return scale; diff --git a/apps/openmw/mwgui/windowbase.hpp b/apps/openmw/mwgui/windowbase.hpp index dde9190666..4bf622a099 100644 --- a/apps/openmw/mwgui/windowbase.hpp +++ b/apps/openmw/mwgui/windowbase.hpp @@ -12,7 +12,7 @@ namespace MWGui { class DragAndDrop; - class WindowBase: public Layout + class WindowBase : public Layout { public: WindowBase(std::string_view parLayout); @@ -31,9 +31,9 @@ namespace MWGui /// Notify that window has been made visible virtual void onOpen() {} /// Notify that window has been hidden - virtual void onClose () {} + virtual void onClose() {} /// Gracefully exits the window - virtual bool exit() {return true;} + virtual bool exit() { return true; } /// Sets the visibility of the window void setVisible(bool visible) override; /// Returns the visibility state of the window @@ -65,7 +65,7 @@ namespace MWGui WindowModal(const std::string& parLayout); void onOpen() override; void onClose() override; - bool exit() override {return true;} + bool exit() override { return true; } }; /// A window that cannot be the target of a drag&drop action. diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 79f4312590..f41f6a4a79 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -8,18 +8,18 @@ #include -#include +#include #include +#include #include #include -#include -#include +#include // For BT_NO_PROFILE #include -#include #include +#include #include @@ -28,17 +28,17 @@ #include -#include #include +#include #include #include #include +#include #include #include -#include #include #include @@ -46,146 +46,145 @@ #include #include -#include #include +#include #include #include "../mwbase/inputmanager.hpp" #include "../mwbase/luamanager.hpp" -#include "../mwbase/statemanager.hpp" #include "../mwbase/soundmanager.hpp" +#include "../mwbase/statemanager.hpp" #include "../mwbase/world.hpp" #include "../mwrender/vismask.hpp" -#include "../mwworld/class.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/cellstore.hpp" +#include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" +#include "../mwworld/player.hpp" -#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/actorutil.hpp" +#include "../mwmechanics/npcstats.hpp" #include "../mwrender/postprocessor.hpp" -#include "console.hpp" -#include "journalwindow.hpp" -#include "journalviewmodel.hpp" -#include "dialogue.hpp" -#include "statswindow.hpp" -#include "scrollwindow.hpp" +#include "alchemywindow.hpp" +#include "backgroundimage.hpp" +#include "bookpage.hpp" #include "bookwindow.hpp" -#include "hud.hpp" -#include "mainmenu.hpp" -#include "countdialog.hpp" -#include "tradewindow.hpp" -#include "spellbuyingwindow.hpp" -#include "travelwindow.hpp" -#include "settingswindow.hpp" +#include "companionwindow.hpp" #include "confirmationdialog.hpp" -#include "alchemywindow.hpp" -#include "spellwindow.hpp" -#include "quickkeysmenu.hpp" -#include "loadingscreen.hpp" -#include "levelupdialog.hpp" -#include "waitdialog.hpp" +#include "console.hpp" +#include "container.hpp" +#include "controllers.hpp" +#include "countdialog.hpp" +#include "cursor.hpp" +#include "debugwindow.hpp" +#include "dialogue.hpp" #include "enchantingdialog.hpp" -#include "trainingwindow.hpp" -#include "recharge.hpp" #include "exposedwindow.hpp" -#include "cursor.hpp" -#include "merchantrepair.hpp" -#include "repair.hpp" -#include "companionwindow.hpp" +#include "hud.hpp" #include "inventorywindow.hpp" -#include "bookpage.hpp" +#include "itemchargeview.hpp" #include "itemview.hpp" -#include "videowidget.hpp" -#include "backgroundimage.hpp" #include "itemwidget.hpp" -#include "screenfader.hpp" -#include "debugwindow.hpp" -#include "postprocessorhud.hpp" -#include "spellview.hpp" -#include "container.hpp" -#include "controllers.hpp" #include "jailscreen.hpp" -#include "itemchargeview.hpp" +#include "journalviewmodel.hpp" +#include "journalwindow.hpp" #include "keyboardnavigation.hpp" +#include "levelupdialog.hpp" +#include "loadingscreen.hpp" +#include "mainmenu.hpp" +#include "merchantrepair.hpp" +#include "postprocessorhud.hpp" +#include "quickkeysmenu.hpp" +#include "recharge.hpp" +#include "repair.hpp" #include "resourceskin.hpp" +#include "screenfader.hpp" +#include "scrollwindow.hpp" +#include "settingswindow.hpp" +#include "spellbuyingwindow.hpp" +#include "spellview.hpp" +#include "spellwindow.hpp" +#include "statswindow.hpp" +#include "tradewindow.hpp" +#include "trainingwindow.hpp" +#include "travelwindow.hpp" #include "ustring.hpp" +#include "videowidget.hpp" +#include "waitdialog.hpp" namespace MWGui { - WindowManager::WindowManager( - SDL_Window* window, osgViewer::Viewer* viewer, osg::Group* guiRoot, Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, - const std::filesystem::path& logpath, bool consoleOnlyScripts, Translation::Storage& translationDataStorage, - ToUTF8::FromType encoding, const std::string& versionDescription, bool useShaders) - : mOldUpdateMask(0) - , mOldCullMask(0) - , mStore(nullptr) - , mResourceSystem(resourceSystem) - , mWorkQueue(workQueue) - , mViewer(viewer) - , mConsoleOnlyScripts(consoleOnlyScripts) - , mCurrentModals() - , mHud(nullptr) - , mMap(nullptr) - , mStatsWindow(nullptr) - , mConsole(nullptr) - , mDialogueWindow(nullptr) - , mInventoryWindow(nullptr) - , mScrollWindow(nullptr) - , mBookWindow(nullptr) - , mCountDialog(nullptr) - , mTradeWindow(nullptr) - , mSettingsWindow(nullptr) - , mConfirmationDialog(nullptr) - , mSpellWindow(nullptr) - , mQuickKeysMenu(nullptr) - , mLoadingScreen(nullptr) - , mWaitDialog(nullptr) - , mVideoBackground(nullptr) - , mVideoWidget(nullptr) - , mWerewolfFader(nullptr) - , mBlindnessFader(nullptr) - , mHitFader(nullptr) - , mScreenFader(nullptr) - , mDebugWindow(nullptr) - , mPostProcessorHud(nullptr) - , mJailScreen(nullptr) - , mContainerWindow(nullptr) - , mTranslationDataStorage (translationDataStorage) - , mInputBlocker(nullptr) - , mCrosshairEnabled(Settings::Manager::getBool ("crosshair", "HUD")) - , mSubtitlesEnabled(Settings::Manager::getBool ("subtitles", "GUI")) - , mHitFaderEnabled(Settings::Manager::getBool ("hit fader", "GUI")) - , mWerewolfOverlayEnabled(Settings::Manager::getBool ("werewolf overlay", "GUI")) - , mHudEnabled(true) - , mCursorVisible(true) - , mCursorActive(true) - , mPlayerBounty(-1) - , mGuiModes() - , mGarbageDialogs() - , mShown(GW_ALL) - , mForceHidden(GW_None) - , mAllowed(GW_ALL) - , mRestAllowed(true) - , mShowOwned(0) - , mEncoding(encoding) - , mVersionDescription(versionDescription) - , mWindowVisible(true) - { - int w,h; + WindowManager::WindowManager(SDL_Window* window, osgViewer::Viewer* viewer, osg::Group* guiRoot, + Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, const std::filesystem::path& logpath, + bool consoleOnlyScripts, Translation::Storage& translationDataStorage, ToUTF8::FromType encoding, + const std::string& versionDescription, bool useShaders) + : mOldUpdateMask(0) + , mOldCullMask(0) + , mStore(nullptr) + , mResourceSystem(resourceSystem) + , mWorkQueue(workQueue) + , mViewer(viewer) + , mConsoleOnlyScripts(consoleOnlyScripts) + , mCurrentModals() + , mHud(nullptr) + , mMap(nullptr) + , mStatsWindow(nullptr) + , mConsole(nullptr) + , mDialogueWindow(nullptr) + , mInventoryWindow(nullptr) + , mScrollWindow(nullptr) + , mBookWindow(nullptr) + , mCountDialog(nullptr) + , mTradeWindow(nullptr) + , mSettingsWindow(nullptr) + , mConfirmationDialog(nullptr) + , mSpellWindow(nullptr) + , mQuickKeysMenu(nullptr) + , mLoadingScreen(nullptr) + , mWaitDialog(nullptr) + , mVideoBackground(nullptr) + , mVideoWidget(nullptr) + , mWerewolfFader(nullptr) + , mBlindnessFader(nullptr) + , mHitFader(nullptr) + , mScreenFader(nullptr) + , mDebugWindow(nullptr) + , mPostProcessorHud(nullptr) + , mJailScreen(nullptr) + , mContainerWindow(nullptr) + , mTranslationDataStorage(translationDataStorage) + , mInputBlocker(nullptr) + , mCrosshairEnabled(Settings::Manager::getBool("crosshair", "HUD")) + , mSubtitlesEnabled(Settings::Manager::getBool("subtitles", "GUI")) + , mHitFaderEnabled(Settings::Manager::getBool("hit fader", "GUI")) + , mWerewolfOverlayEnabled(Settings::Manager::getBool("werewolf overlay", "GUI")) + , mHudEnabled(true) + , mCursorVisible(true) + , mCursorActive(true) + , mPlayerBounty(-1) + , mGuiModes() + , mGarbageDialogs() + , mShown(GW_ALL) + , mForceHidden(GW_None) + , mAllowed(GW_ALL) + , mRestAllowed(true) + , mShowOwned(0) + , mEncoding(encoding) + , mVersionDescription(versionDescription) + , mWindowVisible(true) + { + int w, h; SDL_GetWindowSize(window, &w, &h); - int dw,dh; + int dw, dh; SDL_GL_GetDrawableSize(window, &dw, &dh); mScalingFactor = std::clamp(Settings::Manager::getFloat("scaling factor", "GUI"), 0.5f, 8.f) * (dw / w); mGuiPlatform = std::make_unique(viewer, guiRoot, resourceSystem->getImageManager(), - resourceSystem->getVFS(), mScalingFactor, "mygui", - logpath / "MyGUI.log"); + resourceSystem->getVFS(), mScalingFactor, "mygui", logpath / "MyGUI.log"); mGui = std::make_unique(); mGui->initialise(""); @@ -197,7 +196,7 @@ namespace MWGui // Load fonts mFontLoader = std::make_unique(encoding, resourceSystem->getVFS(), mScalingFactor); - //Register own widgets with MyGUI + // Register own widgets with MyGUI MyGUI::FactoryManager::getInstance().registerFactory("Widget"); MyGUI::FactoryManager::getInstance().registerFactory("Widget"); MyGUI::FactoryManager::getInstance().registerFactory("Widget"); @@ -220,8 +219,10 @@ namespace MWGui MyGUI::FactoryManager::getInstance().registerFactory("Controller"); - MyGUI::FactoryManager::getInstance().registerFactory("Resource", "ResourceImageSetPointer"); - MyGUI::FactoryManager::getInstance().registerFactory("Resource", "AutoSizedResourceSkin"); + MyGUI::FactoryManager::getInstance().registerFactory( + "Resource", "ResourceImageSetPointer"); + MyGUI::FactoryManager::getInstance().registerFactory( + "Resource", "AutoSizedResourceSkin"); MyGUI::ResourceManager::getInstance().load("core.xml"); bool keyboardNav = Settings::Manager::getBool("keyboard navigation", "GUI"); @@ -233,12 +234,14 @@ namespace MWGui mLoadingScreen = loadingScreen.get(); mWindows.push_back(std::move(loadingScreen)); - //set up the hardware cursor manager + // set up the hardware cursor manager mCursorManager = std::make_unique(); - MyGUI::PointerManager::getInstance().eventChangeMousePointer += MyGUI::newDelegate(this, &WindowManager::onCursorChange); + MyGUI::PointerManager::getInstance().eventChangeMousePointer + += MyGUI::newDelegate(this, &WindowManager::onCursorChange); - MyGUI::InputManager::getInstance().eventChangeKeyFocus += MyGUI::newDelegate(this, &WindowManager::onKeyFocusChanged); + MyGUI::InputManager::getInstance().eventChangeKeyFocus + += MyGUI::newDelegate(this, &WindowManager::onKeyFocusChanged); // Create all cursors in advance createCursors(); @@ -248,14 +251,14 @@ namespace MWGui // hide mygui's pointer MyGUI::PointerManager::getInstance().setVisible(false); - mVideoBackground = MyGUI::Gui::getInstance().createWidgetReal("ImageBox", 0,0,1,1, - MyGUI::Align::Default, "Video"); + mVideoBackground = MyGUI::Gui::getInstance().createWidgetReal( + "ImageBox", 0, 0, 1, 1, MyGUI::Align::Default, "Video"); mVideoBackground->setImageTexture("black"); mVideoBackground->setVisible(false); mVideoBackground->setNeedMouseFocus(true); mVideoBackground->setNeedKeyFocus(true); - mVideoWidget = mVideoBackground->createWidgetReal("ImageBox", 0,0,1,1, MyGUI::Align::Default); + mVideoWidget = mVideoBackground->createWidgetReal("ImageBox", 0, 0, 1, 1, MyGUI::Align::Default); mVideoWidget->setNeedMouseFocus(true); mVideoWidget->setNeedKeyFocus(true); mVideoWidget->setVFS(resourceSystem->getVFS()); @@ -264,14 +267,16 @@ namespace MWGui MyGUI::ClipboardManager::getInstance().eventClipboardChanged.clear(); MyGUI::ClipboardManager::getInstance().eventClipboardRequested.clear(); - MyGUI::ClipboardManager::getInstance().eventClipboardChanged += MyGUI::newDelegate(this, &WindowManager::onClipboardChanged); - MyGUI::ClipboardManager::getInstance().eventClipboardRequested += MyGUI::newDelegate(this, &WindowManager::onClipboardRequested); + MyGUI::ClipboardManager::getInstance().eventClipboardChanged + += MyGUI::newDelegate(this, &WindowManager::onClipboardChanged); + MyGUI::ClipboardManager::getInstance().eventClipboardRequested + += MyGUI::newDelegate(this, &WindowManager::onClipboardRequested); mShowOwned = Settings::Manager::getInt("show owned", "Game"); mVideoWrapper = std::make_unique(window, viewer); - mVideoWrapper->setGammaContrast(Settings::Manager::getFloat("gamma", "Video"), - Settings::Manager::getFloat("contrast", "Video")); + mVideoWrapper->setGammaContrast( + Settings::Manager::getFloat("gamma", "Video"), Settings::Manager::getFloat("contrast", "Video")); if (useShaders) mGuiPlatform->getRenderManagerPtr()->enableShaders(mResourceSystem->getSceneManager()->getShaderManager()); @@ -309,7 +314,8 @@ namespace MWGui mWindows.push_back(std::move(statsWindow)); trackWindow(mStatsWindow, "stats"); - auto inventoryWindow = std::make_unique(mDragAndDrop.get(), mViewer->getSceneData()->asGroup(), mResourceSystem); + auto inventoryWindow = std::make_unique( + mDragAndDrop.get(), mViewer->getSceneData()->asGroup(), mResourceSystem); mInventoryWindow = inventoryWindow.get(); mWindows.push_back(std::move(inventoryWindow)); @@ -318,16 +324,16 @@ namespace MWGui mWindows.push_back(std::move(spellWindow)); trackWindow(mSpellWindow, "spells"); - mGuiModeStates[GM_Inventory] = GuiModeState({mMap, mInventoryWindow, mSpellWindow, mStatsWindow}); - mGuiModeStates[GM_None] = GuiModeState({mMap, mInventoryWindow, mSpellWindow, mStatsWindow}); + mGuiModeStates[GM_Inventory] = GuiModeState({ mMap, mInventoryWindow, mSpellWindow, mStatsWindow }); + mGuiModeStates[GM_None] = GuiModeState({ mMap, mInventoryWindow, mSpellWindow, mStatsWindow }); auto tradeWindow = std::make_unique(); mTradeWindow = tradeWindow.get(); mWindows.push_back(std::move(tradeWindow)); trackWindow(mTradeWindow, "barter"); - mGuiModeStates[GM_Barter] = GuiModeState({mInventoryWindow, mTradeWindow}); + mGuiModeStates[GM_Barter] = GuiModeState({ mInventoryWindow, mTradeWindow }); - auto console = std::make_unique(w,h, mConsoleOnlyScripts); + auto console = std::make_unique(w, h, mConsoleOnlyScripts); mConsole = console.get(); mWindows.push_back(std::move(console)); trackWindow(mConsole, "console"); @@ -339,7 +345,8 @@ namespace MWGui mGuiModeStates[GM_Journal].mOpenSound = "book open"; mWindows.push_back(std::move(journal)); - mMessageBoxManager = std::make_unique(mStore->get().find("fMessageTimePerChar")->mValue.getFloat()); + mMessageBoxManager = std::make_unique( + mStore->get().find("fMessageTimePerChar")->mValue.getFloat()); auto spellBuyingWindow = std::make_unique(); mGuiModeStates[GM_SpellBuying] = GuiModeState(spellBuyingWindow.get()); @@ -360,7 +367,7 @@ namespace MWGui mContainerWindow = containerWindow.get(); mWindows.push_back(std::move(containerWindow)); trackWindow(mContainerWindow, "container"); - mGuiModeStates[GM_Container] = GuiModeState({mContainerWindow, mInventoryWindow}); + mGuiModeStates[GM_Container] = GuiModeState({ mContainerWindow, mInventoryWindow }); auto hud = std::make_unique(mCustomMarkers, mDragAndDrop.get(), mLocalMapRender.get()); mHud = hud.get(); @@ -413,7 +420,7 @@ namespace MWGui auto waitDialog = std::make_unique(); mWaitDialog = waitDialog.get(); mWindows.push_back(std::move(waitDialog)); - mGuiModeStates[GM_Rest] = GuiModeState({mWaitDialog->getProgressBar(), mWaitDialog}); + mGuiModeStates[GM_Rest] = GuiModeState({ mWaitDialog->getProgressBar(), mWaitDialog }); auto spellCreationDialog = std::make_unique(); mGuiModeStates[GM_SpellCreation] = GuiModeState(spellCreationDialog.get()); @@ -424,7 +431,7 @@ namespace MWGui mWindows.push_back(std::move(enchantingDialog)); auto trainingWindow = std::make_unique(); - mGuiModeStates[GM_Training] = GuiModeState({trainingWindow->getProgressBar(), trainingWindow.get()}); + mGuiModeStates[GM_Training] = GuiModeState({ trainingWindow->getProgressBar(), trainingWindow.get() }); mWindows.push_back(std::move(trainingWindow)); auto merchantRepair = std::make_unique(); @@ -439,7 +446,7 @@ namespace MWGui auto companionWindow = std::make_unique(mDragAndDrop.get(), mMessageBoxManager.get()); trackWindow(companionWindow.get(), "companion"); - mGuiModeStates[GM_Companion] = GuiModeState({mInventoryWindow, companionWindow.get()}); + mGuiModeStates[GM_Companion] = GuiModeState({ mInventoryWindow, companionWindow.get() }); mWindows.push_back(std::move(companionWindow)); auto jailScreen = std::make_unique(); @@ -461,8 +468,8 @@ namespace MWGui // fall back to player_hit_01.dds if bm_player_hit_01.dds is not available std::string hitFaderTexture = "textures\\bm_player_hit_01.dds"; const std::string hitFaderLayout = "openmw_screen_fader_hit.layout"; - MyGUI::FloatCoord hitFaderCoord (0,0,1,1); - if(!mResourceSystem->getVFS()->exists(hitFaderTexture)) + MyGUI::FloatCoord hitFaderCoord(0, 0, 1, 1); + if (!mResourceSystem->getVFS()->exists(hitFaderTexture)) { hitFaderTexture = "textures\\player_hit_01.dds"; hitFaderCoord = MyGUI::FloatCoord(0.2, 0.25, 0.6, 0.5); @@ -484,7 +491,8 @@ namespace MWGui mWindows.push_back(std::move(postProcessorHud)); trackWindow(mPostProcessorHud, "postprocessor"); - mInputBlocker = MyGUI::Gui::getInstance().createWidget("",0,0,w,h,MyGUI::Align::Stretch,"InputBlocker"); + mInputBlocker = MyGUI::Gui::getInstance().createWidget( + "", 0, 0, w, h, MyGUI::Align::Stretch, "InputBlocker"); mHud->setVisible(true); @@ -549,13 +557,13 @@ namespace MWGui mGuiPlatform->shutdown(); } - catch(const MyGUI::Exception& e) + catch (const MyGUI::Exception& e) { Log(Debug::Error) << "Error in the destructor: " << e.what(); } } - void WindowManager::setStore(const MWWorld::ESMStore &store) + void WindowManager::setStore(const MWWorld::ESMStore& store) { mStore = &store; } @@ -568,7 +576,7 @@ namespace MWGui void WindowManager::enableScene(bool enable) { - unsigned int disablemask = MWRender::Mask_GUI|MWRender::Mask_PreCompile; + unsigned int disablemask = MWRender::Mask_GUI | MWRender::Mask_PreCompile; if (!enable && getCullMask() != disablemask) { mOldUpdateMask = mViewer->getUpdateVisitor()->getTraversalMask(); @@ -592,7 +600,8 @@ namespace MWGui { bool loading = (getMode() == GM_Loading || getMode() == GM_LoadingWallpaper); - bool mainmenucover = containsMode(GM_MainMenu) && MWBase::Environment::get().getStateManager()->getState() == MWBase::StateManager::State_NoGame; + bool mainmenucover = containsMode(GM_MainMenu) + && MWBase::Environment::get().getStateManager()->getState() == MWBase::StateManager::State_NoGame; enableScene(!loading && !mainmenucover); @@ -606,7 +615,7 @@ namespace MWGui MWBase::Environment::get().getInputManager()->changeInputMode(!gameMode); - mInputBlocker->setVisible (gameMode); + mInputBlocker->setVisible(gameMode); if (loading) setCursorVisible(mMessageBoxManager && mMessageBoxManager->isInteractiveMessageBox()); @@ -614,11 +623,12 @@ namespace MWGui setCursorVisible(!gameMode); if (gameMode) - setKeyFocusWidget (nullptr); + setKeyFocusWidget(nullptr); // Icons of forced hidden windows are displayed setMinimapVisibility((mAllowed & GW_Map) && (!mMap->pinned() || (mForceHidden & GW_Map))); - setWeaponVisibility((mAllowed & GW_Inventory) && (!mInventoryWindow->pinned() || (mForceHidden & GW_Inventory))); + setWeaponVisibility( + (mAllowed & GW_Inventory) && (!mInventoryWindow->pinned() || (mForceHidden & GW_Inventory))); setSpellVisibility((mAllowed & GW_Magic) && (!mSpellWindow->pinned() || (mForceHidden & GW_Magic))); setHMSVisibility((mAllowed & GW_Stats) && (!mStatsWindow->pinned() || (mForceHidden & GW_Stats))); @@ -628,9 +638,12 @@ namespace MWGui if (mGuiModes.empty()) { mMap->setVisible(mMap->pinned() && !isConsoleMode() && !(mForceHidden & GW_Map) && (mAllowed & GW_Map)); - mStatsWindow->setVisible(mStatsWindow->pinned() && !isConsoleMode() && !(mForceHidden & GW_Stats) && (mAllowed & GW_Stats)); - mInventoryWindow->setVisible(mInventoryWindow->pinned() && !isConsoleMode() && !(mForceHidden & GW_Inventory) && (mAllowed & GW_Inventory)); - mSpellWindow->setVisible(mSpellWindow->pinned() && !isConsoleMode() && !(mForceHidden & GW_Magic) && (mAllowed & GW_Magic)); + mStatsWindow->setVisible( + mStatsWindow->pinned() && !isConsoleMode() && !(mForceHidden & GW_Stats) && (mAllowed & GW_Stats)); + mInventoryWindow->setVisible(mInventoryWindow->pinned() && !isConsoleMode() + && !(mForceHidden & GW_Inventory) && (mAllowed & GW_Inventory)); + mSpellWindow->setVisible( + mSpellWindow->pinned() && !isConsoleMode() && !(mForceHidden & GW_Magic) && (mAllowed & GW_Magic)); return; } else if (getMode() != GM_Inventory) @@ -639,7 +652,8 @@ namespace MWGui mStatsWindow->setVisible(false); mSpellWindow->setVisible(false); mHud->setDrowningBarVisible(false); - mInventoryWindow->setVisible(getMode() == GM_Container || getMode() == GM_Barter || getMode() == GM_Companion); + mInventoryWindow->setVisible( + getMode() == GM_Container || getMode() == GM_Barter || getMode() == GM_Companion); } GuiMode mode = mGuiModes.back(); @@ -661,23 +675,23 @@ namespace MWGui switch (mode) { - // FIXME: refactor chargen windows to use modes properly (or not use them at all) - case GM_Name: - case GM_Race: - case GM_Class: - case GM_ClassPick: - case GM_ClassCreate: - case GM_Birth: - case GM_ClassGenerate: - case GM_Review: - mCharGen->spawnDialog(mode); - break; - default: - break; + // FIXME: refactor chargen windows to use modes properly (or not use them at all) + case GM_Name: + case GM_Race: + case GM_Class: + case GM_ClassPick: + case GM_ClassCreate: + case GM_Birth: + case GM_ClassGenerate: + case GM_Review: + mCharGen->spawnDialog(mode); + break; + default: + break; } } - void WindowManager::setDrowningTimeLeft (float time, float maxTime) + void WindowManager::setDrowningTimeLeft(float time, float maxTime) { mHud->setDrowningTimeLeft(time, maxTime); } @@ -705,7 +719,7 @@ namespace MWGui { // unable to exit window, but give access to main menu if (!MyGUI::InputManager::getInstance().isModalAny() && getMode() != GM_MainMenu) - pushGuiMode (GM_MainMenu); + pushGuiMode(GM_MainMenu); return; } } @@ -713,18 +727,22 @@ namespace MWGui popGuiMode(); } - void WindowManager::interactiveMessageBox(std::string_view message, const std::vector &buttons, bool block) + void WindowManager::interactiveMessageBox( + std::string_view message, const std::vector& buttons, bool block) { mMessageBoxManager->createInteractiveMessageBox(message, buttons); updateVisible(); if (block) { - Misc::FrameRateLimiter frameRateLimiter = Misc::makeFrameRateLimiter(MWBase::Environment::get().getFrameRateLimit()); + Misc::FrameRateLimiter frameRateLimiter + = Misc::makeFrameRateLimiter(MWBase::Environment::get().getFrameRateLimit()); while (mMessageBoxManager->readPressedButton(false) == -1 - && !MWBase::Environment::get().getStateManager()->hasQuitRequest()) + && !MWBase::Environment::get().getStateManager()->hasQuitRequest()) { - const double dt = std::chrono::duration_cast>(frameRateLimiter.getLastFrameDuration()).count(); + const double dt + = std::chrono::duration_cast>(frameRateLimiter.getLastFrameDuration()) + .count(); mKeyboardNavigation->onFrame(); mMessageBoxManager->onFrame(dt); @@ -750,9 +768,12 @@ namespace MWGui void WindowManager::messageBox(std::string_view message, enum MWGui::ShowInDialogueMode showInDialogueMode) { - if (getMode() == GM_Dialogue && showInDialogueMode != MWGui::ShowInDialogueMode_Never) { + if (getMode() == GM_Dialogue && showInDialogueMode != MWGui::ShowInDialogueMode_Never) + { mDialogueWindow->addMessageBox(MyGUI::LanguageManager::getInstance().replaceTags(toUString(message))); - } else if (showInDialogueMode != MWGui::ShowInDialogueMode_Only) { + } + else if (showInDialogueMode != MWGui::ShowInDialogueMode_Only) + { mMessageBoxManager->createMessageBox(message); } } @@ -777,16 +798,16 @@ namespace MWGui return mMessageBoxManager->getActiveMessageBoxes(); } - int WindowManager::readPressedButton () + int WindowManager::readPressedButton() { return mMessageBoxManager->readPressedButton(); } std::string_view WindowManager::getGameSettingString(std::string_view id, std::string_view default_) { - const ESM::GameSetting *setting = mStore->get().search(id); + const ESM::GameSetting* setting = mStore->get().search(id); - if (setting && setting->mValue.getType()==ESM::VT_String) + if (setting && setting->mValue.getType() == ESM::VT_String) return setting->mValue.getString(); return default_; @@ -800,11 +821,11 @@ namespace MWGui MWWorld::ConstPtr player = MWMechanics::getPlayer(); osg::Vec3f playerPosition = player.getRefData().getPosition().asVec3(); - osg::Quat playerOrientation (-player.getRefData().getPosition().rot[2], osg::Vec3(0,0,1)); + osg::Quat playerOrientation(-player.getRefData().getPosition().rot[2], osg::Vec3(0, 0, 1)); osg::Vec3f playerdirection; - int x,y; - float u,v; + int x, y; + float u, v; mLocalMapRender->updatePlayer(playerPosition, playerOrientation, u, v, x, y, playerdirection); if (!player.getCell()->isExterior()) @@ -819,12 +840,12 @@ namespace MWGui mHud->setPlayerPos(x, y, u, v); } - void WindowManager::update (float frameDuration) + void WindowManager::update(float frameDuration) { handleScheduledMessageBoxes(); - bool gameRunning = MWBase::Environment::get().getStateManager()->getState()!= - MWBase::StateManager::State_NoGame; + bool gameRunning + = MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_NoGame; if (gameRunning) updateMap(); @@ -846,9 +867,11 @@ namespace MWGui // Make sure message boxes are always in front // This is an awful workaround for a series of awfully interwoven issues that couldn't be worked around // in a better way because of an impressive number of even more awfully interwoven issues. - if (mMessageBoxManager && mMessageBoxManager->isInteractiveMessageBox() && mCurrentModals.back() != mMessageBoxManager->getInteractiveMessageBox()) + if (mMessageBoxManager && mMessageBoxManager->isInteractiveMessageBox() + && mCurrentModals.back() != mMessageBoxManager->getInteractiveMessageBox()) { - std::vector::iterator found = std::find(mCurrentModals.begin(), mCurrentModals.end(), mMessageBoxManager->getInteractiveMessageBox()); + std::vector::iterator found = std::find( + mCurrentModals.begin(), mCurrentModals.end(), mMessageBoxManager->getInteractiveMessageBox()); if (found != mCurrentModals.end()) { WindowModal* msgbox = *found; @@ -909,24 +932,24 @@ namespace MWGui { mMap->requestMapRender(cell); - std::string name{MWBase::Environment::get().getWorld()->getCellName(cell)}; + std::string name{ MWBase::Environment::get().getWorld()->getCellName(cell) }; - mMap->setCellName( name ); - mHud->setCellName( name ); + mMap->setCellName(name); + mHud->setCellName(name); if (cell->getCell()->isExterior()) { if (!cell->getCell()->mName.empty()) - mMap->addVisitedLocation (name, cell->getCell()->getGridX (), cell->getCell()->getGridY ()); + mMap->addVisitedLocation(name, cell->getCell()->getGridX(), cell->getCell()->getGridY()); - mMap->cellExplored (cell->getCell()->getGridX(), cell->getCell()->getGridY()); + mMap->cellExplored(cell->getCell()->getGridX(), cell->getCell()->getGridY()); setActiveMap(cell->getCell()->getGridX(), cell->getCell()->getGridY(), false); } else { - mMap->setCellPrefix (cell->getCell()->mName ); - mHud->setCellPrefix (cell->getCell()->mName ); + mMap->setCellPrefix(cell->getCell()->mName); + mHud->setCellPrefix(cell->getCell()->mName); osg::Vec3f worldPos; if (!MWBase::Environment::get().getWorld()->findInteriorPositionInWorldSpace(cell, worldPos)) @@ -941,8 +964,8 @@ namespace MWGui void WindowManager::setActiveMap(int x, int y, bool interior) { - mMap->setActiveCell(x,y, interior); - mHud->setActiveCell(x,y, interior); + mMap->setActiveCell(x, y, interior); + mHud->setActiveCell(x, y, interior); } void WindowManager::setDrowningBarVisibility(bool visible) @@ -952,12 +975,12 @@ namespace MWGui void WindowManager::setHMSVisibility(bool visible) { - mHud->setHmsVisible (visible); + mHud->setHmsVisible(visible); } void WindowManager::setMinimapVisibility(bool visible) { - mHud->setMinimapVisible (visible); + mHud->setMinimapVisible(visible); } bool WindowManager::toggleFogOfWar() @@ -970,7 +993,7 @@ namespace MWGui { mToolTips->setFocusObject(focus); - if(mHud && (mShowOwned == 2 || mShowOwned == 3)) + if (mHud && (mShowOwned == 2 || mShowOwned == 3)) { bool owned = mToolTips->checkOwned(); mHud->setCrosshairOwned(owned); @@ -994,13 +1017,13 @@ namespace MWGui void WindowManager::setWeaponVisibility(bool visible) { - mHud->setWeapVisible (visible); + mHud->setWeapVisible(visible); } void WindowManager::setSpellVisibility(bool visible) { - mHud->setSpellVisible (visible); - mHud->setEffectVisible (visible); + mHud->setSpellVisible(visible); + mHud->setEffectVisible(visible); } void WindowManager::setSneakVisibility(bool visible) @@ -1027,21 +1050,21 @@ namespace MWGui void WindowManager::onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _result) { std::string tag(_tag); - + std::string MyGuiPrefix = "setting="; size_t MyGuiPrefixLength = MyGuiPrefix.length(); std::string tokenToFind = "sCell="; size_t tokenLength = tokenToFind.length(); - - if(tag.compare(0, MyGuiPrefixLength, MyGuiPrefix) == 0) + + if (tag.compare(0, MyGuiPrefixLength, MyGuiPrefix) == 0) { tag = tag.substr(MyGuiPrefixLength, tag.length()); size_t comma_pos = tag.find(','); std::string settingSection = tag.substr(0, comma_pos); - std::string settingTag = tag.substr(comma_pos+1, tag.length()); - - _result = Settings::Manager::getString(settingTag, settingSection); + std::string settingTag = tag.substr(comma_pos + 1, tag.length()); + + _result = Settings::Manager::getString(settingTag, settingSection); } else if (tag.compare(0, tokenLength, tokenToFind) == 0) { @@ -1070,13 +1093,14 @@ namespace MWGui // If not, treat is as GMST name from legacy localization if (!mStore) { - Log(Debug::Error) << "Error: WindowManager::onRetrieveTag: no Store set up yet, can not replace '" << tag << "'"; + Log(Debug::Error) << "Error: WindowManager::onRetrieveTag: no Store set up yet, can not replace '" + << tag << "'"; _result = tag; return; } - const ESM::GameSetting *setting = mStore->get().search(tag); + const ESM::GameSetting* setting = mStore->get().search(tag); - if (setting && setting->mValue.getType()==ESM::VT_String) + if (setting && setting->mValue.getType() == ESM::VT_String) _result = setting->mValue.getString(); else _result = tag; @@ -1091,31 +1115,29 @@ namespace MWGui for (const auto& setting : changed) { if (setting.first == "HUD" && setting.second == "crosshair") - mCrosshairEnabled = Settings::Manager::getBool ("crosshair", "HUD"); + mCrosshairEnabled = Settings::Manager::getBool("crosshair", "HUD"); else if (setting.first == "GUI" && setting.second == "subtitles") - mSubtitlesEnabled = Settings::Manager::getBool ("subtitles", "GUI"); + mSubtitlesEnabled = Settings::Manager::getBool("subtitles", "GUI"); else if (setting.first == "GUI" && setting.second == "menu transparency") setMenuTransparency(Settings::Manager::getFloat("menu transparency", "GUI")); - else if (setting.first == "Video" && ( - setting.second == "resolution x" - || setting.second == "resolution y" - || setting.second == "window mode" - || setting.second == "window border")) + else if (setting.first == "Video" + && (setting.second == "resolution x" || setting.second == "resolution y" + || setting.second == "window mode" || setting.second == "window border")) changeRes = true; else if (setting.first == "Video" && setting.second == "vsync") mVideoWrapper->setSyncToVBlank(Settings::Manager::getBool("vsync", "Video")); else if (setting.first == "Video" && (setting.second == "gamma" || setting.second == "contrast")) - mVideoWrapper->setGammaContrast(Settings::Manager::getFloat("gamma", "Video"), - Settings::Manager::getFloat("contrast", "Video")); + mVideoWrapper->setGammaContrast( + Settings::Manager::getFloat("gamma", "Video"), Settings::Manager::getFloat("contrast", "Video")); } if (changeRes) { mVideoWrapper->setVideoMode(Settings::Manager::getInt("resolution x", "Video"), - Settings::Manager::getInt("resolution y", "Video"), - static_cast(Settings::Manager::getInt("window mode", "Video")), - Settings::Manager::getBool("window border", "Video")); + Settings::Manager::getInt("resolution y", "Video"), + static_cast(Settings::Manager::getInt("window mode", "Video")), + Settings::Manager::getBool("window border", "Video")); } } @@ -1125,14 +1147,12 @@ namespace MWGui Settings::Manager::setInt("resolution y", "Video", y); // We only want to process changes to window-size related settings. - Settings::CategorySettingVector filter = {{"Video", "resolution x"}, - {"Video", "resolution y"}}; + Settings::CategorySettingVector filter = { { "Video", "resolution x" }, { "Video", "resolution y" } }; // If the HUD has not been initialised, the World singleton will not be available. if (mHud) { - MWBase::Environment::get().getWorld()->processChangedSettings( - Settings::Manager::getPendingChanges(filter)); + MWBase::Environment::get().getWorld()->processChangedSettings(Settings::Manager::getPendingChanges(filter)); } Settings::Manager::resetPendingChanges(filter); @@ -1149,16 +1169,17 @@ namespace MWGui if (!mHud) return; // UI not initialized yet - for (std::map::iterator it = mTrackedWindows.begin(); it != mTrackedWindows.end(); ++it) + for (std::map::iterator it = mTrackedWindows.begin(); it != mTrackedWindows.end(); + ++it) { std::string settingName = it->second; if (Settings::Manager::getBool(settingName + " maximized", "Windows")) settingName += " maximized"; MyGUI::IntPoint pos(static_cast(Settings::Manager::getFloat(settingName + " x", "Windows") * x), - static_cast(Settings::Manager::getFloat(settingName + " y", "Windows") * y)); + static_cast(Settings::Manager::getFloat(settingName + " y", "Windows") * y)); MyGUI::IntSize size(static_cast(Settings::Manager::getFloat(settingName + " w", "Windows") * x), - static_cast(Settings::Manager::getFloat(settingName + " h", "Windows") * y)); + static_cast(Settings::Manager::getFloat(settingName + " h", "Windows") * y)); it->first->setPosition(pos); it->first->setSize(size); } @@ -1184,7 +1205,7 @@ namespace MWGui MWBase::Environment::get().getStateManager()->requestQuit(); } - void WindowManager::onCursorChange(const std::string &name) + void WindowManager::onCursorChange(const std::string& name) { mCursorManager->cursorChanged(name); } @@ -1206,7 +1227,7 @@ namespace MWGui void WindowManager::pushGuiMode(GuiMode mode, const MWWorld::Ptr& arg, bool force) { - if (mode==GM_Inventory && mAllowed==GW_None) + if (mode == GM_Inventory && mAllowed == GW_None) return; if (mGuiModes.empty() || mGuiModes.back() != mode) @@ -1227,7 +1248,7 @@ namespace MWGui mGuiModeStates[mode].update(true); playSound(mGuiModeStates[mode].mOpenSound); } - if(force) + if (force) mContainerWindow->treatNextOpenAsLoot(); for (WindowBase* window : mGuiModeStates[mode].mWindows) window->setPtr(arg); @@ -1241,7 +1262,7 @@ namespace MWGui { mViewer->getCamera()->setCullMask(mask); - // We could check whether stereo is enabled here, but these methods are + // We could check whether stereo is enabled here, but these methods are // trivial and have no effect in mono or multiview so just call them regardless. mViewer->getCamera()->setCullMaskLeft(mask); mViewer->getCamera()->setCullMaskRight(mask); @@ -1324,15 +1345,15 @@ namespace MWGui { mSelectedEnchantItem = item; mSelectedSpell.clear(); - const ESM::Enchantment* ench = mStore->get() - .find(item.getClass().getEnchantment(item)); + const ESM::Enchantment* ench = mStore->get().find(item.getClass().getEnchantment(item)); - int chargePercent = static_cast(item.getCellRef().getNormalizedEnchantmentCharge(ench->mData.mCharge) * 100); + int chargePercent + = static_cast(item.getCellRef().getNormalizedEnchantmentCharge(ench->mData.mCharge) * 100); mHud->setSelectedEnchantItem(item, chargePercent); mSpellWindow->setTitle(item.getClass().getName(item)); } - const MWWorld::Ptr &WindowManager::getSelectedEnchantItem() const + const MWWorld::Ptr& WindowManager::getSelectedEnchantItem() const { return mSelectedEnchantItem; } @@ -1349,7 +1370,7 @@ namespace MWGui mInventoryWindow->setTitle(item.getClass().getName(item)); } - const MWWorld::Ptr &WindowManager::getSelectedWeapon() const + const MWWorld::Ptr& WindowManager::getSelectedWeapon() const { return mSelectedWeapon; } @@ -1374,14 +1395,14 @@ namespace MWGui mInventoryWindow->setTitle("#{sSkillHandtohand}"); } - void WindowManager::getMousePosition(int &x, int &y) + void WindowManager::getMousePosition(int& x, int& y) { const MyGUI::IntPoint& pos = MyGUI::InputManager::getInstance().getMousePosition(); x = pos.left; y = pos.top; } - void WindowManager::getMousePosition(float &x, float &y) + void WindowManager::getMousePosition(float& x, float& y) { const MyGUI::IntPoint& pos = MyGUI::InputManager::getInstance().getMousePosition(); x = static_cast(pos.left); @@ -1401,36 +1422,51 @@ namespace MWGui return mScalingFactor; } - void WindowManager::executeInConsole (const std::string& path) + void WindowManager::executeInConsole(const std::string& path) { - mConsole->executeFile (path); + mConsole->executeFile(path); } - MWGui::InventoryWindow* WindowManager::getInventoryWindow() { return mInventoryWindow; } - MWGui::CountDialog* WindowManager::getCountDialog() { return mCountDialog; } - MWGui::ConfirmationDialog* WindowManager::getConfirmationDialog() { return mConfirmationDialog; } - MWGui::TradeWindow* WindowManager::getTradeWindow() { return mTradeWindow; } - MWGui::PostProcessorHud* WindowManager::getPostProcessorHud() { return mPostProcessorHud; } + MWGui::InventoryWindow* WindowManager::getInventoryWindow() + { + return mInventoryWindow; + } + MWGui::CountDialog* WindowManager::getCountDialog() + { + return mCountDialog; + } + MWGui::ConfirmationDialog* WindowManager::getConfirmationDialog() + { + return mConfirmationDialog; + } + MWGui::TradeWindow* WindowManager::getTradeWindow() + { + return mTradeWindow; + } + MWGui::PostProcessorHud* WindowManager::getPostProcessorHud() + { + return mPostProcessorHud; + } - void WindowManager::useItem(const MWWorld::Ptr &item, bool bypassBeastRestrictions) + void WindowManager::useItem(const MWWorld::Ptr& item, bool bypassBeastRestrictions) { if (mInventoryWindow) mInventoryWindow->useItem(item, bypassBeastRestrictions); } - bool WindowManager::isAllowed (GuiWindow wnd) const + bool WindowManager::isAllowed(GuiWindow wnd) const { return (mAllowed & wnd) != 0; } - void WindowManager::allow (GuiWindow wnd) + void WindowManager::allow(GuiWindow wnd) { mAllowed = (GuiWindow)(mAllowed | wnd); if (wnd & GW_Inventory) { - mBookWindow->setInventoryAllowed (true); - mScrollWindow->setInventoryAllowed (true); + mBookWindow->setInventoryAllowed(true); + mScrollWindow->setInventoryAllowed(true); } updateVisible(); @@ -1441,13 +1477,13 @@ namespace MWGui mAllowed = GW_None; mRestAllowed = false; - mBookWindow->setInventoryAllowed (false); - mScrollWindow->setInventoryAllowed (false); + mBookWindow->setInventoryAllowed(false); + mScrollWindow->setInventoryAllowed(false); updateVisible(); } - void WindowManager::toggleVisible (GuiWindow wnd) + void WindowManager::toggleVisible(GuiWindow wnd) { if (getMode() != GM_Inventory) return; @@ -1496,11 +1532,8 @@ namespace MWGui bool WindowManager::isGuiMode() const { - return - !mGuiModes.empty() || - isConsoleMode() || - (mPostProcessorHud && mPostProcessorHud->isVisible()) || - (mMessageBoxManager && mMessageBoxManager->isInteractiveMessageBox()); + return !mGuiModes.empty() || isConsoleMode() || (mPostProcessorHud && mPostProcessorHud->isVisible()) + || (mMessageBoxManager && mMessageBoxManager->isInteractiveMessageBox()); } bool WindowManager::isConsoleMode() const @@ -1522,45 +1555,45 @@ namespace MWGui void WindowManager::disallowMouse() { - mInputBlocker->setVisible (true); + mInputBlocker->setVisible(true); } void WindowManager::allowMouse() { - mInputBlocker->setVisible (!isGuiMode ()); + mInputBlocker->setVisible(!isGuiMode()); } - void WindowManager::notifyInputActionBound () + void WindowManager::notifyInputActionBound() { - mSettingsWindow->updateControlsBox (); + mSettingsWindow->updateControlsBox(); allowMouse(); } bool WindowManager::containsMode(GuiMode mode) const { - if(mGuiModes.empty()) + if (mGuiModes.empty()) return false; return std::find(mGuiModes.begin(), mGuiModes.end(), mode) != mGuiModes.end(); } - void WindowManager::showCrosshair (bool show) + void WindowManager::showCrosshair(bool show) { if (mHud) - mHud->setCrosshairVisible (show && mCrosshairEnabled); + mHud->setCrosshairVisible(show && mCrosshairEnabled); } - void WindowManager::updateActivatedQuickKey () + void WindowManager::updateActivatedQuickKey() { mQuickKeysMenu->updateActivatedQuickKey(); } - void WindowManager::activateQuickKey (int index) + void WindowManager::activateQuickKey(int index) { mQuickKeysMenu->activateQuickKey(index); } - bool WindowManager::getSubtitlesEnabled () + bool WindowManager::getSubtitlesEnabled() { return mSubtitlesEnabled; } @@ -1575,13 +1608,13 @@ namespace MWGui bool WindowManager::getRestEnabled() { - //Enable rest dialogue if character creation finished - if(mRestAllowed==false && MWBase::Environment::get().getWorld()->getGlobalFloat ("chargenstate")==-1) - mRestAllowed=true; + // Enable rest dialogue if character creation finished + if (mRestAllowed == false && MWBase::Environment::get().getWorld()->getGlobalFloat("chargenstate") == -1) + mRestAllowed = true; return mRestAllowed; } - bool WindowManager::getPlayerSleeping () + bool WindowManager::getPlayerSleeping() { return mWaitDialog->getSleeping(); } @@ -1593,7 +1626,7 @@ namespace MWGui void WindowManager::addVisitedLocation(const std::string& name, int x, int y) { - mMap->addVisitedLocation (name, x, y); + mMap->addVisitedLocation(name, x, y); } const Translation::Storage& WindowManager::getTranslationDataStorage() const @@ -1601,7 +1634,7 @@ namespace MWGui return mTranslationDataStorage; } - void WindowManager::changePointer(const std::string &name) + void WindowManager::changePointer(const std::string& name) { MyGUI::PointerManager::getInstance().setPointer(name); onCursorChange(name); @@ -1626,13 +1659,13 @@ namespace MWGui } // Remove this wrapper once onKeyFocusChanged call is rendered unnecessary - void WindowManager::setKeyFocusWidget(MyGUI::Widget *widget) + void WindowManager::setKeyFocusWidget(MyGUI::Widget* widget) { MyGUI::InputManager::getInstance().setKeyFocusWidget(widget); onKeyFocusChanged(widget); } - void WindowManager::onKeyFocusChanged(MyGUI::Widget *widget) + void WindowManager::onKeyFocusChanged(MyGUI::Widget* widget) { if (widget && widget->castType(false)) SDL_StartTextInput(); @@ -1640,7 +1673,7 @@ namespace MWGui SDL_StopTextInput(); } - void WindowManager::setEnemy(const MWWorld::Ptr &enemy) + void WindowManager::setEnemy(const MWWorld::Ptr& enemy) { mHud->setEnemy(enemy); } @@ -1664,7 +1697,7 @@ namespace MWGui return mCursorVisible && mCursorActive; } - void WindowManager::trackWindow(Layout *layout, const std::string &name) + void WindowManager::trackWindow(Layout* layout, const std::string& name) { std::string settingName = name; MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize(); @@ -1672,10 +1705,12 @@ namespace MWGui if (isMaximized) settingName += " maximized"; - MyGUI::IntPoint pos(static_cast(Settings::Manager::getFloat(settingName + " x", "Windows") * viewSize.width), - static_cast(Settings::Manager::getFloat(settingName + " y", "Windows") * viewSize.height)); - MyGUI::IntSize size (static_cast(Settings::Manager::getFloat(settingName + " w", "Windows") * viewSize.width), - static_cast(Settings::Manager::getFloat(settingName + " h", "Windows") * viewSize.height)); + MyGUI::IntPoint pos( + static_cast(Settings::Manager::getFloat(settingName + " x", "Windows") * viewSize.width), + static_cast(Settings::Manager::getFloat(settingName + " y", "Windows") * viewSize.height)); + MyGUI::IntSize size( + static_cast(Settings::Manager::getFloat(settingName + " w", "Windows") * viewSize.width), + static_cast(Settings::Manager::getFloat(settingName + " h", "Windows") * viewSize.height)); layout->mMainWidget->setPosition(pos); layout->mMainWidget->setSize(size); @@ -1684,7 +1719,7 @@ namespace MWGui mTrackedWindows[window] = name; } - void WindowManager::toggleMaximized(Layout *layout) + void WindowManager::toggleMaximized(Layout* layout) { MyGUI::Window* window = layout->mMainWidget->castType(); std::string setting = mTrackedWindows[window]; @@ -1704,7 +1739,7 @@ namespace MWGui Settings::Manager::setBool(mTrackedWindows[window] + " maximized", "Windows", maximized); } - void WindowManager::onWindowChangeCoord(MyGUI::Window *_sender) + void WindowManager::onWindowChangeCoord(MyGUI::Window* _sender) { std::string setting = mTrackedWindows[_sender]; MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize(); @@ -1747,7 +1782,7 @@ namespace MWGui updateVisible(); } - void WindowManager::write(ESM::ESMWriter &writer, Loading::Listener& progress) + void WindowManager::write(ESM::ESMWriter& writer, Loading::Listener& progress) { mMap->write(writer, progress); @@ -1760,7 +1795,8 @@ namespace MWGui writer.endRecord(ESM::REC_ASPL); } - for (CustomMarkerCollection::ContainerType::const_iterator it = mCustomMarkers.begin(); it != mCustomMarkers.end(); ++it) + for (CustomMarkerCollection::ContainerType::const_iterator it = mCustomMarkers.begin(); + it != mCustomMarkers.end(); ++it) { writer.startRecord(ESM::REC_MARK); it->second.save(writer); @@ -1768,7 +1804,7 @@ namespace MWGui } } - void WindowManager::readRecord(ESM::ESMReader &reader, uint32_t type) + void WindowManager::readRecord(ESM::ESMReader& reader, uint32_t type) { if (type == ESM::REC_GMAP) mMap->readRecord(reader, type); @@ -1792,22 +1828,21 @@ namespace MWGui int WindowManager::countSavedGameRecords() const { return 1 // Global map - + 1 // QuickKeysMenu - + mCustomMarkers.size() - + (!mSelectedSpell.empty() ? 1 : 0); + + 1 // QuickKeysMenu + + mCustomMarkers.size() + (!mSelectedSpell.empty() ? 1 : 0); } bool WindowManager::isSavingAllowed() const { return !MyGUI::InputManager::getInstance().isModalAny() - && !isConsoleMode() - // TODO: remove this, once we have properly serialized the state of open windows - && (!isGuiMode() || (mGuiModes.size() == 1 && (getMode() == GM_MainMenu || getMode() == GM_Rest))); + && !isConsoleMode() + // TODO: remove this, once we have properly serialized the state of open windows + && (!isGuiMode() || (mGuiModes.size() == 1 && (getMode() == GM_MainMenu || getMode() == GM_Rest))); } void WindowManager::playVideo(std::string_view name, bool allowSkipping, bool overrideSounds) { - mVideoWidget->playVideo("video\\" + std::string{name}); + mVideoWidget->playVideo("video\\" + std::string{ name }); mVideoWidget->eventKeyButtonPressed.clear(); mVideoBackground->eventKeyButtonPressed.clear(); @@ -1831,14 +1866,16 @@ namespace MWGui setCursorVisible(false); if (overrideSounds && mVideoWidget->hasAudioStream()) - MWBase::Environment::get().getSoundManager()->pauseSounds(MWSound::VideoPlayback, - ~MWSound::Type::Movie & MWSound::Type::Mask - ); + MWBase::Environment::get().getSoundManager()->pauseSounds( + MWSound::VideoPlayback, ~MWSound::Type::Movie & MWSound::Type::Mask); - Misc::FrameRateLimiter frameRateLimiter = Misc::makeFrameRateLimiter(MWBase::Environment::get().getFrameRateLimit()); + Misc::FrameRateLimiter frameRateLimiter + = Misc::makeFrameRateLimiter(MWBase::Environment::get().getFrameRateLimit()); while (mVideoWidget->update() && !MWBase::Environment::get().getStateManager()->hasQuitRequest()) { - const double dt = std::chrono::duration_cast>(frameRateLimiter.getLastFrameDuration()).count(); + const double dt + = std::chrono::duration_cast>(frameRateLimiter.getLastFrameDuration()) + .count(); MWBase::Environment::get().getInputManager()->update(dt, true, false); @@ -1896,7 +1933,7 @@ namespace MWGui } } - void WindowManager::addCurrentModal(WindowModal *input) + void WindowManager::addCurrentModal(WindowModal* input) { if (mCurrentModals.empty()) mKeyboardNavigation->saveFocus(getMode()); @@ -1910,9 +1947,9 @@ namespace MWGui void WindowManager::removeCurrentModal(WindowModal* input) { - if(!mCurrentModals.empty()) + if (!mCurrentModals.empty()) { - if(input == mCurrentModals.back()) + if (input == mCurrentModals.back()) { mCurrentModals.pop_back(); mKeyboardNavigation->saveFocus(-1); @@ -1935,7 +1972,7 @@ namespace MWGui mKeyboardNavigation->setModalWindow(mCurrentModals.back()->mMainWidget); } - void WindowManager::onVideoKeyPressed(MyGUI::Widget *_sender, MyGUI::KeyCode _key, MyGUI::Char _char) + void WindowManager::onVideoKeyPressed(MyGUI::Widget* _sender, MyGUI::KeyCode _key, MyGUI::Char _char) { if (_key == MyGUI::KeyCode::Escape) mVideoWidget->stop(); @@ -1964,20 +2001,20 @@ namespace MWGui { switch (window) { - case GW_Inventory: - mInventoryWindow->setPinned(true); - break; - case GW_Map: - mMap->setPinned(true); - break; - case GW_Magic: - mSpellWindow->setPinned(true); - break; - case GW_Stats: - mStatsWindow->setPinned(true); - break; - default: - break; + case GW_Inventory: + mInventoryWindow->setPinned(true); + break; + case GW_Map: + mMap->setPinned(true); + break; + case GW_Magic: + mSpellWindow->setPinned(true); + break; + case GW_Stats: + mStatsWindow->setPinned(true); + break; + default: + break; } updateVisible(); @@ -2031,17 +2068,17 @@ namespace MWGui mWerewolfFader->notifyAlphaChanged(set ? 1.0f : 0.0f); } - void WindowManager::onClipboardChanged(const std::string &_type, const std::string &_data) + void WindowManager::onClipboardChanged(const std::string& _type, const std::string& _data) { if (_type == "Text") SDL_SetClipboardText(MyGUI::TextIterator::getOnlyText(MyGUI::UString(_data)).asUTF8().c_str()); } - void WindowManager::onClipboardRequested(const std::string &_type, std::string &_data) + void WindowManager::onClipboardRequested(const std::string& _type, std::string& _data) { if (_type != "Text") return; - char* text=nullptr; + char* text = nullptr; text = SDL_GetClipboardText(); if (text) _data = MyGUI::TextIterator::toTagsString(text); @@ -2107,7 +2144,8 @@ namespace MWGui if (soundId.empty()) return; - MWBase::Environment::get().getSoundManager()->playSound(soundId, volume, pitch, MWSound::Type::Sfx, MWSound::PlayMode::NoEnvNoScaling); + MWBase::Environment::get().getSoundManager()->playSound( + soundId, volume, pitch, MWSound::Type::Sfx, MWSound::PlayMode::NoEnvNoScaling); } void WindowManager::updateSpellWindow() @@ -2116,7 +2154,7 @@ namespace MWGui mSpellWindow->updateSpells(); } - void WindowManager::setConsoleSelectedObject(const MWWorld::Ptr &object) + void WindowManager::setConsoleSelectedObject(const MWWorld::Ptr& object) { mConsole->setSelectedObject(object); } @@ -2140,19 +2178,20 @@ namespace MWGui ResourceImageSetPointerFix* imgSetPointer = resource->castType(false); if (!imgSetPointer) continue; - std::string tex_name = imgSetPointer->getImageSet()->getIndexInfo(0,0).texture; + std::string tex_name = imgSetPointer->getImageSet()->getIndexInfo(0, 0).texture; osg::ref_ptr image = mResourceSystem->getImageManager()->getImage(tex_name); - if(image.valid()) + if (image.valid()) { - //everything looks good, send it to the cursor manager + // everything looks good, send it to the cursor manager Uint8 hotspot_x = imgSetPointer->getHotSpot().left; Uint8 hotspot_y = imgSetPointer->getHotSpot().top; int rotation = imgSetPointer->getRotation(); MyGUI::IntSize pointerSize = imgSetPointer->getSize(); - mCursorManager->createCursor(imgSetPointer->getResourceName(), rotation, image, hotspot_x, hotspot_y, pointerSize.width, pointerSize.height); + mCursorManager->createCursor(imgSetPointer->getResourceName(), rotation, image, hotspot_x, hotspot_y, + pointerSize.width, pointerSize.height); } } } @@ -2163,8 +2202,8 @@ namespace MWGui MyGUI::ITexture* tex = MyGUI::RenderManager::getInstance().createTexture("white"); tex->createManual(8, 8, MyGUI::TextureUsage::Write, MyGUI::PixelFormat::R8G8B8); unsigned char* data = reinterpret_cast(tex->lock(MyGUI::TextureUsage::Write)); - for (int x=0; x<8; ++x) - for (int y=0; y<8; ++y) + for (int x = 0; x < 8; ++x) + for (int y = 0; y < 8; ++y) { *(data++) = 255; *(data++) = 255; @@ -2177,8 +2216,8 @@ namespace MWGui MyGUI::ITexture* tex = MyGUI::RenderManager::getInstance().createTexture("black"); tex->createManual(8, 8, MyGUI::TextureUsage::Write, MyGUI::PixelFormat::R8G8B8); unsigned char* data = reinterpret_cast(tex->lock(MyGUI::TextureUsage::Write)); - for (int x=0; x<8; ++x) - for (int y=0; y<8; ++y) + for (int x = 0; x < 8; ++x) + for (int y = 0; y < 8; ++y) { *(data++) = 0; *(data++) = 0; @@ -2198,13 +2237,13 @@ namespace MWGui { MyGUI::ITexture* tex = MyGUI::RenderManager::getInstance().getTexture("transparent"); unsigned char* data = reinterpret_cast(tex->lock(MyGUI::TextureUsage::Write)); - for (int x=0; x<8; ++x) - for (int y=0; y<8; ++y) + for (int x = 0; x < 8; ++x) + for (int y = 0; y < 8; ++y) { *(data++) = 255; *(data++) = 255; *(data++) = 255; - *(data++) = static_cast(value*255); + *(data++) = static_cast(value * 255); } tex->unlock(); } @@ -2214,12 +2253,12 @@ namespace MWGui mLocalMapRender->addCell(cell); } - void WindowManager::removeCell(MWWorld::CellStore *cell) + void WindowManager::removeCell(MWWorld::CellStore* cell) { mLocalMapRender->removeCell(cell); } - void WindowManager::writeFog(MWWorld::CellStore *cell) + void WindowManager::writeFog(MWWorld::CellStore* cell) { mLocalMapRender->saveFogOfWar(cell); } @@ -2242,16 +2281,16 @@ namespace MWGui { switch (key.getValue()) { - case MyGUI::KeyCode::ArrowDown: - case MyGUI::KeyCode::ArrowUp: - case MyGUI::KeyCode::ArrowLeft: - case MyGUI::KeyCode::ArrowRight: - case MyGUI::KeyCode::Return: - case MyGUI::KeyCode::NumpadEnter: - case MyGUI::KeyCode::Space: - return true; - default: - return false; + case MyGUI::KeyCode::ArrowDown: + case MyGUI::KeyCode::ArrowUp: + case MyGUI::KeyCode::ArrowLeft: + case MyGUI::KeyCode::ArrowRight: + case MyGUI::KeyCode::Return: + case MyGUI::KeyCode::NumpadEnter: + case MyGUI::KeyCode::Space: + return true; + default: + return false; } } return false; @@ -2296,7 +2335,7 @@ namespace MWGui void WindowManager::onDeleteCustomData(const MWWorld::Ptr& ptr) { - for(const auto& window : mWindows) + for (const auto& window : mWindows) window->onDeleteCustomData(ptr); } diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index 162f3403aa..773f670d1e 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -7,9 +7,9 @@ and retrieving information from the Gui. **/ +#include #include #include -#include #include @@ -88,492 +88,504 @@ namespace Gui namespace MWGui { - class HUD; - class MapWindow; - class MainMenu; - class StatsWindow; - class InventoryWindow; - struct JournalWindow; - class TextInputDialog; - class InfoBoxDialog; - class SettingsWindow; - class AlchemyWindow; - class QuickKeysMenu; - class LoadingScreen; - class LevelupDialog; - class WaitDialog; - class SpellCreationDialog; - class EnchantingDialog; - class TrainingWindow; - class SpellIcons; - class MerchantRepair; - class Recharge; - class CompanionWindow; - class VideoWidget; - class WindowModal; - class ScreenFader; - class DebugWindow; - class PostProcessorHud; - class JailScreen; - class KeyboardNavigation; - - class WindowManager : - public MWBase::WindowManager - { - public: - typedef std::pair Faction; - typedef std::vector FactionList; - - WindowManager(SDL_Window* window, osgViewer::Viewer* viewer, osg::Group* guiRoot, Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, - const std::filesystem::path& logpath, bool consoleOnlyScripts, Translation::Storage& translationDataStorage, - ToUTF8::FromType encoding, const std::string& versionDescription, bool useShaders); - virtual ~WindowManager(); - - /// Set the ESMStore to use for retrieving of GUI-related strings. - void setStore (const MWWorld::ESMStore& store); - - void initUI(); - - Loading::Listener* getLoadingScreen() override; - - /// @note This method will block until the video finishes playing - /// (and will continually update the window while doing so) - void playVideo(std::string_view name, bool allowSkipping, bool overrideSounds = true) override; - - /// Warning: do not use MyGUI::InputManager::setKeyFocusWidget directly. Instead use this. - void setKeyFocusWidget (MyGUI::Widget* widget) override; - - void setNewGame(bool newgame) override; - - void pushGuiMode(GuiMode mode, const MWWorld::Ptr& arg) override; - void pushGuiMode (GuiMode mode) override; - void popGuiMode(bool noSound=false) override; - void removeGuiMode(GuiMode mode, bool noSound=false) override; ///< can be anywhere in the stack - - void goToJail(int days) override; - - GuiMode getMode() const override; - bool containsMode(GuiMode mode) const override; - - bool isGuiMode() const override; - - bool isConsoleMode() const override; - - bool isPostProcessorHudVisible() const override; - - void toggleVisible(GuiWindow wnd) override; - - void forceHide(MWGui::GuiWindow wnd) override; - void unsetForceHide(MWGui::GuiWindow wnd) override; - - /// Disallow all inventory mode windows - void disallowAll() override; - - /// Allow one or more windows - void allow(GuiWindow wnd) override; - - bool isAllowed(GuiWindow wnd) const override; - - /// \todo investigate, if we really need to expose every single lousy UI element to the outside world - MWGui::InventoryWindow* getInventoryWindow() override; - MWGui::CountDialog* getCountDialog() override; - MWGui::ConfirmationDialog* getConfirmationDialog() override; - MWGui::TradeWindow* getTradeWindow() override; - const std::vector>& getActiveMessageBoxes() const override; - MWGui::PostProcessorHud* getPostProcessorHud() override; - - /// Make the player use an item, while updating GUI state accordingly - void useItem(const MWWorld::Ptr& item, bool bypassBeastRestrictions=false) override; - - void updateSpellWindow() override; - - void setConsoleSelectedObject(const MWWorld::Ptr& object) override; - void printToConsole(const std::string& msg, std::string_view color) override; - void setConsoleMode(const std::string& mode) override; - - /// Set time left for the player to start drowning (update the drowning bar) - /// @param time time left to start drowning - /// @param maxTime how long we can be underwater (in total) until drowning starts - void setDrowningTimeLeft (float time, float maxTime) override; + class HUD; + class MapWindow; + class MainMenu; + class StatsWindow; + class InventoryWindow; + struct JournalWindow; + class TextInputDialog; + class InfoBoxDialog; + class SettingsWindow; + class AlchemyWindow; + class QuickKeysMenu; + class LoadingScreen; + class LevelupDialog; + class WaitDialog; + class SpellCreationDialog; + class EnchantingDialog; + class TrainingWindow; + class SpellIcons; + class MerchantRepair; + class Recharge; + class CompanionWindow; + class VideoWidget; + class WindowModal; + class ScreenFader; + class DebugWindow; + class PostProcessorHud; + class JailScreen; + class KeyboardNavigation; + + class WindowManager : public MWBase::WindowManager + { + public: + typedef std::pair Faction; + typedef std::vector FactionList; - void changeCell(const MWWorld::CellStore* cell) override; ///< change the active cell + WindowManager(SDL_Window* window, osgViewer::Viewer* viewer, osg::Group* guiRoot, + Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, + const std::filesystem::path& logpath, bool consoleOnlyScripts, Translation::Storage& translationDataStorage, + ToUTF8::FromType encoding, const std::string& versionDescription, bool useShaders); + virtual ~WindowManager(); - void setFocusObject(const MWWorld::Ptr& focus) override; - void setFocusObjectScreenCoords(float min_x, float min_y, float max_x, float max_y) override; + /// Set the ESMStore to use for retrieving of GUI-related strings. + void setStore(const MWWorld::ESMStore& store); - void getMousePosition(int &x, int &y) override; - void getMousePosition(float &x, float &y) override; - void setDragDrop(bool dragDrop) override; - bool getWorldMouseOver() override; + void initUI(); - float getScalingFactor() const override; + Loading::Listener* getLoadingScreen() override; - bool toggleFogOfWar() override; - bool toggleFullHelp() override; ///< show extra info in item tooltips (owner, script) - bool getFullHelp() const override; + /// @note This method will block until the video finishes playing + /// (and will continually update the window while doing so) + void playVideo(std::string_view name, bool allowSkipping, bool overrideSounds = true) override; - void setActiveMap(int x, int y, bool interior) override; - ///< set the indices of the map texture that should be used + /// Warning: do not use MyGUI::InputManager::setKeyFocusWidget directly. Instead use this. + void setKeyFocusWidget(MyGUI::Widget* widget) override; - /// sets the visibility of the drowning bar - void setDrowningBarVisibility(bool visible) override; + void setNewGame(bool newgame) override; - // sets the visibility of the hud health/magicka/stamina bars - void setHMSVisibility(bool visible) override; - // sets the visibility of the hud minimap - void setMinimapVisibility(bool visible) override; - void setWeaponVisibility(bool visible) override; - void setSpellVisibility(bool visible) override; - void setSneakVisibility(bool visible) override; + void pushGuiMode(GuiMode mode, const MWWorld::Ptr& arg) override; + void pushGuiMode(GuiMode mode) override; + void popGuiMode(bool noSound = false) override; + void removeGuiMode(GuiMode mode, bool noSound = false) override; ///< can be anywhere in the stack - /// activate selected quick key - void activateQuickKey (int index) override; - /// update activated quick key state (if action executing was delayed for some reason) - void updateActivatedQuickKey () override; + void goToJail(int days) override; - const std::string& getSelectedSpell() override { return mSelectedSpell; } - void setSelectedSpell(const std::string& spellId, int successChancePercent) override; - void setSelectedEnchantItem(const MWWorld::Ptr& item) override; - const MWWorld::Ptr& getSelectedEnchantItem() const override; - void setSelectedWeapon(const MWWorld::Ptr& item) override; - const MWWorld::Ptr& getSelectedWeapon() const override; - int getFontHeight() const override; - void unsetSelectedSpell() override; - void unsetSelectedWeapon() override; + GuiMode getMode() const override; + bool containsMode(GuiMode mode) const override; - void updateConsoleObjectPtr(const MWWorld::Ptr& currentPtr, const MWWorld::Ptr& newPtr) override; + bool isGuiMode() const override; - void showCrosshair(bool show) override; - bool getSubtitlesEnabled() override; + bool isConsoleMode() const override; - /// Turn visibility of HUD on or off - bool toggleHud() override; + bool isPostProcessorHudVisible() const override; - void disallowMouse() override; - void allowMouse() override; - void notifyInputActionBound() override; + void toggleVisible(GuiWindow wnd) override; - void addVisitedLocation(const std::string& name, int x, int y) override; + void forceHide(MWGui::GuiWindow wnd) override; + void unsetForceHide(MWGui::GuiWindow wnd) override; - ///Hides dialog and schedules dialog to be deleted. - void removeDialog(std::unique_ptr&& dialog) override; + /// Disallow all inventory mode windows + void disallowAll() override; - ///Gracefully attempts to exit the topmost GUI mode - void exitCurrentGuiMode() override; + /// Allow one or more windows + void allow(GuiWindow wnd) override; - void messageBox(std::string_view message, enum MWGui::ShowInDialogueMode showInDialogueMode = MWGui::ShowInDialogueMode_IfPossible) override; - void scheduleMessageBox (std::string message, enum MWGui::ShowInDialogueMode showInDialogueMode = MWGui::ShowInDialogueMode_IfPossible) override; - void staticMessageBox(std::string_view message) override; - void removeStaticMessageBox() override; - void interactiveMessageBox(std::string_view message, const std::vector& buttons = {}, bool block = false) override; + bool isAllowed(GuiWindow wnd) const override; - int readPressedButton () override; ///< returns the index of the pressed button or -1 if no button was pressed (->MessageBoxmanager->InteractiveMessageBox) + /// \todo investigate, if we really need to expose every single lousy UI element to the outside world + MWGui::InventoryWindow* getInventoryWindow() override; + MWGui::CountDialog* getCountDialog() override; + MWGui::ConfirmationDialog* getConfirmationDialog() override; + MWGui::TradeWindow* getTradeWindow() override; + const std::vector>& getActiveMessageBoxes() const override; + MWGui::PostProcessorHud* getPostProcessorHud() override; - void update (float duration); + /// Make the player use an item, while updating GUI state accordingly + void useItem(const MWWorld::Ptr& item, bool bypassBeastRestrictions = false) override; - /** - * Fetches a GMST string from the store, if there is no setting with the given - * ID or it is not a string the default string is returned. - * - * @param id Identifier for the GMST setting, e.g. "aName" - * @param default Default value if the GMST setting cannot be used. - */ - std::string_view getGameSettingString(std::string_view id, std::string_view default_) override; + void updateSpellWindow() override; - void processChangedSettings(const Settings::CategorySettingVector& changed) override; + void setConsoleSelectedObject(const MWWorld::Ptr& object) override; + void printToConsole(const std::string& msg, std::string_view color) override; + void setConsoleMode(const std::string& mode) override; - void windowVisibilityChange(bool visible) override; - void windowResized(int x, int y) override; - void windowClosed() override; - bool isWindowVisible() override; + /// Set time left for the player to start drowning (update the drowning bar) + /// @param time time left to start drowning + /// @param maxTime how long we can be underwater (in total) until drowning starts + void setDrowningTimeLeft(float time, float maxTime) override; - void watchActor(const MWWorld::Ptr& ptr) override; - MWWorld::Ptr getWatchedActor() const override; + void changeCell(const MWWorld::CellStore* cell) override; ///< change the active cell - void executeInConsole (const std::string& path) override; + void setFocusObject(const MWWorld::Ptr& focus) override; + void setFocusObjectScreenCoords(float min_x, float min_y, float max_x, float max_y) override; - void enableRest() override { mRestAllowed = true; } - bool getRestEnabled() override; + void getMousePosition(int& x, int& y) override; + void getMousePosition(float& x, float& y) override; + void setDragDrop(bool dragDrop) override; + bool getWorldMouseOver() override; - bool getJournalAllowed() override { return (mAllowed & GW_Magic) != 0; } + float getScalingFactor() const override; - bool getPlayerSleeping() override; - void wakeUpPlayer() override; + bool toggleFogOfWar() override; + bool toggleFullHelp() override; ///< show extra info in item tooltips (owner, script) + bool getFullHelp() const override; - void updatePlayer() override; + void setActiveMap(int x, int y, bool interior) override; + ///< set the indices of the map texture that should be used - void showSoulgemDialog (MWWorld::Ptr item) override; + /// sets the visibility of the drowning bar + void setDrowningBarVisibility(bool visible) override; - void changePointer (const std::string& name) override; + // sets the visibility of the hud health/magicka/stamina bars + void setHMSVisibility(bool visible) override; + // sets the visibility of the hud minimap + void setMinimapVisibility(bool visible) override; + void setWeaponVisibility(bool visible) override; + void setSpellVisibility(bool visible) override; + void setSneakVisibility(bool visible) override; - void setEnemy (const MWWorld::Ptr& enemy) override; + /// activate selected quick key + void activateQuickKey(int index) override; + /// update activated quick key state (if action executing was delayed for some reason) + void updateActivatedQuickKey() override; - int getMessagesCount() const override; + const std::string& getSelectedSpell() override { return mSelectedSpell; } + void setSelectedSpell(const std::string& spellId, int successChancePercent) override; + void setSelectedEnchantItem(const MWWorld::Ptr& item) override; + const MWWorld::Ptr& getSelectedEnchantItem() const override; + void setSelectedWeapon(const MWWorld::Ptr& item) override; + const MWWorld::Ptr& getSelectedWeapon() const override; + int getFontHeight() const override; + void unsetSelectedSpell() override; + void unsetSelectedWeapon() override; - const Translation::Storage& getTranslationDataStorage() const override; + void updateConsoleObjectPtr(const MWWorld::Ptr& currentPtr, const MWWorld::Ptr& newPtr) override; - void onSoulgemDialogButtonPressed (int button); + void showCrosshair(bool show) override; + bool getSubtitlesEnabled() override; - bool getCursorVisible() override; + /// Turn visibility of HUD on or off + bool toggleHud() override; - /// Call when mouse cursor or buttons are used. - void setCursorActive(bool active) override; + void disallowMouse() override; + void allowMouse() override; + void notifyInputActionBound() override; - /// Clear all savegame-specific data - void clear() override; + void addVisitedLocation(const std::string& name, int x, int y) override; - void write (ESM::ESMWriter& writer, Loading::Listener& progress) override; - void readRecord (ESM::ESMReader& reader, uint32_t type) override; - int countSavedGameRecords() const override; + /// Hides dialog and schedules dialog to be deleted. + void removeDialog(std::unique_ptr&& dialog) override; - /// Does the current stack of GUI-windows permit saving? - bool isSavingAllowed() const override; + /// Gracefully attempts to exit the topmost GUI mode + void exitCurrentGuiMode() override; - /// Send exit command to active Modal window **/ - void exitCurrentModal() override; + void messageBox(std::string_view message, + enum MWGui::ShowInDialogueMode showInDialogueMode = MWGui::ShowInDialogueMode_IfPossible) override; + void scheduleMessageBox(std::string message, + enum MWGui::ShowInDialogueMode showInDialogueMode = MWGui::ShowInDialogueMode_IfPossible) override; + void staticMessageBox(std::string_view message) override; + void removeStaticMessageBox() override; + void interactiveMessageBox( + std::string_view message, const std::vector& buttons = {}, bool block = false) override; - /// Sets the current Modal - /** Used to send exit command to active Modal when Esc is pressed **/ - void addCurrentModal(WindowModal* input) override; + int readPressedButton() override; ///< returns the index of the pressed button or -1 if no button was pressed + ///< (->MessageBoxmanager->InteractiveMessageBox) - /// Removes the top Modal - /** Used when one Modal adds another Modal - \param input Pointer to the current modal, to ensure proper modal is removed **/ - void removeCurrentModal(WindowModal* input) override; + void update(float duration); - void pinWindow (MWGui::GuiWindow window) override; - void toggleMaximized(Layout *layout) override; + /** + * Fetches a GMST string from the store, if there is no setting with the given + * ID or it is not a string the default string is returned. + * + * @param id Identifier for the GMST setting, e.g. "aName" + * @param default Default value if the GMST setting cannot be used. + */ + std::string_view getGameSettingString(std::string_view id, std::string_view default_) override; - /// Fade the screen in, over \a time seconds - void fadeScreenIn(const float time, bool clearQueue, float delay) override; - /// Fade the screen out to black, over \a time seconds - void fadeScreenOut(const float time, bool clearQueue, float delay) override; - /// Fade the screen to a specified percentage of black, over \a time seconds - void fadeScreenTo(const int percent, const float time, bool clearQueue, float delay) override; - /// Darken the screen to a specified percentage - void setBlindness(const int percent) override; + void processChangedSettings(const Settings::CategorySettingVector& changed) override; - void activateHitOverlay(bool interrupt) override; - void setWerewolfOverlay(bool set) override; + void windowVisibilityChange(bool visible) override; + void windowResized(int x, int y) override; + void windowClosed() override; + bool isWindowVisible() override; - void toggleConsole() override; - void toggleDebugWindow() override; - void togglePostProcessorHud() override; + void watchActor(const MWWorld::Ptr& ptr) override; + MWWorld::Ptr getWatchedActor() const override; - /// Cycle to next or previous spell - void cycleSpell(bool next) override; - /// Cycle to next or previous weapon - void cycleWeapon(bool next) override; + void executeInConsole(const std::string& path) override; - void playSound(std::string_view soundId, float volume = 1.f, float pitch = 1.f) override; + void enableRest() override { mRestAllowed = true; } + bool getRestEnabled() override; - void addCell(MWWorld::CellStore* cell) override; - void removeCell(MWWorld::CellStore* cell) override; - void writeFog(MWWorld::CellStore* cell) override; + bool getJournalAllowed() override { return (mAllowed & GW_Magic) != 0; } - const MWGui::TextColours& getTextColours() override; + bool getPlayerSleeping() override; + void wakeUpPlayer() override; - bool injectKeyPress(MyGUI::KeyCode key, unsigned int text, bool repeat=false) override; - bool injectKeyRelease(MyGUI::KeyCode key) override; + void updatePlayer() override; - const std::string& getVersionDescription() const override; + void showSoulgemDialog(MWWorld::Ptr item) override; - void onDeleteCustomData(const MWWorld::Ptr& ptr) override; - void forceLootMode(const MWWorld::Ptr& ptr) override; + void changePointer(const std::string& name) override; - void asyncPrepareSaveMap() override; + void setEnemy(const MWWorld::Ptr& enemy) override; - private: - unsigned int mOldUpdateMask; unsigned int mOldCullMask; + int getMessagesCount() const override; - const MWWorld::ESMStore* mStore; - Resource::ResourceSystem* mResourceSystem; - osg::ref_ptr mWorkQueue; + const Translation::Storage& getTranslationDataStorage() const override; - std::unique_ptr mGuiPlatform; - osgViewer::Viewer* mViewer; + void onSoulgemDialogButtonPressed(int button); - std::unique_ptr mFontLoader; - std::unique_ptr mStatsWatcher; + bool getCursorVisible() override; - bool mConsoleOnlyScripts; + /// Call when mouse cursor or buttons are used. + void setCursorActive(bool active) override; - std::map mTrackedWindows; - void trackWindow(Layout* layout, const std::string& name); - void onWindowChangeCoord(MyGUI::Window* _sender); + /// Clear all savegame-specific data + void clear() override; - std::string mSelectedSpell; - MWWorld::Ptr mSelectedEnchantItem; - MWWorld::Ptr mSelectedWeapon; + void write(ESM::ESMWriter& writer, Loading::Listener& progress) override; + void readRecord(ESM::ESMReader& reader, uint32_t type) override; + int countSavedGameRecords() const override; - std::vector mCurrentModals; + /// Does the current stack of GUI-windows permit saving? + bool isSavingAllowed() const override; - // Markers placed manually by the player. Must be shared between both map views (the HUD map and the map window). - CustomMarkerCollection mCustomMarkers; + /// Send exit command to active Modal window **/ + void exitCurrentModal() override; - HUD *mHud; - MapWindow *mMap; - std::unique_ptr mLocalMapRender; - std::unique_ptr mToolTips; - StatsWindow *mStatsWindow; - std::unique_ptr mMessageBoxManager; - Console *mConsole; - DialogueWindow *mDialogueWindow; - std::unique_ptr mDragAndDrop; - InventoryWindow *mInventoryWindow; - ScrollWindow* mScrollWindow; - BookWindow* mBookWindow; - CountDialog* mCountDialog; - TradeWindow* mTradeWindow; - SettingsWindow* mSettingsWindow; - ConfirmationDialog* mConfirmationDialog; - SpellWindow* mSpellWindow; - QuickKeysMenu* mQuickKeysMenu; - LoadingScreen* mLoadingScreen; - WaitDialog* mWaitDialog; - std::unique_ptr mSoulgemDialog; - MyGUI::ImageBox* mVideoBackground; - VideoWidget* mVideoWidget; - ScreenFader* mWerewolfFader; - ScreenFader* mBlindnessFader; - ScreenFader* mHitFader; - ScreenFader* mScreenFader; - DebugWindow* mDebugWindow; - PostProcessorHud* mPostProcessorHud; - JailScreen* mJailScreen; - ContainerWindow* mContainerWindow; - - std::vector> mWindows; - - Translation::Storage& mTranslationDataStorage; - - std::unique_ptr mCharGen; + /// Sets the current Modal + /** Used to send exit command to active Modal when Esc is pressed **/ + void addCurrentModal(WindowModal* input) override; - MyGUI::Widget* mInputBlocker; + /// Removes the top Modal + /** Used when one Modal adds another Modal + \param input Pointer to the current modal, to ensure proper modal is removed **/ + void removeCurrentModal(WindowModal* input) override; - bool mCrosshairEnabled; - bool mSubtitlesEnabled; - bool mHitFaderEnabled; - bool mWerewolfOverlayEnabled; - bool mHudEnabled; - bool mCursorVisible; - bool mCursorActive; + void pinWindow(MWGui::GuiWindow window) override; + void toggleMaximized(Layout* layout) override; - int mPlayerBounty; + /// Fade the screen in, over \a time seconds + void fadeScreenIn(const float time, bool clearQueue, float delay) override; + /// Fade the screen out to black, over \a time seconds + void fadeScreenOut(const float time, bool clearQueue, float delay) override; + /// Fade the screen to a specified percentage of black, over \a time seconds + void fadeScreenTo(const int percent, const float time, bool clearQueue, float delay) override; + /// Darken the screen to a specified percentage + void setBlindness(const int percent) override; - void setCursorVisible(bool visible) override; + void activateHitOverlay(bool interrupt) override; + void setWerewolfOverlay(bool set) override; - std::unique_ptr mGui; // Gui + void toggleConsole() override; + void toggleDebugWindow() override; + void togglePostProcessorHud() override; - struct GuiModeState - { - GuiModeState(WindowBase* window) + /// Cycle to next or previous spell + void cycleSpell(bool next) override; + /// Cycle to next or previous weapon + void cycleWeapon(bool next) override; + + void playSound(std::string_view soundId, float volume = 1.f, float pitch = 1.f) override; + + void addCell(MWWorld::CellStore* cell) override; + void removeCell(MWWorld::CellStore* cell) override; + void writeFog(MWWorld::CellStore* cell) override; + + const MWGui::TextColours& getTextColours() override; + + bool injectKeyPress(MyGUI::KeyCode key, unsigned int text, bool repeat = false) override; + bool injectKeyRelease(MyGUI::KeyCode key) override; + + const std::string& getVersionDescription() const override; + + void onDeleteCustomData(const MWWorld::Ptr& ptr) override; + void forceLootMode(const MWWorld::Ptr& ptr) override; + + void asyncPrepareSaveMap() override; + + private: + unsigned int mOldUpdateMask; + unsigned int mOldCullMask; + + const MWWorld::ESMStore* mStore; + Resource::ResourceSystem* mResourceSystem; + osg::ref_ptr mWorkQueue; + + std::unique_ptr mGuiPlatform; + osgViewer::Viewer* mViewer; + + std::unique_ptr mFontLoader; + std::unique_ptr mStatsWatcher; + + bool mConsoleOnlyScripts; + + std::map mTrackedWindows; + void trackWindow(Layout* layout, const std::string& name); + void onWindowChangeCoord(MyGUI::Window* _sender); + + std::string mSelectedSpell; + MWWorld::Ptr mSelectedEnchantItem; + MWWorld::Ptr mSelectedWeapon; + + std::vector mCurrentModals; + + // Markers placed manually by the player. Must be shared between both map views (the HUD map and the map + // window). + CustomMarkerCollection mCustomMarkers; + + HUD* mHud; + MapWindow* mMap; + std::unique_ptr mLocalMapRender; + std::unique_ptr mToolTips; + StatsWindow* mStatsWindow; + std::unique_ptr mMessageBoxManager; + Console* mConsole; + DialogueWindow* mDialogueWindow; + std::unique_ptr mDragAndDrop; + InventoryWindow* mInventoryWindow; + ScrollWindow* mScrollWindow; + BookWindow* mBookWindow; + CountDialog* mCountDialog; + TradeWindow* mTradeWindow; + SettingsWindow* mSettingsWindow; + ConfirmationDialog* mConfirmationDialog; + SpellWindow* mSpellWindow; + QuickKeysMenu* mQuickKeysMenu; + LoadingScreen* mLoadingScreen; + WaitDialog* mWaitDialog; + std::unique_ptr mSoulgemDialog; + MyGUI::ImageBox* mVideoBackground; + VideoWidget* mVideoWidget; + ScreenFader* mWerewolfFader; + ScreenFader* mBlindnessFader; + ScreenFader* mHitFader; + ScreenFader* mScreenFader; + DebugWindow* mDebugWindow; + PostProcessorHud* mPostProcessorHud; + JailScreen* mJailScreen; + ContainerWindow* mContainerWindow; + + std::vector> mWindows; + + Translation::Storage& mTranslationDataStorage; + + std::unique_ptr mCharGen; + + MyGUI::Widget* mInputBlocker; + + bool mCrosshairEnabled; + bool mSubtitlesEnabled; + bool mHitFaderEnabled; + bool mWerewolfOverlayEnabled; + bool mHudEnabled; + bool mCursorVisible; + bool mCursorActive; + + int mPlayerBounty; + + void setCursorVisible(bool visible) override; + + std::unique_ptr mGui; // Gui + + struct GuiModeState { - mWindows.push_back(window); - } - GuiModeState(const std::vector& windows) - : mWindows(windows) {} - GuiModeState() {} + GuiModeState(WindowBase* window) { mWindows.push_back(window); } + GuiModeState(const std::vector& windows) + : mWindows(windows) + { + } + GuiModeState() {} - void update(bool visible); + void update(bool visible); - std::vector mWindows; + std::vector mWindows; - std::string mCloseSound; - std::string mOpenSound; - }; - // Defines the windows that should be shown in a particular GUI mode. - std::map mGuiModeStates; - // The currently active stack of GUI modes (top mode is the one we are in). - std::vector mGuiModes; + std::string mCloseSound; + std::string mOpenSound; + }; + // Defines the windows that should be shown in a particular GUI mode. + std::map mGuiModeStates; + // The currently active stack of GUI modes (top mode is the one we are in). + std::vector mGuiModes; - std::unique_ptr mCursorManager; + std::unique_ptr mCursorManager; - std::vector> mGarbageDialogs; - void cleanupGarbage(); + std::vector> mGarbageDialogs; + void cleanupGarbage(); - GuiWindow mShown; // Currently shown windows in inventory mode - GuiWindow mForceHidden; // Hidden windows (overrides mShown) + GuiWindow mShown; // Currently shown windows in inventory mode + GuiWindow mForceHidden; // Hidden windows (overrides mShown) - /* Currently ALLOWED windows in inventory mode. This is used at - the start of the game, when windows are enabled one by one - through script commands. You can manipulate this through using - allow() and disableAll(). - */ - GuiWindow mAllowed; - // is the rest window allowed? - bool mRestAllowed; + /* Currently ALLOWED windows in inventory mode. This is used at + the start of the game, when windows are enabled one by one + through script commands. You can manipulate this through using + allow() and disableAll(). + */ + GuiWindow mAllowed; + // is the rest window allowed? + bool mRestAllowed; - void updateVisible(); // Update visibility of all windows based on mode, shown and allowed settings + void updateVisible(); // Update visibility of all windows based on mode, shown and allowed settings - void updateMap(); + void updateMap(); - int mShowOwned; + int mShowOwned; - ToUTF8::FromType mEncoding; + ToUTF8::FromType mEncoding; - std::string mVersionDescription; + std::string mVersionDescription; - bool mWindowVisible; + bool mWindowVisible; - MWGui::TextColours mTextColours; + MWGui::TextColours mTextColours; - std::unique_ptr mKeyboardNavigation; + std::unique_ptr mKeyboardNavigation; - std::unique_ptr mVideoWrapper; + std::unique_ptr mVideoWrapper; - float mScalingFactor; + float mScalingFactor; - struct ScheduledMessageBox - { - std::string mMessage; - MWGui::ShowInDialogueMode mShowInDialogueMode; + struct ScheduledMessageBox + { + std::string mMessage; + MWGui::ShowInDialogueMode mShowInDialogueMode; - ScheduledMessageBox(std::string&& message, MWGui::ShowInDialogueMode showInDialogueMode) - : mMessage(std::move(message)), mShowInDialogueMode(showInDialogueMode) {} - }; + ScheduledMessageBox(std::string&& message, MWGui::ShowInDialogueMode showInDialogueMode) + : mMessage(std::move(message)) + , mShowInDialogueMode(showInDialogueMode) + { + } + }; - Misc::ScopeGuarded> mScheduledMessageBoxes; + Misc::ScopeGuarded> mScheduledMessageBoxes; - /** - * Called when MyGUI tries to retrieve a tag's value. Tags must be denoted in #{tag} notation and will be replaced upon setting a user visible text/property. - * Supported syntax: - * #{GMSTName}: retrieves String value of the GMST called GMSTName - * #{setting=CATEGORY_NAME,SETTING_NAME}: retrieves String value of SETTING_NAME under category CATEGORY_NAME from settings.cfg - * #{sCell=CellID}: retrieves translated name of the given CellID (used only by some Morrowind localisations, in others cell ID is == cell name) - * #{fontcolour=FontColourName}: retrieves the value of the fallback setting "FontColor_color_" from openmw.cfg, - * in the format "r g b a", float values in range 0-1. Useful for "Colour" and "TextColour" properties in skins. - * #{fontcolourhtml=FontColourName}: retrieves the value of the fallback setting "FontColor_color_" from openmw.cfg, - * in the format "#xxxxxx" where x are hexadecimal numbers. Useful in an EditBox's caption to change the color of following text. - */ - void onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _result); + /** + * Called when MyGUI tries to retrieve a tag's value. Tags must be denoted in #{tag} notation and will be + * replaced upon setting a user visible text/property. Supported syntax: + * #{GMSTName}: retrieves String value of the GMST called GMSTName + * #{setting=CATEGORY_NAME,SETTING_NAME}: retrieves String value of SETTING_NAME under category CATEGORY_NAME + * from settings.cfg + * #{sCell=CellID}: retrieves translated name of the given CellID (used only by some Morrowind localisations, in + * others cell ID is == cell name) + * #{fontcolour=FontColourName}: retrieves the value of the fallback setting "FontColor_color_" + * from openmw.cfg, in the format "r g b a", float values in range 0-1. Useful for "Colour" and "TextColour" + * properties in skins. + * #{fontcolourhtml=FontColourName}: retrieves the value of the fallback setting + * "FontColor_color_" from openmw.cfg, in the format "#xxxxxx" where x are hexadecimal numbers. + * Useful in an EditBox's caption to change the color of following text. + */ + void onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _result); - void onCursorChange(const std::string& name); - void onKeyFocusChanged(MyGUI::Widget* widget); + void onCursorChange(const std::string& name); + void onKeyFocusChanged(MyGUI::Widget* widget); - // Key pressed while playing a video - void onVideoKeyPressed(MyGUI::Widget *_sender, MyGUI::KeyCode _key, MyGUI::Char _char); + // Key pressed while playing a video + void onVideoKeyPressed(MyGUI::Widget* _sender, MyGUI::KeyCode _key, MyGUI::Char _char); - void sizeVideo(int screenWidth, int screenHeight); + void sizeVideo(int screenWidth, int screenHeight); - void onClipboardChanged(const std::string& _type, const std::string& _data); - void onClipboardRequested(const std::string& _type, std::string& _data); + void onClipboardChanged(const std::string& _type, const std::string& _data); + void onClipboardRequested(const std::string& _type, std::string& _data); - void createTextures(); - void createCursors(); - void setMenuTransparency(float value); + void createTextures(); + void createCursors(); + void setMenuTransparency(float value); - void updatePinnedWindows(); + void updatePinnedWindows(); - void enableScene(bool enable); + void enableScene(bool enable); - void handleScheduledMessageBoxes(); + void handleScheduledMessageBoxes(); - void pushGuiMode(GuiMode mode, const MWWorld::Ptr& arg, bool force); + void pushGuiMode(GuiMode mode, const MWWorld::Ptr& arg, bool force); - void setCullMask(uint32_t mask) override; - uint32_t getCullMask() override; - }; + void setCullMask(uint32_t mask) override; + uint32_t getCullMask() override; + }; } #endif diff --git a/apps/openmw/mwgui/windowpinnablebase.cpp b/apps/openmw/mwgui/windowpinnablebase.cpp index 6106d6b563..1b3bd1d2d8 100644 --- a/apps/openmw/mwgui/windowpinnablebase.cpp +++ b/apps/openmw/mwgui/windowpinnablebase.cpp @@ -5,10 +5,11 @@ namespace MWGui { WindowPinnableBase::WindowPinnableBase(const std::string& parLayout) - : WindowBase(parLayout), mPinned(false) + : WindowBase(parLayout) + , mPinned(false) { Window* window = mMainWidget->castType(); - mPinButton = window->getSkinWidget ("Button"); + mPinButton = window->getSkinWidget("Button"); mPinButton->eventMouseButtonPressed += MyGUI::newDelegate(this, &WindowPinnableBase::onPinButtonPressed); } @@ -21,9 +22,9 @@ namespace MWGui mPinned = !mPinned; if (mPinned) - mPinButton->changeWidgetSkin ("PinDown"); + mPinButton->changeWidgetSkin("PinDown"); else - mPinButton->changeWidgetSkin ("PinUp"); + mPinButton->changeWidgetSkin("PinUp"); onPinToggled(); } diff --git a/apps/openmw/mwgui/windowpinnablebase.hpp b/apps/openmw/mwgui/windowpinnablebase.hpp index c91f0a1489..ebb3e2cf05 100644 --- a/apps/openmw/mwgui/windowpinnablebase.hpp +++ b/apps/openmw/mwgui/windowpinnablebase.hpp @@ -5,12 +5,12 @@ namespace MWGui { - class WindowPinnableBase: public WindowBase + class WindowPinnableBase : public WindowBase { public: WindowPinnableBase(const std::string& parLayout); bool pinned() { return mPinned; } - void setPinned (bool pinned); + void setPinned(bool pinned); void setPinButtonVisible(bool visible); private: diff --git a/apps/openmw/mwinput/actionmanager.cpp b/apps/openmw/mwinput/actionmanager.cpp index 610f88cef9..3d712fe228 100644 --- a/apps/openmw/mwinput/actionmanager.cpp +++ b/apps/openmw/mwinput/actionmanager.cpp @@ -6,20 +6,20 @@ #include -#include "../mwbase/inputmanager.hpp" -#include "../mwbase/statemanager.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/inputmanager.hpp" #include "../mwbase/luamanager.hpp" #include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/statemanager.hpp" #include "../mwbase/windowmanager.hpp" #include "../mwbase/world.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/class.hpp" #include "../mwworld/inventorystore.hpp" +#include "../mwworld/player.hpp" -#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/actorutil.hpp" +#include "../mwmechanics/npcstats.hpp" #include "../mwgui/messagebox.hpp" @@ -30,9 +30,8 @@ namespace MWInput { ActionManager::ActionManager(BindingsManager* bindingsManager, - osgViewer::ScreenCaptureHandler::CaptureOperation* screenCaptureOperation, - osg::ref_ptr viewer, - osg::ref_ptr screenCaptureHandler) + osgViewer::ScreenCaptureHandler::CaptureOperation* screenCaptureOperation, + osg::ref_ptr viewer, osg::ref_ptr screenCaptureHandler) : mBindingsManager(bindingsManager) , mViewer(viewer) , mScreenCaptureHandler(screenCaptureHandler) @@ -73,7 +72,7 @@ namespace MWInput { alwaysRunAllowed = true; triedToMove = true; - player.setAutoMove (false); + player.setAutoMove(false); player.setForwardBackward(mBindingsManager->actionIsActive(A_MoveForward) ? 1 : -1); } @@ -81,7 +80,7 @@ namespace MWInput { alwaysRunAllowed = true; triedToMove = true; - player.setForwardBackward (1); + player.setForwardBackward(1); } if (mAttemptJump && MWBase::Environment::get().getInputManager()->getControlSwitch("playerjumping")) @@ -93,17 +92,18 @@ namespace MWInput // if player tried to start moving, but can't (due to being overencumbered), display a notification. if (triedToMove) { - MWWorld::Ptr playerPtr = MWBase::Environment::get().getWorld ()->getPlayerPtr(); + MWWorld::Ptr playerPtr = MWBase::Environment::get().getWorld()->getPlayerPtr(); if (playerPtr.getClass().getEncumbrance(playerPtr) > playerPtr.getClass().getCapacity(playerPtr)) { - player.setAutoMove (false); + player.setAutoMove(false); const auto& msgboxs = MWBase::Environment::get().getWindowManager()->getActiveMessageBoxes(); - auto it = std::find_if(msgboxs.begin(), msgboxs.end(), [](const std::unique_ptr& msgbox) - { - return (msgbox->getMessage() == "#{sNotifyMessage59}"); - }); + auto it = std::find_if( + msgboxs.begin(), msgboxs.end(), [](const std::unique_ptr& msgbox) { + return (msgbox->getMessage() == "#{sNotifyMessage59}"); + }); - // if an overencumbered messagebox is already present, reset its expiry timer, otherwise create new one. + // if an overencumbered messagebox is already present, reset its expiry timer, otherwise create new + // one. if (it != msgboxs.end()) (*it)->mCurrentTime = 0; else @@ -117,7 +117,7 @@ namespace MWInput static const bool isToggleSneak = Settings::Manager::getBool("toggle sneak", "Input"); if (!isToggleSneak) { - if(!MWBase::Environment::get().getInputManager()->joystickLastUsed()) + if (!MWBase::Environment::get().getInputManager()->joystickLastUsed()) player.setSneak(mBindingsManager->actionIsActive(A_Sneak)); } @@ -130,15 +130,11 @@ namespace MWInput player.setRunState(mBindingsManager->actionIsActive(A_Run)); } - if (mBindingsManager->actionIsActive(A_MoveForward) || - mBindingsManager->actionIsActive(A_MoveBackward) || - mBindingsManager->actionIsActive(A_MoveLeft) || - mBindingsManager->actionIsActive(A_MoveRight) || - mBindingsManager->actionIsActive(A_Jump) || - mBindingsManager->actionIsActive(A_Sneak) || - mBindingsManager->actionIsActive(A_TogglePOV) || - mBindingsManager->actionIsActive(A_ZoomIn) || - mBindingsManager->actionIsActive(A_ZoomOut)) + if (mBindingsManager->actionIsActive(A_MoveForward) || mBindingsManager->actionIsActive(A_MoveBackward) + || mBindingsManager->actionIsActive(A_MoveLeft) || mBindingsManager->actionIsActive(A_MoveRight) + || mBindingsManager->actionIsActive(A_Jump) || mBindingsManager->actionIsActive(A_Sneak) + || mBindingsManager->actionIsActive(A_TogglePOV) || mBindingsManager->actionIsActive(A_ZoomIn) + || mBindingsManager->actionIsActive(A_ZoomOut)) { resetIdleTime(); } @@ -155,123 +151,123 @@ namespace MWInput void ActionManager::executeAction(int action) { - MWBase::Environment::get().getLuaManager()->inputEvent({MWBase::LuaManager::InputEvent::Action, action}); + MWBase::Environment::get().getLuaManager()->inputEvent({ MWBase::LuaManager::InputEvent::Action, action }); const auto inputManager = MWBase::Environment::get().getInputManager(); const auto windowManager = MWBase::Environment::get().getWindowManager(); // trigger action activated switch (action) { - case A_GameMenu: - toggleMainMenu (); - break; - case A_Screenshot: - screenshot(); - break; - case A_Inventory: - toggleInventory (); - break; - case A_Console: - toggleConsole (); - break; - case A_Activate: - inputManager->resetIdleTime(); - activate(); - break; - case A_MoveLeft: - case A_MoveRight: - case A_MoveForward: - case A_MoveBackward: - handleGuiArrowKey(action); - break; - case A_Journal: - toggleJournal(); - break; - case A_AutoMove: - toggleAutoMove(); - break; - case A_AlwaysRun: - toggleWalking(); - break; - case A_ToggleWeapon: - toggleWeapon(); - break; - case A_Rest: - rest(); - break; - case A_ToggleSpell: - toggleSpell(); - break; - case A_QuickKey1: - quickKey(1); - break; - case A_QuickKey2: - quickKey(2); - break; - case A_QuickKey3: - quickKey(3); - break; - case A_QuickKey4: - quickKey(4); - break; - case A_QuickKey5: - quickKey(5); - break; - case A_QuickKey6: - quickKey(6); - break; - case A_QuickKey7: - quickKey(7); - break; - case A_QuickKey8: - quickKey(8); - break; - case A_QuickKey9: - quickKey(9); - break; - case A_QuickKey10: - quickKey(10); - break; - case A_QuickKeysMenu: - showQuickKeysMenu(); - break; - case A_ToggleHUD: - windowManager->toggleHud(); - break; - case A_ToggleDebug: - windowManager->toggleDebugWindow(); - break; - case A_TogglePostProcessorHUD: - windowManager->togglePostProcessorHud(); - break; - case A_QuickSave: - quickSave(); - break; - case A_QuickLoad: - quickLoad(); - break; - case A_CycleSpellLeft: - if (checkAllowedToUseItems() && windowManager->isAllowed(MWGui::GW_Magic)) - MWBase::Environment::get().getWindowManager()->cycleSpell(false); - break; - case A_CycleSpellRight: - if (checkAllowedToUseItems() && windowManager->isAllowed(MWGui::GW_Magic)) - MWBase::Environment::get().getWindowManager()->cycleSpell(true); - break; - case A_CycleWeaponLeft: - if (checkAllowedToUseItems() && windowManager->isAllowed(MWGui::GW_Inventory)) - MWBase::Environment::get().getWindowManager()->cycleWeapon(false); - break; - case A_CycleWeaponRight: - if (checkAllowedToUseItems() && windowManager->isAllowed(MWGui::GW_Inventory)) - MWBase::Environment::get().getWindowManager()->cycleWeapon(true); - break; - case A_Sneak: - static const bool isToggleSneak = Settings::Manager::getBool("toggle sneak", "Input"); - if (isToggleSneak) - { - toggleSneaking(); - } - break; + case A_GameMenu: + toggleMainMenu(); + break; + case A_Screenshot: + screenshot(); + break; + case A_Inventory: + toggleInventory(); + break; + case A_Console: + toggleConsole(); + break; + case A_Activate: + inputManager->resetIdleTime(); + activate(); + break; + case A_MoveLeft: + case A_MoveRight: + case A_MoveForward: + case A_MoveBackward: + handleGuiArrowKey(action); + break; + case A_Journal: + toggleJournal(); + break; + case A_AutoMove: + toggleAutoMove(); + break; + case A_AlwaysRun: + toggleWalking(); + break; + case A_ToggleWeapon: + toggleWeapon(); + break; + case A_Rest: + rest(); + break; + case A_ToggleSpell: + toggleSpell(); + break; + case A_QuickKey1: + quickKey(1); + break; + case A_QuickKey2: + quickKey(2); + break; + case A_QuickKey3: + quickKey(3); + break; + case A_QuickKey4: + quickKey(4); + break; + case A_QuickKey5: + quickKey(5); + break; + case A_QuickKey6: + quickKey(6); + break; + case A_QuickKey7: + quickKey(7); + break; + case A_QuickKey8: + quickKey(8); + break; + case A_QuickKey9: + quickKey(9); + break; + case A_QuickKey10: + quickKey(10); + break; + case A_QuickKeysMenu: + showQuickKeysMenu(); + break; + case A_ToggleHUD: + windowManager->toggleHud(); + break; + case A_ToggleDebug: + windowManager->toggleDebugWindow(); + break; + case A_TogglePostProcessorHUD: + windowManager->togglePostProcessorHud(); + break; + case A_QuickSave: + quickSave(); + break; + case A_QuickLoad: + quickLoad(); + break; + case A_CycleSpellLeft: + if (checkAllowedToUseItems() && windowManager->isAllowed(MWGui::GW_Magic)) + MWBase::Environment::get().getWindowManager()->cycleSpell(false); + break; + case A_CycleSpellRight: + if (checkAllowedToUseItems() && windowManager->isAllowed(MWGui::GW_Magic)) + MWBase::Environment::get().getWindowManager()->cycleSpell(true); + break; + case A_CycleWeaponLeft: + if (checkAllowedToUseItems() && windowManager->isAllowed(MWGui::GW_Inventory)) + MWBase::Environment::get().getWindowManager()->cycleWeapon(false); + break; + case A_CycleWeaponRight: + if (checkAllowedToUseItems() && windowManager->isAllowed(MWGui::GW_Inventory)) + MWBase::Environment::get().getWindowManager()->cycleWeapon(true); + break; + case A_Sneak: + static const bool isToggleSneak = Settings::Manager::getBool("toggle sneak", "Input"); + if (isToggleSneak) + { + toggleSneaking(); + } + break; } } @@ -299,11 +295,11 @@ namespace MWInput } else { - osg::ref_ptr screenshot (new osg::Image); + osg::ref_ptr screenshot(new osg::Image); if (MWBase::Environment::get().getWorld()->screenshot360(screenshot.get())) { - (*mScreenCaptureOperation) (*(screenshot.get()), 0); + (*mScreenCaptureOperation)(*(screenshot.get()), 0); // FIXME: mScreenCaptureHandler->getCaptureOperation() causes crash for some reason } } @@ -329,11 +325,11 @@ namespace MWInput return; } - if (!MWBase::Environment::get().getWindowManager()->isGuiMode()) //No open GUIs, open up the MainMenu + if (!MWBase::Environment::get().getWindowManager()->isGuiMode()) // No open GUIs, open up the MainMenu { - MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu); + MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_MainMenu); } - else //Close current GUI + else // Close current GUI { MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode(); } @@ -341,10 +337,12 @@ namespace MWInput void ActionManager::toggleSpell() { - if (MWBase::Environment::get().getWindowManager()->isGuiMode()) return; + if (MWBase::Environment::get().getWindowManager()->isGuiMode()) + return; // Not allowed before the magic window is accessible - if (!MWBase::Environment::get().getInputManager()->getControlSwitch("playermagic") || !MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) + if (!MWBase::Environment::get().getInputManager()->getControlSwitch("playermagic") + || !MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) return; if (!checkAllowedToUseItems()) @@ -353,8 +351,8 @@ namespace MWInput // Not allowed if no spell selected MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); MWWorld::InventoryStore& inventory = player.getPlayer().getClass().getInventoryStore(player.getPlayer()); - if (MWBase::Environment::get().getWindowManager()->getSelectedSpell().empty() && - inventory.getSelectedEnchantItem() == inventory.end()) + if (MWBase::Environment::get().getWindowManager()->getSelectedSpell().empty() + && inventory.getSelectedEnchantItem() == inventory.end()) return; if (MWBase::Environment::get().getMechanicsManager()->isAttackingOrSpell(player.getPlayer())) @@ -381,15 +379,18 @@ namespace MWInput void ActionManager::toggleWeapon() { - if (MWBase::Environment::get().getWindowManager()->isGuiMode()) return; + if (MWBase::Environment::get().getWindowManager()->isGuiMode()) + return; // Not allowed before the inventory window is accessible - if (!MWBase::Environment::get().getInputManager()->getControlSwitch("playerfighting") || !MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) + if (!MWBase::Environment::get().getInputManager()->getControlSwitch("playerfighting") + || !MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) return; MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); // We want to interrupt animation only if attack is preparing, but still is not triggered - // Otherwise we will get a "speedshooting" exploit, when player can skip reload animation by hitting "Toggle Weapon" key twice + // Otherwise we will get a "speedshooting" exploit, when player can skip reload animation by hitting "Toggle + // Weapon" key twice if (MWBase::Environment::get().getMechanicsManager()->isAttackPreparing(player.getPlayer())) player.setAttackingOrSpell(false); else if (MWBase::Environment::get().getMechanicsManager()->isAttackingOrSpell(player.getPlayer())) @@ -407,10 +408,11 @@ namespace MWInput if (!MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) return; - if (!MWBase::Environment::get().getWindowManager()->getRestEnabled() || MWBase::Environment::get().getWindowManager()->isGuiMode()) + if (!MWBase::Environment::get().getWindowManager()->getRestEnabled() + || MWBase::Environment::get().getWindowManager()->isGuiMode()) return; - MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Rest); //Open rest GUI + MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Rest); // Open rest GUI } void ActionManager::toggleInventory() @@ -425,12 +427,12 @@ namespace MWInput return; // Toggle between game mode and inventory mode - if(!MWBase::Environment::get().getWindowManager()->isGuiMode()) + if (!MWBase::Environment::get().getWindowManager()->isGuiMode()) MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Inventory); else { MWGui::GuiMode mode = MWBase::Environment::get().getWindowManager()->getMode(); - if(mode == MWGui::GM_Inventory || mode == MWGui::GM_Container) + if (mode == MWGui::GM_Inventory || mode == MWGui::GM_Container) MWBase::Environment::get().getWindowManager()->popGuiMode(); } @@ -449,14 +451,12 @@ namespace MWInput { if (!MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) return; - if (MyGUI::InputManager::getInstance ().isModalAny()) + if (MyGUI::InputManager::getInstance().isModalAny()) return; MWBase::WindowManager* windowManager = MWBase::Environment::get().getWindowManager(); - if (windowManager->getMode() != MWGui::GM_Journal - && windowManager->getMode() != MWGui::GM_MainMenu - && windowManager->getMode() != MWGui::GM_Settings - && windowManager->getJournalAllowed()) + if (windowManager->getMode() != MWGui::GM_Journal && windowManager->getMode() != MWGui::GM_MainMenu + && windowManager->getMode() != MWGui::GM_Settings && windowManager->getJournalAllowed()) { windowManager->pushGuiMode(MWGui::GM_Journal); } @@ -466,35 +466,37 @@ namespace MWInput } } - void ActionManager::quickKey (int index) + void ActionManager::quickKey(int index) { - if (!MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols") || !MWBase::Environment::get().getInputManager()->getControlSwitch("playerfighting") || !MWBase::Environment::get().getInputManager()->getControlSwitch("playermagic")) + if (!MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols") + || !MWBase::Environment::get().getInputManager()->getControlSwitch("playerfighting") + || !MWBase::Environment::get().getInputManager()->getControlSwitch("playermagic")) return; if (!checkAllowedToUseItems()) return; - if (MWBase::Environment::get().getWorld()->getGlobalFloat ("chargenstate")!=-1) + if (MWBase::Environment::get().getWorld()->getGlobalFloat("chargenstate") != -1) return; if (!MWBase::Environment::get().getWindowManager()->isGuiMode()) - MWBase::Environment::get().getWindowManager()->activateQuickKey (index); + MWBase::Environment::get().getWindowManager()->activateQuickKey(index); } void ActionManager::showQuickKeysMenu() { - if (MWBase::Environment::get().getWindowManager()->getMode () == MWGui::GM_QuickKeysMenu) + if (MWBase::Environment::get().getWindowManager()->getMode() == MWGui::GM_QuickKeysMenu) { MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode(); return; } - if (MWBase::Environment::get().getWorld()->getGlobalFloat ("chargenstate") != -1) + if (MWBase::Environment::get().getWorld()->getGlobalFloat("chargenstate") != -1) return; if (!checkAllowedToUseItems()) return; - MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_QuickKeysMenu); + MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_QuickKeysMenu); } void ActionManager::activate() @@ -514,18 +516,20 @@ namespace MWInput void ActionManager::toggleAutoMove() { - if (MWBase::Environment::get().getWindowManager()->isGuiMode()) return; + if (MWBase::Environment::get().getWindowManager()->isGuiMode()) + return; if (MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) { MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); - player.setAutoMove (!player.getAutoMove()); + player.setAutoMove(!player.getAutoMove()); } } void ActionManager::toggleWalking() { - if (MWBase::Environment::get().getWindowManager()->isGuiMode() || SDL_IsTextInputActive()) return; + if (MWBase::Environment::get().getWindowManager()->isGuiMode() || SDL_IsTextInputActive()) + return; mAlwaysRunActive = !mAlwaysRunActive; Settings::Manager::setBool("always run", "Input", mAlwaysRunActive); @@ -533,8 +537,10 @@ namespace MWInput void ActionManager::toggleSneaking() { - if (MWBase::Environment::get().getWindowManager()->isGuiMode()) return; - if (!MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) return; + if (MWBase::Environment::get().getWindowManager()->isGuiMode()) + return; + if (!MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) + return; mSneaking = !mSneaking; MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); player.setSneak(mSneaking); @@ -557,19 +563,19 @@ namespace MWInput MyGUI::KeyCode key; switch (action) { - case A_MoveLeft: - key = MyGUI::KeyCode::ArrowLeft; - break; - case A_MoveRight: - key = MyGUI::KeyCode::ArrowRight; - break; - case A_MoveForward: - key = MyGUI::KeyCode::ArrowUp; - break; - case A_MoveBackward: - default: - key = MyGUI::KeyCode::ArrowDown; - break; + case A_MoveLeft: + key = MyGUI::KeyCode::ArrowLeft; + break; + case A_MoveRight: + key = MyGUI::KeyCode::ArrowRight; + break; + case A_MoveForward: + key = MyGUI::KeyCode::ArrowUp; + break; + case A_MoveBackward: + default: + key = MyGUI::KeyCode::ArrowDown; + break; } MWBase::Environment::get().getWindowManager()->injectKeyPress(key, 0, false); diff --git a/apps/openmw/mwinput/actionmanager.hpp b/apps/openmw/mwinput/actionmanager.hpp index 4c51139d46..6b8fc1ed6b 100644 --- a/apps/openmw/mwinput/actionmanager.hpp +++ b/apps/openmw/mwinput/actionmanager.hpp @@ -17,11 +17,9 @@ namespace MWInput class ActionManager { public: - ActionManager(BindingsManager* bindingsManager, osgViewer::ScreenCaptureHandler::CaptureOperation* screenCaptureOperation, - osg::ref_ptr viewer, - osg::ref_ptr screenCaptureHandler); + osg::ref_ptr viewer, osg::ref_ptr screenCaptureHandler); void update(float dt, bool triedToMove); @@ -44,7 +42,7 @@ namespace MWInput void quickLoad(); void quickSave(); - void quickKey (int index); + void quickKey(int index); void showQuickKeysMenu(); void resetIdleTime(); diff --git a/apps/openmw/mwinput/actions.hpp b/apps/openmw/mwinput/actions.hpp index c7bdbf28d3..e586a613f7 100644 --- a/apps/openmw/mwinput/actions.hpp +++ b/apps/openmw/mwinput/actions.hpp @@ -11,33 +11,33 @@ namespace MWInput A_Unused, - A_Screenshot, // Take a screenshot + A_Screenshot, // Take a screenshot - A_Inventory, // Toggle inventory screen + A_Inventory, // Toggle inventory screen - A_Console, // Toggle console screen + A_Console, // Toggle console screen - A_MoveLeft, // Move player left / right + A_MoveLeft, // Move player left / right A_MoveRight, - A_MoveForward, // Forward / Backward + A_MoveForward, // Forward / Backward A_MoveBackward, A_Activate, - A_Use, //Use weapon, spell, etc. + A_Use, // Use weapon, spell, etc. A_Jump, - A_AutoMove, //Toggle Auto-move forward - A_Rest, //Rest - A_Journal, //Journal - A_Weapon, //Draw/Sheath weapon - A_Spell, //Ready/Unready Casting - A_Run, //Run when held - A_CycleSpellLeft, //cycling through spells + A_AutoMove, // Toggle Auto-move forward + A_Rest, // Rest + A_Journal, // Journal + A_Weapon, // Draw/Sheath weapon + A_Spell, // Ready/Unready Casting + A_Run, // Run when held + A_CycleSpellLeft, // cycling through spells A_CycleSpellRight, - A_CycleWeaponLeft, //Cycling through weapons + A_CycleWeaponLeft, // Cycling through weapons A_CycleWeaponRight, - A_ToggleSneak, //Toggles Sneak - A_AlwaysRun, //Toggle Walking/Running + A_ToggleSneak, // Toggles Sneak + A_AlwaysRun, // Toggle Walking/Running A_Sneak, A_QuickSave, @@ -65,7 +65,7 @@ namespace MWInput A_ToggleDebug, - A_LookUpDown, //Joystick look + A_LookUpDown, // Joystick look A_LookLeftRight, A_MoveForwardBackward, A_MoveLeftRight, @@ -75,7 +75,7 @@ namespace MWInput A_TogglePostProcessorHUD, - A_Last // Marker for the last item + A_Last // Marker for the last item }; } #endif diff --git a/apps/openmw/mwinput/bindingsmanager.cpp b/apps/openmw/mwinput/bindingsmanager.cpp index c799056f45..609be27ddf 100644 --- a/apps/openmw/mwinput/bindingsmanager.cpp +++ b/apps/openmw/mwinput/bindingsmanager.cpp @@ -5,8 +5,8 @@ #include #include -#include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/inputmanager.hpp" @@ -19,7 +19,8 @@ namespace MWInput { - static const int sFakeDeviceId = 1; //As we only support one controller at a time, use a fake deviceID so we don't lose bindings when switching controllers + static const int sFakeDeviceId = 1; // As we only support one controller at a time, use a fake deviceID so we don't + // lose bindings when switching controllers void clearAllKeyBindings(ICS::InputControlSystem* inputBinder, ICS::Control* control) { @@ -28,7 +29,8 @@ namespace MWInput inputBinder->removeKeyBinding(inputBinder->getKeyBinding(control, ICS::Control::INCREASE)); if (inputBinder->getMouseButtonBinding(control, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS) inputBinder->removeMouseButtonBinding(inputBinder->getMouseButtonBinding(control, ICS::Control::INCREASE)); - if (inputBinder->getMouseWheelBinding(control, ICS::Control::INCREASE) != ICS::InputControlSystem::MouseWheelClick::UNASSIGNED) + if (inputBinder->getMouseWheelBinding(control, ICS::Control::INCREASE) + != ICS::InputControlSystem::MouseWheelClick::UNASSIGNED) inputBinder->removeMouseWheelBinding(inputBinder->getMouseWheelBinding(control, ICS::Control::INCREASE)); } @@ -36,23 +38,24 @@ namespace MWInput { // right now we don't really need multiple bindings for the same action, so remove all others first if (inputBinder->getJoystickAxisBinding(control, sFakeDeviceId, ICS::Control::INCREASE) != SDL_SCANCODE_UNKNOWN) - inputBinder->removeJoystickAxisBinding(sFakeDeviceId, inputBinder->getJoystickAxisBinding(control, sFakeDeviceId, ICS::Control::INCREASE)); - if (inputBinder->getJoystickButtonBinding(control, sFakeDeviceId, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS) - inputBinder->removeJoystickButtonBinding(sFakeDeviceId, inputBinder->getJoystickButtonBinding(control, sFakeDeviceId, ICS::Control::INCREASE)); + inputBinder->removeJoystickAxisBinding( + sFakeDeviceId, inputBinder->getJoystickAxisBinding(control, sFakeDeviceId, ICS::Control::INCREASE)); + if (inputBinder->getJoystickButtonBinding(control, sFakeDeviceId, ICS::Control::INCREASE) + != ICS_MAX_DEVICE_BUTTONS) + inputBinder->removeJoystickButtonBinding( + sFakeDeviceId, inputBinder->getJoystickButtonBinding(control, sFakeDeviceId, ICS::Control::INCREASE)); } class InputControlSystem : public ICS::InputControlSystem { public: - InputControlSystem(const std::filesystem::path &bindingsFile) + InputControlSystem(const std::filesystem::path& bindingsFile) : ICS::InputControlSystem(Files::pathToUnicodeString(bindingsFile), true, nullptr, nullptr, A_Last) { } }; - class BindingsListener : - public ICS::ChannelListener, - public ICS::DetectingBindingListener + class BindingsListener : public ICS::ChannelListener, public ICS::DetectingBindingListener { public: BindingsListener(ICS::InputControlSystem* inputBinder, BindingsManager* bindingsManager) @@ -70,13 +73,13 @@ namespace MWInput mBindingsManager->actionValueChanged(action, currentValue, previousValue); } - void keyBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control - , SDL_Scancode key, ICS::Control::ControlChangingDirection direction) override + void keyBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control, SDL_Scancode key, + ICS::Control::ControlChangingDirection direction) override { - //Disallow binding escape key - if (key==SDL_SCANCODE_ESCAPE) + // Disallow binding escape key + if (key == SDL_SCANCODE_ESCAPE) { - //Stop binding if esc pressed + // Stop binding if esc pressed mInputBinder->cancelDetectingBindingState(); MWBase::Environment::get().getWindowManager()->notifyInputActionBound(); return; @@ -86,11 +89,11 @@ namespace MWInput if (key == SDL_SCANCODE_F3 || key == SDL_SCANCODE_F4 || key == SDL_SCANCODE_F10) return; - #ifndef __APPLE__ +#ifndef __APPLE__ // Disallow binding Windows/Meta keys if (key == SDL_SCANCODE_LGUI || key == SDL_SCANCODE_RGUI) return; - #endif +#endif if (!mDetectingKeyboard) return; @@ -101,15 +104,15 @@ namespace MWInput MWBase::Environment::get().getWindowManager()->notifyInputActionBound(); } - void mouseAxisBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control - , ICS::InputControlSystem::NamedAxis axis, ICS::Control::ControlChangingDirection direction) override + void mouseAxisBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control, + ICS::InputControlSystem::NamedAxis axis, ICS::Control::ControlChangingDirection direction) override { // we don't want mouse movement bindings return; } - void mouseButtonBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control - , unsigned int button, ICS::Control::ControlChangingDirection direction) override + void mouseButtonBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control, unsigned int button, + ICS::Control::ControlChangingDirection direction) override { if (!mDetectingKeyboard) return; @@ -119,8 +122,8 @@ namespace MWInput MWBase::Environment::get().getWindowManager()->notifyInputActionBound(); } - void mouseWheelBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control - , ICS::InputControlSystem::MouseWheelClick click, ICS::Control::ControlChangingDirection direction) override + void mouseWheelBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control, + ICS::InputControlSystem::MouseWheelClick click, ICS::Control::ControlChangingDirection direction) override { if (!mDetectingKeyboard) return; @@ -130,30 +133,30 @@ namespace MWInput MWBase::Environment::get().getWindowManager()->notifyInputActionBound(); } - void joystickAxisBindingDetected(ICS::InputControlSystem* ICS, int deviceID, ICS::Control* control - , int axis, ICS::Control::ControlChangingDirection direction) override + void joystickAxisBindingDetected(ICS::InputControlSystem* ICS, int deviceID, ICS::Control* control, int axis, + ICS::Control::ControlChangingDirection direction) override { - //only allow binding to the trigers + // only allow binding to the trigers if (axis != SDL_CONTROLLER_AXIS_TRIGGERLEFT && axis != SDL_CONTROLLER_AXIS_TRIGGERRIGHT) return; if (mDetectingKeyboard) return; clearAllControllerBindings(mInputBinder, control); - control->setValue(0.5f); //axis bindings must start at 0.5 + control->setValue(0.5f); // axis bindings must start at 0.5 control->setInitialValue(0.5f); ICS::DetectingBindingListener::joystickAxisBindingDetected(ICS, deviceID, control, axis, direction); MWBase::Environment::get().getWindowManager()->notifyInputActionBound(); } - void joystickButtonBindingDetected(ICS::InputControlSystem* ICS, int deviceID, ICS::Control* control - , unsigned int button, ICS::Control::ControlChangingDirection direction) override + void joystickButtonBindingDetected(ICS::InputControlSystem* ICS, int deviceID, ICS::Control* control, + unsigned int button, ICS::Control::ControlChangingDirection direction) override { if (mDetectingKeyboard) return; - clearAllControllerBindings(mInputBinder,control); + clearAllControllerBindings(mInputBinder, control); control->setInitialValue(0.0f); - ICS::DetectingBindingListener::joystickButtonBindingDetected (ICS, deviceID, control, button, direction); + ICS::DetectingBindingListener::joystickButtonBindingDetected(ICS, deviceID, control, button, direction); MWBase::Environment::get().getWindowManager()->notifyInputActionBound(); } @@ -168,7 +171,7 @@ namespace MWInput bool mDetectingKeyboard; }; - BindingsManager::BindingsManager(const std::filesystem::path &userFile, bool userFileExists) + BindingsManager::BindingsManager(const std::filesystem::path& userFile, bool userFileExists) : mUserFile(userFile) , mDragDrop(false) { @@ -204,10 +207,12 @@ namespace MWInput bool BindingsManager::isLeftOrRightButton(int action, bool joystick) const { - int mouseBinding = mInputBinder->getMouseButtonBinding(mInputBinder->getControl(action), ICS::Control::INCREASE); + int mouseBinding + = mInputBinder->getMouseButtonBinding(mInputBinder->getControl(action), ICS::Control::INCREASE); if (mouseBinding != ICS_MAX_DEVICE_BUTTONS) return true; - int buttonBinding = mInputBinder->getJoystickButtonBinding(mInputBinder->getControl(action), sFakeDeviceId, ICS::Control::INCREASE); + int buttonBinding = mInputBinder->getJoystickButtonBinding( + mInputBinder->getControl(action), sFakeDeviceId, ICS::Control::INCREASE); if (joystick && (buttonBinding == 0 || buttonBinding == 1)) return true; return false; @@ -215,13 +220,11 @@ namespace MWInput void BindingsManager::setPlayerControlsEnabled(bool enabled) { - int playerChannels[] = {A_AutoMove, A_AlwaysRun, A_ToggleWeapon, - A_ToggleSpell, A_Rest, A_QuickKey1, A_QuickKey2, - A_QuickKey3, A_QuickKey4, A_QuickKey5, A_QuickKey6, - A_QuickKey7, A_QuickKey8, A_QuickKey9, A_QuickKey10, - A_Use, A_Journal}; + int playerChannels[] = { A_AutoMove, A_AlwaysRun, A_ToggleWeapon, A_ToggleSpell, A_Rest, A_QuickKey1, + A_QuickKey2, A_QuickKey3, A_QuickKey4, A_QuickKey5, A_QuickKey6, A_QuickKey7, A_QuickKey8, A_QuickKey9, + A_QuickKey10, A_Use, A_Journal }; - for(int pc : playerChannels) + for (int pc : playerChannels) { mInputBinder->getChannel(pc)->setEnabled(enabled); } @@ -232,23 +235,23 @@ namespace MWInput mInputBinder->setJoystickDeadZone(deadZone); } - float BindingsManager::getActionValue (int id) const + float BindingsManager::getActionValue(int id) const { return mInputBinder->getChannel(id)->getValue(); } - bool BindingsManager::actionIsActive (int id) const + bool BindingsManager::actionIsActive(int id) const { return getActionValue(id) == 1.0; } - void BindingsManager::loadKeyDefaults (bool force) + void BindingsManager::loadKeyDefaults(bool force) { // using hardcoded key defaults is inevitable, if we want the configuration files to stay valid // across different versions of OpenMW (in the case where another input action is added) std::map defaultKeyBindings; - //Gets the Keyvalue from the Scancode; gives the button in the same place reguardless of keyboard format + // Gets the Keyvalue from the Scancode; gives the button in the same place reguardless of keyboard format defaultKeyBindings[A_Activate] = SDL_SCANCODE_SPACE; defaultKeyBindings[A_MoveBackward] = SDL_SCANCODE_S; defaultKeyBindings[A_MoveForward] = SDL_SCANCODE_W; @@ -312,38 +315,41 @@ namespace MWInput control = mInputBinder->getChannel(i)->getAttachedControls().front().control; } - if (!controlExists || force || - (mInputBinder->getKeyBinding(control, ICS::Control::INCREASE) == SDL_SCANCODE_UNKNOWN - && mInputBinder->getMouseButtonBinding(control, ICS::Control::INCREASE) == ICS_MAX_DEVICE_BUTTONS - && mInputBinder->getMouseWheelBinding(control, ICS::Control::INCREASE) == ICS::InputControlSystem::MouseWheelClick::UNASSIGNED)) + if (!controlExists || force + || (mInputBinder->getKeyBinding(control, ICS::Control::INCREASE) == SDL_SCANCODE_UNKNOWN + && mInputBinder->getMouseButtonBinding(control, ICS::Control::INCREASE) == ICS_MAX_DEVICE_BUTTONS + && mInputBinder->getMouseWheelBinding(control, ICS::Control::INCREASE) + == ICS::InputControlSystem::MouseWheelClick::UNASSIGNED)) { clearAllKeyBindings(mInputBinder.get(), control); if (defaultKeyBindings.find(i) != defaultKeyBindings.end() - && (force || !mInputBinder->isKeyBound(defaultKeyBindings[i]))) + && (force || !mInputBinder->isKeyBound(defaultKeyBindings[i]))) { control->setInitialValue(0.0f); mInputBinder->addKeyBinding(control, defaultKeyBindings[i], ICS::Control::INCREASE); } else if (defaultMouseButtonBindings.find(i) != defaultMouseButtonBindings.end() - && (force || !mInputBinder->isMouseButtonBound(defaultMouseButtonBindings[i]))) + && (force || !mInputBinder->isMouseButtonBound(defaultMouseButtonBindings[i]))) { control->setInitialValue(0.0f); mInputBinder->addMouseButtonBinding(control, defaultMouseButtonBindings[i], ICS::Control::INCREASE); } else if (defaultMouseWheelBindings.find(i) != defaultMouseWheelBindings.end() - && (force || !mInputBinder->isMouseWheelBound(defaultMouseWheelBindings[i]))) + && (force || !mInputBinder->isMouseWheelBound(defaultMouseWheelBindings[i]))) { control->setInitialValue(0.f); mInputBinder->addMouseWheelBinding(control, defaultMouseWheelBindings[i], ICS::Control::INCREASE); } - if (i == A_LookLeftRight && !mInputBinder->isKeyBound(SDL_SCANCODE_KP_4) && !mInputBinder->isKeyBound(SDL_SCANCODE_KP_6)) + if (i == A_LookLeftRight && !mInputBinder->isKeyBound(SDL_SCANCODE_KP_4) + && !mInputBinder->isKeyBound(SDL_SCANCODE_KP_6)) { mInputBinder->addKeyBinding(control, SDL_SCANCODE_KP_6, ICS::Control::INCREASE); mInputBinder->addKeyBinding(control, SDL_SCANCODE_KP_4, ICS::Control::DECREASE); } - if (i == A_LookUpDown && !mInputBinder->isKeyBound(SDL_SCANCODE_KP_8) && !mInputBinder->isKeyBound(SDL_SCANCODE_KP_2)) + if (i == A_LookUpDown && !mInputBinder->isKeyBound(SDL_SCANCODE_KP_8) + && !mInputBinder->isKeyBound(SDL_SCANCODE_KP_2)) { mInputBinder->addKeyBinding(control, SDL_SCANCODE_KP_2, ICS::Control::INCREASE); mInputBinder->addKeyBinding(control, SDL_SCANCODE_KP_8, ICS::Control::DECREASE); @@ -361,7 +367,8 @@ namespace MWInput defaultButtonBindings[A_Activate] = SDL_CONTROLLER_BUTTON_A; defaultButtonBindings[A_ToggleWeapon] = SDL_CONTROLLER_BUTTON_X; defaultButtonBindings[A_ToggleSpell] = SDL_CONTROLLER_BUTTON_Y; - //defaultButtonBindings[A_QuickButtonsMenu] = SDL_GetButtonFromScancode(SDL_SCANCODE_F1); // Need to implement, should be ToggleSpell(5) AND Wait(9) + // defaultButtonBindings[A_QuickButtonsMenu] = SDL_GetButtonFromScancode(SDL_SCANCODE_F1); // Need to implement, + // should be ToggleSpell(5) AND Wait(9) defaultButtonBindings[A_Sneak] = SDL_CONTROLLER_BUTTON_LEFTSTICK; defaultButtonBindings[A_Journal] = SDL_CONTROLLER_BUTTON_LEFTSHOULDER; defaultButtonBindings[A_Rest] = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER; @@ -391,7 +398,8 @@ namespace MWInput float initial; if (defaultAxisBindings.find(i) == defaultAxisBindings.end()) initial = 0.0f; - else initial = 0.5f; + else + initial = 0.5f; control = new ICS::Control(std::to_string(i), false, true, initial, ICS::ICS_MAX, ICS::ICS_MAX); mInputBinder->addControl(control); control->attachChannel(mInputBinder->getChannel(i), ICS::Channel::DIRECT); @@ -401,22 +409,28 @@ namespace MWInput control = mInputBinder->getChannel(i)->getAttachedControls().front().control; } - if (!controlExists || force || (mInputBinder->getJoystickAxisBinding(control, sFakeDeviceId, ICS::Control::INCREASE) == ICS::InputControlSystem::UNASSIGNED && - mInputBinder->getJoystickButtonBinding(control, sFakeDeviceId, ICS::Control::INCREASE) == ICS_MAX_DEVICE_BUTTONS)) + if (!controlExists || force + || (mInputBinder->getJoystickAxisBinding(control, sFakeDeviceId, ICS::Control::INCREASE) + == ICS::InputControlSystem::UNASSIGNED + && mInputBinder->getJoystickButtonBinding(control, sFakeDeviceId, ICS::Control::INCREASE) + == ICS_MAX_DEVICE_BUTTONS)) { clearAllControllerBindings(mInputBinder.get(), control); if (defaultButtonBindings.find(i) != defaultButtonBindings.end() - && (force || !mInputBinder->isJoystickButtonBound(sFakeDeviceId, defaultButtonBindings[i]))) + && (force || !mInputBinder->isJoystickButtonBound(sFakeDeviceId, defaultButtonBindings[i]))) { control->setInitialValue(0.0f); - mInputBinder->addJoystickButtonBinding(control, sFakeDeviceId, defaultButtonBindings[i], ICS::Control::INCREASE); + mInputBinder->addJoystickButtonBinding( + control, sFakeDeviceId, defaultButtonBindings[i], ICS::Control::INCREASE); } - else if (defaultAxisBindings.find(i) != defaultAxisBindings.end() && (force || !mInputBinder->isJoystickAxisBound(sFakeDeviceId, defaultAxisBindings[i]))) + else if (defaultAxisBindings.find(i) != defaultAxisBindings.end() + && (force || !mInputBinder->isJoystickAxisBound(sFakeDeviceId, defaultAxisBindings[i]))) { control->setValue(0.5f); control->setInitialValue(0.5f); - mInputBinder->addJoystickAxisBinding(control, sFakeDeviceId, defaultAxisBindings[i], ICS::Control::INCREASE); + mInputBinder->addJoystickAxisBinding( + control, sFakeDeviceId, defaultAxisBindings[i], ICS::Control::INCREASE); } } } @@ -550,39 +564,36 @@ namespace MWInput ICS::Control* c = mInputBinder->getChannel(action)->getAttachedControls().front().control; - if (mInputBinder->getJoystickAxisBinding(c, sFakeDeviceId, ICS::Control::INCREASE) != ICS::InputControlSystem::UNASSIGNED) - return SDLUtil::sdlControllerAxisToString(mInputBinder->getJoystickAxisBinding(c, sFakeDeviceId, ICS::Control::INCREASE)); - else if (mInputBinder->getJoystickButtonBinding(c, sFakeDeviceId, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS) - return SDLUtil::sdlControllerButtonToString(mInputBinder->getJoystickButtonBinding(c, sFakeDeviceId, ICS::Control::INCREASE)); + if (mInputBinder->getJoystickAxisBinding(c, sFakeDeviceId, ICS::Control::INCREASE) + != ICS::InputControlSystem::UNASSIGNED) + return SDLUtil::sdlControllerAxisToString( + mInputBinder->getJoystickAxisBinding(c, sFakeDeviceId, ICS::Control::INCREASE)); + else if (mInputBinder->getJoystickButtonBinding(c, sFakeDeviceId, ICS::Control::INCREASE) + != ICS_MAX_DEVICE_BUTTONS) + return SDLUtil::sdlControllerButtonToString( + mInputBinder->getJoystickButtonBinding(c, sFakeDeviceId, ICS::Control::INCREASE)); else return "#{sNone}"; } const std::initializer_list& BindingsManager::getActionKeySorting() { - static const std::initializer_list actions - { - A_MoveForward, A_MoveBackward, A_MoveLeft, A_MoveRight, A_TogglePOV, A_ZoomIn, A_ZoomOut, - A_Run, A_AlwaysRun, A_Sneak, A_Activate, A_Use, A_ToggleWeapon, A_ToggleSpell, - A_CycleSpellLeft, A_CycleSpellRight, A_CycleWeaponLeft, A_CycleWeaponRight, A_AutoMove, - A_Jump, A_Inventory, A_Journal, A_Rest, A_Console, A_QuickSave, A_QuickLoad, - A_ToggleHUD, A_Screenshot, A_QuickKeysMenu, A_QuickKey1, A_QuickKey2, A_QuickKey3, - A_QuickKey4, A_QuickKey5, A_QuickKey6, A_QuickKey7, A_QuickKey8, A_QuickKey9, A_QuickKey10, - A_TogglePostProcessorHUD - }; + static const std::initializer_list actions{ A_MoveForward, A_MoveBackward, A_MoveLeft, A_MoveRight, + A_TogglePOV, A_ZoomIn, A_ZoomOut, A_Run, A_AlwaysRun, A_Sneak, A_Activate, A_Use, A_ToggleWeapon, + A_ToggleSpell, A_CycleSpellLeft, A_CycleSpellRight, A_CycleWeaponLeft, A_CycleWeaponRight, A_AutoMove, + A_Jump, A_Inventory, A_Journal, A_Rest, A_Console, A_QuickSave, A_QuickLoad, A_ToggleHUD, A_Screenshot, + A_QuickKeysMenu, A_QuickKey1, A_QuickKey2, A_QuickKey3, A_QuickKey4, A_QuickKey5, A_QuickKey6, A_QuickKey7, + A_QuickKey8, A_QuickKey9, A_QuickKey10, A_TogglePostProcessorHUD }; return actions; } const std::initializer_list& BindingsManager::getActionControllerSorting() { - static const std::initializer_list actions - { - A_TogglePOV, A_ZoomIn, A_ZoomOut, A_Sneak, A_Activate, A_Use, A_ToggleWeapon, A_ToggleSpell, - A_AutoMove, A_Jump, A_Inventory, A_Journal, A_Rest, A_QuickSave, A_QuickLoad, A_ToggleHUD, - A_Screenshot, A_QuickKeysMenu, A_QuickKey1, A_QuickKey2, A_QuickKey3, A_QuickKey4, - A_QuickKey5, A_QuickKey6, A_QuickKey7, A_QuickKey8, A_QuickKey9, A_QuickKey10, - A_CycleSpellLeft, A_CycleSpellRight, A_CycleWeaponLeft, A_CycleWeaponRight - }; + static const std::initializer_list actions{ A_TogglePOV, A_ZoomIn, A_ZoomOut, A_Sneak, A_Activate, A_Use, + A_ToggleWeapon, A_ToggleSpell, A_AutoMove, A_Jump, A_Inventory, A_Journal, A_Rest, A_QuickSave, A_QuickLoad, + A_ToggleHUD, A_Screenshot, A_QuickKeysMenu, A_QuickKey1, A_QuickKey2, A_QuickKey3, A_QuickKey4, A_QuickKey5, + A_QuickKey6, A_QuickKey7, A_QuickKey8, A_QuickKey9, A_QuickKey10, A_CycleSpellLeft, A_CycleSpellRight, + A_CycleWeaponLeft, A_CycleWeaponRight }; return actions; } @@ -599,57 +610,57 @@ namespace MWInput return mInputBinder->detectingBindingState(); } - void BindingsManager::mousePressed(const SDL_MouseButtonEvent &arg, int deviceID) + void BindingsManager::mousePressed(const SDL_MouseButtonEvent& arg, int deviceID) { mInputBinder->mousePressed(arg, deviceID); } - void BindingsManager::mouseReleased(const SDL_MouseButtonEvent &arg, int deviceID) + void BindingsManager::mouseReleased(const SDL_MouseButtonEvent& arg, int deviceID) { mInputBinder->mouseReleased(arg, deviceID); } - void BindingsManager::mouseMoved(const SDLUtil::MouseMotionEvent &arg) + void BindingsManager::mouseMoved(const SDLUtil::MouseMotionEvent& arg) { mInputBinder->mouseMoved(arg); } - void BindingsManager::mouseWheelMoved(const SDL_MouseWheelEvent &arg) + void BindingsManager::mouseWheelMoved(const SDL_MouseWheelEvent& arg) { mInputBinder->mouseWheelMoved(arg); } - void BindingsManager::keyPressed(const SDL_KeyboardEvent &arg) + void BindingsManager::keyPressed(const SDL_KeyboardEvent& arg) { mInputBinder->keyPressed(arg); } - void BindingsManager::keyReleased(const SDL_KeyboardEvent &arg) + void BindingsManager::keyReleased(const SDL_KeyboardEvent& arg) { mInputBinder->keyReleased(arg); } - void BindingsManager::controllerAdded(int deviceID, const SDL_ControllerDeviceEvent &arg) + void BindingsManager::controllerAdded(int deviceID, const SDL_ControllerDeviceEvent& arg) { mInputBinder->controllerAdded(deviceID, arg); } - void BindingsManager::controllerRemoved(const SDL_ControllerDeviceEvent &arg) + void BindingsManager::controllerRemoved(const SDL_ControllerDeviceEvent& arg) { mInputBinder->controllerRemoved(arg); } - void BindingsManager::controllerButtonPressed(int deviceID, const SDL_ControllerButtonEvent &arg) + void BindingsManager::controllerButtonPressed(int deviceID, const SDL_ControllerButtonEvent& arg) { mInputBinder->buttonPressed(deviceID, arg); } - void BindingsManager::controllerButtonReleased(int deviceID, const SDL_ControllerButtonEvent &arg) + void BindingsManager::controllerButtonReleased(int deviceID, const SDL_ControllerButtonEvent& arg) { mInputBinder->buttonReleased(deviceID, arg); } - void BindingsManager::controllerAxisMoved(int deviceID, const SDL_ControllerAxisEvent &arg) + void BindingsManager::controllerAxisMoved(int deviceID, const SDL_ControllerAxisEvent& arg) { mInputBinder->axisMoved(deviceID, arg); } @@ -675,11 +686,11 @@ namespace MWInput if (mDragDrop && action != A_GameMenu && action != A_Inventory) return; - if ((previousValue == 1 || previousValue == 0) && (currentValue==1 || currentValue==0)) + if ((previousValue == 1 || previousValue == 0) && (currentValue == 1 || currentValue == 0)) { - //Is a normal button press, so don't change it at all + // Is a normal button press, so don't change it at all } - //Otherwise only trigger button presses as they go through specific points + // Otherwise only trigger button presses as they go through specific points else if (previousValue >= 0.8 && currentValue < 0.8) { currentValue = 0.0; @@ -692,7 +703,7 @@ namespace MWInput } else { - //If it's not switching between those values, ignore the channel change. + // If it's not switching between those values, ignore the channel change. return; } @@ -723,7 +734,8 @@ namespace MWInput action = A_CycleSpellLeft; else - MWBase::Environment::get().getInputManager()->setAttemptJump(currentValue == 1.0 && previousValue == 0.0); + MWBase::Environment::get().getInputManager()->setAttemptJump( + currentValue == 1.0 && previousValue == 0.0); } } diff --git a/apps/openmw/mwinput/bindingsmanager.hpp b/apps/openmw/mwinput/bindingsmanager.hpp index a3b3825b99..a11baf74de 100644 --- a/apps/openmw/mwinput/bindingsmanager.hpp +++ b/apps/openmw/mwinput/bindingsmanager.hpp @@ -1,10 +1,10 @@ #ifndef MWINPUT_MWBINDINGSMANAGER_H #define MWINPUT_MWBINDINGSMANAGER_H +#include #include #include #include -#include #include @@ -16,17 +16,17 @@ namespace MWInput class BindingsManager { public: - BindingsManager(const std::filesystem::path &userFile, bool userFileExists); + BindingsManager(const std::filesystem::path& userFile, bool userFileExists); virtual ~BindingsManager(); std::string_view getActionDescription(int action); - std::string getActionKeyBindingName (int action); - std::string getActionControllerBindingName (int action); + std::string getActionKeyBindingName(int action); + std::string getActionControllerBindingName(int action); const std::initializer_list& getActionKeySorting(); const std::initializer_list& getActionControllerSorting(); - void enableDetectingBindingMode (int action, bool keyboard); + void enableDetectingBindingMode(int action, bool keyboard); bool isDetectingBindingState() const; void loadKeyDefaults(bool force = false); @@ -43,23 +43,23 @@ namespace MWInput bool isLeftOrRightButton(int action, bool joystick) const; bool actionIsActive(int id) const; - float getActionValue(int id) const; // returns value in range [0, 1] + float getActionValue(int id) const; // returns value in range [0, 1] SDL_GameController* getControllerOrNull() const; - void mousePressed(const SDL_MouseButtonEvent &evt, int deviceID); - void mouseReleased(const SDL_MouseButtonEvent &arg, int deviceID); - void mouseMoved(const SDLUtil::MouseMotionEvent &arg); - void mouseWheelMoved(const SDL_MouseWheelEvent &arg); + void mousePressed(const SDL_MouseButtonEvent& evt, int deviceID); + void mouseReleased(const SDL_MouseButtonEvent& arg, int deviceID); + void mouseMoved(const SDLUtil::MouseMotionEvent& arg); + void mouseWheelMoved(const SDL_MouseWheelEvent& arg); - void keyPressed(const SDL_KeyboardEvent &arg); - void keyReleased(const SDL_KeyboardEvent &arg); + void keyPressed(const SDL_KeyboardEvent& arg); + void keyReleased(const SDL_KeyboardEvent& arg); - void controllerAdded(int deviceID, const SDL_ControllerDeviceEvent &arg); - void controllerRemoved(const SDL_ControllerDeviceEvent &arg); - void controllerButtonPressed(int deviceID, const SDL_ControllerButtonEvent &arg); - void controllerButtonReleased(int deviceID, const SDL_ControllerButtonEvent &arg); - void controllerAxisMoved(int deviceID, const SDL_ControllerAxisEvent &arg); + void controllerAdded(int deviceID, const SDL_ControllerDeviceEvent& arg); + void controllerRemoved(const SDL_ControllerDeviceEvent& arg); + void controllerButtonPressed(int deviceID, const SDL_ControllerButtonEvent& arg); + void controllerButtonReleased(int deviceID, const SDL_ControllerButtonEvent& arg); + void controllerAxisMoved(int deviceID, const SDL_ControllerAxisEvent& arg); SDL_Scancode getKeyBinding(int actionId); diff --git a/apps/openmw/mwinput/controllermanager.cpp b/apps/openmw/mwinput/controllermanager.cpp index d6ed81cd15..61f912aa0d 100644 --- a/apps/openmw/mwinput/controllermanager.cpp +++ b/apps/openmw/mwinput/controllermanager.cpp @@ -6,8 +6,8 @@ #include #include -#include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/inputmanager.hpp" @@ -18,22 +18,20 @@ #include "../mwworld/player.hpp" -#include "actions.hpp" #include "actionmanager.hpp" +#include "actions.hpp" #include "bindingsmanager.hpp" #include "mousemanager.hpp" namespace MWInput { - ControllerManager::ControllerManager(BindingsManager* bindingsManager, - ActionManager* actionManager, - MouseManager* mouseManager, - const std::filesystem::path &userControllerBindingsFile, - const std::filesystem::path &controllerBindingsFile) + ControllerManager::ControllerManager(BindingsManager* bindingsManager, ActionManager* actionManager, + MouseManager* mouseManager, const std::filesystem::path& userControllerBindingsFile, + const std::filesystem::path& controllerBindingsFile) : mBindingsManager(bindingsManager) , mActionManager(actionManager) , mMouseManager(mouseManager) - , mJoystickEnabled (Settings::Manager::getBool("enable controller", "Input")) + , mJoystickEnabled(Settings::Manager::getBool("enable controller", "Input")) , mGyroAvailable(false) , mGamepadCursorSpeed(Settings::Manager::getFloat("gamepad cursor speed", "Input")) , mSneakToggleShortcutTimer(0.f) @@ -135,7 +133,7 @@ namespace MWInput if (yAxis != 0.5) { triedToMove = true; - player.setAutoMove (false); + player.setAutoMove(false); player.setForwardBackward((0.5f - yAxis) * 2); } @@ -183,13 +181,13 @@ namespace MWInput return triedToMove; } - void ControllerManager::buttonPressed(int deviceID, const SDL_ControllerButtonEvent &arg) + void ControllerManager::buttonPressed(int deviceID, const SDL_ControllerButtonEvent& arg) { if (!mJoystickEnabled || mBindingsManager->isDetectingBindingState()) return; MWBase::Environment::get().getLuaManager()->inputEvent( - {MWBase::LuaManager::InputEvent::ControllerPressed, arg.button}); + { MWBase::LuaManager::InputEvent::ControllerPressed, arg.button }); mJoystickLastUsed = true; if (MWBase::Environment::get().getWindowManager()->isGuiMode()) @@ -205,7 +203,8 @@ namespace MWInput bool mousePressSuccess = mMouseManager->injectMouseButtonPress(SDL_BUTTON_LEFT); if (MyGUI::InputManager::getInstance().getMouseFocusWidget()) { - MyGUI::Button* b = MyGUI::InputManager::getInstance().getMouseFocusWidget()->castType(false); + MyGUI::Button* b + = MyGUI::InputManager::getInstance().getMouseFocusWidget()->castType(false); if (b && b->getEnabled()) MWBase::Environment::get().getWindowManager()->playSound("Menu Click"); } @@ -217,7 +216,7 @@ namespace MWInput else mBindingsManager->setPlayerControlsEnabled(true); - //esc, to leave initial movie screen + // esc, to leave initial movie screen auto kc = SDLUtil::sdlKeyToMyGUI(SDLK_ESCAPE); mBindingsManager->setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyPress(kc, 0)); @@ -225,7 +224,7 @@ namespace MWInput mBindingsManager->controllerButtonPressed(deviceID, arg); } - void ControllerManager::buttonReleased(int deviceID, const SDL_ControllerButtonEvent &arg) + void ControllerManager::buttonReleased(int deviceID, const SDL_ControllerButtonEvent& arg) { if (mBindingsManager->isDetectingBindingState()) { @@ -236,7 +235,7 @@ namespace MWInput if (mJoystickEnabled) { MWBase::Environment::get().getLuaManager()->inputEvent( - {MWBase::LuaManager::InputEvent::ControllerReleased, arg.button}); + { MWBase::LuaManager::InputEvent::ControllerReleased, arg.button }); } if (!mJoystickEnabled || MWBase::Environment::get().getInputManager()->controlsDisabled()) @@ -251,7 +250,8 @@ namespace MWInput if (arg.button == SDL_CONTROLLER_BUTTON_A) // We'll pretend that A is left click. { bool mousePressSuccess = mMouseManager->injectMouseButtonRelease(SDL_BUTTON_LEFT); - if (mBindingsManager->isDetectingBindingState()) // If the player just triggered binding, don't let button release bind. + if (mBindingsManager->isDetectingBindingState()) // If the player just triggered binding, don't let + // button release bind. return; mBindingsManager->setPlayerControlsEnabled(!mousePressSuccess); @@ -261,14 +261,14 @@ namespace MWInput else mBindingsManager->setPlayerControlsEnabled(true); - //esc, to leave initial movie screen + // esc, to leave initial movie screen auto kc = SDLUtil::sdlKeyToMyGUI(SDLK_ESCAPE); mBindingsManager->setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyRelease(kc)); mBindingsManager->controllerButtonReleased(deviceID, arg); } - void ControllerManager::axisMoved(int deviceID, const SDL_ControllerAxisEvent &arg) + void ControllerManager::axisMoved(int deviceID, const SDL_ControllerAxisEvent& arg) { if (!mJoystickEnabled || MWBase::Environment::get().getInputManager()->controlsDisabled()) return; @@ -278,8 +278,8 @@ namespace MWInput { gamepadToGuiControl(arg); } - else if (mBindingsManager->actionIsActive(A_TogglePOV) && - (arg.axis == SDL_CONTROLLER_AXIS_TRIGGERRIGHT || arg.axis == SDL_CONTROLLER_AXIS_TRIGGERLEFT)) + else if (mBindingsManager->actionIsActive(A_TogglePOV) + && (arg.axis == SDL_CONTROLLER_AXIS_TRIGGERRIGHT || arg.axis == SDL_CONTROLLER_AXIS_TRIGGERLEFT)) { // Preview Mode Gamepad Zooming; do not propagate to mBindingsManager return; @@ -287,18 +287,18 @@ namespace MWInput mBindingsManager->controllerAxisMoved(deviceID, arg); } - void ControllerManager::controllerAdded(int deviceID, const SDL_ControllerDeviceEvent &arg) + void ControllerManager::controllerAdded(int deviceID, const SDL_ControllerDeviceEvent& arg) { mBindingsManager->controllerAdded(deviceID, arg); enableGyroSensor(); } - void ControllerManager::controllerRemoved(const SDL_ControllerDeviceEvent &arg) + void ControllerManager::controllerRemoved(const SDL_ControllerDeviceEvent& arg) { mBindingsManager->controllerRemoved(arg); } - bool ControllerManager::gamepadToGuiControl(const SDL_ControllerButtonEvent &arg) + bool ControllerManager::gamepadToGuiControl(const SDL_ControllerButtonEvent& arg) { // Presumption of GUI mode will be removed in the future. // MyGUI KeyCodes *may* change. @@ -357,7 +357,7 @@ namespace MWInput return true; } - bool ControllerManager::gamepadToGuiControl(const SDL_ControllerAxisEvent &arg) + bool ControllerManager::gamepadToGuiControl(const SDL_ControllerAxisEvent& arg) { switch (arg.axis) { @@ -406,16 +406,16 @@ namespace MWInput void ControllerManager::enableGyroSensor() { mGyroAvailable = false; - #if SDL_VERSION_ATLEAST(2, 0, 14) - SDL_GameController* cntrl = mBindingsManager->getControllerOrNull(); - if (!cntrl) - return; - if (!SDL_GameControllerHasSensor(cntrl, SDL_SENSOR_GYRO)) - return; - if (SDL_GameControllerSetSensorEnabled(cntrl, SDL_SENSOR_GYRO, SDL_TRUE) < 0) - return; - mGyroAvailable = true; - #endif +#if SDL_VERSION_ATLEAST(2, 0, 14) + SDL_GameController* cntrl = mBindingsManager->getControllerOrNull(); + if (!cntrl) + return; + if (!SDL_GameControllerHasSensor(cntrl, SDL_SENSOR_GYRO)) + return; + if (SDL_GameControllerSetSensorEnabled(cntrl, SDL_SENSOR_GYRO, SDL_TRUE) < 0) + return; + mGyroAvailable = true; +#endif } bool ControllerManager::isGyroAvailable() const @@ -426,29 +426,26 @@ namespace MWInput std::array ControllerManager::getGyroValues() const { float gyro[3] = { 0.f }; - #if SDL_VERSION_ATLEAST(2, 0, 14) - SDL_GameController* cntrl = mBindingsManager->getControllerOrNull(); - if (cntrl && mGyroAvailable) - SDL_GameControllerGetSensorData(cntrl, SDL_SENSOR_GYRO, gyro, 3); - #endif - return std::array({gyro[0], gyro[1], gyro[2]}); +#if SDL_VERSION_ATLEAST(2, 0, 14) + SDL_GameController* cntrl = mBindingsManager->getControllerOrNull(); + if (cntrl && mGyroAvailable) + SDL_GameControllerGetSensorData(cntrl, SDL_SENSOR_GYRO, gyro, 3); +#endif + return std::array({ gyro[0], gyro[1], gyro[2] }); } void ControllerManager::touchpadMoved(int deviceId, const SDLUtil::TouchEvent& arg) { - MWBase::Environment::get().getLuaManager()->inputEvent( - { MWBase::LuaManager::InputEvent::TouchMoved, arg }); + MWBase::Environment::get().getLuaManager()->inputEvent({ MWBase::LuaManager::InputEvent::TouchMoved, arg }); } void ControllerManager::touchpadPressed(int deviceId, const SDLUtil::TouchEvent& arg) { - MWBase::Environment::get().getLuaManager()->inputEvent( - { MWBase::LuaManager::InputEvent::TouchPressed, arg }); + MWBase::Environment::get().getLuaManager()->inputEvent({ MWBase::LuaManager::InputEvent::TouchPressed, arg }); } void ControllerManager::touchpadReleased(int deviceId, const SDLUtil::TouchEvent& arg) { - MWBase::Environment::get().getLuaManager()->inputEvent( - { MWBase::LuaManager::InputEvent::TouchReleased, arg }); + MWBase::Environment::get().getLuaManager()->inputEvent({ MWBase::LuaManager::InputEvent::TouchReleased, arg }); } } diff --git a/apps/openmw/mwinput/controllermanager.hpp b/apps/openmw/mwinput/controllermanager.hpp index ea89c8aec3..cbd279204f 100644 --- a/apps/openmw/mwinput/controllermanager.hpp +++ b/apps/openmw/mwinput/controllermanager.hpp @@ -3,8 +3,8 @@ #include -#include #include +#include #include namespace MWInput @@ -16,21 +16,19 @@ namespace MWInput class ControllerManager : public SDLUtil::ControllerListener { public: - ControllerManager(BindingsManager* bindingsManager, - ActionManager* actionManager, - MouseManager* mouseManager, - const std::filesystem::path &userControllerBindingsFile, - const std::filesystem::path &controllerBindingsFile); + ControllerManager(BindingsManager* bindingsManager, ActionManager* actionManager, MouseManager* mouseManager, + const std::filesystem::path& userControllerBindingsFile, + const std::filesystem::path& controllerBindingsFile); virtual ~ControllerManager() = default; bool update(float dt); - void buttonPressed(int deviceID, const SDL_ControllerButtonEvent &arg) override; - void buttonReleased(int deviceID, const SDL_ControllerButtonEvent &arg) override; - void axisMoved(int deviceID, const SDL_ControllerAxisEvent &arg) override; - void controllerAdded(int deviceID, const SDL_ControllerDeviceEvent &arg) override; - void controllerRemoved(const SDL_ControllerDeviceEvent &arg) override; + void buttonPressed(int deviceID, const SDL_ControllerButtonEvent& arg) override; + void buttonReleased(int deviceID, const SDL_ControllerButtonEvent& arg) override; + void axisMoved(int deviceID, const SDL_ControllerAxisEvent& arg) override; + void controllerAdded(int deviceID, const SDL_ControllerDeviceEvent& arg) override; + void controllerRemoved(const SDL_ControllerDeviceEvent& arg) override; void touchpadMoved(int deviceId, const SDLUtil::TouchEvent& arg) override; void touchpadPressed(int deviceId, const SDLUtil::TouchEvent& arg) override; @@ -46,7 +44,7 @@ namespace MWInput void setGamepadGuiCursorEnabled(bool enabled) { mGamepadGuiCursorEnabled = enabled; } bool gamepadGuiCursorEnabled() const { return mGamepadGuiCursorEnabled; } - float getAxisValue(SDL_GameControllerAxis axis) const; // returns value in range [-1, 1] + float getAxisValue(SDL_GameControllerAxis axis) const; // returns value in range [-1, 1] bool isButtonPressed(SDL_GameControllerButton button) const; bool isGyroAvailable() const; @@ -54,8 +52,8 @@ namespace MWInput private: // Return true if GUI consumes input. - bool gamepadToGuiControl(const SDL_ControllerButtonEvent &arg); - bool gamepadToGuiControl(const SDL_ControllerAxisEvent &arg); + bool gamepadToGuiControl(const SDL_ControllerButtonEvent& arg); + bool gamepadToGuiControl(const SDL_ControllerAxisEvent& arg); void enableGyroSensor(); diff --git a/apps/openmw/mwinput/controlswitch.cpp b/apps/openmw/mwinput/controlswitch.cpp index da8df3ac6b..74fa101e4e 100644 --- a/apps/openmw/mwinput/controlswitch.cpp +++ b/apps/openmw/mwinput/controlswitch.cpp @@ -1,8 +1,8 @@ #include "controlswitch.hpp" -#include -#include #include +#include +#include #include @@ -20,13 +20,13 @@ namespace MWInput void ControlSwitch::clear() { - mSwitches["playercontrols"] = true; - mSwitches["playerfighting"] = true; - mSwitches["playerjumping"] = true; - mSwitches["playerlooking"] = true; - mSwitches["playermagic"] = true; - mSwitches["playerviewswitch"] = true; - mSwitches["vanitymode"] = true; + mSwitches["playercontrols"] = true; + mSwitches["playerfighting"] = true; + mSwitches["playerjumping"] = true; + mSwitches["playerlooking"] = true; + mSwitches["playermagic"] = true; + mSwitches["playerviewswitch"] = true; + mSwitches["vanitymode"] = true; } bool ControlSwitch::get(std::string_view key) @@ -75,9 +75,9 @@ namespace MWInput controls.mWeaponDrawingDisabled = !mSwitches["playerfighting"]; controls.mSpellDrawingDisabled = !mSwitches["playermagic"]; - writer.startRecord (ESM::REC_INPU); + writer.startRecord(ESM::REC_INPU); controls.save(writer); - writer.endRecord (ESM::REC_INPU); + writer.endRecord(ESM::REC_INPU); } void ControlSwitch::readRecord(ESM::ESMReader& reader, uint32_t type) diff --git a/apps/openmw/mwinput/gyromanager.cpp b/apps/openmw/mwinput/gyromanager.cpp index b0c6f121c5..1ffa368729 100644 --- a/apps/openmw/mwinput/gyromanager.cpp +++ b/apps/openmw/mwinput/gyromanager.cpp @@ -1,7 +1,7 @@ #include "gyromanager.hpp" -#include "../mwbase/inputmanager.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/inputmanager.hpp" #include "../mwbase/world.hpp" #include "../mwworld/player.hpp" @@ -33,7 +33,8 @@ namespace MWInput , mInputThreshold(Settings::Manager::getFloat("gyro input threshold", "Input")) , mAxisH(gyroscopeAxisFromString(Settings::Manager::getString("gyro horizontal axis", "Input"))) , mAxisV(gyroscopeAxisFromString(Settings::Manager::getString("gyro vertical axis", "Input"))) - {} + { + } void GyroManager::update(float dt, std::array values) const { diff --git a/apps/openmw/mwinput/gyromanager.hpp b/apps/openmw/mwinput/gyromanager.hpp index bcd3b88f49..c9877945a6 100644 --- a/apps/openmw/mwinput/gyromanager.hpp +++ b/apps/openmw/mwinput/gyromanager.hpp @@ -7,40 +7,40 @@ namespace MWInput { class GyroManager { - public: - GyroManager(); + public: + GyroManager(); - bool isEnabled() const { return mEnabled; } + bool isEnabled() const { return mEnabled; } - void update(float dt, std::array values) const; + void update(float dt, std::array values) const; - void processChangedSettings(const Settings::CategorySettingVector& changed); + void processChangedSettings(const Settings::CategorySettingVector& changed); - void setGuiCursorEnabled(bool enabled) { mGuiCursorEnabled = enabled; } + void setGuiCursorEnabled(bool enabled) { mGuiCursorEnabled = enabled; } - private: - enum GyroscopeAxis - { - Unknown = 0, - X = 1, - Y = 2, - Z = 3, - Minus_X = -1, - Minus_Y = -2, - Minus_Z = -3 - }; + private: + enum GyroscopeAxis + { + Unknown = 0, + X = 1, + Y = 2, + Z = 3, + Minus_X = -1, + Minus_Y = -2, + Minus_Z = -3 + }; - static GyroscopeAxis gyroscopeAxisFromString(std::string_view s); + static GyroscopeAxis gyroscopeAxisFromString(std::string_view s); - bool mEnabled; - bool mGuiCursorEnabled; - float mSensitivityH; - float mSensitivityV; - float mInputThreshold; - GyroscopeAxis mAxisH; - GyroscopeAxis mAxisV; + bool mEnabled; + bool mGuiCursorEnabled; + float mSensitivityH; + float mSensitivityV; + float mInputThreshold; + GyroscopeAxis mAxisH; + GyroscopeAxis mAxisV; - float getAxisValue(GyroscopeAxis axis, std::array values) const; + float getAxisValue(GyroscopeAxis axis, std::array values) const; }; } diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index abe9996e01..e31c0f1318 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -2,12 +2,12 @@ #include -#include -#include #include +#include +#include -#include "../mwbase/windowmanager.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/windowmanager.hpp" #include "../mwbase/world.hpp" #include "../mwworld/esmstore.hpp" @@ -16,28 +16,29 @@ #include "bindingsmanager.hpp" #include "controllermanager.hpp" #include "controlswitch.hpp" +#include "gyromanager.hpp" #include "keyboardmanager.hpp" #include "mousemanager.hpp" #include "sensormanager.hpp" -#include "gyromanager.hpp" namespace MWInput { - InputManager::InputManager( - SDL_Window* window, - osg::ref_ptr viewer, - osg::ref_ptr screenCaptureHandler, - osgViewer::ScreenCaptureHandler::CaptureOperation *screenCaptureOperation, - const std::filesystem::path &userFile, bool userFileExists, const std::filesystem::path &userControllerBindingsFile, - const std::filesystem::path &controllerBindingsFile, bool grab) + InputManager::InputManager(SDL_Window* window, osg::ref_ptr viewer, + osg::ref_ptr screenCaptureHandler, + osgViewer::ScreenCaptureHandler::CaptureOperation* screenCaptureOperation, + const std::filesystem::path& userFile, bool userFileExists, + const std::filesystem::path& userControllerBindingsFile, const std::filesystem::path& controllerBindingsFile, + bool grab) : mControlsDisabled(false) , mInputWrapper(std::make_unique(window, viewer, grab)) , mBindingsManager(std::make_unique(userFile, userFileExists)) , mControlSwitch(std::make_unique()) - , mActionManager(std::make_unique(mBindingsManager.get(), screenCaptureOperation, viewer, screenCaptureHandler)) + , mActionManager(std::make_unique( + mBindingsManager.get(), screenCaptureOperation, viewer, screenCaptureHandler)) , mKeyboardManager(std::make_unique(mBindingsManager.get())) , mMouseManager(std::make_unique(mBindingsManager.get(), mInputWrapper.get(), window)) - , mControllerManager(std::make_unique(mBindingsManager.get(), mActionManager.get(), mMouseManager.get(), userControllerBindingsFile, controllerBindingsFile)) + , mControllerManager(std::make_unique(mBindingsManager.get(), mActionManager.get(), + mMouseManager.get(), userControllerBindingsFile, controllerBindingsFile)) , mSensorManager(std::make_unique()) , mGyroManager(std::make_unique()) { @@ -89,8 +90,8 @@ namespace MWInput bool sensorAvailable = mSensorManager->isGyroAvailable(); if (controllerAvailable || sensorAvailable) { - mGyroManager->update(dt, - controllerAvailable ? mControllerManager->getGyroValues() : mSensorManager->getGyroValues()); + mGyroManager->update( + dt, controllerAvailable ? mControllerManager->getGyroValues() : mSensorManager->getGyroValues()); } } } @@ -114,7 +115,8 @@ namespace MWInput if (guiMode) MWBase::Environment::get().getWindowManager()->showCrosshair(false); - bool isCursorVisible = guiMode && (!mControllerManager->joystickLastUsed() || mControllerManager->gamepadGuiCursorEnabled()); + bool isCursorVisible + = guiMode && (!mControllerManager->joystickLastUsed() || mControllerManager->gamepadGuiCursorEnabled()); MWBase::Environment::get().getWindowManager()->setCursorVisible(isCursorVisible); // if not in gui mode, the camera decides whether to show crosshair or not. } diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index d31aeff51b..f5690f277e 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -6,8 +6,8 @@ #include #include -#include #include +#include #include #include "../mwbase/inputmanager.hpp" @@ -43,26 +43,24 @@ namespace MWInput class GyroManager; /** - * @brief Class that provides a high-level API for game input - */ + * @brief Class that provides a high-level API for game input + */ class InputManager final : public MWBase::InputManager { public: - InputManager( - SDL_Window* window, - osg::ref_ptr viewer, + InputManager(SDL_Window* window, osg::ref_ptr viewer, osg::ref_ptr screenCaptureHandler, - osgViewer::ScreenCaptureHandler::CaptureOperation *screenCaptureOperation, - const std::filesystem::path &userFile, bool userFileExists, - const std::filesystem::path &userControllerBindingsFile, - const std::filesystem::path &controllerBindingsFile, bool grab); + osgViewer::ScreenCaptureHandler::CaptureOperation* screenCaptureOperation, + const std::filesystem::path& userFile, bool userFileExists, + const std::filesystem::path& userControllerBindingsFile, + const std::filesystem::path& controllerBindingsFile, bool grab); ~InputManager() final; /// Clear all savegame-specific data void clear() override; - void update(float dt, bool disableControls, bool disableEvents=false) override; + void update(float dt, bool disableControls, bool disableEvents = false) override; void changeInputMode(bool guiMode) override; @@ -76,8 +74,8 @@ namespace MWInput bool getControlSwitch(std::string_view sw) override; std::string_view getActionDescription(int action) const override; - std::string getActionKeyBindingName (int action) const override; - std::string getActionControllerBindingName (int action) const override; + std::string getActionKeyBindingName(int action) const override; + std::string getActionControllerBindingName(int action) const override; bool actionIsActive(int action) const override; float getActionValue(int action) const override; @@ -89,7 +87,7 @@ namespace MWInput int getNumActions() override { return A_Last; } const std::initializer_list& getActionKeySorting() override; const std::initializer_list& getActionControllerSorting() override; - void enableDetectingBindingMode (int action, bool keyboard) override; + void enableDetectingBindingMode(int action, bool keyboard) override; void resetToDefaultKeyBindings() override; void resetToDefaultControllerBindings() override; diff --git a/apps/openmw/mwinput/keyboardmanager.cpp b/apps/openmw/mwinput/keyboardmanager.cpp index d8fc548f25..97d46c1796 100644 --- a/apps/openmw/mwinput/keyboardmanager.cpp +++ b/apps/openmw/mwinput/keyboardmanager.cpp @@ -23,7 +23,7 @@ namespace MWInput { } - void KeyboardManager::textInput(const SDL_TextInputEvent &arg) + void KeyboardManager::textInput(const SDL_TextInputEvent& arg) { MyGUI::UString ustring(&arg.text[0]); MyGUI::UString::utf32string utf32string = ustring.asUTF32(); @@ -31,21 +31,21 @@ namespace MWInput MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::None, *it); } - void KeyboardManager::keyPressed(const SDL_KeyboardEvent &arg) + void KeyboardManager::keyPressed(const SDL_KeyboardEvent& arg) { // HACK: to make default keybinding for the console work without printing an extra "^" upon closing // This assumes that SDL_TextInput events always come *after* the key event // (which is somewhat reasonable, and hopefully true for all SDL platforms) auto kc = SDLUtil::sdlKeyToMyGUI(arg.keysym.sym); if (mBindingsManager->getKeyBinding(A_Console) == arg.keysym.scancode - && MWBase::Environment::get().getWindowManager()->isConsoleMode()) + && MWBase::Environment::get().getWindowManager()->isConsoleMode()) SDL_StopTextInput(); - bool consumed = SDL_IsTextInputActive() && // Little trick to check if key is printable - (!(SDLK_SCANCODE_MASK & arg.keysym.sym) && - // Don't trust isprint for symbols outside the extended ASCII range - ((kc == MyGUI::KeyCode::None && arg.keysym.sym > 0xff) || - (arg.keysym.sym >= 0 && arg.keysym.sym <= 255 && std::isprint(arg.keysym.sym)))); + bool consumed = SDL_IsTextInputActive() && // Little trick to check if key is printable + (!(SDLK_SCANCODE_MASK & arg.keysym.sym) && + // Don't trust isprint for symbols outside the extended ASCII range + ((kc == MyGUI::KeyCode::None && arg.keysym.sym > 0xff) + || (arg.keysym.sym >= 0 && arg.keysym.sym <= 255 && std::isprint(arg.keysym.sym)))); if (kc != MyGUI::KeyCode::None && !mBindingsManager->isDetectingBindingState()) { if (MWBase::Environment::get().getWindowManager()->injectKeyPress(kc, 0, arg.repeat)) @@ -63,13 +63,13 @@ namespace MWInput if (!consumed) { MWBase::Environment::get().getLuaManager()->inputEvent( - {MWBase::LuaManager::InputEvent::KeyPressed, arg.keysym}); + { MWBase::LuaManager::InputEvent::KeyPressed, arg.keysym }); } input->setJoystickLastUsed(false); } - void KeyboardManager::keyReleased(const SDL_KeyboardEvent &arg) + void KeyboardManager::keyReleased(const SDL_KeyboardEvent& arg) { MWBase::Environment::get().getInputManager()->setJoystickLastUsed(false); auto kc = SDLUtil::sdlKeyToMyGUI(arg.keysym.sym); @@ -77,6 +77,7 @@ namespace MWInput if (!mBindingsManager->isDetectingBindingState()) mBindingsManager->setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyRelease(kc)); mBindingsManager->keyReleased(arg); - MWBase::Environment::get().getLuaManager()->inputEvent({MWBase::LuaManager::InputEvent::KeyReleased, arg.keysym}); + MWBase::Environment::get().getLuaManager()->inputEvent( + { MWBase::LuaManager::InputEvent::KeyReleased, arg.keysym }); } } diff --git a/apps/openmw/mwinput/keyboardmanager.hpp b/apps/openmw/mwinput/keyboardmanager.hpp index ca58461a20..f7b1bbee2b 100644 --- a/apps/openmw/mwinput/keyboardmanager.hpp +++ b/apps/openmw/mwinput/keyboardmanager.hpp @@ -14,9 +14,9 @@ namespace MWInput virtual ~KeyboardManager() = default; - void textInput(const SDL_TextInputEvent &arg) override; - void keyPressed(const SDL_KeyboardEvent &arg) override; - void keyReleased(const SDL_KeyboardEvent &arg) override; + void textInput(const SDL_TextInputEvent& arg) override; + void keyPressed(const SDL_KeyboardEvent& arg) override; + void keyReleased(const SDL_KeyboardEvent& arg) override; private: BindingsManager* mBindingsManager; diff --git a/apps/openmw/mwinput/mousemanager.cpp b/apps/openmw/mwinput/mousemanager.cpp index 26bccc79c4..a8938f07a2 100644 --- a/apps/openmw/mwinput/mousemanager.cpp +++ b/apps/openmw/mwinput/mousemanager.cpp @@ -20,7 +20,8 @@ namespace MWInput { - MouseManager::MouseManager(BindingsManager* bindingsManager, SDLUtil::InputWrapper* inputWrapper, SDL_Window* window) + MouseManager::MouseManager( + BindingsManager* bindingsManager, SDLUtil::InputWrapper* inputWrapper, SDL_Window* window) : mInvertX(Settings::Manager::getBool("invert x axis", "Input")) , mInvertY(Settings::Manager::getBool("invert y axis", "Input")) , mGrabCursor(Settings::Manager::getBool("grab cursor", "Input")) @@ -36,7 +37,7 @@ namespace MWInput , mMouseMoveX(0) , mMouseMoveY(0) { - int w,h; + int w, h; SDL_GetWindowSize(window, &w, &h); float uiScale = MWBase::Environment::get().getWindowManager()->getScalingFactor(); @@ -62,7 +63,7 @@ namespace MWInput } } - void MouseManager::mouseMoved(const SDLUtil::MouseMotionEvent &arg) + void MouseManager::mouseMoved(const SDLUtil::MouseMotionEvent& arg) { mBindingsManager->mouseMoved(arg); @@ -82,9 +83,12 @@ namespace MWInput mMouseWheel = static_cast(arg.z); - MyGUI::InputManager::getInstance().injectMouseMove(static_cast(mGuiCursorX), static_cast(mGuiCursorY), mMouseWheel); - // FIXME: inject twice to force updating focused widget states (tooltips) resulting from changing the viewport by scroll wheel - MyGUI::InputManager::getInstance().injectMouseMove(static_cast(mGuiCursorX), static_cast(mGuiCursorY), mMouseWheel); + MyGUI::InputManager::getInstance().injectMouseMove( + static_cast(mGuiCursorX), static_cast(mGuiCursorY), mMouseWheel); + // FIXME: inject twice to force updating focused widget states (tooltips) resulting from changing the + // viewport by scroll wheel + MyGUI::InputManager::getInstance().injectMouseMove( + static_cast(mGuiCursorX), static_cast(mGuiCursorY), mMouseWheel); MWBase::Environment::get().getWindowManager()->setCursorActive(true); } @@ -113,7 +117,7 @@ namespace MWInput } } - void MouseManager::mouseReleased(const SDL_MouseButtonEvent &arg, Uint8 id) + void MouseManager::mouseReleased(const SDL_MouseButtonEvent& arg, Uint8 id) { MWBase::Environment::get().getInputManager()->setJoystickLastUsed(false); @@ -124,11 +128,9 @@ namespace MWInput else { bool guiMode = MWBase::Environment::get().getWindowManager()->isGuiMode(); - guiMode = MyGUI::InputManager::getInstance().injectMouseRelease( - static_cast(mGuiCursorX), - static_cast(mGuiCursorY), - SDLUtil::sdlMouseButtonToMyGui(id) - ) && guiMode; + guiMode = MyGUI::InputManager::getInstance().injectMouseRelease(static_cast(mGuiCursorX), + static_cast(mGuiCursorY), SDLUtil::sdlMouseButtonToMyGui(id)) + && guiMode; if (mBindingsManager->isDetectingBindingState()) return; // don't allow same mouseup to bind as initiated bind @@ -138,7 +140,7 @@ namespace MWInput } } - void MouseManager::mouseWheelMoved(const SDL_MouseWheelEvent &arg) + void MouseManager::mouseWheelMoved(const SDL_MouseWheelEvent& arg) { MWBase::InputManager* input = MWBase::Environment::get().getInputManager(); if (mBindingsManager->isDetectingBindingState() || !input->controlsDisabled()) @@ -147,7 +149,7 @@ namespace MWInput input->setJoystickLastUsed(false); } - void MouseManager::mousePressed(const SDL_MouseButtonEvent &arg, Uint8 id) + void MouseManager::mousePressed(const SDL_MouseButtonEvent& arg, Uint8 id) { MWBase::InputManager* input = MWBase::Environment::get().getInputManager(); input->setJoystickLastUsed(false); @@ -156,14 +158,13 @@ namespace MWInput if (id == SDL_BUTTON_LEFT || id == SDL_BUTTON_RIGHT) // MyGUI only uses these mouse events { guiMode = MWBase::Environment::get().getWindowManager()->isGuiMode(); - guiMode = MyGUI::InputManager::getInstance().injectMousePress( - static_cast(mGuiCursorX), - static_cast(mGuiCursorY), - SDLUtil::sdlMouseButtonToMyGui(id) - ) && guiMode; - if (MyGUI::InputManager::getInstance().getMouseFocusWidget () != nullptr) + guiMode = MyGUI::InputManager::getInstance().injectMousePress(static_cast(mGuiCursorX), + static_cast(mGuiCursorY), SDLUtil::sdlMouseButtonToMyGui(id)) + && guiMode; + if (MyGUI::InputManager::getInstance().getMouseFocusWidget() != nullptr) { - MyGUI::Button* b = MyGUI::InputManager::getInstance().getMouseFocusWidget()->castType(false); + MyGUI::Button* b + = MyGUI::InputManager::getInstance().getMouseFocusWidget()->castType(false); if (b && b->getEnabled() && id == SDL_BUTTON_LEFT) { MWBase::Environment::get().getWindowManager()->playSound("Menu Click"); @@ -176,14 +177,15 @@ namespace MWInput // Don't trigger any mouse bindings while in settings menu, otherwise rebinding controls becomes impossible // Also do not trigger bindings when input controls are disabled, e.g. during save loading - if (MWBase::Environment::get().getWindowManager()->getMode() != MWGui::GM_Settings && !input->controlsDisabled()) + if (MWBase::Environment::get().getWindowManager()->getMode() != MWGui::GM_Settings + && !input->controlsDisabled()) mBindingsManager->mousePressed(arg, id); } void MouseManager::updateCursorMode() { bool grab = !MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_MainMenu) - && !MWBase::Environment::get().getWindowManager()->isConsoleMode(); + && !MWBase::Environment::get().getWindowManager()->isConsoleMode(); bool wasRelative = mInputWrapper->getMouseRelative(); bool isRelative = !MWBase::Environment::get().getWindowManager()->isGuiMode(); @@ -192,11 +194,11 @@ namespace MWInput // stop using raw mouse motions and switch to system cursor movements mInputWrapper->setMouseRelative(isRelative); - //we let the mouse escape in the main menu + // we let the mouse escape in the main menu mInputWrapper->setGrabPointer(grab && (mGrabCursor || isRelative)); - //we switched to non-relative mode, move our cursor to where the in-game - //cursor is + // we switched to non-relative mode, move our cursor to where the in-game + // cursor is if (!isRelative && wasRelative != isRelative) { warpMouse(); @@ -237,17 +239,13 @@ namespace MWInput bool MouseManager::injectMouseButtonPress(Uint8 button) { return MyGUI::InputManager::getInstance().injectMousePress( - static_cast(mGuiCursorX), - static_cast(mGuiCursorY), - SDLUtil::sdlMouseButtonToMyGui(button)); + static_cast(mGuiCursorX), static_cast(mGuiCursorY), SDLUtil::sdlMouseButtonToMyGui(button)); } bool MouseManager::injectMouseButtonRelease(Uint8 button) { return MyGUI::InputManager::getInstance().injectMouseRelease( - static_cast(mGuiCursorX), - static_cast(mGuiCursorY), - SDLUtil::sdlMouseButtonToMyGui(button)); + static_cast(mGuiCursorX), static_cast(mGuiCursorY), SDLUtil::sdlMouseButtonToMyGui(button)); } void MouseManager::injectMouseMove(float xMove, float yMove, float mouseWheelMove) @@ -260,12 +258,13 @@ namespace MWInput mGuiCursorX = std::clamp(mGuiCursorX, 0.f, viewSize.width - 1); mGuiCursorY = std::clamp(mGuiCursorY, 0.f, viewSize.height - 1); - MyGUI::InputManager::getInstance().injectMouseMove(static_cast(mGuiCursorX), static_cast(mGuiCursorY), static_cast(mMouseWheel)); + MyGUI::InputManager::getInstance().injectMouseMove( + static_cast(mGuiCursorX), static_cast(mGuiCursorY), static_cast(mMouseWheel)); } void MouseManager::warpMouse() { float uiScale = MWBase::Environment::get().getWindowManager()->getScalingFactor(); - mInputWrapper->warpMouse(static_cast(mGuiCursorX*uiScale), static_cast(mGuiCursorY*uiScale)); + mInputWrapper->warpMouse(static_cast(mGuiCursorX * uiScale), static_cast(mGuiCursorY * uiScale)); } } diff --git a/apps/openmw/mwinput/mousemanager.hpp b/apps/openmw/mwinput/mousemanager.hpp index 16ea56d62b..4e8996a99c 100644 --- a/apps/openmw/mwinput/mousemanager.hpp +++ b/apps/openmw/mwinput/mousemanager.hpp @@ -1,8 +1,8 @@ #ifndef MWINPUT_MWMOUSEMANAGER_H #define MWINPUT_MWMOUSEMANAGER_H -#include #include +#include namespace SDLUtil { @@ -23,10 +23,10 @@ namespace MWInput void updateCursorMode(); void update(float dt); - void mouseMoved(const SDLUtil::MouseMotionEvent &arg) override; - void mousePressed(const SDL_MouseButtonEvent &arg, Uint8 id) override; - void mouseReleased(const SDL_MouseButtonEvent &arg, Uint8 id) override; - void mouseWheelMoved(const SDL_MouseWheelEvent &arg) override; + void mouseMoved(const SDLUtil::MouseMotionEvent& arg) override; + void mousePressed(const SDL_MouseButtonEvent& arg, Uint8 id) override; + void mouseReleased(const SDL_MouseButtonEvent& arg, Uint8 id) override; + void mouseWheelMoved(const SDL_MouseWheelEvent& arg) override; void processChangedSettings(const Settings::CategorySettingVector& changed); diff --git a/apps/openmw/mwinput/sensormanager.cpp b/apps/openmw/mwinput/sensormanager.cpp index f3cee579e5..33b493f4d4 100644 --- a/apps/openmw/mwinput/sensormanager.cpp +++ b/apps/openmw/mwinput/sensormanager.cpp @@ -47,7 +47,8 @@ namespace MWInput float angle = 0; - SDL_DisplayOrientation currentOrientation = SDL_GetDisplayOrientation(Settings::Manager::getInt("screen", "Video")); + SDL_DisplayOrientation currentOrientation + = SDL_GetDisplayOrientation(Settings::Manager::getInt("screen", "Video")); switch (currentOrientation) { case SDL_ORIENTATION_UNKNOWN: @@ -84,7 +85,8 @@ namespace MWInput if (SDL_SensorGetDeviceType(i) == SDL_SENSOR_GYRO) { // It is unclear how to handle several enabled gyroscopes, so use the first one. - // Note: Android registers some gyroscope as two separate sensors, for non-wake-up mode and for wake-up mode. + // Note: Android registers some gyroscope as two separate sensors, for non-wake-up mode and for + // wake-up mode. if (mGyroscope != nullptr) { SDL_SensorClose(mGyroscope); @@ -93,9 +95,10 @@ namespace MWInput } // FIXME: SDL2 does not provide a way to configure a sensor update frequency so far. - SDL_Sensor *sensor = SDL_SensorOpen(i); + SDL_Sensor* sensor = SDL_SensorOpen(i); if (sensor == nullptr) - Log(Debug::Error) << "Couldn't open sensor " << SDL_SensorGetDeviceName(i) << ": " << SDL_GetError(); + Log(Debug::Error) + << "Couldn't open sensor " << SDL_SensorGetDeviceName(i) << ": " << SDL_GetError(); else { mGyroscope = sensor; @@ -129,12 +132,12 @@ namespace MWInput correctGyroscopeAxes(); } - void SensorManager::sensorUpdated(const SDL_SensorEvent &arg) + void SensorManager::sensorUpdated(const SDL_SensorEvent& arg) { if (!Settings::Manager::getBool("enable gyroscope", "Input")) return; - SDL_Sensor *sensor = SDL_SensorFromInstanceID(arg.which); + SDL_Sensor* sensor = SDL_SensorFromInstanceID(arg.which); if (!sensor) { Log(Debug::Info) << "Couldn't get sensor for sensor event"; @@ -151,9 +154,9 @@ namespace MWInput mGyroValues = mRotation * gyro; mGyroUpdateTimer = 0.f; break; - } - default: - break; + } + default: + break; } } diff --git a/apps/openmw/mwinput/sensormanager.hpp b/apps/openmw/mwinput/sensormanager.hpp index 8f72b99de9..96d46d6280 100644 --- a/apps/openmw/mwinput/sensormanager.hpp +++ b/apps/openmw/mwinput/sensormanager.hpp @@ -6,8 +6,8 @@ #include #include -#include #include +#include namespace SDLUtil { @@ -32,7 +32,7 @@ namespace MWInput void update(float dt); - void sensorUpdated(const SDL_SensorEvent &arg) override; + void sensorUpdated(const SDL_SensorEvent& arg) override; void displayOrientationChanged() override; void processChangedSettings(const Settings::CategorySettingVector& changed); @@ -40,7 +40,6 @@ namespace MWInput std::array getGyroValues() const; private: - void updateSensors(); void correctGyroscopeAxes(); diff --git a/apps/openmw/mwlua/asyncbindings.cpp b/apps/openmw/mwlua/asyncbindings.cpp index 55f9558fb0..00ca7b75ec 100644 --- a/apps/openmw/mwlua/asyncbindings.cpp +++ b/apps/openmw/mwlua/asyncbindings.cpp @@ -5,10 +5,14 @@ namespace sol { template <> - struct is_automagical : std::false_type {}; + struct is_automagical : std::false_type + { + }; template <> - struct is_automagical : std::false_type {}; + struct is_automagical : std::false_type + { + }; } namespace MWLua @@ -24,48 +28,43 @@ namespace MWLua { using TimerType = LuaUtil::ScriptsContainer::TimerType; sol::usertype api = context.mLua->sol().new_usertype("AsyncPackage"); - api["registerTimerCallback"] = [](const AsyncPackageId& asyncId, std::string_view name, sol::function callback) - { - asyncId.mContainer->registerTimerCallback(asyncId.mScriptId, name, std::move(callback)); - return TimerCallback{asyncId, std::string(name)}; + api["registerTimerCallback"] + = [](const AsyncPackageId& asyncId, std::string_view name, sol::function callback) { + asyncId.mContainer->registerTimerCallback(asyncId.mScriptId, name, std::move(callback)); + return TimerCallback{ asyncId, std::string(name) }; + }; + api["newSimulationTimer"] = [world = context.mWorldView](const AsyncPackageId&, double delay, + const TimerCallback& callback, sol::object callbackArg) { + callback.mAsyncId.mContainer->setupSerializableTimer(TimerType::SIMULATION_TIME, + world->getSimulationTime() + delay, callback.mAsyncId.mScriptId, callback.mName, + std::move(callbackArg)); }; - api["newSimulationTimer"] = [world=context.mWorldView](const AsyncPackageId&, double delay, - const TimerCallback& callback, sol::object callbackArg) - { - callback.mAsyncId.mContainer->setupSerializableTimer( - TimerType::SIMULATION_TIME, world->getSimulationTime() + delay, + api["newGameTimer"] = [world = context.mWorldView](const AsyncPackageId&, double delay, + const TimerCallback& callback, sol::object callbackArg) { + callback.mAsyncId.mContainer->setupSerializableTimer(TimerType::GAME_TIME, world->getGameTime() + delay, callback.mAsyncId.mScriptId, callback.mName, std::move(callbackArg)); }; - api["newGameTimer"] = [world=context.mWorldView](const AsyncPackageId&, double delay, - const TimerCallback& callback, sol::object callbackArg) - { - callback.mAsyncId.mContainer->setupSerializableTimer( - TimerType::GAME_TIME, world->getGameTime() + delay, - callback.mAsyncId.mScriptId, callback.mName, std::move(callbackArg)); - }; - api["newUnsavableSimulationTimer"] = [world=context.mWorldView](const AsyncPackageId& asyncId, double delay, sol::function callback) - { - asyncId.mContainer->setupUnsavableTimer( - TimerType::SIMULATION_TIME, world->getSimulationTime() + delay, asyncId.mScriptId, std::move(callback)); - }; - api["newUnsavableGameTimer"] = [world=context.mWorldView](const AsyncPackageId& asyncId, double delay, sol::function callback) - { - asyncId.mContainer->setupUnsavableTimer( - TimerType::GAME_TIME, world->getGameTime() + delay, asyncId.mScriptId, std::move(callback)); - }; - api["callback"] = [](const AsyncPackageId& asyncId, sol::function fn) -> LuaUtil::Callback - { - return LuaUtil::Callback{std::move(fn), asyncId.mHiddenData}; + api["newUnsavableSimulationTimer"] + = [world = context.mWorldView](const AsyncPackageId& asyncId, double delay, sol::function callback) { + asyncId.mContainer->setupUnsavableTimer(TimerType::SIMULATION_TIME, + world->getSimulationTime() + delay, asyncId.mScriptId, std::move(callback)); + }; + api["newUnsavableGameTimer"] + = [world = context.mWorldView](const AsyncPackageId& asyncId, double delay, sol::function callback) { + asyncId.mContainer->setupUnsavableTimer( + TimerType::GAME_TIME, world->getGameTime() + delay, asyncId.mScriptId, std::move(callback)); + }; + api["callback"] = [](const AsyncPackageId& asyncId, sol::function fn) -> LuaUtil::Callback { + return LuaUtil::Callback{ std::move(fn), asyncId.mHiddenData }; }; sol::usertype callbackType = context.mLua->sol().new_usertype("Callback"); - callbackType[sol::meta_function::call] = - [](const LuaUtil::Callback& callback, sol::variadic_args va) { return callback.call(sol::as_args(va)); }; + callbackType[sol::meta_function::call] + = [](const LuaUtil::Callback& callback, sol::variadic_args va) { return callback.call(sol::as_args(va)); }; - auto initializer = [](sol::table hiddenData) - { + auto initializer = [](sol::table hiddenData) { LuaUtil::ScriptsContainer::ScriptId id = hiddenData[LuaUtil::ScriptsContainer::sScriptIdKey]; - return AsyncPackageId{id.mContainer, id.mIndex, hiddenData}; + return AsyncPackageId{ id.mContainer, id.mIndex, hiddenData }; }; return sol::make_object(context.mLua->sol(), initializer); } diff --git a/apps/openmw/mwlua/camerabindings.cpp b/apps/openmw/mwlua/camerabindings.cpp index 3405654d53..3b13e02936 100644 --- a/apps/openmw/mwlua/camerabindings.cpp +++ b/apps/openmw/mwlua/camerabindings.cpp @@ -3,10 +3,10 @@ #include #include -#include "../mwrender/camera.hpp" -#include "../mwrender/renderingmanager.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwrender/camera.hpp" +#include "../mwrender/renderingmanager.hpp" namespace MWLua { @@ -19,25 +19,19 @@ namespace MWLua MWRender::RenderingManager* renderingManager = MWBase::Environment::get().getWorld()->getRenderingManager(); sol::table api(context.mLua->sol(), sol::create); - api["MODE"] = LuaUtil::makeStrictReadOnly(context.mLua->sol().create_table_with( - "Static", CameraMode::Static, - "FirstPerson", CameraMode::FirstPerson, - "ThirdPerson", CameraMode::ThirdPerson, - "Vanity", CameraMode::Vanity, - "Preview", CameraMode::Preview - )); + api["MODE"] = LuaUtil::makeStrictReadOnly( + context.mLua->sol().create_table_with("Static", CameraMode::Static, "FirstPerson", CameraMode::FirstPerson, + "ThirdPerson", CameraMode::ThirdPerson, "Vanity", CameraMode::Vanity, "Preview", CameraMode::Preview)); api["getMode"] = [camera]() -> int { return static_cast(camera->getMode()); }; - api["getQueuedMode"] = [camera]() -> sol::optional - { + api["getQueuedMode"] = [camera]() -> sol::optional { std::optional mode = camera->getQueuedMode(); if (mode) return static_cast(*mode); else return sol::nullopt; }; - api["setMode"] = [camera](int mode, sol::optional force) - { + api["setMode"] = [camera](int mode, sol::optional force) { camera->setMode(static_cast(mode), force ? *force : false); }; @@ -54,14 +48,12 @@ namespace MWLua api["getRoll"] = [camera]() { return -camera->getRoll(); }; api["setStaticPosition"] = [camera](const osg::Vec3f& pos) { camera->setStaticPosition(pos); }; - api["setPitch"] = [camera](float v) - { + api["setPitch"] = [camera](float v) { camera->setPitch(-v, true); if (camera->getMode() == CameraMode::ThirdPerson) camera->calculateDeferredRotation(); }; - api["setYaw"] = [camera](float v) - { + api["setYaw"] = [camera](float v) { camera->setYaw(-v, true); if (camera->getMode() == CameraMode::ThirdPerson) camera->calculateDeferredRotation(); @@ -89,24 +81,23 @@ namespace MWLua api["getCollisionType"] = [camera]() { return camera->getCollisionType(); }; api["setCollisionType"] = [camera](int collisionType) { camera->setCollisionType(collisionType); }; - api["getBaseFieldOfView"] = []() - { - return osg::DegreesToRadians(std::clamp(Settings::Manager::getFloat("field of view", "Camera"), 1.f, 179.f)); + api["getBaseFieldOfView"] = []() { + return osg::DegreesToRadians( + std::clamp(Settings::Manager::getFloat("field of view", "Camera"), 1.f, 179.f)); }; - api["getFieldOfView"] = [renderingManager]() { return osg::DegreesToRadians(renderingManager->getFieldOfView()); }; - api["setFieldOfView"] = [renderingManager](float v) { renderingManager->setFieldOfView(osg::RadiansToDegrees(v)); }; + api["getFieldOfView"] + = [renderingManager]() { return osg::DegreesToRadians(renderingManager->getFieldOfView()); }; + api["setFieldOfView"] + = [renderingManager](float v) { renderingManager->setFieldOfView(osg::RadiansToDegrees(v)); }; - api["getBaseViewDistance"] = []() - { - return std::max(0.f, Settings::Manager::getFloat("viewing distance", "Camera")); - }; + api["getBaseViewDistance"] + = []() { return std::max(0.f, Settings::Manager::getFloat("viewing distance", "Camera")); }; api["getViewDistance"] = [renderingManager]() { return renderingManager->getViewDistance(); }; api["setViewDistance"] = [renderingManager](float d) { renderingManager->setViewDistance(d, true); }; - api["getViewTransform"] = [camera]() { return LuaUtil::TransformM{camera->getViewMatrix()}; }; + api["getViewTransform"] = [camera]() { return LuaUtil::TransformM{ camera->getViewMatrix() }; }; - api["viewportToWorldVector"] = [camera, renderingManager](osg::Vec2f pos) -> osg::Vec3f - { + api["viewportToWorldVector"] = [camera, renderingManager](osg::Vec2f pos) -> osg::Vec3f { double width = Settings::Manager::getInt("resolution x", "Video"); double height = Settings::Manager::getInt("resolution y", "Video"); double aspect = (height == 0.0) ? 1.0 : width / height; diff --git a/apps/openmw/mwlua/cellbindings.cpp b/apps/openmw/mwlua/cellbindings.cpp index 63ea583a6c..9126021575 100644 --- a/apps/openmw/mwlua/cellbindings.cpp +++ b/apps/openmw/mwlua/cellbindings.cpp @@ -10,9 +10,13 @@ namespace sol { template <> - struct is_automagical : std::false_type {}; + struct is_automagical : std::false_type + { + }; template <> - struct is_automagical : std::false_type {}; + struct is_automagical : std::false_type + { + }; } namespace MWLua @@ -24,8 +28,7 @@ namespace MWLua sol::usertype cellT = context.mLua->sol().new_usertype(prefix + "Cell"); cellT[sol::meta_function::equal_to] = [](const CellT& a, const CellT& b) { return a.mStore == b.mStore; }; - cellT[sol::meta_function::to_string] = [](const CellT& c) - { + cellT[sol::meta_function::to_string] = [](const CellT& c) { const ESM::Cell* cell = c.mStore->getCell(); std::stringstream res; if (cell->isExterior()) @@ -41,28 +44,23 @@ namespace MWLua cellT["gridY"] = sol::readonly_property([](const CellT& c) { return c.mStore->getCell()->getGridY(); }); cellT["hasWater"] = sol::readonly_property([](const CellT& c) { return c.mStore->getCell()->hasWater(); }); cellT["isExterior"] = sol::readonly_property([](const CellT& c) { return c.mStore->isExterior(); }); - cellT["isQuasiExterior"] = sol::readonly_property([](const CellT& c) - { - return (c.mStore->getCell()->mData.mFlags & ESM::Cell::QuasiEx) != 0; - }); + cellT["isQuasiExterior"] = sol::readonly_property( + [](const CellT& c) { return (c.mStore->getCell()->mData.mFlags & ESM::Cell::QuasiEx) != 0; }); - cellT["isInSameSpace"] = [](const CellT& c, const ObjectT& obj) - { + cellT["isInSameSpace"] = [](const CellT& c, const ObjectT& obj) { const MWWorld::Ptr& ptr = obj.ptr(); if (!ptr.isInCell()) return false; MWWorld::CellStore* cell = ptr.getCell(); return cell == c.mStore || (cell->isExterior() && c.mStore->isExterior()); }; - + if constexpr (std::is_same_v) - { // only for global scripts - cellT["getAll"] = [worldView=context.mWorldView, ids=getPackageToTypeTable(context.mLua->sol())]( - const CellT& cell, sol::optional type) - { + { // only for global scripts + cellT["getAll"] = [worldView = context.mWorldView, ids = getPackageToTypeTable(context.mLua->sol())]( + const CellT& cell, sol::optional type) { ObjectIdList res = std::make_shared>(); - auto visitor = [&](const MWWorld::Ptr& ptr) - { + auto visitor = [&](const MWWorld::Ptr& ptr) { worldView->getObjectRegistry()->registerPtr(ptr); if (getLiveCellRefType(ptr.mRef) == ptr.getType()) res->push_back(getId(ptr)); @@ -84,37 +82,73 @@ namespace MWLua switch (*typeId) { case ESM::REC_INTERNAL_PLAYER: - { - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); - if (player.getCell() == cell.mStore) - res->push_back(getId(player)); - } - break; - - case ESM::REC_CREA: cell.mStore->template forEachType(visitor); break; - case ESM::REC_NPC_: cell.mStore->template forEachType(visitor); break; - case ESM::REC_ACTI: cell.mStore->template forEachType(visitor); break; - case ESM::REC_DOOR: cell.mStore->template forEachType(visitor); break; - case ESM::REC_CONT: cell.mStore->template forEachType(visitor); break; - - case ESM::REC_ALCH: cell.mStore->template forEachType(visitor); break; - case ESM::REC_ARMO: cell.mStore->template forEachType(visitor); break; - case ESM::REC_BOOK: cell.mStore->template forEachType(visitor); break; - case ESM::REC_CLOT: cell.mStore->template forEachType(visitor); break; - case ESM::REC_INGR: cell.mStore->template forEachType(visitor); break; - case ESM::REC_LIGH: cell.mStore->template forEachType(visitor); break; - case ESM::REC_MISC: cell.mStore->template forEachType(visitor); break; - case ESM::REC_WEAP: cell.mStore->template forEachType(visitor); break; - case ESM::REC_APPA: cell.mStore->template forEachType(visitor); break; - case ESM::REC_LOCK: cell.mStore->template forEachType(visitor); break; - case ESM::REC_PROB: cell.mStore->template forEachType(visitor); break; - case ESM::REC_REPA: cell.mStore->template forEachType(visitor); break; - default: ok = false; + { + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); + if (player.getCell() == cell.mStore) + res->push_back(getId(player)); + } + break; + + case ESM::REC_CREA: + cell.mStore->template forEachType(visitor); + break; + case ESM::REC_NPC_: + cell.mStore->template forEachType(visitor); + break; + case ESM::REC_ACTI: + cell.mStore->template forEachType(visitor); + break; + case ESM::REC_DOOR: + cell.mStore->template forEachType(visitor); + break; + case ESM::REC_CONT: + cell.mStore->template forEachType(visitor); + break; + + case ESM::REC_ALCH: + cell.mStore->template forEachType(visitor); + break; + case ESM::REC_ARMO: + cell.mStore->template forEachType(visitor); + break; + case ESM::REC_BOOK: + cell.mStore->template forEachType(visitor); + break; + case ESM::REC_CLOT: + cell.mStore->template forEachType(visitor); + break; + case ESM::REC_INGR: + cell.mStore->template forEachType(visitor); + break; + case ESM::REC_LIGH: + cell.mStore->template forEachType(visitor); + break; + case ESM::REC_MISC: + cell.mStore->template forEachType(visitor); + break; + case ESM::REC_WEAP: + cell.mStore->template forEachType(visitor); + break; + case ESM::REC_APPA: + cell.mStore->template forEachType(visitor); + break; + case ESM::REC_LOCK: + cell.mStore->template forEachType(visitor); + break; + case ESM::REC_PROB: + cell.mStore->template forEachType(visitor); + break; + case ESM::REC_REPA: + cell.mStore->template forEachType(visitor); + break; + default: + ok = false; } } if (!ok) - throw std::runtime_error(std::string("Incorrect type argument in cell:getAll: " + LuaUtil::toString(*type))); - return GObjectList{res}; + throw std::runtime_error( + std::string("Incorrect type argument in cell:getAll: " + LuaUtil::toString(*type))); + return GObjectList{ res }; }; } } diff --git a/apps/openmw/mwlua/debugbindings.cpp b/apps/openmw/mwlua/debugbindings.cpp index d51ab1897b..b9b5698254 100644 --- a/apps/openmw/mwlua/debugbindings.cpp +++ b/apps/openmw/mwlua/debugbindings.cpp @@ -4,8 +4,8 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" -#include "../mwrender/renderingmanager.hpp" #include "../mwrender/postprocessor.hpp" +#include "../mwrender/renderingmanager.hpp" #include #include @@ -19,57 +19,56 @@ namespace MWLua { sol::table api = context.mLua->newTable(); - api["RENDER_MODE"] = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs({ - {"CollisionDebug", MWRender::Render_CollisionDebug}, - {"Wireframe", MWRender::Render_Wireframe}, - {"Pathgrid", MWRender::Render_Pathgrid}, - {"Water", MWRender::Render_Water}, - {"Scene", MWRender::Render_Scene}, - {"NavMesh", MWRender::Render_NavMesh}, - {"ActorsPaths", MWRender::Render_ActorsPaths}, - {"RecastMesh", MWRender::Render_RecastMesh}, - })); + api["RENDER_MODE"] + = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs({ + { "CollisionDebug", MWRender::Render_CollisionDebug }, + { "Wireframe", MWRender::Render_Wireframe }, + { "Pathgrid", MWRender::Render_Pathgrid }, + { "Water", MWRender::Render_Water }, + { "Scene", MWRender::Render_Scene }, + { "NavMesh", MWRender::Render_NavMesh }, + { "ActorsPaths", MWRender::Render_ActorsPaths }, + { "RecastMesh", MWRender::Render_RecastMesh }, + })); - api["toggleRenderMode"] = [context] (MWRender::RenderMode value) - { - context.mLuaManager->addAction([value] - { - MWBase::Environment::get().getWorld()->toggleRenderMode(value); - }); + api["toggleRenderMode"] = [context](MWRender::RenderMode value) { + context.mLuaManager->addAction([value] { MWBase::Environment::get().getWorld()->toggleRenderMode(value); }); }; - api["NAV_MESH_RENDER_MODE"] = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs({ - {"AreaType", MWRender::NavMeshMode::AreaType}, - {"UpdateFrequency", MWRender::NavMeshMode::UpdateFrequency}, - })); + api["NAV_MESH_RENDER_MODE"] + = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs({ + { "AreaType", MWRender::NavMeshMode::AreaType }, + { "UpdateFrequency", MWRender::NavMeshMode::UpdateFrequency }, + })); - api["setNavMeshRenderMode"] = [context] (MWRender::NavMeshMode value) - { - context.mLuaManager->addAction([value] - { - MWBase::Environment::get().getWorld()->getRenderingManager()->setNavMeshMode(value); - }); + api["setNavMeshRenderMode"] = [context](MWRender::NavMeshMode value) { + context.mLuaManager->addAction( + [value] { MWBase::Environment::get().getWorld()->getRenderingManager()->setNavMeshMode(value); }); }; - api["triggerShaderReload"] = [context]() - { - context.mLuaManager->addAction([] - { - auto world = MWBase::Environment::get().getWorld(); + api["triggerShaderReload"] = [context]() { + context.mLuaManager->addAction([] { + auto world = MWBase::Environment::get().getWorld(); - world->getRenderingManager()->getResourceSystem()->getSceneManager()->getShaderManager().triggerShaderReload(); - world->getPostProcessor()->triggerShaderReload(); - }); + world->getRenderingManager() + ->getResourceSystem() + ->getSceneManager() + ->getShaderManager() + .triggerShaderReload(); + world->getPostProcessor()->triggerShaderReload(); + }); }; - api["setShaderHotReloadEnabled"] = [context](bool value) - { - context.mLuaManager->addAction([value] - { - auto world = MWBase::Environment::get().getWorld(); - world->getRenderingManager()->getResourceSystem()->getSceneManager()->getShaderManager().setHotReloadEnabled(value); - world->getPostProcessor()->mEnableLiveReload = value; - }); + api["setShaderHotReloadEnabled"] = [context](bool value) { + context.mLuaManager->addAction([value] { + auto world = MWBase::Environment::get().getWorld(); + world->getRenderingManager() + ->getResourceSystem() + ->getSceneManager() + ->getShaderManager() + .setHotReloadEnabled(value); + world->getPostProcessor()->mEnableLiveReload = value; + }); }; return LuaUtil::makeReadOnly(api); diff --git a/apps/openmw/mwlua/eventqueue.cpp b/apps/openmw/mwlua/eventqueue.cpp index 86086f29db..cb952e4e3c 100644 --- a/apps/openmw/mwlua/eventqueue.cpp +++ b/apps/openmw/mwlua/eventqueue.cpp @@ -2,9 +2,9 @@ #include +#include #include #include -#include #include @@ -21,7 +21,7 @@ namespace MWLua } void loadEvents(sol::state& lua, ESM::ESMReader& esm, GlobalEventQueue& globalEvents, LocalEventQueue& localEvents, - const std::map& contentFileMapping, const LuaUtil::UserdataSerializer* serializer) + const std::map& contentFileMapping, const LuaUtil::UserdataSerializer* serializer) { while (esm.isNextSub("LUAE")) { @@ -42,17 +42,17 @@ namespace MWLua auto it = contentFileMapping.find(dest.mContentFile); if (it != contentFileMapping.end()) dest.mContentFile = it->second; - localEvents.push_back({dest, std::move(name), std::move(data)}); + localEvents.push_back({ dest, std::move(name), std::move(data) }); } else - globalEvents.push_back({std::move(name), std::move(data)}); + globalEvents.push_back({ std::move(name), std::move(data) }); } } void saveEvents(ESM::ESMWriter& esm, const GlobalEventQueue& globalEvents, const LocalEventQueue& localEvents) { ObjectId globalId; - globalId.unset(); // Used as a marker of a global event. + globalId.unset(); // Used as a marker of a global event. for (const GlobalEvent& e : globalEvents) saveEvent(esm, globalId, e); diff --git a/apps/openmw/mwlua/eventqueue.hpp b/apps/openmw/mwlua/eventqueue.hpp index 0e5f2dfcb4..273a4c2ad7 100644 --- a/apps/openmw/mwlua/eventqueue.hpp +++ b/apps/openmw/mwlua/eventqueue.hpp @@ -36,7 +36,7 @@ namespace MWLua using LocalEventQueue = std::vector; void loadEvents(sol::state& lua, ESM::ESMReader& esm, GlobalEventQueue&, LocalEventQueue&, - const std::map& contentFileMapping, const LuaUtil::UserdataSerializer* serializer); + const std::map& contentFileMapping, const LuaUtil::UserdataSerializer* serializer); void saveEvents(ESM::ESMWriter& esm, const GlobalEventQueue&, const LocalEventQueue&); } diff --git a/apps/openmw/mwlua/globalscripts.hpp b/apps/openmw/mwlua/globalscripts.hpp index 5f8dc1ecf0..9448d626c9 100644 --- a/apps/openmw/mwlua/globalscripts.hpp +++ b/apps/openmw/mwlua/globalscripts.hpp @@ -16,15 +16,11 @@ namespace MWLua class GlobalScripts : public LuaUtil::ScriptsContainer { public: - GlobalScripts(LuaUtil::LuaState* lua) : LuaUtil::ScriptsContainer(lua, "Global") + GlobalScripts(LuaUtil::LuaState* lua) + : LuaUtil::ScriptsContainer(lua, "Global") { - registerEngineHandlers({ - &mObjectActiveHandlers, - &mActorActiveHandlers, - &mItemActiveHandlers, - &mNewGameHandlers, - &mPlayerAddedHandlers - }); + registerEngineHandlers({ &mObjectActiveHandlers, &mActorActiveHandlers, &mItemActiveHandlers, + &mNewGameHandlers, &mPlayerAddedHandlers }); } void newGameStarted() { callEngineHandlers(mNewGameHandlers); } @@ -34,11 +30,11 @@ namespace MWLua void playerAdded(const GObject& obj) { callEngineHandlers(mPlayerAddedHandlers, obj); } private: - EngineHandlerList mObjectActiveHandlers{"onObjectActive"}; - EngineHandlerList mActorActiveHandlers{"onActorActive"}; - EngineHandlerList mItemActiveHandlers{"onItemActive"}; - EngineHandlerList mNewGameHandlers{"onNewGame"}; - EngineHandlerList mPlayerAddedHandlers{"onPlayerAdded"}; + EngineHandlerList mObjectActiveHandlers{ "onObjectActive" }; + EngineHandlerList mActorActiveHandlers{ "onActorActive" }; + EngineHandlerList mItemActiveHandlers{ "onItemActive" }; + EngineHandlerList mNewGameHandlers{ "onNewGame" }; + EngineHandlerList mPlayerAddedHandlers{ "onPlayerAdded" }; }; } diff --git a/apps/openmw/mwlua/inputbindings.cpp b/apps/openmw/mwlua/inputbindings.cpp index 13155c1aa6..105a107301 100644 --- a/apps/openmw/mwlua/inputbindings.cpp +++ b/apps/openmw/mwlua/inputbindings.cpp @@ -13,7 +13,9 @@ namespace sol { template <> - struct is_automagical : std::false_type {}; + struct is_automagical : std::false_type + { + }; } namespace MWLua @@ -22,8 +24,7 @@ namespace MWLua sol::table initInputPackage(const Context& context) { sol::usertype keyEvent = context.mLua->sol().new_usertype("KeyEvent"); - keyEvent["symbol"] = sol::readonly_property([](const SDL_Keysym& e) - { + keyEvent["symbol"] = sol::readonly_property([](const SDL_Keysym& e) { if (e.sym > 0 && e.sym <= 255) return std::string(1, static_cast(e.sym)); else @@ -36,22 +37,20 @@ namespace MWLua keyEvent["withSuper"] = sol::readonly_property([](const SDL_Keysym& e) -> bool { return e.mod & KMOD_GUI; }); auto touchpadEvent = context.mLua->sol().new_usertype("TouchpadEvent"); - touchpadEvent["device"] = sol::readonly_property( - [](const SDLUtil::TouchEvent& e) -> int { return e.mDevice; }); - touchpadEvent["finger"] = sol::readonly_property( - [](const SDLUtil::TouchEvent& e) -> int { return e.mFinger; }); - touchpadEvent["position"] = sol::readonly_property( - [](const SDLUtil::TouchEvent& e) -> osg::Vec2f { return {e.mX, e.mY};}); - touchpadEvent["pressure"] = sol::readonly_property( - [](const SDLUtil::TouchEvent& e) -> float { return e.mPressure; }); + touchpadEvent["device"] = sol::readonly_property([](const SDLUtil::TouchEvent& e) -> int { return e.mDevice; }); + touchpadEvent["finger"] = sol::readonly_property([](const SDLUtil::TouchEvent& e) -> int { return e.mFinger; }); + touchpadEvent["position"] = sol::readonly_property([](const SDLUtil::TouchEvent& e) -> osg::Vec2f { + return { e.mX, e.mY }; + }); + touchpadEvent["pressure"] + = sol::readonly_property([](const SDLUtil::TouchEvent& e) -> float { return e.mPressure; }); MWBase::InputManager* input = MWBase::Environment::get().getInputManager(); sol::table api(context.mLua->sol(), sol::create); api["isIdle"] = [input]() { return input->isIdle(); }; api["isActionPressed"] = [input](int action) { return input->actionIsActive(action); }; - api["isKeyPressed"] = [](SDL_Scancode code) -> bool - { + api["isKeyPressed"] = [](SDL_Scancode code) -> bool { int maxCode; const auto* state = SDL_GetKeyboardState(&maxCode); if (code >= 0 && code < maxCode) @@ -63,18 +62,14 @@ namespace MWLua api["isCtrlPressed"] = []() -> bool { return SDL_GetModState() & KMOD_CTRL; }; api["isAltPressed"] = []() -> bool { return SDL_GetModState() & KMOD_ALT; }; api["isSuperPressed"] = []() -> bool { return SDL_GetModState() & KMOD_GUI; }; - api["isControllerButtonPressed"] = [input](int button) - { + api["isControllerButtonPressed"] = [input](int button) { return input->isControllerButtonPressed(static_cast(button)); }; - api["isMouseButtonPressed"] = [](int button) -> bool - { - return SDL_GetMouseState(nullptr, nullptr) & SDL_BUTTON(button); - }; + api["isMouseButtonPressed"] + = [](int button) -> bool { return SDL_GetMouseState(nullptr, nullptr) & SDL_BUTTON(button); }; api["getMouseMoveX"] = [input]() { return input->getMouseMoveX(); }; api["getMouseMoveY"] = [input]() { return input->getMouseMoveY(); }; - api["getAxisValue"] = [input](int axis) - { + api["getAxisValue"] = [input](int axis) { if (axis < SDL_CONTROLLER_AXIS_MAX) return input->getControllerAxisValue(static_cast(axis)); else @@ -84,216 +79,216 @@ namespace MWLua api["getControlSwitch"] = [input](std::string_view key) { return input->getControlSwitch(key); }; api["setControlSwitch"] = [input](std::string_view key, bool v) { input->toggleControlSwitch(key, v); }; - api["getKeyName"] = [](SDL_Scancode code) { - return SDL_GetKeyName(SDL_GetKeyFromScancode(code)); - }; + api["getKeyName"] = [](SDL_Scancode code) { return SDL_GetKeyName(SDL_GetKeyFromScancode(code)); }; api["ACTION"] = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs({ - {"GameMenu", MWInput::A_GameMenu}, - {"Screenshot", MWInput::A_Screenshot}, - {"Inventory", MWInput::A_Inventory}, - {"Console", MWInput::A_Console}, + { "GameMenu", MWInput::A_GameMenu }, + { "Screenshot", MWInput::A_Screenshot }, + { "Inventory", MWInput::A_Inventory }, + { "Console", MWInput::A_Console }, - {"MoveLeft", MWInput::A_MoveLeft}, - {"MoveRight", MWInput::A_MoveRight}, - {"MoveForward", MWInput::A_MoveForward}, - {"MoveBackward", MWInput::A_MoveBackward}, + { "MoveLeft", MWInput::A_MoveLeft }, + { "MoveRight", MWInput::A_MoveRight }, + { "MoveForward", MWInput::A_MoveForward }, + { "MoveBackward", MWInput::A_MoveBackward }, - {"Activate", MWInput::A_Activate}, - {"Use", MWInput::A_Use}, - {"Jump", MWInput::A_Jump}, - {"AutoMove", MWInput::A_AutoMove}, - {"Rest", MWInput::A_Rest}, - {"Journal", MWInput::A_Journal}, - {"Weapon", MWInput::A_Weapon}, - {"Spell", MWInput::A_Spell}, - {"Run", MWInput::A_Run}, - {"CycleSpellLeft", MWInput::A_CycleSpellLeft}, - {"CycleSpellRight", MWInput::A_CycleSpellRight}, - {"CycleWeaponLeft", MWInput::A_CycleWeaponLeft}, - {"CycleWeaponRight", MWInput::A_CycleWeaponRight}, - {"ToggleSneak", MWInput::A_ToggleSneak}, - {"AlwaysRun", MWInput::A_AlwaysRun}, - {"Sneak", MWInput::A_Sneak}, + { "Activate", MWInput::A_Activate }, + { "Use", MWInput::A_Use }, + { "Jump", MWInput::A_Jump }, + { "AutoMove", MWInput::A_AutoMove }, + { "Rest", MWInput::A_Rest }, + { "Journal", MWInput::A_Journal }, + { "Weapon", MWInput::A_Weapon }, + { "Spell", MWInput::A_Spell }, + { "Run", MWInput::A_Run }, + { "CycleSpellLeft", MWInput::A_CycleSpellLeft }, + { "CycleSpellRight", MWInput::A_CycleSpellRight }, + { "CycleWeaponLeft", MWInput::A_CycleWeaponLeft }, + { "CycleWeaponRight", MWInput::A_CycleWeaponRight }, + { "ToggleSneak", MWInput::A_ToggleSneak }, + { "AlwaysRun", MWInput::A_AlwaysRun }, + { "Sneak", MWInput::A_Sneak }, - {"QuickSave", MWInput::A_QuickSave}, - {"QuickLoad", MWInput::A_QuickLoad}, - {"QuickMenu", MWInput::A_QuickMenu}, - {"ToggleWeapon", MWInput::A_ToggleWeapon}, - {"ToggleSpell", MWInput::A_ToggleSpell}, - {"TogglePOV", MWInput::A_TogglePOV}, + { "QuickSave", MWInput::A_QuickSave }, + { "QuickLoad", MWInput::A_QuickLoad }, + { "QuickMenu", MWInput::A_QuickMenu }, + { "ToggleWeapon", MWInput::A_ToggleWeapon }, + { "ToggleSpell", MWInput::A_ToggleSpell }, + { "TogglePOV", MWInput::A_TogglePOV }, - {"QuickKey1", MWInput::A_QuickKey1}, - {"QuickKey2", MWInput::A_QuickKey2}, - {"QuickKey3", MWInput::A_QuickKey3}, - {"QuickKey4", MWInput::A_QuickKey4}, - {"QuickKey5", MWInput::A_QuickKey5}, - {"QuickKey6", MWInput::A_QuickKey6}, - {"QuickKey7", MWInput::A_QuickKey7}, - {"QuickKey8", MWInput::A_QuickKey8}, - {"QuickKey9", MWInput::A_QuickKey9}, - {"QuickKey10", MWInput::A_QuickKey10}, - {"QuickKeysMenu", MWInput::A_QuickKeysMenu}, + { "QuickKey1", MWInput::A_QuickKey1 }, + { "QuickKey2", MWInput::A_QuickKey2 }, + { "QuickKey3", MWInput::A_QuickKey3 }, + { "QuickKey4", MWInput::A_QuickKey4 }, + { "QuickKey5", MWInput::A_QuickKey5 }, + { "QuickKey6", MWInput::A_QuickKey6 }, + { "QuickKey7", MWInput::A_QuickKey7 }, + { "QuickKey8", MWInput::A_QuickKey8 }, + { "QuickKey9", MWInput::A_QuickKey9 }, + { "QuickKey10", MWInput::A_QuickKey10 }, + { "QuickKeysMenu", MWInput::A_QuickKeysMenu }, - {"ToggleHUD", MWInput::A_ToggleHUD}, - {"ToggleDebug", MWInput::A_ToggleDebug}, - {"TogglePostProcessorHUD", MWInput::A_TogglePostProcessorHUD}, + { "ToggleHUD", MWInput::A_ToggleHUD }, + { "ToggleDebug", MWInput::A_ToggleDebug }, + { "TogglePostProcessorHUD", MWInput::A_TogglePostProcessorHUD }, - {"ZoomIn", MWInput::A_ZoomIn}, - {"ZoomOut", MWInput::A_ZoomOut}, + { "ZoomIn", MWInput::A_ZoomIn }, + { "ZoomOut", MWInput::A_ZoomOut }, })); - api["CONTROL_SWITCH"] = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs({ - {"Controls", "playercontrols"}, - {"Fighting", "playerfighting"}, - {"Jumping", "playerjumping"}, - {"Looking", "playerlooking"}, - {"Magic", "playermagic"}, - {"ViewMode", "playerviewswitch"}, - {"VanityMode", "vanitymode"}, - })); + api["CONTROL_SWITCH"] + = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs({ + { "Controls", "playercontrols" }, + { "Fighting", "playerfighting" }, + { "Jumping", "playerjumping" }, + { "Looking", "playerlooking" }, + { "Magic", "playermagic" }, + { "ViewMode", "playerviewswitch" }, + { "VanityMode", "vanitymode" }, + })); - api["CONTROLLER_BUTTON"] = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs({ - {"A", SDL_CONTROLLER_BUTTON_A}, - {"B", SDL_CONTROLLER_BUTTON_B}, - {"X", SDL_CONTROLLER_BUTTON_X}, - {"Y", SDL_CONTROLLER_BUTTON_Y}, - {"Back", SDL_CONTROLLER_BUTTON_BACK}, - {"Guide", SDL_CONTROLLER_BUTTON_GUIDE}, - {"Start", SDL_CONTROLLER_BUTTON_START}, - {"LeftStick", SDL_CONTROLLER_BUTTON_LEFTSTICK}, - {"RightStick", SDL_CONTROLLER_BUTTON_RIGHTSTICK}, - {"LeftShoulder", SDL_CONTROLLER_BUTTON_LEFTSHOULDER}, - {"RightShoulder", SDL_CONTROLLER_BUTTON_RIGHTSHOULDER}, - {"DPadUp", SDL_CONTROLLER_BUTTON_DPAD_UP}, - {"DPadDown", SDL_CONTROLLER_BUTTON_DPAD_DOWN}, - {"DPadLeft", SDL_CONTROLLER_BUTTON_DPAD_LEFT}, - {"DPadRight", SDL_CONTROLLER_BUTTON_DPAD_RIGHT}, - })); + api["CONTROLLER_BUTTON"] + = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs({ + { "A", SDL_CONTROLLER_BUTTON_A }, + { "B", SDL_CONTROLLER_BUTTON_B }, + { "X", SDL_CONTROLLER_BUTTON_X }, + { "Y", SDL_CONTROLLER_BUTTON_Y }, + { "Back", SDL_CONTROLLER_BUTTON_BACK }, + { "Guide", SDL_CONTROLLER_BUTTON_GUIDE }, + { "Start", SDL_CONTROLLER_BUTTON_START }, + { "LeftStick", SDL_CONTROLLER_BUTTON_LEFTSTICK }, + { "RightStick", SDL_CONTROLLER_BUTTON_RIGHTSTICK }, + { "LeftShoulder", SDL_CONTROLLER_BUTTON_LEFTSHOULDER }, + { "RightShoulder", SDL_CONTROLLER_BUTTON_RIGHTSHOULDER }, + { "DPadUp", SDL_CONTROLLER_BUTTON_DPAD_UP }, + { "DPadDown", SDL_CONTROLLER_BUTTON_DPAD_DOWN }, + { "DPadLeft", SDL_CONTROLLER_BUTTON_DPAD_LEFT }, + { "DPadRight", SDL_CONTROLLER_BUTTON_DPAD_RIGHT }, + })); api["CONTROLLER_AXIS"] = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs({ - {"LeftX", SDL_CONTROLLER_AXIS_LEFTX}, - {"LeftY", SDL_CONTROLLER_AXIS_LEFTY}, - {"RightX", SDL_CONTROLLER_AXIS_RIGHTX}, - {"RightY", SDL_CONTROLLER_AXIS_RIGHTY}, - {"TriggerLeft", SDL_CONTROLLER_AXIS_TRIGGERLEFT}, - {"TriggerRight", SDL_CONTROLLER_AXIS_TRIGGERRIGHT}, + { "LeftX", SDL_CONTROLLER_AXIS_LEFTX }, + { "LeftY", SDL_CONTROLLER_AXIS_LEFTY }, + { "RightX", SDL_CONTROLLER_AXIS_RIGHTX }, + { "RightY", SDL_CONTROLLER_AXIS_RIGHTY }, + { "TriggerLeft", SDL_CONTROLLER_AXIS_TRIGGERLEFT }, + { "TriggerRight", SDL_CONTROLLER_AXIS_TRIGGERRIGHT }, - {"LookUpDown", SDL_CONTROLLER_AXIS_MAX + static_cast(MWInput::A_LookUpDown)}, - {"LookLeftRight", SDL_CONTROLLER_AXIS_MAX + static_cast(MWInput::A_LookLeftRight)}, - {"MoveForwardBackward", SDL_CONTROLLER_AXIS_MAX + static_cast(MWInput::A_MoveForwardBackward)}, - {"MoveLeftRight", SDL_CONTROLLER_AXIS_MAX + static_cast(MWInput::A_MoveLeftRight)}, + { "LookUpDown", SDL_CONTROLLER_AXIS_MAX + static_cast(MWInput::A_LookUpDown) }, + { "LookLeftRight", SDL_CONTROLLER_AXIS_MAX + static_cast(MWInput::A_LookLeftRight) }, + { "MoveForwardBackward", SDL_CONTROLLER_AXIS_MAX + static_cast(MWInput::A_MoveForwardBackward) }, + { "MoveLeftRight", SDL_CONTROLLER_AXIS_MAX + static_cast(MWInput::A_MoveLeftRight) }, })); api["KEY"] = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs({ - {"_0", SDL_SCANCODE_0}, - {"_1", SDL_SCANCODE_1}, - {"_2", SDL_SCANCODE_2}, - {"_3", SDL_SCANCODE_3}, - {"_4", SDL_SCANCODE_4}, - {"_5", SDL_SCANCODE_5}, - {"_6", SDL_SCANCODE_6}, - {"_7", SDL_SCANCODE_7}, - {"_8", SDL_SCANCODE_8}, - {"_9", SDL_SCANCODE_9}, + { "_0", SDL_SCANCODE_0 }, + { "_1", SDL_SCANCODE_1 }, + { "_2", SDL_SCANCODE_2 }, + { "_3", SDL_SCANCODE_3 }, + { "_4", SDL_SCANCODE_4 }, + { "_5", SDL_SCANCODE_5 }, + { "_6", SDL_SCANCODE_6 }, + { "_7", SDL_SCANCODE_7 }, + { "_8", SDL_SCANCODE_8 }, + { "_9", SDL_SCANCODE_9 }, - {"NP_0", SDL_SCANCODE_KP_0}, - {"NP_1", SDL_SCANCODE_KP_1}, - {"NP_2", SDL_SCANCODE_KP_2}, - {"NP_3", SDL_SCANCODE_KP_3}, - {"NP_4", SDL_SCANCODE_KP_4}, - {"NP_5", SDL_SCANCODE_KP_5}, - {"NP_6", SDL_SCANCODE_KP_6}, - {"NP_7", SDL_SCANCODE_KP_7}, - {"NP_8", SDL_SCANCODE_KP_8}, - {"NP_9", SDL_SCANCODE_KP_9}, - {"NP_Divide", SDL_SCANCODE_KP_DIVIDE}, - {"NP_Enter", SDL_SCANCODE_KP_ENTER}, - {"NP_Minus", SDL_SCANCODE_KP_MINUS}, - {"NP_Multiply", SDL_SCANCODE_KP_MULTIPLY}, - {"NP_Delete", SDL_SCANCODE_KP_PERIOD}, - {"NP_Plus", SDL_SCANCODE_KP_PLUS}, + { "NP_0", SDL_SCANCODE_KP_0 }, + { "NP_1", SDL_SCANCODE_KP_1 }, + { "NP_2", SDL_SCANCODE_KP_2 }, + { "NP_3", SDL_SCANCODE_KP_3 }, + { "NP_4", SDL_SCANCODE_KP_4 }, + { "NP_5", SDL_SCANCODE_KP_5 }, + { "NP_6", SDL_SCANCODE_KP_6 }, + { "NP_7", SDL_SCANCODE_KP_7 }, + { "NP_8", SDL_SCANCODE_KP_8 }, + { "NP_9", SDL_SCANCODE_KP_9 }, + { "NP_Divide", SDL_SCANCODE_KP_DIVIDE }, + { "NP_Enter", SDL_SCANCODE_KP_ENTER }, + { "NP_Minus", SDL_SCANCODE_KP_MINUS }, + { "NP_Multiply", SDL_SCANCODE_KP_MULTIPLY }, + { "NP_Delete", SDL_SCANCODE_KP_PERIOD }, + { "NP_Plus", SDL_SCANCODE_KP_PLUS }, - {"F1", SDL_SCANCODE_F1}, - {"F2", SDL_SCANCODE_F2}, - {"F3", SDL_SCANCODE_F3}, - {"F4", SDL_SCANCODE_F4}, - {"F5", SDL_SCANCODE_F5}, - {"F6", SDL_SCANCODE_F6}, - {"F7", SDL_SCANCODE_F7}, - {"F8", SDL_SCANCODE_F8}, - {"F9", SDL_SCANCODE_F9}, - {"F10", SDL_SCANCODE_F10}, - {"F11", SDL_SCANCODE_F11}, - {"F12", SDL_SCANCODE_F12}, + { "F1", SDL_SCANCODE_F1 }, + { "F2", SDL_SCANCODE_F2 }, + { "F3", SDL_SCANCODE_F3 }, + { "F4", SDL_SCANCODE_F4 }, + { "F5", SDL_SCANCODE_F5 }, + { "F6", SDL_SCANCODE_F6 }, + { "F7", SDL_SCANCODE_F7 }, + { "F8", SDL_SCANCODE_F8 }, + { "F9", SDL_SCANCODE_F9 }, + { "F10", SDL_SCANCODE_F10 }, + { "F11", SDL_SCANCODE_F11 }, + { "F12", SDL_SCANCODE_F12 }, - {"A", SDL_SCANCODE_A}, - {"B", SDL_SCANCODE_B}, - {"C", SDL_SCANCODE_C}, - {"D", SDL_SCANCODE_D}, - {"E", SDL_SCANCODE_E}, - {"F", SDL_SCANCODE_F}, - {"G", SDL_SCANCODE_G}, - {"H", SDL_SCANCODE_H}, - {"I", SDL_SCANCODE_I}, - {"J", SDL_SCANCODE_J}, - {"K", SDL_SCANCODE_K}, - {"L", SDL_SCANCODE_L}, - {"M", SDL_SCANCODE_M}, - {"N", SDL_SCANCODE_N}, - {"O", SDL_SCANCODE_O}, - {"P", SDL_SCANCODE_P}, - {"Q", SDL_SCANCODE_Q}, - {"R", SDL_SCANCODE_R}, - {"S", SDL_SCANCODE_S}, - {"T", SDL_SCANCODE_T}, - {"U", SDL_SCANCODE_U}, - {"V", SDL_SCANCODE_V}, - {"W", SDL_SCANCODE_W}, - {"X", SDL_SCANCODE_X}, - {"Y", SDL_SCANCODE_Y}, - {"Z", SDL_SCANCODE_Z}, + { "A", SDL_SCANCODE_A }, + { "B", SDL_SCANCODE_B }, + { "C", SDL_SCANCODE_C }, + { "D", SDL_SCANCODE_D }, + { "E", SDL_SCANCODE_E }, + { "F", SDL_SCANCODE_F }, + { "G", SDL_SCANCODE_G }, + { "H", SDL_SCANCODE_H }, + { "I", SDL_SCANCODE_I }, + { "J", SDL_SCANCODE_J }, + { "K", SDL_SCANCODE_K }, + { "L", SDL_SCANCODE_L }, + { "M", SDL_SCANCODE_M }, + { "N", SDL_SCANCODE_N }, + { "O", SDL_SCANCODE_O }, + { "P", SDL_SCANCODE_P }, + { "Q", SDL_SCANCODE_Q }, + { "R", SDL_SCANCODE_R }, + { "S", SDL_SCANCODE_S }, + { "T", SDL_SCANCODE_T }, + { "U", SDL_SCANCODE_U }, + { "V", SDL_SCANCODE_V }, + { "W", SDL_SCANCODE_W }, + { "X", SDL_SCANCODE_X }, + { "Y", SDL_SCANCODE_Y }, + { "Z", SDL_SCANCODE_Z }, - {"LeftArrow", SDL_SCANCODE_LEFT}, - {"RightArrow", SDL_SCANCODE_RIGHT}, - {"UpArrow", SDL_SCANCODE_UP}, - {"DownArrow", SDL_SCANCODE_DOWN}, + { "LeftArrow", SDL_SCANCODE_LEFT }, + { "RightArrow", SDL_SCANCODE_RIGHT }, + { "UpArrow", SDL_SCANCODE_UP }, + { "DownArrow", SDL_SCANCODE_DOWN }, - {"LeftAlt", SDL_SCANCODE_LALT}, - {"LeftCtrl", SDL_SCANCODE_LCTRL}, - {"LeftBracket", SDL_SCANCODE_LEFTBRACKET}, - {"LeftSuper", SDL_SCANCODE_LGUI}, - {"LeftShift", SDL_SCANCODE_LSHIFT}, - {"RightAlt", SDL_SCANCODE_RALT}, - {"RightCtrl", SDL_SCANCODE_RCTRL}, - {"RightSuper", SDL_SCANCODE_RGUI}, - {"RightBracket", SDL_SCANCODE_RIGHTBRACKET}, - {"RightShift", SDL_SCANCODE_RSHIFT}, + { "LeftAlt", SDL_SCANCODE_LALT }, + { "LeftCtrl", SDL_SCANCODE_LCTRL }, + { "LeftBracket", SDL_SCANCODE_LEFTBRACKET }, + { "LeftSuper", SDL_SCANCODE_LGUI }, + { "LeftShift", SDL_SCANCODE_LSHIFT }, + { "RightAlt", SDL_SCANCODE_RALT }, + { "RightCtrl", SDL_SCANCODE_RCTRL }, + { "RightSuper", SDL_SCANCODE_RGUI }, + { "RightBracket", SDL_SCANCODE_RIGHTBRACKET }, + { "RightShift", SDL_SCANCODE_RSHIFT }, - {"Apostrophe", SDL_SCANCODE_APOSTROPHE}, - {"BackSlash", SDL_SCANCODE_BACKSLASH}, - {"Backspace", SDL_SCANCODE_BACKSPACE}, - {"CapsLock", SDL_SCANCODE_CAPSLOCK}, - {"Comma", SDL_SCANCODE_COMMA}, - {"Delete", SDL_SCANCODE_DELETE}, - {"End", SDL_SCANCODE_END}, - {"Enter", SDL_SCANCODE_RETURN}, - {"Equals", SDL_SCANCODE_EQUALS}, - {"Escape", SDL_SCANCODE_ESCAPE}, - {"Home", SDL_SCANCODE_HOME}, - {"Insert", SDL_SCANCODE_INSERT}, - {"Minus", SDL_SCANCODE_MINUS}, - {"NumLock", SDL_SCANCODE_NUMLOCKCLEAR}, - {"PageDown", SDL_SCANCODE_PAGEDOWN}, - {"PageUp", SDL_SCANCODE_PAGEUP}, - {"Period", SDL_SCANCODE_PERIOD}, - {"Pause", SDL_SCANCODE_PAUSE}, - {"PrintScreen", SDL_SCANCODE_PRINTSCREEN}, - {"ScrollLock", SDL_SCANCODE_SCROLLLOCK}, - {"Semicolon", SDL_SCANCODE_SEMICOLON}, - {"Slash", SDL_SCANCODE_SLASH}, - {"Space", SDL_SCANCODE_SPACE}, - {"Tab", SDL_SCANCODE_TAB}, + { "Apostrophe", SDL_SCANCODE_APOSTROPHE }, + { "BackSlash", SDL_SCANCODE_BACKSLASH }, + { "Backspace", SDL_SCANCODE_BACKSPACE }, + { "CapsLock", SDL_SCANCODE_CAPSLOCK }, + { "Comma", SDL_SCANCODE_COMMA }, + { "Delete", SDL_SCANCODE_DELETE }, + { "End", SDL_SCANCODE_END }, + { "Enter", SDL_SCANCODE_RETURN }, + { "Equals", SDL_SCANCODE_EQUALS }, + { "Escape", SDL_SCANCODE_ESCAPE }, + { "Home", SDL_SCANCODE_HOME }, + { "Insert", SDL_SCANCODE_INSERT }, + { "Minus", SDL_SCANCODE_MINUS }, + { "NumLock", SDL_SCANCODE_NUMLOCKCLEAR }, + { "PageDown", SDL_SCANCODE_PAGEDOWN }, + { "PageUp", SDL_SCANCODE_PAGEUP }, + { "Period", SDL_SCANCODE_PERIOD }, + { "Pause", SDL_SCANCODE_PAUSE }, + { "PrintScreen", SDL_SCANCODE_PRINTSCREEN }, + { "ScrollLock", SDL_SCANCODE_SCROLLLOCK }, + { "Semicolon", SDL_SCANCODE_SEMICOLON }, + { "Slash", SDL_SCANCODE_SLASH }, + { "Space", SDL_SCANCODE_SPACE }, + { "Tab", SDL_SCANCODE_TAB }, })); return LuaUtil::makeReadOnly(api); diff --git a/apps/openmw/mwlua/localscripts.cpp b/apps/openmw/mwlua/localscripts.cpp index 9c925b44a5..1cd1b2359e 100644 --- a/apps/openmw/mwlua/localscripts.cpp +++ b/apps/openmw/mwlua/localscripts.cpp @@ -2,17 +2,17 @@ #include -#include "../mwworld/ptr.hpp" -#include "../mwworld/class.hpp" -#include "../mwmechanics/aisequence.hpp" #include "../mwmechanics/aicombat.hpp" #include "../mwmechanics/aiescort.hpp" #include "../mwmechanics/aifollow.hpp" +#include "../mwmechanics/aipackage.hpp" #include "../mwmechanics/aipursue.hpp" +#include "../mwmechanics/aisequence.hpp" #include "../mwmechanics/aitravel.hpp" #include "../mwmechanics/aiwander.hpp" -#include "../mwmechanics/aipackage.hpp" #include "../mwmechanics/creaturestats.hpp" +#include "../mwworld/class.hpp" +#include "../mwworld/ptr.hpp" #include "context.hpp" #include "worldview.hpp" @@ -20,9 +20,13 @@ namespace sol { template <> - struct is_automagical : std::false_type {}; + struct is_automagical : std::false_type + { + }; template <> - struct is_automagical : std::false_type {}; + struct is_automagical : std::false_type + { + }; } namespace MWLua @@ -33,8 +37,12 @@ namespace MWLua using ActorControls = MWBase::LuaManager::ActorControls; sol::usertype controls = context.mLua->sol().new_usertype("ActorControls"); -#define CONTROL(TYPE, FIELD) sol::property([](const ActorControls& c) { return c.FIELD; },\ - [](ActorControls& c, const TYPE& v) { c.FIELD = v; c.mChanged = true; }) +#define CONTROL(TYPE, FIELD) \ + sol::property([](const ActorControls& c) { return c.FIELD; }, \ + [](ActorControls& c, const TYPE& v) { \ + c.FIELD = v; \ + c.mChanged = true; \ + }) controls["movement"] = CONTROL(float, mMovement); controls["sideMovement"] = CONTROL(float, mSideMovement); controls["pitchChange"] = CONTROL(float, mPitchChange); @@ -44,9 +52,10 @@ namespace MWLua controls["use"] = CONTROL(int, mUse); #undef CONTROL - sol::usertype selfAPI = - context.mLua->sol().new_usertype("SelfObject", sol::base_classes, sol::bases()); - selfAPI[sol::meta_function::to_string] = [](SelfObject& self) { return "openmw.self[" + self.toString() + "]"; }; + sol::usertype selfAPI = context.mLua->sol().new_usertype( + "SelfObject", sol::base_classes, sol::bases()); + selfAPI[sol::meta_function::to_string] + = [](SelfObject& self) { return "openmw.self[" + self.toString() + "]"; }; selfAPI["object"] = sol::readonly_property([](SelfObject& self) -> LObject { return LObject(self); }); selfAPI["controls"] = sol::readonly_property([](SelfObject& self) { return &self.mControls; }); selfAPI["isActive"] = [](SelfObject& self) { return &self.mIsActive; }; @@ -54,37 +63,47 @@ namespace MWLua using AiPackage = MWMechanics::AiPackage; sol::usertype aiPackage = context.mLua->sol().new_usertype("AiPackage"); - aiPackage["type"] = sol::readonly_property([](const AiPackage& p) -> std::string_view - { + aiPackage["type"] = sol::readonly_property([](const AiPackage& p) -> std::string_view { switch (p.getTypeId()) { - case MWMechanics::AiPackageTypeId::Wander: return "Wander"; - case MWMechanics::AiPackageTypeId::Travel: return "Travel"; - case MWMechanics::AiPackageTypeId::Escort: return "Escort"; - case MWMechanics::AiPackageTypeId::Follow: return "Follow"; - case MWMechanics::AiPackageTypeId::Activate: return "Activate"; - case MWMechanics::AiPackageTypeId::Combat: return "Combat"; - case MWMechanics::AiPackageTypeId::Pursue: return "Pursue"; - case MWMechanics::AiPackageTypeId::AvoidDoor: return "AvoidDoor"; - case MWMechanics::AiPackageTypeId::Face: return "Face"; - case MWMechanics::AiPackageTypeId::Breathe: return "Breathe"; - case MWMechanics::AiPackageTypeId::Cast: return "Cast"; - default: return "Unknown"; + case MWMechanics::AiPackageTypeId::Wander: + return "Wander"; + case MWMechanics::AiPackageTypeId::Travel: + return "Travel"; + case MWMechanics::AiPackageTypeId::Escort: + return "Escort"; + case MWMechanics::AiPackageTypeId::Follow: + return "Follow"; + case MWMechanics::AiPackageTypeId::Activate: + return "Activate"; + case MWMechanics::AiPackageTypeId::Combat: + return "Combat"; + case MWMechanics::AiPackageTypeId::Pursue: + return "Pursue"; + case MWMechanics::AiPackageTypeId::AvoidDoor: + return "AvoidDoor"; + case MWMechanics::AiPackageTypeId::Face: + return "Face"; + case MWMechanics::AiPackageTypeId::Breathe: + return "Breathe"; + case MWMechanics::AiPackageTypeId::Cast: + return "Cast"; + default: + return "Unknown"; } }); - aiPackage["target"] = sol::readonly_property([worldView=context.mWorldView](const AiPackage& p) -> sol::optional - { - MWWorld::Ptr target = p.getTarget(); - if (target.isEmpty()) - return sol::nullopt; - else - return LObject(getId(target), worldView->getObjectRegistry()); - }); + aiPackage["target"] + = sol::readonly_property([worldView = context.mWorldView](const AiPackage& p) -> sol::optional { + MWWorld::Ptr target = p.getTarget(); + if (target.isEmpty()) + return sol::nullopt; + else + return LObject(getId(target), worldView->getObjectRegistry()); + }); aiPackage["sideWithTarget"] = sol::readonly_property([](const AiPackage& p) { return p.sideWithTarget(); }); aiPackage["destPosition"] = sol::readonly_property([](const AiPackage& p) { return p.getDestination(); }); - selfAPI["_getActiveAiPackage"] = [](SelfObject& self) -> sol::optional> - { + selfAPI["_getActiveAiPackage"] = [](SelfObject& self) -> sol::optional> { const MWWorld::Ptr& ptr = self.ptr(); MWMechanics::AiSequence& ai = ptr.getClass().getCreatureStats(ptr).getAiSequence(); if (ai.isEmpty()) @@ -92,38 +111,32 @@ namespace MWLua else return *ai.begin(); }; - selfAPI["_iterateAndFilterAiSequence"] = [](SelfObject& self, sol::function callback) - { + selfAPI["_iterateAndFilterAiSequence"] = [](SelfObject& self, sol::function callback) { const MWWorld::Ptr& ptr = self.ptr(); MWMechanics::AiSequence& ai = ptr.getClass().getCreatureStats(ptr).getAiSequence(); - ai.erasePackagesIf([&](auto& entry) - { + ai.erasePackagesIf([&](auto& entry) { bool keep = LuaUtil::call(callback, entry).template get(); return !keep; }); }; - selfAPI["_startAiCombat"] = [](SelfObject& self, const LObject& target) - { + selfAPI["_startAiCombat"] = [](SelfObject& self, const LObject& target) { const MWWorld::Ptr& ptr = self.ptr(); MWMechanics::AiSequence& ai = ptr.getClass().getCreatureStats(ptr).getAiSequence(); ai.stack(MWMechanics::AiCombat(target.ptr()), ptr); }; - selfAPI["_startAiPursue"] = [](SelfObject& self, const LObject& target) - { + selfAPI["_startAiPursue"] = [](SelfObject& self, const LObject& target) { const MWWorld::Ptr& ptr = self.ptr(); MWMechanics::AiSequence& ai = ptr.getClass().getCreatureStats(ptr).getAiSequence(); ai.stack(MWMechanics::AiPursue(target.ptr()), ptr); }; - selfAPI["_startAiFollow"] = [](SelfObject& self, const LObject& target) - { + selfAPI["_startAiFollow"] = [](SelfObject& self, const LObject& target) { const MWWorld::Ptr& ptr = self.ptr(); MWMechanics::AiSequence& ai = ptr.getClass().getCreatureStats(ptr).getAiSequence(); ai.stack(MWMechanics::AiFollow(target.ptr()), ptr); }; - selfAPI["_startAiEscort"] = [](SelfObject& self, const LObject& target, LCell cell, - float duration, const osg::Vec3f& dest) - { + selfAPI["_startAiEscort"] = [](SelfObject& self, const LObject& target, LCell cell, float duration, + const osg::Vec3f& dest) { const MWWorld::Ptr& ptr = self.ptr(); MWMechanics::AiSequence& ai = ptr.getClass().getCreatureStats(ptr).getAiSequence(); // TODO: change AiEscort implementation to accept ptr instead of a non-unique refId. @@ -133,17 +146,17 @@ namespace MWLua if (esmCell->isExterior()) ai.stack(MWMechanics::AiEscort(refId, gameHoursDuration, dest.x(), dest.y(), dest.z(), false), ptr); else - ai.stack(MWMechanics::AiEscort(refId, esmCell->mName, gameHoursDuration, dest.x(), dest.y(), dest.z(), false), ptr); + ai.stack(MWMechanics::AiEscort( + refId, esmCell->mName, gameHoursDuration, dest.x(), dest.y(), dest.z(), false), + ptr); }; - selfAPI["_startAiWander"] = [](SelfObject& self, int distance, float duration) - { + selfAPI["_startAiWander"] = [](SelfObject& self, int distance, float duration) { const MWWorld::Ptr& ptr = self.ptr(); MWMechanics::AiSequence& ai = ptr.getClass().getCreatureStats(ptr).getAiSequence(); int gameHoursDuration = static_cast(std::ceil(duration / 3600.0)); ai.stack(MWMechanics::AiWander(distance, gameHoursDuration, 0, {}, false), ptr); }; - selfAPI["_startAiTravel"] = [](SelfObject& self, const osg::Vec3f& target) - { + selfAPI["_startAiTravel"] = [](SelfObject& self, const osg::Vec3f& target) { const MWWorld::Ptr& ptr = self.ptr(); MWMechanics::AiSequence& ai = ptr.getClass().getCreatureStats(ptr).getAiSequence(); ai.stack(MWMechanics::AiTravel(target.x(), target.y(), target.z(), false), ptr); @@ -151,37 +164,40 @@ namespace MWLua } LocalScripts::LocalScripts(LuaUtil::LuaState* lua, const LObject& obj) - : LuaUtil::ScriptsContainer(lua, "L" + idToString(obj.id())), mData(obj) + : LuaUtil::ScriptsContainer(lua, "L" + idToString(obj.id())) + , mData(obj) { this->addPackage("openmw.self", sol::make_object(lua->sol(), &mData)); - registerEngineHandlers({&mOnActiveHandlers, &mOnInactiveHandlers, &mOnConsumeHandlers, &mOnActivatedHandlers}); + registerEngineHandlers( + { &mOnActiveHandlers, &mOnInactiveHandlers, &mOnConsumeHandlers, &mOnActivatedHandlers }); } void LocalScripts::receiveEngineEvent(const EngineEvent& event) { - std::visit([this](auto&& arg) - { - using EventT = std::decay_t; - if constexpr (std::is_same_v) - { - mData.mIsActive = true; - callEngineHandlers(mOnActiveHandlers); - } - else if constexpr (std::is_same_v) - { - mData.mIsActive = false; - callEngineHandlers(mOnInactiveHandlers); - } - else if constexpr (std::is_same_v) - { - callEngineHandlers(mOnActivatedHandlers, arg.mActivatingActor); - } - else - { - static_assert(std::is_same_v); - callEngineHandlers(mOnConsumeHandlers, arg.mConsumable); - } - }, event); + std::visit( + [this](auto&& arg) { + using EventT = std::decay_t; + if constexpr (std::is_same_v) + { + mData.mIsActive = true; + callEngineHandlers(mOnActiveHandlers); + } + else if constexpr (std::is_same_v) + { + mData.mIsActive = false; + callEngineHandlers(mOnInactiveHandlers); + } + else if constexpr (std::is_same_v) + { + callEngineHandlers(mOnActivatedHandlers, arg.mActivatingActor); + } + else + { + static_assert(std::is_same_v); + callEngineHandlers(mOnConsumeHandlers, arg.mConsumable); + } + }, + event); } void LocalScripts::applyStatsCache() diff --git a/apps/openmw/mwlua/localscripts.hpp b/apps/openmw/mwlua/localscripts.hpp index ec08f5b5f3..c76c1be51a 100644 --- a/apps/openmw/mwlua/localscripts.hpp +++ b/apps/openmw/mwlua/localscripts.hpp @@ -29,13 +29,19 @@ namespace MWLua class CachedStat { public: - using Setter = void(*)(int, std::string_view, const MWWorld::Ptr&, const sol::object&); + using Setter = void (*)(int, std::string_view, const MWWorld::Ptr&, const sol::object&); + private: Setter mSetter; // Function that updates a stat's property int mIndex; // Optional index to disambiguate the stat std::string_view mProp; // Name of the stat's property public: - CachedStat(Setter setter, int index, std::string_view prop) : mSetter(setter), mIndex(index), mProp(std::move(prop)) {} + CachedStat(Setter setter, int index, std::string_view prop) + : mSetter(setter) + , mIndex(index) + , mProp(std::move(prop)) + { + } void operator()(const MWWorld::Ptr& ptr, const sol::object& object) const { @@ -48,17 +54,25 @@ namespace MWLua } }; - SelfObject(const LObject& obj) : LObject(obj), mIsActive(false) {} + SelfObject(const LObject& obj) + : LObject(obj) + , mIsActive(false) + { + } MWBase::LuaManager::ActorControls mControls; std::map mStatsCache; bool mIsActive; }; - struct OnActive {}; - struct OnInactive {}; + struct OnActive + { + }; + struct OnInactive + { + }; struct OnActivated { - LObject mActivatingActor; + LObject mActivatingActor; }; struct OnConsume { @@ -69,14 +83,15 @@ namespace MWLua void receiveEngineEvent(const EngineEvent&); void applyStatsCache(); + protected: SelfObject mData; private: - EngineHandlerList mOnActiveHandlers{"onActive"}; - EngineHandlerList mOnInactiveHandlers{"onInactive"}; - EngineHandlerList mOnConsumeHandlers{"onConsume"}; - EngineHandlerList mOnActivatedHandlers{"onActivated"}; + EngineHandlerList mOnActiveHandlers{ "onActive" }; + EngineHandlerList mOnInactiveHandlers{ "onInactive" }; + EngineHandlerList mOnConsumeHandlers{ "onConsume" }; + EngineHandlerList mOnActivatedHandlers{ "onActivated" }; }; } diff --git a/apps/openmw/mwlua/luabindings.cpp b/apps/openmw/mwlua/luabindings.cpp index 268c8d8165..2abc094a76 100644 --- a/apps/openmw/mwlua/luabindings.cpp +++ b/apps/openmw/mwlua/luabindings.cpp @@ -2,8 +2,8 @@ #include -#include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/statemanager.hpp" @@ -11,8 +11,8 @@ #include "../mwworld/store.hpp" #include "eventqueue.hpp" -#include "worldview.hpp" #include "luamanagerimp.hpp" +#include "worldview.hpp" namespace MWLua { @@ -21,26 +21,22 @@ namespace MWLua { MWBase::World* world = MWBase::Environment::get().getWorld(); - api["getSimulationTime"] = [world=context.mWorldView]() { return world->getSimulationTime(); }; + api["getSimulationTime"] = [world = context.mWorldView]() { return world->getSimulationTime(); }; api["getSimulationTimeScale"] = [world]() { return world->getSimulationTimeScale(); }; - api["getGameTime"] = [world=context.mWorldView]() { return world->getGameTime(); }; - api["getGameTimeScale"] = [world=context.mWorldView]() { return world->getGameTimeScale(); }; - api["isWorldPaused"] = [world=context.mWorldView]() { return world->isPaused(); }; - api["getRealTime"] = []() - { + api["getGameTime"] = [world = context.mWorldView]() { return world->getGameTime(); }; + api["getGameTimeScale"] = [world = context.mWorldView]() { return world->getGameTimeScale(); }; + api["isWorldPaused"] = [world = context.mWorldView]() { return world->isPaused(); }; + api["getRealTime"] = []() { return std::chrono::duration(std::chrono::steady_clock::now().time_since_epoch()).count(); }; if (!global) return; - api["setGameTimeScale"] = [world=context.mWorldView](double scale) { world->setGameTimeScale(scale); }; + api["setGameTimeScale"] = [world = context.mWorldView](double scale) { world->setGameTimeScale(scale); }; - api["setSimulationTimeScale"] = [context, world](float scale) - { - context.mLuaManager->addAction([scale, world] { - world->setSimulationTimeScale(scale); - }); + api["setSimulationTimeScale"] = [context, world](float scale) { + context.mLuaManager->addAction([scale, world] { world->setSimulationTimeScale(scale); }); }; // TODO: Ability to pause/resume world from Lua (needed for UI dehardcoding) @@ -53,25 +49,24 @@ namespace MWLua auto* lua = context.mLua; sol::table api(lua->sol(), sol::create); api["API_REVISION"] = 30; - api["quit"] = [lua]() - { + api["quit"] = [lua]() { Log(Debug::Warning) << "Quit requested by a Lua script.\n" << lua->debugTraceback(); MWBase::Environment::get().getStateManager()->requestQuit(); }; - api["sendGlobalEvent"] = [context](std::string eventName, const sol::object& eventData) - { - context.mGlobalEventQueue->push_back({std::move(eventName), LuaUtil::serialize(eventData, context.mSerializer)}); + api["sendGlobalEvent"] = [context](std::string eventName, const sol::object& eventData) { + context.mGlobalEventQueue->push_back( + { std::move(eventName), LuaUtil::serialize(eventData, context.mSerializer) }); }; addTimeBindings(api, context, false); - api["l10n"] = [l10n=context.mL10n](const std::string& context, const sol::object &fallbackLocale) { + api["l10n"] = [l10n = context.mL10n](const std::string& context, const sol::object& fallbackLocale) { if (fallbackLocale == sol::nil) return l10n->getContext(context); else return l10n->getContext(context, fallbackLocale.as()); }; - const MWWorld::Store* gmst = &MWBase::Environment::get().getWorld()->getStore().get(); - api["getGMST"] = [lua=context.mLua, gmst](const std::string& setting) -> sol::object - { + const MWWorld::Store* gmst + = &MWBase::Environment::get().getWorld()->getStore().get(); + api["getGMST"] = [lua = context.mLua, gmst](const std::string& setting) -> sol::object { const ESM::Variant& value = gmst->find(setting)->mValue; if (value.getType() == ESM::VT_String) return sol::make_object(lua->sol(), value.getString()); @@ -88,23 +83,21 @@ namespace MWLua sol::table api(context.mLua->sol(), sol::create); WorldView* worldView = context.mWorldView; addTimeBindings(api, context, true); - api["getCellByName"] = [worldView=context.mWorldView](const std::string& name) -> sol::optional - { + api["getCellByName"] = [worldView = context.mWorldView](const std::string& name) -> sol::optional { MWWorld::CellStore* cell = worldView->findNamedCell(name); if (cell) - return GCell{cell}; + return GCell{ cell }; else return sol::nullopt; }; - api["getExteriorCell"] = [worldView=context.mWorldView](int x, int y) -> sol::optional - { + api["getExteriorCell"] = [worldView = context.mWorldView](int x, int y) -> sol::optional { MWWorld::CellStore* cell = worldView->findExteriorCell(x, y); if (cell) - return GCell{cell}; + return GCell{ cell }; else return sol::nullopt; }; - api["activeActors"] = GObjectList{worldView->getActorsInScene()}; + api["activeActors"] = GObjectList{ worldView->getActorsInScene() }; // TODO: add world.placeNewObject(recordId, cell, pos, [rot]) return LuaUtil::makeReadOnly(api); } @@ -112,7 +105,8 @@ namespace MWLua sol::table initGlobalStoragePackage(const Context& context, LuaUtil::LuaStorage* globalStorage) { sol::table res(context.mLua->sol(), sol::create); - res["globalSection"] = [globalStorage](std::string_view section) { return globalStorage->getMutableSection(section); }; + res["globalSection"] + = [globalStorage](std::string_view section) { return globalStorage->getMutableSection(section); }; res["allGlobalSections"] = [globalStorage]() { return globalStorage->getAllSections(); }; return LuaUtil::makeReadOnly(res); } @@ -120,18 +114,21 @@ namespace MWLua sol::table initLocalStoragePackage(const Context& context, LuaUtil::LuaStorage* globalStorage) { sol::table res(context.mLua->sol(), sol::create); - res["globalSection"] = [globalStorage](std::string_view section) { return globalStorage->getReadOnlySection(section); }; + res["globalSection"] + = [globalStorage](std::string_view section) { return globalStorage->getReadOnlySection(section); }; return LuaUtil::makeReadOnly(res); } - sol::table initPlayerStoragePackage(const Context& context, LuaUtil::LuaStorage* globalStorage, LuaUtil::LuaStorage* playerStorage) + sol::table initPlayerStoragePackage( + const Context& context, LuaUtil::LuaStorage* globalStorage, LuaUtil::LuaStorage* playerStorage) { sol::table res(context.mLua->sol(), sol::create); - res["globalSection"] = [globalStorage](std::string_view section) { return globalStorage->getReadOnlySection(section); }; - res["playerSection"] = [playerStorage](std::string_view section) { return playerStorage->getMutableSection(section); }; + res["globalSection"] + = [globalStorage](std::string_view section) { return globalStorage->getReadOnlySection(section); }; + res["playerSection"] + = [playerStorage](std::string_view section) { return playerStorage->getMutableSection(section); }; res["allPlayerSections"] = [playerStorage]() { return playerStorage->getAllSections(); }; return LuaUtil::makeReadOnly(res); } } - diff --git a/apps/openmw/mwlua/luabindings.hpp b/apps/openmw/mwlua/luabindings.hpp index 537fc0bf46..88ff7d67e5 100644 --- a/apps/openmw/mwlua/luabindings.hpp +++ b/apps/openmw/mwlua/luabindings.hpp @@ -2,8 +2,8 @@ #define MWLUA_LUABINDINGS_H #include -#include #include +#include #include #include "context.hpp" @@ -22,7 +22,8 @@ namespace MWLua sol::table initGlobalStoragePackage(const Context&, LuaUtil::LuaStorage* globalStorage); sol::table initLocalStoragePackage(const Context&, LuaUtil::LuaStorage* globalStorage); - sol::table initPlayerStoragePackage(const Context&, LuaUtil::LuaStorage* globalStorage, LuaUtil::LuaStorage* playerStorage); + sol::table initPlayerStoragePackage( + const Context&, LuaUtil::LuaStorage* globalStorage, LuaUtil::LuaStorage* playerStorage); // Implemented in nearbybindings.cpp sol::table initNearbyPackage(const Context&); diff --git a/apps/openmw/mwlua/luamanagerimp.cpp b/apps/openmw/mwlua/luamanagerimp.cpp index 2c8754375c..95da0e78c1 100644 --- a/apps/openmw/mwlua/luamanagerimp.cpp +++ b/apps/openmw/mwlua/luamanagerimp.cpp @@ -4,9 +4,9 @@ #include +#include #include #include -#include #include @@ -22,16 +22,16 @@ #include "../mwworld/esmstore.hpp" #include "../mwworld/ptr.hpp" -#include "luabindings.hpp" -#include "userdataserializer.hpp" -#include "types/types.hpp" #include "debugbindings.hpp" +#include "luabindings.hpp" #include "playerscripts.hpp" +#include "types/types.hpp" +#include "userdataserializer.hpp" namespace MWLua { - LuaManager::LuaManager(const VFS::Manager* vfs, const std::filesystem::path &libsDir) + LuaManager::LuaManager(const VFS::Manager* vfs, const std::filesystem::path& libsDir) : mLua(vfs, &mConfiguration) , mUiResourceManager(vfs) , mL10n(vfs, &mLua) @@ -110,7 +110,7 @@ namespace MWLua return mL10n.translate(contextName, key); } - void LuaManager::loadPermanentStorage(const std::filesystem::path &userConfigPath) + void LuaManager::loadPermanentStorage(const std::filesystem::path& userConfigPath) { const auto globalPath = userConfigPath / "global_storage.bin"; const auto playerPath = userConfigPath / "player_storage.bin"; @@ -120,7 +120,7 @@ namespace MWLua mPlayerStorage.load(playerPath); } - void LuaManager::savePermanentStorage(const std::filesystem::path &userConfigPath) + void LuaManager::savePermanentStorage(const std::filesystem::path& userConfigPath) { mGlobalStorage.save(userConfigPath / "global_storage.bin"); mPlayerStorage.save(userConfigPath / "player_storage.bin"); @@ -130,7 +130,7 @@ namespace MWLua { static const bool luaDebug = Settings::Manager::getBool("lua debug", "Lua"); if (mPlayer.isEmpty()) - return; // The game is not started yet. + return; // The game is not started yet. float frameDuration = MWBase::Environment::get().getFrameDuration(); ObjectRegistry* objectRegistry = mWorldView.getObjectRegistry(); @@ -140,7 +140,7 @@ namespace MWLua throw std::logic_error("Player Refnum was changed unexpectedly"); if (!mPlayer.isInCell() || !newPlayerPtr.isInCell() || mPlayer.getCell() != newPlayerPtr.getCell()) { - mPlayer = newPlayerPtr; // player was moved to another cell, update ptr in registry + mPlayer = newPlayerPtr; // player was moved to another cell, update ptr in registry objectRegistry->registerPtr(mPlayer); } @@ -152,7 +152,7 @@ namespace MWLua mLocalEvents = std::vector(); if (!mWorldView.isPaused()) - { // Update time and process timers + { // Update time and process timers double simulationTime = mWorldView.getSimulationTime() + frameDuration; mWorldView.setSimulationTime(simulationTime); double gameTime = mWorldView.getGameTime(); @@ -188,7 +188,8 @@ namespace MWLua if (!obj.isValid()) { if (luaDebug) - Log(Debug::Verbose) << "Can not call engine handlers: object" << idToString(e.mDest) << " is not found"; + Log(Debug::Verbose) << "Can not call engine handlers: object" << idToString(e.mDest) + << " is not found"; continue; } LocalScripts* scripts = obj.ptr().getRefData().getLuaScripts(); @@ -229,7 +230,7 @@ namespace MWLua } else if (luaDebug) Log(Debug::Verbose) << "Could not resolve a Lua object added event: object" << idToString(id) - << " is already removed"; + << " is already removed"; } mObjectAddedEvents.clear(); @@ -240,7 +241,7 @@ namespace MWLua void LuaManager::synchronizedUpdate() { if (mPlayer.isEmpty()) - return; // The game is not started yet. + return; // The game is not started yet. // We apply input events in `synchronizedUpdate` rather than in `update` in order to reduce input latency. mProcessingInputEvents = true; @@ -266,7 +267,7 @@ namespace MWLua for (std::unique_ptr& action : mActionQueue) action->safeApply(mWorldView); mActionQueue.clear(); - + if (mTeleportPlayerAction) mTeleportPlayerAction->safeApply(mWorldView); mTeleportPlayerAction.reset(); @@ -314,7 +315,7 @@ namespace MWLua localScripts->addAutoStartedScripts(); } mActiveLocalScripts.insert(localScripts); - mLocalEngineEvents.push_back({getId(ptr), LocalScripts::OnActive{}}); + mLocalEngineEvents.push_back({ getId(ptr), LocalScripts::OnActive{} }); mPlayerChanged = true; } @@ -335,23 +336,23 @@ namespace MWLua void LuaManager::objectAddedToScene(const MWWorld::Ptr& ptr) { - mWorldView.objectAddedToScene(ptr); // assigns generated RefNum if it is not set yet. + mWorldView.objectAddedToScene(ptr); // assigns generated RefNum if it is not set yet. LocalScripts* localScripts = ptr.getRefData().getLuaScripts(); if (!localScripts) { - LuaUtil::ScriptIdsWithInitializationData autoStartConf = - mConfiguration.getLocalConf(getLiveCellRefType(ptr.mRef), ptr.getCellRef().getRefId(), getId(ptr)); + LuaUtil::ScriptIdsWithInitializationData autoStartConf + = mConfiguration.getLocalConf(getLiveCellRefType(ptr.mRef), ptr.getCellRef().getRefId(), getId(ptr)); if (!autoStartConf.empty()) { localScripts = createLocalScripts(ptr, std::move(autoStartConf)); - localScripts->addAutoStartedScripts(); // TODO: put to a queue and apply on next `update()` + localScripts->addAutoStartedScripts(); // TODO: put to a queue and apply on next `update()` } } if (localScripts) { mActiveLocalScripts.insert(localScripts); - mLocalEngineEvents.push_back({getId(ptr), LocalScripts::OnActive{}}); + mLocalEngineEvents.push_back({ getId(ptr), LocalScripts::OnActive{} }); } if (ptr != mPlayer) @@ -366,7 +367,7 @@ namespace MWLua { mActiveLocalScripts.erase(localScripts); if (!mWorldView.getObjectRegistry()->getPtr(getId(ptr), true).isEmpty()) - mLocalEngineEvents.push_back({getId(ptr), LocalScripts::OnInactive{}}); + mLocalEngineEvents.push_back({ getId(ptr), LocalScripts::OnInactive{} }); } } @@ -383,12 +384,14 @@ namespace MWLua void LuaManager::itemConsumed(const MWWorld::Ptr& consumable, const MWWorld::Ptr& actor) { mWorldView.getObjectRegistry()->registerPtr(consumable); - mLocalEngineEvents.push_back({getId(actor), LocalScripts::OnConsume{LObject(getId(consumable), mWorldView.getObjectRegistry())}}); + mLocalEngineEvents.push_back( + { getId(actor), LocalScripts::OnConsume{ LObject(getId(consumable), mWorldView.getObjectRegistry()) } }); } void LuaManager::objectActivated(const MWWorld::Ptr& object, const MWWorld::Ptr& actor) { - mLocalEngineEvents.push_back({getId(object), LocalScripts::OnActivated{LObject(getId(actor), mWorldView.getObjectRegistry())}}); + mLocalEngineEvents.push_back( + { getId(object), LocalScripts::OnActivated{ LObject(getId(actor), mWorldView.getObjectRegistry()) } }); } MWBase::LuaManager::ActorControls* LuaManager::getActorControls(const MWWorld::Ptr& ptr) const @@ -412,8 +415,8 @@ namespace MWLua localScripts->addCustomScript(scriptId); } - LocalScripts* LuaManager::createLocalScripts(const MWWorld::Ptr& ptr, - std::optional autoStartConf) + LocalScripts* LuaManager::createLocalScripts( + const MWWorld::Ptr& ptr, std::optional autoStartConf) { assert(mInitialized); std::shared_ptr scripts; @@ -514,7 +517,7 @@ namespace MWLua mL10n.clear(); initConfiguration(); - { // Reload global scripts + { // Reload global scripts mGlobalScripts.setSavedDataDeserializer(mGlobalSerializer.get()); ESM::LuaScripts data; mGlobalScripts.save(data); @@ -522,7 +525,7 @@ namespace MWLua } for (const auto& [id, ptr] : mWorldView.getObjectRegistry()->mObjectMapping) - { // Reload local scripts + { // Reload local scripts LocalScripts* scripts = ptr.getRefData().getLuaScripts(); if (scripts == nullptr) continue; @@ -535,23 +538,24 @@ namespace MWLua scripts->receiveEngineEvent(LocalScripts::OnActive()); } - void LuaManager::handleConsoleCommand(const std::string& consoleMode, const std::string& command, const MWWorld::Ptr& selectedPtr) + void LuaManager::handleConsoleCommand( + const std::string& consoleMode, const std::string& command, const MWWorld::Ptr& selectedPtr) { PlayerScripts* playerScripts = nullptr; if (!mPlayer.isEmpty()) playerScripts = dynamic_cast(mPlayer.getRefData().getLuaScripts()); if (!playerScripts) { - MWBase::Environment::get().getWindowManager()->printToConsole("You must enter a game session to run Lua commands\n", - MWBase::WindowManager::sConsoleColor_Error); + MWBase::Environment::get().getWindowManager()->printToConsole( + "You must enter a game session to run Lua commands\n", MWBase::WindowManager::sConsoleColor_Error); return; } sol::object selected = sol::nil; if (!selectedPtr.isEmpty()) selected = sol::make_object(mLua.sol(), LObject(getId(selectedPtr), mWorldView.getObjectRegistry())); if (!playerScripts->consoleCommand(consoleMode, command, selected)) - MWBase::Environment::get().getWindowManager()->printToConsole("No Lua handlers for console\n", - MWBase::WindowManager::sConsoleColor_Error); + MWBase::Environment::get().getWindowManager()->printToConsole( + "No Lua handlers for console\n", MWBase::WindowManager::sConsoleColor_Error); } LuaManager::Action::Action(LuaUtil::LuaState* state) @@ -584,7 +588,11 @@ namespace MWLua { public: FunctionAction(LuaUtil::LuaState* state, std::function fn, std::string_view name) - : Action(state), mFn(std::move(fn)), mName(name) {} + : Action(state) + , mFn(std::move(fn)) + , mName(name) + { + } void apply(WorldView&) const override { mFn(); } std::string toString() const override { return "FunctionAction " + mName; } diff --git a/apps/openmw/mwlua/luamanagerimp.hpp b/apps/openmw/mwlua/luamanagerimp.hpp index 8c4c6f4d95..1146147acc 100644 --- a/apps/openmw/mwlua/luamanagerimp.hpp +++ b/apps/openmw/mwlua/luamanagerimp.hpp @@ -15,11 +15,11 @@ #include "../mwbase/luamanager.hpp" -#include "object.hpp" #include "eventqueue.hpp" #include "globalscripts.hpp" -#include "worldview.hpp" #include "localscripts.hpp" +#include "object.hpp" +#include "worldview.hpp" namespace MWLua { @@ -27,7 +27,7 @@ namespace MWLua class LuaManager : public MWBase::LuaManager { public: - LuaManager(const VFS::Manager* vfs, const std::filesystem::path &libsDir); + LuaManager(const VFS::Manager* vfs, const std::filesystem::path& libsDir); // Called by engine.cpp before UI setup. void initL10n(); @@ -35,8 +35,8 @@ namespace MWLua // Called by engine.cpp when the environment is fully initialized. void init(); - void loadPermanentStorage(const std::filesystem::path &userConfigPath); - void savePermanentStorage(const std::filesystem::path &userConfigPath); + void loadPermanentStorage(const std::filesystem::path& userConfigPath); + void savePermanentStorage(const std::filesystem::path& userConfigPath); // Called by engine.cpp every frame. For performance reasons it works in a separate // thread (in parallel with osg Cull). Can not use scene graph. @@ -61,20 +61,20 @@ namespace MWLua MWBase::LuaManager::ActorControls* getActorControls(const MWWorld::Ptr&) const override; - void clear() override; // should be called before loading game or starting a new game to reset internal state. - void setupPlayer(const MWWorld::Ptr& ptr) override; // Should be called once after each "clear". + void clear() override; // should be called before loading game or starting a new game to reset internal state. + void setupPlayer(const MWWorld::Ptr& ptr) override; // Should be called once after each "clear". // Used only in Lua bindings void addCustomLocalScript(const MWWorld::Ptr&, int scriptId); void addUIMessage(std::string_view message) { mUIMessages.emplace_back(message); } void addInGameConsoleMessage(const std::string& msg, const Misc::Color& color) { - mInGameConsoleMessages.push_back({msg, color}); + mInGameConsoleMessages.push_back({ msg, color }); } - - // Some changes to the game world can not be done from the scripting thread (because it runs in parallel with OSG Cull), - // so we need to queue it and apply from the main thread. All such changes should be implemented as classes inherited - // from MWLua::Action. + + // Some changes to the game world can not be done from the scripting thread (because it runs in parallel with + // OSG Cull), so we need to queue it and apply from the main thread. All such changes should be implemented as + // classes inherited from MWLua::Action. class Action { public: @@ -105,12 +105,13 @@ namespace MWLua // Drops script cache and reloads all scripts. Calls `onSave` and `onLoad` for every script. void reloadAllScripts() override; - void handleConsoleCommand(const std::string& consoleMode, const std::string& command, const MWWorld::Ptr& selectedPtr) override; + void handleConsoleCommand( + const std::string& consoleMode, const std::string& command, const MWWorld::Ptr& selectedPtr) override; // Used to call Lua callbacks from C++ void queueCallback(LuaUtil::Callback callback, sol::object arg) { - mQueuedCallbacks.push_back({std::move(callback), std::move(arg)}); + mQueuedCallbacks.push_back({ std::move(callback), std::move(arg) }); } // Wraps Lua callback into an std::function. @@ -129,7 +130,7 @@ namespace MWLua private: void initConfiguration(); LocalScripts* createLocalScripts(const MWWorld::Ptr& ptr, - std::optional autoStartConf = std::nullopt); + std::optional autoStartConf = std::nullopt); bool mInitialized = false; bool mGlobalScriptsStarted = false; @@ -147,7 +148,7 @@ namespace MWLua sol::table mPostprocessingPackage; sol::table mDebugPackage; - GlobalScripts mGlobalScripts{&mLua}; + GlobalScripts mGlobalScripts{ &mLua }; std::set mActiveLocalScripts; WorldView mWorldView; @@ -188,10 +189,10 @@ namespace MWLua std::vector mUIMessages; std::vector> mInGameConsoleMessages; - LuaUtil::LuaStorage mGlobalStorage{mLua.sol()}; - LuaUtil::LuaStorage mPlayerStorage{mLua.sol()}; + LuaUtil::LuaStorage mGlobalStorage{ mLua.sol() }; + LuaUtil::LuaStorage mPlayerStorage{ mLua.sol() }; }; } -#endif // MWLUA_LUAMANAGERIMP_H +#endif // MWLUA_LUAMANAGERIMP_H diff --git a/apps/openmw/mwlua/nearbybindings.cpp b/apps/openmw/mwlua/nearbybindings.cpp index 6bba80fde2..df1fafc9d7 100644 --- a/apps/openmw/mwlua/nearbybindings.cpp +++ b/apps/openmw/mwlua/nearbybindings.cpp @@ -1,8 +1,8 @@ #include "luabindings.hpp" -#include #include #include +#include #include #include "../mwbase/environment.hpp" @@ -15,7 +15,9 @@ namespace sol { template <> - struct is_automagical : std::false_type {}; + struct is_automagical : std::false_type + { + }; } namespace MWLua @@ -25,53 +27,54 @@ namespace MWLua sol::table api(context.mLua->sol(), sol::create); WorldView* worldView = context.mWorldView; - sol::usertype rayResult = - context.mLua->sol().new_usertype("RayCastingResult"); + sol::usertype rayResult + = context.mLua->sol().new_usertype("RayCastingResult"); rayResult["hit"] = sol::readonly_property([](const MWPhysics::RayCastingResult& r) { return r.mHit; }); - rayResult["hitPos"] = sol::readonly_property([](const MWPhysics::RayCastingResult& r) -> sol::optional - { - if (r.mHit) - return r.mHitPos; - else - return sol::nullopt; - }); - rayResult["hitNormal"] = sol::readonly_property([](const MWPhysics::RayCastingResult& r) -> sol::optional - { - if (r.mHit) - return r.mHitNormal; - else - return sol::nullopt; - }); - rayResult["hitObject"] = sol::readonly_property([worldView](const MWPhysics::RayCastingResult& r) -> sol::optional - { - if (r.mHitObject.isEmpty()) - return sol::nullopt; - else - return LObject(getId(r.mHitObject), worldView->getObjectRegistry()); - }); + rayResult["hitPos"] + = sol::readonly_property([](const MWPhysics::RayCastingResult& r) -> sol::optional { + if (r.mHit) + return r.mHitPos; + else + return sol::nullopt; + }); + rayResult["hitNormal"] + = sol::readonly_property([](const MWPhysics::RayCastingResult& r) -> sol::optional { + if (r.mHit) + return r.mHitNormal; + else + return sol::nullopt; + }); + rayResult["hitObject"] + = sol::readonly_property([worldView](const MWPhysics::RayCastingResult& r) -> sol::optional { + if (r.mHitObject.isEmpty()) + return sol::nullopt; + else + return LObject(getId(r.mHitObject), worldView->getObjectRegistry()); + }); - api["COLLISION_TYPE"] = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs({ - {"World", MWPhysics::CollisionType_World}, - {"Door", MWPhysics::CollisionType_Door}, - {"Actor", MWPhysics::CollisionType_Actor}, - {"HeightMap", MWPhysics::CollisionType_HeightMap}, - {"Projectile", MWPhysics::CollisionType_Projectile}, - {"Water", MWPhysics::CollisionType_Water}, - {"Default", MWPhysics::CollisionType_Default}, - {"AnyPhysical", MWPhysics::CollisionType_AnyPhysical}, - {"Camera", MWPhysics::CollisionType_CameraOnly}, - {"VisualOnly", MWPhysics::CollisionType_VisualOnly}, - })); + api["COLLISION_TYPE"] + = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs({ + { "World", MWPhysics::CollisionType_World }, + { "Door", MWPhysics::CollisionType_Door }, + { "Actor", MWPhysics::CollisionType_Actor }, + { "HeightMap", MWPhysics::CollisionType_HeightMap }, + { "Projectile", MWPhysics::CollisionType_Projectile }, + { "Water", MWPhysics::CollisionType_Water }, + { "Default", MWPhysics::CollisionType_Default }, + { "AnyPhysical", MWPhysics::CollisionType_AnyPhysical }, + { "Camera", MWPhysics::CollisionType_CameraOnly }, + { "VisualOnly", MWPhysics::CollisionType_VisualOnly }, + })); - api["castRay"] = [](const osg::Vec3f& from, const osg::Vec3f& to, sol::optional options) - { + api["castRay"] = [](const osg::Vec3f& from, const osg::Vec3f& to, sol::optional options) { MWWorld::Ptr ignore; int collisionType = MWPhysics::CollisionType_Default; float radius = 0; if (options) { sol::optional ignoreObj = options->get>("ignore"); - if (ignoreObj) ignore = ignoreObj->ptr(); + if (ignoreObj) + ignore = ignoreObj->ptr(); collisionType = options->get>("collisionType").value_or(collisionType); radius = options->get>("radius").value_or(0); } @@ -80,13 +83,15 @@ namespace MWLua return rayCasting->castRay(from, to, ignore, std::vector(), collisionType); else { - if (!ignore.isEmpty()) throw std::logic_error("Currently castRay doesn't support `ignore` when radius > 0"); + if (!ignore.isEmpty()) + throw std::logic_error("Currently castRay doesn't support `ignore` when radius > 0"); return rayCasting->castSphere(from, to, radius, collisionType); } }; // TODO: async raycasting /*api["asyncCastRay"] = [luaManager = context.mLuaManager]( - const Callback& luaCallback, const osg::Vec3f& from, const osg::Vec3f& to, sol::optional options) + const Callback& luaCallback, const osg::Vec3f& from, const osg::Vec3f& to, sol::optional + options) { std::function callback = luaManager->wrapLuaCallback(luaCallback); @@ -94,127 +99,123 @@ namespace MWLua // Handle options the same way as in `castRay`. - // NOTE: `callback` is not thread safe. If MWPhysics works in separate thread, it must put results to a queue + // NOTE: `callback` is not thread safe. If MWPhysics works in separate thread, it must put results to a + queue // and use this callback from the main thread at the beginning of the next frame processing. rayCasting->asyncCastRay(callback, from, to, ignore, std::vector(), collisionType); };*/ - api["castRenderingRay"] = [manager=context.mLuaManager](const osg::Vec3f& from, const osg::Vec3f& to) - { + api["castRenderingRay"] = [manager = context.mLuaManager](const osg::Vec3f& from, const osg::Vec3f& to) { if (!manager->isProcessingInputEvents()) { - throw std::logic_error("castRenderingRay can be used only in player scripts during processing of input events; " - "use asyncCastRenderingRay instead."); + throw std::logic_error( + "castRenderingRay can be used only in player scripts during processing of input events; " + "use asyncCastRenderingRay instead."); } MWPhysics::RayCastingResult res; MWBase::Environment::get().getWorld()->castRenderingRay(res, from, to, false, false); return res; }; - api["asyncCastRenderingRay"] = - [manager=context.mLuaManager](const LuaUtil::Callback& callback, const osg::Vec3f& from, const osg::Vec3f& to) - { - manager->addAction([manager, callback, from, to] - { + api["asyncCastRenderingRay"] = [manager = context.mLuaManager](const LuaUtil::Callback& callback, + const osg::Vec3f& from, const osg::Vec3f& to) { + manager->addAction([manager, callback, from, to] { MWPhysics::RayCastingResult res; MWBase::Environment::get().getWorld()->castRenderingRay(res, from, to, false, false); manager->queueCallback(callback, sol::make_object(callback.mFunc.lua_state(), res)); }); }; - api["activators"] = LObjectList{worldView->getActivatorsInScene()}; - api["actors"] = LObjectList{worldView->getActorsInScene()}; - api["containers"] = LObjectList{worldView->getContainersInScene()}; - api["doors"] = LObjectList{worldView->getDoorsInScene()}; - api["items"] = LObjectList{worldView->getItemsInScene()}; + api["activators"] = LObjectList{ worldView->getActivatorsInScene() }; + api["actors"] = LObjectList{ worldView->getActorsInScene() }; + api["containers"] = LObjectList{ worldView->getContainersInScene() }; + api["doors"] = LObjectList{ worldView->getDoorsInScene() }; + api["items"] = LObjectList{ worldView->getItemsInScene() }; - api["NAVIGATOR_FLAGS"] = LuaUtil::makeStrictReadOnly( - context.mLua->tableFromPairs({ - {"Walk", DetourNavigator::Flag_walk}, - {"Swim", DetourNavigator::Flag_swim}, - {"OpenDoor", DetourNavigator::Flag_openDoor}, - {"UsePathgrid", DetourNavigator::Flag_usePathgrid}, + api["NAVIGATOR_FLAGS"] + = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs({ + { "Walk", DetourNavigator::Flag_walk }, + { "Swim", DetourNavigator::Flag_swim }, + { "OpenDoor", DetourNavigator::Flag_openDoor }, + { "UsePathgrid", DetourNavigator::Flag_usePathgrid }, })); api["COLLISION_SHAPE_TYPE"] = LuaUtil::makeStrictReadOnly( context.mLua->tableFromPairs({ - {"Aabb", DetourNavigator::CollisionShapeType::Aabb}, - {"RotatingBox", DetourNavigator::CollisionShapeType::RotatingBox}, - {"Cylinder", DetourNavigator::CollisionShapeType::Cylinder}, + { "Aabb", DetourNavigator::CollisionShapeType::Aabb }, + { "RotatingBox", DetourNavigator::CollisionShapeType::RotatingBox }, + { "Cylinder", DetourNavigator::CollisionShapeType::Cylinder }, })); - api["FIND_PATH_STATUS"] = LuaUtil::makeStrictReadOnly( - context.mLua->tableFromPairs({ - {"Success", DetourNavigator::Status::Success}, - {"PartialPath", DetourNavigator::Status::PartialPath}, - {"NavMeshNotFound", DetourNavigator::Status::NavMeshNotFound}, - {"StartPolygonNotFound", DetourNavigator::Status::StartPolygonNotFound}, - {"EndPolygonNotFound", DetourNavigator::Status::EndPolygonNotFound}, - {"MoveAlongSurfaceFailed", DetourNavigator::Status::MoveAlongSurfaceFailed}, - {"FindPathOverPolygonsFailed", DetourNavigator::Status::FindPathOverPolygonsFailed}, - {"InitNavMeshQueryFailed", DetourNavigator::Status::InitNavMeshQueryFailed}, + api["FIND_PATH_STATUS"] + = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs({ + { "Success", DetourNavigator::Status::Success }, + { "PartialPath", DetourNavigator::Status::PartialPath }, + { "NavMeshNotFound", DetourNavigator::Status::NavMeshNotFound }, + { "StartPolygonNotFound", DetourNavigator::Status::StartPolygonNotFound }, + { "EndPolygonNotFound", DetourNavigator::Status::EndPolygonNotFound }, + { "MoveAlongSurfaceFailed", DetourNavigator::Status::MoveAlongSurfaceFailed }, + { "FindPathOverPolygonsFailed", DetourNavigator::Status::FindPathOverPolygonsFailed }, + { "InitNavMeshQueryFailed", DetourNavigator::Status::InitNavMeshQueryFailed }, })); - static const DetourNavigator::AgentBounds defaultAgentBounds { + static const DetourNavigator::AgentBounds defaultAgentBounds{ DetourNavigator::toCollisionShapeType(Settings::Manager::getInt("actor collision shape type", "Game")), Settings::Manager::getVector3("default actor pathfind half extents", "Game"), }; - static const float defaultStepSize = 2 * std::max(defaultAgentBounds.mHalfExtents.x(), defaultAgentBounds.mHalfExtents.y()); + static const float defaultStepSize + = 2 * std::max(defaultAgentBounds.mHalfExtents.x(), defaultAgentBounds.mHalfExtents.y()); static constexpr DetourNavigator::Flags defaultIncludeFlags = DetourNavigator::Flag_walk - | DetourNavigator::Flag_swim - | DetourNavigator::Flag_openDoor - | DetourNavigator::Flag_usePathgrid; + | DetourNavigator::Flag_swim | DetourNavigator::Flag_openDoor | DetourNavigator::Flag_usePathgrid; - api["findPath"] = [] (const osg::Vec3f& source, const osg::Vec3f& destination, - const sol::optional& options) - { - DetourNavigator::AgentBounds agentBounds = defaultAgentBounds; - float stepSize = defaultStepSize; - DetourNavigator::Flags includeFlags = defaultIncludeFlags; - DetourNavigator::AreaCosts areaCosts {}; - float destinationTolerance = 1; + api["findPath"] + = [](const osg::Vec3f& source, const osg::Vec3f& destination, const sol::optional& options) { + DetourNavigator::AgentBounds agentBounds = defaultAgentBounds; + float stepSize = defaultStepSize; + DetourNavigator::Flags includeFlags = defaultIncludeFlags; + DetourNavigator::AreaCosts areaCosts{}; + float destinationTolerance = 1; - if (options.has_value()) - { - if (const auto& t = options->get>("agentBounds")) - { - if (const auto& v = t->get>("shapeType")) - agentBounds.mShapeType = *v; - if (const auto& v = t->get>("halfExtents")) - { - agentBounds.mHalfExtents = *v; - stepSize = 2 * std::max(v->x(), v->y()); - } - } - if (const auto& v = options->get>("stepSize")) - stepSize = *v; - if (const auto& v = options->get>("includeFlags")) - includeFlags = *v; - if (const auto& t = options->get>("areaCosts")) - { - if (const auto& v = t->get>("water")) - areaCosts.mWater = *v; - if (const auto& v = t->get>("door")) - areaCosts.mDoor = *v; - if (const auto& v = t->get>("pathgrid")) - areaCosts.mPathgrid = *v; - if (const auto& v = t->get>("ground")) - areaCosts.mGround = *v; - } - if (const auto& v = options->get>("destinationTolerance")) - destinationTolerance = *v; - } + if (options.has_value()) + { + if (const auto& t = options->get>("agentBounds")) + { + if (const auto& v = t->get>("shapeType")) + agentBounds.mShapeType = *v; + if (const auto& v = t->get>("halfExtents")) + { + agentBounds.mHalfExtents = *v; + stepSize = 2 * std::max(v->x(), v->y()); + } + } + if (const auto& v = options->get>("stepSize")) + stepSize = *v; + if (const auto& v = options->get>("includeFlags")) + includeFlags = *v; + if (const auto& t = options->get>("areaCosts")) + { + if (const auto& v = t->get>("water")) + areaCosts.mWater = *v; + if (const auto& v = t->get>("door")) + areaCosts.mDoor = *v; + if (const auto& v = t->get>("pathgrid")) + areaCosts.mPathgrid = *v; + if (const auto& v = t->get>("ground")) + areaCosts.mGround = *v; + } + if (const auto& v = options->get>("destinationTolerance")) + destinationTolerance = *v; + } - std::vector result; + std::vector result; - const DetourNavigator::Status status = DetourNavigator::findPath( - *MWBase::Environment::get().getWorld()->getNavigator(), agentBounds, stepSize, source, - destination, includeFlags, areaCosts, destinationTolerance, std::back_inserter(result)); + const DetourNavigator::Status status = DetourNavigator::findPath( + *MWBase::Environment::get().getWorld()->getNavigator(), agentBounds, stepSize, source, + destination, includeFlags, areaCosts, destinationTolerance, std::back_inserter(result)); - return std::make_tuple(status, std::move(result)); - }; + return std::make_tuple(status, std::move(result)); + }; - api["findRandomPointAroundCircle"] = [] (const osg::Vec3f& position, float maxRadius, - const sol::optional& options) - { + api["findRandomPointAroundCircle"] = [](const osg::Vec3f& position, float maxRadius, + const sol::optional& options) { DetourNavigator::AgentBounds agentBounds = defaultAgentBounds; DetourNavigator::Flags includeFlags = defaultIncludeFlags; @@ -231,37 +232,34 @@ namespace MWLua includeFlags = *v; } - constexpr auto getRandom = [] - { - return Misc::Rng::rollProbability(MWBase::Environment::get().getWorld()->getPrng()); - }; + constexpr auto getRandom + = [] { return Misc::Rng::rollProbability(MWBase::Environment::get().getWorld()->getPrng()); }; return DetourNavigator::findRandomPointAroundCircle(*MWBase::Environment::get().getWorld()->getNavigator(), agentBounds, position, maxRadius, includeFlags, getRandom); }; - api["castNavigationRay"] = [] (const osg::Vec3f& from, const osg::Vec3f& to, - const sol::optional& options) - { - DetourNavigator::AgentBounds agentBounds = defaultAgentBounds; - DetourNavigator::Flags includeFlags = defaultIncludeFlags; + api["castNavigationRay"] + = [](const osg::Vec3f& from, const osg::Vec3f& to, const sol::optional& options) { + DetourNavigator::AgentBounds agentBounds = defaultAgentBounds; + DetourNavigator::Flags includeFlags = defaultIncludeFlags; - if (options.has_value()) - { - if (const auto& t = options->get>("agentBounds")) - { - if (const auto& v = t->get>("shapeType")) - agentBounds.mShapeType = *v; - if (const auto& v = t->get>("halfExtents")) - agentBounds.mHalfExtents = *v; - } - if (const auto& v = options->get>("includeFlags")) - includeFlags = *v; - } + if (options.has_value()) + { + if (const auto& t = options->get>("agentBounds")) + { + if (const auto& v = t->get>("shapeType")) + agentBounds.mShapeType = *v; + if (const auto& v = t->get>("halfExtents")) + agentBounds.mHalfExtents = *v; + } + if (const auto& v = options->get>("includeFlags")) + includeFlags = *v; + } - return DetourNavigator::raycast(*MWBase::Environment::get().getWorld()->getNavigator(), - agentBounds, from, to, includeFlags); - }; + return DetourNavigator::raycast( + *MWBase::Environment::get().getWorld()->getNavigator(), agentBounds, from, to, includeFlags); + }; return LuaUtil::makeReadOnly(api); } diff --git a/apps/openmw/mwlua/object.hpp b/apps/openmw/mwlua/object.hpp index 4c4fbd7908..cf715256a7 100644 --- a/apps/openmw/mwlua/object.hpp +++ b/apps/openmw/mwlua/object.hpp @@ -1,8 +1,8 @@ #ifndef MWLUA_OBJECT_H #define MWLUA_OBJECT_H -#include #include +#include #include @@ -15,7 +15,10 @@ namespace MWLua // ObjectId is a unique identifier of a game object. // It can change only if the order of content files was change. using ObjectId = ESM::RefNum; - inline const ObjectId& getId(const MWWorld::Ptr& ptr) { return ptr.getCellRef().getRefNum(); } + inline const ObjectId& getId(const MWWorld::Ptr& ptr) + { + return ptr.getCellRef().getRefNum(); + } std::string idToString(const ObjectId& id); std::string ptrToString(const MWWorld::Ptr& ptr); bool isMarker(const MWWorld::Ptr& ptr); @@ -26,8 +29,8 @@ namespace MWLua public: ObjectRegistry() { mLastAssignedId.unset(); } - void update(); // Should be called every frame. - void clear(); // Should be called before starting or loading a new game. + void update(); // Should be called every frame. + void clear(); // Should be called before starting or loading a new game. ObjectId registerPtr(const MWWorld::Ptr& ptr); ObjectId deregisterPtr(const MWWorld::Ptr& ptr); @@ -57,7 +60,11 @@ namespace MWLua class Object { public: - Object(ObjectId id, ObjectRegistry* reg) : mId(id), mObjectRegistry(reg) {} + Object(ObjectId id, ObjectRegistry* reg) + : mId(id) + , mObjectRegistry(reg) + { + } virtual ~Object() {} ObjectId id() const { return mId; } @@ -69,8 +76,8 @@ namespace MWLua // Returns `true` if calling `ptr()` is safe. bool isValid() const; - virtual sol::object getObject(lua_State* lua, ObjectId id) const = 0; // returns LObject or GOBject - virtual sol::object getCell(lua_State* lua, MWWorld::CellStore* store) const = 0; // returns LCell or GCell + virtual sol::object getObject(lua_State* lua, ObjectId id) const = 0; // returns LObject or GOBject + virtual sol::object getCell(lua_State* lua, MWWorld::CellStore* store) const = 0; // returns LCell or GCell protected: virtual void updatePtr() const = 0; @@ -91,8 +98,14 @@ namespace MWLua { using Object::Object; void updatePtr() const final { mPtr = mObjectRegistry->getPtr(mId, true); } - sol::object getObject(lua_State* lua, ObjectId id) const final { return sol::make_object(lua, id, mObjectRegistry); } - sol::object getCell(lua_State* lua, MWWorld::CellStore* store) const final { return sol::make_object(lua, LCell{store}); } + sol::object getObject(lua_State* lua, ObjectId id) const final + { + return sol::make_object(lua, id, mObjectRegistry); + } + sol::object getCell(lua_State* lua, MWWorld::CellStore* store) const final + { + return sol::make_object(lua, LCell{ store }); + } }; // Used only in global scripts @@ -104,19 +117,31 @@ namespace MWLua { using Object::Object; void updatePtr() const final { mPtr = mObjectRegistry->getPtr(mId, false); } - sol::object getObject(lua_State* lua, ObjectId id) const final { return sol::make_object(lua, id, mObjectRegistry); } - sol::object getCell(lua_State* lua, MWWorld::CellStore* store) const final { return sol::make_object(lua, GCell{store}); } + sol::object getObject(lua_State* lua, ObjectId id) const final + { + return sol::make_object(lua, id, mObjectRegistry); + } + sol::object getCell(lua_State* lua, MWWorld::CellStore* store) const final + { + return sol::make_object(lua, GCell{ store }); + } }; using ObjectIdList = std::shared_ptr>; template - struct ObjectList { ObjectIdList mIds; }; + struct ObjectList + { + ObjectIdList mIds; + }; using GObjectList = ObjectList; using LObjectList = ObjectList; template - struct Inventory { Obj mObj; }; + struct Inventory + { + Obj mObj; + }; } -#endif // MWLUA_OBJECT_H +#endif // MWLUA_OBJECT_H diff --git a/apps/openmw/mwlua/objectbindings.cpp b/apps/openmw/mwlua/objectbindings.cpp index 85c2b01cd2..2b1d572575 100644 --- a/apps/openmw/mwlua/objectbindings.cpp +++ b/apps/openmw/mwlua/objectbindings.cpp @@ -17,29 +17,49 @@ namespace sol { template <> - struct is_automagical : std::false_type {}; + struct is_automagical : std::false_type + { + }; template <> - struct is_automagical : std::false_type {}; + struct is_automagical : std::false_type + { + }; template <> - struct is_automagical : std::false_type {}; + struct is_automagical : std::false_type + { + }; template <> - struct is_automagical : std::false_type {}; + struct is_automagical : std::false_type + { + }; template <> - struct is_automagical> : std::false_type {}; + struct is_automagical> : std::false_type + { + }; template <> - struct is_automagical> : std::false_type {}; + struct is_automagical> : std::false_type + { + }; } namespace MWLua { - namespace { + namespace + { class TeleportAction final : public LuaManager::Action { public: - TeleportAction(LuaUtil::LuaState* state, ObjectId object, std::string cell, const osg::Vec3f& pos, const osg::Vec3f& rot) - : Action(state), mObject(object), mCell(std::move(cell)), mPos(pos), mRot(rot) {} + TeleportAction(LuaUtil::LuaState* state, ObjectId object, std::string cell, const osg::Vec3f& pos, + const osg::Vec3f& rot) + : Action(state) + , mObject(object) + , mCell(std::move(cell)) + , mPos(pos) + , mRot(rot) + { + } void apply(WorldView& worldView) const override { @@ -85,7 +105,11 @@ namespace MWLua { public: ActivateAction(LuaUtil::LuaState* state, ObjectId object, ObjectId actor) - : Action(state), mObject(object), mActor(actor) {} + : Action(state) + , mObject(object) + , mActor(actor) + { + } void apply(WorldView& worldView) const override { @@ -106,15 +130,15 @@ namespace MWLua std::string toString() const override { - return std::string("ActivateAction object=") + idToString(mObject) + - std::string(" actor=") + idToString(mActor); + return std::string("ActivateAction object=") + idToString(mObject) + std::string(" actor=") + + idToString(mActor); } private: ObjectId mObject; ObjectId mActor; }; - + template using Cell = std::conditional_t, LCell, GCell>; @@ -125,11 +149,10 @@ namespace MWLua sol::state& lua = context.mLua->sol(); ObjectRegistry* registry = context.mWorldView->getObjectRegistry(); sol::usertype listT = lua.new_usertype(prefix + "ObjectList"); - listT[sol::meta_function::to_string] = - [](const ListT& list) { return "{" + std::to_string(list.mIds->size()) + " objects}"; }; + listT[sol::meta_function::to_string] + = [](const ListT& list) { return "{" + std::to_string(list.mIds->size()) + " objects}"; }; listT[sol::meta_function::length] = [](const ListT& list) { return list.mIds->size(); }; - listT[sol::meta_function::index] = [registry](const ListT& list, size_t index) - { + listT[sol::meta_function::index] = [registry](const ListT& list, size_t index) { if (index > 0 && index <= list.mIds->size()) return ObjectT((*list.mIds)[index - 1], registry); else @@ -143,65 +166,57 @@ namespace MWLua void addBasicBindings(sol::usertype& objectT, const Context& context) { objectT["isValid"] = [](const ObjectT& o) { return o.isValid(); }; - objectT["recordId"] = sol::readonly_property([](const ObjectT& o) -> std::string - { - return o.ptr().getCellRef().getRefId(); - }); - objectT["cell"] = sol::readonly_property([](const ObjectT& o) -> sol::optional> - { + objectT["recordId"] = sol::readonly_property( + [](const ObjectT& o) -> std::string { return o.ptr().getCellRef().getRefId(); }); + objectT["cell"] = sol::readonly_property([](const ObjectT& o) -> sol::optional> { const MWWorld::Ptr& ptr = o.ptr(); if (ptr.isInCell()) - return Cell{ptr.getCell()}; + return Cell{ ptr.getCell() }; else return sol::nullopt; }); - objectT["position"] = sol::readonly_property([](const ObjectT& o) -> osg::Vec3f - { - return o.ptr().getRefData().getPosition().asVec3(); - }); - objectT["rotation"] = sol::readonly_property([](const ObjectT& o) -> osg::Vec3f - { - return o.ptr().getRefData().getPosition().asRotationVec3(); - }); + objectT["position"] = sol::readonly_property( + [](const ObjectT& o) -> osg::Vec3f { return o.ptr().getRefData().getPosition().asVec3(); }); + objectT["rotation"] = sol::readonly_property( + [](const ObjectT& o) -> osg::Vec3f { return o.ptr().getRefData().getPosition().asRotationVec3(); }); - objectT["type"] = sol::readonly_property([types=getTypeToPackageTable(context.mLua->sol())](const ObjectT& o) mutable - { - return types[getLiveCellRefType(o.ptr().mRef)]; - }); + objectT["type"] = sol::readonly_property( + [types = getTypeToPackageTable(context.mLua->sol())]( + const ObjectT& o) mutable { return types[getLiveCellRefType(o.ptr().mRef)]; }); objectT["count"] = sol::readonly_property([](const ObjectT& o) { return o.ptr().getRefData().getCount(); }); objectT[sol::meta_function::equal_to] = [](const ObjectT& a, const ObjectT& b) { return a.id() == b.id(); }; objectT[sol::meta_function::to_string] = &ObjectT::toString; - objectT["sendEvent"] = [context](const ObjectT& dest, std::string eventName, const sol::object& eventData) - { - context.mLocalEventQueue->push_back({dest.id(), std::move(eventName), LuaUtil::serialize(eventData, context.mSerializer)}); + objectT["sendEvent"] = [context](const ObjectT& dest, std::string eventName, const sol::object& eventData) { + context.mLocalEventQueue->push_back( + { dest.id(), std::move(eventName), LuaUtil::serialize(eventData, context.mSerializer) }); }; - objectT["activateBy"] = [context](const ObjectT& o, const ObjectT& actor) - { + objectT["activateBy"] = [context](const ObjectT& o, const ObjectT& actor) { uint32_t esmRecordType = actor.ptr().getType(); if (esmRecordType != ESM::REC_CREA && esmRecordType != ESM::REC_NPC_) - throw std::runtime_error("The argument of `activateBy` must be an actor who activates the object. Got: " + - ptrToString(actor.ptr())); + throw std::runtime_error( + "The argument of `activateBy` must be an actor who activates the object. Got: " + + ptrToString(actor.ptr())); context.mLuaManager->addAction(std::make_unique(context.mLua, o.id(), actor.id())); }; if constexpr (std::is_same_v) - { // Only for global scripts - objectT["addScript"] = [lua=context.mLua, luaManager=context.mLuaManager](const GObject& object, std::string_view path) - { + { // Only for global scripts + objectT["addScript"] = [lua = context.mLua, luaManager = context.mLuaManager]( + const GObject& object, std::string_view path) { const LuaUtil::ScriptsConfiguration& cfg = lua->getConfiguration(); std::optional scriptId = cfg.findId(path); if (!scriptId) throw std::runtime_error("Unknown script: " + std::string(path)); if (!(cfg[*scriptId].mFlags & ESM::LuaScriptCfg::sCustom)) - throw std::runtime_error("Script without CUSTOM tag can not be added dynamically: " + std::string(path)); + throw std::runtime_error( + "Script without CUSTOM tag can not be added dynamically: " + std::string(path)); if (object.ptr().getType() == ESM::REC_STAT) throw std::runtime_error("Attaching scripts to Static is not allowed: " + std::string(path)); luaManager->addCustomLocalScript(object.ptr(), *scriptId); }; - objectT["hasScript"] = [lua=context.mLua](const GObject& object, std::string_view path) - { + objectT["hasScript"] = [lua = context.mLua](const GObject& object, std::string_view path) { const LuaUtil::ScriptsConfiguration& cfg = lua->getConfiguration(); std::optional scriptId = cfg.findId(path); if (!scriptId) @@ -213,8 +228,7 @@ namespace MWLua else return false; }; - objectT["removeScript"] = [lua=context.mLua](const GObject& object, std::string_view path) - { + objectT["removeScript"] = [lua = context.mLua](const GObject& object, std::string_view path) { const LuaUtil::ScriptsConfiguration& cfg = lua->getConfiguration(); std::optional scriptId = cfg.findId(path); if (!scriptId) @@ -228,12 +242,12 @@ namespace MWLua localScripts->removeScript(*scriptId); }; - objectT["teleport"] = [context](const GObject& object, std::string_view cell, - const osg::Vec3f& pos, const sol::optional& optRot) - { + objectT["teleport"] = [context](const GObject& object, std::string_view cell, const osg::Vec3f& pos, + const sol::optional& optRot) { MWWorld::Ptr ptr = object.ptr(); osg::Vec3f rot = optRot ? *optRot : ptr.getRefData().getPosition().asRotationVec3(); - auto action = std::make_unique(context.mLua, object.id(), std::string(cell), pos, rot); + auto action + = std::make_unique(context.mLua, object.id(), std::string(cell), pos, rot); if (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr()) context.mLuaManager->addTeleportPlayerAction(std::move(action)); else @@ -248,12 +262,11 @@ namespace MWLua using InventoryT = Inventory; sol::usertype inventoryT = context.mLua->sol().new_usertype(prefix + "Inventory"); - inventoryT[sol::meta_function::to_string] = - [](const InventoryT& inv) { return "Inventory[" + inv.mObj.toString() + "]"; }; + inventoryT[sol::meta_function::to_string] + = [](const InventoryT& inv) { return "Inventory[" + inv.mObj.toString() + "]"; }; - inventoryT["getAll"] = [worldView=context.mWorldView, ids=getPackageToTypeTable(context.mLua->sol())]( - const InventoryT& inventory, sol::optional type) - { + inventoryT["getAll"] = [worldView = context.mWorldView, ids = getPackageToTypeTable(context.mLua->sol())]( + const InventoryT& inventory, sol::optional type) { int mask = -1; sol::optional typeId = sol::nullopt; if (type.has_value()) @@ -265,24 +278,49 @@ namespace MWLua { switch (*typeId) { - case ESM::REC_ALCH: mask = MWWorld::ContainerStore::Type_Potion; break; - case ESM::REC_ARMO: mask = MWWorld::ContainerStore::Type_Armor; break; - case ESM::REC_BOOK: mask = MWWorld::ContainerStore::Type_Book; break; - case ESM::REC_CLOT: mask = MWWorld::ContainerStore::Type_Clothing; break; - case ESM::REC_INGR: mask = MWWorld::ContainerStore::Type_Ingredient; break; - case ESM::REC_LIGH: mask = MWWorld::ContainerStore::Type_Light; break; - case ESM::REC_MISC: mask = MWWorld::ContainerStore::Type_Miscellaneous; break; - case ESM::REC_WEAP: mask = MWWorld::ContainerStore::Type_Weapon; break; - case ESM::REC_APPA: mask = MWWorld::ContainerStore::Type_Apparatus; break; - case ESM::REC_LOCK: mask = MWWorld::ContainerStore::Type_Lockpick; break; - case ESM::REC_PROB: mask = MWWorld::ContainerStore::Type_Probe; break; - case ESM::REC_REPA: mask = MWWorld::ContainerStore::Type_Repair; break; + case ESM::REC_ALCH: + mask = MWWorld::ContainerStore::Type_Potion; + break; + case ESM::REC_ARMO: + mask = MWWorld::ContainerStore::Type_Armor; + break; + case ESM::REC_BOOK: + mask = MWWorld::ContainerStore::Type_Book; + break; + case ESM::REC_CLOT: + mask = MWWorld::ContainerStore::Type_Clothing; + break; + case ESM::REC_INGR: + mask = MWWorld::ContainerStore::Type_Ingredient; + break; + case ESM::REC_LIGH: + mask = MWWorld::ContainerStore::Type_Light; + break; + case ESM::REC_MISC: + mask = MWWorld::ContainerStore::Type_Miscellaneous; + break; + case ESM::REC_WEAP: + mask = MWWorld::ContainerStore::Type_Weapon; + break; + case ESM::REC_APPA: + mask = MWWorld::ContainerStore::Type_Apparatus; + break; + case ESM::REC_LOCK: + mask = MWWorld::ContainerStore::Type_Lockpick; + break; + case ESM::REC_PROB: + mask = MWWorld::ContainerStore::Type_Probe; + break; + case ESM::REC_REPA: + mask = MWWorld::ContainerStore::Type_Repair; + break; default:; } } if (mask == -1) - throw std::runtime_error(std::string("Incorrect type argument in inventory:getAll: " + LuaUtil::toString(*type))); + throw std::runtime_error( + std::string("Incorrect type argument in inventory:getAll: " + LuaUtil::toString(*type))); const MWWorld::Ptr& ptr = inventory.mObj.ptr(); MWWorld::ContainerStore& store = ptr.getClass().getContainerStore(ptr); @@ -294,23 +332,22 @@ namespace MWLua worldView->getObjectRegistry()->registerPtr(item); list->push_back(getId(item)); } - return ObjectList{list}; + return ObjectList{ list }; }; - inventoryT["countOf"] = [](const InventoryT& inventory, const std::string& recordId) - { + inventoryT["countOf"] = [](const InventoryT& inventory, const std::string& recordId) { const MWWorld::Ptr& ptr = inventory.mObj.ptr(); MWWorld::ContainerStore& store = ptr.getClass().getContainerStore(ptr); return store.count(recordId); }; if constexpr (std::is_same_v) - { // Only for global scripts - // TODO - // obj.inventory:drop(obj2, [count]) - // obj.inventory:drop(recordId, [count]) - // obj.inventory:addNew(recordId, [count]) - // obj.inventory:remove(obj/recordId, [count]) + { // Only for global scripts + // TODO + // obj.inventory:drop(obj2, [count]) + // obj.inventory:drop(recordId, [count]) + // obj.inventory:addNew(recordId, [count]) + // obj.inventory:remove(obj/recordId, [count]) /*objectT["moveInto"] = [](const GObject& obj, const InventoryT& inventory) {}; inventoryT["drop"] = [](const InventoryT& inventory) {}; inventoryT["addNew"] = [](const InventoryT& inventory) {}; @@ -321,14 +358,14 @@ namespace MWLua template void initObjectBindings(const std::string& prefix, const Context& context) { - sol::usertype objectT = context.mLua->sol().new_usertype( - prefix + "Object", sol::base_classes, sol::bases()); + sol::usertype objectT + = context.mLua->sol().new_usertype(prefix + "Object", sol::base_classes, sol::bases()); addBasicBindings(objectT, context); addInventoryBindings(objectT, prefix, context); registerObjectList(prefix, context); } - } // namespace + } // namespace void initObjectBindingsForLocalScripts(const Context& context) { diff --git a/apps/openmw/mwlua/playerscripts.hpp b/apps/openmw/mwlua/playerscripts.hpp index b8173f6b7b..577e93a553 100644 --- a/apps/openmw/mwlua/playerscripts.hpp +++ b/apps/openmw/mwlua/playerscripts.hpp @@ -15,14 +15,12 @@ namespace MWLua class PlayerScripts : public LocalScripts { public: - PlayerScripts(LuaUtil::LuaState* lua, const LObject& obj) : LocalScripts(lua, obj) + PlayerScripts(LuaUtil::LuaState* lua, const LObject& obj) + : LocalScripts(lua, obj) { - registerEngineHandlers({ - &mConsoleCommandHandlers, &mKeyPressHandlers, &mKeyReleaseHandlers, - &mControllerButtonPressHandlers, &mControllerButtonReleaseHandlers, - &mActionHandlers, &mOnFrameHandlers, - &mTouchpadPressed, &mTouchpadReleased, &mTouchpadMoved - }); + registerEngineHandlers({ &mConsoleCommandHandlers, &mKeyPressHandlers, &mKeyReleaseHandlers, + &mControllerButtonPressHandlers, &mControllerButtonReleaseHandlers, &mActionHandlers, &mOnFrameHandlers, + &mTouchpadPressed, &mTouchpadReleased, &mTouchpadMoved }); } void processInputEvent(const MWBase::LuaManager::InputEvent& event) @@ -30,49 +28,50 @@ namespace MWLua using InputEvent = MWBase::LuaManager::InputEvent; switch (event.mType) { - case InputEvent::KeyPressed: - callEngineHandlers(mKeyPressHandlers, std::get(event.mValue)); - break; - case InputEvent::KeyReleased: - callEngineHandlers(mKeyReleaseHandlers, std::get(event.mValue)); - break; - case InputEvent::ControllerPressed: - callEngineHandlers(mControllerButtonPressHandlers, std::get(event.mValue)); - break; - case InputEvent::ControllerReleased: - callEngineHandlers(mControllerButtonReleaseHandlers, std::get(event.mValue)); - break; - case InputEvent::Action: - callEngineHandlers(mActionHandlers, std::get(event.mValue)); - break; - case InputEvent::TouchPressed: - callEngineHandlers(mTouchpadPressed, std::get(event.mValue)); - break; - case InputEvent::TouchReleased: - callEngineHandlers(mTouchpadReleased, std::get(event.mValue)); - break; - case InputEvent::TouchMoved: - callEngineHandlers(mTouchpadMoved, std::get(event.mValue)); - break; + case InputEvent::KeyPressed: + callEngineHandlers(mKeyPressHandlers, std::get(event.mValue)); + break; + case InputEvent::KeyReleased: + callEngineHandlers(mKeyReleaseHandlers, std::get(event.mValue)); + break; + case InputEvent::ControllerPressed: + callEngineHandlers(mControllerButtonPressHandlers, std::get(event.mValue)); + break; + case InputEvent::ControllerReleased: + callEngineHandlers(mControllerButtonReleaseHandlers, std::get(event.mValue)); + break; + case InputEvent::Action: + callEngineHandlers(mActionHandlers, std::get(event.mValue)); + break; + case InputEvent::TouchPressed: + callEngineHandlers(mTouchpadPressed, std::get(event.mValue)); + break; + case InputEvent::TouchReleased: + callEngineHandlers(mTouchpadReleased, std::get(event.mValue)); + break; + case InputEvent::TouchMoved: + callEngineHandlers(mTouchpadMoved, std::get(event.mValue)); + break; } } void onFrame(float dt) { callEngineHandlers(mOnFrameHandlers, dt); } - bool consoleCommand(const std::string& consoleMode, const std::string& command, const sol::object& selectedObject) + bool consoleCommand( + const std::string& consoleMode, const std::string& command, const sol::object& selectedObject) { callEngineHandlers(mConsoleCommandHandlers, consoleMode, command, selectedObject); return !mConsoleCommandHandlers.mList.empty(); } private: - EngineHandlerList mConsoleCommandHandlers{"onConsoleCommand"}; - EngineHandlerList mKeyPressHandlers{"onKeyPress"}; - EngineHandlerList mKeyReleaseHandlers{"onKeyRelease"}; - EngineHandlerList mControllerButtonPressHandlers{"onControllerButtonPress"}; - EngineHandlerList mControllerButtonReleaseHandlers{"onControllerButtonRelease"}; - EngineHandlerList mActionHandlers{"onInputAction"}; - EngineHandlerList mOnFrameHandlers{"onFrame"}; + EngineHandlerList mConsoleCommandHandlers{ "onConsoleCommand" }; + EngineHandlerList mKeyPressHandlers{ "onKeyPress" }; + EngineHandlerList mKeyReleaseHandlers{ "onKeyRelease" }; + EngineHandlerList mControllerButtonPressHandlers{ "onControllerButtonPress" }; + EngineHandlerList mControllerButtonReleaseHandlers{ "onControllerButtonRelease" }; + EngineHandlerList mActionHandlers{ "onInputAction" }; + EngineHandlerList mOnFrameHandlers{ "onFrame" }; EngineHandlerList mTouchpadPressed{ "onTouchPress" }; EngineHandlerList mTouchpadReleased{ "onTouchRelease" }; EngineHandlerList mTouchpadMoved{ "onTouchMove" }; diff --git a/apps/openmw/mwlua/postprocessingbindings.cpp b/apps/openmw/mwlua/postprocessingbindings.cpp index 8ae9cd10a8..96e4ac27d3 100644 --- a/apps/openmw/mwlua/postprocessingbindings.cpp +++ b/apps/openmw/mwlua/postprocessingbindings.cpp @@ -11,8 +11,14 @@ namespace class SetUniformShaderAction final : public MWLua::LuaManager::Action { public: - SetUniformShaderAction(LuaUtil::LuaState* state, std::shared_ptr shader, const std::string& name, const T& value) - : MWLua::LuaManager::Action(state), mShader(std::move(shader)), mName(name), mValue(value) {} + SetUniformShaderAction( + LuaUtil::LuaState* state, std::shared_ptr shader, const std::string& name, const T& value) + : MWLua::LuaManager::Action(state) + , mShader(std::move(shader)) + , mName(name) + , mValue(value) + { + } void apply(MWLua::WorldView&) const override { @@ -21,8 +27,8 @@ namespace std::string toString() const override { - return std::string("SetUniformShaderAction shader=") + (mShader ? mShader->getName() : "nil") + - std::string("uniform=") + (mShader ? mName : "nil"); + return std::string("SetUniformShaderAction shader=") + (mShader ? mShader->getName() : "nil") + + std::string("uniform=") + (mShader ? mName : "nil"); } private: @@ -40,7 +46,9 @@ namespace MWLua namespace sol { template <> - struct is_automagical : std::false_type {}; + struct is_automagical : std::false_type + { + }; } namespace MWLua @@ -49,7 +57,10 @@ namespace MWLua { std::shared_ptr mShader; - Shader(std::shared_ptr shader) : mShader(std::move(shader)) {} + Shader(std::shared_ptr shader) + : mShader(std::move(shader)) + { + } std::string toString() const { @@ -59,14 +70,21 @@ namespace MWLua return Misc::StringUtils::format("Shader(%s, %s)", mShader->getName(), mShader->getFileName()); } - enum { Action_None, Action_Enable, Action_Disable } mQueuedAction = Action_None; + enum + { + Action_None, + Action_Enable, + Action_Disable + } mQueuedAction + = Action_None; }; template auto getSetter(const Context& context) { return [context](const Shader& shader, const std::string& name, const T& value) { - context.mLuaManager->addAction(std::make_unique>(context.mLua, shader.mShader, name, value)); + context.mLuaManager->addAction( + std::make_unique>(context.mLua, shader.mShader, name, value)); }; } @@ -74,26 +92,29 @@ namespace MWLua auto getArraySetter(const Context& context) { return [context](const Shader& shader, const std::string& name, const sol::table& table) { - auto targetSize = MWBase::Environment::get().getWorld()->getPostProcessor()->getUniformSize(shader.mShader, name); + auto targetSize + = MWBase::Environment::get().getWorld()->getPostProcessor()->getUniformSize(shader.mShader, name); if (!targetSize.has_value()) throw std::runtime_error(Misc::StringUtils::format("Failed setting uniform array '%s'", name)); if (*targetSize != table.size()) - throw std::runtime_error(Misc::StringUtils::format("Mismatching uniform array size, got %zu expected %zu", table.size(), *targetSize)); + throw std::runtime_error(Misc::StringUtils::format( + "Mismatching uniform array size, got %zu expected %zu", table.size(), *targetSize)); std::vector values; values.reserve(*targetSize); for (size_t i = 0; i < *targetSize; ++i) { - sol::object obj = table[i+1]; + sol::object obj = table[i + 1]; if (!obj.is()) throw std::runtime_error("Invalid type for uniform array"); values.push_back(obj.as()); } - context.mLuaManager->addAction(std::make_unique>>(context.mLua, shader.mShader, name, values)); + context.mLuaManager->addAction( + std::make_unique>>(context.mLua, shader.mShader, name, values)); }; } @@ -104,8 +125,7 @@ namespace MWLua sol::usertype shader = context.mLua->sol().new_usertype("Shader"); shader[sol::meta_function::to_string] = [](const Shader& shader) { return shader.toString(); }; - shader["enable"] = [context](Shader& shader, sol::optional optPos) - { + shader["enable"] = [context](Shader& shader, sol::optional optPos) { std::optional pos = std::nullopt; if (optPos) pos = optPos.value(); @@ -113,32 +133,28 @@ namespace MWLua if (shader.mShader && shader.mShader->isValid()) shader.mQueuedAction = Shader::Action_Enable; - context.mLuaManager->addAction( - [=, &shader] { - shader.mQueuedAction = Shader::Action_None; + context.mLuaManager->addAction([=, &shader] { + shader.mQueuedAction = Shader::Action_None; - if (MWBase::Environment::get().getWorld()->getPostProcessor()->enableTechnique(shader.mShader, pos) == MWRender::PostProcessor::Status_Error) - throw std::runtime_error("Failed enabling shader '" + shader.mShader->getName() + "'"); - } - ); + if (MWBase::Environment::get().getWorld()->getPostProcessor()->enableTechnique(shader.mShader, pos) + == MWRender::PostProcessor::Status_Error) + throw std::runtime_error("Failed enabling shader '" + shader.mShader->getName() + "'"); + }); }; - shader["disable"] = [context](Shader& shader) - { + shader["disable"] = [context](Shader& shader) { shader.mQueuedAction = Shader::Action_Disable; - context.mLuaManager->addAction( - [&] { - shader.mQueuedAction = Shader::Action_None; + context.mLuaManager->addAction([&] { + shader.mQueuedAction = Shader::Action_None; - if (MWBase::Environment::get().getWorld()->getPostProcessor()->disableTechnique(shader.mShader) == MWRender::PostProcessor::Status_Error) - throw std::runtime_error("Failed disabling shader '" + shader.mShader->getName() + "'"); - } - ); + if (MWBase::Environment::get().getWorld()->getPostProcessor()->disableTechnique(shader.mShader) + == MWRender::PostProcessor::Status_Error) + throw std::runtime_error("Failed disabling shader '" + shader.mShader->getName() + "'"); + }); }; - shader["isEnabled"] = [](const Shader& shader) - { + shader["isEnabled"] = [](const Shader& shader) { if (shader.mQueuedAction == Shader::Action_Enable) return true; else if (shader.mQueuedAction == Shader::Action_Disable) @@ -159,9 +175,8 @@ namespace MWLua shader["setVector3Array"] = getArraySetter(context); shader["setVector4Array"] = getArraySetter(context); - api["load"] = [](const std::string& name) - { - Shader shader{MWBase::Environment::get().getWorld()->getPostProcessor()->loadTechnique(name, false)}; + api["load"] = [](const std::string& name) { + Shader shader{ MWBase::Environment::get().getWorld()->getPostProcessor()->loadTechnique(name, false) }; if (!shader.mShader || !shader.mShader->isValid()) throw std::runtime_error(Misc::StringUtils::format("Failed loading shader '%s'", name)); diff --git a/apps/openmw/mwlua/stats.cpp b/apps/openmw/mwlua/stats.cpp index 83bce35cca..977d3b3eec 100644 --- a/apps/openmw/mwlua/stats.cpp +++ b/apps/openmw/mwlua/stats.cpp @@ -6,12 +6,12 @@ #include #include -#include #include +#include +#include "context.hpp" #include "localscripts.hpp" #include "luamanagerimp.hpp" -#include "context.hpp" #include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/npcstats.hpp" @@ -20,21 +20,18 @@ namespace { - template + template auto addIndexedAccessor(int index) { - return sol::overload( - [index](MWLua::LocalScripts::SelfObject& o) { return T::create(&o, index); }, + return sol::overload([index](MWLua::LocalScripts::SelfObject& o) { return T::create(&o, index); }, [index](const MWLua::LObject& o) { return T::create(o, index); }, - [index](const MWLua::GObject& o) { return T::create(o, index); } - ); + [index](const MWLua::GObject& o) { return T::create(o, index); }); } - template + template void addProp(const MWLua::Context& context, sol::usertype& type, std::string_view prop, G getter) { - type[prop] = sol::property( - [=](const T& stat) { return stat.get(context, prop, getter); }, + type[prop] = sol::property([=](const T& stat) { return stat.get(context, prop, getter); }, [=](const T& stat, const sol::object& value) { stat.cache(context, prop, value); }); } @@ -43,36 +40,39 @@ namespace const MWLua::Object* getObject(const StatObject& obj) { - return std::visit([] (auto&& variant) -> const MWLua::Object* - { - using T = std::decay_t; - if constexpr(std::is_same_v) - return variant; - else if constexpr(std::is_same_v) - return &variant; - else if constexpr(std::is_same_v) - return &variant; - }, obj); + return std::visit( + [](auto&& variant) -> const MWLua::Object* { + using T = std::decay_t; + if constexpr (std::is_same_v) + return variant; + else if constexpr (std::is_same_v) + return &variant; + else if constexpr (std::is_same_v) + return &variant; + }, + obj); } - template - sol::object getValue(const MWLua::Context& context, const StatObject& obj, SelfObject::CachedStat::Setter setter, int index, std::string_view prop, G getter) + template + sol::object getValue(const MWLua::Context& context, const StatObject& obj, SelfObject::CachedStat::Setter setter, + int index, std::string_view prop, G getter) { - return std::visit([&] (auto&& variant) - { - using T = std::decay_t; - if constexpr(std::is_same_v) - { - auto it = variant->mStatsCache.find({ setter, index, prop }); - if(it != variant->mStatsCache.end()) - return it->second; - return sol::make_object(context.mLua->sol(), getter(variant)); - } - else if constexpr(std::is_same_v) - return sol::make_object(context.mLua->sol(), getter(&variant)); - else if constexpr(std::is_same_v) - return sol::make_object(context.mLua->sol(), getter(&variant)); - }, obj); + return std::visit( + [&](auto&& variant) { + using T = std::decay_t; + if constexpr (std::is_same_v) + { + auto it = variant->mStatsCache.find({ setter, index, prop }); + if (it != variant->mStatsCache.end()) + return it->second; + return sol::make_object(context.mLua->sol(), getter(variant)); + } + else if constexpr (std::is_same_v) + return sol::make_object(context.mLua->sol(), getter(&variant)); + else if constexpr (std::is_same_v) + return sol::make_object(context.mLua->sol(), getter(&variant)); + }, + obj); } } @@ -83,8 +83,13 @@ namespace MWLua class StatUpdateAction final : public LuaManager::Action { ObjectId mId; + public: - StatUpdateAction(LuaUtil::LuaState* state, ObjectId id) : Action(state), mId(id) {} + StatUpdateAction(LuaUtil::LuaState* state, ObjectId id) + : Action(state) + , mId(id) + { + } void apply(WorldView& worldView) const override { @@ -102,12 +107,15 @@ namespace MWLua { StatObject mObject; - LevelStat(StatObject object) : mObject(std::move(object)) {} + LevelStat(StatObject object) + : mObject(std::move(object)) + { + } + public: sol::object getCurrent(const Context& context) const { - return getValue(context, mObject, &LevelStat::setValue, 0, "current", [](const MWLua::Object* obj) - { + return getValue(context, mObject, &LevelStat::setValue, 0, "current", [](const MWLua::Object* obj) { const auto& ptr = obj->ptr(); return ptr.getClass().getCreatureStats(ptr).getLevel(); }); @@ -116,30 +124,30 @@ namespace MWLua void setCurrent(const Context& context, const sol::object& value) const { SelfObject* obj = std::get(mObject); - if(obj->mStatsCache.empty()) + if (obj->mStatsCache.empty()) context.mLuaManager->addAction(std::make_unique(context.mLua, obj->id())); - obj->mStatsCache[SelfObject::CachedStat{&LevelStat::setValue, 0, "current"}] = value; + obj->mStatsCache[SelfObject::CachedStat{ &LevelStat::setValue, 0, "current" }] = value; } sol::object getProgress(const Context& context) const { const auto& ptr = getObject(mObject)->ptr(); - if(!ptr.getClass().isNpc()) + if (!ptr.getClass().isNpc()) return sol::nil; return sol::make_object(context.mLua->sol(), ptr.getClass().getNpcStats(ptr).getLevelProgress()); } static std::optional create(StatObject object, int index) { - if(!getObject(object)->ptr().getClass().isActor()) + if (!getObject(object)->ptr().getClass().isActor()) return {}; - return LevelStat{std::move(object)}; + return LevelStat{ std::move(object) }; } static void setValue(int, std::string_view prop, const MWWorld::Ptr& ptr, const sol::object& value) { auto& stats = ptr.getClass().getCreatureStats(ptr); - if(prop == "current") + if (prop == "current") stats.setLevel(value.as()); } }; @@ -149,31 +157,36 @@ namespace MWLua StatObject mObject; int mIndex; - DynamicStat(StatObject object, int index) : mObject(std::move(object)), mIndex(index) {} + DynamicStat(StatObject object, int index) + : mObject(std::move(object)) + , mIndex(index) + { + } + public: - template + template sol::object get(const Context& context, std::string_view prop, G getter) const { - return getValue(context, mObject, &DynamicStat::setValue, mIndex, prop, [this, getter](const MWLua::Object* obj) - { - const auto& ptr = obj->ptr(); - return (ptr.getClass().getCreatureStats(ptr).getDynamic(mIndex).*getter)(); - }); + return getValue( + context, mObject, &DynamicStat::setValue, mIndex, prop, [this, getter](const MWLua::Object* obj) { + const auto& ptr = obj->ptr(); + return (ptr.getClass().getCreatureStats(ptr).getDynamic(mIndex).*getter)(); + }); } static std::optional create(StatObject object, int index) { - if(!getObject(object)->ptr().getClass().isActor()) + if (!getObject(object)->ptr().getClass().isActor()) return {}; - return DynamicStat{std::move(object), index}; + return DynamicStat{ std::move(object), index }; } void cache(const Context& context, std::string_view prop, const sol::object& value) const { SelfObject* obj = std::get(mObject); - if(obj->mStatsCache.empty()) + if (obj->mStatsCache.empty()) context.mLuaManager->addAction(std::make_unique(context.mLua, obj->id())); - obj->mStatsCache[SelfObject::CachedStat{&DynamicStat::setValue, mIndex, prop}] = value; + obj->mStatsCache[SelfObject::CachedStat{ &DynamicStat::setValue, mIndex, prop }] = value; } static void setValue(int index, std::string_view prop, const MWWorld::Ptr& ptr, const sol::object& value) @@ -181,11 +194,11 @@ namespace MWLua auto& stats = ptr.getClass().getCreatureStats(ptr); auto stat = stats.getDynamic(index); float floatValue = value.as(); - if(prop == "base") + if (prop == "base") stat.setBase(floatValue); - else if(prop == "current") + else if (prop == "current") stat.setCurrent(floatValue, true, true); - else if(prop == "modifier") + else if (prop == "modifier") stat.setModifier(floatValue); stats.setDynamic(index, stat); } @@ -196,16 +209,21 @@ namespace MWLua StatObject mObject; int mIndex; - AttributeStat(StatObject object, int index) : mObject(std::move(object)), mIndex(index) {} + AttributeStat(StatObject object, int index) + : mObject(std::move(object)) + , mIndex(index) + { + } + public: - template + template sol::object get(const Context& context, std::string_view prop, G getter) const { - return getValue(context, mObject, &AttributeStat::setValue, mIndex, prop, [this, getter](const MWLua::Object* obj) - { - const auto& ptr = obj->ptr(); - return (ptr.getClass().getCreatureStats(ptr).getAttribute(mIndex).*getter)(); - }); + return getValue( + context, mObject, &AttributeStat::setValue, mIndex, prop, [this, getter](const MWLua::Object* obj) { + const auto& ptr = obj->ptr(); + return (ptr.getClass().getCreatureStats(ptr).getAttribute(mIndex).*getter)(); + }); } float getModified(const Context& context) const @@ -218,17 +236,17 @@ namespace MWLua static std::optional create(StatObject object, int index) { - if(!getObject(object)->ptr().getClass().isActor()) + if (!getObject(object)->ptr().getClass().isActor()) return {}; - return AttributeStat{std::move(object), index}; + return AttributeStat{ std::move(object), index }; } void cache(const Context& context, std::string_view prop, const sol::object& value) const { SelfObject* obj = std::get(mObject); - if(obj->mStatsCache.empty()) + if (obj->mStatsCache.empty()) context.mLuaManager->addAction(std::make_unique(context.mLua, obj->id())); - obj->mStatsCache[SelfObject::CachedStat{&AttributeStat::setValue, mIndex, prop}] = value; + obj->mStatsCache[SelfObject::CachedStat{ &AttributeStat::setValue, mIndex, prop }] = value; } static void setValue(int index, std::string_view prop, const MWWorld::Ptr& ptr, const sol::object& value) @@ -236,14 +254,14 @@ namespace MWLua auto& stats = ptr.getClass().getCreatureStats(ptr); auto stat = stats.getAttribute(index); float floatValue = value.as(); - if(prop == "base") + if (prop == "base") stat.setBase(floatValue); - else if(prop == "damage") + else if (prop == "damage") { stat.restore(stat.getDamage()); stat.damage(floatValue); } - else if(prop == "modifier") + else if (prop == "modifier") stat.setModifier(floatValue); stats.setAttribute(index, stat); } @@ -254,30 +272,36 @@ namespace MWLua StatObject mObject; int mIndex; - SkillStat(StatObject object, int index) : mObject(std::move(object)), mIndex(index) {} + SkillStat(StatObject object, int index) + : mObject(std::move(object)) + , mIndex(index) + { + } static float getProgress(const MWWorld::Ptr& ptr, int index, const MWMechanics::SkillValue& stat) { float progress = stat.getProgress(); - if(progress != 0.f) + if (progress != 0.f) progress /= getMaxProgress(ptr, index, stat); return progress; } - static float getMaxProgress(const MWWorld::Ptr& ptr, int index, const MWMechanics::SkillValue& stat) { + static float getMaxProgress(const MWWorld::Ptr& ptr, int index, const MWMechanics::SkillValue& stat) + { const auto& store = MWBase::Environment::get().getWorld()->getStore(); const auto cl = store.get().find(ptr.get()->mBase->mClass); return ptr.getClass().getNpcStats(ptr).getSkillProgressRequirement(index, *cl); } + public: - template + template sol::object get(const Context& context, std::string_view prop, G getter) const { - return getValue(context, mObject, &SkillStat::setValue, mIndex, prop, [this, getter](const MWLua::Object* obj) - { - const auto& ptr = obj->ptr(); - return (ptr.getClass().getNpcStats(ptr).getSkill(mIndex).*getter)(); - }); + return getValue( + context, mObject, &SkillStat::setValue, mIndex, prop, [this, getter](const MWLua::Object* obj) { + const auto& ptr = obj->ptr(); + return (ptr.getClass().getNpcStats(ptr).getSkill(mIndex).*getter)(); + }); } float getModified(const Context& context) const @@ -290,26 +314,26 @@ namespace MWLua sol::object getProgress(const Context& context) const { - return getValue(context, mObject, &SkillStat::setValue, mIndex, "progress", [this](const MWLua::Object* obj) - { - const auto& ptr = obj->ptr(); - return getProgress(ptr, mIndex, ptr.getClass().getNpcStats(ptr).getSkill(mIndex)); - }); + return getValue( + context, mObject, &SkillStat::setValue, mIndex, "progress", [this](const MWLua::Object* obj) { + const auto& ptr = obj->ptr(); + return getProgress(ptr, mIndex, ptr.getClass().getNpcStats(ptr).getSkill(mIndex)); + }); } static std::optional create(StatObject object, int index) { - if(!getObject(object)->ptr().getClass().isNpc()) + if (!getObject(object)->ptr().getClass().isNpc()) return {}; - return SkillStat{std::move(object), index}; + return SkillStat{ std::move(object), index }; } void cache(const Context& context, std::string_view prop, const sol::object& value) const { SelfObject* obj = std::get(mObject); - if(obj->mStatsCache.empty()) + if (obj->mStatsCache.empty()) context.mLuaManager->addAction(std::make_unique(context.mLua, obj->id())); - obj->mStatsCache[SelfObject::CachedStat{&SkillStat::setValue, mIndex, prop}] = value; + obj->mStatsCache[SelfObject::CachedStat{ &SkillStat::setValue, mIndex, prop }] = value; } static void setValue(int index, std::string_view prop, const MWWorld::Ptr& ptr, const sol::object& value) @@ -317,16 +341,16 @@ namespace MWLua auto& stats = ptr.getClass().getNpcStats(ptr); auto stat = stats.getSkill(index); float floatValue = value.as(); - if(prop == "base") + if (prop == "base") stat.setBase(floatValue); - else if(prop == "damage") + else if (prop == "damage") { stat.restore(stat.getDamage()); stat.damage(floatValue); } - else if(prop == "modifier") + else if (prop == "modifier") stat.setModifier(floatValue); - else if(prop == "progress") + else if (prop == "progress") stat.setProgress(floatValue * getMaxProgress(ptr, index, stat)); stats.setSkill(index, stat); } @@ -336,13 +360,21 @@ namespace MWLua namespace sol { template <> - struct is_automagical : std::false_type {}; + struct is_automagical : std::false_type + { + }; template <> - struct is_automagical : std::false_type {}; + struct is_automagical : std::false_type + { + }; template <> - struct is_automagical : std::false_type {}; + struct is_automagical : std::false_type + { + }; template <> - struct is_automagical : std::false_type {}; + struct is_automagical : std::false_type + { + }; } namespace MWLua @@ -353,8 +385,7 @@ namespace MWLua actor["stats"] = LuaUtil::makeReadOnly(stats); auto levelStatT = context.mLua->sol().new_usertype("LevelStat"); - levelStatT["current"] = sol::property( - [context](const LevelStat& stat) { return stat.getCurrent(context); }, + levelStatT["current"] = sol::property([context](const LevelStat& stat) { return stat.getCurrent(context); }, [context](const LevelStat& stat, const sol::object& value) { stat.setCurrent(context, value); }); levelStatT["progress"] = sol::property([context](const LevelStat& stat) { return stat.getProgress(context); }); stats["level"] = addIndexedAccessor(0); @@ -372,12 +403,14 @@ namespace MWLua auto attributeStatT = context.mLua->sol().new_usertype("AttributeStat"); addProp(context, attributeStatT, "base", &MWMechanics::AttributeValue::getBase); addProp(context, attributeStatT, "damage", &MWMechanics::AttributeValue::getDamage); - attributeStatT["modified"] = sol::property([=](const AttributeStat& stat) { return stat.getModified(context); }); + attributeStatT["modified"] + = sol::property([=](const AttributeStat& stat) { return stat.getModified(context); }); addProp(context, attributeStatT, "modifier", &MWMechanics::AttributeValue::getModifier); sol::table attributes(context.mLua->sol(), sol::create); stats["attributes"] = LuaUtil::makeReadOnly(attributes); - for(int id = ESM::Attribute::Strength; id < ESM::Attribute::Length; ++id) - attributes[Misc::StringUtils::lowerCase(ESM::Attribute::sAttributeNames[id])] = addIndexedAccessor(id); + for (int id = ESM::Attribute::Strength; id < ESM::Attribute::Length; ++id) + attributes[Misc::StringUtils::lowerCase(ESM::Attribute::sAttributeNames[id])] + = addIndexedAccessor(id); } void addNpcStatsBindings(sol::table& npc, const Context& context) @@ -393,12 +426,11 @@ namespace MWLua addProp(context, skillStatT, "damage", &MWMechanics::SkillValue::getDamage); skillStatT["modified"] = sol::property([=](const SkillStat& stat) { return stat.getModified(context); }); addProp(context, skillStatT, "modifier", &MWMechanics::SkillValue::getModifier); - skillStatT["progress"] = sol::property( - [context](const SkillStat& stat) { return stat.getProgress(context); }, + skillStatT["progress"] = sol::property([context](const SkillStat& stat) { return stat.getProgress(context); }, [context](const SkillStat& stat, const sol::object& value) { stat.cache(context, "progress", value); }); sol::table skills(context.mLua->sol(), sol::create); npcStats["skills"] = LuaUtil::makeReadOnly(skills); - for(int id = ESM::Skill::Block; id < ESM::Skill::Length; ++id) + for (int id = ESM::Skill::Block; id < ESM::Skill::Length; ++id) skills[Misc::StringUtils::lowerCase(ESM::Skill::sSkillNames[id])] = addIndexedAccessor(id); } } diff --git a/apps/openmw/mwlua/types/activator.cpp b/apps/openmw/mwlua/types/activator.cpp index 6618b0f7ea..e9f1a8494b 100644 --- a/apps/openmw/mwlua/types/activator.cpp +++ b/apps/openmw/mwlua/types/activator.cpp @@ -1,18 +1,20 @@ #include "types.hpp" #include +#include #include #include -#include -#include #include #include +#include namespace sol { template <> - struct is_automagical : std::false_type {}; + struct is_automagical : std::false_type + { + }; } namespace MWLua @@ -21,18 +23,20 @@ namespace MWLua { auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); - const MWWorld::Store* store = &MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store* store + = &MWBase::Environment::get().getWorld()->getStore().get(); activator["record"] = sol::overload( [](const Object& obj) -> const ESM::Activator* { return obj.ptr().get()->mBase; }, [store](const std::string& recordId) -> const ESM::Activator* { return store->find(recordId); }); sol::usertype record = context.mLua->sol().new_usertype("ESM3_Activator"); - record[sol::meta_function::to_string] = [](const ESM::Activator& rec) { return "ESM3_Activator[" + rec.mId + "]"; }; + record[sol::meta_function::to_string] + = [](const ESM::Activator& rec) { return "ESM3_Activator[" + rec.mId + "]"; }; record["id"] = sol::readonly_property([](const ESM::Activator& rec) -> std::string { return rec.mId; }); record["name"] = sol::readonly_property([](const ESM::Activator& rec) -> std::string { return rec.mName; }); - record["model"] = sol::readonly_property([vfs](const ESM::Activator& rec) -> std::string - { + record["model"] = sol::readonly_property([vfs](const ESM::Activator& rec) -> std::string { return Misc::ResourceHelpers::correctMeshPath(rec.mModel, vfs); }); - record["mwscript"] = sol::readonly_property([](const ESM::Activator& rec) -> std::string { return rec.mScript; }); + record["mwscript"] + = sol::readonly_property([](const ESM::Activator& rec) -> std::string { return rec.mScript; }); } } diff --git a/apps/openmw/mwlua/types/actor.cpp b/apps/openmw/mwlua/types/actor.cpp index b3a00faa5c..20c32e4a30 100644 --- a/apps/openmw/mwlua/types/actor.cpp +++ b/apps/openmw/mwlua/types/actor.cpp @@ -1,12 +1,12 @@ #include "types.hpp" -#include #include +#include -#include #include -#include +#include #include +#include #include "../localscripts.hpp" #include "../luamanagerimp.hpp" @@ -19,11 +19,15 @@ namespace MWLua class SetEquipmentAction final : public LuaManager::Action { public: - using Item = std::variant; // recordId or ObjectId - using Equipment = std::map; // slot to item + using Item = std::variant; // recordId or ObjectId + using Equipment = std::map; // slot to item SetEquipmentAction(LuaUtil::LuaState* state, ObjectId actor, Equipment equipment) - : Action(state), mActor(actor), mEquipment(std::move(equipment)) {} + : Action(state) + , mActor(actor) + , mEquipment(std::move(equipment)) + { + } void apply(WorldView& worldView) const override { @@ -33,19 +37,19 @@ namespace MWLua std::fill(usedSlots.begin(), usedSlots.end(), false); static constexpr int anySlot = -1; - auto tryEquipToSlot = [&actor, &store, &usedSlots, &worldView](int slot, const Item& item) -> bool - { + auto tryEquipToSlot = [&actor, &store, &usedSlots, &worldView](int slot, const Item& item) -> bool { auto old_it = slot != anySlot ? store.getSlot(slot) : store.end(); MWWorld::Ptr itemPtr; if (std::holds_alternative(item)) { itemPtr = worldView.getObjectRegistry()->getPtr(std::get(item), false); if (old_it != store.end() && *old_it == itemPtr) - return true; // already equipped - if (itemPtr.isEmpty() || itemPtr.getRefData().getCount() == 0 || - itemPtr.getContainerStore() != static_cast(&store)) + return true; // already equipped + if (itemPtr.isEmpty() || itemPtr.getRefData().getCount() == 0 + || itemPtr.getContainerStore() != static_cast(&store)) { - Log(Debug::Warning) << "Object" << idToString(std::get(item)) << " is not in inventory"; + Log(Debug::Warning) + << "Object" << idToString(std::get(item)) << " is not in inventory"; return false; } } @@ -53,7 +57,7 @@ namespace MWLua { const std::string& recordId = std::get(item); if (old_it != store.end() && old_it->getCellRef().getRefId() == recordId) - return true; // already equipped + return true; // already equipped itemPtr = store.search(recordId); if (itemPtr.isEmpty() || itemPtr.getRefData().getCount() == 0) { @@ -63,10 +67,12 @@ namespace MWLua } auto [allowedSlots, _] = itemPtr.getClass().getEquipmentSlots(itemPtr); - bool requestedSlotIsAllowed = std::find(allowedSlots.begin(), allowedSlots.end(), slot) != allowedSlots.end(); + bool requestedSlotIsAllowed + = std::find(allowedSlots.begin(), allowedSlots.end(), slot) != allowedSlots.end(); if (!requestedSlotIsAllowed) { - auto firstAllowed = std::find_if(allowedSlots.begin(), allowedSlots.end(), [&](int s) { return !usedSlots[s]; }); + auto firstAllowed = std::find_if( + allowedSlots.begin(), allowedSlots.end(), [&](int s) { return !usedSlots[s]; }); if (firstAllowed == allowedSlots.end()) { Log(Debug::Warning) << "No suitable slot for " << ptrToString(itemPtr); @@ -77,11 +83,12 @@ namespace MWLua // TODO: Refactor InventoryStore to accept Ptr and get rid of this linear search. MWWorld::ContainerStoreIterator it = std::find(store.begin(), store.end(), itemPtr); - if (it == store.end()) // should never happen + if (it == store.end()) // should never happen throw std::logic_error("Item not found in container"); store.equip(slot, it, actor); - return requestedSlotIsAllowed; // return true if equipped to requested slot and false if slot was changed + return requestedSlotIsAllowed; // return true if equipped to requested slot and false if slot was + // changed }; for (int slot = 0; slot < MWWorld::InventoryStore::Slots; ++slot) @@ -109,40 +116,34 @@ namespace MWLua Equipment mEquipment; }; } - + using SelfObject = LocalScripts::SelfObject; void addActorBindings(sol::table actor, const Context& context) { - actor["STANCE"] = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs({ - {"Nothing", MWMechanics::DrawState::Nothing}, - {"Weapon", MWMechanics::DrawState::Weapon}, - {"Spell", MWMechanics::DrawState::Spell}, - })); - actor["EQUIPMENT_SLOT"] = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs({ - {"Helmet", MWWorld::InventoryStore::Slot_Helmet}, - {"Cuirass", MWWorld::InventoryStore::Slot_Cuirass}, - {"Greaves", MWWorld::InventoryStore::Slot_Greaves}, - {"LeftPauldron", MWWorld::InventoryStore::Slot_LeftPauldron}, - {"RightPauldron", MWWorld::InventoryStore::Slot_RightPauldron}, - {"LeftGauntlet", MWWorld::InventoryStore::Slot_LeftGauntlet}, - {"RightGauntlet", MWWorld::InventoryStore::Slot_RightGauntlet}, - {"Boots", MWWorld::InventoryStore::Slot_Boots}, - {"Shirt", MWWorld::InventoryStore::Slot_Shirt}, - {"Pants", MWWorld::InventoryStore::Slot_Pants}, - {"Skirt", MWWorld::InventoryStore::Slot_Skirt}, - {"Robe", MWWorld::InventoryStore::Slot_Robe}, - {"LeftRing", MWWorld::InventoryStore::Slot_LeftRing}, - {"RightRing", MWWorld::InventoryStore::Slot_RightRing}, - {"Amulet", MWWorld::InventoryStore::Slot_Amulet}, - {"Belt", MWWorld::InventoryStore::Slot_Belt}, - {"CarriedRight", MWWorld::InventoryStore::Slot_CarriedRight}, - {"CarriedLeft", MWWorld::InventoryStore::Slot_CarriedLeft}, - {"Ammunition", MWWorld::InventoryStore::Slot_Ammunition} - })); - - actor["stance"] = [](const Object& o) - { + actor["STANCE"] + = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs({ + { "Nothing", MWMechanics::DrawState::Nothing }, + { "Weapon", MWMechanics::DrawState::Weapon }, + { "Spell", MWMechanics::DrawState::Spell }, + })); + actor["EQUIPMENT_SLOT"] = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs( + { { "Helmet", MWWorld::InventoryStore::Slot_Helmet }, { "Cuirass", MWWorld::InventoryStore::Slot_Cuirass }, + { "Greaves", MWWorld::InventoryStore::Slot_Greaves }, + { "LeftPauldron", MWWorld::InventoryStore::Slot_LeftPauldron }, + { "RightPauldron", MWWorld::InventoryStore::Slot_RightPauldron }, + { "LeftGauntlet", MWWorld::InventoryStore::Slot_LeftGauntlet }, + { "RightGauntlet", MWWorld::InventoryStore::Slot_RightGauntlet }, + { "Boots", MWWorld::InventoryStore::Slot_Boots }, { "Shirt", MWWorld::InventoryStore::Slot_Shirt }, + { "Pants", MWWorld::InventoryStore::Slot_Pants }, { "Skirt", MWWorld::InventoryStore::Slot_Skirt }, + { "Robe", MWWorld::InventoryStore::Slot_Robe }, { "LeftRing", MWWorld::InventoryStore::Slot_LeftRing }, + { "RightRing", MWWorld::InventoryStore::Slot_RightRing }, + { "Amulet", MWWorld::InventoryStore::Slot_Amulet }, { "Belt", MWWorld::InventoryStore::Slot_Belt }, + { "CarriedRight", MWWorld::InventoryStore::Slot_CarriedRight }, + { "CarriedLeft", MWWorld::InventoryStore::Slot_CarriedLeft }, + { "Ammunition", MWWorld::InventoryStore::Slot_Ammunition } })); + + actor["stance"] = [](const Object& o) { const MWWorld::Class& cls = o.ptr().getClass(); if (cls.isActor()) return cls.getCreatureStats(o.ptr()).getDrawState(); @@ -150,42 +151,31 @@ namespace MWLua throw std::runtime_error("Actor expected"); }; - actor["canMove"] = [](const Object& o) - { + actor["canMove"] = [](const Object& o) { const MWWorld::Class& cls = o.ptr().getClass(); return cls.getMaxSpeed(o.ptr()) > 0; }; - actor["runSpeed"] = [](const Object& o) - { + actor["runSpeed"] = [](const Object& o) { const MWWorld::Class& cls = o.ptr().getClass(); return cls.getRunSpeed(o.ptr()); }; - actor["walkSpeed"] = [](const Object& o) - { + actor["walkSpeed"] = [](const Object& o) { const MWWorld::Class& cls = o.ptr().getClass(); return cls.getWalkSpeed(o.ptr()); }; - actor["currentSpeed"] = [](const Object& o) - { + actor["currentSpeed"] = [](const Object& o) { const MWWorld::Class& cls = o.ptr().getClass(); return cls.getCurrentSpeed(o.ptr()); }; - actor["isOnGround"] = [](const LObject& o) - { - return MWBase::Environment::get().getWorld()->isOnGround(o.ptr()); - }; - actor["isSwimming"] = [](const LObject& o) - { - return MWBase::Environment::get().getWorld()->isSwimming(o.ptr()); - }; + actor["isOnGround"] + = [](const LObject& o) { return MWBase::Environment::get().getWorld()->isOnGround(o.ptr()); }; + actor["isSwimming"] + = [](const LObject& o) { return MWBase::Environment::get().getWorld()->isSwimming(o.ptr()); }; - actor["inventory"] = sol::overload( - [](const LObject& o) { return Inventory{o}; }, - [](const GObject& o) { return Inventory{o}; } - ); - auto getAllEquipment = [context](const Object& o) - { + actor["inventory"] = sol::overload([](const LObject& o) { return Inventory{ o }; }, + [](const GObject& o) { return Inventory{ o }; }); + auto getAllEquipment = [context](const Object& o) { const MWWorld::Ptr& ptr = o.ptr(); sol::table equipment(context.mLua->sol(), sol::create); if (!ptr.getClass().hasInventoryStore(ptr)) @@ -202,8 +192,7 @@ namespace MWLua } return equipment; }; - auto getEquipmentFromSlot = [context](const Object& o, int slot) -> sol::object - { + auto getEquipmentFromSlot = [context](const Object& o, int slot) -> sol::object { const MWWorld::Ptr& ptr = o.ptr(); sol::table equipment(context.mLua->sol(), sol::create); if (!ptr.getClass().hasInventoryStore(ptr)) @@ -216,16 +205,14 @@ namespace MWLua return o.getObject(context.mLua->sol(), getId(*it)); }; actor["equipment"] = sol::overload(getAllEquipment, getEquipmentFromSlot); - actor["hasEquipped"] = [](const Object& o, const Object& item) - { + actor["hasEquipped"] = [](const Object& o, const Object& item) { const MWWorld::Ptr& ptr = o.ptr(); if (!ptr.getClass().hasInventoryStore(ptr)) return false; MWWorld::InventoryStore& store = ptr.getClass().getInventoryStore(ptr); return store.isEquipped(item.ptr()); }; - actor["setEquipment"] = [context](const SelfObject& obj, const sol::table& equipment) - { + actor["setEquipment"] = [context](const SelfObject& obj, const sol::table& equipment) { if (!obj.ptr().getClass().hasInventoryStore(obj.ptr())) { if (!equipment.empty()) @@ -241,11 +228,12 @@ namespace MWLua else eqp[slot] = value.as(); } - context.mLuaManager->addAction(std::make_unique(context.mLua, obj.id(), std::move(eqp))); + context.mLuaManager->addAction( + std::make_unique(context.mLua, obj.id(), std::move(eqp))); }; - actor["getPathfindingAgentBounds"] = [context](const LObject& o) - { - const DetourNavigator::AgentBounds agentBounds = MWBase::Environment::get().getWorld()->getPathfindingAgentBounds(o.ptr()); + actor["getPathfindingAgentBounds"] = [context](const LObject& o) { + const DetourNavigator::AgentBounds agentBounds + = MWBase::Environment::get().getWorld()->getPathfindingAgentBounds(o.ptr()); sol::table result = context.mLua->newTable(); result["shapeType"] = agentBounds.mShapeType; result["halfExtents"] = agentBounds.mHalfExtents; diff --git a/apps/openmw/mwlua/types/apparatus.cpp b/apps/openmw/mwlua/types/apparatus.cpp index 57cc9ff313..6b65b000f1 100644 --- a/apps/openmw/mwlua/types/apparatus.cpp +++ b/apps/openmw/mwlua/types/apparatus.cpp @@ -1,18 +1,20 @@ #include "types.hpp" #include +#include #include #include -#include -#include #include #include +#include namespace sol { template <> - struct is_automagical : std::false_type {}; + struct is_automagical : std::false_type + { + }; } namespace MWLua @@ -20,34 +22,36 @@ namespace MWLua void addApparatusBindings(sol::table apparatus, const Context& context) { apparatus["TYPE"] = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs({ - {"MortarPestle", ESM::Apparatus::MortarPestle}, - {"Alembic", ESM::Apparatus::Alembic}, - {"Calcinator", ESM::Apparatus::Calcinator}, - {"Retort", ESM::Apparatus::Retort}, - })); + { "MortarPestle", ESM::Apparatus::MortarPestle }, + { "Alembic", ESM::Apparatus::Alembic }, + { "Calcinator", ESM::Apparatus::Calcinator }, + { "Retort", ESM::Apparatus::Retort }, + })); auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); - const MWWorld::Store* store = &MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store* store + = &MWBase::Environment::get().getWorld()->getStore().get(); apparatus["record"] = sol::overload( [](const Object& obj) -> const ESM::Apparatus* { return obj.ptr().get()->mBase; }, [store](const std::string& recordId) -> const ESM::Apparatus* { return store->find(recordId); }); sol::usertype record = context.mLua->sol().new_usertype("ESM3_Apparatus"); - record[sol::meta_function::to_string] = [](const ESM::Apparatus& rec) { return "ESM3_Apparatus[" + rec.mId + "]"; }; + record[sol::meta_function::to_string] + = [](const ESM::Apparatus& rec) { return "ESM3_Apparatus[" + rec.mId + "]"; }; record["id"] = sol::readonly_property([](const ESM::Apparatus& rec) -> std::string { return rec.mId; }); record["name"] = sol::readonly_property([](const ESM::Apparatus& rec) -> std::string { return rec.mName; }); - record["model"] = sol::readonly_property([vfs](const ESM::Apparatus& rec) -> std::string - { + record["model"] = sol::readonly_property([vfs](const ESM::Apparatus& rec) -> std::string { return Misc::ResourceHelpers::correctMeshPath(rec.mModel, vfs); }); - record["mwscript"] = sol::readonly_property([](const ESM::Apparatus& rec) -> std::string { return rec.mScript; }); - record["icon"] = sol::readonly_property([vfs](const ESM::Apparatus& rec) -> std::string - { + record["mwscript"] + = sol::readonly_property([](const ESM::Apparatus& rec) -> std::string { return rec.mScript; }); + record["icon"] = sol::readonly_property([vfs](const ESM::Apparatus& rec) -> std::string { return Misc::ResourceHelpers::correctIconPath(rec.mIcon, vfs); }); record["type"] = sol::readonly_property([](const ESM::Apparatus& rec) -> int { return rec.mData.mType; }); record["value"] = sol::readonly_property([](const ESM::Apparatus& rec) -> int { return rec.mData.mValue; }); record["weight"] = sol::readonly_property([](const ESM::Apparatus& rec) -> float { return rec.mData.mWeight; }); - record["quality"] = sol::readonly_property([](const ESM::Apparatus& rec) -> float { return rec.mData.mQuality; }); + record["quality"] + = sol::readonly_property([](const ESM::Apparatus& rec) -> float { return rec.mData.mQuality; }); } } diff --git a/apps/openmw/mwlua/types/book.cpp b/apps/openmw/mwlua/types/book.cpp index c439965f30..d65e884cad 100644 --- a/apps/openmw/mwlua/types/book.cpp +++ b/apps/openmw/mwlua/types/book.cpp @@ -1,25 +1,27 @@ #include "types.hpp" #include +#include #include #include -#include -#include #include #include +#include #include namespace sol { template <> - struct is_automagical : std::false_type {}; + struct is_automagical : std::false_type + { + }; } namespace MWLua { void addBookBindings(sol::table book, const Context& context) - { + { sol::table skill(context.mLua->sol(), sol::create); book["SKILL"] = LuaUtil::makeStrictReadOnly(skill); for (int id = ESM::Skill::Block; id < ESM::Skill::Length; ++id) @@ -31,20 +33,18 @@ namespace MWLua auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); const MWWorld::Store* store = &MWBase::Environment::get().getWorld()->getStore().get(); - book["record"] = sol::overload( - [](const Object& obj) -> const ESM::Book* { return obj.ptr().get()->mBase; }, - [store](const std::string& recordId) -> const ESM::Book* { return store->find(recordId); }); + book["record"] + = sol::overload([](const Object& obj) -> const ESM::Book* { return obj.ptr().get()->mBase; }, + [store](const std::string& recordId) -> const ESM::Book* { return store->find(recordId); }); sol::usertype record = context.mLua->sol().new_usertype("ESM3_Book"); record[sol::meta_function::to_string] = [](const ESM::Book& rec) { return "ESM3_Book[" + rec.mId + "]"; }; record["id"] = sol::readonly_property([](const ESM::Book& rec) -> std::string { return rec.mId; }); record["name"] = sol::readonly_property([](const ESM::Book& rec) -> std::string { return rec.mName; }); - record["model"] = sol::readonly_property([vfs](const ESM::Book& rec) -> std::string - { + record["model"] = sol::readonly_property([vfs](const ESM::Book& rec) -> std::string { return Misc::ResourceHelpers::correctMeshPath(rec.mModel, vfs); }); record["mwscript"] = sol::readonly_property([](const ESM::Book& rec) -> std::string { return rec.mScript; }); - record["icon"] = sol::readonly_property([vfs](const ESM::Book& rec) -> std::string - { + record["icon"] = sol::readonly_property([vfs](const ESM::Book& rec) -> std::string { return Misc::ResourceHelpers::correctIconPath(rec.mIcon, vfs); }); record["text"] = sol::readonly_property([](const ESM::Book& rec) -> std::string { return rec.mText; }); @@ -52,9 +52,9 @@ namespace MWLua record["isScroll"] = sol::readonly_property([](const ESM::Book& rec) -> bool { return rec.mData.mIsScroll; }); record["value"] = sol::readonly_property([](const ESM::Book& rec) -> int { return rec.mData.mValue; }); record["weight"] = sol::readonly_property([](const ESM::Book& rec) -> float { return rec.mData.mWeight; }); - record["enchantCapacity"] = sol::readonly_property([](const ESM::Book& rec) -> float { return rec.mData.mEnchant * 0.1f; }); - record["skill"] = sol::readonly_property([](const ESM::Book& rec) -> sol::optional - { + record["enchantCapacity"] + = sol::readonly_property([](const ESM::Book& rec) -> float { return rec.mData.mEnchant * 0.1f; }); + record["skill"] = sol::readonly_property([](const ESM::Book& rec) -> sol::optional { if (rec.mData.mSkillId >= 0) return Misc::StringUtils::lowerCase(ESM::Skill::sSkillNames[rec.mData.mSkillId]); else diff --git a/apps/openmw/mwlua/types/container.cpp b/apps/openmw/mwlua/types/container.cpp index 2fd0940245..e799535985 100644 --- a/apps/openmw/mwlua/types/container.cpp +++ b/apps/openmw/mwlua/types/container.cpp @@ -1,32 +1,42 @@ #include "types.hpp" #include +#include #include #include -#include -#include -#include #include #include +#include +#include namespace sol { template <> - struct is_automagical : std::false_type {}; + struct is_automagical : std::false_type + { + }; } namespace MWLua { - static const MWWorld::Ptr& containerPtr(const Object& o) { return verifyType(ESM::REC_CONT, o.ptr()); } + static const MWWorld::Ptr& containerPtr(const Object& o) + { + return verifyType(ESM::REC_CONT, o.ptr()); + } void addContainerBindings(sol::table container, const Context& context) { container["content"] = sol::overload( - [](const LObject& o) { containerPtr(o); return Inventory{o}; }, - [](const GObject& o) { containerPtr(o); return Inventory{o}; } - ); + [](const LObject& o) { + containerPtr(o); + return Inventory{ o }; + }, + [](const GObject& o) { + containerPtr(o); + return Inventory{ o }; + }); container["encumbrance"] = [](const Object& obj) -> float { const MWWorld::Ptr& ptr = containerPtr(obj); return ptr.getClass().getEncumbrance(ptr); @@ -38,19 +48,21 @@ namespace MWLua auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); - const MWWorld::Store* store = &MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store* store + = &MWBase::Environment::get().getWorld()->getStore().get(); container["record"] = sol::overload( [](const Object& obj) -> const ESM::Container* { return obj.ptr().get()->mBase; }, [store](const std::string& recordId) -> const ESM::Container* { return store->find(recordId); }); sol::usertype record = context.mLua->sol().new_usertype("ESM3_Container"); - record[sol::meta_function::to_string] = [](const ESM::Container& rec) -> std::string { return "ESM3_Container[" + rec.mId + "]"; }; + record[sol::meta_function::to_string] + = [](const ESM::Container& rec) -> std::string { return "ESM3_Container[" + rec.mId + "]"; }; record["id"] = sol::readonly_property([](const ESM::Container& rec) -> std::string { return rec.mId; }); record["name"] = sol::readonly_property([](const ESM::Container& rec) -> std::string { return rec.mName; }); - record["model"] = sol::readonly_property([vfs](const ESM::Container& rec) -> std::string - { + record["model"] = sol::readonly_property([vfs](const ESM::Container& rec) -> std::string { return Misc::ResourceHelpers::correctMeshPath(rec.mModel, vfs); }); - record["mwscript"] = sol::readonly_property([](const ESM::Container& rec) -> std::string { return rec.mScript; }); + record["mwscript"] + = sol::readonly_property([](const ESM::Container& rec) -> std::string { return rec.mScript; }); record["weight"] = sol::readonly_property([](const ESM::Container& rec) -> float { return rec.mWeight; }); } } diff --git a/apps/openmw/mwlua/types/creature.cpp b/apps/openmw/mwlua/types/creature.cpp index ee67597555..b900286d7c 100644 --- a/apps/openmw/mwlua/types/creature.cpp +++ b/apps/openmw/mwlua/types/creature.cpp @@ -5,14 +5,16 @@ #include #include -#include #include #include +#include namespace sol { template <> - struct is_automagical : std::false_type {}; + struct is_automagical : std::false_type + { + }; } namespace MWLua @@ -21,18 +23,21 @@ namespace MWLua { auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); - const MWWorld::Store* store = &MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store* store + = &MWBase::Environment::get().getWorld()->getStore().get(); creature["record"] = sol::overload( [](const Object& obj) -> const ESM::Creature* { return obj.ptr().get()->mBase; }, [store](const std::string& recordId) -> const ESM::Creature* { return store->find(recordId); }); sol::usertype record = context.mLua->sol().new_usertype("ESM3_Creature"); - record[sol::meta_function::to_string] = [](const ESM::Creature& rec) { return "ESM3_Creature[" + rec.mId + "]"; }; + record[sol::meta_function::to_string] + = [](const ESM::Creature& rec) { return "ESM3_Creature[" + rec.mId + "]"; }; record["name"] = sol::readonly_property([](const ESM::Creature& rec) -> std::string { return rec.mName; }); - record["model"] = sol::readonly_property([vfs](const ESM::Creature& rec) -> std::string - { + record["model"] = sol::readonly_property([vfs](const ESM::Creature& rec) -> std::string { return Misc::ResourceHelpers::correctMeshPath(rec.mModel, vfs); }); - record["mwscript"] = sol::readonly_property([](const ESM::Creature& rec) -> std::string { return rec.mScript; }); - record["baseCreature"] = sol::readonly_property([](const ESM::Creature& rec) -> std::string { return rec.mOriginal; }); + record["mwscript"] + = sol::readonly_property([](const ESM::Creature& rec) -> std::string { return rec.mScript; }); + record["baseCreature"] + = sol::readonly_property([](const ESM::Creature& rec) -> std::string { return rec.mOriginal; }); } } diff --git a/apps/openmw/mwlua/types/door.cpp b/apps/openmw/mwlua/types/door.cpp index f82d78f3f0..9ddf3b18fc 100644 --- a/apps/openmw/mwlua/types/door.cpp +++ b/apps/openmw/mwlua/types/door.cpp @@ -12,27 +12,27 @@ namespace sol { template <> - struct is_automagical : std::false_type {}; + struct is_automagical : std::false_type + { + }; } namespace MWLua { - static const MWWorld::Ptr& doorPtr(const Object& o) { return verifyType(ESM::REC_DOOR, o.ptr()); } + static const MWWorld::Ptr& doorPtr(const Object& o) + { + return verifyType(ESM::REC_DOOR, o.ptr()); + } void addDoorBindings(sol::table door, const Context& context) { door["isTeleport"] = [](const Object& o) { return doorPtr(o).getCellRef().getTeleport(); }; - door["destPosition"] = [](const Object& o) -> osg::Vec3f - { - return doorPtr(o).getCellRef().getDoorDest().asVec3(); - }; - door["destRotation"] = [](const Object& o) -> osg::Vec3f - { - return doorPtr(o).getCellRef().getDoorDest().asRotationVec3(); - }; - door["destCell"] = [worldView=context.mWorldView](sol::this_state lua, const Object& o) -> sol::object - { + door["destPosition"] + = [](const Object& o) -> osg::Vec3f { return doorPtr(o).getCellRef().getDoorDest().asVec3(); }; + door["destRotation"] + = [](const Object& o) -> osg::Vec3f { return doorPtr(o).getCellRef().getDoorDest().asRotationVec3(); }; + door["destCell"] = [worldView = context.mWorldView](sol::this_state lua, const Object& o) -> sol::object { const MWWorld::CellRef& cellRef = doorPtr(o).getCellRef(); if (!cellRef.getTeleport()) return sol::nil; @@ -46,20 +46,22 @@ namespace MWLua auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); const MWWorld::Store* store = &MWBase::Environment::get().getWorld()->getStore().get(); - door["record"] = sol::overload( - [](const Object& obj) -> const ESM::Door* { return obj.ptr().get()->mBase; }, - [store](const std::string& recordId) -> const ESM::Door* { return store->find(recordId); }); + door["record"] + = sol::overload([](const Object& obj) -> const ESM::Door* { return obj.ptr().get()->mBase; }, + [store](const std::string& recordId) -> const ESM::Door* { return store->find(recordId); }); sol::usertype record = context.mLua->sol().new_usertype("ESM3_Door"); - record[sol::meta_function::to_string] = [](const ESM::Door& rec) -> std::string { return "ESM3_Door[" + rec.mId + "]"; }; + record[sol::meta_function::to_string] + = [](const ESM::Door& rec) -> std::string { return "ESM3_Door[" + rec.mId + "]"; }; record["id"] = sol::readonly_property([](const ESM::Door& rec) -> std::string { return rec.mId; }); record["name"] = sol::readonly_property([](const ESM::Door& rec) -> std::string { return rec.mName; }); - record["model"] = sol::readonly_property([vfs](const ESM::Door& rec) -> std::string - { + record["model"] = sol::readonly_property([vfs](const ESM::Door& rec) -> std::string { return Misc::ResourceHelpers::correctMeshPath(rec.mModel, vfs); }); record["mwscript"] = sol::readonly_property([](const ESM::Door& rec) -> std::string { return rec.mScript; }); - record["openSound"] = sol::readonly_property([](const ESM::Door& rec) -> std::string { return rec.mOpenSound; }); - record["closeSound"] = sol::readonly_property([](const ESM::Door& rec) -> std::string { return rec.mCloseSound; }); + record["openSound"] + = sol::readonly_property([](const ESM::Door& rec) -> std::string { return rec.mOpenSound; }); + record["closeSound"] + = sol::readonly_property([](const ESM::Door& rec) -> std::string { return rec.mCloseSound; }); } } diff --git a/apps/openmw/mwlua/types/ingredient.cpp b/apps/openmw/mwlua/types/ingredient.cpp index 3505633036..5f119fc729 100644 --- a/apps/openmw/mwlua/types/ingredient.cpp +++ b/apps/openmw/mwlua/types/ingredient.cpp @@ -13,25 +13,31 @@ namespace sol { template <> - struct is_automagical : std::false_type {}; + struct is_automagical : std::false_type + { + }; } namespace MWLua { void addIngredientBindings(sol::table ingredient, const Context& context) { - const MWWorld::Store* store = &MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store* store + = &MWBase::Environment::get().getWorld()->getStore().get(); ingredient["record"] = sol::overload( - [](const Object& obj)-> const ESM::Ingredient* { return obj.ptr().get()->mBase; }, - [store](const std::string& recordID)-> const ESM::Ingredient* {return store->find(recordID); }); + [](const Object& obj) -> const ESM::Ingredient* { return obj.ptr().get()->mBase; }, + [store](const std::string& recordID) -> const ESM::Ingredient* { return store->find(recordID); }); sol::usertype record = context.mLua->sol().new_usertype(("ESM3_Ingredient")); - record[sol::meta_function::to_string] = [](const ESM::Potion& rec) {return "ESM3_Ingredient[" + rec.mId + "]"; }; - record["id"] = sol::readonly_property([](const ESM::Ingredient& rec) -> std::string {return rec.mId; }); - record["name"] = sol::readonly_property([](const ESM::Ingredient& rec) -> std::string {return rec.mName; }); - record["model"] = sol::readonly_property([](const ESM::Ingredient& rec) -> std::string {return rec.mModel; }); - record["mwscript"] = sol::readonly_property([](const ESM::Ingredient& rec) -> std::string {return rec.mScript; }); - record["icon"] = sol::readonly_property([](const ESM::Ingredient& rec) -> std::string {return rec.mIcon; }); - record["weight"] = sol::readonly_property([](const ESM::Ingredient& rec) -> float {return rec.mData.mWeight; }); - record["value"] = sol::readonly_property([](const ESM::Ingredient& rec) -> int{return rec.mData.mValue; }); + record[sol::meta_function::to_string] + = [](const ESM::Potion& rec) { return "ESM3_Ingredient[" + rec.mId + "]"; }; + record["id"] = sol::readonly_property([](const ESM::Ingredient& rec) -> std::string { return rec.mId; }); + record["name"] = sol::readonly_property([](const ESM::Ingredient& rec) -> std::string { return rec.mName; }); + record["model"] = sol::readonly_property([](const ESM::Ingredient& rec) -> std::string { return rec.mModel; }); + record["mwscript"] + = sol::readonly_property([](const ESM::Ingredient& rec) -> std::string { return rec.mScript; }); + record["icon"] = sol::readonly_property([](const ESM::Ingredient& rec) -> std::string { return rec.mIcon; }); + record["weight"] + = sol::readonly_property([](const ESM::Ingredient& rec) -> float { return rec.mData.mWeight; }); + record["value"] = sol::readonly_property([](const ESM::Ingredient& rec) -> int { return rec.mData.mValue; }); } } diff --git a/apps/openmw/mwlua/types/lockpick.cpp b/apps/openmw/mwlua/types/lockpick.cpp index 807c3fb69f..4bc98f4f6e 100644 --- a/apps/openmw/mwlua/types/lockpick.cpp +++ b/apps/openmw/mwlua/types/lockpick.cpp @@ -1,18 +1,20 @@ #include "types.hpp" #include +#include #include #include -#include -#include #include #include +#include namespace sol { template <> - struct is_automagical : std::false_type {}; + struct is_automagical : std::false_type + { + }; } namespace MWLua @@ -21,26 +23,29 @@ namespace MWLua { auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); - const MWWorld::Store* store = &MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store* store + = &MWBase::Environment::get().getWorld()->getStore().get(); lockpick["record"] = sol::overload( - [](const Object& obj) -> const ESM::Lockpick* { return obj.ptr().get()->mBase;}, - [store](const std::string& recordId) -> const ESM::Lockpick* { return store->find(recordId);}); + [](const Object& obj) -> const ESM::Lockpick* { return obj.ptr().get()->mBase; }, + [store](const std::string& recordId) -> const ESM::Lockpick* { return store->find(recordId); }); sol::usertype record = context.mLua->sol().new_usertype("ESM3_Lockpick"); - record[sol::meta_function::to_string] = [](const ESM::Lockpick& rec) { return "ESM3_Lockpick[" + rec.mId + "]";}; - record["id"] = sol::readonly_property([](const ESM::Lockpick& rec) -> std::string { return rec.mId;}); - record["name"] = sol::readonly_property([](const ESM::Lockpick& rec) -> std::string { return rec.mName;}); - record["model"] = sol::readonly_property([vfs](const ESM::Lockpick& rec) -> std::string - { + record[sol::meta_function::to_string] + = [](const ESM::Lockpick& rec) { return "ESM3_Lockpick[" + rec.mId + "]"; }; + record["id"] = sol::readonly_property([](const ESM::Lockpick& rec) -> std::string { return rec.mId; }); + record["name"] = sol::readonly_property([](const ESM::Lockpick& rec) -> std::string { return rec.mName; }); + record["model"] = sol::readonly_property([vfs](const ESM::Lockpick& rec) -> std::string { return Misc::ResourceHelpers::correctMeshPath(rec.mModel, vfs); }); - record["mwscript"] = sol::readonly_property([](const ESM::Lockpick& rec) -> std::string { return rec.mScript;}); - record["icon"] = sol::readonly_property([vfs](const ESM::Lockpick& rec) -> std::string - { + record["mwscript"] + = sol::readonly_property([](const ESM::Lockpick& rec) -> std::string { return rec.mScript; }); + record["icon"] = sol::readonly_property([vfs](const ESM::Lockpick& rec) -> std::string { return Misc::ResourceHelpers::correctIconPath(rec.mIcon, vfs); }); - record["maxCondition"] = sol::readonly_property([](const ESM::Lockpick& rec) -> int { return rec.mData.mUses;}); - record["value"] = sol::readonly_property([](const ESM::Lockpick& rec) -> int { return rec.mData.mValue;}); - record["weight"] = sol::readonly_property([](const ESM::Lockpick& rec) -> float { return rec.mData.mWeight;}); - record["quality"] = sol::readonly_property([](const ESM::Lockpick& rec) -> float { return rec.mData.mQuality;}); + record["maxCondition"] + = sol::readonly_property([](const ESM::Lockpick& rec) -> int { return rec.mData.mUses; }); + record["value"] = sol::readonly_property([](const ESM::Lockpick& rec) -> int { return rec.mData.mValue; }); + record["weight"] = sol::readonly_property([](const ESM::Lockpick& rec) -> float { return rec.mData.mWeight; }); + record["quality"] + = sol::readonly_property([](const ESM::Lockpick& rec) -> float { return rec.mData.mQuality; }); } } diff --git a/apps/openmw/mwlua/types/misc.cpp b/apps/openmw/mwlua/types/misc.cpp index bbf878e5fd..0b3f66a327 100644 --- a/apps/openmw/mwlua/types/misc.cpp +++ b/apps/openmw/mwlua/types/misc.cpp @@ -1,18 +1,20 @@ #include "types.hpp" #include +#include #include #include -#include -#include #include #include +#include namespace sol { template <> - struct is_automagical : std::false_type {}; + struct is_automagical : std::false_type + { + }; } namespace MWLua @@ -21,25 +23,29 @@ namespace MWLua { auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); - const MWWorld::Store* store = &MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store* store + = &MWBase::Environment::get().getWorld()->getStore().get(); miscellaneous["record"] = sol::overload( [](const Object& obj) -> const ESM::Miscellaneous* { return obj.ptr().get()->mBase; }, [store](const std::string& recordId) -> const ESM::Miscellaneous* { return store->find(recordId); }); - sol::usertype record = context.mLua->sol().new_usertype("ESM3_Miscellaneous"); - record[sol::meta_function::to_string] = [](const ESM::Miscellaneous& rec) { return "ESM3_Miscellaneous[" + rec.mId + "]"; }; + sol::usertype record + = context.mLua->sol().new_usertype("ESM3_Miscellaneous"); + record[sol::meta_function::to_string] + = [](const ESM::Miscellaneous& rec) { return "ESM3_Miscellaneous[" + rec.mId + "]"; }; record["id"] = sol::readonly_property([](const ESM::Miscellaneous& rec) -> std::string { return rec.mId; }); record["name"] = sol::readonly_property([](const ESM::Miscellaneous& rec) -> std::string { return rec.mName; }); - record["model"] = sol::readonly_property([vfs](const ESM::Miscellaneous& rec) -> std::string - { + record["model"] = sol::readonly_property([vfs](const ESM::Miscellaneous& rec) -> std::string { return Misc::ResourceHelpers::correctMeshPath(rec.mModel, vfs); }); - record["mwscript"] = sol::readonly_property([](const ESM::Miscellaneous& rec) -> std::string { return rec.mScript; }); - record["icon"] = sol::readonly_property([vfs](const ESM::Miscellaneous& rec) -> std::string - { + record["mwscript"] + = sol::readonly_property([](const ESM::Miscellaneous& rec) -> std::string { return rec.mScript; }); + record["icon"] = sol::readonly_property([vfs](const ESM::Miscellaneous& rec) -> std::string { return Misc::ResourceHelpers::correctIconPath(rec.mIcon, vfs); }); - record["isKey"] = sol::readonly_property([](const ESM::Miscellaneous& rec) -> bool { return rec.mData.mIsKey; }); + record["isKey"] + = sol::readonly_property([](const ESM::Miscellaneous& rec) -> bool { return rec.mData.mIsKey; }); record["value"] = sol::readonly_property([](const ESM::Miscellaneous& rec) -> int { return rec.mData.mValue; }); - record["weight"] = sol::readonly_property([](const ESM::Miscellaneous& rec) -> float { return rec.mData.mWeight; }); + record["weight"] + = sol::readonly_property([](const ESM::Miscellaneous& rec) -> float { return rec.mData.mWeight; }); } } diff --git a/apps/openmw/mwlua/types/npc.cpp b/apps/openmw/mwlua/types/npc.cpp index 9a2df896bd..9cbee90e04 100644 --- a/apps/openmw/mwlua/types/npc.cpp +++ b/apps/openmw/mwlua/types/npc.cpp @@ -3,16 +3,18 @@ #include #include -#include #include #include +#include #include "../stats.hpp" namespace sol { template <> - struct is_automagical : std::false_type {}; + struct is_automagical : std::false_type + { + }; } namespace MWLua @@ -22,9 +24,9 @@ namespace MWLua addNpcStatsBindings(npc, context); const MWWorld::Store* store = &MWBase::Environment::get().getWorld()->getStore().get(); - npc["record"] = sol::overload( - [](const Object& obj) -> const ESM::NPC* { return obj.ptr().get()->mBase; }, - [store](const std::string& recordId) -> const ESM::NPC* { return store->find(recordId); }); + npc["record"] + = sol::overload([](const Object& obj) -> const ESM::NPC* { return obj.ptr().get()->mBase; }, + [store](const std::string& recordId) -> const ESM::NPC* { return store->find(recordId); }); sol::usertype record = context.mLua->sol().new_usertype("ESM3_NPC"); record[sol::meta_function::to_string] = [](const ESM::NPC& rec) { return "ESM3_NPC[" + rec.mId + "]"; }; record["name"] = sol::readonly_property([](const ESM::NPC& rec) -> std::string { return rec.mName; }); diff --git a/apps/openmw/mwlua/types/potion.cpp b/apps/openmw/mwlua/types/potion.cpp index 51a6dceb81..d0bb1d8779 100644 --- a/apps/openmw/mwlua/types/potion.cpp +++ b/apps/openmw/mwlua/types/potion.cpp @@ -1,40 +1,41 @@ #include "types.hpp" #include +#include #include #include -#include -#include #include #include +#include namespace sol { template <> - struct is_automagical : std::false_type {}; + struct is_automagical : std::false_type + { + }; } namespace MWLua { void addPotionBindings(sol::table potion, const Context& context) { - const MWWorld::Store* store = &MWBase::Environment::get().getWorld()->getStore().get(); - potion["record"] = sol::overload( - [](const Object& obj) -> const ESM::Potion* { return obj.ptr().get()->mBase; }, - [store](const std::string& recordId) -> const ESM::Potion* { return store->find(recordId); }); + const MWWorld::Store* store + = &MWBase::Environment::get().getWorld()->getStore().get(); + potion["record"] + = sol::overload([](const Object& obj) -> const ESM::Potion* { return obj.ptr().get()->mBase; }, + [store](const std::string& recordId) -> const ESM::Potion* { return store->find(recordId); }); auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); sol::usertype record = context.mLua->sol().new_usertype("ESM3_Potion"); record[sol::meta_function::to_string] = [](const ESM::Potion& rec) { return "ESM3_Potion[" + rec.mId + "]"; }; record["id"] = sol::readonly_property([](const ESM::Potion& rec) -> std::string { return rec.mId; }); record["name"] = sol::readonly_property([](const ESM::Potion& rec) -> std::string { return rec.mName; }); - record["model"] = sol::readonly_property([vfs](const ESM::Potion& rec) -> std::string - { + record["model"] = sol::readonly_property([vfs](const ESM::Potion& rec) -> std::string { return Misc::ResourceHelpers::correctMeshPath(rec.mModel, vfs); }); - record["icon"] = sol::readonly_property([vfs](const ESM::Potion& rec) -> std::string - { + record["icon"] = sol::readonly_property([vfs](const ESM::Potion& rec) -> std::string { return Misc::ResourceHelpers::correctIconPath(rec.mIcon, vfs); }); record["mwscript"] = sol::readonly_property([](const ESM::Potion& rec) -> std::string { return rec.mScript; }); diff --git a/apps/openmw/mwlua/types/probe.cpp b/apps/openmw/mwlua/types/probe.cpp index b7dbcc88b4..77843b76e0 100644 --- a/apps/openmw/mwlua/types/probe.cpp +++ b/apps/openmw/mwlua/types/probe.cpp @@ -1,18 +1,20 @@ #include "types.hpp" #include +#include #include #include -#include -#include #include #include +#include namespace sol { template <> - struct is_automagical : std::false_type {}; + struct is_automagical : std::false_type + { + }; } namespace MWLua @@ -22,25 +24,23 @@ namespace MWLua auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); const MWWorld::Store* store = &MWBase::Environment::get().getWorld()->getStore().get(); - probe["record"] = sol::overload( - [](const Object& obj) -> const ESM::Probe* { return obj.ptr().get()->mBase;}, - [store](const std::string& recordId) -> const ESM::Probe* { return store->find(recordId);}); + probe["record"] + = sol::overload([](const Object& obj) -> const ESM::Probe* { return obj.ptr().get()->mBase; }, + [store](const std::string& recordId) -> const ESM::Probe* { return store->find(recordId); }); sol::usertype record = context.mLua->sol().new_usertype("ESM3_Probe"); - record[sol::meta_function::to_string] = [](const ESM::Probe& rec) { return "ESM3_Probe[" + rec.mId + "]";}; - record["id"] = sol::readonly_property([](const ESM::Probe& rec) -> std::string { return rec.mId;}); - record["name"] = sol::readonly_property([](const ESM::Probe& rec) -> std::string { return rec.mName;}); - record["model"] = sol::readonly_property([vfs](const ESM::Probe& rec) -> std::string - { + record[sol::meta_function::to_string] = [](const ESM::Probe& rec) { return "ESM3_Probe[" + rec.mId + "]"; }; + record["id"] = sol::readonly_property([](const ESM::Probe& rec) -> std::string { return rec.mId; }); + record["name"] = sol::readonly_property([](const ESM::Probe& rec) -> std::string { return rec.mName; }); + record["model"] = sol::readonly_property([vfs](const ESM::Probe& rec) -> std::string { return Misc::ResourceHelpers::correctMeshPath(rec.mModel, vfs); }); - record["mwscript"] = sol::readonly_property([](const ESM::Probe& rec) -> std::string { return rec.mScript;}); - record["icon"] = sol::readonly_property([vfs](const ESM::Probe& rec) -> std::string - { + record["mwscript"] = sol::readonly_property([](const ESM::Probe& rec) -> std::string { return rec.mScript; }); + record["icon"] = sol::readonly_property([vfs](const ESM::Probe& rec) -> std::string { return Misc::ResourceHelpers::correctIconPath(rec.mIcon, vfs); }); - record["maxCondition"] = sol::readonly_property([](const ESM::Probe& rec) -> int { return rec.mData.mUses;}); - record["value"] = sol::readonly_property([](const ESM::Probe& rec) -> int { return rec.mData.mValue;}); - record["weight"] = sol::readonly_property([](const ESM::Probe& rec) -> float { return rec.mData.mWeight;}); - record["quality"] = sol::readonly_property([](const ESM::Probe& rec) -> float { return rec.mData.mQuality;}); + record["maxCondition"] = sol::readonly_property([](const ESM::Probe& rec) -> int { return rec.mData.mUses; }); + record["value"] = sol::readonly_property([](const ESM::Probe& rec) -> int { return rec.mData.mValue; }); + record["weight"] = sol::readonly_property([](const ESM::Probe& rec) -> float { return rec.mData.mWeight; }); + record["quality"] = sol::readonly_property([](const ESM::Probe& rec) -> float { return rec.mData.mQuality; }); } } diff --git a/apps/openmw/mwlua/types/repair.cpp b/apps/openmw/mwlua/types/repair.cpp index 88997c2b34..dbf42707b6 100644 --- a/apps/openmw/mwlua/types/repair.cpp +++ b/apps/openmw/mwlua/types/repair.cpp @@ -1,18 +1,20 @@ #include "types.hpp" #include +#include #include #include -#include -#include #include #include +#include namespace sol { template <> - struct is_automagical : std::false_type {}; + struct is_automagical : std::false_type + { + }; } namespace MWLua @@ -21,21 +23,20 @@ namespace MWLua { auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); - const MWWorld::Store* store = &MWBase::Environment::get().getWorld()->getStore().get(); - repair["record"] = sol::overload( - [](const Object& obj) -> const ESM::Repair* { return obj.ptr().get()->mBase; }, - [store](const std::string& recordId) -> const ESM::Repair* { return store->find(recordId); }); + const MWWorld::Store* store + = &MWBase::Environment::get().getWorld()->getStore().get(); + repair["record"] + = sol::overload([](const Object& obj) -> const ESM::Repair* { return obj.ptr().get()->mBase; }, + [store](const std::string& recordId) -> const ESM::Repair* { return store->find(recordId); }); sol::usertype record = context.mLua->sol().new_usertype("ESM3_Repair"); record[sol::meta_function::to_string] = [](const ESM::Repair& rec) { return "ESM3_Repair[" + rec.mId + "]"; }; record["id"] = sol::readonly_property([](const ESM::Repair& rec) -> std::string { return rec.mId; }); record["name"] = sol::readonly_property([](const ESM::Repair& rec) -> std::string { return rec.mName; }); - record["model"] = sol::readonly_property([vfs](const ESM::Repair& rec) -> std::string - { + record["model"] = sol::readonly_property([vfs](const ESM::Repair& rec) -> std::string { return Misc::ResourceHelpers::correctMeshPath(rec.mModel, vfs); }); record["mwscript"] = sol::readonly_property([](const ESM::Repair& rec) -> std::string { return rec.mScript; }); - record["icon"] = sol::readonly_property([vfs](const ESM::Repair& rec) -> std::string - { + record["icon"] = sol::readonly_property([vfs](const ESM::Repair& rec) -> std::string { return Misc::ResourceHelpers::correctIconPath(rec.mIcon, vfs); }); record["maxCondition"] = sol::readonly_property([](const ESM::Repair& rec) -> int { return rec.mData.mUses; }); diff --git a/apps/openmw/mwlua/types/types.cpp b/apps/openmw/mwlua/types/types.cpp index b9ddce4a96..8db8612d06 100644 --- a/apps/openmw/mwlua/types/types.cpp +++ b/apps/openmw/mwlua/types/types.cpp @@ -9,8 +9,8 @@ namespace MWLua { // Names of object types in Lua. // These names are part of OpenMW Lua API. - constexpr std::string_view Actor = "Actor"; // base type for NPC, Creature, Player - constexpr std::string_view Item = "Item"; // base type for all items + constexpr std::string_view Actor = "Actor"; // base type for NPC, Creature, Player + constexpr std::string_view Item = "Item"; // base type for all items constexpr std::string_view Activator = "Activator"; constexpr std::string_view Armor = "Armor"; @@ -37,26 +37,26 @@ namespace MWLua namespace { const static std::unordered_map luaObjectTypeInfo = { - {ESM::REC_INTERNAL_PLAYER, ObjectTypeName::Player}, - {ESM::REC_INTERNAL_MARKER, ObjectTypeName::Marker}, - {ESM::REC_ACTI, ObjectTypeName::Activator}, - {ESM::REC_ARMO, ObjectTypeName::Armor}, - {ESM::REC_BOOK, ObjectTypeName::Book}, - {ESM::REC_CLOT, ObjectTypeName::Clothing}, - {ESM::REC_CONT, ObjectTypeName::Container}, - {ESM::REC_CREA, ObjectTypeName::Creature}, - {ESM::REC_DOOR, ObjectTypeName::Door}, - {ESM::REC_INGR, ObjectTypeName::Ingredient}, - {ESM::REC_LIGH, ObjectTypeName::Light}, - {ESM::REC_MISC, ObjectTypeName::MiscItem}, - {ESM::REC_NPC_, ObjectTypeName::NPC}, - {ESM::REC_ALCH, ObjectTypeName::Potion}, - {ESM::REC_STAT, ObjectTypeName::Static}, - {ESM::REC_WEAP, ObjectTypeName::Weapon}, - {ESM::REC_APPA, ObjectTypeName::Apparatus}, - {ESM::REC_LOCK, ObjectTypeName::Lockpick}, - {ESM::REC_PROB, ObjectTypeName::Probe}, - {ESM::REC_REPA, ObjectTypeName::Repair}, + { ESM::REC_INTERNAL_PLAYER, ObjectTypeName::Player }, + { ESM::REC_INTERNAL_MARKER, ObjectTypeName::Marker }, + { ESM::REC_ACTI, ObjectTypeName::Activator }, + { ESM::REC_ARMO, ObjectTypeName::Armor }, + { ESM::REC_BOOK, ObjectTypeName::Book }, + { ESM::REC_CLOT, ObjectTypeName::Clothing }, + { ESM::REC_CONT, ObjectTypeName::Container }, + { ESM::REC_CREA, ObjectTypeName::Creature }, + { ESM::REC_DOOR, ObjectTypeName::Door }, + { ESM::REC_INGR, ObjectTypeName::Ingredient }, + { ESM::REC_LIGH, ObjectTypeName::Light }, + { ESM::REC_MISC, ObjectTypeName::MiscItem }, + { ESM::REC_NPC_, ObjectTypeName::NPC }, + { ESM::REC_ALCH, ObjectTypeName::Potion }, + { ESM::REC_STAT, ObjectTypeName::Static }, + { ESM::REC_WEAP, ObjectTypeName::Weapon }, + { ESM::REC_APPA, ObjectTypeName::Apparatus }, + { ESM::REC_LOCK, ObjectTypeName::Lockpick }, + { ESM::REC_PROB, ObjectTypeName::Probe }, + { ESM::REC_REPA, ObjectTypeName::Repair }, }; } @@ -84,7 +84,8 @@ namespace MWLua std::string_view getLuaObjectTypeName(const MWWorld::Ptr& ptr) { - return getLuaObjectTypeName(static_cast(getLiveCellRefType(ptr.mRef)), /*fallback=*/ptr.getTypeDescription()); + return getLuaObjectTypeName( + static_cast(getLiveCellRefType(ptr.mRef)), /*fallback=*/ptr.getTypeDescription()); } const MWWorld::Ptr& verifyType(ESM::RecNameInts recordType, const MWWorld::Ptr& ptr) @@ -123,8 +124,7 @@ namespace MWLua auto* lua = context.mLua; sol::table types(lua->sol(), sol::create); auto addType = [&](std::string_view name, std::vector recTypes, - std::optional base = std::nullopt) -> sol::table - { + std::optional base = std::nullopt) -> sol::table { sol::table t(lua->sol(), sol::create); sol::table ro = LuaUtil::makeReadOnly(t); sol::table meta = ro[sol::metatable_key]; @@ -136,8 +136,7 @@ namespace MWLua baseMeta[sol::meta_function::index] = LuaUtil::getMutableFromReadOnly(types[*base]); t[sol::metatable_key] = baseMeta; } - t["objectIsInstance"] = [types=recTypes](const Object& o) - { + t["objectIsInstance"] = [types = recTypes](const Object& o) { unsigned int type = getLiveCellRefType(o.ptr().mRef); for (ESM::RecNameInts t : types) if (t == type) @@ -148,32 +147,34 @@ namespace MWLua return t; }; - addActorBindings(addType(ObjectTypeName::Actor, {ESM::REC_INTERNAL_PLAYER, ESM::REC_CREA, ESM::REC_NPC_}), context); - addType(ObjectTypeName::Item, {ESM::REC_ARMO, ESM::REC_BOOK, ESM::REC_CLOT, ESM::REC_INGR, - ESM::REC_LIGH, ESM::REC_MISC, ESM::REC_ALCH, ESM::REC_WEAP, - ESM::REC_APPA, ESM::REC_LOCK, ESM::REC_PROB, ESM::REC_REPA}); + addActorBindings( + addType(ObjectTypeName::Actor, { ESM::REC_INTERNAL_PLAYER, ESM::REC_CREA, ESM::REC_NPC_ }), context); + addType(ObjectTypeName::Item, + { ESM::REC_ARMO, ESM::REC_BOOK, ESM::REC_CLOT, ESM::REC_INGR, ESM::REC_LIGH, ESM::REC_MISC, ESM::REC_ALCH, + ESM::REC_WEAP, ESM::REC_APPA, ESM::REC_LOCK, ESM::REC_PROB, ESM::REC_REPA }); - addCreatureBindings(addType(ObjectTypeName::Creature, {ESM::REC_CREA}, ObjectTypeName::Actor), context); - addNpcBindings(addType(ObjectTypeName::NPC, {ESM::REC_INTERNAL_PLAYER, ESM::REC_NPC_}, ObjectTypeName::Actor), context); - addType(ObjectTypeName::Player, {ESM::REC_INTERNAL_PLAYER}, ObjectTypeName::NPC); + addCreatureBindings(addType(ObjectTypeName::Creature, { ESM::REC_CREA }, ObjectTypeName::Actor), context); + addNpcBindings( + addType(ObjectTypeName::NPC, { ESM::REC_INTERNAL_PLAYER, ESM::REC_NPC_ }, ObjectTypeName::Actor), context); + addType(ObjectTypeName::Player, { ESM::REC_INTERNAL_PLAYER }, ObjectTypeName::NPC); - addType(ObjectTypeName::Armor, {ESM::REC_ARMO}, ObjectTypeName::Item); - addType(ObjectTypeName::Clothing, {ESM::REC_CLOT}, ObjectTypeName::Item); + addType(ObjectTypeName::Armor, { ESM::REC_ARMO }, ObjectTypeName::Item); + addType(ObjectTypeName::Clothing, { ESM::REC_CLOT }, ObjectTypeName::Item); addIngredientBindings(addType(ObjectTypeName::Ingredient, { ESM::REC_INGR }, ObjectTypeName::Item), context); - addType(ObjectTypeName::Light, {ESM::REC_LIGH}, ObjectTypeName::Item); - addMiscellaneousBindings(addType(ObjectTypeName::MiscItem, {ESM::REC_MISC}, ObjectTypeName::Item), context); - addPotionBindings(addType(ObjectTypeName::Potion, {ESM::REC_ALCH}, ObjectTypeName::Item), context); - addWeaponBindings(addType(ObjectTypeName::Weapon, {ESM::REC_WEAP}, ObjectTypeName::Item), context); - addBookBindings(addType(ObjectTypeName::Book, {ESM::REC_BOOK}, ObjectTypeName::Item), context); - addLockpickBindings(addType(ObjectTypeName::Lockpick, {ESM::REC_LOCK}, ObjectTypeName::Item), context); - addProbeBindings(addType(ObjectTypeName::Probe, {ESM::REC_PROB}, ObjectTypeName::Item), context); - addApparatusBindings(addType(ObjectTypeName::Apparatus, {ESM::REC_APPA}, ObjectTypeName::Item), context); - addRepairBindings(addType(ObjectTypeName::Repair, {ESM::REC_REPA}, ObjectTypeName::Item), context); - - addActivatorBindings(addType(ObjectTypeName::Activator, {ESM::REC_ACTI}), context); - addContainerBindings(addType(ObjectTypeName::Container, {ESM::REC_CONT}), context); - addDoorBindings(addType(ObjectTypeName::Door, {ESM::REC_DOOR}), context); - addType(ObjectTypeName::Static, {ESM::REC_STAT}); + addType(ObjectTypeName::Light, { ESM::REC_LIGH }, ObjectTypeName::Item); + addMiscellaneousBindings(addType(ObjectTypeName::MiscItem, { ESM::REC_MISC }, ObjectTypeName::Item), context); + addPotionBindings(addType(ObjectTypeName::Potion, { ESM::REC_ALCH }, ObjectTypeName::Item), context); + addWeaponBindings(addType(ObjectTypeName::Weapon, { ESM::REC_WEAP }, ObjectTypeName::Item), context); + addBookBindings(addType(ObjectTypeName::Book, { ESM::REC_BOOK }, ObjectTypeName::Item), context); + addLockpickBindings(addType(ObjectTypeName::Lockpick, { ESM::REC_LOCK }, ObjectTypeName::Item), context); + addProbeBindings(addType(ObjectTypeName::Probe, { ESM::REC_PROB }, ObjectTypeName::Item), context); + addApparatusBindings(addType(ObjectTypeName::Apparatus, { ESM::REC_APPA }, ObjectTypeName::Item), context); + addRepairBindings(addType(ObjectTypeName::Repair, { ESM::REC_REPA }, ObjectTypeName::Item), context); + + addActivatorBindings(addType(ObjectTypeName::Activator, { ESM::REC_ACTI }), context); + addContainerBindings(addType(ObjectTypeName::Container, { ESM::REC_CONT }), context); + addDoorBindings(addType(ObjectTypeName::Door, { ESM::REC_DOOR }), context); + addType(ObjectTypeName::Static, { ESM::REC_STAT }); sol::table typeToPackage = getTypeToPackageTable(context.mLua->sol()); sol::table packageToType = getPackageToTypeTable(context.mLua->sol()); diff --git a/apps/openmw/mwlua/types/weapon.cpp b/apps/openmw/mwlua/types/weapon.cpp index dd12cbc583..1f3ab35c2c 100644 --- a/apps/openmw/mwlua/types/weapon.cpp +++ b/apps/openmw/mwlua/types/weapon.cpp @@ -1,18 +1,20 @@ #include "types.hpp" #include +#include #include #include -#include -#include #include #include +#include namespace sol { template <> - struct is_automagical : std::false_type {}; + struct is_automagical : std::false_type + { + }; } #include namespace MWLua @@ -20,38 +22,38 @@ namespace MWLua void addWeaponBindings(sol::table weapon, const Context& context) { weapon["TYPE"] = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs({ - {"ShortBladeOneHand", ESM::Weapon::ShortBladeOneHand}, - {"LongBladeOneHand", ESM::Weapon::LongBladeOneHand}, - {"LongBladeTwoHand", ESM::Weapon::LongBladeTwoHand}, - {"BluntOneHand", ESM::Weapon::BluntOneHand}, - {"BluntTwoClose", ESM::Weapon::BluntTwoClose}, - {"BluntTwoWide", ESM::Weapon::BluntTwoWide}, - {"SpearTwoWide", ESM::Weapon::SpearTwoWide}, - {"AxeOneHand", ESM::Weapon::AxeOneHand}, - {"AxeTwoHand", ESM::Weapon::AxeTwoHand}, - {"MarksmanBow", ESM::Weapon::MarksmanBow}, - {"MarksmanCrossbow", ESM::Weapon::MarksmanCrossbow}, - {"MarksmanThrown", ESM::Weapon::MarksmanThrown}, - {"Arrow", ESM::Weapon::Arrow}, - {"Bolt", ESM::Weapon::Bolt}, + { "ShortBladeOneHand", ESM::Weapon::ShortBladeOneHand }, + { "LongBladeOneHand", ESM::Weapon::LongBladeOneHand }, + { "LongBladeTwoHand", ESM::Weapon::LongBladeTwoHand }, + { "BluntOneHand", ESM::Weapon::BluntOneHand }, + { "BluntTwoClose", ESM::Weapon::BluntTwoClose }, + { "BluntTwoWide", ESM::Weapon::BluntTwoWide }, + { "SpearTwoWide", ESM::Weapon::SpearTwoWide }, + { "AxeOneHand", ESM::Weapon::AxeOneHand }, + { "AxeTwoHand", ESM::Weapon::AxeTwoHand }, + { "MarksmanBow", ESM::Weapon::MarksmanBow }, + { "MarksmanCrossbow", ESM::Weapon::MarksmanCrossbow }, + { "MarksmanThrown", ESM::Weapon::MarksmanThrown }, + { "Arrow", ESM::Weapon::Arrow }, + { "Bolt", ESM::Weapon::Bolt }, })); auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); - const MWWorld::Store* store = &MWBase::Environment::get().getWorld()->getStore().get(); - weapon["record"] = sol::overload( - [](const Object& obj) -> const ESM::Weapon* { return obj.ptr().get()->mBase; }, - [store](const std::string& recordId) -> const ESM::Weapon* { return store->find(recordId); }); + const MWWorld::Store* store + = &MWBase::Environment::get().getWorld()->getStore().get(); + weapon["record"] + = sol::overload([](const Object& obj) -> const ESM::Weapon* { return obj.ptr().get()->mBase; }, + [store](const std::string& recordId) -> const ESM::Weapon* { return store->find(recordId); }); sol::usertype record = context.mLua->sol().new_usertype("ESM3_Weapon"); - record[sol::meta_function::to_string] = [](const ESM::Weapon& rec) -> std::string { return "ESM3_Weapon[" + rec.mId + "]"; }; + record[sol::meta_function::to_string] + = [](const ESM::Weapon& rec) -> std::string { return "ESM3_Weapon[" + rec.mId + "]"; }; record["id"] = sol::readonly_property([](const ESM::Weapon& rec) -> std::string { return rec.mId; }); record["name"] = sol::readonly_property([](const ESM::Weapon& rec) -> std::string { return rec.mName; }); - record["model"] = sol::readonly_property([vfs](const ESM::Weapon& rec) -> std::string - { + record["model"] = sol::readonly_property([vfs](const ESM::Weapon& rec) -> std::string { return Misc::ResourceHelpers::correctMeshPath(rec.mModel, vfs); }); - record["icon"] = sol::readonly_property([vfs](const ESM::Weapon& rec) -> std::string - { + record["icon"] = sol::readonly_property([vfs](const ESM::Weapon& rec) -> std::string { return Misc::ResourceHelpers::correctIconPath(rec.mIcon, vfs); }); record["enchant"] = sol::readonly_property([](const ESM::Weapon& rec) -> std::string { return rec.mEnchant; }); @@ -66,13 +68,20 @@ namespace MWLua record["health"] = sol::readonly_property([](const ESM::Weapon& rec) -> int { return rec.mData.mHealth; }); record["speed"] = sol::readonly_property([](const ESM::Weapon& rec) -> float { return rec.mData.mSpeed; }); record["reach"] = sol::readonly_property([](const ESM::Weapon& rec) -> float { return rec.mData.mReach; }); - record["enchantCapacity"] = sol::readonly_property([](const ESM::Weapon& rec) -> float { return rec.mData.mEnchant * 0.1f; }); - record["chopMinDamage"] = sol::readonly_property([](const ESM::Weapon& rec) -> int { return rec.mData.mChop[0]; }); - record["chopMaxDamage"] = sol::readonly_property([](const ESM::Weapon& rec) -> int { return rec.mData.mChop[1]; }); - record["slashMinDamage"] = sol::readonly_property([](const ESM::Weapon& rec) -> int { return rec.mData.mSlash[0]; }); - record["slashMaxDamage"] = sol::readonly_property([](const ESM::Weapon& rec) -> int { return rec.mData.mSlash[1]; }); - record["thrustMinDamage"] = sol::readonly_property([](const ESM::Weapon& rec) -> int { return rec.mData.mThrust[0]; }); - record["thrustMaxDamage"] = sol::readonly_property([](const ESM::Weapon& rec) -> int { return rec.mData.mThrust[1]; }); + record["enchantCapacity"] + = sol::readonly_property([](const ESM::Weapon& rec) -> float { return rec.mData.mEnchant * 0.1f; }); + record["chopMinDamage"] + = sol::readonly_property([](const ESM::Weapon& rec) -> int { return rec.mData.mChop[0]; }); + record["chopMaxDamage"] + = sol::readonly_property([](const ESM::Weapon& rec) -> int { return rec.mData.mChop[1]; }); + record["slashMinDamage"] + = sol::readonly_property([](const ESM::Weapon& rec) -> int { return rec.mData.mSlash[0]; }); + record["slashMaxDamage"] + = sol::readonly_property([](const ESM::Weapon& rec) -> int { return rec.mData.mSlash[1]; }); + record["thrustMinDamage"] + = sol::readonly_property([](const ESM::Weapon& rec) -> int { return rec.mData.mThrust[0]; }); + record["thrustMaxDamage"] + = sol::readonly_property([](const ESM::Weapon& rec) -> int { return rec.mData.mThrust[1]; }); } } diff --git a/apps/openmw/mwlua/uibindings.cpp b/apps/openmw/mwlua/uibindings.cpp index 6fe6926489..fdc58554fe 100644 --- a/apps/openmw/mwlua/uibindings.cpp +++ b/apps/openmw/mwlua/uibindings.cpp @@ -1,13 +1,13 @@ -#include +#include +#include #include #include -#include #include -#include #include +#include -#include #include +#include #include "context.hpp" #include "luamanagerimp.hpp" @@ -20,116 +20,102 @@ namespace MWLua { class UiAction final : public LuaManager::Action { - public: - enum Type - { - CREATE = 0, - UPDATE, - DESTROY, - }; - - UiAction(Type type, std::shared_ptr element, LuaUtil::LuaState* state) - : Action(state) - , mType{ type } - , mElement{ std::move(element) } - {} + public: + enum Type + { + CREATE = 0, + UPDATE, + DESTROY, + }; - void apply(WorldView&) const override - { - try { - switch (mType) - { - case CREATE: - mElement->create(); - break; - case UPDATE: - mElement->update(); - break; - case DESTROY: - mElement->destroy(); - break; - } - } - catch (std::exception&) - { - // prevent any actions on a potentially corrupted widget - mElement->mRoot = nullptr; - throw; - } - } + UiAction(Type type, std::shared_ptr element, LuaUtil::LuaState* state) + : Action(state) + , mType{ type } + , mElement{ std::move(element) } + { + } - std::string toString() const override + void apply(WorldView&) const override + { + try { - std::string result; switch (mType) { case CREATE: - result += "Create"; + mElement->create(); break; case UPDATE: - result += "Update"; + mElement->update(); break; case DESTROY: - result += "Destroy"; + mElement->destroy(); break; } - result += " UI"; - return result; } + catch (std::exception&) + { + // prevent any actions on a potentially corrupted widget + mElement->mRoot = nullptr; + throw; + } + } + + std::string toString() const override + { + std::string result; + switch (mType) + { + case CREATE: + result += "Create"; + break; + case UPDATE: + result += "Update"; + break; + case DESTROY: + result += "Destroy"; + break; + } + result += " UI"; + return result; + } - private: - Type mType; - std::shared_ptr mElement; + private: + Type mType; + std::shared_ptr mElement; }; // Lua arrays index from 1 - inline size_t fromLuaIndex(size_t i) { return i - 1; } - inline size_t toLuaIndex(size_t i) { return i + 1; } + inline size_t fromLuaIndex(size_t i) + { + return i - 1; + } + inline size_t toLuaIndex(size_t i) + { + return i + 1; + } } sol::table initUserInterfacePackage(const Context& context) { auto uiContent = context.mLua->sol().new_usertype("UiContent"); - uiContent[sol::meta_function::length] = [](const LuaUi::Content& content) - { - return content.size(); - }; - uiContent[sol::meta_function::index] = sol::overload( - [](const LuaUi::Content& content, size_t index) - { - return content.at(fromLuaIndex(index)); - }, - [](const LuaUi::Content& content, std::string_view name) - { - return content.at(name); - }); - uiContent[sol::meta_function::new_index] = sol::overload( - [](LuaUi::Content& content, size_t index, const sol::table& table) - { - content.assign(fromLuaIndex(index), table); - }, - [](LuaUi::Content& content, size_t index, sol::nil_t nil) - { - content.remove(fromLuaIndex(index)); - }, - [](LuaUi::Content& content, std::string_view name, const sol::table& table) - { - content.assign(name, table); - }, - [](LuaUi::Content& content, std::string_view name, sol::nil_t nil) - { - content.remove(name); - }); - uiContent["insert"] = [](LuaUi::Content& content, size_t index, const sol::table& table) - { + uiContent[sol::meta_function::length] = [](const LuaUi::Content& content) { return content.size(); }; + uiContent[sol::meta_function::index] + = sol::overload([](const LuaUi::Content& content, size_t index) { return content.at(fromLuaIndex(index)); }, + [](const LuaUi::Content& content, std::string_view name) { return content.at(name); }); + uiContent[sol::meta_function::new_index] + = sol::overload([](LuaUi::Content& content, size_t index, + const sol::table& table) { content.assign(fromLuaIndex(index), table); }, + [](LuaUi::Content& content, size_t index, sol::nil_t nil) { content.remove(fromLuaIndex(index)); }, + [](LuaUi::Content& content, std::string_view name, const sol::table& table) { + content.assign(name, table); + }, + [](LuaUi::Content& content, std::string_view name, sol::nil_t nil) { content.remove(name); }); + uiContent["insert"] = [](LuaUi::Content& content, size_t index, const sol::table& table) { content.insert(fromLuaIndex(index), table); }; - uiContent["add"] = [](LuaUi::Content& content, const sol::table& table) - { - content.insert(content.size(), table); - }; - uiContent["indexOf"] = [](LuaUi::Content& content, const sol::table& table) -> sol::optional - { + uiContent["add"] + = [](LuaUi::Content& content, const sol::table& table) { content.insert(content.size(), table); }; + uiContent["indexOf"] = [](LuaUi::Content& content, const sol::table& table) -> sol::optional { size_t index = content.indexOf(table); if (index < content.size()) return toLuaIndex(index); @@ -137,10 +123,8 @@ namespace MWLua return sol::nullopt; }; { - auto pairs = [](LuaUi::Content& content) - { - auto next = [](LuaUi::Content& content, size_t i) -> sol::optional> - { + auto pairs = [](LuaUi::Content& content) { + auto next = [](LuaUi::Content& content, size_t i) -> sol::optional> { if (i < content.size()) return std::make_tuple(i + 1, content.at(i)); else @@ -153,25 +137,15 @@ namespace MWLua } auto element = context.mLua->sol().new_usertype("Element"); - element["layout"] = sol::property( - [](LuaUi::Element& element) - { - return element.mLayout; - }, - [](LuaUi::Element& element, const sol::table& layout) - { - element.mLayout = layout; - } - ); - element["update"] = [context](const std::shared_ptr& element) - { + element["layout"] = sol::property([](LuaUi::Element& element) { return element.mLayout; }, + [](LuaUi::Element& element, const sol::table& layout) { element.mLayout = layout; }); + element["update"] = [context](const std::shared_ptr& element) { if (element->mDestroy || element->mUpdate) return; element->mUpdate = true; context.mLuaManager->addAction(std::make_unique(UiAction::UPDATE, element, context.mLua)); }; - element["destroy"] = [context](const std::shared_ptr& element) - { + element["destroy"] = [context](const std::shared_ptr& element) { if (element->mDestroy) return; element->mDestroy = true; @@ -179,88 +153,66 @@ namespace MWLua }; sol::table api = context.mLua->newTable(); - api["showMessage"] = [luaManager=context.mLuaManager](std::string_view message) - { - luaManager->addUIMessage(message); - }; + api["showMessage"] + = [luaManager = context.mLuaManager](std::string_view message) { luaManager->addUIMessage(message); }; api["CONSOLE_COLOR"] = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs({ - {"Default", Misc::Color::fromHex(MWBase::WindowManager::sConsoleColor_Default.substr(1))}, - {"Error", Misc::Color::fromHex(MWBase::WindowManager::sConsoleColor_Error.substr(1))}, - {"Success", Misc::Color::fromHex(MWBase::WindowManager::sConsoleColor_Success.substr(1))}, - {"Info", Misc::Color::fromHex(MWBase::WindowManager::sConsoleColor_Info.substr(1))}, + { "Default", Misc::Color::fromHex(MWBase::WindowManager::sConsoleColor_Default.substr(1)) }, + { "Error", Misc::Color::fromHex(MWBase::WindowManager::sConsoleColor_Error.substr(1)) }, + { "Success", Misc::Color::fromHex(MWBase::WindowManager::sConsoleColor_Success.substr(1)) }, + { "Info", Misc::Color::fromHex(MWBase::WindowManager::sConsoleColor_Info.substr(1)) }, })); - api["printToConsole"] = [luaManager=context.mLuaManager](const std::string& message, const Misc::Color& color) - { - luaManager->addInGameConsoleMessage(message + "\n", color); - }; - api["setConsoleMode"] = [luaManager=context.mLuaManager](std::string_view mode) - { + api["printToConsole"] + = [luaManager = context.mLuaManager](const std::string& message, const Misc::Color& color) { + luaManager->addInGameConsoleMessage(message + "\n", color); + }; + api["setConsoleMode"] = [luaManager = context.mLuaManager](std::string_view mode) { luaManager->addAction( - [mode = std::string(mode)]{ MWBase::Environment::get().getWindowManager()->setConsoleMode(mode); }); + [mode = std::string(mode)] { MWBase::Environment::get().getWindowManager()->setConsoleMode(mode); }); }; - api["setConsoleSelectedObject"] = [luaManager=context.mLuaManager](const sol::object& obj) - { + api["setConsoleSelectedObject"] = [luaManager = context.mLuaManager](const sol::object& obj) { const auto wm = MWBase::Environment::get().getWindowManager(); if (obj == sol::nil) - luaManager->addAction([wm]{ wm->setConsoleSelectedObject(MWWorld::Ptr()); }); + luaManager->addAction([wm] { wm->setConsoleSelectedObject(MWWorld::Ptr()); }); else { if (!obj.is()) throw std::runtime_error("Game object expected"); - luaManager->addAction([wm, obj=obj.as()]{ wm->setConsoleSelectedObject(obj.ptr()); }); + luaManager->addAction([wm, obj = obj.as()] { wm->setConsoleSelectedObject(obj.ptr()); }); } }; - api["content"] = [](const sol::table& table) - { - return LuaUi::Content(table); - }; - api["create"] = [context](const sol::table& layout) - { + api["content"] = [](const sol::table& table) { return LuaUi::Content(table); }; + api["create"] = [context](const sol::table& layout) { auto element = LuaUi::Element::make(layout); context.mLuaManager->addAction(std::make_unique(UiAction::CREATE, element, context.mLua)); return element; }; - api["updateAll"] = [context]() - { + api["updateAll"] = [context]() { LuaUi::Element::forEach([](LuaUi::Element* e) { e->mUpdate = true; }); - context.mLuaManager->addAction([]() - { - LuaUi::Element::forEach([](LuaUi::Element* e) { e->update(); }); - }, "Update all UI elements"); - }; - api["_getMenuTransparency"] = []() - { - return Settings::Manager::getFloat("menu transparency", "GUI"); + context.mLuaManager->addAction( + []() { LuaUi::Element::forEach([](LuaUi::Element* e) { e->update(); }); }, "Update all UI elements"); }; + api["_getMenuTransparency"] = []() { return Settings::Manager::getFloat("menu transparency", "GUI"); }; auto uiLayer = context.mLua->sol().new_usertype("UiLayer"); uiLayer["name"] = sol::property([](LuaUi::Layer& self) { return self.name(); }); uiLayer["size"] = sol::property([](LuaUi::Layer& self) { return self.size(); }); - uiLayer[sol::meta_function::to_string] = [](LuaUi::Layer& self) - { - return Misc::StringUtils::format("UiLayer(%s)", self.name()); - }; + uiLayer[sol::meta_function::to_string] + = [](LuaUi::Layer& self) { return Misc::StringUtils::format("UiLayer(%s)", self.name()); }; sol::table layers = context.mLua->newTable(); - layers[sol::meta_function::length] = []() - { - return LuaUi::Layer::count(); - }; - layers[sol::meta_function::index] = [](size_t index) - { + layers[sol::meta_function::length] = []() { return LuaUi::Layer::count(); }; + layers[sol::meta_function::index] = [](size_t index) { index = fromLuaIndex(index); return LuaUi::Layer(index); }; - layers["indexOf"] = [](std::string_view name) -> sol::optional - { + layers["indexOf"] = [](std::string_view name) -> sol::optional { size_t index = LuaUi::Layer::indexOf(name); if (index == LuaUi::Layer::count()) return sol::nullopt; else return toLuaIndex(index); }; - layers["insertAfter"] = [context](std::string_view afterName, std::string_view name, const sol::object& opt) - { + layers["insertAfter"] = [context](std::string_view afterName, std::string_view name, const sol::object& opt) { LuaUi::Layer::Options options; options.mInteractive = LuaUtil::getValueOrDefault(LuaUtil::getFieldOrNil(opt, "interactive"), true); size_t index = LuaUi::Layer::indexOf(afterName); @@ -269,8 +221,7 @@ namespace MWLua index++; context.mLuaManager->addAction([=]() { LuaUi::Layer::insert(index, name, options); }, "Insert UI layer"); }; - layers["insertBefore"] = [context](std::string_view beforename, std::string_view name, const sol::object& opt) - { + layers["insertBefore"] = [context](std::string_view beforename, std::string_view name, const sol::object& opt) { LuaUi::Layer::Options options; options.mInteractive = LuaUtil::getValueOrDefault(LuaUtil::getFieldOrNil(opt, "interactive"), true); size_t index = LuaUi::Layer::indexOf(beforename); @@ -279,10 +230,8 @@ namespace MWLua context.mLuaManager->addAction([=]() { LuaUi::Layer::insert(index, name, options); }, "Insert UI layer"); }; { - auto pairs = [layers](const sol::object&) - { - auto next = [](const sol::table& l, size_t i) -> sol::optional> - { + auto pairs = [layers](const sol::object&) { + auto next = [](const sol::table& l, size_t i) -> sol::optional> { if (i < LuaUi::Layer::count()) return std::make_tuple(i + 1, LuaUi::Layer(i)); else @@ -300,16 +249,13 @@ namespace MWLua typeTable.set(it.second, it.first); api["TYPE"] = LuaUtil::makeStrictReadOnly(typeTable); - api["ALIGNMENT"] = LuaUtil::makeStrictReadOnly(context.mLua->tableFromPairs({ - { "Start", LuaUi::Alignment::Start }, - { "Center", LuaUi::Alignment::Center }, - { "End", LuaUi::Alignment::End } - })); + api["ALIGNMENT"] = LuaUtil::makeStrictReadOnly( + context.mLua->tableFromPairs({ { "Start", LuaUi::Alignment::Start }, + { "Center", LuaUi::Alignment::Center }, { "End", LuaUi::Alignment::End } })); api["registerSettingsPage"] = &LuaUi::registerSettingsPage; - api["texture"] = [luaManager=context.mLuaManager](const sol::table& options) - { + api["texture"] = [luaManager = context.mLuaManager](const sol::table& options) { LuaUi::TextureData data; sol::object path = LuaUtil::getFieldOrNil(options, "path"); if (path.is()) @@ -325,12 +271,9 @@ namespace MWLua return luaManager->uiResourceManager()->registerTexture(data); }; - api["screenSize"] = []() - { + api["screenSize"] = []() { return osg::Vec2f( - Settings::Manager::getInt("resolution x", "Video"), - Settings::Manager::getInt("resolution y", "Video") - ); + Settings::Manager::getInt("resolution x", "Video"), Settings::Manager::getInt("resolution y", "Video")); }; return LuaUtil::makeReadOnly(api); diff --git a/apps/openmw/mwlua/userdataserializer.cpp b/apps/openmw/mwlua/userdataserializer.cpp index 3aabbfe0ac..9640a05625 100644 --- a/apps/openmw/mwlua/userdataserializer.cpp +++ b/apps/openmw/mwlua/userdataserializer.cpp @@ -12,7 +12,11 @@ namespace MWLua { public: explicit Serializer(bool localSerializer, ObjectRegistry* registry, std::map* contentFileMapping) - : mLocalSerializer(localSerializer), mObjectRegistry(registry), mContentFileMapping(contentFileMapping) {} + : mLocalSerializer(localSerializer) + , mObjectRegistry(registry) + , mContentFileMapping(contentFileMapping) + { + } private: // Appends serialized sol::userdata to the end of BinaryData. @@ -27,8 +31,8 @@ namespace MWLua return false; } - // Deserializes userdata of type "typeName" from binaryData. Should push the result on stack using sol::stack::push. - // Returns false if this type is not supported by this serializer. + // Deserializes userdata of type "typeName" from binaryData. Should push the result on stack using + // sol::stack::push. Returns false if this type is not supported by this serializer. bool deserialize(std::string_view typeName, std::string_view binaryData, lua_State* lua) const override { if (typeName == sRefNumTypeName) diff --git a/apps/openmw/mwlua/worldview.cpp b/apps/openmw/mwlua/worldview.cpp index e1bf3002a7..49b28226d2 100644 --- a/apps/openmw/mwlua/worldview.cpp +++ b/apps/openmw/mwlua/worldview.cpp @@ -8,9 +8,9 @@ #include "../mwclass/container.hpp" +#include "../mwworld/cellutils.hpp" #include "../mwworld/class.hpp" #include "../mwworld/timestamp.hpp" -#include "../mwworld/cellutils.hpp" namespace MWLua { @@ -122,7 +122,8 @@ namespace MWLua group.mChanged = true; } - // TODO: If Lua scripts will use several threads at the same time, then `find*Cell` functions should have critical sections. + // TODO: If Lua scripts will use several threads at the same time, then `find*Cell` functions should have critical + // sections. MWWorld::CellStore* WorldView::findCell(const std::string& name, osg::Vec3f position) { MWBase::World* world = MWBase::Environment::get().getWorld(); diff --git a/apps/openmw/mwlua/worldview.hpp b/apps/openmw/mwlua/worldview.hpp index 181a73c0b0..8c5127b6f6 100644 --- a/apps/openmw/mwlua/worldview.hpp +++ b/apps/openmw/mwlua/worldview.hpp @@ -21,8 +21,8 @@ namespace MWLua class WorldView { public: - void update(); // Should be called every frame. - void clear(); // Should be called every time before starting or loading a new game. + void update(); // Should be called every frame. + void clear(); // Should be called every time before starting or loading a new game. // Whether the world is paused (i.e. game time is not changing and actors don't move). bool isPaused() const { return mPaused; } diff --git a/apps/openmw/mwmechanics/activespells.cpp b/apps/openmw/mwmechanics/activespells.cpp index 6d61b59553..8cfce2db7e 100644 --- a/apps/openmw/mwmechanics/activespells.cpp +++ b/apps/openmw/mwmechanics/activespells.cpp @@ -4,15 +4,15 @@ #include -#include #include +#include #include -#include -#include #include +#include #include +#include #include @@ -27,8 +27,8 @@ #include "../mwrender/animation.hpp" -#include "../mwworld/esmstore.hpp" #include "../mwworld/class.hpp" +#include "../mwworld/esmstore.hpp" #include "../mwworld/inventorystore.hpp" namespace @@ -36,20 +36,22 @@ namespace bool merge(std::vector& present, const std::vector& queued) { // Can't merge if we already have an effect with the same effect index - auto problem = std::find_if(queued.begin(), queued.end(), [&] (const auto& qEffect) - { - return std::find_if(present.begin(), present.end(), [&] (const auto& pEffect) { return pEffect.mEffectIndex == qEffect.mEffectIndex; }) != present.end(); + auto problem = std::find_if(queued.begin(), queued.end(), [&](const auto& qEffect) { + return std::find_if(present.begin(), present.end(), [&](const auto& pEffect) { + return pEffect.mEffectIndex == qEffect.mEffectIndex; + }) != present.end(); }); - if(problem != queued.end()) + if (problem != queued.end()) return false; present.insert(present.end(), queued.begin(), queued.end()); return true; } - void addEffects(std::vector& effects, const ESM::EffectList& list, bool ignoreResistances = false) + void addEffects( + std::vector& effects, const ESM::EffectList& list, bool ignoreResistances = false) { int currentEffectIndex = 0; - for(const auto& enam : list.mList) + for (const auto& enam : list.mList) { ESM::ActiveEffect effect; effect.mEffectId = enam.mEffectID; @@ -59,7 +61,7 @@ namespace effect.mMaxMagnitude = enam.mMagnMax; effect.mEffectIndex = currentEffectIndex++; effect.mFlags = ESM::ActiveEffect::Flag_None; - if(ignoreResistances) + if (ignoreResistances) effect.mFlags |= ESM::ActiveEffect::Flag_Ignore_Resistances; effect.mDuration = -1; effect.mTimeLeft = -1; @@ -70,7 +72,8 @@ namespace namespace MWMechanics { - ActiveSpells::IterationGuard::IterationGuard(ActiveSpells& spells) : mActiveSpells(spells) + ActiveSpells::IterationGuard::IterationGuard(ActiveSpells& spells) + : mActiveSpells(spells) { mActiveSpells.mIterating = true; } @@ -81,38 +84,65 @@ namespace MWMechanics } ActiveSpells::ActiveSpellParams::ActiveSpellParams(const CastSpell& cast, const MWWorld::Ptr& caster) - : mId(cast.mId), mDisplayName(cast.mSourceName), mCasterActorId(-1), mSlot(cast.mSlot), mType(cast.mType), mWorsenings(-1) + : mId(cast.mId) + , mDisplayName(cast.mSourceName) + , mCasterActorId(-1) + , mSlot(cast.mSlot) + , mType(cast.mType) + , mWorsenings(-1) { - if(!caster.isEmpty() && caster.getClass().isActor()) + if (!caster.isEmpty() && caster.getClass().isActor()) mCasterActorId = caster.getClass().getCreatureStats(caster).getActorId(); } - ActiveSpells::ActiveSpellParams::ActiveSpellParams(const ESM::Spell* spell, const MWWorld::Ptr& actor, bool ignoreResistances) - : mId(spell->mId), mDisplayName(spell->mName), mCasterActorId(actor.getClass().getCreatureStats(actor).getActorId()), mSlot(0) - , mType(spell->mData.mType == ESM::Spell::ST_Ability ? ESM::ActiveSpells::Type_Ability : ESM::ActiveSpells::Type_Permanent), mWorsenings(-1) + ActiveSpells::ActiveSpellParams::ActiveSpellParams( + const ESM::Spell* spell, const MWWorld::Ptr& actor, bool ignoreResistances) + : mId(spell->mId) + , mDisplayName(spell->mName) + , mCasterActorId(actor.getClass().getCreatureStats(actor).getActorId()) + , mSlot(0) + , mType(spell->mData.mType == ESM::Spell::ST_Ability ? ESM::ActiveSpells::Type_Ability + : ESM::ActiveSpells::Type_Permanent) + , mWorsenings(-1) { assert(spell->mData.mType != ESM::Spell::ST_Spell && spell->mData.mType != ESM::Spell::ST_Power); addEffects(mEffects, spell->mEffects, ignoreResistances); } - ActiveSpells::ActiveSpellParams::ActiveSpellParams(const MWWorld::ConstPtr& item, const ESM::Enchantment* enchantment, int slotIndex, const MWWorld::Ptr& actor) - : mId(item.getCellRef().getRefId()), mDisplayName(item.getClass().getName(item)), mCasterActorId(actor.getClass().getCreatureStats(actor).getActorId()) - , mSlot(slotIndex), mType(ESM::ActiveSpells::Type_Enchantment), mWorsenings(-1) + ActiveSpells::ActiveSpellParams::ActiveSpellParams( + const MWWorld::ConstPtr& item, const ESM::Enchantment* enchantment, int slotIndex, const MWWorld::Ptr& actor) + : mId(item.getCellRef().getRefId()) + , mDisplayName(item.getClass().getName(item)) + , mCasterActorId(actor.getClass().getCreatureStats(actor).getActorId()) + , mSlot(slotIndex) + , mType(ESM::ActiveSpells::Type_Enchantment) + , mWorsenings(-1) { assert(enchantment->mData.mType == ESM::Enchantment::ConstantEffect); addEffects(mEffects, enchantment->mEffects); } ActiveSpells::ActiveSpellParams::ActiveSpellParams(const ESM::ActiveSpells::ActiveSpellParams& params) - : mId(params.mId), mEffects(params.mEffects), mDisplayName(params.mDisplayName), mCasterActorId(params.mCasterActorId) - , mSlot(params.mItem.isSet() ? params.mItem.mIndex : 0) - , mType(params.mType), mWorsenings(params.mWorsenings), mNextWorsening({params.mNextWorsening}) - {} + : mId(params.mId) + , mEffects(params.mEffects) + , mDisplayName(params.mDisplayName) + , mCasterActorId(params.mCasterActorId) + , mSlot(params.mItem.isSet() ? params.mItem.mIndex : 0) + , mType(params.mType) + , mWorsenings(params.mWorsenings) + , mNextWorsening({ params.mNextWorsening }) + { + } ActiveSpells::ActiveSpellParams::ActiveSpellParams(const ActiveSpellParams& params, const MWWorld::Ptr& actor) - : mId(params.mId), mDisplayName(params.mDisplayName), mCasterActorId(actor.getClass().getCreatureStats(actor).getActorId()) - , mSlot(params.mSlot), mType(params.mType), mWorsenings(-1) - {} + : mId(params.mId) + , mDisplayName(params.mDisplayName) + , mCasterActorId(actor.getClass().getCreatureStats(actor).getActorId()) + , mSlot(params.mSlot) + , mType(params.mType) + , mWorsenings(-1) + { + } ESM::ActiveSpells::ActiveSpellParams ActiveSpells::ActiveSpellParams::toEsm() const { @@ -122,7 +152,7 @@ namespace MWMechanics params.mDisplayName = mDisplayName; params.mCasterActorId = mCasterActorId; params.mItem.unset(); - if(mSlot) + if (mSlot) { // Note that we're storing the inventory slot as a RefNum instead of an int as a matter of future proofing // mSlot needs to be replaced with a RefNum once inventory items get persistent RefNum (#4508 #6148) @@ -137,7 +167,7 @@ namespace MWMechanics void ActiveSpells::ActiveSpellParams::worsen() { ++mWorsenings; - if(!mWorsenings) + if (!mWorsenings) mNextWorsening = MWBase::Environment::get().getWorld()->getTimeStamp(); mNextWorsening += CorprusStats::sWorseningPeriod; } @@ -156,25 +186,26 @@ namespace MWMechanics { const auto& creatureStats = ptr.getClass().getCreatureStats(ptr); assert(&creatureStats.getActiveSpells() == this); - IterationGuard guard{*this}; + IterationGuard guard{ *this }; // Erase no longer active spells and effects - for(auto spellIt = mSpells.begin(); spellIt != mSpells.end();) + for (auto spellIt = mSpells.begin(); spellIt != mSpells.end();) { - if(spellIt->mType != ESM::ActiveSpells::Type_Temporary && spellIt->mType != ESM::ActiveSpells::Type_Consumable) + if (spellIt->mType != ESM::ActiveSpells::Type_Temporary + && spellIt->mType != ESM::ActiveSpells::Type_Consumable) { ++spellIt; continue; } bool removedSpell = false; - for(auto effectIt = spellIt->mEffects.begin(); effectIt != spellIt->mEffects.end();) + for (auto effectIt = spellIt->mEffects.begin(); effectIt != spellIt->mEffects.end();) { - if(effectIt->mFlags & ESM::ActiveEffect::Flag_Remove && effectIt->mTimeLeft <= 0.f) + if (effectIt->mFlags & ESM::ActiveEffect::Flag_Remove && effectIt->mTimeLeft <= 0.f) { auto effect = *effectIt; effectIt = spellIt->mEffects.erase(effectIt); onMagicEffectRemoved(ptr, *spellIt, effect); removedSpell = applyPurges(ptr, &spellIt, &effectIt); - if(removedSpell) + if (removedSpell) break; } else @@ -182,55 +213,62 @@ namespace MWMechanics ++effectIt; } } - if(removedSpell) + if (removedSpell) continue; - if(spellIt->mEffects.empty()) + if (spellIt->mEffects.empty()) spellIt = mSpells.erase(spellIt); else ++spellIt; } - for(const auto& spell : mQueue) + for (const auto& spell : mQueue) addToSpells(ptr, spell); mQueue.clear(); // Vanilla only does this on cell change I think const auto& spells = creatureStats.getSpells(); - for(const ESM::Spell* spell : spells) + for (const ESM::Spell* spell : spells) { - if(spell->mData.mType != ESM::Spell::ST_Spell && spell->mData.mType != ESM::Spell::ST_Power && !isSpellActive(spell->mId)) - mSpells.emplace_back(ActiveSpellParams{spell, ptr}); + if (spell->mData.mType != ESM::Spell::ST_Spell && spell->mData.mType != ESM::Spell::ST_Power + && !isSpellActive(spell->mId)) + mSpells.emplace_back(ActiveSpellParams{ spell, ptr }); } - if(ptr.getClass().hasInventoryStore(ptr) && !(creatureStats.isDead() && !creatureStats.isDeathAnimationFinished())) + if (ptr.getClass().hasInventoryStore(ptr) + && !(creatureStats.isDead() && !creatureStats.isDeathAnimationFinished())) { auto& store = ptr.getClass().getInventoryStore(ptr); - if(store.getInvListener() != nullptr) + if (store.getInvListener() != nullptr) { bool playNonLooping = !store.isFirstEquip(); const auto world = MWBase::Environment::get().getWorld(); - for(int slotIndex = 0; slotIndex < MWWorld::InventoryStore::Slots; slotIndex++) + for (int slotIndex = 0; slotIndex < MWWorld::InventoryStore::Slots; slotIndex++) { auto slot = store.getSlot(slotIndex); - if(slot == store.end()) + if (slot == store.end()) continue; const std::string_view enchantmentId = slot->getClass().getEnchantment(*slot); - if(enchantmentId.empty()) + if (enchantmentId.empty()) continue; const ESM::Enchantment* enchantment = world->getStore().get().find(enchantmentId); - if(enchantment->mData.mType != ESM::Enchantment::ConstantEffect) + if (enchantment->mData.mType != ESM::Enchantment::ConstantEffect) continue; - if(std::find_if(mSpells.begin(), mSpells.end(), [&] (const ActiveSpellParams& params) - { - return params.mSlot == slotIndex && params.mType == ESM::ActiveSpells::Type_Enchantment && params.mId == slot->getCellRef().getRefId(); - }) != mSpells.end()) + if (std::find_if(mSpells.begin(), mSpells.end(), + [&](const ActiveSpellParams& params) { + return params.mSlot == slotIndex && params.mType == ESM::ActiveSpells::Type_Enchantment + && params.mId == slot->getCellRef().getRefId(); + }) + != mSpells.end()) continue; - // world->breakInvisibility leads to a stack overflow as it calls this method so just break invisibility manually + // world->breakInvisibility leads to a stack overflow as it calls this method so just break + // invisibility manually purgeEffect(ptr, ESM::MagicEffect::Invisibility); applyPurges(ptr); - const ActiveSpellParams& params = mSpells.emplace_back(ActiveSpellParams{*slot, enchantment, slotIndex, ptr}); - for(const auto& effect : params.mEffects) - MWMechanics::playEffects(ptr, *world->getStore().get().find(effect.mEffectId), playNonLooping); + const ActiveSpellParams& params + = mSpells.emplace_back(ActiveSpellParams{ *slot, enchantment, slotIndex, ptr }); + for (const auto& effect : params.mEffects) + MWMechanics::playEffects( + ptr, *world->getStore().get().find(effect.mEffectId), playNonLooping); } } } @@ -239,88 +277,92 @@ namespace MWMechanics bool updatedHitOverlay = false; bool updatedEnemy = false; // Update effects - for(auto spellIt = mSpells.begin(); spellIt != mSpells.end();) + for (auto spellIt = mSpells.begin(); spellIt != mSpells.end();) { - const auto caster = MWBase::Environment::get().getWorld()->searchPtrViaActorId(spellIt->mCasterActorId); //Maybe make this search outside active grid? + const auto caster = MWBase::Environment::get().getWorld()->searchPtrViaActorId( + spellIt->mCasterActorId); // Maybe make this search outside active grid? bool removedSpell = false; std::optional reflected; - for(auto it = spellIt->mEffects.begin(); it != spellIt->mEffects.end();) + for (auto it = spellIt->mEffects.begin(); it != spellIt->mEffects.end();) { auto result = applyMagicEffect(ptr, caster, *spellIt, *it, duration); - if(result.mType == MagicApplicationResult::Type::REFLECTED) + if (result.mType == MagicApplicationResult::Type::REFLECTED) { - if(!reflected) + if (!reflected) { - static const bool keepOriginalCaster = Settings::Manager::getBool("classic reflected absorb spells behavior", "Game"); - if(keepOriginalCaster) - reflected = {*spellIt, caster}; + static const bool keepOriginalCaster + = Settings::Manager::getBool("classic reflected absorb spells behavior", "Game"); + if (keepOriginalCaster) + reflected = { *spellIt, caster }; else - reflected = {*spellIt, ptr}; + reflected = { *spellIt, ptr }; } auto& reflectedEffect = reflected->mEffects.emplace_back(*it); - reflectedEffect.mFlags = ESM::ActiveEffect::Flag_Ignore_Reflect | ESM::ActiveEffect::Flag_Ignore_SpellAbsorption; + reflectedEffect.mFlags + = ESM::ActiveEffect::Flag_Ignore_Reflect | ESM::ActiveEffect::Flag_Ignore_SpellAbsorption; it = spellIt->mEffects.erase(it); } - else if(result.mType == MagicApplicationResult::Type::REMOVED) + else if (result.mType == MagicApplicationResult::Type::REMOVED) it = spellIt->mEffects.erase(it); else { ++it; - if(!updatedEnemy && result.mShowHealth && caster == player && ptr != player) + if (!updatedEnemy && result.mShowHealth && caster == player && ptr != player) { MWBase::Environment::get().getWindowManager()->setEnemy(ptr); updatedEnemy = true; } - if(!updatedHitOverlay && result.mShowHit && ptr == player) + if (!updatedHitOverlay && result.mShowHit && ptr == player) { MWBase::Environment::get().getWindowManager()->activateHitOverlay(false); updatedHitOverlay = true; } } removedSpell = applyPurges(ptr, &spellIt, &it); - if(removedSpell) + if (removedSpell) break; } - if(reflected) + if (reflected) { - const ESM::Static* reflectStatic = MWBase::Environment::get().getWorld()->getStore().get().find("VFX_Reflect"); + const ESM::Static* reflectStatic + = MWBase::Environment::get().getWorld()->getStore().get().find("VFX_Reflect"); MWRender::Animation* animation = MWBase::Environment::get().getWorld()->getAnimation(ptr); - if(animation && !reflectStatic->mModel.empty()) + if (animation && !reflectStatic->mModel.empty()) { const VFS::Manager* const vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); - animation->addEffect( - Misc::ResourceHelpers::correctMeshPath(reflectStatic->mModel, vfs), + animation->addEffect(Misc::ResourceHelpers::correctMeshPath(reflectStatic->mModel, vfs), ESM::MagicEffect::Reflect, false); } caster.getClass().getCreatureStats(caster).getActiveSpells().addSpell(*reflected); } - if(removedSpell) + if (removedSpell) continue; bool remove = false; - if(spellIt->mType == ESM::ActiveSpells::Type_Ability || spellIt->mType == ESM::ActiveSpells::Type_Permanent) + if (spellIt->mType == ESM::ActiveSpells::Type_Ability + || spellIt->mType == ESM::ActiveSpells::Type_Permanent) { try { remove = !spells.hasSpell(spellIt->mId); } - catch(const std::runtime_error& e) + catch (const std::runtime_error& e) { remove = true; Log(Debug::Error) << "Removing active effect: " << e.what(); } } - else if(spellIt->mType == ESM::ActiveSpells::Type_Enchantment) + else if (spellIt->mType == ESM::ActiveSpells::Type_Enchantment) { const auto& store = ptr.getClass().getInventoryStore(ptr); auto slot = store.getSlot(spellIt->mSlot); remove = slot == store.end() || slot->getCellRef().getRefId() != spellIt->mId; } - if(remove) + if (remove) { auto params = *spellIt; spellIt = mSpells.erase(spellIt); - for(const auto& effect : params.mEffects) + for (const auto& effect : params.mEffects) onMagicEffectRemoved(ptr, params, effect); applyPurges(ptr, &spellIt); continue; @@ -331,27 +373,29 @@ namespace MWMechanics void ActiveSpells::addToSpells(const MWWorld::Ptr& ptr, const ActiveSpellParams& spell) { - if(spell.mType != ESM::ActiveSpells::Type_Consumable) + if (spell.mType != ESM::ActiveSpells::Type_Consumable) { - auto found = std::find_if(mSpells.begin(), mSpells.end(), [&] (const auto& existing) - { - return spell.mId == existing.mId && spell.mCasterActorId == existing.mCasterActorId && spell.mSlot == existing.mSlot; + auto found = std::find_if(mSpells.begin(), mSpells.end(), [&](const auto& existing) { + return spell.mId == existing.mId && spell.mCasterActorId == existing.mCasterActorId + && spell.mSlot == existing.mSlot; }); - if(found != mSpells.end()) + if (found != mSpells.end()) { - if(merge(found->mEffects, spell.mEffects)) + if (merge(found->mEffects, spell.mEffects)) return; auto params = *found; mSpells.erase(found); - for(const auto& effect : params.mEffects) + for (const auto& effect : params.mEffects) onMagicEffectRemoved(ptr, params, effect); } } mSpells.emplace_back(spell); } - ActiveSpells::ActiveSpells() : mIterating(false) - {} + ActiveSpells::ActiveSpells() + : mIterating(false) + { + } ActiveSpells::TIterator ActiveSpells::begin() const { @@ -365,8 +409,7 @@ namespace MWMechanics bool ActiveSpells::isSpellActive(std::string_view id) const { - return std::find_if(mSpells.begin(), mSpells.end(), [&] (const auto& spell) - { + return std::find_if(mSpells.begin(), mSpells.end(), [&](const auto& spell) { return Misc::StringUtils::ciEqual(spell.mId, id); }) != mSpells.end(); } @@ -378,16 +421,16 @@ namespace MWMechanics void ActiveSpells::addSpell(const ESM::Spell* spell, const MWWorld::Ptr& actor) { - mQueue.emplace_back(ActiveSpellParams{spell, actor, true}); + mQueue.emplace_back(ActiveSpellParams{ spell, actor, true }); } void ActiveSpells::purge(ParamsPredicate predicate, const MWWorld::Ptr& ptr) { assert(&ptr.getClass().getCreatureStats(ptr).getActiveSpells() == this); mPurges.emplace(predicate); - if(!mIterating) + if (!mIterating) { - IterationGuard guard{*this}; + IterationGuard guard{ *this }; applyPurges(ptr); } } @@ -396,69 +439,71 @@ namespace MWMechanics { assert(&ptr.getClass().getCreatureStats(ptr).getActiveSpells() == this); mPurges.emplace(predicate); - if(!mIterating) + if (!mIterating) { - IterationGuard guard{*this}; + IterationGuard guard{ *this }; applyPurges(ptr); } } - bool ActiveSpells::applyPurges(const MWWorld::Ptr& ptr, std::list::iterator* currentSpell, std::vector::iterator* currentEffect) + bool ActiveSpells::applyPurges(const MWWorld::Ptr& ptr, std::list::iterator* currentSpell, + std::vector::iterator* currentEffect) { bool removedCurrentSpell = false; - while(!mPurges.empty()) + while (!mPurges.empty()) { auto predicate = mPurges.front(); mPurges.pop(); - for(auto spellIt = mSpells.begin(); spellIt != mSpells.end();) + for (auto spellIt = mSpells.begin(); spellIt != mSpells.end();) { bool isCurrentSpell = currentSpell && *currentSpell == spellIt; - std::visit([&] (auto&& variant) - { - using T = std::decay_t; - if constexpr (std::is_same_v) - { - if(variant(*spellIt)) + std::visit( + [&](auto&& variant) { + using T = std::decay_t; + if constexpr (std::is_same_v) { - auto params = *spellIt; - spellIt = mSpells.erase(spellIt); - if(isCurrentSpell) + if (variant(*spellIt)) { - *currentSpell = spellIt; - removedCurrentSpell = true; + auto params = *spellIt; + spellIt = mSpells.erase(spellIt); + if (isCurrentSpell) + { + *currentSpell = spellIt; + removedCurrentSpell = true; + } + for (const auto& effect : params.mEffects) + onMagicEffectRemoved(ptr, params, effect); } - for(const auto& effect : params.mEffects) - onMagicEffectRemoved(ptr, params, effect); + else + ++spellIt; } else - ++spellIt; - } - else - { - static_assert(std::is_same_v, "Non-exhaustive visitor"); - for(auto effectIt = spellIt->mEffects.begin(); effectIt != spellIt->mEffects.end();) { - if(variant(*spellIt, *effectIt)) + static_assert(std::is_same_v, "Non-exhaustive visitor"); + for (auto effectIt = spellIt->mEffects.begin(); effectIt != spellIt->mEffects.end();) { - auto effect = *effectIt; - if(isCurrentSpell && currentEffect) + if (variant(*spellIt, *effectIt)) { - auto distance = std::distance(spellIt->mEffects.begin(), *currentEffect); - if(effectIt <= *currentEffect) - distance--; - effectIt = spellIt->mEffects.erase(effectIt); - *currentEffect = spellIt->mEffects.begin() + distance; + auto effect = *effectIt; + if (isCurrentSpell && currentEffect) + { + auto distance = std::distance(spellIt->mEffects.begin(), *currentEffect); + if (effectIt <= *currentEffect) + distance--; + effectIt = spellIt->mEffects.erase(effectIt); + *currentEffect = spellIt->mEffects.begin() + distance; + } + else + effectIt = spellIt->mEffects.erase(effectIt); + onMagicEffectRemoved(ptr, *spellIt, effect); } else - effectIt = spellIt->mEffects.erase(effectIt); - onMagicEffectRemoved(ptr, *spellIt, effect); + ++effectIt; } - else - ++effectIt; + ++spellIt; } - ++spellIt; - } - }, predicate); + }, + predicate); } } return removedCurrentSpell; @@ -466,65 +511,59 @@ namespace MWMechanics void ActiveSpells::removeEffects(const MWWorld::Ptr& ptr, std::string_view id) { - purge([=] (const ActiveSpellParams& params) - { - return params.mId == id; - }, ptr); + purge([=](const ActiveSpellParams& params) { return params.mId == id; }, ptr); } void ActiveSpells::purgeEffect(const MWWorld::Ptr& ptr, short effectId) { - purge([=] (const ActiveSpellParams&, const ESM::ActiveEffect& effect) - { - return effect.mEffectId == effectId; - }, ptr); + purge([=](const ActiveSpellParams&, const ESM::ActiveEffect& effect) { return effect.mEffectId == effectId; }, + ptr); } void ActiveSpells::purge(const MWWorld::Ptr& ptr, int casterActorId) { - purge([=] (const ActiveSpellParams& params) - { - return params.mCasterActorId == casterActorId; - }, ptr); + purge([=](const ActiveSpellParams& params) { return params.mCasterActorId == casterActorId; }, ptr); } void ActiveSpells::clear(const MWWorld::Ptr& ptr) { mQueue.clear(); - purge([] (const ActiveSpellParams& params) { return true; }, ptr); + purge([](const ActiveSpellParams& params) { return true; }, ptr); } void ActiveSpells::skipWorsenings(double hours) { - for(auto& spell : mSpells) + for (auto& spell : mSpells) { - if(spell.mWorsenings >= 0) + if (spell.mWorsenings >= 0) spell.mNextWorsening += hours; } } - void ActiveSpells::writeState(ESM::ActiveSpells &state) const + void ActiveSpells::writeState(ESM::ActiveSpells& state) const { - for(const auto& spell : mSpells) + for (const auto& spell : mSpells) state.mSpells.emplace_back(spell.toEsm()); - for(const auto& spell : mQueue) + for (const auto& spell : mQueue) state.mQueue.emplace_back(spell.toEsm()); } - void ActiveSpells::readState(const ESM::ActiveSpells &state) + void ActiveSpells::readState(const ESM::ActiveSpells& state) { - for(const ESM::ActiveSpells::ActiveSpellParams& spell : state.mSpells) - mSpells.emplace_back(ActiveSpellParams{spell}); - for(const ESM::ActiveSpells::ActiveSpellParams& spell : state.mQueue) - mQueue.emplace_back(ActiveSpellParams{spell}); + for (const ESM::ActiveSpells::ActiveSpellParams& spell : state.mSpells) + mSpells.emplace_back(ActiveSpellParams{ spell }); + for (const ESM::ActiveSpells::ActiveSpellParams& spell : state.mQueue) + mQueue.emplace_back(ActiveSpellParams{ spell }); } void ActiveSpells::unloadActor(const MWWorld::Ptr& ptr) { - purge([] (const auto& spell) - { - return spell.getType() == ESM::ActiveSpells::Type_Consumable || spell.getType() == ESM::ActiveSpells::Type_Temporary; - }, ptr); + purge( + [](const auto& spell) { + return spell.getType() == ESM::ActiveSpells::Type_Consumable + || spell.getType() == ESM::ActiveSpells::Type_Temporary; + }, + ptr); mQueue.clear(); } } diff --git a/apps/openmw/mwmechanics/activespells.hpp b/apps/openmw/mwmechanics/activespells.hpp index 5481211985..38445a0a7f 100644 --- a/apps/openmw/mwmechanics/activespells.hpp +++ b/apps/openmw/mwmechanics/activespells.hpp @@ -10,8 +10,8 @@ #include -#include "../mwworld/timestamp.hpp" #include "../mwworld/ptr.hpp" +#include "../mwworld/timestamp.hpp" #include "spellcasting.hpp" @@ -29,123 +29,124 @@ namespace MWMechanics /// effects. class ActiveSpells { - public: + public: + using ActiveEffect = ESM::ActiveEffect; + class ActiveSpellParams + { + std::string mId; + std::vector mEffects; + std::string mDisplayName; + int mCasterActorId; + int mSlot; + ESM::ActiveSpells::EffectType mType; + int mWorsenings; + MWWorld::TimeStamp mNextWorsening; - using ActiveEffect = ESM::ActiveEffect; - class ActiveSpellParams - { - std::string mId; - std::vector mEffects; - std::string mDisplayName; - int mCasterActorId; - int mSlot; - ESM::ActiveSpells::EffectType mType; - int mWorsenings; - MWWorld::TimeStamp mNextWorsening; + ActiveSpellParams(const ESM::ActiveSpells::ActiveSpellParams& params); - ActiveSpellParams(const ESM::ActiveSpells::ActiveSpellParams& params); + ActiveSpellParams(const ESM::Spell* spell, const MWWorld::Ptr& actor, bool ignoreResistances = false); - ActiveSpellParams(const ESM::Spell* spell, const MWWorld::Ptr& actor, bool ignoreResistances = false); + ActiveSpellParams(const MWWorld::ConstPtr& item, const ESM::Enchantment* enchantment, int slotIndex, + const MWWorld::Ptr& actor); - ActiveSpellParams(const MWWorld::ConstPtr& item, const ESM::Enchantment* enchantment, int slotIndex, const MWWorld::Ptr& actor); + ActiveSpellParams(const ActiveSpellParams& params, const MWWorld::Ptr& actor); - ActiveSpellParams(const ActiveSpellParams& params, const MWWorld::Ptr& actor); + ESM::ActiveSpells::ActiveSpellParams toEsm() const; - ESM::ActiveSpells::ActiveSpellParams toEsm() const; + friend class ActiveSpells; - friend class ActiveSpells; - public: - ActiveSpellParams(const CastSpell& cast, const MWWorld::Ptr& caster); - - const std::string& getId() const { return mId; } + public: + ActiveSpellParams(const CastSpell& cast, const MWWorld::Ptr& caster); - const std::vector& getEffects() const { return mEffects; } - std::vector& getEffects() { return mEffects; } + const std::string& getId() const { return mId; } - ESM::ActiveSpells::EffectType getType() const { return mType; } + const std::vector& getEffects() const { return mEffects; } + std::vector& getEffects() { return mEffects; } - int getCasterActorId() const { return mCasterActorId; } + ESM::ActiveSpells::EffectType getType() const { return mType; } - int getWorsenings() const { return mWorsenings; } + int getCasterActorId() const { return mCasterActorId; } - const std::string& getDisplayName() const { return mDisplayName; } + int getWorsenings() const { return mWorsenings; } - // Increments worsenings count and sets the next timestamp - void worsen(); + const std::string& getDisplayName() const { return mDisplayName; } - bool shouldWorsen() const; + // Increments worsenings count and sets the next timestamp + void worsen(); - void resetWorsenings(); - }; + bool shouldWorsen() const; - typedef std::list::const_iterator TIterator; + void resetWorsenings(); + }; - void readState (const ESM::ActiveSpells& state); - void writeState (ESM::ActiveSpells& state) const; + typedef std::list::const_iterator TIterator; - TIterator begin() const; + void readState(const ESM::ActiveSpells& state); + void writeState(ESM::ActiveSpells& state) const; - TIterator end() const; + TIterator begin() const; - void update(const MWWorld::Ptr& ptr, float duration); + TIterator end() const; - private: - using ParamsPredicate = std::function; - using EffectPredicate = std::function; - using Predicate = std::variant; + void update(const MWWorld::Ptr& ptr, float duration); - struct IterationGuard - { - ActiveSpells& mActiveSpells; + private: + using ParamsPredicate = std::function; + using EffectPredicate = std::function; + using Predicate = std::variant; - IterationGuard(ActiveSpells& spells); - ~IterationGuard(); - }; + struct IterationGuard + { + ActiveSpells& mActiveSpells; - std::list mSpells; - std::vector mQueue; - std::queue mPurges; - bool mIterating; + IterationGuard(ActiveSpells& spells); + ~IterationGuard(); + }; - void addToSpells(const MWWorld::Ptr& ptr, const ActiveSpellParams& spell); + std::list mSpells; + std::vector mQueue; + std::queue mPurges; + bool mIterating; - bool applyPurges(const MWWorld::Ptr& ptr, std::list::iterator* currentSpell = nullptr, std::vector::iterator* currentEffect = nullptr); + void addToSpells(const MWWorld::Ptr& ptr, const ActiveSpellParams& spell); - public: + bool applyPurges(const MWWorld::Ptr& ptr, std::list::iterator* currentSpell = nullptr, + std::vector::iterator* currentEffect = nullptr); - ActiveSpells(); + public: + ActiveSpells(); - /// Add lasting effects - /// - /// \brief addSpell - /// \param id ID for stacking purposes. - /// - void addSpell (const ActiveSpellParams& params); + /// Add lasting effects + /// + /// \brief addSpell + /// \param id ID for stacking purposes. + /// + void addSpell(const ActiveSpellParams& params); - /// Bypasses resistances - void addSpell(const ESM::Spell* spell, const MWWorld::Ptr& actor); + /// Bypasses resistances + void addSpell(const ESM::Spell* spell, const MWWorld::Ptr& actor); - /// Removes the active effects from this spell/potion/.. with \a id - void removeEffects (const MWWorld::Ptr& ptr, std::string_view id); + /// Removes the active effects from this spell/potion/.. with \a id + void removeEffects(const MWWorld::Ptr& ptr, std::string_view id); - /// Remove all active effects with this effect id - void purgeEffect (const MWWorld::Ptr& ptr, short effectId); + /// Remove all active effects with this effect id + void purgeEffect(const MWWorld::Ptr& ptr, short effectId); - void purge(EffectPredicate predicate, const MWWorld::Ptr& ptr); - void purge(ParamsPredicate predicate, const MWWorld::Ptr& ptr); + void purge(EffectPredicate predicate, const MWWorld::Ptr& ptr); + void purge(ParamsPredicate predicate, const MWWorld::Ptr& ptr); - /// Remove all effects that were cast by \a casterActorId - void purge (const MWWorld::Ptr& ptr, int casterActorId); + /// Remove all effects that were cast by \a casterActorId + void purge(const MWWorld::Ptr& ptr, int casterActorId); - /// Remove all spells - void clear(const MWWorld::Ptr& ptr); + /// Remove all spells + void clear(const MWWorld::Ptr& ptr); - bool isSpellActive (std::string_view id) const; - ///< case insensitive + bool isSpellActive(std::string_view id) const; + ///< case insensitive - void skipWorsenings(double hours); + void skipWorsenings(double hours); - void unloadActor(const MWWorld::Ptr& ptr); + void unloadActor(const MWWorld::Ptr& ptr); }; } diff --git a/apps/openmw/mwmechanics/actor.hpp b/apps/openmw/mwmechanics/actor.hpp index 1e257f613d..b9f1f97a4b 100644 --- a/apps/openmw/mwmechanics/actor.hpp +++ b/apps/openmw/mwmechanics/actor.hpp @@ -29,7 +29,8 @@ namespace MWMechanics Actor(const MWWorld::Ptr& ptr, MWRender::Animation* animation) : mCharacterController(ptr, animation) , mPositionAdjusted(false) - {} + { + } const MWWorld::Ptr& getPtr() const { return mCharacterController.getPtr(); } @@ -61,11 +62,12 @@ namespace MWMechanics private: CharacterController mCharacterController; - int mGreetingTimer{0}; - float mTargetAngleRadians{0.f}; - GreetingState mGreetingState{Greet_None}; - bool mIsTurningToPlayer{false}; - Misc::DeviatingPeriodicTimer mEngageCombat{1.0f, 0.25f, Misc::Rng::deviate(0, 0.25f, MWBase::Environment::get().getWorld()->getPrng())}; + int mGreetingTimer{ 0 }; + float mTargetAngleRadians{ 0.f }; + GreetingState mGreetingState{ Greet_None }; + bool mIsTurningToPlayer{ false }; + Misc::DeviatingPeriodicTimer mEngageCombat{ 1.0f, 0.25f, + Misc::Rng::deviate(0, 0.25f, MWBase::Environment::get().getWorld()->getPrng()) }; bool mPositionAdjusted; }; diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 3a2d9e19db..c0cdceb3f6 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -5,240 +5,244 @@ #include #include -#include #include -#include #include -#include #include +#include +#include +#include -#include -#include #include +#include +#include #include - -#include "../mwworld/esmstore.hpp" +#include "../mwworld/actionequip.hpp" #include "../mwworld/class.hpp" +#include "../mwworld/esmstore.hpp" #include "../mwworld/inventorystore.hpp" -#include "../mwworld/actionequip.hpp" #include "../mwworld/player.hpp" -#include "../mwbase/world.hpp" -#include "../mwbase/environment.hpp" -#include "../mwbase/windowmanager.hpp" #include "../mwbase/dialoguemanager.hpp" -#include "../mwbase/soundmanager.hpp" +#include "../mwbase/environment.hpp" +#include "../mwbase/luamanager.hpp" #include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwbase/statemanager.hpp" -#include "../mwbase/luamanager.hpp" +#include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" #include "../mwmechanics/aibreathe.hpp" #include "../mwrender/vismask.hpp" -#include "spellcasting.hpp" -#include "steering.hpp" -#include "npcstats.hpp" -#include "creaturestats.hpp" -#include "movement.hpp" -#include "character.hpp" +#include "actor.hpp" +#include "actorutil.hpp" #include "aicombat.hpp" #include "aicombataction.hpp" #include "aifollow.hpp" #include "aipursue.hpp" #include "aiwander.hpp" -#include "actor.hpp" +#include "character.hpp" +#include "creaturestats.hpp" +#include "movement.hpp" +#include "npcstats.hpp" +#include "spellcasting.hpp" +#include "steering.hpp" #include "summoning.hpp" -#include "actorutil.hpp" namespace { -bool isConscious(const MWWorld::Ptr& ptr) -{ - const MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); - return !stats.isDead() && !stats.getKnockedDown(); -} + bool isConscious(const MWWorld::Ptr& ptr) + { + const MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); + return !stats.isDead() && !stats.getKnockedDown(); + } -bool isCommanded(const MWWorld::Ptr& actor) -{ - const auto& actorClass = actor.getClass(); - const auto& stats = actorClass.getCreatureStats(actor); - const bool isActorNpc = actorClass.isNpc(); - const auto level = stats.getLevel(); - for (const auto& params : stats.getActiveSpells()) + bool isCommanded(const MWWorld::Ptr& actor) { - for (const auto& effect : params.getEffects()) + const auto& actorClass = actor.getClass(); + const auto& stats = actorClass.getCreatureStats(actor); + const bool isActorNpc = actorClass.isNpc(); + const auto level = stats.getLevel(); + for (const auto& params : stats.getActiveSpells()) { - if (((effect.mEffectId == ESM::MagicEffect::CommandHumanoid && isActorNpc) - || (effect.mEffectId == ESM::MagicEffect::CommandCreature && !isActorNpc)) - && effect.mMagnitude >= level) - return true; + for (const auto& effect : params.getEffects()) + { + if (((effect.mEffectId == ESM::MagicEffect::CommandHumanoid && isActorNpc) + || (effect.mEffectId == ESM::MagicEffect::CommandCreature && !isActorNpc)) + && effect.mMagnitude >= level) + return true; + } } + return false; } - return false; -} -// Check for command effects having ended and remove package if necessary -void adjustCommandedActor (const MWWorld::Ptr& actor) -{ - if (isCommanded(actor)) - return; + // Check for command effects having ended and remove package if necessary + void adjustCommandedActor(const MWWorld::Ptr& actor) + { + if (isCommanded(actor)) + return; - MWMechanics::CreatureStats& stats = actor.getClass().getCreatureStats(actor); + MWMechanics::CreatureStats& stats = actor.getClass().getCreatureStats(actor); - stats.getAiSequence().erasePackageIf([](auto& entry) - { - if (entry->getTypeId() == MWMechanics::AiPackageTypeId::Follow && - static_cast(entry.get())->isCommanded()) - { - return true; - } - return false; - }); -} + stats.getAiSequence().erasePackageIf([](auto& entry) { + if (entry->getTypeId() == MWMechanics::AiPackageTypeId::Follow + && static_cast(entry.get())->isCommanded()) + { + return true; + } + return false; + }); + } -std::pair getRestorationPerHourOfSleep(const MWWorld::Ptr& ptr) -{ - const MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats (ptr); - const MWWorld::Store& settings = MWBase::Environment::get().getWorld()->getStore().get(); + std::pair getRestorationPerHourOfSleep(const MWWorld::Ptr& ptr) + { + const MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); + const MWWorld::Store& settings + = MWBase::Environment::get().getWorld()->getStore().get(); - const float endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified(); - const float health = 0.1f * endurance; + const float endurance = stats.getAttribute(ESM::Attribute::Endurance).getModified(); + const float health = 0.1f * endurance; - static const float fRestMagicMult = settings.find("fRestMagicMult")->mValue.getFloat(); - const float magicka = fRestMagicMult * stats.getAttribute(ESM::Attribute::Intelligence).getModified(); + static const float fRestMagicMult = settings.find("fRestMagicMult")->mValue.getFloat(); + const float magicka = fRestMagicMult * stats.getAttribute(ESM::Attribute::Intelligence).getModified(); - return {health, magicka}; -} + return { health, magicka }; + } -template -void forEachFollowingPackage(const std::list& actors, const MWWorld::Ptr& actorPtr, const MWWorld::Ptr& player, T&& func) -{ - for (const MWMechanics::Actor& actor : actors) + template + void forEachFollowingPackage( + const std::list& actors, const MWWorld::Ptr& actorPtr, const MWWorld::Ptr& player, T&& func) { - const MWWorld::Ptr &iteratedActor = actor.getPtr(); - if (iteratedActor == player || iteratedActor == actorPtr) - continue; + for (const MWMechanics::Actor& actor : actors) + { + const MWWorld::Ptr& iteratedActor = actor.getPtr(); + if (iteratedActor == player || iteratedActor == actorPtr) + continue; - const MWMechanics::CreatureStats &stats = iteratedActor.getClass().getCreatureStats(iteratedActor); - if (stats.isDead()) - continue; + const MWMechanics::CreatureStats& stats = iteratedActor.getClass().getCreatureStats(iteratedActor); + if (stats.isDead()) + continue; - // An actor counts as following if AiFollow is the current AiPackage, - // or there are only Combat and Wander packages before the AiFollow package - for (const auto& package : stats.getAiSequence()) - { - if (!func(actor, package)) - break; + // An actor counts as following if AiFollow is the current AiPackage, + // or there are only Combat and Wander packages before the AiFollow package + for (const auto& package : stats.getAiSequence()) + { + if (!func(actor, package)) + break; + } } } -} -float getStuntedMagickaDuration(const MWWorld::Ptr& actor) -{ - float remainingTime = 0.f; - for(const auto& params : actor.getClass().getCreatureStats(actor).getActiveSpells()) + float getStuntedMagickaDuration(const MWWorld::Ptr& actor) { - for(const auto& effect : params.getEffects()) + float remainingTime = 0.f; + for (const auto& params : actor.getClass().getCreatureStats(actor).getActiveSpells()) { - if(effect.mEffectId == ESM::MagicEffect::StuntedMagicka) + for (const auto& effect : params.getEffects()) { - if(effect.mDuration == -1.f) - return -1.f; - remainingTime = std::max(remainingTime, effect.mTimeLeft); + if (effect.mEffectId == ESM::MagicEffect::StuntedMagicka) + { + if (effect.mDuration == -1.f) + return -1.f; + remainingTime = std::max(remainingTime, effect.mTimeLeft); + } } } + return remainingTime; } - return remainingTime; -} -void soulTrap(const MWWorld::Ptr& creature) -{ - const auto& stats = creature.getClass().getCreatureStats(creature); - if(!stats.getMagicEffects().get(ESM::MagicEffect::Soultrap).getMagnitude()) - return; - const int creatureSoulValue = creature.get()->mBase->mData.mSoul; - if (creatureSoulValue == 0) - return; - MWBase::World* const world = MWBase::Environment::get().getWorld(); - static const float fSoulgemMult = world->getStore().get().find("fSoulgemMult")->mValue.getFloat(); - for(const auto& params : stats.getActiveSpells()) - { - for(const auto& effect : params.getEffects()) + void soulTrap(const MWWorld::Ptr& creature) + { + const auto& stats = creature.getClass().getCreatureStats(creature); + if (!stats.getMagicEffects().get(ESM::MagicEffect::Soultrap).getMagnitude()) + return; + const int creatureSoulValue = creature.get()->mBase->mData.mSoul; + if (creatureSoulValue == 0) + return; + MWBase::World* const world = MWBase::Environment::get().getWorld(); + static const float fSoulgemMult + = world->getStore().get().find("fSoulgemMult")->mValue.getFloat(); + for (const auto& params : stats.getActiveSpells()) { - if(effect.mEffectId != ESM::MagicEffect::Soultrap || effect.mMagnitude <= 0.f) - continue; - MWWorld::Ptr caster = world->searchPtrViaActorId(params.getCasterActorId()); - if (caster.isEmpty() || !caster.getClass().isActor()) - continue; - - // Use the smallest soulgem that is large enough to hold the soul - MWWorld::ContainerStore& container = caster.getClass().getContainerStore(caster); - MWWorld::ContainerStoreIterator gem = container.end(); - float gemCapacity = std::numeric_limits::max(); - for (auto it = container.begin(MWWorld::ContainerStore::Type_Miscellaneous); it != container.end(); ++it) + for (const auto& effect : params.getEffects()) { - if (it->getClass().isSoulGem(*it)) + if (effect.mEffectId != ESM::MagicEffect::Soultrap || effect.mMagnitude <= 0.f) + continue; + MWWorld::Ptr caster = world->searchPtrViaActorId(params.getCasterActorId()); + if (caster.isEmpty() || !caster.getClass().isActor()) + continue; + + // Use the smallest soulgem that is large enough to hold the soul + MWWorld::ContainerStore& container = caster.getClass().getContainerStore(caster); + MWWorld::ContainerStoreIterator gem = container.end(); + float gemCapacity = std::numeric_limits::max(); + for (auto it = container.begin(MWWorld::ContainerStore::Type_Miscellaneous); it != container.end(); + ++it) { - float thisGemCapacity = it->get()->mBase->mData.mValue * fSoulgemMult; - if (thisGemCapacity >= creatureSoulValue && thisGemCapacity < gemCapacity - && it->getCellRef().getSoul().empty()) + if (it->getClass().isSoulGem(*it)) { - gem = it; - gemCapacity = thisGemCapacity; + float thisGemCapacity = it->get()->mBase->mData.mValue * fSoulgemMult; + if (thisGemCapacity >= creatureSoulValue && thisGemCapacity < gemCapacity + && it->getCellRef().getSoul().empty()) + { + gem = it; + gemCapacity = thisGemCapacity; + } } } - } - if (gem == container.end()) - continue; + if (gem == container.end()) + continue; - // Set the soul on just one of the gems, not the whole stack - gem->getContainerStore()->unstack(*gem, caster); - gem->getCellRef().setSoul(creature.getCellRef().getRefId()); + // Set the soul on just one of the gems, not the whole stack + gem->getContainerStore()->unstack(*gem, caster); + gem->getCellRef().setSoul(creature.getCellRef().getRefId()); - // Restack the gem with other gems with the same soul - gem->getContainerStore()->restack(*gem); + // Restack the gem with other gems with the same soul + gem->getContainerStore()->restack(*gem); - if (caster == MWMechanics::getPlayer()) - MWBase::Environment::get().getWindowManager()->messageBox("#{sSoultrapSuccess}"); + if (caster == MWMechanics::getPlayer()) + MWBase::Environment::get().getWindowManager()->messageBox("#{sSoultrapSuccess}"); - const ESM::Static* const fx = world->getStore().get().search("VFX_Soul_Trap"); - if (fx != nullptr) - { - const VFS::Manager* const vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); - world->spawnEffect( - Misc::ResourceHelpers::correctMeshPath(fx->mModel, vfs), - "", creature.getRefData().getPosition().asVec3()); - } + const ESM::Static* const fx = world->getStore().get().search("VFX_Soul_Trap"); + if (fx != nullptr) + { + const VFS::Manager* const vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); + world->spawnEffect(Misc::ResourceHelpers::correctMeshPath(fx->mModel, vfs), "", + creature.getRefData().getPosition().asVec3()); + } - MWBase::Environment::get().getSoundManager()->playSound3D(creature.getRefData().getPosition().asVec3(), "conjuration hit", 1.f, 1.f); - return; //remove to get vanilla behaviour + MWBase::Environment::get().getSoundManager()->playSound3D( + creature.getRefData().getPosition().asVec3(), "conjuration hit", 1.f, 1.f); + return; // remove to get vanilla behaviour + } } } -} -void removeTemporaryEffects(const MWWorld::Ptr& ptr) -{ - ptr.getClass().getCreatureStats(ptr).getActiveSpells().unloadActor(ptr); -} + void removeTemporaryEffects(const MWWorld::Ptr& ptr) + { + ptr.getClass().getCreatureStats(ptr).getActiveSpells().unloadActor(ptr); + } } namespace MWMechanics { static constexpr int GREETING_SHOULD_START = 4; // how many updates should pass before NPC can greet player - static constexpr int GREETING_SHOULD_END = 20; // how many updates should pass before NPC stops turning to player - static constexpr int GREETING_COOLDOWN = 40; // how many updates should pass before NPC can continue movement + static constexpr int GREETING_SHOULD_END = 20; // how many updates should pass before NPC stops turning to player + static constexpr int GREETING_COOLDOWN = 40; // how many updates should pass before NPC can continue movement static constexpr float DECELERATE_DISTANCE = 512.f; namespace { - float getTimeToDestination(const AiPackage& package, const osg::Vec3f& position, float speed, float duration, const osg::Vec3f& halfExtents) + float getTimeToDestination(const AiPackage& package, const osg::Vec3f& position, float speed, float duration, + const osg::Vec3f& halfExtents) { - const auto distanceToNextPathPoint = (package.getNextPathPoint(package.getDestination()) - position).length(); + const auto distanceToNextPathPoint + = (package.getNextPathPoint(package.getDestination()) - position).length(); return (distanceToNextPathPoint - package.getNextPathPointTolerance(speed, duration, halfExtents)) / speed; } @@ -255,10 +259,18 @@ namespace MWMechanics if (isTargetMagicallyHidden(targetActor)) return; - static const float fMaxHeadTrackDistance = MWBase::Environment::get().getWorld()->getStore() - .get().find("fMaxHeadTrackDistance")->mValue.getFloat(); - static const float fInteriorHeadTrackMult = MWBase::Environment::get().getWorld()->getStore() - .get().find("fInteriorHeadTrackMult")->mValue.getFloat(); + static const float fMaxHeadTrackDistance = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fMaxHeadTrackDistance") + ->mValue.getFloat(); + static const float fInteriorHeadTrackMult = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fInteriorHeadTrackMult") + ->mValue.getFloat(); float maxDistance = fMaxHeadTrackDistance; const ESM::Cell* currentCell = actor.getCell()->getCell(); if (!currentCell->isExterior() && !(currentCell->mData.mFlags & ESM::Cell::QuasiEx)) @@ -272,7 +284,7 @@ namespace MWMechanics return; // stop tracking when target is behind the actor - osg::Vec3f actorDirection = actorRefData.getBaseNode()->getAttitude() * osg::Vec3f(0,1,0); + osg::Vec3f actorDirection = actorRefData.getBaseNode()->getAttitude() * osg::Vec3f(0, 1, 0); osg::Vec3f targetDirection(actor2Pos - actor1Pos); actorDirection.z() = 0; targetDirection.z() = 0; @@ -286,7 +298,8 @@ namespace MWMechanics } } - void updateHeadTracking(const MWWorld::Ptr& ptr, const std::list& actors, bool isPlayer, CharacterController& ctrl) + void updateHeadTracking( + const MWWorld::Ptr& ptr, const std::list& actors, bool isPlayer, CharacterController& ctrl) { float sqrHeadTrackDistance = std::numeric_limits::max(); MWWorld::Ptr headTrackTarget; @@ -306,7 +319,8 @@ namespace MWMechanics if (!activePackageTarget.isEmpty()) { // Track the specified target of package. - updateHeadTracking(ptr, activePackageTarget, headTrackTarget, sqrHeadTrackDistance, inCombatOrPursue); + updateHeadTracking( + ptr, activePackageTarget, headTrackTarget, sqrHeadTrackDistance, inCombatOrPursue); } } else @@ -317,7 +331,8 @@ namespace MWMechanics if (otherActor.getPtr() == ptr) continue; - updateHeadTracking(ptr, otherActor.getPtr(), headTrackTarget, sqrHeadTrackDistance, inCombatOrPursue); + updateHeadTracking( + ptr, otherActor.getPtr(), headTrackTarget, sqrHeadTrackDistance, inCombatOrPursue); } } } @@ -362,7 +377,7 @@ namespace MWMechanics void Actors::updateActor(const MWWorld::Ptr& ptr, float duration) const { // magic effects - adjustMagicEffects (ptr, duration); + adjustMagicEffects(ptr, duration); // fatigue restoration calculateRestoration(ptr, duration); @@ -370,10 +385,11 @@ namespace MWMechanics void Actors::playIdleDialogue(const MWWorld::Ptr& actor) const { - if (!actor.getClass().isActor() || actor == getPlayer() || MWBase::Environment::get().getSoundManager()->sayActive(actor)) + if (!actor.getClass().isActor() || actor == getPlayer() + || MWBase::Environment::get().getSoundManager()->sayActive(actor)) return; - const CreatureStats &stats = actor.getClass().getCreatureStats(actor); + const CreatureStats& stats = actor.getClass().getCreatureStats(actor); if (stats.getAiSetting(AiSetting::Hello).getModified() == 0) return; @@ -390,8 +406,10 @@ namespace MWMechanics // Our implementation is not FPS-dependent unlike Morrowind's so it needs to be recalibrated. // We chose to use the chance MW would have when run at 60 FPS with the default value of the GMST. const float delta = MWBase::Environment::get().getFrameDuration() * 6.f; - static const float fVoiceIdleOdds = world->getStore().get().find("fVoiceIdleOdds")->mValue.getFloat(); - if (Misc::Rng::rollProbability(world->getPrng()) * 10000.f < fVoiceIdleOdds * delta && world->getLOS(getPlayer(), actor)) + static const float fVoiceIdleOdds + = world->getStore().get().find("fVoiceIdleOdds")->mValue.getFloat(); + if (Misc::Rng::rollProbability(world->getPrng()) * 10000.f < fVoiceIdleOdds * delta + && world->getLOS(getPlayer(), actor)) MWBase::Environment::get().getDialogueManager()->say(actor, "idle"); } @@ -401,7 +419,7 @@ namespace MWMechanics return; const auto& actorClass = actor.getClass(); - const CreatureStats &stats = actorClass.getCreatureStats(actor); + const CreatureStats& stats = actorClass.getCreatureStats(actor); const MWMechanics::AiSequence& seq = stats.getAiSequence(); if (!seq.isEmpty() && seq.getActivePackage().useVariableSpeed()) @@ -430,9 +448,9 @@ namespace MWMechanics const MWMechanics::AiSequence& seq = actorStats.getAiSequence(); const auto packageId = seq.getTypeId(); - if (seq.isInCombat() || - MWBase::Environment::get().getWorld()->isSwimming(actor) || - (packageId != AiPackageTypeId::Wander && packageId != AiPackageTypeId::Travel && packageId != AiPackageTypeId::None)) + if (seq.isInCombat() || MWBase::Environment::get().getWorld()->isSwimming(actor) + || (packageId != AiPackageTypeId::Wander && packageId != AiPackageTypeId::Travel + && packageId != AiPackageTypeId::None)) { actorState.setTurningToPlayer(false); actorState.setGreetingTimer(0); @@ -462,18 +480,23 @@ namespace MWMechanics return; // Play a random voice greeting if the player gets too close - static const int iGreetDistanceMultiplier = MWBase::Environment::get().getWorld()->getStore() - .get().find("iGreetDistanceMultiplier")->mValue.getInteger(); - - const float helloDistance = static_cast(actorStats.getAiSetting(AiSetting::Hello).getModified() * iGreetDistanceMultiplier); + static const int iGreetDistanceMultiplier = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("iGreetDistanceMultiplier") + ->mValue.getInteger(); + + const float helloDistance + = static_cast(actorStats.getAiSetting(AiSetting::Hello).getModified() * iGreetDistanceMultiplier); const auto& playerStats = player.getClass().getCreatureStats(player); int greetingTimer = actorState.getGreetingTimer(); GreetingState greetingState = actorState.getGreetingState(); if (greetingState == Greet_None) { - if ((playerPos - actorPos).length2() <= helloDistance * helloDistance && - !playerStats.isDead() && !actorStats.isParalyzed() && !isTargetMagicallyHidden(player) + if ((playerPos - actorPos).length2() <= helloDistance * helloDistance && !playerStats.isDead() + && !actorStats.isParalyzed() && !isTargetMagicallyHidden(player) && MWBase::Environment::get().getWorld()->getLOS(player, actor) && MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, actor)) greetingTimer++; @@ -490,8 +513,10 @@ namespace MWMechanics { greetingTimer++; - if (!actorStats.getMovementFlag(CreatureStats::Flag_ForceJump) && !actorStats.getMovementFlag(CreatureStats::Flag_ForceSneak) - && (greetingTimer <= GREETING_SHOULD_END || MWBase::Environment::get().getSoundManager()->sayActive(actor))) + if (!actorStats.getMovementFlag(CreatureStats::Flag_ForceJump) + && !actorStats.getMovementFlag(CreatureStats::Flag_ForceSneak) + && (greetingTimer <= GREETING_SHOULD_END + || MWBase::Environment::get().getSoundManager()->sayActive(actor))) turnActorToFacePlayer(actor, actorState, dir); if (greetingTimer >= GREETING_COOLDOWN) @@ -534,15 +559,15 @@ namespace MWMechanics { auto& ai = ptr.getClass().getCreatureStats(ptr).getAiSequence(); std::vector targets; - if(ai.getCombatTargets(targets)) + if (ai.getCombatTargets(targets)) { std::set allySet; getActorsSidingWith(ptr, allySet); allySet.insert(ptr); std::vector allies(allySet.begin(), allySet.end()); - for(const auto& ally : allies) + for (const auto& ally : allies) ally.getClass().getCreatureStats(ally).getAiSequence().stopCombat(targets); - for(const auto& target : targets) + for (const auto& target : targets) target.getClass().getCreatureStats(target).getAiSequence().stopCombat(allies); } } @@ -569,17 +594,19 @@ namespace MWMechanics if (sqrDist > mActorsProcessingRange * mActorsProcessingRange) return; - // If this is set to true, actor1 will start combat with actor2 if the awareness check at the end of the method returns true + // If this is set to true, actor1 will start combat with actor2 if the awareness check at the end of the method + // returns true bool aggressive = false; - // Get actors allied with actor1. Includes those following or escorting actor1, actors following or escorting those actors, (recursive) - // and any actor currently being followed or escorted by actor1 + // Get actors allied with actor1. Includes those following or escorting actor1, actors following or escorting + // those actors, (recursive) and any actor currently being followed or escorted by actor1 std::set allies1; getActorsSidingWith(actor1, allies1, cachedAllies); const auto mechanicsManager = MWBase::Environment::get().getMechanicsManager(); - // If an ally of actor1 has been attacked by actor2 or has attacked actor2, start combat between actor1 and actor2 + // If an ally of actor1 has been attacked by actor2 or has attacked actor2, start combat between actor1 and + // actor2 for (const MWWorld::Ptr& ally : allies1) { if (creatureStats1.getAiSequence().isInCombat(ally)) @@ -594,7 +621,8 @@ namespace MWMechanics return; } - // If there's been no attack attempt yet but an ally of actor1 is in combat with actor2, become aggressive to actor2 + // If there's been no attack attempt yet but an ally of actor1 is in combat with actor2, become aggressive + // to actor2 if (ally.getClass().getCreatureStats(ally).getAiSequence().isInCombat(actor2)) aggressive = true; } @@ -637,7 +665,8 @@ namespace MWMechanics if (!canFight(actor1, actor2)) return; - // If set in the settings file, player followers and escorters will become aggressive toward enemies in combat with them or the player + // If set in the settings file, player followers and escorters will become aggressive toward enemies in combat + // with them or the player static const bool followersAttackOnSight = Settings::Manager::getBool("followers attack on sight", "Game"); if (!aggressive && isPlayerFollowerOrEscorter && followersAttackOnSight) { @@ -670,10 +699,12 @@ namespace MWMechanics // Make guards go aggressive with creatures that are in combat, unless the creature is a follower or escorter const auto world = MWBase::Environment::get().getWorld(); - if (!aggressive && actor1.getClass().isClass(actor1, "Guard") && !actor2.getClass().isNpc() && creatureStats2.getAiSequence().isInCombat()) + if (!aggressive && actor1.getClass().isClass(actor1, "Guard") && !actor2.getClass().isNpc() + && creatureStats2.getAiSequence().isInCombat()) { // Check if the creature is too far - static const float fAlarmRadius = world->getStore().get().find("fAlarmRadius")->mValue.getFloat(); + static const float fAlarmRadius + = world->getStore().get().find("fAlarmRadius")->mValue.getFloat(); if (sqrDist > fAlarmRadius * fAlarmRadius) return; @@ -693,11 +724,11 @@ namespace MWMechanics aggressive = true; } - // If any of the above conditions turned actor1 aggressive towards actor2, do an awareness check. If it passes, start combat with actor2. + // If any of the above conditions turned actor1 aggressive towards actor2, do an awareness check. If it passes, + // start combat with actor2. if (aggressive) { - bool LOS = world->getLOS(actor1, actor2) && - mechanicsManager->awarenessCheck(actor2, actor1); + bool LOS = world->getLOS(actor1, actor2) && mechanicsManager->awarenessCheck(actor2, actor1); if (LOS) mechanicsManager->startCombat(actor1, actor2); @@ -706,7 +737,7 @@ namespace MWMechanics void Actors::adjustMagicEffects(const MWWorld::Ptr& creature, float duration) const { - CreatureStats& creatureStats = creature.getClass().getCreatureStats (creature); + CreatureStats& creatureStats = creature.getClass().getCreatureStats(creature); const bool wasDead = creatureStats.isDead(); creatureStats.getActiveSpells().update(creature, duration); @@ -723,15 +754,22 @@ namespace MWMechanics { bool actorKilled = false; - MWWorld::Ptr caster = MWBase::Environment::get().getWorld()->searchPtrViaActorId(spell.getCasterActorId()); + MWWorld::Ptr caster + = MWBase::Environment::get().getWorld()->searchPtrViaActorId(spell.getCasterActorId()); for (const auto& effect : spell.getEffects()) { static const std::array damageEffects{ - ESM::MagicEffect::FireDamage, ESM::MagicEffect::ShockDamage, ESM::MagicEffect::FrostDamage, ESM::MagicEffect::Poison, - ESM::MagicEffect::SunDamage, ESM::MagicEffect::DamageHealth, ESM::MagicEffect::AbsorbHealth, + ESM::MagicEffect::FireDamage, + ESM::MagicEffect::ShockDamage, + ESM::MagicEffect::FrostDamage, + ESM::MagicEffect::Poison, + ESM::MagicEffect::SunDamage, + ESM::MagicEffect::DamageHealth, + ESM::MagicEffect::AbsorbHealth, }; - const bool isDamageEffect = std::find(damageEffects.begin(), damageEffects.end(), effect.mEffectId) != damageEffects.end(); + const bool isDamageEffect = std::find(damageEffects.begin(), damageEffects.end(), effect.mEffectId) + != damageEffects.end(); if (isDamageEffect) { @@ -762,11 +800,12 @@ namespace MWMechanics void Actors::restoreDynamicStats(const MWWorld::Ptr& ptr, double hours, bool sleep) const { - MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats (ptr); + MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); if (stats.isDead()) return; - const MWWorld::Store& settings = MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& settings + = MWBase::Environment::get().getWorld()->getStore().get(); if (sleep) { @@ -777,7 +816,7 @@ namespace MWMechanics stats.setHealth(stat); double restoreHours = hours; - const bool stunted = stats.getMagicEffects ().get(ESM::MagicEffect::StuntedMagicka).getMagnitude() > 0; + const bool stunted = stats.getMagicEffects().get(ESM::MagicEffect::StuntedMagicka).getMagnitude() > 0; if (stunted) { // Stunted Magicka effect should be taken into account. @@ -787,7 +826,7 @@ namespace MWMechanics if (remainingTime > 0) { double timeScale = MWBase::Environment::get().getWorld()->getTimeScaleFactor(); - if(timeScale == 0.0) + if (timeScale == 0.0) timeScale = 1; restoreHours = std::max(0.0, hours - remainingTime * timeScale / 3600.f); @@ -811,21 +850,21 @@ namespace MWMechanics return; // Restore fatigue - static const float fFatigueReturnBase = settings.find("fFatigueReturnBase")->mValue.getFloat (); - static const float fFatigueReturnMult = settings.find("fFatigueReturnMult")->mValue.getFloat (); - static const float fEndFatigueMult = settings.find("fEndFatigueMult")->mValue.getFloat (); + static const float fFatigueReturnBase = settings.find("fFatigueReturnBase")->mValue.getFloat(); + static const float fFatigueReturnMult = settings.find("fFatigueReturnMult")->mValue.getFloat(); + static const float fEndFatigueMult = settings.find("fEndFatigueMult")->mValue.getFloat(); - const float endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified (); + const float endurance = stats.getAttribute(ESM::Attribute::Endurance).getModified(); float normalizedEncumbrance = ptr.getClass().getNormalizedEncumbrance(ptr); if (normalizedEncumbrance > 1) normalizedEncumbrance = 1; - const float x = (fFatigueReturnBase + fFatigueReturnMult * (1 - normalizedEncumbrance)) - * (fEndFatigueMult * endurance); + const float x + = (fFatigueReturnBase + fFatigueReturnMult * (1 - normalizedEncumbrance)) * (fEndFatigueMult * endurance); - fatigue.setCurrent (fatigue.getCurrent() + 3600 * x * hours); - stats.setFatigue (fatigue); + fatigue.setCurrent(fatigue.getCurrent() + 3600 * x * hours); + stats.setFatigue(fatigue); } void Actors::calculateRestoration(const MWWorld::Ptr& ptr, float duration) const @@ -833,7 +872,7 @@ namespace MWMechanics if (ptr.getClass().getCreatureStats(ptr).isDead()) return; - MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats (ptr); + MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); // Current fatigue can be above base value due to a fortify effect. // In that case stop here and don't try to restore. @@ -843,14 +882,15 @@ namespace MWMechanics // Restore fatigue const float endurance = stats.getAttribute(ESM::Attribute::Endurance).getModified(); - const MWWorld::Store& settings = MWBase::Environment::get().getWorld()->getStore().get(); - static const float fFatigueReturnBase = settings.find("fFatigueReturnBase")->mValue.getFloat (); - static const float fFatigueReturnMult = settings.find("fFatigueReturnMult")->mValue.getFloat (); + const MWWorld::Store& settings + = MWBase::Environment::get().getWorld()->getStore().get(); + static const float fFatigueReturnBase = settings.find("fFatigueReturnBase")->mValue.getFloat(); + static const float fFatigueReturnMult = settings.find("fFatigueReturnMult")->mValue.getFloat(); const float x = fFatigueReturnBase + fFatigueReturnMult * endurance; - fatigue.setCurrent (fatigue.getCurrent() + duration * x); - stats.setFatigue (fatigue); + fatigue.setCurrent(fatigue.getCurrent() + duration * x); + stats.setFatigue(fatigue); } bool Actors::isAttackPreparing(const MWWorld::Ptr& ptr) const @@ -883,19 +923,25 @@ namespace MWMechanics NpcStats& stats = actorClass.getNpcStats(ptr); // When npc stats are just initialized, mTimeToStartDrowning == -1 and we should get value from GMST - static const float fHoldBreathTime = MWBase::Environment::get().getWorld()->getStore().get().find("fHoldBreathTime")->mValue.getFloat(); + static const float fHoldBreathTime = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fHoldBreathTime") + ->mValue.getFloat(); if (stats.getTimeToStartDrowning() == -1.f) stats.setTimeToStartDrowning(fHoldBreathTime); if (!isPlayer && stats.getTimeToStartDrowning() < fHoldBreathTime / 2) { AiSequence& seq = actorClass.getCreatureStats(ptr).getAiSequence(); - if (seq.getTypeId() != AiPackageTypeId::Breathe) //Only add it once + if (seq.getTypeId() != AiPackageTypeId::Breathe) // Only add it once seq.stack(AiBreathe(), ptr); } const MWBase::World* const world = MWBase::Environment::get().getWorld(); - const bool knockedOutUnderwater = (isKnockedOut && world->isUnderwater(ptr.getCell(), osg::Vec3f(ptr.getRefData().getPosition().asVec3()))); + const bool knockedOutUnderwater + = (isKnockedOut && world->isUnderwater(ptr.getCell(), osg::Vec3f(ptr.getRefData().getPosition().asVec3()))); if ((world->isSubmerged(ptr) || knockedOutUnderwater) && stats.getMagicEffects().get(ESM::MagicEffect::WaterBreathing).getMagnitude() == 0) { @@ -915,7 +961,8 @@ namespace MWMechanics if (timeLeft == 0.0f && !godmode) { // If drowning, apply 3 points of damage per second - static const float fSuffocationDamage = world->getStore().get().find("fSuffocationDamage")->mValue.getFloat(); + static const float fSuffocationDamage + = world->getStore().get().find("fSuffocationDamage")->mValue.getFloat(); DynamicStat health = stats.getHealth(); health.setCurrent(health.getCurrent() - fSuffocationDamage * duration); stats.setHealth(health); @@ -947,11 +994,9 @@ namespace MWMechanics */ if (!isPlayer) { - auto torchIter = std::find_if(std::begin(inventoryStore), std::end(inventoryStore), [&](auto entry) - { - return entry.getType() == ESM::Light::sRecordId && - entry.getClass().canBeEquipped(entry, ptr).first; - }); + auto torchIter = std::find_if(std::begin(inventoryStore), std::end(inventoryStore), [&](auto entry) { + return entry.getType() == ESM::Light::sRecordId && entry.getClass().canBeEquipped(entry, ptr).first; + }); if (mayEquip) { if (torchIter != inventoryStore.end()) @@ -992,13 +1037,13 @@ namespace MWMechanics heldIter = inventoryStore.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); - //If holding a light... + // If holding a light... const auto world = MWBase::Environment::get().getWorld(); - MWRender::Animation *anim = world->getAnimation(ptr); + MWRender::Animation* anim = world->getAnimation(ptr); if (heldIter.getType() == MWWorld::ContainerStore::Type_Light && anim && anim->getCarriedLeftShown()) { // Use time from the player's light - if(isPlayer) + if (isPlayer) { float timeRemaining = heldIter->getClass().getRemainingUsageTime(*heldIter); @@ -1017,14 +1062,14 @@ namespace MWMechanics } // Both NPC and player lights extinguish in water. - if(world->isSwimming(ptr)) + if (world->isSwimming(ptr)) { inventoryStore.remove(*heldIter, 1, ptr); // remove it // ...But, only the player makes a sound. - if(isPlayer) - MWBase::Environment::get().getSoundManager()->playSound("torch out", - 1.0, 1.0, MWSound::Type::Sfx, MWSound::PlayMode::NoEnv); + if (isPlayer) + MWBase::Environment::get().getSoundManager()->playSound( + "torch out", 1.0, 1.0, MWSound::Type::Sfx, MWSound::PlayMode::NoEnv); } } } @@ -1051,23 +1096,28 @@ namespace MWMechanics const auto mechanicsManager = MWBase::Environment::get().getMechanicsManager(); const auto world = MWBase::Environment::get().getWorld(); - if (actorClass.isClass(ptr, "Guard") && !creatureStats.getAiSequence().isInPursuit() && !creatureStats.getAiSequence().isInCombat() + if (actorClass.isClass(ptr, "Guard") && !creatureStats.getAiSequence().isInPursuit() + && !creatureStats.getAiSequence().isInCombat() && creatureStats.getMagicEffects().get(ESM::MagicEffect::CalmHumanoid).getMagnitude() == 0) { const MWWorld::ESMStore& esmStore = world->getStore(); static const int cutoff = esmStore.get().find("iCrimeThreshold")->mValue.getInteger(); // Force dialogue on sight if bounty is greater than the cutoff - // In vanilla morrowind, the greeting dialogue is scripted to either arrest the player (< 5000 bounty) or attack (>= 5000 bounty) + // In vanilla morrowind, the greeting dialogue is scripted to either arrest the player (< 5000 bounty) or + // attack (>= 5000 bounty) if (playerStats.getBounty() >= cutoff - // TODO: do not run these two every frame. keep an Aware state for each actor and update it every 0.2 s or so? - && world->getLOS(ptr, player) - && mechanicsManager->awarenessCheck(player, ptr)) + // TODO: do not run these two every frame. keep an Aware state for each actor and update it every 0.2 s + // or so? + && world->getLOS(ptr, player) && mechanicsManager->awarenessCheck(player, ptr)) { - static const int iCrimeThresholdMultiplier = esmStore.get().find("iCrimeThresholdMultiplier")->mValue.getInteger(); + static const int iCrimeThresholdMultiplier + = esmStore.get().find("iCrimeThresholdMultiplier")->mValue.getInteger(); if (playerStats.getBounty() >= cutoff * iCrimeThresholdMultiplier) { mechanicsManager->startCombat(ptr, player); - creatureStats.setHitAttemptActorId(playerClass.getCreatureStats(player).getActorId()); // Stops the guard from quitting combat if player is unreachable + creatureStats.setHitAttemptActorId( + playerClass.getCreatureStats(player) + .getActorId()); // Stops the guard from quitting combat if player is unreachable } else creatureStats.getAiSequence().stack(AiPursue(player), ptr); @@ -1098,9 +1148,11 @@ namespace MWMechanics } } - Actors::Actors() : mSmoothMovement(Settings::Manager::getBool("smooth movement", "Game")) + Actors::Actors() + : mSmoothMovement(Settings::Manager::getBool("smooth movement", "Game")) { - mTimerDisposeSummonsCorpses = 0.2f; // We should add a delay between summoned creature death and its corpse despawning + mTimerDisposeSummonsCorpses + = 0.2f; // We should add a delay between summoned creature death and its corpse despawning updateProcessingRange(); } @@ -1112,18 +1164,20 @@ namespace MWMechanics void Actors::updateProcessingRange() { - // We have to cap it since using high values (larger than 7168) will make some quests harder or impossible to complete (bug #1876) + // We have to cap it since using high values (larger than 7168) will make some quests harder or impossible to + // complete (bug #1876) static constexpr float maxRange = 7168.f; static constexpr float minRange = maxRange / 2.f; - mActorsProcessingRange = std::clamp(Settings::Manager::getFloat("actors processing range", "Game"), minRange, maxRange); + mActorsProcessingRange + = std::clamp(Settings::Manager::getFloat("actors processing range", "Game"), minRange, maxRange); } - void Actors::addActor (const MWWorld::Ptr& ptr, bool updateImmediately) + void Actors::addActor(const MWWorld::Ptr& ptr, bool updateImmediately) { removeActor(ptr, true); - MWRender::Animation *anim = MWBase::Environment::get().getWorld()->getAnimation(ptr); + MWRender::Animation* anim = MWBase::Environment::get().getWorld()->getAnimation(ptr); if (!anim) return; const auto it = mActors.emplace(mActors.end(), ptr, anim); @@ -1147,7 +1201,8 @@ namespace MWMechanics if (ptr == player) return; - const float dist = (player.getRefData().getPosition().asVec3() - ptr.getRefData().getPosition().asVec3()).length(); + const float dist + = (player.getRefData().getPosition().asVec3() - ptr.getRefData().getPosition().asVec3()).length(); if (dist > mActorsProcessingRange) { ptr.getRefData().getBaseNode()->setNodeMask(0); @@ -1158,9 +1213,9 @@ namespace MWMechanics // Fade away actors on large distance (>90% of actor's processing distance) float visibilityRatio = 1.0; - const float fadeStartDistance = mActorsProcessingRange*0.9f; + const float fadeStartDistance = mActorsProcessingRange * 0.9f; const float fadeEndDistance = mActorsProcessingRange; - const float fadeRatio = (dist - fadeStartDistance)/(fadeEndDistance - fadeStartDistance); + const float fadeRatio = (dist - fadeStartDistance) / (fadeEndDistance - fadeStartDistance); if (fadeRatio > 0) visibilityRatio -= std::max(0.f, fadeRatio); @@ -1169,12 +1224,12 @@ namespace MWMechanics ctrl.setVisibility(visibilityRatio); } - void Actors::removeActor (const MWWorld::Ptr& ptr, bool keepActive) + void Actors::removeActor(const MWWorld::Ptr& ptr, bool keepActive) { const auto iter = mIndex.find(ptr.mRef); if (iter != mIndex.end()) { - if(!keepActive) + if (!keepActive) removeTemporaryEffects(iter->second->getPtr()); mActors.erase(iter->second); mIndex.erase(iter); @@ -1196,22 +1251,21 @@ namespace MWMechanics // If an observer is NPC, check if he detected an actor if (!observer.isEmpty() && observer.getClass().isNpc()) { - return - MWBase::Environment::get().getWorld()->getLOS(observer, actor) && - MWBase::Environment::get().getMechanicsManager()->awarenessCheck(actor, observer); + return MWBase::Environment::get().getWorld()->getLOS(observer, actor) + && MWBase::Environment::get().getMechanicsManager()->awarenessCheck(actor, observer); } // Otherwise check if any actor in AI processing range sees the target actor std::vector neighbors; - osg::Vec3f position (actor.getRefData().getPosition().asVec3()); + osg::Vec3f position(actor.getRefData().getPosition().asVec3()); getObjectsInRange(position, mActorsProcessingRange, neighbors); - for (const MWWorld::Ptr &neighbor : neighbors) + for (const MWWorld::Ptr& neighbor : neighbors) { if (neighbor == actor) continue; const bool result = MWBase::Environment::get().getWorld()->getLOS(neighbor, actor) - && MWBase::Environment::get().getMechanicsManager()->awarenessCheck(actor, neighbor); + && MWBase::Environment::get().getMechanicsManager()->awarenessCheck(actor, neighbor); if (result) return true; @@ -1220,14 +1274,14 @@ namespace MWMechanics return false; } - void Actors::updateActor(const MWWorld::Ptr &old, const MWWorld::Ptr &ptr) const + void Actors::updateActor(const MWWorld::Ptr& old, const MWWorld::Ptr& ptr) const { const auto iter = mIndex.find(old.mRef); if (iter != mIndex.end()) iter->second->updatePtr(ptr); } - void Actors::dropActors (const MWWorld::CellStore *cellStore, const MWWorld::Ptr& ignore) + void Actors::dropActors(const MWWorld::CellStore* cellStore, const MWWorld::Ptr& ignore) { for (auto iter = mActors.begin(); iter != mActors.end();) { @@ -1242,7 +1296,7 @@ namespace MWMechanics } } - void Actors::updateCombatMusic () + void Actors::updateCombatMusic() { const MWWorld::Ptr player = getPlayer(); const osg::Vec3f playerPos = player.getRefData().getPosition().asVec3(); @@ -1253,9 +1307,11 @@ namespace MWMechanics { for (const Actor& actor : mActors) { - if (actor.getPtr() == player) continue; + if (actor.getPtr() == player) + continue; - bool inProcessingRange = (playerPos - actor.getPtr().getRefData().getPosition().asVec3()).length2() <= mActorsProcessingRange*mActorsProcessingRange; + bool inProcessingRange = (playerPos - actor.getPtr().getRefData().getPosition().asVec3()).length2() + <= mActorsProcessingRange * mActorsProcessingRange; if (inProcessingRange) { MWMechanics::CreatureStats& stats = actor.getPtr().getClass().getCreatureStats(actor.getPtr()); @@ -1270,8 +1326,8 @@ namespace MWMechanics // check if we still have any player enemies to switch music if (mCurrentMusic != MusicType::Explore && !hasHostiles - && !(player.getClass().getCreatureStats(player).isDead() - && MWBase::Environment::get().getSoundManager()->isMusicPlaying())) + && !(player.getClass().getCreatureStats(player).isDead() + && MWBase::Environment::get().getSoundManager()->isMusicPlaying())) { MWBase::Environment::get().getSoundManager()->playPlaylist(std::string("Explore")); mCurrentMusic = MusicType::Explore; @@ -1281,7 +1337,6 @@ namespace MWMechanics MWBase::Environment::get().getSoundManager()->playPlaylist(std::string("Battle")); mCurrentMusic = MusicType::Battle; } - } void Actors::predictAndAvoidCollisions(float duration) const @@ -1333,7 +1388,8 @@ namespace MWMechanics if (!static_cast(package).isStationary()) shouldGiveWay = true; } - else if (package.getTypeId() == AiPackageTypeId::Combat || package.getTypeId() == AiPackageTypeId::Pursue) + else if (package.getTypeId() == AiPackageTypeId::Combat + || package.getTypeId() == AiPackageTypeId::Pursue) { currentTarget = package.getTarget(); shouldAvoidCollision = isMoving; @@ -1352,7 +1408,8 @@ namespace MWMechanics float timeToCheck = maxTimeToCheck; if (!shouldGiveWay && !aiSequence.isEmpty()) - timeToCheck = std::min(timeToCheck, getTimeToDestination(**aiSequence.begin(), basePos, maxSpeed, duration, halfExtents)); + timeToCheck = std::min( + timeToCheck, getTimeToDestination(**aiSequence.begin(), basePos, maxSpeed, duration, halfExtents)); float timeToCollision = timeToCheck; osg::Vec2f movementCorrection(0, 0); @@ -1379,9 +1436,10 @@ namespace MWMechanics continue; const osg::Vec3f speed = otherPtr.getClass().getMovementSettings(otherPtr).asVec3() - * otherPtr.getClass().getMaxSpeed(otherPtr); + * otherPtr.getClass().getMaxSpeed(otherPtr); const float rotZ = otherPtr.getRefData().getPosition().rot[2]; - const osg::Vec2f relSpeed = Misc::rotateVec2f(osg::Vec2f(speed.x(), speed.y()), baseRotZ - rotZ) - baseSpeed; + const osg::Vec2f relSpeed + = Misc::rotateVec2f(osg::Vec2f(speed.x(), speed.y()), baseRotZ - rotZ) - baseSpeed; float collisionDist = minGap + halfExtents.x() + otherHalfExtents.x(); collisionDist = std::min(collisionDist, relPos.length()); @@ -1406,8 +1464,11 @@ namespace MWMechanics timeToCollision = t; angleToApproachingActor = std::atan2(deltaPos.x(), deltaPos.y()); const osg::Vec2f posAtT = relPos + relSpeed * t; - const float coef = (posAtT.x() * relSpeed.x() + posAtT.y() * relSpeed.y()) / (collisionDist * collisionDist * maxSpeed) - * std::clamp((maxDistForPartialAvoiding - dist) / (maxDistForPartialAvoiding - maxDistForStrictAvoiding), 0.f, 1.f); + const float coef = (posAtT.x() * relSpeed.x() + posAtT.y() * relSpeed.y()) + / (collisionDist * collisionDist * maxSpeed) + * std::clamp( + (maxDistForPartialAvoiding - dist) / (maxDistForPartialAvoiding - maxDistForStrictAvoiding), + 0.f, 1.f); movementCorrection = posAtT * coef; if (otherPtr.getClass().getCreatureStats(otherPtr).isDead()) // In case of dead body still try to go around (it looks natural), but reduce the correction twice. @@ -1418,7 +1479,8 @@ namespace MWMechanics { // Try to evade the nearest collision. osg::Vec2f newMovement = origMovement + movementCorrection; - // Step to the side rather than backward. Otherwise player will be able to push the NPC far away from it's original location. + // Step to the side rather than backward. Otherwise player will be able to push the NPC far away from + // it's original location. newMovement.y() = std::max(newMovement.y(), 0.f); newMovement.normalize(); if (isMoving) @@ -1431,9 +1493,9 @@ namespace MWMechanics } } - void Actors::update (float duration, bool paused) + void Actors::update(float duration, bool paused) { - if(!paused) + if (!paused) { const float updateEquippedLightInterval = 1.0f; @@ -1458,7 +1520,8 @@ namespace MWMechanics /// \todo move update logic to Actor class where appropriate - std::map > cachedAllies; // will be filled as engageCombat iterates + std::map> + cachedAllies; // will be filled as engageCombat iterates const bool aiActive = MWBase::Environment::get().getMechanicsManager()->isAIActive(); const int attackedByPlayerId = player.getClass().getCreatureStats(player).getHitAttemptActorId(); @@ -1471,25 +1534,28 @@ namespace MWMechanics } const bool godmode = MWBase::Environment::get().getWorld()->getGodModeState(); - // AI and magic effects update + // AI and magic effects update for (Actor& actor : mActors) { const bool isPlayer = actor.getPtr() == player; CharacterController& ctrl = actor.getCharacterController(); - MWBase::LuaManager::ActorControls* luaControls = - MWBase::Environment::get().getLuaManager()->getActorControls(actor.getPtr()); + MWBase::LuaManager::ActorControls* luaControls + = MWBase::Environment::get().getLuaManager()->getActorControls(actor.getPtr()); const float distSqr = (playerPos - actor.getPtr().getRefData().getPosition().asVec3()).length2(); // AI processing is only done within given distance to the player. - const bool inProcessingRange = distSqr <= mActorsProcessingRange*mActorsProcessingRange; - - // If dead or no longer in combat, no longer store any actors who attempted to hit us. Also remove for the player. - if (!isPlayer && (actor.getPtr().getClass().getCreatureStats(actor.getPtr()).isDead() - || !actor.getPtr().getClass().getCreatureStats(actor.getPtr()).getAiSequence().isInCombat() - || !inProcessingRange)) + const bool inProcessingRange = distSqr <= mActorsProcessingRange * mActorsProcessingRange; + + // If dead or no longer in combat, no longer store any actors who attempted to hit us. Also remove for + // the player. + if (!isPlayer + && (actor.getPtr().getClass().getCreatureStats(actor.getPtr()).isDead() + || !actor.getPtr().getClass().getCreatureStats(actor.getPtr()).getAiSequence().isInCombat() + || !inProcessingRange)) { actor.getPtr().getClass().getCreatureStats(actor.getPtr()).setHitAttemptActorId(-1); - if (player.getClass().getCreatureStats(player).getHitAttemptActorId() == actor.getPtr().getClass().getCreatureStats(actor.getPtr()).getActorId()) + if (player.getClass().getCreatureStats(player).getHitAttemptActorId() + == actor.getPtr().getClass().getCreatureStats(actor.getPtr()).getActorId()) player.getClass().getCreatureStats(player).setHitAttemptActorId(-1); } @@ -1506,7 +1572,8 @@ namespace MWMechanics else { const bool cellChanged = world->hasCellChanged(); - const MWWorld::Ptr actorPtr = actor.getPtr(); // make a copy of the map key to avoid it being invalidated when the player teleports + const MWWorld::Ptr actorPtr = actor.getPtr(); // make a copy of the map key to avoid it being + // invalidated when the player teleports updateActor(actorPtr, duration); // Looping magic VFX update @@ -1532,7 +1599,8 @@ namespace MWMechanics { if (otherActor.getPtr() == actor.getPtr() || isPlayer) // player is not AI-controlled continue; - engageCombat(actor.getPtr(), otherActor.getPtr(), cachedAllies, otherActor.getPtr() == player); + engageCombat( + actor.getPtr(), otherActor.getPtr(), cachedAllies, otherActor.getPtr() == player); } } if (mTimerUpdateHeadTrack == 0) @@ -1543,7 +1611,7 @@ namespace MWMechanics if (!isPlayer) { - CreatureStats &stats = actor.getPtr().getClass().getCreatureStats(actor.getPtr()); + CreatureStats& stats = actor.getPtr().getClass().getCreatureStats(actor.getPtr()); if (isConscious(actor.getPtr()) && !(luaControls && luaControls->mDisableAI)) { stats.getAiSequence().execute(actor.getPtr(), ctrl, duration); @@ -1553,15 +1621,17 @@ namespace MWMechanics } } } - else if (aiActive && !isPlayer && isConscious(actor.getPtr()) && !(luaControls && luaControls->mDisableAI)) + else if (aiActive && !isPlayer && isConscious(actor.getPtr()) + && !(luaControls && luaControls->mDisableAI)) { - CreatureStats &stats = actor.getPtr().getClass().getCreatureStats(actor.getPtr()); - stats.getAiSequence().execute(actor.getPtr(), ctrl, duration, /*outOfRange*/true); + CreatureStats& stats = actor.getPtr().getClass().getCreatureStats(actor.getPtr()); + stats.getAiSequence().execute(actor.getPtr(), ctrl, duration, /*outOfRange*/ true); } if (inProcessingRange && actor.getPtr().getClass().isNpc()) { - // We can not update drowning state for actors outside of AI distance - they can not resurface to breathe + // We can not update drowning state for actors outside of AI distance - they can not resurface + // to breathe updateDrowning(actor.getPtr(), duration, ctrl.isKnockedOut(), isPlayer); } if (mTimerUpdateEquippedLight == 0 && actor.getPtr().getClass().hasInventoryStore(actor.getPtr())) @@ -1587,7 +1657,7 @@ namespace MWMechanics { const float dist = (playerPos - actor.getPtr().getRefData().getPosition().asVec3()).length(); const bool isPlayer = actor.getPtr() == player; - CreatureStats &stats = actor.getPtr().getClass().getCreatureStats(actor.getPtr()); + CreatureStats& stats = actor.getPtr().getClass().getCreatureStats(actor.getPtr()); // Actors with active AI should be able to move. bool alwaysActive = false; if (!isPlayer && isConscious(actor.getPtr()) && !stats.isParalyzed()) @@ -1596,7 +1666,8 @@ namespace MWMechanics alwaysActive = !seq.isEmpty() && seq.getActivePackage().alwaysActive(); } const bool inRange = isPlayer || dist <= mActorsProcessingRange || alwaysActive; - const int activeFlag = isPlayer ? 2 : 1; // Can be changed back to '2' to keep updating bounding boxes off screen (more accurate, but slower) + const int activeFlag = isPlayer ? 2 : 1; // Can be changed back to '2' to keep updating bounding boxes + // off screen (more accurate, but slower) const int active = inRange ? activeFlag : 0; CharacterController& ctrl = actor.getCharacterController(); @@ -1612,7 +1683,8 @@ namespace MWMechanics world->setActorActive(actor.getPtr(), true); const bool isDead = actor.getPtr().getClass().getCreatureStats(actor.getPtr()).isDead(); - if (!isDead && (!godmode || !isPlayer) && actor.getPtr().getClass().getCreatureStats(actor.getPtr()).isParalyzed()) + if (!isDead && (!godmode || !isPlayer) + && actor.getPtr().getClass().getCreatureStats(actor.getPtr()).isParalyzed()) ctrl.skipAnim(); // Handle player last, in case a cell transition occurs by casting a teleportation spell @@ -1624,7 +1696,8 @@ namespace MWMechanics } actor.getPtr().getRefData().getBaseNode()->setNodeMask(MWRender::Mask_Actor); - world->setActorCollisionMode(actor.getPtr(), true, !actor.getPtr().getClass().getCreatureStats(actor.getPtr()).isDeathAnimationFinished()); + world->setActorCollisionMode(actor.getPtr(), true, + !actor.getPtr().getClass().getCreatureStats(actor.getPtr()).isDeathAnimationFinished()); if (!actor.getPositionAdjusted()) { @@ -1646,18 +1719,18 @@ namespace MWMechanics for (const Actor& actor : mActors) { - const MWWorld::Class &cls = actor.getPtr().getClass(); - CreatureStats &stats = cls.getCreatureStats(actor.getPtr()); + const MWWorld::Class& cls = actor.getPtr().getClass(); + CreatureStats& stats = cls.getCreatureStats(actor.getPtr()); - //KnockedOutOneFrameLogic - //Used for "OnKnockedOut" command - //Put here to ensure that it's run for PRECISELY one frame. + // KnockedOutOneFrameLogic + // Used for "OnKnockedOut" command + // Put here to ensure that it's run for PRECISELY one frame. if (stats.getKnockedDown() && !stats.getKnockedDownOneFrame() && !stats.getKnockedDownOverOneFrame()) - { //Start it for one frame if nessesary + { // Start it for one frame if nessesary stats.setKnockedDownOneFrame(true); } else if (stats.getKnockedDownOneFrame() && !stats.getKnockedDownOverOneFrame()) - { //Turn off KnockedOutOneframe + { // Turn off KnockedOutOneframe stats.setKnockedDownOneFrame(false); stats.setKnockedDownOverOneFrame(true); } @@ -1670,14 +1743,14 @@ namespace MWMechanics updateCombatMusic(); } - void Actors::notifyDied(const MWWorld::Ptr &actor) + void Actors::notifyDied(const MWWorld::Ptr& actor) { actor.getClass().getCreatureStats(actor).notifyDied(); ++mDeathCount[Misc::StringUtils::lowerCase(actor.getCellRef().getRefId())]; } - void Actors::resurrect(const MWWorld::Ptr &ptr) const + void Actors::resurrect(const MWWorld::Ptr& ptr) const { const auto iter = mIndex.find(ptr.mRef); if (iter != mIndex.end()) @@ -1695,10 +1768,10 @@ namespace MWMechanics { for (Actor& actor : mActors) { - const MWWorld::Class &cls = actor.getPtr().getClass(); - CreatureStats &stats = cls.getCreatureStats(actor.getPtr()); + const MWWorld::Class& cls = actor.getPtr().getClass(); + CreatureStats& stats = cls.getCreatureStats(actor.getPtr()); - if(!stats.isDead()) + if (!stats.isDead()) continue; MWBase::Environment::get().getWorld()->removeActorPath(actor.getPtr()); @@ -1733,7 +1806,7 @@ namespace MWMechanics if (isPlayer) { - //player's death animation is over + // player's death animation is over MWBase::Environment::get().getStateManager()->askLoadRecent(); // Play Death Music if it was the player dying MWBase::Environment::get().getSoundManager()->streamMusic("Special/MW_Death.mp3"); @@ -1754,14 +1827,14 @@ namespace MWMechanics { MWBase::Environment::get().getWorld()->deleteObject(ptr); - const ESM::Static* fx = MWBase::Environment::get().getWorld()->getStore().get() - .search("VFX_Summon_End"); + const ESM::Static* fx + = MWBase::Environment::get().getWorld()->getStore().get().search("VFX_Summon_End"); if (fx) { const VFS::Manager* const vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); MWBase::Environment::get().getWorld()->spawnEffect( - Misc::ResourceHelpers::correctMeshPath(fx->mModel, vfs), - "", ptr.getRefData().getPosition().asVec3()); + Misc::ResourceHelpers::correctMeshPath(fx->mModel, vfs), "", + ptr.getRefData().getPosition().asVec3()); } // Remove the summoned creature's summoned creatures as well @@ -1786,7 +1859,8 @@ namespace MWMechanics { for (const Actor& actor : mActors) { - MWMechanics::ActiveSpells& spells = actor.getPtr().getClass().getCreatureStats(actor.getPtr()).getActiveSpells(); + MWMechanics::ActiveSpells& spells + = actor.getPtr().getClass().getCreatureStats(actor.getPtr()).getActiveSpells(); spells.purge(actor.getPtr(), casterActorId); } } @@ -1812,11 +1886,12 @@ namespace MWMechanics if (!sleep || actor.getPtr() == player) restoreDynamicStats(actor.getPtr(), hours, sleep); - if ((!actor.getPtr().getRefData().getBaseNode()) || - (playerPos - actor.getPtr().getRefData().getPosition().asVec3()).length2() > mActorsProcessingRange*mActorsProcessingRange) + if ((!actor.getPtr().getRefData().getBaseNode()) + || (playerPos - actor.getPtr().getRefData().getPosition().asVec3()).length2() + > mActorsProcessingRange * mActorsProcessingRange) continue; - adjustMagicEffects (actor.getPtr(), duration); + adjustMagicEffects(actor.getPtr(), duration); MWRender::Animation* animation = MWBase::Environment::get().getWorld()->getAnimation(actor.getPtr()); if (animation) @@ -1867,7 +1942,7 @@ namespace MWMechanics std::set sidingActors; getActorsSidingWith(player, sidingActors); - for (const MWWorld::Ptr &observer : observers) + for (const MWWorld::Ptr& observer : observers) { if (observer == player || observer.getClass().getCreatureStats(observer).isDead()) continue; @@ -1905,27 +1980,27 @@ namespace MWMechanics mSneakSkillTimer += duration; } - int Actors::getHoursToRest(const MWWorld::Ptr &ptr) const + int Actors::getHoursToRest(const MWWorld::Ptr& ptr) const { const auto [healthPerHour, magickaPerHour] = getRestorationPerHourOfSleep(ptr); CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); - const bool stunted = stats.getMagicEffects ().get(ESM::MagicEffect::StuntedMagicka).getMagnitude() > 0; + const bool stunted = stats.getMagicEffects().get(ESM::MagicEffect::StuntedMagicka).getMagnitude() > 0; - const float healthHours = healthPerHour > 0 - ? (stats.getHealth().getModified() - stats.getHealth().getCurrent()) / healthPerHour - : 1.0f; + const float healthHours = healthPerHour > 0 + ? (stats.getHealth().getModified() - stats.getHealth().getCurrent()) / healthPerHour + : 1.0f; const float magickaHours = magickaPerHour > 0 && !stunted - ? (stats.getMagicka().getModified() - stats.getMagicka().getCurrent()) / magickaPerHour - : 1.0f; + ? (stats.getMagicka().getModified() - stats.getMagicka().getCurrent()) / magickaPerHour + : 1.0f; return static_cast(std::ceil(std::max(1.f, std::max(healthHours, magickaHours)))); } - int Actors::countDeaths (const std::string& id) const + int Actors::countDeaths(const std::string& id) const { const auto iter = mDeathCount.find(id); - if(iter != mDeathCount.end()) + if (iter != mDeathCount.end()) return iter->second; return 0; } @@ -1937,16 +2012,18 @@ namespace MWMechanics iter->second->getCharacterController().forceStateUpdate(); } - bool Actors::playAnimationGroup(const MWWorld::Ptr& ptr, std::string_view groupName, int mode, int number, bool persist) const + bool Actors::playAnimationGroup( + const MWWorld::Ptr& ptr, std::string_view groupName, int mode, int number, bool persist) const { const auto iter = mIndex.find(ptr.mRef); - if(iter != mIndex.end()) + if (iter != mIndex.end()) { return iter->second->getCharacterController().playGroup(groupName, mode, number, persist); } else { - Log(Debug::Warning) << "Warning: Actors::playAnimationGroup: Unable to find " << ptr.getCellRef().getRefId(); + Log(Debug::Warning) << "Warning: Actors::playAnimationGroup: Unable to find " + << ptr.getCellRef().getRefId(); return false; } } @@ -1960,7 +2037,7 @@ namespace MWMechanics bool Actors::checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string& groupName) const { const auto iter = mIndex.find(ptr.mRef); - if(iter != mIndex.end()) + if (iter != mIndex.end()) return iter->second->getCharacterController().isAnimPlaying(groupName); return false; } @@ -1975,7 +2052,7 @@ namespace MWMechanics { for (const Actor& actor : mActors) { - if ((actor.getPtr().getRefData().getPosition().asVec3() - position).length2() <= radius*radius) + if ((actor.getPtr().getRefData().getPosition().asVec3() - position).length2() <= radius * radius) out.push_back(actor.getPtr()); } } @@ -1984,7 +2061,7 @@ namespace MWMechanics { for (const Actor& actor : mActors) { - if ((actor.getPtr().getRefData().getPosition().asVec3() - position).length2() <= radius*radius) + if ((actor.getPtr().getRefData().getPosition().asVec3() - position).length2() <= radius * radius) return true; } @@ -2002,25 +2079,27 @@ namespace MWMechanics const bool sameActor = (iteratedActor == actorPtr); - const CreatureStats &stats = iteratedActor.getClass().getCreatureStats(iteratedActor); + const CreatureStats& stats = iteratedActor.getClass().getCreatureStats(iteratedActor); if (stats.isDead()) continue; - // An actor counts as siding with this actor if Follow or Escort is the current AI package, or there are only Wander packages before the Follow/Escort package - // Actors that are targeted by this actor's Follow or Escort packages also side with them + // An actor counts as siding with this actor if Follow or Escort is the current AI package, or there are + // only Wander packages before the Follow/Escort package Actors that are targeted by this actor's Follow or + // Escort packages also side with them for (const auto& package : stats.getAiSequence()) { - if (excludeInfighting && !sameActor && package->getTypeId() == AiPackageTypeId::Combat && package->getTarget() == actorPtr) + if (excludeInfighting && !sameActor && package->getTypeId() == AiPackageTypeId::Combat + && package->getTarget() == actorPtr) break; if (package->sideWithTarget() && !package->getTarget().isEmpty()) { if (sameActor) { - if(excludeInfighting) + if (excludeInfighting) { MWWorld::Ptr ally = package->getTarget(); std::vector enemies; - if(ally.getClass().getCreatureStats(ally).getAiSequence().getCombatTargets(enemies) + if (ally.getClass().getCreatureStats(ally).getAiSequence().getCombatTargets(enemies) && std::find(enemies.begin(), enemies.end(), actorPtr) != enemies.end()) break; } @@ -2032,7 +2111,8 @@ namespace MWMechanics } break; } - else if (package->getTypeId() > AiPackageTypeId::Wander && package->getTypeId() <= AiPackageTypeId::Activate) // Don't count "fake" package types + else if (package->getTypeId() > AiPackageTypeId::Wander + && package->getTypeId() <= AiPackageTypeId::Activate) // Don't count "fake" package types break; } } @@ -2042,49 +2122,51 @@ namespace MWMechanics std::vector Actors::getActorsFollowing(const MWWorld::Ptr& actorPtr) const { std::vector list; - forEachFollowingPackage(mActors, actorPtr, getPlayer(), [&] (const Actor& actor, const std::shared_ptr& package) - { - if (package->followTargetThroughDoors() && package->getTarget() == actorPtr) - list.push_back(actor.getPtr()); - else if (package->getTypeId() != AiPackageTypeId::Combat && package->getTypeId() != AiPackageTypeId::Wander) - return false; - return true; - }); + forEachFollowingPackage( + mActors, actorPtr, getPlayer(), [&](const Actor& actor, const std::shared_ptr& package) { + if (package->followTargetThroughDoors() && package->getTarget() == actorPtr) + list.push_back(actor.getPtr()); + else if (package->getTypeId() != AiPackageTypeId::Combat + && package->getTypeId() != AiPackageTypeId::Wander) + return false; + return true; + }); return list; } - void Actors::getActorsFollowing(const MWWorld::Ptr &actor, std::set& out) const + void Actors::getActorsFollowing(const MWWorld::Ptr& actor, std::set& out) const { auto followers = getActorsFollowing(actor); - for(const MWWorld::Ptr &follower : followers) + for (const MWWorld::Ptr& follower : followers) if (out.insert(follower).second) getActorsFollowing(follower, out); } - void Actors::getActorsSidingWith(const MWWorld::Ptr &actor, std::set& out, bool excludeInfighting) const + void Actors::getActorsSidingWith( + const MWWorld::Ptr& actor, std::set& out, bool excludeInfighting) const { auto followers = getActorsSidingWith(actor, excludeInfighting); - for(const MWWorld::Ptr &follower : followers) + for (const MWWorld::Ptr& follower : followers) if (out.insert(follower).second) getActorsSidingWith(follower, out, excludeInfighting); } - void Actors::getActorsSidingWith(const MWWorld::Ptr &actor, std::set& out, + void Actors::getActorsSidingWith(const MWWorld::Ptr& actor, std::set& out, std::map>& cachedAllies) const { // If we have already found actor's allies, use the cache - std::map >::const_iterator search = cachedAllies.find(actor); + std::map>::const_iterator search = cachedAllies.find(actor); if (search != cachedAllies.end()) out.insert(search->second.begin(), search->second.end()); else { - for (const MWWorld::Ptr &follower : getActorsSidingWith(actor, true)) + for (const MWWorld::Ptr& follower : getActorsSidingWith(actor, true)) if (out.insert(follower).second) getActorsSidingWith(follower, out, cachedAllies); // Cache ptrs and their sets of allies cachedAllies.insert(std::make_pair(actor, out)); - for (const MWWorld::Ptr &iter : out) + for (const MWWorld::Ptr& iter : out) { search = cachedAllies.find(iter); if (search == cachedAllies.end()) @@ -2093,38 +2175,40 @@ namespace MWMechanics } } - std::vector Actors::getActorsFollowingIndices(const MWWorld::Ptr &actor) const + std::vector Actors::getActorsFollowingIndices(const MWWorld::Ptr& actor) const { std::vector list; - forEachFollowingPackage(mActors, actor, getPlayer(), [&] (const Actor&, const std::shared_ptr& package) - { - if (package->followTargetThroughDoors() && package->getTarget() == actor) - { - list.push_back(static_cast(package.get())->getFollowIndex()); - return false; - } - else if (package->getTypeId() != AiPackageTypeId::Combat && package->getTypeId() != AiPackageTypeId::Wander) - return false; - return true; - }); + forEachFollowingPackage( + mActors, actor, getPlayer(), [&](const Actor&, const std::shared_ptr& package) { + if (package->followTargetThroughDoors() && package->getTarget() == actor) + { + list.push_back(static_cast(package.get())->getFollowIndex()); + return false; + } + else if (package->getTypeId() != AiPackageTypeId::Combat + && package->getTypeId() != AiPackageTypeId::Wander) + return false; + return true; + }); return list; } - std::map Actors::getActorsFollowingByIndex(const MWWorld::Ptr &actor) const + std::map Actors::getActorsFollowingByIndex(const MWWorld::Ptr& actor) const { std::map map; - forEachFollowingPackage(mActors, actor, getPlayer(), [&] (const Actor& otherActor, const std::shared_ptr& package) - { - if (package->followTargetThroughDoors() && package->getTarget() == actor) - { - const int index = static_cast(package.get())->getFollowIndex(); - map[index] = otherActor.getPtr(); - return false; - } - else if (package->getTypeId() != AiPackageTypeId::Combat && package->getTypeId() != AiPackageTypeId::Wander) - return false; - return true; - }); + forEachFollowingPackage( + mActors, actor, getPlayer(), [&](const Actor& otherActor, const std::shared_ptr& package) { + if (package->followTargetThroughDoors() && package->getTarget() == actor) + { + const int index = static_cast(package.get())->getFollowIndex(); + map[index] = otherActor.getPtr(); + return false; + } + else if (package->getTypeId() != AiPackageTypeId::Combat + && package->getTypeId() != AiPackageTypeId::Wander) + return false; + return true; + }); return map; } @@ -2134,12 +2218,12 @@ namespace MWMechanics std::vector neighbors; const osg::Vec3f position(actor.getRefData().getPosition().asVec3()); getObjectsInRange(position, mActorsProcessingRange, neighbors); - for(const MWWorld::Ptr& neighbor : neighbors) + for (const MWWorld::Ptr& neighbor : neighbors) { if (neighbor == actor) continue; - const CreatureStats &stats = neighbor.getClass().getCreatureStats(neighbor); + const CreatureStats& stats = neighbor.getClass().getCreatureStats(neighbor); if (stats.isDead()) continue; @@ -2153,39 +2237,38 @@ namespace MWMechanics { std::vector list; std::vector neighbors; - osg::Vec3f position (actor.getRefData().getPosition().asVec3()); + osg::Vec3f position(actor.getRefData().getPosition().asVec3()); getObjectsInRange(position, mActorsProcessingRange, neighbors); std::set followers; getActorsFollowing(actor, followers); for (const MWWorld::Ptr& neighbor : neighbors) { - const CreatureStats &stats = neighbor.getClass().getCreatureStats(neighbor); + const CreatureStats& stats = neighbor.getClass().getCreatureStats(neighbor); if (stats.isDead() || neighbor == actor || neighbor.getClass().isPureWaterCreature(neighbor)) continue; const bool isFollower = followers.find(neighbor) != followers.end(); if (stats.getAiSequence().isInCombat(actor) - || (MWBase::Environment::get().getMechanicsManager()->isAggressive(neighbor, actor) && !isFollower)) + || (MWBase::Environment::get().getMechanicsManager()->isAggressive(neighbor, actor) && !isFollower)) list.push_back(neighbor); } return list; } - - void Actors::write (ESM::ESMWriter& writer, Loading::Listener& listener) const + void Actors::write(ESM::ESMWriter& writer, Loading::Listener& listener) const { writer.startRecord(ESM::REC_DCOU); for (const auto& [id, count] : mDeathCount) { writer.writeHNString("ID__", id); - writer.writeHNT ("COUN", count); + writer.writeHNT("COUN", count); } writer.endRecord(ESM::REC_DCOU); } - void Actors::readRecord (ESM::ESMReader& reader, uint32_t type) + void Actors::readRecord(ESM::ESMReader& reader, uint32_t type) { if (type == ESM::REC_DCOU) { @@ -2207,12 +2290,12 @@ namespace MWMechanics mDeathCount.clear(); } - void Actors::updateMagicEffects(const MWWorld::Ptr &ptr) const + void Actors::updateMagicEffects(const MWWorld::Ptr& ptr) const { adjustMagicEffects(ptr, 0.f); } - bool Actors::isReadyToBlock(const MWWorld::Ptr &ptr) const + bool Actors::isReadyToBlock(const MWWorld::Ptr& ptr) const { const auto it = mIndex.find(ptr.mRef); if (it == mIndex.end()) @@ -2221,7 +2304,7 @@ namespace MWMechanics return it->second->getCharacterController().isReadyToBlock(); } - bool Actors::isCastingSpell(const MWWorld::Ptr &ptr) const + bool Actors::isCastingSpell(const MWWorld::Ptr& ptr) const { const auto it = mIndex.find(ptr.mRef); if (it == mIndex.end()) @@ -2284,9 +2367,7 @@ namespace MWMechanics { const MWWorld::Ptr ptr = it->getPtr(); ++it; - if (ptr == getPlayer() - || !isConscious(ptr) - || ptr.getClass().getCreatureStats(ptr).isParalyzed()) + if (ptr == getPlayer() || !isConscious(ptr) || ptr.getClass().getCreatureStats(ptr).isParalyzed()) continue; MWMechanics::AiSequence& seq = ptr.getClass().getCreatureStats(ptr).getAiSequence(); seq.fastForward(ptr); diff --git a/apps/openmw/mwmechanics/actors.hpp b/apps/openmw/mwmechanics/actors.hpp index c2102615f3..f9ce7eb3cc 100644 --- a/apps/openmw/mwmechanics/actors.hpp +++ b/apps/openmw/mwmechanics/actors.hpp @@ -1,11 +1,11 @@ #ifndef GAME_MWMECHANICS_ACTORS_H #define GAME_MWMECHANICS_ACTORS_H -#include -#include -#include #include #include +#include +#include +#include #include "actor.hpp" @@ -39,185 +39,182 @@ namespace MWMechanics class Actors { - public: - - Actors(); - - std::list::const_iterator begin() const { return mActors.begin(); } - std::list::const_iterator end() const { return mActors.end(); } - std::size_t size() const { return mActors.size(); } + public: + Actors(); - void notifyDied(const MWWorld::Ptr &actor); + std::list::const_iterator begin() const { return mActors.begin(); } + std::list::const_iterator end() const { return mActors.end(); } + std::size_t size() const { return mActors.size(); } - /// Check if the target actor was detected by an observer - /// If the observer is a non-NPC, check all actors in AI processing distance as observers - bool isActorDetected(const MWWorld::Ptr& actor, const MWWorld::Ptr& observer) const; + void notifyDied(const MWWorld::Ptr& actor); - /// Update magic effects for an actor. Usually done automatically once per frame, but if we're currently - /// paused we may want to do it manually (after equipping permanent enchantment) - void updateMagicEffects(const MWWorld::Ptr& ptr) const; + /// Check if the target actor was detected by an observer + /// If the observer is a non-NPC, check all actors in AI processing distance as observers + bool isActorDetected(const MWWorld::Ptr& actor, const MWWorld::Ptr& observer) const; - void updateProcessingRange(); - float getProcessingRange() const; + /// Update magic effects for an actor. Usually done automatically once per frame, but if we're currently + /// paused we may want to do it manually (after equipping permanent enchantment) + void updateMagicEffects(const MWWorld::Ptr& ptr) const; - void addActor (const MWWorld::Ptr& ptr, bool updateImmediately=false); - ///< Register an actor for stats management - /// - /// \note Dead actors are ignored. + void updateProcessingRange(); + float getProcessingRange() const; - void removeActor (const MWWorld::Ptr& ptr, bool keepActive); - ///< Deregister an actor for stats management - /// - /// \note Ignored, if \a ptr is not a registered actor. + void addActor(const MWWorld::Ptr& ptr, bool updateImmediately = false); + ///< Register an actor for stats management + /// + /// \note Dead actors are ignored. - void resurrect(const MWWorld::Ptr& ptr) const; + void removeActor(const MWWorld::Ptr& ptr, bool keepActive); + ///< Deregister an actor for stats management + /// + /// \note Ignored, if \a ptr is not a registered actor. - void castSpell(const MWWorld::Ptr& ptr, const std::string& spellId, bool manualSpell = false) const; + void resurrect(const MWWorld::Ptr& ptr) const; - void updateActor(const MWWorld::Ptr &old, const MWWorld::Ptr& ptr) const; - ///< Updates an actor with a new Ptr + void castSpell(const MWWorld::Ptr& ptr, const std::string& spellId, bool manualSpell = false) const; - void dropActors (const MWWorld::CellStore *cellStore, const MWWorld::Ptr& ignore); - ///< Deregister all actors (except for \a ignore) in the given cell. + void updateActor(const MWWorld::Ptr& old, const MWWorld::Ptr& ptr) const; + ///< Updates an actor with a new Ptr - void updateCombatMusic(); - ///< Update combat music state + void dropActors(const MWWorld::CellStore* cellStore, const MWWorld::Ptr& ignore); + ///< Deregister all actors (except for \a ignore) in the given cell. - void update (float duration, bool paused); - ///< Update actor stats and store desired velocity vectors in \a movement + void updateCombatMusic(); + ///< Update combat music state - void updateActor(const MWWorld::Ptr& ptr, float duration) const; - ///< This function is normally called automatically during the update process, but it can - /// also be called explicitly at any time to force an update. + void update(float duration, bool paused); + ///< Update actor stats and store desired velocity vectors in \a movement - /// Removes an actor from combat and makes all of their allies stop fighting the actor's targets - void stopCombat(const MWWorld::Ptr& ptr) const; + void updateActor(const MWWorld::Ptr& ptr, float duration) const; + ///< This function is normally called automatically during the update process, but it can + /// also be called explicitly at any time to force an update. - void playIdleDialogue(const MWWorld::Ptr& actor) const; - void updateMovementSpeed(const MWWorld::Ptr& actor) const; - void updateGreetingState(const MWWorld::Ptr& actor, Actor& actorState, bool turnOnly); - void turnActorToFacePlayer(const MWWorld::Ptr& actor, Actor& actorState, const osg::Vec3f& dir) const; + /// Removes an actor from combat and makes all of their allies stop fighting the actor's targets + void stopCombat(const MWWorld::Ptr& ptr) const; - void rest(double hours, bool sleep) const; - ///< Update actors while the player is waiting or sleeping. + void playIdleDialogue(const MWWorld::Ptr& actor) const; + void updateMovementSpeed(const MWWorld::Ptr& actor) const; + void updateGreetingState(const MWWorld::Ptr& actor, Actor& actorState, bool turnOnly); + void turnActorToFacePlayer(const MWWorld::Ptr& actor, Actor& actorState, const osg::Vec3f& dir) const; - void updateSneaking(CharacterController* ctrl, float duration); - ///< Update the sneaking indicator state according to the given player character controller. + void rest(double hours, bool sleep) const; + ///< Update actors while the player is waiting or sleeping. - void restoreDynamicStats(const MWWorld::Ptr& actor, double hours, bool sleep) const; + void updateSneaking(CharacterController* ctrl, float duration); + ///< Update the sneaking indicator state according to the given player character controller. - int getHoursToRest(const MWWorld::Ptr& ptr) const; - ///< Calculate how many hours the given actor needs to rest in order to be fully healed + void restoreDynamicStats(const MWWorld::Ptr& actor, double hours, bool sleep) const; - void fastForwardAi() const; - ///< Simulate the passing of time + int getHoursToRest(const MWWorld::Ptr& ptr) const; + ///< Calculate how many hours the given actor needs to rest in order to be fully healed - int countDeaths (const std::string& id) const; - ///< Return the number of deaths for actors with the given ID. + void fastForwardAi() const; + ///< Simulate the passing of time - bool isAttackPreparing(const MWWorld::Ptr& ptr) const; - bool isRunning(const MWWorld::Ptr& ptr) const; - bool isSneaking(const MWWorld::Ptr& ptr) const; + int countDeaths(const std::string& id) const; + ///< Return the number of deaths for actors with the given ID. - void forceStateUpdate(const MWWorld::Ptr &ptr) const; + bool isAttackPreparing(const MWWorld::Ptr& ptr) const; + bool isRunning(const MWWorld::Ptr& ptr) const; + bool isSneaking(const MWWorld::Ptr& ptr) const; - bool playAnimationGroup(const MWWorld::Ptr& ptr, std::string_view groupName, int mode, - int number, bool persist = false) const; - void skipAnimation(const MWWorld::Ptr& ptr) const; - bool checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string& groupName) const; - void persistAnimationStates() const; + void forceStateUpdate(const MWWorld::Ptr& ptr) const; - void getObjectsInRange(const osg::Vec3f& position, float radius, std::vector& out) const; + bool playAnimationGroup( + const MWWorld::Ptr& ptr, std::string_view groupName, int mode, int number, bool persist = false) const; + void skipAnimation(const MWWorld::Ptr& ptr) const; + bool checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string& groupName) const; + void persistAnimationStates() const; - bool isAnyObjectInRange(const osg::Vec3f& position, float radius) const; + void getObjectsInRange(const osg::Vec3f& position, float radius, std::vector& out) const; - void cleanupSummonedCreature(CreatureStats& casterStats, int creatureActorId) const; + bool isAnyObjectInRange(const osg::Vec3f& position, float radius) const; - ///Returns the list of actors which are siding with the given actor in fights - /**ie AiFollow or AiEscort is active and the target is the actor **/ - std::vector getActorsSidingWith(const MWWorld::Ptr& actor, - bool excludeInfighting = false) const; - std::vector getActorsFollowing(const MWWorld::Ptr& actor) const; + void cleanupSummonedCreature(CreatureStats& casterStats, int creatureActorId) const; - /// Recursive version of getActorsFollowing - void getActorsFollowing(const MWWorld::Ptr &actor, std::set& out) const; - /// Recursive version of getActorsSidingWith - void getActorsSidingWith(const MWWorld::Ptr &actor, std::set& out, - bool excludeInfighting = false) const; + /// Returns the list of actors which are siding with the given actor in fights + /**ie AiFollow or AiEscort is active and the target is the actor **/ + std::vector getActorsSidingWith(const MWWorld::Ptr& actor, bool excludeInfighting = false) const; + std::vector getActorsFollowing(const MWWorld::Ptr& actor) const; - /// Get the list of AiFollow::mFollowIndex for all actors following this target - std::vector getActorsFollowingIndices(const MWWorld::Ptr& actor) const; - std::map getActorsFollowingByIndex(const MWWorld::Ptr& actor) const; + /// Recursive version of getActorsFollowing + void getActorsFollowing(const MWWorld::Ptr& actor, std::set& out) const; + /// Recursive version of getActorsSidingWith + void getActorsSidingWith( + const MWWorld::Ptr& actor, std::set& out, bool excludeInfighting = false) const; - ///Returns the list of actors which are fighting the given actor - /**ie AiCombat is active and the target is the actor **/ - std::vector getActorsFighting(const MWWorld::Ptr& actor) const; + /// Get the list of AiFollow::mFollowIndex for all actors following this target + std::vector getActorsFollowingIndices(const MWWorld::Ptr& actor) const; + std::map getActorsFollowingByIndex(const MWWorld::Ptr& actor) const; - /// Unlike getActorsFighting, also returns actors that *would* fight the given actor if they saw him. - std::vector getEnemiesNearby(const MWWorld::Ptr& actor) const; + /// Returns the list of actors which are fighting the given actor + /**ie AiCombat is active and the target is the actor **/ + std::vector getActorsFighting(const MWWorld::Ptr& actor) const; - void write (ESM::ESMWriter& writer, Loading::Listener& listener) const; + /// Unlike getActorsFighting, also returns actors that *would* fight the given actor if they saw him. + std::vector getEnemiesNearby(const MWWorld::Ptr& actor) const; - void readRecord (ESM::ESMReader& reader, uint32_t type); + void write(ESM::ESMWriter& writer, Loading::Listener& listener) const; - void clear(); // Clear death counter + void readRecord(ESM::ESMReader& reader, uint32_t type); - bool isCastingSpell(const MWWorld::Ptr& ptr) const; - bool isReadyToBlock(const MWWorld::Ptr& ptr) const; - bool isAttackingOrSpell(const MWWorld::Ptr& ptr) const; + void clear(); // Clear death counter - int getGreetingTimer(const MWWorld::Ptr& ptr) const; - float getAngleToPlayer(const MWWorld::Ptr& ptr) const; - GreetingState getGreetingState(const MWWorld::Ptr& ptr) const; - bool isTurningToPlayer(const MWWorld::Ptr& ptr) const; + bool isCastingSpell(const MWWorld::Ptr& ptr) const; + bool isReadyToBlock(const MWWorld::Ptr& ptr) const; + bool isAttackingOrSpell(const MWWorld::Ptr& ptr) const; - private: - enum class MusicType - { - Title, - Explore, - Battle - }; + int getGreetingTimer(const MWWorld::Ptr& ptr) const; + float getAngleToPlayer(const MWWorld::Ptr& ptr) const; + GreetingState getGreetingState(const MWWorld::Ptr& ptr) const; + bool isTurningToPlayer(const MWWorld::Ptr& ptr) const; - std::map mDeathCount; - std::list mActors; - std::map::iterator> mIndex; - float mTimerDisposeSummonsCorpses; - float mTimerUpdateHeadTrack = 0; - float mTimerUpdateEquippedLight = 0; - float mTimerUpdateHello = 0; - float mSneakTimer = 0; // Times update of sneak icon - float mSneakSkillTimer = 0; // Times sneak skill progress from "avoid notice" - float mActorsProcessingRange; - bool mSmoothMovement; - MusicType mCurrentMusic = MusicType::Title; + private: + enum class MusicType + { + Title, + Explore, + Battle + }; - void updateVisibility(const MWWorld::Ptr& ptr, CharacterController& ctrl) const; + std::map mDeathCount; + std::list mActors; + std::map::iterator> mIndex; + float mTimerDisposeSummonsCorpses; + float mTimerUpdateHeadTrack = 0; + float mTimerUpdateEquippedLight = 0; + float mTimerUpdateHello = 0; + float mSneakTimer = 0; // Times update of sneak icon + float mSneakSkillTimer = 0; // Times sneak skill progress from "avoid notice" + float mActorsProcessingRange; + bool mSmoothMovement; + MusicType mCurrentMusic = MusicType::Title; - void adjustMagicEffects(const MWWorld::Ptr& creature, float duration) const; + void updateVisibility(const MWWorld::Ptr& ptr, CharacterController& ctrl) const; - void calculateRestoration(const MWWorld::Ptr& ptr, float duration) const; + void adjustMagicEffects(const MWWorld::Ptr& creature, float duration) const; - void updateCrimePursuit(const MWWorld::Ptr& ptr, float duration) const; + void calculateRestoration(const MWWorld::Ptr& ptr, float duration) const; - void killDeadActors (); + void updateCrimePursuit(const MWWorld::Ptr& ptr, float duration) const; - void purgeSpellEffects(int casterActorId) const; + void killDeadActors(); - void predictAndAvoidCollisions(float duration) const; + void purgeSpellEffects(int casterActorId) const; - /** Start combat between two actors - @Notes: If againstPlayer = true then actor2 should be the Player. - If one of the combatants is creature it should be actor1. - */ - void engageCombat(const MWWorld::Ptr& actor1, const MWWorld::Ptr& actor2, - std::map>& cachedAllies, bool againstPlayer) const; + void predictAndAvoidCollisions(float duration) const; - /// Recursive version of getActorsSidingWith that takes, adds to and returns a cache of - /// actors mapped to their allies. Excludes infighting - void getActorsSidingWith(const MWWorld::Ptr &actor, std::set& out, - std::map>& cachedAllies) const; + /** Start combat between two actors + @Notes: If againstPlayer = true then actor2 should be the Player. + If one of the combatants is creature it should be actor1. + */ + void engageCombat(const MWWorld::Ptr& actor1, const MWWorld::Ptr& actor2, + std::map>& cachedAllies, bool againstPlayer) const; + /// Recursive version of getActorsSidingWith that takes, adds to and returns a cache of + /// actors mapped to their allies. Excludes infighting + void getActorsSidingWith(const MWWorld::Ptr& actor, std::set& out, + std::map>& cachedAllies) const; }; } diff --git a/apps/openmw/mwmechanics/actorutil.cpp b/apps/openmw/mwmechanics/actorutil.cpp index 3c6c9593c2..5b255b3d78 100644 --- a/apps/openmw/mwmechanics/actorutil.cpp +++ b/apps/openmw/mwmechanics/actorutil.cpp @@ -1,13 +1,13 @@ #include "actorutil.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" #include "../mwworld/class.hpp" #include "../mwworld/player.hpp" -#include "../mwmechanics/magiceffects.hpp" #include "../mwmechanics/creaturestats.hpp" +#include "../mwmechanics/magiceffects.hpp" #include diff --git a/apps/openmw/mwmechanics/aiactivate.cpp b/apps/openmw/mwmechanics/aiactivate.cpp index d5bb335936..43dcb33a7a 100644 --- a/apps/openmw/mwmechanics/aiactivate.cpp +++ b/apps/openmw/mwmechanics/aiactivate.cpp @@ -2,8 +2,8 @@ #include -#include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" #include "../mwworld/class.hpp" @@ -14,13 +14,16 @@ namespace MWMechanics { AiActivate::AiActivate(std::string_view objectId, bool repeat) - : TypedAiPackage(repeat), mObjectId(objectId) + : TypedAiPackage(repeat) + , mObjectId(objectId) { } - bool AiActivate::execute(const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) + bool AiActivate::execute( + const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) { - const MWWorld::Ptr target = MWBase::Environment::get().getWorld()->searchPtr(mObjectId, false); //The target to follow + const MWWorld::Ptr target + = MWBase::Environment::get().getWorld()->searchPtr(mObjectId, false); // The target to follow actor.getClass().getCreatureStats(actor).setDrawState(DrawState::Nothing); @@ -30,7 +33,8 @@ namespace MWMechanics return true; // Turn to target and move to it directly, without pathfinding. - const osg::Vec3f targetDir = target.getRefData().getPosition().asVec3() - actor.getRefData().getPosition().asVec3(); + const osg::Vec3f targetDir + = target.getRefData().getPosition().asVec3() - actor.getRefData().getPosition().asVec3(); zTurn(actor, std::atan2(targetDir.x(), targetDir.y()), 0.f); actor.getClass().getMovementSettings(actor).mPosition[1] = 1; @@ -38,13 +42,14 @@ namespace MWMechanics if (MWBase::Environment::get().getWorld()->getMaxActivationDistance() >= targetDir.length()) { - // Note: we intentionally do not cancel package after activation here for backward compatibility with original engine. + // Note: we intentionally do not cancel package after activation here for backward compatibility with + // original engine. MWBase::Environment::get().getWorld()->activate(target, actor); } return false; } - void AiActivate::writeState(ESM::AiSequence::AiSequence &sequence) const + void AiActivate::writeState(ESM::AiSequence::AiSequence& sequence) const { auto activate = std::make_unique(); activate->mTargetId = mObjectId; @@ -56,7 +61,7 @@ namespace MWMechanics sequence.mPackages.push_back(std::move(package)); } - AiActivate::AiActivate(const ESM::AiSequence::AiActivate *activate) + AiActivate::AiActivate(const ESM::AiSequence::AiActivate* activate) : AiActivate(activate->mTargetId, activate->mRepeat) { } diff --git a/apps/openmw/mwmechanics/aiactivate.hpp b/apps/openmw/mwmechanics/aiactivate.hpp index f8686d746b..01b469f3aa 100644 --- a/apps/openmw/mwmechanics/aiactivate.hpp +++ b/apps/openmw/mwmechanics/aiactivate.hpp @@ -8,10 +8,10 @@ namespace ESM { -namespace AiSequence -{ - struct AiActivate; -} + namespace AiSequence + { + struct AiActivate; + } } namespace MWMechanics @@ -20,21 +20,22 @@ namespace MWMechanics /** Will activate when close to object **/ class AiActivate final : public TypedAiPackage { - public: - /// Constructor - /** \param objectId Reference to object to activate **/ - explicit AiActivate(std::string_view objectId, bool repeat); + public: + /// Constructor + /** \param objectId Reference to object to activate **/ + explicit AiActivate(std::string_view objectId, bool repeat); - explicit AiActivate(const ESM::AiSequence::AiActivate* activate); + explicit AiActivate(const ESM::AiSequence::AiActivate* activate); - bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override; + bool execute(const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, + float duration) override; - static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Activate; } + static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Activate; } - void writeState(ESM::AiSequence::AiSequence& sequence) const override; + void writeState(ESM::AiSequence::AiSequence& sequence) const override; - private: - const std::string mObjectId; + private: + const std::string mObjectId; }; } #endif // GAME_MWMECHANICS_AIACTIVATE_H diff --git a/apps/openmw/mwmechanics/aiavoiddoor.cpp b/apps/openmw/mwmechanics/aiavoiddoor.cpp index e8cb71add0..1f229f61bf 100644 --- a/apps/openmw/mwmechanics/aiavoiddoor.cpp +++ b/apps/openmw/mwmechanics/aiavoiddoor.cpp @@ -2,56 +2,58 @@ #include -#include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/world.hpp" #include "../mwworld/class.hpp" +#include "actorutil.hpp" #include "creaturestats.hpp" #include "movement.hpp" -#include "actorutil.hpp" #include "steering.hpp" static const int MAX_DIRECTIONS = 4; MWMechanics::AiAvoidDoor::AiAvoidDoor(const MWWorld::ConstPtr& doorPtr) -: mDuration(1), mDoorPtr(doorPtr), mDirection(0) + : mDuration(1) + , mDoorPtr(doorPtr) + , mDirection(0) { - } -bool MWMechanics::AiAvoidDoor::execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) +bool MWMechanics::AiAvoidDoor::execute( + const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) { ESM::Position pos = actor.getRefData().getPosition(); - if(mDuration == 1) //If it just started, get the actor position as the stuck detection thing + if (mDuration == 1) // If it just started, get the actor position as the stuck detection thing mLastPos = pos.asVec3(); - mDuration -= duration; //Update timer + mDuration -= duration; // Update timer if (mDuration < 0) { if (isStuck(pos.asVec3())) { adjustDirection(); - mDuration = 1; //reset timer + mDuration = 1; // reset timer } else return true; // We have tried backing up for more than one second, we've probably cleared it } if (mDoorPtr.getClass().getDoorState(mDoorPtr) == MWWorld::DoorState::Idle) - return true; //Door is no longer opening + return true; // Door is no longer opening - ESM::Position tPos = mDoorPtr.getRefData().getPosition(); //Position of the door + ESM::Position tPos = mDoorPtr.getRefData().getPosition(); // Position of the door float x = pos.pos[1] - tPos.pos[1]; float y = pos.pos[0] - tPos.pos[0]; actor.getClass().getCreatureStats(actor).setMovementFlag(CreatureStats::Flag_Run, true); // Turn away from the door and move when turn completed - if (zTurn(actor, std::atan2(y,x) + getAdjustedAngle(), osg::DegreesToRadians(5.f))) + if (zTurn(actor, std::atan2(y, x) + getAdjustedAngle(), osg::DegreesToRadians(5.f))) actor.getClass().getMovementSettings(actor).mPosition[1] = 1; else actor.getClass().getMovementSettings(actor).mPosition[1] = 0; @@ -59,8 +61,8 @@ bool MWMechanics::AiAvoidDoor::execute (const MWWorld::Ptr& actor, CharacterCont // Make all nearby actors also avoid the door std::vector actors; - MWBase::Environment::get().getMechanicsManager()->getActorsInRange(pos.asVec3(),100,actors); - for(auto& neighbor : actors) + MWBase::Environment::get().getMechanicsManager()->getActorsInRange(pos.asVec3(), 100, actors); + for (auto& neighbor : actors) { if (neighbor == getPlayer()) continue; diff --git a/apps/openmw/mwmechanics/aiavoiddoor.hpp b/apps/openmw/mwmechanics/aiavoiddoor.hpp index 5a91bb012d..8b268ef816 100644 --- a/apps/openmw/mwmechanics/aiavoiddoor.hpp +++ b/apps/openmw/mwmechanics/aiavoiddoor.hpp @@ -6,39 +6,40 @@ namespace MWMechanics { /// \brief AiPackage to have an actor avoid an opening door - /** The AI will retreat from the door until it has finished opening, walked far away from it, or one second has passed, in an attempt to avoid it - **/ + /** The AI will retreat from the door until it has finished opening, walked far away from it, or one second has + *passed, in an attempt to avoid it + **/ class AiAvoidDoor final : public TypedAiPackage { - public: - /// Avoid door until the door is fully open - explicit AiAvoidDoor(const MWWorld::ConstPtr& doorPtr); + public: + /// Avoid door until the door is fully open + explicit AiAvoidDoor(const MWWorld::ConstPtr& doorPtr); - bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override; + bool execute(const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, + float duration) override; - static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::AvoidDoor; } + static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::AvoidDoor; } - static constexpr Options makeDefaultOptions() - { - AiPackage::Options options; - options.mPriority = 2; - options.mCanCancel = false; - options.mShouldCancelPreviousAi = false; - return options; - } + static constexpr Options makeDefaultOptions() + { + AiPackage::Options options; + options.mPriority = 2; + options.mCanCancel = false; + options.mShouldCancelPreviousAi = false; + return options; + } - private: - float mDuration; - const MWWorld::ConstPtr mDoorPtr; - osg::Vec3f mLastPos; - int mDirection; + private: + float mDuration; + const MWWorld::ConstPtr mDoorPtr; + osg::Vec3f mLastPos; + int mDirection; - bool isStuck(const osg::Vec3f& actorPos) const; + bool isStuck(const osg::Vec3f& actorPos) const; - void adjustDirection(); + void adjustDirection(); - float getAdjustedAngle() const; + float getAdjustedAngle() const; }; } #endif - diff --git a/apps/openmw/mwmechanics/aibreathe.cpp b/apps/openmw/mwmechanics/aibreathe.cpp index 94e4ecd955..e437547a7a 100644 --- a/apps/openmw/mwmechanics/aibreathe.cpp +++ b/apps/openmw/mwmechanics/aibreathe.cpp @@ -1,7 +1,7 @@ #include "aibreathe.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" #include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" @@ -11,9 +11,15 @@ #include "movement.hpp" #include "steering.hpp" -bool MWMechanics::AiBreathe::execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) +bool MWMechanics::AiBreathe::execute( + const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) { - static const float fHoldBreathTime = MWBase::Environment::get().getWorld()->getStore().get().find("fHoldBreathTime")->mValue.getFloat(); + static const float fHoldBreathTime = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fHoldBreathTime") + ->mValue.getFloat(); const MWWorld::Class& actorClass = actor.getClass(); if (actorClass.isNpc()) diff --git a/apps/openmw/mwmechanics/aibreathe.hpp b/apps/openmw/mwmechanics/aibreathe.hpp index b84c0eb76e..6b2bdfed8e 100644 --- a/apps/openmw/mwmechanics/aibreathe.hpp +++ b/apps/openmw/mwmechanics/aibreathe.hpp @@ -9,19 +9,20 @@ namespace MWMechanics // The AI will go up if lesser than half breath left class AiBreathe final : public TypedAiPackage { - public: - bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override; + public: + bool execute(const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, + float duration) override; - static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Breathe; } + static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Breathe; } - static constexpr Options makeDefaultOptions() - { - AiPackage::Options options; - options.mPriority = 2; - options.mCanCancel = false; - options.mShouldCancelPreviousAi = false; - return options; - } + static constexpr Options makeDefaultOptions() + { + AiPackage::Options options; + options.mPriority = 2; + options.mCanCancel = false; + options.mShouldCancelPreviousAi = false; + return options; + } }; } #endif diff --git a/apps/openmw/mwmechanics/aicast.cpp b/apps/openmw/mwmechanics/aicast.cpp index 630c04a6a7..91876f2f04 100644 --- a/apps/openmw/mwmechanics/aicast.cpp +++ b/apps/openmw/mwmechanics/aicast.cpp @@ -26,11 +26,16 @@ namespace MWMechanics } MWMechanics::AiCast::AiCast(const std::string& targetId, const std::string& spellId, bool manualSpell) - : mTargetId(targetId), mSpellId(spellId), mCasting(false), mManual(manualSpell), mDistance(getInitialDistance(spellId)) + : mTargetId(targetId) + , mSpellId(spellId) + , mCasting(false) + , mManual(manualSpell) + , mDistance(getInitialDistance(spellId)) { } -bool MWMechanics::AiCast::execute(const MWWorld::Ptr& actor, MWMechanics::CharacterController& characterController, MWMechanics::AiState& state, float duration) +bool MWMechanics::AiCast::execute(const MWWorld::Ptr& actor, MWMechanics::CharacterController& characterController, + MWMechanics::AiState& state, float duration) { MWWorld::Ptr target; if (actor.getCellRef().getRefId() == mTargetId) diff --git a/apps/openmw/mwmechanics/aicast.hpp b/apps/openmw/mwmechanics/aicast.hpp index 9758c2b94d..e3ab224d7d 100644 --- a/apps/openmw/mwmechanics/aicast.hpp +++ b/apps/openmw/mwmechanics/aicast.hpp @@ -11,31 +11,33 @@ namespace MWWorld namespace MWMechanics { /// AiPackage which makes an actor to cast given spell. - class AiCast final : public TypedAiPackage { - public: - AiCast(const std::string& targetId, const std::string& spellId, bool manualSpell=false); - - bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override; - - static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Cast; } - - MWWorld::Ptr getTarget() const override; - - static constexpr Options makeDefaultOptions() - { - AiPackage::Options options; - options.mPriority = 3; - options.mCanCancel = false; - options.mShouldCancelPreviousAi = false; - return options; - } - - private: - const std::string mTargetId; - const std::string mSpellId; - bool mCasting; - const bool mManual; - const float mDistance; + class AiCast final : public TypedAiPackage + { + public: + AiCast(const std::string& targetId, const std::string& spellId, bool manualSpell = false); + + bool execute(const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, + float duration) override; + + static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Cast; } + + MWWorld::Ptr getTarget() const override; + + static constexpr Options makeDefaultOptions() + { + AiPackage::Options options; + options.mPriority = 3; + options.mCanCancel = false; + options.mShouldCancelPreviousAi = false; + return options; + } + + private: + const std::string mTargetId; + const std::string mSpellId; + bool mCasting; + const bool mManual; + const float mDistance; }; } diff --git a/apps/openmw/mwmechanics/aicombat.cpp b/apps/openmw/mwmechanics/aicombat.cpp index 2be388568b..6a21411315 100644 --- a/apps/openmw/mwmechanics/aicombat.cpp +++ b/apps/openmw/mwmechanics/aicombat.cpp @@ -1,42 +1,42 @@ #include "aicombat.hpp" -#include #include +#include #include #include -#include #include +#include #include "../mwphysics/collisiontype.hpp" #include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" -#include "../mwbase/environment.hpp" #include "../mwbase/dialoguemanager.hpp" +#include "../mwbase/environment.hpp" #include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/world.hpp" -#include "pathgrid.hpp" +#include "actorutil.hpp" +#include "aicombataction.hpp" +#include "character.hpp" #include "creaturestats.hpp" -#include "steering.hpp" #include "movement.hpp" -#include "character.hpp" -#include "aicombataction.hpp" -#include "actorutil.hpp" +#include "pathgrid.hpp" +#include "steering.hpp" #include "weapontype.hpp" namespace { - //chooses an attack depending on probability to avoid uniformity + // chooses an attack depending on probability to avoid uniformity std::string_view chooseBestAttack(const ESM::Weapon* weapon); - osg::Vec3f AimDirToMovingTarget(const MWWorld::Ptr& actor, const MWWorld::Ptr& target, const osg::Vec3f& vLastTargetPos, - float duration, int weapType, float strength); + osg::Vec3f AimDirToMovingTarget(const MWWorld::Ptr& actor, const MWWorld::Ptr& target, + const osg::Vec3f& vLastTargetPos, float duration, int weapType, float strength); } namespace MWMechanics @@ -46,15 +46,12 @@ namespace MWMechanics mTargetActorId = actor.getClass().getCreatureStats(actor).getActorId(); } - AiCombat::AiCombat(const ESM::AiSequence::AiCombat *combat) + AiCombat::AiCombat(const ESM::AiSequence::AiCombat* combat) { mTargetActorId = combat->mTargetActorId; } - void AiCombat::init() - { - - } + void AiCombat::init() {} /* * Current AiCombat movement states (as of 0.29.0), ignoring the details of the @@ -103,12 +100,13 @@ namespace MWMechanics * whether the target was hit, etc. */ - bool AiCombat::execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) + bool AiCombat::execute( + const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) { // get or create temporary storage AiCombatStorage& storage = state.get(); - - //General description + + // General description if (actor.getClass().getCreatureStats(actor).isDead()) return true; @@ -116,9 +114,10 @@ namespace MWMechanics if (target.isEmpty()) return false; - if(!target.getRefData().getCount() || !target.getRefData().isEnabled() // Really we should be checking whether the target is currently registered - // with the MechanicsManager - || target.getClass().getCreatureStats(target).isDead()) + if (!target.getRefData().getCount() + || !target.getRefData().isEnabled() // Really we should be checking whether the target is currently + // registered with the MechanicsManager + || target.getClass().getCreatureStats(target).isDead()) return true; if (actor == target) // This should never happen. @@ -128,19 +127,22 @@ namespace MWMechanics { if (storage.mCurrentAction.get()) // need to wait to init action with its attack range { - //Update every frame. UpdateLOS uses a timer, so the LOS check does not happen every frame. + // Update every frame. UpdateLOS uses a timer, so the LOS check does not happen every frame. updateLOS(actor, target, duration, storage); - const float targetReachedTolerance = storage.mLOS && !storage.mUseCustomDestination - ? storage.mAttackRange : 0.0f; + const float targetReachedTolerance + = storage.mLOS && !storage.mUseCustomDestination ? storage.mAttackRange : 0.0f; const osg::Vec3f destination = storage.mUseCustomDestination - ? storage.mCustomDestination : target.getRefData().getPosition().asVec3(); + ? storage.mCustomDestination + : target.getRefData().getPosition().asVec3(); const bool is_target_reached = pathTo(actor, destination, duration, targetReachedTolerance); - if (is_target_reached) storage.mReadyToAttack = true; + if (is_target_reached) + storage.mReadyToAttack = true; } storage.updateCombatMove(duration); storage.mRotateMove = false; - if (storage.mReadyToAttack) updateActorsMovement(actor, duration, storage); + if (storage.mReadyToAttack) + updateActorsMovement(actor, duration, storage); if (storage.mRotateMove) return false; storage.updateAttack(actor, characterController); @@ -157,11 +159,12 @@ namespace MWMechanics return attack(actor, target, storage, characterController); } - bool AiCombat::attack(const MWWorld::Ptr& actor, const MWWorld::Ptr& target, AiCombatStorage& storage, CharacterController& characterController) + bool AiCombat::attack(const MWWorld::Ptr& actor, const MWWorld::Ptr& target, AiCombatStorage& storage, + CharacterController& characterController) { const MWWorld::CellStore*& currentCell = storage.mCell; bool cellChange = currentCell && (actor.getCell() != currentCell); - if(!currentCell || cellChange) + if (!currentCell || cellChange) { currentCell = actor.getCell(); } @@ -173,11 +176,16 @@ namespace MWMechanics actor.getClass().getCreatureStats(actor).setAttackingOrSpell(false); storage.mActionCooldown = 0.f; // Continue combat if target is player or player follower/escorter and an attack has been attempted - const auto& playerFollowersAndEscorters = MWBase::Environment::get().getMechanicsManager()->getActorsSidingWith(MWMechanics::getPlayer()); - bool targetSidesWithPlayer = (std::find(playerFollowersAndEscorters.begin(), playerFollowersAndEscorters.end(), target) != playerFollowersAndEscorters.end()); + const auto& playerFollowersAndEscorters + = MWBase::Environment::get().getMechanicsManager()->getActorsSidingWith(MWMechanics::getPlayer()); + bool targetSidesWithPlayer + = (std::find(playerFollowersAndEscorters.begin(), playerFollowersAndEscorters.end(), target) + != playerFollowersAndEscorters.end()); if ((target == MWMechanics::getPlayer() || targetSidesWithPlayer) - && ((actor.getClass().getCreatureStats(actor).getHitAttemptActorId() == target.getClass().getCreatureStats(target).getActorId()) - || (target.getClass().getCreatureStats(target).getHitAttemptActorId() == actor.getClass().getCreatureStats(actor).getActorId()))) + && ((actor.getClass().getCreatureStats(actor).getHitAttemptActorId() + == target.getClass().getCreatureStats(target).getActorId()) + || (target.getClass().getCreatureStats(target).getHitAttemptActorId() + == actor.getClass().getCreatureStats(actor).getActorId()))) forceFlee = true; else // Otherwise end combat return true; @@ -222,7 +230,7 @@ namespace MWMechanics } bool isRangedCombat = false; - float &rangeAttack = storage.mAttackRange; + float& rangeAttack = storage.mAttackRange; rangeAttack = currentAction->getCombatRange(isRangedCombat); @@ -240,7 +248,8 @@ namespace MWMechanics if (isRangedCombat) { // rotate actor taking into account target movement direction and projectile speed - osg::Vec3f vAimDir = AimDirToMovingTarget(actor, target, storage.mLastTargetPos, AI_REACTION_TIME, (weapon ? weapon->mData.mType : 0), storage.mStrength); + osg::Vec3f vAimDir = AimDirToMovingTarget(actor, target, storage.mLastTargetPos, AI_REACTION_TIME, + (weapon ? weapon->mData.mType : 0), storage.mStrength); storage.mMovement.mRotation[0] = getXAngleToDir(vAimDir); storage.mMovement.mRotation[2] = getZAngleToDir(vAimDir); @@ -249,7 +258,8 @@ namespace MWMechanics { osg::Vec3f vAimDir = MWBase::Environment::get().getWorld()->aimToTarget(actor, target, false); storage.mMovement.mRotation[0] = getXAngleToDir(vAimDir); - storage.mMovement.mRotation[2] = getZAngleToDir((vTargetPos-vActorPos)); // using vAimDir results in spastic movements since the head is animated + storage.mMovement.mRotation[2] = getZAngleToDir( + (vTargetPos - vActorPos)); // using vAimDir results in spastic movements since the head is animated } storage.mLastTargetPos = vTargetPos; @@ -275,20 +285,21 @@ namespace MWMechanics const auto areaCosts = getAreaCosts(actor); const auto pathGridGraph = getPathGridGraph(actor.getCell()); mPathFinder.buildPath(actor, vActorPos, vTargetPos, actor.getCell(), pathGridGraph, agentBounds, - navigatorFlags, areaCosts, storage.mAttackRange, PathType::Full); + navigatorFlags, areaCosts, storage.mAttackRange, PathType::Full); if (!mPathFinder.isPathConstructed()) { // If there is no path, try to find a point on a line from the actor position to target projected // on navmesh to attack the target from there. const auto navigator = world->getNavigator(); - const auto hit = DetourNavigator::raycast(*navigator, agentBounds, vActorPos, vTargetPos, navigatorFlags); + const auto hit + = DetourNavigator::raycast(*navigator, agentBounds, vActorPos, vTargetPos, navigatorFlags); if (hit.has_value() && (*hit - vTargetPos).length() <= rangeAttack) { // If the point is close enough, try to find a path to that point. mPathFinder.buildPath(actor, vActorPos, *hit, actor.getCell(), pathGridGraph, agentBounds, - navigatorFlags, areaCosts, storage.mAttackRange, PathType::Full); + navigatorFlags, areaCosts, storage.mAttackRange, PathType::Full); if (mPathFinder.isPathConstructed()) { // If path to that point is found use it as custom destination. @@ -317,7 +328,8 @@ namespace MWMechanics return false; } - void MWMechanics::AiCombat::updateLOS(const MWWorld::Ptr& actor, const MWWorld::Ptr& target, float duration, MWMechanics::AiCombatStorage& storage) + void MWMechanics::AiCombat::updateLOS( + const MWWorld::Ptr& actor, const MWWorld::Ptr& target, float duration, MWMechanics::AiCombatStorage& storage) { static const float LOS_UPDATE_DURATION = 0.5f; if (storage.mUpdateLOSTimer <= 0.f) @@ -329,7 +341,8 @@ namespace MWMechanics storage.mUpdateLOSTimer -= duration; } - void MWMechanics::AiCombat::updateFleeing(const MWWorld::Ptr& actor, const MWWorld::Ptr& target, float duration, MWMechanics::AiCombatStorage& storage) + void MWMechanics::AiCombat::updateFleeing( + const MWWorld::Ptr& actor, const MWWorld::Ptr& target, float duration, MWMechanics::AiCombatStorage& storage) { static const float BLIND_RUN_DURATION = 1.0f; @@ -342,85 +355,95 @@ namespace MWMechanics return; case AiCombatStorage::FleeState_Idle: + { + float triggerDist = getMaxAttackDistance(target); + + if (storage.mLOS && (triggerDist >= 1000 || getDistanceMinusHalfExtents(actor, target) <= triggerDist)) { - float triggerDist = getMaxAttackDistance(target); + const ESM::Pathgrid* pathgrid + = MWBase::Environment::get().getWorld()->getStore().get().search( + *storage.mCell->getCell()); - if (storage.mLOS && - (triggerDist >= 1000 || getDistanceMinusHalfExtents(actor, target) <= triggerDist)) + bool runFallback = true; + + if (pathgrid != nullptr && !pathgrid->mPoints.empty() + && !actor.getClass().isPureWaterCreature(actor)) { - const ESM::Pathgrid* pathgrid = - MWBase::Environment::get().getWorld()->getStore().get().search(*storage.mCell->getCell()); + ESM::Pathgrid::PointList points; + Misc::CoordinateConverter coords(storage.mCell->getCell()); - bool runFallback = true; + osg::Vec3f localPos = actor.getRefData().getPosition().asVec3(); + coords.toLocal(localPos); - if (pathgrid != nullptr && !pathgrid->mPoints.empty() && !actor.getClass().isPureWaterCreature(actor)) + int closestPointIndex = PathFinder::getClosestPoint(pathgrid, localPos); + for (int i = 0; i < static_cast(pathgrid->mPoints.size()); i++) { - ESM::Pathgrid::PointList points; - Misc::CoordinateConverter coords(storage.mCell->getCell()); - - osg::Vec3f localPos = actor.getRefData().getPosition().asVec3(); - coords.toLocal(localPos); - - int closestPointIndex = PathFinder::getClosestPoint(pathgrid, localPos); - for (int i = 0; i < static_cast(pathgrid->mPoints.size()); i++) + if (i != closestPointIndex + && getPathGridGraph(storage.mCell).isPointConnected(closestPointIndex, i)) { - if (i != closestPointIndex && getPathGridGraph(storage.mCell).isPointConnected(closestPointIndex, i)) - { - points.push_back(pathgrid->mPoints[static_cast(i)]); - } + points.push_back(pathgrid->mPoints[static_cast(i)]); } + } - if (!points.empty()) - { - auto& prng = MWBase::Environment::get().getWorld()->getPrng(); - ESM::Pathgrid::Point dest = points[Misc::Rng::rollDice(points.size(), prng)]; - coords.toWorld(dest); + if (!points.empty()) + { + auto& prng = MWBase::Environment::get().getWorld()->getPrng(); + ESM::Pathgrid::Point dest = points[Misc::Rng::rollDice(points.size(), prng)]; + coords.toWorld(dest); - state = AiCombatStorage::FleeState_RunToDestination; - storage.mFleeDest = ESM::Pathgrid::Point(dest.mX, dest.mY, dest.mZ); + state = AiCombatStorage::FleeState_RunToDestination; + storage.mFleeDest = ESM::Pathgrid::Point(dest.mX, dest.mY, dest.mZ); - runFallback = false; - } + runFallback = false; } + } - if (runFallback) - { - state = AiCombatStorage::FleeState_RunBlindly; - storage.mFleeBlindRunTimer = 0.0f; - } + if (runFallback) + { + state = AiCombatStorage::FleeState_RunBlindly; + storage.mFleeBlindRunTimer = 0.0f; } } - break; + } + break; case AiCombatStorage::FleeState_RunBlindly: + { + // timer to prevent twitchy movement that can be observed in vanilla MW + if (storage.mFleeBlindRunTimer < BLIND_RUN_DURATION) { - // timer to prevent twitchy movement that can be observed in vanilla MW - if (storage.mFleeBlindRunTimer < BLIND_RUN_DURATION) - { - storage.mFleeBlindRunTimer += duration; - - storage.mMovement.mRotation[0] = -actor.getRefData().getPosition().rot[0]; - storage.mMovement.mRotation[2] = osg::PI + getZAngleToDir(target.getRefData().getPosition().asVec3()-actor.getRefData().getPosition().asVec3()); - storage.mMovement.mPosition[1] = 1; - updateActorsMovement(actor, duration, storage); - } - else - state = AiCombatStorage::FleeState_Idle; + storage.mFleeBlindRunTimer += duration; + + storage.mMovement.mRotation[0] = -actor.getRefData().getPosition().rot[0]; + storage.mMovement.mRotation[2] = osg::PI + + getZAngleToDir( + target.getRefData().getPosition().asVec3() - actor.getRefData().getPosition().asVec3()); + storage.mMovement.mPosition[1] = 1; + updateActorsMovement(actor, duration, storage); } - break; + else + state = AiCombatStorage::FleeState_Idle; + } + break; case AiCombatStorage::FleeState_RunToDestination: + { + static const float fFleeDistance = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fFleeDistance") + ->mValue.getFloat(); + + float dist + = (actor.getRefData().getPosition().asVec3() - target.getRefData().getPosition().asVec3()).length(); + if ((dist > fFleeDistance && !storage.mLOS) + || pathTo(actor, PathFinder::makeOsgVec3(storage.mFleeDest), duration)) { - static const float fFleeDistance = MWBase::Environment::get().getWorld()->getStore().get().find("fFleeDistance")->mValue.getFloat(); - - float dist = (actor.getRefData().getPosition().asVec3() - target.getRefData().getPosition().asVec3()).length(); - if ((dist > fFleeDistance && !storage.mLOS) - || pathTo(actor, PathFinder::makeOsgVec3(storage.mFleeDest), duration)) - { - state = AiCombatStorage::FleeState_Idle; - } + state = AiCombatStorage::FleeState_Idle; } - break; + } + break; }; } @@ -440,8 +463,8 @@ namespace MWMechanics rotateActorOnAxis(actor, 0, actorMovementSettings, storage); } - void AiCombat::rotateActorOnAxis(const MWWorld::Ptr& actor, int axis, - MWMechanics::Movement& actorMovementSettings, AiCombatStorage& storage) + void AiCombat::rotateActorOnAxis( + const MWWorld::Ptr& actor, int axis, MWMechanics::Movement& actorMovementSettings, AiCombatStorage& storage) { actorMovementSettings.mRotation[axis] = 0; bool isRangedCombat = false; @@ -453,14 +476,15 @@ namespace MWMechanics MWWorld::Ptr AiCombat::getTarget() const { - if (mCachedTarget.isEmpty() || mCachedTarget.getRefData().isDeleted() || !mCachedTarget.getRefData().isEnabled()) + if (mCachedTarget.isEmpty() || mCachedTarget.getRefData().isDeleted() + || !mCachedTarget.getRefData().isEnabled()) { mCachedTarget = MWBase::Environment::get().getWorld()->searchPtrViaActorId(mTargetActorId); } return mCachedTarget; } - void AiCombat::writeState(ESM::AiSequence::AiSequence &sequence) const + void AiCombat::writeState(ESM::AiSequence::AiSequence& sequence) const { auto combat = std::make_unique(); combat->mTargetActorId = mTargetActorId; @@ -471,35 +495,34 @@ namespace MWMechanics sequence.mPackages.push_back(std::move(package)); } - - AiCombatStorage::AiCombatStorage() : - mAttackCooldown(0.0f), - mReaction(MWBase::Environment::get().getWorld()->getPrng()), - mTimerCombatMove(0.0f), - mReadyToAttack(false), - mAttack(false), - mAttackRange(0.0f), - mCombatMove(false), - mRotateMove(false), - mLastTargetPos(0, 0, 0), - mCell(nullptr), - mCurrentAction(), - mActionCooldown(0.0f), - mStrength(), - mForceNoShortcut(false), - mShortcutFailPos(), - mMovement(), - mFleeState(FleeState_None), - mLOS(false), - mUpdateLOSTimer(0.0f), - mFleeBlindRunTimer(0.0f), - mUseCustomDestination(false), - mCustomDestination() + AiCombatStorage::AiCombatStorage() + : mAttackCooldown(0.0f) + , mReaction(MWBase::Environment::get().getWorld()->getPrng()) + , mTimerCombatMove(0.0f) + , mReadyToAttack(false) + , mAttack(false) + , mAttackRange(0.0f) + , mCombatMove(false) + , mRotateMove(false) + , mLastTargetPos(0, 0, 0) + , mCell(nullptr) + , mCurrentAction() + , mActionCooldown(0.0f) + , mStrength() + , mForceNoShortcut(false) + , mShortcutFailPos() + , mMovement() + , mFleeState(FleeState_None) + , mLOS(false) + , mUpdateLOSTimer(0.0f) + , mFleeBlindRunTimer(0.0f) + , mUseCustomDestination(false) + , mCustomDestination() { - } - void AiCombatStorage::startCombatMove(bool isDistantCombat, float distToTarget, float rangeAttack, const MWWorld::Ptr& actor, const MWWorld::Ptr& target) + void AiCombatStorage::startCombatMove(bool isDistantCombat, float distToTarget, float rangeAttack, + const MWWorld::Ptr& actor, const MWWorld::Ptr& target) { auto& prng = MWBase::Environment::get().getWorld()->getPrng(); @@ -528,7 +551,8 @@ namespace MWMechanics else if (actor.getClass().isBipedal(actor) && !isDistantCombat) { float moveDuration = 0; - float angleToTarget = Misc::normalizeAngle(mMovement.mRotation[2] - actor.getRefData().getPosition().rot[2]); + float angleToTarget + = Misc::normalizeAngle(mMovement.mRotation[2] - actor.getRefData().getPosition().rot[2]); // Apply a big side step if enemy tries to get around and come from behind. // Otherwise apply a random side step (kind of dodging) with some probability // if actor is within range of target's weapon. @@ -552,14 +576,16 @@ namespace MWMechanics // (in vanilla - only as far as oponent's weapon range), // or not at all if opponent is using a ranged weapon - if (targetUsesRanged || distToTarget > rangeAttackOfTarget*1.5) // Don't back up if the target is wielding ranged weapon + if (targetUsesRanged + || distToTarget > rangeAttackOfTarget * 1.5) // Don't back up if the target is wielding ranged weapon return; // actor should not back up into water if (MWBase::Environment::get().getWorld()->isUnderwater(MWWorld::ConstPtr(actor), 0.5f)) return; - int mask = MWPhysics::CollisionType_World | MWPhysics::CollisionType_HeightMap | MWPhysics::CollisionType_Door; + int mask + = MWPhysics::CollisionType_World | MWPhysics::CollisionType_HeightMap | MWPhysics::CollisionType_Door; // Actor can not back up if there is no free space behind // Currently we take the 35% of actor's height from the ground as vector height. @@ -567,10 +593,11 @@ namespace MWMechanics osg::Vec3f halfExtents = MWBase::Environment::get().getWorld()->getHalfExtents(actor); osg::Vec3f pos = actor.getRefData().getPosition().asVec3(); osg::Vec3f source = pos + osg::Vec3f(0, 0, 0.75f * halfExtents.z()); - osg::Vec3f fallbackDirection = actor.getRefData().getBaseNode()->getAttitude() * osg::Vec3f(0,-1,0); + osg::Vec3f fallbackDirection = actor.getRefData().getBaseNode()->getAttitude() * osg::Vec3f(0, -1, 0); osg::Vec3f destination = source + fallbackDirection * (halfExtents.y() + 16); - bool isObstacleDetected = MWBase::Environment::get().getWorld()->castRay(source.x(), source.y(), source.z(), destination.x(), destination.y(), destination.z(), mask); + bool isObstacleDetected = MWBase::Environment::get().getWorld()->castRay( + source.x(), source.y(), source.z(), destination.x(), destination.y(), destination.z(), mask); if (isObstacleDetected) return; @@ -579,7 +606,8 @@ namespace MWMechanics // If we did not hit anything, there is a cliff behind actor. source = pos + osg::Vec3f(0, 0, 0.75f * halfExtents.z()) + fallbackDirection * (halfExtents.y() + 96); destination = source - osg::Vec3f(0, 0, 0.75f * halfExtents.z() + 96); - bool isCliffDetected = !MWBase::Environment::get().getWorld()->castRay(source.x(), source.y(), source.z(), destination.x(), destination.y(), destination.z(), mask); + bool isCliffDetected = !MWBase::Environment::get().getWorld()->castRay( + source.x(), source.y(), source.z(), destination.x(), destination.y(), destination.z(), mask); if (isCliffDetected) return; @@ -606,7 +634,7 @@ namespace MWMechanics mCombatMove = false; } - void AiCombatStorage::startAttackIfReady(const MWWorld::Ptr& actor, CharacterController& characterController, + void AiCombatStorage::startAttackIfReady(const MWWorld::Ptr& actor, CharacterController& characterController, const ESM::Weapon* weapon, bool distantCombat) { if (mReadyToAttack && characterController.readyToStartAttack()) @@ -622,7 +650,7 @@ namespace MWMechanics auto& prng = MWBase::Environment::get().getWorld()->getPrng(); mStrength = Misc::Rng::rollClosedProbability(prng); - const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); float baseDelay = store.get().find("fCombatDelayCreature")->mValue.getFloat(); if (actor.getClass().isNpc()) @@ -631,7 +659,8 @@ namespace MWMechanics } // Say a provoking combat phrase - const int iVoiceAttackOdds = store.get().find("iVoiceAttackOdds")->mValue.getInteger(); + const int iVoiceAttackOdds + = store.get().find("iVoiceAttackOdds")->mValue.getInteger(); if (Misc::Rng::roll0to99(prng) < iVoiceAttackOdds) { MWBase::Environment::get().getDialogueManager()->say(actor, "attack"); @@ -648,7 +677,8 @@ namespace MWMechanics if (mAttack) { float attackStrength = characterController.calculateWindUp(); - mAttack = !characterController.readyToPrepareAttack() && attackStrength < mStrength && attackStrength != -1.f; + mAttack + = !characterController.readyToPrepareAttack() && attackStrength < mStrength && attackStrength != -1.f; } actor.getClass().getCreatureStats(actor).setAttackingOrSpell(mAttack); } @@ -683,94 +713,95 @@ namespace MWMechanics } } - namespace { -std::string_view chooseBestAttack(const ESM::Weapon* weapon) -{ - if (weapon != nullptr) + std::string_view chooseBestAttack(const ESM::Weapon* weapon) { - //the more damage attackType deals the more probability it has - int slash = (weapon->mData.mSlash[0] + weapon->mData.mSlash[1])/2; - int chop = (weapon->mData.mChop[0] + weapon->mData.mChop[1])/2; - int thrust = (weapon->mData.mThrust[0] + weapon->mData.mThrust[1])/2; - - auto& prng = MWBase::Environment::get().getWorld()->getPrng(); - float roll = Misc::Rng::rollClosedProbability(prng) * (slash + chop + thrust); - if(roll <= slash) - return "slash"; - else if(roll <= (slash + thrust)) - return "thrust"; - else - return "chop"; + if (weapon != nullptr) + { + // the more damage attackType deals the more probability it has + int slash = (weapon->mData.mSlash[0] + weapon->mData.mSlash[1]) / 2; + int chop = (weapon->mData.mChop[0] + weapon->mData.mChop[1]) / 2; + int thrust = (weapon->mData.mThrust[0] + weapon->mData.mThrust[1]) / 2; + + auto& prng = MWBase::Environment::get().getWorld()->getPrng(); + float roll = Misc::Rng::rollClosedProbability(prng) * (slash + chop + thrust); + if (roll <= slash) + return "slash"; + else if (roll <= (slash + thrust)) + return "thrust"; + else + return "chop"; + } + return MWMechanics::CharacterController::getRandomAttackType(); } - return MWMechanics::CharacterController::getRandomAttackType(); -} - -osg::Vec3f AimDirToMovingTarget(const MWWorld::Ptr& actor, const MWWorld::Ptr& target, const osg::Vec3f& vLastTargetPos, - float duration, int weapType, float strength) -{ - float projSpeed; - const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); - // get projectile speed (depending on weapon type) - if (MWMechanics::getWeaponType(weapType)->mWeaponClass == ESM::WeaponType::Thrown) + osg::Vec3f AimDirToMovingTarget(const MWWorld::Ptr& actor, const MWWorld::Ptr& target, + const osg::Vec3f& vLastTargetPos, float duration, int weapType, float strength) { - static float fThrownWeaponMinSpeed = gmst.find("fThrownWeaponMinSpeed")->mValue.getFloat(); - static float fThrownWeaponMaxSpeed = gmst.find("fThrownWeaponMaxSpeed")->mValue.getFloat(); + float projSpeed; + const MWWorld::Store& gmst + = MWBase::Environment::get().getWorld()->getStore().get(); - projSpeed = fThrownWeaponMinSpeed + (fThrownWeaponMaxSpeed - fThrownWeaponMinSpeed) * strength; - } - else if (weapType != 0) - { - static float fProjectileMinSpeed = gmst.find("fProjectileMinSpeed")->mValue.getFloat(); - static float fProjectileMaxSpeed = gmst.find("fProjectileMaxSpeed")->mValue.getFloat(); + // get projectile speed (depending on weapon type) + if (MWMechanics::getWeaponType(weapType)->mWeaponClass == ESM::WeaponType::Thrown) + { + static float fThrownWeaponMinSpeed = gmst.find("fThrownWeaponMinSpeed")->mValue.getFloat(); + static float fThrownWeaponMaxSpeed = gmst.find("fThrownWeaponMaxSpeed")->mValue.getFloat(); - projSpeed = fProjectileMinSpeed + (fProjectileMaxSpeed - fProjectileMinSpeed) * strength; - } - else // weapType is 0 ==> it's a target spell projectile - { - projSpeed = gmst.find("fTargetSpellMaxSpeed")->mValue.getFloat(); - } + projSpeed = fThrownWeaponMinSpeed + (fThrownWeaponMaxSpeed - fThrownWeaponMinSpeed) * strength; + } + else if (weapType != 0) + { + static float fProjectileMinSpeed = gmst.find("fProjectileMinSpeed")->mValue.getFloat(); + static float fProjectileMaxSpeed = gmst.find("fProjectileMaxSpeed")->mValue.getFloat(); - // idea: perpendicular to dir to target speed components of target move vector and projectile vector should be the same + projSpeed = fProjectileMinSpeed + (fProjectileMaxSpeed - fProjectileMinSpeed) * strength; + } + else // weapType is 0 ==> it's a target spell projectile + { + projSpeed = gmst.find("fTargetSpellMaxSpeed")->mValue.getFloat(); + } - osg::Vec3f vTargetPos = target.getRefData().getPosition().asVec3(); - osg::Vec3f vDirToTarget = MWBase::Environment::get().getWorld()->aimToTarget(actor, target, true); - float distToTarget = vDirToTarget.length(); + // idea: perpendicular to dir to target speed components of target move vector and projectile vector should be + // the same - osg::Vec3f vTargetMoveDir = vTargetPos - vLastTargetPos; - vTargetMoveDir /= duration; // |vTargetMoveDir| is target real speed in units/sec now + osg::Vec3f vTargetPos = target.getRefData().getPosition().asVec3(); + osg::Vec3f vDirToTarget = MWBase::Environment::get().getWorld()->aimToTarget(actor, target, true); + float distToTarget = vDirToTarget.length(); - osg::Vec3f vPerpToDir = vDirToTarget ^ osg::Vec3f(0,0,1); // cross product + osg::Vec3f vTargetMoveDir = vTargetPos - vLastTargetPos; + vTargetMoveDir /= duration; // |vTargetMoveDir| is target real speed in units/sec now - vPerpToDir.normalize(); - osg::Vec3f vDirToTargetNormalized = vDirToTarget; - vDirToTargetNormalized.normalize(); + osg::Vec3f vPerpToDir = vDirToTarget ^ osg::Vec3f(0, 0, 1); // cross product - // dot product - float velPerp = vTargetMoveDir * vPerpToDir; - float velDir = vTargetMoveDir * vDirToTargetNormalized; + vPerpToDir.normalize(); + osg::Vec3f vDirToTargetNormalized = vDirToTarget; + vDirToTargetNormalized.normalize(); - // time to collision between target and projectile - float t_collision; + // dot product + float velPerp = vTargetMoveDir * vPerpToDir; + float velDir = vTargetMoveDir * vDirToTargetNormalized; - float projVelDirSquared = projSpeed * projSpeed - velPerp * velPerp; - if (projVelDirSquared > 0) - { - osg::Vec3f vTargetMoveDirNormalized = vTargetMoveDir; - vTargetMoveDirNormalized.normalize(); + // time to collision between target and projectile + float t_collision; - float projDistDiff = vDirToTarget * vTargetMoveDirNormalized; // dot product - projDistDiff = std::sqrt(distToTarget * distToTarget - projDistDiff * projDistDiff); + float projVelDirSquared = projSpeed * projSpeed - velPerp * velPerp; + if (projVelDirSquared > 0) + { + osg::Vec3f vTargetMoveDirNormalized = vTargetMoveDir; + vTargetMoveDirNormalized.normalize(); - t_collision = projDistDiff / (std::sqrt(projVelDirSquared) - velDir); - } - else - t_collision = 0; // speed of projectile is not enough to reach moving target + float projDistDiff = vDirToTarget * vTargetMoveDirNormalized; // dot product + projDistDiff = std::sqrt(distToTarget * distToTarget - projDistDiff * projDistDiff); - return vDirToTarget + vTargetMoveDir * t_collision; -} + t_collision = projDistDiff / (std::sqrt(projVelDirSquared) - velDir); + } + else + t_collision = 0; // speed of projectile is not enough to reach moving target + + return vDirToTarget + vTargetMoveDir * t_collision; + } } diff --git a/apps/openmw/mwmechanics/aicombat.hpp b/apps/openmw/mwmechanics/aicombat.hpp index a9153041e3..0ae40e48e2 100644 --- a/apps/openmw/mwmechanics/aicombat.hpp +++ b/apps/openmw/mwmechanics/aicombat.hpp @@ -1,13 +1,13 @@ #ifndef GAME_MWMECHANICS_AICOMBAT_H #define GAME_MWMECHANICS_AICOMBAT_H -#include "typedaipackage.hpp" #include "aitemporarybase.hpp" +#include "typedaipackage.hpp" #include "../mwworld/cellstore.hpp" // for Doors -#include "movement.hpp" #include "aitimer.hpp" +#include "movement.hpp" namespace ESM { @@ -59,7 +59,8 @@ namespace MWMechanics AiCombatStorage(); - void startCombatMove(bool isDistantCombat, float distToTarget, float rangeAttack, const MWWorld::Ptr& actor, const MWWorld::Ptr& target); + void startCombatMove(bool isDistantCombat, float distToTarget, float rangeAttack, const MWWorld::Ptr& actor, + const MWWorld::Ptr& target); void updateCombatMove(float duration); void stopCombatMove(); void startAttackIfReady(const MWWorld::Ptr& actor, CharacterController& characterController, @@ -75,48 +76,50 @@ namespace MWMechanics /// \brief Causes the actor to fight another actor class AiCombat final : public TypedAiPackage { - public: - ///Constructor - /** \param actor Actor to fight **/ - explicit AiCombat(const MWWorld::Ptr& actor); + public: + /// Constructor + /** \param actor Actor to fight **/ + explicit AiCombat(const MWWorld::Ptr& actor); - explicit AiCombat (const ESM::AiSequence::AiCombat* combat); + explicit AiCombat(const ESM::AiSequence::AiCombat* combat); - void init(); + void init(); - bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override; + bool execute(const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, + float duration) override; - static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Combat; } + static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Combat; } - static constexpr Options makeDefaultOptions() - { - AiPackage::Options options; - options.mPriority = 1; - options.mCanCancel = false; - options.mShouldCancelPreviousAi = false; - return options; - } + static constexpr Options makeDefaultOptions() + { + AiPackage::Options options; + options.mPriority = 1; + options.mCanCancel = false; + options.mShouldCancelPreviousAi = false; + return options; + } - ///Returns target ID - MWWorld::Ptr getTarget() const override; + /// Returns target ID + MWWorld::Ptr getTarget() const override; - void writeState(ESM::AiSequence::AiSequence &sequence) const override; + void writeState(ESM::AiSequence::AiSequence& sequence) const override; - private: - /// Returns true if combat should end - bool attack(const MWWorld::Ptr& actor, const MWWorld::Ptr& target, AiCombatStorage& storage, CharacterController& characterController); + private: + /// Returns true if combat should end + bool attack(const MWWorld::Ptr& actor, const MWWorld::Ptr& target, AiCombatStorage& storage, + CharacterController& characterController); - void updateLOS(const MWWorld::Ptr& actor, const MWWorld::Ptr& target, float duration, AiCombatStorage& storage); + void updateLOS(const MWWorld::Ptr& actor, const MWWorld::Ptr& target, float duration, AiCombatStorage& storage); - void updateFleeing(const MWWorld::Ptr& actor, const MWWorld::Ptr& target, float duration, AiCombatStorage& storage); + void updateFleeing( + const MWWorld::Ptr& actor, const MWWorld::Ptr& target, float duration, AiCombatStorage& storage); - /// Transfer desired movement (from AiCombatStorage) to Actor - void updateActorsMovement(const MWWorld::Ptr& actor, float duration, AiCombatStorage& storage); - void rotateActorOnAxis(const MWWorld::Ptr& actor, int axis, - MWMechanics::Movement& actorMovementSettings, AiCombatStorage& storage); + /// Transfer desired movement (from AiCombatStorage) to Actor + void updateActorsMovement(const MWWorld::Ptr& actor, float duration, AiCombatStorage& storage); + void rotateActorOnAxis(const MWWorld::Ptr& actor, int axis, MWMechanics::Movement& actorMovementSettings, + AiCombatStorage& storage); }; - - + } #endif diff --git a/apps/openmw/mwmechanics/aicombataction.cpp b/apps/openmw/mwmechanics/aicombataction.cpp index 2def2696bb..1d73a77059 100644 --- a/apps/openmw/mwmechanics/aicombataction.cpp +++ b/apps/openmw/mwmechanics/aicombataction.cpp @@ -4,28 +4,38 @@ #include #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/world.hpp" +#include "../mwworld/actionequip.hpp" +#include "../mwworld/cellstore.hpp" #include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" #include "../mwworld/inventorystore.hpp" -#include "../mwworld/actionequip.hpp" -#include "../mwworld/cellstore.hpp" #include "actorutil.hpp" -#include "npcstats.hpp" #include "combat.hpp" -#include "weaponpriority.hpp" +#include "npcstats.hpp" #include "spellpriority.hpp" +#include "weaponpriority.hpp" #include "weapontype.hpp" namespace MWMechanics { float suggestCombatRange(int rangeTypes) { - static const float fCombatDistance = MWBase::Environment::get().getWorld()->getStore().get().find("fCombatDistance")->mValue.getFloat(); - static float fHandToHandReach = MWBase::Environment::get().getWorld()->getStore().get().find("fHandToHandReach")->mValue.getFloat(); + static const float fCombatDistance = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fCombatDistance") + ->mValue.getFloat(); + static float fHandToHandReach = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fHandToHandReach") + ->mValue.getFloat(); // This distance is a possible distance of melee attack static float distance = fCombatDistance * std::max(2.f, fHandToHandReach); @@ -38,7 +48,7 @@ namespace MWMechanics return distance * 4; } - void ActionSpell::prepare(const MWWorld::Ptr &actor) + void ActionSpell::prepare(const MWWorld::Ptr& actor) { actor.getClass().getCreatureStats(actor).getSpells().setSelectedSpell(mSpellId); actor.getClass().getCreatureStats(actor).setDrawState(DrawState::Spell); @@ -52,7 +62,7 @@ namespace MWMechanics MWBase::Environment::get().getWorld()->preloadEffects(&spell->mEffects); } - float ActionSpell::getCombatRange (bool& isRanged) const + float ActionSpell::getCombatRange(bool& isRanged) const { const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get().find(mSpellId); int types = getRangeTypes(spell->mEffects); @@ -61,7 +71,7 @@ namespace MWMechanics return suggestCombatRange(types); } - void ActionEnchantedItem::prepare(const MWWorld::Ptr &actor) + void ActionEnchantedItem::prepare(const MWWorld::Ptr& actor) { actor.getClass().getCreatureStats(actor).getSpells().setSelectedSpell(std::string()); actor.getClass().getInventoryStore(actor).setSelectedEnchantItem(mItem); @@ -70,7 +80,9 @@ namespace MWMechanics float ActionEnchantedItem::getCombatRange(bool& isRanged) const { - const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get().find(mItem->getClass().getEnchantment(*mItem)); + const ESM::Enchantment* enchantment + = MWBase::Environment::get().getWorld()->getStore().get().find( + mItem->getClass().getEnchantment(*mItem)); int types = getRangeTypes(enchantment->mEffects); isRanged = (types & RangeTypes::Target) | (types & RangeTypes::Self); @@ -84,17 +96,18 @@ namespace MWMechanics return 600.f; } - void ActionPotion::prepare(const MWWorld::Ptr &actor) + void ActionPotion::prepare(const MWWorld::Ptr& actor) { actor.getClass().consume(mPotion, actor); } - void ActionWeapon::prepare(const MWWorld::Ptr &actor) + void ActionWeapon::prepare(const MWWorld::Ptr& actor) { if (actor.getClass().hasInventoryStore(actor)) { if (mWeapon.isEmpty()) - actor.getClass().getInventoryStore(actor).unequipSlot(MWWorld::InventoryStore::Slot_CarriedRight, actor); + actor.getClass().getInventoryStore(actor).unequipSlot( + MWWorld::InventoryStore::Slot_CarriedRight, actor); else { MWWorld::ActionEquip equip(mWeapon); @@ -114,13 +127,27 @@ namespace MWMechanics { isRanged = false; - static const float fCombatDistance = MWBase::Environment::get().getWorld()->getStore().get().find("fCombatDistance")->mValue.getFloat(); - static const float fProjectileMaxSpeed = MWBase::Environment::get().getWorld()->getStore().get().find("fProjectileMaxSpeed")->mValue.getFloat(); + static const float fCombatDistance = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fCombatDistance") + ->mValue.getFloat(); + static const float fProjectileMaxSpeed = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fProjectileMaxSpeed") + ->mValue.getFloat(); if (mWeapon.isEmpty()) { - static float fHandToHandReach = - MWBase::Environment::get().getWorld()->getStore().get().find("fHandToHandReach")->mValue.getFloat(); + static float fHandToHandReach = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fHandToHandReach") + ->mValue.getFloat(); return fHandToHandReach * fCombatDistance; } @@ -141,7 +168,7 @@ namespace MWMechanics return mWeapon.get()->mBase; } - std::unique_ptr prepareNextAction(const MWWorld::Ptr &actor, const MWWorld::Ptr &enemy) + std::unique_ptr prepareNextAction(const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy) { Spells& spells = actor.getClass().getCreatureStats(actor).getSpells(); @@ -228,7 +255,7 @@ namespace MWMechanics return bestAction; } - float getBestActionRating(const MWWorld::Ptr &actor, const MWWorld::Ptr &enemy) + float getBestActionRating(const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy) { Spells& spells = actor.getClass().getCreatureStats(actor).getSpells(); @@ -278,7 +305,6 @@ namespace MWMechanics return bestActionRating; } - float getDistanceMinusHalfExtents(const MWWorld::Ptr& actor1, const MWWorld::Ptr& actor2, bool minusZDist) { osg::Vec3f actor1Pos = actor1.getRefData().getPosition().asVec3(); @@ -289,15 +315,15 @@ namespace MWMechanics if (minusZDist) dist -= std::abs(actor1Pos.z() - actor2Pos.z()); - return (dist - - MWBase::Environment::get().getWorld()->getHalfExtents(actor1).y() - - MWBase::Environment::get().getWorld()->getHalfExtents(actor2).y()); + return (dist - MWBase::Environment::get().getWorld()->getHalfExtents(actor1).y() + - MWBase::Environment::get().getWorld()->getHalfExtents(actor2).y()); } float getMaxAttackDistance(const MWWorld::Ptr& actor) { const CreatureStats& stats = actor.getClass().getCreatureStats(actor); - const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& gmst + = MWBase::Environment::get().getWorld()->getStore().get(); const std::string& selectedSpellId = stats.getSpells().getSelectedSpell(); MWWorld::Ptr selectedEnchItem; @@ -330,13 +356,16 @@ namespace MWMechanics dist = 1.0f; if (!selectedSpellId.empty()) { - const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get().find(selectedSpellId); - for (std::vector::const_iterator effectIt = - spell->mEffects.mList.begin(); effectIt != spell->mEffects.mList.end(); ++effectIt) + const ESM::Spell* spell + = MWBase::Environment::get().getWorld()->getStore().get().find(selectedSpellId); + for (std::vector::const_iterator effectIt = spell->mEffects.mList.begin(); + effectIt != spell->mEffects.mList.end(); ++effectIt) { if (effectIt->mRange == ESM::RT_Target) { - const ESM::MagicEffect* effect = MWBase::Environment::get().getWorld()->getStore().get().find(effectIt->mEffectID); + const ESM::MagicEffect* effect + = MWBase::Environment::get().getWorld()->getStore().get().find( + effectIt->mEffectID); dist = effect->mData.mSpeed; break; } @@ -347,13 +376,16 @@ namespace MWMechanics std::string_view enchId = selectedEnchItem.getClass().getEnchantment(selectedEnchItem); if (!enchId.empty()) { - const ESM::Enchantment* ench = MWBase::Environment::get().getWorld()->getStore().get().find(enchId); - for (std::vector::const_iterator effectIt = - ench->mEffects.mList.begin(); effectIt != ench->mEffects.mList.end(); ++effectIt) + const ESM::Enchantment* ench + = MWBase::Environment::get().getWorld()->getStore().get().find(enchId); + for (std::vector::const_iterator effectIt = ench->mEffects.mList.begin(); + effectIt != ench->mEffects.mList.end(); ++effectIt) { if (effectIt->mRange == ESM::RT_Target) { - const ESM::MagicEffect* effect = MWBase::Environment::get().getWorld()->getStore().get().find(effectIt->mEffectID); + const ESM::MagicEffect* effect + = MWBase::Environment::get().getWorld()->getStore().get().find( + effectIt->mEffectID); dist = effect->mData.mSpeed; break; } @@ -403,7 +435,8 @@ namespace MWMechanics ESM::Position actorPos = actor.getRefData().getPosition(); ESM::Position enemyPos = enemy.getRefData().getPosition(); - if (isTargetMagicallyHidden(enemy) && !MWBase::Environment::get().getMechanicsManager()->awarenessCheck(enemy, actor)) + if (isTargetMagicallyHidden(enemy) + && !MWBase::Environment::get().getMechanicsManager()->awarenessCheck(enemy, actor)) { return false; } @@ -415,14 +448,14 @@ namespace MWMechanics } float atDist = getMaxAttackDistance(actor); - if (atDist > getDistanceMinusHalfExtents(actor, enemy) - && atDist > std::abs(actorPos.pos[2] - enemyPos.pos[2])) + if (atDist > getDistanceMinusHalfExtents(actor, enemy) && atDist > std::abs(actorPos.pos[2] - enemyPos.pos[2])) { if (MWBase::Environment::get().getWorld()->getLOS(actor, enemy)) return true; } - if (actor.getClass().isPureLandCreature(actor) && MWBase::Environment::get().getWorld()->isWalkingOnWater(enemy)) + if (actor.getClass().isPureLandCreature(actor) + && MWBase::Environment::get().getWorld()->isWalkingOnWater(enemy)) { return false; } @@ -435,14 +468,20 @@ namespace MWMechanics if (actor.getClass().isBipedal(actor) || !actor.getClass().canFly(actor)) { - if (enemy.getClass().getCreatureStats(enemy).getMagicEffects().get(ESM::MagicEffect::Levitate).getMagnitude() > 0) + if (enemy.getClass() + .getCreatureStats(enemy) + .getMagicEffects() + .get(ESM::MagicEffect::Levitate) + .getMagnitude() + > 0) { float attackDistance = getMaxAttackDistance(actor); if ((attackDistance + actorPos.pos[2]) < enemyPos.pos[2]) { if (enemy.getCell()->isExterior()) { - if (attackDistance < (enemyPos.pos[2] - MWBase::Environment::get().getWorld()->getTerrainHeightAt(enemyPos.asVec3()))) + if (attackDistance < (enemyPos.pos[2] + - MWBase::Environment::get().getWorld()->getTerrainHeightAt(enemyPos.asVec3()))) return false; } } @@ -452,7 +491,8 @@ namespace MWMechanics if (!actor.getClass().canWalk(actor) && !actor.getClass().isBipedal(actor)) return true; - if (actor.getClass().getCreatureStats(actor).getMagicEffects().get(ESM::MagicEffect::Levitate).getMagnitude() > 0) + if (actor.getClass().getCreatureStats(actor).getMagicEffects().get(ESM::MagicEffect::Levitate).getMagnitude() + > 0) return true; if (MWBase::Environment::get().getWorld()->isSwimming(actor)) @@ -467,7 +507,8 @@ namespace MWMechanics float vanillaRateFlee(const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy) { const CreatureStats& stats = actor.getClass().getCreatureStats(actor); - const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& gmst + = MWBase::Environment::get().getWorld()->getStore().get(); const int flee = stats.getAiSetting(AiSetting::Flee).getModified(); if (flee >= 100) diff --git a/apps/openmw/mwmechanics/aicombataction.hpp b/apps/openmw/mwmechanics/aicombataction.hpp index 56d2247e99..e6b87064e5 100644 --- a/apps/openmw/mwmechanics/aicombataction.hpp +++ b/apps/openmw/mwmechanics/aicombataction.hpp @@ -3,8 +3,8 @@ #include -#include "../mwworld/ptr.hpp" #include "../mwworld/containerstore.hpp" +#include "../mwworld/ptr.hpp" namespace MWMechanics { @@ -13,7 +13,7 @@ namespace MWMechanics public: virtual ~Action() {} virtual void prepare(const MWWorld::Ptr& actor) = 0; - virtual float getCombatRange (bool& isRanged) const = 0; + virtual float getCombatRange(bool& isRanged) const = 0; virtual float getActionCooldown() { return 0.f; } virtual const ESM::Weapon* getWeapon() const { return nullptr; } virtual bool isAttackingOrSpell() const { return true; } @@ -25,7 +25,7 @@ namespace MWMechanics public: ActionFlee() {} void prepare(const MWWorld::Ptr& actor) override {} - float getCombatRange (bool& isRanged) const override { return 0.0f; } + float getCombatRange(bool& isRanged) const override { return 0.0f; } float getActionCooldown() override { return 3.0f; } bool isAttackingOrSpell() const override { return false; } bool isFleeing() const override { return true; } @@ -34,22 +34,28 @@ namespace MWMechanics class ActionSpell : public Action { public: - ActionSpell(const std::string& spellId) : mSpellId(spellId) {} + ActionSpell(const std::string& spellId) + : mSpellId(spellId) + { + } std::string mSpellId; /// Sets the given spell as selected on the actor's spell list. void prepare(const MWWorld::Ptr& actor) override; - float getCombatRange (bool& isRanged) const override; + float getCombatRange(bool& isRanged) const override; }; class ActionEnchantedItem : public Action { public: - ActionEnchantedItem(const MWWorld::ContainerStoreIterator& item) : mItem(item) {} + ActionEnchantedItem(const MWWorld::ContainerStoreIterator& item) + : mItem(item) + { + } MWWorld::ContainerStoreIterator mItem; /// Sets the given item as selected enchanted item in the actor's InventoryStore. void prepare(const MWWorld::Ptr& actor) override; - float getCombatRange (bool& isRanged) const override; + float getCombatRange(bool& isRanged) const override; /// Since this action has no animation, apply a small cool down for using it float getActionCooldown() override { return 0.75f; } @@ -58,11 +64,14 @@ namespace MWMechanics class ActionPotion : public Action { public: - ActionPotion(const MWWorld::Ptr& potion) : mPotion(potion) {} + ActionPotion(const MWWorld::Ptr& potion) + : mPotion(potion) + { + } MWWorld::Ptr mPotion; /// Drinks the given potion. void prepare(const MWWorld::Ptr& actor) override; - float getCombatRange (bool& isRanged) const override; + float getCombatRange(bool& isRanged) const override; bool isAttackingOrSpell() const override { return false; } /// Since this action has no animation, apply a small cool down for using it @@ -78,17 +87,20 @@ namespace MWMechanics public: /// \a weapon may be empty for hand-to-hand combat ActionWeapon(const MWWorld::Ptr& weapon, const MWWorld::Ptr& ammo = MWWorld::Ptr()) - : mAmmunition(ammo), mWeapon(weapon) {} + : mAmmunition(ammo) + , mWeapon(weapon) + { + } /// Equips the given weapon. void prepare(const MWWorld::Ptr& actor) override; - float getCombatRange (bool& isRanged) const override; + float getCombatRange(bool& isRanged) const override; const ESM::Weapon* getWeapon() const override; }; - std::unique_ptr prepareNextAction (const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy); - float getBestActionRating(const MWWorld::Ptr &actor, const MWWorld::Ptr &enemy); + std::unique_ptr prepareNextAction(const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy); + float getBestActionRating(const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy); - float getDistanceMinusHalfExtents(const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy, bool minusZDist=false); + float getDistanceMinusHalfExtents(const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy, bool minusZDist = false); float getMaxAttackDistance(const MWWorld::Ptr& actor); bool canFight(const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy); diff --git a/apps/openmw/mwmechanics/aiescort.cpp b/apps/openmw/mwmechanics/aiescort.cpp index bbbab3b5a8..33eb48b58e 100644 --- a/apps/openmw/mwmechanics/aiescort.cpp +++ b/apps/openmw/mwmechanics/aiescort.cpp @@ -3,12 +3,12 @@ #include #include -#include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/world.hpp" -#include "../mwworld/class.hpp" #include "../mwworld/cellstore.hpp" +#include "../mwworld/class.hpp" #include "creaturestats.hpp" #include "movement.hpp" @@ -21,23 +21,39 @@ namespace MWMechanics { AiEscort::AiEscort(std::string_view actorId, int duration, float x, float y, float z, bool repeat) - : TypedAiPackage(repeat), mX(x), mY(y), mZ(z), mDuration(duration), mRemainingDuration(static_cast(duration)) - , mCellX(std::numeric_limits::max()) - , mCellY(std::numeric_limits::max()) + : TypedAiPackage(repeat) + , mX(x) + , mY(y) + , mZ(z) + , mDuration(duration) + , mRemainingDuration(static_cast(duration)) + , mCellX(std::numeric_limits::max()) + , mCellY(std::numeric_limits::max()) { mTargetActorRefId = std::string(actorId); } - AiEscort::AiEscort(std::string_view actorId, std::string_view cellId, int duration, float x, float y, float z, bool repeat) - : TypedAiPackage(repeat), mCellId(cellId), mX(x), mY(y), mZ(z), mDuration(duration), mRemainingDuration(static_cast(duration)) - , mCellX(std::numeric_limits::max()) - , mCellY(std::numeric_limits::max()) + AiEscort::AiEscort( + std::string_view actorId, std::string_view cellId, int duration, float x, float y, float z, bool repeat) + : TypedAiPackage(repeat) + , mCellId(cellId) + , mX(x) + , mY(y) + , mZ(z) + , mDuration(duration) + , mRemainingDuration(static_cast(duration)) + , mCellX(std::numeric_limits::max()) + , mCellY(std::numeric_limits::max()) { mTargetActorRefId = std::string(actorId); } - AiEscort::AiEscort(const ESM::AiSequence::AiEscort *escort) - : TypedAiPackage(escort->mRepeat), mCellId(escort->mCellId), mX(escort->mData.mX), mY(escort->mData.mY), mZ(escort->mData.mZ) + AiEscort::AiEscort(const ESM::AiSequence::AiEscort* escort) + : TypedAiPackage(escort->mRepeat) + , mCellId(escort->mCellId) + , mX(escort->mData.mX) + , mY(escort->mData.mY) + , mZ(escort->mData.mZ) , mDuration(escort->mData.mDuration) , mRemainingDuration(escort->mRemainingDuration) , mCellX(std::numeric_limits::max()) @@ -47,13 +63,14 @@ namespace MWMechanics mTargetActorId = escort->mTargetActorId; } - bool AiEscort::execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) + bool AiEscort::execute( + const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) { // If AiEscort has ran for as long or longer then the duration specified // and the duration is not infinite, the package is complete. if (mDuration > 0) { - mRemainingDuration -= ((duration*MWBase::Environment::get().getWorld()->getTimeScaleFactor()) / 3600); + mRemainingDuration -= ((duration * MWBase::Environment::get().getWorld()->getTimeScaleFactor()) / 3600); if (mRemainingDuration <= 0) { mRemainingDuration = mDuration; @@ -76,7 +93,7 @@ namespace MWMechanics if ((leaderPos - followerPos).length2() <= mMaxDist * mMaxDist) { const osg::Vec3f dest(mX, mY, mZ); - if (pathTo(actor, dest, duration, maxHalfExtent)) //Returns true on path complete + if (pathTo(actor, dest, duration, maxHalfExtent)) // Returns true on path complete { mRemainingDuration = mDuration; return true; @@ -94,7 +111,7 @@ namespace MWMechanics return false; } - void AiEscort::writeState(ESM::AiSequence::AiSequence &sequence) const + void AiEscort::writeState(ESM::AiSequence::AiSequence& sequence) const { auto escort = std::make_unique(); escort->mData.mX = mX; @@ -113,11 +130,10 @@ namespace MWMechanics sequence.mPackages.push_back(std::move(package)); } - void AiEscort::fastForward(const MWWorld::Ptr& actor, AiState &state) + void AiEscort::fastForward(const MWWorld::Ptr& actor, AiState& state) { // Update duration counter if this package has a duration if (mDuration > 0) mRemainingDuration--; } } - diff --git a/apps/openmw/mwmechanics/aiescort.hpp b/apps/openmw/mwmechanics/aiescort.hpp index 0f601a29ed..32a14131df 100644 --- a/apps/openmw/mwmechanics/aiescort.hpp +++ b/apps/openmw/mwmechanics/aiescort.hpp @@ -8,10 +8,10 @@ namespace ESM { -namespace AiSequence -{ - struct AiEscort; -} + namespace AiSequence + { + struct AiEscort; + } } namespace MWMechanics @@ -19,47 +19,49 @@ namespace MWMechanics /// \brief AI Package to have an NPC lead the player to a specific point class AiEscort final : public TypedAiPackage { - public: - /// Implementation of AiEscort - /** The Actor will escort the specified actor to the world position x, y, z until they reach their position, or they run out of time - \implement AiEscort **/ - AiEscort(std::string_view actorId, int duration, float x, float y, float z, bool repeat); - /// Implementation of AiEscortCell - /** The Actor will escort the specified actor to the cell position x, y, z until they reach their position, or they run out of time - \implement AiEscortCell **/ - AiEscort(std::string_view actorId, std::string_view cellId, int duration, float x, float y, float z, bool repeat); + public: + /// Implementation of AiEscort + /** The Actor will escort the specified actor to the world position x, y, z until they reach their position, or + they run out of time \implement AiEscort **/ + AiEscort(std::string_view actorId, int duration, float x, float y, float z, bool repeat); + /// Implementation of AiEscortCell + /** The Actor will escort the specified actor to the cell position x, y, z until they reach their position, or + they run out of time \implement AiEscortCell **/ + AiEscort( + std::string_view actorId, std::string_view cellId, int duration, float x, float y, float z, bool repeat); - AiEscort(const ESM::AiSequence::AiEscort* escort); + AiEscort(const ESM::AiSequence::AiEscort* escort); - bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override; + bool execute(const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, + float duration) override; - static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Escort; } + static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Escort; } - static constexpr Options makeDefaultOptions() - { - AiPackage::Options options; - options.mUseVariableSpeed = true; - options.mSideWithTarget = true; - return options; - } + static constexpr Options makeDefaultOptions() + { + AiPackage::Options options; + options.mUseVariableSpeed = true; + options.mSideWithTarget = true; + return options; + } - void writeState(ESM::AiSequence::AiSequence &sequence) const override; + void writeState(ESM::AiSequence::AiSequence& sequence) const override; - void fastForward(const MWWorld::Ptr& actor, AiState& state) override; + void fastForward(const MWWorld::Ptr& actor, AiState& state) override; - osg::Vec3f getDestination() const override { return osg::Vec3f(mX, mY, mZ); } + osg::Vec3f getDestination() const override { return osg::Vec3f(mX, mY, mZ); } - private: - const std::string mCellId; - const float mX; - const float mY; - const float mZ; - float mMaxDist = 450; - const float mDuration; // In hours - float mRemainingDuration; // In hours + private: + const std::string mCellId; + const float mX; + const float mY; + const float mZ; + float mMaxDist = 450; + const float mDuration; // In hours + float mRemainingDuration; // In hours - const int mCellX; - const int mCellY; + const int mCellX; + const int mCellY; }; } #endif diff --git a/apps/openmw/mwmechanics/aiface.cpp b/apps/openmw/mwmechanics/aiface.cpp index 17b18babc1..2cd46a7a00 100644 --- a/apps/openmw/mwmechanics/aiface.cpp +++ b/apps/openmw/mwmechanics/aiface.cpp @@ -5,11 +5,13 @@ #include "steering.hpp" MWMechanics::AiFace::AiFace(float targetX, float targetY) - : mTargetX(targetX), mTargetY(targetY) + : mTargetX(targetX) + , mTargetY(targetY) { } -bool MWMechanics::AiFace::execute(const MWWorld::Ptr& actor, MWMechanics::CharacterController& /*characterController*/, MWMechanics::AiState& /*state*/, float /*duration*/) +bool MWMechanics::AiFace::execute(const MWWorld::Ptr& actor, MWMechanics::CharacterController& /*characterController*/, + MWMechanics::AiState& /*state*/, float /*duration*/) { osg::Vec3f dir = osg::Vec3f(mTargetX, mTargetY, 0) - actor.getRefData().getPosition().asVec3(); return zTurn(actor, std::atan2(dir.x(), dir.y()), osg::DegreesToRadians(3.f)); diff --git a/apps/openmw/mwmechanics/aiface.hpp b/apps/openmw/mwmechanics/aiface.hpp index e176eb52ec..56747c078e 100644 --- a/apps/openmw/mwmechanics/aiface.hpp +++ b/apps/openmw/mwmechanics/aiface.hpp @@ -6,26 +6,28 @@ namespace MWMechanics { /// AiPackage which makes an actor face a certain direction. - class AiFace final : public TypedAiPackage { - public: - AiFace(float targetX, float targetY); + class AiFace final : public TypedAiPackage + { + public: + AiFace(float targetX, float targetY); - bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override; + bool execute(const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, + float duration) override; - static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Face; } + static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Face; } - static constexpr Options makeDefaultOptions() - { - AiPackage::Options options; - options.mPriority = 2; - options.mCanCancel = false; - options.mShouldCancelPreviousAi = false; - return options; - } + static constexpr Options makeDefaultOptions() + { + AiPackage::Options options; + options.mPriority = 2; + options.mCanCancel = false; + options.mShouldCancelPreviousAi = false; + return options; + } - private: - const float mTargetX; - const float mTargetY; + private: + const float mTargetX; + const float mTargetY; }; } diff --git a/apps/openmw/mwmechanics/aifollow.cpp b/apps/openmw/mwmechanics/aifollow.cpp index 9a64a5bee3..60659687ed 100644 --- a/apps/openmw/mwmechanics/aifollow.cpp +++ b/apps/openmw/mwmechanics/aifollow.cpp @@ -3,12 +3,12 @@ #include #include -#include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/world.hpp" -#include "../mwworld/class.hpp" #include "../mwworld/cellstore.hpp" +#include "../mwworld/class.hpp" #include "creaturestats.hpp" #include "movement.hpp" @@ -16,221 +16,254 @@ namespace { -osg::Vec3f::value_type getHalfExtents(const MWWorld::ConstPtr& actor) -{ - if(actor.getClass().isNpc()) - return 64; - return MWBase::Environment::get().getWorld()->getHalfExtents(actor).y(); -} + osg::Vec3f::value_type getHalfExtents(const MWWorld::ConstPtr& actor) + { + if (actor.getClass().isNpc()) + return 64; + return MWBase::Environment::get().getWorld()->getHalfExtents(actor).y(); + } } namespace MWMechanics { -int AiFollow::mFollowIndexCounter = 0; - -AiFollow::AiFollow(std::string_view actorId, float duration, float x, float y, float z, bool repeat) -: TypedAiPackage(repeat), mAlwaysFollow(false), mDuration(duration), mRemainingDuration(duration), mX(x), mY(y), mZ(z) -, mCellId(""), mActive(false), mFollowIndex(mFollowIndexCounter++) -{ - mTargetActorRefId = std::string(actorId); -} - -AiFollow::AiFollow(std::string_view actorId, std::string_view cellId, float duration, float x, float y, float z, bool repeat) -: TypedAiPackage(repeat), mAlwaysFollow(false), mDuration(duration), mRemainingDuration(duration), mX(x), mY(y), mZ(z) -, mCellId(cellId), mActive(false), mFollowIndex(mFollowIndexCounter++) -{ - mTargetActorRefId = std::string(actorId); -} - -AiFollow::AiFollow(const MWWorld::Ptr& actor, bool commanded) -: TypedAiPackage(makeDefaultOptions().withShouldCancelPreviousAi(!commanded)) -, mAlwaysFollow(true), mDuration(0), mRemainingDuration(0), mX(0), mY(0), mZ(0) -, mCellId(""), mActive(false), mFollowIndex(mFollowIndexCounter++) -{ - mTargetActorRefId = actor.getCellRef().getRefId(); - mTargetActorId = actor.getClass().getCreatureStats(actor).getActorId(); -} - -AiFollow::AiFollow(const ESM::AiSequence::AiFollow *follow) - : TypedAiPackage(makeDefaultOptions().withShouldCancelPreviousAi(!follow->mCommanded).withRepeat(follow->mRepeat)) - , mAlwaysFollow(follow->mAlwaysFollow) - , mDuration(follow->mData.mDuration) - , mRemainingDuration(follow->mRemainingDuration) - , mX(follow->mData.mX), mY(follow->mData.mY), mZ(follow->mData.mZ) - , mCellId(follow->mCellId), mActive(follow->mActive), mFollowIndex(mFollowIndexCounter++) -{ - mTargetActorRefId = follow->mTargetId; - mTargetActorId = follow->mTargetActorId; -} - -bool AiFollow::execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) -{ - const MWWorld::Ptr target = getTarget(); + int AiFollow::mFollowIndexCounter = 0; + + AiFollow::AiFollow(std::string_view actorId, float duration, float x, float y, float z, bool repeat) + : TypedAiPackage(repeat) + , mAlwaysFollow(false) + , mDuration(duration) + , mRemainingDuration(duration) + , mX(x) + , mY(y) + , mZ(z) + , mCellId("") + , mActive(false) + , mFollowIndex(mFollowIndexCounter++) + { + mTargetActorRefId = std::string(actorId); + } - // Target is not here right now, wait for it to return - // Really we should be checking whether the target is currently registered with the MechanicsManager - if (target == MWWorld::Ptr() || !target.getRefData().getCount() || !target.getRefData().isEnabled()) - return false; + AiFollow::AiFollow( + std::string_view actorId, std::string_view cellId, float duration, float x, float y, float z, bool repeat) + : TypedAiPackage(repeat) + , mAlwaysFollow(false) + , mDuration(duration) + , mRemainingDuration(duration) + , mX(x) + , mY(y) + , mZ(z) + , mCellId(cellId) + , mActive(false) + , mFollowIndex(mFollowIndexCounter++) + { + mTargetActorRefId = std::string(actorId); + } - actor.getClass().getCreatureStats(actor).setDrawState(DrawState::Nothing); + AiFollow::AiFollow(const MWWorld::Ptr& actor, bool commanded) + : TypedAiPackage(makeDefaultOptions().withShouldCancelPreviousAi(!commanded)) + , mAlwaysFollow(true) + , mDuration(0) + , mRemainingDuration(0) + , mX(0) + , mY(0) + , mZ(0) + , mCellId("") + , mActive(false) + , mFollowIndex(mFollowIndexCounter++) + { + mTargetActorRefId = actor.getCellRef().getRefId(); + mTargetActorId = actor.getClass().getCreatureStats(actor).getActorId(); + } - AiFollowStorage& storage = state.get(); + AiFollow::AiFollow(const ESM::AiSequence::AiFollow* follow) + : TypedAiPackage( + makeDefaultOptions().withShouldCancelPreviousAi(!follow->mCommanded).withRepeat(follow->mRepeat)) + , mAlwaysFollow(follow->mAlwaysFollow) + , mDuration(follow->mData.mDuration) + , mRemainingDuration(follow->mRemainingDuration) + , mX(follow->mData.mX) + , mY(follow->mData.mY) + , mZ(follow->mData.mZ) + , mCellId(follow->mCellId) + , mActive(follow->mActive) + , mFollowIndex(mFollowIndexCounter++) + { + mTargetActorRefId = follow->mTargetId; + mTargetActorId = follow->mTargetActorId; + } - bool& rotate = storage.mTurnActorToTarget; - if (rotate) + bool AiFollow::execute( + const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) { - if (zTurn(actor, storage.mTargetAngleRadians)) - rotate = false; + const MWWorld::Ptr target = getTarget(); - return false; - } + // Target is not here right now, wait for it to return + // Really we should be checking whether the target is currently registered with the MechanicsManager + if (target == MWWorld::Ptr() || !target.getRefData().getCount() || !target.getRefData().isEnabled()) + return false; - const osg::Vec3f actorPos(actor.getRefData().getPosition().asVec3()); - const osg::Vec3f targetPos(target.getRefData().getPosition().asVec3()); - const osg::Vec3f targetDir = targetPos - actorPos; + actor.getClass().getCreatureStats(actor).setDrawState(DrawState::Nothing); - // AiFollow requires the target to be in range and within sight for the initial activation - if (!mActive) - { - storage.mTimer -= duration; + AiFollowStorage& storage = state.get(); - if (storage.mTimer < 0) + bool& rotate = storage.mTurnActorToTarget; + if (rotate) { - if (targetDir.length2() < 500*500 && MWBase::Environment::get().getWorld()->getLOS(actor, target)) - mActive = true; - storage.mTimer = 0.5f; + if (zTurn(actor, storage.mTargetAngleRadians)) + rotate = false; + + return false; } - } - if (!mActive) - return false; - // In the original engine the first follower stays closer to the player than any subsequent followers. - // Followers beyond the first usually attempt to stand inside each other. - osg::Vec3f::value_type floatingDistance = 0; - auto followers = MWBase::Environment::get().getMechanicsManager()->getActorsFollowingByIndex(target); - if (followers.size() >= 2 && followers.cbegin()->first != mFollowIndex) - { - for(auto& follower : followers) + const osg::Vec3f actorPos(actor.getRefData().getPosition().asVec3()); + const osg::Vec3f targetPos(target.getRefData().getPosition().asVec3()); + const osg::Vec3f targetDir = targetPos - actorPos; + + // AiFollow requires the target to be in range and within sight for the initial activation + if (!mActive) { - auto halfExtent = getHalfExtents(follower.second); - if(halfExtent > floatingDistance) - floatingDistance = halfExtent; - } - floatingDistance += 128; - } - floatingDistance += getHalfExtents(target) + 64; - floatingDistance += getHalfExtents(actor) * 2; - short followDistance = static_cast(floatingDistance); + storage.mTimer -= duration; - if (!mAlwaysFollow) //Update if you only follow for a bit - { - //Check if we've run out of time - if (mDuration > 0) + if (storage.mTimer < 0) + { + if (targetDir.length2() < 500 * 500 && MWBase::Environment::get().getWorld()->getLOS(actor, target)) + mActive = true; + storage.mTimer = 0.5f; + } + } + if (!mActive) + return false; + + // In the original engine the first follower stays closer to the player than any subsequent followers. + // Followers beyond the first usually attempt to stand inside each other. + osg::Vec3f::value_type floatingDistance = 0; + auto followers = MWBase::Environment::get().getMechanicsManager()->getActorsFollowingByIndex(target); + if (followers.size() >= 2 && followers.cbegin()->first != mFollowIndex) { - mRemainingDuration -= ((duration*MWBase::Environment::get().getWorld()->getTimeScaleFactor()) / 3600); - if (mRemainingDuration <= 0) + for (auto& follower : followers) { - mRemainingDuration = mDuration; - return true; + auto halfExtent = getHalfExtents(follower.second); + if (halfExtent > floatingDistance) + floatingDistance = halfExtent; } + floatingDistance += 128; } + floatingDistance += getHalfExtents(target) + 64; + floatingDistance += getHalfExtents(actor) * 2; + short followDistance = static_cast(floatingDistance); - osg::Vec3f finalPos(mX, mY, mZ); - if ((actorPos-finalPos).length2() < followDistance*followDistance) //Close-ish to final position + if (!mAlwaysFollow) // Update if you only follow for a bit { - if (actor.getCell()->isExterior()) //Outside? + // Check if we've run out of time + if (mDuration > 0) { - if (mCellId == "") //No cell to travel to + mRemainingDuration -= ((duration * MWBase::Environment::get().getWorld()->getTimeScaleFactor()) / 3600); + if (mRemainingDuration <= 0) { mRemainingDuration = mDuration; return true; } } - else if (mCellId == actor.getCell()->getCell()->mName) //Cell to travel to + + osg::Vec3f finalPos(mX, mY, mZ); + if ((actorPos - finalPos).length2() < followDistance * followDistance) // Close-ish to final position { - mRemainingDuration = mDuration; - return true; + if (actor.getCell()->isExterior()) // Outside? + { + if (mCellId == "") // No cell to travel to + { + mRemainingDuration = mDuration; + return true; + } + } + else if (mCellId == actor.getCell()->getCell()->mName) // Cell to travel to + { + mRemainingDuration = mDuration; + return true; + } } } - } + short baseFollowDistance = followDistance; + short threshold = 30; // to avoid constant switching between moving/stopping + if (storage.mMoving) + followDistance -= threshold; + else + followDistance += threshold; - short baseFollowDistance = followDistance; - short threshold = 30; // to avoid constant switching between moving/stopping - if (storage.mMoving) - followDistance -= threshold; - else - followDistance += threshold; + if (targetDir.length2() <= followDistance * followDistance) + { + float faceAngleRadians = std::atan2(targetDir.x(), targetDir.y()); - if (targetDir.length2() <= followDistance * followDistance) - { - float faceAngleRadians = std::atan2(targetDir.x(), targetDir.y()); + if (!zTurn(actor, faceAngleRadians, osg::DegreesToRadians(45.f))) + { + storage.mTargetAngleRadians = faceAngleRadians; + storage.mTurnActorToTarget = true; + } - if (!zTurn(actor, faceAngleRadians, osg::DegreesToRadians(45.f))) + return false; + } + + storage.mMoving = !pathTo(actor, targetPos, duration, baseFollowDistance); // Go to the destination + + if (storage.mMoving) { - storage.mTargetAngleRadians = faceAngleRadians; - storage.mTurnActorToTarget = true; + // Check if you're far away + if (targetDir.length2() > 450 * 450) + actor.getClass().getCreatureStats(actor).setMovementFlag( + MWMechanics::CreatureStats::Flag_Run, true); // Make NPC run + else if (targetDir.length2() + < 325 * 325) // Have a bit of a dead zone, otherwise npc will constantly flip between running and not + // when right on the edge of the running threshold + actor.getClass().getCreatureStats(actor).setMovementFlag( + MWMechanics::CreatureStats::Flag_Run, false); // make NPC walk } return false; } - storage.mMoving = !pathTo(actor, targetPos, duration, baseFollowDistance); // Go to the destination - - if (storage.mMoving) + std::string AiFollow::getFollowedActor() { - //Check if you're far away - if (targetDir.length2() > 450 * 450) - actor.getClass().getCreatureStats(actor).setMovementFlag(MWMechanics::CreatureStats::Flag_Run, true); //Make NPC run - else if (targetDir.length2() < 325 * 325) //Have a bit of a dead zone, otherwise npc will constantly flip between running and not when right on the edge of the running threshold - actor.getClass().getCreatureStats(actor).setMovementFlag(MWMechanics::CreatureStats::Flag_Run, false); //make NPC walk + return mTargetActorRefId; } - return false; -} - -std::string AiFollow::getFollowedActor() -{ - return mTargetActorRefId; -} - -bool AiFollow::isCommanded() const -{ - return !mOptions.mShouldCancelPreviousAi; -} + bool AiFollow::isCommanded() const + { + return !mOptions.mShouldCancelPreviousAi; + } -void AiFollow::writeState(ESM::AiSequence::AiSequence &sequence) const -{ - auto follow = std::make_unique(); - follow->mData.mX = mX; - follow->mData.mY = mY; - follow->mData.mZ = mZ; - follow->mData.mDuration = mDuration; - follow->mTargetId = mTargetActorRefId; - follow->mTargetActorId = mTargetActorId; - follow->mRemainingDuration = mRemainingDuration; - follow->mCellId = mCellId; - follow->mAlwaysFollow = mAlwaysFollow; - follow->mCommanded = isCommanded(); - follow->mActive = mActive; - follow->mRepeat = getRepeat(); - - ESM::AiSequence::AiPackageContainer package; - package.mType = ESM::AiSequence::Ai_Follow; - package.mPackage = std::move(follow); - sequence.mPackages.push_back(std::move(package)); -} + void AiFollow::writeState(ESM::AiSequence::AiSequence& sequence) const + { + auto follow = std::make_unique(); + follow->mData.mX = mX; + follow->mData.mY = mY; + follow->mData.mZ = mZ; + follow->mData.mDuration = mDuration; + follow->mTargetId = mTargetActorRefId; + follow->mTargetActorId = mTargetActorId; + follow->mRemainingDuration = mRemainingDuration; + follow->mCellId = mCellId; + follow->mAlwaysFollow = mAlwaysFollow; + follow->mCommanded = isCommanded(); + follow->mActive = mActive; + follow->mRepeat = getRepeat(); + + ESM::AiSequence::AiPackageContainer package; + package.mType = ESM::AiSequence::Ai_Follow; + package.mPackage = std::move(follow); + sequence.mPackages.push_back(std::move(package)); + } -int AiFollow::getFollowIndex() const -{ - return mFollowIndex; -} + int AiFollow::getFollowIndex() const + { + return mFollowIndex; + } -void AiFollow::fastForward(const MWWorld::Ptr& actor, AiState &state) -{ - // Update duration counter if this package has a duration - if (mDuration > 0) - mRemainingDuration--; -} + void AiFollow::fastForward(const MWWorld::Ptr& actor, AiState& state) + { + // Update duration counter if this package has a duration + if (mDuration > 0) + mRemainingDuration--; + } } diff --git a/apps/openmw/mwmechanics/aifollow.hpp b/apps/openmw/mwmechanics/aifollow.hpp index c1969a7e27..6f20336efa 100644 --- a/apps/openmw/mwmechanics/aifollow.hpp +++ b/apps/openmw/mwmechanics/aifollow.hpp @@ -1,8 +1,8 @@ #ifndef GAME_MWMECHANICS_AIFOLLOW_H #define GAME_MWMECHANICS_AIFOLLOW_H -#include "typedaipackage.hpp" #include "aitemporarybase.hpp" +#include "typedaipackage.hpp" #include #include @@ -25,76 +25,80 @@ namespace MWMechanics float mTargetAngleRadians; bool mTurnActorToTarget; - AiFollowStorage() : - mTimer(0.f), - mMoving(false), - mTargetAngleRadians(0.f), - mTurnActorToTarget(false) - {} + AiFollowStorage() + : mTimer(0.f) + , mMoving(false) + , mTargetAngleRadians(0.f) + , mTurnActorToTarget(false) + { + } }; /// \brief AiPackage for an actor to follow another actor/the PC - /** The AI will follow the target until a condition (time, or position) are set. Both can be disabled to cause the actor to follow the other indefinitely - **/ + /** The AI will follow the target until a condition (time, or position) are set. Both can be disabled to cause the + *actor to follow the other indefinitely + **/ class AiFollow final : public TypedAiPackage { - public: - /// Follow Actor for duration or until you arrive at a world position - AiFollow(std::string_view actorId, float duration, float x, float y, float z, bool repeat); - /// Follow Actor for duration or until you arrive at a position in a cell - AiFollow(std::string_view actorId, std::string_view cellId, float duration, float x, float y, float z, bool repeat); - /// Follow Actor indefinitively - AiFollow(const MWWorld::Ptr& actor, bool commanded=false); - - AiFollow(const ESM::AiSequence::AiFollow* follow); - - bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override; - - static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Follow; } - - static constexpr Options makeDefaultOptions() - { - AiPackage::Options options; - options.mUseVariableSpeed = true; - options.mSideWithTarget = true; - options.mFollowTargetThroughDoors = true; - return options; - } - - /// Returns the actor being followed - std::string getFollowedActor(); - - void writeState (ESM::AiSequence::AiSequence& sequence) const override; - - bool isCommanded() const; - - int getFollowIndex() const; - - void fastForward(const MWWorld::Ptr& actor, AiState& state) override; - - osg::Vec3f getDestination() const override - { - MWWorld::Ptr target = getTarget(); - if (target.isEmpty()) - return osg::Vec3f(0, 0, 0); - - return target.getRefData().getPosition().asVec3(); - } - - private: - /// This will make the actor always follow. - /** Thus ignoring mDuration and mX,mY,mZ (used for summoned creatures). **/ - const bool mAlwaysFollow; - const float mDuration; // Hours - float mRemainingDuration; // Hours - const float mX; - const float mY; - const float mZ; - const std::string mCellId; - bool mActive; // have we spotted the target? - const int mFollowIndex; - - static int mFollowIndexCounter; + public: + /// Follow Actor for duration or until you arrive at a world position + AiFollow(std::string_view actorId, float duration, float x, float y, float z, bool repeat); + /// Follow Actor for duration or until you arrive at a position in a cell + AiFollow( + std::string_view actorId, std::string_view cellId, float duration, float x, float y, float z, bool repeat); + /// Follow Actor indefinitively + AiFollow(const MWWorld::Ptr& actor, bool commanded = false); + + AiFollow(const ESM::AiSequence::AiFollow* follow); + + bool execute(const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, + float duration) override; + + static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Follow; } + + static constexpr Options makeDefaultOptions() + { + AiPackage::Options options; + options.mUseVariableSpeed = true; + options.mSideWithTarget = true; + options.mFollowTargetThroughDoors = true; + return options; + } + + /// Returns the actor being followed + std::string getFollowedActor(); + + void writeState(ESM::AiSequence::AiSequence& sequence) const override; + + bool isCommanded() const; + + int getFollowIndex() const; + + void fastForward(const MWWorld::Ptr& actor, AiState& state) override; + + osg::Vec3f getDestination() const override + { + MWWorld::Ptr target = getTarget(); + if (target.isEmpty()) + return osg::Vec3f(0, 0, 0); + + return target.getRefData().getPosition().asVec3(); + } + + private: + /// This will make the actor always follow. + /** Thus ignoring mDuration and mX,mY,mZ (used for summoned creatures). **/ + const bool mAlwaysFollow; + const float mDuration; // Hours + float mRemainingDuration; // Hours + const float mX; + const float mY; + const float mZ; + const std::string mCellId; + bool mActive; // have we spotted the target? + const int mFollowIndex; + + static int mFollowIndexCounter; }; } #endif diff --git a/apps/openmw/mwmechanics/aipackage.cpp b/apps/openmw/mwmechanics/aipackage.cpp index edaa481f10..68dfaff7cf 100644 --- a/apps/openmw/mwmechanics/aipackage.cpp +++ b/apps/openmw/mwmechanics/aipackage.cpp @@ -1,25 +1,25 @@ #include "aipackage.hpp" +#include +#include #include #include -#include -#include #include #include -#include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" #include "../mwworld/action.hpp" -#include "../mwworld/class.hpp" #include "../mwworld/cellstore.hpp" +#include "../mwworld/class.hpp" #include "../mwworld/inventorystore.hpp" -#include "pathgrid.hpp" +#include "actorutil.hpp" #include "creaturestats.hpp" #include "movement.hpp" +#include "pathgrid.hpp" #include "steering.hpp" -#include "actorutil.hpp" #include @@ -27,7 +27,8 @@ namespace { float divOrMax(float dividend, float divisor) { - return divisor == 0 ? std::numeric_limits::max() * std::numeric_limits::epsilon() : dividend / divisor; + return divisor == 0 ? std::numeric_limits::max() * std::numeric_limits::epsilon() + : dividend / divisor; } float getPointTolerance(float speed, float duration, const osg::Vec3f& halfExtents) @@ -42,17 +43,17 @@ namespace } } -MWMechanics::AiPackage::AiPackage(AiPackageTypeId typeId, const Options& options) : - mTypeId(typeId), - mOptions(options), - mReaction(MWBase::Environment::get().getWorld()->getPrng()), - mTargetActorRefId(""), - mTargetActorId(-1), - mCachedTarget(), - mRotateOnTheRunChecks(0), - mIsShortcutting(false), - mShortcutProhibited(false), - mShortcutFailPos() +MWMechanics::AiPackage::AiPackage(AiPackageTypeId typeId, const Options& options) + : mTypeId(typeId) + , mOptions(options) + , mReaction(MWBase::Environment::get().getWorld()->getPrng()) + , mTargetActorRefId("") + , mTargetActorId(-1) + , mCachedTarget() + , mRotateOnTheRunChecks(0) + , mIsShortcutting(false) + , mShortcutProhibited(false) + , mShortcutFailPos() { } @@ -108,16 +109,17 @@ void MWMechanics::AiPackage::reset() } bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const osg::Vec3f& dest, float duration, - float destTolerance, float endTolerance, PathType pathType) + float destTolerance, float endTolerance, PathType pathType) { const Misc::TimerStatus timerStatus = mReaction.update(duration); - const osg::Vec3f position = actor.getRefData().getPosition().asVec3(); //position of the actor + const osg::Vec3f position = actor.getRefData().getPosition().asVec3(); // position of the actor MWBase::World* world = MWBase::Environment::get().getWorld(); const DetourNavigator::AgentBounds agentBounds = world->getPathfindingAgentBounds(actor); /// Stops the actor when it gets too close to a unloaded cell - //... At current time, this test is unnecessary. AI shuts down when actor is more than "actors processing range" setting value + //... At current time, this test is unnecessary. AI shuts down when actor is more than "actors processing range" + // setting value //... units from player, and exterior cells are 8192 units long and wide. //... But AI processing distance may increase in the future. if (isNearInactiveCell(position)) @@ -160,7 +162,8 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const osg::Vec3f& // get point just before dest auto pPointBeforeDest = mPathFinder.getPath().rbegin() + 1; - // if start point is closer to the target then last point of path (excluding target itself) then go straight on the target + // if start point is closer to the target then last point of path (excluding target itself) then go + // straight on the target if (distance(position, dest) <= distance(dest, *pPointBeforeDest)) { mPathFinder.clearPath(); @@ -169,23 +172,23 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const osg::Vec3f& } } - if (!mPathFinder.getPath().empty()) //Path has points in it + if (!mPathFinder.getPath().empty()) // Path has points in it { - const osg::Vec3f& lastPos = mPathFinder.getPath().back(); //Get the end of the proposed path + const osg::Vec3f& lastPos = mPathFinder.getPath().back(); // Get the end of the proposed path - if(distance(dest, lastPos) > 100) //End of the path is far from the destination - mPathFinder.addPointToPath(dest); //Adds the final destination to the path, to try to get to where you want to go + if (distance(dest, lastPos) > 100) // End of the path is far from the destination + mPathFinder.addPointToPath( + dest); // Adds the final destination to the path, to try to get to where you want to go } } } - const float pointTolerance = getPointTolerance(actor.getClass().getMaxSpeed(actor), duration, - world->getHalfExtents(actor)); + const float pointTolerance + = getPointTolerance(actor.getClass().getMaxSpeed(actor), duration, world->getHalfExtents(actor)); static const bool smoothMovement = Settings::Manager::getBool("smooth movement", "Game"); mPathFinder.update(position, pointTolerance, DEFAULT_TOLERANCE, - /*shortenIfAlmostStraight=*/smoothMovement, actorCanMoveByZ, - agentBounds, getNavigatorFlags(actor)); + /*shortenIfAlmostStraight=*/smoothMovement, actorCanMoveByZ, agentBounds, getNavigatorFlags(actor)); if (isDestReached || mPathFinder.checkPathCompleted()) // if path is finished { @@ -201,10 +204,12 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const osg::Vec3f& world->updateActorPath(actor, mPathFinder.getPath(), agentBounds, position, dest); if (mRotateOnTheRunChecks == 0 - || isReachableRotatingOnTheRun(actor, *mPathFinder.getPath().begin())) // to prevent circling around a path point + || isReachableRotatingOnTheRun( + actor, *mPathFinder.getPath().begin())) // to prevent circling around a path point { actor.getClass().getMovementSettings(actor).mPosition[1] = 1; // move to the target - if (mRotateOnTheRunChecks > 0) mRotateOnTheRunChecks--; + if (mRotateOnTheRunChecks > 0) + mRotateOnTheRunChecks--; } // turn to next path point by X,Z axes @@ -244,7 +249,8 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const osg::Vec3f& void MWMechanics::AiPackage::evadeObstacles(const MWWorld::Ptr& actor) { // check if stuck due to obstacles - if (!mObstacleCheck.isEvading()) return; + if (!mObstacleCheck.isEvading()) + return; // first check if obstacle is a door static float distance = MWBase::Environment::get().getWorld()->getMaxActivationDistance(); @@ -294,7 +300,7 @@ void MWMechanics::AiPackage::openDoors(const MWWorld::Ptr& actor) if (!isDoorOnTheWay(actor, door, mPathFinder.getPath().front())) return; - if ((door.getCellRef().getTrap().empty() && door.getCellRef().getLockLevel() <= 0 )) + if ((door.getCellRef().getTrap().empty() && door.getCellRef().getLockLevel() <= 0)) { world->activate(door, actor); return; @@ -304,7 +310,7 @@ void MWMechanics::AiPackage::openDoors(const MWWorld::Ptr& actor) if (keyId.empty()) return; - MWWorld::ContainerStore &invStore = actor.getClass().getContainerStore(actor); + MWWorld::ContainerStore& invStore = actor.getClass().getContainerStore(actor); MWWorld::Ptr keyPtr = invStore.search(keyId); if (!keyPtr.isEmpty()) @@ -312,31 +318,32 @@ void MWMechanics::AiPackage::openDoors(const MWWorld::Ptr& actor) } } -const MWMechanics::PathgridGraph& MWMechanics::AiPackage::getPathGridGraph(const MWWorld::CellStore *cell) +const MWMechanics::PathgridGraph& MWMechanics::AiPackage::getPathGridGraph(const MWWorld::CellStore* cell) { const ESM::CellId& id = cell->getCell()->getCellId(); // static cache is OK for now, pathgrids can never change during runtime - typedef std::map > CacheMap; + typedef std::map> CacheMap; static CacheMap cache; CacheMap::iterator found = cache.find(id); if (found == cache.end()) { - cache.insert(std::make_pair(id, std::make_unique(MWMechanics::PathgridGraph(cell)))); + cache.insert( + std::make_pair(id, std::make_unique(MWMechanics::PathgridGraph(cell)))); } return *cache[id].get(); } bool MWMechanics::AiPackage::shortcutPath(const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, - const MWWorld::Ptr& actor, bool *destInLOS, bool isPathClear) + const MWWorld::Ptr& actor, bool* destInLOS, bool isPathClear) { if (!mShortcutProhibited || (mShortcutFailPos - startPoint).length() >= PATHFIND_SHORTCUT_RETRY_DIST) { // check if target is clearly visible isPathClear = !MWBase::Environment::get().getWorld()->castRay( - startPoint.x(), startPoint.y(), startPoint.z(), - endPoint.x(), endPoint.y(), endPoint.z()); + startPoint.x(), startPoint.y(), startPoint.z(), endPoint.x(), endPoint.y(), endPoint.z()); - if (destInLOS != nullptr) *destInLOS = isPathClear; + if (destInLOS != nullptr) + *destInLOS = isPathClear; if (!isPathClear) return false; @@ -355,16 +362,18 @@ bool MWMechanics::AiPackage::shortcutPath(const osg::Vec3f& startPoint, const os return false; } -bool MWMechanics::AiPackage::checkWayIsClearForActor(const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, const MWWorld::Ptr& actor) +bool MWMechanics::AiPackage::checkWayIsClearForActor( + const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, const MWWorld::Ptr& actor) { if (canActorMoveByZAxis(actor)) return true; const float actorSpeed = actor.getClass().getMaxSpeed(actor); - const float maxAvoidDist = AI_REACTION_TIME * actorSpeed + actorSpeed / getAngularVelocity(actorSpeed) * 2; // *2 - for reliability + const float maxAvoidDist + = AI_REACTION_TIME * actorSpeed + actorSpeed / getAngularVelocity(actorSpeed) * 2; // *2 - for reliability const float distToTarget = osg::Vec2f(endPoint.x(), endPoint.y()).length(); - const float offsetXY = distToTarget > maxAvoidDist*1.5? maxAvoidDist : maxAvoidDist/2; + const float offsetXY = distToTarget > maxAvoidDist * 1.5 ? maxAvoidDist : maxAvoidDist / 2; // update shortcut prohibit state if (checkWayIsClear(startPoint, endPoint, offsetXY)) @@ -390,8 +399,7 @@ bool MWMechanics::AiPackage::checkWayIsClearForActor(const osg::Vec3f& startPoin bool MWMechanics::AiPackage::doesPathNeedRecalc(const osg::Vec3f& newDest, const MWWorld::Ptr& actor) const { - return mPathFinder.getPath().empty() - || getPathDistance(actor, mPathFinder.getPath().back(), newDest) > 10 + return mPathFinder.getPath().empty() || getPathDistance(actor, mPathFinder.getPath().back(), newDest) > 10 || mPathFinder.getPathCell() != actor.getCell(); } @@ -408,8 +416,8 @@ bool MWMechanics::AiPackage::isNearInactiveCell(osg::Vec3f position) const float distanceFromEdge = 200.0; float minThreshold = (-1.0f * ESM::Land::REAL_SIZE) + distanceFromEdge; float maxThreshold = (2.0f * ESM::Land::REAL_SIZE) - distanceFromEdge; - return (position.x() < minThreshold) || (maxThreshold < position.x()) - || (position.y() < minThreshold) || (maxThreshold < position.y()); + return (position.x() < minThreshold) || (maxThreshold < position.x()) || (position.y() < minThreshold) + || (maxThreshold < position.y()); } else { @@ -447,17 +455,17 @@ bool MWMechanics::AiPackage::isReachableRotatingOnTheRun(const MWWorld::Ptr& act DetourNavigator::Flags MWMechanics::AiPackage::getNavigatorFlags(const MWWorld::Ptr& actor) const { - static const bool allowToFollowOverWaterSurface = Settings::Manager::getBool("allow actors to follow over water surface", "Game"); + static const bool allowToFollowOverWaterSurface + = Settings::Manager::getBool("allow actors to follow over water surface", "Game"); const MWWorld::Class& actorClass = actor.getClass(); DetourNavigator::Flags result = DetourNavigator::Flag_none; if ((actorClass.isPureWaterCreature(actor) - || (getTypeId() != AiPackageTypeId::Wander - && ((allowToFollowOverWaterSurface && getTypeId() == AiPackageTypeId::Follow) - || actorClass.canSwim(actor) - || hasWaterWalking(actor))) - ) && actorClass.getSwimSpeed(actor) > 0) + || (getTypeId() != AiPackageTypeId::Wander + && ((allowToFollowOverWaterSurface && getTypeId() == AiPackageTypeId::Follow) + || actorClass.canSwim(actor) || hasWaterWalking(actor)))) + && actorClass.getSwimSpeed(actor) > 0) result |= DetourNavigator::Flag_swim; if (actorClass.canWalk(actor) && actor.getClass().getWalkSpeed(actor) > 0) @@ -479,18 +487,15 @@ DetourNavigator::AreaCosts MWMechanics::AiPackage::getAreaCosts(const MWWorld::P const DetourNavigator::Flags flags = getNavigatorFlags(actor); const MWWorld::Class& actorClass = actor.getClass(); - const float swimSpeed = (flags & DetourNavigator::Flag_swim) == 0 - ? 0.0f - : actorClass.getSwimSpeed(actor); + const float swimSpeed = (flags & DetourNavigator::Flag_swim) == 0 ? 0.0f : actorClass.getSwimSpeed(actor); - const float walkSpeed = [&] - { + const float walkSpeed = [&] { if ((flags & DetourNavigator::Flag_walk) == 0) return 0.0f; if (getTypeId() == AiPackageTypeId::Wander) return actorClass.getWalkSpeed(actor); return actorClass.getRunSpeed(actor); - } (); + }(); const float maxSpeed = std::max(swimSpeed, walkSpeed); @@ -513,7 +518,8 @@ osg::Vec3f MWMechanics::AiPackage::getNextPathPoint(const osg::Vec3f& destinatio return mPathFinder.getPath().empty() ? destination : mPathFinder.getPath().front(); } -float MWMechanics::AiPackage::getNextPathPointTolerance(float speed, float duration, const osg::Vec3f& halfExtents) const +float MWMechanics::AiPackage::getNextPathPointTolerance( + float speed, float duration, const osg::Vec3f& halfExtents) const { if (mPathFinder.getPathSize() <= 1) return std::max(DEFAULT_TOLERANCE, mLastDestinationTolerance); diff --git a/apps/openmw/mwmechanics/aipackage.hpp b/apps/openmw/mwmechanics/aipackage.hpp index 684ff3338d..97a56b9c5a 100644 --- a/apps/openmw/mwmechanics/aipackage.hpp +++ b/apps/openmw/mwmechanics/aipackage.hpp @@ -5,11 +5,11 @@ #include -#include "pathfinding.hpp" -#include "obstacle.hpp" #include "aipackagetypeid.hpp" -#include "aitimer.hpp" #include "aistatefwd.hpp" +#include "aitimer.hpp" +#include "obstacle.hpp" +#include "pathfinding.hpp" #include "../mwworld/ptr.hpp" @@ -22,7 +22,6 @@ namespace ESM } } - namespace MWMechanics { class CharacterController; @@ -31,150 +30,150 @@ namespace MWMechanics /// \brief Base class for AI packages class AiPackage { - public: - struct Options + public: + struct Options + { + unsigned int mPriority = 0; + bool mUseVariableSpeed = false; + bool mSideWithTarget = false; + bool mFollowTargetThroughDoors = false; + bool mCanCancel = true; + bool mShouldCancelPreviousAi = true; + bool mRepeat = false; + bool mAlwaysActive = false; + + constexpr Options withRepeat(bool value) { - unsigned int mPriority = 0; - bool mUseVariableSpeed = false; - bool mSideWithTarget = false; - bool mFollowTargetThroughDoors = false; - bool mCanCancel = true; - bool mShouldCancelPreviousAi = true; - bool mRepeat = false; - bool mAlwaysActive = false; - - constexpr Options withRepeat(bool value) - { - mRepeat = value; - return *this; - } - - constexpr Options withShouldCancelPreviousAi(bool value) - { - mShouldCancelPreviousAi = value; - return *this; - } - }; - - AiPackage(AiPackageTypeId typeId, const Options& options); - - virtual ~AiPackage() = default; - - static constexpr Options makeDefaultOptions() + mRepeat = value; + return *this; + } + + constexpr Options withShouldCancelPreviousAi(bool value) { - return Options{}; + mShouldCancelPreviousAi = value; + return *this; } + }; + + AiPackage(AiPackageTypeId typeId, const Options& options); - ///Clones the package - virtual std::unique_ptr clone() const = 0; + virtual ~AiPackage() = default; - /// Updates and runs the package (Should run every frame) - /// \return Package completed? - virtual bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) = 0; + static constexpr Options makeDefaultOptions() { return Options{}; } - /// Returns the TypeID of the AiPackage - /// \see enum TypeId - AiPackageTypeId getTypeId() const { return mTypeId; } + /// Clones the package + virtual std::unique_ptr clone() const = 0; - /// Higher number is higher priority (0 being the lowest) - unsigned int getPriority() const { return mOptions.mPriority; } + /// Updates and runs the package (Should run every frame) + /// \return Package completed? + virtual bool execute( + const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) + = 0; - /// Check if package use movement with variable speed - bool useVariableSpeed() const { return mOptions.mUseVariableSpeed; } + /// Returns the TypeID of the AiPackage + /// \see enum TypeId + AiPackageTypeId getTypeId() const { return mTypeId; } - virtual void writeState (ESM::AiSequence::AiSequence& sequence) const {} + /// Higher number is higher priority (0 being the lowest) + unsigned int getPriority() const { return mOptions.mPriority; } - /// Simulates the passing of time - virtual void fastForward(const MWWorld::Ptr& actor, AiState& state) {} + /// Check if package use movement with variable speed + bool useVariableSpeed() const { return mOptions.mUseVariableSpeed; } - /// Get the target actor the AI is targeted at (not applicable to all AI packages, default return empty Ptr) - virtual MWWorld::Ptr getTarget() const; + virtual void writeState(ESM::AiSequence::AiSequence& sequence) const {} - /// Get the destination point of the AI package (not applicable to all AI packages, default return (0, 0, 0)) - virtual osg::Vec3f getDestination(const MWWorld::Ptr& actor) const { return osg::Vec3f(0, 0, 0); }; + /// Simulates the passing of time + virtual void fastForward(const MWWorld::Ptr& actor, AiState& state) {} - /// Return true if having this AiPackage makes the actor side with the target in fights (default false) - bool sideWithTarget() const { return mOptions.mSideWithTarget; } + /// Get the target actor the AI is targeted at (not applicable to all AI packages, default return empty Ptr) + virtual MWWorld::Ptr getTarget() const; - /// Return true if the actor should follow the target through teleport doors (default false) - bool followTargetThroughDoors() const { return mOptions.mFollowTargetThroughDoors; } + /// Get the destination point of the AI package (not applicable to all AI packages, default return (0, 0, 0)) + virtual osg::Vec3f getDestination(const MWWorld::Ptr& actor) const { return osg::Vec3f(0, 0, 0); }; - /// Can this Ai package be canceled? (default true) - bool canCancel() const { return mOptions.mCanCancel; } + /// Return true if having this AiPackage makes the actor side with the target in fights (default false) + bool sideWithTarget() const { return mOptions.mSideWithTarget; } - /// Upon adding this Ai package, should the Ai Sequence attempt to cancel previous Ai packages (default true)? - bool shouldCancelPreviousAi() const { return mOptions.mShouldCancelPreviousAi; } + /// Return true if the actor should follow the target through teleport doors (default false) + bool followTargetThroughDoors() const { return mOptions.mFollowTargetThroughDoors; } - /// Return true if this package should repeat. - bool getRepeat() const { return mOptions.mRepeat; } + /// Can this Ai package be canceled? (default true) + bool canCancel() const { return mOptions.mCanCancel; } - virtual osg::Vec3f getDestination() const { return osg::Vec3f(0, 0, 0); } + /// Upon adding this Ai package, should the Ai Sequence attempt to cancel previous Ai packages (default true)? + bool shouldCancelPreviousAi() const { return mOptions.mShouldCancelPreviousAi; } - /// Return true if any loaded actor with this AI package must be active. - bool alwaysActive() const { return mOptions.mAlwaysActive; } + /// Return true if this package should repeat. + bool getRepeat() const { return mOptions.mRepeat; } - /// Reset pathfinding state - void reset(); + virtual osg::Vec3f getDestination() const { return osg::Vec3f(0, 0, 0); } - /// Return if actor's rotation speed is sufficient to rotate to the destination pathpoint on the run. Otherwise actor should rotate while standing. - static bool isReachableRotatingOnTheRun(const MWWorld::Ptr& actor, const osg::Vec3f& dest); + /// Return true if any loaded actor with this AI package must be active. + bool alwaysActive() const { return mOptions.mAlwaysActive; } - osg::Vec3f getNextPathPoint(const osg::Vec3f& destination) const; + /// Reset pathfinding state + void reset(); - float getNextPathPointTolerance(float speed, float duration, const osg::Vec3f& halfExtents) const; + /// Return if actor's rotation speed is sufficient to rotate to the destination pathpoint on the run. Otherwise + /// actor should rotate while standing. + static bool isReachableRotatingOnTheRun(const MWWorld::Ptr& actor, const osg::Vec3f& dest); - protected: - /// Handles path building and shortcutting with obstacles avoiding - /** \return If the actor has arrived at his destination **/ - bool pathTo(const MWWorld::Ptr& actor, const osg::Vec3f& dest, float duration, - float destTolerance = 0.0f, float endTolerance = 0.0f, PathType pathType = PathType::Full); + osg::Vec3f getNextPathPoint(const osg::Vec3f& destination) const; - /// Check if there aren't any obstacles along the path to make shortcut possible - /// If a shortcut is possible then path will be cleared and filled with the destination point. - /// \param destInLOS If not nullptr function will return ray cast check result - /// \return If can shortcut the path - bool shortcutPath(const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, const MWWorld::Ptr& actor, - bool *destInLOS, bool isPathClear); + float getNextPathPointTolerance(float speed, float duration, const osg::Vec3f& halfExtents) const; - /// Check if the way to the destination is clear, taking into account actor speed - bool checkWayIsClearForActor(const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, const MWWorld::Ptr& actor); + protected: + /// Handles path building and shortcutting with obstacles avoiding + /** \return If the actor has arrived at his destination **/ + bool pathTo(const MWWorld::Ptr& actor, const osg::Vec3f& dest, float duration, float destTolerance = 0.0f, + float endTolerance = 0.0f, PathType pathType = PathType::Full); - bool doesPathNeedRecalc(const osg::Vec3f& newDest, const MWWorld::Ptr& actor) const; + /// Check if there aren't any obstacles along the path to make shortcut possible + /// If a shortcut is possible then path will be cleared and filled with the destination point. + /// \param destInLOS If not nullptr function will return ray cast check result + /// \return If can shortcut the path + bool shortcutPath(const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, const MWWorld::Ptr& actor, + bool* destInLOS, bool isPathClear); - void evadeObstacles(const MWWorld::Ptr& actor); + /// Check if the way to the destination is clear, taking into account actor speed + bool checkWayIsClearForActor( + const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, const MWWorld::Ptr& actor); - void openDoors(const MWWorld::Ptr& actor); + bool doesPathNeedRecalc(const osg::Vec3f& newDest, const MWWorld::Ptr& actor) const; - const PathgridGraph& getPathGridGraph(const MWWorld::CellStore* cell); + void evadeObstacles(const MWWorld::Ptr& actor); - DetourNavigator::Flags getNavigatorFlags(const MWWorld::Ptr& actor) const; + void openDoors(const MWWorld::Ptr& actor); - DetourNavigator::AreaCosts getAreaCosts(const MWWorld::Ptr& actor) const; + const PathgridGraph& getPathGridGraph(const MWWorld::CellStore* cell); - const AiPackageTypeId mTypeId; - const Options mOptions; + DetourNavigator::Flags getNavigatorFlags(const MWWorld::Ptr& actor) const; - // TODO: all this does not belong here, move into temporary storage - PathFinder mPathFinder; - ObstacleCheck mObstacleCheck; + DetourNavigator::AreaCosts getAreaCosts(const MWWorld::Ptr& actor) const; - AiReactionTimer mReaction; + const AiPackageTypeId mTypeId; + const Options mOptions; - std::string mTargetActorRefId; - mutable int mTargetActorId; - mutable MWWorld::Ptr mCachedTarget; + // TODO: all this does not belong here, move into temporary storage + PathFinder mPathFinder; + ObstacleCheck mObstacleCheck; - short mRotateOnTheRunChecks; // attempts to check rotation to the pathpoint on the run possibility + AiReactionTimer mReaction; - bool mIsShortcutting; // if shortcutting at the moment - bool mShortcutProhibited; // shortcutting may be prohibited after unsuccessful attempt - osg::Vec3f mShortcutFailPos; // position of last shortcut fail - float mLastDestinationTolerance = 0; + std::string mTargetActorRefId; + mutable int mTargetActorId; + mutable MWWorld::Ptr mCachedTarget; - private: - bool isNearInactiveCell(osg::Vec3f position); + short mRotateOnTheRunChecks; // attempts to check rotation to the pathpoint on the run possibility + + bool mIsShortcutting; // if shortcutting at the moment + bool mShortcutProhibited; // shortcutting may be prohibited after unsuccessful attempt + osg::Vec3f mShortcutFailPos; // position of last shortcut fail + float mLastDestinationTolerance = 0; + + private: + bool isNearInactiveCell(osg::Vec3f position); }; } #endif - diff --git a/apps/openmw/mwmechanics/aipackagetypeid.hpp b/apps/openmw/mwmechanics/aipackagetypeid.hpp index 2b9c4fe9c9..3c1df5df51 100644 --- a/apps/openmw/mwmechanics/aipackagetypeid.hpp +++ b/apps/openmw/mwmechanics/aipackagetypeid.hpp @@ -3,7 +3,7 @@ namespace MWMechanics { - ///Enumerates the various AITypes available + /// Enumerates the various AITypes available enum class AiPackageTypeId { None = -1, diff --git a/apps/openmw/mwmechanics/aipursue.cpp b/apps/openmw/mwmechanics/aipursue.cpp index f48bd7ce51..fa4f901494 100644 --- a/apps/openmw/mwmechanics/aipursue.cpp +++ b/apps/openmw/mwmechanics/aipursue.cpp @@ -9,88 +9,93 @@ #include "../mwworld/class.hpp" -#include "movement.hpp" -#include "creaturestats.hpp" #include "actorutil.hpp" +#include "creaturestats.hpp" +#include "movement.hpp" namespace MWMechanics { -AiPursue::AiPursue(const MWWorld::Ptr& actor) -{ - mTargetActorId = actor.getClass().getCreatureStats(actor).getActorId(); -} + AiPursue::AiPursue(const MWWorld::Ptr& actor) + { + mTargetActorId = actor.getClass().getCreatureStats(actor).getActorId(); + } -AiPursue::AiPursue(const ESM::AiSequence::AiPursue *pursue) -{ - mTargetActorId = pursue->mTargetActorId; -} + AiPursue::AiPursue(const ESM::AiSequence::AiPursue* pursue) + { + mTargetActorId = pursue->mTargetActorId; + } -bool AiPursue::execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) -{ - if(actor.getClass().getCreatureStats(actor).isDead()) - return true; + bool AiPursue::execute( + const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) + { + if (actor.getClass().getCreatureStats(actor).isDead()) + return true; - const MWWorld::Ptr target = MWBase::Environment::get().getWorld()->searchPtrViaActorId(mTargetActorId); //The target to follow + const MWWorld::Ptr target + = MWBase::Environment::get().getWorld()->searchPtrViaActorId(mTargetActorId); // The target to follow - // Stop if the target doesn't exist - // Really we should be checking whether the target is currently registered with the MechanicsManager - if (target == MWWorld::Ptr() || !target.getRefData().getCount() || !target.getRefData().isEnabled()) - return true; + // Stop if the target doesn't exist + // Really we should be checking whether the target is currently registered with the MechanicsManager + if (target == MWWorld::Ptr() || !target.getRefData().getCount() || !target.getRefData().isEnabled()) + return true; - if (isTargetMagicallyHidden(target) && !MWBase::Environment::get().getMechanicsManager()->awarenessCheck(target, actor)) - return false; + if (isTargetMagicallyHidden(target) + && !MWBase::Environment::get().getMechanicsManager()->awarenessCheck(target, actor)) + return false; - if (target.getClass().getCreatureStats(target).isDead()) - return true; + if (target.getClass().getCreatureStats(target).isDead()) + return true; - actor.getClass().getCreatureStats(actor).setDrawState(DrawState::Nothing); + actor.getClass().getCreatureStats(actor).setDrawState(DrawState::Nothing); - //Set the target destination - const osg::Vec3f dest = target.getRefData().getPosition().asVec3(); - const osg::Vec3f actorPos = actor.getRefData().getPosition().asVec3(); + // Set the target destination + const osg::Vec3f dest = target.getRefData().getPosition().asVec3(); + const osg::Vec3f actorPos = actor.getRefData().getPosition().asVec3(); - const float pathTolerance = 100.f; + const float pathTolerance = 100.f; - // check the true distance in case the target is far away in Z-direction - bool reached = pathTo(actor, dest, duration, pathTolerance, (actorPos - dest).length(), PathType::Partial) && - std::abs(dest.z() - actorPos.z()) < pathTolerance; + // check the true distance in case the target is far away in Z-direction + bool reached = pathTo(actor, dest, duration, pathTolerance, (actorPos - dest).length(), PathType::Partial) + && std::abs(dest.z() - actorPos.z()) < pathTolerance; - if (reached) - { - if (!MWBase::Environment::get().getWorld()->getLOS(target, actor)) - return false; - MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Dialogue, actor); //Arrest player when reached - return true; - } + if (reached) + { + if (!MWBase::Environment::get().getWorld()->getLOS(target, actor)) + return false; + MWBase::Environment::get().getWindowManager()->pushGuiMode( + MWGui::GM_Dialogue, actor); // Arrest player when reached + return true; + } - actor.getClass().getCreatureStats(actor).setMovementFlag(MWMechanics::CreatureStats::Flag_Run, true); //Make NPC run + actor.getClass().getCreatureStats(actor).setMovementFlag( + MWMechanics::CreatureStats::Flag_Run, true); // Make NPC run - return false; -} + return false; + } -MWWorld::Ptr AiPursue::getTarget() const -{ - if (!mCachedTarget.isEmpty()) + MWWorld::Ptr AiPursue::getTarget() const { - if (mCachedTarget.getRefData().isDeleted() || !mCachedTarget.getRefData().isEnabled()) - mCachedTarget = MWWorld::Ptr(); - else - return mCachedTarget; + if (!mCachedTarget.isEmpty()) + { + if (mCachedTarget.getRefData().isDeleted() || !mCachedTarget.getRefData().isEnabled()) + mCachedTarget = MWWorld::Ptr(); + else + return mCachedTarget; + } + mCachedTarget = MWBase::Environment::get().getWorld()->searchPtrViaActorId(mTargetActorId); + return mCachedTarget; } - mCachedTarget = MWBase::Environment::get().getWorld()->searchPtrViaActorId(mTargetActorId); - return mCachedTarget; -} -void AiPursue::writeState(ESM::AiSequence::AiSequence &sequence) const -{ - auto pursue = std::make_unique(); - pursue->mTargetActorId = mTargetActorId; - - ESM::AiSequence::AiPackageContainer package; - package.mType = ESM::AiSequence::Ai_Pursue; - package.mPackage = std::move(pursue); - sequence.mPackages.push_back(std::move(package)); -} + void AiPursue::writeState(ESM::AiSequence::AiSequence& sequence) const + { + auto pursue = std::make_unique(); + pursue->mTargetActorId = mTargetActorId; + + ESM::AiSequence::AiPackageContainer package; + package.mType = ESM::AiSequence::Ai_Pursue; + package.mPackage = std::move(pursue); + sequence.mPackages.push_back(std::move(package)); + } } // namespace MWMechanics diff --git a/apps/openmw/mwmechanics/aipursue.hpp b/apps/openmw/mwmechanics/aipursue.hpp index 2fbc13b87c..39a8711ae5 100644 --- a/apps/openmw/mwmechanics/aipursue.hpp +++ b/apps/openmw/mwmechanics/aipursue.hpp @@ -5,10 +5,10 @@ namespace ESM { -namespace AiSequence -{ - struct AiPursue; -} + namespace AiSequence + { + struct AiPursue; + } } namespace MWMechanics @@ -19,28 +19,29 @@ namespace MWMechanics path is completed). **/ class AiPursue final : public TypedAiPackage { - public: - ///Constructor - /** \param actor Actor to pursue **/ - AiPursue(const MWWorld::Ptr& actor); + public: + /// Constructor + /** \param actor Actor to pursue **/ + AiPursue(const MWWorld::Ptr& actor); - AiPursue(const ESM::AiSequence::AiPursue* pursue); + AiPursue(const ESM::AiSequence::AiPursue* pursue); - bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override; + bool execute(const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, + float duration) override; - static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Pursue; } + static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Pursue; } - static constexpr Options makeDefaultOptions() - { - AiPackage::Options options; - options.mCanCancel = false; - options.mShouldCancelPreviousAi = false; - return options; - } + static constexpr Options makeDefaultOptions() + { + AiPackage::Options options; + options.mCanCancel = false; + options.mShouldCancelPreviousAi = false; + return options; + } - MWWorld::Ptr getTarget() const override; + MWWorld::Ptr getTarget() const override; - void writeState (ESM::AiSequence::AiSequence& sequence) const override; + void writeState(ESM::AiSequence::AiSequence& sequence) const override; }; } #endif diff --git a/apps/openmw/mwmechanics/aisequence.cpp b/apps/openmw/mwmechanics/aisequence.cpp index a9de4a5152..ded72c7406 100644 --- a/apps/openmw/mwmechanics/aisequence.cpp +++ b/apps/openmw/mwmechanics/aisequence.cpp @@ -1,560 +1,571 @@ #include "aisequence.hpp" -#include #include +#include #include #include -#include "aipackage.hpp" -#include "aistate.hpp" -#include "aiwander.hpp" -#include "aiescort.hpp" -#include "aitravel.hpp" -#include "aifollow.hpp" +#include "../mwworld/class.hpp" +#include "actorutil.hpp" #include "aiactivate.hpp" #include "aicombat.hpp" #include "aicombataction.hpp" +#include "aiescort.hpp" +#include "aifollow.hpp" +#include "aipackage.hpp" #include "aipursue.hpp" -#include "actorutil.hpp" -#include "../mwworld/class.hpp" +#include "aistate.hpp" +#include "aitravel.hpp" +#include "aiwander.hpp" namespace MWMechanics { -void AiSequence::copy (const AiSequence& sequence) -{ - for (const auto& package : sequence.mPackages) - mPackages.push_back(package->clone()); - - // We need to keep an AiWander storage, if present - it has a state machine. - // Not sure about another temporary storages - sequence.mAiState.copy(mAiState); + void AiSequence::copy(const AiSequence& sequence) + { + for (const auto& package : sequence.mPackages) + mPackages.push_back(package->clone()); - mNumCombatPackages = sequence.mNumCombatPackages; - mNumPursuitPackages = sequence.mNumPursuitPackages; -} + // We need to keep an AiWander storage, if present - it has a state machine. + // Not sure about another temporary storages + sequence.mAiState.copy(mAiState); -AiSequence::AiSequence() : mDone (false), mLastAiPackage(AiPackageTypeId::None) {} + mNumCombatPackages = sequence.mNumCombatPackages; + mNumPursuitPackages = sequence.mNumPursuitPackages; + } -AiSequence::AiSequence (const AiSequence& sequence) -{ - copy (sequence); - mDone = sequence.mDone; - mLastAiPackage = sequence.mLastAiPackage; -} + AiSequence::AiSequence() + : mDone(false) + , mLastAiPackage(AiPackageTypeId::None) + { + } -AiSequence& AiSequence::operator= (const AiSequence& sequence) -{ - if (this!=&sequence) + AiSequence::AiSequence(const AiSequence& sequence) { - clear(); - copy (sequence); + copy(sequence); mDone = sequence.mDone; mLastAiPackage = sequence.mLastAiPackage; } - return *this; -} + AiSequence& AiSequence::operator=(const AiSequence& sequence) + { + if (this != &sequence) + { + clear(); + copy(sequence); + mDone = sequence.mDone; + mLastAiPackage = sequence.mLastAiPackage; + } -AiSequence::~AiSequence() -{ - clear(); -} + return *this; + } -void AiSequence::onPackageAdded(const AiPackage& package) -{ - if (package.getTypeId() == AiPackageTypeId::Combat) - mNumCombatPackages++; - else if (package.getTypeId() == AiPackageTypeId::Pursue) - mNumPursuitPackages++; + AiSequence::~AiSequence() + { + clear(); + } - assert(mNumCombatPackages >= 0); - assert(mNumPursuitPackages >= 0); -} + void AiSequence::onPackageAdded(const AiPackage& package) + { + if (package.getTypeId() == AiPackageTypeId::Combat) + mNumCombatPackages++; + else if (package.getTypeId() == AiPackageTypeId::Pursue) + mNumPursuitPackages++; -void AiSequence::onPackageRemoved(const AiPackage& package) -{ - if (package.getTypeId() == AiPackageTypeId::Combat) - mNumCombatPackages--; - else if (package.getTypeId() == AiPackageTypeId::Pursue) - mNumPursuitPackages--; + assert(mNumCombatPackages >= 0); + assert(mNumPursuitPackages >= 0); + } - assert(mNumCombatPackages >= 0); - assert(mNumPursuitPackages >= 0); -} + void AiSequence::onPackageRemoved(const AiPackage& package) + { + if (package.getTypeId() == AiPackageTypeId::Combat) + mNumCombatPackages--; + else if (package.getTypeId() == AiPackageTypeId::Pursue) + mNumPursuitPackages--; -AiPackageTypeId AiSequence::getTypeId() const -{ - if (mPackages.empty()) - return AiPackageTypeId::None; + assert(mNumCombatPackages >= 0); + assert(mNumPursuitPackages >= 0); + } - return mPackages.front()->getTypeId(); -} + AiPackageTypeId AiSequence::getTypeId() const + { + if (mPackages.empty()) + return AiPackageTypeId::None; -bool AiSequence::getCombatTarget(MWWorld::Ptr &targetActor) const -{ - if (getTypeId() != AiPackageTypeId::Combat) - return false; + return mPackages.front()->getTypeId(); + } - targetActor = mPackages.front()->getTarget(); + bool AiSequence::getCombatTarget(MWWorld::Ptr& targetActor) const + { + if (getTypeId() != AiPackageTypeId::Combat) + return false; - return !targetActor.isEmpty(); -} + targetActor = mPackages.front()->getTarget(); -bool AiSequence::getCombatTargets(std::vector &targetActors) const -{ - for (auto it = mPackages.begin(); it != mPackages.end(); ++it) - { - if ((*it)->getTypeId() == MWMechanics::AiPackageTypeId::Combat) - targetActors.push_back((*it)->getTarget()); + return !targetActor.isEmpty(); } - return !targetActors.empty(); -} + bool AiSequence::getCombatTargets(std::vector& targetActors) const + { + for (auto it = mPackages.begin(); it != mPackages.end(); ++it) + { + if ((*it)->getTypeId() == MWMechanics::AiPackageTypeId::Combat) + targetActors.push_back((*it)->getTarget()); + } -AiPackages::iterator AiSequence::erase(AiPackages::iterator package) -{ - // Not sure if manually terminated packages should trigger mDone, probably not? - auto& ptr = *package; - onPackageRemoved(*ptr); + return !targetActors.empty(); + } - return mPackages.erase(package); -} + AiPackages::iterator AiSequence::erase(AiPackages::iterator package) + { + // Not sure if manually terminated packages should trigger mDone, probably not? + auto& ptr = *package; + onPackageRemoved(*ptr); -bool AiSequence::isInCombat() const -{ - return mNumCombatPackages > 0; -} + return mPackages.erase(package); + } -bool AiSequence::isInPursuit() const -{ - return mNumPursuitPackages > 0; -} + bool AiSequence::isInCombat() const + { + return mNumCombatPackages > 0; + } -bool AiSequence::isEngagedWithActor() const -{ - if (!isInCombat()) - return false; + bool AiSequence::isInPursuit() const + { + return mNumPursuitPackages > 0; + } - for (auto it = mPackages.begin(); it != mPackages.end(); ++it) + bool AiSequence::isEngagedWithActor() const { - if ((*it)->getTypeId() == AiPackageTypeId::Combat) + if (!isInCombat()) + return false; + + for (auto it = mPackages.begin(); it != mPackages.end(); ++it) { - MWWorld::Ptr target2 = (*it)->getTarget(); - if (!target2.isEmpty() && target2.getClass().isNpc()) - return true; + if ((*it)->getTypeId() == AiPackageTypeId::Combat) + { + MWWorld::Ptr target2 = (*it)->getTarget(); + if (!target2.isEmpty() && target2.getClass().isNpc()) + return true; + } } + return false; } - return false; -} -bool AiSequence::hasPackage(AiPackageTypeId typeId) const -{ - auto it = std::find_if(mPackages.begin(), mPackages.end(), [typeId](const auto& package) + bool AiSequence::hasPackage(AiPackageTypeId typeId) const { - return package->getTypeId() == typeId; - }); - return it != mPackages.end(); -} - -bool AiSequence::isInCombat(const MWWorld::Ptr &actor) const -{ - if (!isInCombat()) - return false; + auto it = std::find_if(mPackages.begin(), mPackages.end(), + [typeId](const auto& package) { return package->getTypeId() == typeId; }); + return it != mPackages.end(); + } - for (auto it = mPackages.begin(); it != mPackages.end(); ++it) + bool AiSequence::isInCombat(const MWWorld::Ptr& actor) const { - if ((*it)->getTypeId() == AiPackageTypeId::Combat) + if (!isInCombat()) + return false; + + for (auto it = mPackages.begin(); it != mPackages.end(); ++it) { - if ((*it)->getTarget() == actor) - return true; + if ((*it)->getTypeId() == AiPackageTypeId::Combat) + { + if ((*it)->getTarget() == actor) + return true; + } } + return false; } - return false; -} -void AiSequence::removePackagesById(AiPackageTypeId id) -{ - for (auto it = mPackages.begin(); it != mPackages.end(); ) + void AiSequence::removePackagesById(AiPackageTypeId id) { - if ((*it)->getTypeId() == id) + for (auto it = mPackages.begin(); it != mPackages.end();) { - it = erase(it); + if ((*it)->getTypeId() == id) + { + it = erase(it); + } + else + ++it; } - else - ++it; } -} -void AiSequence::stopCombat() -{ - removePackagesById(AiPackageTypeId::Combat); -} + void AiSequence::stopCombat() + { + removePackagesById(AiPackageTypeId::Combat); + } -void AiSequence::stopCombat(const std::vector& targets) -{ - for(auto it = mPackages.begin(); it != mPackages.end(); ) + void AiSequence::stopCombat(const std::vector& targets) { - if ((*it)->getTypeId() == AiPackageTypeId::Combat && std::find(targets.begin(), targets.end(), (*it)->getTarget()) != targets.end()) + for (auto it = mPackages.begin(); it != mPackages.end();) { - it = erase(it); + if ((*it)->getTypeId() == AiPackageTypeId::Combat + && std::find(targets.begin(), targets.end(), (*it)->getTarget()) != targets.end()) + { + it = erase(it); + } + else + ++it; } - else - ++it; } -} - -void AiSequence::stopPursuit() -{ - removePackagesById(AiPackageTypeId::Pursue); -} -bool AiSequence::isPackageDone() const -{ - return mDone; -} - -namespace -{ - bool isActualAiPackage(AiPackageTypeId packageTypeId) + void AiSequence::stopPursuit() { - return (packageTypeId >= AiPackageTypeId::Wander && - packageTypeId <= AiPackageTypeId::Activate); + removePackagesById(AiPackageTypeId::Pursue); } -} -void AiSequence::execute (const MWWorld::Ptr& actor, CharacterController& characterController, float duration, bool outOfRange) -{ - if (actor == getPlayer()) + bool AiSequence::isPackageDone() const { - // Players don't use this. - return; + return mDone; } - if (mPackages.empty()) + namespace { - mLastAiPackage = AiPackageTypeId::None; - return; + bool isActualAiPackage(AiPackageTypeId packageTypeId) + { + return (packageTypeId >= AiPackageTypeId::Wander && packageTypeId <= AiPackageTypeId::Activate); + } } - auto* package = mPackages.front().get(); - if (!package->alwaysActive() && outOfRange) - return; - - auto packageTypeId = package->getTypeId(); - // workaround ai packages not being handled as in the vanilla engine - if (isActualAiPackage(packageTypeId)) - mLastAiPackage = packageTypeId; - // if active package is combat one, choose nearest target - if (packageTypeId == AiPackageTypeId::Combat) + void AiSequence::execute( + const MWWorld::Ptr& actor, CharacterController& characterController, float duration, bool outOfRange) { - auto itActualCombat = mPackages.end(); + if (actor == getPlayer()) + { + // Players don't use this. + return; + } - float nearestDist = std::numeric_limits::max(); - osg::Vec3f vActorPos = actor.getRefData().getPosition().asVec3(); + if (mPackages.empty()) + { + mLastAiPackage = AiPackageTypeId::None; + return; + } - float bestRating = 0.f; + auto* package = mPackages.front().get(); + if (!package->alwaysActive() && outOfRange) + return; - for (auto it = mPackages.begin(); it != mPackages.end();) + auto packageTypeId = package->getTypeId(); + // workaround ai packages not being handled as in the vanilla engine + if (isActualAiPackage(packageTypeId)) + mLastAiPackage = packageTypeId; + // if active package is combat one, choose nearest target + if (packageTypeId == AiPackageTypeId::Combat) { - if ((*it)->getTypeId() != AiPackageTypeId::Combat) break; + auto itActualCombat = mPackages.end(); - MWWorld::Ptr target = (*it)->getTarget(); + float nearestDist = std::numeric_limits::max(); + osg::Vec3f vActorPos = actor.getRefData().getPosition().asVec3(); - // target disappeared (e.g. summoned creatures) - if (target.isEmpty()) - { - it = erase(it); - } - else + float bestRating = 0.f; + + for (auto it = mPackages.begin(); it != mPackages.end();) { - float rating = MWMechanics::getBestActionRating(actor, target); + if ((*it)->getTypeId() != AiPackageTypeId::Combat) + break; - const ESM::Position &targetPos = target.getRefData().getPosition(); + MWWorld::Ptr target = (*it)->getTarget(); - float distTo = (targetPos.asVec3() - vActorPos).length2(); + // target disappeared (e.g. summoned creatures) + if (target.isEmpty()) + { + it = erase(it); + } + else + { + float rating = MWMechanics::getBestActionRating(actor, target); - // Small threshold for changing target - if (it == mPackages.begin()) - distTo = std::max(0.f, distTo - 2500.f); + const ESM::Position& targetPos = target.getRefData().getPosition(); - // if a target has higher priority than current target or has same priority but closer - if (rating > bestRating || ((distTo < nearestDist) && rating == bestRating)) - { - nearestDist = distTo; - itActualCombat = it; - bestRating = rating; + float distTo = (targetPos.asVec3() - vActorPos).length2(); + + // Small threshold for changing target + if (it == mPackages.begin()) + distTo = std::max(0.f, distTo - 2500.f); + + // if a target has higher priority than current target or has same priority but closer + if (rating > bestRating || ((distTo < nearestDist) && rating == bestRating)) + { + nearestDist = distTo; + itActualCombat = it; + bestRating = rating; + } + ++it; } - ++it; } - } - if (mPackages.empty()) - return; + if (mPackages.empty()) + return; - if (nearestDist < std::numeric_limits::max() && mPackages.begin() != itActualCombat) - { - assert(itActualCombat != mPackages.end()); - // move combat package with nearest target to the front - std::rotate(mPackages.begin(), itActualCombat, std::next(itActualCombat)); - } + if (nearestDist < std::numeric_limits::max() && mPackages.begin() != itActualCombat) + { + assert(itActualCombat != mPackages.end()); + // move combat package with nearest target to the front + std::rotate(mPackages.begin(), itActualCombat, std::next(itActualCombat)); + } - package = mPackages.front().get(); - packageTypeId = package->getTypeId(); - } + package = mPackages.front().get(); + packageTypeId = package->getTypeId(); + } - try - { - if (package->execute(actor, characterController, mAiState, duration)) + try { - // Put repeating non-combat AI packages on the end of the stack so they can be used again - if (isActualAiPackage(packageTypeId) && package->getRepeat()) + if (package->execute(actor, characterController, mAiState, duration)) { - package->reset(); - mPackages.push_back(package->clone()); - } - - // The active package is typically the first entry, this is however not always the case - // e.g. AiPursue executing a dialogue script that uses startCombat adds a combat package to the front - // due to the priority. - auto activePackageIt = std::find_if(mPackages.begin(), mPackages.end(), [&](auto& entry) + // Put repeating non-combat AI packages on the end of the stack so they can be used again + if (isActualAiPackage(packageTypeId) && package->getRepeat()) { - return entry.get() == package; - }); + package->reset(); + mPackages.push_back(package->clone()); + } - erase(activePackageIt); + // The active package is typically the first entry, this is however not always the case + // e.g. AiPursue executing a dialogue script that uses startCombat adds a combat package to the front + // due to the priority. + auto activePackageIt = std::find_if( + mPackages.begin(), mPackages.end(), [&](auto& entry) { return entry.get() == package; }); - if (isActualAiPackage(packageTypeId)) - mDone = true; + erase(activePackageIt); + + if (isActualAiPackage(packageTypeId)) + mDone = true; + } + else + { + mDone = false; + } } - else + catch (std::exception& e) { - mDone = false; + Log(Debug::Error) << "Error during AiSequence::execute: " << e.what(); } } - catch (std::exception& e) + + void AiSequence::clear() { - Log(Debug::Error) << "Error during AiSequence::execute: " << e.what(); + mPackages.clear(); + mNumCombatPackages = 0; + mNumPursuitPackages = 0; } -} -void AiSequence::clear() -{ - mPackages.clear(); - mNumCombatPackages = 0; - mNumPursuitPackages = 0; -} - -void AiSequence::stack (const AiPackage& package, const MWWorld::Ptr& actor, bool cancelOther) -{ - if (actor == getPlayer()) - throw std::runtime_error("Can't add AI packages to player"); - - // Stop combat when a non-combat AI package is added - if (isActualAiPackage(package.getTypeId())) - stopCombat(); - - // We should return a wandering actor back after combat, casting or pursuit. - // The same thing for actors without AI packages. - // Also there is no point to stack return packages. - const auto currentTypeId = getTypeId(); - const auto newTypeId = package.getTypeId(); - if (currentTypeId <= MWMechanics::AiPackageTypeId::Wander - && !hasPackage(MWMechanics::AiPackageTypeId::InternalTravel) - && (newTypeId <= MWMechanics::AiPackageTypeId::Combat - || newTypeId == MWMechanics::AiPackageTypeId::Pursue - || newTypeId == MWMechanics::AiPackageTypeId::Cast)) + void AiSequence::stack(const AiPackage& package, const MWWorld::Ptr& actor, bool cancelOther) { - osg::Vec3f dest; - if (currentTypeId == MWMechanics::AiPackageTypeId::Wander) + if (actor == getPlayer()) + throw std::runtime_error("Can't add AI packages to player"); + + // Stop combat when a non-combat AI package is added + if (isActualAiPackage(package.getTypeId())) + stopCombat(); + + // We should return a wandering actor back after combat, casting or pursuit. + // The same thing for actors without AI packages. + // Also there is no point to stack return packages. + const auto currentTypeId = getTypeId(); + const auto newTypeId = package.getTypeId(); + if (currentTypeId <= MWMechanics::AiPackageTypeId::Wander + && !hasPackage(MWMechanics::AiPackageTypeId::InternalTravel) + && (newTypeId <= MWMechanics::AiPackageTypeId::Combat || newTypeId == MWMechanics::AiPackageTypeId::Pursue + || newTypeId == MWMechanics::AiPackageTypeId::Cast)) { - dest = getActivePackage().getDestination(actor); - } - else - { - dest = actor.getRefData().getPosition().asVec3(); - } + osg::Vec3f dest; + if (currentTypeId == MWMechanics::AiPackageTypeId::Wander) + { + dest = getActivePackage().getDestination(actor); + } + else + { + dest = actor.getRefData().getPosition().asVec3(); + } - MWMechanics::AiInternalTravel travelPackage(dest.x(), dest.y(), dest.z()); - stack(travelPackage, actor, false); - } + MWMechanics::AiInternalTravel travelPackage(dest.x(), dest.y(), dest.z()); + stack(travelPackage, actor, false); + } - // remove previous packages if required - if (cancelOther && package.shouldCancelPreviousAi()) - { - for (auto it = mPackages.begin(); it != mPackages.end();) + // remove previous packages if required + if (cancelOther && package.shouldCancelPreviousAi()) { - if((*it)->canCancel()) + for (auto it = mPackages.begin(); it != mPackages.end();) { - it = erase(it); + if ((*it)->canCancel()) + { + it = erase(it); + } + else + ++it; } - else - ++it; } - } - // insert new package in correct place depending on priority - for (auto it = mPackages.begin(); it != mPackages.end(); ++it) - { - // We should override current AiCast package, if we try to add a new one. - if ((*it)->getTypeId() == MWMechanics::AiPackageTypeId::Cast && - package.getTypeId() == MWMechanics::AiPackageTypeId::Cast) + // insert new package in correct place depending on priority + for (auto it = mPackages.begin(); it != mPackages.end(); ++it) { - *it = package.clone(); - return; + // We should override current AiCast package, if we try to add a new one. + if ((*it)->getTypeId() == MWMechanics::AiPackageTypeId::Cast + && package.getTypeId() == MWMechanics::AiPackageTypeId::Cast) + { + *it = package.clone(); + return; + } + + if ((*it)->getPriority() <= package.getPriority()) + { + onPackageAdded(package); + mPackages.insert(it, package.clone()); + return; + } } - if((*it)->getPriority() <= package.getPriority()) + onPackageAdded(package); + mPackages.push_back(package.clone()); + + // Make sure that temporary storage is empty + if (cancelOther) { - onPackageAdded(package); - mPackages.insert(it, package.clone()); - return; + mAiState.moveIn(std::make_unique()); + mAiState.moveIn(std::make_unique()); + mAiState.moveIn(std::make_unique()); } } - onPackageAdded(package); - mPackages.push_back(package.clone()); - - // Make sure that temporary storage is empty - if (cancelOther) + bool MWMechanics::AiSequence::isEmpty() const { - mAiState.moveIn(std::make_unique()); - mAiState.moveIn(std::make_unique()); - mAiState.moveIn(std::make_unique()); + return mPackages.empty(); } -} -bool MWMechanics::AiSequence::isEmpty() const -{ - return mPackages.empty(); -} - -const AiPackage& MWMechanics::AiSequence::getActivePackage() const -{ - if(mPackages.empty()) - throw std::runtime_error(std::string("No AI Package!")); - return *mPackages.front(); -} + const AiPackage& MWMechanics::AiSequence::getActivePackage() const + { + if (mPackages.empty()) + throw std::runtime_error(std::string("No AI Package!")); + return *mPackages.front(); + } -void AiSequence::fill(const ESM::AIPackageList &list) -{ - for (const auto& esmPackage : list.mList) + void AiSequence::fill(const ESM::AIPackageList& list) { - std::unique_ptr package; - if (esmPackage.mType == ESM::AI_Wander) - { - ESM::AIWander data = esmPackage.mWander; - std::vector idles; - idles.reserve(8); - for (int i=0; i<8; ++i) - idles.push_back(data.mIdle[i]); - package = std::make_unique(data.mDistance, data.mDuration, data.mTimeOfDay, idles, data.mShouldRepeat != 0); - } - else if (esmPackage.mType == ESM::AI_Escort) - { - ESM::AITarget data = esmPackage.mTarget; - package = std::make_unique(data.mId.toStringView(), data.mDuration, data.mX, data.mY, data.mZ, data.mShouldRepeat != 0); - } - else if (esmPackage.mType == ESM::AI_Travel) + for (const auto& esmPackage : list.mList) { - ESM::AITravel data = esmPackage.mTravel; - package = std::make_unique(data.mX, data.mY, data.mZ, data.mShouldRepeat != 0); - } - else if (esmPackage.mType == ESM::AI_Activate) - { - ESM::AIActivate data = esmPackage.mActivate; - package = std::make_unique(data.mName.toStringView(), data.mShouldRepeat != 0); - } - else //if (esmPackage.mType == ESM::AI_Follow) - { - ESM::AITarget data = esmPackage.mTarget; - package = std::make_unique(data.mId.toStringView(), data.mDuration, data.mX, data.mY, data.mZ, data.mShouldRepeat != 0); - } + std::unique_ptr package; + if (esmPackage.mType == ESM::AI_Wander) + { + ESM::AIWander data = esmPackage.mWander; + std::vector idles; + idles.reserve(8); + for (int i = 0; i < 8; ++i) + idles.push_back(data.mIdle[i]); + package = std::make_unique( + data.mDistance, data.mDuration, data.mTimeOfDay, idles, data.mShouldRepeat != 0); + } + else if (esmPackage.mType == ESM::AI_Escort) + { + ESM::AITarget data = esmPackage.mTarget; + package = std::make_unique( + data.mId.toStringView(), data.mDuration, data.mX, data.mY, data.mZ, data.mShouldRepeat != 0); + } + else if (esmPackage.mType == ESM::AI_Travel) + { + ESM::AITravel data = esmPackage.mTravel; + package = std::make_unique(data.mX, data.mY, data.mZ, data.mShouldRepeat != 0); + } + else if (esmPackage.mType == ESM::AI_Activate) + { + ESM::AIActivate data = esmPackage.mActivate; + package = std::make_unique(data.mName.toStringView(), data.mShouldRepeat != 0); + } + else // if (esmPackage.mType == ESM::AI_Follow) + { + ESM::AITarget data = esmPackage.mTarget; + package = std::make_unique( + data.mId.toStringView(), data.mDuration, data.mX, data.mY, data.mZ, data.mShouldRepeat != 0); + } - onPackageAdded(*package); - mPackages.push_back(std::move(package)); + onPackageAdded(*package); + mPackages.push_back(std::move(package)); + } } -} -void AiSequence::writeState(ESM::AiSequence::AiSequence &sequence) const -{ - for (const auto& package : mPackages) - package->writeState(sequence); - - sequence.mLastAiPackage = static_cast(mLastAiPackage); -} + void AiSequence::writeState(ESM::AiSequence::AiSequence& sequence) const + { + for (const auto& package : mPackages) + package->writeState(sequence); -void AiSequence::readState(const ESM::AiSequence::AiSequence &sequence) -{ - if (!sequence.mPackages.empty()) - clear(); + sequence.mLastAiPackage = static_cast(mLastAiPackage); + } - // Load packages - for (auto& container : sequence.mPackages) + void AiSequence::readState(const ESM::AiSequence::AiSequence& sequence) { - std::unique_ptr package; - switch (container.mType) - { - case ESM::AiSequence::Ai_Wander: - { - package = std::make_unique(&static_cast(*container.mPackage)); - break; - } - case ESM::AiSequence::Ai_Travel: - { - const ESM::AiSequence::AiTravel& source = static_cast(*container.mPackage); - if (source.mHidden) - package = std::make_unique(&source); - else - package = std::make_unique(&source); - break; - } - case ESM::AiSequence::Ai_Escort: - { - package = std::make_unique(&static_cast(*container.mPackage)); - break; - } - case ESM::AiSequence::Ai_Follow: - { - package = std::make_unique(&static_cast(*container.mPackage)); - break; - } - case ESM::AiSequence::Ai_Activate: - { - package = std::make_unique(&static_cast(*container.mPackage)); - break; - } - case ESM::AiSequence::Ai_Combat: - { - package = std::make_unique(&static_cast(*container.mPackage)); - break; - } - case ESM::AiSequence::Ai_Pursue: + if (!sequence.mPackages.empty()) + clear(); + + // Load packages + for (auto& container : sequence.mPackages) { - package = std::make_unique(&static_cast(*container.mPackage)); - break; - } - default: - break; - } + std::unique_ptr package; + switch (container.mType) + { + case ESM::AiSequence::Ai_Wander: + { + package = std::make_unique( + &static_cast(*container.mPackage)); + break; + } + case ESM::AiSequence::Ai_Travel: + { + const ESM::AiSequence::AiTravel& source + = static_cast(*container.mPackage); + if (source.mHidden) + package = std::make_unique(&source); + else + package = std::make_unique(&source); + break; + } + case ESM::AiSequence::Ai_Escort: + { + package = std::make_unique( + &static_cast(*container.mPackage)); + break; + } + case ESM::AiSequence::Ai_Follow: + { + package = std::make_unique( + &static_cast(*container.mPackage)); + break; + } + case ESM::AiSequence::Ai_Activate: + { + package = std::make_unique( + &static_cast(*container.mPackage)); + break; + } + case ESM::AiSequence::Ai_Combat: + { + package = std::make_unique( + &static_cast(*container.mPackage)); + break; + } + case ESM::AiSequence::Ai_Pursue: + { + package = std::make_unique( + &static_cast(*container.mPackage)); + break; + } + default: + break; + } - if (!package.get()) - continue; + if (!package.get()) + continue; - onPackageAdded(*package); - mPackages.push_back(std::move(package)); - } + onPackageAdded(*package); + mPackages.push_back(std::move(package)); + } - mLastAiPackage = static_cast(sequence.mLastAiPackage); -} + mLastAiPackage = static_cast(sequence.mLastAiPackage); + } -void AiSequence::fastForward(const MWWorld::Ptr& actor) -{ - if (!mPackages.empty()) + void AiSequence::fastForward(const MWWorld::Ptr& actor) { - mPackages.front()->fastForward(actor, mAiState); + if (!mPackages.empty()) + { + mPackages.front()->fastForward(actor, mAiState); + } } -} } // namespace MWMechanics diff --git a/apps/openmw/mwmechanics/aisequence.hpp b/apps/openmw/mwmechanics/aisequence.hpp index e6f5a108c2..ab3cc11e2c 100644 --- a/apps/openmw/mwmechanics/aisequence.hpp +++ b/apps/openmw/mwmechanics/aisequence.hpp @@ -1,12 +1,12 @@ #ifndef GAME_MWMECHANICS_AISEQUENCE_H #define GAME_MWMECHANICS_AISEQUENCE_H +#include #include #include -#include -#include "aistate.hpp" #include "aipackagetypeid.hpp" +#include "aistate.hpp" #include @@ -34,142 +34,144 @@ namespace MWMechanics /** The top-most AI package is run each frame. When completed, it is removed from the stack. **/ class AiSequence { - ///AiPackages to run though - AiPackages mPackages; - - ///Finished with top AIPackage, set for one frame - bool mDone{}; + /// AiPackages to run though + AiPackages mPackages; - int mNumCombatPackages{}; - int mNumPursuitPackages{}; + /// Finished with top AIPackage, set for one frame + bool mDone{}; - ///Copy AiSequence - void copy (const AiSequence& sequence); + int mNumCombatPackages{}; + int mNumPursuitPackages{}; - /// The type of AI package that ran last - AiPackageTypeId mLastAiPackage; - AiState mAiState; + /// Copy AiSequence + void copy(const AiSequence& sequence); - void onPackageAdded(const AiPackage& package); - void onPackageRemoved(const AiPackage& package); + /// The type of AI package that ran last + AiPackageTypeId mLastAiPackage; + AiState mAiState; - AiPackages::iterator erase(AiPackages::iterator package); + void onPackageAdded(const AiPackage& package); + void onPackageRemoved(const AiPackage& package); - public: - ///Default constructor - AiSequence(); + AiPackages::iterator erase(AiPackages::iterator package); - /// Copy Constructor - AiSequence (const AiSequence& sequence); + public: + /// Default constructor + AiSequence(); - /// Assignment operator - AiSequence& operator= (const AiSequence& sequence); + /// Copy Constructor + AiSequence(const AiSequence& sequence); - virtual ~AiSequence(); + /// Assignment operator + AiSequence& operator=(const AiSequence& sequence); - /// Iterator may be invalidated by any function calls other than begin() or end(). - AiPackages::const_iterator begin() const { return mPackages.begin(); } - AiPackages::const_iterator end() const { return mPackages.end(); } + virtual ~AiSequence(); - /// Removes all packages controlled by the predicate. - template - void erasePackagesIf(const F&& pred) - { - mPackages.erase(std::remove_if(mPackages.begin(), mPackages.end(), [&](auto& entry) - { - const bool doRemove = pred(entry); - if (doRemove) - onPackageRemoved(*entry); - return doRemove; - }), mPackages.end()); - } + /// Iterator may be invalidated by any function calls other than begin() or end(). + AiPackages::const_iterator begin() const { return mPackages.begin(); } + AiPackages::const_iterator end() const { return mPackages.end(); } - /// Removes a single package controlled by the predicate. - template - void erasePackageIf(const F&& pred) - { - auto it = std::find_if(mPackages.begin(), mPackages.end(), pred); - if (it == mPackages.end()) - return; - erase(it); - } + /// Removes all packages controlled by the predicate. + template + void erasePackagesIf(const F&& pred) + { + mPackages.erase(std::remove_if(mPackages.begin(), mPackages.end(), + [&](auto& entry) { + const bool doRemove = pred(entry); + if (doRemove) + onPackageRemoved(*entry); + return doRemove; + }), + mPackages.end()); + } - /// Returns currently executing AiPackage type - /** \see enum class AiPackageTypeId **/ - AiPackageTypeId getTypeId() const; + /// Removes a single package controlled by the predicate. + template + void erasePackageIf(const F&& pred) + { + auto it = std::find_if(mPackages.begin(), mPackages.end(), pred); + if (it == mPackages.end()) + return; + erase(it); + } - /// Get the typeid of the Ai package that ran last - /** NOT the currently "active" Ai package that will be run in the next frame. - This difference is important when an Ai package has just finished and been removed. - \see enum class AiPackageTypeId **/ - AiPackageTypeId getLastRunTypeId() const { return mLastAiPackage; } + /// Returns currently executing AiPackage type + /** \see enum class AiPackageTypeId **/ + AiPackageTypeId getTypeId() const; - /// Return true and assign target if combat package is currently active, return false otherwise - bool getCombatTarget (MWWorld::Ptr &targetActor) const; + /// Get the typeid of the Ai package that ran last + /** NOT the currently "active" Ai package that will be run in the next frame. + This difference is important when an Ai package has just finished and been removed. + \see enum class AiPackageTypeId **/ + AiPackageTypeId getLastRunTypeId() const { return mLastAiPackage; } - /// Return true and assign targets for all combat packages, or return false if there are no combat packages - bool getCombatTargets(std::vector &targetActors) const; + /// Return true and assign target if combat package is currently active, return false otherwise + bool getCombatTarget(MWWorld::Ptr& targetActor) const; - /// Is there any combat package? - bool isInCombat () const; + /// Return true and assign targets for all combat packages, or return false if there are no combat packages + bool getCombatTargets(std::vector& targetActors) const; - /// Is there any pursuit package. - bool isInPursuit() const; + /// Is there any combat package? + bool isInCombat() const; - /// Removes all packages using the specified id. - void removePackagesById(AiPackageTypeId id); + /// Is there any pursuit package. + bool isInPursuit() const; - /// Are we in combat with any other actor, who's also engaging us? - bool isEngagedWithActor () const; + /// Removes all packages using the specified id. + void removePackagesById(AiPackageTypeId id); - /// Does this AI sequence have the given package type? - bool hasPackage(AiPackageTypeId typeId) const; + /// Are we in combat with any other actor, who's also engaging us? + bool isEngagedWithActor() const; - /// Are we in combat with this particular actor? - bool isInCombat (const MWWorld::Ptr& actor) const; + /// Does this AI sequence have the given package type? + bool hasPackage(AiPackageTypeId typeId) const; - bool canAddTarget(const ESM::Position& actorPos, float distToTarget) const; - ///< Function assumes that actor can have only 1 target apart player + /// Are we in combat with this particular actor? + bool isInCombat(const MWWorld::Ptr& actor) const; - /// Removes all combat packages until first non-combat or stack empty. - void stopCombat(); + bool canAddTarget(const ESM::Position& actorPos, float distToTarget) const; + ///< Function assumes that actor can have only 1 target apart player - /// Removes all combat packages with the given targets - void stopCombat(const std::vector& targets); + /// Removes all combat packages until first non-combat or stack empty. + void stopCombat(); - /// Has a package been completed during the last update? - bool isPackageDone() const; + /// Removes all combat packages with the given targets + void stopCombat(const std::vector& targets); - /// Removes all pursue packages until first non-pursue or stack empty. - void stopPursuit(); + /// Has a package been completed during the last update? + bool isPackageDone() const; - /// Execute current package, switching if needed. - void execute (const MWWorld::Ptr& actor, CharacterController& characterController, float duration, bool outOfRange=false); + /// Removes all pursue packages until first non-pursue or stack empty. + void stopPursuit(); - /// Simulate the passing of time using the currently active AI package - void fastForward(const MWWorld::Ptr &actor); + /// Execute current package, switching if needed. + void execute(const MWWorld::Ptr& actor, CharacterController& characterController, float duration, + bool outOfRange = false); - /// Remove all packages. - void clear(); + /// Simulate the passing of time using the currently active AI package + void fastForward(const MWWorld::Ptr& actor); - ///< Add \a package to the front of the sequence - /** Suspends current package - @param actor The actor that owns this AiSequence **/ - void stack (const AiPackage& package, const MWWorld::Ptr& actor, bool cancelOther=true); + /// Remove all packages. + void clear(); - /// Return the current active package. - /** If there is no active package, it will throw an exception **/ - const AiPackage& getActivePackage() const; + ///< Add \a package to the front of the sequence + /** Suspends current package + @param actor The actor that owns this AiSequence **/ + void stack(const AiPackage& package, const MWWorld::Ptr& actor, bool cancelOther = true); - /// Fills the AiSequence with packages - /** Typically used for loading from the ESM - \see ESM::AIPackageList **/ - void fill (const ESM::AIPackageList& list); + /// Return the current active package. + /** If there is no active package, it will throw an exception **/ + const AiPackage& getActivePackage() const; - bool isEmpty() const; + /// Fills the AiSequence with packages + /** Typically used for loading from the ESM + \see ESM::AIPackageList **/ + void fill(const ESM::AIPackageList& list); + + bool isEmpty() const; - void writeState (ESM::AiSequence::AiSequence& sequence) const; - void readState (const ESM::AiSequence::AiSequence& sequence); + void writeState(ESM::AiSequence::AiSequence& sequence) const; + void readState(const ESM::AiSequence::AiSequence& sequence); }; } diff --git a/apps/openmw/mwmechanics/aistate.hpp b/apps/openmw/mwmechanics/aistate.hpp index ca05c44b36..d79469a9a0 100644 --- a/apps/openmw/mwmechanics/aistate.hpp +++ b/apps/openmw/mwmechanics/aistate.hpp @@ -14,7 +14,7 @@ namespace MWMechanics * the stored object if it has the correct type or otherwise replaces * it with an object of the requested type. */ - template< class Base > + template class DerivedClassStorage { private: @@ -22,7 +22,7 @@ namespace MWMechanics public: /// \brief returns reference to stored object or deletes it and creates a fitting - template< class Derived > + template Derived& get() { Derived* result = dynamic_cast(mStorage.get()); @@ -34,11 +34,11 @@ namespace MWMechanics mStorage = std::move(storage); } - //return a reference to the (new allocated) object + // return a reference to the (new allocated) object return *result; } - template< class Derived > + template void copy(DerivedClassStorage& destination) const { Derived* result = dynamic_cast(mStorage.get()); @@ -46,8 +46,8 @@ namespace MWMechanics destination.store(*result); } - template< class Derived > - void store( const Derived& payload ) + template + void store(const Derived& payload) { mStorage = std::make_unique(payload); } diff --git a/apps/openmw/mwmechanics/aitimer.hpp b/apps/openmw/mwmechanics/aitimer.hpp index e4bc07e52d..d2e023f1c8 100644 --- a/apps/openmw/mwmechanics/aitimer.hpp +++ b/apps/openmw/mwmechanics/aitimer.hpp @@ -10,23 +10,22 @@ namespace MWMechanics class AiReactionTimer { - public: - static constexpr float sDeviation = 0.1f; + public: + static constexpr float sDeviation = 0.1f; - AiReactionTimer(Misc::Rng::Generator& prng) - : mPrng{ prng } - , mImpl{ AI_REACTION_TIME, sDeviation, Misc::Rng::deviate(0, sDeviation, prng) } - { - } + AiReactionTimer(Misc::Rng::Generator& prng) + : mPrng{ prng } + , mImpl{ AI_REACTION_TIME, sDeviation, Misc::Rng::deviate(0, sDeviation, prng) } + { + } - Misc::TimerStatus update(float duration) { return mImpl.update(duration, mPrng); } + Misc::TimerStatus update(float duration) { return mImpl.update(duration, mPrng); } - void reset() { mImpl.reset(Misc::Rng::deviate(0, sDeviation, mPrng)); } - - private: - Misc::Rng::Generator& mPrng; - Misc::DeviatingPeriodicTimer mImpl; + void reset() { mImpl.reset(Misc::Rng::deviate(0, sDeviation, mPrng)); } + private: + Misc::Rng::Generator& mPrng; + Misc::DeviatingPeriodicTimer mImpl; }; } diff --git a/apps/openmw/mwmechanics/aitravel.cpp b/apps/openmw/mwmechanics/aitravel.cpp index 71432a5537..0ebfe911d1 100644 --- a/apps/openmw/mwmechanics/aitravel.cpp +++ b/apps/openmw/mwmechanics/aitravel.cpp @@ -2,43 +2,54 @@ #include -#include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/world.hpp" -#include "../mwworld/class.hpp" #include "../mwworld/cellstore.hpp" +#include "../mwworld/class.hpp" -#include "movement.hpp" #include "creaturestats.hpp" +#include "movement.hpp" namespace { constexpr float TRAVEL_FINISH_TIME = 2.f; -bool isWithinMaxRange(const osg::Vec3f& pos1, const osg::Vec3f& pos2) -{ - // Maximum travel distance for vanilla compatibility. - // Was likely meant to prevent NPCs walking into non-loaded exterior cells, but for some reason is used in interior cells as well. - // We can make this configurable at some point, but the default *must* be the below value. Anything else will break shoddily-written content (*cough* MW *cough*) in bizarre ways. - return (pos1 - pos2).length2() <= 7168*7168; -} + bool isWithinMaxRange(const osg::Vec3f& pos1, const osg::Vec3f& pos2) + { + // Maximum travel distance for vanilla compatibility. + // Was likely meant to prevent NPCs walking into non-loaded exterior cells, but for some reason is used in + // interior cells as well. We can make this configurable at some point, but the default *must* be the below + // value. Anything else will break shoddily-written content (*cough* MW *cough*) in bizarre ways. + return (pos1 - pos2).length2() <= 7168 * 7168; + } } namespace MWMechanics { AiTravel::AiTravel(float x, float y, float z, bool repeat, AiTravel*) - : TypedAiPackage(repeat), mX(x), mY(y), mZ(z), mHidden(false), mDestinationTimer(TRAVEL_FINISH_TIME) + : TypedAiPackage(repeat) + , mX(x) + , mY(y) + , mZ(z) + , mHidden(false) + , mDestinationTimer(TRAVEL_FINISH_TIME) { } AiTravel::AiTravel(float x, float y, float z, AiInternalTravel* derived) - : TypedAiPackage(derived), mX(x), mY(y), mZ(z), mHidden(true), mDestinationTimer(TRAVEL_FINISH_TIME) + : TypedAiPackage(derived) + , mX(x) + , mY(y) + , mZ(z) + , mHidden(true) + , mDestinationTimer(TRAVEL_FINISH_TIME) { } @@ -47,21 +58,27 @@ namespace MWMechanics { } - AiTravel::AiTravel(const ESM::AiSequence::AiTravel *travel) - : TypedAiPackage(travel->mRepeat), mX(travel->mData.mX), mY(travel->mData.mY), mZ(travel->mData.mZ), mHidden(false) + AiTravel::AiTravel(const ESM::AiSequence::AiTravel* travel) + : TypedAiPackage(travel->mRepeat) + , mX(travel->mData.mX) + , mY(travel->mData.mY) + , mZ(travel->mData.mZ) + , mHidden(false) , mDestinationTimer(TRAVEL_FINISH_TIME) { // Hidden ESM::AiSequence::AiTravel package should be converted into MWMechanics::AiInternalTravel type assert(!travel->mHidden); } - bool AiTravel::execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) + bool AiTravel::execute( + const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) { MWBase::MechanicsManager* mechMgr = MWBase::Environment::get().getMechanicsManager(); auto& stats = actor.getClass().getCreatureStats(actor); - if (!stats.getMovementFlag(CreatureStats::Flag_ForceJump) && !stats.getMovementFlag(CreatureStats::Flag_ForceSneak) - && (mechMgr->isTurningToPlayer(actor) || mechMgr->getGreetingState(actor) == Greet_InProgress)) + if (!stats.getMovementFlag(CreatureStats::Flag_ForceJump) + && !stats.getMovementFlag(CreatureStats::Flag_ForceSneak) + && (mechMgr->isTurningToPlayer(actor) || mechMgr->getGreetingState(actor) == Greet_InProgress)) return false; const osg::Vec3f actorPos(actor.getRefData().getPosition().asVec3()); @@ -86,10 +103,12 @@ namespace MWMechanics // but Morrowind might stop the actor prematurely under unclear conditions. // Note Morrowind uses the halved eye level, but this is close enough. - float dist = distanceIgnoreZ(actorPos, targetPos) - MWBase::Environment::get().getWorld()->getHalfExtents(actor).z(); + float dist + = distanceIgnoreZ(actorPos, targetPos) - MWBase::Environment::get().getWorld()->getHalfExtents(actor).z(); const float endTolerance = std::max(64.f, actor.getClass().getCurrentSpeed(actor) * duration); - // Even if we have entered the threshold, we might have been pushed away. Reset the timer if we're currently too far. + // Even if we have entered the threshold, we might have been pushed away. Reset the timer if we're currently too + // far. if (dist > endTolerance) { mDestinationTimer = TRAVEL_FINISH_TIME; @@ -116,7 +135,7 @@ namespace MWMechanics reset(); } - void AiTravel::writeState(ESM::AiSequence::AiSequence &sequence) const + void AiTravel::writeState(ESM::AiSequence::AiSequence& sequence) const { auto travel = std::make_unique(); travel->mData.mX = mX; @@ -146,4 +165,3 @@ namespace MWMechanics return std::make_unique(*this); } } - diff --git a/apps/openmw/mwmechanics/aitravel.hpp b/apps/openmw/mwmechanics/aitravel.hpp index dde63b3aa4..d8e249d465 100644 --- a/apps/openmw/mwmechanics/aitravel.hpp +++ b/apps/openmw/mwmechanics/aitravel.hpp @@ -5,10 +5,10 @@ namespace ESM { -namespace AiSequence -{ - struct AiTravel; -} + namespace AiSequence + { + struct AiTravel; + } } namespace MWMechanics @@ -18,42 +18,43 @@ namespace MWMechanics /// \brief Causes the AI to travel to the specified point class AiTravel : public TypedAiPackage { - public: - AiTravel(float x, float y, float z, bool repeat, AiTravel* derived); + public: + AiTravel(float x, float y, float z, bool repeat, AiTravel* derived); - AiTravel(float x, float y, float z, AiInternalTravel* derived); + AiTravel(float x, float y, float z, AiInternalTravel* derived); - AiTravel(float x, float y, float z, bool repeat); + AiTravel(float x, float y, float z, bool repeat); - explicit AiTravel(const ESM::AiSequence::AiTravel* travel); + explicit AiTravel(const ESM::AiSequence::AiTravel* travel); - /// Simulates the passing of time - void fastForward(const MWWorld::Ptr& actor, AiState& state) override; + /// Simulates the passing of time + void fastForward(const MWWorld::Ptr& actor, AiState& state) override; - void writeState(ESM::AiSequence::AiSequence &sequence) const override; + void writeState(ESM::AiSequence::AiSequence& sequence) const override; - bool execute (const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override; + bool execute(const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, + float duration) override; - static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Travel; } + static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Travel; } - static constexpr Options makeDefaultOptions() - { - AiPackage::Options options; - options.mUseVariableSpeed = true; - options.mAlwaysActive = true; - return options; - } + static constexpr Options makeDefaultOptions() + { + AiPackage::Options options; + options.mUseVariableSpeed = true; + options.mAlwaysActive = true; + return options; + } - osg::Vec3f getDestination() const override { return osg::Vec3f(mX, mY, mZ); } + osg::Vec3f getDestination() const override { return osg::Vec3f(mX, mY, mZ); } - private: - const float mX; - const float mY; - const float mZ; + private: + const float mX; + const float mY; + const float mZ; - const bool mHidden; + const bool mHidden; - float mDestinationTimer; + float mDestinationTimer; }; struct AiInternalTravel final : public AiTravel diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index 05eff857e0..1aeab99767 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -5,25 +5,25 @@ #include #include -#include -#include #include +#include #include +#include -#include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/world.hpp" +#include "../mwworld/cellstore.hpp" #include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" -#include "../mwworld/cellstore.hpp" #include "../mwphysics/collisiontype.hpp" -#include "pathgrid.hpp" +#include "actorutil.hpp" #include "creaturestats.hpp" #include "movement.hpp" -#include "actorutil.hpp" +#include "pathgrid.hpp" namespace MWMechanics { @@ -38,8 +38,7 @@ namespace MWMechanics static const std::size_t MAX_IDLE_SIZE = 8; - const std::string AiWander::sIdleSelectToGroupName[GroupIndex_MaxIdle - GroupIndex_MinIdle + 1] = - { + const std::string AiWander::sIdleSelectToGroupName[GroupIndex_MaxIdle - GroupIndex_MinIdle + 1] = { std::string("idle2"), std::string("idle3"), std::string("idle4"), @@ -68,23 +67,20 @@ namespace MWMechanics return position + osg::Vec3f(distance, 0.0, 0.0) * rotation; } - bool isDestinationHidden(const MWWorld::ConstPtr &actor, const osg::Vec3f& destination) + bool isDestinationHidden(const MWWorld::ConstPtr& actor, const osg::Vec3f& destination) { const auto position = actor.getRefData().getPosition().asVec3(); const bool isWaterCreature = actor.getClass().isPureWaterCreature(actor); const bool isFlyingCreature = actor.getClass().isPureFlyingCreature(actor); - const osg::Vec3f halfExtents = MWBase::Environment::get().getWorld()->getPathfindingAgentBounds(actor).mHalfExtents; + const osg::Vec3f halfExtents + = MWBase::Environment::get().getWorld()->getPathfindingAgentBounds(actor).mHalfExtents; osg::Vec3f direction = destination - position; direction.normalize(); - const auto visibleDestination = ( - isWaterCreature || isFlyingCreature - ? destination - : destination + osg::Vec3f(0, 0, halfExtents.z()) - ) + direction * std::max(halfExtents.x(), std::max(halfExtents.y(), halfExtents.z())); - const int mask = MWPhysics::CollisionType_World - | MWPhysics::CollisionType_HeightMap - | MWPhysics::CollisionType_Door - | MWPhysics::CollisionType_Actor; + const auto visibleDestination + = (isWaterCreature || isFlyingCreature ? destination : destination + osg::Vec3f(0, 0, halfExtents.z())) + + direction * std::max(halfExtents.x(), std::max(halfExtents.y(), halfExtents.z())); + const int mask = MWPhysics::CollisionType_World | MWPhysics::CollisionType_HeightMap + | MWPhysics::CollisionType_Door | MWPhysics::CollisionType_Actor; return MWBase::Environment::get().getWorld()->castRay(position, visibleDestination, mask, actor); } @@ -109,29 +105,33 @@ namespace MWMechanics } - AiWanderStorage::AiWanderStorage() : - mReaction(MWBase::Environment::get().getWorld()->getPrng()), - mState(Wander_ChooseAction), - mIsWanderingManually(false), - mCanWanderAlongPathGrid(true), - mIdleAnimation(0), - mBadIdles(), - mPopulateAvailableNodes(true), - mAllowedNodes(), - mTrimCurrentNode(false), - mCheckIdlePositionTimer(0), - mStuckCount(0) + AiWanderStorage::AiWanderStorage() + : mReaction(MWBase::Environment::get().getWorld()->getPrng()) + , mState(Wander_ChooseAction) + , mIsWanderingManually(false) + , mCanWanderAlongPathGrid(true) + , mIdleAnimation(0) + , mBadIdles() + , mPopulateAvailableNodes(true) + , mAllowedNodes() + , mTrimCurrentNode(false) + , mCheckIdlePositionTimer(0) + , mStuckCount(0) { } - AiWander::AiWander(int distance, int duration, int timeOfDay, const std::vector& idle, bool repeat): - TypedAiPackage(repeat), - mDistance(std::max(0, distance)), - mDuration(std::max(0, duration)), - mRemainingDuration(duration), mTimeOfDay(timeOfDay), - mIdle(getInitialIdle(idle)), - mStoredInitialActorPosition(false), mInitialActorPosition(osg::Vec3f(0, 0, 0)), - mHasDestination(false), mDestination(osg::Vec3f(0, 0, 0)), mUsePathgrid(false) + AiWander::AiWander(int distance, int duration, int timeOfDay, const std::vector& idle, bool repeat) + : TypedAiPackage(repeat) + , mDistance(std::max(0, distance)) + , mDuration(std::max(0, duration)) + , mRemainingDuration(duration) + , mTimeOfDay(timeOfDay) + , mIdle(getInitialIdle(idle)) + , mStoredInitialActorPosition(false) + , mInitialActorPosition(osg::Vec3f(0, 0, 0)) + , mHasDestination(false) + , mDestination(osg::Vec3f(0, 0, 0)) + , mUsePathgrid(false) { } @@ -185,7 +185,8 @@ namespace MWMechanics * actors will enter combat (i.e. no longer wandering) and different pathfinding * will kick in. */ - bool AiWander::execute (const MWWorld::Ptr& actor, CharacterController& /*characterController*/, AiState& state, float duration) + bool AiWander::execute( + const MWWorld::Ptr& actor, CharacterController& /*characterController*/, AiState& state, float duration) { MWMechanics::CreatureStats& cStats = actor.getClass().getCreatureStats(actor); if (cStats.isDead() || cStats.getHealth().getCurrent() <= 0) @@ -194,7 +195,7 @@ namespace MWMechanics // get or create temporary storage AiWanderStorage& storage = state.get(); - mRemainingDuration -= ((duration*MWBase::Environment::get().getWorld()->getTimeScaleFactor()) / 3600); + mRemainingDuration -= ((duration * MWBase::Environment::get().getWorld()->getTimeScaleFactor()) / 3600); cStats.setDrawState(DrawState::Nothing); cStats.setMovementFlag(CreatureStats::Flag_Run, false); @@ -207,8 +208,8 @@ namespace MWMechanics { if (mUsePathgrid) { - mPathFinder.buildPathByPathgrid(pos.asVec3(), mDestination, actor.getCell(), - getPathGridGraph(actor.getCell())); + mPathFinder.buildPathByPathgrid( + pos.asVec3(), mDestination, actor.getCell(), getPathGridGraph(actor.getCell())); } else { @@ -223,7 +224,8 @@ namespace MWMechanics storage.setState(AiWanderStorage::Wander_Walking); } - if(!cStats.getMovementFlag(CreatureStats::Flag_ForceJump) && !cStats.getMovementFlag(CreatureStats::Flag_ForceSneak)) + if (!cStats.getMovementFlag(CreatureStats::Flag_ForceJump) + && !cStats.getMovementFlag(CreatureStats::Flag_ForceSneak)) { GreetingState greetingState = MWBase::Environment::get().getMechanicsManager()->getGreetingState(actor); if (greetingState == Greet_InProgress) @@ -254,7 +256,7 @@ namespace MWMechanics { stopWalking(actor); // Reset package so it can be used again - mRemainingDuration=mDuration; + mRemainingDuration = mDuration; return true; } @@ -271,9 +273,11 @@ namespace MWMechanics } auto& prng = MWBase::Environment::get().getWorld()->getPrng(); - if (canActorMoveByZAxis(actor) && mDistance > 0) { + if (canActorMoveByZAxis(actor) && mDistance > 0) + { // Typically want to idle for a short time before the next wander - if (Misc::Rng::rollDice(100, prng) >= 92 && storage.mState != AiWanderStorage::Wander_Walking) { + if (Misc::Rng::rollDice(100, prng) >= 92 && storage.mState != AiWanderStorage::Wander_Walking) + { wanderNearStart(actor, storage, mDistance); } @@ -281,26 +285,33 @@ namespace MWMechanics } // If the package has a wander distance but no pathgrid is available, // randomly idle or wander near spawn point - else if(storage.mAllowedNodes.empty() && mDistance > 0 && !storage.mIsWanderingManually) { + else if (storage.mAllowedNodes.empty() && mDistance > 0 && !storage.mIsWanderingManually) + { // Typically want to idle for a short time before the next wander - if (Misc::Rng::rollDice(100, prng) >= 96) { + if (Misc::Rng::rollDice(100, prng) >= 96) + { wanderNearStart(actor, storage, mDistance); - } else { + } + else + { storage.setState(AiWanderStorage::Wander_IdleNow); } - } else if (storage.mAllowedNodes.empty() && !storage.mIsWanderingManually) { + } + else if (storage.mAllowedNodes.empty() && !storage.mIsWanderingManually) + { storage.mCanWanderAlongPathGrid = false; } // If Wandering manually and hit an obstacle, stop - if (storage.mIsWanderingManually && mObstacleCheck.isEvading()) { + if (storage.mIsWanderingManually && mObstacleCheck.isEvading()) + { completeManualWalking(actor, storage); } if (storage.mState == AiWanderStorage::Wander_MoveNow && storage.mCanWanderAlongPathGrid) { // Construct a new path if there isn't one - if(!mPathFinder.isPathConstructed()) + if (!mPathFinder.isPathConstructed()) { if (!storage.mAllowedNodes.empty()) { @@ -313,10 +324,8 @@ namespace MWMechanics completeManualWalking(actor, storage); } - if (storage.mIsWanderingManually - && storage.mState == AiWanderStorage::Wander_Walking - && (mPathFinder.getPathSize() == 0 - || isDestinationHidden(actor, mPathFinder.getPath().back()) + if (storage.mIsWanderingManually && storage.mState == AiWanderStorage::Wander_Walking + && (mPathFinder.getPathSize() == 0 || isDestinationHidden(actor, mPathFinder.getPath().back()) || isAreaOccupiedByOtherActor(actor, mPathFinder.getPath().back()))) completeManualWalking(actor, storage); @@ -340,7 +349,8 @@ namespace MWMechanics /* * Commands actor to walk to a random location near original spawn location. */ - void AiWander::wanderNearStart(const MWWorld::Ptr &actor, AiWanderStorage &storage, int wanderDistance) { + void AiWander::wanderNearStart(const MWWorld::Ptr& actor, AiWanderStorage& storage, int wanderDistance) + { const auto currentPosition = actor.getRefData().getPosition().asVec3(); std::size_t attempts = 10; // If a unit can't wander out of water, don't want to hang here @@ -353,19 +363,18 @@ namespace MWMechanics const auto areaCosts = getAreaCosts(actor); auto& prng = MWBase::Environment::get().getWorld()->getPrng(); - do { + do + { // Determine a random location within radius of original position const float wanderRadius = (0.2f + Misc::Rng::rollClosedProbability(prng) * 0.8f) * wanderDistance; if (!isWaterCreature && !isFlyingCreature) { // findRandomPointAroundCircle uses wanderDistance as limit for random and not as exact distance - const auto getRandom = []() - { - return Misc::Rng::rollProbability(MWBase::Environment::get().getWorld()->getPrng()); - }; - auto destination = DetourNavigator::findRandomPointAroundCircle(*navigator, agentBounds, - mInitialActorPosition, wanderRadius, navigatorFlags, getRandom); + const auto getRandom + = []() { return Misc::Rng::rollProbability(MWBase::Environment::get().getWorld()->getPrng()); }; + auto destination = DetourNavigator::findRandomPointAroundCircle( + *navigator, agentBounds, mInitialActorPosition, wanderRadius, navigatorFlags, getRandom); if (destination.has_value()) { osg::Vec3f direction = *destination - mInitialActorPosition; @@ -373,8 +382,8 @@ namespace MWMechanics { direction.normalize(); const osg::Vec3f adjustedDestination = mInitialActorPosition + direction * wanderRadius; - destination = DetourNavigator::raycast(*navigator, agentBounds, currentPosition, - adjustedDestination, navigatorFlags); + destination = DetourNavigator::raycast( + *navigator, agentBounds, currentPosition, adjustedDestination, navigatorFlags); if (destination.has_value() && (*destination - mInitialActorPosition).length() > wanderDistance) continue; } @@ -401,7 +410,7 @@ namespace MWMechanics mPathFinder.buildStraightPath(mDestination); else mPathFinder.buildPathByNavMesh(actor, currentPosition, mDestination, agentBounds, navigatorFlags, - areaCosts, endTolerance, PathType::Full); + areaCosts, endTolerance, PathType::Full); if (mPathFinder.isPathConstructed()) { @@ -417,14 +426,17 @@ namespace MWMechanics /* * Returns true if the position provided is above water. */ - bool AiWander::destinationIsAtWater(const MWWorld::Ptr &actor, const osg::Vec3f& destination) { - float heightToGroundOrWater = MWBase::Environment::get().getWorld()->getDistToNearestRayHit(destination, osg::Vec3f(0,0,-1), 1000.0, true); + bool AiWander::destinationIsAtWater(const MWWorld::Ptr& actor, const osg::Vec3f& destination) + { + float heightToGroundOrWater = MWBase::Environment::get().getWorld()->getDistToNearestRayHit( + destination, osg::Vec3f(0, 0, -1), 1000.0, true); osg::Vec3f positionBelowSurface = destination; positionBelowSurface[2] = positionBelowSurface[2] - heightToGroundOrWater - 1.0f; return MWBase::Environment::get().getWorld()->isUnderwater(actor.getCell(), positionBelowSurface); } - void AiWander::completeManualWalking(const MWWorld::Ptr &actor, AiWanderStorage &storage) { + void AiWander::completeManualWalking(const MWWorld::Ptr& actor, AiWanderStorage& storage) + { stopWalking(actor); mObstacleCheck.clear(); storage.setState(AiWanderStorage::Wander_IdleNow); @@ -447,7 +459,7 @@ namespace MWMechanics break; case AiWanderStorage::Wander_MoveNow: - break; // nothing to do + break; // nothing to do default: // should never get here @@ -463,7 +475,7 @@ namespace MWMechanics if (storage.mCheckIdlePositionTimer >= IDLE_POSITION_CHECK_INTERVAL && !isStationary()) { - storage.mCheckIdlePositionTimer = 0; // restart timer + storage.mCheckIdlePositionTimer = 0; // restart timer static float distance = MWBase::Environment::get().getWorld()->getMaxActivationDistance() * 1.6f; if (proximityToDoor(actor, distance) || !isNearAllowedNode(actor, storage, distance)) { @@ -501,7 +513,8 @@ namespace MWMechanics void AiWander::onWalkingStatePerFrameActions(const MWWorld::Ptr& actor, float duration, AiWanderStorage& storage) { // Is there no destination or are we there yet? - if ((!mPathFinder.isPathConstructed()) || pathTo(actor, osg::Vec3f(mPathFinder.getPath().back()), duration, DESTINATION_TOLERANCE)) + if ((!mPathFinder.isPathConstructed()) + || pathTo(actor, osg::Vec3f(mPathFinder.getPath().back()), duration, DESTINATION_TOLERANCE)) { stopWalking(actor); storage.setState(AiWanderStorage::Wander_ChooseAction); @@ -527,11 +540,11 @@ namespace MWMechanics storage.setState(AiWanderStorage::Wander_MoveNow); return; } - if(idleAnimation) + if (idleAnimation) { - if(std::find(storage.mBadIdles.begin(), storage.mBadIdles.end(), idleAnimation)==storage.mBadIdles.end()) + if (std::find(storage.mBadIdles.begin(), storage.mBadIdles.end(), idleAnimation) == storage.mBadIdles.end()) { - if(!playIdle(actor, idleAnimation)) + if (!playIdle(actor, idleAnimation)) { storage.mBadIdles.push_back(idleAnimation); storage.setState(AiWanderStorage::Wander_ChooseAction); @@ -548,8 +561,8 @@ namespace MWMechanics if (mUsePathgrid) { const auto agentBounds = MWBase::Environment::get().getWorld()->getPathfindingAgentBounds(actor); - mPathFinder.buildPathByNavMeshToNextPoint(actor, agentBounds, getNavigatorFlags(actor), - getAreaCosts(actor)); + mPathFinder.buildPathByNavMeshToNextPoint( + actor, agentBounds, getNavigatorFlags(actor), getAreaCosts(actor)); } if (mObstacleCheck.isEvading()) @@ -566,7 +579,7 @@ namespace MWMechanics storage.setState(AiWanderStorage::Wander_MoveNow); } - storage.mStuckCount++; // TODO: maybe no longer needed + storage.mStuckCount++; // TODO: maybe no longer needed } // if stuck for sufficiently long, act like current location was the destination @@ -579,9 +592,8 @@ namespace MWMechanics } } - - - void AiWander::setPathToAnAllowedNode(const MWWorld::Ptr& actor, AiWanderStorage& storage, const ESM::Position& actorPos) + void AiWander::setPathToAnAllowedNode( + const MWWorld::Ptr& actor, AiWanderStorage& storage, const ESM::Position& actorPos) { auto& prng = MWBase::Environment::get().getWorld()->getPrng(); unsigned int randNode = Misc::Rng::rollDice(storage.mAllowedNodes.size(), prng); @@ -601,7 +613,8 @@ namespace MWMechanics mDestination = destVec3f; mHasDestination = true; mUsePathgrid = true; - // Remove this node as an option and add back the previously used node (stops NPC from picking the same node): + // Remove this node as an option and add back the previously used node (stops NPC from picking the same + // node): ESM::Pathgrid::Point temp = storage.mAllowedNodes[randNode]; storage.mAllowedNodes.erase(storage.mAllowedNodes.begin() + randNode); // check if mCurrentNode was taken out of mAllowedNodes @@ -618,13 +631,12 @@ namespace MWMechanics storage.mAllowedNodes.erase(storage.mAllowedNodes.begin() + randNode); } - void AiWander::ToWorldCoordinates(ESM::Pathgrid::Point& point, const ESM::Cell * cell) + void AiWander::ToWorldCoordinates(ESM::Pathgrid::Point& point, const ESM::Cell* cell) { Misc::CoordinateConverter(cell).toWorld(point); } - void AiWander::trimAllowedNodes(std::vector& nodes, - const PathFinder& pathfinder) + void AiWander::trimAllowedNodes(std::vector& nodes, const PathFinder& pathfinder) { // TODO: how to add these back in once the door opens? // Idea: keep a list of detected closed doors (see aicombat.cpp) @@ -632,10 +644,10 @@ namespace MWMechanics // at the end of playing idle?) If the door is opened then re-calculate // allowed nodes starting from the spawn point. auto paths = pathfinder.getPath(); - while(paths.size() >= 2) + while (paths.size() >= 2) { const auto pt = paths.back(); - for(unsigned int j = 0; j < nodes.size(); j++) + for (unsigned int j = 0; j < nodes.size(); j++) { // FIXME: doesn't handle a door with the same X/Y // coordinates but with a different Z @@ -665,7 +677,8 @@ namespace MWMechanics } else { - Log(Debug::Verbose) << "Attempted to play out of range idle animation \"" << idleSelect << "\" for " << actor.getCellRef().getRefId(); + Log(Debug::Verbose) << "Attempted to play out of range idle animation \"" << idleSelect << "\" for " + << actor.getCellRef().getRefId(); return false; } } @@ -686,7 +699,8 @@ namespace MWMechanics int AiWander::getRandomIdle() const { MWBase::World* world = MWBase::Environment::get().getWorld(); - static const float fIdleChanceMultiplier = world->getStore().get().find("fIdleChanceMultiplier")->mValue.getFloat(); + static const float fIdleChanceMultiplier + = world->getStore().get().find("fIdleChanceMultiplier")->mValue.getFloat(); if (Misc::Rng::rollClosedProbability(world->getPrng()) > fIdleChanceMultiplier) return 0; @@ -705,7 +719,7 @@ namespace MWMechanics return newIdle; } - void AiWander::fastForward(const MWWorld::Ptr& actor, AiState &state) + void AiWander::fastForward(const MWWorld::Ptr& actor, AiState& state) { // Update duration counter mRemainingDuration--; @@ -725,7 +739,8 @@ namespace MWMechanics ESM::Pathgrid::Point worldDest = dest; ToWorldCoordinates(worldDest, actor.getCell()->getCell()); - bool isPathGridOccupied = MWBase::Environment::get().getMechanicsManager()->isAnyActorInRange(PathFinder::makeOsgVec3(worldDest), 60); + bool isPathGridOccupied = MWBase::Environment::get().getMechanicsManager()->isAnyActorInRange( + PathFinder::makeOsgVec3(worldDest), 60); // add offset only if the selected pathgrid is occupied by another actor if (isPathGridOccupied) @@ -753,11 +768,13 @@ namespace MWMechanics for (int j = 1; j <= 3; j++) { // move for 5-15% towards random neighboring node - dest = PathFinder::makePathgridPoint(PathFinder::makeOsgVec3(dest) + dir * (j * 5 * length / 100.f)); + dest + = PathFinder::makePathgridPoint(PathFinder::makeOsgVec3(dest) + dir * (j * 5 * length / 100.f)); worldDest = dest; ToWorldCoordinates(worldDest, actor.getCell()->getCell()); - isOccupied = MWBase::Environment::get().getMechanicsManager()->isAnyActorInRange(PathFinder::makeOsgVec3(worldDest), 60); + isOccupied = MWBase::Environment::get().getMechanicsManager()->isAnyActorInRange( + PathFinder::makeOsgVec3(worldDest), 60); if (!isOccupied) break; @@ -767,7 +784,7 @@ namespace MWMechanics break; // Will try an another neighboring node - points.erase(points.begin()+randomIndex); + points.erase(points.begin() + randomIndex); } // there is no free space, nowhere to move @@ -775,8 +792,8 @@ namespace MWMechanics return; } - // place above to prevent moving inside objects, e.g. stairs, because a vector between pathgrids can be underground. - // Adding 20 in adjustPosition() is not enough. + // place above to prevent moving inside objects, e.g. stairs, because a vector between pathgrids can be + // underground. Adding 20 in adjustPosition() is not enough. dest.mZ += 60; ToWorldCoordinates(dest, actor.getCell()->getCell()); @@ -788,10 +805,11 @@ namespace MWMechanics actor.getClass().adjustPosition(actor, false); } - void AiWander::getNeighbouringNodes(ESM::Pathgrid::Point dest, const MWWorld::CellStore* currentCell, ESM::Pathgrid::PointList& points) + void AiWander::getNeighbouringNodes( + ESM::Pathgrid::Point dest, const MWWorld::CellStore* currentCell, ESM::Pathgrid::PointList& points) { - const ESM::Pathgrid *pathgrid = - MWBase::Environment::get().getWorld()->getStore().get().search(*currentCell->getCell()); + const ESM::Pathgrid* pathgrid + = MWBase::Environment::get().getWorld()->getStore().get().search(*currentCell->getCell()); if (pathgrid == nullptr || pathgrid->mPoints.empty()) return; @@ -804,8 +822,8 @@ namespace MWMechanics void AiWander::getAllowedNodes(const MWWorld::Ptr& actor, const ESM::Cell* cell, AiWanderStorage& storage) { // infrequently used, therefore no benefit in caching it as a member - const ESM::Pathgrid * - pathgrid = MWBase::Environment::get().getWorld()->getStore().get().search(*cell); + const ESM::Pathgrid* pathgrid + = MWBase::Environment::get().getWorld()->getStore().get().search(*cell); const MWWorld::CellStore* cellStore = actor.getCell(); storage.mAllowedNodes.clear(); @@ -814,7 +832,7 @@ namespace MWMechanics // https://forum.openmw.org/viewtopic.php?t=1556 // http://www.fliggerty.com/phpBB3/viewtopic.php?f=30&t=5833 // Note: In order to wander, need at least two points. - if(!pathgrid || (pathgrid->mPoints.size() < 2)) + if (!pathgrid || (pathgrid->mPoints.size() < 2)) storage.mCanWanderAlongPathGrid = false; // A distance value passed into the constructor indicates how far the @@ -835,11 +853,11 @@ namespace MWMechanics // and if the point is connected to the closest current point // NOTE: mPoints and mAllowedNodes are in local coordinates int pointIndex = 0; - for(unsigned int counter = 0; counter < pathgrid->mPoints.size(); counter++) + for (unsigned int counter = 0; counter < pathgrid->mPoints.size(); counter++) { osg::Vec3f nodePos(PathFinder::makeOsgVec3(pathgrid->mPoints[counter])); - if((npcPos - nodePos).length2() <= mDistance * mDistance && - getPathGridGraph(cellStore).isPointConnected(closestPointIndex, counter)) + if ((npcPos - nodePos).length2() <= mDistance * mDistance + && getPathGridGraph(cellStore).isPointConnected(closestPointIndex, counter)) { storage.mAllowedNodes.push_back(pathgrid->mPoints[counter]); pointIndex = counter; @@ -849,7 +867,7 @@ namespace MWMechanics { AddNonPathGridAllowedPoints(npcPos, pathgrid, pointIndex, storage); } - if(!storage.mAllowedNodes.empty()) + if (!storage.mAllowedNodes.empty()) { SetCurrentNodeToClosestAllowedNode(npcPos, storage); } @@ -862,7 +880,8 @@ namespace MWMechanics // additional points for NPC to wander to are: // 1. NPC's initial location // 2. Partway along the path between the point and its connected points. - void AiWander::AddNonPathGridAllowedPoints(osg::Vec3f npcPos, const ESM::Pathgrid * pathGrid, int pointIndex, AiWanderStorage& storage) + void AiWander::AddNonPathGridAllowedPoints( + osg::Vec3f npcPos, const ESM::Pathgrid* pathGrid, int pointIndex, AiWanderStorage& storage) { storage.mAllowedNodes.push_back(PathFinder::makePathgridPoint(npcPos)); for (auto& edge : pathGrid->mEdges) @@ -874,7 +893,8 @@ namespace MWMechanics } } - void AiWander::AddPointBetweenPathGridPoints(const ESM::Pathgrid::Point& start, const ESM::Pathgrid::Point& end, AiWanderStorage& storage) + void AiWander::AddPointBetweenPathGridPoints( + const ESM::Pathgrid::Point& start, const ESM::Pathgrid::Point& end, AiWanderStorage& storage) { osg::Vec3f vectorStart = PathFinder::makeOsgVec3(start); osg::Vec3f delta = PathFinder::makeOsgVec3(end) - vectorStart; @@ -907,7 +927,7 @@ namespace MWMechanics storage.mAllowedNodes.erase(storage.mAllowedNodes.begin() + index); } - void AiWander::writeState(ESM::AiSequence::AiSequence &sequence) const + void AiWander::writeState(ESM::AiSequence::AiSequence& sequence) const { float remainingDuration; if (mRemainingDuration > 0 && mRemainingDuration < 24) @@ -920,8 +940,8 @@ namespace MWMechanics wander->mData.mDuration = mDuration; wander->mData.mTimeOfDay = mTimeOfDay; wander->mDurationData.mRemainingDuration = remainingDuration; - assert (mIdle.size() == 8); - for (int i=0; i<8; ++i) + assert(mIdle.size() == 8); + for (int i = 0; i < 8; ++i) wander->mData.mIdle[i] = mIdle[i]; wander->mData.mShouldRepeat = mOptions.mRepeat; wander->mStoredInitialActorPosition = mStoredInitialActorPosition; @@ -934,7 +954,7 @@ namespace MWMechanics sequence.mPackages.push_back(std::move(package)); } - AiWander::AiWander (const ESM::AiSequence::AiWander* wander) + AiWander::AiWander(const ESM::AiSequence::AiWander* wander) : TypedAiPackage(makeDefaultOptions().withRepeat(wander->mData.mShouldRepeat != 0)) , mDistance(std::max(static_cast(0), wander->mData.mDistance)) , mDuration(std::max(static_cast(0), wander->mData.mDuration)) diff --git a/apps/openmw/mwmechanics/aiwander.hpp b/apps/openmw/mwmechanics/aiwander.hpp index 96f1c474b3..35e5c06366 100644 --- a/apps/openmw/mwmechanics/aiwander.hpp +++ b/apps/openmw/mwmechanics/aiwander.hpp @@ -5,9 +5,9 @@ #include -#include "pathfinding.hpp" #include "aitemporarybase.hpp" #include "aitimer.hpp" +#include "pathfinding.hpp" namespace ESM { @@ -66,104 +66,109 @@ namespace MWMechanics /// \brief Causes the Actor to wander within a specified range class AiWander final : public TypedAiPackage { - public: - /// Constructor - /** \param distance Max distance the ACtor will wander - \param duration Time, in hours, that this package will be preformed - \param timeOfDay Currently unimplemented. Not functional in the original engine. - \param idle Chances of each idle to play (9 in total) - \param repeat Repeat wander or not **/ - AiWander(int distance, int duration, int timeOfDay, const std::vector& idle, bool repeat); - - explicit AiWander (const ESM::AiSequence::AiWander* wander); - - bool execute(const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, float duration) override; - - static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Wander; } - - static constexpr Options makeDefaultOptions() - { - AiPackage::Options options; - options.mUseVariableSpeed = true; - return options; - } - - void writeState(ESM::AiSequence::AiSequence &sequence) const override; - - void fastForward(const MWWorld::Ptr& actor, AiState& state) override; - - osg::Vec3f getDestination(const MWWorld::Ptr& actor) const override; + public: + /// Constructor + /** \param distance Max distance the ACtor will wander + \param duration Time, in hours, that this package will be preformed + \param timeOfDay Currently unimplemented. Not functional in the original engine. + \param idle Chances of each idle to play (9 in total) + \param repeat Repeat wander or not **/ + AiWander(int distance, int duration, int timeOfDay, const std::vector& idle, bool repeat); - osg::Vec3f getDestination() const override - { - if (!mHasDestination) - return osg::Vec3f(0, 0, 0); + explicit AiWander(const ESM::AiSequence::AiWander* wander); - return mDestination; - } + bool execute(const MWWorld::Ptr& actor, CharacterController& characterController, AiState& state, + float duration) override; - bool isStationary() const { return mDistance == 0; } + static constexpr AiPackageTypeId getTypeId() { return AiPackageTypeId::Wander; } - private: - void stopWalking(const MWWorld::Ptr& actor); - - /// Have the given actor play an idle animation - /// @return Success or error - bool playIdle(const MWWorld::Ptr& actor, unsigned short idleSelect); - bool checkIdle(const MWWorld::Ptr& actor, unsigned short idleSelect); - int getRandomIdle() const; - void setPathToAnAllowedNode(const MWWorld::Ptr& actor, AiWanderStorage& storage, const ESM::Position& actorPos); - void evadeObstacles(const MWWorld::Ptr& actor, AiWanderStorage& storage); - void doPerFrameActionsForState(const MWWorld::Ptr& actor, float duration, AiWanderStorage& storage); - void onIdleStatePerFrameActions(const MWWorld::Ptr& actor, float duration, AiWanderStorage& storage); - void onWalkingStatePerFrameActions(const MWWorld::Ptr& actor, float duration, AiWanderStorage& storage); - void onChooseActionStatePerFrameActions(const MWWorld::Ptr& actor, AiWanderStorage& storage); - bool reactionTimeActions(const MWWorld::Ptr& actor, AiWanderStorage& storage, ESM::Position& pos); - inline bool isPackageCompleted() const; - void wanderNearStart(const MWWorld::Ptr &actor, AiWanderStorage &storage, int wanderDistance); - bool destinationIsAtWater(const MWWorld::Ptr &actor, const osg::Vec3f& destination); - void completeManualWalking(const MWWorld::Ptr &actor, AiWanderStorage &storage); - bool isNearAllowedNode(const MWWorld::Ptr &actor, const AiWanderStorage& storage, float distance) const; - - const int mDistance; // how far the actor can wander from the spawn point - const int mDuration; - float mRemainingDuration; - const int mTimeOfDay; - const std::vector mIdle; + static constexpr Options makeDefaultOptions() + { + AiPackage::Options options; + options.mUseVariableSpeed = true; + return options; + } - bool mStoredInitialActorPosition; - osg::Vec3f mInitialActorPosition; // Note: an original engine does not reset coordinates even when actor changes a cell + void writeState(ESM::AiSequence::AiSequence& sequence) const override; - bool mHasDestination; - osg::Vec3f mDestination; - bool mUsePathgrid; + void fastForward(const MWWorld::Ptr& actor, AiState& state) override; - void getNeighbouringNodes(ESM::Pathgrid::Point dest, const MWWorld::CellStore* currentCell, ESM::Pathgrid::PointList& points); + osg::Vec3f getDestination(const MWWorld::Ptr& actor) const override; - void getAllowedNodes(const MWWorld::Ptr& actor, const ESM::Cell* cell, AiWanderStorage& storage); + osg::Vec3f getDestination() const override + { + if (!mHasDestination) + return osg::Vec3f(0, 0, 0); - void trimAllowedNodes(std::vector& nodes, const PathFinder& pathfinder); + return mDestination; + } - // constants for converting idleSelect values into groupNames - enum GroupIndex - { - GroupIndex_MinIdle = 2, - GroupIndex_MaxIdle = 9 - }; + bool isStationary() const { return mDistance == 0; } + + private: + void stopWalking(const MWWorld::Ptr& actor); + + /// Have the given actor play an idle animation + /// @return Success or error + bool playIdle(const MWWorld::Ptr& actor, unsigned short idleSelect); + bool checkIdle(const MWWorld::Ptr& actor, unsigned short idleSelect); + int getRandomIdle() const; + void setPathToAnAllowedNode(const MWWorld::Ptr& actor, AiWanderStorage& storage, const ESM::Position& actorPos); + void evadeObstacles(const MWWorld::Ptr& actor, AiWanderStorage& storage); + void doPerFrameActionsForState(const MWWorld::Ptr& actor, float duration, AiWanderStorage& storage); + void onIdleStatePerFrameActions(const MWWorld::Ptr& actor, float duration, AiWanderStorage& storage); + void onWalkingStatePerFrameActions(const MWWorld::Ptr& actor, float duration, AiWanderStorage& storage); + void onChooseActionStatePerFrameActions(const MWWorld::Ptr& actor, AiWanderStorage& storage); + bool reactionTimeActions(const MWWorld::Ptr& actor, AiWanderStorage& storage, ESM::Position& pos); + inline bool isPackageCompleted() const; + void wanderNearStart(const MWWorld::Ptr& actor, AiWanderStorage& storage, int wanderDistance); + bool destinationIsAtWater(const MWWorld::Ptr& actor, const osg::Vec3f& destination); + void completeManualWalking(const MWWorld::Ptr& actor, AiWanderStorage& storage); + bool isNearAllowedNode(const MWWorld::Ptr& actor, const AiWanderStorage& storage, float distance) const; + + const int mDistance; // how far the actor can wander from the spawn point + const int mDuration; + float mRemainingDuration; + const int mTimeOfDay; + const std::vector mIdle; + + bool mStoredInitialActorPosition; + osg::Vec3f + mInitialActorPosition; // Note: an original engine does not reset coordinates even when actor changes a cell + + bool mHasDestination; + osg::Vec3f mDestination; + bool mUsePathgrid; + + void getNeighbouringNodes( + ESM::Pathgrid::Point dest, const MWWorld::CellStore* currentCell, ESM::Pathgrid::PointList& points); + + void getAllowedNodes(const MWWorld::Ptr& actor, const ESM::Cell* cell, AiWanderStorage& storage); + + void trimAllowedNodes(std::vector& nodes, const PathFinder& pathfinder); + + // constants for converting idleSelect values into groupNames + enum GroupIndex + { + GroupIndex_MinIdle = 2, + GroupIndex_MaxIdle = 9 + }; - /// convert point from local (i.e. cell) to world coordinates - void ToWorldCoordinates(ESM::Pathgrid::Point& point, const ESM::Cell * cell); + /// convert point from local (i.e. cell) to world coordinates + void ToWorldCoordinates(ESM::Pathgrid::Point& point, const ESM::Cell* cell); - void SetCurrentNodeToClosestAllowedNode(const osg::Vec3f& npcPos, AiWanderStorage& storage); + void SetCurrentNodeToClosestAllowedNode(const osg::Vec3f& npcPos, AiWanderStorage& storage); - void AddNonPathGridAllowedPoints(osg::Vec3f npcPos, const ESM::Pathgrid * pathGrid, int pointIndex, AiWanderStorage& storage); + void AddNonPathGridAllowedPoints( + osg::Vec3f npcPos, const ESM::Pathgrid* pathGrid, int pointIndex, AiWanderStorage& storage); - void AddPointBetweenPathGridPoints(const ESM::Pathgrid::Point& start, const ESM::Pathgrid::Point& end, AiWanderStorage& storage); + void AddPointBetweenPathGridPoints( + const ESM::Pathgrid::Point& start, const ESM::Pathgrid::Point& end, AiWanderStorage& storage); - /// lookup table for converting idleSelect value to groupName - static const std::string sIdleSelectToGroupName[GroupIndex_MaxIdle - GroupIndex_MinIdle + 1]; + /// lookup table for converting idleSelect value to groupName + static const std::string sIdleSelectToGroupName[GroupIndex_MaxIdle - GroupIndex_MinIdle + 1]; - static int OffsetToPreventOvercrowding(); + static int OffsetToPreventOvercrowding(); }; } diff --git a/apps/openmw/mwmechanics/alchemy.cpp b/apps/openmw/mwmechanics/alchemy.cpp index d60eac15de..fdff3cf2ed 100644 --- a/apps/openmw/mwmechanics/alchemy.cpp +++ b/apps/openmw/mwmechanics/alchemy.cpp @@ -4,26 +4,26 @@ #include #include -#include #include +#include #include -#include #include #include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" -#include "../mwworld/esmstore.hpp" -#include "../mwworld/containerstore.hpp" -#include "../mwworld/class.hpp" #include "../mwworld/cellstore.hpp" +#include "../mwworld/class.hpp" +#include "../mwworld/containerstore.hpp" +#include "../mwworld/esmstore.hpp" -#include "magiceffects.hpp" #include "creaturestats.hpp" +#include "magiceffects.hpp" MWMechanics::Alchemy::Alchemy() : mValue(0) @@ -35,20 +35,20 @@ std::set MWMechanics::Alchemy::listEffects() const { std::map effects; - for (TIngredientsIterator iter (mIngredients.begin()); iter!=mIngredients.end(); ++iter) + for (TIngredientsIterator iter(mIngredients.begin()); iter != mIngredients.end(); ++iter) { if (!iter->isEmpty()) { - const MWWorld::LiveCellRef *ingredient = iter->get(); + const MWWorld::LiveCellRef* ingredient = iter->get(); std::set seenEffects; - for (int i=0; i<4; ++i) - if (ingredient->mBase->mData.mEffectID[i]!=-1) + for (int i = 0; i < 4; ++i) + if (ingredient->mBase->mData.mEffectID[i] != -1) { - EffectKey key ( - ingredient->mBase->mData.mEffectID[i], ingredient->mBase->mData.mSkills[i]!=-1 ? - ingredient->mBase->mData.mSkills[i] : ingredient->mBase->mData.mAttributes[i]); + EffectKey key(ingredient->mBase->mData.mEffectID[i], + ingredient->mBase->mData.mSkills[i] != -1 ? ingredient->mBase->mData.mSkills[i] + : ingredient->mBase->mData.mAttributes[i]); if (seenEffects.insert(key).second) ++effects[key]; @@ -58,14 +58,14 @@ std::set MWMechanics::Alchemy::listEffects() const std::set effects2; - for (std::map::const_iterator iter (effects.begin()); iter!=effects.end(); ++iter) - if (iter->second>1) - effects2.insert (iter->first); + for (std::map::const_iterator iter(effects.begin()); iter != effects.end(); ++iter) + if (iter->second > 1) + effects2.insert(iter->first); return effects2; } -void MWMechanics::Alchemy::applyTools (int flags, float& value) const +void MWMechanics::Alchemy::applyTools(int flags, float& value) const { bool magnitude = !(flags & ESM::MagicEffect::NoMagnitude); bool duration = !(flags & ESM::MagicEffect::NoDuration); @@ -84,9 +84,10 @@ void MWMechanics::Alchemy::applyTools (int flags, float& value) const else return; - float toolQuality = setup==1 || setup==2 ? mTools[tool].get()->mBase->mData.mQuality : 0; - float calcinatorQuality = setup==1 || setup==3 ? - mTools[ESM::Apparatus::Calcinator].get()->mBase->mData.mQuality : 0; + float toolQuality = setup == 1 || setup == 2 ? mTools[tool].get()->mBase->mData.mQuality : 0; + float calcinatorQuality = setup == 1 || setup == 3 + ? mTools[ESM::Apparatus::Calcinator].get()->mBase->mData.mQuality + : 0; float quality = 1; @@ -94,14 +95,14 @@ void MWMechanics::Alchemy::applyTools (int flags, float& value) const { case 1: - quality = negative ? 2 * toolQuality + 3 * calcinatorQuality : - (magnitude && duration ? - 2 * toolQuality + calcinatorQuality : 2/3.0f * (toolQuality + calcinatorQuality) + 0.5f); + quality = negative ? 2 * toolQuality + 3 * calcinatorQuality + : (magnitude && duration ? 2 * toolQuality + calcinatorQuality + : 2 / 3.0f * (toolQuality + calcinatorQuality) + 0.5f); break; case 2: - quality = negative ? 1+toolQuality : (magnitude && duration ? toolQuality : toolQuality + 0.5f); + quality = negative ? 1 + toolQuality : (magnitude && duration ? toolQuality : toolQuality + 0.5f); break; case 3: @@ -110,14 +111,14 @@ void MWMechanics::Alchemy::applyTools (int flags, float& value) const break; } - if (setup==3 || !negative) + if (setup == 3 || !negative) { value += quality; } else { - if (quality==0) - throw std::runtime_error ("invalid derived alchemy apparatus quality"); + if (quality == 0) + throw std::runtime_error("invalid derived alchemy apparatus quality"); value /= quality; } @@ -128,61 +129,81 @@ void MWMechanics::Alchemy::updateEffects() mEffects.clear(); mValue = 0; - if (countIngredients()<2 || mAlchemist.isEmpty() || mTools[ESM::Apparatus::MortarPestle].isEmpty()) + if (countIngredients() < 2 || mAlchemist.isEmpty() || mTools[ESM::Apparatus::MortarPestle].isEmpty()) return; // find effects - std::set effects (listEffects()); + std::set effects(listEffects()); // general alchemy factor float x = getAlchemyFactor(); x *= mTools[ESM::Apparatus::MortarPestle].get()->mBase->mData.mQuality; - x *= MWBase::Environment::get().getWorld()->getStore().get().find ("fPotionStrengthMult")->mValue.getFloat(); + x *= MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fPotionStrengthMult") + ->mValue.getFloat(); // value - mValue = static_cast ( - x * MWBase::Environment::get().getWorld()->getStore().get().find ("iAlchemyMod")->mValue.getFloat()); + mValue = static_cast(x + * MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("iAlchemyMod") + ->mValue.getFloat()); // build quantified effect list - for (std::set::const_iterator iter (effects.begin()); iter!=effects.end(); ++iter) + for (std::set::const_iterator iter(effects.begin()); iter != effects.end(); ++iter) { - const ESM::MagicEffect *magicEffect = - MWBase::Environment::get().getWorld()->getStore().get().find (iter->mId); + const ESM::MagicEffect* magicEffect + = MWBase::Environment::get().getWorld()->getStore().get().find(iter->mId); - if (magicEffect->mData.mBaseCost<=0) + if (magicEffect->mData.mBaseCost <= 0) { const std::string os = "invalid base cost for magic effect " + std::to_string(iter->mId); - throw std::runtime_error (os); + throw std::runtime_error(os); } - float fPotionT1MagMul = - MWBase::Environment::get().getWorld()->getStore().get().find ("fPotionT1MagMult")->mValue.getFloat(); - - if (fPotionT1MagMul<=0) - throw std::runtime_error ("invalid gmst: fPotionT1MagMul"); - - float fPotionT1DurMult = - MWBase::Environment::get().getWorld()->getStore().get().find ("fPotionT1DurMult")->mValue.getFloat(); - - if (fPotionT1DurMult<=0) - throw std::runtime_error ("invalid gmst: fPotionT1DurMult"); - - float magnitude = (magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude) ? - 1.0f : (x / fPotionT1MagMul) / magicEffect->mData.mBaseCost; - float duration = (magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration) ? - 1.0f : (x / fPotionT1DurMult) / magicEffect->mData.mBaseCost; + float fPotionT1MagMul = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fPotionT1MagMult") + ->mValue.getFloat(); + + if (fPotionT1MagMul <= 0) + throw std::runtime_error("invalid gmst: fPotionT1MagMul"); + + float fPotionT1DurMult = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fPotionT1DurMult") + ->mValue.getFloat(); + + if (fPotionT1DurMult <= 0) + throw std::runtime_error("invalid gmst: fPotionT1DurMult"); + + float magnitude = (magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude) + ? 1.0f + : (x / fPotionT1MagMul) / magicEffect->mData.mBaseCost; + float duration = (magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration) + ? 1.0f + : (x / fPotionT1DurMult) / magicEffect->mData.mBaseCost; if (!(magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude)) - applyTools (magicEffect->mData.mFlags, magnitude); + applyTools(magicEffect->mData.mFlags, magnitude); if (!(magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration)) - applyTools (magicEffect->mData.mFlags, duration); + applyTools(magicEffect->mData.mFlags, duration); duration = roundf(duration); magnitude = roundf(magnitude); - if (magnitude>0 && duration>0) + if (magnitude > 0 && duration > 0) { ESM::ENAMstruct effect; effect.mEffectID = iter->mId; @@ -201,15 +222,14 @@ void MWMechanics::Alchemy::updateEffects() effect.mDuration = static_cast(duration); effect.mMagnMin = effect.mMagnMax = static_cast(magnitude); - mEffects.push_back (effect); + mEffects.push_back(effect); } } } -const ESM::Potion *MWMechanics::Alchemy::getRecord(const ESM::Potion& toFind) const +const ESM::Potion* MWMechanics::Alchemy::getRecord(const ESM::Potion& toFind) const { - const MWWorld::Store &potions = - MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& potions = MWBase::Environment::get().getWorld()->getStore().get(); MWWorld::Store::iterator iter = potions.begin(); for (; iter != potions.end(); ++iter) @@ -217,11 +237,9 @@ const ESM::Potion *MWMechanics::Alchemy::getRecord(const ESM::Potion& toFind) co if (iter->mEffects.mList.size() != mEffects.size()) continue; - if (iter->mName != toFind.mName - || iter->mScript != toFind.mScript - || iter->mData.mWeight != toFind.mData.mWeight - || iter->mData.mValue != toFind.mData.mValue - || iter->mData.mAutoCalc != toFind.mData.mAutoCalc) + if (iter->mName != toFind.mName || iter->mScript != toFind.mScript + || iter->mData.mWeight != toFind.mData.mWeight || iter->mData.mValue != toFind.mData.mValue + || iter->mData.mAutoCalc != toFind.mData.mAutoCalc) continue; // Don't choose an ID that came from the content files, would have unintended side effects @@ -231,19 +249,15 @@ const ESM::Potion *MWMechanics::Alchemy::getRecord(const ESM::Potion& toFind) co bool mismatch = false; - for (int i=0; i (iter->mEffects.mList.size()); ++i) + for (int i = 0; i < static_cast(iter->mEffects.mList.size()); ++i) { const ESM::ENAMstruct& first = iter->mEffects.mList[i]; const ESM::ENAMstruct& second = mEffects[i]; - if (first.mEffectID!=second.mEffectID || - first.mArea!=second.mArea || - first.mRange!=second.mRange || - first.mSkill!=second.mSkill || - first.mAttribute!=second.mAttribute || - first.mMagnMin!=second.mMagnMin || - first.mMagnMax!=second.mMagnMax || - first.mDuration!=second.mDuration) + if (first.mEffectID != second.mEffectID || first.mArea != second.mArea || first.mRange != second.mRange + || first.mSkill != second.mSkill || first.mAttribute != second.mAttribute + || first.mMagnMin != second.mMagnMin || first.mMagnMax != second.mMagnMax + || first.mDuration != second.mDuration) { mismatch = true; break; @@ -259,25 +273,25 @@ const ESM::Potion *MWMechanics::Alchemy::getRecord(const ESM::Potion& toFind) co void MWMechanics::Alchemy::removeIngredients() { - for (TIngredientsContainer::iterator iter (mIngredients.begin()); iter!=mIngredients.end(); ++iter) + for (TIngredientsContainer::iterator iter(mIngredients.begin()); iter != mIngredients.end(); ++iter) if (!iter->isEmpty()) { iter->getContainerStore()->remove(*iter, 1, mAlchemist); - if (iter->getRefData().getCount()<1) + if (iter->getRefData().getCount() < 1) *iter = MWWorld::Ptr(); } updateEffects(); } -void MWMechanics::Alchemy::addPotion (const std::string& name) +void MWMechanics::Alchemy::addPotion(const std::string& name) { ESM::Potion newRecord; newRecord.mData.mWeight = 0; - for (TIngredientsIterator iter (beginIngredients()); iter!=endIngredients(); ++iter) + for (TIngredientsIterator iter(beginIngredients()); iter != endIngredients(); ++iter) if (!iter->isEmpty()) newRecord.mData.mWeight += iter->get()->mBase->mData.mWeight; @@ -291,42 +305,41 @@ void MWMechanics::Alchemy::addPotion (const std::string& name) auto& prng = MWBase::Environment::get().getWorld()->getPrng(); int index = Misc::Rng::rollDice(6, prng); - assert (index>=0 && index<6); + assert(index >= 0 && index < 6); - static const char *meshes[] = { "standard", "bargain", "cheap", "fresh", "exclusive", "quality" }; + static const char* meshes[] = { "standard", "bargain", "cheap", "fresh", "exclusive", "quality" }; - newRecord.mModel = "m\\misc_potion_" + std::string (meshes[index]) + "_01.nif"; - newRecord.mIcon = "m\\tx_potion_" + std::string (meshes[index]) + "_01.dds"; + newRecord.mModel = "m\\misc_potion_" + std::string(meshes[index]) + "_01.nif"; + newRecord.mIcon = "m\\tx_potion_" + std::string(meshes[index]) + "_01.dds"; newRecord.mEffects.mList = mEffects; const ESM::Potion* record = getRecord(newRecord); if (!record) - record = MWBase::Environment::get().getWorld()->createRecord (newRecord); + record = MWBase::Environment::get().getWorld()->createRecord(newRecord); - mAlchemist.getClass().getContainerStore (mAlchemist).add (record->mId, 1, mAlchemist); + mAlchemist.getClass().getContainerStore(mAlchemist).add(record->mId, 1, mAlchemist); } void MWMechanics::Alchemy::increaseSkill() { - mAlchemist.getClass().skillUsageSucceeded (mAlchemist, ESM::Skill::Alchemy, 0); + mAlchemist.getClass().skillUsageSucceeded(mAlchemist, ESM::Skill::Alchemy, 0); } float MWMechanics::Alchemy::getAlchemyFactor() const { - const CreatureStats& creatureStats = mAlchemist.getClass().getCreatureStats (mAlchemist); + const CreatureStats& creatureStats = mAlchemist.getClass().getCreatureStats(mAlchemist); - return - (mAlchemist.getClass().getSkill(mAlchemist, ESM::Skill::Alchemy) + - 0.1f * creatureStats.getAttribute (ESM::Attribute::Intelligence).getModified() - + 0.1f * creatureStats.getAttribute (ESM::Attribute::Luck).getModified()); + return (mAlchemist.getClass().getSkill(mAlchemist, ESM::Skill::Alchemy) + + 0.1f * creatureStats.getAttribute(ESM::Attribute::Intelligence).getModified() + + 0.1f * creatureStats.getAttribute(ESM::Attribute::Luck).getModified()); } int MWMechanics::Alchemy::countIngredients() const { int ingredients = 0; - for (TIngredientsIterator iter (beginIngredients()); iter!=endIngredients(); ++iter) + for (TIngredientsIterator iter(beginIngredients()); iter != endIngredients(); ++iter) if (!iter->isEmpty()) ++ingredients; @@ -341,7 +354,7 @@ int MWMechanics::Alchemy::countPotionsToBrew() const int toBrew = -1; - for (TIngredientsIterator iter (beginIngredients()); iter!=endIngredients(); ++iter) + for (TIngredientsIterator iter(beginIngredients()); iter != endIngredients(); ++iter) if (!iter->isEmpty()) { int count = iter->getRefData().getCount(); @@ -352,34 +365,34 @@ int MWMechanics::Alchemy::countPotionsToBrew() const return toBrew; } -void MWMechanics::Alchemy::setAlchemist (const MWWorld::Ptr& npc) +void MWMechanics::Alchemy::setAlchemist(const MWWorld::Ptr& npc) { mAlchemist = npc; - mIngredients.resize (4); + mIngredients.resize(4); - std::fill (mIngredients.begin(), mIngredients.end(), MWWorld::Ptr()); + std::fill(mIngredients.begin(), mIngredients.end(), MWWorld::Ptr()); - mTools.resize (4); + mTools.resize(4); - std::fill (mTools.begin(), mTools.end(), MWWorld::Ptr()); + std::fill(mTools.begin(), mTools.end(), MWWorld::Ptr()); mEffects.clear(); - MWWorld::ContainerStore& store = npc.getClass().getContainerStore (npc); + MWWorld::ContainerStore& store = npc.getClass().getContainerStore(npc); - for (MWWorld::ContainerStoreIterator iter (store.begin (MWWorld::ContainerStore::Type_Apparatus)); - iter!=store.end(); ++iter) + for (MWWorld::ContainerStoreIterator iter(store.begin(MWWorld::ContainerStore::Type_Apparatus)); + iter != store.end(); ++iter) { MWWorld::LiveCellRef* ref = iter->get(); int type = ref->mBase->mData.mType; - if (type<0 || type>=static_cast (mTools.size())) - throw std::runtime_error ("invalid apparatus type"); + if (type < 0 || type >= static_cast(mTools.size())) + throw std::runtime_error("invalid apparatus type"); if (!mTools[type].isEmpty()) - if (ref->mBase->mData.mQuality<=mTools[type].get()->mBase->mData.mQuality) + if (ref->mBase->mData.mQuality <= mTools[type].get()->mBase->mData.mQuality) continue; mTools[type] = *iter; @@ -420,24 +433,24 @@ void MWMechanics::Alchemy::setPotionName(const std::string& name) mPotionName = name; } -int MWMechanics::Alchemy::addIngredient (const MWWorld::Ptr& ingredient) +int MWMechanics::Alchemy::addIngredient(const MWWorld::Ptr& ingredient) { // find a free slot int slot = -1; - for (int i=0; i (mIngredients.size()); ++i) + for (int i = 0; i < static_cast(mIngredients.size()); ++i) if (mIngredients[i].isEmpty()) { slot = i; break; } - if (slot==-1) + if (slot == -1) return -1; - for (TIngredientsIterator iter (mIngredients.begin()); iter!=mIngredients.end(); ++iter) - if (!iter->isEmpty() && Misc::StringUtils::ciEqual(ingredient.getCellRef().getRefId(), - iter->getCellRef().getRefId())) + for (TIngredientsIterator iter(mIngredients.begin()); iter != mIngredients.end(); ++iter) + if (!iter->isEmpty() + && Misc::StringUtils::ciEqual(ingredient.getCellRef().getRefId(), iter->getCellRef().getRefId())) return -1; mIngredients[slot] = ingredient; @@ -447,9 +460,9 @@ int MWMechanics::Alchemy::addIngredient (const MWWorld::Ptr& ingredient) return slot; } -void MWMechanics::Alchemy::removeIngredient (int index) +void MWMechanics::Alchemy::removeIngredient(int index) { - if (index>=0 && index (mIngredients.size())) + if (index >= 0 && index < static_cast(mIngredients.size())) { mIngredients[index] = MWWorld::Ptr(); updateEffects(); @@ -466,15 +479,19 @@ MWMechanics::Alchemy::TEffectsIterator MWMechanics::Alchemy::endEffects() const return mEffects.end(); } -bool MWMechanics::Alchemy::knownEffect(unsigned int potionEffectIndex, const MWWorld::Ptr &npc) +bool MWMechanics::Alchemy::knownEffect(unsigned int potionEffectIndex, const MWWorld::Ptr& npc) { - float alchemySkill = npc.getClass().getSkill (npc, ESM::Skill::Alchemy); - static const float fWortChanceValue = - MWBase::Environment::get().getWorld()->getStore().get().find("fWortChanceValue")->mValue.getFloat(); + float alchemySkill = npc.getClass().getSkill(npc, ESM::Skill::Alchemy); + static const float fWortChanceValue = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fWortChanceValue") + ->mValue.getFloat(); return (potionEffectIndex <= 1 && alchemySkill >= fWortChanceValue) - || (potionEffectIndex <= 3 && alchemySkill >= fWortChanceValue*2) - || (potionEffectIndex <= 5 && alchemySkill >= fWortChanceValue*3) - || (potionEffectIndex <= 7 && alchemySkill >= fWortChanceValue*4); + || (potionEffectIndex <= 3 && alchemySkill >= fWortChanceValue * 2) + || (potionEffectIndex <= 5 && alchemySkill >= fWortChanceValue * 3) + || (potionEffectIndex <= 7 && alchemySkill >= fWortChanceValue * 4); } MWMechanics::Alchemy::Result MWMechanics::Alchemy::getReadyStatus() const @@ -482,7 +499,7 @@ MWMechanics::Alchemy::Result MWMechanics::Alchemy::getReadyStatus() const if (mTools[ESM::Apparatus::MortarPestle].isEmpty()) return Result_NoMortarAndPestle; - if (countIngredients()<2) + if (countIngredients() < 2) return Result_LessThanTwoIngredients; if (mPotionName.empty()) @@ -494,7 +511,7 @@ MWMechanics::Alchemy::Result MWMechanics::Alchemy::getReadyStatus() const return Result_Success; } -MWMechanics::Alchemy::Result MWMechanics::Alchemy::create (const std::string& name, int& count) +MWMechanics::Alchemy::Result MWMechanics::Alchemy::create(const std::string& name, int& count) { setPotionName(name); Result readyStatus = getReadyStatus(); @@ -520,7 +537,7 @@ MWMechanics::Alchemy::Result MWMechanics::Alchemy::create (const std::string& na return result; } -MWMechanics::Alchemy::Result MWMechanics::Alchemy::createSingle () +MWMechanics::Alchemy::Result MWMechanics::Alchemy::createSingle() { if (beginEffects() == endEffects()) { @@ -551,11 +568,15 @@ std::string MWMechanics::Alchemy::suggestPotionName() return ""; int effectId = effects.begin()->mId; - return MWBase::Environment::get().getWorld()->getStore().get().find( - ESM::MagicEffect::effectIdToString(effectId))->mValue.getString(); + return MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find(ESM::MagicEffect::effectIdToString(effectId)) + ->mValue.getString(); } -std::vector MWMechanics::Alchemy::effectsDescription (const MWWorld::ConstPtr &ptr, const int alchemySkill) +std::vector MWMechanics::Alchemy::effectsDescription(const MWWorld::ConstPtr& ptr, const int alchemySkill) { std::vector effects; @@ -583,7 +604,6 @@ std::vector MWMechanics::Alchemy::effectsDescription (const MWWorld effect += " " + gmst.find(ESM::Attribute::sGmstAttributeIds[attributeID])->mValue.getString(); effects.push_back(effect); - } } return effects; diff --git a/apps/openmw/mwmechanics/alchemy.hpp b/apps/openmw/mwmechanics/alchemy.hpp index 8c91a81177..ab6225e544 100644 --- a/apps/openmw/mwmechanics/alchemy.hpp +++ b/apps/openmw/mwmechanics/alchemy.hpp @@ -1,8 +1,8 @@ #ifndef GAME_MWMECHANICS_ALCHEMY_H #define GAME_MWMECHANICS_ALCHEMY_H -#include #include +#include #include @@ -20,121 +20,118 @@ namespace MWMechanics /// \brief Potion creation via alchemy skill class Alchemy { - public: - - Alchemy(); + public: + Alchemy(); - typedef std::vector TToolsContainer; - typedef TToolsContainer::const_iterator TToolsIterator; + typedef std::vector TToolsContainer; + typedef TToolsContainer::const_iterator TToolsIterator; - typedef std::vector TIngredientsContainer; - typedef TIngredientsContainer::const_iterator TIngredientsIterator; + typedef std::vector TIngredientsContainer; + typedef TIngredientsContainer::const_iterator TIngredientsIterator; - typedef std::vector TEffectsContainer; - typedef TEffectsContainer::const_iterator TEffectsIterator; + typedef std::vector TEffectsContainer; + typedef TEffectsContainer::const_iterator TEffectsIterator; - enum Result - { - Result_Success, + enum Result + { + Result_Success, - Result_NoMortarAndPestle, - Result_LessThanTwoIngredients, - Result_NoName, - Result_NoEffects, - Result_RandomFailure - }; + Result_NoMortarAndPestle, + Result_LessThanTwoIngredients, + Result_NoName, + Result_NoEffects, + Result_RandomFailure + }; - private: + private: + MWWorld::Ptr mAlchemist; + TToolsContainer mTools; + TIngredientsContainer mIngredients; + TEffectsContainer mEffects; + int mValue; + std::string mPotionName; - MWWorld::Ptr mAlchemist; - TToolsContainer mTools; - TIngredientsContainer mIngredients; - TEffectsContainer mEffects; - int mValue; - std::string mPotionName; + void applyTools(int flags, float& value) const; - void applyTools (int flags, float& value) const; + void updateEffects(); - void updateEffects(); + Result getReadyStatus() const; - Result getReadyStatus() const; + const ESM::Potion* getRecord(const ESM::Potion& toFind) const; + ///< Try to find a potion record similar to \a toFind in the record store, or return 0 if not found + /// \note Does not account for record ID, model or icon - const ESM::Potion *getRecord(const ESM::Potion& toFind) const; - ///< Try to find a potion record similar to \a toFind in the record store, or return 0 if not found - /// \note Does not account for record ID, model or icon + void removeIngredients(); + ///< Remove selected ingredients from alchemist's inventory, cleanup selected ingredients and + /// update effect list accordingly. - void removeIngredients(); - ///< Remove selected ingredients from alchemist's inventory, cleanup selected ingredients and - /// update effect list accordingly. + void addPotion(const std::string& name); + ///< Add a potion to the alchemist's inventory. - void addPotion (const std::string& name); - ///< Add a potion to the alchemist's inventory. + void increaseSkill(); + ///< Increase alchemist's skill. - void increaseSkill(); - ///< Increase alchemist's skill. + Result createSingle(); + ///< Try to create a potion from the ingredients, place it in the inventory of the alchemist and + /// adjust the skills of the alchemist accordingly. - Result createSingle (); - ///< Try to create a potion from the ingredients, place it in the inventory of the alchemist and - /// adjust the skills of the alchemist accordingly. + float getAlchemyFactor() const; - float getAlchemyFactor() const; + int countIngredients() const; - int countIngredients() const; + TEffectsIterator beginEffects() const; - TEffectsIterator beginEffects() const; + TEffectsIterator endEffects() const; - TEffectsIterator endEffects() const; + public: + int countPotionsToBrew() const; + ///< calculates maximum amount of potions, which you can make from selected ingredients - public: - int countPotionsToBrew() const; - ///< calculates maximum amount of potions, which you can make from selected ingredients + static bool knownEffect(unsigned int potionEffectIndex, const MWWorld::Ptr& npc); + ///< Does npc have sufficient alchemy skill to know about this potion effect? - static bool knownEffect (unsigned int potionEffectIndex, const MWWorld::Ptr& npc); - ///< Does npc have sufficient alchemy skill to know about this potion effect? + void setAlchemist(const MWWorld::Ptr& npc); + ///< Set alchemist and configure alchemy setup accordingly. \a npc may be empty to indicate that + /// there is no alchemist (alchemy session has ended). - void setAlchemist (const MWWorld::Ptr& npc); - ///< Set alchemist and configure alchemy setup accordingly. \a npc may be empty to indicate that - /// there is no alchemist (alchemy session has ended). + TToolsIterator beginTools() const; + ///< \attention Iterates over tool slots, not over tools. Some of the slots may be empty. - TToolsIterator beginTools() const; - ///< \attention Iterates over tool slots, not over tools. Some of the slots may be empty. + TToolsIterator endTools() const; - TToolsIterator endTools() const; + TIngredientsIterator beginIngredients() const; + ///< \attention Iterates over ingredient slots, not over ingredients. Some of the slots may be empty. - TIngredientsIterator beginIngredients() const; - ///< \attention Iterates over ingredient slots, not over ingredients. Some of the slots may be empty. + TIngredientsIterator endIngredients() const; - TIngredientsIterator endIngredients() const; + void clear(); + ///< Remove alchemist, tools and ingredients. - void clear(); - ///< Remove alchemist, tools and ingredients. + void setPotionName(const std::string& name); + ///< Set name of potion to create - void setPotionName(const std::string& name); - ///< Set name of potion to create + std::set listEffects() const; + ///< List all effects shared by at least two ingredients. - std::set listEffects() const; - ///< List all effects shared by at least two ingredients. + int addIngredient(const MWWorld::Ptr& ingredient); + ///< Add ingredient into the next free slot. + /// + /// \return Slot index or -1, if adding failed because of no free slot or the ingredient type being + /// listed already. - int addIngredient (const MWWorld::Ptr& ingredient); - ///< Add ingredient into the next free slot. - /// - /// \return Slot index or -1, if adding failed because of no free slot or the ingredient type being - /// listed already. + void removeIngredient(int index); + ///< Remove ingredient from slot (calling this function on an empty slot is a no-op). - void removeIngredient (int index); - ///< Remove ingredient from slot (calling this function on an empty slot is a no-op). + std::string suggestPotionName(); + ///< Suggest a name for the potion, based on the current effects - std::string suggestPotionName (); - ///< Suggest a name for the potion, based on the current effects + Result create(const std::string& name, int& count); + ///< Try to create potions from the ingredients, place them in the inventory of the alchemist and + /// adjust the skills of the alchemist accordingly. + /// \param name must not be an empty string, or Result_NoName is returned - Result create (const std::string& name, int& count); - ///< Try to create potions from the ingredients, place them in the inventory of the alchemist and - /// adjust the skills of the alchemist accordingly. - /// \param name must not be an empty string, or Result_NoName is returned - - static std::vector effectsDescription (const MWWorld::ConstPtr &ptr, const int alchemySKill); + static std::vector effectsDescription(const MWWorld::ConstPtr& ptr, const int alchemySKill); }; } #endif - diff --git a/apps/openmw/mwmechanics/autocalcspell.cpp b/apps/openmw/mwmechanics/autocalcspell.cpp index fd7bcd7d5e..72398e456d 100644 --- a/apps/openmw/mwmechanics/autocalcspell.cpp +++ b/apps/openmw/mwmechanics/autocalcspell.cpp @@ -2,15 +2,15 @@ #include -#include -#include #include #include +#include +#include #include "../mwworld/esmstore.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" #include "spellutil.hpp" @@ -26,20 +26,21 @@ namespace MWMechanics std::string mWeakestSpell; }; - std::vector autoCalcNpcSpells(const int *actorSkills, const int *actorAttributes, const ESM::Race* race) + std::vector autoCalcNpcSpells( + const int* actorSkills, const int* actorAttributes, const ESM::Race* race) { - const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& gmst + = MWBase::Environment::get().getWorld()->getStore().get(); static const float fNPCbaseMagickaMult = gmst.find("fNPCbaseMagickaMult")->mValue.getFloat(); float baseMagicka = fNPCbaseMagickaMult * actorAttributes[ESM::Attribute::Intelligence]; - static const std::string schools[] = { - "alteration", "conjuration", "destruction", "illusion", "mysticism", "restoration" - }; + static const std::string schools[] + = { "alteration", "conjuration", "destruction", "illusion", "mysticism", "restoration" }; static int iAutoSpellSchoolMax[6]; static bool init = false; if (!init) { - for (int i=0; i<6; ++i) + for (int i = 0; i < 6; ++i) { const std::string& gmstName = "iAutoSpell" + schools[i] + "Max"; iAutoSpellSchoolMax[i] = gmst.find(gmstName)->mValue.getInteger(); @@ -48,7 +49,7 @@ namespace MWMechanics } std::map schoolCaps; - for (int i=0; i<6; ++i) + for (int i = 0; i < 6; ++i) { SchoolCaps caps; caps.mCount = 0; @@ -61,8 +62,7 @@ namespace MWMechanics std::vector selectedSpells; - const MWWorld::Store &spells = - MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& spells = MWBase::Environment::get().getWorld()->getStore().get(); // Note: the algorithm heavily depends on the traversal order of the spells. For vanilla-compatible results the // Store must preserve the record ordering as it was in the content files. @@ -100,7 +100,8 @@ namespace MWMechanics if (cap.mReachedLimit) { - std::vector::iterator found = std::find(selectedSpells.begin(), selectedSpells.end(), cap.mWeakestSpell); + std::vector::iterator found + = std::find(selectedSpells.begin(), selectedSpells.end(), cap.mWeakestSpell); if (found != selectedSpells.end()) selectedSpells.erase(found); @@ -110,19 +111,20 @@ namespace MWMechanics const ESM::Spell* testSpell = spells.find(testSpellName); int testSpellCost = MWMechanics::calcSpellCost(*testSpell); - //int testSchool; - //float dummySkillTerm; - //calcWeakestSchool(testSpell, actorSkills, testSchool, dummySkillTerm); + // int testSchool; + // float dummySkillTerm; + // calcWeakestSchool(testSpell, actorSkills, testSchool, dummySkillTerm); // Note: if there are multiple spells with the same cost, we pick the first one we found. // So the algorithm depends on the iteration order of the outer loop. if ( - // There is a huge bug here. It is not checked that weakestSpell is of the correct school. - // As result multiple SchoolCaps could have the same mWeakestSpell. Erasing the weakest spell would then fail if another school - // already erased it, and so the number of spells would often exceed the sum of limits. - // This bug cannot be fixed without significantly changing the results of the spell autocalc, which will not have been playtested. - //testSchool == school && - testSpellCost < cap.mMinCost) + // There is a huge bug here. It is not checked that weakestSpell is of the correct school. + // As result multiple SchoolCaps could have the same mWeakestSpell. Erasing the weakest spell + // would then fail if another school already erased it, and so the number of spells would often + // exceed the sum of limits. This bug cannot be fixed without significantly changing the results + // of the spell autocalc, which will not have been playtested. + // testSchool == school && + testSpellCost < cap.mMinCost) { cap.mMinCost = testSpellCost; cap.mWeakestSpell = testSpell->mId; @@ -146,11 +148,13 @@ namespace MWMechanics return selectedSpells; } - std::vector autoCalcPlayerSpells(const int* actorSkills, const int* actorAttributes, const ESM::Race* race) + std::vector autoCalcPlayerSpells( + const int* actorSkills, const int* actorAttributes, const ESM::Race* race) { const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); - static const float fPCbaseMagickaMult = esmStore.get().find("fPCbaseMagickaMult")->mValue.getFloat(); + static const float fPCbaseMagickaMult + = esmStore.get().find("fPCbaseMagickaMult")->mValue.getFloat(); float baseMagicka = fPCbaseMagickaMult * actorAttributes[ESM::Attribute::Intelligence]; bool reachedLimit = false; @@ -159,7 +163,7 @@ namespace MWMechanics std::vector selectedSpells; - const MWWorld::Store &spells = esmStore.get(); + const MWWorld::Store& spells = esmStore.get(); for (const ESM::Spell& spell : spells) { if (spell.mData.mType != ESM::Spell::ST_Spell) @@ -170,12 +174,15 @@ namespace MWMechanics int spellCost = MWMechanics::calcSpellCost(spell); if (reachedLimit && spellCost <= minCost) continue; - if (race && std::find(race->mPowers.mList.begin(), race->mPowers.mList.end(), spell.mId) != race->mPowers.mList.end()) + if (race + && std::find(race->mPowers.mList.begin(), race->mPowers.mList.end(), spell.mId) + != race->mPowers.mList.end()) continue; if (baseMagicka < spellCost) continue; - static const float fAutoPCSpellChance = esmStore.get().find("fAutoPCSpellChance")->mValue.getFloat(); + static const float fAutoPCSpellChance + = esmStore.get().find("fAutoPCSpellChance")->mValue.getFloat(); if (calcAutoCastChance(&spell, actorSkills, actorAttributes, -1) < fAutoPCSpellChance) continue; @@ -186,7 +193,8 @@ namespace MWMechanics if (reachedLimit) { - std::vector::iterator it = std::find(selectedSpells.begin(), selectedSpells.end(), weakestSpell->mId); + std::vector::iterator it + = std::find(selectedSpells.begin(), selectedSpells.end(), weakestSpell->mId); if (it != selectedSpells.end()) selectedSpells.erase(it); @@ -209,7 +217,8 @@ namespace MWMechanics weakestSpell = &spell; minCost = MWMechanics::calcSpellCost(*weakestSpell); } - static const unsigned int iAutoPCSpellMax = esmStore.get().find("iAutoPCSpellMax")->mValue.getInteger(); + static const unsigned int iAutoPCSpellMax + = esmStore.get().find("iAutoPCSpellMax")->mValue.getInteger(); if (selectedSpells.size() == iAutoPCSpellMax) reachedLimit = true; } @@ -218,23 +227,29 @@ namespace MWMechanics return selectedSpells; } - bool attrSkillCheck (const ESM::Spell* spell, const int* actorSkills, const int* actorAttributes) + bool attrSkillCheck(const ESM::Spell* spell, const int* actorSkills, const int* actorAttributes) { for (const auto& spellEffect : spell->mEffects.mList) { - const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getWorld()->getStore().get().find(spellEffect.mEffectID); - static const int iAutoSpellAttSkillMin = MWBase::Environment::get().getWorld()->getStore().get().find("iAutoSpellAttSkillMin")->mValue.getInteger(); + const ESM::MagicEffect* magicEffect + = MWBase::Environment::get().getWorld()->getStore().get().find(spellEffect.mEffectID); + static const int iAutoSpellAttSkillMin = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("iAutoSpellAttSkillMin") + ->mValue.getInteger(); if ((magicEffect->mData.mFlags & ESM::MagicEffect::TargetSkill)) { - assert (spellEffect.mSkill >= 0 && spellEffect.mSkill < ESM::Skill::Length); + assert(spellEffect.mSkill >= 0 && spellEffect.mSkill < ESM::Skill::Length); if (actorSkills[spellEffect.mSkill] < iAutoSpellAttSkillMin) return false; } if ((magicEffect->mData.mFlags & ESM::MagicEffect::TargetAttribute)) { - assert (spellEffect.mAttribute >= 0 && spellEffect.mAttribute < ESM::Attribute::Length); + assert(spellEffect.mAttribute >= 0 && spellEffect.mAttribute < ESM::Attribute::Length); if (actorAttributes[spellEffect.mAttribute] < iAutoSpellAttSkillMin) return false; } @@ -243,13 +258,14 @@ namespace MWMechanics return true; } - void calcWeakestSchool (const ESM::Spell* spell, const int* actorSkills, int& effectiveSchool, float& skillTerm) + void calcWeakestSchool(const ESM::Spell* spell, const int* actorSkills, int& effectiveSchool, float& skillTerm) { // Morrowind for some reason uses a formula slightly different from magicka cost calculation float minChance = std::numeric_limits::max(); for (const ESM::ENAMstruct& effect : spell->mEffects.mList) { - const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getWorld()->getStore().get().find(effect.mEffectID); + const ESM::MagicEffect* magicEffect + = MWBase::Environment::get().getWorld()->getStore().get().find(effect.mEffectID); int minMagn = 1; int maxMagn = 1; @@ -265,8 +281,12 @@ namespace MWMechanics if (!(magicEffect->mData.mFlags & ESM::MagicEffect::AppliedOnce)) duration = std::max(1, duration); - static const float fEffectCostMult = MWBase::Environment::get().getWorld()->getStore() - .get().find("fEffectCostMult")->mValue.getFloat(); + static const float fEffectCostMult = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fEffectCostMult") + ->mValue.getFloat(); float x = 0.5 * (std::max(1, minMagn) + std::max(1, maxMagn)); x *= 0.1 * magicEffect->mData.mBaseCost; @@ -287,7 +307,8 @@ namespace MWMechanics } } - float calcAutoCastChance(const ESM::Spell *spell, const int *actorSkills, const int *actorAttributes, int effectiveSchool) + float calcAutoCastChance( + const ESM::Spell* spell, const int* actorSkills, const int* actorAttributes, int effectiveSchool) { if (spell->mData.mType != ESM::Spell::ST_Spell) return 100.f; @@ -299,11 +320,11 @@ namespace MWMechanics if (effectiveSchool != -1) skillTerm = 2.f * actorSkills[spellSchoolToSkill(effectiveSchool)]; else - calcWeakestSchool(spell, actorSkills, effectiveSchool, skillTerm); // Note effectiveSchool is unused after this + calcWeakestSchool( + spell, actorSkills, effectiveSchool, skillTerm); // Note effectiveSchool is unused after this float castChance = skillTerm - MWMechanics::calcSpellCost(*spell) - + 0.2f * actorAttributes[ESM::Attribute::Willpower] - + 0.1f * actorAttributes[ESM::Attribute::Luck]; + + 0.2f * actorAttributes[ESM::Attribute::Willpower] + 0.1f * actorAttributes[ESM::Attribute::Luck]; return castChance; } } diff --git a/apps/openmw/mwmechanics/autocalcspell.hpp b/apps/openmw/mwmechanics/autocalcspell.hpp index 460713ae37..444077f3fe 100644 --- a/apps/openmw/mwmechanics/autocalcspell.hpp +++ b/apps/openmw/mwmechanics/autocalcspell.hpp @@ -13,20 +13,23 @@ namespace ESM namespace MWMechanics { -/// Contains algorithm for calculating an NPC's spells based on stats -/// @note We might want to move this code to a component later, so the editor can use it for preview purposes + /// Contains algorithm for calculating an NPC's spells based on stats + /// @note We might want to move this code to a component later, so the editor can use it for preview purposes -std::vector autoCalcNpcSpells(const int* actorSkills, const int* actorAttributes, const ESM::Race* race); + std::vector autoCalcNpcSpells( + const int* actorSkills, const int* actorAttributes, const ESM::Race* race); -std::vector autoCalcPlayerSpells(const int* actorSkills, const int* actorAttributes, const ESM::Race* race); + std::vector autoCalcPlayerSpells( + const int* actorSkills, const int* actorAttributes, const ESM::Race* race); -// Helpers + // Helpers -bool attrSkillCheck (const ESM::Spell* spell, const int* actorSkills, const int* actorAttributes); + bool attrSkillCheck(const ESM::Spell* spell, const int* actorSkills, const int* actorAttributes); -void calcWeakestSchool(const ESM::Spell* spell, const int* actorSkills, int& effectiveSchool, float& skillTerm); + void calcWeakestSchool(const ESM::Spell* spell, const int* actorSkills, int& effectiveSchool, float& skillTerm); -float calcAutoCastChance(const ESM::Spell* spell, const int* actorSkills, const int* actorAttributes, int effectiveSchool); + float calcAutoCastChance( + const ESM::Spell* spell, const int* actorSkills, const int* actorAttributes, int effectiveSchool); } diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 7f14185ad2..76f83eb277 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -21,11 +21,11 @@ #include +#include #include +#include #include #include -#include -#include #include @@ -35,2766 +35,2875 @@ #include "../mwbase/environment.hpp" #include "../mwbase/mechanicsmanager.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/soundmanager.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" #include "../mwworld/class.hpp" -#include "../mwworld/inventorystore.hpp" #include "../mwworld/esmstore.hpp" +#include "../mwworld/inventorystore.hpp" #include "../mwworld/player.hpp" #include "../mwworld/spellcaststate.hpp" +#include "actorutil.hpp" #include "aicombataction.hpp" +#include "creaturestats.hpp" #include "movement.hpp" #include "npcstats.hpp" -#include "creaturestats.hpp" #include "security.hpp" -#include "actorutil.hpp" #include "spellcasting.hpp" #include "weapontype.hpp" namespace { -std::string_view getBestAttack(const ESM::Weapon* weapon) -{ - int slash = weapon->mData.mSlash[0] + weapon->mData.mSlash[1]; - int chop = weapon->mData.mChop[0] + weapon->mData.mChop[1]; - int thrust = weapon->mData.mThrust[0] + weapon->mData.mThrust[1]; - if (slash == chop && slash == thrust) - return "slash"; - else if (thrust >= chop && thrust >= slash) - return "thrust"; - else if (slash >= chop && slash >= thrust) - return "slash"; - else - return "chop"; -} - -// Converts a movement Run state to its equivalent Walk state, if there is one. -MWMechanics::CharacterState runStateToWalkState (MWMechanics::CharacterState state) -{ - using namespace MWMechanics; - switch (state) - { - case CharState_RunForward: return CharState_WalkForward; - case CharState_RunBack: return CharState_WalkBack; - case CharState_RunLeft: return CharState_WalkLeft; - case CharState_RunRight: return CharState_WalkRight; - case CharState_SwimRunForward: return CharState_SwimWalkForward; - case CharState_SwimRunBack: return CharState_SwimWalkBack; - case CharState_SwimRunLeft: return CharState_SwimWalkLeft; - case CharState_SwimRunRight: return CharState_SwimWalkRight; - default: return state; - } -} - -// Converts a Hit state to its equivalent Death state. -MWMechanics::CharacterState hitStateToDeathState (MWMechanics::CharacterState state) -{ - using namespace MWMechanics; - switch (state) + std::string_view getBestAttack(const ESM::Weapon* weapon) { - case CharState_SwimKnockDown: return CharState_SwimDeathKnockDown; - case CharState_SwimKnockOut: return CharState_SwimDeathKnockOut; - case CharState_KnockDown: return CharState_DeathKnockDown; - case CharState_KnockOut: return CharState_DeathKnockOut; - default: return CharState_None; - } -} - -// Converts a movement state to its equivalent base animation group as long as it is a movement state. -std::string_view movementStateToAnimGroup(MWMechanics::CharacterState state) -{ - using namespace MWMechanics; - switch (state) - { - case CharState_WalkForward: return "walkforward"; - case CharState_WalkBack: return "walkback"; - case CharState_WalkLeft: return "walkleft"; - case CharState_WalkRight: return "walkright"; - - case CharState_SwimWalkForward: return "swimwalkforward"; - case CharState_SwimWalkBack: return "swimwalkback"; - case CharState_SwimWalkLeft: return "swimwalkleft"; - case CharState_SwimWalkRight: return "swimwalkright"; - - case CharState_RunForward: return "runforward"; - case CharState_RunBack: return "runback"; - case CharState_RunLeft: return "runleft"; - case CharState_RunRight: return "runright"; - - case CharState_SwimRunForward: return "swimrunforward"; - case CharState_SwimRunBack: return "swimrunback"; - case CharState_SwimRunLeft: return "swimrunleft"; - case CharState_SwimRunRight: return "swimrunright"; - - case CharState_SneakForward: return "sneakforward"; - case CharState_SneakBack: return "sneakback"; - case CharState_SneakLeft: return "sneakleft"; - case CharState_SneakRight: return "sneakright"; - - case CharState_TurnLeft: return "turnleft"; - case CharState_TurnRight: return "turnright"; - case CharState_SwimTurnLeft: return "swimturnleft"; - case CharState_SwimTurnRight: return "swimturnright"; - default: return {}; - } -} + int slash = weapon->mData.mSlash[0] + weapon->mData.mSlash[1]; + int chop = weapon->mData.mChop[0] + weapon->mData.mChop[1]; + int thrust = weapon->mData.mThrust[0] + weapon->mData.mThrust[1]; + if (slash == chop && slash == thrust) + return "slash"; + else if (thrust >= chop && thrust >= slash) + return "thrust"; + else if (slash >= chop && slash >= thrust) + return "slash"; + else + return "chop"; + } + + // Converts a movement Run state to its equivalent Walk state, if there is one. + MWMechanics::CharacterState runStateToWalkState(MWMechanics::CharacterState state) + { + using namespace MWMechanics; + switch (state) + { + case CharState_RunForward: + return CharState_WalkForward; + case CharState_RunBack: + return CharState_WalkBack; + case CharState_RunLeft: + return CharState_WalkLeft; + case CharState_RunRight: + return CharState_WalkRight; + case CharState_SwimRunForward: + return CharState_SwimWalkForward; + case CharState_SwimRunBack: + return CharState_SwimWalkBack; + case CharState_SwimRunLeft: + return CharState_SwimWalkLeft; + case CharState_SwimRunRight: + return CharState_SwimWalkRight; + default: + return state; + } + } + + // Converts a Hit state to its equivalent Death state. + MWMechanics::CharacterState hitStateToDeathState(MWMechanics::CharacterState state) + { + using namespace MWMechanics; + switch (state) + { + case CharState_SwimKnockDown: + return CharState_SwimDeathKnockDown; + case CharState_SwimKnockOut: + return CharState_SwimDeathKnockOut; + case CharState_KnockDown: + return CharState_DeathKnockDown; + case CharState_KnockOut: + return CharState_DeathKnockOut; + default: + return CharState_None; + } + } + + // Converts a movement state to its equivalent base animation group as long as it is a movement state. + std::string_view movementStateToAnimGroup(MWMechanics::CharacterState state) + { + using namespace MWMechanics; + switch (state) + { + case CharState_WalkForward: + return "walkforward"; + case CharState_WalkBack: + return "walkback"; + case CharState_WalkLeft: + return "walkleft"; + case CharState_WalkRight: + return "walkright"; + + case CharState_SwimWalkForward: + return "swimwalkforward"; + case CharState_SwimWalkBack: + return "swimwalkback"; + case CharState_SwimWalkLeft: + return "swimwalkleft"; + case CharState_SwimWalkRight: + return "swimwalkright"; + + case CharState_RunForward: + return "runforward"; + case CharState_RunBack: + return "runback"; + case CharState_RunLeft: + return "runleft"; + case CharState_RunRight: + return "runright"; + + case CharState_SwimRunForward: + return "swimrunforward"; + case CharState_SwimRunBack: + return "swimrunback"; + case CharState_SwimRunLeft: + return "swimrunleft"; + case CharState_SwimRunRight: + return "swimrunright"; + + case CharState_SneakForward: + return "sneakforward"; + case CharState_SneakBack: + return "sneakback"; + case CharState_SneakLeft: + return "sneakleft"; + case CharState_SneakRight: + return "sneakright"; + + case CharState_TurnLeft: + return "turnleft"; + case CharState_TurnRight: + return "turnright"; + case CharState_SwimTurnLeft: + return "swimturnleft"; + case CharState_SwimTurnRight: + return "swimturnright"; + default: + return {}; + } + } + + // Converts a death state to its equivalent animation group as long as it is a death state. + std::string_view deathStateToAnimGroup(MWMechanics::CharacterState state) + { + using namespace MWMechanics; + switch (state) + { + case CharState_SwimDeath: + return "swimdeath"; + case CharState_SwimDeathKnockDown: + return "swimdeathknockdown"; + case CharState_SwimDeathKnockOut: + return "swimdeathknockout"; + case CharState_DeathKnockDown: + return "deathknockdown"; + case CharState_DeathKnockOut: + return "deathknockout"; + case CharState_Death1: + return "death1"; + case CharState_Death2: + return "death2"; + case CharState_Death3: + return "death3"; + case CharState_Death4: + return "death4"; + case CharState_Death5: + return "death5"; + default: + return {}; + } + } + + // Converts a hit state to its equivalent animation group as long as it is a hit state. + std::string hitStateToAnimGroup(MWMechanics::CharacterState state) + { + using namespace MWMechanics; + switch (state) + { + case CharState_SwimHit: + return "swimhit"; + case CharState_SwimKnockDown: + return "swimknockdown"; + case CharState_SwimKnockOut: + return "swimknockout"; + + case CharState_Hit: + return "hit"; + case CharState_KnockDown: + return "knockdown"; + case CharState_KnockOut: + return "knockout"; + + case CharState_Block: + return "shield"; + + default: + return {}; + } + } + + // Converts an idle state to its equivalent animation group. + std::string idleStateToAnimGroup(MWMechanics::CharacterState state) + { + using namespace MWMechanics; + switch (state) + { + case CharState_IdleSwim: + return "idleswim"; + case CharState_IdleSneak: + return "idlesneak"; + case CharState_Idle: + case CharState_SpecialIdle: + return "idle"; + default: + return {}; + } + } -// Converts a death state to its equivalent animation group as long as it is a death state. -std::string_view deathStateToAnimGroup(MWMechanics::CharacterState state) -{ - using namespace MWMechanics; - switch (state) - { - case CharState_SwimDeath: return "swimdeath"; - case CharState_SwimDeathKnockDown: return "swimdeathknockdown"; - case CharState_SwimDeathKnockOut: return "swimdeathknockout"; - case CharState_DeathKnockDown: return "deathknockdown"; - case CharState_DeathKnockOut: return "deathknockout"; - case CharState_Death1: return "death1"; - case CharState_Death2: return "death2"; - case CharState_Death3: return "death3"; - case CharState_Death4: return "death4"; - case CharState_Death5: return "death5"; - default: return {}; + MWRender::Animation::AnimPriority getIdlePriority(MWMechanics::CharacterState state) + { + using namespace MWMechanics; + MWRender::Animation::AnimPriority priority(Priority_Default); + switch (state) + { + case CharState_IdleSwim: + return Priority_SwimIdle; + case CharState_IdleSneak: + priority[MWRender::Animation::BoneGroup_LowerBody] = Priority_SneakIdleLowerBody; + [[fallthrough]]; + default: + return priority; + } } -} -// Converts a hit state to its equivalent animation group as long as it is a hit state. -std::string hitStateToAnimGroup(MWMechanics::CharacterState state) -{ - using namespace MWMechanics; - switch (state) + float getFallDamage(const MWWorld::Ptr& ptr, float fallHeight) { - case CharState_SwimHit: return "swimhit"; - case CharState_SwimKnockDown: return "swimknockdown"; - case CharState_SwimKnockOut: return "swimknockout"; + MWBase::World* world = MWBase::Environment::get().getWorld(); + const MWWorld::Store& store = world->getStore().get(); - case CharState_Hit: return "hit"; - case CharState_KnockDown: return "knockdown"; - case CharState_KnockOut: return "knockout"; + const float fallDistanceMin = store.find("fFallDamageDistanceMin")->mValue.getFloat(); - case CharState_Block: return "shield"; + if (fallHeight >= fallDistanceMin) + { + const float acrobaticsSkill = static_cast(ptr.getClass().getSkill(ptr, ESM::Skill::Acrobatics)); + const float jumpSpellBonus + = ptr.getClass().getCreatureStats(ptr).getMagicEffects().get(ESM::MagicEffect::Jump).getMagnitude(); + const float fallAcroBase = store.find("fFallAcroBase")->mValue.getFloat(); + const float fallAcroMult = store.find("fFallAcroMult")->mValue.getFloat(); + const float fallDistanceBase = store.find("fFallDistanceBase")->mValue.getFloat(); + const float fallDistanceMult = store.find("fFallDistanceMult")->mValue.getFloat(); - default: return {}; - } -} + float x = fallHeight - fallDistanceMin; + x -= (1.5f * acrobaticsSkill) + jumpSpellBonus; + x = std::max(0.0f, x); -// Converts an idle state to its equivalent animation group. -std::string idleStateToAnimGroup(MWMechanics::CharacterState state) -{ - using namespace MWMechanics; - switch (state) - { - case CharState_IdleSwim: - return "idleswim"; - case CharState_IdleSneak: - return "idlesneak"; - case CharState_Idle: - case CharState_SpecialIdle: - return "idle"; - default: - return {}; - } -} + float a = fallAcroBase + fallAcroMult * (100 - acrobaticsSkill); + x = fallDistanceBase + fallDistanceMult * x; + x *= a; -MWRender::Animation::AnimPriority getIdlePriority(MWMechanics::CharacterState state) -{ - using namespace MWMechanics; - MWRender::Animation::AnimPriority priority(Priority_Default); - switch (state) - { - case CharState_IdleSwim: - return Priority_SwimIdle; - case CharState_IdleSneak: - priority[MWRender::Animation::BoneGroup_LowerBody] = Priority_SneakIdleLowerBody; - [[fallthrough]]; - default: - return priority; + return x; + } + return 0.f; } -} -float getFallDamage(const MWWorld::Ptr& ptr, float fallHeight) -{ - MWBase::World *world = MWBase::Environment::get().getWorld(); - const MWWorld::Store &store = world->getStore().get(); - - const float fallDistanceMin = store.find("fFallDamageDistanceMin")->mValue.getFloat(); - - if (fallHeight >= fallDistanceMin) + bool isRealWeapon(int weaponType) { - const float acrobaticsSkill = static_cast(ptr.getClass().getSkill(ptr, ESM::Skill::Acrobatics)); - const float jumpSpellBonus = ptr.getClass().getCreatureStats(ptr).getMagicEffects().get(ESM::MagicEffect::Jump).getMagnitude(); - const float fallAcroBase = store.find("fFallAcroBase")->mValue.getFloat(); - const float fallAcroMult = store.find("fFallAcroMult")->mValue.getFloat(); - const float fallDistanceBase = store.find("fFallDistanceBase")->mValue.getFloat(); - const float fallDistanceMult = store.find("fFallDistanceMult")->mValue.getFloat(); - - float x = fallHeight - fallDistanceMin; - x -= (1.5f * acrobaticsSkill) + jumpSpellBonus; - x = std::max(0.0f, x); - - float a = fallAcroBase + fallAcroMult * (100 - acrobaticsSkill); - x = fallDistanceBase + fallDistanceMult * x; - x *= a; - - return x; + return weaponType != ESM::Weapon::HandToHand && weaponType != ESM::Weapon::Spell + && weaponType != ESM::Weapon::None; } - return 0.f; -} - -bool isRealWeapon(int weaponType) -{ - return weaponType != ESM::Weapon::HandToHand - && weaponType != ESM::Weapon::Spell - && weaponType != ESM::Weapon::None; -} } namespace MWMechanics { -std::string CharacterController::chooseRandomGroup (const std::string& prefix, int* num) const -{ - auto& prng = MWBase::Environment::get().getWorld()->getPrng(); - - int numAnims=0; - while (mAnimation->hasAnimation(prefix + std::to_string(numAnims+1))) - ++numAnims; - - int roll = Misc::Rng::rollDice(numAnims, prng) + 1; // [1, numAnims] - if (num) - *num = roll; - return prefix + std::to_string(roll); -} - - -void CharacterController::clearStateAnimation(std::string &anim) const -{ - if (anim.empty()) - return; - if (mAnimation) - mAnimation->disable(anim); - anim.clear(); -} - -void CharacterController::resetCurrentJumpState() -{ - clearStateAnimation(mCurrentJump); - mJumpState = JumpState_None; -} - -void CharacterController::resetCurrentMovementState() -{ - clearStateAnimation(mCurrentMovement); - mMovementState = CharState_None; -} - -void CharacterController::resetCurrentIdleState() -{ - clearStateAnimation(mCurrentIdle); - mIdleState = CharState_None; -} - -void CharacterController::resetCurrentHitState() -{ - clearStateAnimation(mCurrentHit); - mHitState = CharState_None; -} - -void CharacterController::resetCurrentWeaponState() -{ - clearStateAnimation(mCurrentWeapon); - mUpperBodyState = UpperBodyState::None; -} + std::string CharacterController::chooseRandomGroup(const std::string& prefix, int* num) const + { + auto& prng = MWBase::Environment::get().getWorld()->getPrng(); -void CharacterController::resetCurrentDeathState() -{ - clearStateAnimation(mCurrentDeath); - mDeathState = CharState_None; -} + int numAnims = 0; + while (mAnimation->hasAnimation(prefix + std::to_string(numAnims + 1))) + ++numAnims; -void CharacterController::refreshHitRecoilAnims() -{ - auto& charClass = mPtr.getClass(); - if (!charClass.isActor()) - return; - const auto world = MWBase::Environment::get().getWorld(); - auto& stats = charClass.getCreatureStats(mPtr); - bool knockout = stats.getFatigue().getCurrent() < 0 || stats.getFatigue().getBase() == 0; - bool recovery = stats.getHitRecovery(); - bool knockdown = stats.getKnockedDown(); - bool block = stats.getBlock(); - bool isSwimming = world->isSwimming(mPtr); + int roll = Misc::Rng::rollDice(numAnims, prng) + 1; // [1, numAnims] + if (num) + *num = roll; + return prefix + std::to_string(roll); + } - if (mHitState != CharState_None) + void CharacterController::clearStateAnimation(std::string& anim) const { - if (!mAnimation->isPlaying(mCurrentHit)) - { - mHitState = CharState_None; - mCurrentHit.clear(); - stats.setKnockedDown(false); - stats.setHitRecovery(false); - stats.setBlock(false); - resetCurrentIdleState(); - } - else if (isKnockedOut()) - mAnimation->setLoopingEnabled(mCurrentHit, knockout); - return; + if (anim.empty()) + return; + if (mAnimation) + mAnimation->disable(anim); + anim.clear(); } - if (!knockout && !knockdown && !recovery && !block) - return; - - MWRender::Animation::AnimPriority priority(Priority_Knockdown); - std::string_view startKey = "start"; - std::string_view stopKey = "stop"; - if (knockout) + void CharacterController::resetCurrentJumpState() { - mHitState = isSwimming ? CharState_SwimKnockOut : CharState_KnockOut; - stats.setKnockedDown(true); + clearStateAnimation(mCurrentJump); + mJumpState = JumpState_None; } - else if (knockdown) + + void CharacterController::resetCurrentMovementState() { - mHitState = isSwimming ? CharState_SwimKnockDown : CharState_KnockDown; + clearStateAnimation(mCurrentMovement); + mMovementState = CharState_None; } - else if (recovery) + + void CharacterController::resetCurrentIdleState() { - mHitState = isSwimming ? CharState_SwimHit : CharState_Hit; - priority = Priority_Hit; + clearStateAnimation(mCurrentIdle); + mIdleState = CharState_None; } - else if (block) + + void CharacterController::resetCurrentHitState() { - mHitState = CharState_Block; - priority = Priority_Hit; - priority[MWRender::Animation::BoneGroup_LeftArm] = Priority_Block; - priority[MWRender::Animation::BoneGroup_LowerBody] = Priority_WeaponLowerBody; - startKey = "block start"; - stopKey = "block stop"; + clearStateAnimation(mCurrentHit); + mHitState = CharState_None; } - mCurrentHit = hitStateToAnimGroup(mHitState); - - if (isRecovery()) + void CharacterController::resetCurrentWeaponState() { - mCurrentHit = chooseRandomGroup(mCurrentHit); - if (mHitState == CharState_SwimHit && !mAnimation->hasAnimation(mCurrentHit)) - mCurrentHit = chooseRandomGroup(hitStateToAnimGroup(CharState_Hit)); + clearStateAnimation(mCurrentWeapon); + mUpperBodyState = UpperBodyState::None; } - if (!mAnimation->hasAnimation(mCurrentHit)) + void CharacterController::resetCurrentDeathState() { - // The hit animation is missing. Reset the current hit state and immediately cancel all states as if the animation were instantaneous. - mHitState = CharState_None; - mCurrentHit.clear(); - stats.setKnockedDown(false); - stats.setHitRecovery(false); - stats.setBlock(false); - resetCurrentIdleState(); - return; + clearStateAnimation(mCurrentDeath); + mDeathState = CharState_None; } - // Cancel upper body animations - if (isKnockedOut() || isKnockedDown()) + void CharacterController::refreshHitRecoilAnims() { - if (!mCurrentWeapon.empty()) - mAnimation->disable(mCurrentWeapon); - if (mUpperBodyState > UpperBodyState::WeaponEquipped) + auto& charClass = mPtr.getClass(); + if (!charClass.isActor()) + return; + const auto world = MWBase::Environment::get().getWorld(); + auto& stats = charClass.getCreatureStats(mPtr); + bool knockout = stats.getFatigue().getCurrent() < 0 || stats.getFatigue().getBase() == 0; + bool recovery = stats.getHitRecovery(); + bool knockdown = stats.getKnockedDown(); + bool block = stats.getBlock(); + bool isSwimming = world->isSwimming(mPtr); + + if (mHitState != CharState_None) { - mUpperBodyState = UpperBodyState::WeaponEquipped; - if (mWeaponType > ESM::Weapon::None) - mAnimation->showWeapons(true); + if (!mAnimation->isPlaying(mCurrentHit)) + { + mHitState = CharState_None; + mCurrentHit.clear(); + stats.setKnockedDown(false); + stats.setHitRecovery(false); + stats.setBlock(false); + resetCurrentIdleState(); + } + else if (isKnockedOut()) + mAnimation->setLoopingEnabled(mCurrentHit, knockout); + return; } - else if (mUpperBodyState < UpperBodyState::WeaponEquipped) + + if (!knockout && !knockdown && !recovery && !block) + return; + + MWRender::Animation::AnimPriority priority(Priority_Knockdown); + std::string_view startKey = "start"; + std::string_view stopKey = "stop"; + if (knockout) { - mUpperBodyState = UpperBodyState::None; + mHitState = isSwimming ? CharState_SwimKnockOut : CharState_KnockOut; + stats.setKnockedDown(true); + } + else if (knockdown) + { + mHitState = isSwimming ? CharState_SwimKnockDown : CharState_KnockDown; + } + else if (recovery) + { + mHitState = isSwimming ? CharState_SwimHit : CharState_Hit; + priority = Priority_Hit; + } + else if (block) + { + mHitState = CharState_Block; + priority = Priority_Hit; + priority[MWRender::Animation::BoneGroup_LeftArm] = Priority_Block; + priority[MWRender::Animation::BoneGroup_LowerBody] = Priority_WeaponLowerBody; + startKey = "block start"; + stopKey = "block stop"; } - } - mAnimation->play(mCurrentHit, priority, MWRender::Animation::BlendMask_All, true, 1, startKey, stopKey, 0.0f, ~0ul); -} + mCurrentHit = hitStateToAnimGroup(mHitState); -void CharacterController::refreshJumpAnims(JumpingState jump, bool force) -{ - if (!force && jump == mJumpState) - return; + if (isRecovery()) + { + mCurrentHit = chooseRandomGroup(mCurrentHit); + if (mHitState == CharState_SwimHit && !mAnimation->hasAnimation(mCurrentHit)) + mCurrentHit = chooseRandomGroup(hitStateToAnimGroup(CharState_Hit)); + } - if (jump == JumpState_None) - { - if (!mCurrentJump.empty()) + if (!mAnimation->hasAnimation(mCurrentHit)) + { + // The hit animation is missing. Reset the current hit state and immediately cancel all states as if the + // animation were instantaneous. + mHitState = CharState_None; + mCurrentHit.clear(); + stats.setKnockedDown(false); + stats.setHitRecovery(false); + stats.setBlock(false); resetCurrentIdleState(); - resetCurrentJumpState(); - return; - } + return; + } - std::string_view weapShortGroup = getWeaponShortGroup(mWeaponType); - std::string jumpAnimName = "jump"; - jumpAnimName += weapShortGroup; - MWRender::Animation::BlendMask jumpmask = MWRender::Animation::BlendMask_All; - if (!weapShortGroup.empty() && !mAnimation->hasAnimation(jumpAnimName)) - jumpAnimName = fallbackShortWeaponGroup("jump", &jumpmask); + // Cancel upper body animations + if (isKnockedOut() || isKnockedDown()) + { + if (!mCurrentWeapon.empty()) + mAnimation->disable(mCurrentWeapon); + if (mUpperBodyState > UpperBodyState::WeaponEquipped) + { + mUpperBodyState = UpperBodyState::WeaponEquipped; + if (mWeaponType > ESM::Weapon::None) + mAnimation->showWeapons(true); + } + else if (mUpperBodyState < UpperBodyState::WeaponEquipped) + { + mUpperBodyState = UpperBodyState::None; + } + } - if (!mAnimation->hasAnimation(jumpAnimName)) - { - if (!mCurrentJump.empty()) - resetCurrentIdleState(); - resetCurrentJumpState(); - return; + mAnimation->play( + mCurrentHit, priority, MWRender::Animation::BlendMask_All, true, 1, startKey, stopKey, 0.0f, ~0ul); } - bool startAtLoop = (jump == mJumpState); - mJumpState = jump; - clearStateAnimation(mCurrentJump); - - mCurrentJump = jumpAnimName; - if(mJumpState == JumpState_InAir) - mAnimation->play(jumpAnimName, Priority_Jump, jumpmask, false, 1.0f, startAtLoop ? "loop start" : "start", "stop", 0.f, ~0ul); - else if (mJumpState == JumpState_Landing) - mAnimation->play(jumpAnimName, Priority_Jump, jumpmask, true, 1.0f, "loop stop", "stop", 0.0f, 0); -} - -bool CharacterController::onOpen() const -{ - if (mPtr.getType() == ESM::Container::sRecordId) + void CharacterController::refreshJumpAnims(JumpingState jump, bool force) { - if (!mAnimation->hasAnimation("containeropen")) - return true; - - if (mAnimation->isPlaying("containeropen")) - return false; - - if (mAnimation->isPlaying("containerclose")) - return false; + if (!force && jump == mJumpState) + return; - mAnimation->play("containeropen", Priority_Persistent, MWRender::Animation::BlendMask_All, false, 1.0f, "start", "stop", 0.f, 0); - if (mAnimation->isPlaying("containeropen")) - return false; - } + if (jump == JumpState_None) + { + if (!mCurrentJump.empty()) + resetCurrentIdleState(); + resetCurrentJumpState(); + return; + } - return true; -} + std::string_view weapShortGroup = getWeaponShortGroup(mWeaponType); + std::string jumpAnimName = "jump"; + jumpAnimName += weapShortGroup; + MWRender::Animation::BlendMask jumpmask = MWRender::Animation::BlendMask_All; + if (!weapShortGroup.empty() && !mAnimation->hasAnimation(jumpAnimName)) + jumpAnimName = fallbackShortWeaponGroup("jump", &jumpmask); -void CharacterController::onClose() const -{ - if (mPtr.getType() == ESM::Container::sRecordId) - { - if (!mAnimation->hasAnimation("containerclose")) + if (!mAnimation->hasAnimation(jumpAnimName)) + { + if (!mCurrentJump.empty()) + resetCurrentIdleState(); + resetCurrentJumpState(); return; + } - float complete, startPoint = 0.f; - bool animPlaying = mAnimation->getInfo("containeropen", &complete); - if (animPlaying) - startPoint = 1.f - complete; + bool startAtLoop = (jump == mJumpState); + mJumpState = jump; + clearStateAnimation(mCurrentJump); - mAnimation->play("containerclose", Priority_Persistent, MWRender::Animation::BlendMask_All, false, 1.0f, "start", "stop", startPoint, 0); + mCurrentJump = jumpAnimName; + if (mJumpState == JumpState_InAir) + mAnimation->play(jumpAnimName, Priority_Jump, jumpmask, false, 1.0f, startAtLoop ? "loop start" : "start", + "stop", 0.f, ~0ul); + else if (mJumpState == JumpState_Landing) + mAnimation->play(jumpAnimName, Priority_Jump, jumpmask, true, 1.0f, "loop stop", "stop", 0.0f, 0); } -} -std::string_view CharacterController::getWeaponAnimation(int weaponType) const -{ - std::string_view weaponGroup = getWeaponType(weaponType)->mLongGroup; - if (isRealWeapon(weaponType) && !mAnimation->hasAnimation(weaponGroup)) + bool CharacterController::onOpen() const { - static const std::string_view oneHandFallback = getWeaponType(ESM::Weapon::LongBladeOneHand)->mLongGroup; - static const std::string_view twoHandFallback = getWeaponType(ESM::Weapon::LongBladeTwoHand)->mLongGroup; - - const ESM::WeaponType* weapInfo = getWeaponType(weaponType); - - // For real two-handed melee weapons use 2h swords animations as fallback, otherwise use the 1h ones - if (weapInfo->mFlags & ESM::WeaponType::TwoHanded && weapInfo->mWeaponClass == ESM::WeaponType::Melee) - weaponGroup = twoHandFallback; - else - weaponGroup = oneHandFallback; - } - else if (weaponType == ESM::Weapon::HandToHand && !mPtr.getClass().isBipedal(mPtr)) - return "attack1"; + if (mPtr.getType() == ESM::Container::sRecordId) + { + if (!mAnimation->hasAnimation("containeropen")) + return true; - return weaponGroup; -} + if (mAnimation->isPlaying("containeropen")) + return false; -std::string_view CharacterController::getWeaponShortGroup(int weaponType) const -{ - if (weaponType == ESM::Weapon::HandToHand && !mPtr.getClass().isBipedal(mPtr)) - return {}; - return getWeaponType(weaponType)->mShortGroup; -} + if (mAnimation->isPlaying("containerclose")) + return false; -std::string CharacterController::fallbackShortWeaponGroup(const std::string& baseGroupName, MWRender::Animation::BlendMask* blendMask) const -{ - if (!isRealWeapon(mWeaponType)) - { - if (blendMask != nullptr) - *blendMask = MWRender::Animation::BlendMask_LowerBody; + mAnimation->play("containeropen", Priority_Persistent, MWRender::Animation::BlendMask_All, false, 1.0f, + "start", "stop", 0.f, 0); + if (mAnimation->isPlaying("containeropen")) + return false; + } - return baseGroupName; + return true; } - static const std::string_view oneHandFallback = getWeaponShortGroup(ESM::Weapon::LongBladeOneHand); - static const std::string_view twoHandFallback = getWeaponShortGroup(ESM::Weapon::LongBladeTwoHand); - - std::string groupName = baseGroupName; - const ESM::WeaponType* weapInfo = getWeaponType(mWeaponType); + void CharacterController::onClose() const + { + if (mPtr.getType() == ESM::Container::sRecordId) + { + if (!mAnimation->hasAnimation("containerclose")) + return; - // For real two-handed melee weapons use 2h swords animations as fallback, otherwise use the 1h ones - if (weapInfo->mFlags & ESM::WeaponType::TwoHanded && weapInfo->mWeaponClass == ESM::WeaponType::Melee) - groupName += twoHandFallback; - else - groupName += oneHandFallback; + float complete, startPoint = 0.f; + bool animPlaying = mAnimation->getInfo("containeropen", &complete); + if (animPlaying) + startPoint = 1.f - complete; - // Special case for crossbows - we shouls apply 1h animations a fallback only for lower body - if (mWeaponType == ESM::Weapon::MarksmanCrossbow && blendMask != nullptr) - *blendMask = MWRender::Animation::BlendMask_LowerBody; + mAnimation->play("containerclose", Priority_Persistent, MWRender::Animation::BlendMask_All, false, 1.0f, + "start", "stop", startPoint, 0); + } + } - if (!mAnimation->hasAnimation(groupName)) + std::string_view CharacterController::getWeaponAnimation(int weaponType) const { - groupName = baseGroupName; - if (blendMask != nullptr) - *blendMask = MWRender::Animation::BlendMask_LowerBody; - } + std::string_view weaponGroup = getWeaponType(weaponType)->mLongGroup; + if (isRealWeapon(weaponType) && !mAnimation->hasAnimation(weaponGroup)) + { + static const std::string_view oneHandFallback = getWeaponType(ESM::Weapon::LongBladeOneHand)->mLongGroup; + static const std::string_view twoHandFallback = getWeaponType(ESM::Weapon::LongBladeTwoHand)->mLongGroup; - return groupName; -} + const ESM::WeaponType* weapInfo = getWeaponType(weaponType); -void CharacterController::refreshMovementAnims(CharacterState movement, bool force) -{ - if (movement == mMovementState && !force) - return; + // For real two-handed melee weapons use 2h swords animations as fallback, otherwise use the 1h ones + if (weapInfo->mFlags & ESM::WeaponType::TwoHanded && weapInfo->mWeaponClass == ESM::WeaponType::Melee) + weaponGroup = twoHandFallback; + else + weaponGroup = oneHandFallback; + } + else if (weaponType == ESM::Weapon::HandToHand && !mPtr.getClass().isBipedal(mPtr)) + return "attack1"; - std::string_view movementAnimGroup = movementStateToAnimGroup(movement); + return weaponGroup; + } - if (movementAnimGroup.empty()) + std::string_view CharacterController::getWeaponShortGroup(int weaponType) const { - if (!mCurrentMovement.empty()) - resetCurrentIdleState(); - resetCurrentMovementState(); - return; + if (weaponType == ESM::Weapon::HandToHand && !mPtr.getClass().isBipedal(mPtr)) + return {}; + return getWeaponType(weaponType)->mShortGroup; } - std::string movementAnimName{movementAnimGroup}; - mMovementState = movement; - std::string::size_type swimpos = movementAnimName.find("swim"); - if (!mAnimation->hasAnimation(movementAnimName)) + std::string CharacterController::fallbackShortWeaponGroup( + const std::string& baseGroupName, MWRender::Animation::BlendMask* blendMask) const { - if (swimpos != std::string::npos) + if (!isRealWeapon(mWeaponType)) { - movementAnimName.erase(swimpos, 4); - swimpos = std::string::npos; - } - } + if (blendMask != nullptr) + *blendMask = MWRender::Animation::BlendMask_LowerBody; - MWRender::Animation::BlendMask movemask = MWRender::Animation::BlendMask_All; + return baseGroupName; + } - std::string_view weapShortGroup = getWeaponShortGroup(mWeaponType); + static const std::string_view oneHandFallback = getWeaponShortGroup(ESM::Weapon::LongBladeOneHand); + static const std::string_view twoHandFallback = getWeaponShortGroup(ESM::Weapon::LongBladeTwoHand); - // Non-biped creatures don't use spellcasting-specific movement animations. - if(!isRealWeapon(mWeaponType) && !mPtr.getClass().isBipedal(mPtr)) - weapShortGroup = {}; + std::string groupName = baseGroupName; + const ESM::WeaponType* weapInfo = getWeaponType(mWeaponType); - if (swimpos == std::string::npos && !weapShortGroup.empty()) - { - std::string weapMovementAnimName; - // Spellcasting stance turning is a special case - if (mWeaponType == ESM::Weapon::Spell && isTurning()) - { - weapMovementAnimName = weapShortGroup; - weapMovementAnimName += movementAnimName; - } + // For real two-handed melee weapons use 2h swords animations as fallback, otherwise use the 1h ones + if (weapInfo->mFlags & ESM::WeaponType::TwoHanded && weapInfo->mWeaponClass == ESM::WeaponType::Melee) + groupName += twoHandFallback; else + groupName += oneHandFallback; + + // Special case for crossbows - we shouls apply 1h animations a fallback only for lower body + if (mWeaponType == ESM::Weapon::MarksmanCrossbow && blendMask != nullptr) + *blendMask = MWRender::Animation::BlendMask_LowerBody; + + if (!mAnimation->hasAnimation(groupName)) { - weapMovementAnimName = movementAnimName; - weapMovementAnimName += weapShortGroup; + groupName = baseGroupName; + if (blendMask != nullptr) + *blendMask = MWRender::Animation::BlendMask_LowerBody; } - if (!mAnimation->hasAnimation(weapMovementAnimName)) - weapMovementAnimName = fallbackShortWeaponGroup(movementAnimName, &movemask); - - movementAnimName = weapMovementAnimName; + return groupName; } - if (!mAnimation->hasAnimation(movementAnimName)) + void CharacterController::refreshMovementAnims(CharacterState movement, bool force) { - std::string::size_type runpos = movementAnimName.find("run"); - if (runpos != std::string::npos) - movementAnimName.replace(runpos, 3, "walk"); + if (movement == mMovementState && !force) + return; - if (!mAnimation->hasAnimation(movementAnimName)) + std::string_view movementAnimGroup = movementStateToAnimGroup(movement); + + if (movementAnimGroup.empty()) { if (!mCurrentMovement.empty()) resetCurrentIdleState(); resetCurrentMovementState(); return; } - } + std::string movementAnimName{ movementAnimGroup }; - // If we're playing the same animation, start it from the point it ended - float startpoint = 0.f; - if (!mCurrentMovement.empty() && movementAnimName == mCurrentMovement) - mAnimation->getInfo(mCurrentMovement, &startpoint); + mMovementState = movement; + std::string::size_type swimpos = movementAnimName.find("swim"); + if (!mAnimation->hasAnimation(movementAnimName)) + { + if (swimpos != std::string::npos) + { + movementAnimName.erase(swimpos, 4); + swimpos = std::string::npos; + } + } - mMovementAnimationControlled = true; + MWRender::Animation::BlendMask movemask = MWRender::Animation::BlendMask_All; - clearStateAnimation(mCurrentMovement); - mCurrentMovement = movementAnimName; + std::string_view weapShortGroup = getWeaponShortGroup(mWeaponType); - // For non-flying creatures, MW uses the Walk animation to calculate the animation velocity - // even if we are running. This must be replicated, otherwise the observed speed would differ drastically. - mAdjustMovementAnimSpeed = true; - if (mPtr.getClass().getType() == ESM::Creature::sRecordId && !(mPtr.get()->mBase->mFlags & ESM::Creature::Flies)) - { - CharacterState walkState = runStateToWalkState(mMovementState); - std::string_view anim = movementStateToAnimGroup(walkState); + // Non-biped creatures don't use spellcasting-specific movement animations. + if (!isRealWeapon(mWeaponType) && !mPtr.getClass().isBipedal(mPtr)) + weapShortGroup = {}; - mMovementAnimSpeed = mAnimation->getVelocity(anim); - if (mMovementAnimSpeed <= 1.0f) + if (swimpos == std::string::npos && !weapShortGroup.empty()) { - // Another bug: when using a fallback animation (e.g. RunForward as fallback to SwimRunForward), - // then the equivalent Walk animation will not use a fallback, and if that animation doesn't exist - // we will play without any scaling. - // Makes the speed attribute of most water creatures totally useless. - // And again, this can not be fixed without patching game data. - mAdjustMovementAnimSpeed = false; - mMovementAnimSpeed = 1.f; + std::string weapMovementAnimName; + // Spellcasting stance turning is a special case + if (mWeaponType == ESM::Weapon::Spell && isTurning()) + { + weapMovementAnimName = weapShortGroup; + weapMovementAnimName += movementAnimName; + } + else + { + weapMovementAnimName = movementAnimName; + weapMovementAnimName += weapShortGroup; + } + + if (!mAnimation->hasAnimation(weapMovementAnimName)) + weapMovementAnimName = fallbackShortWeaponGroup(movementAnimName, &movemask); + + movementAnimName = weapMovementAnimName; } - } - else - { - mMovementAnimSpeed = mAnimation->getVelocity(mCurrentMovement); - if (mMovementAnimSpeed <= 1.0f) + if (!mAnimation->hasAnimation(movementAnimName)) { - // The first person anims don't have any velocity to calculate a speed multiplier from. - // We use the third person velocities instead. - // FIXME: should be pulled from the actual animation, but it is not presently loaded. - bool sneaking = mMovementState == CharState_SneakForward || mMovementState == CharState_SneakBack - || mMovementState == CharState_SneakLeft || mMovementState == CharState_SneakRight; - mMovementAnimSpeed = (sneaking ? 33.5452f : (isRunning() ? 222.857f : 154.064f)); - mMovementAnimationControlled = false; + std::string::size_type runpos = movementAnimName.find("run"); + if (runpos != std::string::npos) + movementAnimName.replace(runpos, 3, "walk"); + + if (!mAnimation->hasAnimation(movementAnimName)) + { + if (!mCurrentMovement.empty()) + resetCurrentIdleState(); + resetCurrentMovementState(); + return; + } } - } - mAnimation->play(mCurrentMovement, Priority_Movement, movemask, false, 1.f, "start", "stop", startpoint, ~0ul, true); -} + // If we're playing the same animation, start it from the point it ended + float startpoint = 0.f; + if (!mCurrentMovement.empty() && movementAnimName == mCurrentMovement) + mAnimation->getInfo(mCurrentMovement, &startpoint); -void CharacterController::refreshIdleAnims(CharacterState idle, bool force) -{ - // FIXME: if one of the below states is close to their last animation frame (i.e. will be disabled in the coming update), - // the idle animation should be displayed - if (((mUpperBodyState != UpperBodyState::None && mUpperBodyState != UpperBodyState::WeaponEquipped) - || mMovementState != CharState_None || mHitState != CharState_None) && !mPtr.getClass().isBipedal(mPtr)) - { - resetCurrentIdleState(); - return; - } + mMovementAnimationControlled = true; - if (!force && idle == mIdleState && (mAnimation->isPlaying(mCurrentIdle) || !mAnimQueue.empty())) - return; + clearStateAnimation(mCurrentMovement); + mCurrentMovement = movementAnimName; - mIdleState = idle; + // For non-flying creatures, MW uses the Walk animation to calculate the animation velocity + // even if we are running. This must be replicated, otherwise the observed speed would differ drastically. + mAdjustMovementAnimSpeed = true; + if (mPtr.getClass().getType() == ESM::Creature::sRecordId + && !(mPtr.get()->mBase->mFlags & ESM::Creature::Flies)) + { + CharacterState walkState = runStateToWalkState(mMovementState); + std::string_view anim = movementStateToAnimGroup(walkState); - std::string idleGroup = idleStateToAnimGroup(mIdleState); - if (idleGroup.empty()) - { - resetCurrentIdleState(); - return; - } + mMovementAnimSpeed = mAnimation->getVelocity(anim); + if (mMovementAnimSpeed <= 1.0f) + { + // Another bug: when using a fallback animation (e.g. RunForward as fallback to SwimRunForward), + // then the equivalent Walk animation will not use a fallback, and if that animation doesn't exist + // we will play without any scaling. + // Makes the speed attribute of most water creatures totally useless. + // And again, this can not be fixed without patching game data. + mAdjustMovementAnimSpeed = false; + mMovementAnimSpeed = 1.f; + } + } + else + { + mMovementAnimSpeed = mAnimation->getVelocity(mCurrentMovement); - MWRender::Animation::AnimPriority priority = getIdlePriority(mIdleState); - size_t numLoops = std::numeric_limits::max(); + if (mMovementAnimSpeed <= 1.0f) + { + // The first person anims don't have any velocity to calculate a speed multiplier from. + // We use the third person velocities instead. + // FIXME: should be pulled from the actual animation, but it is not presently loaded. + bool sneaking = mMovementState == CharState_SneakForward || mMovementState == CharState_SneakBack + || mMovementState == CharState_SneakLeft || mMovementState == CharState_SneakRight; + mMovementAnimSpeed = (sneaking ? 33.5452f : (isRunning() ? 222.857f : 154.064f)); + mMovementAnimationControlled = false; + } + } - // Only play "idleswim" or "idlesneak" if they exist. Otherwise, fallback to - // "idle"+weapon or "idle". - bool fallback = mIdleState != CharState_Idle && !mAnimation->hasAnimation(idleGroup); - if (fallback) - { - priority = getIdlePriority(CharState_Idle); - idleGroup = idleStateToAnimGroup(CharState_Idle); + mAnimation->play( + mCurrentMovement, Priority_Movement, movemask, false, 1.f, "start", "stop", startpoint, ~0ul, true); } - if (fallback || mIdleState == CharState_Idle || mIdleState == CharState_SpecialIdle) + void CharacterController::refreshIdleAnims(CharacterState idle, bool force) { - std::string_view weapShortGroup = getWeaponShortGroup(mWeaponType); - if (!weapShortGroup.empty()) + // FIXME: if one of the below states is close to their last animation frame (i.e. will be disabled in the coming + // update), the idle animation should be displayed + if (((mUpperBodyState != UpperBodyState::None && mUpperBodyState != UpperBodyState::WeaponEquipped) + || mMovementState != CharState_None || mHitState != CharState_None) + && !mPtr.getClass().isBipedal(mPtr)) { - std::string weapIdleGroup = idleGroup; - weapIdleGroup += weapShortGroup; - if (!mAnimation->hasAnimation(weapIdleGroup)) - weapIdleGroup = fallbackShortWeaponGroup(idleGroup); - idleGroup = weapIdleGroup; + resetCurrentIdleState(); + return; + } - // play until the Loop Stop key 2 to 5 times, then play until the Stop key - // this replicates original engine behavior for the "Idle1h" 1st-person animation - auto& prng = MWBase::Environment::get().getWorld()->getPrng(); - numLoops = 1 + Misc::Rng::rollDice(4, prng); + if (!force && idle == mIdleState && (mAnimation->isPlaying(mCurrentIdle) || !mAnimQueue.empty())) + return; + + mIdleState = idle; + + std::string idleGroup = idleStateToAnimGroup(mIdleState); + if (idleGroup.empty()) + { + resetCurrentIdleState(); + return; } - } - if (!mAnimation->hasAnimation(idleGroup)) - { - resetCurrentIdleState(); - return; - } + MWRender::Animation::AnimPriority priority = getIdlePriority(mIdleState); + size_t numLoops = std::numeric_limits::max(); - float startPoint = 0.f; - // There is no need to restart anim if the new and old anims are the same. - // Just update the number of loops. - if (mCurrentIdle == idleGroup) - mAnimation->getInfo(mCurrentIdle, &startPoint); + // Only play "idleswim" or "idlesneak" if they exist. Otherwise, fallback to + // "idle"+weapon or "idle". + bool fallback = mIdleState != CharState_Idle && !mAnimation->hasAnimation(idleGroup); + if (fallback) + { + priority = getIdlePriority(CharState_Idle); + idleGroup = idleStateToAnimGroup(CharState_Idle); + } - clearStateAnimation(mCurrentIdle); - mCurrentIdle = idleGroup; - mAnimation->play(mCurrentIdle, priority, MWRender::Animation::BlendMask_All, false, 1.0f, "start", "stop", startPoint, numLoops, true); -} + if (fallback || mIdleState == CharState_Idle || mIdleState == CharState_SpecialIdle) + { + std::string_view weapShortGroup = getWeaponShortGroup(mWeaponType); + if (!weapShortGroup.empty()) + { + std::string weapIdleGroup = idleGroup; + weapIdleGroup += weapShortGroup; + if (!mAnimation->hasAnimation(weapIdleGroup)) + weapIdleGroup = fallbackShortWeaponGroup(idleGroup); + idleGroup = weapIdleGroup; + + // play until the Loop Stop key 2 to 5 times, then play until the Stop key + // this replicates original engine behavior for the "Idle1h" 1st-person animation + auto& prng = MWBase::Environment::get().getWorld()->getPrng(); + numLoops = 1 + Misc::Rng::rollDice(4, prng); + } + } -void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterState movement, JumpingState jump, bool force) -{ - // If the current animation is persistent, do not touch it - if (isPersistentAnimPlaying()) - return; + if (!mAnimation->hasAnimation(idleGroup)) + { + resetCurrentIdleState(); + return; + } - refreshHitRecoilAnims(); - refreshJumpAnims(jump, force); - refreshMovementAnims(movement, force); + float startPoint = 0.f; + // There is no need to restart anim if the new and old anims are the same. + // Just update the number of loops. + if (mCurrentIdle == idleGroup) + mAnimation->getInfo(mCurrentIdle, &startPoint); - // idle handled last as it can depend on the other states - refreshIdleAnims(idle, force); -} + clearStateAnimation(mCurrentIdle); + mCurrentIdle = idleGroup; + mAnimation->play(mCurrentIdle, priority, MWRender::Animation::BlendMask_All, false, 1.0f, "start", "stop", + startPoint, numLoops, true); + } -void CharacterController::playDeath(float startpoint, CharacterState death) -{ - mDeathState = death; - mCurrentDeath = deathStateToAnimGroup(mDeathState); - mPtr.getClass().getCreatureStats(mPtr).setDeathAnimation(mDeathState - CharState_Death1); - - // For dead actors, refreshCurrentAnims is no longer called, so we need to disable the movement state manually. - // Note that these animations wouldn't actually be visible (due to the Death animation's priority being higher). - // However, they could still trigger text keys, such as Hit events, or sounds. - resetCurrentMovementState(); - resetCurrentWeaponState(); - resetCurrentHitState(); - resetCurrentIdleState(); - resetCurrentJumpState(); - mMovementAnimationControlled = true; - - mAnimation->play(mCurrentDeath, Priority_Death, MWRender::Animation::BlendMask_All, - false, 1.0f, "start", "stop", startpoint, 0); -} + void CharacterController::refreshCurrentAnims( + CharacterState idle, CharacterState movement, JumpingState jump, bool force) + { + // If the current animation is persistent, do not touch it + if (isPersistentAnimPlaying()) + return; -CharacterState CharacterController::chooseRandomDeathState() const -{ - int selected=0; - chooseRandomGroup("death", &selected); - return static_cast(CharState_Death1 + (selected-1)); -} + refreshHitRecoilAnims(); + refreshJumpAnims(jump, force); + refreshMovementAnims(movement, force); -void CharacterController::playRandomDeath(float startpoint) -{ - if (mPtr == getPlayer()) + // idle handled last as it can depend on the other states + refreshIdleAnims(idle, force); + } + + void CharacterController::playDeath(float startpoint, CharacterState death) { - // The first-person animations do not include death, so we need to - // force-switch to third person before playing the death animation. - MWBase::Environment::get().getWorld()->useDeathCamera(); + mDeathState = death; + mCurrentDeath = deathStateToAnimGroup(mDeathState); + mPtr.getClass().getCreatureStats(mPtr).setDeathAnimation(mDeathState - CharState_Death1); + + // For dead actors, refreshCurrentAnims is no longer called, so we need to disable the movement state manually. + // Note that these animations wouldn't actually be visible (due to the Death animation's priority being higher). + // However, they could still trigger text keys, such as Hit events, or sounds. + resetCurrentMovementState(); + resetCurrentWeaponState(); + resetCurrentHitState(); + resetCurrentIdleState(); + resetCurrentJumpState(); + mMovementAnimationControlled = true; + + mAnimation->play(mCurrentDeath, Priority_Death, MWRender::Animation::BlendMask_All, false, 1.0f, "start", + "stop", startpoint, 0); } - mDeathState = hitStateToDeathState(mHitState); - if (mDeathState == CharState_None && MWBase::Environment::get().getWorld()->isSwimming(mPtr)) - mDeathState = CharState_SwimDeath; + CharacterState CharacterController::chooseRandomDeathState() const + { + int selected = 0; + chooseRandomGroup("death", &selected); + return static_cast(CharState_Death1 + (selected - 1)); + } - if (mDeathState == CharState_None || !mAnimation->hasAnimation(deathStateToAnimGroup(mDeathState))) - mDeathState = chooseRandomDeathState(); + void CharacterController::playRandomDeath(float startpoint) + { + if (mPtr == getPlayer()) + { + // The first-person animations do not include death, so we need to + // force-switch to third person before playing the death animation. + MWBase::Environment::get().getWorld()->useDeathCamera(); + } - // Do not interrupt scripted animation by death - if (isPersistentAnimPlaying()) - return; + mDeathState = hitStateToDeathState(mHitState); + if (mDeathState == CharState_None && MWBase::Environment::get().getWorld()->isSwimming(mPtr)) + mDeathState = CharState_SwimDeath; - playDeath(startpoint, mDeathState); -} + if (mDeathState == CharState_None || !mAnimation->hasAnimation(deathStateToAnimGroup(mDeathState))) + mDeathState = chooseRandomDeathState(); -std::string CharacterController::chooseRandomAttackAnimation() const -{ - std::string result; - bool isSwimming = MWBase::Environment::get().getWorld()->isSwimming(mPtr); + // Do not interrupt scripted animation by death + if (isPersistentAnimPlaying()) + return; - if (isSwimming) - result = chooseRandomGroup("swimattack"); + playDeath(startpoint, mDeathState); + } - if (!isSwimming || !mAnimation->hasAnimation(result)) - result = chooseRandomGroup("attack"); + std::string CharacterController::chooseRandomAttackAnimation() const + { + std::string result; + bool isSwimming = MWBase::Environment::get().getWorld()->isSwimming(mPtr); - return result; -} + if (isSwimming) + result = chooseRandomGroup("swimattack"); -CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim) - : mPtr(ptr) - , mAnimation(anim) -{ - if(!mAnimation) - return; + if (!isSwimming || !mAnimation->hasAnimation(result)) + result = chooseRandomGroup("attack"); - mAnimation->setTextKeyListener(this); + return result; + } - const MWWorld::Class &cls = mPtr.getClass(); - if(cls.isActor()) + CharacterController::CharacterController(const MWWorld::Ptr& ptr, MWRender::Animation* anim) + : mPtr(ptr) + , mAnimation(anim) { - /* Accumulate along X/Y only for now, until we can figure out how we should - * handle knockout and death which moves the character down. */ - mAnimation->setAccumulation(osg::Vec3f(1.0f, 1.0f, 0.0f)); + if (!mAnimation) + return; - if (cls.hasInventoryStore(mPtr)) + mAnimation->setTextKeyListener(this); + + const MWWorld::Class& cls = mPtr.getClass(); + if (cls.isActor()) { - getActiveWeapon(mPtr, &mWeaponType); - if (mWeaponType != ESM::Weapon::None) + /* Accumulate along X/Y only for now, until we can figure out how we should + * handle knockout and death which moves the character down. */ + mAnimation->setAccumulation(osg::Vec3f(1.0f, 1.0f, 0.0f)); + + if (cls.hasInventoryStore(mPtr)) { - mUpperBodyState = UpperBodyState::WeaponEquipped; - mCurrentWeapon = getWeaponAnimation(mWeaponType); + getActiveWeapon(mPtr, &mWeaponType); + if (mWeaponType != ESM::Weapon::None) + { + mUpperBodyState = UpperBodyState::WeaponEquipped; + mCurrentWeapon = getWeaponAnimation(mWeaponType); + } + + if (mWeaponType != ESM::Weapon::None && mWeaponType != ESM::Weapon::Spell + && mWeaponType != ESM::Weapon::HandToHand) + { + mAnimation->showWeapons(true); + // Note: controllers for ranged weapon should use time for beginning of animation to play shooting + // properly, for other weapons they should use absolute time. Some mods rely on this behaviour (to + // rotate throwing projectiles, for example) + ESM::WeaponType::Class weaponClass = getWeaponType(mWeaponType)->mWeaponClass; + bool useRelativeDuration = weaponClass == ESM::WeaponType::Ranged; + mAnimation->setWeaponGroup(mCurrentWeapon, useRelativeDuration); + } + + mAnimation->showCarriedLeft(updateCarriedLeftVisible(mWeaponType)); } - if(mWeaponType != ESM::Weapon::None && mWeaponType != ESM::Weapon::Spell && mWeaponType != ESM::Weapon::HandToHand) + if (!cls.getCreatureStats(mPtr).isDead()) { - mAnimation->showWeapons(true); - // Note: controllers for ranged weapon should use time for beginning of animation to play shooting properly, - // for other weapons they should use absolute time. Some mods rely on this behaviour (to rotate throwing projectiles, for example) - ESM::WeaponType::Class weaponClass = getWeaponType(mWeaponType)->mWeaponClass; - bool useRelativeDuration = weaponClass == ESM::WeaponType::Ranged; - mAnimation->setWeaponGroup(mCurrentWeapon, useRelativeDuration); + mIdleState = CharState_Idle; + if (cls.getCreatureStats(mPtr).getFallHeight() > 0) + mJumpState = JumpState_InAir; } + else + { + const MWMechanics::CreatureStats& cStats = mPtr.getClass().getCreatureStats(mPtr); + if (cStats.isDeathAnimationFinished()) + { + // Set the death state, but don't play it yet + // We will play it in the first frame, but only if no script set the skipAnim flag + signed char deathanim = cStats.getDeathAnimation(); + if (deathanim == -1) + mDeathState = chooseRandomDeathState(); + else + mDeathState = static_cast(CharState_Death1 + deathanim); - mAnimation->showCarriedLeft(updateCarriedLeftVisible(mWeaponType)); - } - - if(!cls.getCreatureStats(mPtr).isDead()) - { - mIdleState = CharState_Idle; - if (cls.getCreatureStats(mPtr).getFallHeight() > 0) - mJumpState = JumpState_InAir; + mFloatToSurface = false; + } + // else: nothing to do, will detect death in the next frame and start playing death animation + } } else { - const MWMechanics::CreatureStats& cStats = mPtr.getClass().getCreatureStats(mPtr); - if (cStats.isDeathAnimationFinished()) - { - // Set the death state, but don't play it yet - // We will play it in the first frame, but only if no script set the skipAnim flag - signed char deathanim = cStats.getDeathAnimation(); - if (deathanim == -1) - mDeathState = chooseRandomDeathState(); - else - mDeathState = static_cast(CharState_Death1 + deathanim); + /* Don't accumulate with non-actors. */ + mAnimation->setAccumulation(osg::Vec3f(0.f, 0.f, 0.f)); - mFloatToSurface = false; - } - // else: nothing to do, will detect death in the next frame and start playing death animation + mIdleState = CharState_Idle; } - } - else - { - /* Don't accumulate with non-actors. */ - mAnimation->setAccumulation(osg::Vec3f(0.f, 0.f, 0.f)); - - mIdleState = CharState_Idle; - } - - // Do not update animation status for dead actors - if(mDeathState == CharState_None && (!cls.isActor() || !cls.getCreatureStats(mPtr).isDead())) - refreshCurrentAnims(mIdleState, mMovementState, mJumpState, true); - mAnimation->runAnimation(0.f); + // Do not update animation status for dead actors + if (mDeathState == CharState_None && (!cls.isActor() || !cls.getCreatureStats(mPtr).isDead())) + refreshCurrentAnims(mIdleState, mMovementState, mJumpState, true); - unpersistAnimationState(); -} + mAnimation->runAnimation(0.f); -CharacterController::~CharacterController() -{ - if (mAnimation) - { - persistAnimationState(); - mAnimation->setTextKeyListener(nullptr); + unpersistAnimationState(); } -} - -void CharacterController::handleTextKey(std::string_view groupname, SceneUtil::TextKeyMap::ConstIterator key, const SceneUtil::TextKeyMap& map) -{ - std::string_view evt = key->second; - if (evt.substr(0, 7) == "sound: ") + CharacterController::~CharacterController() { - MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); - sndMgr->playSound3D(mPtr, evt.substr(7), 1.0f, 1.0f); - return; + if (mAnimation) + { + persistAnimationState(); + mAnimation->setTextKeyListener(nullptr); + } } - auto& charClass = mPtr.getClass(); - if (evt.substr(0, 10) == "soundgen: ") + void CharacterController::handleTextKey( + std::string_view groupname, SceneUtil::TextKeyMap::ConstIterator key, const SceneUtil::TextKeyMap& map) { - std::string_view soundgen = evt.substr(10); + std::string_view evt = key->second; - // The event can optionally contain volume and pitch modifiers - float volume=1.f, pitch=1.f; - if (soundgen.find(' ') != std::string::npos) + if (evt.substr(0, 7) == "sound: ") { - std::vector tokens; - Misc::StringUtils::split(soundgen, tokens); - soundgen = tokens[0]; - if (tokens.size() >= 2) - { - std::stringstream stream; - stream << tokens[1]; - stream >> volume; - } - if (tokens.size() >= 3) - { - std::stringstream stream; - stream << tokens[2]; - stream >> pitch; - } + MWBase::SoundManager* sndMgr = MWBase::Environment::get().getSoundManager(); + sndMgr->playSound3D(mPtr, evt.substr(7), 1.0f, 1.0f); + return; } - std::string_view sound = charClass.getSoundIdFromSndGen(mPtr, soundgen); - if(!sound.empty()) + auto& charClass = mPtr.getClass(); + if (evt.substr(0, 10) == "soundgen: ") { - MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); - if (soundgen == "left" || soundgen == "right") + std::string_view soundgen = evt.substr(10); + + // The event can optionally contain volume and pitch modifiers + float volume = 1.f, pitch = 1.f; + if (soundgen.find(' ') != std::string::npos) { - sndMgr->playSound3D(mPtr, sound, volume, pitch, MWSound::Type::Foot, - MWSound::PlayMode::NoPlayerLocal); + std::vector tokens; + Misc::StringUtils::split(soundgen, tokens); + soundgen = tokens[0]; + if (tokens.size() >= 2) + { + std::stringstream stream; + stream << tokens[1]; + stream >> volume; + } + if (tokens.size() >= 3) + { + std::stringstream stream; + stream << tokens[2]; + stream >> pitch; + } } - else + + std::string_view sound = charClass.getSoundIdFromSndGen(mPtr, soundgen); + if (!sound.empty()) { - sndMgr->playSound3D(mPtr, sound, volume, pitch); + MWBase::SoundManager* sndMgr = MWBase::Environment::get().getSoundManager(); + if (soundgen == "left" || soundgen == "right") + { + sndMgr->playSound3D( + mPtr, sound, volume, pitch, MWSound::Type::Foot, MWSound::PlayMode::NoPlayerLocal); + } + else + { + sndMgr->playSound3D(mPtr, sound, volume, pitch); + } } + return; } - return; - } - if (evt.substr(0, groupname.size()) != groupname || evt.substr(groupname.size(), 2) != ": ") - { - // Not ours, skip it - return; - } + if (evt.substr(0, groupname.size()) != groupname || evt.substr(groupname.size(), 2) != ": ") + { + // Not ours, skip it + return; + } - std::string_view action = evt.substr(groupname.size() + 2); - if (action == "equip attach") - { - if (groupname == "shield") - mAnimation->showCarriedLeft(true); - else - mAnimation->showWeapons(true); - } - else if (action == "unequip detach") - { - if (groupname == "shield") - mAnimation->showCarriedLeft(false); - else - mAnimation->showWeapons(false); - } - else if (action == "chop hit") - charClass.hit(mPtr, mAttackStrength, ESM::Weapon::AT_Chop, mAttackVictim, mAttackHitPos, mAttackSuccess); - else if (action == "slash hit") - charClass.hit(mPtr, mAttackStrength, ESM::Weapon::AT_Slash, mAttackVictim, mAttackHitPos, mAttackSuccess); - else if (action == "thrust hit") - charClass.hit(mPtr, mAttackStrength, ESM::Weapon::AT_Thrust, mAttackVictim, mAttackHitPos, mAttackSuccess); - else if (action == "hit") - { - if (groupname == "attack1" || groupname == "swimattack1") + std::string_view action = evt.substr(groupname.size() + 2); + if (action == "equip attach") + { + if (groupname == "shield") + mAnimation->showCarriedLeft(true); + else + mAnimation->showWeapons(true); + } + else if (action == "unequip detach") + { + if (groupname == "shield") + mAnimation->showCarriedLeft(false); + else + mAnimation->showWeapons(false); + } + else if (action == "chop hit") charClass.hit(mPtr, mAttackStrength, ESM::Weapon::AT_Chop, mAttackVictim, mAttackHitPos, mAttackSuccess); - else if (groupname == "attack2" || groupname == "swimattack2") + else if (action == "slash hit") charClass.hit(mPtr, mAttackStrength, ESM::Weapon::AT_Slash, mAttackVictim, mAttackHitPos, mAttackSuccess); - else if (groupname == "attack3" || groupname == "swimattack3") + else if (action == "thrust hit") charClass.hit(mPtr, mAttackStrength, ESM::Weapon::AT_Thrust, mAttackVictim, mAttackHitPos, mAttackSuccess); - else - charClass.hit(mPtr, mAttackStrength, -1, mAttackVictim, mAttackHitPos, mAttackSuccess); - } - else if (isRandomAttackAnimation(groupname) && action == "start") - { - std::multimap::const_iterator hitKey = key; - - // Not all animations have a hit key defined. If there is none, the hit happens with the start key. - bool hasHitKey = false; - while (hitKey != map.end()) + else if (action == "hit") + { + if (groupname == "attack1" || groupname == "swimattack1") + charClass.hit( + mPtr, mAttackStrength, ESM::Weapon::AT_Chop, mAttackVictim, mAttackHitPos, mAttackSuccess); + else if (groupname == "attack2" || groupname == "swimattack2") + charClass.hit( + mPtr, mAttackStrength, ESM::Weapon::AT_Slash, mAttackVictim, mAttackHitPos, mAttackSuccess); + else if (groupname == "attack3" || groupname == "swimattack3") + charClass.hit( + mPtr, mAttackStrength, ESM::Weapon::AT_Thrust, mAttackVictim, mAttackHitPos, mAttackSuccess); + else + charClass.hit(mPtr, mAttackStrength, -1, mAttackVictim, mAttackHitPos, mAttackSuccess); + } + else if (isRandomAttackAnimation(groupname) && action == "start") { - if (hitKey->second.starts_with(groupname)) + std::multimap::const_iterator hitKey = key; + + // Not all animations have a hit key defined. If there is none, the hit happens with the start key. + bool hasHitKey = false; + while (hitKey != map.end()) { - std::string_view suffix = std::string_view(hitKey->second).substr(groupname.size()); - if (suffix == ": hit") + if (hitKey->second.starts_with(groupname)) { - hasHitKey = true; - break; + std::string_view suffix = std::string_view(hitKey->second).substr(groupname.size()); + if (suffix == ": hit") + { + hasHitKey = true; + break; + } + if (suffix == ": stop") + break; } - if (suffix == ": stop") - break; + ++hitKey; + } + if (!hasHitKey) + { + if (groupname == "attack1" || groupname == "swimattack1") + charClass.hit( + mPtr, mAttackStrength, ESM::Weapon::AT_Chop, mAttackVictim, mAttackHitPos, mAttackSuccess); + else if (groupname == "attack2" || groupname == "swimattack2") + charClass.hit( + mPtr, mAttackStrength, ESM::Weapon::AT_Slash, mAttackVictim, mAttackHitPos, mAttackSuccess); + else if (groupname == "attack3" || groupname == "swimattack3") + charClass.hit( + mPtr, mAttackStrength, ESM::Weapon::AT_Thrust, mAttackVictim, mAttackHitPos, mAttackSuccess); } - ++hitKey; } - if (!hasHitKey) + else if (action == "shoot attach") + mAnimation->attachArrow(); + else if (action == "shoot release") + mAnimation->releaseArrow(mAttackStrength); + else if (action == "shoot follow attach") + mAnimation->attachArrow(); + // Make sure this key is actually for the RangeType we are casting. The flame atronach has + // the same animation for all range types, so there are 3 "release" keys on the same time, one for each range + // type. + else if (groupname == "spellcast" && action == mAttackType + " release") { - if (groupname == "attack1" || groupname == "swimattack1") - charClass.hit(mPtr, mAttackStrength, ESM::Weapon::AT_Chop, mAttackVictim, mAttackHitPos, mAttackSuccess); - else if (groupname == "attack2" || groupname == "swimattack2") - charClass.hit(mPtr, mAttackStrength, ESM::Weapon::AT_Slash, mAttackVictim, mAttackHitPos, mAttackSuccess); - else if (groupname == "attack3" || groupname == "swimattack3") - charClass.hit(mPtr, mAttackStrength, ESM::Weapon::AT_Thrust, mAttackVictim, mAttackHitPos, mAttackSuccess); + if (mCanCast) + MWBase::Environment::get().getWorld()->castSpell(mPtr, mCastingManualSpell); + mCastingManualSpell = false; + mCanCast = false; } + else if (groupname == "shield" && action == "block hit") + charClass.block(mPtr); + else if (groupname == "containeropen" && action == "loot") + MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Container, mPtr); } - else if (action == "shoot attach") - mAnimation->attachArrow(); - else if (action == "shoot release") - mAnimation->releaseArrow(mAttackStrength); - else if (action == "shoot follow attach") - mAnimation->attachArrow(); - // Make sure this key is actually for the RangeType we are casting. The flame atronach has - // the same animation for all range types, so there are 3 "release" keys on the same time, one for each range type. - else if (groupname == "spellcast" && action == mAttackType + " release") - { - if (mCanCast) - MWBase::Environment::get().getWorld()->castSpell(mPtr, mCastingManualSpell); - mCastingManualSpell = false; - mCanCast = false; - } - else if (groupname == "shield" && action == "block hit") - charClass.block(mPtr); - else if (groupname == "containeropen" && action == "loot") - MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Container, mPtr); -} -void CharacterController::updatePtr(const MWWorld::Ptr &ptr) -{ - mPtr = ptr; -} - -void CharacterController::updateIdleStormState(bool inwater) const -{ - if (!mAnimation->hasAnimation("idlestorm") || mUpperBodyState != UpperBodyState::None || inwater) + void CharacterController::updatePtr(const MWWorld::Ptr& ptr) { - mAnimation->disable("idlestorm"); - return; + mPtr = ptr; } - const auto world = MWBase::Environment::get().getWorld(); - if (world->isInStorm()) + void CharacterController::updateIdleStormState(bool inwater) const { - osg::Vec3f stormDirection = world->getStormDirection(); - osg::Vec3f characterDirection = mPtr.getRefData().getBaseNode()->getAttitude() * osg::Vec3f(0,1,0); - stormDirection.normalize(); - characterDirection.normalize(); - if (stormDirection * characterDirection < -0.5f) + if (!mAnimation->hasAnimation("idlestorm") || mUpperBodyState != UpperBodyState::None || inwater) { - if (!mAnimation->isPlaying("idlestorm")) - { - int mask = MWRender::Animation::BlendMask_Torso | MWRender::Animation::BlendMask_RightArm; - mAnimation->play("idlestorm", Priority_Storm, mask, true, 1.0f, "start", "stop", 0.0f, ~0ul); - } - else + mAnimation->disable("idlestorm"); + return; + } + + const auto world = MWBase::Environment::get().getWorld(); + if (world->isInStorm()) + { + osg::Vec3f stormDirection = world->getStormDirection(); + osg::Vec3f characterDirection = mPtr.getRefData().getBaseNode()->getAttitude() * osg::Vec3f(0, 1, 0); + stormDirection.normalize(); + characterDirection.normalize(); + if (stormDirection * characterDirection < -0.5f) { - mAnimation->setLoopingEnabled("idlestorm", true); + if (!mAnimation->isPlaying("idlestorm")) + { + int mask = MWRender::Animation::BlendMask_Torso | MWRender::Animation::BlendMask_RightArm; + mAnimation->play("idlestorm", Priority_Storm, mask, true, 1.0f, "start", "stop", 0.0f, ~0ul); + } + else + { + mAnimation->setLoopingEnabled("idlestorm", true); + } + return; } - return; + } + + if (mAnimation->isPlaying("idlestorm")) + { + mAnimation->setLoopingEnabled("idlestorm", false); } } - if (mAnimation->isPlaying("idlestorm")) + bool CharacterController::updateCarriedLeftVisible(const int weaptype) const { - mAnimation->setLoopingEnabled("idlestorm", false); + // Shields/torches shouldn't be visible during any operation involving two hands + // There seems to be no text keys for this purpose, except maybe for "[un]equip start/stop", + // but they are also present in weapon drawing animation. + return mAnimation->updateCarriedLeftVisible(weaptype); } -} - -bool CharacterController::updateCarriedLeftVisible(const int weaptype) const -{ - // Shields/torches shouldn't be visible during any operation involving two hands - // There seems to be no text keys for this purpose, except maybe for "[un]equip start/stop", - // but they are also present in weapon drawing animation. - return mAnimation->updateCarriedLeftVisible(weaptype); -} -float CharacterController::calculateWindUp() const -{ - if (mCurrentWeapon.empty() || mWeaponType == ESM::Weapon::PickProbe || isRandomAttackAnimation(mCurrentWeapon)) - return -1.f; - - float minAttackTime = mAnimation->getTextKeyTime(mCurrentWeapon + ": " + mAttackType + " min attack"); - float maxAttackTime = mAnimation->getTextKeyTime(mCurrentWeapon + ": " + mAttackType + " max attack"); - if (minAttackTime == -1.f || minAttackTime >= maxAttackTime) - return -1.f; + float CharacterController::calculateWindUp() const + { + if (mCurrentWeapon.empty() || mWeaponType == ESM::Weapon::PickProbe || isRandomAttackAnimation(mCurrentWeapon)) + return -1.f; - return std::clamp((mAnimation->getCurrentTime(mCurrentWeapon) - minAttackTime) / (maxAttackTime - minAttackTime), 0.f, 1.f); -} + float minAttackTime = mAnimation->getTextKeyTime(mCurrentWeapon + ": " + mAttackType + " min attack"); + float maxAttackTime = mAnimation->getTextKeyTime(mCurrentWeapon + ": " + mAttackType + " max attack"); + if (minAttackTime == -1.f || minAttackTime >= maxAttackTime) + return -1.f; -bool CharacterController::updateWeaponState() -{ - const auto world = MWBase::Environment::get().getWorld(); - auto& prng = world->getPrng(); - MWBase::SoundManager* sndMgr = MWBase::Environment::get().getSoundManager(); + return std::clamp( + (mAnimation->getCurrentTime(mCurrentWeapon) - minAttackTime) / (maxAttackTime - minAttackTime), 0.f, 1.f); + } - const MWWorld::Class &cls = mPtr.getClass(); - CreatureStats &stats = cls.getCreatureStats(mPtr); - int weaptype = ESM::Weapon::None; - if(stats.getDrawState() == DrawState::Weapon) - weaptype = ESM::Weapon::HandToHand; - else if (stats.getDrawState() == DrawState::Spell) - weaptype = ESM::Weapon::Spell; + bool CharacterController::updateWeaponState() + { + const auto world = MWBase::Environment::get().getWorld(); + auto& prng = world->getPrng(); + MWBase::SoundManager* sndMgr = MWBase::Environment::get().getSoundManager(); - const bool isWerewolf = cls.isNpc() && cls.getNpcStats(mPtr).isWerewolf(); + const MWWorld::Class& cls = mPtr.getClass(); + CreatureStats& stats = cls.getCreatureStats(mPtr); + int weaptype = ESM::Weapon::None; + if (stats.getDrawState() == DrawState::Weapon) + weaptype = ESM::Weapon::HandToHand; + else if (stats.getDrawState() == DrawState::Spell) + weaptype = ESM::Weapon::Spell; - std::string_view downSoundId; - bool weaponChanged = false; - bool ammunition = true; - float weapSpeed = 1.f; - if (cls.hasInventoryStore(mPtr)) - { - MWWorld::InventoryStore &inv = cls.getInventoryStore(mPtr); - MWWorld::ContainerStoreIterator weapon = getActiveWeapon(mPtr, &weaptype); - if(stats.getDrawState() == DrawState::Spell) - weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); + const bool isWerewolf = cls.isNpc() && cls.getNpcStats(mPtr).isWerewolf(); - MWWorld::Ptr newWeapon; - if (weapon != inv.end()) + std::string_view downSoundId; + bool weaponChanged = false; + bool ammunition = true; + float weapSpeed = 1.f; + if (cls.hasInventoryStore(mPtr)) { - newWeapon = *weapon; - if (isRealWeapon(mWeaponType)) - downSoundId = newWeapon.getClass().getDownSoundId(newWeapon); - } - // weapon->HtH switch: weapon is empty already, so we need to take sound from previous weapon - else if (!mWeapon.isEmpty() && weaptype == ESM::Weapon::HandToHand && mWeaponType != ESM::Weapon::Spell) - downSoundId = mWeapon.getClass().getDownSoundId(mWeapon); + MWWorld::InventoryStore& inv = cls.getInventoryStore(mPtr); + MWWorld::ContainerStoreIterator weapon = getActiveWeapon(mPtr, &weaptype); + if (stats.getDrawState() == DrawState::Spell) + weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); - if (mWeapon != newWeapon) - { - mWeapon = newWeapon; - weaponChanged = true; - } + MWWorld::Ptr newWeapon; + if (weapon != inv.end()) + { + newWeapon = *weapon; + if (isRealWeapon(mWeaponType)) + downSoundId = newWeapon.getClass().getDownSoundId(newWeapon); + } + // weapon->HtH switch: weapon is empty already, so we need to take sound from previous weapon + else if (!mWeapon.isEmpty() && weaptype == ESM::Weapon::HandToHand && mWeaponType != ESM::Weapon::Spell) + downSoundId = mWeapon.getClass().getDownSoundId(mWeapon); - if (stats.getDrawState() == DrawState::Weapon && !mWeapon.isEmpty() && mWeapon.getType() == ESM::Weapon::sRecordId) - { - weapSpeed = mWeapon.get()->mBase->mData.mSpeed; - MWWorld::ConstContainerStoreIterator ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition); - int ammotype = getWeaponType(mWeapon.get()->mBase->mData.mType)->mAmmoType; - if (ammotype != ESM::Weapon::None) - ammunition = ammo != inv.end() && ammo->get()->mBase->mData.mType == ammotype; - // Cancel attack if we no longer have ammunition - if (!ammunition) + if (mWeapon != newWeapon) + { + mWeapon = newWeapon; + weaponChanged = true; + } + + if (stats.getDrawState() == DrawState::Weapon && !mWeapon.isEmpty() + && mWeapon.getType() == ESM::Weapon::sRecordId) { - if (mUpperBodyState == UpperBodyState::AttackWindUp) + weapSpeed = mWeapon.get()->mBase->mData.mSpeed; + MWWorld::ConstContainerStoreIterator ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition); + int ammotype = getWeaponType(mWeapon.get()->mBase->mData.mType)->mAmmoType; + if (ammotype != ESM::Weapon::None) + ammunition = ammo != inv.end() && ammo->get()->mBase->mData.mType == ammotype; + // Cancel attack if we no longer have ammunition + if (!ammunition) { - mAnimation->disable(mCurrentWeapon); - mUpperBodyState = UpperBodyState::WeaponEquipped; + if (mUpperBodyState == UpperBodyState::AttackWindUp) + { + mAnimation->disable(mCurrentWeapon); + mUpperBodyState = UpperBodyState::WeaponEquipped; + } + setAttackingOrSpell(false); } - setAttackingOrSpell(false); } - } - MWWorld::ConstContainerStoreIterator torch = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); - if (torch != inv.end() && torch->getType() == ESM::Light::sRecordId && updateCarriedLeftVisible(mWeaponType)) - { - if (mAnimation->isPlaying("shield")) - mAnimation->disable("shield"); + MWWorld::ConstContainerStoreIterator torch = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); + if (torch != inv.end() && torch->getType() == ESM::Light::sRecordId + && updateCarriedLeftVisible(mWeaponType)) + { + if (mAnimation->isPlaying("shield")) + mAnimation->disable("shield"); - mAnimation->play("torch", Priority_Torch, MWRender::Animation::BlendMask_LeftArm, - false, 1.0f, "start", "stop", 0.0f, std::numeric_limits::max(), true); - } - else if (mAnimation->isPlaying("torch")) - { - mAnimation->disable("torch"); + mAnimation->play("torch", Priority_Torch, MWRender::Animation::BlendMask_LeftArm, false, 1.0f, "start", + "stop", 0.0f, std::numeric_limits::max(), true); + } + else if (mAnimation->isPlaying("torch")) + { + mAnimation->disable("torch"); + } } - } - // For biped actors, blend weapon animations with lower body animations with higher priority - MWRender::Animation::AnimPriority priorityWeapon(Priority_Weapon); - if (cls.isBipedal(mPtr)) - priorityWeapon[MWRender::Animation::BoneGroup_LowerBody] = Priority_WeaponLowerBody; + // For biped actors, blend weapon animations with lower body animations with higher priority + MWRender::Animation::AnimPriority priorityWeapon(Priority_Weapon); + if (cls.isBipedal(mPtr)) + priorityWeapon[MWRender::Animation::BoneGroup_LowerBody] = Priority_WeaponLowerBody; - bool forcestateupdate = false; + bool forcestateupdate = false; - // We should not play equipping animation and sound during weapon->weapon transition - const bool isStillWeapon = isRealWeapon(mWeaponType) && isRealWeapon(weaptype); + // We should not play equipping animation and sound during weapon->weapon transition + const bool isStillWeapon = isRealWeapon(mWeaponType) && isRealWeapon(weaptype); - // If the current weapon type was changed in the middle of attack (e.g. by Equip console command or when bound spell expires), - // we should force actor to the "weapon equipped" state, interrupt attack and update animations. - if (isStillWeapon && mWeaponType != weaptype && mUpperBodyState > UpperBodyState::WeaponEquipped) - { - forcestateupdate = true; - if (!mCurrentWeapon.empty()) - mAnimation->disable(mCurrentWeapon); - mUpperBodyState = UpperBodyState::WeaponEquipped; - setAttackingOrSpell(false); - mAnimation->showWeapons(true); - } + // If the current weapon type was changed in the middle of attack (e.g. by Equip console command or when bound + // spell expires), we should force actor to the "weapon equipped" state, interrupt attack and update animations. + if (isStillWeapon && mWeaponType != weaptype && mUpperBodyState > UpperBodyState::WeaponEquipped) + { + forcestateupdate = true; + if (!mCurrentWeapon.empty()) + mAnimation->disable(mCurrentWeapon); + mUpperBodyState = UpperBodyState::WeaponEquipped; + setAttackingOrSpell(false); + mAnimation->showWeapons(true); + } - if(!isKnockedOut() && !isKnockedDown() && !isRecovery()) - { - std::string weapgroup; - if ((!isWerewolf || mWeaponType != ESM::Weapon::Spell) - && weaptype != mWeaponType - && mUpperBodyState != UpperBodyState::Unequipping - && !isStillWeapon) + if (!isKnockedOut() && !isKnockedDown() && !isRecovery()) { - // We can not play un-equip animation if weapon changed since last update - if (!weaponChanged) + std::string weapgroup; + if ((!isWerewolf || mWeaponType != ESM::Weapon::Spell) && weaptype != mWeaponType + && mUpperBodyState != UpperBodyState::Unequipping && !isStillWeapon) { - // Note: we do not disable unequipping animation automatically to avoid body desync - weapgroup = getWeaponAnimation(mWeaponType); - int unequipMask = MWRender::Animation::BlendMask_All; - bool useShieldAnims = mAnimation->useShieldAnimations(); - if (useShieldAnims && mWeaponType != ESM::Weapon::HandToHand && mWeaponType != ESM::Weapon::Spell && !(mWeaponType == ESM::Weapon::None && weaptype == ESM::Weapon::Spell)) + // We can not play un-equip animation if weapon changed since last update + if (!weaponChanged) { - unequipMask = unequipMask |~MWRender::Animation::BlendMask_LeftArm; - mAnimation->play("shield", Priority_Block, - MWRender::Animation::BlendMask_LeftArm, true, - 1.0f, "unequip start", "unequip stop", 0.0f, 0); - } - else if (mWeaponType == ESM::Weapon::HandToHand) - mAnimation->showCarriedLeft(false); + // Note: we do not disable unequipping animation automatically to avoid body desync + weapgroup = getWeaponAnimation(mWeaponType); + int unequipMask = MWRender::Animation::BlendMask_All; + bool useShieldAnims = mAnimation->useShieldAnimations(); + if (useShieldAnims && mWeaponType != ESM::Weapon::HandToHand && mWeaponType != ESM::Weapon::Spell + && !(mWeaponType == ESM::Weapon::None && weaptype == ESM::Weapon::Spell)) + { + unequipMask = unequipMask | ~MWRender::Animation::BlendMask_LeftArm; + mAnimation->play("shield", Priority_Block, MWRender::Animation::BlendMask_LeftArm, true, 1.0f, + "unequip start", "unequip stop", 0.0f, 0); + } + else if (mWeaponType == ESM::Weapon::HandToHand) + mAnimation->showCarriedLeft(false); - mAnimation->play(weapgroup, priorityWeapon, unequipMask, false, - 1.0f, "unequip start", "unequip stop", 0.0f, 0); - mUpperBodyState = UpperBodyState::Unequipping; + mAnimation->play( + weapgroup, priorityWeapon, unequipMask, false, 1.0f, "unequip start", "unequip stop", 0.0f, 0); + mUpperBodyState = UpperBodyState::Unequipping; - mAnimation->detachArrow(); + mAnimation->detachArrow(); - // If we do not have the "unequip detach" key, hide weapon manually. - if (mAnimation->getTextKeyTime(weapgroup+": unequip detach") < 0) - mAnimation->showWeapons(false); - } + // If we do not have the "unequip detach" key, hide weapon manually. + if (mAnimation->getTextKeyTime(weapgroup + ": unequip detach") < 0) + mAnimation->showWeapons(false); + } - if(!downSoundId.empty()) - { - sndMgr->playSound3D(mPtr, downSoundId, 1.0f, 1.0f); + if (!downSoundId.empty()) + { + sndMgr->playSound3D(mPtr, downSoundId, 1.0f, 1.0f); + } } - } - float complete; - bool animPlaying = mAnimation->getInfo(mCurrentWeapon, &complete); - if (!animPlaying || complete >= 1.0f) - { - // Weapon is changed, no current animation (e.g. unequipping or attack). - // Start equipping animation now. - if (weaptype != mWeaponType) + float complete; + bool animPlaying = mAnimation->getInfo(mCurrentWeapon, &complete); + if (!animPlaying || complete >= 1.0f) { - forcestateupdate = true; - bool useShieldAnims = mAnimation->useShieldAnimations(); - if (!useShieldAnims) - mAnimation->showCarriedLeft(updateCarriedLeftVisible(weaptype)); + // Weapon is changed, no current animation (e.g. unequipping or attack). + // Start equipping animation now. + if (weaptype != mWeaponType) + { + forcestateupdate = true; + bool useShieldAnims = mAnimation->useShieldAnimations(); + if (!useShieldAnims) + mAnimation->showCarriedLeft(updateCarriedLeftVisible(weaptype)); - weapgroup = getWeaponAnimation(weaptype); + weapgroup = getWeaponAnimation(weaptype); - // Note: controllers for ranged weapon should use time for beginning of animation to play shooting properly, - // for other weapons they should use absolute time. Some mods rely on this behaviour (to rotate throwing projectiles, for example) - ESM::WeaponType::Class weaponClass = getWeaponType(weaptype)->mWeaponClass; - bool useRelativeDuration = weaponClass == ESM::WeaponType::Ranged; - mAnimation->setWeaponGroup(weapgroup, useRelativeDuration); + // Note: controllers for ranged weapon should use time for beginning of animation to play shooting + // properly, for other weapons they should use absolute time. Some mods rely on this behaviour (to + // rotate throwing projectiles, for example) + ESM::WeaponType::Class weaponClass = getWeaponType(weaptype)->mWeaponClass; + bool useRelativeDuration = weaponClass == ESM::WeaponType::Ranged; + mAnimation->setWeaponGroup(weapgroup, useRelativeDuration); - if (!isStillWeapon) - { - if (animPlaying) - mAnimation->disable(mCurrentWeapon); - if (weaptype != ESM::Weapon::None) + if (!isStillWeapon) { - mAnimation->showWeapons(false); - int equipMask = MWRender::Animation::BlendMask_All; - if (useShieldAnims && weaptype != ESM::Weapon::Spell) + if (animPlaying) + mAnimation->disable(mCurrentWeapon); + if (weaptype != ESM::Weapon::None) { - equipMask = equipMask |~MWRender::Animation::BlendMask_LeftArm; - mAnimation->play("shield", Priority_Block, - MWRender::Animation::BlendMask_LeftArm, true, - 1.0f, "equip start", "equip stop", 0.0f, 0); - } + mAnimation->showWeapons(false); + int equipMask = MWRender::Animation::BlendMask_All; + if (useShieldAnims && weaptype != ESM::Weapon::Spell) + { + equipMask = equipMask | ~MWRender::Animation::BlendMask_LeftArm; + mAnimation->play("shield", Priority_Block, MWRender::Animation::BlendMask_LeftArm, true, + 1.0f, "equip start", "equip stop", 0.0f, 0); + } - mAnimation->play(weapgroup, priorityWeapon, equipMask, true, - 1.0f, "equip start", "equip stop", 0.0f, 0); - mUpperBodyState = UpperBodyState::Equipping; + mAnimation->play( + weapgroup, priorityWeapon, equipMask, true, 1.0f, "equip start", "equip stop", 0.0f, 0); + mUpperBodyState = UpperBodyState::Equipping; - // If we do not have the "equip attach" key, show weapon manually. - if (weaptype != ESM::Weapon::Spell && mAnimation->getTextKeyTime(weapgroup+": equip attach") < 0) - { - mAnimation->showWeapons(true); + // If we do not have the "equip attach" key, show weapon manually. + if (weaptype != ESM::Weapon::Spell + && mAnimation->getTextKeyTime(weapgroup + ": equip attach") < 0) + { + mAnimation->showWeapons(true); + } + + if (!mWeapon.isEmpty() && mWeaponType != ESM::Weapon::HandToHand && isRealWeapon(weaptype)) + { + std::string_view upSoundId = mWeapon.getClass().getUpSoundId(mWeapon); + if (!upSoundId.empty()) + sndMgr->playSound3D(mPtr, upSoundId, 1.0f, 1.0f); + } } + } - if (!mWeapon.isEmpty() && mWeaponType != ESM::Weapon::HandToHand && isRealWeapon(weaptype)) + if (isWerewolf) + { + const MWWorld::ESMStore& store = world->getStore(); + const ESM::Sound* sound = store.get().searchRandom("WolfEquip", prng); + if (sound) { - std::string_view upSoundId = mWeapon.getClass().getUpSoundId(mWeapon); - if (!upSoundId.empty()) - sndMgr->playSound3D(mPtr, upSoundId, 1.0f, 1.0f); + sndMgr->playSound3D(mPtr, sound->mId, 1.0f, 1.0f); } } + + mWeaponType = weaptype; + mCurrentWeapon = weapgroup; } - if(isWerewolf) + // Make sure that we disabled unequipping animation + if (mUpperBodyState == UpperBodyState::Unequipping) { - const MWWorld::ESMStore &store = world->getStore(); - const ESM::Sound *sound = store.get().searchRandom("WolfEquip", prng); - if(sound) - { - sndMgr->playSound3D(mPtr, sound->mId, 1.0f, 1.0f); - } + resetCurrentWeaponState(); + mWeaponType = ESM::Weapon::None; } - - mWeaponType = weaptype; - mCurrentWeapon = weapgroup; - } - - // Make sure that we disabled unequipping animation - if (mUpperBodyState == UpperBodyState::Unequipping) - { - resetCurrentWeaponState(); - mWeaponType = ESM::Weapon::None; } } - } - if(isWerewolf) - { - if(stats.getStance(MWMechanics::CreatureStats::Stance_Run) - && mHasMovedInXY - && !world->isSwimming(mPtr) - && mWeaponType == ESM::Weapon::None) + if (isWerewolf) { - if(!sndMgr->getSoundPlaying(mPtr, "WolfRun")) - sndMgr->playSound3D(mPtr, "WolfRun", 1.0f, 1.0f, MWSound::Type::Sfx, - MWSound::PlayMode::Loop); + if (stats.getStance(MWMechanics::CreatureStats::Stance_Run) && mHasMovedInXY && !world->isSwimming(mPtr) + && mWeaponType == ESM::Weapon::None) + { + if (!sndMgr->getSoundPlaying(mPtr, "WolfRun")) + sndMgr->playSound3D(mPtr, "WolfRun", 1.0f, 1.0f, MWSound::Type::Sfx, MWSound::PlayMode::Loop); + } + else + sndMgr->stopSound3D(mPtr, "WolfRun"); } - else - sndMgr->stopSound3D(mPtr, "WolfRun"); - } - // Combat for actors with persistent animations obviously will be buggy - if (isPersistentAnimPlaying()) - return forcestateupdate; + // Combat for actors with persistent animations obviously will be buggy + if (isPersistentAnimPlaying()) + return forcestateupdate; - float complete = 0.f; - bool animPlaying = false; - ESM::WeaponType::Class weapclass = getWeaponType(mWeaponType)->mWeaponClass; - if(getAttackingOrSpell()) - { - bool resetIdle = true; - if (mUpperBodyState == UpperBodyState::WeaponEquipped && (mHitState == CharState_None || mHitState == CharState_Block)) + float complete = 0.f; + bool animPlaying = false; + ESM::WeaponType::Class weapclass = getWeaponType(mWeaponType)->mWeaponClass; + if (getAttackingOrSpell()) { - mAttackStrength = 0; - - // Randomize attacks for non-bipedal creatures - if (!cls.isBipedal(mPtr) && (!mAnimation->hasAnimation(mCurrentWeapon) || isRandomAttackAnimation(mCurrentWeapon))) + bool resetIdle = true; + if (mUpperBodyState == UpperBodyState::WeaponEquipped + && (mHitState == CharState_None || mHitState == CharState_Block)) { - mCurrentWeapon = chooseRandomAttackAnimation(); - } + mAttackStrength = 0; - if(mWeaponType == ESM::Weapon::Spell) - { - // Unset casting flag, otherwise pressing the mouse button down would - // continue casting every frame if there is no animation - setAttackingOrSpell(false); - if (mPtr == getPlayer()) + // Randomize attacks for non-bipedal creatures + if (!cls.isBipedal(mPtr) + && (!mAnimation->hasAnimation(mCurrentWeapon) || isRandomAttackAnimation(mCurrentWeapon))) { - // For the player, set the spell we want to cast - // This has to be done at the start of the casting animation, - // *not* when selecting a spell in the GUI (otherwise you could change the spell mid-animation) - const std::string& selectedSpell = MWBase::Environment::get().getWindowManager()->getSelectedSpell(); - stats.getSpells().setSelectedSpell(selectedSpell); + mCurrentWeapon = chooseRandomAttackAnimation(); } - std::string_view spellid = stats.getSpells().getSelectedSpell(); - bool isMagicItem = false; - // Play hand VFX and allow castSpell use (assuming an animation is going to be played) if spellcasting is successful. - // Manual spellcasting bypasses restrictions. - MWWorld::SpellCastState spellCastResult = MWWorld::SpellCastState::Success; - if (!mCastingManualSpell) - spellCastResult = world->startSpellCast(mPtr); - mCanCast = spellCastResult == MWWorld::SpellCastState::Success; - - if (spellid.empty() && cls.hasInventoryStore(mPtr)) + if (mWeaponType == ESM::Weapon::Spell) { - MWWorld::InventoryStore& inv = cls.getInventoryStore(mPtr); - if (inv.getSelectedEnchantItem() != inv.end()) + // Unset casting flag, otherwise pressing the mouse button down would + // continue casting every frame if there is no animation + setAttackingOrSpell(false); + if (mPtr == getPlayer()) { - const MWWorld::Ptr& enchantItem = *inv.getSelectedEnchantItem(); - spellid = enchantItem.getClass().getEnchantment(enchantItem); - isMagicItem = true; + // For the player, set the spell we want to cast + // This has to be done at the start of the casting animation, + // *not* when selecting a spell in the GUI (otherwise you could change the spell mid-animation) + const std::string& selectedSpell + = MWBase::Environment::get().getWindowManager()->getSelectedSpell(); + stats.getSpells().setSelectedSpell(selectedSpell); } - } + std::string_view spellid = stats.getSpells().getSelectedSpell(); + bool isMagicItem = false; - static const bool useCastingAnimations = Settings::Manager::getBool("use magic item animations", "Game"); - if (isMagicItem && !useCastingAnimations) - { - world->breakInvisibility(mPtr); - // Enchanted items by default do not use casting animations - world->castSpell(mPtr); - resetIdle = false; - // Spellcasting animation needs to "play" for at least one frame to reset the aiming factor - animPlaying = true; - mUpperBodyState = UpperBodyState::Casting; - } - // Play the spellcasting animation/VFX if the spellcasting was successful or failed due to insufficient magicka. - // Used up powers are exempt from this from some reason. - else if (!spellid.empty() && spellCastResult != MWWorld::SpellCastState::PowerAlreadyUsed) - { - world->breakInvisibility(mPtr); - MWMechanics::CastSpell cast(mPtr, {}, false, mCastingManualSpell); + // Play hand VFX and allow castSpell use (assuming an animation is going to be played) if + // spellcasting is successful. Manual spellcasting bypasses restrictions. + MWWorld::SpellCastState spellCastResult = MWWorld::SpellCastState::Success; + if (!mCastingManualSpell) + spellCastResult = world->startSpellCast(mPtr); + mCanCast = spellCastResult == MWWorld::SpellCastState::Success; - const std::vector* effects{nullptr}; - const MWWorld::ESMStore &store = world->getStore(); - if (isMagicItem) + if (spellid.empty() && cls.hasInventoryStore(mPtr)) { - const ESM::Enchantment *enchantment = store.get().find(spellid); - effects = &enchantment->mEffects.mList; - cast.playSpellCastingEffects(enchantment); + MWWorld::InventoryStore& inv = cls.getInventoryStore(mPtr); + if (inv.getSelectedEnchantItem() != inv.end()) + { + const MWWorld::Ptr& enchantItem = *inv.getSelectedEnchantItem(); + spellid = enchantItem.getClass().getEnchantment(enchantItem); + isMagicItem = true; + } } - else + + static const bool useCastingAnimations + = Settings::Manager::getBool("use magic item animations", "Game"); + if (isMagicItem && !useCastingAnimations) { - const ESM::Spell *spell = store.get().find(spellid); - effects = &spell->mEffects.mList; - cast.playSpellCastingEffects(spell); + world->breakInvisibility(mPtr); + // Enchanted items by default do not use casting animations + world->castSpell(mPtr); + resetIdle = false; + // Spellcasting animation needs to "play" for at least one frame to reset the aiming factor + animPlaying = true; + mUpperBodyState = UpperBodyState::Casting; } - if (mCanCast) + // Play the spellcasting animation/VFX if the spellcasting was successful or failed due to + // insufficient magicka. Used up powers are exempt from this from some reason. + else if (!spellid.empty() && spellCastResult != MWWorld::SpellCastState::PowerAlreadyUsed) { - const ESM::MagicEffect *effect = store.get().find(effects->back().mEffectID); // use last effect of list for color of VFX_Hands + world->breakInvisibility(mPtr); + MWMechanics::CastSpell cast(mPtr, {}, false, mCastingManualSpell); + + const std::vector* effects{ nullptr }; + const MWWorld::ESMStore& store = world->getStore(); + if (isMagicItem) + { + const ESM::Enchantment* enchantment = store.get().find(spellid); + effects = &enchantment->mEffects.mList; + cast.playSpellCastingEffects(enchantment); + } + else + { + const ESM::Spell* spell = store.get().find(spellid); + effects = &spell->mEffects.mList; + cast.playSpellCastingEffects(spell); + } + if (mCanCast) + { + const ESM::MagicEffect* effect = store.get().find( + effects->back().mEffectID); // use last effect of list for color of VFX_Hands + + const ESM::Static* castStatic = world->getStore().get().find("VFX_Hands"); - const ESM::Static* castStatic = world->getStore().get().find ("VFX_Hands"); + const VFS::Manager* const vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); + + if (!effects->empty()) + { + if (mAnimation->getNode("Bip01 L Hand")) + mAnimation->addEffect( + Misc::ResourceHelpers::correctMeshPath(castStatic->mModel, vfs), -1, false, + "Bip01 L Hand", effect->mParticle); + + if (mAnimation->getNode("Bip01 R Hand")) + mAnimation->addEffect( + Misc::ResourceHelpers::correctMeshPath(castStatic->mModel, vfs), -1, false, + "Bip01 R Hand", effect->mParticle); + } + } - const VFS::Manager* const vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); + const ESM::ENAMstruct& firstEffect = effects->at(0); // first effect used for casting animation - if (!effects->empty()) + std::string startKey; + std::string stopKey; + if (isRandomAttackAnimation(mCurrentWeapon)) { - if (mAnimation->getNode("Bip01 L Hand")) - mAnimation->addEffect( - Misc::ResourceHelpers::correctMeshPath(castStatic->mModel, vfs), - -1, false, "Bip01 L Hand", effect->mParticle); - - if (mAnimation->getNode("Bip01 R Hand")) - mAnimation->addEffect( - Misc::ResourceHelpers::correctMeshPath(castStatic->mModel, vfs), - -1, false, "Bip01 R Hand", effect->mParticle); + startKey = "start"; + stopKey = "stop"; + if (mCanCast) + world->castSpell( + mPtr, mCastingManualSpell); // No "release" text key to use, so cast immediately + mCastingManualSpell = false; + mCanCast = false; } - } + else + { + switch (firstEffect.mRange) + { + case 0: + mAttackType = "self"; + break; + case 1: + mAttackType = "touch"; + break; + case 2: + mAttackType = "target"; + break; + } - const ESM::ENAMstruct& firstEffect = effects->at(0); // first effect used for casting animation + startKey = mAttackType + " start"; + stopKey = mAttackType + " stop"; + } - std::string startKey; - std::string stopKey; - if (isRandomAttackAnimation(mCurrentWeapon)) - { - startKey = "start"; - stopKey = "stop"; - if (mCanCast) - world->castSpell(mPtr, mCastingManualSpell); // No "release" text key to use, so cast immediately - mCastingManualSpell = false; - mCanCast = false; + mAnimation->play(mCurrentWeapon, priorityWeapon, MWRender::Animation::BlendMask_All, false, 1, + startKey, stopKey, 0.0f, 0); + mUpperBodyState = UpperBodyState::Casting; } else { - switch(firstEffect.mRange) - { - case 0: mAttackType = "self"; break; - case 1: mAttackType = "touch"; break; - case 2: mAttackType = "target"; break; - } - - startKey = mAttackType+" start"; - stopKey = mAttackType+" stop"; + resetIdle = false; } - - mAnimation->play(mCurrentWeapon, priorityWeapon, - MWRender::Animation::BlendMask_All, false, - 1, startKey, stopKey, - 0.0f, 0); - mUpperBodyState = UpperBodyState::Casting; } else { - resetIdle = false; - } - } - else - { - std::string startKey = "start"; - std::string stopKey = "stop"; + std::string startKey = "start"; + std::string stopKey = "stop"; - if (mWeaponType != ESM::Weapon::PickProbe && !isRandomAttackAnimation(mCurrentWeapon)) - { - if (weapclass == ESM::WeaponType::Ranged || weapclass == ESM::WeaponType::Thrown) - mAttackType = "shoot"; - else if (mPtr == getPlayer()) + if (mWeaponType != ESM::Weapon::PickProbe && !isRandomAttackAnimation(mCurrentWeapon)) { - if (Settings::Manager::getBool("best attack", "Game")) + if (weapclass == ESM::WeaponType::Ranged || weapclass == ESM::WeaponType::Thrown) + mAttackType = "shoot"; + else if (mPtr == getPlayer()) { - if (!mWeapon.isEmpty() && mWeapon.getType() == ESM::Weapon::sRecordId) + if (Settings::Manager::getBool("best attack", "Game")) { - mAttackType = getBestAttack(mWeapon.get()->mBase); + if (!mWeapon.isEmpty() && mWeapon.getType() == ESM::Weapon::sRecordId) + { + mAttackType = getBestAttack(mWeapon.get()->mBase); + } + else + { + // There is no "best attack" for Hand-to-Hand + mAttackType = getRandomAttackType(); + } } else { - // There is no "best attack" for Hand-to-Hand - mAttackType = getRandomAttackType(); + mAttackType = getMovementBasedAttackType(); } } - else - { - mAttackType = getMovementBasedAttackType(); - } + // else if (mPtr != getPlayer()) use mAttackType set by AiCombat + startKey = mAttackType + ' ' + startKey; + stopKey = mAttackType + " max attack"; } - // else if (mPtr != getPlayer()) use mAttackType set by AiCombat - startKey = mAttackType + ' ' + startKey; - stopKey = mAttackType + " max attack"; - } - mAnimation->play(mCurrentWeapon, priorityWeapon, - MWRender::Animation::BlendMask_All, false, - weapSpeed, startKey, stopKey, - 0.0f, 0); - mUpperBodyState = UpperBodyState::AttackWindUp; + mAnimation->play(mCurrentWeapon, priorityWeapon, MWRender::Animation::BlendMask_All, false, + weapSpeed, startKey, stopKey, 0.0f, 0); + mUpperBodyState = UpperBodyState::AttackWindUp; - // Reset the attack results when the attack starts. - // Strictly speaking this should probably be done when the attack ends, - // but the attack animation might be cancelled in a myriad different ways. - mAttackSuccess = false; - mAttackVictim = MWWorld::Ptr(); - mAttackHitPos = osg::Vec3f(); + // Reset the attack results when the attack starts. + // Strictly speaking this should probably be done when the attack ends, + // but the attack animation might be cancelled in a myriad different ways. + mAttackSuccess = false; + mAttackVictim = MWWorld::Ptr(); + mAttackHitPos = osg::Vec3f(); + } } - } - // We should not break swim and sneak animations - if (resetIdle && mIdleState != CharState_IdleSneak && mIdleState != CharState_IdleSwim) - { - resetCurrentIdleState(); + // We should not break swim and sneak animations + if (resetIdle && mIdleState != CharState_IdleSneak && mIdleState != CharState_IdleSwim) + { + resetCurrentIdleState(); + } } - } - // Random attack and pick/probe animations never have wind up and are played to their end. - // Other animations must be released when the attack state is unset. - if (mUpperBodyState == UpperBodyState::AttackWindUp && (mWeaponType == ESM::Weapon::PickProbe || isRandomAttackAnimation(mCurrentWeapon) || !getAttackingOrSpell())) - { - mUpperBodyState = UpperBodyState::AttackRelease; - world->breakInvisibility(mPtr); - if (mWeaponType == ESM::Weapon::PickProbe) + // Random attack and pick/probe animations never have wind up and are played to their end. + // Other animations must be released when the attack state is unset. + if (mUpperBodyState == UpperBodyState::AttackWindUp + && (mWeaponType == ESM::Weapon::PickProbe || isRandomAttackAnimation(mCurrentWeapon) + || !getAttackingOrSpell())) { - // TODO: this will only work for the player, and needs to be fixed if NPCs should ever use lockpicks/probes. - MWWorld::Ptr target = world->getFacedObject(); + mUpperBodyState = UpperBodyState::AttackRelease; + world->breakInvisibility(mPtr); + if (mWeaponType == ESM::Weapon::PickProbe) + { + // TODO: this will only work for the player, and needs to be fixed if NPCs should ever use + // lockpicks/probes. + MWWorld::Ptr target = world->getFacedObject(); - if (!target.isEmpty()) + if (!target.isEmpty()) + { + std::string_view resultMessage, resultSound; + if (mWeapon.getType() == ESM::Lockpick::sRecordId) + Security(mPtr).pickLock(target, mWeapon, resultMessage, resultSound); + else if (mWeapon.getType() == ESM::Probe::sRecordId) + Security(mPtr).probeTrap(target, mWeapon, resultMessage, resultSound); + if (!resultMessage.empty()) + MWBase::Environment::get().getWindowManager()->messageBox(resultMessage); + if (!resultSound.empty()) + sndMgr->playSound3D(target, resultSound, 1.0f, 1.0f); + } + } + else { - std::string_view resultMessage, resultSound; - if (mWeapon.getType() == ESM::Lockpick::sRecordId) - Security(mPtr).pickLock(target, mWeapon, resultMessage, resultSound); - else if (mWeapon.getType() == ESM::Probe::sRecordId) - Security(mPtr).probeTrap(target, mWeapon, resultMessage, resultSound); - if (!resultMessage.empty()) - MWBase::Environment::get().getWindowManager()->messageBox(resultMessage); - if (!resultSound.empty()) - sndMgr->playSound3D(target, resultSound, 1.0f, 1.0f); + mAttackStrength = calculateWindUp(); + if (mAttackStrength == -1.f) + mAttackStrength = std::min(1.f, 0.1f + Misc::Rng::rollClosedProbability(prng)); + if (weapclass != ESM::WeaponType::Ranged && weapclass != ESM::WeaponType::Thrown) + { + mAttackSuccess = cls.evaluateHit(mPtr, mAttackVictim, mAttackHitPos); + if (!mAttackSuccess) + mAttackStrength = 0.f; + playSwishSound(); + } } + + if (mWeaponType == ESM::Weapon::PickProbe || isRandomAttackAnimation(mCurrentWeapon)) + mUpperBodyState = UpperBodyState::AttackEnd; } - else + + if (mUpperBodyState == UpperBodyState::AttackRelease) { - mAttackStrength = calculateWindUp(); - if (mAttackStrength == -1.f) - mAttackStrength = std::min(1.f, 0.1f + Misc::Rng::rollClosedProbability(prng)); - if (weapclass != ESM::WeaponType::Ranged && weapclass != ESM::WeaponType::Thrown) + // The release state might have been reached before reaching the wind-up section. We'll play the new section + // only when the wind-up section is reached. + float currentTime = mAnimation->getCurrentTime(mCurrentWeapon); + float minAttackTime = mAnimation->getTextKeyTime(mCurrentWeapon + ": " + mAttackType + " min attack"); + float maxAttackTime = mAnimation->getTextKeyTime(mCurrentWeapon + ": " + mAttackType + " max attack"); + if (minAttackTime <= currentTime && currentTime <= maxAttackTime) + { + std::string hit = mAttackType != "shoot" ? "hit" : "release"; + + float startPoint = 0.f; + + // Skip a bit of the pre-hit section based on the attack strength + if (minAttackTime != -1.f && minAttackTime < maxAttackTime) + { + startPoint = 1.f - mAttackStrength; + float minHitTime = mAnimation->getTextKeyTime(mCurrentWeapon + ": " + mAttackType + " min hit"); + float hitTime = mAnimation->getTextKeyTime(mCurrentWeapon + ": " + mAttackType + ' ' + hit); + if (maxAttackTime <= minHitTime && minHitTime < hitTime) + startPoint *= (minHitTime - maxAttackTime) / (hitTime - maxAttackTime); + } + + mAnimation->disable(mCurrentWeapon); + mAnimation->play(mCurrentWeapon, priorityWeapon, MWRender::Animation::BlendMask_All, false, weapSpeed, + mAttackType + " max attack", mAttackType + ' ' + hit, startPoint, 0); + } + + animPlaying = mAnimation->getInfo(mCurrentWeapon, &complete); + + // Try playing the "follow" section if the attack animation ended naturally or didn't play at all. + if (!animPlaying || (currentTime >= maxAttackTime && complete >= 1.f)) { - mAttackSuccess = cls.evaluateHit(mPtr, mAttackVictim, mAttackHitPos); - if (!mAttackSuccess) - mAttackStrength = 0.f; - playSwishSound(); + std::string start = "follow start"; + std::string stop = "follow stop"; + + if (mAttackType != "shoot") + { + std::string strength = mAttackStrength < 0.33f ? "small" + : mAttackStrength < 0.66f ? "medium" + : "large"; + start = strength + ' ' + start; + stop = strength + ' ' + stop; + } + + if (animPlaying) + mAnimation->disable(mCurrentWeapon); + MWRender::Animation::AnimPriority priorityFollow(priorityWeapon); + // Follow animations have lower priority than movement for non-biped creatures, logic be damned + if (!cls.isBipedal(mPtr)) + priorityFollow = Priority_Default; + mAnimation->play(mCurrentWeapon, priorityFollow, MWRender::Animation::BlendMask_All, false, weapSpeed, + mAttackType + ' ' + start, mAttackType + ' ' + stop, 0.0f, 0); + mUpperBodyState = UpperBodyState::AttackEnd; + + animPlaying = mAnimation->getInfo(mCurrentWeapon, &complete); } } - if (mWeaponType == ESM::Weapon::PickProbe || isRandomAttackAnimation(mCurrentWeapon)) - mUpperBodyState = UpperBodyState::AttackEnd; - } + if (!animPlaying) + animPlaying = mAnimation->getInfo(mCurrentWeapon, &complete); - if (mUpperBodyState == UpperBodyState::AttackRelease) - { - // The release state might have been reached before reaching the wind-up section. We'll play the new section only when the wind-up section is reached. - float currentTime = mAnimation->getCurrentTime(mCurrentWeapon); - float minAttackTime = mAnimation->getTextKeyTime(mCurrentWeapon + ": " + mAttackType + " min attack"); - float maxAttackTime = mAnimation->getTextKeyTime(mCurrentWeapon + ": " + mAttackType + " max attack"); - if (minAttackTime <= currentTime && currentTime <= maxAttackTime) + if (!animPlaying || complete >= 1.f) { - std::string hit = mAttackType != "shoot" ? "hit" : "release"; + if (mUpperBodyState == UpperBodyState::Equipping || mUpperBodyState == UpperBodyState::AttackEnd + || mUpperBodyState == UpperBodyState::Casting) + { + if (ammunition && mWeaponType == ESM::Weapon::MarksmanCrossbow) + mAnimation->attachArrow(); - float startPoint = 0.f; + // Cancel stagger animation at the end of an attack to avoid abrupt transitions + // in favor of a different abrupt transition, like Morrowind + if (mUpperBodyState != UpperBodyState::Equipping && isRecovery()) + mAnimation->disable(mCurrentHit); - // Skip a bit of the pre-hit section based on the attack strength - if (minAttackTime != -1.f && minAttackTime < maxAttackTime) + if (animPlaying) + mAnimation->disable(mCurrentWeapon); + + mUpperBodyState = UpperBodyState::WeaponEquipped; + } + else if (mUpperBodyState == UpperBodyState::Unequipping) { - startPoint = 1.f - mAttackStrength; - float minHitTime = mAnimation->getTextKeyTime(mCurrentWeapon + ": " + mAttackType + " min hit"); - float hitTime = mAnimation->getTextKeyTime(mCurrentWeapon + ": " + mAttackType + ' ' + hit); - if (maxAttackTime <= minHitTime && minHitTime < hitTime) - startPoint *= (minHitTime - maxAttackTime) / (hitTime - maxAttackTime); + if (animPlaying) + mAnimation->disable(mCurrentWeapon); + mUpperBodyState = UpperBodyState::None; } - - mAnimation->disable(mCurrentWeapon); - mAnimation->play(mCurrentWeapon, priorityWeapon, MWRender::Animation::BlendMask_All, false, weapSpeed, - mAttackType + " max attack", mAttackType + ' ' + hit, startPoint, 0); } - animPlaying = mAnimation->getInfo(mCurrentWeapon, &complete); - - // Try playing the "follow" section if the attack animation ended naturally or didn't play at all. - if (!animPlaying || (currentTime >= maxAttackTime && complete >= 1.f)) + mAnimation->setPitchFactor(0.f); + if (mUpperBodyState > UpperBodyState::WeaponEquipped + && (weapclass == ESM::WeaponType::Ranged || weapclass == ESM::WeaponType::Thrown)) { - std::string start = "follow start"; - std::string stop = "follow stop"; + mAnimation->setPitchFactor(1.f); - if (mAttackType != "shoot") + // A smooth transition can be provided if a pre-wind-up section is defined. Random attack animations never + // have one. + if (mUpperBodyState == UpperBodyState::AttackWindUp && !isRandomAttackAnimation(mCurrentWeapon)) + { + float currentTime = mAnimation->getCurrentTime(mCurrentWeapon); + float minAttackTime = mAnimation->getTextKeyTime(mCurrentWeapon + ": " + mAttackType + " min attack"); + float startTime = mAnimation->getTextKeyTime(mCurrentWeapon + ": " + mAttackType + " start"); + if (startTime <= currentTime && currentTime < minAttackTime) + mAnimation->setPitchFactor((currentTime - startTime) / (minAttackTime - startTime)); + } + else if (mUpperBodyState == UpperBodyState::AttackEnd) { - std::string strength = mAttackStrength < 0.33f ? "small" : mAttackStrength < 0.66f ? "medium" : "large"; - start = strength + ' ' + start; - stop = strength + ' ' + stop; + // technically we do not need a pitch for crossbow reload animation, + // but we should avoid abrupt repositioning + if (mWeaponType == ESM::Weapon::MarksmanCrossbow) + mAnimation->setPitchFactor(std::max(0.f, 1.f - complete * 10.f)); + else + mAnimation->setPitchFactor(1.f - complete); } + } - if (animPlaying) - mAnimation->disable(mCurrentWeapon); - MWRender::Animation::AnimPriority priorityFollow(priorityWeapon); - // Follow animations have lower priority than movement for non-biped creatures, logic be damned - if (!cls.isBipedal(mPtr)) - priorityFollow = Priority_Default; - mAnimation->play(mCurrentWeapon, priorityFollow, MWRender::Animation::BlendMask_All, false, weapSpeed, mAttackType + ' ' + start, mAttackType + ' ' + stop, 0.0f, 0); - mUpperBodyState = UpperBodyState::AttackEnd; + mAnimation->setAccurateAiming(mUpperBodyState > UpperBodyState::WeaponEquipped); - animPlaying = mAnimation->getInfo(mCurrentWeapon, &complete); - } + return forcestateupdate; } - if (!animPlaying) - animPlaying = mAnimation->getInfo(mCurrentWeapon, &complete); - - if (!animPlaying || complete >= 1.f) + void CharacterController::updateAnimQueue() { - if (mUpperBodyState == UpperBodyState::Equipping || - mUpperBodyState == UpperBodyState::AttackEnd || - mUpperBodyState == UpperBodyState::Casting) + if (mAnimQueue.size() > 1) { - if (ammunition && mWeaponType == ESM::Weapon::MarksmanCrossbow) - mAnimation->attachArrow(); - - // Cancel stagger animation at the end of an attack to avoid abrupt transitions - // in favor of a different abrupt transition, like Morrowind - if (mUpperBodyState != UpperBodyState::Equipping && isRecovery()) - mAnimation->disable(mCurrentHit); - - if (animPlaying) - mAnimation->disable(mCurrentWeapon); + if (mAnimation->isPlaying(mAnimQueue.front().mGroup) == false) + { + mAnimation->disable(mAnimQueue.front().mGroup); + mAnimQueue.pop_front(); - mUpperBodyState = UpperBodyState::WeaponEquipped; - } - else if (mUpperBodyState == UpperBodyState::Unequipping) - { - if (animPlaying) - mAnimation->disable(mCurrentWeapon); - mUpperBodyState = UpperBodyState::None; + bool loopfallback = (mAnimQueue.front().mGroup.compare(0, 4, "idle") == 0); + mAnimation->play(mAnimQueue.front().mGroup, Priority_Default, MWRender::Animation::BlendMask_All, false, + 1.0f, "start", "stop", 0.0f, mAnimQueue.front().mLoopCount, loopfallback); + } } + + if (!mAnimQueue.empty()) + mAnimation->setLoopingEnabled(mAnimQueue.front().mGroup, mAnimQueue.size() <= 1); } - mAnimation->setPitchFactor(0.f); - if (mUpperBodyState > UpperBodyState::WeaponEquipped && (weapclass == ESM::WeaponType::Ranged || weapclass == ESM::WeaponType::Thrown)) + void CharacterController::update(float duration) { - mAnimation->setPitchFactor(1.f); + MWBase::World* world = MWBase::Environment::get().getWorld(); + MWBase::SoundManager* sndMgr = MWBase::Environment::get().getSoundManager(); + const MWWorld::Class& cls = mPtr.getClass(); + osg::Vec3f movement(0.f, 0.f, 0.f); + float speed = 0.f; - // A smooth transition can be provided if a pre-wind-up section is defined. Random attack animations never have one. - if (mUpperBodyState == UpperBodyState::AttackWindUp && !isRandomAttackAnimation(mCurrentWeapon)) - { - float currentTime = mAnimation->getCurrentTime(mCurrentWeapon); - float minAttackTime = mAnimation->getTextKeyTime(mCurrentWeapon + ": " + mAttackType + " min attack"); - float startTime = mAnimation->getTextKeyTime(mCurrentWeapon + ": " + mAttackType + " start"); - if (startTime <= currentTime && currentTime < minAttackTime) - mAnimation->setPitchFactor((currentTime - startTime) / (minAttackTime - startTime)); - } - else if (mUpperBodyState == UpperBodyState::AttackEnd) - { - // technically we do not need a pitch for crossbow reload animation, - // but we should avoid abrupt repositioning - if (mWeaponType == ESM::Weapon::MarksmanCrossbow) - mAnimation->setPitchFactor(std::max(0.f, 1.f-complete*10.f)); - else - mAnimation->setPitchFactor(1.f-complete); - } - } + updateMagicEffects(); - mAnimation->setAccurateAiming(mUpperBodyState > UpperBodyState::WeaponEquipped); + bool isPlayer = mPtr == MWMechanics::getPlayer(); + bool isFirstPersonPlayer = isPlayer && MWBase::Environment::get().getWorld()->isFirstPerson(); + bool godmode = isPlayer && MWBase::Environment::get().getWorld()->getGodModeState(); - return forcestateupdate; -} + float scale = mPtr.getCellRef().getScale(); -void CharacterController::updateAnimQueue() -{ - if(mAnimQueue.size() > 1) - { - if(mAnimation->isPlaying(mAnimQueue.front().mGroup) == false) + static const bool normalizeSpeed = Settings::Manager::getBool("normalise race speed", "Game"); + if (!normalizeSpeed && mPtr.getClass().isNpc()) { - mAnimation->disable(mAnimQueue.front().mGroup); - mAnimQueue.pop_front(); - - bool loopfallback = (mAnimQueue.front().mGroup.compare(0,4,"idle") == 0); - mAnimation->play(mAnimQueue.front().mGroup, Priority_Default, - MWRender::Animation::BlendMask_All, false, - 1.0f, "start", "stop", 0.0f, mAnimQueue.front().mLoopCount, loopfallback); + const ESM::NPC* npc = mPtr.get()->mBase; + const ESM::Race* race = world->getStore().get().find(npc->mRace); + float weight = npc->isMale() ? race->mData.mWeight.mMale : race->mData.mWeight.mFemale; + scale *= weight; } - } - if(!mAnimQueue.empty()) - mAnimation->setLoopingEnabled(mAnimQueue.front().mGroup, mAnimQueue.size() <= 1); -} - -void CharacterController::update(float duration) -{ - MWBase::World *world = MWBase::Environment::get().getWorld(); - MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); - const MWWorld::Class &cls = mPtr.getClass(); - osg::Vec3f movement(0.f, 0.f, 0.f); - float speed = 0.f; - - updateMagicEffects(); - - bool isPlayer = mPtr == MWMechanics::getPlayer(); - bool isFirstPersonPlayer = isPlayer && MWBase::Environment::get().getWorld()->isFirstPerson(); - bool godmode = isPlayer && MWBase::Environment::get().getWorld()->getGodModeState(); - - float scale = mPtr.getCellRef().getScale(); - - static const bool normalizeSpeed = Settings::Manager::getBool("normalise race speed", "Game"); - if (!normalizeSpeed && mPtr.getClass().isNpc()) - { - const ESM::NPC* npc = mPtr.get()->mBase; - const ESM::Race* race = world->getStore().get().find(npc->mRace); - float weight = npc->isMale() ? race->mData.mWeight.mMale : race->mData.mWeight.mFemale; - scale *= weight; - } - - if(!cls.isActor()) - updateAnimQueue(); - else if(!cls.getCreatureStats(mPtr).isDead()) - { - bool onground = world->isOnGround(mPtr); - bool incapacitated = ((!godmode && cls.getCreatureStats(mPtr).isParalyzed()) || cls.getCreatureStats(mPtr).getKnockedDown()); - bool inwater = world->isSwimming(mPtr); - bool flying = world->isFlying(mPtr); - bool solid = world->isActorCollisionEnabled(mPtr); - // Can't run and sneak while flying (see speed formula in Npc/Creature::getSpeed) - bool sneak = cls.getCreatureStats(mPtr).getStance(MWMechanics::CreatureStats::Stance_Sneak) && !flying && !inwater; - bool isrunning = cls.getCreatureStats(mPtr).getStance(MWMechanics::CreatureStats::Stance_Run) && !flying; - CreatureStats &stats = cls.getCreatureStats(mPtr); - Movement& movementSettings = cls.getMovementSettings(mPtr); - - //Force Jump Logic - - bool isMoving = (std::abs(movementSettings.mPosition[0]) > .5 || std::abs(movementSettings.mPosition[1]) > .5); - if(!inwater && !flying && solid) - { - //Force Jump - if(stats.getMovementFlag(MWMechanics::CreatureStats::Flag_ForceJump)) - movementSettings.mPosition[2] = onground ? 1 : 0; - //Force Move Jump, only jump if they're otherwise moving - if(stats.getMovementFlag(MWMechanics::CreatureStats::Flag_ForceMoveJump) && isMoving) - movementSettings.mPosition[2] = onground ? 1 : 0; - } - - osg::Vec3f rot = cls.getRotationVector(mPtr); - osg::Vec3f vec(movementSettings.asVec3()); - movementSettings.mSpeedFactor = std::min(vec.length(), 1.f); - vec.normalize(); - - // TODO: Move this check to mwinput. - // Joystick analogue movement. - // Due to the half way split between walking/running, we multiply speed by 2 while walking, unless a keyboard was used. - if (isPlayer && !isrunning && !sneak && !flying && movementSettings.mSpeedFactor <= 0.5f) - movementSettings.mSpeedFactor *= 2.f; - - static const bool smoothMovement = Settings::Manager::getBool("smooth movement", "Game"); - if (smoothMovement) - { - static const float playerTurningCoef = 1.0 / std::max(0.01f, Settings::Manager::getFloat("smooth movement player turning delay", "Game")); - float angle = mPtr.getRefData().getPosition().rot[2]; - osg::Vec2f targetSpeed = Misc::rotateVec2f(osg::Vec2f(vec.x(), vec.y()), -angle) * movementSettings.mSpeedFactor; - osg::Vec2f delta = targetSpeed - mSmoothedSpeed; - float speedDelta = movementSettings.mSpeedFactor - mSmoothedSpeed.length(); - float deltaLen = delta.length(); - - float maxDelta; - if (isFirstPersonPlayer) - maxDelta = 1; - else if (std::abs(speedDelta) < deltaLen / 2) - // Turning is smooth for player and less smooth for NPCs (otherwise NPC can miss a path point). - maxDelta = duration * (isPlayer ? playerTurningCoef : 6.f); - else if (isPlayer && speedDelta < -deltaLen / 2) - // As soon as controls are released, mwinput switches player from running to walking. - // So stopping should be instant for player, otherwise it causes a small twitch. - maxDelta = 1; - else // In all other cases speeding up and stopping are smooth. - maxDelta = duration * 3.f; - - if (deltaLen > maxDelta) - delta *= maxDelta / deltaLen; - mSmoothedSpeed += delta; - - osg::Vec2f newSpeed = Misc::rotateVec2f(mSmoothedSpeed, angle); - movementSettings.mSpeedFactor = newSpeed.normalize(); - vec.x() = newSpeed.x(); - vec.y() = newSpeed.y(); - - const float eps = 0.001f; - if (movementSettings.mSpeedFactor < eps) - { - movementSettings.mSpeedFactor = 0; - vec.x() = 0; - vec.y() = 1; - } - else if ((vec.y() < 0) != mIsMovingBackward) - { - if (targetSpeed.length() < eps || (movementSettings.mPosition[1] < 0) == mIsMovingBackward) - vec.y() = mIsMovingBackward ? -eps : eps; + if (!cls.isActor()) + updateAnimQueue(); + else if (!cls.getCreatureStats(mPtr).isDead()) + { + bool onground = world->isOnGround(mPtr); + bool incapacitated = ((!godmode && cls.getCreatureStats(mPtr).isParalyzed()) + || cls.getCreatureStats(mPtr).getKnockedDown()); + bool inwater = world->isSwimming(mPtr); + bool flying = world->isFlying(mPtr); + bool solid = world->isActorCollisionEnabled(mPtr); + // Can't run and sneak while flying (see speed formula in Npc/Creature::getSpeed) + bool sneak + = cls.getCreatureStats(mPtr).getStance(MWMechanics::CreatureStats::Stance_Sneak) && !flying && !inwater; + bool isrunning = cls.getCreatureStats(mPtr).getStance(MWMechanics::CreatureStats::Stance_Run) && !flying; + CreatureStats& stats = cls.getCreatureStats(mPtr); + Movement& movementSettings = cls.getMovementSettings(mPtr); + + // Force Jump Logic + + bool isMoving + = (std::abs(movementSettings.mPosition[0]) > .5 || std::abs(movementSettings.mPosition[1]) > .5); + if (!inwater && !flying && solid) + { + // Force Jump + if (stats.getMovementFlag(MWMechanics::CreatureStats::Flag_ForceJump)) + movementSettings.mPosition[2] = onground ? 1 : 0; + // Force Move Jump, only jump if they're otherwise moving + if (stats.getMovementFlag(MWMechanics::CreatureStats::Flag_ForceMoveJump) && isMoving) + movementSettings.mPosition[2] = onground ? 1 : 0; } + + osg::Vec3f rot = cls.getRotationVector(mPtr); + osg::Vec3f vec(movementSettings.asVec3()); + movementSettings.mSpeedFactor = std::min(vec.length(), 1.f); vec.normalize(); - } - float effectiveRotation = rot.z(); - bool canMove = cls.getMaxSpeed(mPtr) > 0; - static const bool turnToMovementDirection = Settings::Manager::getBool("turn to movement direction", "Game"); - if (!turnToMovementDirection || isFirstPersonPlayer) - { - movementSettings.mIsStrafing = std::abs(vec.x()) > std::abs(vec.y()) * 2; - stats.setSideMovementAngle(0); - } - else if (canMove) - { - float targetMovementAngle = vec.y() >= 0 ? std::atan2(-vec.x(), vec.y()) : std::atan2(vec.x(), -vec.y()); - movementSettings.mIsStrafing = (stats.getDrawState() != MWMechanics::DrawState::Nothing || inwater) - && std::abs(targetMovementAngle) > osg::DegreesToRadians(60.0f); - if (movementSettings.mIsStrafing) - targetMovementAngle = 0; - float delta = targetMovementAngle - stats.getSideMovementAngle(); - float cosDelta = cosf(delta); + // TODO: Move this check to mwinput. + // Joystick analogue movement. + // Due to the half way split between walking/running, we multiply speed by 2 while walking, unless a + // keyboard was used. + if (isPlayer && !isrunning && !sneak && !flying && movementSettings.mSpeedFactor <= 0.5f) + movementSettings.mSpeedFactor *= 2.f; - if ((vec.y() < 0) == mIsMovingBackward) - movementSettings.mSpeedFactor *= std::min(std::max(cosDelta, 0.f) + 0.3f, 1.f); // slow down when turn - if (std::abs(delta) < osg::DegreesToRadians(20.0f)) - mIsMovingBackward = vec.y() < 0; + static const bool smoothMovement = Settings::Manager::getBool("smooth movement", "Game"); + if (smoothMovement) + { + static const float playerTurningCoef = 1.0 + / std::max(0.01f, Settings::Manager::getFloat("smooth movement player turning delay", "Game")); + float angle = mPtr.getRefData().getPosition().rot[2]; + osg::Vec2f targetSpeed + = Misc::rotateVec2f(osg::Vec2f(vec.x(), vec.y()), -angle) * movementSettings.mSpeedFactor; + osg::Vec2f delta = targetSpeed - mSmoothedSpeed; + float speedDelta = movementSettings.mSpeedFactor - mSmoothedSpeed.length(); + float deltaLen = delta.length(); + + float maxDelta; + if (isFirstPersonPlayer) + maxDelta = 1; + else if (std::abs(speedDelta) < deltaLen / 2) + // Turning is smooth for player and less smooth for NPCs (otherwise NPC can miss a path point). + maxDelta = duration * (isPlayer ? playerTurningCoef : 6.f); + else if (isPlayer && speedDelta < -deltaLen / 2) + // As soon as controls are released, mwinput switches player from running to walking. + // So stopping should be instant for player, otherwise it causes a small twitch. + maxDelta = 1; + else // In all other cases speeding up and stopping are smooth. + maxDelta = duration * 3.f; + + if (deltaLen > maxDelta) + delta *= maxDelta / deltaLen; + mSmoothedSpeed += delta; + + osg::Vec2f newSpeed = Misc::rotateVec2f(mSmoothedSpeed, angle); + movementSettings.mSpeedFactor = newSpeed.normalize(); + vec.x() = newSpeed.x(); + vec.y() = newSpeed.y(); + + const float eps = 0.001f; + if (movementSettings.mSpeedFactor < eps) + { + movementSettings.mSpeedFactor = 0; + vec.x() = 0; + vec.y() = 1; + } + else if ((vec.y() < 0) != mIsMovingBackward) + { + if (targetSpeed.length() < eps || (movementSettings.mPosition[1] < 0) == mIsMovingBackward) + vec.y() = mIsMovingBackward ? -eps : eps; + } + vec.normalize(); + } - float maxDelta = osg::PI * duration * (2.5f - cosDelta); - delta = std::clamp(delta, -maxDelta, maxDelta); - stats.setSideMovementAngle(stats.getSideMovementAngle() + delta); - effectiveRotation += delta; - } + float effectiveRotation = rot.z(); + bool canMove = cls.getMaxSpeed(mPtr) > 0; + static const bool turnToMovementDirection + = Settings::Manager::getBool("turn to movement direction", "Game"); + if (!turnToMovementDirection || isFirstPersonPlayer) + { + movementSettings.mIsStrafing = std::abs(vec.x()) > std::abs(vec.y()) * 2; + stats.setSideMovementAngle(0); + } + else if (canMove) + { + float targetMovementAngle + = vec.y() >= 0 ? std::atan2(-vec.x(), vec.y()) : std::atan2(vec.x(), -vec.y()); + movementSettings.mIsStrafing = (stats.getDrawState() != MWMechanics::DrawState::Nothing || inwater) + && std::abs(targetMovementAngle) > osg::DegreesToRadians(60.0f); + if (movementSettings.mIsStrafing) + targetMovementAngle = 0; + float delta = targetMovementAngle - stats.getSideMovementAngle(); + float cosDelta = cosf(delta); + + if ((vec.y() < 0) == mIsMovingBackward) + movementSettings.mSpeedFactor + *= std::min(std::max(cosDelta, 0.f) + 0.3f, 1.f); // slow down when turn + if (std::abs(delta) < osg::DegreesToRadians(20.0f)) + mIsMovingBackward = vec.y() < 0; + + float maxDelta = osg::PI * duration * (2.5f - cosDelta); + delta = std::clamp(delta, -maxDelta, maxDelta); + stats.setSideMovementAngle(stats.getSideMovementAngle() + delta); + effectiveRotation += delta; + } - mAnimation->setLegsYawRadians(stats.getSideMovementAngle()); - if (stats.getDrawState() == MWMechanics::DrawState::Nothing || inwater) - mAnimation->setUpperBodyYawRadians(stats.getSideMovementAngle() / 2); - else - mAnimation->setUpperBodyYawRadians(stats.getSideMovementAngle() / 4); - if (smoothMovement && !isPlayer && !inwater) - mAnimation->setUpperBodyYawRadians(mAnimation->getUpperBodyYawRadians() + mAnimation->getHeadYaw() / 2); + mAnimation->setLegsYawRadians(stats.getSideMovementAngle()); + if (stats.getDrawState() == MWMechanics::DrawState::Nothing || inwater) + mAnimation->setUpperBodyYawRadians(stats.getSideMovementAngle() / 2); + else + mAnimation->setUpperBodyYawRadians(stats.getSideMovementAngle() / 4); + if (smoothMovement && !isPlayer && !inwater) + mAnimation->setUpperBodyYawRadians(mAnimation->getUpperBodyYawRadians() + mAnimation->getHeadYaw() / 2); - speed = cls.getCurrentSpeed(mPtr); - vec.x() *= speed; - vec.y() *= speed; + speed = cls.getCurrentSpeed(mPtr); + vec.x() *= speed; + vec.y() *= speed; - if(mHitState != CharState_None && mHitState != CharState_Block && mJumpState == JumpState_None) - vec = osg::Vec3f(); + if (mHitState != CharState_None && mHitState != CharState_Block && mJumpState == JumpState_None) + vec = osg::Vec3f(); - CharacterState movestate = CharState_None; - CharacterState idlestate = CharState_None; - JumpingState jumpstate = JumpState_None; + CharacterState movestate = CharState_None; + CharacterState idlestate = CharState_None; + JumpingState jumpstate = JumpState_None; - mHasMovedInXY = std::abs(vec.x())+std::abs(vec.y()) > 0.0f; - isrunning = isrunning && mHasMovedInXY; + mHasMovedInXY = std::abs(vec.x()) + std::abs(vec.y()) > 0.0f; + isrunning = isrunning && mHasMovedInXY; - // advance athletics - if(mHasMovedInXY && isPlayer) - { - if(inwater) + // advance athletics + if (mHasMovedInXY && isPlayer) { - mSecondsOfSwimming += duration; - while(mSecondsOfSwimming > 1) + if (inwater) { - cls.skillUsageSucceeded(mPtr, ESM::Skill::Athletics, 1); - mSecondsOfSwimming -= 1; + mSecondsOfSwimming += duration; + while (mSecondsOfSwimming > 1) + { + cls.skillUsageSucceeded(mPtr, ESM::Skill::Athletics, 1); + mSecondsOfSwimming -= 1; + } } - } - else if(isrunning && !sneak) - { - mSecondsOfRunning += duration; - while(mSecondsOfRunning > 1) + else if (isrunning && !sneak) { - cls.skillUsageSucceeded(mPtr, ESM::Skill::Athletics, 0); - mSecondsOfRunning -= 1; + mSecondsOfRunning += duration; + while (mSecondsOfRunning > 1) + { + cls.skillUsageSucceeded(mPtr, ESM::Skill::Athletics, 0); + mSecondsOfRunning -= 1; + } } } - } - // reduce fatigue - const MWWorld::Store &gmst = world->getStore().get(); - float fatigueLoss = 0; - static const float fFatigueRunBase = gmst.find("fFatigueRunBase")->mValue.getFloat(); - static const float fFatigueRunMult = gmst.find("fFatigueRunMult")->mValue.getFloat(); - static const float fFatigueSwimWalkBase = gmst.find("fFatigueSwimWalkBase")->mValue.getFloat(); - static const float fFatigueSwimRunBase = gmst.find("fFatigueSwimRunBase")->mValue.getFloat(); - static const float fFatigueSwimWalkMult = gmst.find("fFatigueSwimWalkMult")->mValue.getFloat(); - static const float fFatigueSwimRunMult = gmst.find("fFatigueSwimRunMult")->mValue.getFloat(); - static const float fFatigueSneakBase = gmst.find("fFatigueSneakBase")->mValue.getFloat(); - static const float fFatigueSneakMult = gmst.find("fFatigueSneakMult")->mValue.getFloat(); - - if (cls.getEncumbrance(mPtr) <= cls.getCapacity(mPtr)) - { - const float encumbrance = cls.getNormalizedEncumbrance(mPtr); - if (sneak) - fatigueLoss = fFatigueSneakBase + encumbrance * fFatigueSneakMult; - else + // reduce fatigue + const MWWorld::Store& gmst = world->getStore().get(); + float fatigueLoss = 0; + static const float fFatigueRunBase = gmst.find("fFatigueRunBase")->mValue.getFloat(); + static const float fFatigueRunMult = gmst.find("fFatigueRunMult")->mValue.getFloat(); + static const float fFatigueSwimWalkBase = gmst.find("fFatigueSwimWalkBase")->mValue.getFloat(); + static const float fFatigueSwimRunBase = gmst.find("fFatigueSwimRunBase")->mValue.getFloat(); + static const float fFatigueSwimWalkMult = gmst.find("fFatigueSwimWalkMult")->mValue.getFloat(); + static const float fFatigueSwimRunMult = gmst.find("fFatigueSwimRunMult")->mValue.getFloat(); + static const float fFatigueSneakBase = gmst.find("fFatigueSneakBase")->mValue.getFloat(); + static const float fFatigueSneakMult = gmst.find("fFatigueSneakMult")->mValue.getFloat(); + + if (cls.getEncumbrance(mPtr) <= cls.getCapacity(mPtr)) { - if (inwater) + const float encumbrance = cls.getNormalizedEncumbrance(mPtr); + if (sneak) + fatigueLoss = fFatigueSneakBase + encumbrance * fFatigueSneakMult; + else { - if (!isrunning) - fatigueLoss = fFatigueSwimWalkBase + encumbrance * fFatigueSwimWalkMult; - else - fatigueLoss = fFatigueSwimRunBase + encumbrance * fFatigueSwimRunMult; + if (inwater) + { + if (!isrunning) + fatigueLoss = fFatigueSwimWalkBase + encumbrance * fFatigueSwimWalkMult; + else + fatigueLoss = fFatigueSwimRunBase + encumbrance * fFatigueSwimRunMult; + } + else if (isrunning) + fatigueLoss = fFatigueRunBase + encumbrance * fFatigueRunMult; } - else if (isrunning) - fatigueLoss = fFatigueRunBase + encumbrance * fFatigueRunMult; } - } - fatigueLoss *= duration; - fatigueLoss *= movementSettings.mSpeedFactor; - DynamicStat fatigue = cls.getCreatureStats(mPtr).getFatigue(); - - if (!godmode) - { - fatigue.setCurrent(fatigue.getCurrent() - fatigueLoss, fatigue.getCurrent() < 0); - cls.getCreatureStats(mPtr).setFatigue(fatigue); - } + fatigueLoss *= duration; + fatigueLoss *= movementSettings.mSpeedFactor; + DynamicStat fatigue = cls.getCreatureStats(mPtr).getFatigue(); - float z = cls.getJump(mPtr); - if(sneak || inwater || flying || incapacitated || !solid || z <= 0) - vec.z() = 0.0f; + if (!godmode) + { + fatigue.setCurrent(fatigue.getCurrent() - fatigueLoss, fatigue.getCurrent() < 0); + cls.getCreatureStats(mPtr).setFatigue(fatigue); + } - bool inJump = true; - bool playLandingSound = false; - if(!onground && !flying && !inwater && solid) - { - // In the air (either getting up —ascending part of jump— or falling). - jumpstate = JumpState_InAir; + float z = cls.getJump(mPtr); + if (sneak || inwater || flying || incapacitated || !solid || z <= 0) + vec.z() = 0.0f; - static const float fJumpMoveBase = gmst.find("fJumpMoveBase")->mValue.getFloat(); - static const float fJumpMoveMult = gmst.find("fJumpMoveMult")->mValue.getFloat(); - float factor = fJumpMoveBase + fJumpMoveMult * mPtr.getClass().getSkill(mPtr, ESM::Skill::Acrobatics)/100.f; - factor = std::min(1.f, factor); - vec.x() *= factor; - vec.y() *= factor; - vec.z() = 0.0f; - } - else if(vec.z() > 0.0f && mJumpState != JumpState_InAir) - { - // Started a jump. - if (z > 0) + bool inJump = true; + bool playLandingSound = false; + if (!onground && !flying && !inwater && solid) { - if(vec.x() == 0 && vec.y() == 0) - vec = osg::Vec3f(0.0f, 0.0f, z); - else + // In the air (either getting up —ascending part of jump— or falling). + jumpstate = JumpState_InAir; + + static const float fJumpMoveBase = gmst.find("fJumpMoveBase")->mValue.getFloat(); + static const float fJumpMoveMult = gmst.find("fJumpMoveMult")->mValue.getFloat(); + float factor + = fJumpMoveBase + fJumpMoveMult * mPtr.getClass().getSkill(mPtr, ESM::Skill::Acrobatics) / 100.f; + factor = std::min(1.f, factor); + vec.x() *= factor; + vec.y() *= factor; + vec.z() = 0.0f; + } + else if (vec.z() > 0.0f && mJumpState != JumpState_InAir) + { + // Started a jump. + if (z > 0) { - osg::Vec3f lat (vec.x(), vec.y(), 0.0f); - lat.normalize(); - vec = osg::Vec3f(lat.x(), lat.y(), 1.0f) * z * 0.707f; + if (vec.x() == 0 && vec.y() == 0) + vec = osg::Vec3f(0.0f, 0.0f, z); + else + { + osg::Vec3f lat(vec.x(), vec.y(), 0.0f); + lat.normalize(); + vec = osg::Vec3f(lat.x(), lat.y(), 1.0f) * z * 0.707f; + } } } - } - else - { - if (mJumpState == JumpState_InAir && !flying && solid) + else { - float height = cls.getCreatureStats(mPtr).land(isPlayer); - float healthLost = 0.f; - if (!inwater) - healthLost = getFallDamage(mPtr, height); - - if (healthLost > 0.0f) + if (mJumpState == JumpState_InAir && !flying && solid) { - const float fatigueTerm = cls.getCreatureStats(mPtr).getFatigueTerm(); + float height = cls.getCreatureStats(mPtr).land(isPlayer); + float healthLost = 0.f; + if (!inwater) + healthLost = getFallDamage(mPtr, height); - // inflict fall damages - if (!godmode) + if (healthLost > 0.0f) { - DynamicStat health = cls.getCreatureStats(mPtr).getHealth(); - float realHealthLost = healthLost * (1.0f - 0.25f * fatigueTerm); - health.setCurrent(health.getCurrent() - realHealthLost); - cls.getCreatureStats(mPtr).setHealth(health); - sndMgr->playSound3D(mPtr, "Health Damage", 1.0f, 1.0f); - if (isPlayer) - MWBase::Environment::get().getWindowManager()->activateHitOverlay(); - } + const float fatigueTerm = cls.getCreatureStats(mPtr).getFatigueTerm(); - const float acrobaticsSkill = cls.getSkill(mPtr, ESM::Skill::Acrobatics); - if (healthLost > (acrobaticsSkill * fatigueTerm)) - { + // inflict fall damages if (!godmode) - cls.getCreatureStats(mPtr).setKnockedDown(true); - } - else - { - // report acrobatics progression - if (isPlayer) - cls.skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 1); + { + DynamicStat health = cls.getCreatureStats(mPtr).getHealth(); + float realHealthLost = healthLost * (1.0f - 0.25f * fatigueTerm); + health.setCurrent(health.getCurrent() - realHealthLost); + cls.getCreatureStats(mPtr).setHealth(health); + sndMgr->playSound3D(mPtr, "Health Damage", 1.0f, 1.0f); + if (isPlayer) + MWBase::Environment::get().getWindowManager()->activateHitOverlay(); + } + + const float acrobaticsSkill = cls.getSkill(mPtr, ESM::Skill::Acrobatics); + if (healthLost > (acrobaticsSkill * fatigueTerm)) + { + if (!godmode) + cls.getCreatureStats(mPtr).setKnockedDown(true); + } + else + { + // report acrobatics progression + if (isPlayer) + cls.skillUsageSucceeded(mPtr, ESM::Skill::Acrobatics, 1); + } } + + if (mPtr.getClass().isNpc()) + playLandingSound = true; } - if (mPtr.getClass().isNpc()) - playLandingSound = true; - } + if (mAnimation->isPlaying(mCurrentJump)) + jumpstate = JumpState_Landing; - if (mAnimation->isPlaying(mCurrentJump)) - jumpstate = JumpState_Landing; + vec.x() *= scale; + vec.y() *= scale; + vec.z() = 0.0f; - vec.x() *= scale; - vec.y() *= scale; - vec.z() = 0.0f; + inJump = false; - inJump = false; + if (movementSettings.mIsStrafing) + { + if (vec.x() > 0.0f) + movestate = (inwater ? (isrunning ? CharState_SwimRunRight : CharState_SwimWalkRight) + : (sneak ? CharState_SneakRight + : (isrunning ? CharState_RunRight : CharState_WalkRight))); + else if (vec.x() < 0.0f) + movestate = (inwater + ? (isrunning ? CharState_SwimRunLeft : CharState_SwimWalkLeft) + : (sneak ? CharState_SneakLeft : (isrunning ? CharState_RunLeft : CharState_WalkLeft))); + } + else if (vec.length2() > 0.0f) + { + if (vec.y() >= 0.0f) + movestate = (inwater ? (isrunning ? CharState_SwimRunForward : CharState_SwimWalkForward) + : (sneak ? CharState_SneakForward + : (isrunning ? CharState_RunForward : CharState_WalkForward))); + else + movestate = (inwater + ? (isrunning ? CharState_SwimRunBack : CharState_SwimWalkBack) + : (sneak ? CharState_SneakBack : (isrunning ? CharState_RunBack : CharState_WalkBack))); + } + else + { + // Do not play turning animation for player if rotation speed is very slow. + // Actual threshold should take framerate in account. + float rotationThreshold = (isPlayer ? 0.015f : 0.001f) * 60 * duration; + + // It seems only bipedal actors use turning animations. + // Also do not use turning animations in the first-person view and when sneaking. + if (!sneak && !isFirstPersonPlayer && mPtr.getClass().isBipedal(mPtr)) + { + if (effectiveRotation > rotationThreshold) + movestate = inwater ? CharState_SwimTurnRight : CharState_TurnRight; + else if (effectiveRotation < -rotationThreshold) + movestate = inwater ? CharState_SwimTurnLeft : CharState_TurnLeft; + } + } + } - if (movementSettings.mIsStrafing) + if (playLandingSound) { - if(vec.x() > 0.0f) - movestate = (inwater ? (isrunning ? CharState_SwimRunRight : CharState_SwimWalkRight) - : (sneak ? CharState_SneakRight - : (isrunning ? CharState_RunRight : CharState_WalkRight))); - else if(vec.x() < 0.0f) - movestate = (inwater ? (isrunning ? CharState_SwimRunLeft : CharState_SwimWalkLeft) - : (sneak ? CharState_SneakLeft - : (isrunning ? CharState_RunLeft : CharState_WalkLeft))); + std::string_view sound; + osg::Vec3f pos(mPtr.getRefData().getPosition().asVec3()); + if (world->isUnderwater(mPtr.getCell(), pos) || world->isWalkingOnWater(mPtr)) + sound = "DefaultLandWater"; + else if (onground) + sound = "DefaultLand"; + + if (!sound.empty()) + sndMgr->playSound3D(mPtr, sound, 1.f, 1.f, MWSound::Type::Foot, MWSound::PlayMode::NoPlayerLocal); } - else if (vec.length2() > 0.0f) + + if (turnToMovementDirection && !isFirstPersonPlayer + && (movestate == CharState_SwimRunForward || movestate == CharState_SwimWalkForward + || movestate == CharState_SwimRunBack || movestate == CharState_SwimWalkBack)) { - if (vec.y() >= 0.0f) - movestate = (inwater ? (isrunning ? CharState_SwimRunForward : CharState_SwimWalkForward) - : (sneak ? CharState_SneakForward - : (isrunning ? CharState_RunForward : CharState_WalkForward))); - else - movestate = (inwater ? (isrunning ? CharState_SwimRunBack : CharState_SwimWalkBack) - : (sneak ? CharState_SneakBack - : (isrunning ? CharState_RunBack : CharState_WalkBack))); + float swimmingPitch = mAnimation->getBodyPitchRadians(); + float targetSwimmingPitch = -mPtr.getRefData().getPosition().rot[0]; + float maxSwimPitchDelta = 3.0f * duration; + swimmingPitch += std::clamp(targetSwimmingPitch - swimmingPitch, -maxSwimPitchDelta, maxSwimPitchDelta); + mAnimation->setBodyPitchRadians(swimmingPitch); } else + mAnimation->setBodyPitchRadians(0); + + static const bool swimUpwardCorrection = Settings::Manager::getBool("swim upward correction", "Game"); + if (inwater && isPlayer && !isFirstPersonPlayer && swimUpwardCorrection) { - // Do not play turning animation for player if rotation speed is very slow. - // Actual threshold should take framerate in account. - float rotationThreshold = (isPlayer ? 0.015f : 0.001f) * 60 * duration; + static const float swimUpwardCoef = Settings::Manager::getFloat("swim upward coef", "Game"); + static const float swimForwardCoef = sqrtf(1.0f - swimUpwardCoef * swimUpwardCoef); + vec.z() = std::abs(vec.y()) * swimUpwardCoef; + vec.y() *= swimForwardCoef; + } - // It seems only bipedal actors use turning animations. - // Also do not use turning animations in the first-person view and when sneaking. - if (!sneak && !isFirstPersonPlayer && mPtr.getClass().isBipedal(mPtr)) + // Player can not use smooth turning as NPCs, so we play turning animation a bit to avoid jittering + if (isPlayer) + { + float threshold = mCurrentMovement.find("swim") == std::string::npos ? 0.4f : 0.8f; + float complete; + bool animPlaying = mAnimation->getInfo(mCurrentMovement, &complete); + if (movestate == CharState_None && jumpstate == JumpState_None && isTurning()) { - if(effectiveRotation > rotationThreshold) - movestate = inwater ? CharState_SwimTurnRight : CharState_TurnRight; - else if(effectiveRotation < -rotationThreshold) - movestate = inwater ? CharState_SwimTurnLeft : CharState_TurnLeft; + if (animPlaying && complete < threshold) + movestate = mMovementState; } } - } + else + { + if (mPtr.getClass().isBipedal(mPtr)) + { + if (mTurnAnimationThreshold > 0) + mTurnAnimationThreshold -= duration; - if (playLandingSound) - { - std::string_view sound; - osg::Vec3f pos(mPtr.getRefData().getPosition().asVec3()); - if (world->isUnderwater(mPtr.getCell(), pos) || world->isWalkingOnWater(mPtr)) - sound = "DefaultLandWater"; - else if (onground) - sound = "DefaultLand"; + if (movestate == CharState_TurnRight || movestate == CharState_TurnLeft + || movestate == CharState_SwimTurnRight || movestate == CharState_SwimTurnLeft) + { + mTurnAnimationThreshold = 0.05f; + } + else if (movestate == CharState_None && isTurning() && mTurnAnimationThreshold > 0) + { + movestate = mMovementState; + } + } + } - if (!sound.empty()) - sndMgr->playSound3D(mPtr, sound, 1.f, 1.f, MWSound::Type::Foot, MWSound::PlayMode::NoPlayerLocal); - } + if (movestate != CharState_None) + { + clearAnimQueue(); + jumpstate = JumpState_None; + } - if (turnToMovementDirection && !isFirstPersonPlayer && - (movestate == CharState_SwimRunForward || movestate == CharState_SwimWalkForward || - movestate == CharState_SwimRunBack || movestate == CharState_SwimWalkBack)) - { - float swimmingPitch = mAnimation->getBodyPitchRadians(); - float targetSwimmingPitch = -mPtr.getRefData().getPosition().rot[0]; - float maxSwimPitchDelta = 3.0f * duration; - swimmingPitch += std::clamp(targetSwimmingPitch - swimmingPitch, -maxSwimPitchDelta, maxSwimPitchDelta); - mAnimation->setBodyPitchRadians(swimmingPitch); - } - else - mAnimation->setBodyPitchRadians(0); + if (mAnimQueue.empty() || inwater || (sneak && mIdleState != CharState_SpecialIdle)) + { + if (inwater) + idlestate = CharState_IdleSwim; + else if (sneak && !inJump) + idlestate = CharState_IdleSneak; + else + idlestate = CharState_Idle; + } + else + updateAnimQueue(); - static const bool swimUpwardCorrection = Settings::Manager::getBool("swim upward correction", "Game"); - if (inwater && isPlayer && !isFirstPersonPlayer && swimUpwardCorrection) - { - static const float swimUpwardCoef = Settings::Manager::getFloat("swim upward coef", "Game"); - static const float swimForwardCoef = sqrtf(1.0f - swimUpwardCoef * swimUpwardCoef); - vec.z() = std::abs(vec.y()) * swimUpwardCoef; - vec.y() *= swimForwardCoef; - } + if (!mSkipAnim) + { + refreshCurrentAnims(idlestate, movestate, jumpstate, updateWeaponState()); + updateIdleStormState(inwater); + } - // Player can not use smooth turning as NPCs, so we play turning animation a bit to avoid jittering - if (isPlayer) - { - float threshold = mCurrentMovement.find("swim") == std::string::npos ? 0.4f : 0.8f; - float complete; - bool animPlaying = mAnimation->getInfo(mCurrentMovement, &complete); - if (movestate == CharState_None && jumpstate == JumpState_None && isTurning()) + if (inJump) + mMovementAnimationControlled = false; + + if (isTurning()) { - if (animPlaying && complete < threshold) - movestate = mMovementState; + // Adjust animation speed from 1.0 to 1.5 multiplier + if (duration > 0) + { + float turnSpeed = std::min(1.5f, std::abs(rot.z()) / duration / static_cast(osg::PI)); + mAnimation->adjustSpeedMult(mCurrentMovement, std::max(turnSpeed, 1.0f)); + } } - } - else - { - if (mPtr.getClass().isBipedal(mPtr)) + else if (mMovementState != CharState_None && mAdjustMovementAnimSpeed) { - if (mTurnAnimationThreshold > 0) - mTurnAnimationThreshold -= duration; + // Vanilla caps the played animation speed. + const float maxSpeedMult = 10.f; + const float speedMult = speed / mMovementAnimSpeed; + mAnimation->adjustSpeedMult(mCurrentMovement, std::min(maxSpeedMult, speedMult)); + // Make sure the actual speed is the "expected" speed even though the animation is slower + scale *= std::max(1.f, speedMult / maxSpeedMult); + } - if (movestate == CharState_TurnRight || movestate == CharState_TurnLeft || - movestate == CharState_SwimTurnRight || movestate == CharState_SwimTurnLeft) + if (!mSkipAnim) + { + if (!isKnockedDown() && !isKnockedOut()) { - mTurnAnimationThreshold = 0.05f; + if (rot != osg::Vec3f()) + world->rotateObject(mPtr, rot, true); } - else if (movestate == CharState_None && isTurning() - && mTurnAnimationThreshold > 0) + else // avoid z-rotating for knockdown { - movestate = mMovementState; + if (rot.x() != 0 && rot.y() != 0) + { + rot.z() = 0.0f; + world->rotateObject(mPtr, rot, true); + } } + + if (!mMovementAnimationControlled) + world->queueMovement(mPtr, vec); } - } - if (movestate != CharState_None) - { - clearAnimQueue(); - jumpstate = JumpState_None; - } + movement = vec; + movementSettings.mPosition[0] = movementSettings.mPosition[1] = 0; + if (movement.z() == 0.f) + movementSettings.mPosition[2] = 0; + // Can't reset jump state (mPosition[2]) here in full; we don't know for sure whether the PhysicSystem will + // actually handle it in this frame due to the fixed minimum timestep used for the physics update. It will + // be reset in PhysicSystem::move once the jump is handled. - if(mAnimQueue.empty() || inwater || (sneak && mIdleState != CharState_SpecialIdle)) - { - if (inwater) - idlestate = CharState_IdleSwim; - else if (sneak && !inJump) - idlestate = CharState_IdleSneak; - else - idlestate = CharState_Idle; + if (!mSkipAnim) + updateHeadTracking(duration); } - else - updateAnimQueue(); - - if (!mSkipAnim) + else if (cls.getCreatureStats(mPtr).isDead()) { - refreshCurrentAnims(idlestate, movestate, jumpstate, updateWeaponState()); - updateIdleStormState(inwater); + // initial start of death animation for actors that started the game as dead + // not done in constructor since we need to give scripts a chance to set the mSkipAnim flag + if (!mSkipAnim && mDeathState != CharState_None && mCurrentDeath.empty()) + { + // Fast-forward death animation to end for persisting corpses or corpses after end of death animation + if (cls.isPersistent(mPtr) || cls.getCreatureStats(mPtr).isDeathAnimationFinished()) + playDeath(1.f, mDeathState); + } } - if (inJump) - mMovementAnimationControlled = false; + bool isPersist = isPersistentAnimPlaying(); + osg::Vec3f moved = mAnimation->runAnimation(mSkipAnim && !isPersist ? 0.f : duration); + if (duration > 0.0f) + moved /= duration; + else + moved = osg::Vec3f(0.f, 0.f, 0.f); + + moved.x() *= scale; + moved.y() *= scale; - if (isTurning()) + // Ensure we're moving in generally the right direction... + if (speed > 0.f && moved != osg::Vec3f()) { - // Adjust animation speed from 1.0 to 1.5 multiplier - if (duration > 0) + float l = moved.length(); + if (std::abs(movement.x() - moved.x()) > std::abs(moved.x()) / 2 + || std::abs(movement.y() - moved.y()) > std::abs(moved.y()) / 2 + || std::abs(movement.z() - moved.z()) > std::abs(moved.z()) / 2) { - float turnSpeed = std::min(1.5f, std::abs(rot.z()) / duration / static_cast(osg::PI)); - mAnimation->adjustSpeedMult(mCurrentMovement, std::max(turnSpeed, 1.0f)); + moved = movement; + // For some creatures getSpeed doesn't work, so we adjust speed to the animation. + // TODO: Fix Creature::getSpeed. + float newLength = moved.length(); + if (newLength > 0 && !cls.isNpc()) + moved *= (l / newLength); } } - else if (mMovementState != CharState_None && mAdjustMovementAnimSpeed) - { - // Vanilla caps the played animation speed. - const float maxSpeedMult = 10.f; - const float speedMult = speed / mMovementAnimSpeed; - mAnimation->adjustSpeedMult(mCurrentMovement, std::min(maxSpeedMult, speedMult)); - // Make sure the actual speed is the "expected" speed even though the animation is slower - scale *= std::max(1.f, speedMult / maxSpeedMult); - } - if (!mSkipAnim) + if (mFloatToSurface && cls.isActor()) { - if(!isKnockedDown() && !isKnockedOut()) + if (cls.getCreatureStats(mPtr).isDead() + || (!godmode + && cls.getCreatureStats(mPtr).getMagicEffects().get(ESM::MagicEffect::Paralyze).getModifier() > 0)) { - if (rot != osg::Vec3f()) - world->rotateObject(mPtr, rot, true); - } - else //avoid z-rotating for knockdown - { - if (rot.x() != 0 && rot.y() != 0) - { - rot.z() = 0.0f; - world->rotateObject(mPtr, rot, true); - } + moved.z() = 1.0; } - - if (!mMovementAnimationControlled) - world->queueMovement(mPtr, vec); } - movement = vec; - movementSettings.mPosition[0] = movementSettings.mPosition[1] = 0; - if (movement.z() == 0.f) - movementSettings.mPosition[2] = 0; - // Can't reset jump state (mPosition[2]) here in full; we don't know for sure whether the PhysicSystem will actually handle it in this frame - // due to the fixed minimum timestep used for the physics update. It will be reset in PhysicSystem::move once the jump is handled. + // Update movement + if (mMovementAnimationControlled && mPtr.getClass().isActor()) + world->queueMovement(mPtr, moved); + + mSkipAnim = false; - if (!mSkipAnim) - updateHeadTracking(duration); + mAnimation->enableHeadAnimation(cls.isActor() && !cls.getCreatureStats(mPtr).isDead()); } - else if(cls.getCreatureStats(mPtr).isDead()) + + void CharacterController::persistAnimationState() const { - // initial start of death animation for actors that started the game as dead - // not done in constructor since we need to give scripts a chance to set the mSkipAnim flag - if (!mSkipAnim && mDeathState != CharState_None && mCurrentDeath.empty()) + ESM::AnimationState& state = mPtr.getRefData().getAnimationState(); + + state.mScriptedAnims.clear(); + for (AnimationQueue::const_iterator iter = mAnimQueue.begin(); iter != mAnimQueue.end(); ++iter) { - // Fast-forward death animation to end for persisting corpses or corpses after end of death animation - if (cls.isPersistent(mPtr) || cls.getCreatureStats(mPtr).isDeathAnimationFinished()) - playDeath(1.f, mDeathState); - } - } + if (!iter->mPersist) + continue; - bool isPersist = isPersistentAnimPlaying(); - osg::Vec3f moved = mAnimation->runAnimation(mSkipAnim && !isPersist ? 0.f : duration); - if(duration > 0.0f) - moved /= duration; - else - moved = osg::Vec3f(0.f, 0.f, 0.f); + ESM::AnimationState::ScriptedAnimation anim; + anim.mGroup = iter->mGroup; - moved.x() *= scale; - moved.y() *= scale; + if (iter == mAnimQueue.begin()) + { + anim.mLoopCount = mAnimation->getCurrentLoopCount(anim.mGroup); + float complete; + mAnimation->getInfo(anim.mGroup, &complete, nullptr); + anim.mTime = complete; + } + else + { + anim.mLoopCount = iter->mLoopCount; + anim.mTime = 0.f; + } - // Ensure we're moving in generally the right direction... - if (speed > 0.f && moved != osg::Vec3f()) - { - float l = moved.length(); - if (std::abs(movement.x() - moved.x()) > std::abs(moved.x()) / 2 || - std::abs(movement.y() - moved.y()) > std::abs(moved.y()) / 2 || - std::abs(movement.z() - moved.z()) > std::abs(moved.z()) / 2) - { - moved = movement; - // For some creatures getSpeed doesn't work, so we adjust speed to the animation. - // TODO: Fix Creature::getSpeed. - float newLength = moved.length(); - if (newLength > 0 && !cls.isNpc()) - moved *= (l / newLength); + state.mScriptedAnims.push_back(anim); } } - if (mFloatToSurface && cls.isActor()) + void CharacterController::unpersistAnimationState() { - if (cls.getCreatureStats(mPtr).isDead() - || (!godmode && cls.getCreatureStats(mPtr).getMagicEffects().get(ESM::MagicEffect::Paralyze).getModifier() > 0)) + const ESM::AnimationState& state = mPtr.getRefData().getAnimationState(); + + if (!state.mScriptedAnims.empty()) { - moved.z() = 1.0; - } - } + clearAnimQueue(); + for (ESM::AnimationState::ScriptedAnimations::const_iterator iter = state.mScriptedAnims.begin(); + iter != state.mScriptedAnims.end(); ++iter) + { + AnimationQueueEntry entry; + entry.mGroup = iter->mGroup; + entry.mLoopCount = iter->mLoopCount; + entry.mPersist = true; - // Update movement - if(mMovementAnimationControlled && mPtr.getClass().isActor()) - world->queueMovement(mPtr, moved); + mAnimQueue.push_back(entry); + } - mSkipAnim = false; + const ESM::AnimationState::ScriptedAnimation& anim = state.mScriptedAnims.front(); + float complete = anim.mTime; + if (anim.mAbsolute) + { + float start = mAnimation->getTextKeyTime(anim.mGroup + ": start"); + float stop = mAnimation->getTextKeyTime(anim.mGroup + ": stop"); + float time = std::clamp(anim.mTime, start, stop); + complete = (time - start) / (stop - start); + } - mAnimation->enableHeadAnimation(cls.isActor() && !cls.getCreatureStats(mPtr).isDead()); -} + clearStateAnimation(mCurrentIdle); + mIdleState = CharState_SpecialIdle; -void CharacterController::persistAnimationState() const -{ - ESM::AnimationState& state = mPtr.getRefData().getAnimationState(); + bool loopfallback = (mAnimQueue.front().mGroup.compare(0, 4, "idle") == 0); + mAnimation->play(anim.mGroup, Priority_Persistent, MWRender::Animation::BlendMask_All, false, 1.0f, "start", + "stop", complete, anim.mLoopCount, loopfallback); + } + } - state.mScriptedAnims.clear(); - for (AnimationQueue::const_iterator iter = mAnimQueue.begin(); iter != mAnimQueue.end(); ++iter) + bool CharacterController::playGroup(std::string_view groupname, int mode, int count, bool persist) { - if (!iter->mPersist) - continue; + if (!mAnimation || !mAnimation->hasAnimation(groupname)) + return false; - ESM::AnimationState::ScriptedAnimation anim; - anim.mGroup = iter->mGroup; + // We should not interrupt persistent animations by non-persistent ones + if (isPersistentAnimPlaying() && !persist) + return true; - if (iter == mAnimQueue.begin()) + // If this animation is a looped animation (has a "loop start" key) that is already playing + // and has not yet reached the end of the loop, allow it to continue animating with its existing loop count + // and remove any other animations that were queued. + // This emulates observed behavior from the original allows the script "OutsideBanner" to animate banners + // correctly. + if (!mAnimQueue.empty() && mAnimQueue.front().mGroup == groupname + && mAnimation->getTextKeyTime(mAnimQueue.front().mGroup + ": loop start") >= 0 + && mAnimation->isPlaying(groupname)) { - anim.mLoopCount = mAnimation->getCurrentLoopCount(anim.mGroup); - float complete; - mAnimation->getInfo(anim.mGroup, &complete, nullptr); - anim.mTime = complete; - } - else - { - anim.mLoopCount = iter->mLoopCount; - anim.mTime = 0.f; + float endOfLoop = mAnimation->getTextKeyTime(mAnimQueue.front().mGroup + ": loop stop"); + + if (endOfLoop < 0) // if no Loop Stop key was found, use the Stop key + endOfLoop = mAnimation->getTextKeyTime(mAnimQueue.front().mGroup + ": stop"); + + if (endOfLoop > 0 && (mAnimation->getCurrentTime(mAnimQueue.front().mGroup) < endOfLoop)) + { + mAnimQueue.resize(1); + return true; + } } - state.mScriptedAnims.push_back(anim); - } -} + count = std::max(count, 1); -void CharacterController::unpersistAnimationState() -{ - const ESM::AnimationState& state = mPtr.getRefData().getAnimationState(); + AnimationQueueEntry entry; + entry.mGroup = groupname; + entry.mLoopCount = count - 1; + entry.mPersist = persist; - if (!state.mScriptedAnims.empty()) - { - clearAnimQueue(); - for (ESM::AnimationState::ScriptedAnimations::const_iterator iter = state.mScriptedAnims.begin(); iter != state.mScriptedAnims.end(); ++iter) + if (mode != 0 || mAnimQueue.empty() || !isAnimPlaying(mAnimQueue.front().mGroup)) { - AnimationQueueEntry entry; - entry.mGroup = iter->mGroup; - entry.mLoopCount = iter->mLoopCount; - entry.mPersist = true; + clearAnimQueue(persist); - mAnimQueue.push_back(entry); - } + clearStateAnimation(mCurrentIdle); - const ESM::AnimationState::ScriptedAnimation& anim = state.mScriptedAnims.front(); - float complete = anim.mTime; - if (anim.mAbsolute) + mIdleState = CharState_SpecialIdle; + bool loopfallback = (entry.mGroup.compare(0, 4, "idle") == 0); + mAnimation->play(groupname, persist && groupname != "idle" ? Priority_Persistent : Priority_Default, + MWRender::Animation::BlendMask_All, false, 1.0f, ((mode == 2) ? "loop start" : "start"), "stop", 0.0f, + count - 1, loopfallback); + } + else { - float start = mAnimation->getTextKeyTime(anim.mGroup+": start"); - float stop = mAnimation->getTextKeyTime(anim.mGroup+": stop"); - float time = std::clamp(anim.mTime, start, stop); - complete = (time - start) / (stop - start); + mAnimQueue.resize(1); } - clearStateAnimation(mCurrentIdle); - mIdleState = CharState_SpecialIdle; + // "PlayGroup idle" is a special case, used to remove to stop scripted animations playing + if (groupname == "idle") + entry.mPersist = false; - bool loopfallback = (mAnimQueue.front().mGroup.compare(0,4,"idle") == 0); - mAnimation->play(anim.mGroup, - Priority_Persistent, MWRender::Animation::BlendMask_All, false, 1.0f, - "start", "stop", complete, anim.mLoopCount, loopfallback); + mAnimQueue.push_back(entry); + + return true; } -} -bool CharacterController::playGroup(std::string_view groupname, int mode, int count, bool persist) -{ - if(!mAnimation || !mAnimation->hasAnimation(groupname)) + void CharacterController::skipAnim() + { + mSkipAnim = true; + } + + bool CharacterController::isPersistentAnimPlaying() const + { + if (!mAnimQueue.empty()) + { + const AnimationQueueEntry& first = mAnimQueue.front(); + return first.mPersist && isAnimPlaying(first.mGroup); + } + return false; + } - // We should not interrupt persistent animations by non-persistent ones - if (isPersistentAnimPlaying() && !persist) - return true; + bool CharacterController::isAnimPlaying(std::string_view groupName) const + { + if (mAnimation == nullptr) + return false; + return mAnimation->isPlaying(groupName); + } - // If this animation is a looped animation (has a "loop start" key) that is already playing - // and has not yet reached the end of the loop, allow it to continue animating with its existing loop count - // and remove any other animations that were queued. - // This emulates observed behavior from the original allows the script "OutsideBanner" to animate banners correctly. - if (!mAnimQueue.empty() && mAnimQueue.front().mGroup == groupname && - mAnimation->getTextKeyTime(mAnimQueue.front().mGroup + ": loop start") >= 0 && - mAnimation->isPlaying(groupname)) + void CharacterController::clearAnimQueue(bool clearPersistAnims) { - float endOfLoop = mAnimation->getTextKeyTime(mAnimQueue.front().mGroup+": loop stop"); + // Do not interrupt scripted animations, if we want to keep them + if ((!isPersistentAnimPlaying() || clearPersistAnims) && !mAnimQueue.empty()) + mAnimation->disable(mAnimQueue.front().mGroup); - if (endOfLoop < 0) // if no Loop Stop key was found, use the Stop key - endOfLoop = mAnimation->getTextKeyTime(mAnimQueue.front().mGroup+": stop"); + if (clearPersistAnims) + { + mAnimQueue.clear(); + return; + } - if (endOfLoop > 0 && (mAnimation->getCurrentTime(mAnimQueue.front().mGroup) < endOfLoop)) + for (AnimationQueue::iterator it = mAnimQueue.begin(); it != mAnimQueue.end();) { - mAnimQueue.resize(1); - return true; + if (!it->mPersist) + it = mAnimQueue.erase(it); + else + ++it; } } - count = std::max(count, 1); + void CharacterController::forceStateUpdate() + { + if (!mAnimation) + return; + clearAnimQueue(); - AnimationQueueEntry entry; - entry.mGroup = groupname; - entry.mLoopCount = count-1; - entry.mPersist = persist; + // Make sure we canceled the current attack or spellcasting, + // because we disabled attack animations anyway. + mCanCast = false; + mCastingManualSpell = false; + setAttackingOrSpell(false); + if (mUpperBodyState != UpperBodyState::None) + mUpperBodyState = UpperBodyState::WeaponEquipped; - if(mode != 0 || mAnimQueue.empty() || !isAnimPlaying(mAnimQueue.front().mGroup)) - { - clearAnimQueue(persist); + refreshCurrentAnims(mIdleState, mMovementState, mJumpState, true); - clearStateAnimation(mCurrentIdle); + if (mDeathState != CharState_None) + { + playRandomDeath(); + } - mIdleState = CharState_SpecialIdle; - bool loopfallback = (entry.mGroup.compare(0,4,"idle") == 0); - mAnimation->play(groupname, persist && groupname != "idle" ? Priority_Persistent : Priority_Default, - MWRender::Animation::BlendMask_All, false, 1.0f, - ((mode==2) ? "loop start" : "start"), "stop", 0.0f, count-1, loopfallback); + mAnimation->runAnimation(0.f); } - else + + CharacterController::KillResult CharacterController::kill() { - mAnimQueue.resize(1); + if (mDeathState == CharState_None) + { + playRandomDeath(); + resetCurrentIdleState(); + return Result_DeathAnimStarted; + } + + MWMechanics::CreatureStats& cStats = mPtr.getClass().getCreatureStats(mPtr); + if (isAnimPlaying(mCurrentDeath)) + return Result_DeathAnimPlaying; + if (!cStats.isDeathAnimationFinished()) + { + cStats.setDeathAnimationFinished(true); + return Result_DeathAnimJustFinished; + } + return Result_DeathAnimFinished; } - // "PlayGroup idle" is a special case, used to remove to stop scripted animations playing - if (groupname == "idle") - entry.mPersist = false; + void CharacterController::resurrect() + { + if (mDeathState == CharState_None) + return; - mAnimQueue.push_back(entry); + resetCurrentDeathState(); + mWeaponType = ESM::Weapon::None; + } - return true; -} + void CharacterController::updateContinuousVfx() const + { + // Keeping track of when to stop a continuous VFX seems to be very difficult to do inside the spells code, + // as it's extremely spread out (ActiveSpells, Spells, InventoryStore effects, etc...) so we do it here. -void CharacterController::skipAnim() -{ - mSkipAnim = true; -} + // Stop any effects that are no longer active + std::vector effects; + mAnimation->getLoopingEffects(effects); -bool CharacterController::isPersistentAnimPlaying() const -{ - if (!mAnimQueue.empty()) - { - const AnimationQueueEntry& first = mAnimQueue.front(); - return first.mPersist && isAnimPlaying(first.mGroup); + for (int effectId : effects) + { + if (mPtr.getClass().getCreatureStats(mPtr).isDeathAnimationFinished() + || mPtr.getClass() + .getCreatureStats(mPtr) + .getMagicEffects() + .get(MWMechanics::EffectKey(effectId)) + .getMagnitude() + <= 0) + mAnimation->removeEffect(effectId); + } } - return false; -} + void CharacterController::updateMagicEffects() const + { + if (!mPtr.getClass().isActor()) + return; -bool CharacterController::isAnimPlaying(std::string_view groupName) const -{ - if(mAnimation == nullptr) - return false; - return mAnimation->isPlaying(groupName); -} + float light + = mPtr.getClass().getCreatureStats(mPtr).getMagicEffects().get(ESM::MagicEffect::Light).getMagnitude(); + mAnimation->setLightEffect(light); -void CharacterController::clearAnimQueue(bool clearPersistAnims) -{ - // Do not interrupt scripted animations, if we want to keep them - if ((!isPersistentAnimPlaying() || clearPersistAnims) && !mAnimQueue.empty()) - mAnimation->disable(mAnimQueue.front().mGroup); + // If you're dead you don't care about whether you've started/stopped being a vampire or not + if (mPtr.getClass().getCreatureStats(mPtr).isDead()) + return; - if (clearPersistAnims) - { - mAnimQueue.clear(); - return; + bool vampire + = mPtr.getClass().getCreatureStats(mPtr).getMagicEffects().get(ESM::MagicEffect::Vampirism).getMagnitude() + > 0.0f; + mAnimation->setVampire(vampire); } - for (AnimationQueue::iterator it = mAnimQueue.begin(); it != mAnimQueue.end();) + void CharacterController::setVisibility(float visibility) const { - if (!it->mPersist) - it = mAnimQueue.erase(it); - else - ++it; - } -} - -void CharacterController::forceStateUpdate() -{ - if(!mAnimation) - return; - clearAnimQueue(); + // We should take actor's invisibility in account + if (mPtr.getClass().isActor()) + { + float alpha = 1.f; + if (mPtr.getClass() + .getCreatureStats(mPtr) + .getMagicEffects() + .get(ESM::MagicEffect::Invisibility) + .getModifier()) // Ignore base magnitude (see bug #3555). + { + if (mPtr == getPlayer()) + alpha = 0.25f; + else + alpha = 0.05f; + } + float chameleon = mPtr.getClass() + .getCreatureStats(mPtr) + .getMagicEffects() + .get(ESM::MagicEffect::Chameleon) + .getMagnitude(); + if (chameleon) + { + alpha *= std::clamp(1.f - chameleon / 100.f, 0.25f, 0.75f); + } - // Make sure we canceled the current attack or spellcasting, - // because we disabled attack animations anyway. - mCanCast = false; - mCastingManualSpell = false; - setAttackingOrSpell(false); - if (mUpperBodyState != UpperBodyState::None) - mUpperBodyState = UpperBodyState::WeaponEquipped; + visibility = std::min(visibility, alpha); + } - refreshCurrentAnims(mIdleState, mMovementState, mJumpState, true); + // TODO: implement a dithering shader rather than just change object transparency. + mAnimation->setAlpha(visibility); + } - if(mDeathState != CharState_None) + std::string_view CharacterController::getMovementBasedAttackType() const { - playRandomDeath(); + float* move = mPtr.getClass().getMovementSettings(mPtr).mPosition; + if (std::abs(move[1]) > std::abs(move[0]) + 0.2f) // forward-backward + return "thrust"; + if (std::abs(move[0]) > std::abs(move[1]) + 0.2f) // sideway + return "slash"; + return "chop"; } - mAnimation->runAnimation(0.f); -} - -CharacterController::KillResult CharacterController::kill() -{ - if (mDeathState == CharState_None) + bool CharacterController::isRandomAttackAnimation(std::string_view group) { - playRandomDeath(); - resetCurrentIdleState(); - return Result_DeathAnimStarted; + return (group == "attack1" || group == "swimattack1" || group == "attack2" || group == "swimattack2" + || group == "attack3" || group == "swimattack3"); } - MWMechanics::CreatureStats& cStats = mPtr.getClass().getCreatureStats(mPtr); - if (isAnimPlaying(mCurrentDeath)) - return Result_DeathAnimPlaying; - if (!cStats.isDeathAnimationFinished()) + bool CharacterController::isAttackPreparing() const { - cStats.setDeathAnimationFinished(true); - return Result_DeathAnimJustFinished; + return mUpperBodyState == UpperBodyState::AttackWindUp; } - return Result_DeathAnimFinished; -} - -void CharacterController::resurrect() -{ - if(mDeathState == CharState_None) - return; - - resetCurrentDeathState(); - mWeaponType = ESM::Weapon::None; -} -void CharacterController::updateContinuousVfx() const -{ - // Keeping track of when to stop a continuous VFX seems to be very difficult to do inside the spells code, - // as it's extremely spread out (ActiveSpells, Spells, InventoryStore effects, etc...) so we do it here. - - // Stop any effects that are no longer active - std::vector effects; - mAnimation->getLoopingEffects(effects); - - for (int effectId : effects) + bool CharacterController::isCastingSpell() const { - if (mPtr.getClass().getCreatureStats(mPtr).isDeathAnimationFinished() - || mPtr.getClass().getCreatureStats(mPtr).getMagicEffects().get(MWMechanics::EffectKey(effectId)).getMagnitude() <= 0) - mAnimation->removeEffect(effectId); + return mCastingManualSpell || mUpperBodyState == UpperBodyState::Casting; } -} -void CharacterController::updateMagicEffects() const -{ - if (!mPtr.getClass().isActor()) - return; - - float light = mPtr.getClass().getCreatureStats(mPtr).getMagicEffects().get(ESM::MagicEffect::Light).getMagnitude(); - mAnimation->setLightEffect(light); - - // If you're dead you don't care about whether you've started/stopped being a vampire or not - if (mPtr.getClass().getCreatureStats(mPtr).isDead()) - return; - - bool vampire = mPtr.getClass().getCreatureStats(mPtr).getMagicEffects().get(ESM::MagicEffect::Vampirism).getMagnitude() > 0.0f; - mAnimation->setVampire(vampire); -} - -void CharacterController::setVisibility(float visibility) const -{ - // We should take actor's invisibility in account - if (mPtr.getClass().isActor()) + bool CharacterController::isReadyToBlock() const { - float alpha = 1.f; - if (mPtr.getClass().getCreatureStats(mPtr).getMagicEffects().get(ESM::MagicEffect::Invisibility).getModifier()) // Ignore base magnitude (see bug #3555). - { - if (mPtr == getPlayer()) - alpha = 0.25f; - else - alpha = 0.05f; - } - float chameleon = mPtr.getClass().getCreatureStats(mPtr).getMagicEffects().get(ESM::MagicEffect::Chameleon).getMagnitude(); - if (chameleon) - { - alpha *= std::clamp(1.f - chameleon / 100.f, 0.25f, 0.75f); - } - - visibility = std::min(visibility, alpha); + return updateCarriedLeftVisible(mWeaponType); } - // TODO: implement a dithering shader rather than just change object transparency. - mAnimation->setAlpha(visibility); -} - -std::string_view CharacterController::getMovementBasedAttackType() const -{ - float *move = mPtr.getClass().getMovementSettings(mPtr).mPosition; - if (std::abs(move[1]) > std::abs(move[0]) + 0.2f) // forward-backward - return "thrust"; - if (std::abs(move[0]) > std::abs(move[1]) + 0.2f) // sideway - return "slash"; - return "chop"; -} - -bool CharacterController::isRandomAttackAnimation(std::string_view group) -{ - return (group == "attack1" || group == "swimattack1" || - group == "attack2" || group == "swimattack2" || - group == "attack3" || group == "swimattack3"); -} - -bool CharacterController::isAttackPreparing() const -{ - return mUpperBodyState == UpperBodyState::AttackWindUp; -} - -bool CharacterController::isCastingSpell() const -{ - return mCastingManualSpell || mUpperBodyState == UpperBodyState::Casting; -} - -bool CharacterController::isReadyToBlock() const -{ - return updateCarriedLeftVisible(mWeaponType); -} - -bool CharacterController::isKnockedDown() const -{ - return mHitState == CharState_KnockDown || - mHitState == CharState_SwimKnockDown; -} + bool CharacterController::isKnockedDown() const + { + return mHitState == CharState_KnockDown || mHitState == CharState_SwimKnockDown; + } -bool CharacterController::isKnockedOut() const -{ - return mHitState == CharState_KnockOut || - mHitState == CharState_SwimKnockOut; -} + bool CharacterController::isKnockedOut() const + { + return mHitState == CharState_KnockOut || mHitState == CharState_SwimKnockOut; + } -bool CharacterController::isTurning() const -{ - return mMovementState == CharState_TurnLeft || - mMovementState == CharState_TurnRight || - mMovementState == CharState_SwimTurnLeft || - mMovementState == CharState_SwimTurnRight; -} + bool CharacterController::isTurning() const + { + return mMovementState == CharState_TurnLeft || mMovementState == CharState_TurnRight + || mMovementState == CharState_SwimTurnLeft || mMovementState == CharState_SwimTurnRight; + } -bool CharacterController::isRecovery() const -{ - return mHitState == CharState_Hit || - mHitState == CharState_SwimHit; -} + bool CharacterController::isRecovery() const + { + return mHitState == CharState_Hit || mHitState == CharState_SwimHit; + } -bool CharacterController::isAttackingOrSpell() const -{ - return mUpperBodyState != UpperBodyState::None && mUpperBodyState != UpperBodyState::WeaponEquipped; -} + bool CharacterController::isAttackingOrSpell() const + { + return mUpperBodyState != UpperBodyState::None && mUpperBodyState != UpperBodyState::WeaponEquipped; + } -bool CharacterController::isSneaking() const -{ - return mIdleState == CharState_IdleSneak || - mMovementState == CharState_SneakForward || - mMovementState == CharState_SneakBack || - mMovementState == CharState_SneakLeft || - mMovementState == CharState_SneakRight; -} + bool CharacterController::isSneaking() const + { + return mIdleState == CharState_IdleSneak || mMovementState == CharState_SneakForward + || mMovementState == CharState_SneakBack || mMovementState == CharState_SneakLeft + || mMovementState == CharState_SneakRight; + } -bool CharacterController::isRunning() const -{ - return mMovementState == CharState_RunForward || - mMovementState == CharState_RunBack || - mMovementState == CharState_RunLeft || - mMovementState == CharState_RunRight || - mMovementState == CharState_SwimRunForward || - mMovementState == CharState_SwimRunBack || - mMovementState == CharState_SwimRunLeft || - mMovementState == CharState_SwimRunRight; -} + bool CharacterController::isRunning() const + { + return mMovementState == CharState_RunForward || mMovementState == CharState_RunBack + || mMovementState == CharState_RunLeft || mMovementState == CharState_RunRight + || mMovementState == CharState_SwimRunForward || mMovementState == CharState_SwimRunBack + || mMovementState == CharState_SwimRunLeft || mMovementState == CharState_SwimRunRight; + } -void CharacterController::setAttackingOrSpell(bool attackingOrSpell) const -{ - mPtr.getClass().getCreatureStats(mPtr).setAttackingOrSpell(attackingOrSpell); -} + void CharacterController::setAttackingOrSpell(bool attackingOrSpell) const + { + mPtr.getClass().getCreatureStats(mPtr).setAttackingOrSpell(attackingOrSpell); + } -void CharacterController::castSpell(const std::string& spellId, bool manualSpell) -{ - setAttackingOrSpell(true); - mCastingManualSpell = manualSpell; - ActionSpell action = ActionSpell(spellId); - action.prepare(mPtr); -} + void CharacterController::castSpell(const std::string& spellId, bool manualSpell) + { + setAttackingOrSpell(true); + mCastingManualSpell = manualSpell; + ActionSpell action = ActionSpell(spellId); + action.prepare(mPtr); + } -void CharacterController::setAIAttackType(std::string_view attackType) -{ - mAttackType = attackType; -} + void CharacterController::setAIAttackType(std::string_view attackType) + { + mAttackType = attackType; + } -std::string_view CharacterController::getRandomAttackType() -{ - MWBase::World* world = MWBase::Environment::get().getWorld(); - float random = Misc::Rng::rollProbability(world->getPrng()); - if (random >= 2/3.f) - return "thrust"; - if (random >= 1/3.f) - return "slash"; - return "chop"; -} + std::string_view CharacterController::getRandomAttackType() + { + MWBase::World* world = MWBase::Environment::get().getWorld(); + float random = Misc::Rng::rollProbability(world->getPrng()); + if (random >= 2 / 3.f) + return "thrust"; + if (random >= 1 / 3.f) + return "slash"; + return "chop"; + } -bool CharacterController::readyToPrepareAttack() const -{ - return (mHitState == CharState_None || mHitState == CharState_Block) + bool CharacterController::readyToPrepareAttack() const + { + return (mHitState == CharState_None || mHitState == CharState_Block) && mUpperBodyState <= UpperBodyState::WeaponEquipped; -} - -bool CharacterController::readyToStartAttack() const -{ - if (mHitState != CharState_None && mHitState != CharState_Block) - return false; - - return mUpperBodyState == UpperBodyState::WeaponEquipped; -} + } -float CharacterController::getAttackStrength() const -{ - return mAttackStrength; -} + bool CharacterController::readyToStartAttack() const + { + if (mHitState != CharState_None && mHitState != CharState_Block) + return false; -bool CharacterController::getAttackingOrSpell() const -{ - return mPtr.getClass().getCreatureStats(mPtr).getAttackingOrSpell(); -} + return mUpperBodyState == UpperBodyState::WeaponEquipped; + } -void CharacterController::setActive(int active) const -{ - mAnimation->setActive(active); -} + float CharacterController::getAttackStrength() const + { + return mAttackStrength; + } -void CharacterController::setHeadTrackTarget(const MWWorld::ConstPtr &target) -{ - mHeadTrackTarget = target; -} + bool CharacterController::getAttackingOrSpell() const + { + return mPtr.getClass().getCreatureStats(mPtr).getAttackingOrSpell(); + } -void CharacterController::playSwishSound() const -{ - std::string_view soundId = "Weapon Swish"; - float volume = 0.98f + mAttackStrength * 0.02f; - float pitch = 0.75f + mAttackStrength * 0.4f; + void CharacterController::setActive(int active) const + { + mAnimation->setActive(active); + } - const MWWorld::Class &cls = mPtr.getClass(); - if (cls.isNpc() && cls.getNpcStats(mPtr).isWerewolf()) + void CharacterController::setHeadTrackTarget(const MWWorld::ConstPtr& target) { - MWBase::World* world = MWBase::Environment::get().getWorld(); - const MWWorld::ESMStore &store = world->getStore(); - const ESM::Sound *sound = store.get().searchRandom("WolfSwing", world->getPrng()); - if (sound) - soundId = sound->mId; + mHeadTrackTarget = target; } - if (!soundId.empty()) - MWBase::Environment::get().getSoundManager()->playSound3D(mPtr, soundId, volume, pitch); -} + void CharacterController::playSwishSound() const + { + std::string_view soundId = "Weapon Swish"; + float volume = 0.98f + mAttackStrength * 0.02f; + float pitch = 0.75f + mAttackStrength * 0.4f; -void CharacterController::updateHeadTracking(float duration) -{ - const osg::Node* head = mAnimation->getNode("Bip01 Head"); - if (!head) - return; + const MWWorld::Class& cls = mPtr.getClass(); + if (cls.isNpc() && cls.getNpcStats(mPtr).isWerewolf()) + { + MWBase::World* world = MWBase::Environment::get().getWorld(); + const MWWorld::ESMStore& store = world->getStore(); + const ESM::Sound* sound = store.get().searchRandom("WolfSwing", world->getPrng()); + if (sound) + soundId = sound->mId; + } - double zAngleRadians = 0.f; - double xAngleRadians = 0.f; + if (!soundId.empty()) + MWBase::Environment::get().getSoundManager()->playSound3D(mPtr, soundId, volume, pitch); + } - if (!mHeadTrackTarget.isEmpty()) + void CharacterController::updateHeadTracking(float duration) { - osg::NodePathList nodepaths = head->getParentalNodePaths(); - if (nodepaths.empty()) + const osg::Node* head = mAnimation->getNode("Bip01 Head"); + if (!head) return; - osg::Matrixf mat = osg::computeLocalToWorld(nodepaths[0]); - osg::Vec3f headPos = mat.getTrans(); - osg::Vec3f direction; - if (const MWRender::Animation* anim = MWBase::Environment::get().getWorld()->getAnimation(mHeadTrackTarget)) + double zAngleRadians = 0.f; + double xAngleRadians = 0.f; + + if (!mHeadTrackTarget.isEmpty()) { - const osg::Node* node = anim->getNode("Head"); - if (node == nullptr) - node = anim->getNode("Bip01 Head"); - if (node != nullptr) + osg::NodePathList nodepaths = head->getParentalNodePaths(); + if (nodepaths.empty()) + return; + osg::Matrixf mat = osg::computeLocalToWorld(nodepaths[0]); + osg::Vec3f headPos = mat.getTrans(); + + osg::Vec3f direction; + if (const MWRender::Animation* anim = MWBase::Environment::get().getWorld()->getAnimation(mHeadTrackTarget)) { - nodepaths = node->getParentalNodePaths(); - if (!nodepaths.empty()) - direction = osg::computeLocalToWorld(nodepaths[0]).getTrans() - headPos; + const osg::Node* node = anim->getNode("Head"); + if (node == nullptr) + node = anim->getNode("Bip01 Head"); + if (node != nullptr) + { + nodepaths = node->getParentalNodePaths(); + if (!nodepaths.empty()) + direction = osg::computeLocalToWorld(nodepaths[0]).getTrans() - headPos; + } + else + // no head node to look at, fall back to look at center of collision box + direction = MWBase::Environment::get().getWorld()->aimToTarget(mPtr, mHeadTrackTarget, false); } - else - // no head node to look at, fall back to look at center of collision box - direction = MWBase::Environment::get().getWorld()->aimToTarget(mPtr, mHeadTrackTarget, false); - } - direction.normalize(); + direction.normalize(); - if (!mPtr.getRefData().getBaseNode()) - return; - const osg::Vec3f actorDirection = mPtr.getRefData().getBaseNode()->getAttitude() * osg::Vec3f(0,1,0); + if (!mPtr.getRefData().getBaseNode()) + return; + const osg::Vec3f actorDirection = mPtr.getRefData().getBaseNode()->getAttitude() * osg::Vec3f(0, 1, 0); - zAngleRadians = std::atan2(actorDirection.x(), actorDirection.y()) - std::atan2(direction.x(), direction.y()); - zAngleRadians = Misc::normalizeAngle(zAngleRadians - mAnimation->getHeadYaw()) + mAnimation->getHeadYaw(); - zAngleRadians *= (1 - direction.z() * direction.z()); - xAngleRadians = std::asin(direction.z()); - } + zAngleRadians + = std::atan2(actorDirection.x(), actorDirection.y()) - std::atan2(direction.x(), direction.y()); + zAngleRadians = Misc::normalizeAngle(zAngleRadians - mAnimation->getHeadYaw()) + mAnimation->getHeadYaw(); + zAngleRadians *= (1 - direction.z() * direction.z()); + xAngleRadians = std::asin(direction.z()); + } - const double xLimit = osg::DegreesToRadians(40.0); - const double zLimit = osg::DegreesToRadians(30.0); - double zLimitOffset = mAnimation->getUpperBodyYawRadians(); - xAngleRadians = std::clamp(xAngleRadians, -xLimit, xLimit); - zAngleRadians = std::clamp(zAngleRadians, -zLimit + zLimitOffset, zLimit + zLimitOffset); + const double xLimit = osg::DegreesToRadians(40.0); + const double zLimit = osg::DegreesToRadians(30.0); + double zLimitOffset = mAnimation->getUpperBodyYawRadians(); + xAngleRadians = std::clamp(xAngleRadians, -xLimit, xLimit); + zAngleRadians = std::clamp(zAngleRadians, -zLimit + zLimitOffset, zLimit + zLimitOffset); - float factor = duration*5; - factor = std::min(factor, 1.f); - xAngleRadians = (1.f-factor) * mAnimation->getHeadPitch() + factor * xAngleRadians; - zAngleRadians = (1.f-factor) * mAnimation->getHeadYaw() + factor * zAngleRadians; + float factor = duration * 5; + factor = std::min(factor, 1.f); + xAngleRadians = (1.f - factor) * mAnimation->getHeadPitch() + factor * xAngleRadians; + zAngleRadians = (1.f - factor) * mAnimation->getHeadYaw() + factor * zAngleRadians; - mAnimation->setHeadPitch(xAngleRadians); - mAnimation->setHeadYaw(zAngleRadians); -} + mAnimation->setHeadPitch(xAngleRadians); + mAnimation->setHeadYaw(zAngleRadians); + } } diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 3f7dcd1114..bf6a61deae 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -22,294 +22,300 @@ namespace MWRender namespace MWMechanics { -struct Movement; -class CreatureStats; - -enum Priority { - Priority_Default, - Priority_WeaponLowerBody, - Priority_SneakIdleLowerBody, - Priority_SwimIdle, - Priority_Jump, - Priority_Movement, - Priority_Hit, - Priority_Weapon, - Priority_Block, - Priority_Knockdown, - Priority_Torch, - Priority_Storm, - Priority_Death, - Priority_Persistent, - - Num_Priorities -}; - -enum CharacterState { - CharState_None, - - CharState_SpecialIdle, - CharState_Idle, - CharState_IdleSwim, - CharState_IdleSneak, - - CharState_WalkForward, - CharState_WalkBack, - CharState_WalkLeft, - CharState_WalkRight, - - CharState_SwimWalkForward, - CharState_SwimWalkBack, - CharState_SwimWalkLeft, - CharState_SwimWalkRight, - - CharState_RunForward, - CharState_RunBack, - CharState_RunLeft, - CharState_RunRight, - - CharState_SwimRunForward, - CharState_SwimRunBack, - CharState_SwimRunLeft, - CharState_SwimRunRight, - - CharState_SneakForward, - CharState_SneakBack, - CharState_SneakLeft, - CharState_SneakRight, - - CharState_TurnLeft, - CharState_TurnRight, - CharState_SwimTurnLeft, - CharState_SwimTurnRight, - - CharState_Death1, - CharState_Death2, - CharState_Death3, - CharState_Death4, - CharState_Death5, - CharState_SwimDeath, - CharState_SwimDeathKnockDown, - CharState_SwimDeathKnockOut, - CharState_DeathKnockDown, - CharState_DeathKnockOut, - - CharState_Hit, - CharState_SwimHit, - CharState_KnockDown, - CharState_KnockOut, - CharState_SwimKnockDown, - CharState_SwimKnockOut, - CharState_Block -}; - -enum class UpperBodyState -{ - None, - Equipping, - Unequipping, - WeaponEquipped, - AttackWindUp, - AttackRelease, - AttackEnd, - Casting -}; - -enum JumpingState { - JumpState_None, - JumpState_InAir, - JumpState_Landing -}; - -struct WeaponInfo; - -class CharacterController : public MWRender::Animation::TextKeyListener -{ - MWWorld::Ptr mPtr; - MWWorld::Ptr mWeapon; - MWRender::Animation *mAnimation; - - struct AnimationQueueEntry + struct Movement; + class CreatureStats; + + enum Priority + { + Priority_Default, + Priority_WeaponLowerBody, + Priority_SneakIdleLowerBody, + Priority_SwimIdle, + Priority_Jump, + Priority_Movement, + Priority_Hit, + Priority_Weapon, + Priority_Block, + Priority_Knockdown, + Priority_Torch, + Priority_Storm, + Priority_Death, + Priority_Persistent, + + Num_Priorities + }; + + enum CharacterState + { + CharState_None, + + CharState_SpecialIdle, + CharState_Idle, + CharState_IdleSwim, + CharState_IdleSneak, + + CharState_WalkForward, + CharState_WalkBack, + CharState_WalkLeft, + CharState_WalkRight, + + CharState_SwimWalkForward, + CharState_SwimWalkBack, + CharState_SwimWalkLeft, + CharState_SwimWalkRight, + + CharState_RunForward, + CharState_RunBack, + CharState_RunLeft, + CharState_RunRight, + + CharState_SwimRunForward, + CharState_SwimRunBack, + CharState_SwimRunLeft, + CharState_SwimRunRight, + + CharState_SneakForward, + CharState_SneakBack, + CharState_SneakLeft, + CharState_SneakRight, + + CharState_TurnLeft, + CharState_TurnRight, + CharState_SwimTurnLeft, + CharState_SwimTurnRight, + + CharState_Death1, + CharState_Death2, + CharState_Death3, + CharState_Death4, + CharState_Death5, + CharState_SwimDeath, + CharState_SwimDeathKnockDown, + CharState_SwimDeathKnockOut, + CharState_DeathKnockDown, + CharState_DeathKnockOut, + + CharState_Hit, + CharState_SwimHit, + CharState_KnockDown, + CharState_KnockOut, + CharState_SwimKnockDown, + CharState_SwimKnockOut, + CharState_Block + }; + + enum class UpperBodyState + { + None, + Equipping, + Unequipping, + WeaponEquipped, + AttackWindUp, + AttackRelease, + AttackEnd, + Casting + }; + + enum JumpingState { - std::string mGroup; - size_t mLoopCount; - bool mPersist; + JumpState_None, + JumpState_InAir, + JumpState_Landing }; - typedef std::deque AnimationQueue; - AnimationQueue mAnimQueue; - CharacterState mIdleState{CharState_None}; - std::string mCurrentIdle; + struct WeaponInfo; - CharacterState mMovementState{CharState_None}; - std::string mCurrentMovement; - float mMovementAnimSpeed{0.f}; - bool mAdjustMovementAnimSpeed{false}; - bool mHasMovedInXY{false}; - bool mMovementAnimationControlled{true}; + class CharacterController : public MWRender::Animation::TextKeyListener + { + MWWorld::Ptr mPtr; + MWWorld::Ptr mWeapon; + MWRender::Animation* mAnimation; - CharacterState mDeathState{CharState_None}; - std::string mCurrentDeath; - bool mFloatToSurface{true}; + struct AnimationQueueEntry + { + std::string mGroup; + size_t mLoopCount; + bool mPersist; + }; + typedef std::deque AnimationQueue; + AnimationQueue mAnimQueue; - CharacterState mHitState{CharState_None}; - std::string mCurrentHit; + CharacterState mIdleState{ CharState_None }; + std::string mCurrentIdle; - UpperBodyState mUpperBodyState{UpperBodyState::None}; + CharacterState mMovementState{ CharState_None }; + std::string mCurrentMovement; + float mMovementAnimSpeed{ 0.f }; + bool mAdjustMovementAnimSpeed{ false }; + bool mHasMovedInXY{ false }; + bool mMovementAnimationControlled{ true }; - JumpingState mJumpState{JumpState_None}; - std::string mCurrentJump; + CharacterState mDeathState{ CharState_None }; + std::string mCurrentDeath; + bool mFloatToSurface{ true }; - int mWeaponType{ESM::Weapon::None}; - std::string mCurrentWeapon; + CharacterState mHitState{ CharState_None }; + std::string mCurrentHit; - float mAttackStrength{0.f}; - MWWorld::Ptr mAttackVictim; - osg::Vec3f mAttackHitPos; - bool mAttackSuccess{false}; + UpperBodyState mUpperBodyState{ UpperBodyState::None }; - bool mSkipAnim{false}; + JumpingState mJumpState{ JumpState_None }; + std::string mCurrentJump; - // counted for skill increase - float mSecondsOfSwimming{0.f}; - float mSecondsOfRunning{0.f}; + int mWeaponType{ ESM::Weapon::None }; + std::string mCurrentWeapon; - MWWorld::ConstPtr mHeadTrackTarget; + float mAttackStrength{ 0.f }; + MWWorld::Ptr mAttackVictim; + osg::Vec3f mAttackHitPos; + bool mAttackSuccess{ false }; - float mTurnAnimationThreshold{0.f}; // how long to continue playing turning animation after actor stopped turning + bool mSkipAnim{ false }; - std::string mAttackType; // slash, chop or thrust + // counted for skill increase + float mSecondsOfSwimming{ 0.f }; + float mSecondsOfRunning{ 0.f }; - bool mCanCast{false}; + MWWorld::ConstPtr mHeadTrackTarget; - bool mCastingManualSpell{false}; + float mTurnAnimationThreshold{ + 0.f + }; // how long to continue playing turning animation after actor stopped turning - bool mIsMovingBackward{false}; - osg::Vec2f mSmoothedSpeed; + std::string mAttackType; // slash, chop or thrust - std::string_view getMovementBasedAttackType() const; + bool mCanCast{ false }; - void clearStateAnimation(std::string &anim) const; - void resetCurrentJumpState(); - void resetCurrentMovementState(); - void resetCurrentIdleState(); - void resetCurrentHitState(); - void resetCurrentWeaponState(); - void resetCurrentDeathState(); + bool mCastingManualSpell{ false }; - void refreshCurrentAnims(CharacterState idle, CharacterState movement, JumpingState jump, bool force=false); - void refreshHitRecoilAnims(); - void refreshJumpAnims(JumpingState jump, bool force=false); - void refreshMovementAnims(CharacterState movement, bool force=false); - void refreshIdleAnims(CharacterState idle, bool force=false); + bool mIsMovingBackward{ false }; + osg::Vec2f mSmoothedSpeed; - void clearAnimQueue(bool clearPersistAnims = false); + std::string_view getMovementBasedAttackType() const; - bool updateWeaponState(); - void updateIdleStormState(bool inwater) const; + void clearStateAnimation(std::string& anim) const; + void resetCurrentJumpState(); + void resetCurrentMovementState(); + void resetCurrentIdleState(); + void resetCurrentHitState(); + void resetCurrentWeaponState(); + void resetCurrentDeathState(); - std::string chooseRandomAttackAnimation() const; - static bool isRandomAttackAnimation(std::string_view group); + void refreshCurrentAnims(CharacterState idle, CharacterState movement, JumpingState jump, bool force = false); + void refreshHitRecoilAnims(); + void refreshJumpAnims(JumpingState jump, bool force = false); + void refreshMovementAnims(CharacterState movement, bool force = false); + void refreshIdleAnims(CharacterState idle, bool force = false); - bool isPersistentAnimPlaying() const; + void clearAnimQueue(bool clearPersistAnims = false); - void updateAnimQueue(); + bool updateWeaponState(); + void updateIdleStormState(bool inwater) const; - void updateHeadTracking(float duration); + std::string chooseRandomAttackAnimation() const; + static bool isRandomAttackAnimation(std::string_view group); - void updateMagicEffects() const; + bool isPersistentAnimPlaying() const; - void playDeath(float startpoint, CharacterState death); - CharacterState chooseRandomDeathState() const; - void playRandomDeath(float startpoint = 0.0f); + void updateAnimQueue(); - /// choose a random animation group with \a prefix and numeric suffix - /// @param num if non-nullptr, the chosen animation number will be written here - std::string chooseRandomGroup (const std::string& prefix, int* num = nullptr) const; + void updateHeadTracking(float duration); - bool updateCarriedLeftVisible(int weaptype) const; + void updateMagicEffects() const; - std::string fallbackShortWeaponGroup(const std::string& baseGroupName, MWRender::Animation::BlendMask* blendMask = nullptr) const; + void playDeath(float startpoint, CharacterState death); + CharacterState chooseRandomDeathState() const; + void playRandomDeath(float startpoint = 0.0f); - std::string_view getWeaponAnimation(int weaponType) const; - std::string_view getWeaponShortGroup(int weaponType) const; + /// choose a random animation group with \a prefix and numeric suffix + /// @param num if non-nullptr, the chosen animation number will be written here + std::string chooseRandomGroup(const std::string& prefix, int* num = nullptr) const; - bool getAttackingOrSpell() const; - void setAttackingOrSpell(bool attackingOrSpell) const; + bool updateCarriedLeftVisible(int weaptype) const; -public: - CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim); - virtual ~CharacterController(); + std::string fallbackShortWeaponGroup( + const std::string& baseGroupName, MWRender::Animation::BlendMask* blendMask = nullptr) const; - CharacterController(const CharacterController&) = delete; - CharacterController(CharacterController&&) = delete; + std::string_view getWeaponAnimation(int weaponType) const; + std::string_view getWeaponShortGroup(int weaponType) const; - const MWWorld::Ptr& getPtr() const { return mPtr; } + bool getAttackingOrSpell() const; + void setAttackingOrSpell(bool attackingOrSpell) const; - void handleTextKey(std::string_view groupname, SceneUtil::TextKeyMap::ConstIterator key, const SceneUtil::TextKeyMap& map) override; + public: + CharacterController(const MWWorld::Ptr& ptr, MWRender::Animation* anim); + virtual ~CharacterController(); - // Be careful when to call this, see comment in Actors - void updateContinuousVfx() const; + CharacterController(const CharacterController&) = delete; + CharacterController(CharacterController&&) = delete; - void updatePtr(const MWWorld::Ptr &ptr); + const MWWorld::Ptr& getPtr() const { return mPtr; } - void update(float duration); + void handleTextKey(std::string_view groupname, SceneUtil::TextKeyMap::ConstIterator key, + const SceneUtil::TextKeyMap& map) override; - bool onOpen() const; - void onClose() const; + // Be careful when to call this, see comment in Actors + void updateContinuousVfx() const; - void persistAnimationState() const; - void unpersistAnimationState(); + void updatePtr(const MWWorld::Ptr& ptr); - bool playGroup(std::string_view groupname, int mode, int count, bool persist=false); - void skipAnim(); - bool isAnimPlaying(std::string_view groupName) const; + void update(float duration); - enum KillResult - { - Result_DeathAnimStarted, - Result_DeathAnimPlaying, - Result_DeathAnimJustFinished, - Result_DeathAnimFinished - }; - KillResult kill(); + bool onOpen() const; + void onClose() const; - void resurrect(); - bool isDead() const - { return mDeathState != CharState_None; } + void persistAnimationState() const; + void unpersistAnimationState(); - void forceStateUpdate(); - - bool isAttackPreparing() const; - bool isCastingSpell() const; - bool isReadyToBlock() const; - bool isKnockedDown() const; - bool isKnockedOut() const; - bool isRecovery() const; - bool isSneaking() const; - bool isRunning() const; - bool isTurning() const; - bool isAttackingOrSpell() const; + bool playGroup(std::string_view groupname, int mode, int count, bool persist = false); + void skipAnim(); + bool isAnimPlaying(std::string_view groupName) const; - void setVisibility(float visibility) const; - void castSpell(const std::string& spellId, bool manualSpell=false); - void setAIAttackType(std::string_view attackType); - static std::string_view getRandomAttackType(); + enum KillResult + { + Result_DeathAnimStarted, + Result_DeathAnimPlaying, + Result_DeathAnimJustFinished, + Result_DeathAnimFinished + }; + KillResult kill(); - bool readyToPrepareAttack() const; - bool readyToStartAttack() const; + void resurrect(); + bool isDead() const { return mDeathState != CharState_None; } - float calculateWindUp() const; + void forceStateUpdate(); - float getAttackStrength() const; + bool isAttackPreparing() const; + bool isCastingSpell() const; + bool isReadyToBlock() const; + bool isKnockedDown() const; + bool isKnockedOut() const; + bool isRecovery() const; + bool isSneaking() const; + bool isRunning() const; + bool isTurning() const; + bool isAttackingOrSpell() const; - /// @see Animation::setActive - void setActive(int active) const; + void setVisibility(float visibility) const; + void castSpell(const std::string& spellId, bool manualSpell = false); + void setAIAttackType(std::string_view attackType); + static std::string_view getRandomAttackType(); - /// Make this character turn its head towards \a target. To turn off head tracking, pass an empty Ptr. - void setHeadTrackTarget(const MWWorld::ConstPtr& target); + bool readyToPrepareAttack() const; + bool readyToStartAttack() const; - void playSwishSound() const; -}; + float calculateWindUp() const; + + float getAttackStrength() const; + + /// @see Animation::setActive + void setActive(int active) const; + + /// Make this character turn its head towards \a target. To turn off head tracking, pass an empty Ptr. + void setHeadTrackTarget(const MWWorld::ConstPtr& target); + + void playSwishSound() const; + }; } #endif /* GAME_MWMECHANICS_CHARACTER_HPP */ diff --git a/apps/openmw/mwmechanics/combat.cpp b/apps/openmw/mwmechanics/combat.cpp index 612f178d65..f7cac36e74 100644 --- a/apps/openmw/mwmechanics/combat.cpp +++ b/apps/openmw/mwmechanics/combat.cpp @@ -11,50 +11,51 @@ #include #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/soundmanager.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" #include "../mwworld/class.hpp" -#include "../mwworld/inventorystore.hpp" #include "../mwworld/esmstore.hpp" +#include "../mwworld/inventorystore.hpp" -#include "npcstats.hpp" +#include "actorutil.hpp" +#include "difficultyscaling.hpp" #include "movement.hpp" +#include "npcstats.hpp" +#include "pathfinding.hpp" #include "spellcasting.hpp" #include "spellresistance.hpp" -#include "difficultyscaling.hpp" -#include "actorutil.hpp" -#include "pathfinding.hpp" namespace { -float signedAngleRadians (const osg::Vec3f& v1, const osg::Vec3f& v2, const osg::Vec3f& normal) -{ - return std::atan2((normal * (v1 ^ v2)), (v1 * v2)); -} + float signedAngleRadians(const osg::Vec3f& v1, const osg::Vec3f& v2, const osg::Vec3f& normal) + { + return std::atan2((normal * (v1 ^ v2)), (v1 * v2)); + } } namespace MWMechanics { - bool applyOnStrikeEnchantment(const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, const MWWorld::Ptr& object, const osg::Vec3f& hitPosition, const bool fromProjectile) + bool applyOnStrikeEnchantment(const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, const MWWorld::Ptr& object, + const osg::Vec3f& hitPosition, const bool fromProjectile) { std::string_view enchantmentName = !object.isEmpty() ? object.getClass().getEnchantment(object) : ""; if (!enchantmentName.empty()) { - const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get().find( - enchantmentName); + const ESM::Enchantment* enchantment + = MWBase::Environment::get().getWorld()->getStore().get().find(enchantmentName); if (enchantment->mData.mType == ESM::Enchantment::WhenStrikes) { MWMechanics::CastSpell cast(attacker, victim, fromProjectile); cast.mHitPosition = hitPosition; cast.cast(object, 0, false); // Apply magic effects directly instead of waiting a frame to allow soul trap to work on one-hit kills - if(!victim.isEmpty() && victim.getClass().isActor()) + if (!victim.isEmpty() && victim.getClass().isActor()) MWBase::Environment::get().getMechanicsManager()->updateMagicEffects(victim); return true; } @@ -62,7 +63,8 @@ namespace MWMechanics return false; } - bool blockMeleeAttack(const MWWorld::Ptr &attacker, const MWWorld::Ptr &blocker, const MWWorld::Ptr &weapon, float damage, float attackStrength) + bool blockMeleeAttack(const MWWorld::Ptr& attacker, const MWWorld::Ptr& blocker, const MWWorld::Ptr& weapon, + float damage, float attackStrength) { if (!blocker.getClass().hasInventoryStore(blocker)) return false; @@ -70,8 +72,7 @@ namespace MWMechanics MWMechanics::CreatureStats& blockerStats = blocker.getClass().getCreatureStats(blocker); if (blockerStats.getKnockedDown() // Used for both knockout or knockdown - || blockerStats.getHitRecovery() - || blockerStats.isParalyzed()) + || blockerStats.getHitRecovery() || blockerStats.isParalyzed()) return false; if (!MWBase::Environment::get().getMechanicsManager()->isReadyToBlock(blocker)) @@ -85,13 +86,12 @@ namespace MWMechanics if (!blocker.getRefData().getBaseNode()) return false; // shouldn't happen - float angleDegrees = osg::RadiansToDegrees( - signedAngleRadians ( - (attacker.getRefData().getPosition().asVec3() - blocker.getRefData().getPosition().asVec3()), - blocker.getRefData().getBaseNode()->getAttitude() * osg::Vec3f(0,1,0), - osg::Vec3f(0,0,1))); + float angleDegrees = osg::RadiansToDegrees(signedAngleRadians( + (attacker.getRefData().getPosition().asVec3() - blocker.getRefData().getPosition().asVec3()), + blocker.getRefData().getBaseNode()->getAttitude() * osg::Vec3f(0, 1, 0), osg::Vec3f(0, 0, 1))); - const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& gmst + = MWBase::Environment::get().getWorld()->getStore().get(); static const float fCombatBlockLeftAngle = gmst.find("fCombatBlockLeftAngle")->mValue.getFloat(); if (angleDegrees < fCombatBlockLeftAngle) return false; @@ -101,7 +101,8 @@ namespace MWMechanics MWMechanics::CreatureStats& attackerStats = attacker.getClass().getCreatureStats(attacker); - float blockTerm = blocker.getClass().getSkill(blocker, ESM::Skill::Block) + 0.2f * blockerStats.getAttribute(ESM::Attribute::Agility).getModified() + float blockTerm = blocker.getClass().getSkill(blocker, ESM::Skill::Block) + + 0.2f * blockerStats.getAttribute(ESM::Attribute::Agility).getModified() + 0.1f * blockerStats.getAttribute(ESM::Attribute::Luck).getModified(); float enemySwing = attackStrength; static const float fSwingBlockMult = gmst.find("fSwingBlockMult")->mValue.getFloat(); @@ -122,7 +123,7 @@ namespace MWMechanics else attackerSkill = attacker.getClass().getSkill(attacker, weapon.getClass().getEquipmentSkill(weapon)); float attackerTerm = attackerSkill + 0.2f * attackerStats.getAttribute(ESM::Attribute::Agility).getModified() - + 0.1f * attackerStats.getAttribute(ESM::Attribute::Luck).getModified(); + + 0.1f * attackerStats.getAttribute(ESM::Attribute::Luck).getModified(); attackerTerm *= attackerStats.getFatigueTerm(); static const int iBlockMaxChance = gmst.find("iBlockMaxChance")->mValue.getInteger(); @@ -162,7 +163,7 @@ namespace MWMechanics return false; } - bool isNormalWeapon(const MWWorld::Ptr &weapon) + bool isNormalWeapon(const MWWorld::Ptr& weapon) { if (weapon.isEmpty()) return false; @@ -172,10 +173,12 @@ namespace MWMechanics bool isMagical = flags & ESM::Weapon::Magical; bool isEnchanted = !weapon.getClass().getEnchantment(weapon).empty(); - return !isSilver && !isMagical && (!isEnchanted || !Settings::Manager::getBool("enchanted weapons are magical", "Game")); + return !isSilver && !isMagical + && (!isEnchanted || !Settings::Manager::getBool("enchanted weapons are magical", "Game")); } - void resistNormalWeapon(const MWWorld::Ptr &actor, const MWWorld::Ptr& attacker, const MWWorld::Ptr &weapon, float &damage) + void resistNormalWeapon( + const MWWorld::Ptr& actor, const MWWorld::Ptr& attacker, const MWWorld::Ptr& weapon, float& damage) { if (damage == 0 || weapon.isEmpty() || !isNormalWeapon(weapon)) return; @@ -184,13 +187,13 @@ namespace MWMechanics const float resistance = effects.get(ESM::MagicEffect::ResistNormalWeapons).getMagnitude() / 100.f; const float weakness = effects.get(ESM::MagicEffect::WeaknessToNormalWeapons).getMagnitude() / 100.f; - damage *= 1.f - std::min(1.f, resistance-weakness); + damage *= 1.f - std::min(1.f, resistance - weakness); if (damage == 0 && attacker == getPlayer()) MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicTargetResistsWeapons}"); } - void applyWerewolfDamageMult(const MWWorld::Ptr &actor, const MWWorld::Ptr &weapon, float &damage) + void applyWerewolfDamageMult(const MWWorld::Ptr& actor, const MWWorld::Ptr& weapon, float& damage) { if (damage == 0 || weapon.isEmpty() || !actor.getClass().isNpc()) return; @@ -205,11 +208,11 @@ namespace MWMechanics } } - void projectileHit(const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, MWWorld::Ptr weapon, const MWWorld::Ptr& projectile, - const osg::Vec3f& hitPosition, float attackStrength) + void projectileHit(const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, MWWorld::Ptr weapon, + const MWWorld::Ptr& projectile, const osg::Vec3f& hitPosition, float attackStrength) { - MWBase::World *world = MWBase::Environment::get().getWorld(); - const MWWorld::Store &gmst = world->getStore().get(); + MWBase::World* world = MWBase::Environment::get().getWorld(); + const MWWorld::Store& gmst = world->getStore().get(); bool validVictim = !victim.isEmpty() && victim.getClass().isActor(); @@ -247,7 +250,9 @@ namespace MWMechanics if (validVictim) { - if (weapon == projectile || Settings::Manager::getBool("only appropriate ammunition bypasses resistance", "Game") || isNormalWeapon(weapon)) + if (weapon == projectile + || Settings::Manager::getBool("only appropriate ammunition bypasses resistance", "Game") + || isNormalWeapon(weapon)) resistNormalWeapon(victim, attacker, projectile, damage); applyWerewolfDamageMult(victim, projectile, damage); @@ -275,7 +280,8 @@ namespace MWMechanics // Non-enchanted arrows shot at enemies have a chance to turn up in their inventory if (victim != getPlayer() && !appliedEnchantment) { - static const float fProjectileThrownStoreChance = gmst.find("fProjectileThrownStoreChance")->mValue.getFloat(); + static const float fProjectileThrownStoreChance + = gmst.find("fProjectileThrownStoreChance")->mValue.getFloat(); if (Misc::Rng::rollProbability(world->getPrng()) < fProjectileThrownStoreChance / 100.f) victim.getClass().getContainerStore(victim).add(projectile, 1, victim); } @@ -284,69 +290,67 @@ namespace MWMechanics } } - float getHitChance(const MWWorld::Ptr &attacker, const MWWorld::Ptr &victim, int skillValue) + float getHitChance(const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, int skillValue) { - MWMechanics::CreatureStats &stats = attacker.getClass().getCreatureStats(attacker); - const MWMechanics::MagicEffects &mageffects = stats.getMagicEffects(); + MWMechanics::CreatureStats& stats = attacker.getClass().getCreatureStats(attacker); + const MWMechanics::MagicEffects& mageffects = stats.getMagicEffects(); - MWBase::World *world = MWBase::Environment::get().getWorld(); - const MWWorld::Store &gmst = world->getStore().get(); + MWBase::World* world = MWBase::Environment::get().getWorld(); + const MWWorld::Store& gmst = world->getStore().get(); float defenseTerm = 0; MWMechanics::CreatureStats& victimStats = victim.getClass().getCreatureStats(victim); if (victimStats.getFatigue().getCurrent() >= 0) { // Maybe we should keep an aware state for actors updated every so often instead of testing every time - bool unaware = (!victimStats.getAiSequence().isInCombat()) - && (attacker == getPlayer()) - && (!MWBase::Environment::get().getMechanicsManager()->awarenessCheck(attacker, victim)); - if (!(victimStats.getKnockedDown() || - victimStats.isParalyzed() - || unaware )) + bool unaware = (!victimStats.getAiSequence().isInCombat()) && (attacker == getPlayer()) + && (!MWBase::Environment::get().getMechanicsManager()->awarenessCheck(attacker, victim)); + if (!(victimStats.getKnockedDown() || victimStats.isParalyzed() || unaware)) { defenseTerm = victimStats.getEvasion(); } static const float fCombatInvisoMult = gmst.find("fCombatInvisoMult")->mValue.getFloat(); defenseTerm += std::min(100.f, - fCombatInvisoMult * - victimStats.getMagicEffects().get(ESM::MagicEffect::Chameleon).getMagnitude()); + fCombatInvisoMult * victimStats.getMagicEffects().get(ESM::MagicEffect::Chameleon).getMagnitude()); defenseTerm += std::min(100.f, - fCombatInvisoMult * - victimStats.getMagicEffects().get(ESM::MagicEffect::Invisibility).getMagnitude()); + fCombatInvisoMult * victimStats.getMagicEffects().get(ESM::MagicEffect::Invisibility).getMagnitude()); } - float attackTerm = skillValue + - (stats.getAttribute(ESM::Attribute::Agility).getModified() / 5.0f) + - (stats.getAttribute(ESM::Attribute::Luck).getModified() / 10.0f); + float attackTerm = skillValue + (stats.getAttribute(ESM::Attribute::Agility).getModified() / 5.0f) + + (stats.getAttribute(ESM::Attribute::Luck).getModified() / 10.0f); attackTerm *= stats.getFatigueTerm(); - attackTerm += mageffects.get(ESM::MagicEffect::FortifyAttack).getMagnitude() - - mageffects.get(ESM::MagicEffect::Blind).getMagnitude(); + attackTerm += mageffects.get(ESM::MagicEffect::FortifyAttack).getMagnitude() + - mageffects.get(ESM::MagicEffect::Blind).getMagnitude(); return round(attackTerm - defenseTerm); } - void applyElementalShields(const MWWorld::Ptr &attacker, const MWWorld::Ptr &victim) + void applyElementalShields(const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim) { // Don't let elemental shields harm the player in god mode. bool godmode = attacker == getPlayer() && MWBase::Environment::get().getWorld()->getGodModeState(); if (godmode) return; auto& prng = MWBase::Environment::get().getWorld()->getPrng(); - for (int i=0; i<3; ++i) + for (int i = 0; i < 3; ++i) { - float magnitude = victim.getClass().getCreatureStats(victim).getMagicEffects().get(ESM::MagicEffect::FireShield+i).getMagnitude(); + float magnitude = victim.getClass() + .getCreatureStats(victim) + .getMagicEffects() + .get(ESM::MagicEffect::FireShield + i) + .getMagnitude(); if (!magnitude) continue; CreatureStats& attackerStats = attacker.getClass().getCreatureStats(attacker); float saveTerm = attacker.getClass().getSkill(attacker, ESM::Skill::Destruction) - + 0.2f * attackerStats.getAttribute(ESM::Attribute::Willpower).getModified() - + 0.1f * attackerStats.getAttribute(ESM::Attribute::Luck).getModified(); + + 0.2f * attackerStats.getAttribute(ESM::Attribute::Willpower).getModified() + + 0.1f * attackerStats.getAttribute(ESM::Attribute::Luck).getModified(); float fatigueMax = attackerStats.getFatigue().getModified(); float fatigueCurrent = attackerStats.getFatigue().getCurrent(); - float normalisedFatigue = floor(fatigueMax)==0 ? 1 : std::max (0.0f, (fatigueCurrent/fatigueMax)); + float normalisedFatigue = floor(fatigueMax) == 0 ? 1 : std::max(0.0f, (fatigueCurrent / fatigueMax)); saveTerm *= 1.25f * normalisedFatigue; @@ -358,11 +362,17 @@ namespace MWMechanics if (i == 2) element = ESM::MagicEffect::FrostDamage; - float elementResistance = MWMechanics::getEffectResistanceAttribute(element, &attackerStats.getMagicEffects()); + float elementResistance + = MWMechanics::getEffectResistanceAttribute(element, &attackerStats.getMagicEffects()); x = std::min(100.f, x + elementResistance); - static const float fElementalShieldMult = MWBase::Environment::get().getWorld()->getStore().get().find("fElementalShieldMult")->mValue.getFloat(); + static const float fElementalShieldMult = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fElementalShieldMult") + ->mValue.getFloat(); x = fElementalShieldMult * magnitude * (1.f - 0.01f * x); // Note swapped victim and attacker, since the attacker takes the damage here. @@ -376,7 +386,7 @@ namespace MWMechanics } } - void reduceWeaponCondition(float damage, bool hit, MWWorld::Ptr &weapon, const MWWorld::Ptr &attacker) + void reduceWeaponCondition(float damage, bool hit, MWWorld::Ptr& weapon, const MWWorld::Ptr& attacker) { if (weapon.isEmpty()) return; @@ -385,16 +395,22 @@ namespace MWMechanics damage = 0.f; const bool weaphashealth = weapon.getClass().hasItemHealth(weapon); - if(weaphashealth) + if (weaphashealth) { int weaphealth = weapon.getClass().getItemHealth(weapon); - bool godmode = attacker == MWMechanics::getPlayer() && MWBase::Environment::get().getWorld()->getGodModeState(); + bool godmode + = attacker == MWMechanics::getPlayer() && MWBase::Environment::get().getWorld()->getGodModeState(); // weapon condition does not degrade when godmode is on if (!godmode) { - const float fWeaponDamageMult = MWBase::Environment::get().getWorld()->getStore().get().find("fWeaponDamageMult")->mValue.getFloat(); + const float fWeaponDamageMult = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fWeaponDamageMult") + ->mValue.getFloat(); float x = std::max(1.f, fWeaponDamageMult * damage); weaphealth -= std::min(int(x), weaphealth); @@ -407,7 +423,7 @@ namespace MWMechanics } } - void adjustWeaponDamage(float &damage, const MWWorld::Ptr &weapon, const MWWorld::Ptr& attacker) + void adjustWeaponDamage(float& damage, const MWWorld::Ptr& weapon, const MWWorld::Ptr& attacker) { if (weapon.isEmpty()) return; @@ -418,25 +434,34 @@ namespace MWMechanics damage *= weapon.getClass().getItemNormalizedHealth(weapon); } - static const float fDamageStrengthBase = MWBase::Environment::get().getWorld()->getStore().get() - .find("fDamageStrengthBase")->mValue.getFloat(); - static const float fDamageStrengthMult = MWBase::Environment::get().getWorld()->getStore().get() - .find("fDamageStrengthMult")->mValue.getFloat(); - damage *= fDamageStrengthBase + - (attacker.getClass().getCreatureStats(attacker).getAttribute(ESM::Attribute::Strength).getModified() * fDamageStrengthMult * 0.1f); + static const float fDamageStrengthBase = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fDamageStrengthBase") + ->mValue.getFloat(); + static const float fDamageStrengthMult = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fDamageStrengthMult") + ->mValue.getFloat(); + damage *= fDamageStrengthBase + + (attacker.getClass().getCreatureStats(attacker).getAttribute(ESM::Attribute::Strength).getModified() + * fDamageStrengthMult * 0.1f); } - void getHandToHandDamage(const MWWorld::Ptr &attacker, const MWWorld::Ptr &victim, float &damage, bool &healthdmg, float attackStrength) + void getHandToHandDamage( + const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, float& damage, bool& healthdmg, float attackStrength) { const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); static const float minstrike = store.get().find("fMinHandToHandMult")->mValue.getFloat(); static const float maxstrike = store.get().find("fMaxHandToHandMult")->mValue.getFloat(); - damage = static_cast(attacker.getClass().getSkill(attacker, ESM::Skill::HandToHand)); - damage *= minstrike + ((maxstrike-minstrike)*attackStrength); + damage = static_cast(attacker.getClass().getSkill(attacker, ESM::Skill::HandToHand)); + damage *= minstrike + ((maxstrike - minstrike) * attackStrength); MWMechanics::CreatureStats& otherstats = victim.getClass().getCreatureStats(victim); - healthdmg = otherstats.isParalyzed() - || otherstats.getKnockedDown(); + healthdmg = otherstats.isParalyzed() || otherstats.getKnockedDown(); bool isWerewolf = (attacker.getClass().isNpc() && attacker.getClass().getNpcStats(attacker).isWerewolf()); // Options in the launcher's combo box: unarmedFactorsStrengthComboBox @@ -444,11 +469,14 @@ namespace MWMechanics // 1 = Factor into werewolf hand-to-hand combat. // 2 = Ignore werewolves. int factorStrength = Settings::Manager::getInt("strength influences hand to hand", "Game"); - if (factorStrength == 1 || (factorStrength == 2 && !isWerewolf)) { - damage *= attacker.getClass().getCreatureStats(attacker).getAttribute(ESM::Attribute::Strength).getModified() / 40.0f; + if (factorStrength == 1 || (factorStrength == 2 && !isWerewolf)) + { + damage + *= attacker.getClass().getCreatureStats(attacker).getAttribute(ESM::Attribute::Strength).getModified() + / 40.0f; } - if(isWerewolf) + if (isWerewolf) { healthdmg = true; // GLOB instead of GMST because it gets updated during a quest @@ -456,26 +484,28 @@ namespace MWMechanics } if (healthdmg) { - static const float fHandtoHandHealthPer = store.get().find("fHandtoHandHealthPer")->mValue.getFloat(); + static const float fHandtoHandHealthPer + = store.get().find("fHandtoHandHealthPer")->mValue.getFloat(); damage *= fHandtoHandHealthPer; } - MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); - if(isWerewolf) + MWBase::SoundManager* sndMgr = MWBase::Environment::get().getSoundManager(); + if (isWerewolf) { auto& prng = MWBase::Environment::get().getWorld()->getPrng(); - const ESM::Sound *sound = store.get().searchRandom("WolfHit", prng); - if(sound) + const ESM::Sound* sound = store.get().searchRandom("WolfHit", prng); + if (sound) sndMgr->playSound3D(victim, sound->mId, 1.0f, 1.0f); } else if (!healthdmg) sndMgr->playSound3D(victim, "Hand To Hand Hit", 1.0f, 1.0f); } - void applyFatigueLoss(const MWWorld::Ptr &attacker, const MWWorld::Ptr &weapon, float attackStrength) + void applyFatigueLoss(const MWWorld::Ptr& attacker, const MWWorld::Ptr& weapon, float attackStrength) { // somewhat of a guess, but using the weapon weight makes sense - const MWWorld::Store& store = MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& store + = MWBase::Environment::get().getWorld()->getStore().get(); static const float fFatigueAttackBase = store.find("fFatigueAttackBase")->mValue.getFloat(); static const float fFatigueAttackMult = store.find("fFatigueAttackMult")->mValue.getFloat(); static const float fWeaponFatigueMult = store.find("fWeaponFatigueMult")->mValue.getFloat(); @@ -497,15 +527,23 @@ namespace MWMechanics float getFightDistanceBias(const MWWorld::Ptr& actor1, const MWWorld::Ptr& actor2) { - osg::Vec3f pos1 (actor1.getRefData().getPosition().asVec3()); - osg::Vec3f pos2 (actor2.getRefData().getPosition().asVec3()); + osg::Vec3f pos1(actor1.getRefData().getPosition().asVec3()); + osg::Vec3f pos2(actor2.getRefData().getPosition().asVec3()); float d = getAggroDistance(actor1, pos1, pos2); - static const int iFightDistanceBase = MWBase::Environment::get().getWorld()->getStore().get().find( - "iFightDistanceBase")->mValue.getInteger(); - static const float fFightDistanceMultiplier = MWBase::Environment::get().getWorld()->getStore().get().find( - "fFightDistanceMultiplier")->mValue.getFloat(); + static const int iFightDistanceBase = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("iFightDistanceBase") + ->mValue.getInteger(); + static const float fFightDistanceMultiplier = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fFightDistanceMultiplier") + ->mValue.getFloat(); return (iFightDistanceBase - fFightDistanceMultiplier * d); } diff --git a/apps/openmw/mwmechanics/combat.hpp b/apps/openmw/mwmechanics/combat.hpp index 355d609b46..2e7caf6189 100644 --- a/apps/openmw/mwmechanics/combat.hpp +++ b/apps/openmw/mwmechanics/combat.hpp @@ -14,47 +14,50 @@ namespace MWWorld namespace MWMechanics { -bool applyOnStrikeEnchantment(const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, const MWWorld::Ptr& object, const osg::Vec3f& hitPosition, - const bool fromProjectile=false); + bool applyOnStrikeEnchantment(const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, const MWWorld::Ptr& object, + const osg::Vec3f& hitPosition, const bool fromProjectile = false); -/// @return can we block the attack? -bool blockMeleeAttack (const MWWorld::Ptr& attacker, const MWWorld::Ptr& blocker, const MWWorld::Ptr& weapon, float damage, float attackStrength); + /// @return can we block the attack? + bool blockMeleeAttack(const MWWorld::Ptr& attacker, const MWWorld::Ptr& blocker, const MWWorld::Ptr& weapon, + float damage, float attackStrength); -/// @return does normal weapon resistance and weakness apply to the weapon? -bool isNormalWeapon (const MWWorld::Ptr& weapon); + /// @return does normal weapon resistance and weakness apply to the weapon? + bool isNormalWeapon(const MWWorld::Ptr& weapon); -void resistNormalWeapon (const MWWorld::Ptr& actor, const MWWorld::Ptr& attacker, const MWWorld::Ptr& weapon, float& damage); + void resistNormalWeapon( + const MWWorld::Ptr& actor, const MWWorld::Ptr& attacker, const MWWorld::Ptr& weapon, float& damage); -void applyWerewolfDamageMult (const MWWorld::Ptr& actor, const MWWorld::Ptr& weapon, float &damage); + void applyWerewolfDamageMult(const MWWorld::Ptr& actor, const MWWorld::Ptr& weapon, float& damage); -/// @note for a thrown weapon, \a weapon == \a projectile, for bows/crossbows, \a projectile is the arrow/bolt -/// @note \a victim may be empty (e.g. for a hit on terrain), a non-actor (environment objects) or an actor -void projectileHit (const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, MWWorld::Ptr weapon, const MWWorld::Ptr& projectile, - const osg::Vec3f& hitPosition, float attackStrength); + /// @note for a thrown weapon, \a weapon == \a projectile, for bows/crossbows, \a projectile is the arrow/bolt + /// @note \a victim may be empty (e.g. for a hit on terrain), a non-actor (environment objects) or an actor + void projectileHit(const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, MWWorld::Ptr weapon, + const MWWorld::Ptr& projectile, const osg::Vec3f& hitPosition, float attackStrength); -/// Get the chance (in percent) for \a attacker to successfully hit \a victim with a given weapon skill value -float getHitChance (const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, int skillValue); + /// Get the chance (in percent) for \a attacker to successfully hit \a victim with a given weapon skill value + float getHitChance(const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, int skillValue); -/// Applies damage to attacker based on the victim's elemental shields. -void applyElementalShields(const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim); + /// Applies damage to attacker based on the victim's elemental shields. + void applyElementalShields(const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim); -/// @param damage Unmitigated weapon damage of the attack -/// @param hit Was the attack successful? -/// @param weapon The weapon used. -/// @note if the weapon is unequipped as result of condition damage, a new Ptr will be assigned to \a weapon. -void reduceWeaponCondition (float damage, bool hit, MWWorld::Ptr& weapon, const MWWorld::Ptr& attacker); + /// @param damage Unmitigated weapon damage of the attack + /// @param hit Was the attack successful? + /// @param weapon The weapon used. + /// @note if the weapon is unequipped as result of condition damage, a new Ptr will be assigned to \a weapon. + void reduceWeaponCondition(float damage, bool hit, MWWorld::Ptr& weapon, const MWWorld::Ptr& attacker); -/// Adjust weapon damage based on its condition. A used weapon will be less effective. -void adjustWeaponDamage (float& damage, const MWWorld::Ptr& weapon, const MWWorld::Ptr& attacker); + /// Adjust weapon damage based on its condition. A used weapon will be less effective. + void adjustWeaponDamage(float& damage, const MWWorld::Ptr& weapon, const MWWorld::Ptr& attacker); -void getHandToHandDamage (const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, float& damage, bool& healthdmg, float attackStrength); + void getHandToHandDamage( + const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, float& damage, bool& healthdmg, float attackStrength); -/// Apply the fatigue loss incurred by attacking with the given weapon (weapon may be empty = hand-to-hand) -void applyFatigueLoss(const MWWorld::Ptr& attacker, const MWWorld::Ptr& weapon, float attackStrength); + /// Apply the fatigue loss incurred by attacking with the given weapon (weapon may be empty = hand-to-hand) + void applyFatigueLoss(const MWWorld::Ptr& attacker, const MWWorld::Ptr& weapon, float attackStrength); -float getFightDistanceBias(const MWWorld::Ptr& actor1, const MWWorld::Ptr& actor2); + float getFightDistanceBias(const MWWorld::Ptr& actor1, const MWWorld::Ptr& actor2); -float getAggroDistance(const MWWorld::Ptr& actor, const osg::Vec3f& lhs, const osg::Vec3f& rhs); + float getAggroDistance(const MWWorld::Ptr& actor, const osg::Vec3f& lhs, const osg::Vec3f& rhs); } diff --git a/apps/openmw/mwmechanics/creaturestats.cpp b/apps/openmw/mwmechanics/creaturestats.cpp index 97e30620da..931d0a3206 100644 --- a/apps/openmw/mwmechanics/creaturestats.cpp +++ b/apps/openmw/mwmechanics/creaturestats.cpp @@ -20,12 +20,30 @@ namespace MWMechanics int CreatureStats::sActorId = 0; CreatureStats::CreatureStats() - : mDrawState (DrawState::Nothing), mDead (false), mDeathAnimationFinished(false), mDied (false), mMurdered(false), mFriendlyHits (0), - mTalkedTo (false), mAlarmed (false), mAttacked (false), - mKnockdown(false), mKnockdownOneFrame(false), mKnockdownOverOneFrame(false), - mHitRecovery(false), mBlock(false), mMovementFlags(0), - mFallHeight(0), mLastRestock(0,0), mGoldPool(0), mActorId(-1), mHitAttemptActorId(-1), - mDeathAnimation(-1), mTimeOfDeath(), mSideMovementAngle(0), mLevel (0) + : mDrawState(DrawState::Nothing) + , mDead(false) + , mDeathAnimationFinished(false) + , mDied(false) + , mMurdered(false) + , mFriendlyHits(0) + , mTalkedTo(false) + , mAlarmed(false) + , mAttacked(false) + , mKnockdown(false) + , mKnockdownOneFrame(false) + , mKnockdownOverOneFrame(false) + , mHitRecovery(false) + , mBlock(false) + , mMovementFlags(0) + , mFallHeight(0) + , mLastRestock(0, 0) + , mGoldPool(0) + , mActorId(-1) + , mHitAttemptActorId(-1) + , mDeathAnimation(-1) + , mTimeOfDeath() + , mSideMovementAngle(0) + , mLevel(0) , mAttackingOrSpell(false) { } @@ -45,51 +63,52 @@ namespace MWMechanics float max = getFatigue().getModified(); float current = getFatigue().getCurrent(); - float normalised = std::floor(max) == 0 ? 1 : std::max (0.0f, current / max); + float normalised = std::floor(max) == 0 ? 1 : std::max(0.0f, current / max); - const MWWorld::Store &gmst = - MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& gmst + = MWBase::Environment::get().getWorld()->getStore().get(); static const float fFatigueBase = gmst.find("fFatigueBase")->mValue.getFloat(); static const float fFatigueMult = gmst.find("fFatigueMult")->mValue.getFloat(); - return fFatigueBase - fFatigueMult * (1-normalised); + return fFatigueBase - fFatigueMult * (1 - normalised); } - const AttributeValue &CreatureStats::getAttribute(int index) const + const AttributeValue& CreatureStats::getAttribute(int index) const { - if (index < 0 || index > 7) { + if (index < 0 || index > 7) + { throw std::runtime_error("attribute index is out of range"); } return mAttributes[index]; } - const DynamicStat &CreatureStats::getHealth() const + const DynamicStat& CreatureStats::getHealth() const { return mDynamic[0]; } - const DynamicStat &CreatureStats::getMagicka() const + const DynamicStat& CreatureStats::getMagicka() const { return mDynamic[1]; } - const DynamicStat &CreatureStats::getFatigue() const + const DynamicStat& CreatureStats::getFatigue() const { return mDynamic[2]; } - const Spells &CreatureStats::getSpells() const + const Spells& CreatureStats::getSpells() const { return mSpells; } - const ActiveSpells &CreatureStats::getActiveSpells() const + const ActiveSpells& CreatureStats::getActiveSpells() const { return mActiveSpells; } - const MagicEffects &CreatureStats::getMagicEffects() const + const MagicEffects& CreatureStats::getMagicEffects() const { return mMagicEffects; } @@ -99,30 +118,31 @@ namespace MWMechanics return mLevel; } - Stat CreatureStats::getAiSetting (AiSetting index) const + Stat CreatureStats::getAiSetting(AiSetting index) const { return mAiSettings[static_cast>(index)]; } - const DynamicStat &CreatureStats::getDynamic(int index) const + const DynamicStat& CreatureStats::getDynamic(int index) const { - if (index < 0 || index > 2) { + if (index < 0 || index > 2) + { throw std::runtime_error("dynamic stat index is out of range"); } return mDynamic[index]; } - Spells &CreatureStats::getSpells() + Spells& CreatureStats::getSpells() { return mSpells; } - ActiveSpells &CreatureStats::getActiveSpells() + ActiveSpells& CreatureStats::getActiveSpells() { return mActiveSpells; } - MagicEffects &CreatureStats::getMagicEffects() + MagicEffects& CreatureStats::getMagicEffects() { return mMagicEffects; } @@ -134,9 +154,10 @@ namespace MWMechanics setAttribute(index, current); } - void CreatureStats::setAttribute(int index, const AttributeValue &value) + void CreatureStats::setAttribute(int index, const AttributeValue& value) { - if (index < 0 || index > 7) { + if (index < 0 || index > 7) + { throw std::runtime_error("attribute index is out of range"); } @@ -148,15 +169,13 @@ namespace MWMechanics if (index == ESM::Attribute::Intelligence) recalculateMagicka(); - else if (index == ESM::Attribute::Strength || - index == ESM::Attribute::Willpower || - index == ESM::Attribute::Agility || - index == ESM::Attribute::Endurance) + else if (index == ESM::Attribute::Strength || index == ESM::Attribute::Willpower + || index == ESM::Attribute::Agility || index == ESM::Attribute::Endurance) { - float strength = getAttribute(ESM::Attribute::Strength).getModified(); - float willpower = getAttribute(ESM::Attribute::Willpower).getModified(); - float agility = getAttribute(ESM::Attribute::Agility).getModified(); - float endurance = getAttribute(ESM::Attribute::Endurance).getModified(); + float strength = getAttribute(ESM::Attribute::Strength).getModified(); + float willpower = getAttribute(ESM::Attribute::Willpower).getModified(); + float agility = getAttribute(ESM::Attribute::Agility).getModified(); + float endurance = getAttribute(ESM::Attribute::Endurance).getModified(); DynamicStat fatigue = getFatigue(); float currentToBaseRatio = fatigue.getBase() > 0 ? (fatigue.getCurrent() / fatigue.getBase()) : 0; fatigue.setBase(std::max(0.f, strength + willpower + agility + endurance)); @@ -166,29 +185,29 @@ namespace MWMechanics } } - void CreatureStats::setHealth(const DynamicStat &value) + void CreatureStats::setHealth(const DynamicStat& value) { - setDynamic (0, value); + setDynamic(0, value); } - void CreatureStats::setMagicka(const DynamicStat &value) + void CreatureStats::setMagicka(const DynamicStat& value) { - setDynamic (1, value); + setDynamic(1, value); } - void CreatureStats::setFatigue(const DynamicStat &value) + void CreatureStats::setFatigue(const DynamicStat& value) { - setDynamic (2, value); + setDynamic(2, value); } - void CreatureStats::setDynamic (int index, const DynamicStat &value) + void CreatureStats::setDynamic(int index, const DynamicStat& value) { if (index < 0 || index > 2) throw std::runtime_error("dynamic stat index is out of range"); mDynamic[index] = value; - if (index==0 && mDynamic[index].getCurrent()<1) + if (index == 0 && mDynamic[index].getCurrent() < 1) { if (!mDead) mTimeOfDeath = MWBase::Environment::get().getWorld()->getTimeStamp(); @@ -204,20 +223,21 @@ namespace MWMechanics mLevel = level; } - void CreatureStats::modifyMagicEffects(const MagicEffects &effects) + void CreatureStats::modifyMagicEffects(const MagicEffects& effects) { - bool recalc = effects.get(ESM::MagicEffect::FortifyMaximumMagicka).getModifier() != mMagicEffects.get(ESM::MagicEffect::FortifyMaximumMagicka).getModifier(); + bool recalc = effects.get(ESM::MagicEffect::FortifyMaximumMagicka).getModifier() + != mMagicEffects.get(ESM::MagicEffect::FortifyMaximumMagicka).getModifier(); mMagicEffects.setModifiers(effects); - if(recalc) + if (recalc) recalculateMagicka(); } - void CreatureStats::setAiSetting (AiSetting index, Stat value) + void CreatureStats::setAiSetting(AiSetting index, Stat value) { mAiSettings[static_cast>(index)] = value; } - void CreatureStats::setAiSetting (AiSetting index, int base) + void CreatureStats::setAiSetting(AiSetting index, int base) { Stat stat = getAiSetting(index); stat.setBase(base); @@ -319,7 +339,7 @@ namespace MWMechanics return mAlarmed; } - void CreatureStats::setAlarmed (bool alarmed) + void CreatureStats::setAlarmed(bool alarmed) { mAlarmed = alarmed; } @@ -329,15 +349,15 @@ namespace MWMechanics return mAttacked; } - void CreatureStats::setAttacked (bool attacked) + void CreatureStats::setAttacked(bool attacked) { mAttacked = attacked; } float CreatureStats::getEvasion() const { - float evasion = (getAttribute(ESM::Attribute::Agility).getModified() / 5.0f) + - (getAttribute(ESM::Attribute::Luck).getModified() / 10.0f); + float evasion = (getAttribute(ESM::Attribute::Agility).getModified() / 5.0f) + + (getAttribute(ESM::Attribute::Luck).getModified() / 10.0f); evasion *= getFatigueTerm(); evasion += std::min(100.f, mMagicEffects.get(ESM::MagicEffect::Sanctuary).getMagnitude()); @@ -354,7 +374,7 @@ namespace MWMechanics mLastHitObject.clear(); } - const std::string &CreatureStats::getLastHitObject() const + const std::string& CreatureStats::getLastHitObject() const { return mLastHitObject; } @@ -369,7 +389,7 @@ namespace MWMechanics mLastHitAttemptObject.clear(); } - const std::string &CreatureStats::getLastHitAttemptObject() const + const std::string& CreatureStats::getLastHitAttemptObject() const { return mLastHitAttemptObject; } @@ -416,7 +436,8 @@ namespace MWMechanics else base = world->getStore().get().find("fNPCbaseMagickaMult")->mValue.getFloat(); - double magickaFactor = base + mMagicEffects.get(EffectKey(ESM::MagicEffect::FortifyMaximumMagicka)).getMagnitude() * 0.1; + double magickaFactor + = base + mMagicEffects.get(EffectKey(ESM::MagicEffect::FortifyMaximumMagicka)).getMagnitude() * 0.1; DynamicStat magicka = getMagicka(); float currentToBaseRatio = magicka.getBase() > 0 ? magicka.getCurrent() / magicka.getBase() : 0; @@ -428,7 +449,7 @@ namespace MWMechanics void CreatureStats::setKnockedDown(bool value) { mKnockdown = value; - if(!value) //Resets the "OverOneFrame" flag + if (!value) // Resets the "OverOneFrame" flag setKnockedDownOverOneFrame(false); } @@ -447,10 +468,12 @@ namespace MWMechanics return mKnockdownOneFrame; } - void CreatureStats::setKnockedDownOverOneFrame(bool value) { + void CreatureStats::setKnockedDownOverOneFrame(bool value) + { mKnockdownOverOneFrame = value; } - bool CreatureStats::getKnockedDownOverOneFrame() const { + bool CreatureStats::getKnockedDownOverOneFrame() const + { return mKnockdownOverOneFrame; } @@ -474,12 +497,12 @@ namespace MWMechanics return mBlock; } - bool CreatureStats::getMovementFlag (Flag flag) const + bool CreatureStats::getMovementFlag(Flag flag) const { return (mMovementFlags & flag) != 0; } - void CreatureStats::setMovementFlag (Flag flag, bool state) + void CreatureStats::setMovementFlag(Flag flag, bool state) { if (state) mMovementFlags |= flag; @@ -492,9 +515,9 @@ namespace MWMechanics switch (flag) { case Stance_Run: - return getMovementFlag (Flag_Run) || getMovementFlag (Flag_ForceRun); + return getMovementFlag(Flag_Run) || getMovementFlag(Flag_ForceRun); case Stance_Sneak: - return getMovementFlag (Flag_Sneak) || getMovementFlag (Flag_ForceSneak); + return getMovementFlag(Flag_Sneak) || getMovementFlag(Flag_ForceSneak); default: return false; } @@ -510,13 +533,13 @@ namespace MWMechanics mDrawState = state; } - void CreatureStats::writeState (ESM::CreatureStats& state) const + void CreatureStats::writeState(ESM::CreatureStats& state) const { - for (int i=0; i #include -#include #include +#include -#include "stat.hpp" -#include "magiceffects.hpp" -#include "spells.hpp" #include "activespells.hpp" #include "aisequence.hpp" -#include "drawstate.hpp" #include "aisetting.hpp" +#include "drawstate.hpp" +#include "magiceffects.hpp" +#include "spells.hpp" +#include "stat.hpp" #include #include @@ -108,56 +108,56 @@ namespace MWMechanics /// Reset the fall height /// @return total fall height - float land(bool isPlayer=false); + float land(bool isPlayer = false); - const AttributeValue & getAttribute(int index) const; + const AttributeValue& getAttribute(int index) const; - const DynamicStat & getHealth() const; + const DynamicStat& getHealth() const; - const DynamicStat & getMagicka() const; + const DynamicStat& getMagicka() const; - const DynamicStat & getFatigue() const; + const DynamicStat& getFatigue() const; - const DynamicStat & getDynamic (int index) const; + const DynamicStat& getDynamic(int index) const; - const Spells & getSpells() const; + const Spells& getSpells() const; - const ActiveSpells & getActiveSpells() const; + const ActiveSpells& getActiveSpells() const; - const MagicEffects & getMagicEffects() const; + const MagicEffects& getMagicEffects() const; bool getAttackingOrSpell() const { return mAttackingOrSpell; } int getLevel() const; - Spells & getSpells(); + Spells& getSpells(); - ActiveSpells & getActiveSpells(); + ActiveSpells& getActiveSpells(); - MagicEffects & getMagicEffects(); + MagicEffects& getMagicEffects(); - void setAttribute(int index, const AttributeValue &value); + void setAttribute(int index, const AttributeValue& value); // Shortcut to set only the base void setAttribute(int index, float base); - void setHealth(const DynamicStat &value); + void setHealth(const DynamicStat& value); - void setMagicka(const DynamicStat &value); + void setMagicka(const DynamicStat& value); - void setFatigue(const DynamicStat &value); + void setFatigue(const DynamicStat& value); - void setDynamic (int index, const DynamicStat &value); + void setDynamic(int index, const DynamicStat& value); /// Set Modifier for each magic effect according to \a effects. Does not touch Base values. - void modifyMagicEffects(const MagicEffects &effects); + void modifyMagicEffects(const MagicEffects& effects); void setAttackingOrSpell(bool attackingOrSpell) { mAttackingOrSpell = attackingOrSpell; } void setLevel(int level); - void setAiSetting (AiSetting index, Stat value); - void setAiSetting (AiSetting index, int base); - Stat getAiSetting (AiSetting index) const; + void setAiSetting(AiSetting index, Stat value); + void setAiSetting(AiSetting index, int base); + Stat getAiSetting(AiSetting index) const; const AiSequence& getAiSequence() const; @@ -203,10 +203,10 @@ namespace MWMechanics void talkedToPlayer(); bool isAlarmed() const; - void setAlarmed (bool alarmed); + void setAlarmed(bool alarmed); bool getAttacked() const; - void setAttacked (bool attacked); + void setAttacked(bool attacked); float getEvasion() const; @@ -215,10 +215,11 @@ namespace MWMechanics /// including transition animations (falling down & standing up) bool getKnockedDown() const; void setKnockedDownOneFrame(bool value); - ///Returns true only for the first frame of the actor being knocked out; used for "onKnockedOut" command + /// Returns true only for the first frame of the actor being knocked out; used for "onKnockedOut" command bool getKnockedDownOneFrame() const; void setKnockedDownOverOneFrame(bool value); - ///Returns true for all but the first frame of being knocked out; used to know to not reset mKnockedDownOneFrame + /// Returns true for all but the first frame of being knocked out; used to know to not reset + /// mKnockedDownOneFrame bool getKnockedDownOverOneFrame() const; void setHitRecovery(bool value); bool getHitRecovery() const; @@ -243,26 +244,26 @@ namespace MWMechanics Stance_Sneak }; - bool getMovementFlag (Flag flag) const; - void setMovementFlag (Flag flag, bool state); + bool getMovementFlag(Flag flag) const; + void setMovementFlag(Flag flag, bool state); /// Like getMovementFlag, but also takes into account if the flag is Forced - bool getStance (Stance flag) const; + bool getStance(Stance flag) const; - void setLastHitObject(const std::string &objectid); + void setLastHitObject(const std::string& objectid); void clearLastHitObject(); - const std::string &getLastHitObject() const; - void setLastHitAttemptObject(const std::string &objectid); + const std::string& getLastHitObject() const; + void setLastHitAttemptObject(const std::string& objectid); void clearLastHitAttemptObject(); - const std::string &getLastHitAttemptObject() const; + const std::string& getLastHitAttemptObject() const; void setHitAttemptActorId(const int actorId); int getHitAttemptActorId() const; - void writeState (ESM::CreatureStats& state) const; + void writeState(ESM::CreatureStats& state) const; - void readState (const ESM::CreatureStats& state); + void readState(const ESM::CreatureStats& state); - static void writeActorIdCounter (ESM::ESMWriter& esm); - static void readActorIdCounter (ESM::ESMReader& esm); + static void writeActorIdCounter(ESM::ESMWriter& esm); + static void readActorIdCounter(ESM::ESMReader& esm); void setLastRestockTime(MWWorld::TimeStamp tradeTime); MWWorld::TimeStamp getLastRestockTime() const; @@ -278,7 +279,7 @@ namespace MWMechanics int getActorId(); ///< Will generate an actor ID, if the actor does not have one yet. - bool matchesActorId (int id) const; + bool matchesActorId(int id) const; ///< Check if \a id matches the actor ID of *this (if the actor does not have an ID /// assigned this function will return false). diff --git a/apps/openmw/mwmechanics/difficultyscaling.cpp b/apps/openmw/mwmechanics/difficultyscaling.cpp index e973e0ed52..fc027a03c9 100644 --- a/apps/openmw/mwmechanics/difficultyscaling.cpp +++ b/apps/openmw/mwmechanics/difficultyscaling.cpp @@ -2,8 +2,8 @@ #include -#include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" #include "../mwworld/esmstore.hpp" #include "actorutil.hpp" @@ -15,7 +15,12 @@ float scaleDamage(float damage, const MWWorld::Ptr& attacker, const MWWorld::Ptr // [-500, 500] const int difficultySetting = std::clamp(Settings::Manager::getInt("difficulty", "Game"), -500, 500); - static const float fDifficultyMult = MWBase::Environment::get().getWorld()->getStore().get().find("fDifficultyMult")->mValue.getFloat(); + static const float fDifficultyMult = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fDifficultyMult") + ->mValue.getFloat(); float difficultyTerm = 0.01f * difficultySetting; diff --git a/apps/openmw/mwmechanics/disease.hpp b/apps/openmw/mwmechanics/disease.hpp index fad9afd015..6b2b185b44 100644 --- a/apps/openmw/mwmechanics/disease.hpp +++ b/apps/openmw/mwmechanics/disease.hpp @@ -1,21 +1,21 @@ #ifndef OPENMW_MECHANICS_DISEASE_H #define OPENMW_MECHANICS_DISEASE_H +#include #include #include -#include -#include "../mwbase/windowmanager.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/windowmanager.hpp" #include "../mwbase/world.hpp" -#include "../mwworld/ptr.hpp" #include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" +#include "../mwworld/ptr.hpp" -#include "spells.hpp" -#include "creaturestats.hpp" #include "actorutil.hpp" +#include "creaturestats.hpp" +#include "spells.hpp" namespace MWMechanics { @@ -23,14 +23,17 @@ namespace MWMechanics /// Call when \a actor has got in contact with \a carrier (e.g. hit by him, or loots him) /// @param actor The actor that will potentially catch diseases. Currently only the player can catch diseases. /// @param carrier The disease carrier. - inline void diseaseContact (const MWWorld::Ptr& actor, const MWWorld::Ptr& carrier) + inline void diseaseContact(const MWWorld::Ptr& actor, const MWWorld::Ptr& carrier) { if (!carrier.getClass().isActor() || actor != getPlayer()) return; - float fDiseaseXferChance = - MWBase::Environment::get().getWorld()->getStore().get().find( - "fDiseaseXferChance")->mValue.getFloat(); + float fDiseaseXferChance = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fDiseaseXferChance") + ->mValue.getFloat(); const MagicEffects& actorEffects = actor.getClass().getCreatureStats(actor).getMagicEffects(); @@ -42,14 +45,20 @@ namespace MWMechanics float resist = 0.f; if (Spells::hasCorprusEffect(spell)) - resist = 1.f - 0.01f * (actorEffects.get(ESM::MagicEffect::ResistCorprusDisease).getMagnitude() - - actorEffects.get(ESM::MagicEffect::WeaknessToCorprusDisease).getMagnitude()); + resist = 1.f + - 0.01f + * (actorEffects.get(ESM::MagicEffect::ResistCorprusDisease).getMagnitude() + - actorEffects.get(ESM::MagicEffect::WeaknessToCorprusDisease).getMagnitude()); else if (spell->mData.mType == ESM::Spell::ST_Disease) - resist = 1.f - 0.01f * (actorEffects.get(ESM::MagicEffect::ResistCommonDisease).getMagnitude() - - actorEffects.get(ESM::MagicEffect::WeaknessToCommonDisease).getMagnitude()); + resist = 1.f + - 0.01f + * (actorEffects.get(ESM::MagicEffect::ResistCommonDisease).getMagnitude() + - actorEffects.get(ESM::MagicEffect::WeaknessToCommonDisease).getMagnitude()); else if (spell->mData.mType == ESM::Spell::ST_Blight) - resist = 1.f - 0.01f * (actorEffects.get(ESM::MagicEffect::ResistBlightDisease).getMagnitude() - - actorEffects.get(ESM::MagicEffect::WeaknessToBlightDisease).getMagnitude()); + resist = 1.f + - 0.01f + * (actorEffects.get(ESM::MagicEffect::ResistBlightDisease).getMagnitude() + - actorEffects.get(ESM::MagicEffect::WeaknessToBlightDisease).getMagnitude()); else continue; @@ -61,7 +70,12 @@ namespace MWMechanics actor.getClass().getCreatureStats(actor).getSpells().add(spell); MWBase::Environment::get().getWorld()->applyLoopingParticles(actor); - std::string msg = MWBase::Environment::get().getWorld()->getStore().get().find("sMagicContractDisease")->mValue.getString(); + std::string msg = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("sMagicContractDisease") + ->mValue.getString(); msg = Misc::StringUtils::format(msg, spell->mName); MWBase::Environment::get().getWindowManager()->messageBox(msg); } @@ -69,5 +83,4 @@ namespace MWMechanics } } - #endif diff --git a/apps/openmw/mwmechanics/enchanting.cpp b/apps/openmw/mwmechanics/enchanting.cpp index 6540b405a0..bb8b78fa99 100644 --- a/apps/openmw/mwmechanics/enchanting.cpp +++ b/apps/openmw/mwmechanics/enchanting.cpp @@ -1,22 +1,22 @@ #include "enchanting.hpp" -#include -#include #include #include +#include +#include -#include "../mwworld/manualref.hpp" #include "../mwworld/class.hpp" #include "../mwworld/containerstore.hpp" #include "../mwworld/esmstore.hpp" +#include "../mwworld/manualref.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/world.hpp" +#include "actorutil.hpp" #include "creaturestats.hpp" #include "spellutil.hpp" -#include "actorutil.hpp" #include "weapontype.hpp" namespace MWMechanics @@ -26,14 +26,15 @@ namespace MWMechanics , mSelfEnchanting(false) , mObjectType(0) , mWeaponType(-1) - {} + { + } void Enchanting::setOldItem(const MWWorld::Ptr& oldItem) { - mOldItemPtr=oldItem; + mOldItemPtr = oldItem; mWeaponType = -1; mObjectType = 0; - if(!itemEmpty()) + if (!itemEmpty()) { mObjectType = mOldItemPtr.getType(); if (mObjectType == ESM::Weapon::sRecordId) @@ -43,12 +44,12 @@ namespace MWMechanics void Enchanting::setNewItemName(const std::string& s) { - mNewItemName=s; + mNewItemName = s; } void Enchanting::setEffect(const ESM::EffectList& effectList) { - mEffectList=effectList; + mEffectList = effectList; } int Enchanting::getCastStyle() const @@ -58,7 +59,7 @@ namespace MWMechanics void Enchanting::setSoulGem(const MWWorld::Ptr& soulGem) { - mSoulGemPtr=soulGem; + mSoulGemPtr = soulGem; } bool Enchanting::create() @@ -72,24 +73,24 @@ namespace MWMechanics store.remove(mSoulGemPtr, 1, player); - //Exception for Azura Star, new one will be added after enchanting - if(Misc::StringUtils::ciEqual(mSoulGemPtr.get()->mBase->mId, "Misc_SoulGem_Azura")) + // Exception for Azura Star, new one will be added after enchanting + if (Misc::StringUtils::ciEqual(mSoulGemPtr.get()->mBase->mId, "Misc_SoulGem_Azura")) store.add("Misc_SoulGem_Azura", 1, player); - if(mSelfEnchanting) + if (mSelfEnchanting) { auto& prng = MWBase::Environment::get().getWorld()->getPrng(); - if(getEnchantChance() <= (Misc::Rng::roll0to99(prng))) + if (getEnchantChance() <= (Misc::Rng::roll0to99(prng))) return false; - mEnchanter.getClass().skillUsageSucceeded (mEnchanter, ESM::Skill::Enchant, 2); + mEnchanter.getClass().skillUsageSucceeded(mEnchanter, ESM::Skill::Enchant, 2); } enchantment.mEffects = mEffectList; int count = getEnchantItemsCount(); - if(mCastStyle==ESM::Enchantment::ConstantEffect) + if (mCastStyle == ESM::Enchantment::ConstantEffect) enchantment.mData.mCharge = 0; else enchantment.mData.mCharge = getGemCharge() / count; @@ -97,31 +98,36 @@ namespace MWMechanics // Try to find a dynamic enchantment with the same stats, create a new one if not found. const ESM::Enchantment* enchantmentPtr = getRecord(enchantment); if (enchantmentPtr == nullptr) - enchantmentPtr = MWBase::Environment::get().getWorld()->createRecord (enchantment); + enchantmentPtr = MWBase::Environment::get().getWorld()->createRecord(enchantment); // Apply the enchantment - const std::string& newItemId = mOldItemPtr.getClass().applyEnchantment(mOldItemPtr, enchantmentPtr->mId, getGemCharge(), mNewItemName); + const std::string& newItemId + = mOldItemPtr.getClass().applyEnchantment(mOldItemPtr, enchantmentPtr->mId, getGemCharge(), mNewItemName); // Add the new item to player inventory and remove the old one store.remove(mOldItemPtr, count, player); store.add(newItemId, count, player); - if(!mSelfEnchanting) + if (!mSelfEnchanting) payForEnchantment(); return true; } - + void Enchanting::nextCastStyle() { if (itemEmpty()) return; - const bool powerfulSoul = getGemCharge() >= \ - MWBase::Environment::get().getWorld()->getStore().get().find ("iSoulAmountForConstantEffect")->mValue.getInteger(); + const bool powerfulSoul = getGemCharge() >= MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("iSoulAmountForConstantEffect") + ->mValue.getInteger(); if ((mObjectType == ESM::Armor::sRecordId) || (mObjectType == ESM::Clothing::sRecordId)) { // Armor or Clothing - switch(mCastStyle) + switch (mCastStyle) { case ESM::Enchantment::WhenUsed: if (powerfulSoul) @@ -135,7 +141,7 @@ namespace MWMechanics else if (mWeaponType != -1) { // Weapon ESM::WeaponType::Class weapclass = MWMechanics::getWeaponType(mWeaponType)->mWeaponClass; - switch(mCastStyle) + switch (mCastStyle) { case ESM::Enchantment::WhenStrikes: if (weapclass == ESM::WeaponType::Melee || weapclass == ESM::WeaponType::Ranged) @@ -154,7 +160,7 @@ namespace MWMechanics return; } } - else if(mObjectType == ESM::Book::sRecordId) + else if (mObjectType == ESM::Book::sRecordId) { // Scroll or Book mCastStyle = ESM::Enchantment::CastOnce; return; @@ -184,9 +190,10 @@ namespace MWMechanics // No effects added, cost = 0 return 0; - const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); const float fEffectCostMult = store.get().find("fEffectCostMult")->mValue.getFloat(); - const float fEnchantmentConstantDurationMult = store.get().find("fEnchantmentConstantDurationMult")->mValue.getFloat(); + const float fEnchantmentConstantDurationMult + = store.get().find("fEnchantmentConstantDurationMult")->mValue.getFloat(); float enchantmentCost = 0.f; float cost = 0.f; @@ -215,18 +222,17 @@ namespace MWMechanics const ESM::Enchantment* Enchanting::getRecord(const ESM::Enchantment& toFind) const { - const MWWorld::Store& enchantments = MWBase::Environment::get().getWorld()->getStore().get(); - MWWorld::Store::iterator iter (enchantments.begin()); + const MWWorld::Store& enchantments + = MWBase::Environment::get().getWorld()->getStore().get(); + MWWorld::Store::iterator iter(enchantments.begin()); iter += (enchantments.getSize() - enchantments.getDynamicSize()); for (; iter != enchantments.end(); ++iter) { if (iter->mEffects.mList.size() != toFind.mEffects.mList.size()) continue; - if (iter->mData.mFlags != toFind.mData.mFlags - || iter->mData.mType != toFind.mData.mType - || iter->mData.mCost != toFind.mData.mCost - || iter->mData.mCharge != toFind.mData.mCharge) + if (iter->mData.mFlags != toFind.mData.mFlags || iter->mData.mType != toFind.mData.mType + || iter->mData.mCost != toFind.mData.mCost || iter->mData.mCharge != toFind.mData.mCharge) continue; // Don't choose an ID that came from the content files, would have unintended side effects @@ -235,19 +241,15 @@ namespace MWMechanics bool mismatch = false; - for (int i=0; i (iter->mEffects.mList.size()); ++i) + for (int i = 0; i < static_cast(iter->mEffects.mList.size()); ++i) { const ESM::ENAMstruct& first = iter->mEffects.mList[i]; const ESM::ENAMstruct& second = toFind.mEffects.mList[i]; - if (first.mEffectID!=second.mEffectID || - first.mArea!=second.mArea || - first.mRange!=second.mRange || - first.mSkill!=second.mSkill || - first.mAttribute!=second.mAttribute || - first.mMagnMin!=second.mMagnMin || - first.mMagnMax!=second.mMagnMax || - first.mDuration!=second.mDuration) + if (first.mEffectID != second.mEffectID || first.mArea != second.mArea || first.mRange != second.mRange + || first.mSkill != second.mSkill || first.mAttribute != second.mAttribute + || first.mMagnMin != second.mMagnMin || first.mMagnMax != second.mMagnMax + || first.mDuration != second.mDuration) { mismatch = true; break; @@ -276,27 +278,32 @@ namespace MWMechanics return getEffectiveEnchantmentCastCost(static_cast(baseCost), player); } - int Enchanting::getEnchantPrice() const { - if(mEnchanter.isEmpty()) + if (mEnchanter.isEmpty()) return 0; - float priceMultipler = MWBase::Environment::get().getWorld()->getStore().get().find ("fEnchantmentValueMult")->mValue.getFloat(); - int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mEnchanter, static_cast(getEnchantPoints() * priceMultipler), true); + float priceMultipler = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fEnchantmentValueMult") + ->mValue.getFloat(); + int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer( + mEnchanter, static_cast(getEnchantPoints() * priceMultipler), true); price *= getEnchantItemsCount() * getTypeMultiplier(); return std::max(1, price); } int Enchanting::getGemCharge() const { - const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); - if(soulEmpty()) + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + if (soulEmpty()) return 0; - if(mSoulGemPtr.getCellRef().getSoul()=="") + if (mSoulGemPtr.getCellRef().getSoul() == "") return 0; const ESM::Creature* soul = store.get().search(mSoulGemPtr.getCellRef().getSoul()); - if(soul) + if (soul) return soul->mData.mSoul; else return 0; @@ -307,9 +314,10 @@ namespace MWMechanics if (itemEmpty()) return 0; - const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); - return static_cast(mOldItemPtr.getClass().getEnchantmentPoints(mOldItemPtr) * store.get().find("fEnchantmentMult")->mValue.getFloat()); + return static_cast(mOldItemPtr.getClass().getEnchantmentPoints(mOldItemPtr) + * store.get().find("fEnchantmentMult")->mValue.getFloat()); } bool Enchanting::soulEmpty() const { @@ -336,14 +344,17 @@ namespace MWMechanics int Enchanting::getEnchantChance() const { const CreatureStats& stats = mEnchanter.getClass().getCreatureStats(mEnchanter); - const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& gmst + = MWBase::Environment::get().getWorld()->getStore().get(); const float a = static_cast(mEnchanter.getClass().getSkill(mEnchanter, ESM::Skill::Enchant)); - const float b = static_cast(stats.getAttribute (ESM::Attribute::Intelligence).getModified()); - const float c = static_cast(stats.getAttribute (ESM::Attribute::Luck).getModified()); + const float b = static_cast(stats.getAttribute(ESM::Attribute::Intelligence).getModified()); + const float c = static_cast(stats.getAttribute(ESM::Attribute::Luck).getModified()); const float fEnchantmentChanceMult = gmst.find("fEnchantmentChanceMult")->mValue.getFloat(); const float fEnchantmentConstantChanceMult = gmst.find("fEnchantmentConstantChanceMult")->mValue.getFloat(); - float x = (a - getEnchantPoints() * fEnchantmentChanceMult * getTypeMultiplier() * getEnchantItemsCount() + 0.2f * b + 0.1f * c) * stats.getFatigueTerm(); + float x = (a - getEnchantPoints() * fEnchantmentChanceMult * getTypeMultiplier() * getEnchantItemsCount() + + 0.2f * b + 0.1f * c) + * stats.getFatigueTerm(); if (mCastStyle == ESM::Enchantment::ConstantEffect) x *= fEnchantmentConstantChanceMult; @@ -359,7 +370,8 @@ namespace MWMechanics ESM::WeaponType::Class weapclass = MWMechanics::getWeaponType(mWeaponType)->mWeaponClass; if (weapclass == ESM::WeaponType::Thrown || weapclass == ESM::WeaponType::Ammo) { - static const float multiplier = std::clamp(Settings::Manager::getFloat("projectiles enchant multiplier", "Game"), 0.f, 1.f); + static const float multiplier + = std::clamp(Settings::Manager::getFloat("projectiles enchant multiplier", "Game"), 0.f, 1.f); MWWorld::Ptr player = getPlayer(); count = player.getClass().getContainerStore(player).count(mOldItemPtr.getCellRef().getRefId()); count = std::clamp(getGemCharge() * multiplier / enchantPoints, 1, count); diff --git a/apps/openmw/mwmechanics/enchanting.hpp b/apps/openmw/mwmechanics/enchanting.hpp index 5e1a6fa239..53c3fc3f91 100644 --- a/apps/openmw/mwmechanics/enchanting.hpp +++ b/apps/openmw/mwmechanics/enchanting.hpp @@ -12,47 +12,48 @@ namespace MWMechanics { class Enchanting { - MWWorld::Ptr mOldItemPtr; - MWWorld::Ptr mSoulGemPtr; - MWWorld::Ptr mEnchanter; - - int mCastStyle; - - bool mSelfEnchanting; - - ESM::EffectList mEffectList; - - std::string mNewItemName; - unsigned int mObjectType; - int mWeaponType; - - const ESM::Enchantment* getRecord(const ESM::Enchantment& newEnchantment) const; - - public: - Enchanting(); - void setEnchanter(const MWWorld::Ptr& enchanter); - void setSelfEnchanting(bool selfEnchanting); - void setOldItem(const MWWorld::Ptr& oldItem); - MWWorld::Ptr getOldItem() { return mOldItemPtr; } - MWWorld::Ptr getGem() { return mSoulGemPtr; } - void setNewItemName(const std::string& s); - void setEffect(const ESM::EffectList& effectList); - void setSoulGem(const MWWorld::Ptr& soulGem); - bool create(); //Return true if created, false if failed. - void nextCastStyle(); //Set enchant type to next possible type (for mOldItemPtr object) - int getCastStyle() const; - float getEnchantPoints(bool precise = true) const; - int getBaseCastCost() const; // To be saved in the enchantment's record - int getEffectiveCastCost() const; // Effective cost taking player Enchant skill into account, used for preview purposes in the UI - int getEnchantPrice() const; - int getMaxEnchantValue() const; - int getGemCharge() const; - int getEnchantChance() const; - int getEnchantItemsCount() const; - float getTypeMultiplier() const; - bool soulEmpty() const; //Return true if empty - bool itemEmpty() const; //Return true if empty - void payForEnchantment() const; + MWWorld::Ptr mOldItemPtr; + MWWorld::Ptr mSoulGemPtr; + MWWorld::Ptr mEnchanter; + + int mCastStyle; + + bool mSelfEnchanting; + + ESM::EffectList mEffectList; + + std::string mNewItemName; + unsigned int mObjectType; + int mWeaponType; + + const ESM::Enchantment* getRecord(const ESM::Enchantment& newEnchantment) const; + + public: + Enchanting(); + void setEnchanter(const MWWorld::Ptr& enchanter); + void setSelfEnchanting(bool selfEnchanting); + void setOldItem(const MWWorld::Ptr& oldItem); + MWWorld::Ptr getOldItem() { return mOldItemPtr; } + MWWorld::Ptr getGem() { return mSoulGemPtr; } + void setNewItemName(const std::string& s); + void setEffect(const ESM::EffectList& effectList); + void setSoulGem(const MWWorld::Ptr& soulGem); + bool create(); // Return true if created, false if failed. + void nextCastStyle(); // Set enchant type to next possible type (for mOldItemPtr object) + int getCastStyle() const; + float getEnchantPoints(bool precise = true) const; + int getBaseCastCost() const; // To be saved in the enchantment's record + int getEffectiveCastCost() + const; // Effective cost taking player Enchant skill into account, used for preview purposes in the UI + int getEnchantPrice() const; + int getMaxEnchantValue() const; + int getGemCharge() const; + int getEnchantChance() const; + int getEnchantItemsCount() const; + float getTypeMultiplier() const; + bool soulEmpty() const; // Return true if empty + bool itemEmpty() const; // Return true if empty + void payForEnchantment() const; }; } #endif diff --git a/apps/openmw/mwmechanics/inventory.hpp b/apps/openmw/mwmechanics/inventory.hpp index 517eb24820..6c7fe2d3a6 100644 --- a/apps/openmw/mwmechanics/inventory.hpp +++ b/apps/openmw/mwmechanics/inventory.hpp @@ -6,8 +6,8 @@ #include "../mwworld/esmstore.hpp" -#include #include +#include #include #include diff --git a/apps/openmw/mwmechanics/levelledlist.hpp b/apps/openmw/mwmechanics/levelledlist.hpp index 35ad048a27..9911c06820 100644 --- a/apps/openmw/mwmechanics/levelledlist.hpp +++ b/apps/openmw/mwmechanics/levelledlist.hpp @@ -2,25 +2,26 @@ #define OPENMW_MECHANICS_LEVELLEDLIST_H #include -#include #include +#include -#include "../mwworld/ptr.hpp" +#include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" #include "../mwworld/manualref.hpp" -#include "../mwworld/class.hpp" +#include "../mwworld/ptr.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" -#include "creaturestats.hpp" #include "actorutil.hpp" +#include "creaturestats.hpp" namespace MWMechanics { /// @return ID of resulting item, or empty if none - inline std::string_view getLevelledItem(const ESM::LevelledListBase* levItem, bool creature, Misc::Rng::Generator& prng) + inline std::string_view getLevelledItem( + const ESM::LevelledListBase* levItem, bool creature, Misc::Rng::Generator& prng) { const std::vector& items = levItem->mList; @@ -43,11 +44,10 @@ namespace MWMechanics if (creature) allLevels = levItem->mFlags & ESM::CreatureLevList::AllLevels; - std::pair highest = {-1, {}}; + std::pair highest = { -1, {} }; for (const auto& levelledItem : items) { - if (playerLevel >= levelledItem.mLevel - && (allLevels || levelledItem.mLevel == highestLevel)) + if (playerLevel >= levelledItem.mLevel && (allLevels || levelledItem.mLevel == highestLevel)) { candidates.push_back(levelledItem.mId); if (levelledItem.mLevel >= highest.first) @@ -61,14 +61,15 @@ namespace MWMechanics // Vanilla doesn't fail on nonexistent items in levelled lists if (!MWBase::Environment::get().getWorld()->getStore().find(item)) { - Log(Debug::Warning) << "Warning: ignoring nonexistent item '" << item << "' in levelled list '" << levItem->mId << "'"; + Log(Debug::Warning) << "Warning: ignoring nonexistent item '" << item << "' in levelled list '" + << levItem->mId << "'"; return {}; } // Is this another levelled item or a real item? - MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), item, 1); + MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), item, 1); if (ref.getPtr().getType() != ESM::ItemLevList::sRecordId - && ref.getPtr().getType() != ESM::CreatureLevList::sRecordId) + && ref.getPtr().getType() != ESM::CreatureLevList::sRecordId) { return item; } diff --git a/apps/openmw/mwmechanics/magiceffects.cpp b/apps/openmw/mwmechanics/magiceffects.cpp index d4b89c56d0..ceb17f03d3 100644 --- a/apps/openmw/mwmechanics/magiceffects.cpp +++ b/apps/openmw/mwmechanics/magiceffects.cpp @@ -17,35 +17,38 @@ namespace namespace MWMechanics { - EffectKey::EffectKey() : mId (0), mArg (-1) {} + EffectKey::EffectKey() + : mId(0) + , mArg(-1) + { + } - EffectKey::EffectKey (const ESM::ENAMstruct& effect) + EffectKey::EffectKey(const ESM::ENAMstruct& effect) { mId = effect.mEffectID; mArg = -1; - if (effect.mSkill!=-1) + if (effect.mSkill != -1) mArg = effect.mSkill; - if (effect.mAttribute!=-1) + if (effect.mAttribute != -1) { - if (mArg!=-1) - throw std::runtime_error ( - "magic effect can't have both a skill and an attribute argument"); + if (mArg != -1) + throw std::runtime_error("magic effect can't have both a skill and an attribute argument"); mArg = effect.mAttribute; } } - bool operator< (const EffectKey& left, const EffectKey& right) + bool operator<(const EffectKey& left, const EffectKey& right) { - if (left.mIdright.mId) + if (left.mId > right.mId) return false; - return left.mArgfirst); + Collection::const_iterator other = prev.mCollection.find(iter->first); - if (other==prev.end()) + if (other == prev.end()) { // adding - result.add (iter->first, iter->second); + result.add(iter->first, iter->second); } else { // changing - result.add (iter->first, iter->second - other->second); + result.add(iter->first, iter->second - other->second); } } // removing - for (Collection::const_iterator iter (prev.begin()); iter!=prev.end(); ++iter) + for (Collection::const_iterator iter(prev.begin()); iter != prev.end(); ++iter) { - Collection::const_iterator other = now.mCollection.find (iter->first); - if (other==now.end()) + Collection::const_iterator other = now.mCollection.find(iter->first); + if (other == now.end()) { - result.add (iter->first, EffectParam() - iter->second); + result.add(iter->first, EffectParam() - iter->second); } } return result; } - void MagicEffects::writeState(ESM::MagicEffects &state) const + void MagicEffects::writeState(ESM::MagicEffects& state) const { for (const auto& [key, params] : mCollection) { if (params.getBase() != 0 || params.getModifier() != 0.f) { // Don't worry about mArg, never used by magic effect script instructions - state.mEffects[key.mId] = {params.getBase(), params.getModifier()}; + state.mEffects[key.mId] = { params.getBase(), params.getModifier() }; } } } - void MagicEffects::readState(const ESM::MagicEffects &state) + void MagicEffects::readState(const ESM::MagicEffects& state) { for (const auto& [key, params] : state.mEffects) { diff --git a/apps/openmw/mwmechanics/magiceffects.hpp b/apps/openmw/mwmechanics/magiceffects.hpp index e8175f6a78..55cfe4dba4 100644 --- a/apps/openmw/mwmechanics/magiceffects.hpp +++ b/apps/openmw/mwmechanics/magiceffects.hpp @@ -21,12 +21,16 @@ namespace MWMechanics EffectKey(); - EffectKey (int id, int arg = -1) : mId (id), mArg (arg) {} + EffectKey(int id, int arg = -1) + : mId(id) + , mArg(arg) + { + } - EffectKey (const ESM::ENAMstruct& effect); + EffectKey(const ESM::ENAMstruct& effect); }; - bool operator< (const EffectKey& left, const EffectKey& right); + bool operator<(const EffectKey& left, const EffectKey& right); struct EffectParam { @@ -50,58 +54,59 @@ namespace MWMechanics EffectParam(); - EffectParam(float magnitude) : mModifier(magnitude), mBase(0) {} + EffectParam(float magnitude) + : mModifier(magnitude) + , mBase(0) + { + } - EffectParam& operator+= (const EffectParam& param); + EffectParam& operator+=(const EffectParam& param); - EffectParam& operator-= (const EffectParam& param); + EffectParam& operator-=(const EffectParam& param); }; - inline EffectParam operator+ (const EffectParam& left, const EffectParam& right) + inline EffectParam operator+(const EffectParam& left, const EffectParam& right) { - EffectParam param (left); + EffectParam param(left); return param += right; } - inline EffectParam operator- (const EffectParam& left, const EffectParam& right) + inline EffectParam operator-(const EffectParam& left, const EffectParam& right) { - EffectParam param (left); + EffectParam param(left); return param -= right; } /// \brief Effects currently affecting a NPC or creature class MagicEffects { - public: - - typedef std::map Collection; - - private: - - Collection mCollection; + public: + typedef std::map Collection; - public: + private: + Collection mCollection; - Collection::const_iterator begin() const { return mCollection.begin(); } + public: + Collection::const_iterator begin() const { return mCollection.begin(); } - Collection::const_iterator end() const { return mCollection.end(); } + Collection::const_iterator end() const { return mCollection.end(); } - void readState (const ESM::MagicEffects& state); - void writeState (ESM::MagicEffects& state) const; + void readState(const ESM::MagicEffects& state); + void writeState(ESM::MagicEffects& state) const; - void add (const EffectKey& key, const EffectParam& param); - void remove (const EffectKey& key); + void add(const EffectKey& key, const EffectParam& param); + void remove(const EffectKey& key); - void modifyBase (const EffectKey& key, int diff); + void modifyBase(const EffectKey& key, int diff); - /// Copy Modifier values from \a effects, but keep original mBase values. - void setModifiers(const MagicEffects& effects); + /// Copy Modifier values from \a effects, but keep original mBase values. + void setModifiers(const MagicEffects& effects); - EffectParam get (const EffectKey& key) const; - ///< This function can safely be used for keys that are not present. + EffectParam get(const EffectKey& key) const; + ///< This function can safely be used for keys that are not present. - static MagicEffects diff (const MagicEffects& prev, const MagicEffects& now); - ///< Return changes from \a prev to \a now. + static MagicEffects diff(const MagicEffects& prev, const MagicEffects& now); + ///< Return changes from \a prev to \a now. }; } diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 1d69faaa8e..81ae2917d6 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -4,52 +4,59 @@ #include +#include #include -#include #include #include -#include +#include #include +#include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" #include "../mwworld/inventorystore.hpp" -#include "../mwworld/class.hpp" #include "../mwworld/player.hpp" #include "../mwworld/ptr.hpp" +#include "../mwbase/dialoguemanager.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/statemanager.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" -#include "../mwbase/dialoguemanager.hpp" +#include "../mwbase/world.hpp" +#include "actor.hpp" +#include "actorutil.hpp" #include "aicombat.hpp" #include "aipursue.hpp" -#include "spellutil.hpp" #include "autocalcspell.hpp" -#include "npcstats.hpp" -#include "actorutil.hpp" #include "combat.hpp" -#include "actor.hpp" +#include "npcstats.hpp" +#include "spellutil.hpp" namespace { float getFightDispositionBias(float disposition) { - static const float fFightDispMult = MWBase::Environment::get().getWorld()->getStore().get().find( - "fFightDispMult")->mValue.getFloat(); - return ((50.f - disposition) * fFightDispMult); + static const float fFightDispMult = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fFightDispMult") + ->mValue.getFloat(); + return ((50.f - disposition) * fFightDispMult); } - void getPersuasionRatings(const MWMechanics::NpcStats& stats, float& rating1, float& rating2, float& rating3, bool player) + void getPersuasionRatings( + const MWMechanics::NpcStats& stats, float& rating1, float& rating2, float& rating3, bool player) { - const MWWorld::Store &gmst = - MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& gmst + = MWBase::Environment::get().getWorld()->getStore().get(); - float persTerm = stats.getAttribute(ESM::Attribute::Personality).getModified() / gmst.find("fPersonalityMod")->mValue.getFloat(); - float luckTerm = stats.getAttribute(ESM::Attribute::Luck).getModified() / gmst.find("fLuckMod")->mValue.getFloat(); + float persTerm = stats.getAttribute(ESM::Attribute::Personality).getModified() + / gmst.find("fPersonalityMod")->mValue.getFloat(); + float luckTerm + = stats.getAttribute(ESM::Attribute::Luck).getModified() / gmst.find("fLuckMod")->mValue.getFloat(); float repTerm = stats.getReputation() * gmst.find("fReputationMod")->mValue.getFloat(); float fatigueTerm = stats.getFatigueTerm(); float levelTerm = stats.getLevel() * gmst.find("fLevelMod")->mValue.getFloat(); @@ -63,8 +70,11 @@ namespace } else { - rating2 = (levelTerm + repTerm + luckTerm + persTerm + stats.getSkill(ESM::Skill::Speechcraft).getModified()) * fatigueTerm; - rating3 = (stats.getSkill(ESM::Skill::Mercantile).getModified() + repTerm + luckTerm + persTerm) * fatigueTerm; + rating2 + = (levelTerm + repTerm + luckTerm + persTerm + stats.getSkill(ESM::Skill::Speechcraft).getModified()) + * fatigueTerm; + rating3 + = (stats.getSkill(ESM::Skill::Mercantile).getModified() + repTerm + luckTerm + persTerm) * fatigueTerm; } } @@ -105,20 +115,20 @@ namespace MWMechanics { MWWorld::Ptr ptr = getPlayer(); - MWMechanics::CreatureStats& creatureStats = ptr.getClass().getCreatureStats (ptr); - MWMechanics::NpcStats& npcStats = ptr.getClass().getNpcStats (ptr); + MWMechanics::CreatureStats& creatureStats = ptr.getClass().getCreatureStats(ptr); + MWMechanics::NpcStats& npcStats = ptr.getClass().getNpcStats(ptr); npcStats.recalculateMagicka(); - const ESM::NPC *player = ptr.get()->mBase; + const ESM::NPC* player = ptr.get()->mBase; // reset creatureStats.setLevel(player->mNpdt.mLevel); creatureStats.getSpells().clear(true); creatureStats.getActiveSpells().clear(ptr); - for (int i=0; i<27; ++i) - npcStats.getSkill (i).setBase (player->mNpdt.mSkills[i]); + for (int i = 0; i < 27; ++i) + npcStats.getSkill(i).setBase(player->mNpdt.mSkills[i]); creatureStats.setAttribute(ESM::Attribute::Strength, player->mNpdt.mStrength); creatureStats.setAttribute(ESM::Attribute::Intelligence, player->mNpdt.mIntelligence); @@ -128,54 +138,50 @@ namespace MWMechanics creatureStats.setAttribute(ESM::Attribute::Endurance, player->mNpdt.mEndurance); creatureStats.setAttribute(ESM::Attribute::Personality, player->mNpdt.mPersonality); creatureStats.setAttribute(ESM::Attribute::Luck, player->mNpdt.mLuck); - const MWWorld::ESMStore &esmStore = - MWBase::Environment::get().getWorld()->getStore(); + const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); // race if (mRaceSelected) { - const ESM::Race *race = - esmStore.get().find(player->mRace); + const ESM::Race* race = esmStore.get().find(player->mRace); bool male = (player->mFlags & ESM::NPC::Female) == 0; - for (int i=0; i<8; ++i) + for (int i = 0; i < 8; ++i) { const ESM::Race::MaleFemale& attribute = race->mData.mAttributeValues[i]; creatureStats.setAttribute(i, male ? attribute.mMale : attribute.mFemale); } - for (int i=0; i<27; ++i) + for (int i = 0; i < 27; ++i) { int bonus = 0; - for (int i2=0; i2<7; ++i2) - if (race->mData.mBonus[i2].mSkill==i) + for (int i2 = 0; i2 < 7; ++i2) + if (race->mData.mBonus[i2].mSkill == i) { bonus = race->mData.mBonus[i2].mBonus; break; } - npcStats.getSkill (i).setBase (5 + bonus); + npcStats.getSkill(i).setBase(5 + bonus); } - for (const std::string &power : race->mPowers.mList) + for (const std::string& power : race->mPowers.mList) { creatureStats.getSpells().add(power); } } // birthsign - const std::string &signId = - MWBase::Environment::get().getWorld()->getPlayer().getBirthSign(); + const std::string& signId = MWBase::Environment::get().getWorld()->getPlayer().getBirthSign(); if (!signId.empty()) { - const ESM::BirthSign *sign = - esmStore.get().find(signId); + const ESM::BirthSign* sign = esmStore.get().find(signId); - for (const std::string &power : sign->mPowers.mList) + for (const std::string& power : sign->mPowers.mList) { creatureStats.getSpells().add(power); } @@ -184,49 +190,44 @@ namespace MWMechanics // class if (mClassSelected) { - const ESM::Class *class_ = - esmStore.get().find(player->mClass); + const ESM::Class* class_ = esmStore.get().find(player->mClass); - for (int i=0; i<2; ++i) + for (int i = 0; i < 2; ++i) { int attribute = class_->mData.mAttribute[i]; - if (attribute>=0 && attribute<8) + if (attribute >= 0 && attribute < 8) { - creatureStats.setAttribute(attribute, - creatureStats.getAttribute(attribute).getBase() + 10); + creatureStats.setAttribute(attribute, creatureStats.getAttribute(attribute).getBase() + 10); } } - for (int i=0; i<2; ++i) + for (int i = 0; i < 2; ++i) { - int bonus = i==0 ? 10 : 25; + int bonus = i == 0 ? 10 : 25; - for (int i2=0; i2<5; ++i2) + for (int i2 = 0; i2 < 5; ++i2) { int index = class_->mData.mSkills[i2][i]; - if (index>=0 && index<27) + if (index >= 0 && index < 27) { - npcStats.getSkill (index).setBase ( - npcStats.getSkill (index).getBase() + bonus); + npcStats.getSkill(index).setBase(npcStats.getSkill(index).getBase() + bonus); } } } - const MWWorld::Store &skills = - esmStore.get(); + const MWWorld::Store& skills = esmStore.get(); MWWorld::Store::iterator iter = skills.begin(); for (; iter != skills.end(); ++iter) { - if (iter->second.mData.mSpecialization==class_->mData.mSpecialization) + if (iter->second.mData.mSpecialization == class_->mData.mSpecialization) { int index = iter->first; - if (index>=0 && index<27) + if (index >= 0 && index < 27) { - npcStats.getSkill (index).setBase ( - npcStats.getSkill (index).getBase() + 5); + npcStats.getSkill(index).setBase(npcStats.getSkill(index).getBase() + 5); } } } @@ -238,46 +239,49 @@ namespace MWMechanics race = esmStore.get().find(player->mRace); int skills[ESM::Skill::Length]; - for (int i=0; i selectedSpells = autoCalcPlayerSpells(skills, attributes, race); - for (const std::string &spell : selectedSpells) + for (const std::string& spell : selectedSpells) creatureStats.getSpells().add(spell); // forced update and current value adjustments - mActors.updateActor (ptr, 0); + mActors.updateActor(ptr, 0); - for (int i=0; i<3; ++i) + for (int i = 0; i < 3; ++i) { - DynamicStat stat = creatureStats.getDynamic (i); - stat.setCurrent (stat.getModified()); - creatureStats.setDynamic (i, stat); + DynamicStat stat = creatureStats.getDynamic(i); + stat.setCurrent(stat.getModified()); + creatureStats.setDynamic(i, stat); } - // auto-equip again. we need this for when the race is changed to a beast race and shoes are no longer equippable + // auto-equip again. we need this for when the race is changed to a beast race and shoes are no longer + // equippable MWWorld::InventoryStore& invStore = ptr.getClass().getInventoryStore(ptr); - for (int i=0; igetWatchedActor()) + if (ptr == MWBase::Environment::get().getWindowManager()->getWatchedActor()) MWBase::Environment::get().getWindowManager()->watchActor(MWWorld::Ptr()); mActors.removeActor(ptr, keepActive); mObjects.removeObject(ptr); } - void MechanicsManager::updateCell(const MWWorld::Ptr &old, const MWWorld::Ptr &ptr) + void MechanicsManager::updateCell(const MWWorld::Ptr& old, const MWWorld::Ptr& ptr) { - if(old == MWBase::Environment::get().getWindowManager()->getWatchedActor()) + if (old == MWBase::Environment::get().getWindowManager()->getWatchedActor()) MWBase::Environment::get().getWindowManager()->watchActor(ptr); - if(ptr.getClass().isActor()) + if (ptr.getClass().isActor()) mActors.updateActor(old, ptr); else mObjects.updateObject(old, ptr); } - void MechanicsManager::drop(const MWWorld::CellStore *cellStore) + void MechanicsManager::drop(const MWWorld::CellStore* cellStore) { mActors.dropActors(cellStore, getPlayer()); mObjects.dropObjects(cellStore); @@ -318,7 +322,7 @@ namespace MWMechanics { // Note: we should do it here since game mechanics and world updates use these values MWWorld::Ptr ptr = getPlayer(); - MWBase::WindowManager *winMgr = MWBase::Environment::get().getWindowManager(); + MWBase::WindowManager* winMgr = MWBase::Environment::get().getWindowManager(); MWWorld::InventoryStore& inv = ptr.getClass().getInventoryStore(ptr); MWWorld::ContainerStoreIterator weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); @@ -356,7 +360,7 @@ namespace MWMechanics mObjects.update(duration, paused); } - void MechanicsManager::processChangedSettings(const Settings::CategorySettingVector &changed) + void MechanicsManager::processChangedSettings(const Settings::CategorySettingVector& changed) { for (Settings::CategorySettingVector::const_iterator it = changed.begin(); it != changed.end(); ++it) { @@ -427,12 +431,11 @@ namespace MWMechanics return mActors.getHoursToRest(getPlayer()); } - void MechanicsManager::setPlayerName (const std::string& name) + void MechanicsManager::setPlayerName(const std::string& name) { - MWBase::World *world = MWBase::Environment::get().getWorld(); + MWBase::World* world = MWBase::Environment::get().getWorld(); - ESM::NPC player = - *world->getPlayerPtr().get()->mBase; + ESM::NPC player = *world->getPlayerPtr().get()->mBase; player.mName = name; world->createRecord(player); @@ -440,12 +443,12 @@ namespace MWMechanics mUpdatePlayer = true; } - void MechanicsManager::setPlayerRace (const std::string& race, bool male, const std::string &head, const std::string &hair) + void MechanicsManager::setPlayerRace( + const std::string& race, bool male, const std::string& head, const std::string& hair) { - MWBase::World *world = MWBase::Environment::get().getWorld(); + MWBase::World* world = MWBase::Environment::get().getWorld(); - ESM::NPC player = - *world->getPlayerPtr().get()->mBase; + ESM::NPC player = *world->getPlayerPtr().get()->mBase; player.mRace = race; player.mHead = head; @@ -459,19 +462,18 @@ namespace MWMechanics mUpdatePlayer = true; } - void MechanicsManager::setPlayerBirthsign (const std::string& id) + void MechanicsManager::setPlayerBirthsign(const std::string& id) { MWBase::Environment::get().getWorld()->getPlayer().setBirthSign(id); buildPlayer(); mUpdatePlayer = true; } - void MechanicsManager::setPlayerClass (const std::string& id) + void MechanicsManager::setPlayerClass(const std::string& id) { - MWBase::World *world = MWBase::Environment::get().getWorld(); + MWBase::World* world = MWBase::Environment::get().getWorld(); - ESM::NPC player = - *world->getPlayerPtr().get()->mBase; + ESM::NPC player = *world->getPlayerPtr().get()->mBase; player.mClass = id; world->createRecord(player); @@ -481,14 +483,13 @@ namespace MWMechanics mUpdatePlayer = true; } - void MechanicsManager::setPlayerClass (const ESM::Class &cls) + void MechanicsManager::setPlayerClass(const ESM::Class& cls) { - MWBase::World *world = MWBase::Environment::get().getWorld(); + MWBase::World* world = MWBase::Environment::get().getWorld(); - const ESM::Class *ptr = world->createRecord(cls); + const ESM::Class* ptr = world->createRecord(cls); - ESM::NPC player = - *world->getPlayerPtr().get()->mBase; + ESM::NPC player = *world->getPlayerPtr().get()->mBase; player.mClass = ptr->mId; world->createRecord(player); @@ -506,16 +507,18 @@ namespace MWMechanics MWWorld::LiveCellRef* npc = ptr.get(); MWWorld::Ptr playerPtr = getPlayer(); MWWorld::LiveCellRef* player = playerPtr.get(); - const MWMechanics::NpcStats &playerStats = playerPtr.getClass().getNpcStats(playerPtr); + const MWMechanics::NpcStats& playerStats = playerPtr.getClass().getNpcStats(playerPtr); - const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& gmst + = MWBase::Environment::get().getWorld()->getStore().get(); static const float fDispRaceMod = gmst.find("fDispRaceMod")->mValue.getFloat(); if (Misc::StringUtils::ciEqual(npc->mBase->mRace, player->mBase->mRace)) x += fDispRaceMod; static const float fDispPersonalityMult = gmst.find("fDispPersonalityMult")->mValue.getFloat(); static const float fDispPersonalityBase = gmst.find("fDispPersonalityBase")->mValue.getFloat(); - x += fDispPersonalityMult * (playerStats.getAttribute(ESM::Attribute::Personality).getModified() - fDispPersonalityBase); + x += fDispPersonalityMult + * (playerStats.getAttribute(ESM::Attribute::Personality).getModified() - fDispPersonalityBase); float reaction = 0; int rank = 0; @@ -526,7 +529,8 @@ namespace MWMechanics if (!playerStats.getExpelled(npcFaction)) { // faction reaction towards itself. yes, that exists - reaction = static_cast(MWBase::Environment::get().getDialogueManager()->getFactionReaction(npcFaction, npcFaction)); + reaction = static_cast( + MWBase::Environment::get().getDialogueManager()->getFactionReaction(npcFaction, npcFaction)); rank = playerStats.getFactionRanks().find(npcFaction)->second; } @@ -542,7 +546,8 @@ namespace MWMechanics if (playerStats.getExpelled(itFaction)) continue; - int itReaction = MWBase::Environment::get().getDialogueManager()->getFactionReaction(npcFaction, itFaction); + int itReaction + = MWBase::Environment::get().getDialogueManager()->getFactionReaction(npcFaction, itFaction); if (playerFactionIt == playerStats.getFactionRanks().begin() || itReaction < reaction) { reaction = static_cast(itReaction); @@ -559,9 +564,7 @@ namespace MWMechanics static const float fDispFactionRankMult = gmst.find("fDispFactionRankMult")->mValue.getFloat(); static const float fDispFactionRankBase = gmst.find("fDispFactionRankBase")->mValue.getFloat(); static const float fDispFactionMod = gmst.find("fDispFactionMod")->mValue.getFloat(); - x += (fDispFactionRankMult * rank - + fDispFactionRankBase) - * fDispFactionMod * reaction; + x += (fDispFactionRankMult * rank + fDispFactionRankBase) * fDispFactionMod * reaction; static const float fDispCrimeMod = gmst.find("fDispCrimeMod")->mValue.getFloat(); static const float fDispDiseaseMod = gmst.find("fDispDiseaseMod")->mValue.getFloat(); @@ -576,24 +579,24 @@ namespace MWMechanics x += ptr.getClass().getCreatureStats(ptr).getMagicEffects().get(ESM::MagicEffect::Charm).getMagnitude(); if (clamp) - return std::clamp(x, 0, 100);//, normally clamped to [0..100] when used + return std::clamp(x, 0, 100); //, normally clamped to [0..100] when used return static_cast(x); } - int MechanicsManager::getBarterOffer(const MWWorld::Ptr& ptr,int basePrice, bool buying) + int MechanicsManager::getBarterOffer(const MWWorld::Ptr& ptr, int basePrice, bool buying) { // Make sure zero base price items/services can't be bought/sold for 1 gold // and return the intended base price for creature merchants if (basePrice == 0 || ptr.getType() == ESM::Creature::sRecordId) return basePrice; - const MWMechanics::NpcStats &sellerStats = ptr.getClass().getNpcStats(ptr); + const MWMechanics::NpcStats& sellerStats = ptr.getClass().getNpcStats(ptr); MWWorld::Ptr playerPtr = getPlayer(); - const MWMechanics::NpcStats &playerStats = playerPtr.getClass().getNpcStats(playerPtr); + const MWMechanics::NpcStats& playerStats = playerPtr.getClass().getNpcStats(playerPtr); - // I suppose the temporary disposition change (second param to getDerivedDisposition()) _has_ to be considered here, - // otherwise one would get different prices when exiting and re-entering the dialogue window... + // I suppose the temporary disposition change (second param to getDerivedDisposition()) _has_ to be considered + // here, otherwise one would get different prices when exiting and re-entering the dialogue window... int clampedDisposition = getDerivedDisposition(ptr); float a = std::min(playerPtr.getClass().getSkill(playerPtr, ESM::Skill::Mercantile), 100.f); float b = std::min(0.1f * playerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10.f); @@ -609,20 +612,21 @@ namespace MWMechanics return std::max(1, offerPrice); } - int MechanicsManager::countDeaths (const std::string& id) const + int MechanicsManager::countDeaths(const std::string& id) const { - return mActors.countDeaths (id); + return mActors.countDeaths(id); } - void MechanicsManager::getPersuasionDispositionChange (const MWWorld::Ptr& npc, PersuasionType type, bool& success, int& tempChange, int& permChange) + void MechanicsManager::getPersuasionDispositionChange( + const MWWorld::Ptr& npc, PersuasionType type, bool& success, int& tempChange, int& permChange) { - const MWWorld::Store &gmst = - MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& gmst + = MWBase::Environment::get().getWorld()->getStore().get(); MWMechanics::NpcStats& npcStats = npc.getClass().getNpcStats(npc); MWWorld::Ptr playerPtr = getPlayer(); - const MWMechanics::NpcStats &playerStats = playerPtr.getClass().getNpcStats(playerPtr); + const MWMechanics::NpcStats& playerStats = playerPtr.getClass().getNpcStats(playerPtr); float npcRating1, npcRating2, npcRating3; getPersuasionRatings(npcStats, npcRating1, npcRating2, npcRating3, false); @@ -637,9 +641,12 @@ namespace MWMechanics float target2 = d * (playerRating2 - npcRating2 + 50); float bribeMod; - if (type == PT_Bribe10) bribeMod = gmst.find("fBribe10Mod")->mValue.getFloat(); - else if (type == PT_Bribe100) bribeMod = gmst.find("fBribe100Mod")->mValue.getFloat(); - else bribeMod = gmst.find("fBribe1000Mod")->mValue.getFloat(); + if (type == PT_Bribe10) + bribeMod = gmst.find("fBribe10Mod")->mValue.getFloat(); + else if (type == PT_Bribe100) + bribeMod = gmst.find("fBribe100Mod")->mValue.getFloat(); + else + bribeMod = gmst.find("fBribe1000Mod")->mValue.getFloat(); float target3 = d * (playerRating3 - npcRating3 + 50) + bribeMod; @@ -665,7 +672,7 @@ namespace MWMechanics { target2 = std::max(iPerMinChance, target2); - success = (roll <= target2); + success = (roll <= target2); float r; if (roll != target2) @@ -679,10 +686,10 @@ namespace MWMechanics const int flee = npcStats.getAiSetting(MWMechanics::AiSetting::Flee).getBase(); const int fight = npcStats.getAiSetting(MWMechanics::AiSetting::Fight).getBase(); - npcStats.setAiSetting (MWMechanics::AiSetting::Flee, - std::clamp(flee + int(std::max(iPerMinChange, s)), 0, 100)); - npcStats.setAiSetting (MWMechanics::AiSetting::Fight, - std::clamp(fight + int(std::min(-iPerMinChange, -s)), 0, 100)); + npcStats.setAiSetting( + MWMechanics::AiSetting::Flee, std::clamp(flee + int(std::max(iPerMinChange, s)), 0, 100)); + npcStats.setAiSetting( + MWMechanics::AiSetting::Fight, std::clamp(fight + int(std::min(-iPerMinChange, -s)), 0, 100)); } float c = -std::abs(floor(r * fPerDieRollMult)); @@ -720,10 +727,10 @@ namespace MWMechanics float s = c * fPerDieRollMult * fPerTempMult; const int flee = npcStats.getAiSetting(AiSetting::Flee).getBase(); const int fight = npcStats.getAiSetting(AiSetting::Fight).getBase(); - npcStats.setAiSetting(AiSetting::Flee, - std::clamp(flee + std::min(-int(iPerMinChange), int(-s)), 0, 100)); - npcStats.setAiSetting(AiSetting::Fight, - std::clamp(fight + std::max(int(iPerMinChange), int(s)), 0, 100)); + npcStats.setAiSetting( + AiSetting::Flee, std::clamp(flee + std::min(-int(iPerMinChange), int(-s)), 0, 100)); + npcStats.setAiSetting( + AiSetting::Fight, std::clamp(fight + std::max(int(iPerMinChange), int(s)), 0, 100)); } x = floor(-c * fPerDieRollMult); @@ -741,7 +748,6 @@ namespace MWMechanics tempChange = type == PT_Intimidate ? int(x) : int(x * fPerTempMult); - int cappedDispositionChange = tempChange; if (currentDisposition + tempChange > 100) cappedDispositionChange = 100 - currentDisposition; @@ -754,33 +760,34 @@ namespace MWMechanics permChange = floor(cappedDispositionChange / fPerTempMult); if (type == PT_Intimidate) { - permChange = success ? -int(cappedDispositionChange/ fPerTempMult) : int(y); + permChange = success ? -int(cappedDispositionChange / fPerTempMult) : int(y); } } - void MechanicsManager::forceStateUpdate(const MWWorld::Ptr &ptr) + void MechanicsManager::forceStateUpdate(const MWWorld::Ptr& ptr) { - if(ptr.getClass().isActor()) + if (ptr.getClass().isActor()) mActors.forceStateUpdate(ptr); } - bool MechanicsManager::playAnimationGroup(const MWWorld::Ptr& ptr, std::string_view groupName, int mode, int number, bool persist) + bool MechanicsManager::playAnimationGroup( + const MWWorld::Ptr& ptr, std::string_view groupName, int mode, int number, bool persist) { - if(ptr.getClass().isActor()) + if (ptr.getClass().isActor()) return mActors.playAnimationGroup(ptr, groupName, mode, number, persist); else return mObjects.playAnimationGroup(ptr, groupName, mode, number, persist); } void MechanicsManager::skipAnimation(const MWWorld::Ptr& ptr) { - if(ptr.getClass().isActor()) + if (ptr.getClass().isActor()) mActors.skipAnimation(ptr); else mObjects.skipAnimation(ptr); } - bool MechanicsManager::checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string &groupName) + bool MechanicsManager::checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string& groupName) { - if(ptr.getClass().isActor()) + if (ptr.getClass().isActor()) return mActors.checkAnimationPlaying(ptr, groupName); else return false; @@ -788,7 +795,7 @@ namespace MWMechanics bool MechanicsManager::onOpen(const MWWorld::Ptr& ptr) { - if(ptr.getClass().isActor()) + if (ptr.getClass().isActor()) return true; else return mObjects.onOpen(ptr); @@ -796,7 +803,7 @@ namespace MWMechanics void MechanicsManager::onClose(const MWWorld::Ptr& ptr) { - if(!ptr.getClass().isActor()) + if (!ptr.getClass().isActor()) mObjects.onClose(ptr); } @@ -806,7 +813,7 @@ namespace MWMechanics mObjects.persistAnimationStates(); } - void MechanicsManager::updateMagicEffects(const MWWorld::Ptr &ptr) + void MechanicsManager::updateMagicEffects(const MWWorld::Ptr& ptr) { mActors.updateMagicEffects(ptr); } @@ -834,13 +841,15 @@ namespace MWMechanics { static std::set boundItemIDCache; - // If this is empty then we haven't executed the GMST cache logic yet; or there isn't any sMagicBound* GMST's for some reason + // If this is empty then we haven't executed the GMST cache logic yet; or there isn't any sMagicBound* GMST's + // for some reason if (boundItemIDCache.empty()) { // Build a list of known bound item ID's - const MWWorld::Store &gameSettings = MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& gameSettings + = MWBase::Environment::get().getWorld()->getStore().get(); - for (const ESM::GameSetting ¤tSetting : gameSettings) + for (const ESM::GameSetting& currentSetting : gameSettings) { // Don't bother checking this GMST if it's not a sMagicBound* one. if (!Misc::StringUtils::ciStartsWith(currentSetting.mId, "smagicbound")) @@ -864,7 +873,7 @@ namespace MWMechanics return false; } - bool MechanicsManager::isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::Ptr& target, MWWorld::Ptr& victim) + bool MechanicsManager::isAllowedToUse(const MWWorld::Ptr& ptr, const MWWorld::Ptr& target, MWWorld::Ptr& victim) { if (target.isEmpty()) return true; @@ -872,9 +881,8 @@ namespace MWMechanics const MWWorld::CellRef& cellref = target.getCellRef(); // there is no harm to use unlocked doors int lockLevel = cellref.getLockLevel(); - if (target.getClass().isDoor() && - (lockLevel <= 0 || lockLevel == ESM::UnbreakableLock) && - cellref.getTrap().empty()) + if (target.getClass().isDoor() && (lockLevel <= 0 || lockLevel == ESM::UnbreakableLock) + && cellref.getTrap().empty()) { return true; } @@ -908,7 +916,7 @@ namespace MWMechanics return !Misc::StringUtils::ciEqual(cellref.getRefId(), "stolen_goods"); } - bool MechanicsManager::sleepInBed(const MWWorld::Ptr &ptr, const MWWorld::Ptr &bed) + bool MechanicsManager::sleepInBed(const MWWorld::Ptr& ptr, const MWWorld::Ptr& bed) { if (ptr.getClass().getNpcStats(ptr).isWerewolf()) { @@ -916,7 +924,8 @@ namespace MWMechanics return true; } - if(MWBase::Environment::get().getWorld()->getPlayer().enemiesNearby()) { + if (MWBase::Environment::get().getWorld()->getPlayer().enemiesNearby()) + { MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage2}"); return true; } @@ -925,7 +934,7 @@ namespace MWMechanics if (isAllowedToUse(ptr, bed, victim)) return false; - if(commitCrime(ptr, victim, OT_SleepingInOwnedBed, bed.getCellRef().getFaction())) + if (commitCrime(ptr, victim, OT_SleepingInOwnedBed, bed.getCellRef().getFaction())) { MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage64}"); return true; @@ -934,22 +943,23 @@ namespace MWMechanics return false; } - void MechanicsManager::unlockAttempted(const MWWorld::Ptr &ptr, const MWWorld::Ptr &item) + void MechanicsManager::unlockAttempted(const MWWorld::Ptr& ptr, const MWWorld::Ptr& item) { MWWorld::Ptr victim; if (isOwned(ptr, item, victim)) { - // Note that attempting to unlock something that has ever been locked (even ESM::UnbreakableLock) is a crime even if it's already unlocked. - // Likewise, it's illegal to unlock something that has a trap but isn't otherwise locked. + // Note that attempting to unlock something that has ever been locked (even ESM::UnbreakableLock) is a crime + // even if it's already unlocked. Likewise, it's illegal to unlock something that has a trap but isn't + // otherwise locked. const auto& cellref = item.getCellRef(); - if(cellref.getLockLevel() || !cellref.getTrap().empty()) + if (cellref.getLockLevel() || !cellref.getTrap().empty()) commitCrime(ptr, victim, OT_Trespassing, item.getCellRef().getFaction()); } } - std::vector > MechanicsManager::getStolenItemOwners(const std::string& itemid) + std::vector> MechanicsManager::getStolenItemOwners(const std::string& itemid) { - std::vector > result; + std::vector> result; StolenItemsMap::const_iterator it = mStolenItems.find(Misc::StringUtils::lowerCase(itemid)); if (it == mStolenItems.end()) return result; @@ -962,7 +972,7 @@ namespace MWMechanics } } - bool MechanicsManager::isItemStolenFrom(const std::string &itemid, const MWWorld::Ptr& ptr) + bool MechanicsManager::isItemStolenFrom(const std::string& itemid, const MWWorld::Ptr& ptr) { StolenItemsMap::const_iterator it = mStolenItems.find(Misc::StringUtils::lowerCase(itemid)); if (it == mStolenItems.end()) @@ -977,14 +987,16 @@ namespace MWMechanics const std::string_view factionid = ptr.getClass().getPrimaryFaction(ptr); if (!factionid.empty()) { - OwnerMap::const_iterator factionOwnerFound = owners.find(std::make_pair(Misc::StringUtils::lowerCase(factionid), true)); + OwnerMap::const_iterator factionOwnerFound + = owners.find(std::make_pair(Misc::StringUtils::lowerCase(factionid), true)); return factionOwnerFound != owners.end(); } return false; } - void MechanicsManager::confiscateStolenItemToOwner(const MWWorld::Ptr &player, const MWWorld::Ptr &item, const MWWorld::Ptr& victim, int count) + void MechanicsManager::confiscateStolenItemToOwner( + const MWWorld::Ptr& player, const MWWorld::Ptr& item, const MWWorld::Ptr& victim, int count) { if (player != getPlayer()) return; @@ -1000,7 +1012,8 @@ namespace MWMechanics owner.second = false; const std::string_view victimFaction = victim.getClass().getPrimaryFaction(victim); - if (!victimFaction.empty() && Misc::StringUtils::ciEqual(item.getCellRef().getFaction(), victimFaction)) // Is the item faction-owned? + if (!victimFaction.empty() + && Misc::StringUtils::ciEqual(item.getCellRef().getFaction(), victimFaction)) // Is the item faction-owned? { owner.first = victimFaction; owner.second = true; @@ -1025,16 +1038,18 @@ namespace MWMechanics // move items from player to owner and report about theft victim.getClass().getContainerStore(victim).add(item, toRemove, victim); store.remove(item, toRemove, player); - commitCrime(player, victim, OT_Theft, item.getCellRef().getFaction(), item.getClass().getValue(item) * toRemove); + commitCrime( + player, victim, OT_Theft, item.getCellRef().getFaction(), item.getClass().getValue(item) * toRemove); } - void MechanicsManager::confiscateStolenItems(const MWWorld::Ptr &player, const MWWorld::Ptr &targetContainer) + void MechanicsManager::confiscateStolenItems(const MWWorld::Ptr& player, const MWWorld::Ptr& targetContainer) { MWWorld::ContainerStore& store = player.getClass().getContainerStore(player); MWWorld::ContainerStore& containerStore = targetContainer.getClass().getContainerStore(targetContainer); for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it) { - StolenItemsMap::iterator stolenIt = mStolenItems.find(Misc::StringUtils::lowerCase(it->getCellRef().getRefId())); + StolenItemsMap::iterator stolenIt + = mStolenItems.find(Misc::StringUtils::lowerCase(it->getCellRef().getRefId())); if (stolenIt == mStolenItems.end()) continue; OwnerMap& owners = stolenIt->second; @@ -1059,8 +1074,8 @@ namespace MWMechanics targetContainer.getCellRef().lock(50); } - void MechanicsManager::itemTaken(const MWWorld::Ptr &ptr, const MWWorld::Ptr &item, const MWWorld::Ptr& container, - int count, bool alarm) + void MechanicsManager::itemTaken( + const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, const MWWorld::Ptr& container, int count, bool alarm) { if (ptr != getPlayer()) return; @@ -1109,15 +1124,17 @@ namespace MWMechanics if (!Misc::StringUtils::ciEqual(item.getCellRef().getRefId(), MWWorld::ContainerStore::sGoldId)) { - if (victim.isEmpty() || (victim.getClass().isActor() && victim.getRefData().getCount() > 0 && !victim.getClass().getCreatureStats(victim).isDead())) + if (victim.isEmpty() + || (victim.getClass().isActor() && victim.getRefData().getCount() > 0 + && !victim.getClass().getCreatureStats(victim).isDead())) mStolenItems[Misc::StringUtils::lowerCase(item.getCellRef().getRefId())][owner] += count; } if (alarm) commitCrime(ptr, victim, OT_Theft, ownerCellRef->getFaction(), item.getClass().getValue(item) * count); } - - bool MechanicsManager::commitCrime(const MWWorld::Ptr &player, const MWWorld::Ptr &victim, OffenseType type, const std::string& factionId, int arg, bool victimAware) + bool MechanicsManager::commitCrime(const MWWorld::Ptr& player, const MWWorld::Ptr& victim, OffenseType type, + const std::string& factionId, int arg, bool victimAware) { // NOTE: victim may be empty @@ -1128,14 +1145,14 @@ namespace MWMechanics // Find all the actors within the alarm radius std::vector neighbors; - osg::Vec3f from (player.getRefData().getPosition().asVec3()); + osg::Vec3f from(player.getRefData().getPosition().asVec3()); const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); float radius = esmStore.get().find("fAlarmRadius")->mValue.getFloat(); mActors.getObjectsInRange(from, radius, neighbors); // victim should be considered even beyond alarm radius - if (!victim.isEmpty() && (from - victim.getRefData().getPosition().asVec3()).length2() > radius*radius) + if (!victim.isEmpty() && (from - victim.getRefData().getPosition().asVec3()).length2() > radius * radius) neighbors.push_back(victim); // get the player's followers / allies (works recursively) that will not report crimes @@ -1144,16 +1161,17 @@ namespace MWMechanics // Did anyone see it? bool crimeSeen = false; - for (const MWWorld::Ptr &neighbor : neighbors) + for (const MWWorld::Ptr& neighbor : neighbors) { if (!canReportCrime(neighbor, victim, playerFollowers)) continue; if ((neighbor == victim && victimAware) - // Murder crime can be reported even if no one saw it (hearing is enough, I guess). - // TODO: Add mod support for stealth executions! - || (type == OT_Murder && neighbor != victim) - || (MWBase::Environment::get().getWorld()->getLOS(player, neighbor) && awarenessCheck(player, neighbor))) + // Murder crime can be reported even if no one saw it (hearing is enough, I guess). + // TODO: Add mod support for stealth executions! + || (type == OT_Murder && neighbor != victim) + || (MWBase::Environment::get().getWorld()->getLOS(player, neighbor) + && awarenessCheck(player, neighbor))) { // NPC will complain about theft even if he will do nothing about it if (type == OT_Theft || type == OT_Pickpocket) @@ -1173,15 +1191,16 @@ namespace MWMechanics reported = reportCrime(player, victim, type, std::string(), arg); if (!reported) - startCombat(victim, player); // TODO: combat should be started with an "unaware" flag, which makes the victim flee? + startCombat(victim, + player); // TODO: combat should be started with an "unaware" flag, which makes the victim flee? } return crimeSeen; } - bool MechanicsManager::canReportCrime(const MWWorld::Ptr &actor, const MWWorld::Ptr &victim, std::set &playerFollowers) + bool MechanicsManager::canReportCrime( + const MWWorld::Ptr& actor, const MWWorld::Ptr& victim, std::set& playerFollowers) { - if (actor == getPlayer() - || !actor.getClass().isNpc() || actor.getClass().getCreatureStats(actor).isDead()) + if (actor == getPlayer() || !actor.getClass().isNpc() || actor.getClass().getCreatureStats(actor).isDead()) return false; if (actor.getClass().getCreatureStats(actor).getAiSequence().isInCombat(victim)) @@ -1201,9 +1220,11 @@ namespace MWMechanics return true; } - bool MechanicsManager::reportCrime(const MWWorld::Ptr &player, const MWWorld::Ptr &victim, OffenseType type, const std::string& factionId, int arg) + bool MechanicsManager::reportCrime( + const MWWorld::Ptr& player, const MWWorld::Ptr& victim, OffenseType type, const std::string& factionId, int arg) { - const MWWorld::Store& store = MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& store + = MWBase::Environment::get().getWorld()->getStore().get(); if (type == OT_Murder && !victim.isEmpty()) victim.getClass().getCreatureStats(victim).notifyMurder(); @@ -1243,13 +1264,13 @@ namespace MWMechanics const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); - osg::Vec3f from (player.getRefData().getPosition().asVec3()); + osg::Vec3f from(player.getRefData().getPosition().asVec3()); float radius = esmStore.get().find("fAlarmRadius")->mValue.getFloat(); mActors.getObjectsInRange(from, radius, neighbors); // victim should be considered even beyond alarm radius - if (!victim.isEmpty() && (from - victim.getRefData().getPosition().asVec3()).length2() > radius*radius) + if (!victim.isEmpty() && (from - victim.getRefData().getPosition().asVec3()).length2() > radius * radius) neighbors.push_back(victim); int id = MWBase::Environment::get().getWorld()->getPlayer().getNewCrimeId(); @@ -1262,7 +1283,8 @@ namespace MWMechanics else if (type == OT_Pickpocket) { fight = esmStore.get().find("iFightPickpocket")->mValue.getInteger(); - fightVictim = esmStore.get().find("iFightPickpocket")->mValue.getInteger() * 4; // *4 according to research wiki + fightVictim = esmStore.get().find("iFightPickpocket")->mValue.getInteger() + * 4; // *4 according to research wiki } else if (type == OT_Assault) { @@ -1280,7 +1302,7 @@ namespace MWMechanics getActorsSidingWith(player, playerFollowers); // Tell everyone (including the original reporter) in alarm range - for (const MWWorld::Ptr &actor : neighbors) + for (const MWWorld::Ptr& actor : neighbors) { if (!canReportCrime(actor, victim, playerFollowers)) continue; @@ -1295,7 +1317,7 @@ namespace MWMechanics } } - for (const MWWorld::Ptr &actor : neighbors) + for (const MWWorld::Ptr& actor : neighbors) { if (!canReportCrime(actor, victim, playerFollowers)) continue; @@ -1318,7 +1340,8 @@ namespace MWMechanics { float dispTerm = (actor == victim) ? dispVictim : disp; - float alarmTerm = 0.01f * actor.getClass().getCreatureStats(actor).getAiSetting(AiSetting::Alarm).getBase(); + float alarmTerm + = 0.01f * actor.getClass().getCreatureStats(actor).getAiSetting(AiSetting::Alarm).getBase(); if (type == OT_Pickpocket && alarmTerm <= 0) alarmTerm = 1.0; @@ -1330,7 +1353,8 @@ namespace MWMechanics fightTerm += getFightDistanceBias(actor, player); fightTerm *= alarmTerm; - const int observerFightRating = actor.getClass().getCreatureStats(actor).getAiSetting(AiSetting::Fight).getBase(); + const int observerFightRating + = actor.getClass().getCreatureStats(actor).getAiSetting(AiSetting::Fight).getBase(); if (observerFightRating + fightTerm > 100) fightTerm = static_cast(100 - observerFightRating); fightTerm = std::max(0.f, fightTerm); @@ -1358,8 +1382,7 @@ namespace MWMechanics if (reported) { - player.getClass().getNpcStats(player).setBounty(player.getClass().getNpcStats(player).getBounty() - + arg); + player.getClass().getNpcStats(player).setBounty(player.getClass().getNpcStats(player).getBounty() + arg); // If committing a crime against a faction member, expell from the faction if (!victim.isEmpty() && victim.getClass().isNpc()) @@ -1382,8 +1405,8 @@ namespace MWMechanics } if (type == OT_Assault && !victim.isEmpty() - && !victim.getClass().getCreatureStats(victim).getAiSequence().isInCombat(player) - && victim.getClass().isNpc()) + && !victim.getClass().getCreatureStats(victim).getAiSequence().isInCombat(player) + && victim.getClass().isNpc()) { // Attacker is in combat with us, but we are not in combat with the attacker yet. Time to fight back. // Note: accidental or collateral damage attacks are ignored. @@ -1399,7 +1422,7 @@ namespace MWMechanics return reported; } - bool MechanicsManager::actorAttacked(const MWWorld::Ptr &target, const MWWorld::Ptr &attacker) + bool MechanicsManager::actorAttacked(const MWWorld::Ptr& target, const MWWorld::Ptr& attacker) { const MWWorld::Ptr& player = getPlayer(); if (target == player || !attacker.getClass().isActor()) @@ -1439,9 +1462,11 @@ namespace MWMechanics // he will attack the player only if we will force him (e.g. via StartCombat console command) bool peaceful = false; std::string_view script = target.getClass().getScript(target); - if (!script.empty() && target.getRefData().getLocals().hasVar(script, "onpchitme") && attacker == player) + if (!script.empty() && target.getRefData().getLocals().hasVar(script, "onpchitme") + && attacker == player) { - const int fight = target.getClass().getCreatureStats(target).getAiSetting(AiSetting::Fight).getModified(); + const int fight + = target.getClass().getCreatureStats(target).getAiSetting(AiSetting::Fight).getModified(); peaceful = (fight == 0); } @@ -1451,9 +1476,9 @@ namespace MWMechanics // Force friendly actors into combat to prevent infighting between followers std::set followersTarget; getActorsSidingWith(target, followersTarget); - for(const auto& follower : followersTarget) + for (const auto& follower : followersTarget) { - if(follower != attacker && follower != player) + if (follower != attacker && follower != player) startCombat(follower, attacker); } } @@ -1463,15 +1488,15 @@ namespace MWMechanics return true; } - bool MechanicsManager::canCommitCrimeAgainst(const MWWorld::Ptr &target, const MWWorld::Ptr &attacker) + bool MechanicsManager::canCommitCrimeAgainst(const MWWorld::Ptr& target, const MWWorld::Ptr& attacker) { const MWMechanics::AiSequence& seq = target.getClass().getCreatureStats(target).getAiSequence(); return target.getClass().isNpc() && !attacker.isEmpty() && !seq.isInCombat(attacker) - && !isAggressive(target, attacker) && !seq.isEngagedWithActor() - && !target.getClass().getCreatureStats(target).getAiSequence().isInPursuit(); + && !isAggressive(target, attacker) && !seq.isEngagedWithActor() + && !target.getClass().getCreatureStats(target).getAiSequence().isInPursuit(); } - void MechanicsManager::actorKilled(const MWWorld::Ptr &victim, const MWWorld::Ptr &attacker) + void MechanicsManager::actorKilled(const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker) { if (attacker.isEmpty() || victim.isEmpty()) return; @@ -1483,7 +1508,7 @@ namespace MWMechanics return; // TODO: implement animal rights const MWMechanics::NpcStats& victimStats = victim.getClass().getNpcStats(victim); - const MWWorld::Ptr &player = getPlayer(); + const MWWorld::Ptr& player = getPlayer(); bool canCommit = attacker == player && canCommitCrimeAgainst(victim, attacker); // For now we report only about crimes of player and player's followers @@ -1504,12 +1529,13 @@ namespace MWMechanics commitCrime(player, victim, MWBase::MechanicsManager::OT_Murder); } - bool MechanicsManager::awarenessCheck(const MWWorld::Ptr &ptr, const MWWorld::Ptr &observer) + bool MechanicsManager::awarenessCheck(const MWWorld::Ptr& ptr, const MWWorld::Ptr& observer) { if (observer.getClass().getCreatureStats(observer).isDead() || !observer.getRefData().isEnabled()) return false; - const MWWorld::Store& store = MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& store + = MWBase::Environment::get().getWorld()->getStore().get(); CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); @@ -1535,8 +1561,8 @@ namespace MWMechanics static float fSneakDistBase = store.find("fSneakDistanceBase")->mValue.getFloat(); static float fSneakDistMult = store.find("fSneakDistanceMultiplier")->mValue.getFloat(); - osg::Vec3f pos1 (ptr.getRefData().getPosition().asVec3()); - osg::Vec3f pos2 (observer.getRefData().getPosition().asVec3()); + osg::Vec3f pos1(ptr.getRefData().getPosition().asVec3()); + osg::Vec3f pos2(observer.getRefData().getPosition().asVec3()); float distTerm = fSneakDistBase + fSneakDistMult * (pos1 - pos2).length(); float chameleon = stats.getMagicEffects().get(ESM::MagicEffect::Chameleon).getMagnitude(); @@ -1560,7 +1586,7 @@ namespace MWMechanics osg::Vec3f vec = pos1 - pos2; if (observer.getRefData().getBaseNode()) { - osg::Vec3f observerDir = (observer.getRefData().getBaseNode()->getAttitude() * osg::Vec3f(0,1,0)); + osg::Vec3f observerDir = (observer.getRefData().getBaseNode()->getAttitude() * osg::Vec3f(0, 1, 0)); float angleRadians = std::acos(observerDir * vec / (observerDir.length() * vec.length())); if (angleRadians > osg::DegreesToRadians(90.f)) @@ -1574,7 +1600,7 @@ namespace MWMechanics return (Misc::Rng::roll0to99(prng) >= target); } - void MechanicsManager::startCombat(const MWWorld::Ptr &ptr, const MWWorld::Ptr &target) + void MechanicsManager::startCombat(const MWWorld::Ptr& ptr, const MWWorld::Ptr& target) { CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); @@ -1597,17 +1623,27 @@ namespace MWMechanics // if guard starts combat with player, guards pursuing player should do the same if (ptr.getClass().isClass(ptr, "Guard")) { - stats.setHitAttemptActorId(target.getClass().getCreatureStats(target).getActorId()); // Stops guard from ending combat if player is unreachable + stats.setHitAttemptActorId( + target.getClass() + .getCreatureStats(target) + .getActorId()); // Stops guard from ending combat if player is unreachable for (const Actor& actor : mActors) { if (actor.getPtr().getClass().isClass(actor.getPtr(), "Guard")) { - MWMechanics::AiSequence& aiSeq = actor.getPtr().getClass().getCreatureStats(actor.getPtr()).getAiSequence(); + MWMechanics::AiSequence& aiSeq + = actor.getPtr().getClass().getCreatureStats(actor.getPtr()).getAiSequence(); if (aiSeq.getTypeId() == MWMechanics::AiPackageTypeId::Pursue) { aiSeq.stopPursuit(); aiSeq.stack(MWMechanics::AiCombat(target), ptr); - actor.getPtr().getClass().getCreatureStats(actor.getPtr()).setHitAttemptActorId(target.getClass().getCreatureStats(target).getActorId()); // Stops guard from ending combat if player is unreachable + actor.getPtr() + .getClass() + .getCreatureStats(actor.getPtr()) + .setHitAttemptActorId( + target.getClass() + .getCreatureStats(target) + .getActorId()); // Stops guard from ending combat if player is unreachable } } } @@ -1623,18 +1659,20 @@ namespace MWMechanics mActors.stopCombat(actor); } - void MechanicsManager::getObjectsInRange(const osg::Vec3f &position, float radius, std::vector &objects) + void MechanicsManager::getObjectsInRange( + const osg::Vec3f& position, float radius, std::vector& objects) { mActors.getObjectsInRange(position, radius, objects); mObjects.getObjectsInRange(position, radius, objects); } - void MechanicsManager::getActorsInRange(const osg::Vec3f &position, float radius, std::vector &objects) + void MechanicsManager::getActorsInRange( + const osg::Vec3f& position, float radius, std::vector& objects) { mActors.getObjectsInRange(position, radius, objects); } - bool MechanicsManager::isAnyActorInRange(const osg::Vec3f &position, float radius) + bool MechanicsManager::isAnyActorInRange(const osg::Vec3f& position, float radius) { return mActors.isAnyObjectInRange(position, radius); } @@ -1659,29 +1697,33 @@ namespace MWMechanics return mActors.getActorsFollowingByIndex(actor); } - std::vector MechanicsManager::getActorsFighting(const MWWorld::Ptr& actor) { + std::vector MechanicsManager::getActorsFighting(const MWWorld::Ptr& actor) + { return mActors.getActorsFighting(actor); } - std::vector MechanicsManager::getEnemiesNearby(const MWWorld::Ptr& actor) { + std::vector MechanicsManager::getEnemiesNearby(const MWWorld::Ptr& actor) + { return mActors.getEnemiesNearby(actor); } - void MechanicsManager::getActorsFollowing(const MWWorld::Ptr& actor, std::set& out) { + void MechanicsManager::getActorsFollowing(const MWWorld::Ptr& actor, std::set& out) + { mActors.getActorsFollowing(actor, out); } - void MechanicsManager::getActorsSidingWith(const MWWorld::Ptr& actor, std::set& out) { + void MechanicsManager::getActorsSidingWith(const MWWorld::Ptr& actor, std::set& out) + { mActors.getActorsSidingWith(actor, out); } int MechanicsManager::countSavedGameRecords() const { return 1 // Death counter - +1; // Stolen items + + 1; // Stolen items } - void MechanicsManager::write(ESM::ESMWriter &writer, Loading::Listener &listener) const + void MechanicsManager::write(ESM::ESMWriter& writer, Loading::Listener& listener) const { mActors.write(writer, listener); @@ -1692,7 +1734,7 @@ namespace MWMechanics writer.endRecord(ESM::REC_STLN); } - void MechanicsManager::readRecord(ESM::ESMReader &reader, uint32_t type) + void MechanicsManager::readRecord(ESM::ESMReader& reader, uint32_t type) { if (type == ESM::REC_STLN) { @@ -1712,12 +1754,24 @@ namespace MWMechanics mRaceSelected = false; } - bool MechanicsManager::isAggressive(const MWWorld::Ptr &ptr, const MWWorld::Ptr &target) + bool MechanicsManager::isAggressive(const MWWorld::Ptr& ptr, const MWWorld::Ptr& target) { // Don't become aggressive if a calm effect is active, since it would cause combat to cycle on/off as // combat is activated here and then canceled by the calm effect - if ((ptr.getClass().isNpc() && ptr.getClass().getCreatureStats(ptr).getMagicEffects().get(ESM::MagicEffect::CalmHumanoid).getMagnitude() > 0) - || (!ptr.getClass().isNpc() && ptr.getClass().getCreatureStats(ptr).getMagicEffects().get(ESM::MagicEffect::CalmCreature).getMagnitude() > 0)) + if ((ptr.getClass().isNpc() + && ptr.getClass() + .getCreatureStats(ptr) + .getMagicEffects() + .get(ESM::MagicEffect::CalmHumanoid) + .getMagnitude() + > 0) + || (!ptr.getClass().isNpc() + && ptr.getClass() + .getCreatureStats(ptr) + .getMagicEffects() + .get(ESM::MagicEffect::CalmCreature) + .getMagnitude() + > 0)) return false; int disposition = 50; @@ -1725,15 +1779,17 @@ namespace MWMechanics disposition = getDerivedDisposition(ptr); int fight = ptr.getClass().getCreatureStats(ptr).getAiSetting(AiSetting::Fight).getModified() - + static_cast(getFightDistanceBias(ptr, target) + getFightDispositionBias(static_cast(disposition))); + + static_cast( + getFightDistanceBias(ptr, target) + getFightDispositionBias(static_cast(disposition))); if (ptr.getClass().isNpc() && target.getClass().isNpc()) { - if (target.getClass().getNpcStats(target).isWerewolf() || - (target == getPlayer() && - MWBase::Environment::get().getWorld()->getGlobalInt("pcknownwerewolf"))) + if (target.getClass().getNpcStats(target).isWerewolf() + || (target == getPlayer() && MWBase::Environment::get().getWorld()->getGlobalInt("pcknownwerewolf"))) { - const ESM::GameSetting * iWerewolfFightMod = MWBase::Environment::get().getWorld()->getStore().get().find("iWerewolfFightMod"); + const ESM::GameSetting* iWerewolfFightMod + = MWBase::Environment::get().getWorld()->getStore().get().find( + "iWerewolfFightMod"); fight += iWerewolfFightMod->mValue.getInteger(); } } @@ -1741,7 +1797,7 @@ namespace MWMechanics return (fight >= 100); } - void MechanicsManager::resurrect(const MWWorld::Ptr &ptr) + void MechanicsManager::resurrect(const MWWorld::Ptr& ptr) { CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); if (stats.isDead()) @@ -1751,17 +1807,17 @@ namespace MWMechanics } } - bool MechanicsManager::isCastingSpell(const MWWorld::Ptr &ptr) const + bool MechanicsManager::isCastingSpell(const MWWorld::Ptr& ptr) const { return mActors.isCastingSpell(ptr); } - bool MechanicsManager::isReadyToBlock(const MWWorld::Ptr &ptr) const + bool MechanicsManager::isReadyToBlock(const MWWorld::Ptr& ptr) const { return mActors.isReadyToBlock(ptr); } - bool MechanicsManager::isAttackingOrSpell(const MWWorld::Ptr &ptr) const + bool MechanicsManager::isAttackingOrSpell(const MWWorld::Ptr& ptr) const { return mActors.isAttackingOrSpell(ptr); } @@ -1782,9 +1838,9 @@ namespace MWMechanics npcStats.setWerewolf(werewolf); - MWWorld::InventoryStore &inv = actor.getClass().getInventoryStore(actor); + MWWorld::InventoryStore& inv = actor.getClass().getInventoryStore(actor); - if(werewolf) + if (werewolf) { inv.unequipAll(actor); inv.equip(MWWorld::InventoryStore::Slot_Robe, inv.ContainerStore::add("werewolfrobe", 1, actor), actor); @@ -1795,7 +1851,7 @@ namespace MWMechanics inv.ContainerStore::remove("werewolfrobe", 1, actor); } - if(actor == player->getPlayer()) + if (actor == player->getPlayer()) { MWBase::Environment::get().getWorld()->reattachPlayerCamera(); @@ -1803,10 +1859,12 @@ namespace MWMechanics MWBase::WindowManager* windowManager = MWBase::Environment::get().getWindowManager(); // Transforming removes all temporary effects - actor.getClass().getCreatureStats(actor).getActiveSpells().purge([] (const auto& params) - { - return params.getType() == ESM::ActiveSpells::Type_Consumable || params.getType() == ESM::ActiveSpells::Type_Temporary; - }, actor); + actor.getClass().getCreatureStats(actor).getActiveSpells().purge( + [](const auto& params) { + return params.getType() == ESM::ActiveSpells::Type_Consumable + || params.getType() == ESM::ActiveSpells::Type_Temporary; + }, + actor); mActors.updateActor(actor, 0.f); if (werewolf) @@ -1827,8 +1885,10 @@ namespace MWMechanics // Witnesses of the player's transformation will make them a globally known werewolf std::vector neighbors; - const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); - getActorsInRange(actor.getRefData().getPosition().asVec3(), gmst.find("fAlarmRadius")->mValue.getFloat(), neighbors); + const MWWorld::Store& gmst + = MWBase::Environment::get().getWorld()->getStore().get(); + getActorsInRange( + actor.getRefData().getPosition().asVec3(), gmst.find("fAlarmRadius")->mValue.getFloat(), neighbors); bool detected = false, reported = false; for (const MWWorld::Ptr& neighbor : neighbors) @@ -1839,7 +1899,11 @@ namespace MWMechanics if (MWBase::Environment::get().getWorld()->getLOS(neighbor, actor) && awarenessCheck(actor, neighbor)) { detected = true; - if (neighbor.getClass().getCreatureStats(neighbor).getAiSetting(MWMechanics::AiSetting::Alarm).getModified() > 0) + if (neighbor.getClass() + .getCreatureStats(neighbor) + .getAiSetting(MWMechanics::AiSetting::Alarm) + .getModified() + > 0) { reported = true; break; @@ -1854,22 +1918,22 @@ namespace MWMechanics if (reported) { - npcStats.setBounty(npcStats.getBounty()+ - gmst.find("iWereWolfBounty")->mValue.getInteger()); + npcStats.setBounty(npcStats.getBounty() + gmst.find("iWereWolfBounty")->mValue.getInteger()); } } } } - void MechanicsManager::applyWerewolfAcrobatics(const MWWorld::Ptr &actor) + void MechanicsManager::applyWerewolfAcrobatics(const MWWorld::Ptr& actor) { - const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); - MWMechanics::NpcStats &stats = actor.getClass().getNpcStats(actor); + const MWWorld::Store& gmst + = MWBase::Environment::get().getWorld()->getStore().get(); + MWMechanics::NpcStats& stats = actor.getClass().getNpcStats(actor); auto& skill = stats.getSkill(ESM::Skill::Acrobatics); skill.setModifier(gmst.find("fWerewolfAcrobatics")->mValue.getFloat() - skill.getModified()); } - void MechanicsManager::cleanupSummonedCreature(const MWWorld::Ptr &caster, int creatureActorId) + void MechanicsManager::cleanupSummonedCreature(const MWWorld::Ptr& caster, int creatureActorId) { mActors.cleanupSummonedCreature(caster.getClass().getCreatureStats(caster), creatureActorId); } @@ -1880,22 +1944,22 @@ namespace MWMechanics stats.setAttribute(frameNumber, "Mechanics Objects", mObjects.size()); } - int MechanicsManager::getGreetingTimer(const MWWorld::Ptr &ptr) const + int MechanicsManager::getGreetingTimer(const MWWorld::Ptr& ptr) const { return mActors.getGreetingTimer(ptr); } - float MechanicsManager::getAngleToPlayer(const MWWorld::Ptr &ptr) const + float MechanicsManager::getAngleToPlayer(const MWWorld::Ptr& ptr) const { return mActors.getAngleToPlayer(ptr); } - GreetingState MechanicsManager::getGreetingState(const MWWorld::Ptr &ptr) const + GreetingState MechanicsManager::getGreetingState(const MWWorld::Ptr& ptr) const { return mActors.getGreetingState(ptr); } - bool MechanicsManager::isTurningToPlayer(const MWWorld::Ptr &ptr) const + bool MechanicsManager::isTurningToPlayer(const MWWorld::Ptr& ptr) const { return mActors.isTurningToPlayer(ptr); } diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index 3dae0d9a1e..f821319476 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -7,9 +7,9 @@ #include "../mwworld/ptr.hpp" +#include "actors.hpp" #include "npcstats.hpp" #include "objects.hpp" -#include "actors.hpp" namespace MWWorld { @@ -20,223 +20,227 @@ namespace MWMechanics { class MechanicsManager : public MWBase::MechanicsManager { - bool mUpdatePlayer; - bool mClassSelected; - bool mRaceSelected; - bool mAI;///< is AI active? - - Objects mObjects; - Actors mActors; + bool mUpdatePlayer; + bool mClassSelected; + bool mRaceSelected; + bool mAI; ///< is AI active? - typedef std::pair Owner; // < Owner id, bool isFaction > - typedef std::map OwnerMap; // < Owner, number of stolen items with this id from this owner > - typedef std::map StolenItemsMap; - StolenItemsMap mStolenItems; + Objects mObjects; + Actors mActors; - public: + typedef std::pair Owner; // < Owner id, bool isFaction > + typedef std::map OwnerMap; // < Owner, number of stolen items with this id from this owner > + typedef std::map StolenItemsMap; + StolenItemsMap mStolenItems; - void buildPlayer(); - ///< build player according to stored class/race/birthsign information. Will - /// default to the values of the ESM::NPC object, if no explicit information is given. + public: + void buildPlayer(); + ///< build player according to stored class/race/birthsign information. Will + /// default to the values of the ESM::NPC object, if no explicit information is given. - MechanicsManager(); + MechanicsManager(); - void add (const MWWorld::Ptr& ptr) override; - ///< Register an object for management + void add(const MWWorld::Ptr& ptr) override; + ///< Register an object for management - void remove (const MWWorld::Ptr& ptr, bool keepActive) override; - ///< Deregister an object for management + void remove(const MWWorld::Ptr& ptr, bool keepActive) override; + ///< Deregister an object for management - void updateCell(const MWWorld::Ptr &old, const MWWorld::Ptr &ptr) override; - ///< Moves an object to a new cell + void updateCell(const MWWorld::Ptr& old, const MWWorld::Ptr& ptr) override; + ///< Moves an object to a new cell - void drop(const MWWorld::CellStore *cellStore) override; - ///< Deregister all objects in the given cell. + void drop(const MWWorld::CellStore* cellStore) override; + ///< Deregister all objects in the given cell. - void update(float duration, bool paused); - ///< Update objects - /// - /// \param paused In game type does not currently advance (this usually means some GUI - /// component is up). + void update(float duration, bool paused); + ///< Update objects + /// + /// \param paused In game type does not currently advance (this usually means some GUI + /// component is up). - void setPlayerName (const std::string& name) override; - ///< Set player name. + void setPlayerName(const std::string& name) override; + ///< Set player name. - void setPlayerRace (const std::string& id, bool male, const std::string &head, const std::string &hair) override; - ///< Set player race. + void setPlayerRace(const std::string& id, bool male, const std::string& head, const std::string& hair) override; + ///< Set player race. - void setPlayerBirthsign (const std::string& id) override; - ///< Set player birthsign. + void setPlayerBirthsign(const std::string& id) override; + ///< Set player birthsign. - void setPlayerClass (const std::string& id) override; - ///< Set player class to stock class. + void setPlayerClass(const std::string& id) override; + ///< Set player class to stock class. - void setPlayerClass (const ESM::Class& class_) override; - ///< Set player class to custom class. + void setPlayerClass(const ESM::Class& class_) override; + ///< Set player class to custom class. - void restoreDynamicStats(const MWWorld::Ptr& actor, double hours, bool sleep) override; + void restoreDynamicStats(const MWWorld::Ptr& actor, double hours, bool sleep) override; - void rest(double hours, bool sleep) override; - ///< If the player is sleeping or waiting, this should be called every hour. - /// @param sleep is the player sleeping or waiting? + void rest(double hours, bool sleep) override; + ///< If the player is sleeping or waiting, this should be called every hour. + /// @param sleep is the player sleeping or waiting? - int getHoursToRest() const override; - ///< Calculate how many hours the player needs to rest in order to be fully healed + int getHoursToRest() const override; + ///< Calculate how many hours the player needs to rest in order to be fully healed - int getBarterOffer(const MWWorld::Ptr& ptr,int basePrice, bool buying) override; - ///< This is used by every service to determine the price of objects given the trading skills of the player and NPC. + int getBarterOffer(const MWWorld::Ptr& ptr, int basePrice, bool buying) override; + ///< This is used by every service to determine the price of objects given the trading skills of the player and + ///< NPC. - int getDerivedDisposition(const MWWorld::Ptr& ptr, bool clamp = true) override; - ///< Calculate the diposition of an NPC toward the player. + int getDerivedDisposition(const MWWorld::Ptr& ptr, bool clamp = true) override; + ///< Calculate the diposition of an NPC toward the player. - int countDeaths (const std::string& id) const override; - ///< Return the number of deaths for actors with the given ID. + int countDeaths(const std::string& id) const override; + ///< Return the number of deaths for actors with the given ID. - void getPersuasionDispositionChange (const MWWorld::Ptr& npc, PersuasionType type, bool& success, int& tempChange, int& permChange) override; - ///< Perform a persuasion action on NPC + void getPersuasionDispositionChange( + const MWWorld::Ptr& npc, PersuasionType type, bool& success, int& tempChange, int& permChange) override; + ///< Perform a persuasion action on NPC - /// Check if \a observer is potentially aware of \a ptr. Does not do a line of sight check! - bool awarenessCheck (const MWWorld::Ptr& ptr, const MWWorld::Ptr& observer) override; + /// Check if \a observer is potentially aware of \a ptr. Does not do a line of sight check! + bool awarenessCheck(const MWWorld::Ptr& ptr, const MWWorld::Ptr& observer) override; - /// Makes \a ptr fight \a target. Also shouts a combat taunt. - void startCombat (const MWWorld::Ptr& ptr, const MWWorld::Ptr& target) override; + /// Makes \a ptr fight \a target. Also shouts a combat taunt. + void startCombat(const MWWorld::Ptr& ptr, const MWWorld::Ptr& target) override; - void stopCombat(const MWWorld::Ptr& ptr) override; + void stopCombat(const MWWorld::Ptr& ptr) override; - /** - * @note victim may be empty - * @param arg Depends on \a type, e.g. for Theft, the value of the item that was stolen. - * @param victimAware Is the victim already aware of the crime? - * If this parameter is false, it will be determined by a line-of-sight and awareness check. - * @return was the crime seen? - */ - bool commitCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, - OffenseType type, const std::string& factionId="", int arg=0, bool victimAware=false) override; - /// @return false if the attack was considered a "friendly hit" and forgiven - bool actorAttacked (const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker) override; + /** + * @note victim may be empty + * @param arg Depends on \a type, e.g. for Theft, the value of the item that was stolen. + * @param victimAware Is the victim already aware of the crime? + * If this parameter is false, it will be determined by a line-of-sight and awareness check. + * @return was the crime seen? + */ + bool commitCrime(const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, OffenseType type, + const std::string& factionId = "", int arg = 0, bool victimAware = false) override; + /// @return false if the attack was considered a "friendly hit" and forgiven + bool actorAttacked(const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker) override; - /// Notify that actor was killed, add a murder bounty if applicable - /// @note No-op for non-player attackers - void actorKilled (const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker) override; + /// Notify that actor was killed, add a murder bounty if applicable + /// @note No-op for non-player attackers + void actorKilled(const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker) override; - /// Utility to check if taking this item is illegal and calling commitCrime if so - /// @param container The container the item is in; may be empty for an item in the world - void itemTaken (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, const MWWorld::Ptr& container, - int count, bool alarm = true) override; - /// Utility to check if unlocking this object is illegal and calling commitCrime if so - void unlockAttempted (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item) override; - /// Attempt sleeping in a bed. If this is illegal, call commitCrime. - /// @return was it illegal, and someone saw you doing it? Also returns fail when enemies are nearby - bool sleepInBed (const MWWorld::Ptr& ptr, const MWWorld::Ptr& bed) override; + /// Utility to check if taking this item is illegal and calling commitCrime if so + /// @param container The container the item is in; may be empty for an item in the world + void itemTaken(const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, const MWWorld::Ptr& container, int count, + bool alarm = true) override; + /// Utility to check if unlocking this object is illegal and calling commitCrime if so + void unlockAttempted(const MWWorld::Ptr& ptr, const MWWorld::Ptr& item) override; + /// Attempt sleeping in a bed. If this is illegal, call commitCrime. + /// @return was it illegal, and someone saw you doing it? Also returns fail when enemies are nearby + bool sleepInBed(const MWWorld::Ptr& ptr, const MWWorld::Ptr& bed) override; - void forceStateUpdate(const MWWorld::Ptr &ptr) override; + void forceStateUpdate(const MWWorld::Ptr& ptr) override; - /// Attempt to play an animation group - /// @return Success or error - bool playAnimationGroup(const MWWorld::Ptr& ptr, std::string_view groupName, int mode, int number, bool persist=false) override; - void skipAnimation(const MWWorld::Ptr& ptr) override; - bool checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string &groupName) override; - void persistAnimationStates() override; + /// Attempt to play an animation group + /// @return Success or error + bool playAnimationGroup( + const MWWorld::Ptr& ptr, std::string_view groupName, int mode, int number, bool persist = false) override; + void skipAnimation(const MWWorld::Ptr& ptr) override; + bool checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string& groupName) override; + void persistAnimationStates() override; - /// Update magic effects for an actor. Usually done automatically once per frame, but if we're currently - /// paused we may want to do it manually (after equipping permanent enchantment) - void updateMagicEffects (const MWWorld::Ptr& ptr) override; + /// Update magic effects for an actor. Usually done automatically once per frame, but if we're currently + /// paused we may want to do it manually (after equipping permanent enchantment) + void updateMagicEffects(const MWWorld::Ptr& ptr) override; - void getObjectsInRange (const osg::Vec3f& position, float radius, std::vector& objects) override; - void getActorsInRange(const osg::Vec3f &position, float radius, std::vector &objects) override; + void getObjectsInRange(const osg::Vec3f& position, float radius, std::vector& objects) override; + void getActorsInRange(const osg::Vec3f& position, float radius, std::vector& objects) override; - /// Check if there are actors in selected range - bool isAnyActorInRange(const osg::Vec3f &position, float radius) override; + /// Check if there are actors in selected range + bool isAnyActorInRange(const osg::Vec3f& position, float radius) override; - std::vector getActorsSidingWith(const MWWorld::Ptr& actor) override; - std::vector getActorsFollowing(const MWWorld::Ptr& actor) override; - std::vector getActorsFollowingIndices(const MWWorld::Ptr& actor) override; - std::map getActorsFollowingByIndex(const MWWorld::Ptr& actor) override; + std::vector getActorsSidingWith(const MWWorld::Ptr& actor) override; + std::vector getActorsFollowing(const MWWorld::Ptr& actor) override; + std::vector getActorsFollowingIndices(const MWWorld::Ptr& actor) override; + std::map getActorsFollowingByIndex(const MWWorld::Ptr& actor) override; - std::vector getActorsFighting(const MWWorld::Ptr& actor) override; - std::vector getEnemiesNearby(const MWWorld::Ptr& actor) override; + std::vector getActorsFighting(const MWWorld::Ptr& actor) override; + std::vector getEnemiesNearby(const MWWorld::Ptr& actor) override; - /// Recursive version of getActorsFollowing - void getActorsFollowing(const MWWorld::Ptr& actor, std::set& out) override; - /// Recursive version of getActorsSidingWith - void getActorsSidingWith(const MWWorld::Ptr& actor, std::set& out) override; + /// Recursive version of getActorsFollowing + void getActorsFollowing(const MWWorld::Ptr& actor, std::set& out) override; + /// Recursive version of getActorsSidingWith + void getActorsSidingWith(const MWWorld::Ptr& actor, std::set& out) override; - bool toggleAI() override; - bool isAIActive() override; + bool toggleAI() override; + bool isAIActive() override; - void playerLoaded() override; + void playerLoaded() override; - bool onOpen(const MWWorld::Ptr& ptr) override; - void onClose(const MWWorld::Ptr& ptr) override; + bool onOpen(const MWWorld::Ptr& ptr) override; + void onClose(const MWWorld::Ptr& ptr) override; - int countSavedGameRecords() const override; + int countSavedGameRecords() const override; - void write (ESM::ESMWriter& writer, Loading::Listener& listener) const override; + void write(ESM::ESMWriter& writer, Loading::Listener& listener) const override; - void readRecord (ESM::ESMReader& reader, uint32_t type) override; + void readRecord(ESM::ESMReader& reader, uint32_t type) override; - void clear() override; + void clear() override; - bool isAggressive (const MWWorld::Ptr& ptr, const MWWorld::Ptr& target) override; + bool isAggressive(const MWWorld::Ptr& ptr, const MWWorld::Ptr& target) override; - void resurrect(const MWWorld::Ptr& ptr) override; + void resurrect(const MWWorld::Ptr& ptr) override; - bool isCastingSpell (const MWWorld::Ptr& ptr) const override; + bool isCastingSpell(const MWWorld::Ptr& ptr) const override; - bool isReadyToBlock (const MWWorld::Ptr& ptr) const override; - /// Is \a ptr casting spell or using weapon now? - bool isAttackingOrSpell(const MWWorld::Ptr &ptr) const override; + bool isReadyToBlock(const MWWorld::Ptr& ptr) const override; + /// Is \a ptr casting spell or using weapon now? + bool isAttackingOrSpell(const MWWorld::Ptr& ptr) const override; - void castSpell(const MWWorld::Ptr& ptr, const std::string& spellId, bool manualSpell=false) override; + void castSpell(const MWWorld::Ptr& ptr, const std::string& spellId, bool manualSpell = false) override; - void processChangedSettings(const Settings::CategorySettingVector& settings) override; + void processChangedSettings(const Settings::CategorySettingVector& settings) override; - float getActorsProcessingRange() const override; + float getActorsProcessingRange() const override; - void notifyDied(const MWWorld::Ptr& actor) override; + void notifyDied(const MWWorld::Ptr& actor) override; - /// Check if the target actor was detected by an observer - /// If the observer is a non-NPC, check all actors in AI processing distance as observers - bool isActorDetected(const MWWorld::Ptr& actor, const MWWorld::Ptr& observer) override; + /// Check if the target actor was detected by an observer + /// If the observer is a non-NPC, check all actors in AI processing distance as observers + bool isActorDetected(const MWWorld::Ptr& actor, const MWWorld::Ptr& observer) override; - void confiscateStolenItems (const MWWorld::Ptr& player, const MWWorld::Ptr& targetContainer) override; + void confiscateStolenItems(const MWWorld::Ptr& player, const MWWorld::Ptr& targetContainer) override; - /// List the owners that the player has stolen this item from (the owner can be an NPC or a faction). - /// - std::vector > getStolenItemOwners(const std::string& itemid) override; + /// List the owners that the player has stolen this item from (the owner can be an NPC or a faction). + /// + std::vector> getStolenItemOwners(const std::string& itemid) override; - /// Has the player stolen this item from the given owner? - bool isItemStolenFrom(const std::string& itemid, const MWWorld::Ptr& ptr) override; + /// Has the player stolen this item from the given owner? + bool isItemStolenFrom(const std::string& itemid, const MWWorld::Ptr& ptr) override; - bool isBoundItem(const MWWorld::Ptr& item) override; + bool isBoundItem(const MWWorld::Ptr& item) override; - /// @return is \a ptr allowed to take/use \a target or is it a crime? - bool isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::Ptr& target, MWWorld::Ptr& victim) override; + /// @return is \a ptr allowed to take/use \a target or is it a crime? + bool isAllowedToUse(const MWWorld::Ptr& ptr, const MWWorld::Ptr& target, MWWorld::Ptr& victim) override; - void setWerewolf(const MWWorld::Ptr& actor, bool werewolf) override; - void applyWerewolfAcrobatics(const MWWorld::Ptr& actor) override; + void setWerewolf(const MWWorld::Ptr& actor, bool werewolf) override; + void applyWerewolfAcrobatics(const MWWorld::Ptr& actor) override; - void cleanupSummonedCreature(const MWWorld::Ptr& caster, int creatureActorId) override; + void cleanupSummonedCreature(const MWWorld::Ptr& caster, int creatureActorId) override; - void confiscateStolenItemToOwner(const MWWorld::Ptr &player, const MWWorld::Ptr &item, const MWWorld::Ptr& victim, int count) override; + void confiscateStolenItemToOwner( + const MWWorld::Ptr& player, const MWWorld::Ptr& item, const MWWorld::Ptr& victim, int count) override; - bool isAttackPreparing(const MWWorld::Ptr& ptr) override; - bool isRunning(const MWWorld::Ptr& ptr) override; - bool isSneaking(const MWWorld::Ptr& ptr) override; + bool isAttackPreparing(const MWWorld::Ptr& ptr) override; + bool isRunning(const MWWorld::Ptr& ptr) override; + bool isSneaking(const MWWorld::Ptr& ptr) override; - void reportStats(unsigned int frameNumber, osg::Stats& stats) const override; + void reportStats(unsigned int frameNumber, osg::Stats& stats) const override; - int getGreetingTimer(const MWWorld::Ptr& ptr) const override; - float getAngleToPlayer(const MWWorld::Ptr& ptr) const override; - GreetingState getGreetingState(const MWWorld::Ptr& ptr) const override; - bool isTurningToPlayer(const MWWorld::Ptr& ptr) const override; + int getGreetingTimer(const MWWorld::Ptr& ptr) const override; + float getAngleToPlayer(const MWWorld::Ptr& ptr) const override; + GreetingState getGreetingState(const MWWorld::Ptr& ptr) const override; + bool isTurningToPlayer(const MWWorld::Ptr& ptr) const override; - private: - bool canCommitCrimeAgainst(const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker); - bool canReportCrime(const MWWorld::Ptr &actor, const MWWorld::Ptr &victim, std::set &playerFollowers); + private: + bool canCommitCrimeAgainst(const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker); + bool canReportCrime( + const MWWorld::Ptr& actor, const MWWorld::Ptr& victim, std::set& playerFollowers); - bool reportCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, - OffenseType type, const std::string& factionId, int arg=0); + bool reportCrime(const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, OffenseType type, + const std::string& factionId, int arg = 0); }; } diff --git a/apps/openmw/mwmechanics/movement.hpp b/apps/openmw/mwmechanics/movement.hpp index 57e106cdec..20606cff45 100644 --- a/apps/openmw/mwmechanics/movement.hpp +++ b/apps/openmw/mwmechanics/movement.hpp @@ -27,10 +27,7 @@ namespace MWMechanics mIsStrafing = false; } - osg::Vec3f asVec3() - { - return osg::Vec3f(mPosition[0], mPosition[1], mPosition[2]); - } + osg::Vec3f asVec3() { return osg::Vec3f(mPosition[0], mPosition[1], mPosition[2]); } }; } diff --git a/apps/openmw/mwmechanics/npcstats.cpp b/apps/openmw/mwmechanics/npcstats.cpp index a89e01259c..2f08019617 100644 --- a/apps/openmw/mwmechanics/npcstats.cpp +++ b/apps/openmw/mwmechanics/npcstats.cpp @@ -4,8 +4,8 @@ #include #include -#include #include +#include #include #include @@ -13,20 +13,20 @@ #include "../mwworld/esmstore.hpp" #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" MWMechanics::NpcStats::NpcStats() - : mDisposition (0) -, mReputation(0) -, mCrimeId(-1) -, mBounty(0) -, mWerewolfKills (0) -, mLevelProgress(0) -, mTimeToStartDrowning(-1.0) // set breath to special value, it will be replaced during actor update + : mDisposition(0) + , mReputation(0) + , mCrimeId(-1) + , mBounty(0) + , mWerewolfKills(0) + , mLevelProgress(0) + , mTimeToStartDrowning(-1.0) // set breath to special value, it will be replaced during actor update , mIsWerewolf(false) { - mSkillIncreases.resize (ESM::Attribute::Length, 0); + mSkillIncreases.resize(ESM::Attribute::Length, 0); mSpecIncreases.resize(3, 0); } @@ -40,26 +40,26 @@ void MWMechanics::NpcStats::setBaseDisposition(int disposition) mDisposition = disposition; } -const MWMechanics::SkillValue& MWMechanics::NpcStats::getSkill (int index) const +const MWMechanics::SkillValue& MWMechanics::NpcStats::getSkill(int index) const { - if (index<0 || index>=ESM::Skill::Length) - throw std::runtime_error ("skill index out of range"); + if (index < 0 || index >= ESM::Skill::Length) + throw std::runtime_error("skill index out of range"); return mSkill[index]; } -MWMechanics::SkillValue& MWMechanics::NpcStats::getSkill (int index) +MWMechanics::SkillValue& MWMechanics::NpcStats::getSkill(int index) { - if (index<0 || index>=ESM::Skill::Length) - throw std::runtime_error ("skill index out of range"); + if (index < 0 || index >= ESM::Skill::Length) + throw std::runtime_error("skill index out of range"); return mSkill[index]; } -void MWMechanics::NpcStats::setSkill(int index, const MWMechanics::SkillValue &value) +void MWMechanics::NpcStats::setSkill(int index, const MWMechanics::SkillValue& value) { - if (index<0 || index>=ESM::Skill::Length) - throw std::runtime_error ("skill index out of range"); + if (index < 0 || index >= ESM::Skill::Length) + throw std::runtime_error("skill index out of range"); mSkill[index] = value; } @@ -86,8 +86,9 @@ void MWMechanics::NpcStats::raiseRank(std::string_view faction) if (it != mFactionRank.end()) { // Does the next rank exist? - const ESM::Faction* factionPtr = MWBase::Environment::get().getWorld()->getStore().get().find(lower); - if (it->second+1 < 10 && !factionPtr->mRanks[it->second+1].empty()) + const ESM::Faction* factionPtr + = MWBase::Environment::get().getWorld()->getStore().get().find(lower); + if (it->second + 1 < 10 && !factionPtr->mRanks[it->second + 1].empty()) it->second += 1; } } @@ -98,7 +99,7 @@ void MWMechanics::NpcStats::lowerRank(std::string_view faction) std::map::iterator it = mFactionRank.find(lower); if (it != mFactionRank.end()) { - it->second = it->second-1; + it->second = it->second - 1; if (it->second < 0) { mFactionRank.erase(it); @@ -144,9 +145,9 @@ bool MWMechanics::NpcStats::isInFaction(std::string_view faction) const int MWMechanics::NpcStats::getFactionReputation(std::string_view faction) const { - std::map::const_iterator iter = mFactionReputation.find (Misc::StringUtils::lowerCase(faction)); + std::map::const_iterator iter = mFactionReputation.find(Misc::StringUtils::lowerCase(faction)); - if (iter==mFactionReputation.end()) + if (iter == mFactionReputation.end()) return 0; return iter->second; @@ -157,91 +158,90 @@ void MWMechanics::NpcStats::setFactionReputation(std::string_view faction, int v mFactionReputation[Misc::StringUtils::lowerCase(faction)] = value; } -float MWMechanics::NpcStats::getSkillProgressRequirement (int skillIndex, const ESM::Class& class_) const +float MWMechanics::NpcStats::getSkillProgressRequirement(int skillIndex, const ESM::Class& class_) const { float progressRequirement = static_cast(1 + getSkill(skillIndex).getBase()); - const MWWorld::Store &gmst = - MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& gmst + = MWBase::Environment::get().getWorld()->getStore().get(); - float typeFactor = gmst.find ("fMiscSkillBonus")->mValue.getFloat(); + float typeFactor = gmst.find("fMiscSkillBonus")->mValue.getFloat(); - for (int i=0; i<5; ++i) + for (int i = 0; i < 5; ++i) { - if (class_.mData.mSkills[i][0]==skillIndex) + if (class_.mData.mSkills[i][0] == skillIndex) { - typeFactor = gmst.find ("fMinorSkillBonus")->mValue.getFloat(); + typeFactor = gmst.find("fMinorSkillBonus")->mValue.getFloat(); break; } - else if (class_.mData.mSkills[i][1]==skillIndex) + else if (class_.mData.mSkills[i][1] == skillIndex) { - typeFactor = gmst.find ("fMajorSkillBonus")->mValue.getFloat(); + typeFactor = gmst.find("fMajorSkillBonus")->mValue.getFloat(); break; } } progressRequirement *= typeFactor; - if (typeFactor<=0) - throw std::runtime_error ("invalid skill type factor"); + if (typeFactor <= 0) + throw std::runtime_error("invalid skill type factor"); float specialisationFactor = 1; - const ESM::Skill *skill = - MWBase::Environment::get().getWorld()->getStore().get().find (skillIndex); - if (skill->mData.mSpecialization==class_.mData.mSpecialization) + const ESM::Skill* skill = MWBase::Environment::get().getWorld()->getStore().get().find(skillIndex); + if (skill->mData.mSpecialization == class_.mData.mSpecialization) { - specialisationFactor = gmst.find ("fSpecialSkillBonus")->mValue.getFloat(); + specialisationFactor = gmst.find("fSpecialSkillBonus")->mValue.getFloat(); - if (specialisationFactor<=0) - throw std::runtime_error ("invalid skill specialisation factor"); + if (specialisationFactor <= 0) + throw std::runtime_error("invalid skill specialisation factor"); } progressRequirement *= specialisationFactor; return progressRequirement; } -void MWMechanics::NpcStats::useSkill (int skillIndex, const ESM::Class& class_, int usageType, float extraFactor) +void MWMechanics::NpcStats::useSkill(int skillIndex, const ESM::Class& class_, int usageType, float extraFactor) { - const ESM::Skill *skill = - MWBase::Environment::get().getWorld()->getStore().get().find (skillIndex); + const ESM::Skill* skill = MWBase::Environment::get().getWorld()->getStore().get().find(skillIndex); float skillGain = 1; - if (usageType>=4) - throw std::runtime_error ("skill usage type out of range"); - if (usageType>=0) + if (usageType >= 4) + throw std::runtime_error("skill usage type out of range"); + if (usageType >= 0) { skillGain = skill->mData.mUseValue[usageType]; - if (skillGain<0) - throw std::runtime_error ("invalid skill gain factor"); + if (skillGain < 0) + throw std::runtime_error("invalid skill gain factor"); } skillGain *= extraFactor; - MWMechanics::SkillValue& value = getSkill (skillIndex); + MWMechanics::SkillValue& value = getSkill(skillIndex); value.setProgress(value.getProgress() + skillGain); - if (int(value.getProgress())>=int(getSkillProgressRequirement(skillIndex, class_))) + if (int(value.getProgress()) >= int(getSkillProgressRequirement(skillIndex, class_))) { // skill levelled up increaseSkill(skillIndex, class_, false); } } -void MWMechanics::NpcStats::increaseSkill(int skillIndex, const ESM::Class &class_, bool preserveProgress, bool readBook) +void MWMechanics::NpcStats::increaseSkill( + int skillIndex, const ESM::Class& class_, bool preserveProgress, bool readBook) { - float base = getSkill (skillIndex).getBase(); + float base = getSkill(skillIndex).getBase(); if (base >= 100.f) return; base += 1; - const MWWorld::Store &gmst = - MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& gmst + = MWBase::Environment::get().getWorld()->getStore().get(); // is this a minor or major skill? int increase = gmst.find("iLevelupMiscMultAttriubte")->mValue.getInteger(); // Note: GMST has a typo - for (int k=0; k<5; ++k) + for (int k = 0; k < 5; ++k) { if (class_.mData.mSkills[k][0] == skillIndex) { @@ -257,8 +257,7 @@ void MWMechanics::NpcStats::increaseSkill(int skillIndex, const ESM::Class &clas } } - const ESM::Skill* skill = - MWBase::Environment::get().getWorld ()->getStore ().get().find(skillIndex); + const ESM::Skill* skill = MWBase::Environment::get().getWorld()->getStore().get().find(skillIndex); mSkillIncreases[skill->mData.mAttribute] += increase; mSpecIncreases[skill->mData.mSpecialization] += gmst.find("iLevelupSpecialization")->mValue.getInteger(); @@ -267,39 +266,40 @@ void MWMechanics::NpcStats::increaseSkill(int skillIndex, const ESM::Class &clas /// \todo check if character is the player, if levelling is ever implemented for NPCs MWBase::Environment::get().getWindowManager()->playSound("skillraise"); - std::string message{MWBase::Environment::get().getWindowManager()->getGameSettingString("sNotifyMessage39", {})}; - message = Misc::StringUtils::format(message, ("#{" + ESM::Skill::sSkillNameIds[skillIndex] + "}"), static_cast(base)); + std::string message{ MWBase::Environment::get().getWindowManager()->getGameSettingString("sNotifyMessage39", {}) }; + message = Misc::StringUtils::format( + message, ("#{" + ESM::Skill::sSkillNameIds[skillIndex] + "}"), static_cast(base)); if (readBook) message = "#{sBookSkillMessage}\n" + message; - - MWBase::Environment::get().getWindowManager ()->messageBox(message, MWGui::ShowInDialogueMode_Never); + + MWBase::Environment::get().getWindowManager()->messageBox(message, MWGui::ShowInDialogueMode_Never); if (mLevelProgress >= gmst.find("iLevelUpTotal")->mValue.getInteger()) { // levelup is possible now - MWBase::Environment::get().getWindowManager ()->messageBox ("#{sLevelUpMsg}", MWGui::ShowInDialogueMode_Never); + MWBase::Environment::get().getWindowManager()->messageBox("#{sLevelUpMsg}", MWGui::ShowInDialogueMode_Never); } - getSkill(skillIndex).setBase (base); + getSkill(skillIndex).setBase(base); if (!preserveProgress) getSkill(skillIndex).setProgress(0); } -int MWMechanics::NpcStats::getLevelProgress () const +int MWMechanics::NpcStats::getLevelProgress() const { return mLevelProgress; } void MWMechanics::NpcStats::levelUp() { - const MWWorld::Store &gmst = - MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& gmst + = MWBase::Environment::get().getWorld()->getStore().get(); mLevelProgress -= gmst.find("iLevelUpTotal")->mValue.getInteger(); mLevelProgress = std::max(0, mLevelProgress); // might be necessary when levelup was invoked via console - for (int i=0; igetStore().get().find(gmst.str())->mValue.getInteger(); + return MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find(gmst.str()) + ->mValue.getInteger(); } int MWMechanics::NpcStats::getSkillIncreasesForSpecialization(int spec) const @@ -346,14 +351,14 @@ int MWMechanics::NpcStats::getSkillIncreasesForSpecialization(int spec) const return mSpecIncreases[spec]; } -void MWMechanics::NpcStats::flagAsUsed (const std::string& id) +void MWMechanics::NpcStats::flagAsUsed(const std::string& id) { - mUsedIds.insert (id); + mUsedIds.insert(id); } -bool MWMechanics::NpcStats::hasBeenUsed (const std::string& id) const +bool MWMechanics::NpcStats::hasBeenUsed(const std::string& id) const { - return mUsedIds.find (id)!=mUsedIds.end(); + return mUsedIds.find(id) != mUsedIds.end(); } int MWMechanics::NpcStats::getBounty() const @@ -361,7 +366,7 @@ int MWMechanics::NpcStats::getBounty() const return mBounty; } -void MWMechanics::NpcStats::setBounty (int bounty) +void MWMechanics::NpcStats::setBounty(int bounty) { mBounty = bounty; } @@ -389,44 +394,44 @@ void MWMechanics::NpcStats::setCrimeId(int id) bool MWMechanics::NpcStats::hasSkillsForRank(std::string_view factionId, int rank) const { - if (rank<0 || rank>=10) - throw std::runtime_error ("rank index out of range"); + if (rank < 0 || rank >= 10) + throw std::runtime_error("rank index out of range"); - const ESM::Faction& faction = - *MWBase::Environment::get().getWorld()->getStore().get().find (factionId); + const ESM::Faction& faction + = *MWBase::Environment::get().getWorld()->getStore().get().find(factionId); std::vector skills; - for (int i=0; i<7; ++i) + for (int i = 0; i < 7; ++i) { if (faction.mData.mSkills[i] != -1) - skills.push_back (static_cast (getSkill (faction.mData.mSkills[i]).getBase())); + skills.push_back(static_cast(getSkill(faction.mData.mSkills[i]).getBase())); } if (skills.empty()) return true; - std::sort (skills.begin(), skills.end()); + std::sort(skills.begin(), skills.end()); std::vector::const_reverse_iterator iter = skills.rbegin(); const ESM::RankData& rankData = faction.mData.mRankData[rank]; - if (*iter::const_iterator iter (mFactionRank.begin()); - iter!=mFactionRank.end(); ++iter) + for (std::map::const_iterator iter(mFactionRank.begin()); iter != mFactionRank.end(); ++iter) state.mFactions[iter->first].mRank = iter->second; state.mDisposition = mDisposition; - for (int i=0; i::const_iterator iter (mExpelled.begin()); - iter!=mExpelled.end(); ++iter) + for (std::set::const_iterator iter(mExpelled.begin()); iter != mExpelled.end(); ++iter) state.mFactions[*iter].mExpelled = true; - for (std::map::const_iterator iter (mFactionReputation.begin()); - iter!=mFactionReputation.end(); ++iter) + for (std::map::const_iterator iter(mFactionReputation.begin()); iter != mFactionReputation.end(); + ++iter) state.mFactions[iter->first].mReputation = iter->second; state.mReputation = mReputation; state.mWerewolfKills = mWerewolfKills; state.mLevelProgress = mLevelProgress; - for (int i=0; igetStore(); - for (std::map::const_iterator iter (state.mFactions.begin()); - iter!=state.mFactions.end(); ++iter) - if (store.get().search (iter->first)) + for (std::map::const_iterator iter(state.mFactions.begin()); + iter != state.mFactions.end(); ++iter) + if (store.get().search(iter->first)) { if (iter->second.mExpelled) - mExpelled.insert (iter->first); + mExpelled.insert(iter->first); if (iter->second.mRank >= 0) mFactionRank[iter->first] = iter->second.mRank; @@ -538,8 +541,8 @@ void MWMechanics::NpcStats::readState (const ESM::NpcStats& state) mDisposition = state.mDisposition; - for (int i=0; i::const_iterator iter (state.mUsedIds.begin()); - iter!=state.mUsedIds.end(); ++iter) - if (store.find (*iter)) - mUsedIds.insert (*iter); + for (std::vector::const_iterator iter(state.mUsedIds.begin()); iter != state.mUsedIds.end(); ++iter) + if (store.find(*iter)) + mUsedIds.insert(*iter); mTimeToStartDrowning = state.mTimeToStartDrowning; } diff --git a/apps/openmw/mwmechanics/npcstats.hpp b/apps/openmw/mwmechanics/npcstats.hpp index 1e83208f06..6b8e73d615 100644 --- a/apps/openmw/mwmechanics/npcstats.hpp +++ b/apps/openmw/mwmechanics/npcstats.hpp @@ -20,118 +20,119 @@ namespace MWMechanics class NpcStats : public CreatureStats { - int mDisposition; - SkillValue mSkill[ESM::Skill::Length]; // SkillValue.mProgress used by the player only + int mDisposition; + SkillValue mSkill[ESM::Skill::Length]; // SkillValue.mProgress used by the player only - int mReputation; - int mCrimeId; + int mReputation; + int mCrimeId; - // ----- used by the player only, maybe should be moved at some point ------- - int mBounty; - int mWerewolfKills; - /// Used only for the player and for NPC's with ranks, modified by scripts; other NPCs have maximum one faction defined in their NPC record - std::map mFactionRank; - std::set mExpelled; - std::map mFactionReputation; - int mLevelProgress; // 0-10 - std::vector mSkillIncreases; // number of skill increases for each attribute (resets after leveling up) - std::vector mSpecIncreases; // number of skill increases for each specialization (accumulates throughout the entire game) - std::set mUsedIds; - // --------------------------------------------------------------------------- + // ----- used by the player only, maybe should be moved at some point ------- + int mBounty; + int mWerewolfKills; + /// Used only for the player and for NPC's with ranks, modified by scripts; other NPCs have maximum one faction + /// defined in their NPC record + std::map mFactionRank; + std::set mExpelled; + std::map mFactionReputation; + int mLevelProgress; // 0-10 + std::vector mSkillIncreases; // number of skill increases for each attribute (resets after leveling up) + std::vector mSpecIncreases; // number of skill increases for each specialization (accumulates throughout + // the entire game) + std::set mUsedIds; + // --------------------------------------------------------------------------- - /// Countdown to getting damage while underwater - float mTimeToStartDrowning; + /// Countdown to getting damage while underwater + float mTimeToStartDrowning; - bool mIsWerewolf; + bool mIsWerewolf; - public: + public: + NpcStats(); - NpcStats(); + int getBaseDisposition() const; + void setBaseDisposition(int disposition); - int getBaseDisposition() const; - void setBaseDisposition(int disposition); + int getReputation() const; + void setReputation(int reputation); - int getReputation() const; - void setReputation(int reputation); + int getCrimeId() const; + void setCrimeId(int id); - int getCrimeId() const; - void setCrimeId(int id); + const SkillValue& getSkill(int index) const; + SkillValue& getSkill(int index); + void setSkill(int index, const SkillValue& value); - const SkillValue& getSkill (int index) const; - SkillValue& getSkill (int index); - void setSkill(int index, const SkillValue& value); + int getFactionRank(std::string_view faction) const; + const std::map& getFactionRanks() const; - int getFactionRank(std::string_view faction) const; - const std::map& getFactionRanks() const; + /// Increase the rank in this faction by 1, if such a rank exists. + void raiseRank(std::string_view faction); + /// Lower the rank in this faction by 1, if such a rank exists. + void lowerRank(std::string_view faction); + /// Join this faction, setting the initial rank to 0. + void joinFaction(std::string_view faction); - /// Increase the rank in this faction by 1, if such a rank exists. - void raiseRank(std::string_view faction); - /// Lower the rank in this faction by 1, if such a rank exists. - void lowerRank(std::string_view faction); - /// Join this faction, setting the initial rank to 0. - void joinFaction(std::string_view faction); + const std::set& getExpelled() const { return mExpelled; } + bool getExpelled(std::string_view factionID) const; + void expell(std::string_view factionID); + void clearExpelled(std::string_view factionID); - const std::set& getExpelled() const { return mExpelled; } - bool getExpelled(std::string_view factionID) const; - void expell(std::string_view factionID); - void clearExpelled(std::string_view factionID); + bool isInFaction(std::string_view faction) const; - bool isInFaction(std::string_view faction) const; + float getSkillProgressRequirement(int skillIndex, const ESM::Class& class_) const; - float getSkillProgressRequirement (int skillIndex, const ESM::Class& class_) const; + void useSkill(int skillIndex, const ESM::Class& class_, int usageType = -1, float extraFactor = 1.f); + ///< Increase skill by usage. - void useSkill (int skillIndex, const ESM::Class& class_, int usageType = -1, float extraFactor=1.f); - ///< Increase skill by usage. + void increaseSkill(int skillIndex, const ESM::Class& class_, bool preserveProgress, bool readBook = false); - void increaseSkill (int skillIndex, const ESM::Class& class_, bool preserveProgress, bool readBook = false); + int getLevelProgress() const; - int getLevelProgress() const; + int getLevelupAttributeMultiplier(int attribute) const; - int getLevelupAttributeMultiplier(int attribute) const; + int getSkillIncreasesForSpecialization(int spec) const; - int getSkillIncreasesForSpecialization(int spec) const; + void levelUp(); - void levelUp(); + void updateHealth(); + ///< Calculate health based on endurance and strength. + /// Called at character creation. - void updateHealth(); - ///< Calculate health based on endurance and strength. - /// Called at character creation. + void flagAsUsed(const std::string& id); + ///< @note Id must be lower-case - void flagAsUsed (const std::string& id); - ///< @note Id must be lower-case + bool hasBeenUsed(const std::string& id) const; + ///< @note Id must be lower-case - bool hasBeenUsed (const std::string& id) const; - ///< @note Id must be lower-case + int getBounty() const; - int getBounty() const; + void setBounty(int bounty); - void setBounty (int bounty); + int getFactionReputation(std::string_view faction) const; - int getFactionReputation(std::string_view faction) const; + void setFactionReputation(std::string_view faction, int value); - void setFactionReputation(std::string_view faction, int value); + bool hasSkillsForRank(std::string_view factionId, int rank) const; - bool hasSkillsForRank(std::string_view factionId, int rank) const; + bool isWerewolf() const; - bool isWerewolf() const; + void setWerewolf(bool set); - void setWerewolf(bool set); + int getWerewolfKills() const; - int getWerewolfKills() const; + /// Increments mWerewolfKills by 1. + void addWerewolfKill(); - /// Increments mWerewolfKills by 1. - void addWerewolfKill(); + float getTimeToStartDrowning() const; + /// Sets time left for the creature to drown if it stays underwater. + /// @param time value from [0,20] + void setTimeToStartDrowning(float time); - float getTimeToStartDrowning() const; - /// Sets time left for the creature to drown if it stays underwater. - /// @param time value from [0,20] - void setTimeToStartDrowning(float time); + void writeState(ESM::CreatureStats& state) const; + void writeState(ESM::NpcStats& state) const; - void writeState (ESM::CreatureStats& state) const; - void writeState (ESM::NpcStats& state) const; - - void readState (const ESM::CreatureStats& state); - void readState (const ESM::NpcStats& state); + void readState(const ESM::CreatureStats& state); + void readState(const ESM::NpcStats& state); }; } diff --git a/apps/openmw/mwmechanics/objects.cpp b/apps/openmw/mwmechanics/objects.cpp index 2814240db7..a6f9727965 100644 --- a/apps/openmw/mwmechanics/objects.cpp +++ b/apps/openmw/mwmechanics/objects.cpp @@ -13,123 +13,125 @@ namespace MWMechanics { -void Objects::addObject(const MWWorld::Ptr& ptr) -{ - removeObject(ptr); - - MWRender::Animation *anim = MWBase::Environment::get().getWorld()->getAnimation(ptr); - if (anim == nullptr) - return; + void Objects::addObject(const MWWorld::Ptr& ptr) + { + removeObject(ptr); - const auto it = mObjects.emplace(mObjects.end(), ptr, anim); - mIndex.emplace(ptr.mRef, it); -} + MWRender::Animation* anim = MWBase::Environment::get().getWorld()->getAnimation(ptr); + if (anim == nullptr) + return; -void Objects::removeObject(const MWWorld::Ptr& ptr) -{ - const auto iter = mIndex.find(ptr.mRef); - if (iter != mIndex.end()) - { - mObjects.erase(iter->second); - mIndex.erase(iter); + const auto it = mObjects.emplace(mObjects.end(), ptr, anim); + mIndex.emplace(ptr.mRef, it); } -} -void Objects::updateObject(const MWWorld::Ptr &old, const MWWorld::Ptr &ptr) -{ - const auto iter = mIndex.find(old.mRef); - if (iter != mIndex.end()) - iter->second->updatePtr(ptr); -} - -void Objects::dropObjects (const MWWorld::CellStore *cellStore) -{ - for (auto iter = mObjects.begin(); iter != mObjects.end();) + void Objects::removeObject(const MWWorld::Ptr& ptr) { - if (iter->getPtr().getCell() == cellStore) + const auto iter = mIndex.find(ptr.mRef); + if (iter != mIndex.end()) { - mIndex.erase(iter->getPtr().mRef); - iter = mObjects.erase(iter); + mObjects.erase(iter->second); + mIndex.erase(iter); } - else - ++iter; } -} -void Objects::update(float duration, bool paused) -{ - if(!paused) + void Objects::updateObject(const MWWorld::Ptr& old, const MWWorld::Ptr& ptr) { - for (CharacterController& object : mObjects) - object.update(duration); + const auto iter = mIndex.find(old.mRef); + if (iter != mIndex.end()) + iter->second->updatePtr(ptr); } - else + + void Objects::dropObjects(const MWWorld::CellStore* cellStore) { - // We still should play container opening animation in the Container GUI mode. - MWGui::GuiMode mode = MWBase::Environment::get().getWindowManager()->getMode(); - if(mode != MWGui::GM_Container) - return; + for (auto iter = mObjects.begin(); iter != mObjects.end();) + { + if (iter->getPtr().getCell() == cellStore) + { + mIndex.erase(iter->getPtr().mRef); + iter = mObjects.erase(iter); + } + else + ++iter; + } + } - for (CharacterController& object : mObjects) + void Objects::update(float duration, bool paused) + { + if (!paused) + { + for (CharacterController& object : mObjects) + object.update(duration); + } + else { - if (object.getPtr().getType() != ESM::Container::sRecordId) - continue; + // We still should play container opening animation in the Container GUI mode. + MWGui::GuiMode mode = MWBase::Environment::get().getWindowManager()->getMode(); + if (mode != MWGui::GM_Container) + return; - if (object.isAnimPlaying("containeropen")) + for (CharacterController& object : mObjects) { - object.update(duration); - MWBase::Environment::get().getWorld()->updateAnimatedCollisionShape(object.getPtr()); + if (object.getPtr().getType() != ESM::Container::sRecordId) + continue; + + if (object.isAnimPlaying("containeropen")) + { + object.update(duration); + MWBase::Environment::get().getWorld()->updateAnimatedCollisionShape(object.getPtr()); + } } } } -} -bool Objects::onOpen(const MWWorld::Ptr& ptr) -{ - const auto iter = mIndex.find(ptr.mRef); - if (iter != mIndex.end()) - return iter->second->onOpen(); - return true; -} + bool Objects::onOpen(const MWWorld::Ptr& ptr) + { + const auto iter = mIndex.find(ptr.mRef); + if (iter != mIndex.end()) + return iter->second->onOpen(); + return true; + } -void Objects::onClose(const MWWorld::Ptr& ptr) -{ - const auto iter = mIndex.find(ptr.mRef); - if (iter != mIndex.end()) - iter->second->onClose(); -} + void Objects::onClose(const MWWorld::Ptr& ptr) + { + const auto iter = mIndex.find(ptr.mRef); + if (iter != mIndex.end()) + iter->second->onClose(); + } -bool Objects::playAnimationGroup(const MWWorld::Ptr& ptr, std::string_view groupName, int mode, int number, bool persist) -{ - const auto iter = mIndex.find(ptr.mRef); - if (iter != mIndex.end()) + bool Objects::playAnimationGroup( + const MWWorld::Ptr& ptr, std::string_view groupName, int mode, int number, bool persist) { - return iter->second->playGroup(groupName, mode, number, persist); + const auto iter = mIndex.find(ptr.mRef); + if (iter != mIndex.end()) + { + return iter->second->playGroup(groupName, mode, number, persist); + } + else + { + Log(Debug::Warning) << "Warning: Objects::playAnimationGroup: Unable to find " + << ptr.getCellRef().getRefId(); + return false; + } } - else + void Objects::skipAnimation(const MWWorld::Ptr& ptr) { - Log(Debug::Warning) << "Warning: Objects::playAnimationGroup: Unable to find " << ptr.getCellRef().getRefId(); - return false; + const auto iter = mIndex.find(ptr.mRef); + if (iter != mIndex.end()) + iter->second->skipAnim(); } -} -void Objects::skipAnimation(const MWWorld::Ptr& ptr) -{ - const auto iter = mIndex.find(ptr.mRef); - if (iter != mIndex.end()) - iter->second->skipAnim(); -} -void Objects::persistAnimationStates() -{ - for (CharacterController& object : mObjects) - object.persistAnimationState(); -} + void Objects::persistAnimationStates() + { + for (CharacterController& object : mObjects) + object.persistAnimationState(); + } -void Objects::getObjectsInRange(const osg::Vec3f& position, float radius, std::vector& out) const -{ - for (const CharacterController& object : mObjects) - if ((position - object.getPtr().getRefData().getPosition().asVec3()).length2() <= radius * radius) - out.push_back(object.getPtr()); -} + void Objects::getObjectsInRange(const osg::Vec3f& position, float radius, std::vector& out) const + { + for (const CharacterController& object : mObjects) + if ((position - object.getPtr().getRefData().getPosition().asVec3()).length2() <= radius * radius) + out.push_back(object.getPtr()); + } } diff --git a/apps/openmw/mwmechanics/objects.hpp b/apps/openmw/mwmechanics/objects.hpp index 7463093480..8b5962109c 100644 --- a/apps/openmw/mwmechanics/objects.hpp +++ b/apps/openmw/mwmechanics/objects.hpp @@ -3,10 +3,10 @@ #include "character.hpp" -#include +#include #include +#include #include -#include namespace osg { @@ -27,16 +27,16 @@ namespace MWMechanics std::map::iterator> mIndex; public: - void addObject (const MWWorld::Ptr& ptr); + void addObject(const MWWorld::Ptr& ptr); ///< Register an animated object - void removeObject (const MWWorld::Ptr& ptr); + void removeObject(const MWWorld::Ptr& ptr); ///< Deregister an object - void updateObject(const MWWorld::Ptr &old, const MWWorld::Ptr& ptr); + void updateObject(const MWWorld::Ptr& old, const MWWorld::Ptr& ptr); ///< Updates an object with a new Ptr - void dropObjects(const MWWorld::CellStore *cellStore); + void dropObjects(const MWWorld::CellStore* cellStore); ///< Deregister all objects in the given cell. void update(float duration, bool paused); @@ -45,16 +45,14 @@ namespace MWMechanics bool onOpen(const MWWorld::Ptr& ptr); void onClose(const MWWorld::Ptr& ptr); - bool playAnimationGroup(const MWWorld::Ptr& ptr, std::string_view groupName, int mode, int number, bool persist=false); + bool playAnimationGroup( + const MWWorld::Ptr& ptr, std::string_view groupName, int mode, int number, bool persist = false); void skipAnimation(const MWWorld::Ptr& ptr); void persistAnimationStates(); void getObjectsInRange(const osg::Vec3f& position, float radius, std::vector& out) const; - std::size_t size() const - { - return mObjects.size(); - } + std::size_t size() const { return mObjects.size(); } }; } diff --git a/apps/openmw/mwmechanics/obstacle.cpp b/apps/openmw/mwmechanics/obstacle.cpp index c7573c3158..0b59782992 100644 --- a/apps/openmw/mwmechanics/obstacle.cpp +++ b/apps/openmw/mwmechanics/obstacle.cpp @@ -2,15 +2,15 @@ #include -#include #include #include #include +#include -#include "../mwworld/class.hpp" -#include "../mwworld/cellstore.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwworld/cellstore.hpp" +#include "../mwworld/class.hpp" #include "movement.hpp" @@ -21,17 +21,16 @@ namespace MWMechanics static const float DURATION_SAME_SPOT = 1.5f; static const float DURATION_TO_EVADE = 0.4f; - const float ObstacleCheck::evadeDirections[NUM_EVADE_DIRECTIONS][2] = - { - { 1.0f, 0.0f }, // move to side - { 1.0f, -1.0f }, // move to side and backwards - { -1.0f, 0.0f }, // move to other side - { -1.0f, -1.0f } // move to side and backwards + const float ObstacleCheck::evadeDirections[NUM_EVADE_DIRECTIONS][2] = { + { 1.0f, 0.0f }, // move to side + { 1.0f, -1.0f }, // move to side and backwards + { -1.0f, 0.0f }, // move to other side + { -1.0f, -1.0f } // move to side and backwards }; bool proximityToDoor(const MWWorld::Ptr& actor, float minDist) { - if(getNearbyDoor(actor, minDist).isEmpty()) + if (getNearbyDoor(actor, minDist).isEmpty()) return false; else return true; @@ -39,21 +38,22 @@ namespace MWMechanics const MWWorld::Ptr getNearbyDoor(const MWWorld::Ptr& actor, float minDist) { - MWWorld::CellStore *cell = actor.getCell(); + MWWorld::CellStore* cell = actor.getCell(); // Check all the doors in this cell const MWWorld::CellRefList& doors = cell->getReadOnlyDoors(); osg::Vec3f pos(actor.getRefData().getPosition().asVec3()); pos.z() = 0; - osg::Vec3f actorDir = (actor.getRefData().getBaseNode()->getAttitude() * osg::Vec3f(0,1,0)); + osg::Vec3f actorDir = (actor.getRefData().getBaseNode()->getAttitude() * osg::Vec3f(0, 1, 0)); for (const auto& ref : doors.mList) { osg::Vec3f doorPos(ref.mData.getPosition().asVec3()); // FIXME: cast - const MWWorld::Ptr doorPtr = MWWorld::Ptr(&const_cast &>(ref), actor.getCell()); + const MWWorld::Ptr doorPtr + = MWWorld::Ptr(&const_cast&>(ref), actor.getCell()); const auto doorState = doorPtr.getClass().getDoorState(doorPtr); float doorRot = ref.mData.getPosition().rot[2] - doorPtr.getCellRef().getPosition().rot[2]; @@ -70,7 +70,7 @@ namespace MWMechanics continue; // Door is not close enough - if ((pos - doorPos).length2() > minDist*minDist) + if ((pos - doorPos).length2() > minDist * minDist) continue; return doorPtr; // found, stop searching @@ -87,17 +87,17 @@ namespace MWMechanics const auto maxHalfExtent = std::max(halfExtents.x(), std::max(halfExtents.y(), halfExtents.z())); if (ignorePlayer) { - const std::array ignore {actor, world->getPlayerConstPtr()}; + const std::array ignore{ actor, world->getPlayerConstPtr() }; return world->isAreaOccupiedByOtherActor(destination, 2 * maxHalfExtent, ignore, occupyingActors); } - const std::array ignore {actor}; + const std::array ignore{ actor }; return world->isAreaOccupiedByOtherActor(destination, 2 * maxHalfExtent, ignore, occupyingActors); } ObstacleCheck::ObstacleCheck() - : mWalkState(WalkState::Initial) - , mStateDuration(0) - , mEvadeDirectionIndex(0) + : mWalkState(WalkState::Initial) + , mStateDuration(0) + , mEvadeDirectionIndex(0) { } @@ -180,7 +180,7 @@ namespace MWMechanics } mStateDuration += duration; - if(mStateDuration >= DURATION_TO_EVADE) + if (mStateDuration >= DURATION_TO_EVADE) { // tried to evade, assume all is ok and start again mWalkState = WalkState::Norm; diff --git a/apps/openmw/mwmechanics/obstacle.hpp b/apps/openmw/mwmechanics/obstacle.hpp index 2026f22129..bb11a9d611 100644 --- a/apps/openmw/mwmechanics/obstacle.hpp +++ b/apps/openmw/mwmechanics/obstacle.hpp @@ -24,45 +24,45 @@ namespace MWMechanics /** \return Pointer to the door, or empty pointer if none exists **/ const MWWorld::Ptr getNearbyDoor(const MWWorld::Ptr& actor, float minDist); - bool isAreaOccupiedByOtherActor(const MWWorld::ConstPtr& actor, const osg::Vec3f& destination, bool ignorePlayer = false, - std::vector* occupyingActors = nullptr); + bool isAreaOccupiedByOtherActor(const MWWorld::ConstPtr& actor, const osg::Vec3f& destination, + bool ignorePlayer = false, std::vector* occupyingActors = nullptr); class ObstacleCheck { - public: - ObstacleCheck(); + public: + ObstacleCheck(); - // Clear the timers and set the state machine to default - void clear(); + // Clear the timers and set the state machine to default + void clear(); - bool isEvading() const; + bool isEvading() const; - // Updates internal state, call each frame for moving actor - void update(const MWWorld::Ptr& actor, const osg::Vec3f& destination, float duration); + // Updates internal state, call each frame for moving actor + void update(const MWWorld::Ptr& actor, const osg::Vec3f& destination, float duration); - // change direction to try to fix "stuck" actor - void takeEvasiveAction(MWMechanics::Movement& actorMovement) const; + // change direction to try to fix "stuck" actor + void takeEvasiveAction(MWMechanics::Movement& actorMovement) const; - private: - osg::Vec3f mPrev; + private: + osg::Vec3f mPrev; - // directions to try moving in when get stuck - static const float evadeDirections[NUM_EVADE_DIRECTIONS][2]; + // directions to try moving in when get stuck + static const float evadeDirections[NUM_EVADE_DIRECTIONS][2]; - enum class WalkState - { - Initial, - Norm, - CheckStuck, - Evade - }; - WalkState mWalkState; + enum class WalkState + { + Initial, + Norm, + CheckStuck, + Evade + }; + WalkState mWalkState; - float mStateDuration; - int mEvadeDirectionIndex; - float mInitialDistance = 0; + float mStateDuration; + int mEvadeDirectionIndex; + float mInitialDistance = 0; - void chooseEvasionDirection(); + void chooseEvasionDirection(); }; } diff --git a/apps/openmw/mwmechanics/pathfinding.cpp b/apps/openmw/mwmechanics/pathfinding.cpp index 9a75585cc1..02dfd17a93 100644 --- a/apps/openmw/mwmechanics/pathfinding.cpp +++ b/apps/openmw/mwmechanics/pathfinding.cpp @@ -5,29 +5,28 @@ #include -#include -#include #include +#include +#include #include #include -#include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" #include "../mwphysics/collisiontype.hpp" #include "../mwworld/cellstore.hpp" #include "../mwworld/class.hpp" -#include "pathgrid.hpp" #include "actorutil.hpp" +#include "pathgrid.hpp" namespace { // Chooses a reachable end pathgrid point. start is assumed reachable. - std::pair getClosestReachablePoint(const ESM::Pathgrid* grid, - const MWMechanics::PathgridGraph *graph, - const osg::Vec3f& pos, int start) + std::pair getClosestReachablePoint( + const ESM::Pathgrid* grid, const MWMechanics::PathgridGraph* graph, const osg::Vec3f& pos, int start) { assert(grid && !grid->mPoints.empty()); @@ -37,7 +36,7 @@ namespace int closestReachableIndex = 0; // TODO: if this full scan causes performance problems mapping pathgrid // points to a quadtree may help - for(unsigned int counter = 0; counter < grid->mPoints.size(); counter++) + for (unsigned int counter = 0; counter < grid->mPoints.size(); counter++) { float potentialDistBetween = MWMechanics::PathFinder::distanceSquared(grid->mPoints[counter], pos); if (potentialDistBetween < closestDistanceReachable) @@ -63,8 +62,7 @@ namespace // allowed nodes if not. Hence a path needs to be created even if the start // and the end points are the same. - return std::pair - (closestReachableIndex, closestReachableIndex == closestIndex); + return std::pair(closestReachableIndex, closestReachableIndex == closestIndex); } float sqrDistance(const osg::Vec2f& lhs, const osg::Vec2f& rhs) @@ -92,7 +90,8 @@ namespace } // Returns true if turn in `p2` is less than 10 degrees and all the 3 points are almost on one line. - bool isAlmostStraight(const osg::Vec3f& p1, const osg::Vec3f& p2, const osg::Vec3f& p3, float pointTolerance) { + bool isAlmostStraight(const osg::Vec3f& p1, const osg::Vec3f& p2, const osg::Vec3f& p3, float pointTolerance) + { osg::Vec3f v1 = p1 - p2; osg::Vec3f v3 = p3 - p2; v1.z() = v3.z() = 0; @@ -118,7 +117,8 @@ namespace bool operator()(const osg::Vec3f& start, const osg::Vec3f& end) const { const auto position = DetourNavigator::raycast(*mNavigator, mAgentBounds, start, end, mFlags); - return position.has_value() && std::abs((position.value() - start).length2() - (end - start).length2()) <= 1; + return position.has_value() + && std::abs((position.value() - start).length2() - (end - start).length2()) <= 1; } }; } @@ -138,10 +138,12 @@ namespace MWMechanics dir.z() = 0; dir.normalize(); float verticalOffset = 200; // instead of '200' here we want the height of the actor - osg::Vec3f _from = from + dir*offsetXY + osg::Z_AXIS * verticalOffset; + osg::Vec3f _from = from + dir * offsetXY + osg::Z_AXIS * verticalOffset; // cast up-down ray and find height of hit in world space - float h = _from.z() - MWBase::Environment::get().getWorld()->getDistToNearestRayHit(_from, -osg::Z_AXIS, verticalOffset + PATHFIND_Z_REACH + 1); + float h = _from.z() + - MWBase::Environment::get().getWorld()->getDistToNearestRayHit( + _from, -osg::Z_AXIS, verticalOffset + PATHFIND_Z_REACH + 1); return (std::abs(from.z() - h) <= PATHFIND_Z_REACH); } @@ -190,7 +192,7 @@ namespace MWMechanics // Refer to AiWander reseach topic on openmw forums for some background. // Maybe there is no pathgrid for this cell. Just go to destination and let // physics take care of any blockages. - if(!pathgrid || pathgrid->mPoints.empty()) + if (!pathgrid || pathgrid->mPoints.empty()) return; // NOTE: getClosestPoint expects local coordinates @@ -205,9 +207,8 @@ namespace MWMechanics int startNode = getClosestPoint(pathgrid, startPointInLocalCoords); osg::Vec3f endPointInLocalCoords(converter.toLocalVec3(endPoint)); - std::pair endNode = getClosestReachablePoint(pathgrid, &pathgridGraph, - endPointInLocalCoords, - startNode); + std::pair endNode + = getClosestReachablePoint(pathgrid, &pathgridGraph, endPointInLocalCoords, startNode); // if it's shorter for actor to travel from start to end, than to travel from either // start or end to nearest pathgrid point, just travel from start to end. @@ -225,7 +226,7 @@ namespace MWMechanics // even if the start and the end points are the same. // NOTE: aStarSearch will return an empty path if the start and end // nodes are the same - if(startNode == endNode.first) + if (startNode == endNode.first) { ESM::Pathgrid::Point temp(pathgrid->mPoints[startNode]); converter.toWorld(temp); @@ -259,12 +260,10 @@ namespace MWMechanics } // convert supplied path to world coordinates - std::transform(path.begin(), path.end(), out, - [&] (ESM::Pathgrid::Point& point) - { - converter.toWorld(point); - return makeOsgVec3(point); - }); + std::transform(path.begin(), path.end(), out, [&](ESM::Pathgrid::Point& point) { + converter.toWorld(point); + return makeOsgVec3(point); + }); } // If endNode found is NOT the closest PathGrid point to the endPoint, @@ -287,7 +286,7 @@ namespace MWMechanics { // This should never happen (programmers should have an if statement checking // isPathConstructed that prevents this call if otherwise). - if(mPath.empty()) + if (mPath.empty()) return 0.; const auto& nextPoint = mPath.front(); @@ -301,7 +300,7 @@ namespace MWMechanics { // This should never happen (programmers should have an if statement checking // isPathConstructed that prevents this call if otherwise). - if(mPath.empty()) + if (mPath.empty()) return 0.; const osg::Vec3f dir = mPath.front() - osg::Vec3f(x, y, z); @@ -319,18 +318,16 @@ namespace MWMechanics while (mPath.size() > 1 && sqrDistanceIgnoreZ(mPath.front(), position) < pointTolerance * pointTolerance) mPath.pop_front(); - const IsValidShortcut isValidShortcut { - MWBase::Environment::get().getWorld()->getNavigator(), - agentBounds, flags - }; + const IsValidShortcut isValidShortcut{ MWBase::Environment::get().getWorld()->getNavigator(), agentBounds, + flags }; if (shortenIfAlmostStraight) { while (mPath.size() > 2 && isAlmostStraight(mPath[0], mPath[1], mPath[2], pointTolerance) - && isValidShortcut(mPath[0], mPath[2])) + && isValidShortcut(mPath[0], mPath[2])) mPath.erase(mPath.begin() + 1); if (mPath.size() > 1 && isAlmostStraight(position, mPath[0], mPath[1], pointTolerance) - && isValidShortcut(position, mPath[1])) + && isValidShortcut(position, mPath[1])) mPath.pop_front(); } @@ -397,9 +394,9 @@ namespace MWMechanics } void PathFinder::buildPath(const MWWorld::ConstPtr& actor, const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, - const MWWorld::CellStore* cell, const PathgridGraph& pathgridGraph, const DetourNavigator::AgentBounds& agentBounds, - const DetourNavigator::Flags flags, const DetourNavigator::AreaCosts& areaCosts, float endTolerance, - PathType pathType) + const MWWorld::CellStore* cell, const PathgridGraph& pathgridGraph, + const DetourNavigator::AgentBounds& agentBounds, const DetourNavigator::Flags flags, + const DetourNavigator::AreaCosts& areaCosts, float endTolerance, PathType pathType) { mPath.clear(); mCell = cell; @@ -408,16 +405,18 @@ namespace MWMechanics if (!actor.getClass().isPureWaterCreature(actor) && !actor.getClass().isPureFlyingCreature(actor)) { - status = buildPathByNavigatorImpl(actor, startPoint, endPoint, agentBounds, flags, areaCosts, - endTolerance, pathType, std::back_inserter(mPath)); + status = buildPathByNavigatorImpl(actor, startPoint, endPoint, agentBounds, flags, areaCosts, endTolerance, + pathType, std::back_inserter(mPath)); if (status != DetourNavigator::Status::Success) mPath.clear(); } - if (status != DetourNavigator::Status::NavMeshNotFound && mPath.empty() && (flags & DetourNavigator::Flag_usePathgrid) == 0) + if (status != DetourNavigator::Status::NavMeshNotFound && mPath.empty() + && (flags & DetourNavigator::Flag_usePathgrid) == 0) { status = buildPathByNavigatorImpl(actor, startPoint, endPoint, agentBounds, - flags | DetourNavigator::Flag_usePathgrid, areaCosts, endTolerance, pathType, std::back_inserter(mPath)); + flags | DetourNavigator::Flag_usePathgrid, areaCosts, endTolerance, pathType, + std::back_inserter(mPath)); if (status != DetourNavigator::Status::Success) mPath.clear(); } @@ -431,16 +430,16 @@ namespace MWMechanics mConstructed = !mPath.empty(); } - DetourNavigator::Status PathFinder::buildPathByNavigatorImpl(const MWWorld::ConstPtr& actor, const osg::Vec3f& startPoint, - const osg::Vec3f& endPoint, const DetourNavigator::AgentBounds& agentBounds, const DetourNavigator::Flags flags, - const DetourNavigator::AreaCosts& areaCosts, float endTolerance, PathType pathType, - std::back_insert_iterator> out) + DetourNavigator::Status PathFinder::buildPathByNavigatorImpl(const MWWorld::ConstPtr& actor, + const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, const DetourNavigator::AgentBounds& agentBounds, + const DetourNavigator::Flags flags, const DetourNavigator::AreaCosts& areaCosts, float endTolerance, + PathType pathType, std::back_insert_iterator> out) { const auto world = MWBase::Environment::get().getWorld(); const auto stepSize = getPathStepSize(actor); const auto navigator = world->getNavigator(); - const auto status = DetourNavigator::findPath(*navigator, agentBounds, stepSize, - startPoint, endPoint, flags, areaCosts, endTolerance, out); + const auto status = DetourNavigator::findPath( + *navigator, agentBounds, stepSize, startPoint, endPoint, flags, areaCosts, endTolerance, out); if (pathType == PathType::Partial && status == DetourNavigator::Status::PartialPath) return DetourNavigator::Status::Success; @@ -448,9 +447,9 @@ namespace MWMechanics if (status != DetourNavigator::Status::Success) { Log(Debug::Debug) << "Build path by navigator error: \"" << DetourNavigator::getMessage(status) - << "\" for \"" << actor.getClass().getName(actor) << "\" (" << actor.getBase() - << ") from " << startPoint << " to " << endPoint << " with flags (" - << DetourNavigator::WriteFlags {flags} << ")"; + << "\" for \"" << actor.getClass().getName(actor) << "\" (" << actor.getBase() + << ") from " << startPoint << " to " << endPoint << " with flags (" + << DetourNavigator::WriteFlags{ flags } << ")"; } return status; @@ -473,8 +472,8 @@ namespace MWMechanics std::deque prePath; auto prePathInserter = std::back_inserter(prePath); const float endTolerance = 0; - const auto status = DetourNavigator::findPath(*navigator, agentBounds, stepSize, - startPoint, mPath.front(), flags, areaCosts, endTolerance, prePathInserter); + const auto status = DetourNavigator::findPath(*navigator, agentBounds, stepSize, startPoint, mPath.front(), + flags, areaCosts, endTolerance, prePathInserter); if (status == DetourNavigator::Status::NavMeshNotFound) return; @@ -482,9 +481,9 @@ namespace MWMechanics if (status != DetourNavigator::Status::Success) { Log(Debug::Debug) << "Build path by navigator error: \"" << DetourNavigator::getMessage(status) - << "\" for \"" << actor.getClass().getName(actor) << "\" (" << actor.getBase() - << ") from " << startPoint << " to " << mPath.front() << " with flags (" - << DetourNavigator::WriteFlags {flags} << ")"; + << "\" for \"" << actor.getClass().getName(actor) << "\" (" << actor.getBase() + << ") from " << startPoint << " to " << mPath.front() << " with flags (" + << DetourNavigator::WriteFlags{ flags } << ")"; return; } @@ -497,21 +496,19 @@ namespace MWMechanics std::copy(prePath.rbegin(), prePath.rend(), std::front_inserter(mPath)); } - void PathFinder::buildLimitedPath(const MWWorld::ConstPtr& actor, const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, - const MWWorld::CellStore* cell, const PathgridGraph& pathgridGraph, + void PathFinder::buildLimitedPath(const MWWorld::ConstPtr& actor, const osg::Vec3f& startPoint, + const osg::Vec3f& endPoint, const MWWorld::CellStore* cell, const PathgridGraph& pathgridGraph, const DetourNavigator::AgentBounds& agentBounds, const DetourNavigator::Flags flags, const DetourNavigator::AreaCosts& areaCosts, float endTolerance, PathType pathType) { const auto navigator = MWBase::Environment::get().getWorld()->getNavigator(); - const auto maxDistance = std::min( - navigator->getMaxNavmeshAreaRealRadius(), - static_cast(Constants::CellSizeInUnits) - ); + const auto maxDistance + = std::min(navigator->getMaxNavmeshAreaRealRadius(), static_cast(Constants::CellSizeInUnits)); const auto startToEnd = endPoint - startPoint; const auto distance = startToEnd.length(); if (distance <= maxDistance) return buildPath(actor, startPoint, endPoint, cell, pathgridGraph, agentBounds, flags, areaCosts, - endTolerance, pathType); + endTolerance, pathType); const auto end = startPoint + startToEnd * maxDistance / distance; buildPath(actor, startPoint, end, cell, pathgridGraph, agentBounds, flags, areaCosts, endTolerance, pathType); } diff --git a/apps/openmw/mwmechanics/pathfinding.hpp b/apps/openmw/mwmechanics/pathfinding.hpp index c07b085e5a..330e9fbb0c 100644 --- a/apps/openmw/mwmechanics/pathfinding.hpp +++ b/apps/openmw/mwmechanics/pathfinding.hpp @@ -1,12 +1,12 @@ #ifndef GAME_MWMECHANICS_PATHFINDING_H #define GAME_MWMECHANICS_PATHFINDING_H -#include #include +#include #include -#include #include +#include #include #include #include @@ -30,9 +30,7 @@ namespace MWMechanics template inline float distance(const T& lhs, const T& rhs) { - static_assert(std::is_same::value - || std::is_same::value, - "T is not a position"); + static_assert(std::is_same::value || std::is_same::value, "T is not a position"); return (lhs - rhs).length(); } @@ -83,151 +81,138 @@ namespace MWMechanics class PathFinder { - public: - PathFinder() - : mConstructed(false) - , mCell(nullptr) - { - } - - void clearPath() + public: + PathFinder() + : mConstructed(false) + , mCell(nullptr) + { + } + + void clearPath() + { + mConstructed = false; + mPath.clear(); + mCell = nullptr; + } + + void buildStraightPath(const osg::Vec3f& endPoint); + + void buildPathByPathgrid(const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, + const MWWorld::CellStore* cell, const PathgridGraph& pathgridGraph); + + void buildPathByNavMesh(const MWWorld::ConstPtr& actor, const osg::Vec3f& startPoint, + const osg::Vec3f& endPoint, const DetourNavigator::AgentBounds& agentBounds, + const DetourNavigator::Flags flags, const DetourNavigator::AreaCosts& areaCosts, float endTolerance, + PathType pathType); + + void buildPath(const MWWorld::ConstPtr& actor, const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, + const MWWorld::CellStore* cell, const PathgridGraph& pathgridGraph, + const DetourNavigator::AgentBounds& agentBounds, const DetourNavigator::Flags flags, + const DetourNavigator::AreaCosts& areaCosts, float endTolerance, PathType pathType); + + void buildPathByNavMeshToNextPoint(const MWWorld::ConstPtr& actor, + const DetourNavigator::AgentBounds& agentBounds, const DetourNavigator::Flags flags, + const DetourNavigator::AreaCosts& areaCosts); + + void buildLimitedPath(const MWWorld::ConstPtr& actor, const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, + const MWWorld::CellStore* cell, const PathgridGraph& pathgridGraph, + const DetourNavigator::AgentBounds& agentBounds, const DetourNavigator::Flags flags, + const DetourNavigator::AreaCosts& areaCosts, float endTolerance, PathType pathType); + + /// Remove front point if exist and within tolerance + void update(const osg::Vec3f& position, float pointTolerance, float destinationTolerance, + bool shortenIfAlmostStraight, bool canMoveByZ, const DetourNavigator::AgentBounds& agentBounds, + const DetourNavigator::Flags flags); + + bool checkPathCompleted() const { return mConstructed && mPath.empty(); } + + /// In radians + float getZAngleToNext(float x, float y) const; + + float getXAngleToNext(float x, float y, float z) const; + + bool isPathConstructed() const { return mConstructed && !mPath.empty(); } + + std::size_t getPathSize() const { return mPath.size(); } + + const std::deque& getPath() const { return mPath; } + + const MWWorld::CellStore* getPathCell() const { return mCell; } + + void addPointToPath(const osg::Vec3f& point) + { + mConstructed = true; + mPath.push_back(point); + } + + /// utility function to convert a osg::Vec3f to a Pathgrid::Point + static ESM::Pathgrid::Point makePathgridPoint(const osg::Vec3f& v) + { + return ESM::Pathgrid::Point(static_cast(v[0]), static_cast(v[1]), static_cast(v[2])); + } + + /// utility function to convert an ESM::Position to a Pathgrid::Point + static ESM::Pathgrid::Point makePathgridPoint(const ESM::Position& p) + { + return ESM::Pathgrid::Point( + static_cast(p.pos[0]), static_cast(p.pos[1]), static_cast(p.pos[2])); + } + + static osg::Vec3f makeOsgVec3(const ESM::Pathgrid::Point& p) + { + return osg::Vec3f(static_cast(p.mX), static_cast(p.mY), static_cast(p.mZ)); + } + + // Slightly cheaper version for comparisons. + // Caller needs to be careful for very short distances (i.e. less than 1) + // or when accumuating the results i.e. (a + b)^2 != a^2 + b^2 + // + static float distanceSquared(const ESM::Pathgrid::Point& point, const osg::Vec3f& pos) + { + return (MWMechanics::PathFinder::makeOsgVec3(point) - pos).length2(); + } + + // Return the closest pathgrid point index from the specified position + // coordinates. NOTE: Does not check if there is a sensible way to get there + // (e.g. a cliff in front). + // + // NOTE: pos is expected to be in local coordinates, as is grid->mPoints + // + static int getClosestPoint(const ESM::Pathgrid* grid, const osg::Vec3f& pos) + { + assert(grid && !grid->mPoints.empty()); + + float distanceBetween = distanceSquared(grid->mPoints[0], pos); + int closestIndex = 0; + + // TODO: if this full scan causes performance problems mapping pathgrid + // points to a quadtree may help + for (unsigned int counter = 1; counter < grid->mPoints.size(); counter++) { - mConstructed = false; - mPath.clear(); - mCell = nullptr; - } - - void buildStraightPath(const osg::Vec3f& endPoint); - - void buildPathByPathgrid(const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, - const MWWorld::CellStore* cell, const PathgridGraph& pathgridGraph); - - void buildPathByNavMesh(const MWWorld::ConstPtr& actor, const osg::Vec3f& startPoint, - const osg::Vec3f& endPoint, const DetourNavigator::AgentBounds& agentBounds, - const DetourNavigator::Flags flags, const DetourNavigator::AreaCosts& areaCosts, float endTolerance, - PathType pathType); - - void buildPath(const MWWorld::ConstPtr& actor, const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, - const MWWorld::CellStore* cell, const PathgridGraph& pathgridGraph, - const DetourNavigator::AgentBounds& agentBounds, const DetourNavigator::Flags flags, - const DetourNavigator::AreaCosts& areaCosts, float endTolerance, PathType pathType); - - void buildPathByNavMeshToNextPoint(const MWWorld::ConstPtr& actor, const DetourNavigator::AgentBounds& agentBounds, - const DetourNavigator::Flags flags, const DetourNavigator::AreaCosts& areaCosts); - - void buildLimitedPath(const MWWorld::ConstPtr& actor, const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, - const MWWorld::CellStore* cell, const PathgridGraph& pathgridGraph, const DetourNavigator::AgentBounds& agentBounds, - const DetourNavigator::Flags flags, const DetourNavigator::AreaCosts& areaCosts, float endTolerance, - PathType pathType); - - /// Remove front point if exist and within tolerance - void update(const osg::Vec3f& position, float pointTolerance, float destinationTolerance, - bool shortenIfAlmostStraight, bool canMoveByZ, const DetourNavigator::AgentBounds& agentBounds, - const DetourNavigator::Flags flags); - - bool checkPathCompleted() const - { - return mConstructed && mPath.empty(); - } - - /// In radians - float getZAngleToNext(float x, float y) const; - - float getXAngleToNext(float x, float y, float z) const; - - bool isPathConstructed() const - { - return mConstructed && !mPath.empty(); - } - - std::size_t getPathSize() const - { - return mPath.size(); - } - - const std::deque& getPath() const - { - return mPath; - } - - const MWWorld::CellStore* getPathCell() const - { - return mCell; - } - - void addPointToPath(const osg::Vec3f& point) - { - mConstructed = true; - mPath.push_back(point); - } - - /// utility function to convert a osg::Vec3f to a Pathgrid::Point - static ESM::Pathgrid::Point makePathgridPoint(const osg::Vec3f& v) - { - return ESM::Pathgrid::Point(static_cast(v[0]), static_cast(v[1]), static_cast(v[2])); - } - - /// utility function to convert an ESM::Position to a Pathgrid::Point - static ESM::Pathgrid::Point makePathgridPoint(const ESM::Position& p) - { - return ESM::Pathgrid::Point(static_cast(p.pos[0]), static_cast(p.pos[1]), static_cast(p.pos[2])); - } - - static osg::Vec3f makeOsgVec3(const ESM::Pathgrid::Point& p) - { - return osg::Vec3f(static_cast(p.mX), static_cast(p.mY), static_cast(p.mZ)); - } - - // Slightly cheaper version for comparisons. - // Caller needs to be careful for very short distances (i.e. less than 1) - // or when accumuating the results i.e. (a + b)^2 != a^2 + b^2 - // - static float distanceSquared(const ESM::Pathgrid::Point& point, const osg::Vec3f& pos) - { - return (MWMechanics::PathFinder::makeOsgVec3(point) - pos).length2(); - } - - // Return the closest pathgrid point index from the specified position - // coordinates. NOTE: Does not check if there is a sensible way to get there - // (e.g. a cliff in front). - // - // NOTE: pos is expected to be in local coordinates, as is grid->mPoints - // - static int getClosestPoint(const ESM::Pathgrid* grid, const osg::Vec3f& pos) - { - assert(grid && !grid->mPoints.empty()); - - float distanceBetween = distanceSquared(grid->mPoints[0], pos); - int closestIndex = 0; - - // TODO: if this full scan causes performance problems mapping pathgrid - // points to a quadtree may help - for(unsigned int counter = 1; counter < grid->mPoints.size(); counter++) + float potentialDistBetween = distanceSquared(grid->mPoints[counter], pos); + if (potentialDistBetween < distanceBetween) { - float potentialDistBetween = distanceSquared(grid->mPoints[counter], pos); - if(potentialDistBetween < distanceBetween) - { - distanceBetween = potentialDistBetween; - closestIndex = counter; - } + distanceBetween = potentialDistBetween; + closestIndex = counter; } - - return closestIndex; } - private: - bool mConstructed; - std::deque mPath; + return closestIndex; + } + + private: + bool mConstructed; + std::deque mPath; - const MWWorld::CellStore* mCell; + const MWWorld::CellStore* mCell; - void buildPathByPathgridImpl(const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, - const PathgridGraph& pathgridGraph, std::back_insert_iterator> out); + void buildPathByPathgridImpl(const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, + const PathgridGraph& pathgridGraph, std::back_insert_iterator> out); - [[nodiscard]] DetourNavigator::Status buildPathByNavigatorImpl(const MWWorld::ConstPtr& actor, - const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, const DetourNavigator::AgentBounds& agentBounds, - const DetourNavigator::Flags flags, const DetourNavigator::AreaCosts& areaCosts, float endTolerance, PathType pathType, - std::back_insert_iterator> out); + [[nodiscard]] DetourNavigator::Status buildPathByNavigatorImpl(const MWWorld::ConstPtr& actor, + const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, const DetourNavigator::AgentBounds& agentBounds, + const DetourNavigator::Flags flags, const DetourNavigator::AreaCosts& areaCosts, float endTolerance, + PathType pathType, std::back_insert_iterator> out); }; } diff --git a/apps/openmw/mwmechanics/pathgrid.cpp b/apps/openmw/mwmechanics/pathgrid.cpp index ee1de3b5ad..6cac10c1be 100644 --- a/apps/openmw/mwmechanics/pathgrid.cpp +++ b/apps/openmw/mwmechanics/pathgrid.cpp @@ -1,7 +1,7 @@ #include "pathgrid.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" #include "../mwworld/cellstore.hpp" #include "../mwworld/esmstore.hpp" @@ -42,14 +42,14 @@ namespace // - faster but not the shortest path float costAStar(const ESM::Pathgrid::Point& a, const ESM::Pathgrid::Point& b) { - //return distance(a, b); + // return distance(a, b); return manhattan(a, b); } } namespace MWMechanics { - PathgridGraph::PathgridGraph(const MWWorld::CellStore *cell) + PathgridGraph::PathgridGraph(const MWWorld::CellStore* cell) : mCell(nullptr) , mPathgrid(nullptr) , mGraph(0) @@ -96,40 +96,39 @@ namespace MWMechanics * +----------------> * high cost */ - bool PathgridGraph::load(const MWWorld::CellStore *cell) + bool PathgridGraph::load(const MWWorld::CellStore* cell) { - if(!cell) + if (!cell) return false; - if(mIsGraphConstructed) + if (mIsGraphConstructed) return true; mCell = cell->getCell(); mPathgrid = MWBase::Environment::get().getWorld()->getStore().get().search(*cell->getCell()); - if(!mPathgrid) + if (!mPathgrid) return false; - mGraph.resize(mPathgrid->mPoints.size()); - for(int i = 0; i < static_cast (mPathgrid->mEdges.size()); i++) + for (int i = 0; i < static_cast(mPathgrid->mEdges.size()); i++) { ConnectedPoint neighbour; - neighbour.cost = costAStar(mPathgrid->mPoints[mPathgrid->mEdges[i].mV0], - mPathgrid->mPoints[mPathgrid->mEdges[i].mV1]); + neighbour.cost + = costAStar(mPathgrid->mPoints[mPathgrid->mEdges[i].mV0], mPathgrid->mPoints[mPathgrid->mEdges[i].mV1]); // forward path of the edge neighbour.index = mPathgrid->mEdges[i].mV1; mGraph[mPathgrid->mEdges[i].mV0].edges.push_back(neighbour); // reverse path of the edge // NOTE: These are redundant, ESM already contains the required reverse paths - //neighbour.index = mPathgrid->mEdges[i].mV0; - //mGraph[mPathgrid->mEdges[i].mV1].edges.push_back(neighbour); + // neighbour.index = mPathgrid->mEdges[i].mV0; + // mGraph[mPathgrid->mEdges[i].mV1].edges.push_back(neighbour); } buildConnectedPoints(); mIsGraphConstructed = true; return true; } - const ESM::Pathgrid *PathgridGraph::getPathgrid() const + const ESM::Pathgrid* PathgridGraph::getPathgrid() const { return mPathgrid; } @@ -137,38 +136,35 @@ namespace MWMechanics // v is the pathgrid point index (some call them vertices) void PathgridGraph::recursiveStrongConnect(int v) { - mSCCPoint[v].first = mSCCIndex; // index + mSCCPoint[v].first = mSCCIndex; // index mSCCPoint[v].second = mSCCIndex; // lowlink mSCCIndex++; mSCCStack.push_back(v); int w; - for(int i = 0; i < static_cast (mGraph[v].edges.size()); i++) + for (int i = 0; i < static_cast(mGraph[v].edges.size()); i++) { w = mGraph[v].edges[i].index; - if(mSCCPoint[w].first == -1) // not visited + if (mSCCPoint[w].first == -1) // not visited { recursiveStrongConnect(w); // recurse - mSCCPoint[v].second = std::min(mSCCPoint[v].second, - mSCCPoint[w].second); + mSCCPoint[v].second = std::min(mSCCPoint[v].second, mSCCPoint[w].second); } else { - if(find(mSCCStack.begin(), mSCCStack.end(), w) != mSCCStack.end()) - mSCCPoint[v].second = std::min(mSCCPoint[v].second, - mSCCPoint[w].first); + if (find(mSCCStack.begin(), mSCCStack.end(), w) != mSCCStack.end()) + mSCCPoint[v].second = std::min(mSCCPoint[v].second, mSCCPoint[w].first); } } - if(mSCCPoint[v].second == mSCCPoint[v].first) - { // new component + if (mSCCPoint[v].second == mSCCPoint[v].first) + { // new component do { w = mSCCStack.back(); mSCCStack.pop_back(); mGraph[w].componentId = mSCCId; - } - while(w != v); + } while (w != v); mSCCId++; } return; @@ -200,15 +196,15 @@ namespace MWMechanics void PathgridGraph::buildConnectedPoints() { // both of these are set to zero in the constructor - //mSCCId = 0; // how many strongly connected components in this cell - //mSCCIndex = 0; - int pointsSize = static_cast (mPathgrid->mPoints.size()); - mSCCPoint.resize(pointsSize, std::pair (-1, -1)); + // mSCCId = 0; // how many strongly connected components in this cell + // mSCCIndex = 0; + int pointsSize = static_cast(mPathgrid->mPoints.size()); + mSCCPoint.resize(pointsSize, std::pair(-1, -1)); mSCCStack.reserve(pointsSize); - for(int v = 0; v < pointsSize; v++) + for (int v = 0; v < pointsSize; v++) { - if(mSCCPoint[v].first == -1) // undefined (haven't visited) + if (mSCCPoint[v].first == -1) // undefined (haven't visited) recursiveStrongConnect(v); } } @@ -218,9 +214,9 @@ namespace MWMechanics return (mGraph[start].componentId == mGraph[end].componentId); } - void PathgridGraph::getNeighbouringPoints(const int index, ESM::Pathgrid::PointList &nodes) const + void PathgridGraph::getNeighbouringPoints(const int index, ESM::Pathgrid::PointList& nodes) const { - for(int i = 0; i < static_cast (mGraph[index].edges.size()); i++) + for (int i = 0; i < static_cast(mGraph[index].edges.size()); i++) { int neighbourIndex = mGraph[index].edges[i].index; if (neighbourIndex != index) @@ -258,15 +254,15 @@ namespace MWMechanics std::deque PathgridGraph::aStarSearch(const int start, const int goal) const { std::deque path; - if(!isPointConnected(start, goal)) + if (!isPointConnected(start, goal)) { return path; // there is no path, return an empty path } - int graphSize = static_cast (mGraph.size()); - std::vector gScore (graphSize, -1); - std::vector fScore (graphSize, -1); - std::vector graphParent (graphSize, -1); + int graphSize = static_cast(mGraph.size()); + std::vector gScore(graphSize, -1); + std::vector fScore(graphSize, -1); + std::vector graphParent(graphSize, -1); // gScore & fScore keep costs for each pathgrid point in mPoints gScore[start] = 0; @@ -278,41 +274,38 @@ namespace MWMechanics int current = -1; - while(!openset.empty()) + while (!openset.empty()) { current = openset.front(); // front has the lowest cost openset.pop_front(); - if(current == goal) + if (current == goal) break; closedset.push_back(current); // remember we've been here // check all edges for the current point index - for(int j = 0; j < static_cast (mGraph[current].edges.size()); j++) + for (int j = 0; j < static_cast(mGraph[current].edges.size()); j++) { - if(std::find(closedset.begin(), closedset.end(), mGraph[current].edges[j].index) == - closedset.end()) + if (std::find(closedset.begin(), closedset.end(), mGraph[current].edges[j].index) == closedset.end()) { // not in closedset - i.e. have not traversed this edge destination int dest = mGraph[current].edges[j].index; float tentative_g = gScore[current] + mGraph[current].edges[j].cost; bool isInOpenSet = std::find(openset.begin(), openset.end(), dest) != openset.end(); - if(!isInOpenSet - || tentative_g < gScore[dest]) + if (!isInOpenSet || tentative_g < gScore[dest]) { graphParent[dest] = current; gScore[dest] = tentative_g; - fScore[dest] = tentative_g + costAStar(mPathgrid->mPoints[dest], - mPathgrid->mPoints[goal]); - if(!isInOpenSet) + fScore[dest] = tentative_g + costAStar(mPathgrid->mPoints[dest], mPathgrid->mPoints[goal]); + if (!isInOpenSet) { // add this edge to openset, lowest cost goes to the front // TODO: if this causes performance problems a hash table may help std::list::iterator it = openset.begin(); - for(it = openset.begin(); it!= openset.end(); ++it) + for (it = openset.begin(); it != openset.end(); ++it) { - if(fScore[*it] > fScore[dest]) + if (fScore[*it] > fScore[dest]) break; } openset.insert(it, dest); @@ -322,11 +315,11 @@ namespace MWMechanics } } - if(current != goal) + if (current != goal) return path; // for some reason couldn't build a path // reconstruct path to return, using local coordinates - while(graphParent[current] != -1) + while (graphParent[current] != -1) { path.push_front(mPathgrid->mPoints[current]); current = graphParent[current]; @@ -337,4 +330,3 @@ namespace MWMechanics return path; } } - diff --git a/apps/openmw/mwmechanics/pathgrid.hpp b/apps/openmw/mwmechanics/pathgrid.hpp index dfe958e745..a681033dca 100644 --- a/apps/openmw/mwmechanics/pathgrid.hpp +++ b/apps/openmw/mwmechanics/pathgrid.hpp @@ -19,65 +19,64 @@ namespace MWMechanics { class PathgridGraph { - public: - PathgridGraph(const MWWorld::CellStore* cell); - - bool load(const MWWorld::CellStore *cell); - - const ESM::Pathgrid* getPathgrid() const; - - // returns true if end point is strongly connected (i.e. reachable - // from start point) both start and end are pathgrid point indexes - bool isPointConnected(const int start, const int end) const; - - // get neighbouring nodes for index node and put them to "nodes" vector - void getNeighbouringPoints(const int index, ESM::Pathgrid::PointList &nodes) const; - - // the input parameters are pathgrid point indexes - // the output list is in local (internal cells) or world (external - // cells) coordinates - // - // NOTE: if start equals end an empty path is returned - std::deque aStarSearch(const int start, const int end) const; - - private: - - const ESM::Cell *mCell; - const ESM::Pathgrid *mPathgrid; - - struct ConnectedPoint // edge - { - int index; // pathgrid point index of neighbour - float cost; - }; - - struct Node // point - { - int componentId; - std::vector edges; // neighbours - }; - - // componentId is an integer indicating the groups of connected - // pathgrid points (all connected points will have the same value) - // - // In Seyda Neen there are 3: - // - // 52, 53 and 54 are one set (enclosed yard) - // 48, 49, 50, 51, 84, 85, 86, 87, 88, 89, 90 (ship & office) - // all other pathgrid points are the third set - // - std::vector mGraph; - bool mIsGraphConstructed; - - // variables used to calculate connected components - int mSCCId; - int mSCCIndex; - std::vector mSCCStack; - typedef std::pair VPair; // first is index, second is lowlink - std::vector mSCCPoint; - // methods used to calculate connected components - void recursiveStrongConnect(int v); - void buildConnectedPoints(); + public: + PathgridGraph(const MWWorld::CellStore* cell); + + bool load(const MWWorld::CellStore* cell); + + const ESM::Pathgrid* getPathgrid() const; + + // returns true if end point is strongly connected (i.e. reachable + // from start point) both start and end are pathgrid point indexes + bool isPointConnected(const int start, const int end) const; + + // get neighbouring nodes for index node and put them to "nodes" vector + void getNeighbouringPoints(const int index, ESM::Pathgrid::PointList& nodes) const; + + // the input parameters are pathgrid point indexes + // the output list is in local (internal cells) or world (external + // cells) coordinates + // + // NOTE: if start equals end an empty path is returned + std::deque aStarSearch(const int start, const int end) const; + + private: + const ESM::Cell* mCell; + const ESM::Pathgrid* mPathgrid; + + struct ConnectedPoint // edge + { + int index; // pathgrid point index of neighbour + float cost; + }; + + struct Node // point + { + int componentId; + std::vector edges; // neighbours + }; + + // componentId is an integer indicating the groups of connected + // pathgrid points (all connected points will have the same value) + // + // In Seyda Neen there are 3: + // + // 52, 53 and 54 are one set (enclosed yard) + // 48, 49, 50, 51, 84, 85, 86, 87, 88, 89, 90 (ship & office) + // all other pathgrid points are the third set + // + std::vector mGraph; + bool mIsGraphConstructed; + + // variables used to calculate connected components + int mSCCId; + int mSCCIndex; + std::vector mSCCStack; + typedef std::pair VPair; // first is index, second is lowlink + std::vector mSCCPoint; + // methods used to calculate connected components + void recursiveStrongConnect(int v); + void buildConnectedPoints(); }; } diff --git a/apps/openmw/mwmechanics/pickpocket.cpp b/apps/openmw/mwmechanics/pickpocket.cpp index 1b638eadd2..58c871880f 100644 --- a/apps/openmw/mwmechanics/pickpocket.cpp +++ b/apps/openmw/mwmechanics/pickpocket.cpp @@ -5,21 +5,21 @@ #include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" #include "npcstats.hpp" namespace MWMechanics { - Pickpocket::Pickpocket(const MWWorld::Ptr &thief, const MWWorld::Ptr &victim) + Pickpocket::Pickpocket(const MWWorld::Ptr& thief, const MWWorld::Ptr& victim) : mThief(thief) , mVictim(victim) { } - float Pickpocket::getChanceModifier(const MWWorld::Ptr &ptr, float add) + float Pickpocket::getChanceModifier(const MWWorld::Ptr& ptr, float add) { NpcStats& stats = ptr.getClass().getNpcStats(ptr); float agility = stats.getAttribute(ESM::Attribute::Agility).getModified(); @@ -33,13 +33,21 @@ namespace MWMechanics float x = getChanceModifier(mThief); float y = getChanceModifier(mVictim, valueTerm); - float t = 2*x - y; + float t = 2 * x - y; float pcSneak = static_cast(mThief.getClass().getSkill(mThief, ESM::Skill::Sneak)); - int iPickMinChance = MWBase::Environment::get().getWorld()->getStore().get() - .find("iPickMinChance")->mValue.getInteger(); - int iPickMaxChance = MWBase::Environment::get().getWorld()->getStore().get() - .find("iPickMaxChance")->mValue.getInteger(); + int iPickMinChance = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("iPickMinChance") + ->mValue.getInteger(); + int iPickMaxChance = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("iPickMaxChance") + ->mValue.getInteger(); auto& prng = MWBase::Environment::get().getWorld()->getPrng(); int roll = Misc::Rng::roll0to99(prng); @@ -57,8 +65,12 @@ namespace MWMechanics bool Pickpocket::pick(const MWWorld::Ptr& item, int count) { float stackValue = static_cast(item.getClass().getValue(item) * count); - float fPickPocketMod = MWBase::Environment::get().getWorld()->getStore().get() - .find("fPickPocketMod")->mValue.getFloat(); + float fPickPocketMod = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fPickPocketMod") + ->mValue.getFloat(); float valueTerm = 10 * fPickPocketMod * stackValue; return getDetected(valueTerm); diff --git a/apps/openmw/mwmechanics/pickpocket.hpp b/apps/openmw/mwmechanics/pickpocket.hpp index 0957b7a680..83dbca69c2 100644 --- a/apps/openmw/mwmechanics/pickpocket.hpp +++ b/apps/openmw/mwmechanics/pickpocket.hpp @@ -9,18 +9,18 @@ namespace MWMechanics class Pickpocket { public: - Pickpocket (const MWWorld::Ptr& thief, const MWWorld::Ptr& victim); + Pickpocket(const MWWorld::Ptr& thief, const MWWorld::Ptr& victim); /// Steal some items /// @return Was the thief detected? - bool pick (const MWWorld::Ptr& item, int count); + bool pick(const MWWorld::Ptr& item, int count); /// End the pickpocketing process /// @return Was the thief detected? - bool finish (); + bool finish(); private: bool getDetected(float valueTerm); - float getChanceModifier(const MWWorld::Ptr& ptr, float add=0); + float getChanceModifier(const MWWorld::Ptr& ptr, float add = 0); MWWorld::Ptr mThief; MWWorld::Ptr mVictim; }; diff --git a/apps/openmw/mwmechanics/recharge.cpp b/apps/openmw/mwmechanics/recharge.cpp index d15b44d298..707edb0930 100644 --- a/apps/openmw/mwmechanics/recharge.cpp +++ b/apps/openmw/mwmechanics/recharge.cpp @@ -1,96 +1,108 @@ #include "recharge.hpp" +#include +#include #include #include -#include -#include -#include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" -#include "../mwworld/containerstore.hpp" #include "../mwworld/class.hpp" +#include "../mwworld/containerstore.hpp" #include "../mwworld/esmstore.hpp" -#include "creaturestats.hpp" #include "actorutil.hpp" +#include "creaturestats.hpp" namespace MWMechanics { -bool rechargeItem(const MWWorld::Ptr &item, const float maxCharge, const float duration) -{ - float charge = item.getCellRef().getEnchantmentCharge(); - if (charge == -1 || charge == maxCharge) - return false; - - static const float fMagicItemRechargePerSecond = MWBase::Environment::get().getWorld()->getStore().get().find( - "fMagicItemRechargePerSecond")->mValue.getFloat(); - - item.getCellRef().setEnchantmentCharge(std::min(charge + fMagicItemRechargePerSecond * duration, maxCharge)); - return true; -} - -bool rechargeItem(const MWWorld::Ptr &item, const MWWorld::Ptr &gem) -{ - if (!gem.getRefData().getCount()) - return false; - - MWWorld::Ptr player = MWMechanics::getPlayer(); - MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player); - - float luckTerm = 0.1f * stats.getAttribute(ESM::Attribute::Luck).getModified(); - if (luckTerm < 1 || luckTerm > 10) - luckTerm = 1; - - float intelligenceTerm = 0.2f * stats.getAttribute(ESM::Attribute::Intelligence).getModified(); - - if (intelligenceTerm > 20) - intelligenceTerm = 20; - if (intelligenceTerm < 1) - intelligenceTerm = 1; + bool rechargeItem(const MWWorld::Ptr& item, const float maxCharge, const float duration) + { + float charge = item.getCellRef().getEnchantmentCharge(); + if (charge == -1 || charge == maxCharge) + return false; + + static const float fMagicItemRechargePerSecond = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fMagicItemRechargePerSecond") + ->mValue.getFloat(); + + item.getCellRef().setEnchantmentCharge(std::min(charge + fMagicItemRechargePerSecond * duration, maxCharge)); + return true; + } - float x = (player.getClass().getSkill(player, ESM::Skill::Enchant) + intelligenceTerm + luckTerm) * stats.getFatigueTerm(); - auto& prng = MWBase::Environment::get().getWorld()->getPrng(); - int roll = Misc::Rng::roll0to99(prng); - if (roll < x) + bool rechargeItem(const MWWorld::Ptr& item, const MWWorld::Ptr& gem) { - const std::string& soul = gem.getCellRef().getSoul(); - const ESM::Creature *creature = MWBase::Environment::get().getWorld()->getStore().get().find(soul); + if (!gem.getRefData().getCount()) + return false; - float restored = creature->mData.mSoul * (roll / x); + MWWorld::Ptr player = MWMechanics::getPlayer(); + MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player); - const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get().find( - item.getClass().getEnchantment(item)); - item.getCellRef().setEnchantmentCharge( - std::min(item.getCellRef().getEnchantmentCharge() + restored, static_cast(enchantment->mData.mCharge))); + float luckTerm = 0.1f * stats.getAttribute(ESM::Attribute::Luck).getModified(); + if (luckTerm < 1 || luckTerm > 10) + luckTerm = 1; - MWBase::Environment::get().getWindowManager()->playSound("Enchant Success"); + float intelligenceTerm = 0.2f * stats.getAttribute(ESM::Attribute::Intelligence).getModified(); - player.getClass().getContainerStore(player).restack(item); - } - else - { - MWBase::Environment::get().getWindowManager()->playSound("Enchant Fail"); - } + if (intelligenceTerm > 20) + intelligenceTerm = 20; + if (intelligenceTerm < 1) + intelligenceTerm = 1; - player.getClass().skillUsageSucceeded (player, ESM::Skill::Enchant, 0); - gem.getContainerStore()->remove(gem, 1, player); - - if (gem.getRefData().getCount() == 0) - { - std::string message = MWBase::Environment::get().getWorld()->getStore().get().find("sNotifyMessage51")->mValue.getString(); - message = Misc::StringUtils::format(message, gem.getClass().getName(gem)); + float x = (player.getClass().getSkill(player, ESM::Skill::Enchant) + intelligenceTerm + luckTerm) + * stats.getFatigueTerm(); + auto& prng = MWBase::Environment::get().getWorld()->getPrng(); + int roll = Misc::Rng::roll0to99(prng); + if (roll < x) + { + const std::string& soul = gem.getCellRef().getSoul(); + const ESM::Creature* creature + = MWBase::Environment::get().getWorld()->getStore().get().find(soul); - MWBase::Environment::get().getWindowManager()->messageBox(message); + float restored = creature->mData.mSoul * (roll / x); - // special case: readd Azura's Star - if (Misc::StringUtils::ciEqual(gem.get()->mBase->mId, "Misc_SoulGem_Azura")) - player.getClass().getContainerStore(player).add("Misc_SoulGem_Azura", 1, player); + const ESM::Enchantment* enchantment + = MWBase::Environment::get().getWorld()->getStore().get().find( + item.getClass().getEnchantment(item)); + item.getCellRef().setEnchantmentCharge(std::min( + item.getCellRef().getEnchantmentCharge() + restored, static_cast(enchantment->mData.mCharge))); + + MWBase::Environment::get().getWindowManager()->playSound("Enchant Success"); + + player.getClass().getContainerStore(player).restack(item); + } + else + { + MWBase::Environment::get().getWindowManager()->playSound("Enchant Fail"); + } + + player.getClass().skillUsageSucceeded(player, ESM::Skill::Enchant, 0); + gem.getContainerStore()->remove(gem, 1, player); + + if (gem.getRefData().getCount() == 0) + { + std::string message = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("sNotifyMessage51") + ->mValue.getString(); + message = Misc::StringUtils::format(message, gem.getClass().getName(gem)); + + MWBase::Environment::get().getWindowManager()->messageBox(message); + + // special case: readd Azura's Star + if (Misc::StringUtils::ciEqual(gem.get()->mBase->mId, "Misc_SoulGem_Azura")) + player.getClass().getContainerStore(player).add("Misc_SoulGem_Azura", 1, player); + } + + return true; } - return true; -} - } diff --git a/apps/openmw/mwmechanics/recharge.hpp b/apps/openmw/mwmechanics/recharge.hpp index 913f2109b7..ac1c7ced54 100644 --- a/apps/openmw/mwmechanics/recharge.hpp +++ b/apps/openmw/mwmechanics/recharge.hpp @@ -6,9 +6,9 @@ namespace MWMechanics { - bool rechargeItem(const MWWorld::Ptr &item, const float maxCharge, const float duration); + bool rechargeItem(const MWWorld::Ptr& item, const float maxCharge, const float duration); - bool rechargeItem(const MWWorld::Ptr &item, const MWWorld::Ptr &gem); + bool rechargeItem(const MWWorld::Ptr& item, const MWWorld::Ptr& gem); } diff --git a/apps/openmw/mwmechanics/repair.cpp b/apps/openmw/mwmechanics/repair.cpp index 266b8dd3c4..42e2fcfe9a 100644 --- a/apps/openmw/mwmechanics/repair.cpp +++ b/apps/openmw/mwmechanics/repair.cpp @@ -3,107 +3,113 @@ #include #include -#include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" -#include "../mwworld/containerstore.hpp" #include "../mwworld/class.hpp" +#include "../mwworld/containerstore.hpp" #include "../mwworld/esmstore.hpp" -#include "creaturestats.hpp" #include "actorutil.hpp" +#include "creaturestats.hpp" namespace MWMechanics { -void Repair::repair(const MWWorld::Ptr &itemToRepair) -{ - MWWorld::Ptr player = getPlayer(); - MWWorld::LiveCellRef *ref = - mTool.get(); + void Repair::repair(const MWWorld::Ptr& itemToRepair) + { + MWWorld::Ptr player = getPlayer(); + MWWorld::LiveCellRef* ref = mTool.get(); - // unstack tool if required - player.getClass().getContainerStore(player).unstack(mTool, player); + // unstack tool if required + player.getClass().getContainerStore(player).unstack(mTool, player); - // reduce number of uses left - int uses = mTool.getClass().getItemHealth(mTool); - uses -= std::min(uses, 1); - mTool.getCellRef().setCharge(uses); + // reduce number of uses left + int uses = mTool.getClass().getItemHealth(mTool); + uses -= std::min(uses, 1); + mTool.getCellRef().setCharge(uses); - MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player); + MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player); - float fatigueTerm = stats.getFatigueTerm(); - float pcStrength = stats.getAttribute(ESM::Attribute::Strength).getModified(); - float pcLuck = stats.getAttribute(ESM::Attribute::Luck).getModified(); - float armorerSkill = player.getClass().getSkill(player, ESM::Skill::Armorer); + float fatigueTerm = stats.getFatigueTerm(); + float pcStrength = stats.getAttribute(ESM::Attribute::Strength).getModified(); + float pcLuck = stats.getAttribute(ESM::Attribute::Luck).getModified(); + float armorerSkill = player.getClass().getSkill(player, ESM::Skill::Armorer); - float fRepairAmountMult = MWBase::Environment::get().getWorld()->getStore().get() - .find("fRepairAmountMult")->mValue.getFloat(); + float fRepairAmountMult = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fRepairAmountMult") + ->mValue.getFloat(); - float toolQuality = ref->mBase->mData.mQuality; + float toolQuality = ref->mBase->mData.mQuality; - float x = (0.1f * pcStrength + 0.1f * pcLuck + armorerSkill) * fatigueTerm; + float x = (0.1f * pcStrength + 0.1f * pcLuck + armorerSkill) * fatigueTerm; - auto& prng = MWBase::Environment::get().getWorld()->getPrng(); - int roll = Misc::Rng::roll0to99(prng); - if (roll <= x) - { - int y = static_cast(fRepairAmountMult * toolQuality * roll); - y = std::max(1, y); + auto& prng = MWBase::Environment::get().getWorld()->getPrng(); + int roll = Misc::Rng::roll0to99(prng); + if (roll <= x) + { + int y = static_cast(fRepairAmountMult * toolQuality * roll); + y = std::max(1, y); - // repair by 'y' points - int charge = itemToRepair.getClass().getItemHealth(itemToRepair); - charge = std::min(charge + y, itemToRepair.getClass().getItemMaxHealth(itemToRepair)); - itemToRepair.getCellRef().setCharge(charge); + // repair by 'y' points + int charge = itemToRepair.getClass().getItemHealth(itemToRepair); + charge = std::min(charge + y, itemToRepair.getClass().getItemMaxHealth(itemToRepair)); + itemToRepair.getCellRef().setCharge(charge); - // attempt to re-stack item, in case it was fully repaired - MWWorld::ContainerStoreIterator stacked = player.getClass().getContainerStore(player).restack(itemToRepair); + // attempt to re-stack item, in case it was fully repaired + MWWorld::ContainerStoreIterator stacked = player.getClass().getContainerStore(player).restack(itemToRepair); - // set the OnPCRepair variable on the item's script - std::string_view script = stacked->getClass().getScript(itemToRepair); - if(!script.empty()) - stacked->getRefData().getLocals().setVarByInt(script, "onpcrepair", 1); + // set the OnPCRepair variable on the item's script + std::string_view script = stacked->getClass().getScript(itemToRepair); + if (!script.empty()) + stacked->getRefData().getLocals().setVarByInt(script, "onpcrepair", 1); - // increase skill - player.getClass().skillUsageSucceeded(player, ESM::Skill::Armorer, 0); + // increase skill + player.getClass().skillUsageSucceeded(player, ESM::Skill::Armorer, 0); - MWBase::Environment::get().getWindowManager()->playSound("Repair"); - MWBase::Environment::get().getWindowManager()->messageBox("#{sRepairSuccess}"); - } - else - { - MWBase::Environment::get().getWindowManager()->playSound("Repair Fail"); - MWBase::Environment::get().getWindowManager()->messageBox("#{sRepairFailed}"); - } + MWBase::Environment::get().getWindowManager()->playSound("Repair"); + MWBase::Environment::get().getWindowManager()->messageBox("#{sRepairSuccess}"); + } + else + { + MWBase::Environment::get().getWindowManager()->playSound("Repair Fail"); + MWBase::Environment::get().getWindowManager()->messageBox("#{sRepairFailed}"); + } - // tool used up? - if (mTool.getCellRef().getCharge() == 0) - { - MWWorld::ContainerStore& store = player.getClass().getContainerStore(player); + // tool used up? + if (mTool.getCellRef().getCharge() == 0) + { + MWWorld::ContainerStore& store = player.getClass().getContainerStore(player); - store.remove(mTool, 1, player); + store.remove(mTool, 1, player); - std::string message = MWBase::Environment::get().getWorld()->getStore().get() - .find("sNotifyMessage51")->mValue.getString(); - message = Misc::StringUtils::format(message, mTool.getClass().getName(mTool)); + std::string message = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("sNotifyMessage51") + ->mValue.getString(); + message = Misc::StringUtils::format(message, mTool.getClass().getName(mTool)); - MWBase::Environment::get().getWindowManager()->messageBox(message); + MWBase::Environment::get().getWindowManager()->messageBox(message); - // try to find a new tool of the same ID - for (MWWorld::ContainerStoreIterator iter (store.begin()); - iter!=store.end(); ++iter) - { - if (Misc::StringUtils::ciEqual(iter->getCellRef().getRefId(), mTool.getCellRef().getRefId())) + // try to find a new tool of the same ID + for (MWWorld::ContainerStoreIterator iter(store.begin()); iter != store.end(); ++iter) { - mTool = *iter; + if (Misc::StringUtils::ciEqual(iter->getCellRef().getRefId(), mTool.getCellRef().getRefId())) + { + mTool = *iter; - MWBase::Environment::get().getWindowManager()->playSound("Item Repair Up"); + MWBase::Environment::get().getWindowManager()->playSound("Item Repair Up"); - break; + break; + } } } } -} } diff --git a/apps/openmw/mwmechanics/repair.hpp b/apps/openmw/mwmechanics/repair.hpp index 6f9a866af1..a596f0d28b 100644 --- a/apps/openmw/mwmechanics/repair.hpp +++ b/apps/openmw/mwmechanics/repair.hpp @@ -9,10 +9,10 @@ namespace MWMechanics class Repair { public: - void setTool (const MWWorld::Ptr& tool) { mTool = tool; } + void setTool(const MWWorld::Ptr& tool) { mTool = tool; } MWWorld::Ptr getTool() { return mTool; } - void repair (const MWWorld::Ptr& itemToRepair); + void repair(const MWWorld::Ptr& itemToRepair); private: MWWorld::Ptr mTool; diff --git a/apps/openmw/mwmechanics/security.cpp b/apps/openmw/mwmechanics/security.cpp index d41bf817a3..e42a7829f8 100644 --- a/apps/openmw/mwmechanics/security.cpp +++ b/apps/openmw/mwmechanics/security.cpp @@ -6,16 +6,16 @@ #include "../mwworld/containerstore.hpp" #include "../mwworld/esmstore.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/world.hpp" #include "creaturestats.hpp" namespace MWMechanics { - Security::Security(const MWWorld::Ptr &actor) + Security::Security(const MWWorld::Ptr& actor) : mActor(actor) { CreatureStats& creatureStats = actor.getClass().getCreatureStats(actor); @@ -25,12 +25,11 @@ namespace MWMechanics mFatigueTerm = creatureStats.getFatigueTerm(); } - void Security::pickLock(const MWWorld::Ptr &lock, const MWWorld::Ptr &lockpick, - std::string_view& resultMessage, std::string_view& resultSound) + void Security::pickLock(const MWWorld::Ptr& lock, const MWWorld::Ptr& lockpick, std::string_view& resultMessage, + std::string_view& resultSound) { - if (lock.getCellRef().getLockLevel() <= 0 || - lock.getCellRef().getLockLevel() == ESM::UnbreakableLock || - !lock.getClass().hasToolTip(lock)) //If it's unlocked or can not be unlocked back out immediately + if (lock.getCellRef().getLockLevel() <= 0 || lock.getCellRef().getLockLevel() == ESM::UnbreakableLock + || !lock.getClass().hasToolTip(lock)) // If it's unlocked or can not be unlocked back out immediately return; int uses = lockpick.getClass().getItemHealth(lockpick); @@ -41,7 +40,12 @@ namespace MWMechanics float pickQuality = lockpick.get()->mBase->mData.mQuality; - float fPickLockMult = MWBase::Environment::get().getWorld()->getStore().get().find("fPickLockMult")->mValue.getFloat(); + float fPickLockMult = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fPickLockMult") + ->mValue.getFloat(); float x = 0.2f * mAgility + 0.1f * mLuck + mSecuritySkill; x *= pickQuality * mFatigueTerm; @@ -71,8 +75,8 @@ namespace MWMechanics lockpick.getContainerStore()->remove(lockpick, 1, mActor); } - void Security::probeTrap(const MWWorld::Ptr &trap, const MWWorld::Ptr &probe, - std::string_view& resultMessage, std::string_view& resultSound) + void Security::probeTrap(const MWWorld::Ptr& trap, const MWWorld::Ptr& probe, std::string_view& resultMessage, + std::string_view& resultSound) { if (trap.getCellRef().getTrap().empty()) return; @@ -83,10 +87,16 @@ namespace MWMechanics float probeQuality = probe.get()->mBase->mData.mQuality; - const ESM::Spell* trapSpell = MWBase::Environment::get().getWorld()->getStore().get().find(trap.getCellRef().getTrap()); + const ESM::Spell* trapSpell + = MWBase::Environment::get().getWorld()->getStore().get().find(trap.getCellRef().getTrap()); int trapSpellPoints = trapSpell->mData.mCost; - float fTrapCostMult = MWBase::Environment::get().getWorld()->getStore().get().find("fTrapCostMult")->mValue.getFloat(); + float fTrapCostMult = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fTrapCostMult") + ->mValue.getFloat(); float x = 0.2f * mAgility + 0.1f * mLuck + mSecuritySkill; x += fTrapCostMult * trapSpellPoints; diff --git a/apps/openmw/mwmechanics/security.hpp b/apps/openmw/mwmechanics/security.hpp index b555dcc299..7765bcb5dc 100644 --- a/apps/openmw/mwmechanics/security.hpp +++ b/apps/openmw/mwmechanics/security.hpp @@ -10,12 +10,12 @@ namespace MWMechanics class Security { public: - Security (const MWWorld::Ptr& actor); + Security(const MWWorld::Ptr& actor); - void pickLock (const MWWorld::Ptr& lock, const MWWorld::Ptr& lockpick, - std::string_view& resultMessage, std::string_view& resultSound); - void probeTrap (const MWWorld::Ptr& trap, const MWWorld::Ptr& probe, - std::string_view& resultMessage, std::string_view& resultSound); + void pickLock(const MWWorld::Ptr& lock, const MWWorld::Ptr& lockpick, std::string_view& resultMessage, + std::string_view& resultSound); + void probeTrap(const MWWorld::Ptr& trap, const MWWorld::Ptr& probe, std::string_view& resultMessage, + std::string_view& resultSound); private: float mAgility, mLuck, mSecuritySkill, mFatigueTerm; diff --git a/apps/openmw/mwmechanics/setbaseaisetting.hpp b/apps/openmw/mwmechanics/setbaseaisetting.hpp index f90462182e..ff63ee09fd 100644 --- a/apps/openmw/mwmechanics/setbaseaisetting.hpp +++ b/apps/openmw/mwmechanics/setbaseaisetting.hpp @@ -12,7 +12,7 @@ namespace MWMechanics { - template + template void setBaseAISetting(const std::string& id, MWMechanics::AiSetting setting, int value) { T copy = *MWBase::Environment::get().getWorld()->getStore().get().find(id); diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index 63a9b0ba4c..db92629dbc 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -1,26 +1,26 @@ #include "spellcasting.hpp" +#include +#include +#include #include -#include #include +#include #include -#include -#include -#include -#include "../mwbase/windowmanager.hpp" -#include "../mwbase/soundmanager.hpp" -#include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/soundmanager.hpp" +#include "../mwbase/windowmanager.hpp" #include "../mwbase/world.hpp" -#include "../mwworld/containerstore.hpp" #include "../mwworld/actionteleport.hpp" -#include "../mwworld/player.hpp" -#include "../mwworld/class.hpp" #include "../mwworld/cellstore.hpp" +#include "../mwworld/class.hpp" +#include "../mwworld/containerstore.hpp" #include "../mwworld/esmstore.hpp" #include "../mwworld/inventorystore.hpp" +#include "../mwworld/player.hpp" #include "../mwrender/animation.hpp" @@ -34,7 +34,8 @@ namespace MWMechanics { - CastSpell::CastSpell(const MWWorld::Ptr &caster, const MWWorld::Ptr &target, const bool fromProjectile, const bool manualSpell) + CastSpell::CastSpell( + const MWWorld::Ptr& caster, const MWWorld::Ptr& target, const bool fromProjectile, const bool manualSpell) : mCaster(caster) , mTarget(target) , mFromProjectile(fromProjectile) @@ -42,26 +43,30 @@ namespace MWMechanics { } - void CastSpell::explodeSpell(const ESM::EffectList& effects, const MWWorld::Ptr& ignore, ESM::RangeType rangeType) const + void CastSpell::explodeSpell( + const ESM::EffectList& effects, const MWWorld::Ptr& ignore, ESM::RangeType rangeType) const { const auto world = MWBase::Environment::get().getWorld(); const VFS::Manager* const vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); - std::map > toApply; + std::map> toApply; int index = -1; for (const ESM::ENAMstruct& effectInfo : effects.mList) { ++index; const ESM::MagicEffect* effect = world->getStore().get().find(effectInfo.mEffectID); - if (effectInfo.mRange != rangeType || (effectInfo.mArea <= 0 && !ignore.isEmpty() && ignore.getClass().isActor())) + if (effectInfo.mRange != rangeType + || (effectInfo.mArea <= 0 && !ignore.isEmpty() && ignore.getClass().isActor())) continue; // Not right range type, or not area effect and hit an actor if (mFromProjectile && effectInfo.mArea <= 0) continue; // Don't play explosion for projectiles with 0-area effects - if (!mFromProjectile && effectInfo.mRange == ESM::RT_Touch && !ignore.isEmpty() && !ignore.getClass().isActor() && !ignore.getClass().hasToolTip(ignore) + if (!mFromProjectile && effectInfo.mRange == ESM::RT_Touch && !ignore.isEmpty() + && !ignore.getClass().isActor() && !ignore.getClass().hasToolTip(ignore) && (mCaster.isEmpty() || mCaster.getClass().isActor())) - continue; // Don't play explosion for touch spells on non-activatable objects except when spell is from a projectile enchantment or ExplodeSpell + continue; // Don't play explosion for touch spells on non-activatable objects except when spell is from + // a projectile enchantment or ExplodeSpell // Spawn the explosion orb effect const ESM::Static* areaStatic; @@ -75,30 +80,33 @@ namespace MWMechanics if (effectInfo.mArea <= 0) { if (effectInfo.mRange == ESM::RT_Target) - world->spawnEffect(Misc::ResourceHelpers::correctMeshPath(areaStatic->mModel, vfs), texture, mHitPosition, 1.0f); + world->spawnEffect( + Misc::ResourceHelpers::correctMeshPath(areaStatic->mModel, vfs), texture, mHitPosition, 1.0f); continue; } else - world->spawnEffect(Misc::ResourceHelpers::correctMeshPath(areaStatic->mModel, vfs), texture, mHitPosition, static_cast(effectInfo.mArea * 2)); + world->spawnEffect(Misc::ResourceHelpers::correctMeshPath(areaStatic->mModel, vfs), texture, + mHitPosition, static_cast(effectInfo.mArea * 2)); // Play explosion sound (make sure to use NoTrack, since we will delete the projectile now) - static const std::string schools[] = { - "alteration", "conjuration", "destruction", "illusion", "mysticism", "restoration" - }; + static const std::string schools[] + = { "alteration", "conjuration", "destruction", "illusion", "mysticism", "restoration" }; { - MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); - if(!effect->mAreaSound.empty()) + MWBase::SoundManager* sndMgr = MWBase::Environment::get().getSoundManager(); + if (!effect->mAreaSound.empty()) sndMgr->playSound3D(mHitPosition, effect->mAreaSound, 1.0f, 1.0f); else - sndMgr->playSound3D(mHitPosition, schools[effect->mData.mSchool]+" area", 1.0f, 1.0f); + sndMgr->playSound3D(mHitPosition, schools[effect->mData.mSchool] + " area", 1.0f, 1.0f); } // Get the actors in range of the effect std::vector objects; static const int unitsPerFoot = ceil(Constants::UnitsPerFoot); - MWBase::Environment::get().getMechanicsManager()->getObjectsInRange(mHitPosition, static_cast(effectInfo.mArea * unitsPerFoot), objects); + MWBase::Environment::get().getMechanicsManager()->getObjectsInRange( + mHitPosition, static_cast(effectInfo.mArea * unitsPerFoot), objects); for (const MWWorld::Ptr& affected : objects) { - // Ignore actors without collisions here, otherwise it will be possible to hit actors outside processing range. + // Ignore actors without collisions here, otherwise it will be possible to hit actors outside processing + // range. if (affected.getClass().isActor() && !world->isActorCollisionEnabled(affected)) continue; @@ -141,14 +149,14 @@ namespace MWMechanics // Fall back to a "caster to target" direction if we have no other means of determining it // (e.g. when cast by a non-actor) if (!mTarget.isEmpty()) - fallbackDirection = - (mTarget.getRefData().getPosition().asVec3() + offset) - - (mCaster.getRefData().getPosition().asVec3()); + fallbackDirection = (mTarget.getRefData().getPosition().asVec3() + offset) + - (mCaster.getRefData().getPosition().asVec3()); MWBase::Environment::get().getWorld()->launchMagicBolt(mId, mCaster, fallbackDirection, mSlot); } - void CastSpell::inflict(const MWWorld::Ptr& target, const ESM::EffectList& effects, ESM::RangeType range, bool exploded) const + void CastSpell::inflict( + const MWWorld::Ptr& target, const ESM::EffectList& effects, ESM::RangeType range, bool exploded) const { const bool targetIsActor = !target.isEmpty() && target.getClass().isActor(); if (targetIsActor) @@ -180,23 +188,23 @@ namespace MWMechanics if (targetIsActor) targetSpells = &target.getClass().getCreatureStats(target).getActiveSpells(); - bool canCastAnEffect = false; // For bound equipment.If this remains false - // throughout the iteration of this spell's - // effects, we display a "can't re-cast" message + bool canCastAnEffect = false; // For bound equipment.If this remains false + // throughout the iteration of this spell's + // effects, we display a "can't re-cast" message int currentEffectIndex = 0; - for (std::vector::const_iterator effectIt (effects.mList.begin()); + for (std::vector::const_iterator effectIt(effects.mList.begin()); !target.isEmpty() && effectIt != effects.mList.end(); ++effectIt, ++currentEffectIndex) { if (effectIt->mRange != range) continue; - const ESM::MagicEffect *magicEffect = - MWBase::Environment::get().getWorld()->getStore().get().find ( - effectIt->mEffectID); + const ESM::MagicEffect* magicEffect + = MWBase::Environment::get().getWorld()->getStore().get().find(effectIt->mEffectID); // Re-casting a bound equipment effect has no effect if the spell is still active - if (magicEffect->mData.mFlags & ESM::MagicEffect::NonRecastable && targetSpells && targetSpells->isSpellActive(mId)) + if (magicEffect->mData.mFlags & ESM::MagicEffect::NonRecastable && targetSpells + && targetSpells->isSpellActive(mId)) { if (effectIt == (effects.mList.end() - 1) && !canCastAnEffect && castByPlayer) MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicCannotRecast}"); @@ -205,7 +213,8 @@ namespace MWMechanics canCastAnEffect = true; // caster needs to be an actor for linked effects (e.g. Absorb) - if (magicEffect->mData.mFlags & ESM::MagicEffect::CasterLinked && (mCaster.isEmpty() || !mCaster.getClass().isActor())) + if (magicEffect->mData.mFlags & ESM::MagicEffect::CasterLinked + && (mCaster.isEmpty() || !mCaster.getClass().isActor())) continue; ActiveSpells::ActiveEffect effect; @@ -217,7 +226,7 @@ namespace MWMechanics effect.mTimeLeft = 0.f; effect.mEffectIndex = currentEffectIndex; effect.mFlags = ESM::ActiveEffect::Flag_None; - if(mManualSpell) + if (mManualSpell) effect.mFlags |= ESM::ActiveEffect::Flag_Ignore_Reflect; bool hasDuration = !(magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration); @@ -232,10 +241,12 @@ namespace MWMechanics // add to list of active effects, to apply in next frame params.getEffects().emplace_back(effect); - bool effectAffectsHealth = magicEffect->mData.mFlags & ESM::MagicEffect::Harmful || effectIt->mEffectID == ESM::MagicEffect::RestoreHealth; + bool effectAffectsHealth = magicEffect->mData.mFlags & ESM::MagicEffect::Harmful + || effectIt->mEffectID == ESM::MagicEffect::RestoreHealth; if (castByPlayer && target != mCaster && targetIsActor && effectAffectsHealth) { - // If player is attempting to cast a harmful spell on or is healing a living target, show the target's HP bar. + // If player is attempting to cast a harmful spell on or is healing a living target, show the target's + // HP bar. MWBase::Environment::get().getWindowManager()->setEnemy(target); } @@ -252,13 +263,13 @@ namespace MWMechanics { if (!params.getEffects().empty()) { - if(targetIsActor) + if (targetIsActor) target.getClass().getCreatureStats(target).getActiveSpells().addSpell(params); else { - // Apply effects instantly. We can ignore effect deletion since the entire params object gets deleted afterwards anyway - // and we can ignore reflection since non-actors cannot reflect spells - for(auto& effect : params.getEffects()) + // Apply effects instantly. We can ignore effect deletion since the entire params object gets + // deleted afterwards anyway and we can ignore reflection since non-actors cannot reflect spells + for (auto& effect : params.getEffects()) applyMagicEffect(target, mCaster, params, effect, 0.f); } } @@ -280,7 +291,7 @@ namespace MWMechanics throw std::runtime_error("ID type cannot be casted"); } - bool CastSpell::cast(const MWWorld::Ptr &item, int slot, bool launchProjectile) + bool CastSpell::cast(const MWWorld::Ptr& item, int slot, bool launchProjectile) { std::string_view enchantmentName = item.getClass().getEnchantment(item); if (enchantmentName.empty()) @@ -289,7 +300,8 @@ namespace MWMechanics mSourceName = item.getClass().getName(item); mId = item.getCellRef().getRefId(); - const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get().find(enchantmentName); + const ESM::Enchantment* enchantment + = MWBase::Environment::get().getWorld()->getStore().get().find(enchantmentName); mSlot = slot; @@ -304,7 +316,8 @@ namespace MWMechanics int type = enchantment->mData.mType; // Check if there's enough charge left - if (!godmode && (type == ESM::Enchantment::WhenUsed || (!isProjectile && type == ESM::Enchantment::WhenStrikes))) + if (!godmode + && (type == ESM::Enchantment::WhenUsed || (!isProjectile && type == ESM::Enchantment::WhenStrikes))) { int castCost = getEffectiveEnchantmentCastCost(static_cast(enchantment->mData.mCost), mCaster); @@ -322,14 +335,14 @@ namespace MWMechanics if (!enchantment->mEffects.mList.empty()) { short effectId = enchantment->mEffects.mList.front().mEffectID; - const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getWorld()->getStore().get().find(effectId); + const ESM::MagicEffect* magicEffect + = MWBase::Environment::get().getWorld()->getStore().get().find(effectId); school = magicEffect->mData.mSchool; } - static const std::string schools[] = { - "alteration", "conjuration", "destruction", "illusion", "mysticism", "restoration" - }; - MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); + static const std::string schools[] + = { "alteration", "conjuration", "destruction", "illusion", "mysticism", "restoration" }; + MWBase::SoundManager* sndMgr = MWBase::Environment::get().getSoundManager(); sndMgr->playSound3D(mCaster, "Spell Failure " + schools[school], 1.0f, 1.0f); } return false; @@ -341,7 +354,7 @@ namespace MWMechanics if (type == ESM::Enchantment::WhenUsed) { if (mCaster == getPlayer()) - mCaster.getClass().skillUsageSucceeded (mCaster, ESM::Skill::Enchant, 1); + mCaster.getClass().skillUsageSucceeded(mCaster, ESM::Skill::Enchant, 1); } else if (type == ESM::Enchantment::CastOnce) { @@ -351,7 +364,7 @@ namespace MWMechanics else if (type == ESM::Enchantment::WhenStrikes) { if (mCaster == getPlayer()) - mCaster.getClass().skillUsageSucceeded (mCaster, ESM::Skill::Enchant, 3); + mCaster.getClass().skillUsageSucceeded(mCaster, ESM::Skill::Enchant, 3); } if (isProjectile) @@ -413,11 +426,10 @@ namespace MWMechanics if (fail) { // Failure sound - static const std::string schools[] = { - "alteration", "conjuration", "destruction", "illusion", "mysticism", "restoration" - }; + static const std::string schools[] + = { "alteration", "conjuration", "destruction", "illusion", "mysticism", "restoration" }; - MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); + MWBase::SoundManager* sndMgr = MWBase::Environment::get().getSoundManager(); sndMgr->playSound3D(mCaster, "Spell Failure " + schools[school], 1.0f, 1.0f); return false; } @@ -445,7 +457,7 @@ namespace MWMechanics return true; } - bool CastSpell::cast (const ESM::Ingredient* ingredient) + bool CastSpell::cast(const ESM::Ingredient* ingredient) { mId = ingredient->mId; mType = ESM::ActiveSpells::Type_Consumable; @@ -462,10 +474,10 @@ namespace MWMechanics const auto magicEffect = store.get().find(effect.mEffectID); const MWMechanics::CreatureStats& creatureStats = mCaster.getClass().getCreatureStats(mCaster); - float x = (mCaster.getClass().getSkill(mCaster, ESM::Skill::Alchemy) + - 0.2f * creatureStats.getAttribute (ESM::Attribute::Intelligence).getModified() - + 0.1f * creatureStats.getAttribute (ESM::Attribute::Luck).getModified()) - * creatureStats.getFatigueTerm(); + float x = (mCaster.getClass().getSkill(mCaster, ESM::Skill::Alchemy) + + 0.2f * creatureStats.getAttribute(ESM::Attribute::Intelligence).getModified() + + 0.1f * creatureStats.getAttribute(ESM::Attribute::Luck).getModified()) + * creatureStats.getFatigueTerm(); auto& prng = MWBase::Environment::get().getWorld()->getPrng(); int roll = Misc::Rng::roll0to99(prng); @@ -530,33 +542,32 @@ namespace MWMechanics const ESM::Static* castStatic; if (!effect->mCasting.empty()) - castStatic = store.get().find (effect->mCasting); + castStatic = store.get().find(effect->mCasting); else - castStatic = store.get().find ("VFX_DefaultCast"); + castStatic = store.get().find("VFX_DefaultCast"); // check if the effect was already added if (std::find(addedEffects.begin(), addedEffects.end(), - Misc::ResourceHelpers::correctMeshPath(castStatic->mModel, vfs)) + Misc::ResourceHelpers::correctMeshPath(castStatic->mModel, vfs)) != addedEffects.end()) continue; MWRender::Animation* animation = MWBase::Environment::get().getWorld()->getAnimation(mCaster); if (animation) { - animation->addEffect( - Misc::ResourceHelpers::correctMeshPath(castStatic->mModel, vfs), - effect->mIndex, false, {}, effect->mParticle); + animation->addEffect(Misc::ResourceHelpers::correctMeshPath(castStatic->mModel, vfs), effect->mIndex, + false, {}, effect->mParticle); } else { // If the caster has no animation, add the effect directly to the effectManager // We must scale and position it manually float scale = mCaster.getCellRef().getScale(); - osg::Vec3f pos (mCaster.getRefData().getPosition().asVec3()); + osg::Vec3f pos(mCaster.getRefData().getPosition().asVec3()); if (!mCaster.getClass().isNpc()) { - osg::Vec3f bounds (MWBase::Environment::get().getWorld()->getHalfExtents(mCaster) * 2.f); - scale *= std::max({bounds.x(), bounds.y(), bounds.z() / 2.f}) / 64.f; + osg::Vec3f bounds(MWBase::Environment::get().getWorld()->getHalfExtents(mCaster) * 2.f); + scale *= std::max({ bounds.x(), bounds.y(), bounds.z() / 2.f }) / 64.f; float offset = 0.f; if (bounds.z() < 128.f) offset = bounds.z() - 128.f; @@ -569,30 +580,28 @@ namespace MWMechanics else { // Additionally use the NPC's height - osg::Vec3f npcScaleVec (1.f, 1.f, 1.f); + osg::Vec3f npcScaleVec(1.f, 1.f, 1.f); mCaster.getClass().adjustScale(mCaster, npcScaleVec, true); scale *= npcScaleVec.z(); } scale = std::max(scale, 1.f); MWBase::Environment::get().getWorld()->spawnEffect( - Misc::ResourceHelpers::correctMeshPath(castStatic->mModel, vfs), - effect->mParticle, pos, scale); + Misc::ResourceHelpers::correctMeshPath(castStatic->mModel, vfs), effect->mParticle, pos, scale); } if (animation && !mCaster.getClass().isActor()) animation->addSpellCastGlow(effect); - static const std::string schools[] = { - "alteration", "conjuration", "destruction", "illusion", "mysticism", "restoration" - }; + static const std::string schools[] + = { "alteration", "conjuration", "destruction", "illusion", "mysticism", "restoration" }; addedEffects.push_back(Misc::ResourceHelpers::correctMeshPath(castStatic->mModel, vfs)); - MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); - if(!effect->mCastSound.empty()) + MWBase::SoundManager* sndMgr = MWBase::Environment::get().getSoundManager(); + if (!effect->mCastSound.empty()) sndMgr->playSound3D(mCaster, effect->mCastSound, 1.0f, 1.0f); else - sndMgr->playSound3D(mCaster, schools[effect->mData.mSchool]+" cast", 1.0f, 1.0f); + sndMgr->playSound3D(mCaster, schools[effect->mData.mSchool] + " cast", 1.0f, 1.0f); } } @@ -600,35 +609,33 @@ namespace MWMechanics { if (playNonLooping) { - static const std::string schools[] = { - "alteration", "conjuration", "destruction", "illusion", "mysticism", "restoration" - }; + static const std::string schools[] + = { "alteration", "conjuration", "destruction", "illusion", "mysticism", "restoration" }; - MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); - if(!magicEffect.mHitSound.empty()) + MWBase::SoundManager* sndMgr = MWBase::Environment::get().getSoundManager(); + if (!magicEffect.mHitSound.empty()) sndMgr->playSound3D(target, magicEffect.mHitSound, 1.0f, 1.0f); else - sndMgr->playSound3D(target, schools[magicEffect.mData.mSchool]+" hit", 1.0f, 1.0f); + sndMgr->playSound3D(target, schools[magicEffect.mData.mSchool] + " hit", 1.0f, 1.0f); } // Add VFX const ESM::Static* castStatic; if (!magicEffect.mHit.empty()) - castStatic = MWBase::Environment::get().getWorld()->getStore().get().find (magicEffect.mHit); + castStatic = MWBase::Environment::get().getWorld()->getStore().get().find(magicEffect.mHit); else - castStatic = MWBase::Environment::get().getWorld()->getStore().get().find ("VFX_DefaultHit"); + castStatic = MWBase::Environment::get().getWorld()->getStore().get().find("VFX_DefaultHit"); bool loop = (magicEffect.mData.mFlags & ESM::MagicEffect::ContinuousVfx) != 0; MWRender::Animation* anim = MWBase::Environment::get().getWorld()->getAnimation(target); - if(anim && !castStatic->mModel.empty()) + if (anim && !castStatic->mModel.empty()) { // Don't play particle VFX unless the effect is new or it should be looping. if (playNonLooping || loop) { const VFS::Manager* const vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); - anim->addEffect( - Misc::ResourceHelpers::correctMeshPath(castStatic->mModel, vfs), - magicEffect.mIndex, loop, {}, magicEffect.mParticle); + anim->addEffect(Misc::ResourceHelpers::correctMeshPath(castStatic->mModel, vfs), magicEffect.mIndex, + loop, {}, magicEffect.mParticle); } } } diff --git a/apps/openmw/mwmechanics/spellcasting.hpp b/apps/openmw/mwmechanics/spellcasting.hpp index bc17a00042..fee460f448 100644 --- a/apps/openmw/mwmechanics/spellcasting.hpp +++ b/apps/openmw/mwmechanics/spellcasting.hpp @@ -36,35 +36,41 @@ namespace MWMechanics public: std::string mId; // ID of spell, potion, item etc std::string mSourceName; // Display name for spell, potion, etc - osg::Vec3f mHitPosition{0,0,0}; // Used for spawning area orb - bool mAlwaysSucceed{false}; // Always succeed spells casted by NPCs/creatures regardless of their chance (default: false) + osg::Vec3f mHitPosition{ 0, 0, 0 }; // Used for spawning area orb + bool mAlwaysSucceed{ + false + }; // Always succeed spells casted by NPCs/creatures regardless of their chance (default: false) bool mFromProjectile; // True if spell is cast by enchantment of some projectile (arrow, bolt or thrown weapon) - bool mManualSpell; // True if spell is casted from script and ignores some checks (mana level, success chance, etc.) - int mSlot{0}; - ESM::ActiveSpells::EffectType mType{ESM::ActiveSpells::Type_Temporary}; + bool mManualSpell; // True if spell is casted from script and ignores some checks (mana level, success chance, + // etc.) + int mSlot{ 0 }; + ESM::ActiveSpells::EffectType mType{ ESM::ActiveSpells::Type_Temporary }; - CastSpell(const MWWorld::Ptr& caster, const MWWorld::Ptr& target, const bool fromProjectile=false, const bool manualSpell=false); + CastSpell(const MWWorld::Ptr& caster, const MWWorld::Ptr& target, const bool fromProjectile = false, + const bool manualSpell = false); - bool cast (const ESM::Spell* spell); + bool cast(const ESM::Spell* spell); /// @note mCaster must be an actor - /// @param launchProjectile If set to false, "on target" effects are directly applied instead of being launched as projectile originating from the caster. - bool cast (const MWWorld::Ptr& item, int slot, bool launchProjectile=true); + /// @param launchProjectile If set to false, "on target" effects are directly applied instead of being launched + /// as projectile originating from the caster. + bool cast(const MWWorld::Ptr& item, int slot, bool launchProjectile = true); /// @note mCaster must be an NPC - bool cast (const ESM::Ingredient* ingredient); + bool cast(const ESM::Ingredient* ingredient); - bool cast (const ESM::Potion* potion); + bool cast(const ESM::Potion* potion); /// @note Auto detects if spell, ingredient or potion - bool cast (const std::string& id); + bool cast(const std::string& id); void playSpellCastingEffects(const ESM::Enchantment* enchantment) const; void playSpellCastingEffects(const ESM::Spell* spell) const; /// @note \a target can be any type of object, not just actors. - void inflict(const MWWorld::Ptr& target, const ESM::EffectList& effects, ESM::RangeType range, bool exploded = false) const; + void inflict(const MWWorld::Ptr& target, const ESM::EffectList& effects, ESM::RangeType range, + bool exploded = false) const; }; void playEffects(const MWWorld::Ptr& target, const ESM::MagicEffect& magicEffect, bool playNonLooping = true); diff --git a/apps/openmw/mwmechanics/spelleffects.cpp b/apps/openmw/mwmechanics/spelleffects.cpp index 99d5dcce2b..c9de5bd1b9 100644 --- a/apps/openmw/mwmechanics/spelleffects.cpp +++ b/apps/openmw/mwmechanics/spelleffects.cpp @@ -2,14 +2,14 @@ #include +#include +#include +#include #include +#include +#include #include #include -#include -#include -#include -#include -#include #include "../mwbase/environment.hpp" #include "../mwbase/mechanicsmanager.hpp" @@ -38,15 +38,16 @@ namespace { float roll(const ESM::ActiveEffect& effect) { - if(effect.mMinMagnitude == effect.mMaxMagnitude) + if (effect.mMinMagnitude == effect.mMaxMagnitude) return effect.mMinMagnitude; auto& prng = MWBase::Environment::get().getWorld()->getPrng(); return effect.mMinMagnitude + Misc::Rng::rollDice(effect.mMaxMagnitude - effect.mMinMagnitude + 1, prng); } - void modifyAiSetting(const MWWorld::Ptr& target, const ESM::ActiveEffect& effect, ESM::MagicEffect::Effects creatureEffect, MWMechanics::AiSetting setting, float magnitude, bool& invalid) + void modifyAiSetting(const MWWorld::Ptr& target, const ESM::ActiveEffect& effect, + ESM::MagicEffect::Effects creatureEffect, MWMechanics::AiSetting setting, float magnitude, bool& invalid) { - if(target == MWMechanics::getPlayer() || (effect.mEffectId == creatureEffect) == target.getClass().isNpc()) + if (target == MWMechanics::getPlayer() || (effect.mEffectId == creatureEffect) == target.getClass().isNpc()) invalid = true; else { @@ -57,7 +58,8 @@ namespace } } - void adjustDynamicStat(const MWWorld::Ptr& target, int index, float magnitude, bool allowDecreaseBelowZero = false, bool allowIncreaseAboveModified = false) + void adjustDynamicStat(const MWWorld::Ptr& target, int index, float magnitude, bool allowDecreaseBelowZero = false, + bool allowIncreaseAboveModified = false) { auto& creatureStats = target.getClass().getCreatureStats(target); auto stat = creatureStats.getDynamic(index); @@ -79,7 +81,7 @@ namespace { auto& creatureStats = target.getClass().getCreatureStats(target); auto attr = creatureStats.getAttribute(effect.mArg); - if(effect.mEffectId == ESM::MagicEffect::DamageAttribute) + if (effect.mEffectId == ESM::MagicEffect::DamageAttribute) magnitude = std::min(attr.getModified(), magnitude); attr.damage(magnitude); creatureStats.setAttribute(effect.mArg, attr); @@ -105,7 +107,7 @@ namespace { auto& npcStats = target.getClass().getNpcStats(target); auto& skill = npcStats.getSkill(effect.mArg); - if(effect.mEffectId == ESM::MagicEffect::DamageSkill) + if (effect.mEffectId == ESM::MagicEffect::DamageSkill) magnitude = std::min(skill.getModified(), magnitude); skill.damage(magnitude); } @@ -129,7 +131,9 @@ namespace MWWorld::InventoryStore& inv = ptr.getClass().getInventoryStore(ptr); MWWorld::ContainerStoreIterator item = inv.getSlot(slot); - if (item != inv.end() && (item.getType() == MWWorld::ContainerStore::Type_Armor || item.getType() == MWWorld::ContainerStore::Type_Weapon)) + if (item != inv.end() + && (item.getType() == MWWorld::ContainerStore::Type_Armor + || item.getType() == MWWorld::ContainerStore::Type_Weapon)) { if (!item->getClass().hasItemHealth(*item)) return false; @@ -162,7 +166,7 @@ namespace int getBoundItemSlot(const MWWorld::Ptr& boundPtr) { const auto [slots, _] = boundPtr.getClass().getEquipmentSlots(boundPtr); - if(!slots.empty()) + if (!slots.empty()) return slots[0]; return -1; } @@ -184,7 +188,7 @@ namespace MWWorld::Ptr newItem; auto it = slot >= 0 ? store.getSlot(slot) : store.end(); // Equip can fail because beast races cannot equip boots/helmets - if(it != store.end()) + if (it != store.end()) newItem = *it; if (newItem.isEmpty() || boundPtr != newItem) @@ -203,17 +207,16 @@ namespace void removeBoundItem(const std::string& itemId, const MWWorld::Ptr& actor) { MWWorld::InventoryStore& store = actor.getClass().getInventoryStore(actor); - auto item = std::find_if(store.begin(), store.end(), [&] (const auto& it) - { - return Misc::StringUtils::ciEqual(it.getCellRef().getRefId(), itemId); - }); - if(item == store.end()) + auto item = std::find_if(store.begin(), store.end(), + [&](const auto& it) { return Misc::StringUtils::ciEqual(it.getCellRef().getRefId(), itemId); }); + if (item == store.end()) return; int slot = getBoundItemSlot(*item); auto currentItem = store.getSlot(slot); - bool wasEquipped = currentItem != store.end() && Misc::StringUtils::ciEqual(currentItem->getCellRef().getRefId(), itemId); + bool wasEquipped + = currentItem != store.end() && Misc::StringUtils::ciEqual(currentItem->getCellRef().getRefId(), itemId); if (actor != MWMechanics::getPlayer()) { @@ -262,10 +265,12 @@ namespace bool isCorprusEffect(const MWMechanics::ActiveSpells::ActiveEffect& effect, bool harmfulOnly = false) { - if(effect.mFlags & ESM::ActiveEffect::Flag_Applied && effect.mEffectId != ESM::MagicEffect::Corprus) + if (effect.mFlags & ESM::ActiveEffect::Flag_Applied && effect.mEffectId != ESM::MagicEffect::Corprus) { - const auto* magicEffect = MWBase::Environment::get().getWorld()->getStore().get().find(effect.mEffectId); - if(magicEffect->mData.mFlags & ESM::MagicEffect::Flags::AppliedOnce && (!harmfulOnly || magicEffect->mData.mFlags & ESM::MagicEffect::Flags::Harmful)) + const auto* magicEffect + = MWBase::Environment::get().getWorld()->getStore().get().find(effect.mEffectId); + if (magicEffect->mData.mFlags & ESM::MagicEffect::Flags::AppliedOnce + && (!harmfulOnly || magicEffect->mData.mFlags & ESM::MagicEffect::Flags::Harmful)) return true; } return false; @@ -279,8 +284,7 @@ namespace if (animation && !absorbStatic->mModel.empty()) { const VFS::Manager* const vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); - animation->addEffect( - Misc::ResourceHelpers::correctMeshPath(absorbStatic->mModel, vfs), + animation->addEffect(Misc::ResourceHelpers::correctMeshPath(absorbStatic->mModel, vfs), ESM::MagicEffect::SpellAbsorption, false); } const ESM::Spell* spell = esmStore.get().search(spellId); @@ -293,7 +297,8 @@ namespace { const ESM::Enchantment* enchantment = esmStore.get().search(spellId); if (enchantment) - spellCost = MWMechanics::getEffectiveEnchantmentCastCost(static_cast(enchantment->mData.mCost), caster); + spellCost = MWMechanics::getEffectiveEnchantmentCastCost( + static_cast(enchantment->mData.mCost), caster); } // Magicka is increased by the cost of the spell @@ -304,35 +309,39 @@ namespace } MWMechanics::MagicApplicationResult::Type applyProtections(const MWWorld::Ptr& target, const MWWorld::Ptr& caster, - const MWMechanics::ActiveSpells::ActiveSpellParams& spellParams, ESM::ActiveEffect& effect, const ESM::MagicEffect* magicEffect) + const MWMechanics::ActiveSpells::ActiveSpellParams& spellParams, ESM::ActiveEffect& effect, + const ESM::MagicEffect* magicEffect) { auto& stats = target.getClass().getCreatureStats(target); auto& magnitudes = stats.getMagicEffects(); // Apply reflect and spell absorption - if(target != caster && spellParams.getType() != ESM::ActiveSpells::Type_Enchantment && spellParams.getType() != ESM::ActiveSpells::Type_Permanent) + if (target != caster && spellParams.getType() != ESM::ActiveSpells::Type_Enchantment + && spellParams.getType() != ESM::ActiveSpells::Type_Permanent) { - bool canReflect = !(magicEffect->mData.mFlags & ESM::MagicEffect::Unreflectable) && !(effect.mFlags & ESM::ActiveEffect::Flag_Ignore_Reflect) && - magnitudes.get(ESM::MagicEffect::Reflect).getMagnitude() > 0.f && !caster.isEmpty(); - bool canAbsorb = !(effect.mFlags & ESM::ActiveEffect::Flag_Ignore_SpellAbsorption) && magnitudes.get(ESM::MagicEffect::SpellAbsorption).getMagnitude() > 0.f; - if(canReflect || canAbsorb) + bool canReflect = !(magicEffect->mData.mFlags & ESM::MagicEffect::Unreflectable) + && !(effect.mFlags & ESM::ActiveEffect::Flag_Ignore_Reflect) + && magnitudes.get(ESM::MagicEffect::Reflect).getMagnitude() > 0.f && !caster.isEmpty(); + bool canAbsorb = !(effect.mFlags & ESM::ActiveEffect::Flag_Ignore_SpellAbsorption) + && magnitudes.get(ESM::MagicEffect::SpellAbsorption).getMagnitude() > 0.f; + if (canReflect || canAbsorb) { auto& prng = MWBase::Environment::get().getWorld()->getPrng(); - for(const auto& activeParam : stats.getActiveSpells()) + for (const auto& activeParam : stats.getActiveSpells()) { - for(const auto& activeEffect : activeParam.getEffects()) + for (const auto& activeEffect : activeParam.getEffects()) { - if(!(activeEffect.mFlags & ESM::ActiveEffect::Flag_Applied)) + if (!(activeEffect.mFlags & ESM::ActiveEffect::Flag_Applied)) continue; - if(activeEffect.mEffectId == ESM::MagicEffect::Reflect) + if (activeEffect.mEffectId == ESM::MagicEffect::Reflect) { - if(canReflect && Misc::Rng::roll0to99(prng) < activeEffect.mMagnitude) + if (canReflect && Misc::Rng::roll0to99(prng) < activeEffect.mMagnitude) { return MWMechanics::MagicApplicationResult::Type::REFLECTED; } } - else if(activeEffect.mEffectId == ESM::MagicEffect::SpellAbsorption) + else if (activeEffect.mEffectId == ESM::MagicEffect::SpellAbsorption) { - if(canAbsorb && Misc::Rng::roll0to99(prng) < activeEffect.mMagnitude) + if (canAbsorb && Misc::Rng::roll0to99(prng) < activeEffect.mMagnitude) { absorbSpell(spellParams.getId(), caster, target); return MWMechanics::MagicApplicationResult::Type::REMOVED; @@ -347,12 +356,13 @@ namespace if (target.getClass().isActor() && target != caster && !caster.isEmpty() && isHarmful) target.getClass().onHit(target, 0.0f, true, MWWorld::Ptr(), caster, osg::Vec3f(), true); // Apply resistances - if(!(effect.mFlags & ESM::ActiveEffect::Flag_Ignore_Resistances)) + if (!(effect.mFlags & ESM::ActiveEffect::Flag_Ignore_Resistances)) { const ESM::Spell* spell = nullptr; - if(spellParams.getType() == ESM::ActiveSpells::Type_Temporary) + if (spellParams.getType() == ESM::ActiveSpells::Type_Temporary) spell = MWBase::Environment::get().getWorld()->getStore().get().search(spellParams.getId()); - float magnitudeMult = MWMechanics::getEffectMultiplier(effect.mEffectId, target, caster, spell, &magnitudes); + float magnitudeMult + = MWMechanics::getEffectMultiplier(effect.mEffectId, target, caster, spell, &magnitudes); if (magnitudeMult == 0) { // Fully resisted, show message @@ -369,651 +379,688 @@ namespace } static const std::map sBoundItemsMap{ - {ESM::MagicEffect::BoundBattleAxe, "sMagicBoundBattleAxeID"}, - {ESM::MagicEffect::BoundBoots, "sMagicBoundBootsID"}, - {ESM::MagicEffect::BoundCuirass, "sMagicBoundCuirassID"}, - {ESM::MagicEffect::BoundDagger, "sMagicBoundDaggerID"}, - {ESM::MagicEffect::BoundGloves, "sMagicBoundLeftGauntletID"}, - {ESM::MagicEffect::BoundHelm, "sMagicBoundHelmID"}, - {ESM::MagicEffect::BoundLongbow, "sMagicBoundLongbowID"}, - {ESM::MagicEffect::BoundLongsword, "sMagicBoundLongswordID"}, - {ESM::MagicEffect::BoundMace, "sMagicBoundMaceID"}, - {ESM::MagicEffect::BoundShield, "sMagicBoundShieldID"}, - {ESM::MagicEffect::BoundSpear, "sMagicBoundSpearID"}, + { ESM::MagicEffect::BoundBattleAxe, "sMagicBoundBattleAxeID" }, + { ESM::MagicEffect::BoundBoots, "sMagicBoundBootsID" }, + { ESM::MagicEffect::BoundCuirass, "sMagicBoundCuirassID" }, + { ESM::MagicEffect::BoundDagger, "sMagicBoundDaggerID" }, + { ESM::MagicEffect::BoundGloves, "sMagicBoundLeftGauntletID" }, + { ESM::MagicEffect::BoundHelm, "sMagicBoundHelmID" }, + { ESM::MagicEffect::BoundLongbow, "sMagicBoundLongbowID" }, + { ESM::MagicEffect::BoundLongsword, "sMagicBoundLongswordID" }, + { ESM::MagicEffect::BoundMace, "sMagicBoundMaceID" }, + { ESM::MagicEffect::BoundShield, "sMagicBoundShieldID" }, + { ESM::MagicEffect::BoundSpear, "sMagicBoundSpearID" }, }; } namespace MWMechanics { -void applyMagicEffect(const MWWorld::Ptr& target, const MWWorld::Ptr& caster, const ActiveSpells::ActiveSpellParams& spellParams, ESM::ActiveEffect& effect, bool& invalid, bool& receivedMagicDamage, bool& affectedHealth, bool& recalculateMagicka) -{ - const auto world = MWBase::Environment::get().getWorld(); - bool godmode = target == getPlayer() && world->getGodModeState(); - switch(effect.mEffectId) + void applyMagicEffect(const MWWorld::Ptr& target, const MWWorld::Ptr& caster, + const ActiveSpells::ActiveSpellParams& spellParams, ESM::ActiveEffect& effect, bool& invalid, + bool& receivedMagicDamage, bool& affectedHealth, bool& recalculateMagicka) { - case ESM::MagicEffect::CureCommonDisease: - target.getClass().getCreatureStats(target).getSpells().purgeCommonDisease(); - break; - case ESM::MagicEffect::CureBlightDisease: - target.getClass().getCreatureStats(target).getSpells().purgeBlightDisease(); - break; - case ESM::MagicEffect::RemoveCurse: - target.getClass().getCreatureStats(target).getSpells().purgeCurses(); - break; - case ESM::MagicEffect::CureCorprusDisease: - target.getClass().getCreatureStats(target).getActiveSpells().purgeEffect(target, ESM::MagicEffect::Corprus); - break; - case ESM::MagicEffect::CurePoison: - target.getClass().getCreatureStats(target).getActiveSpells().purgeEffect(target, ESM::MagicEffect::Poison); - break; - case ESM::MagicEffect::CureParalyzation: - target.getClass().getCreatureStats(target).getActiveSpells().purgeEffect(target, ESM::MagicEffect::Paralyze); - break; - case ESM::MagicEffect::Dispel: - // Dispel removes entire spells at once - target.getClass().getCreatureStats(target).getActiveSpells().purge([magnitude=effect.mMagnitude] (const ActiveSpells::ActiveSpellParams& params) - { - if(params.getType() == ESM::ActiveSpells::Type_Temporary) + const auto world = MWBase::Environment::get().getWorld(); + bool godmode = target == getPlayer() && world->getGodModeState(); + switch (effect.mEffectId) + { + case ESM::MagicEffect::CureCommonDisease: + target.getClass().getCreatureStats(target).getSpells().purgeCommonDisease(); + break; + case ESM::MagicEffect::CureBlightDisease: + target.getClass().getCreatureStats(target).getSpells().purgeBlightDisease(); + break; + case ESM::MagicEffect::RemoveCurse: + target.getClass().getCreatureStats(target).getSpells().purgeCurses(); + break; + case ESM::MagicEffect::CureCorprusDisease: + target.getClass().getCreatureStats(target).getActiveSpells().purgeEffect( + target, ESM::MagicEffect::Corprus); + break; + case ESM::MagicEffect::CurePoison: + target.getClass().getCreatureStats(target).getActiveSpells().purgeEffect( + target, ESM::MagicEffect::Poison); + break; + case ESM::MagicEffect::CureParalyzation: + target.getClass().getCreatureStats(target).getActiveSpells().purgeEffect( + target, ESM::MagicEffect::Paralyze); + break; + case ESM::MagicEffect::Dispel: + // Dispel removes entire spells at once + target.getClass().getCreatureStats(target).getActiveSpells().purge( + [magnitude = effect.mMagnitude](const ActiveSpells::ActiveSpellParams& params) { + if (params.getType() == ESM::ActiveSpells::Type_Temporary) + { + const ESM::Spell* spell + = MWBase::Environment::get().getWorld()->getStore().get().search( + params.getId()); + if (spell && spell->mData.mType == ESM::Spell::ST_Spell) + { + auto& prng = MWBase::Environment::get().getWorld()->getPrng(); + return Misc::Rng::roll0to99(prng) < magnitude; + } + } + return false; + }, + target); + break; + case ESM::MagicEffect::AlmsiviIntervention: + case ESM::MagicEffect::DivineIntervention: + if (target != getPlayer()) + invalid = true; + else if (world->isTeleportingEnabled()) { - const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get().search(params.getId()); - if (spell && spell->mData.mType == ESM::Spell::ST_Spell) + std::string_view marker + = (effect.mEffectId == ESM::MagicEffect::DivineIntervention) ? "divinemarker" : "templemarker"; + world->teleportToClosestMarker(target, marker); + if (!caster.isEmpty()) { - auto& prng = MWBase::Environment::get().getWorld()->getPrng(); - return Misc::Rng::roll0to99(prng) < magnitude; + MWRender::Animation* anim = world->getAnimation(caster); + anim->removeEffect(effect.mEffectId); + const ESM::Static* fx = world->getStore().get().search("VFX_Summon_end"); + if (fx) + { + const VFS::Manager* const vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); + anim->addEffect(Misc::ResourceHelpers::correctMeshPath(fx->mModel, vfs), -1); + } } } - return false; - }, target); - break; - case ESM::MagicEffect::AlmsiviIntervention: - case ESM::MagicEffect::DivineIntervention: - if (target != getPlayer()) - invalid = true; - else if (world->isTeleportingEnabled()) - { - std::string_view marker = (effect.mEffectId == ESM::MagicEffect::DivineIntervention) ? "divinemarker" : "templemarker"; - world->teleportToClosestMarker(target, marker); - if(!caster.isEmpty()) + else if (caster == getPlayer()) + MWBase::Environment::get().getWindowManager()->messageBox("#{sTeleportDisabled}"); + break; + case ESM::MagicEffect::Mark: + if (target != getPlayer()) + invalid = true; + else if (world->isTeleportingEnabled()) + world->getPlayer().markPosition(target.getCell(), target.getRefData().getPosition()); + else if (caster == getPlayer()) + MWBase::Environment::get().getWindowManager()->messageBox("#{sTeleportDisabled}"); + break; + case ESM::MagicEffect::Recall: + if (target != getPlayer()) + invalid = true; + else if (world->isTeleportingEnabled()) { - MWRender::Animation* anim = world->getAnimation(caster); - anim->removeEffect(effect.mEffectId); - const ESM::Static* fx = world->getStore().get().search("VFX_Summon_end"); - if (fx) + MWWorld::CellStore* markedCell = nullptr; + ESM::Position markedPosition; + + world->getPlayer().getMarkedPosition(markedCell, markedPosition); + if (markedCell) { - const VFS::Manager* const vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); - anim->addEffect(Misc::ResourceHelpers::correctMeshPath(fx->mModel, vfs), -1); + std::string_view dest; + if (!markedCell->isExterior()) + dest = markedCell->getCell()->mName; + MWWorld::ActionTeleport action(dest, markedPosition, false); + action.execute(target); + if (!caster.isEmpty()) + { + MWRender::Animation* anim = world->getAnimation(caster); + anim->removeEffect(effect.mEffectId); + } } } - } - else if (caster == getPlayer()) - MWBase::Environment::get().getWindowManager()->messageBox("#{sTeleportDisabled}"); - break; - case ESM::MagicEffect::Mark: - if (target != getPlayer()) - invalid = true; - else if (world->isTeleportingEnabled()) - world->getPlayer().markPosition(target.getCell(), target.getRefData().getPosition()); - else if (caster == getPlayer()) - MWBase::Environment::get().getWindowManager()->messageBox("#{sTeleportDisabled}"); - break; - case ESM::MagicEffect::Recall: - if (target != getPlayer()) - invalid = true; - else if (world->isTeleportingEnabled()) - { - MWWorld::CellStore* markedCell = nullptr; - ESM::Position markedPosition; - - world->getPlayer().getMarkedPosition(markedCell, markedPosition); - if (markedCell) + else if (caster == getPlayer()) + MWBase::Environment::get().getWindowManager()->messageBox("#{sTeleportDisabled}"); + break; + case ESM::MagicEffect::CommandCreature: + case ESM::MagicEffect::CommandHumanoid: + if (caster.isEmpty() || !caster.getClass().isActor() || target == getPlayer() + || (effect.mEffectId == ESM::MagicEffect::CommandCreature) == target.getClass().isNpc()) + invalid = true; + else if (effect.mMagnitude >= target.getClass().getCreatureStats(target).getLevel()) { - std::string_view dest; - if (!markedCell->isExterior()) - dest = markedCell->getCell()->mName; - MWWorld::ActionTeleport action(dest, markedPosition, false); - action.execute(target); - if(!caster.isEmpty()) - { - MWRender::Animation* anim = world->getAnimation(caster); - anim->removeEffect(effect.mEffectId); - } + MWMechanics::AiFollow package(caster, true); + target.getClass().getCreatureStats(target).getAiSequence().stack(package, target); } - } - else if (caster == getPlayer()) - MWBase::Environment::get().getWindowManager()->messageBox("#{sTeleportDisabled}"); - break; - case ESM::MagicEffect::CommandCreature: - case ESM::MagicEffect::CommandHumanoid: - if(caster.isEmpty() || !caster.getClass().isActor() || target == getPlayer() || (effect.mEffectId == ESM::MagicEffect::CommandCreature) == target.getClass().isNpc()) - invalid = true; - else if(effect.mMagnitude >= target.getClass().getCreatureStats(target).getLevel()) - { - MWMechanics::AiFollow package(caster, true); - target.getClass().getCreatureStats(target).getAiSequence().stack(package, target); - } - break; - case ESM::MagicEffect::ExtraSpell: - if(target.getClass().hasInventoryStore(target)) - { - auto& store = target.getClass().getInventoryStore(target); - store.unequipAll(target); - } - else - invalid = true; - break; - case ESM::MagicEffect::TurnUndead: - if(target.getClass().isNpc() || target.get()->mBase->mData.mType != ESM::Creature::Undead) - invalid = true; - else - { - auto& creatureStats = target.getClass().getCreatureStats(target); - Stat stat = creatureStats.getAiSetting(AiSetting::Flee); - stat.setModifier(static_cast(stat.getModifier() + effect.mMagnitude)); - creatureStats.setAiSetting(AiSetting::Flee, stat); - } - break; - case ESM::MagicEffect::FrenzyCreature: - case ESM::MagicEffect::FrenzyHumanoid: - modifyAiSetting(target, effect, ESM::MagicEffect::FrenzyCreature, AiSetting::Fight, effect.mMagnitude, invalid); - break; - case ESM::MagicEffect::CalmCreature: - case ESM::MagicEffect::CalmHumanoid: - modifyAiSetting(target, effect, ESM::MagicEffect::CalmCreature, AiSetting::Fight, -effect.mMagnitude, invalid); - if(!invalid && effect.mMagnitude > 0) - { - auto& creatureStats = target.getClass().getCreatureStats(target); - creatureStats.getAiSequence().stopCombat(); - } - break; - case ESM::MagicEffect::DemoralizeCreature: - case ESM::MagicEffect::DemoralizeHumanoid: - modifyAiSetting(target, effect, ESM::MagicEffect::DemoralizeCreature, AiSetting::Flee, effect.mMagnitude, invalid); - break; - case ESM::MagicEffect::RallyCreature: - case ESM::MagicEffect::RallyHumanoid: - modifyAiSetting(target, effect, ESM::MagicEffect::RallyCreature, AiSetting::Flee, -effect.mMagnitude, invalid); - break; - case ESM::MagicEffect::Sound: - if(target == getPlayer()) - { - const auto& magnitudes = target.getClass().getCreatureStats(target).getMagicEffects(); - float volume = std::clamp((magnitudes.get(effect.mEffectId).getModifier() + effect.mMagnitude) / 100.f, 0.f, 1.f); - MWBase::Environment::get().getSoundManager()->playSound3D(target, "magic sound", volume, 1.f, MWSound::Type::Sfx, MWSound::PlayMode::LoopNoEnv); - } - break; - case ESM::MagicEffect::SummonScamp: - case ESM::MagicEffect::SummonClannfear: - case ESM::MagicEffect::SummonDaedroth: - case ESM::MagicEffect::SummonDremora: - case ESM::MagicEffect::SummonAncestralGhost: - case ESM::MagicEffect::SummonSkeletalMinion: - case ESM::MagicEffect::SummonBonewalker: - case ESM::MagicEffect::SummonGreaterBonewalker: - case ESM::MagicEffect::SummonBonelord: - case ESM::MagicEffect::SummonWingedTwilight: - case ESM::MagicEffect::SummonHunger: - case ESM::MagicEffect::SummonGoldenSaint: - case ESM::MagicEffect::SummonFlameAtronach: - case ESM::MagicEffect::SummonFrostAtronach: - case ESM::MagicEffect::SummonStormAtronach: - case ESM::MagicEffect::SummonCenturionSphere: - case ESM::MagicEffect::SummonFabricant: - case ESM::MagicEffect::SummonWolf: - case ESM::MagicEffect::SummonBear: - case ESM::MagicEffect::SummonBonewolf: - case ESM::MagicEffect::SummonCreature04: - case ESM::MagicEffect::SummonCreature05: - if(!target.isInCell()) - invalid = true; - else - effect.mArg = summonCreature(effect.mEffectId, target); - break; - case ESM::MagicEffect::BoundGloves: - if(!target.getClass().hasInventoryStore(target)) - { - invalid = true; break; - } - addBoundItem(world->getStore().get().find("sMagicBoundRightGauntletID")->mValue.getString(), target); - // left gauntlet added below - [[fallthrough]]; - case ESM::MagicEffect::BoundDagger: - case ESM::MagicEffect::BoundLongsword: - case ESM::MagicEffect::BoundMace: - case ESM::MagicEffect::BoundBattleAxe: - case ESM::MagicEffect::BoundSpear: - case ESM::MagicEffect::BoundLongbow: - case ESM::MagicEffect::BoundCuirass: - case ESM::MagicEffect::BoundHelm: - case ESM::MagicEffect::BoundBoots: - case ESM::MagicEffect::BoundShield: - if(!target.getClass().hasInventoryStore(target)) - invalid = true; - else - { - const std::string& item = sBoundItemsMap.at(effect.mEffectId); - addBoundItem(world->getStore().get().find(item)->mValue.getString(), target); - } - break; - case ESM::MagicEffect::FireDamage: - case ESM::MagicEffect::ShockDamage: - case ESM::MagicEffect::FrostDamage: - case ESM::MagicEffect::DamageHealth: - case ESM::MagicEffect::Poison: - case ESM::MagicEffect::DamageMagicka: - case ESM::MagicEffect::DamageFatigue: - if(!godmode) - { - int index = 0; - if(effect.mEffectId == ESM::MagicEffect::DamageMagicka) - index = 1; - else if(effect.mEffectId == ESM::MagicEffect::DamageFatigue) - index = 2; - // Damage "Dynamic" abilities reduce the base value - if(spellParams.getType() == ESM::ActiveSpells::Type_Ability) - modDynamicStat(target, index, -effect.mMagnitude); + case ESM::MagicEffect::ExtraSpell: + if (target.getClass().hasInventoryStore(target)) + { + auto& store = target.getClass().getInventoryStore(target); + store.unequipAll(target); + } + else + invalid = true; + break; + case ESM::MagicEffect::TurnUndead: + if (target.getClass().isNpc() + || target.get()->mBase->mData.mType != ESM::Creature::Undead) + invalid = true; else { - static const bool uncappedDamageFatigue = Settings::Manager::getBool("uncapped damage fatigue", "Game"); - adjustDynamicStat(target, index, -effect.mMagnitude, index == 2 && uncappedDamageFatigue); - if(index == 0) - receivedMagicDamage = affectedHealth = true; + auto& creatureStats = target.getClass().getCreatureStats(target); + Stat stat = creatureStats.getAiSetting(AiSetting::Flee); + stat.setModifier(static_cast(stat.getModifier() + effect.mMagnitude)); + creatureStats.setAiSetting(AiSetting::Flee, stat); } - } - break; - case ESM::MagicEffect::DamageAttribute: - if(!godmode) - damageAttribute(target, effect, effect.mMagnitude); - break; - case ESM::MagicEffect::DamageSkill: - if(!target.getClass().isNpc()) - invalid = true; - else if(!godmode) - { - // Damage Skill abilities reduce base skill :todd: - if(spellParams.getType() == ESM::ActiveSpells::Type_Ability) + break; + case ESM::MagicEffect::FrenzyCreature: + case ESM::MagicEffect::FrenzyHumanoid: + modifyAiSetting( + target, effect, ESM::MagicEffect::FrenzyCreature, AiSetting::Fight, effect.mMagnitude, invalid); + break; + case ESM::MagicEffect::CalmCreature: + case ESM::MagicEffect::CalmHumanoid: + modifyAiSetting( + target, effect, ESM::MagicEffect::CalmCreature, AiSetting::Fight, -effect.mMagnitude, invalid); + if (!invalid && effect.mMagnitude > 0) + { + auto& creatureStats = target.getClass().getCreatureStats(target); + creatureStats.getAiSequence().stopCombat(); + } + break; + case ESM::MagicEffect::DemoralizeCreature: + case ESM::MagicEffect::DemoralizeHumanoid: + modifyAiSetting( + target, effect, ESM::MagicEffect::DemoralizeCreature, AiSetting::Flee, effect.mMagnitude, invalid); + break; + case ESM::MagicEffect::RallyCreature: + case ESM::MagicEffect::RallyHumanoid: + modifyAiSetting( + target, effect, ESM::MagicEffect::RallyCreature, AiSetting::Flee, -effect.mMagnitude, invalid); + break; + case ESM::MagicEffect::Sound: + if (target == getPlayer()) + { + const auto& magnitudes = target.getClass().getCreatureStats(target).getMagicEffects(); + float volume = std::clamp( + (magnitudes.get(effect.mEffectId).getModifier() + effect.mMagnitude) / 100.f, 0.f, 1.f); + MWBase::Environment::get().getSoundManager()->playSound3D( + target, "magic sound", volume, 1.f, MWSound::Type::Sfx, MWSound::PlayMode::LoopNoEnv); + } + break; + case ESM::MagicEffect::SummonScamp: + case ESM::MagicEffect::SummonClannfear: + case ESM::MagicEffect::SummonDaedroth: + case ESM::MagicEffect::SummonDremora: + case ESM::MagicEffect::SummonAncestralGhost: + case ESM::MagicEffect::SummonSkeletalMinion: + case ESM::MagicEffect::SummonBonewalker: + case ESM::MagicEffect::SummonGreaterBonewalker: + case ESM::MagicEffect::SummonBonelord: + case ESM::MagicEffect::SummonWingedTwilight: + case ESM::MagicEffect::SummonHunger: + case ESM::MagicEffect::SummonGoldenSaint: + case ESM::MagicEffect::SummonFlameAtronach: + case ESM::MagicEffect::SummonFrostAtronach: + case ESM::MagicEffect::SummonStormAtronach: + case ESM::MagicEffect::SummonCenturionSphere: + case ESM::MagicEffect::SummonFabricant: + case ESM::MagicEffect::SummonWolf: + case ESM::MagicEffect::SummonBear: + case ESM::MagicEffect::SummonBonewolf: + case ESM::MagicEffect::SummonCreature04: + case ESM::MagicEffect::SummonCreature05: + if (!target.isInCell()) + invalid = true; + else + effect.mArg = summonCreature(effect.mEffectId, target); + break; + case ESM::MagicEffect::BoundGloves: + if (!target.getClass().hasInventoryStore(target)) + { + invalid = true; + break; + } + addBoundItem( + world->getStore().get().find("sMagicBoundRightGauntletID")->mValue.getString(), + target); + // left gauntlet added below + [[fallthrough]]; + case ESM::MagicEffect::BoundDagger: + case ESM::MagicEffect::BoundLongsword: + case ESM::MagicEffect::BoundMace: + case ESM::MagicEffect::BoundBattleAxe: + case ESM::MagicEffect::BoundSpear: + case ESM::MagicEffect::BoundLongbow: + case ESM::MagicEffect::BoundCuirass: + case ESM::MagicEffect::BoundHelm: + case ESM::MagicEffect::BoundBoots: + case ESM::MagicEffect::BoundShield: + if (!target.getClass().hasInventoryStore(target)) + invalid = true; + else + { + const std::string& item = sBoundItemsMap.at(effect.mEffectId); + addBoundItem(world->getStore().get().find(item)->mValue.getString(), target); + } + break; + case ESM::MagicEffect::FireDamage: + case ESM::MagicEffect::ShockDamage: + case ESM::MagicEffect::FrostDamage: + case ESM::MagicEffect::DamageHealth: + case ESM::MagicEffect::Poison: + case ESM::MagicEffect::DamageMagicka: + case ESM::MagicEffect::DamageFatigue: + if (!godmode) + { + int index = 0; + if (effect.mEffectId == ESM::MagicEffect::DamageMagicka) + index = 1; + else if (effect.mEffectId == ESM::MagicEffect::DamageFatigue) + index = 2; + // Damage "Dynamic" abilities reduce the base value + if (spellParams.getType() == ESM::ActiveSpells::Type_Ability) + modDynamicStat(target, index, -effect.mMagnitude); + else + { + static const bool uncappedDamageFatigue + = Settings::Manager::getBool("uncapped damage fatigue", "Game"); + adjustDynamicStat(target, index, -effect.mMagnitude, index == 2 && uncappedDamageFatigue); + if (index == 0) + receivedMagicDamage = affectedHealth = true; + } + } + break; + case ESM::MagicEffect::DamageAttribute: + if (!godmode) + damageAttribute(target, effect, effect.mMagnitude); + break; + case ESM::MagicEffect::DamageSkill: + if (!target.getClass().isNpc()) + invalid = true; + else if (!godmode) { - auto& npcStats = target.getClass().getNpcStats(target); - SkillValue& skill = npcStats.getSkill(effect.mArg); // Damage Skill abilities reduce base skill :todd: - skill.setBase(std::max(skill.getBase() - effect.mMagnitude, 0.f)); + if (spellParams.getType() == ESM::ActiveSpells::Type_Ability) + { + auto& npcStats = target.getClass().getNpcStats(target); + SkillValue& skill = npcStats.getSkill(effect.mArg); + // Damage Skill abilities reduce base skill :todd: + skill.setBase(std::max(skill.getBase() - effect.mMagnitude, 0.f)); + } + else + damageSkill(target, effect, effect.mMagnitude); } + break; + case ESM::MagicEffect::RestoreAttribute: + restoreAttribute(target, effect, effect.mMagnitude); + break; + case ESM::MagicEffect::RestoreSkill: + if (!target.getClass().isNpc()) + invalid = true; else - damageSkill(target, effect, effect.mMagnitude); - } - break; - case ESM::MagicEffect::RestoreAttribute: - restoreAttribute(target, effect, effect.mMagnitude); - break; - case ESM::MagicEffect::RestoreSkill: - if(!target.getClass().isNpc()) - invalid = true; - else - restoreSkill(target, effect, effect.mMagnitude); - break; - case ESM::MagicEffect::RestoreHealth: - affectedHealth = true; - [[fallthrough]]; - case ESM::MagicEffect::RestoreMagicka: - case ESM::MagicEffect::RestoreFatigue: - adjustDynamicStat(target, effect.mEffectId - ESM::MagicEffect::RestoreHealth, effect.mMagnitude); - break; - case ESM::MagicEffect::SunDamage: + restoreSkill(target, effect, effect.mMagnitude); + break; + case ESM::MagicEffect::RestoreHealth: + affectedHealth = true; + [[fallthrough]]; + case ESM::MagicEffect::RestoreMagicka: + case ESM::MagicEffect::RestoreFatigue: + adjustDynamicStat(target, effect.mEffectId - ESM::MagicEffect::RestoreHealth, effect.mMagnitude); + break; + case ESM::MagicEffect::SunDamage: { // isInCell shouldn't be needed, but updateActor called during game start - if (!target.isInCell() || !(target.getCell()->isExterior() || target.getCell()->isQuasiExterior()) || godmode) + if (!target.isInCell() || !(target.getCell()->isExterior() || target.getCell()->isQuasiExterior()) + || godmode) break; const float sunRisen = world->getSunPercentage(); - static float fMagicSunBlockedMult = world->getStore().get().find("fMagicSunBlockedMult")->mValue.getFloat(); - const float damageScale = std::clamp(std::max(world->getSunVisibility() * sunRisen, fMagicSunBlockedMult * sunRisen), 0.f, 1.f); + static float fMagicSunBlockedMult + = world->getStore().get().find("fMagicSunBlockedMult")->mValue.getFloat(); + const float damageScale = std::clamp( + std::max(world->getSunVisibility() * sunRisen, fMagicSunBlockedMult * sunRisen), 0.f, 1.f); float damage = effect.mMagnitude * damageScale; adjustDynamicStat(target, 0, -damage); if (damage > 0.f) receivedMagicDamage = affectedHealth = true; } break; - case ESM::MagicEffect::DrainHealth: - case ESM::MagicEffect::DrainMagicka: - case ESM::MagicEffect::DrainFatigue: - if(!godmode) - { - static const bool uncappedDamageFatigue = Settings::Manager::getBool("uncapped damage fatigue", "Game"); - int index = effect.mEffectId - ESM::MagicEffect::DrainHealth; - adjustDynamicStat(target, index, -effect.mMagnitude, uncappedDamageFatigue && index == 2); - if(index == 0) - receivedMagicDamage = affectedHealth = true; - } - break; - case ESM::MagicEffect::FortifyHealth: - case ESM::MagicEffect::FortifyMagicka: - case ESM::MagicEffect::FortifyFatigue: - if(spellParams.getType() == ESM::ActiveSpells::Type_Ability) - modDynamicStat(target, effect.mEffectId - ESM::MagicEffect::FortifyHealth, effect.mMagnitude); - else - adjustDynamicStat(target, effect.mEffectId - ESM::MagicEffect::FortifyHealth, effect.mMagnitude, false, true); - break; - case ESM::MagicEffect::DrainAttribute: - if(!godmode) - damageAttribute(target, effect, effect.mMagnitude); - break; - case ESM::MagicEffect::FortifyAttribute: - // Abilities affect base stats, but not for drain - if(spellParams.getType() == ESM::ActiveSpells::Type_Ability) - { - auto& creatureStats = target.getClass().getCreatureStats(target); - AttributeValue attr = creatureStats.getAttribute(effect.mArg); - attr.setBase(attr.getBase() + effect.mMagnitude); - creatureStats.setAttribute(effect.mArg, attr); - } - else - fortifyAttribute(target, effect, effect.mMagnitude); - break; - case ESM::MagicEffect::DrainSkill: - if(!target.getClass().isNpc()) - invalid = true; - else if(!godmode) - damageSkill(target, effect, effect.mMagnitude); - break; - case ESM::MagicEffect::FortifySkill: - if(!target.getClass().isNpc()) - invalid = true; - else if(spellParams.getType() == ESM::ActiveSpells::Type_Ability) - { + case ESM::MagicEffect::DrainHealth: + case ESM::MagicEffect::DrainMagicka: + case ESM::MagicEffect::DrainFatigue: + if (!godmode) + { + static const bool uncappedDamageFatigue + = Settings::Manager::getBool("uncapped damage fatigue", "Game"); + int index = effect.mEffectId - ESM::MagicEffect::DrainHealth; + adjustDynamicStat(target, index, -effect.mMagnitude, uncappedDamageFatigue && index == 2); + if (index == 0) + receivedMagicDamage = affectedHealth = true; + } + break; + case ESM::MagicEffect::FortifyHealth: + case ESM::MagicEffect::FortifyMagicka: + case ESM::MagicEffect::FortifyFatigue: + if (spellParams.getType() == ESM::ActiveSpells::Type_Ability) + modDynamicStat(target, effect.mEffectId - ESM::MagicEffect::FortifyHealth, effect.mMagnitude); + else + adjustDynamicStat( + target, effect.mEffectId - ESM::MagicEffect::FortifyHealth, effect.mMagnitude, false, true); + break; + case ESM::MagicEffect::DrainAttribute: + if (!godmode) + damageAttribute(target, effect, effect.mMagnitude); + break; + case ESM::MagicEffect::FortifyAttribute: // Abilities affect base stats, but not for drain - auto& npcStats = target.getClass().getNpcStats(target); - auto& skill = npcStats.getSkill(effect.mArg); - skill.setBase(skill.getBase() + effect.mMagnitude); - } - else - fortifySkill(target, effect, effect.mMagnitude); - break; - case ESM::MagicEffect::FortifyMaximumMagicka: - recalculateMagicka = true; - break; - case ESM::MagicEffect::AbsorbHealth: - case ESM::MagicEffect::AbsorbMagicka: - case ESM::MagicEffect::AbsorbFatigue: - if(!godmode) - { - int index = effect.mEffectId - ESM::MagicEffect::AbsorbHealth; - adjustDynamicStat(target, index, -effect.mMagnitude); - if(!caster.isEmpty()) - adjustDynamicStat(caster, index, effect.mMagnitude); - if(index == 0) - receivedMagicDamage = affectedHealth = true; - } - break; - case ESM::MagicEffect::AbsorbAttribute: - if(!godmode) - { - damageAttribute(target, effect, effect.mMagnitude); - if(!caster.isEmpty()) - fortifyAttribute(caster, effect, effect.mMagnitude); - } - break; - case ESM::MagicEffect::AbsorbSkill: - if(!target.getClass().isNpc()) - invalid = true; - else if(!godmode) + if (spellParams.getType() == ESM::ActiveSpells::Type_Ability) + { + auto& creatureStats = target.getClass().getCreatureStats(target); + AttributeValue attr = creatureStats.getAttribute(effect.mArg); + attr.setBase(attr.getBase() + effect.mMagnitude); + creatureStats.setAttribute(effect.mArg, attr); + } + else + fortifyAttribute(target, effect, effect.mMagnitude); + break; + case ESM::MagicEffect::DrainSkill: + if (!target.getClass().isNpc()) + invalid = true; + else if (!godmode) + damageSkill(target, effect, effect.mMagnitude); + break; + case ESM::MagicEffect::FortifySkill: + if (!target.getClass().isNpc()) + invalid = true; + else if (spellParams.getType() == ESM::ActiveSpells::Type_Ability) + { + // Abilities affect base stats, but not for drain + auto& npcStats = target.getClass().getNpcStats(target); + auto& skill = npcStats.getSkill(effect.mArg); + skill.setBase(skill.getBase() + effect.mMagnitude); + } + else + fortifySkill(target, effect, effect.mMagnitude); + break; + case ESM::MagicEffect::FortifyMaximumMagicka: + recalculateMagicka = true; + break; + case ESM::MagicEffect::AbsorbHealth: + case ESM::MagicEffect::AbsorbMagicka: + case ESM::MagicEffect::AbsorbFatigue: + if (!godmode) + { + int index = effect.mEffectId - ESM::MagicEffect::AbsorbHealth; + adjustDynamicStat(target, index, -effect.mMagnitude); + if (!caster.isEmpty()) + adjustDynamicStat(caster, index, effect.mMagnitude); + if (index == 0) + receivedMagicDamage = affectedHealth = true; + } + break; + case ESM::MagicEffect::AbsorbAttribute: + if (!godmode) + { + damageAttribute(target, effect, effect.mMagnitude); + if (!caster.isEmpty()) + fortifyAttribute(caster, effect, effect.mMagnitude); + } + break; + case ESM::MagicEffect::AbsorbSkill: + if (!target.getClass().isNpc()) + invalid = true; + else if (!godmode) + { + damageSkill(target, effect, effect.mMagnitude); + if (!caster.isEmpty()) + fortifySkill(caster, effect, effect.mMagnitude); + } + break; + case ESM::MagicEffect::DisintegrateArmor: { - damageSkill(target, effect, effect.mMagnitude); - if(!caster.isEmpty()) - fortifySkill(caster, effect, effect.mMagnitude); + if (!target.getClass().hasInventoryStore(target)) + { + invalid = true; + break; + } + if (godmode) + break; + static const std::array priorities{ + MWWorld::InventoryStore::Slot_CarriedLeft, + MWWorld::InventoryStore::Slot_Cuirass, + MWWorld::InventoryStore::Slot_LeftPauldron, + MWWorld::InventoryStore::Slot_RightPauldron, + MWWorld::InventoryStore::Slot_LeftGauntlet, + MWWorld::InventoryStore::Slot_RightGauntlet, + MWWorld::InventoryStore::Slot_Helmet, + MWWorld::InventoryStore::Slot_Greaves, + MWWorld::InventoryStore::Slot_Boots, + }; + for (const int priority : priorities) + { + if (disintegrateSlot(target, priority, effect.mMagnitude)) + break; + } + break; } - break; - case ESM::MagicEffect::DisintegrateArmor: + case ESM::MagicEffect::DisintegrateWeapon: + if (!target.getClass().hasInventoryStore(target)) + { + invalid = true; + break; + } + if (!godmode) + disintegrateSlot(target, MWWorld::InventoryStore::Slot_CarriedRight, effect.mMagnitude); + break; + } + } + + bool shouldRemoveEffect(const MWWorld::Ptr& target, const ESM::ActiveEffect& effect) + { + const auto world = MWBase::Environment::get().getWorld(); + switch (effect.mEffectId) { - if (!target.getClass().hasInventoryStore(target)) + case ESM::MagicEffect::Levitate: { - invalid = true; + if (!world->isLevitationEnabled()) + { + if (target == getPlayer()) + MWBase::Environment::get().getWindowManager()->messageBox("#{sLevitateDisabled}"); + return true; + } break; } - if (godmode) - break; - static const std::array priorities + case ESM::MagicEffect::Recall: + case ESM::MagicEffect::DivineIntervention: + case ESM::MagicEffect::AlmsiviIntervention: { - MWWorld::InventoryStore::Slot_CarriedLeft, - MWWorld::InventoryStore::Slot_Cuirass, - MWWorld::InventoryStore::Slot_LeftPauldron, - MWWorld::InventoryStore::Slot_RightPauldron, - MWWorld::InventoryStore::Slot_LeftGauntlet, - MWWorld::InventoryStore::Slot_RightGauntlet, - MWWorld::InventoryStore::Slot_Helmet, - MWWorld::InventoryStore::Slot_Greaves, - MWWorld::InventoryStore::Slot_Boots, - }; - for (const int priority : priorities) - { - if (disintegrateSlot(target, priority, effect.mMagnitude)) - break; + return effect.mFlags & ESM::ActiveEffect::Flag_Applied; } - break; - } - case ESM::MagicEffect::DisintegrateWeapon: - if (!target.getClass().hasInventoryStore(target)) + case ESM::MagicEffect::WaterWalking: { - invalid = true; + if (target.getClass().isPureWaterCreature(target) && world->isSwimming(target)) + return true; + if (effect.mFlags & ESM::ActiveEffect::Flag_Applied) + break; + if (!world->isWaterWalkingCastableOnTarget(target)) + { + if (target == getPlayer()) + MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicInvalidEffect}"); + return true; + } break; } - if (!godmode) - disintegrateSlot(target, MWWorld::InventoryStore::Slot_CarriedRight, effect.mMagnitude); - break; + } + return false; } -} -bool shouldRemoveEffect(const MWWorld::Ptr& target, const ESM::ActiveEffect& effect) -{ - const auto world = MWBase::Environment::get().getWorld(); - switch(effect.mEffectId) + MagicApplicationResult applyMagicEffect(const MWWorld::Ptr& target, const MWWorld::Ptr& caster, + ActiveSpells::ActiveSpellParams& spellParams, ESM::ActiveEffect& effect, float dt) { - case ESM::MagicEffect::Levitate: + const auto world = MWBase::Environment::get().getWorld(); + bool invalid = false; + bool receivedMagicDamage = false; + bool recalculateMagicka = false; + bool affectedHealth = false; + if (effect.mEffectId == ESM::MagicEffect::Corprus && spellParams.shouldWorsen()) { - if(!world->isLevitationEnabled()) + spellParams.worsen(); + for (auto& otherEffect : spellParams.getEffects()) { - if(target == getPlayer()) - MWBase::Environment::get().getWindowManager()->messageBox("#{sLevitateDisabled}"); - return true; + if (isCorprusEffect(otherEffect)) + applyMagicEffect(target, caster, spellParams, otherEffect, invalid, receivedMagicDamage, + affectedHealth, recalculateMagicka); } - break; + if (target == getPlayer()) + MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicCorprusWorsens}"); + return { MagicApplicationResult::Type::APPLIED, receivedMagicDamage, affectedHealth }; } - case ESM::MagicEffect::Recall: - case ESM::MagicEffect::DivineIntervention: - case ESM::MagicEffect::AlmsiviIntervention: + else if (shouldRemoveEffect(target, effect)) { - return effect.mFlags & ESM::ActiveEffect::Flag_Applied; + onMagicEffectRemoved(target, spellParams, effect); + return { MagicApplicationResult::Type::REMOVED, receivedMagicDamage, affectedHealth }; } - case ESM::MagicEffect::WaterWalking: + const auto* magicEffect = world->getStore().get().find(effect.mEffectId); + if (effect.mFlags & ESM::ActiveEffect::Flag_Applied) { - if (target.getClass().isPureWaterCreature(target) && world->isSwimming(target)) - return true; - if (effect.mFlags & ESM::ActiveEffect::Flag_Applied) - break; - if (!world->isWaterWalkingCastableOnTarget(target)) + if (magicEffect->mData.mFlags & ESM::MagicEffect::Flags::AppliedOnce) { - if(target == getPlayer()) - MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicInvalidEffect}"); - return true; + effect.mTimeLeft -= dt; + return { MagicApplicationResult::Type::APPLIED, receivedMagicDamage, affectedHealth }; } - break; + else if (!dt) + return { MagicApplicationResult::Type::APPLIED, receivedMagicDamage, affectedHealth }; } - } - return false; -} - -MagicApplicationResult applyMagicEffect(const MWWorld::Ptr& target, const MWWorld::Ptr& caster, ActiveSpells::ActiveSpellParams& spellParams, ESM::ActiveEffect& effect, float dt) -{ - const auto world = MWBase::Environment::get().getWorld(); - bool invalid = false; - bool receivedMagicDamage = false; - bool recalculateMagicka = false; - bool affectedHealth = false; - if(effect.mEffectId == ESM::MagicEffect::Corprus && spellParams.shouldWorsen()) - { - spellParams.worsen(); - for(auto& otherEffect : spellParams.getEffects()) + if (effect.mEffectId == ESM::MagicEffect::Lock) { - if(isCorprusEffect(otherEffect)) - applyMagicEffect(target, caster, spellParams, otherEffect, invalid, receivedMagicDamage, affectedHealth, recalculateMagicka); - } - if(target == getPlayer()) - MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicCorprusWorsens}"); - return {MagicApplicationResult::Type::APPLIED, receivedMagicDamage, affectedHealth}; - } - else if(shouldRemoveEffect(target, effect)) - { - onMagicEffectRemoved(target, spellParams, effect); - return {MagicApplicationResult::Type::REMOVED, receivedMagicDamage, affectedHealth}; - } - const auto* magicEffect = world->getStore().get().find(effect.mEffectId); - if(effect.mFlags & ESM::ActiveEffect::Flag_Applied) - { - if(magicEffect->mData.mFlags & ESM::MagicEffect::Flags::AppliedOnce) - { - effect.mTimeLeft -= dt; - return {MagicApplicationResult::Type::APPLIED, receivedMagicDamage, affectedHealth}; - } - else if(!dt) - return {MagicApplicationResult::Type::APPLIED, receivedMagicDamage, affectedHealth}; - } - if(effect.mEffectId == ESM::MagicEffect::Lock) - { - if(target.getClass().canLock(target)) - { - MWRender::Animation* animation = world->getAnimation(target); - if(animation) - animation->addSpellCastGlow(magicEffect); - int magnitude = static_cast(roll(effect)); - if(target.getCellRef().getLockLevel() < magnitude) //If the door is not already locked to a higher value, lock it to spell magnitude + if (target.getClass().canLock(target)) { - if(caster == getPlayer()) - MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicLockSuccess}"); - target.getCellRef().lock(magnitude); + MWRender::Animation* animation = world->getAnimation(target); + if (animation) + animation->addSpellCastGlow(magicEffect); + int magnitude = static_cast(roll(effect)); + if (target.getCellRef().getLockLevel() + < magnitude) // If the door is not already locked to a higher value, lock it to spell magnitude + { + if (caster == getPlayer()) + MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicLockSuccess}"); + target.getCellRef().lock(magnitude); + } } + else + invalid = true; } - else - invalid = true; - } - else if(effect.mEffectId == ESM::MagicEffect::Open) - { - if(target.getClass().canLock(target)) + else if (effect.mEffectId == ESM::MagicEffect::Open) { - // Use the player instead of the caster for vanilla crime compatibility - MWBase::Environment::get().getMechanicsManager()->unlockAttempted(getPlayer(), target); - - MWRender::Animation* animation = world->getAnimation(target); - if(animation) - animation->addSpellCastGlow(magicEffect); - int magnitude = static_cast(roll(effect)); - if(target.getCellRef().getLockLevel() <= magnitude) + if (target.getClass().canLock(target)) { - if(target.getCellRef().getLockLevel() > 0) + // Use the player instead of the caster for vanilla crime compatibility + MWBase::Environment::get().getMechanicsManager()->unlockAttempted(getPlayer(), target); + + MWRender::Animation* animation = world->getAnimation(target); + if (animation) + animation->addSpellCastGlow(magicEffect); + int magnitude = static_cast(roll(effect)); + if (target.getCellRef().getLockLevel() <= magnitude) { - MWBase::Environment::get().getSoundManager()->playSound3D(target, "Open Lock", 1.f, 1.f); + if (target.getCellRef().getLockLevel() > 0) + { + MWBase::Environment::get().getSoundManager()->playSound3D(target, "Open Lock", 1.f, 1.f); - if(caster == getPlayer()) - MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicOpenSuccess}"); + if (caster == getPlayer()) + MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicOpenSuccess}"); + } + target.getCellRef().unlock(); + } + else + { + MWBase::Environment::get().getSoundManager()->playSound3D(target, "Open Lock Fail", 1.f, 1.f); } - target.getCellRef().unlock(); } else - { - MWBase::Environment::get().getSoundManager()->playSound3D(target, "Open Lock Fail", 1.f, 1.f); - } + invalid = true; } - else - invalid = true; - } - else if(!target.getClass().isActor()) - { - invalid = true; - } - else - { - auto& stats = target.getClass().getCreatureStats(target); - auto& magnitudes = stats.getMagicEffects(); - if(spellParams.getType() != ESM::ActiveSpells::Type_Ability && !(effect.mFlags & ESM::ActiveEffect::Flag_Applied)) + else if (!target.getClass().isActor()) { - MagicApplicationResult::Type result = applyProtections(target, caster, spellParams, effect, magicEffect); - if(result != MagicApplicationResult::Type::APPLIED) - return {result, receivedMagicDamage, affectedHealth}; + invalid = true; } - float oldMagnitude = 0.f; - if(effect.mFlags & ESM::ActiveEffect::Flag_Applied) - oldMagnitude = effect.mMagnitude; else { - if(spellParams.getType() != ESM::ActiveSpells::Type_Enchantment) - playEffects(target, *magicEffect, spellParams.getType() == ESM::ActiveSpells::Type_Consumable || spellParams.getType() == ESM::ActiveSpells::Type_Temporary); - if(effect.mEffectId == ESM::MagicEffect::Soultrap && !target.getClass().isNpc() && target.getType() == ESM::Creature::sRecordId && target.get()->mBase->mData.mSoul == 0 && caster == getPlayer()) - MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicInvalidTarget}"); - } - float magnitude = roll(effect); - //Note that there's an early out for Flag_Applied AppliedOnce effects so we don't have to exclude them here - effect.mMagnitude = magnitude; - if(!(magicEffect->mData.mFlags & (ESM::MagicEffect::Flags::NoMagnitude | ESM::MagicEffect::Flags::AppliedOnce))) - { - if(effect.mDuration != 0) + auto& stats = target.getClass().getCreatureStats(target); + auto& magnitudes = stats.getMagicEffects(); + if (spellParams.getType() != ESM::ActiveSpells::Type_Ability + && !(effect.mFlags & ESM::ActiveEffect::Flag_Applied)) { - float mult = dt; - if(spellParams.getType() == ESM::ActiveSpells::Type_Consumable || spellParams.getType() == ESM::ActiveSpells::Type_Temporary) - mult = std::min(effect.mTimeLeft, dt); - effect.mMagnitude *= mult; + MagicApplicationResult::Type result + = applyProtections(target, caster, spellParams, effect, magicEffect); + if (result != MagicApplicationResult::Type::APPLIED) + return { result, receivedMagicDamage, affectedHealth }; } - if(effect.mMagnitude == 0) + float oldMagnitude = 0.f; + if (effect.mFlags & ESM::ActiveEffect::Flag_Applied) + oldMagnitude = effect.mMagnitude; + else { - effect.mMagnitude = oldMagnitude; - effect.mFlags |= ESM::ActiveEffect::Flag_Applied | ESM::ActiveEffect::Flag_Remove; - effect.mTimeLeft -= dt; - return {MagicApplicationResult::Type::APPLIED, receivedMagicDamage, affectedHealth}; + if (spellParams.getType() != ESM::ActiveSpells::Type_Enchantment) + playEffects(target, *magicEffect, + spellParams.getType() == ESM::ActiveSpells::Type_Consumable + || spellParams.getType() == ESM::ActiveSpells::Type_Temporary); + if (effect.mEffectId == ESM::MagicEffect::Soultrap && !target.getClass().isNpc() + && target.getType() == ESM::Creature::sRecordId + && target.get()->mBase->mData.mSoul == 0 && caster == getPlayer()) + MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicInvalidTarget}"); + } + float magnitude = roll(effect); + // Note that there's an early out for Flag_Applied AppliedOnce effects so we don't have to exclude them here + effect.mMagnitude = magnitude; + if (!(magicEffect->mData.mFlags + & (ESM::MagicEffect::Flags::NoMagnitude | ESM::MagicEffect::Flags::AppliedOnce))) + { + if (effect.mDuration != 0) + { + float mult = dt; + if (spellParams.getType() == ESM::ActiveSpells::Type_Consumable + || spellParams.getType() == ESM::ActiveSpells::Type_Temporary) + mult = std::min(effect.mTimeLeft, dt); + effect.mMagnitude *= mult; + } + if (effect.mMagnitude == 0) + { + effect.mMagnitude = oldMagnitude; + effect.mFlags |= ESM::ActiveEffect::Flag_Applied | ESM::ActiveEffect::Flag_Remove; + effect.mTimeLeft -= dt; + return { MagicApplicationResult::Type::APPLIED, receivedMagicDamage, affectedHealth }; + } } + if (effect.mEffectId == ESM::MagicEffect::Corprus) + spellParams.worsen(); + else + applyMagicEffect(target, caster, spellParams, effect, invalid, receivedMagicDamage, affectedHealth, + recalculateMagicka); + effect.mMagnitude = magnitude; + magnitudes.add(EffectKey(effect.mEffectId, effect.mArg), EffectParam(effect.mMagnitude - oldMagnitude)); + } + effect.mTimeLeft -= dt; + if (invalid) + { + effect.mTimeLeft = 0; + effect.mFlags |= ESM::ActiveEffect::Flag_Remove; + auto anim = world->getAnimation(target); + if (anim) + anim->removeEffect(effect.mEffectId); } - if(effect.mEffectId == ESM::MagicEffect::Corprus) - spellParams.worsen(); else - applyMagicEffect(target, caster, spellParams, effect, invalid, receivedMagicDamage, affectedHealth, recalculateMagicka); - effect.mMagnitude = magnitude; - magnitudes.add(EffectKey(effect.mEffectId, effect.mArg), EffectParam(effect.mMagnitude - oldMagnitude)); - } - effect.mTimeLeft -= dt; - if(invalid) - { - effect.mTimeLeft = 0; - effect.mFlags |= ESM::ActiveEffect::Flag_Remove; - auto anim = world->getAnimation(target); - if(anim) - anim->removeEffect(effect.mEffectId); + effect.mFlags |= ESM::ActiveEffect::Flag_Applied | ESM::ActiveEffect::Flag_Remove; + if (recalculateMagicka) + target.getClass().getCreatureStats(target).recalculateMagicka(); + return { MagicApplicationResult::Type::APPLIED, receivedMagicDamage, affectedHealth }; } - else - effect.mFlags |= ESM::ActiveEffect::Flag_Applied | ESM::ActiveEffect::Flag_Remove; - if(recalculateMagicka) - target.getClass().getCreatureStats(target).recalculateMagicka(); - return {MagicApplicationResult::Type::APPLIED, receivedMagicDamage, affectedHealth}; -} -void removeMagicEffect(const MWWorld::Ptr& target, ActiveSpells::ActiveSpellParams& spellParams, const ESM::ActiveEffect& effect) -{ - const auto world = MWBase::Environment::get().getWorld(); - auto& magnitudes = target.getClass().getCreatureStats(target).getMagicEffects(); - bool invalid; - switch(effect.mEffectId) + void removeMagicEffect( + const MWWorld::Ptr& target, ActiveSpells::ActiveSpellParams& spellParams, const ESM::ActiveEffect& effect) { - case ESM::MagicEffect::CommandCreature: - case ESM::MagicEffect::CommandHumanoid: - if(magnitudes.get(effect.mEffectId).getMagnitude() <= 0.f) - { - auto& seq = target.getClass().getCreatureStats(target).getAiSequence(); - seq.erasePackageIf([&](const auto& package) + const auto world = MWBase::Environment::get().getWorld(); + auto& magnitudes = target.getClass().getCreatureStats(target).getMagicEffects(); + bool invalid; + switch (effect.mEffectId) + { + case ESM::MagicEffect::CommandCreature: + case ESM::MagicEffect::CommandHumanoid: + if (magnitudes.get(effect.mEffectId).getMagnitude() <= 0.f) { - return package->getTypeId() == MWMechanics::AiPackageTypeId::Follow && static_cast(package.get())->isCommanded(); - }); - } - break; - case ESM::MagicEffect::ExtraSpell: - if(magnitudes.get(effect.mEffectId).getMagnitude() <= 0.f) - target.getClass().getInventoryStore(target).autoEquip(target); - break; - case ESM::MagicEffect::TurnUndead: + auto& seq = target.getClass().getCreatureStats(target).getAiSequence(); + seq.erasePackageIf([&](const auto& package) { + return package->getTypeId() == MWMechanics::AiPackageTypeId::Follow + && static_cast(package.get())->isCommanded(); + }); + } + break; + case ESM::MagicEffect::ExtraSpell: + if (magnitudes.get(effect.mEffectId).getMagnitude() <= 0.f) + target.getClass().getInventoryStore(target).autoEquip(target); + break; + case ESM::MagicEffect::TurnUndead: { auto& creatureStats = target.getClass().getCreatureStats(target); Stat stat = creatureStats.getAiSetting(AiSetting::Flee); @@ -1021,69 +1068,75 @@ void removeMagicEffect(const MWWorld::Ptr& target, ActiveSpells::ActiveSpellPara creatureStats.setAiSetting(AiSetting::Flee, stat); } break; - case ESM::MagicEffect::FrenzyCreature: - case ESM::MagicEffect::FrenzyHumanoid: - modifyAiSetting(target, effect, ESM::MagicEffect::FrenzyCreature, AiSetting::Fight, -effect.mMagnitude, invalid); - break; - case ESM::MagicEffect::CalmCreature: - case ESM::MagicEffect::CalmHumanoid: - modifyAiSetting(target, effect, ESM::MagicEffect::CalmCreature, AiSetting::Fight, effect.mMagnitude, invalid); - break; - case ESM::MagicEffect::DemoralizeCreature: - case ESM::MagicEffect::DemoralizeHumanoid: - modifyAiSetting(target, effect, ESM::MagicEffect::DemoralizeCreature, AiSetting::Flee, -effect.mMagnitude, invalid); - break; - case ESM::MagicEffect::NightEye: + case ESM::MagicEffect::FrenzyCreature: + case ESM::MagicEffect::FrenzyHumanoid: + modifyAiSetting( + target, effect, ESM::MagicEffect::FrenzyCreature, AiSetting::Fight, -effect.mMagnitude, invalid); + break; + case ESM::MagicEffect::CalmCreature: + case ESM::MagicEffect::CalmHumanoid: + modifyAiSetting( + target, effect, ESM::MagicEffect::CalmCreature, AiSetting::Fight, effect.mMagnitude, invalid); + break; + case ESM::MagicEffect::DemoralizeCreature: + case ESM::MagicEffect::DemoralizeHumanoid: + modifyAiSetting( + target, effect, ESM::MagicEffect::DemoralizeCreature, AiSetting::Flee, -effect.mMagnitude, invalid); + break; + case ESM::MagicEffect::NightEye: { const MWMechanics::EffectParam nightEye = magnitudes.get(effect.mEffectId); - if(nightEye.getMagnitude() < 0.f && nightEye.getBase() < 0) + if (nightEye.getMagnitude() < 0.f && nightEye.getBase() < 0) { - // The PCVisionBonus functions are different from every other magic effect function in that they clamp the value to [0, 1]. - // Morrowind.exe applies the same clamping to the night-eye effect, which can create situations where an effect is still active - // (i.e. shown in the menu) but the screen is no longer bright. Modifying the base value here should prevent that while preserving their function. + // The PCVisionBonus functions are different from every other magic effect function in that they + // clamp the value to [0, 1]. Morrowind.exe applies the same clamping to the night-eye effect, which + // can create situations where an effect is still active (i.e. shown in the menu) but the screen is + // no longer bright. Modifying the base value here should prevent that while preserving their + // function. float delta = std::clamp(-nightEye.getMagnitude(), 0.f, -static_cast(nightEye.getBase())); magnitudes.modifyBase(effect.mEffectId, static_cast(delta)); } } break; - case ESM::MagicEffect::RallyCreature: - case ESM::MagicEffect::RallyHumanoid: - modifyAiSetting(target, effect, ESM::MagicEffect::RallyCreature, AiSetting::Flee, effect.mMagnitude, invalid); - break; - case ESM::MagicEffect::Sound: - if(magnitudes.get(effect.mEffectId).getModifier() <= 0.f && target == getPlayer()) - MWBase::Environment::get().getSoundManager()->stopSound3D(target, "magic sound"); - break; - case ESM::MagicEffect::SummonScamp: - case ESM::MagicEffect::SummonClannfear: - case ESM::MagicEffect::SummonDaedroth: - case ESM::MagicEffect::SummonDremora: - case ESM::MagicEffect::SummonAncestralGhost: - case ESM::MagicEffect::SummonSkeletalMinion: - case ESM::MagicEffect::SummonBonewalker: - case ESM::MagicEffect::SummonGreaterBonewalker: - case ESM::MagicEffect::SummonBonelord: - case ESM::MagicEffect::SummonWingedTwilight: - case ESM::MagicEffect::SummonHunger: - case ESM::MagicEffect::SummonGoldenSaint: - case ESM::MagicEffect::SummonFlameAtronach: - case ESM::MagicEffect::SummonFrostAtronach: - case ESM::MagicEffect::SummonStormAtronach: - case ESM::MagicEffect::SummonCenturionSphere: - case ESM::MagicEffect::SummonFabricant: - case ESM::MagicEffect::SummonWolf: - case ESM::MagicEffect::SummonBear: - case ESM::MagicEffect::SummonBonewolf: - case ESM::MagicEffect::SummonCreature04: - case ESM::MagicEffect::SummonCreature05: + case ESM::MagicEffect::RallyCreature: + case ESM::MagicEffect::RallyHumanoid: + modifyAiSetting( + target, effect, ESM::MagicEffect::RallyCreature, AiSetting::Flee, effect.mMagnitude, invalid); + break; + case ESM::MagicEffect::Sound: + if (magnitudes.get(effect.mEffectId).getModifier() <= 0.f && target == getPlayer()) + MWBase::Environment::get().getSoundManager()->stopSound3D(target, "magic sound"); + break; + case ESM::MagicEffect::SummonScamp: + case ESM::MagicEffect::SummonClannfear: + case ESM::MagicEffect::SummonDaedroth: + case ESM::MagicEffect::SummonDremora: + case ESM::MagicEffect::SummonAncestralGhost: + case ESM::MagicEffect::SummonSkeletalMinion: + case ESM::MagicEffect::SummonBonewalker: + case ESM::MagicEffect::SummonGreaterBonewalker: + case ESM::MagicEffect::SummonBonelord: + case ESM::MagicEffect::SummonWingedTwilight: + case ESM::MagicEffect::SummonHunger: + case ESM::MagicEffect::SummonGoldenSaint: + case ESM::MagicEffect::SummonFlameAtronach: + case ESM::MagicEffect::SummonFrostAtronach: + case ESM::MagicEffect::SummonStormAtronach: + case ESM::MagicEffect::SummonCenturionSphere: + case ESM::MagicEffect::SummonFabricant: + case ESM::MagicEffect::SummonWolf: + case ESM::MagicEffect::SummonBear: + case ESM::MagicEffect::SummonBonewolf: + case ESM::MagicEffect::SummonCreature04: + case ESM::MagicEffect::SummonCreature05: { - if(effect.mArg != -1) + if (effect.mArg != -1) MWBase::Environment::get().getMechanicsManager()->cleanupSummonedCreature(target, effect.mArg); auto& summons = target.getClass().getCreatureStats(target).getSummonedCreatureMap(); auto [begin, end] = summons.equal_range(effect.mEffectId); - for(auto it = begin; it != end; ++it) + for (auto it = begin; it != end; ++it) { - if(it->second == effect.mArg) + if (it->second == effect.mArg) { summons.erase(it); break; @@ -1091,123 +1144,127 @@ void removeMagicEffect(const MWWorld::Ptr& target, ActiveSpells::ActiveSpellPara } } break; - case ESM::MagicEffect::BoundGloves: - removeBoundItem(world->getStore().get().find("sMagicBoundRightGauntletID")->mValue.getString(), target); - [[fallthrough]]; - case ESM::MagicEffect::BoundDagger: - case ESM::MagicEffect::BoundLongsword: - case ESM::MagicEffect::BoundMace: - case ESM::MagicEffect::BoundBattleAxe: - case ESM::MagicEffect::BoundSpear: - case ESM::MagicEffect::BoundLongbow: - case ESM::MagicEffect::BoundCuirass: - case ESM::MagicEffect::BoundHelm: - case ESM::MagicEffect::BoundBoots: - case ESM::MagicEffect::BoundShield: + case ESM::MagicEffect::BoundGloves: + removeBoundItem( + world->getStore().get().find("sMagicBoundRightGauntletID")->mValue.getString(), + target); + [[fallthrough]]; + case ESM::MagicEffect::BoundDagger: + case ESM::MagicEffect::BoundLongsword: + case ESM::MagicEffect::BoundMace: + case ESM::MagicEffect::BoundBattleAxe: + case ESM::MagicEffect::BoundSpear: + case ESM::MagicEffect::BoundLongbow: + case ESM::MagicEffect::BoundCuirass: + case ESM::MagicEffect::BoundHelm: + case ESM::MagicEffect::BoundBoots: + case ESM::MagicEffect::BoundShield: { const std::string& item = sBoundItemsMap.at(effect.mEffectId); removeBoundItem(world->getStore().get().find(item)->mValue.getString(), target); } break; - case ESM::MagicEffect::DrainHealth: - case ESM::MagicEffect::DrainMagicka: - case ESM::MagicEffect::DrainFatigue: - adjustDynamicStat(target, effect.mEffectId - ESM::MagicEffect::DrainHealth, effect.mMagnitude); - break; - case ESM::MagicEffect::FortifyHealth: - case ESM::MagicEffect::FortifyMagicka: - case ESM::MagicEffect::FortifyFatigue: - if(spellParams.getType() == ESM::ActiveSpells::Type_Ability) - modDynamicStat(target, effect.mEffectId - ESM::MagicEffect::FortifyHealth, -effect.mMagnitude); - else - adjustDynamicStat(target, effect.mEffectId - ESM::MagicEffect::FortifyHealth, -effect.mMagnitude, true); - break; - case ESM::MagicEffect::DrainAttribute: - restoreAttribute(target, effect, effect.mMagnitude); - break; - case ESM::MagicEffect::FortifyAttribute: - // Abilities affect base stats, but not for drain - if(spellParams.getType() == ESM::ActiveSpells::Type_Ability) - { - auto& creatureStats = target.getClass().getCreatureStats(target); - AttributeValue attr = creatureStats.getAttribute(effect.mArg); - attr.setBase(attr.getBase() - effect.mMagnitude); - creatureStats.setAttribute(effect.mArg, attr); - } - else - fortifyAttribute(target, effect, -effect.mMagnitude); - break; - case ESM::MagicEffect::DrainSkill: - restoreSkill(target, effect, effect.mMagnitude); - break; - case ESM::MagicEffect::FortifySkill: - // Abilities affect base stats, but not for drain - if(spellParams.getType() == ESM::ActiveSpells::Type_Ability) - { - auto& npcStats = target.getClass().getNpcStats(target); - auto& skill = npcStats.getSkill(effect.mArg); - skill.setBase(skill.getBase() - effect.mMagnitude); - } - else - fortifySkill(target, effect, -effect.mMagnitude); - break; - case ESM::MagicEffect::FortifyMaximumMagicka: - target.getClass().getCreatureStats(target).recalculateMagicka(); - break; - case ESM::MagicEffect::AbsorbAttribute: + case ESM::MagicEffect::DrainHealth: + case ESM::MagicEffect::DrainMagicka: + case ESM::MagicEffect::DrainFatigue: + adjustDynamicStat(target, effect.mEffectId - ESM::MagicEffect::DrainHealth, effect.mMagnitude); + break; + case ESM::MagicEffect::FortifyHealth: + case ESM::MagicEffect::FortifyMagicka: + case ESM::MagicEffect::FortifyFatigue: + if (spellParams.getType() == ESM::ActiveSpells::Type_Ability) + modDynamicStat(target, effect.mEffectId - ESM::MagicEffect::FortifyHealth, -effect.mMagnitude); + else + adjustDynamicStat( + target, effect.mEffectId - ESM::MagicEffect::FortifyHealth, -effect.mMagnitude, true); + break; + case ESM::MagicEffect::DrainAttribute: + restoreAttribute(target, effect, effect.mMagnitude); + break; + case ESM::MagicEffect::FortifyAttribute: + // Abilities affect base stats, but not for drain + if (spellParams.getType() == ESM::ActiveSpells::Type_Ability) + { + auto& creatureStats = target.getClass().getCreatureStats(target); + AttributeValue attr = creatureStats.getAttribute(effect.mArg); + attr.setBase(attr.getBase() - effect.mMagnitude); + creatureStats.setAttribute(effect.mArg, attr); + } + else + fortifyAttribute(target, effect, -effect.mMagnitude); + break; + case ESM::MagicEffect::DrainSkill: + restoreSkill(target, effect, effect.mMagnitude); + break; + case ESM::MagicEffect::FortifySkill: + // Abilities affect base stats, but not for drain + if (spellParams.getType() == ESM::ActiveSpells::Type_Ability) + { + auto& npcStats = target.getClass().getNpcStats(target); + auto& skill = npcStats.getSkill(effect.mArg); + skill.setBase(skill.getBase() - effect.mMagnitude); + } + else + fortifySkill(target, effect, -effect.mMagnitude); + break; + case ESM::MagicEffect::FortifyMaximumMagicka: + target.getClass().getCreatureStats(target).recalculateMagicka(); + break; + case ESM::MagicEffect::AbsorbAttribute: { const auto caster = world->searchPtrViaActorId(spellParams.getCasterActorId()); restoreAttribute(target, effect, effect.mMagnitude); - if(!caster.isEmpty()) + if (!caster.isEmpty()) fortifyAttribute(caster, effect, -effect.mMagnitude); } break; - case ESM::MagicEffect::AbsorbSkill: + case ESM::MagicEffect::AbsorbSkill: { const auto caster = world->searchPtrViaActorId(spellParams.getCasterActorId()); restoreSkill(target, effect, effect.mMagnitude); - if(!caster.isEmpty()) + if (!caster.isEmpty()) fortifySkill(caster, effect, -effect.mMagnitude); } break; - case ESM::MagicEffect::Corprus: + case ESM::MagicEffect::Corprus: { int worsenings = spellParams.getWorsenings(); spellParams.resetWorsenings(); - if(worsenings > 0) + if (worsenings > 0) { - for(const auto& otherEffect : spellParams.getEffects()) + for (const auto& otherEffect : spellParams.getEffects()) { - if(isCorprusEffect(otherEffect, true)) + if (isCorprusEffect(otherEffect, true)) { - for(int i = 0; i < worsenings; i++) + for (int i = 0; i < worsenings; i++) removeMagicEffect(target, spellParams, otherEffect); } } } - //Note that we remove the effects, but keep the params - target.getClass().getCreatureStats(target).getActiveSpells().purge([&spellParams] (const ActiveSpells::ActiveSpellParams& params, const auto&) - { - return &spellParams == ¶ms; - }, target); + // Note that we remove the effects, but keep the params + target.getClass().getCreatureStats(target).getActiveSpells().purge( + [&spellParams]( + const ActiveSpells::ActiveSpellParams& params, const auto&) { return &spellParams == ¶ms; }, + target); } break; + } } -} -void onMagicEffectRemoved(const MWWorld::Ptr& target, ActiveSpells::ActiveSpellParams& spellParams, const ESM::ActiveEffect& effect) -{ - if(!(effect.mFlags & ESM::ActiveEffect::Flag_Applied)) - return; - auto& magnitudes = target.getClass().getCreatureStats(target).getMagicEffects(); - magnitudes.add(EffectKey(effect.mEffectId, effect.mArg), EffectParam(-effect.mMagnitude)); - removeMagicEffect(target, spellParams, effect); - if(magnitudes.get(effect.mEffectId).getMagnitude() <= 0.f) + void onMagicEffectRemoved( + const MWWorld::Ptr& target, ActiveSpells::ActiveSpellParams& spellParams, const ESM::ActiveEffect& effect) { - auto anim = MWBase::Environment::get().getWorld()->getAnimation(target); - if(anim) - anim->removeEffect(effect.mEffectId); + if (!(effect.mFlags & ESM::ActiveEffect::Flag_Applied)) + return; + auto& magnitudes = target.getClass().getCreatureStats(target).getMagicEffects(); + magnitudes.add(EffectKey(effect.mEffectId, effect.mArg), EffectParam(-effect.mMagnitude)); + removeMagicEffect(target, spellParams, effect); + if (magnitudes.get(effect.mEffectId).getMagnitude() <= 0.f) + { + auto anim = MWBase::Environment::get().getWorld()->getAnimation(target); + if (anim) + anim->removeEffect(effect.mEffectId); + } } -} } diff --git a/apps/openmw/mwmechanics/spelleffects.hpp b/apps/openmw/mwmechanics/spelleffects.hpp index 57caa5d33a..2dafedf31f 100644 --- a/apps/openmw/mwmechanics/spelleffects.hpp +++ b/apps/openmw/mwmechanics/spelleffects.hpp @@ -3,8 +3,8 @@ #include "activespells.hpp" -// These functions should probably be split up into separate Lua functions for each magic effect when magic is dehardcoded. -// That way ESM::MGEF could point to two Lua scripts for each effect. Needs discussion. +// These functions should probably be split up into separate Lua functions for each magic effect when magic is +// dehardcoded. That way ESM::MGEF could point to two Lua scripts for each effect. Needs discussion. namespace MWWorld { @@ -17,7 +17,9 @@ namespace MWMechanics { enum class Type { - APPLIED, REMOVED, REFLECTED + APPLIED, + REMOVED, + REFLECTED }; Type mType; bool mShowHit; @@ -25,10 +27,12 @@ namespace MWMechanics }; // Applies a tick of a single effect. Returns true if the effect should be removed immediately - MagicApplicationResult applyMagicEffect(const MWWorld::Ptr& target, const MWWorld::Ptr& caster, ActiveSpells::ActiveSpellParams& spellParams, ESM::ActiveEffect& effect, float dt); + MagicApplicationResult applyMagicEffect(const MWWorld::Ptr& target, const MWWorld::Ptr& caster, + ActiveSpells::ActiveSpellParams& spellParams, ESM::ActiveEffect& effect, float dt); // Undoes permanent effects created by ESM::MagicEffect::AppliedOnce - void onMagicEffectRemoved(const MWWorld::Ptr& target, ActiveSpells::ActiveSpellParams& spell, const ESM::ActiveEffect& effect); + void onMagicEffectRemoved( + const MWWorld::Ptr& target, ActiveSpells::ActiveSpellParams& spell, const ESM::ActiveEffect& effect); } #endif diff --git a/apps/openmw/mwmechanics/spelllist.cpp b/apps/openmw/mwmechanics/spelllist.cpp index 7c302f7861..6da7a4e11b 100644 --- a/apps/openmw/mwmechanics/spelllist.cpp +++ b/apps/openmw/mwmechanics/spelllist.cpp @@ -2,9 +2,9 @@ #include -#include #include #include +#include #include "spells.hpp" @@ -15,18 +15,18 @@ namespace { - template + template const std::vector getSpellList(std::string_view id) { return MWBase::Environment::get().getWorld()->getStore().get().find(id)->mSpells.mList; } - template + template bool withBaseRecord(std::string_view id, const std::function&)>& function) { T copy = *MWBase::Environment::get().getWorld()->getStore().get().find(id); bool changed = function(copy.mSpells.mList); - if(changed) + if (changed) MWBase::Environment::get().getWorld()->createOverrideRecord(copy); return changed; } @@ -34,11 +34,15 @@ namespace namespace MWMechanics { - SpellList::SpellList(const std::string& id, int type) : mId(id), mType(type) {} + SpellList::SpellList(const std::string& id, int type) + : mId(id) + , mType(type) + { + } bool SpellList::withBaseRecord(const std::function&)>& function) { - switch(mType) + switch (mType) { case ESM::REC_CREA: return ::withBaseRecord(mId, function); @@ -51,7 +55,7 @@ namespace MWMechanics const std::vector SpellList::getSpells() const { - switch(mType) + switch (mType) { case ESM::REC_CREA: return getSpellList(mId); @@ -67,34 +71,32 @@ namespace MWMechanics return MWBase::Environment::get().getWorld()->getStore().get().find(id); } - void SpellList::add (const ESM::Spell* spell) + void SpellList::add(const ESM::Spell* spell) { auto& id = spell->mId; - bool changed = withBaseRecord([&] (auto& spells) - { - for(const auto& it : spells) + bool changed = withBaseRecord([&](auto& spells) { + for (const auto& it : spells) { - if(Misc::StringUtils::ciEqual(id, it)) + if (Misc::StringUtils::ciEqual(id, it)) return false; } spells.push_back(id); return true; }); - if(changed) + if (changed) { - for(auto listener : mListeners) + for (auto listener : mListeners) listener->addSpell(spell); } } - void SpellList::remove (const ESM::Spell* spell) + void SpellList::remove(const ESM::Spell* spell) { auto& id = spell->mId; - bool changed = withBaseRecord([&] (auto& spells) - { - for(auto it = spells.begin(); it != spells.end(); it++) + bool changed = withBaseRecord([&](auto& spells) { + for (auto it = spells.begin(); it != spells.end(); it++) { - if(Misc::StringUtils::ciEqual(id, *it)) + if (Misc::StringUtils::ciEqual(id, *it)) { spells.erase(it); return true; @@ -102,20 +104,18 @@ namespace MWMechanics } return false; }); - if(changed) + if (changed) { - for(auto listener : mListeners) + for (auto listener : mListeners) listener->removeSpell(spell); } } - void SpellList::removeAll (const std::vector& ids) + void SpellList::removeAll(const std::vector& ids) { - bool changed = withBaseRecord([&] (auto& spells) - { - const auto it = std::remove_if(spells.begin(), spells.end(), [&] (const auto& spell) - { - const auto isSpell = [&] (const auto& id) { return Misc::StringUtils::ciEqual(spell, id); }; + bool changed = withBaseRecord([&](auto& spells) { + const auto it = std::remove_if(spells.begin(), spells.end(), [&](const auto& spell) { + const auto isSpell = [&](const auto& id) { return Misc::StringUtils::ciEqual(spell, id); }; return ids.end() != std::find_if(ids.begin(), ids.end(), isSpell); }); if (it == spells.end()) @@ -123,11 +123,11 @@ namespace MWMechanics spells.erase(it, spells.end()); return true; }); - if(changed) + if (changed) { - for(auto listener : mListeners) + for (auto listener : mListeners) { - for(auto& id : ids) + for (auto& id : ids) { const auto spell = getSpell(id); listener->removeSpell(spell); @@ -138,16 +138,15 @@ namespace MWMechanics void SpellList::clear() { - bool changed = withBaseRecord([] (auto& spells) - { - if(spells.empty()) + bool changed = withBaseRecord([](auto& spells) { + if (spells.empty()) return false; spells.clear(); return true; }); - if(changed) + if (changed) { - for(auto listener : mListeners) + for (auto listener : mListeners) listener->removeAllSpells(); } } diff --git a/apps/openmw/mwmechanics/spelllist.hpp b/apps/openmw/mwmechanics/spelllist.hpp index d4f78e5ed3..383b9dddd6 100644 --- a/apps/openmw/mwmechanics/spelllist.hpp +++ b/apps/openmw/mwmechanics/spelllist.hpp @@ -3,8 +3,8 @@ #include #include -#include #include +#include #include #include @@ -20,42 +20,45 @@ namespace MWMechanics /// Multiple instances of the same actor share the same spell list in Morrowind. /// The most obvious result of this is that adding a spell or ability to one instance adds it to all instances. - /// @note The original game will only update visual effects associated with any added abilities for the originally targeted actor, + /// @note The original game will only update visual effects associated with any added abilities for the originally + /// targeted actor, /// changing cells applies the update to all actors. - /// Aside from sharing the same active spell list, changes made to this list are also written to the actor's base record. - /// Interestingly, it is not just scripted changes that are persisted to the base record. Curing one instance's disease will cure all instances. + /// Aside from sharing the same active spell list, changes made to this list are also written to the actor's base + /// record. Interestingly, it is not just scripted changes that are persisted to the base record. Curing one + /// instance's disease will cure all instances. /// @note The original game is inconsistent in persisting this example; /// saving and loading the game might reapply the cured disease depending on which instance was cured. class SpellList { - const std::string mId; - const int mType; - std::vector mListeners; + const std::string mId; + const int mType; + std::vector mListeners; + + bool withBaseRecord(const std::function&)>& function); - bool withBaseRecord(const std::function&)>& function); - public: - SpellList(const std::string& id, int type); + public: + SpellList(const std::string& id, int type); - /// Get spell from ID, throws exception if not found - static const ESM::Spell* getSpell(std::string_view id); + /// Get spell from ID, throws exception if not found + static const ESM::Spell* getSpell(std::string_view id); - void add (const ESM::Spell* spell); - ///< Adding a spell that is already listed in *this is a no-op. + void add(const ESM::Spell* spell); + ///< Adding a spell that is already listed in *this is a no-op. - void remove (const ESM::Spell* spell); + void remove(const ESM::Spell* spell); - void removeAll(const std::vector& spells); + void removeAll(const std::vector& spells); - void clear(); - ///< Remove all spells of all types. + void clear(); + ///< Remove all spells of all types. - void addListener(Spells* spells); + void addListener(Spells* spells); - void removeListener(Spells* spells); + void removeListener(Spells* spells); - void updateListener(Spells* before, Spells* after); + void updateListener(Spells* before, Spells* after); - const std::vector getSpells() const; + const std::vector getSpells() const; }; } diff --git a/apps/openmw/mwmechanics/spellpriority.cpp b/apps/openmw/mwmechanics/spellpriority.cpp index de0158040d..2a09ed03f4 100644 --- a/apps/openmw/mwmechanics/spellpriority.cpp +++ b/apps/openmw/mwmechanics/spellpriority.cpp @@ -3,36 +3,38 @@ #include #include -#include #include +#include #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/world.hpp" +#include "../mwworld/cellstore.hpp" #include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" #include "../mwworld/inventorystore.hpp" -#include "../mwworld/cellstore.hpp" #include "creaturestats.hpp" #include "spellresistance.hpp" -#include "weapontype.hpp" -#include "summoning.hpp" #include "spellutil.hpp" +#include "summoning.hpp" +#include "weapontype.hpp" namespace { - int numEffectsToDispel (const MWWorld::Ptr& actor, int effectFilter=-1, bool negative = true) + int numEffectsToDispel(const MWWorld::Ptr& actor, int effectFilter = -1, bool negative = true) { - int toCure=0; + int toCure = 0; const MWMechanics::ActiveSpells& activeSpells = actor.getClass().getCreatureStats(actor).getActiveSpells(); for (MWMechanics::ActiveSpells::TIterator it = activeSpells.begin(); it != activeSpells.end(); ++it) { - // if the effect filter is not specified, take in account only spells effects. Leave potions, enchanted items etc. + // if the effect filter is not specified, take in account only spells effects. Leave potions, enchanted + // items etc. if (effectFilter == -1) { - const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get().search(it->getId()); + const ESM::Spell* spell + = MWBase::Environment::get().getWorld()->getStore().get().search(it->getId()); if (!spell || spell->mData.mType != ESM::Spell::ST_Spell) continue; } @@ -43,7 +45,8 @@ namespace int effectId = effect.mEffectId; if (effectFilter != -1 && effectId != effectFilter) continue; - const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getWorld()->getStore().get().find(effectId); + const ESM::MagicEffect* magicEffect + = MWBase::Environment::get().getWorld()->getStore().get().find(effectId); if (effect.mDuration <= 3) // Don't attempt to dispel if effect runs out shortly anyway continue; @@ -58,7 +61,7 @@ namespace return toCure; } - float getSpellDuration (const MWWorld::Ptr& actor, const std::string& spellId) + float getSpellDuration(const MWWorld::Ptr& actor, const std::string& spellId) { float duration = 0; const MWMechanics::ActiveSpells& activeSpells = actor.getClass().getCreatureStats(actor).getActiveSpells(); @@ -81,8 +84,7 @@ namespace { int actorId = caster.getClass().getCreatureStats(caster).getActorId(); const auto& active = target.getClass().getCreatureStats(target).getActiveSpells(); - return std::find_if(active.begin(), active.end(), [&](const auto& spell) - { + return std::find_if(active.begin(), active.end(), [&](const auto& spell) { return spell.getCasterActorId() == actorId && Misc::StringUtils::ciEqual(spell.getId(), id); }) != active.end(); } @@ -90,7 +92,7 @@ namespace namespace MWMechanics { - int getRangeTypes (const ESM::EffectList& effects) + int getRangeTypes(const ESM::EffectList& effects) { int types = 0; for (std::vector::const_iterator it = effects.mList.begin(); it != effects.mList.end(); ++it) @@ -105,7 +107,7 @@ namespace MWMechanics return types; } - float ratePotion (const MWWorld::Ptr &item, const MWWorld::Ptr& actor) + float ratePotion(const MWWorld::Ptr& item, const MWWorld::Ptr& actor) { if (item.getType() != ESM::Potion::sRecordId) return 0.f; @@ -114,7 +116,7 @@ namespace MWMechanics return rateEffects(potion->mEffects, actor, MWWorld::Ptr()); } - float rateSpell(const ESM::Spell *spell, const MWWorld::Ptr &actor, const MWWorld::Ptr& enemy) + float rateSpell(const ESM::Spell* spell, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy) { float successChance = MWMechanics::getSpellSuccessChance(spell, actor); if (successChance == 0.f) @@ -136,25 +138,28 @@ namespace MWMechanics int types = getRangeTypes(spell->mEffects); if ((types & Self) && isSpellActive(actor, actor, spell->mId)) return 0.f; - if ( ((types & Touch) || (types & Target)) && isSpellActive(actor, enemy, spell->mId)) + if (((types & Touch) || (types & Target)) && isSpellActive(actor, enemy, spell->mId)) return 0.f; return rateEffects(spell->mEffects, actor, enemy) * (successChance / 100.f); } - float rateMagicItem(const MWWorld::Ptr &ptr, const MWWorld::Ptr &actor, const MWWorld::Ptr& enemy) + float rateMagicItem(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy) { if (ptr.getClass().getEnchantment(ptr).empty()) return 0.f; - const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get().find(ptr.getClass().getEnchantment(ptr)); + const ESM::Enchantment* enchantment + = MWBase::Environment::get().getWorld()->getStore().get().find( + ptr.getClass().getEnchantment(ptr)); // Spells don't stack, so early out if the spell is still active on the target int types = getRangeTypes(enchantment->mEffects); - if ((types & Self) && actor.getClass().getCreatureStats(actor).getActiveSpells().isSpellActive(ptr.getCellRef().getRefId())) + if ((types & Self) + && actor.getClass().getCreatureStats(actor).getActiveSpells().isSpellActive(ptr.getCellRef().getRefId())) return 0.f; - if (types & (Touch|Target) && getSpellDuration(enemy, ptr.getCellRef().getRefId()) > 3) + if (types & (Touch | Target) && getSpellDuration(enemy, ptr.getCellRef().getRefId()) > 3) return 0.f; if (enchantment->mData.mType == ESM::Enchantment::CastOnce) @@ -165,14 +170,13 @@ namespace MWMechanics { MWWorld::InventoryStore& store = actor.getClass().getInventoryStore(actor); - // Creatures can not wear armor/clothing, so allow creatures to use non-equipped items, + // Creatures can not wear armor/clothing, so allow creatures to use non-equipped items, if (actor.getClass().isNpc() && !store.isEquipped(ptr)) return 0.f; int castCost = getEffectiveEnchantmentCastCost(static_cast(enchantment->mData.mCost), actor); - if (ptr.getCellRef().getEnchantmentCharge() != -1 - && ptr.getCellRef().getEnchantmentCharge() < castCost) + if (ptr.getCellRef().getEnchantmentCharge() != -1 && ptr.getCellRef().getEnchantmentCharge() < castCost) return 0.f; float rating = rateEffects(enchantment->mEffects, actor, enemy); @@ -184,61 +188,61 @@ namespace MWMechanics return 0.f; } - float rateEffect(const ESM::ENAMstruct &effect, const MWWorld::Ptr &actor, const MWWorld::Ptr &enemy) + float rateEffect(const ESM::ENAMstruct& effect, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy) { // NOTE: enemy may be empty float rating = 1; switch (effect.mEffectID) { - case ESM::MagicEffect::Soultrap: - case ESM::MagicEffect::AlmsiviIntervention: - case ESM::MagicEffect::DivineIntervention: - case ESM::MagicEffect::CalmHumanoid: - case ESM::MagicEffect::CalmCreature: - case ESM::MagicEffect::FrenzyHumanoid: - case ESM::MagicEffect::FrenzyCreature: - case ESM::MagicEffect::DemoralizeHumanoid: - case ESM::MagicEffect::DemoralizeCreature: - case ESM::MagicEffect::RallyHumanoid: - case ESM::MagicEffect::RallyCreature: - case ESM::MagicEffect::Charm: - case ESM::MagicEffect::DetectAnimal: - case ESM::MagicEffect::DetectEnchantment: - case ESM::MagicEffect::DetectKey: - case ESM::MagicEffect::Telekinesis: - case ESM::MagicEffect::Mark: - case ESM::MagicEffect::Recall: - case ESM::MagicEffect::Jump: - case ESM::MagicEffect::WaterBreathing: - case ESM::MagicEffect::SwiftSwim: - case ESM::MagicEffect::WaterWalking: - case ESM::MagicEffect::SlowFall: - case ESM::MagicEffect::Light: - case ESM::MagicEffect::Lock: - case ESM::MagicEffect::Open: - case ESM::MagicEffect::TurnUndead: - case ESM::MagicEffect::WeaknessToCommonDisease: - case ESM::MagicEffect::WeaknessToBlightDisease: - case ESM::MagicEffect::WeaknessToCorprusDisease: - case ESM::MagicEffect::CureCommonDisease: - case ESM::MagicEffect::CureBlightDisease: - case ESM::MagicEffect::CureCorprusDisease: - case ESM::MagicEffect::ResistBlightDisease: - case ESM::MagicEffect::ResistCommonDisease: - case ESM::MagicEffect::ResistCorprusDisease: - case ESM::MagicEffect::Invisibility: - case ESM::MagicEffect::Chameleon: - case ESM::MagicEffect::NightEye: - case ESM::MagicEffect::Vampirism: - case ESM::MagicEffect::StuntedMagicka: - case ESM::MagicEffect::ExtraSpell: - case ESM::MagicEffect::RemoveCurse: - case ESM::MagicEffect::CommandCreature: - case ESM::MagicEffect::CommandHumanoid: - return 0.f; + case ESM::MagicEffect::Soultrap: + case ESM::MagicEffect::AlmsiviIntervention: + case ESM::MagicEffect::DivineIntervention: + case ESM::MagicEffect::CalmHumanoid: + case ESM::MagicEffect::CalmCreature: + case ESM::MagicEffect::FrenzyHumanoid: + case ESM::MagicEffect::FrenzyCreature: + case ESM::MagicEffect::DemoralizeHumanoid: + case ESM::MagicEffect::DemoralizeCreature: + case ESM::MagicEffect::RallyHumanoid: + case ESM::MagicEffect::RallyCreature: + case ESM::MagicEffect::Charm: + case ESM::MagicEffect::DetectAnimal: + case ESM::MagicEffect::DetectEnchantment: + case ESM::MagicEffect::DetectKey: + case ESM::MagicEffect::Telekinesis: + case ESM::MagicEffect::Mark: + case ESM::MagicEffect::Recall: + case ESM::MagicEffect::Jump: + case ESM::MagicEffect::WaterBreathing: + case ESM::MagicEffect::SwiftSwim: + case ESM::MagicEffect::WaterWalking: + case ESM::MagicEffect::SlowFall: + case ESM::MagicEffect::Light: + case ESM::MagicEffect::Lock: + case ESM::MagicEffect::Open: + case ESM::MagicEffect::TurnUndead: + case ESM::MagicEffect::WeaknessToCommonDisease: + case ESM::MagicEffect::WeaknessToBlightDisease: + case ESM::MagicEffect::WeaknessToCorprusDisease: + case ESM::MagicEffect::CureCommonDisease: + case ESM::MagicEffect::CureBlightDisease: + case ESM::MagicEffect::CureCorprusDisease: + case ESM::MagicEffect::ResistBlightDisease: + case ESM::MagicEffect::ResistCommonDisease: + case ESM::MagicEffect::ResistCorprusDisease: + case ESM::MagicEffect::Invisibility: + case ESM::MagicEffect::Chameleon: + case ESM::MagicEffect::NightEye: + case ESM::MagicEffect::Vampirism: + case ESM::MagicEffect::StuntedMagicka: + case ESM::MagicEffect::ExtraSpell: + case ESM::MagicEffect::RemoveCurse: + case ESM::MagicEffect::CommandCreature: + case ESM::MagicEffect::CommandHumanoid: + return 0.f; - case ESM::MagicEffect::Blind: + case ESM::MagicEffect::Blind: { if (enemy.isEmpty()) return 0.f; @@ -256,7 +260,7 @@ namespace MWMechanics break; } - case ESM::MagicEffect::Sound: + case ESM::MagicEffect::Sound: { if (enemy.isEmpty()) return 0.f; @@ -277,7 +281,7 @@ namespace MWMechanics break; } - case ESM::MagicEffect::Silence: + case ESM::MagicEffect::Silence: { if (enemy.isEmpty()) return 0.f; @@ -294,33 +298,34 @@ namespace MWMechanics break; } - case ESM::MagicEffect::RestoreAttribute: - return 0.f; // TODO: implement based on attribute damage - case ESM::MagicEffect::RestoreSkill: - return 0.f; // TODO: implement based on skill damage - - case ESM::MagicEffect::ResistFire: - case ESM::MagicEffect::ResistFrost: - case ESM::MagicEffect::ResistMagicka: - case ESM::MagicEffect::ResistNormalWeapons: - case ESM::MagicEffect::ResistParalysis: - case ESM::MagicEffect::ResistPoison: - case ESM::MagicEffect::ResistShock: - case ESM::MagicEffect::SpellAbsorption: - case ESM::MagicEffect::Reflect: - return 0.f; // probably useless since we don't know in advance what the enemy will cast - - // don't cast these for now as they would make the NPC cast the same effect over and over again, especially when they have potions - case ESM::MagicEffect::FortifyAttribute: - case ESM::MagicEffect::FortifyHealth: - case ESM::MagicEffect::FortifyMagicka: - case ESM::MagicEffect::FortifyFatigue: - case ESM::MagicEffect::FortifySkill: - case ESM::MagicEffect::FortifyMaximumMagicka: - case ESM::MagicEffect::FortifyAttack: - return 0.f; + case ESM::MagicEffect::RestoreAttribute: + return 0.f; // TODO: implement based on attribute damage + case ESM::MagicEffect::RestoreSkill: + return 0.f; // TODO: implement based on skill damage + + case ESM::MagicEffect::ResistFire: + case ESM::MagicEffect::ResistFrost: + case ESM::MagicEffect::ResistMagicka: + case ESM::MagicEffect::ResistNormalWeapons: + case ESM::MagicEffect::ResistParalysis: + case ESM::MagicEffect::ResistPoison: + case ESM::MagicEffect::ResistShock: + case ESM::MagicEffect::SpellAbsorption: + case ESM::MagicEffect::Reflect: + return 0.f; // probably useless since we don't know in advance what the enemy will cast + + // don't cast these for now as they would make the NPC cast the same effect over and over again, especially + // when they have potions + case ESM::MagicEffect::FortifyAttribute: + case ESM::MagicEffect::FortifyHealth: + case ESM::MagicEffect::FortifyMagicka: + case ESM::MagicEffect::FortifyFatigue: + case ESM::MagicEffect::FortifySkill: + case ESM::MagicEffect::FortifyMaximumMagicka: + case ESM::MagicEffect::FortifyAttack: + return 0.f; - case ESM::MagicEffect::Burden: + case ESM::MagicEffect::Burden: { if (enemy.isEmpty()) return 0.f; @@ -334,7 +339,7 @@ namespace MWMechanics if (burden > 0) return 0.f; - if ((effect.mMagnMin + effect.mMagnMax)/2.f > -burden) + if ((effect.mMagnMin + effect.mMagnMax) / 2.f > -burden) rating *= 3; else return 0.f; @@ -342,7 +347,7 @@ namespace MWMechanics break; } - case ESM::MagicEffect::Feather: + case ESM::MagicEffect::Feather: { // Ignore actors without inventory if (!actor.getClass().hasInventoryStore(actor)) @@ -353,7 +358,7 @@ namespace MWMechanics if (burden <= 0) return 0.f; - if ((effect.mMagnMin + effect.mMagnMax)/2.f >= burden) + if ((effect.mMagnMin + effect.mMagnMax) / 2.f >= burden) rating *= 3; else return 0.f; @@ -361,120 +366,124 @@ namespace MWMechanics break; } - case ESM::MagicEffect::Levitate: - return 0.f; // AI isn't designed to take advantage of this, and could be perceived as unfair anyway - case ESM::MagicEffect::BoundBoots: - case ESM::MagicEffect::BoundHelm: - if (actor.getClass().isNpc()) - { - // Beast races can't wear helmets or boots - const std::string& raceid = actor.get()->mBase->mRace; - const ESM::Race* race = MWBase::Environment::get().getWorld()->getStore().get().find(raceid); - if (race->mData.mFlags & ESM::Race::Beast) + case ESM::MagicEffect::Levitate: + return 0.f; // AI isn't designed to take advantage of this, and could be perceived as unfair anyway + case ESM::MagicEffect::BoundBoots: + case ESM::MagicEffect::BoundHelm: + if (actor.getClass().isNpc()) + { + // Beast races can't wear helmets or boots + const std::string& raceid = actor.get()->mBase->mRace; + const ESM::Race* race + = MWBase::Environment::get().getWorld()->getStore().get().find(raceid); + if (race->mData.mFlags & ESM::Race::Beast) + return 0.f; + } + else return 0.f; - } - else - return 0.f; - break; - case ESM::MagicEffect::BoundShield: - if(!actor.getClass().hasInventoryStore(actor)) - return 0.f; - else if(!actor.getClass().isNpc()) - { - // If the actor is an NPC they can benefit from the armor rating, otherwise check if we've got a one-handed weapon to use with the shield - const auto& store = actor.getClass().getInventoryStore(actor); - auto oneHanded = std::find_if(store.cbegin(MWWorld::ContainerStore::Type_Weapon), store.cend(), [](const MWWorld::ConstPtr& weapon) + break; + case ESM::MagicEffect::BoundShield: + if (!actor.getClass().hasInventoryStore(actor)) + return 0.f; + else if (!actor.getClass().isNpc()) { - if(weapon.getClass().getItemHealth(weapon) <= 0.f) - return false; - short type = weapon.get()->mBase->mData.mType; - return !(MWMechanics::getWeaponType(type)->mFlags & ESM::WeaponType::TwoHanded); - }); - if(oneHanded == store.cend()) + // If the actor is an NPC they can benefit from the armor rating, otherwise check if we've got a + // one-handed weapon to use with the shield + const auto& store = actor.getClass().getInventoryStore(actor); + auto oneHanded = std::find_if(store.cbegin(MWWorld::ContainerStore::Type_Weapon), store.cend(), + [](const MWWorld::ConstPtr& weapon) { + if (weapon.getClass().getItemHealth(weapon) <= 0.f) + return false; + short type = weapon.get()->mBase->mData.mType; + return !(MWMechanics::getWeaponType(type)->mFlags & ESM::WeaponType::TwoHanded); + }); + if (oneHanded == store.cend()) + return 0.f; + } + break; + // Creatures can not wear armor + case ESM::MagicEffect::BoundCuirass: + case ESM::MagicEffect::BoundGloves: + if (!actor.getClass().isNpc()) return 0.f; - } - break; - // Creatures can not wear armor - case ESM::MagicEffect::BoundCuirass: - case ESM::MagicEffect::BoundGloves: - if (!actor.getClass().isNpc()) - return 0.f; - break; + break; - case ESM::MagicEffect::BoundLongbow: - // AI should not summon the bow if there is no suitable ammo. - if (rateAmmo(actor, enemy, getWeaponType(ESM::Weapon::MarksmanBow)->mAmmoType) <= 0.f) - return 0.f; - break; + case ESM::MagicEffect::BoundLongbow: + // AI should not summon the bow if there is no suitable ammo. + if (rateAmmo(actor, enemy, getWeaponType(ESM::Weapon::MarksmanBow)->mAmmoType) <= 0.f) + return 0.f; + break; - case ESM::MagicEffect::RestoreHealth: - case ESM::MagicEffect::RestoreMagicka: - case ESM::MagicEffect::RestoreFatigue: - if (effect.mRange == ESM::RT_Self) - { - int priority = 1; - if (effect.mEffectID == ESM::MagicEffect::RestoreHealth) - priority = 10; - const MWMechanics::CreatureStats& stats = actor.getClass().getCreatureStats(actor); - const DynamicStat& current = stats.getDynamic(effect.mEffectID - ESM::MagicEffect::RestoreHealth); - // NB: this currently assumes the hardcoded magic effect flags are used - const float magnitude = (effect.mMagnMin + effect.mMagnMax)/2.f; - const float toHeal = magnitude * std::max(1, effect.mDuration); - // Effect doesn't heal more than we need, *or* we are below 1/2 health - if (current.getModified() - current.getCurrent() > toHeal - || current.getCurrent() < current.getModified()*0.5) + case ESM::MagicEffect::RestoreHealth: + case ESM::MagicEffect::RestoreMagicka: + case ESM::MagicEffect::RestoreFatigue: + if (effect.mRange == ESM::RT_Self) { - return 10000.f * priority - - (toHeal - (current.getModified()-current.getCurrent())); // prefer the most fitting potion + int priority = 1; + if (effect.mEffectID == ESM::MagicEffect::RestoreHealth) + priority = 10; + const MWMechanics::CreatureStats& stats = actor.getClass().getCreatureStats(actor); + const DynamicStat& current + = stats.getDynamic(effect.mEffectID - ESM::MagicEffect::RestoreHealth); + // NB: this currently assumes the hardcoded magic effect flags are used + const float magnitude = (effect.mMagnMin + effect.mMagnMax) / 2.f; + const float toHeal = magnitude * std::max(1, effect.mDuration); + // Effect doesn't heal more than we need, *or* we are below 1/2 health + if (current.getModified() - current.getCurrent() > toHeal + || current.getCurrent() < current.getModified() * 0.5) + { + return 10000.f * priority + - (toHeal + - (current.getModified() - current.getCurrent())); // prefer the most fitting potion + } + else + return -10000.f * priority; // Save for later } - else - return -10000.f * priority; // Save for later - } - break; - - case ESM::MagicEffect::Dispel: - { - int numPositive = 0; - int numNegative = 0; - int diff = 0; + break; - if (effect.mRange == ESM::RT_Self) + case ESM::MagicEffect::Dispel: { - numPositive = numEffectsToDispel(actor, -1, false); - numNegative = numEffectsToDispel(actor); + int numPositive = 0; + int numNegative = 0; + int diff = 0; - diff = numNegative - numPositive; - } - else - { - if (enemy.isEmpty()) - return 0.f; + if (effect.mRange == ESM::RT_Self) + { + numPositive = numEffectsToDispel(actor, -1, false); + numNegative = numEffectsToDispel(actor); - numPositive = numEffectsToDispel(enemy, -1, false); - numNegative = numEffectsToDispel(enemy); + diff = numNegative - numPositive; + } + else + { + if (enemy.isEmpty()) + return 0.f; - diff = numPositive - numNegative; + numPositive = numEffectsToDispel(enemy, -1, false); + numNegative = numEffectsToDispel(enemy); - // if rating < 0 here, the spell will be considered as negative later - rating *= -1; - } + diff = numPositive - numNegative; - if (diff <= 0) - return 0.f; + // if rating < 0 here, the spell will be considered as negative later + rating *= -1; + } - rating *= (diff) / 5.f; + if (diff <= 0) + return 0.f; - break; - } + rating *= (diff) / 5.f; + + break; + } - // Prefer Cure effects over Dispel, because Dispel also removes positive effects - case ESM::MagicEffect::CureParalyzation: - return 1001.f * numEffectsToDispel(actor, ESM::MagicEffect::Paralyze); + // Prefer Cure effects over Dispel, because Dispel also removes positive effects + case ESM::MagicEffect::CureParalyzation: + return 1001.f * numEffectsToDispel(actor, ESM::MagicEffect::Paralyze); - case ESM::MagicEffect::CurePoison: - return 1001.f * numEffectsToDispel(actor, ESM::MagicEffect::Poison); - case ESM::MagicEffect::DisintegrateArmor: + case ESM::MagicEffect::CurePoison: + return 1001.f * numEffectsToDispel(actor, ESM::MagicEffect::Poison); + case ESM::MagicEffect::DisintegrateArmor: { if (enemy.isEmpty()) return 0.f; @@ -501,7 +510,7 @@ namespace MWMechanics bool enemyHasArmor = false; // Ignore enemy without armor - for (unsigned int i=0; i= 0 && effect.mAttribute < ESM::Attribute::Length) + case ESM::MagicEffect::DamageAttribute: + case ESM::MagicEffect::DrainAttribute: + if (!enemy.isEmpty() + && enemy.getClass().getCreatureStats(enemy).getAttribute(effect.mAttribute).getModified() <= 0) + return 0.f; { - const float attributePriorities[ESM::Attribute::Length] = { - 1.0f, // Strength - 0.5f, // Intelligence - 0.6f, // Willpower - 0.7f, // Agility - 0.5f, // Speed - 0.8f, // Endurance - 0.7f, // Personality - 0.3f // Luck - }; - rating *= attributePriorities[effect.mAttribute]; + if (effect.mAttribute >= 0 && effect.mAttribute < ESM::Attribute::Length) + { + const float attributePriorities[ESM::Attribute::Length] = { + 1.0f, // Strength + 0.5f, // Intelligence + 0.6f, // Willpower + 0.7f, // Agility + 0.5f, // Speed + 0.8f, // Endurance + 0.7f, // Personality + 0.3f // Luck + }; + rating *= attributePriorities[effect.mAttribute]; + } } - } - break; + break; - case ESM::MagicEffect::DamageSkill: - case ESM::MagicEffect::DrainSkill: - if (enemy.isEmpty() || !enemy.getClass().isNpc()) - return 0.f; - if (enemy.getClass().getSkill(enemy, effect.mSkill) <= 0) - return 0.f; - break; + case ESM::MagicEffect::DamageSkill: + case ESM::MagicEffect::DrainSkill: + if (enemy.isEmpty() || !enemy.getClass().isNpc()) + return 0.f; + if (enemy.getClass().getSkill(enemy, effect.mSkill) <= 0) + return 0.f; + break; - default: - break; + default: + break; } // Allow only one summoned creature at time @@ -579,11 +589,12 @@ namespace MWMechanics if (!creatureStats.getSummonedCreatureMap().empty()) return 0.f; } - if(effect.mEffectID >= ESM::MagicEffect::BoundDagger && effect.mEffectID <= ESM::MagicEffect::BoundGloves) + if (effect.mEffectID >= ESM::MagicEffect::BoundDagger && effect.mEffectID <= ESM::MagicEffect::BoundGloves) { - // While rateSpell prevents actors from recasting the same spell, it doesn't prevent them from casting different spells with the same effect. - // Multiple instances of the same bound item don't stack so if the effect is already active, rate it as useless. - if(actor.getClass().getCreatureStats(actor).getMagicEffects().get(effect.mEffectID).getMagnitude() > 0.f) + // While rateSpell prevents actors from recasting the same spell, it doesn't prevent them from casting + // different spells with the same effect. Multiple instances of the same bound item don't stack so if the + // effect is already active, rate it as useless. + if (actor.getClass().getCreatureStats(actor).getMagicEffects().get(effect.mEffectID).getMagnitude() > 0.f) return 0.f; } @@ -600,7 +611,8 @@ namespace MWMechanics return 0.f; } - const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getWorld()->getStore().get().find(effect.mEffectID); + const ESM::MagicEffect* magicEffect + = MWBase::Environment::get().getWorld()->getStore().get().find(effect.mEffectID); if (magicEffect->mData.mFlags & ESM::MagicEffect::Harmful) { rating *= -1.f; @@ -646,14 +658,15 @@ namespace MWMechanics return rating; } - float rateEffects(const ESM::EffectList &list, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy) + float rateEffects(const ESM::EffectList& list, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy) { // NOTE: enemy may be empty float rating = 0.f; float ratingMult = 1.f; // NB: this multiplier is applied to the effect rating, not the final rating - const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& gmst + = MWBase::Environment::get().getWorld()->getStore().get(); static const float fAIMagicSpellMult = gmst.find("fAIMagicSpellMult")->mValue.getFloat(); static const float fAIRangeMagicSpellMult = gmst.find("fAIRangeMagicSpellMult")->mValue.getFloat(); @@ -668,15 +681,16 @@ namespace MWMechanics float vanillaRateSpell(const ESM::Spell* spell, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy) { - const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& gmst + = MWBase::Environment::get().getWorld()->getStore().get(); static const float fAIMagicSpellMult = gmst.find("fAIMagicSpellMult")->mValue.getFloat(); static const float fAIRangeMagicSpellMult = gmst.find("fAIRangeMagicSpellMult")->mValue.getFloat(); float mult = fAIMagicSpellMult; - for (std::vector::const_iterator effectIt = - spell->mEffects.mList.begin(); effectIt != spell->mEffects.mList.end(); ++effectIt) + for (std::vector::const_iterator effectIt = spell->mEffects.mList.begin(); + effectIt != spell->mEffects.mList.end(); ++effectIt) { if (effectIt->mRange == ESM::RT_Target) { diff --git a/apps/openmw/mwmechanics/spellpriority.hpp b/apps/openmw/mwmechanics/spellpriority.hpp index 0305f24b5c..b35c5aaf0e 100644 --- a/apps/openmw/mwmechanics/spellpriority.hpp +++ b/apps/openmw/mwmechanics/spellpriority.hpp @@ -23,16 +23,16 @@ namespace MWMechanics Target = 0x100 }; - int getRangeTypes (const ESM::EffectList& effects); + int getRangeTypes(const ESM::EffectList& effects); - float rateSpell (const ESM::Spell* spell, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy); - float rateMagicItem (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy); - float ratePotion (const MWWorld::Ptr& item, const MWWorld::Ptr &actor); + float rateSpell(const ESM::Spell* spell, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy); + float rateMagicItem(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy); + float ratePotion(const MWWorld::Ptr& item, const MWWorld::Ptr& actor); /// @note target may be empty - float rateEffect (const ESM::ENAMstruct& effect, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy); + float rateEffect(const ESM::ENAMstruct& effect, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy); /// @note target may be empty - float rateEffects (const ESM::EffectList& list, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy); + float rateEffects(const ESM::EffectList& list, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy); float vanillaRateSpell(const ESM::Spell* spell, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy); } diff --git a/apps/openmw/mwmechanics/spellresistance.cpp b/apps/openmw/mwmechanics/spellresistance.cpp index d865172875..0c27f9c197 100644 --- a/apps/openmw/mwmechanics/spellresistance.cpp +++ b/apps/openmw/mwmechanics/spellresistance.cpp @@ -17,7 +17,7 @@ namespace MWMechanics { float getEffectMultiplier(short effectId, const MWWorld::Ptr& actor, const MWWorld::Ptr& caster, - const ESM::Spell* spell, const MagicEffects* effects) + const ESM::Spell* spell, const MagicEffects* effects) { if (!actor.getClass().isActor()) return 1; @@ -26,14 +26,15 @@ namespace MWMechanics return 1 - resistance / 100.f; } - float getEffectResistance (short effectId, const MWWorld::Ptr& actor, const MWWorld::Ptr& caster, - const ESM::Spell* spell, const MagicEffects* effects) + float getEffectResistance(short effectId, const MWWorld::Ptr& actor, const MWWorld::Ptr& caster, + const ESM::Spell* spell, const MagicEffects* effects) { // Effects with no resistance attribute belonging to them can not be resisted if (ESM::MagicEffect::getResistanceEffect(effectId) == -1) return 0.f; - const auto magicEffect = MWBase::Environment::get().getWorld()->getStore().get().find(effectId); + const auto magicEffect + = MWBase::Environment::get().getWorld()->getStore().get().find(effectId); const MWMechanics::CreatureStats& stats = actor.getClass().getCreatureStats(actor); const MWMechanics::MagicEffects* magicEffects = &stats.getMagicEffects(); @@ -72,7 +73,7 @@ namespace MWMechanics return x; } - float getEffectResistanceAttribute (short effectId, const MagicEffects* actorEffects) + float getEffectResistanceAttribute(short effectId, const MagicEffects* actorEffects) { short resistanceEffect = ESM::MagicEffect::getResistanceEffect(effectId); short weaknessEffect = ESM::MagicEffect::getWeaknessEffect(effectId); diff --git a/apps/openmw/mwmechanics/spellresistance.hpp b/apps/openmw/mwmechanics/spellresistance.hpp index 8e74c22601..6966a456d1 100644 --- a/apps/openmw/mwmechanics/spellresistance.hpp +++ b/apps/openmw/mwmechanics/spellresistance.hpp @@ -20,18 +20,18 @@ namespace MWMechanics /// @param effects Override the actor's current magicEffects. Useful if there are effects currently /// being applied (but not applied yet) that should also be considered. float getEffectMultiplier(short effectId, const MWWorld::Ptr& actor, const MWWorld::Ptr& caster, - const ESM::Spell* spell = nullptr, const MagicEffects* effects = nullptr); + const ESM::Spell* spell = nullptr, const MagicEffects* effects = nullptr); /// Get the effective resistance against an effect casted by the given actor in the given spell (optional). /// @return >=100 for fully resisted. can also return negative value for damage amplification. /// @param effects Override the actor's current magicEffects. Useful if there are effects currently /// being applied (but not applied yet) that should also be considered. - float getEffectResistance (short effectId, const MWWorld::Ptr& actor, const MWWorld::Ptr& caster, - const ESM::Spell* spell = nullptr, const MagicEffects* effects = nullptr); + float getEffectResistance(short effectId, const MWWorld::Ptr& actor, const MWWorld::Ptr& caster, + const ESM::Spell* spell = nullptr, const MagicEffects* effects = nullptr); /// Get the resistance attribute against an effect for a given actor. This will add together /// ResistX and Weakness to X effects relevant against the given effect. - float getEffectResistanceAttribute (short effectId, const MagicEffects* actorEffects); + float getEffectResistanceAttribute(short effectId, const MagicEffects* actorEffects); } #endif diff --git a/apps/openmw/mwmechanics/spells.cpp b/apps/openmw/mwmechanics/spells.cpp index 481d555c01..21769e776b 100644 --- a/apps/openmw/mwmechanics/spells.cpp +++ b/apps/openmw/mwmechanics/spells.cpp @@ -20,19 +20,23 @@ namespace MWMechanics { - Spells::Spells() - { - } + Spells::Spells() {} - Spells::Spells(const Spells& spells) : mSpellList(spells.mSpellList), mSpells(spells.mSpells), - mSelectedSpell(spells.mSelectedSpell), mUsedPowers(spells.mUsedPowers) + Spells::Spells(const Spells& spells) + : mSpellList(spells.mSpellList) + , mSpells(spells.mSpells) + , mSelectedSpell(spells.mSelectedSpell) + , mUsedPowers(spells.mUsedPowers) { - if(mSpellList) + if (mSpellList) mSpellList->addListener(this); } - Spells::Spells(Spells&& spells) : mSpellList(std::move(spells.mSpellList)), mSpells(std::move(spells.mSpells)), - mSelectedSpell(std::move(spells.mSelectedSpell)), mUsedPowers(std::move(spells.mUsedPowers)) + Spells::Spells(Spells&& spells) + : mSpellList(std::move(spells.mSpellList)) + , mSpells(std::move(spells.mSpells)) + , mSelectedSpell(std::move(spells.mSelectedSpell)) + , mUsedPowers(std::move(spells.mUsedPowers)) { if (mSpellList) mSpellList->updateListener(&spells, this); @@ -53,12 +57,12 @@ namespace MWMechanics return hasSpell(SpellList::getSpell(spell)); } - bool Spells::hasSpell(const ESM::Spell *spell) const + bool Spells::hasSpell(const ESM::Spell* spell) const { return std::find(mSpells.begin(), mSpells.end(), spell) != mSpells.end(); } - void Spells::add (const ESM::Spell* spell) + void Spells::add(const ESM::Spell* spell) { mSpellList->add(spell); } @@ -80,14 +84,14 @@ namespace MWMechanics removeSpell(spell); mSpellList->remove(spell); - if (spellId==mSelectedSpell) + if (spellId == mSelectedSpell) mSelectedSpell.clear(); } void Spells::removeSpell(const ESM::Spell* spell) { const auto it = std::find(mSpells.begin(), mSpells.end(), spell); - if(it != mSpells.end()) + if (it != mSpells.end()) mSpells.erase(it); } @@ -99,11 +103,11 @@ namespace MWMechanics void Spells::clear(bool modifyBase) { removeAllSpells(); - if(modifyBase) + if (modifyBase) mSpellList->clear(); } - void Spells::setSelectedSpell (const std::string& spellId) + void Spells::setSelectedSpell(const std::string& spellId) { mSelectedSpell = spellId; } @@ -115,10 +119,8 @@ namespace MWMechanics bool Spells::hasSpellType(const ESM::Spell::SpellType type) const { - auto it = std::find_if(std::begin(mSpells), std::end(mSpells), [=](const ESM::Spell* spell) - { - return spell->mData.mType == type; - }); + auto it = std::find_if(std::begin(mSpells), std::end(mSpells), + [=](const ESM::Spell* spell) { return spell->mData.mType == type; }); return it != std::end(mSpells); } @@ -135,9 +137,9 @@ namespace MWMechanics void Spells::purge(const SpellFilter& filter) { std::vector purged; - for (auto iter = mSpells.begin(); iter!=mSpells.end();) + for (auto iter = mSpells.begin(); iter != mSpells.end();) { - const ESM::Spell *spell = *iter; + const ESM::Spell* spell = *iter; if (filter(spell)) { iter = mSpells.erase(iter); @@ -146,7 +148,7 @@ namespace MWMechanics else ++iter; } - if(!purged.empty()) + if (!purged.empty()) mSpellList->removeAll(purged); } @@ -170,7 +172,7 @@ namespace MWMechanics purge([](auto spell) { return spell->mData.mType == ESM::Spell::ST_Curse; }); } - bool Spells::hasCorprusEffect(const ESM::Spell *spell) + bool Spells::hasCorprusEffect(const ESM::Spell* spell) { for (const auto& effectIt : spell->mEffects.mList) { @@ -184,14 +186,16 @@ namespace MWMechanics bool Spells::canUsePower(const ESM::Spell* spell) const { - const auto it = std::find_if(std::begin(mUsedPowers), std::end(mUsedPowers), [&](auto& pair) { return pair.first == spell; }); + const auto it = std::find_if( + std::begin(mUsedPowers), std::end(mUsedPowers), [&](auto& pair) { return pair.first == spell; }); return it == mUsedPowers.end() || it->second + 24 <= MWBase::Environment::get().getWorld()->getTimeStamp(); } void Spells::usePower(const ESM::Spell* spell) { // Updates or inserts a new entry with the current timestamp. - const auto it = std::find_if(std::begin(mUsedPowers), std::end(mUsedPowers), [&](auto& pair) { return pair.first == spell; }); + const auto it = std::find_if( + std::begin(mUsedPowers), std::end(mUsedPowers), [&](auto& pair) { return pair.first == spell; }); const auto timestamp = MWBase::Environment::get().getWorld()->getTimeStamp(); if (it == mUsedPowers.end()) mUsedPowers.emplace_back(spell, timestamp); @@ -199,7 +203,7 @@ namespace MWMechanics it->second = timestamp; } - void Spells::readState(const ESM::SpellState &state, CreatureStats* creatureStats) + void Spells::readState(const ESM::SpellState& state, CreatureStats* creatureStats) { const auto& baseSpells = mSpellList->getSpells(); @@ -216,26 +220,31 @@ namespace MWMechanics } } // Add spells from the base record - for(const std::string& id : baseSpells) + for (const std::string& id : baseSpells) { const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get().search(id); - if(spell) + if (spell) addSpell(spell); } - for (std::map::const_iterator it = state.mUsedPowers.begin(); it != state.mUsedPowers.end(); ++it) + for (std::map::const_iterator it = state.mUsedPowers.begin(); + it != state.mUsedPowers.end(); ++it) { - const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get().search(it->first); + const ESM::Spell* spell + = MWBase::Environment::get().getWorld()->getStore().get().search(it->first); if (!spell) continue; mUsedPowers.emplace_back(spell, MWWorld::TimeStamp(it->second)); } - // Permanent effects are used only to keep the custom magnitude of corprus spells effects (after cure too), and only in old saves. Convert data to the new approach. - for (std::map >::const_iterator it = - state.mPermanentSpellEffects.begin(); it != state.mPermanentSpellEffects.end(); ++it) + // Permanent effects are used only to keep the custom magnitude of corprus spells effects (after cure too), and + // only in old saves. Convert data to the new approach. + for (std::map>::const_iterator it + = state.mPermanentSpellEffects.begin(); + it != state.mPermanentSpellEffects.end(); ++it) { - const ESM::Spell * spell = MWBase::Environment::get().getWorld()->getStore().get().search(it->first); + const ESM::Spell* spell + = MWBase::Environment::get().getWorld()->getStore().get().search(it->first); if (!spell) continue; @@ -245,7 +254,8 @@ namespace MWMechanics return; // Note: if target actor has the Restore attirbute effects, stats will be restored. - for (std::vector::const_iterator effectIt = it->second.begin(); effectIt != it->second.end(); ++effectIt) + for (std::vector::const_iterator effectIt = it->second.begin(); + effectIt != it->second.end(); ++effectIt) { // Applied corprus effects are already in loaded stats modifiers if (effectIt->mId == ESM::MagicEffect::FortifyAttribute) @@ -266,14 +276,14 @@ namespace MWMechanics } } - void Spells::writeState(ESM::SpellState &state) const + void Spells::writeState(ESM::SpellState& state) const { const auto& baseSpells = mSpellList->getSpells(); for (const auto spell : mSpells) { // Don't save spells and powers stored in the base record - if((spell->mData.mType != ESM::Spell::ST_Spell && spell->mData.mType != ESM::Spell::ST_Power) || - std::find(baseSpells.begin(), baseSpells.end(), spell->mId) == baseSpells.end()) + if ((spell->mData.mType != ESM::Spell::ST_Spell && spell->mData.mType != ESM::Spell::ST_Power) + || std::find(baseSpells.begin(), baseSpells.end(), spell->mId) == baseSpells.end()) { state.mSpells.emplace_back(spell->mId); } @@ -296,10 +306,10 @@ namespace MWMechanics void Spells::addAllToInstance(const std::vector& spells) { - for(const std::string& id : spells) + for (const std::string& id : spells) { const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get().search(id); - if(spell) + if (spell) addSpell(spell); else Log(Debug::Warning) << "Warning: ignoring nonexistent spell '" << id << "'"; @@ -308,7 +318,7 @@ namespace MWMechanics Spells::~Spells() { - if(mSpellList) + if (mSpellList) mSpellList->removeListener(this); } } diff --git a/apps/openmw/mwmechanics/spells.hpp b/apps/openmw/mwmechanics/spells.hpp index 2dd8706b1c..4248e6de95 100644 --- a/apps/openmw/mwmechanics/spells.hpp +++ b/apps/openmw/mwmechanics/spells.hpp @@ -1,8 +1,8 @@ #ifndef GAME_MWMECHANICS_SPELLS_H #define GAME_MWMECHANICS_SPELLS_H -#include #include +#include #include #include @@ -27,79 +27,80 @@ namespace MWMechanics /// diseases. It also keeps track of used powers (which can only be used every 24h). class Spells { - std::shared_ptr mSpellList; - std::vector mSpells; + std::shared_ptr mSpellList; + std::vector mSpells; + + // Note: this is the spell that's about to be cast, *not* the spell selected in the GUI (which may be different) + std::string mSelectedSpell; - // Note: this is the spell that's about to be cast, *not* the spell selected in the GUI (which may be different) - std::string mSelectedSpell; + std::vector> mUsedPowers; - std::vector> mUsedPowers; + bool hasSpellType(const ESM::Spell::SpellType type) const; - bool hasSpellType(const ESM::Spell::SpellType type) const; + using SpellFilter = bool (*)(const ESM::Spell*); + void purge(const SpellFilter& filter); - using SpellFilter = bool (*)(const ESM::Spell*); - void purge(const SpellFilter& filter); + void addSpell(const ESM::Spell* spell); + void removeSpell(const ESM::Spell* spell); + void removeAllSpells(); - void addSpell(const ESM::Spell* spell); - void removeSpell(const ESM::Spell* spell); - void removeAllSpells(); + friend class SpellList; - friend class SpellList; - public: - Spells(); + public: + Spells(); - Spells(const Spells&); + Spells(const Spells&); - Spells(Spells&& spells); + Spells(Spells&& spells); - ~Spells(); + ~Spells(); - static bool hasCorprusEffect(const ESM::Spell *spell); + static bool hasCorprusEffect(const ESM::Spell* spell); - bool canUsePower (const ESM::Spell* spell) const; - void usePower (const ESM::Spell* spell); + bool canUsePower(const ESM::Spell* spell) const; + void usePower(const ESM::Spell* spell); - void purgeCommonDisease(); - void purgeBlightDisease(); - void purgeCorprusDisease(); - void purgeCurses(); + void purgeCommonDisease(); + void purgeBlightDisease(); + void purgeCorprusDisease(); + void purgeCurses(); - std::vector::const_iterator begin() const; + std::vector::const_iterator begin() const; - std::vector::const_iterator end() const; + std::vector::const_iterator end() const; - bool hasSpell(std::string_view spell) const; - bool hasSpell(const ESM::Spell* spell) const; + bool hasSpell(std::string_view spell) const; + bool hasSpell(const ESM::Spell* spell) const; - void add(std::string_view spell); - ///< Adding a spell that is already listed in *this is a no-op. + void add(std::string_view spell); + ///< Adding a spell that is already listed in *this is a no-op. - void add (const ESM::Spell* spell); - ///< Adding a spell that is already listed in *this is a no-op. + void add(const ESM::Spell* spell); + ///< Adding a spell that is already listed in *this is a no-op. - void remove(std::string_view spell); - ///< If the spell to be removed is the selected spell, the selected spell will be changed to - /// no spell (empty string). + void remove(std::string_view spell); + ///< If the spell to be removed is the selected spell, the selected spell will be changed to + /// no spell (empty string). - void clear(bool modifyBase = false); - ///< Remove all spells of al types. + void clear(bool modifyBase = false); + ///< Remove all spells of al types. - void setSelectedSpell (const std::string& spellId); - ///< This function does not verify, if the spell is available. + void setSelectedSpell(const std::string& spellId); + ///< This function does not verify, if the spell is available. - const std::string& getSelectedSpell() const; - ///< May return an empty string. + const std::string& getSelectedSpell() const; + ///< May return an empty string. - bool hasCommonDisease() const; + bool hasCommonDisease() const; - bool hasBlightDisease() const; + bool hasBlightDisease() const; - void readState (const ESM::SpellState& state, CreatureStats* creatureStats); - void writeState (ESM::SpellState& state) const; + void readState(const ESM::SpellState& state, CreatureStats* creatureStats); + void writeState(ESM::SpellState& state) const; - bool setSpells(const std::string& id); + bool setSpells(const std::string& id); - void addAllToInstance(const std::vector& spells); + void addAllToInstance(const std::vector& spells); }; } diff --git a/apps/openmw/mwmechanics/spellutil.cpp b/apps/openmw/mwmechanics/spellutil.cpp index bfe15e820a..08c2085986 100644 --- a/apps/openmw/mwmechanics/spellutil.cpp +++ b/apps/openmw/mwmechanics/spellutil.cpp @@ -17,15 +17,19 @@ namespace MWMechanics { ESM::Skill::SkillEnum spellSchoolToSkill(int school) { - static const std::array schoolSkillArray - { - ESM::Skill::Alteration, ESM::Skill::Conjuration, ESM::Skill::Destruction, - ESM::Skill::Illusion, ESM::Skill::Mysticism, ESM::Skill::Restoration, + static const std::array schoolSkillArray{ + ESM::Skill::Alteration, + ESM::Skill::Conjuration, + ESM::Skill::Destruction, + ESM::Skill::Illusion, + ESM::Skill::Mysticism, + ESM::Skill::Restoration, }; return schoolSkillArray.at(school); } - float calcEffectCost(const ESM::ENAMstruct& effect, const ESM::MagicEffect* magicEffect, const EffectCostMethod method) + float calcEffectCost( + const ESM::ENAMstruct& effect, const ESM::MagicEffect* magicEffect, const EffectCostMethod method) { const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); if (!magicEffect) @@ -42,7 +46,8 @@ namespace MWMechanics int durationOffset = 0; int minArea = 0; - if (method == EffectCostMethod::PlayerSpell) { + if (method == EffectCostMethod::PlayerSpell) + { durationOffset = 1; minArea = 1; } @@ -55,7 +60,7 @@ namespace MWMechanics return x * fEffectCostMult; } - int calcSpellCost (const ESM::Spell& spell) + int calcSpellCost(const ESM::Spell& spell) { if (!(spell.mData.mFlags & ESM::Spell::F_Autocalc)) return spell.mData.mCost; @@ -77,7 +82,7 @@ namespace MWMechanics return std::round(cost); } - int getEffectiveEnchantmentCastCost(float castCost, const MWWorld::Ptr &actor) + int getEffectiveEnchantmentCastCost(float castCost, const MWWorld::Ptr& actor) { /* * Each point of enchant skill above/under 10 subtracts/adds @@ -89,7 +94,7 @@ namespace MWMechanics return static_cast((result < 1) ? 1 : result); } - float calcSpellBaseSuccessChance (const ESM::Spell* spell, const MWWorld::Ptr& actor, int* effectiveSchool) + float calcSpellBaseSuccessChance(const ESM::Spell* spell, const MWWorld::Ptr& actor, int* effectiveSchool) { // Morrowind for some reason uses a formula slightly different from magicka cost calculation float y = std::numeric_limits::max(); @@ -98,7 +103,8 @@ namespace MWMechanics for (const ESM::ENAMstruct& effect : spell->mEffects.mList) { float x = static_cast(effect.mDuration); - const auto magicEffect = MWBase::Environment::get().getWorld()->getStore().get().find(effect.mEffectID); + const auto magicEffect + = MWBase::Environment::get().getWorld()->getStore().get().find(effect.mEffectID); if (!(magicEffect->mData.mFlags & ESM::MagicEffect::AppliedOnce)) x = std::max(1.f, x); @@ -108,8 +114,12 @@ namespace MWMechanics x += effect.mArea * 0.05f * magicEffect->mData.mBaseCost; if (effect.mRange == ESM::RT_Target) x *= 1.5f; - static const float fEffectCostMult = MWBase::Environment::get().getWorld()->getStore().get().find( - "fEffectCostMult")->mValue.getFloat(); + static const float fEffectCostMult = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fEffectCostMult") + ->mValue.getFloat(); x *= fEffectCostMult; float s = 2.0f * actor.getClass().getSkill(actor, spellSchoolToSkill(magicEffect->mData.mSchool)); @@ -132,7 +142,8 @@ namespace MWMechanics return castChance; } - float getSpellSuccessChance (const ESM::Spell* spell, const MWWorld::Ptr& actor, int* effectiveSchool, bool cap, bool checkMagicka) + float getSpellSuccessChance( + const ESM::Spell* spell, const MWWorld::Ptr& actor, int* effectiveSchool, bool cap, bool checkMagicka) { // NB: Base chance is calculated here because the effective school pointer must be filled float baseChance = calcSpellBaseSuccessChance(spell, actor, effectiveSchool); @@ -169,7 +180,8 @@ namespace MWMechanics return std::max(castChance, 0.f); } - float getSpellSuccessChance (const std::string& spellId, const MWWorld::Ptr& actor, int* effectiveSchool, bool cap, bool checkMagicka) + float getSpellSuccessChance( + const std::string& spellId, const MWWorld::Ptr& actor, int* effectiveSchool, bool cap, bool checkMagicka) { if (const auto spell = MWBase::Environment::get().getWorld()->getStore().get().search(spellId)) return getSpellSuccessChance(spell, actor, effectiveSchool, cap, checkMagicka); @@ -190,12 +202,12 @@ namespace MWMechanics return school; } - bool spellIncreasesSkill(const ESM::Spell *spell) + bool spellIncreasesSkill(const ESM::Spell* spell) { return spell->mData.mType == ESM::Spell::ST_Spell && !(spell->mData.mFlags & ESM::Spell::F_Always); } - bool spellIncreasesSkill(const std::string &spellId) + bool spellIncreasesSkill(const std::string& spellId) { const auto spell = MWBase::Environment::get().getWorld()->getStore().get().search(spellId); return spell && spellIncreasesSkill(spell); diff --git a/apps/openmw/mwmechanics/spellutil.hpp b/apps/openmw/mwmechanics/spellutil.hpp index 571e02d166..457782d7be 100644 --- a/apps/openmw/mwmechanics/spellutil.hpp +++ b/apps/openmw/mwmechanics/spellutil.hpp @@ -19,15 +19,17 @@ namespace MWMechanics { ESM::Skill::SkillEnum spellSchoolToSkill(int school); - enum class EffectCostMethod { + enum class EffectCostMethod + { GameSpell, PlayerSpell, }; - float calcEffectCost(const ESM::ENAMstruct& effect, const ESM::MagicEffect* magicEffect = nullptr, const EffectCostMethod method = EffectCostMethod::GameSpell); - int calcSpellCost (const ESM::Spell& spell); + float calcEffectCost(const ESM::ENAMstruct& effect, const ESM::MagicEffect* magicEffect = nullptr, + const EffectCostMethod method = EffectCostMethod::GameSpell); + int calcSpellCost(const ESM::Spell& spell); - int getEffectiveEnchantmentCastCost (float castCost, const MWWorld::Ptr& actor); + int getEffectiveEnchantmentCastCost(float castCost, const MWWorld::Ptr& actor); /** * @param spell spell to cast @@ -38,9 +40,11 @@ namespace MWMechanics * @note actor can be an NPC or a creature * @return success chance from 0 to 100 (in percent), if cap=false then chance above 100 may be returned. */ - float calcSpellBaseSuccessChance (const ESM::Spell* spell, const MWWorld::Ptr& actor, int* effectiveSchool); - float getSpellSuccessChance (const ESM::Spell* spell, const MWWorld::Ptr& actor, int* effectiveSchool = nullptr, bool cap=true, bool checkMagicka=true); - float getSpellSuccessChance (const std::string& spellId, const MWWorld::Ptr& actor, int* effectiveSchool = nullptr, bool cap=true, bool checkMagicka=true); + float calcSpellBaseSuccessChance(const ESM::Spell* spell, const MWWorld::Ptr& actor, int* effectiveSchool); + float getSpellSuccessChance(const ESM::Spell* spell, const MWWorld::Ptr& actor, int* effectiveSchool = nullptr, + bool cap = true, bool checkMagicka = true); + float getSpellSuccessChance(const std::string& spellId, const MWWorld::Ptr& actor, int* effectiveSchool = nullptr, + bool cap = true, bool checkMagicka = true); int getSpellSchool(const std::string& spellId, const MWWorld::Ptr& actor); int getSpellSchool(const ESM::Spell* spell, const MWWorld::Ptr& actor); diff --git a/apps/openmw/mwmechanics/stat.cpp b/apps/openmw/mwmechanics/stat.cpp index eacfca98ae..d96d2cac39 100644 --- a/apps/openmw/mwmechanics/stat.cpp +++ b/apps/openmw/mwmechanics/stat.cpp @@ -4,44 +4,67 @@ namespace MWMechanics { - template - Stat::Stat() : mBase (0), mModifier (0) {} - template - Stat::Stat(T base, T modified) : mBase (base), mModifier (modified) {} + template + Stat::Stat() + : mBase(0) + , mModifier(0) + { + } + template + Stat::Stat(T base, T modified) + : mBase(base) + , mModifier(modified) + { + } - template + template T Stat::getModified(bool capped) const { - if(capped) + if (capped) return std::max({}, mModifier + mBase); return mModifier + mBase; } - template - void Stat::writeState (ESM::StatState& state) const + template + void Stat::writeState(ESM::StatState& state) const { state.mBase = mBase; state.mMod = mModifier; } - template - void Stat::readState (const ESM::StatState& state) + template + void Stat::readState(const ESM::StatState& state) { mBase = state.mBase; mModifier = state.mMod; } + template + DynamicStat::DynamicStat() + : mStatic(0, 0) + , mCurrent(0) + { + } + template + DynamicStat::DynamicStat(T base) + : mStatic(base, 0) + , mCurrent(base) + { + } + template + DynamicStat::DynamicStat(T base, T modified, T current) + : mStatic(base, modified) + , mCurrent(current) + { + } + template + DynamicStat::DynamicStat(const Stat& stat, T current) + : mStatic(stat) + , mCurrent(current) + { + } - template - DynamicStat::DynamicStat() : mStatic(0, 0), mCurrent(0) {} - template - DynamicStat::DynamicStat(T base) : mStatic(base, 0), mCurrent(base) {} - template - DynamicStat::DynamicStat(T base, T modified, T current) : mStatic(base, modified), mCurrent (current) {} - template - DynamicStat::DynamicStat(const Stat &stat, T current) : mStatic(stat), mCurrent (current) {} - - template - void DynamicStat::setCurrent (const T& value, bool allowDecreaseBelowZero, bool allowIncreaseAboveModified) + template + void DynamicStat::setCurrent(const T& value, bool allowDecreaseBelowZero, bool allowIncreaseAboveModified) { if (value > mCurrent) { @@ -65,34 +88,36 @@ namespace MWMechanics } } - template + template T DynamicStat::getRatio(bool nanIsZero) const { T modified = getModified(); - if(modified == T{}) + if (modified == T{}) { - if(nanIsZero) + if (nanIsZero) return modified; - return {1}; + return { 1 }; } return getCurrent() / modified; } - template - void DynamicStat::writeState (ESM::StatState& state) const + template + void DynamicStat::writeState(ESM::StatState& state) const { - mStatic.writeState (state); + mStatic.writeState(state); state.mCurrent = mCurrent; } - template - void DynamicStat::readState (const ESM::StatState& state) + template + void DynamicStat::readState(const ESM::StatState& state) { - mStatic.readState (state); + mStatic.readState(state); mCurrent = state.mCurrent; } - AttributeValue::AttributeValue() : - mBase(0.f), mModifier(0.f), mDamage(0.f) + AttributeValue::AttributeValue() + : mBase(0.f) + , mModifier(0.f) + , mDamage(0.f) { } @@ -112,7 +137,7 @@ namespace MWMechanics void AttributeValue::setBase(float base, bool clearModifier) { mBase = base; - if(clearModifier) + if (clearModifier) { mModifier = 0.f; mDamage = 0.f; @@ -121,7 +146,7 @@ namespace MWMechanics void AttributeValue::setModifier(float mod) { - if(mod < 0) + if (mod < 0) { mModifier = 0.f; mDamage -= mod; @@ -136,7 +161,8 @@ namespace MWMechanics } void AttributeValue::restore(float amount) { - if (mDamage <= 0) return; + if (mDamage <= 0) + return; mDamage -= std::min(mDamage, amount); } @@ -146,22 +172,22 @@ namespace MWMechanics return mDamage; } - void AttributeValue::writeState (ESM::StatState& state) const + void AttributeValue::writeState(ESM::StatState& state) const { state.mBase = mBase; state.mMod = mModifier; state.mDamage = mDamage; } - void AttributeValue::readState (const ESM::StatState& state) + void AttributeValue::readState(const ESM::StatState& state) { mBase = state.mBase; mModifier = state.mMod; mDamage = state.mDamage; } - SkillValue::SkillValue() : - mProgress(0) + SkillValue::SkillValue() + : mProgress(0) { } @@ -174,15 +200,15 @@ namespace MWMechanics mProgress = progress; } - void SkillValue::writeState (ESM::StatState& state) const + void SkillValue::writeState(ESM::StatState& state) const { - AttributeValue::writeState (state); + AttributeValue::writeState(state); state.mProgress = mProgress; } - void SkillValue::readState (const ESM::StatState& state) + void SkillValue::readState(const ESM::StatState& state) { - AttributeValue::readState (state); + AttributeValue::readState(state); mProgress = state.mProgress; } } diff --git a/apps/openmw/mwmechanics/stat.hpp b/apps/openmw/mwmechanics/stat.hpp index 1e9bb100d0..c37cf61990 100644 --- a/apps/openmw/mwmechanics/stat.hpp +++ b/apps/openmw/mwmechanics/stat.hpp @@ -6,93 +6,91 @@ namespace ESM { - template + template struct StatState; } namespace MWMechanics { - template + template class Stat { - T mBase; - T mModifier; + T mBase; + T mModifier; - public: - typedef T Type; + public: + typedef T Type; - Stat(); - Stat(T base, T modified); + Stat(); + Stat(T base, T modified); - const T& getBase() const { return mBase; }; + const T& getBase() const { return mBase; }; - T getModified(bool capped = true) const; - T getModifier() const { return mModifier; }; + T getModified(bool capped = true) const; + T getModifier() const { return mModifier; }; - void setBase(const T& value) { mBase = value; }; + void setBase(const T& value) { mBase = value; }; - void setModifier(const T& modifier) { mModifier = modifier; }; + void setModifier(const T& modifier) { mModifier = modifier; }; - void writeState (ESM::StatState& state) const; - void readState (const ESM::StatState& state); + void writeState(ESM::StatState& state) const; + void readState(const ESM::StatState& state); }; - template - inline bool operator== (const Stat& left, const Stat& right) + template + inline bool operator==(const Stat& left, const Stat& right) { - return left.getBase()==right.getBase() && - left.getModifier()==right.getModifier(); + return left.getBase() == right.getBase() && left.getModifier() == right.getModifier(); } - template - inline bool operator!= (const Stat& left, const Stat& right) + template + inline bool operator!=(const Stat& left, const Stat& right) { - return !(left==right); + return !(left == right); } - template + template class DynamicStat { - Stat mStatic; - T mCurrent; + Stat mStatic; + T mCurrent; - public: - typedef T Type; + public: + typedef T Type; - DynamicStat(); - DynamicStat(T base); - DynamicStat(T base, T modified, T current); - DynamicStat(const Stat &stat, T current); + DynamicStat(); + DynamicStat(T base); + DynamicStat(T base, T modified, T current); + DynamicStat(const Stat& stat, T current); - const T& getBase() const { return mStatic.getBase(); }; - T getModified(bool capped = true) const { return mStatic.getModified(capped); }; - const T& getCurrent() const { return mCurrent; }; - T getRatio(bool nanIsZero = true) const; + const T& getBase() const { return mStatic.getBase(); }; + T getModified(bool capped = true) const { return mStatic.getModified(capped); }; + const T& getCurrent() const { return mCurrent; }; + T getRatio(bool nanIsZero = true) const; - /// Set base and adjust current accordingly. - void setBase(const T& value) { mStatic.setBase(value); }; + /// Set base and adjust current accordingly. + void setBase(const T& value) { mStatic.setBase(value); }; - void setCurrent (const T& value, bool allowDecreaseBelowZero = false, bool allowIncreaseAboveModified = false); + void setCurrent(const T& value, bool allowDecreaseBelowZero = false, bool allowIncreaseAboveModified = false); - T getModifier() const { return mStatic.getModifier(); } - void setModifier(T value) { mStatic.setModifier(value); } + T getModifier() const { return mStatic.getModifier(); } + void setModifier(T value) { mStatic.setModifier(value); } - void writeState (ESM::StatState& state) const; - void readState (const ESM::StatState& state); + void writeState(ESM::StatState& state) const; + void readState(const ESM::StatState& state); }; - template - inline bool operator== (const DynamicStat& left, const DynamicStat& right) + template + inline bool operator==(const DynamicStat& left, const DynamicStat& right) { - return left.getBase()==right.getBase() && - left.getModifier()==right.getModifier() && - left.getCurrent()==right.getCurrent(); + return left.getBase() == right.getBase() && left.getModifier() == right.getModifier() + && left.getCurrent() == right.getCurrent(); } - template - inline bool operator!= (const DynamicStat& left, const DynamicStat& right) + template + inline bool operator!=(const DynamicStat& left, const DynamicStat& right) { - return !(left==right); + return !(left == right); } class AttributeValue @@ -121,41 +119,39 @@ namespace MWMechanics float getDamage() const; - void writeState (ESM::StatState& state) const; - void readState (const ESM::StatState& state); + void writeState(ESM::StatState& state) const; + void readState(const ESM::StatState& state); }; class SkillValue : public AttributeValue { float mProgress; + public: SkillValue(); float getProgress() const; void setProgress(float progress); - void writeState (ESM::StatState& state) const; - void readState (const ESM::StatState& state); + void writeState(ESM::StatState& state) const; + void readState(const ESM::StatState& state); }; - inline bool operator== (const AttributeValue& left, const AttributeValue& right) + inline bool operator==(const AttributeValue& left, const AttributeValue& right) { - return left.getBase() == right.getBase() - && left.getModifier() == right.getModifier() - && left.getDamage() == right.getDamage(); + return left.getBase() == right.getBase() && left.getModifier() == right.getModifier() + && left.getDamage() == right.getDamage(); } - inline bool operator!= (const AttributeValue& left, const AttributeValue& right) + inline bool operator!=(const AttributeValue& left, const AttributeValue& right) { return !(left == right); } - inline bool operator== (const SkillValue& left, const SkillValue& right) + inline bool operator==(const SkillValue& left, const SkillValue& right) { - return left.getBase() == right.getBase() - && left.getModifier() == right.getModifier() - && left.getDamage() == right.getDamage() - && left.getProgress() == right.getProgress(); + return left.getBase() == right.getBase() && left.getModifier() == right.getModifier() + && left.getDamage() == right.getDamage() && left.getProgress() == right.getProgress(); } - inline bool operator!= (const SkillValue& left, const SkillValue& right) + inline bool operator!=(const SkillValue& left, const SkillValue& right) { return !(left == right); } diff --git a/apps/openmw/mwmechanics/steering.cpp b/apps/openmw/mwmechanics/steering.cpp index eaf37fbd2a..7271b3bc41 100644 --- a/apps/openmw/mwmechanics/steering.cpp +++ b/apps/openmw/mwmechanics/steering.cpp @@ -13,32 +13,33 @@ namespace MWMechanics { -bool smoothTurn(const MWWorld::Ptr& actor, float targetAngleRadians, int axis, float epsilonRadians) -{ - MWMechanics::Movement& movement = actor.getClass().getMovementSettings(actor); - float diff = Misc::normalizeAngle(targetAngleRadians - actor.getRefData().getPosition().rot[axis]); - float absDiff = std::abs(diff); - - // The turning animation actually moves you slightly, so the angle will be wrong again. - // Use epsilon to prevent jerkiness. - if (absDiff < epsilonRadians) - return true; - - float limit = getAngularVelocity(actor.getClass().getMaxSpeed(actor)) * MWBase::Environment::get().getFrameDuration(); - static const bool smoothMovement = Settings::Manager::getBool("smooth movement", "Game"); - if (smoothMovement) - limit *= std::min(absDiff / osg::PI + 0.1, 0.5); - - if (absDiff > limit) - diff = osg::sign(diff) * limit; - - movement.mRotation[axis] = diff; - return false; -} - -bool zTurn(const MWWorld::Ptr& actor, float targetAngleRadians, float epsilonRadians) -{ - return smoothTurn(actor, targetAngleRadians, 2, epsilonRadians); -} + bool smoothTurn(const MWWorld::Ptr& actor, float targetAngleRadians, int axis, float epsilonRadians) + { + MWMechanics::Movement& movement = actor.getClass().getMovementSettings(actor); + float diff = Misc::normalizeAngle(targetAngleRadians - actor.getRefData().getPosition().rot[axis]); + float absDiff = std::abs(diff); + + // The turning animation actually moves you slightly, so the angle will be wrong again. + // Use epsilon to prevent jerkiness. + if (absDiff < epsilonRadians) + return true; + + float limit + = getAngularVelocity(actor.getClass().getMaxSpeed(actor)) * MWBase::Environment::get().getFrameDuration(); + static const bool smoothMovement = Settings::Manager::getBool("smooth movement", "Game"); + if (smoothMovement) + limit *= std::min(absDiff / osg::PI + 0.1, 0.5); + + if (absDiff > limit) + diff = osg::sign(diff) * limit; + + movement.mRotation[axis] = diff; + return false; + } + + bool zTurn(const MWWorld::Ptr& actor, float targetAngleRadians, float epsilonRadians) + { + return smoothTurn(actor, targetAngleRadians, 2, epsilonRadians); + } } diff --git a/apps/openmw/mwmechanics/steering.hpp b/apps/openmw/mwmechanics/steering.hpp index 99fa1387db..d1d120e091 100644 --- a/apps/openmw/mwmechanics/steering.hpp +++ b/apps/openmw/mwmechanics/steering.hpp @@ -7,29 +7,28 @@ namespace MWWorld { -class Ptr; + class Ptr; } namespace MWMechanics { -// Max rotating speed, radian/sec -inline float getAngularVelocity(const float actorSpeed) -{ - constexpr float degreesPerFrame = 15.f; - constexpr int framesPerSecond = 60; - const float baseAngularVelocity = osg::DegreesToRadians(degreesPerFrame * framesPerSecond); - const float baseSpeed = 200; - return baseAngularVelocity * std::max(actorSpeed / baseSpeed, 1.0f); -} - -/// configure rotation settings for an actor to reach this target angle (eventually) -/// @return have we reached the target angle? -bool zTurn(const MWWorld::Ptr& actor, float targetAngleRadians, - float epsilonRadians = osg::DegreesToRadians(0.5)); - -bool smoothTurn(const MWWorld::Ptr& actor, float targetAngleRadians, int axis, - float epsilonRadians = osg::DegreesToRadians(0.5)); + // Max rotating speed, radian/sec + inline float getAngularVelocity(const float actorSpeed) + { + constexpr float degreesPerFrame = 15.f; + constexpr int framesPerSecond = 60; + const float baseAngularVelocity = osg::DegreesToRadians(degreesPerFrame * framesPerSecond); + const float baseSpeed = 200; + return baseAngularVelocity * std::max(actorSpeed / baseSpeed, 1.0f); + } + + /// configure rotation settings for an actor to reach this target angle (eventually) + /// @return have we reached the target angle? + bool zTurn(const MWWorld::Ptr& actor, float targetAngleRadians, float epsilonRadians = osg::DegreesToRadians(0.5)); + + bool smoothTurn(const MWWorld::Ptr& actor, float targetAngleRadians, int axis, + float epsilonRadians = osg::DegreesToRadians(0.5)); } diff --git a/apps/openmw/mwmechanics/summoning.cpp b/apps/openmw/mwmechanics/summoning.cpp index f875d6759a..7bd6851e37 100644 --- a/apps/openmw/mwmechanics/summoning.cpp +++ b/apps/openmw/mwmechanics/summoning.cpp @@ -1,24 +1,24 @@ #include "summoning.hpp" #include -#include #include #include #include +#include #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/world.hpp" -#include "../mwworld/esmstore.hpp" #include "../mwworld/class.hpp" -#include "../mwworld/manualref.hpp" +#include "../mwworld/esmstore.hpp" #include "../mwworld/inventorystore.hpp" +#include "../mwworld/manualref.hpp" #include "../mwrender/animation.hpp" -#include "creaturestats.hpp" #include "aifollow.hpp" +#include "creaturestats.hpp" namespace MWMechanics { @@ -26,41 +26,45 @@ namespace MWMechanics bool isSummoningEffect(int effectId) { return ((effectId >= ESM::MagicEffect::SummonScamp && effectId <= ESM::MagicEffect::SummonStormAtronach) - || (effectId == ESM::MagicEffect::SummonCenturionSphere) - || (effectId >= ESM::MagicEffect::SummonFabricant && effectId <= ESM::MagicEffect::SummonCreature05)); + || (effectId == ESM::MagicEffect::SummonCenturionSphere) + || (effectId >= ESM::MagicEffect::SummonFabricant && effectId <= ESM::MagicEffect::SummonCreature05)); } std::string_view getSummonedCreature(int effectId) { - static const std::map summonMap - { - {ESM::MagicEffect::SummonAncestralGhost, "sMagicAncestralGhostID"}, - {ESM::MagicEffect::SummonBonelord, "sMagicBonelordID"}, - {ESM::MagicEffect::SummonBonewalker, "sMagicLeastBonewalkerID"}, - {ESM::MagicEffect::SummonCenturionSphere, "sMagicCenturionSphereID"}, - {ESM::MagicEffect::SummonClannfear, "sMagicClannfearID"}, - {ESM::MagicEffect::SummonDaedroth, "sMagicDaedrothID"}, - {ESM::MagicEffect::SummonDremora, "sMagicDremoraID"}, - {ESM::MagicEffect::SummonFabricant, "sMagicFabricantID"}, - {ESM::MagicEffect::SummonFlameAtronach, "sMagicFlameAtronachID"}, - {ESM::MagicEffect::SummonFrostAtronach, "sMagicFrostAtronachID"}, - {ESM::MagicEffect::SummonGoldenSaint, "sMagicGoldenSaintID"}, - {ESM::MagicEffect::SummonGreaterBonewalker, "sMagicGreaterBonewalkerID"}, - {ESM::MagicEffect::SummonHunger, "sMagicHungerID"}, - {ESM::MagicEffect::SummonScamp, "sMagicScampID"}, - {ESM::MagicEffect::SummonSkeletalMinion, "sMagicSkeletalMinionID"}, - {ESM::MagicEffect::SummonStormAtronach, "sMagicStormAtronachID"}, - {ESM::MagicEffect::SummonWingedTwilight, "sMagicWingedTwilightID"}, - {ESM::MagicEffect::SummonWolf, "sMagicCreature01ID"}, - {ESM::MagicEffect::SummonBear, "sMagicCreature02ID"}, - {ESM::MagicEffect::SummonBonewolf, "sMagicCreature03ID"}, - {ESM::MagicEffect::SummonCreature04, "sMagicCreature04ID"}, - {ESM::MagicEffect::SummonCreature05, "sMagicCreature05ID"}, + static const std::map summonMap{ + { ESM::MagicEffect::SummonAncestralGhost, "sMagicAncestralGhostID" }, + { ESM::MagicEffect::SummonBonelord, "sMagicBonelordID" }, + { ESM::MagicEffect::SummonBonewalker, "sMagicLeastBonewalkerID" }, + { ESM::MagicEffect::SummonCenturionSphere, "sMagicCenturionSphereID" }, + { ESM::MagicEffect::SummonClannfear, "sMagicClannfearID" }, + { ESM::MagicEffect::SummonDaedroth, "sMagicDaedrothID" }, + { ESM::MagicEffect::SummonDremora, "sMagicDremoraID" }, + { ESM::MagicEffect::SummonFabricant, "sMagicFabricantID" }, + { ESM::MagicEffect::SummonFlameAtronach, "sMagicFlameAtronachID" }, + { ESM::MagicEffect::SummonFrostAtronach, "sMagicFrostAtronachID" }, + { ESM::MagicEffect::SummonGoldenSaint, "sMagicGoldenSaintID" }, + { ESM::MagicEffect::SummonGreaterBonewalker, "sMagicGreaterBonewalkerID" }, + { ESM::MagicEffect::SummonHunger, "sMagicHungerID" }, + { ESM::MagicEffect::SummonScamp, "sMagicScampID" }, + { ESM::MagicEffect::SummonSkeletalMinion, "sMagicSkeletalMinionID" }, + { ESM::MagicEffect::SummonStormAtronach, "sMagicStormAtronachID" }, + { ESM::MagicEffect::SummonWingedTwilight, "sMagicWingedTwilightID" }, + { ESM::MagicEffect::SummonWolf, "sMagicCreature01ID" }, + { ESM::MagicEffect::SummonBear, "sMagicCreature02ID" }, + { ESM::MagicEffect::SummonBonewolf, "sMagicCreature03ID" }, + { ESM::MagicEffect::SummonCreature04, "sMagicCreature04ID" }, + { ESM::MagicEffect::SummonCreature05, "sMagicCreature05ID" }, }; auto it = summonMap.find(effectId); if (it != summonMap.end()) - return MWBase::Environment::get().getWorld()->getStore().get().find(it->second)->mValue.getString(); + return MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find(it->second) + ->mValue.getString(); return {}; } @@ -75,7 +79,8 @@ namespace MWMechanics auto world = MWBase::Environment::get().getWorld(); MWWorld::ManualRef ref(world->getStore(), creatureID, 1); - MWMechanics::CreatureStats& summonedCreatureStats = ref.getPtr().getClass().getCreatureStats(ref.getPtr()); + MWMechanics::CreatureStats& summonedCreatureStats + = ref.getPtr().getClass().getCreatureStats(ref.getPtr()); // Make the summoned creature follow its master and help in fights AiFollow package(summoner); @@ -98,7 +103,8 @@ namespace MWMechanics catch (std::exception& e) { Log(Debug::Error) << "Failed to spawn summoned creature: " << e.what(); - // still insert into creatureMap so we don't try to spawn again every frame, that would spam the warning log + // still insert into creatureMap so we don't try to spawn again every frame, that would spam the warning + // log } summoner.getClass().getCreatureStats(summoner).getSummonedCreatureMap().emplace(effectId, creatureActorId); @@ -120,16 +126,17 @@ namespace MWMechanics if (!cleanup) return; - for (auto it = creatureMap.begin(); it != creatureMap.end(); ) + for (auto it = creatureMap.begin(); it != creatureMap.end();) { - if(it->second == -1) + if (it->second == -1) { // Keep the spell effect active if we failed to spawn anything it++; continue; } MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->searchPtrViaActorId(it->second); - if (!ptr.isEmpty() && ptr.getClass().getCreatureStats(ptr).isDead() && ptr.getClass().getCreatureStats(ptr).isDeathAnimationFinished()) + if (!ptr.isEmpty() && ptr.getClass().getCreatureStats(ptr).isDead() + && ptr.getClass().getCreatureStats(ptr).isDeathAnimationFinished()) { // Purge the magic effect so a new creature can be summoned if desired auto summon = *it; @@ -144,10 +151,11 @@ namespace MWMechanics void purgeSummonEffect(const MWWorld::Ptr& summoner, const std::pair& summon) { auto& creatureStats = summoner.getClass().getCreatureStats(summoner); - creatureStats.getActiveSpells().purge([summon] (const auto& spell, const auto& effect) - { - return effect.mEffectId == summon.first && effect.mArg == summon.second; - }, summoner); + creatureStats.getActiveSpells().purge( + [summon](const auto& spell, const auto& effect) { + return effect.mEffectId == summon.first && effect.mArg == summon.second; + }, + summoner); MWBase::Environment::get().getMechanicsManager()->cleanupSummonedCreature(summoner, summon.second); } diff --git a/apps/openmw/mwmechanics/trading.cpp b/apps/openmw/mwmechanics/trading.cpp index a40b745d21..0fceda46a4 100644 --- a/apps/openmw/mwmechanics/trading.cpp +++ b/apps/openmw/mwmechanics/trading.cpp @@ -18,30 +18,30 @@ namespace MWMechanics bool Trading::haggle(const MWWorld::Ptr& player, const MWWorld::Ptr& merchant, int playerOffer, int merchantOffer) { // accept if merchant offer is better than player offer - if ( playerOffer <= merchantOffer ) { + if (playerOffer <= merchantOffer) + { return true; } // reject if npc is a creature - if ( merchant.getType() != ESM::NPC::sRecordId ) { + if (merchant.getType() != ESM::NPC::sRecordId) + { return false; } - const MWWorld::Store &gmst = - MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& gmst + = MWBase::Environment::get().getWorld()->getStore().get(); // Is the player buying? bool buying = (merchantOffer < 0); int a = std::abs(merchantOffer); int b = std::abs(playerOffer); - int d = (buying) - ? int(100 * (a - b) / a) - : int(100 * (b - a) / b); + int d = (buying) ? int(100 * (a - b) / a) : int(100 * (b - a) / b); int clampedDisposition = MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(merchant); - const MWMechanics::CreatureStats &merchantStats = merchant.getClass().getCreatureStats(merchant); - const MWMechanics::CreatureStats &playerStats = player.getClass().getCreatureStats(player); + const MWMechanics::CreatureStats& merchantStats = merchant.getClass().getCreatureStats(merchant); + const MWMechanics::CreatureStats& playerStats = player.getClass().getCreatureStats(player); float a1 = static_cast(player.getClass().getSkill(player, ESM::Skill::Mercantile)); float b1 = 0.1f * playerStats.getAttribute(ESM::Attribute::Luck).getModified(); @@ -54,15 +54,15 @@ namespace MWMechanics float pcTerm = (dispositionTerm + a1 + b1 + c1) * playerStats.getFatigueTerm(); float npcTerm = (d1 + e1 + f1) * merchantStats.getFatigueTerm(); float x = gmst.find("fBargainOfferMulti")->mValue.getFloat() * d - + gmst.find("fBargainOfferBase")->mValue.getFloat() - + int(pcTerm - npcTerm); + + gmst.find("fBargainOfferBase")->mValue.getFloat() + int(pcTerm - npcTerm); auto& prng = MWBase::Environment::get().getWorld()->getPrng(); int roll = Misc::Rng::rollDice(100, prng) + 1; // reject if roll fails // (or if player tries to buy things and get money) - if ( roll > x || (merchantOffer < 0 && 0 < playerOffer) ) { + if (roll > x || (merchantOffer < 0 && 0 < playerOffer)) + { return false; } @@ -71,10 +71,12 @@ namespace MWMechanics int finalPrice = std::abs(playerOffer); int initialMerchantOffer = std::abs(merchantOffer); - if ( !buying && (finalPrice > initialMerchantOffer) ) { + if (!buying && (finalPrice > initialMerchantOffer)) + { skillGain = std::floor(100.f * (finalPrice - initialMerchantOffer) / finalPrice); } - else if ( buying && (finalPrice < initialMerchantOffer) ) { + else if (buying && (finalPrice < initialMerchantOffer)) + { skillGain = std::floor(100.f * (initialMerchantOffer - finalPrice) / initialMerchantOffer); } player.getClass().skillUsageSucceeded(player, ESM::Skill::Mercantile, 0, skillGain); diff --git a/apps/openmw/mwmechanics/typedaipackage.hpp b/apps/openmw/mwmechanics/typedaipackage.hpp index 0ea276999f..9cbcc95aee 100644 --- a/apps/openmw/mwmechanics/typedaipackage.hpp +++ b/apps/openmw/mwmechanics/typedaipackage.hpp @@ -8,23 +8,28 @@ namespace MWMechanics template struct TypedAiPackage : public AiPackage { - TypedAiPackage() : - AiPackage(T::getTypeId(), T::makeDefaultOptions()) {} + TypedAiPackage() + : AiPackage(T::getTypeId(), T::makeDefaultOptions()) + { + } - TypedAiPackage(bool repeat) : - AiPackage(T::getTypeId(), T::makeDefaultOptions().withRepeat(repeat)) {} + TypedAiPackage(bool repeat) + : AiPackage(T::getTypeId(), T::makeDefaultOptions().withRepeat(repeat)) + { + } - TypedAiPackage(const Options& options) : - AiPackage(T::getTypeId(), options) {} + TypedAiPackage(const Options& options) + : AiPackage(T::getTypeId(), options) + { + } template - TypedAiPackage(Derived*) : - AiPackage(Derived::getTypeId(), Derived::makeDefaultOptions()) {} - - std::unique_ptr clone() const override + TypedAiPackage(Derived*) + : AiPackage(Derived::getTypeId(), Derived::makeDefaultOptions()) { - return std::make_unique(*static_cast(this)); } + + std::unique_ptr clone() const override { return std::make_unique(*static_cast(this)); } }; } diff --git a/apps/openmw/mwmechanics/weaponpriority.cpp b/apps/openmw/mwmechanics/weaponpriority.cpp index 0beecae990..b6550af9c8 100644 --- a/apps/openmw/mwmechanics/weaponpriority.cpp +++ b/apps/openmw/mwmechanics/weaponpriority.cpp @@ -1,8 +1,8 @@ #include "weaponpriority.hpp" +#include #include #include -#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" @@ -11,16 +11,16 @@ #include "../mwworld/esmstore.hpp" #include "../mwworld/inventorystore.hpp" -#include "combat.hpp" #include "aicombataction.hpp" +#include "combat.hpp" #include "spellpriority.hpp" #include "spellutil.hpp" #include "weapontype.hpp" namespace MWMechanics { - float rateWeapon (const MWWorld::Ptr &item, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy, int type, - float arrowRating, float boltRating) + float rateWeapon(const MWWorld::Ptr& item, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy, int type, + float arrowRating, float boltRating) { if (enemy.isEmpty() || item.getType() != ESM::Weapon::sRecordId) return 0.f; @@ -40,7 +40,7 @@ namespace MWMechanics if (type == -1 && weapclass == ESM::WeaponType::Ammo) return 0.f; - float rating=0.f; + float rating = 0.f; static const float fAIMeleeWeaponMult = gmst.find("fAIMeleeWeaponMult")->mValue.getFloat(); float ratingMult = fAIMeleeWeaponMult; @@ -48,7 +48,7 @@ namespace MWMechanics { // Underwater ranged combat is impossible if (world->isUnderwater(MWWorld::ConstPtr(actor), 0.75f) - || world->isUnderwater(MWWorld::ConstPtr(enemy), 0.75f)) + || world->isUnderwater(MWWorld::ConstPtr(enemy), 0.75f)) return 0.f; // Use a higher rating multiplier if the actor is out of enemy's reach, use the normal mult otherwise @@ -111,7 +111,8 @@ namespace MWMechanics int castCost = getEffectiveEnchantmentCastCost(static_cast(enchantment->mData.mCost), actor); float charge = item.getCellRef().getEnchantmentCharge(); - if (charge == -1 || charge >= castCost || weapclass == ESM::WeaponType::Thrown || weapclass == ESM::WeaponType::Ammo) + if (charge == -1 || charge >= castCost || weapclass == ESM::WeaponType::Thrown + || weapclass == ESM::WeaponType::Ammo) rating += rateEffects(enchantment->mEffects, actor, enemy); } } @@ -121,11 +122,11 @@ namespace MWMechanics { int skill = item.getClass().getEquipmentSkill(item); if (skill != -1) - value = actor.getClass().getSkill(actor, skill); + value = actor.getClass().getSkill(actor, skill); } else { - MWWorld::LiveCellRef *ref = actor.get(); + MWWorld::LiveCellRef* ref = actor.get(); value = ref->mBase->mData.mCombat; } @@ -138,7 +139,7 @@ namespace MWMechanics return rating * ratingMult; } - float rateAmmo(const MWWorld::Ptr &actor, const MWWorld::Ptr &enemy, MWWorld::Ptr &bestAmmo, int ammoType) + float rateAmmo(const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy, MWWorld::Ptr& bestAmmo, int ammoType) { float bestAmmoRating = 0.f; if (!actor.getClass().hasInventoryStore(actor)) @@ -159,15 +160,17 @@ namespace MWMechanics return bestAmmoRating; } - float rateAmmo(const MWWorld::Ptr &actor, const MWWorld::Ptr &enemy, int ammoType) + float rateAmmo(const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy, int ammoType) { MWWorld::Ptr emptyPtr; return rateAmmo(actor, enemy, emptyPtr, ammoType); } - float vanillaRateWeaponAndAmmo(const MWWorld::Ptr& weapon, const MWWorld::Ptr& ammo, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy) + float vanillaRateWeaponAndAmmo( + const MWWorld::Ptr& weapon, const MWWorld::Ptr& ammo, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy) { - const MWWorld::Store& gmst = MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& gmst + = MWBase::Environment::get().getWorld()->getStore().get(); static const float fAIMeleeWeaponMult = gmst.find("fAIMeleeWeaponMult")->mValue.getFloat(); static const float fAIMeleeArmorMult = gmst.find("fAIMeleeArmorMult")->mValue.getFloat(); @@ -198,7 +201,7 @@ namespace MWMechanics float thrustRating = esmWeap->mData.mThrust[1] * skillMult * fAIMeleeWeaponMult; return actor.getClass().getArmorRating(actor) * fAIMeleeArmorMult - + std::max(std::max(chopRating, slashRating), thrustRating); + + std::max(std::max(chopRating, slashRating), thrustRating); } } diff --git a/apps/openmw/mwmechanics/weaponpriority.hpp b/apps/openmw/mwmechanics/weaponpriority.hpp index 97abec137e..44e9611b49 100644 --- a/apps/openmw/mwmechanics/weaponpriority.hpp +++ b/apps/openmw/mwmechanics/weaponpriority.hpp @@ -8,13 +8,14 @@ namespace MWWorld namespace MWMechanics { - float rateWeapon (const MWWorld::Ptr& item, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy, - int type=-1, float arrowRating=0.f, float boltRating=0.f); + float rateWeapon(const MWWorld::Ptr& item, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy, int type = -1, + float arrowRating = 0.f, float boltRating = 0.f); - float rateAmmo(const MWWorld::Ptr &actor, const MWWorld::Ptr &enemy, MWWorld::Ptr &bestAmmo, int ammoType); - float rateAmmo(const MWWorld::Ptr &actor, const MWWorld::Ptr &enemy, int ammoType); + float rateAmmo(const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy, MWWorld::Ptr& bestAmmo, int ammoType); + float rateAmmo(const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy, int ammoType); - float vanillaRateWeaponAndAmmo(const MWWorld::Ptr& weapon, const MWWorld::Ptr& ammo, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy); + float vanillaRateWeaponAndAmmo( + const MWWorld::Ptr& weapon, const MWWorld::Ptr& ammo, const MWWorld::Ptr& actor, const MWWorld::Ptr& enemy); } #endif diff --git a/apps/openmw/mwmechanics/weapontype.cpp b/apps/openmw/mwmechanics/weapontype.cpp index 9bf2daa886..0612ca1a2e 100644 --- a/apps/openmw/mwmechanics/weapontype.cpp +++ b/apps/openmw/mwmechanics/weapontype.cpp @@ -1,7 +1,7 @@ #include "weapontype.hpp" -#include "drawstate.hpp" #include "creaturestats.hpp" +#include "drawstate.hpp" #include "../mwworld/class.hpp" #include "../mwworld/inventorystore.hpp" @@ -11,13 +11,14 @@ namespace MWMechanics { template - struct Weapon {}; + struct Weapon + { + }; template <> struct Weapon { - inline static const ESM::WeaponType sValue { - /* short group */ "", + inline static const ESM::WeaponType sValue{ /* short group */ "", /* long group */ "", /* sound ID */ "", /* attach bone */ "", @@ -25,15 +26,13 @@ namespace MWMechanics /* usage skill */ ESM::Skill::HandToHand, /* weapon class*/ ESM::WeaponType::Melee, /* ammo type */ ESM::Weapon::None, - /* flags */ 0 - }; + /* flags */ 0 }; }; template <> struct Weapon { - inline static const ESM::WeaponType sValue { - /* short group */ "1h", + inline static const ESM::WeaponType sValue{ /* short group */ "1h", /* long group */ "pickprobe", /* sound ID */ "", /* attach bone */ "", @@ -41,15 +40,13 @@ namespace MWMechanics /* usage skill */ ESM::Skill::Security, /* weapon class*/ ESM::WeaponType::Melee, /* ammo type */ ESM::Weapon::None, - /* flags */ 0 - }; + /* flags */ 0 }; }; template <> struct Weapon { - inline static const ESM::WeaponType sValue { - /* short group */ "spell", + inline static const ESM::WeaponType sValue{ /* short group */ "spell", /* long group */ "spellcast", /* sound ID */ "", /* attach bone */ "", @@ -57,15 +54,13 @@ namespace MWMechanics /* usage skill */ ESM::Skill::HandToHand, /* weapon class*/ ESM::WeaponType::Melee, /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::TwoHanded - }; + /* flags */ ESM::WeaponType::TwoHanded }; }; template <> struct Weapon { - inline static const ESM::WeaponType sValue { - /* short group */ "hh", + inline static const ESM::WeaponType sValue{ /* short group */ "hh", /* long group */ "handtohand", /* sound ID */ "", /* attach bone */ "", @@ -73,15 +68,13 @@ namespace MWMechanics /* usage skill */ ESM::Skill::HandToHand, /* weapon class*/ ESM::WeaponType::Melee, /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::TwoHanded - }; + /* flags */ ESM::WeaponType::TwoHanded }; }; template <> struct Weapon { - inline static const ESM::WeaponType sValue { - /* short group */ "1s", + inline static const ESM::WeaponType sValue{ /* short group */ "1s", /* long group */ "shortbladeonehand", /* sound ID */ "Item Weapon Shortblade", /* attach bone */ "Weapon Bone", @@ -89,15 +82,13 @@ namespace MWMechanics /* usage skill */ ESM::Skill::ShortBlade, /* weapon class*/ ESM::WeaponType::Melee, /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth - }; + /* flags */ ESM::WeaponType::HasHealth }; }; template <> struct Weapon { - inline static const ESM::WeaponType sValue { - /* short group */ "1h", + inline static const ESM::WeaponType sValue{ /* short group */ "1h", /* long group */ "weapononehand", /* sound ID */ "Item Weapon Longblade", /* attach bone */ "Weapon Bone", @@ -105,15 +96,13 @@ namespace MWMechanics /* usage skill */ ESM::Skill::LongBlade, /* weapon class*/ ESM::WeaponType::Melee, /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth - }; + /* flags */ ESM::WeaponType::HasHealth }; }; template <> struct Weapon { - inline static const ESM::WeaponType sValue { - /* short group */ "1b", + inline static const ESM::WeaponType sValue{ /* short group */ "1b", /* long group */ "bluntonehand", /* sound ID */ "Item Weapon Blunt", /* attach bone */ "Weapon Bone", @@ -121,15 +110,13 @@ namespace MWMechanics /* usage skill */ ESM::Skill::BluntWeapon, /* weapon class*/ ESM::WeaponType::Melee, /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth - }; + /* flags */ ESM::WeaponType::HasHealth }; }; template <> struct Weapon { - inline static const ESM::WeaponType sValue { - /* short group */ "1b", + inline static const ESM::WeaponType sValue{ /* short group */ "1b", /* long group */ "bluntonehand", /* sound ID */ "Item Weapon Blunt", /* attach bone */ "Weapon Bone", @@ -137,15 +124,13 @@ namespace MWMechanics /* usage skill */ ESM::Skill::Axe, /* weapon class*/ ESM::WeaponType::Melee, /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth - }; + /* flags */ ESM::WeaponType::HasHealth }; }; template <> struct Weapon { - inline static const ESM::WeaponType sValue { - /* short group */ "2c", + inline static const ESM::WeaponType sValue{ /* short group */ "2c", /* long group */ "weapontwohand", /* sound ID */ "Item Weapon Longblade", /* attach bone */ "Weapon Bone", @@ -153,15 +138,13 @@ namespace MWMechanics /* usage skill */ ESM::Skill::LongBlade, /* weapon class*/ ESM::WeaponType::Melee, /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth|ESM::WeaponType::TwoHanded - }; + /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; }; template <> struct Weapon { - inline static const ESM::WeaponType sValue { - /* short group */ "2b", + inline static const ESM::WeaponType sValue{ /* short group */ "2b", /* long group */ "blunttwohand", /* sound ID */ "Item Weapon Blunt", /* attach bone */ "Weapon Bone", @@ -169,15 +152,13 @@ namespace MWMechanics /* usage skill */ ESM::Skill::Axe, /* weapon class*/ ESM::WeaponType::Melee, /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth|ESM::WeaponType::TwoHanded - }; + /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; }; template <> struct Weapon { - inline static const ESM::WeaponType sValue { - /* short group */ "2b", + inline static const ESM::WeaponType sValue{ /* short group */ "2b", /* long group */ "blunttwohand", /* sound ID */ "Item Weapon Blunt", /* attach bone */ "Weapon Bone", @@ -185,15 +166,13 @@ namespace MWMechanics /* usage skill */ ESM::Skill::BluntWeapon, /* weapon class*/ ESM::WeaponType::Melee, /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth|ESM::WeaponType::TwoHanded - }; + /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; }; template <> struct Weapon { - inline static const ESM::WeaponType sValue { - /* short group */ "2w", + inline static const ESM::WeaponType sValue{ /* short group */ "2w", /* long group */ "weapontwowide", /* sound ID */ "Item Weapon Blunt", /* attach bone */ "Weapon Bone", @@ -201,15 +180,13 @@ namespace MWMechanics /* usage skill */ ESM::Skill::BluntWeapon, /* weapon class*/ ESM::WeaponType::Melee, /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth|ESM::WeaponType::TwoHanded - }; + /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; }; template <> struct Weapon { - inline static const ESM::WeaponType sValue { - /* short group */ "2w", + inline static const ESM::WeaponType sValue{ /* short group */ "2w", /* long group */ "weapontwowide", /* sound ID */ "Item Weapon Spear", /* attach bone */ "Weapon Bone", @@ -217,15 +194,13 @@ namespace MWMechanics /* usage skill */ ESM::Skill::Spear, /* weapon class*/ ESM::WeaponType::Melee, /* ammo type */ ESM::Weapon::None, - /* flags */ ESM::WeaponType::HasHealth|ESM::WeaponType::TwoHanded - }; + /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; }; template <> struct Weapon { - inline static const ESM::WeaponType sValue { - /* short group */ "bow", + inline static const ESM::WeaponType sValue{ /* short group */ "bow", /* long group */ "bowandarrow", /* sound ID */ "Item Weapon Bow", /* attach bone */ "Weapon Bone Left", @@ -233,15 +208,13 @@ namespace MWMechanics /* usage skill */ ESM::Skill::Marksman, /* weapon class*/ ESM::WeaponType::Ranged, /* ammo type */ ESM::Weapon::Arrow, - /* flags */ ESM::WeaponType::HasHealth|ESM::WeaponType::TwoHanded - }; + /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; }; template <> struct Weapon { - inline static const ESM::WeaponType sValue { - /* short group */ "crossbow", + inline static const ESM::WeaponType sValue{ /* short group */ "crossbow", /* long group */ "crossbow", /* sound ID */ "Item Weapon Crossbow", /* attach bone */ "Weapon Bone", @@ -249,15 +222,13 @@ namespace MWMechanics /* usage skill */ ESM::Skill::Marksman, /* weapon class*/ ESM::WeaponType::Ranged, /* ammo type */ ESM::Weapon::Bolt, - /* flags */ ESM::WeaponType::HasHealth|ESM::WeaponType::TwoHanded - }; + /* flags */ ESM::WeaponType::HasHealth | ESM::WeaponType::TwoHanded }; }; template <> struct Weapon { - inline static const ESM::WeaponType sValue { - /* short group */ "1t", + inline static const ESM::WeaponType sValue{ /* short group */ "1t", /* long group */ "throwweapon", /* sound ID */ "Item Weapon Blunt", /* attach bone */ "Weapon Bone", @@ -265,15 +236,13 @@ namespace MWMechanics /* usage skill */ ESM::Skill::Marksman, /* weapon class*/ ESM::WeaponType::Thrown, /* ammo type */ ESM::Weapon::None, - /* flags */ 0 - }; + /* flags */ 0 }; }; template <> struct Weapon { - inline static const ESM::WeaponType sValue { - /* short group */ "", + inline static const ESM::WeaponType sValue{ /* short group */ "", /* long group */ "", /* sound ID */ "Item Ammo", /* attach bone */ "Bip01 Arrow", @@ -281,15 +250,13 @@ namespace MWMechanics /* usage skill */ ESM::Skill::Marksman, /* weapon class*/ ESM::WeaponType::Ammo, /* ammo type */ ESM::Weapon::None, - /* flags */ 0 - }; + /* flags */ 0 }; }; template <> struct Weapon { - inline static const ESM::WeaponType sValue { - /* short group */ "", + inline static const ESM::WeaponType sValue{ /* short group */ "", /* long group */ "", /* sound ID */ "Item Ammo", /* attach bone */ "ArrowBone", @@ -297,31 +264,30 @@ namespace MWMechanics /* usage skill */ ESM::Skill::Marksman, /* weapon class*/ ESM::WeaponType::Ammo, /* ammo type */ ESM::Weapon::None, - /* flags */ 0 - }; + /* flags */ 0 }; }; - MWWorld::ContainerStoreIterator getActiveWeapon(const MWWorld::Ptr& actor, int *weaptype) + MWWorld::ContainerStoreIterator getActiveWeapon(const MWWorld::Ptr& actor, int* weaptype) { - MWWorld::InventoryStore &inv = actor.getClass().getInventoryStore(actor); - CreatureStats &stats = actor.getClass().getCreatureStats(actor); - if(stats.getDrawState() == MWMechanics::DrawState::Spell) + MWWorld::InventoryStore& inv = actor.getClass().getInventoryStore(actor); + CreatureStats& stats = actor.getClass().getCreatureStats(actor); + if (stats.getDrawState() == MWMechanics::DrawState::Spell) { *weaptype = ESM::Weapon::Spell; return inv.end(); } - if(stats.getDrawState() == MWMechanics::DrawState::Weapon) + if (stats.getDrawState() == MWMechanics::DrawState::Weapon) { MWWorld::ContainerStoreIterator weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); - if(weapon == inv.end()) + if (weapon == inv.end()) *weaptype = ESM::Weapon::HandToHand; else { auto type = weapon->getType(); - if(type == ESM::Weapon::sRecordId) + if (type == ESM::Weapon::sRecordId) { - const MWWorld::LiveCellRef *ref = weapon->get(); + const MWWorld::LiveCellRef* ref = weapon->get(); *weaptype = ref->mBase->mData.mType; } else if (type == ESM::Lockpick::sRecordId || type == ESM::Probe::sRecordId) @@ -338,24 +304,42 @@ namespace MWMechanics { switch (static_cast(weaponType)) { - case ESM::Weapon::PickProbe: return &Weapon::sValue; - case ESM::Weapon::HandToHand: return &Weapon::sValue; - case ESM::Weapon::Spell: return &Weapon::sValue; - case ESM::Weapon::None: return &Weapon::sValue; - case ESM::Weapon::ShortBladeOneHand: return &Weapon::sValue; - case ESM::Weapon::LongBladeOneHand: return &Weapon::sValue; - case ESM::Weapon::LongBladeTwoHand: return &Weapon::sValue; - case ESM::Weapon::BluntOneHand: return &Weapon::sValue; - case ESM::Weapon::BluntTwoClose: return &Weapon::sValue; - case ESM::Weapon::BluntTwoWide: return &Weapon::sValue; - case ESM::Weapon::SpearTwoWide: return &Weapon::sValue; - case ESM::Weapon::AxeOneHand: return &Weapon::sValue; - case ESM::Weapon::AxeTwoHand: return &Weapon::sValue; - case ESM::Weapon::MarksmanBow: return &Weapon::sValue; - case ESM::Weapon::MarksmanCrossbow: return &Weapon::sValue; - case ESM::Weapon::MarksmanThrown: return &Weapon::sValue; - case ESM::Weapon::Arrow: return &Weapon::sValue; - case ESM::Weapon::Bolt: return &Weapon::sValue; + case ESM::Weapon::PickProbe: + return &Weapon::sValue; + case ESM::Weapon::HandToHand: + return &Weapon::sValue; + case ESM::Weapon::Spell: + return &Weapon::sValue; + case ESM::Weapon::None: + return &Weapon::sValue; + case ESM::Weapon::ShortBladeOneHand: + return &Weapon::sValue; + case ESM::Weapon::LongBladeOneHand: + return &Weapon::sValue; + case ESM::Weapon::LongBladeTwoHand: + return &Weapon::sValue; + case ESM::Weapon::BluntOneHand: + return &Weapon::sValue; + case ESM::Weapon::BluntTwoClose: + return &Weapon::sValue; + case ESM::Weapon::BluntTwoWide: + return &Weapon::sValue; + case ESM::Weapon::SpearTwoWide: + return &Weapon::sValue; + case ESM::Weapon::AxeOneHand: + return &Weapon::sValue; + case ESM::Weapon::AxeTwoHand: + return &Weapon::sValue; + case ESM::Weapon::MarksmanBow: + return &Weapon::sValue; + case ESM::Weapon::MarksmanCrossbow: + return &Weapon::sValue; + case ESM::Weapon::MarksmanThrown: + return &Weapon::sValue; + case ESM::Weapon::Arrow: + return &Weapon::sValue; + case ESM::Weapon::Bolt: + return &Weapon::sValue; } return &Weapon::sValue; diff --git a/apps/openmw/mwmechanics/weapontype.hpp b/apps/openmw/mwmechanics/weapontype.hpp index 6c31be1d27..db7b3013f6 100644 --- a/apps/openmw/mwmechanics/weapontype.hpp +++ b/apps/openmw/mwmechanics/weapontype.hpp @@ -18,7 +18,7 @@ namespace MWWorld namespace MWMechanics { - MWWorld::ContainerStoreIterator getActiveWeapon(const MWWorld::Ptr& actor, int *weaptype); + MWWorld::ContainerStoreIterator getActiveWeapon(const MWWorld::Ptr& actor, int* weaptype); const ESM::WeaponType* getWeaponType(const int weaponType); } diff --git a/apps/openmw/mwphysics/actor.cpp b/apps/openmw/mwphysics/actor.cpp index 6c7345c031..9c7d6c964e 100644 --- a/apps/openmw/mwphysics/actor.cpp +++ b/apps/openmw/mwphysics/actor.cpp @@ -1,12 +1,12 @@ #include "actor.hpp" -#include #include +#include -#include -#include #include #include +#include +#include #include "../mwworld/class.hpp" @@ -19,307 +19,313 @@ namespace MWPhysics { - -Actor::Actor(const MWWorld::Ptr& ptr, const Resource::BulletShape* shape, PhysicsTaskScheduler* scheduler, - bool canWaterWalk, DetourNavigator::CollisionShapeType collisionShapeType) - : PtrHolder(ptr, ptr.getRefData().getPosition().asVec3()) - , mStandingOnPtr(nullptr), mCanWaterWalk(canWaterWalk), mWalkingOnWater(false) - , mMeshTranslation(shape->mCollisionBox.mCenter), mOriginalHalfExtents(shape->mCollisionBox.mExtents) - , mStuckFrames(0), mLastStuckPosition{0, 0, 0} - , mForce(0.f, 0.f, 0.f), mOnGround(true), mOnSlope(false) - , mInternalCollisionMode(true) - , mExternalCollisionMode(true) - , mActive(false) - , mTaskScheduler(scheduler) -{ - // We can not create actor without collisions - he will fall through the ground. - // In this case we should autogenerate collision box based on mesh shape - // (NPCs have bodyparts and use a different approach) - if (!ptr.getClass().isNpc() && mOriginalHalfExtents.length2() == 0.f) + Actor::Actor(const MWWorld::Ptr& ptr, const Resource::BulletShape* shape, PhysicsTaskScheduler* scheduler, + bool canWaterWalk, DetourNavigator::CollisionShapeType collisionShapeType) + : PtrHolder(ptr, ptr.getRefData().getPosition().asVec3()) + , mStandingOnPtr(nullptr) + , mCanWaterWalk(canWaterWalk) + , mWalkingOnWater(false) + , mMeshTranslation(shape->mCollisionBox.mCenter) + , mOriginalHalfExtents(shape->mCollisionBox.mExtents) + , mStuckFrames(0) + , mLastStuckPosition{ 0, 0, 0 } + , mForce(0.f, 0.f, 0.f) + , mOnGround(true) + , mOnSlope(false) + , mInternalCollisionMode(true) + , mExternalCollisionMode(true) + , mActive(false) + , mTaskScheduler(scheduler) { - if (shape->mCollisionShape) + // We can not create actor without collisions - he will fall through the ground. + // In this case we should autogenerate collision box based on mesh shape + // (NPCs have bodyparts and use a different approach) + if (!ptr.getClass().isNpc() && mOriginalHalfExtents.length2() == 0.f) { - btTransform transform; - transform.setIdentity(); - btVector3 min; - btVector3 max; - - shape->mCollisionShape->getAabb(transform, min, max); - mOriginalHalfExtents.x() = (max[0] - min[0])/2.f; - mOriginalHalfExtents.y() = (max[1] - min[1])/2.f; - mOriginalHalfExtents.z() = (max[2] - min[2])/2.f; - - mMeshTranslation = osg::Vec3f(0.f, 0.f, mOriginalHalfExtents.z()); + if (shape->mCollisionShape) + { + btTransform transform; + transform.setIdentity(); + btVector3 min; + btVector3 max; + + shape->mCollisionShape->getAabb(transform, min, max); + mOriginalHalfExtents.x() = (max[0] - min[0]) / 2.f; + mOriginalHalfExtents.y() = (max[1] - min[1]) / 2.f; + mOriginalHalfExtents.z() = (max[2] - min[2]) / 2.f; + + mMeshTranslation = osg::Vec3f(0.f, 0.f, mOriginalHalfExtents.z()); + } + + if (mOriginalHalfExtents.length2() == 0.f) + Log(Debug::Error) << "Error: Failed to calculate bounding box for actor \"" + << ptr.getCellRef().getRefId() << "\"."; } - if (mOriginalHalfExtents.length2() == 0.f) - Log(Debug::Error) << "Error: Failed to calculate bounding box for actor \"" << ptr.getCellRef().getRefId() << "\"."; - } - - const btVector3 halfExtents = Misc::Convert::toBullet(mOriginalHalfExtents); - if ((mMeshTranslation.x() == 0.0 && mMeshTranslation.y() == 0.0) + const btVector3 halfExtents = Misc::Convert::toBullet(mOriginalHalfExtents); + if ((mMeshTranslation.x() == 0.0 && mMeshTranslation.y() == 0.0) && std::fabs(mOriginalHalfExtents.x() - mOriginalHalfExtents.y()) < 2.2) - { - switch (collisionShapeType) { - case DetourNavigator::CollisionShapeType::Aabb: - mShape = std::make_unique(halfExtents); - mRotationallyInvariant = true; - break; - case DetourNavigator::CollisionShapeType::RotatingBox: - mShape = std::make_unique(halfExtents); - mRotationallyInvariant = false; - break; - case DetourNavigator::CollisionShapeType::Cylinder: - mShape = std::make_unique(halfExtents); - mRotationallyInvariant = true; - break; + switch (collisionShapeType) + { + case DetourNavigator::CollisionShapeType::Aabb: + mShape = std::make_unique(halfExtents); + mRotationallyInvariant = true; + break; + case DetourNavigator::CollisionShapeType::RotatingBox: + mShape = std::make_unique(halfExtents); + mRotationallyInvariant = false; + break; + case DetourNavigator::CollisionShapeType::Cylinder: + mShape = std::make_unique(halfExtents); + mRotationallyInvariant = true; + break; + } + mCollisionShapeType = collisionShapeType; + } + else + { + mShape = std::make_unique(halfExtents); + mRotationallyInvariant = false; + mCollisionShapeType = DetourNavigator::CollisionShapeType::RotatingBox; } - mCollisionShapeType = collisionShapeType; - } - else - { - mShape = std::make_unique(halfExtents); - mRotationallyInvariant = false; - mCollisionShapeType = DetourNavigator::CollisionShapeType::RotatingBox; - } - mConvexShape = static_cast(mShape.get()); - mConvexShape->setMargin(0.001); // make sure bullet isn't using the huge default convex shape margin of 0.04 + mConvexShape = static_cast(mShape.get()); + mConvexShape->setMargin(0.001); // make sure bullet isn't using the huge default convex shape margin of 0.04 - mCollisionObject = std::make_unique(); - mCollisionObject->setCollisionFlags(btCollisionObject::CF_KINEMATIC_OBJECT); - mCollisionObject->setActivationState(DISABLE_DEACTIVATION); - mCollisionObject->setCollisionShape(mShape.get()); - mCollisionObject->setUserPointer(this); + mCollisionObject = std::make_unique(); + mCollisionObject->setCollisionFlags(btCollisionObject::CF_KINEMATIC_OBJECT); + mCollisionObject->setActivationState(DISABLE_DEACTIVATION); + mCollisionObject->setCollisionShape(mShape.get()); + mCollisionObject->setUserPointer(this); - updateScaleUnsafe(); + updateScaleUnsafe(); - if(!mRotationallyInvariant) - mRotation = mPtr.getRefData().getBaseNode()->getAttitude(); + if (!mRotationallyInvariant) + mRotation = mPtr.getRefData().getBaseNode()->getAttitude(); - addCollisionMask(getCollisionMask()); - updateCollisionObjectPositionUnsafe(); -} + addCollisionMask(getCollisionMask()); + updateCollisionObjectPositionUnsafe(); + } -Actor::~Actor() -{ - mTaskScheduler->removeCollisionObject(mCollisionObject.get()); -} + Actor::~Actor() + { + mTaskScheduler->removeCollisionObject(mCollisionObject.get()); + } -void Actor::enableCollisionMode(bool collision) -{ - mInternalCollisionMode = collision; -} + void Actor::enableCollisionMode(bool collision) + { + mInternalCollisionMode = collision; + } -void Actor::enableCollisionBody(bool collision) -{ - if (mExternalCollisionMode != collision) + void Actor::enableCollisionBody(bool collision) { - mExternalCollisionMode = collision; - updateCollisionMask(); + if (mExternalCollisionMode != collision) + { + mExternalCollisionMode = collision; + updateCollisionMask(); + } } -} -void Actor::addCollisionMask(int collisionMask) -{ - mTaskScheduler->addCollisionObject(mCollisionObject.get(), CollisionType_Actor, collisionMask); -} + void Actor::addCollisionMask(int collisionMask) + { + mTaskScheduler->addCollisionObject(mCollisionObject.get(), CollisionType_Actor, collisionMask); + } -void Actor::updateCollisionMask() -{ - mTaskScheduler->setCollisionFilterMask(mCollisionObject.get(), getCollisionMask()); -} + void Actor::updateCollisionMask() + { + mTaskScheduler->setCollisionFilterMask(mCollisionObject.get(), getCollisionMask()); + } -int Actor::getCollisionMask() const -{ - int collisionMask = CollisionType_World | CollisionType_HeightMap; - if (mExternalCollisionMode) - collisionMask |= CollisionType_Actor | CollisionType_Projectile | CollisionType_Door; - if (mCanWaterWalk) - collisionMask |= CollisionType_Water; - return collisionMask; -} + int Actor::getCollisionMask() const + { + int collisionMask = CollisionType_World | CollisionType_HeightMap; + if (mExternalCollisionMode) + collisionMask |= CollisionType_Actor | CollisionType_Projectile | CollisionType_Door; + if (mCanWaterWalk) + collisionMask |= CollisionType_Water; + return collisionMask; + } -void Actor::updatePosition() -{ - std::scoped_lock lock(mPositionMutex); - const auto worldPosition = mPtr.getRefData().getPosition().asVec3(); - mPreviousPosition = worldPosition; - mPosition = worldPosition; - mSimulationPosition = worldPosition; - mPositionOffset = osg::Vec3f(); - mStandingOnPtr = nullptr; - mSkipSimulation = true; -} + void Actor::updatePosition() + { + std::scoped_lock lock(mPositionMutex); + const auto worldPosition = mPtr.getRefData().getPosition().asVec3(); + mPreviousPosition = worldPosition; + mPosition = worldPosition; + mSimulationPosition = worldPosition; + mPositionOffset = osg::Vec3f(); + mStandingOnPtr = nullptr; + mSkipSimulation = true; + } -void Actor::setSimulationPosition(const osg::Vec3f& position) -{ - if (!std::exchange(mSkipSimulation, false)) - mSimulationPosition = position; -} + void Actor::setSimulationPosition(const osg::Vec3f& position) + { + if (!std::exchange(mSkipSimulation, false)) + mSimulationPosition = position; + } -osg::Vec3f Actor::getScaledMeshTranslation() const -{ - return mRotation * osg::componentMultiply(mMeshTranslation, mScale); -} + osg::Vec3f Actor::getScaledMeshTranslation() const + { + return mRotation * osg::componentMultiply(mMeshTranslation, mScale); + } -void Actor::updateCollisionObjectPosition() -{ - std::scoped_lock lock(mPositionMutex); - updateCollisionObjectPositionUnsafe(); -} + void Actor::updateCollisionObjectPosition() + { + std::scoped_lock lock(mPositionMutex); + updateCollisionObjectPositionUnsafe(); + } -void Actor::updateCollisionObjectPositionUnsafe() -{ - mShape->setLocalScaling(Misc::Convert::toBullet(mScale)); - osg::Vec3f newPosition = getScaledMeshTranslation() + mPosition; + void Actor::updateCollisionObjectPositionUnsafe() + { + mShape->setLocalScaling(Misc::Convert::toBullet(mScale)); + osg::Vec3f newPosition = getScaledMeshTranslation() + mPosition; - auto& trans = mCollisionObject->getWorldTransform(); - trans.setOrigin(Misc::Convert::toBullet(newPosition)); - trans.setRotation(Misc::Convert::toBullet(mRotation)); - mCollisionObject->setWorldTransform(trans); + auto& trans = mCollisionObject->getWorldTransform(); + trans.setOrigin(Misc::Convert::toBullet(newPosition)); + trans.setRotation(Misc::Convert::toBullet(mRotation)); + mCollisionObject->setWorldTransform(trans); - mWorldPositionChanged = false; -} + mWorldPositionChanged = false; + } -osg::Vec3f Actor::getCollisionObjectPosition() const -{ - std::scoped_lock lock(mPositionMutex); - return getScaledMeshTranslation() + mPosition; -} + osg::Vec3f Actor::getCollisionObjectPosition() const + { + std::scoped_lock lock(mPositionMutex); + return getScaledMeshTranslation() + mPosition; + } -bool Actor::setPosition(const osg::Vec3f& position) -{ - std::scoped_lock lock(mPositionMutex); - applyOffsetChange(); - bool hasChanged = (mPosition.operator!=(position) && !mSkipSimulation) || mWorldPositionChanged; - if (!mSkipSimulation) + bool Actor::setPosition(const osg::Vec3f& position) { - mPreviousPosition = mPosition; - mPosition = position; + std::scoped_lock lock(mPositionMutex); + applyOffsetChange(); + bool hasChanged = (mPosition.operator!=(position) && !mSkipSimulation) || mWorldPositionChanged; + if (!mSkipSimulation) + { + mPreviousPosition = mPosition; + mPosition = position; + } + return hasChanged; } - return hasChanged; -} -void Actor::adjustPosition(const osg::Vec3f& offset) -{ - std::scoped_lock lock(mPositionMutex); - mPositionOffset += offset; -} + void Actor::adjustPosition(const osg::Vec3f& offset) + { + std::scoped_lock lock(mPositionMutex); + mPositionOffset += offset; + } -void Actor::applyOffsetChange() -{ - if (mPositionOffset.length() == 0) - return; - mPosition += mPositionOffset; - mPreviousPosition += mPositionOffset; - mSimulationPosition += mPositionOffset; - mPositionOffset = osg::Vec3f(); - mWorldPositionChanged = true; -} + void Actor::applyOffsetChange() + { + if (mPositionOffset.length() == 0) + return; + mPosition += mPositionOffset; + mPreviousPosition += mPositionOffset; + mSimulationPosition += mPositionOffset; + mPositionOffset = osg::Vec3f(); + mWorldPositionChanged = true; + } -void Actor::setRotation(osg::Quat quat) -{ - std::scoped_lock lock(mPositionMutex); - mRotation = quat; -} + void Actor::setRotation(osg::Quat quat) + { + std::scoped_lock lock(mPositionMutex); + mRotation = quat; + } -bool Actor::isRotationallyInvariant() const -{ - return mRotationallyInvariant; -} + bool Actor::isRotationallyInvariant() const + { + return mRotationallyInvariant; + } -void Actor::updateScale() -{ - std::scoped_lock lock(mPositionMutex); - updateScaleUnsafe(); -} + void Actor::updateScale() + { + std::scoped_lock lock(mPositionMutex); + updateScaleUnsafe(); + } -void Actor::updateScaleUnsafe() -{ - float scale = mPtr.getCellRef().getScale(); - osg::Vec3f scaleVec(scale,scale,scale); + void Actor::updateScaleUnsafe() + { + float scale = mPtr.getCellRef().getScale(); + osg::Vec3f scaleVec(scale, scale, scale); - mPtr.getClass().adjustScale(mPtr, scaleVec, false); - mScale = scaleVec; - mHalfExtents = osg::componentMultiply(mOriginalHalfExtents, scaleVec); + mPtr.getClass().adjustScale(mPtr, scaleVec, false); + mScale = scaleVec; + mHalfExtents = osg::componentMultiply(mOriginalHalfExtents, scaleVec); - scaleVec = osg::Vec3f(scale,scale,scale); - mPtr.getClass().adjustScale(mPtr, scaleVec, true); - mRenderingHalfExtents = osg::componentMultiply(mOriginalHalfExtents, scaleVec); -} + scaleVec = osg::Vec3f(scale, scale, scale); + mPtr.getClass().adjustScale(mPtr, scaleVec, true); + mRenderingHalfExtents = osg::componentMultiply(mOriginalHalfExtents, scaleVec); + } -osg::Vec3f Actor::getHalfExtents() const -{ - return mHalfExtents; -} + osg::Vec3f Actor::getHalfExtents() const + { + return mHalfExtents; + } -osg::Vec3f Actor::getOriginalHalfExtents() const -{ - return mOriginalHalfExtents; -} + osg::Vec3f Actor::getOriginalHalfExtents() const + { + return mOriginalHalfExtents; + } -osg::Vec3f Actor::getRenderingHalfExtents() const -{ - return mRenderingHalfExtents; -} + osg::Vec3f Actor::getRenderingHalfExtents() const + { + return mRenderingHalfExtents; + } -void Actor::setInertialForce(const osg::Vec3f &force) -{ - mForce = force; -} + void Actor::setInertialForce(const osg::Vec3f& force) + { + mForce = force; + } -void Actor::setOnGround(bool grounded) -{ - mOnGround = grounded; -} + void Actor::setOnGround(bool grounded) + { + mOnGround = grounded; + } -void Actor::setOnSlope(bool slope) -{ - mOnSlope = slope; -} + void Actor::setOnSlope(bool slope) + { + mOnSlope = slope; + } -bool Actor::isWalkingOnWater() const -{ - return mWalkingOnWater; -} + bool Actor::isWalkingOnWater() const + { + return mWalkingOnWater; + } -void Actor::setWalkingOnWater(bool walkingOnWater) -{ - mWalkingOnWater = walkingOnWater; -} + void Actor::setWalkingOnWater(bool walkingOnWater) + { + mWalkingOnWater = walkingOnWater; + } -void Actor::setCanWaterWalk(bool waterWalk) -{ - if (waterWalk != mCanWaterWalk) + void Actor::setCanWaterWalk(bool waterWalk) { - mCanWaterWalk = waterWalk; - updateCollisionMask(); + if (waterWalk != mCanWaterWalk) + { + mCanWaterWalk = waterWalk; + updateCollisionMask(); + } } -} -MWWorld::Ptr Actor::getStandingOnPtr() const -{ - std::scoped_lock lock(mPositionMutex); - return mStandingOnPtr; -} + MWWorld::Ptr Actor::getStandingOnPtr() const + { + std::scoped_lock lock(mPositionMutex); + return mStandingOnPtr; + } -void Actor::setStandingOnPtr(const MWWorld::Ptr& ptr) -{ - std::scoped_lock lock(mPositionMutex); - mStandingOnPtr = ptr; -} + void Actor::setStandingOnPtr(const MWWorld::Ptr& ptr) + { + std::scoped_lock lock(mPositionMutex); + mStandingOnPtr = ptr; + } -bool Actor::canMoveToWaterSurface(float waterlevel, const btCollisionWorld* world) const -{ - const float halfZ = getHalfExtents().z(); - const osg::Vec3f actorPosition = getPosition(); - const osg::Vec3f startingPosition(actorPosition.x(), actorPosition.y(), actorPosition.z() + halfZ); - const osg::Vec3f destinationPosition(actorPosition.x(), actorPosition.y(), waterlevel + halfZ); - MWPhysics::ActorTracer tracer; - tracer.doTrace(getCollisionObject(), startingPosition, destinationPosition, world); - return (tracer.mFraction >= 1.0f); -} + bool Actor::canMoveToWaterSurface(float waterlevel, const btCollisionWorld* world) const + { + const float halfZ = getHalfExtents().z(); + const osg::Vec3f actorPosition = getPosition(); + const osg::Vec3f startingPosition(actorPosition.x(), actorPosition.y(), actorPosition.z() + halfZ); + const osg::Vec3f destinationPosition(actorPosition.x(), actorPosition.y(), waterlevel + halfZ); + MWPhysics::ActorTracer tracer; + tracer.doTrace(getCollisionObject(), startingPosition, destinationPosition, world); + return (tracer.mFraction >= 1.0f); + } } diff --git a/apps/openmw/mwphysics/actor.hpp b/apps/openmw/mwphysics/actor.hpp index 4d7412e88b..40d4f27c0f 100644 --- a/apps/openmw/mwphysics/actor.hpp +++ b/apps/openmw/mwphysics/actor.hpp @@ -9,8 +9,8 @@ #include #include -#include #include +#include class btCollisionShape; class btCollisionObject; @@ -42,15 +42,13 @@ namespace MWPhysics */ void enableCollisionMode(bool collision); - bool getCollisionMode() const - { - return mInternalCollisionMode; - } + bool getCollisionMode() const { return mInternalCollisionMode; } btConvexShape* getConvexShape() const { return mConvexShape; } /** - * Enables or disables the *external* collision body. If disabled, other actors will not collide with this actor. + * Enables or disables the *external* collision body. If disabled, other actors will not collide with this + * actor. */ void enableCollisionBody(bool collision); @@ -63,9 +61,9 @@ namespace MWPhysics bool isRotationallyInvariant() const; /** - * Used by the physics simulation to store the simulation result. Used in conjunction with mWorldPosition - * to account for e.g. scripted movements - */ + * Used by the physics simulation to store the simulation result. Used in conjunction with mWorldPosition + * to account for e.g. scripted movements + */ void setSimulationPosition(const osg::Vec3f& position); void updateCollisionObjectPosition(); @@ -82,14 +80,15 @@ namespace MWPhysics /** * Returns the position of the collision body - * @note The collision shape's origin is in its center, so the position returned can be described as center of the actor collision box in world space. + * @note The collision shape's origin is in its center, so the position returned can be described as center of + * the actor collision box in world space. */ osg::Vec3f getCollisionObjectPosition() const; /** - * Store the current position into mPreviousPosition, then move to this position. - * Returns true if the new position is different. - */ + * Store the current position into mPreviousPosition, then move to this position. + * Returns true if the new position is different. + */ bool setPosition(const osg::Vec3f& position); // force set actor position to be as in Ptr::RefData @@ -103,23 +102,21 @@ namespace MWPhysics /** * Returns the half extents of the collision body (scaled according to rendering scale) - * @note The reason we need this extra method is because of an inconsistency in MW - NPC race scales aren't applied to the collision shape, - * most likely to make environment collision testing easier. However in some cases (swimming level) we want the actual scale. + * @note The reason we need this extra method is because of an inconsistency in MW - NPC race scales aren't + * applied to the collision shape, most likely to make environment collision testing easier. However in some + * cases (swimming level) we want the actual scale. */ osg::Vec3f getRenderingHalfExtents() const; /** * Sets the current amount of inertial force (incl. gravity) affecting this physic actor */ - void setInertialForce(const osg::Vec3f &force); + void setInertialForce(const osg::Vec3f& force); /** * Gets the current amount of inertial force (incl. gravity) affecting this physic actor */ - const osg::Vec3f &getInertialForce() const - { - return mForce; - } + const osg::Vec3f& getInertialForce() const { return mForce; } void setOnGround(bool grounded); @@ -139,23 +136,11 @@ namespace MWPhysics MWWorld::Ptr getStandingOnPtr() const; void setStandingOnPtr(const MWWorld::Ptr& ptr); - unsigned int getStuckFrames() const - { - return mStuckFrames; - } - void setStuckFrames(unsigned int frames) - { - mStuckFrames = frames; - } - - const osg::Vec3f &getLastStuckPosition() const - { - return mLastStuckPosition; - } - void setLastStuckPosition(osg::Vec3f position) - { - mLastStuckPosition = position; - } + unsigned int getStuckFrames() const { return mStuckFrames; } + void setStuckFrames(unsigned int frames) { mStuckFrames = frames; } + + const osg::Vec3f& getLastStuckPosition() const { return mLastStuckPosition; } + void setLastStuckPosition(osg::Vec3f position) { mLastStuckPosition = position; } bool canMoveToWaterSurface(float waterlevel, const btCollisionWorld* world) const; @@ -216,5 +201,4 @@ namespace MWPhysics } - #endif diff --git a/apps/openmw/mwphysics/actorconvexcallback.cpp b/apps/openmw/mwphysics/actorconvexcallback.cpp index 672af05058..db077beb31 100644 --- a/apps/openmw/mwphysics/actorconvexcallback.cpp +++ b/apps/openmw/mwphysics/actorconvexcallback.cpp @@ -14,53 +14,58 @@ namespace MWPhysics public: bool overlapping = false; - btScalar addSingleResult(btManifoldPoint& cp, - const btCollisionObjectWrapper* colObj0Wrap, - int partId0, - int index0, - const btCollisionObjectWrapper* colObj1Wrap, - int partId1, - int index1) override + btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap, int partId0, + int index0, const btCollisionObjectWrapper* colObj1Wrap, int partId1, int index1) override { - if(cp.getDistance() <= 0.0f) + if (cp.getDistance() <= 0.0f) overlapping = true; return btScalar(1); } }; - ActorConvexCallback::ActorConvexCallback(const btCollisionObject *me, const btVector3 &motion, btScalar minCollisionDot, const btCollisionWorld * world) - : btCollisionWorld::ClosestConvexResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)), - mMe(me), mMotion(motion), mMinCollisionDot(minCollisionDot), mWorld(world) + ActorConvexCallback::ActorConvexCallback( + const btCollisionObject* me, const btVector3& motion, btScalar minCollisionDot, const btCollisionWorld* world) + : btCollisionWorld::ClosestConvexResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)) + , mMe(me) + , mMotion(motion) + , mMinCollisionDot(minCollisionDot) + , mWorld(world) { } - btScalar ActorConvexCallback::addSingleResult(btCollisionWorld::LocalConvexResult& convexResult, bool normalInWorldSpace) + btScalar ActorConvexCallback::addSingleResult( + btCollisionWorld::LocalConvexResult& convexResult, bool normalInWorldSpace) { if (convexResult.m_hitCollisionObject == mMe) return btScalar(1); // override data for actor-actor collisions - // vanilla Morrowind seems to make overlapping actors collide as though they are both cylinders with a diameter of the distance between them - // For some reason this doesn't work as well as it should when using capsules, but it still helps a lot. - if(convexResult.m_hitCollisionObject->getBroadphaseHandle()->m_collisionFilterGroup == CollisionType_Actor) + // vanilla Morrowind seems to make overlapping actors collide as though they are both cylinders with a diameter + // of the distance between them For some reason this doesn't work as well as it should when using capsules, but + // it still helps a lot. + if (convexResult.m_hitCollisionObject->getBroadphaseHandle()->m_collisionFilterGroup == CollisionType_Actor) { ActorOverlapTester isOverlapping; - // FIXME: This is absolutely terrible and bullet should feel terrible for not making contactPairTest const-correct. - ContactTestWrapper::contactPairTest(const_cast(mWorld), const_cast(mMe), const_cast(convexResult.m_hitCollisionObject), isOverlapping); + // FIXME: This is absolutely terrible and bullet should feel terrible for not making contactPairTest + // const-correct. + ContactTestWrapper::contactPairTest(const_cast(mWorld), + const_cast(mMe), const_cast(convexResult.m_hitCollisionObject), + isOverlapping); - if(isOverlapping.overlapping) + if (isOverlapping.overlapping) { auto originA = Misc::Convert::toOsg(mMe->getWorldTransform().getOrigin()); auto originB = Misc::Convert::toOsg(convexResult.m_hitCollisionObject->getWorldTransform().getOrigin()); osg::Vec3f motion = Misc::Convert::toOsg(mMotion); - osg::Vec3f normal = (originA-originB); + osg::Vec3f normal = (originA - originB); normal.z() = 0; normal.normalize(); - // only collide if horizontally moving towards the hit actor (note: the motion vector appears to be inverted) - // FIXME: This kinda screws with standing on actors that walk up slopes for some reason. Makes you fall through them. - // It happens in vanilla Morrowind too, but much less often. - // I tried hunting down why but couldn't figure it out. Possibly a stair stepping or ground ejection bug. - if(normal * motion > 0.0f) + // only collide if horizontally moving towards the hit actor (note: the motion vector appears to be + // inverted) + // FIXME: This kinda screws with standing on actors that walk up slopes for some reason. Makes you fall + // through them. It happens in vanilla Morrowind too, but much less often. I tried hunting down why but + // couldn't figure it out. Possibly a stair stepping or ground ejection bug. + if (normal * motion > 0.0f) { convexResult.m_hitFraction = 0.0f; convexResult.m_hitNormalLocal = Misc::Convert::toBullet(normal); @@ -72,7 +77,8 @@ namespace MWPhysics } } } - if (convexResult.m_hitCollisionObject->getBroadphaseHandle()->m_collisionFilterGroup == CollisionType_Projectile) + if (convexResult.m_hitCollisionObject->getBroadphaseHandle()->m_collisionFilterGroup + == CollisionType_Projectile) { auto* projectileHolder = static_cast(convexResult.m_hitCollisionObject->getUserPointer()); if (!projectileHolder->isActive()) @@ -87,8 +93,9 @@ namespace MWPhysics hitNormalWorld = convexResult.m_hitNormalLocal; else { - ///need to transform normal into worldspace - hitNormalWorld = convexResult.m_hitCollisionObject->getWorldTransform().getBasis()*convexResult.m_hitNormalLocal; + /// need to transform normal into worldspace + hitNormalWorld + = convexResult.m_hitCollisionObject->getWorldTransform().getBasis() * convexResult.m_hitNormalLocal; } // dot product of the motion vector against the collision contact normal diff --git a/apps/openmw/mwphysics/actorconvexcallback.hpp b/apps/openmw/mwphysics/actorconvexcallback.hpp index 1c28ee6cc4..4b9ab1a8a4 100644 --- a/apps/openmw/mwphysics/actorconvexcallback.hpp +++ b/apps/openmw/mwphysics/actorconvexcallback.hpp @@ -10,15 +10,16 @@ namespace MWPhysics class ActorConvexCallback : public btCollisionWorld::ClosestConvexResultCallback { public: - ActorConvexCallback(const btCollisionObject *me, const btVector3 &motion, btScalar minCollisionDot, const btCollisionWorld * world); + ActorConvexCallback(const btCollisionObject* me, const btVector3& motion, btScalar minCollisionDot, + const btCollisionWorld* world); - btScalar addSingleResult(btCollisionWorld::LocalConvexResult& convexResult,bool normalInWorldSpace) override; + btScalar addSingleResult(btCollisionWorld::LocalConvexResult& convexResult, bool normalInWorldSpace) override; protected: - const btCollisionObject *mMe; + const btCollisionObject* mMe; const btVector3 mMotion; const btScalar mMinCollisionDot; - const btCollisionWorld * mWorld; + const btCollisionWorld* mWorld; }; } diff --git a/apps/openmw/mwphysics/closestnotmerayresultcallback.cpp b/apps/openmw/mwphysics/closestnotmerayresultcallback.cpp index 3f6cb2b727..b39603a767 100644 --- a/apps/openmw/mwphysics/closestnotmerayresultcallback.cpp +++ b/apps/openmw/mwphysics/closestnotmerayresultcallback.cpp @@ -12,13 +12,16 @@ namespace MWPhysics { - ClosestNotMeRayResultCallback::ClosestNotMeRayResultCallback(const btCollisionObject* me, std::vector targets, const btVector3& from, const btVector3& to) - : btCollisionWorld::ClosestRayResultCallback(from, to) - , mMe(me), mTargets(std::move(targets)) + ClosestNotMeRayResultCallback::ClosestNotMeRayResultCallback(const btCollisionObject* me, + std::vector targets, const btVector3& from, const btVector3& to) + : btCollisionWorld::ClosestRayResultCallback(from, to) + , mMe(me) + , mTargets(std::move(targets)) { } - btScalar ClosestNotMeRayResultCallback::addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace) + btScalar ClosestNotMeRayResultCallback::addSingleResult( + btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace) { const auto* hitObject = rayResult.m_collisionObject; if (hitObject == mMe) diff --git a/apps/openmw/mwphysics/closestnotmerayresultcallback.hpp b/apps/openmw/mwphysics/closestnotmerayresultcallback.hpp index 1fa32ef686..e6f5c45d36 100644 --- a/apps/openmw/mwphysics/closestnotmerayresultcallback.hpp +++ b/apps/openmw/mwphysics/closestnotmerayresultcallback.hpp @@ -14,7 +14,8 @@ namespace MWPhysics class ClosestNotMeRayResultCallback : public btCollisionWorld::ClosestRayResultCallback { public: - ClosestNotMeRayResultCallback(const btCollisionObject* me, std::vector targets, const btVector3& from, const btVector3& to); + ClosestNotMeRayResultCallback(const btCollisionObject* me, std::vector targets, + const btVector3& from, const btVector3& to); btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace) override; diff --git a/apps/openmw/mwphysics/collisiontype.hpp b/apps/openmw/mwphysics/collisiontype.hpp index b51a22a2f5..5dda2a6aeb 100644 --- a/apps/openmw/mwphysics/collisiontype.hpp +++ b/apps/openmw/mwphysics/collisiontype.hpp @@ -4,18 +4,21 @@ namespace MWPhysics { -enum CollisionType { - CollisionType_World = 1<<0, - CollisionType_Door = 1<<1, - CollisionType_Actor = 1<<2, - CollisionType_HeightMap = 1<<3, - CollisionType_Projectile = 1<<4, - CollisionType_Water = 1<<5, - CollisionType_Default = CollisionType_World|CollisionType_HeightMap|CollisionType_Actor|CollisionType_Door, - CollisionType_AnyPhysical = CollisionType_World|CollisionType_HeightMap|CollisionType_Actor|CollisionType_Door|CollisionType_Projectile|CollisionType_Water, - CollisionType_CameraOnly = 1<<6, - CollisionType_VisualOnly = 1<<7 -}; + enum CollisionType + { + CollisionType_World = 1 << 0, + CollisionType_Door = 1 << 1, + CollisionType_Actor = 1 << 2, + CollisionType_HeightMap = 1 << 3, + CollisionType_Projectile = 1 << 4, + CollisionType_Water = 1 << 5, + CollisionType_Default + = CollisionType_World | CollisionType_HeightMap | CollisionType_Actor | CollisionType_Door, + CollisionType_AnyPhysical = CollisionType_World | CollisionType_HeightMap | CollisionType_Actor + | CollisionType_Door | CollisionType_Projectile | CollisionType_Water, + CollisionType_CameraOnly = 1 << 6, + CollisionType_VisualOnly = 1 << 7 + }; } diff --git a/apps/openmw/mwphysics/constants.hpp b/apps/openmw/mwphysics/constants.hpp index b2d189e874..0b3c71408e 100644 --- a/apps/openmw/mwphysics/constants.hpp +++ b/apps/openmw/mwphysics/constants.hpp @@ -7,7 +7,8 @@ namespace MWPhysics static constexpr float sMinStep = 10.0f; // hack to skip over tiny unwalkable slopes static constexpr float sMinStep2 = 20.0f; // hack to skip over shorter but longer/wider/further unwalkable slopes - // whether to do the above stairstepping logic hacks to work around bad morrowind assets - disabling causes problems but improves performance + // whether to do the above stairstepping logic hacks to work around bad morrowind assets - disabling causes problems + // but improves performance static constexpr bool sDoExtraStairHacks = true; static constexpr float sGroundOffset = 1.0f; @@ -16,8 +17,9 @@ namespace MWPhysics static constexpr int sMaxIterations = 8; // Allows for more precise movement solving without getting stuck or snagging too easily. static constexpr float sCollisionMargin = 0.2f; - // Allow for a small amount of penetration to prevent numerical precision issues from causing the "unstuck"ing code to run unnecessarily - // Currently set to 0 because having the "unstuck"ing code run whenever possible prevents some glitchy snagging issues + // Allow for a small amount of penetration to prevent numerical precision issues from causing the "unstuck"ing code + // to run unnecessarily Currently set to 0 because having the "unstuck"ing code run whenever possible prevents some + // glitchy snagging issues static constexpr float sAllowedPenetration = 0.0f; } diff --git a/apps/openmw/mwphysics/contacttestresultcallback.cpp b/apps/openmw/mwphysics/contacttestresultcallback.cpp index 5829ee02f5..dae0a65af0 100644 --- a/apps/openmw/mwphysics/contacttestresultcallback.cpp +++ b/apps/openmw/mwphysics/contacttestresultcallback.cpp @@ -13,16 +13,16 @@ namespace MWPhysics { } - btScalar ContactTestResultCallback::addSingleResult(btManifoldPoint& cp, - const btCollisionObjectWrapper* col0Wrap,int partId0,int index0, - const btCollisionObjectWrapper* col1Wrap,int partId1,int index1) + btScalar ContactTestResultCallback::addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* col0Wrap, + int partId0, int index0, const btCollisionObjectWrapper* col1Wrap, int partId1, int index1) { const btCollisionObject* collisionObject = col0Wrap->m_collisionObject; if (collisionObject == mTestedAgainst) collisionObject = col1Wrap->m_collisionObject; PtrHolder* holder = static_cast(collisionObject->getUserPointer()); if (holder) - mResult.emplace_back(ContactPoint{holder->getPtr(), Misc::Convert::toOsg(cp.m_positionWorldOnB), Misc::Convert::toOsg(cp.m_normalWorldOnB)}); + mResult.emplace_back(ContactPoint{ holder->getPtr(), Misc::Convert::toOsg(cp.m_positionWorldOnB), + Misc::Convert::toOsg(cp.m_normalWorldOnB) }); return 0.f; } diff --git a/apps/openmw/mwphysics/contacttestresultcallback.hpp b/apps/openmw/mwphysics/contacttestresultcallback.hpp index 3d1b3b8aab..ae900e0208 100644 --- a/apps/openmw/mwphysics/contacttestresultcallback.hpp +++ b/apps/openmw/mwphysics/contacttestresultcallback.hpp @@ -19,9 +19,8 @@ namespace MWPhysics public: ContactTestResultCallback(const btCollisionObject* testedAgainst); - btScalar addSingleResult(btManifoldPoint& cp, - const btCollisionObjectWrapper* col0Wrap,int partId0,int index0, - const btCollisionObjectWrapper* col1Wrap,int partId1,int index1) override; + btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* col0Wrap, int partId0, int index0, + const btCollisionObjectWrapper* col1Wrap, int partId1, int index1) override; std::vector mResult; }; diff --git a/apps/openmw/mwphysics/contacttestwrapper.cpp b/apps/openmw/mwphysics/contacttestwrapper.cpp index c11a7e2926..d5da9e67e3 100644 --- a/apps/openmw/mwphysics/contacttestwrapper.cpp +++ b/apps/openmw/mwphysics/contacttestwrapper.cpp @@ -6,13 +6,15 @@ namespace MWPhysics { // Concurrent calls to contactPairTest (and by extension contactTest) are forbidden. static std::mutex contactMutex; - void ContactTestWrapper::contactTest(btCollisionWorld* collisionWorld, btCollisionObject* colObj, btCollisionWorld::ContactResultCallback& resultCallback) + void ContactTestWrapper::contactTest(btCollisionWorld* collisionWorld, btCollisionObject* colObj, + btCollisionWorld::ContactResultCallback& resultCallback) { std::unique_lock lock(contactMutex); collisionWorld->contactTest(colObj, resultCallback); } - void ContactTestWrapper::contactPairTest(btCollisionWorld* collisionWorld, btCollisionObject* colObjA, btCollisionObject* colObjB, btCollisionWorld::ContactResultCallback& resultCallback) + void ContactTestWrapper::contactPairTest(btCollisionWorld* collisionWorld, btCollisionObject* colObjA, + btCollisionObject* colObjB, btCollisionWorld::ContactResultCallback& resultCallback) { std::unique_lock lock(contactMutex); collisionWorld->contactPairTest(colObjA, colObjB, resultCallback); diff --git a/apps/openmw/mwphysics/contacttestwrapper.h b/apps/openmw/mwphysics/contacttestwrapper.h index b3b6edc59a..6a53f9ae27 100644 --- a/apps/openmw/mwphysics/contacttestwrapper.h +++ b/apps/openmw/mwphysics/contacttestwrapper.h @@ -7,8 +7,10 @@ namespace MWPhysics { struct ContactTestWrapper { - static void contactTest(btCollisionWorld* collisionWorld, btCollisionObject* colObj, btCollisionWorld::ContactResultCallback& resultCallback); - static void contactPairTest(btCollisionWorld* collisionWorld, btCollisionObject* colObjA, btCollisionObject* colObjB, btCollisionWorld::ContactResultCallback& resultCallback); + static void contactTest(btCollisionWorld* collisionWorld, btCollisionObject* colObj, + btCollisionWorld::ContactResultCallback& resultCallback); + static void contactPairTest(btCollisionWorld* collisionWorld, btCollisionObject* colObjA, + btCollisionObject* colObjB, btCollisionWorld::ContactResultCallback& resultCallback); }; } #endif diff --git a/apps/openmw/mwphysics/deepestnotmecontacttestresultcallback.cpp b/apps/openmw/mwphysics/deepestnotmecontacttestresultcallback.cpp index 3531cc8eb8..773eaf7ff1 100644 --- a/apps/openmw/mwphysics/deepestnotmecontacttestresultcallback.cpp +++ b/apps/openmw/mwphysics/deepestnotmecontacttestresultcallback.cpp @@ -12,26 +12,31 @@ namespace MWPhysics { - DeepestNotMeContactTestResultCallback::DeepestNotMeContactTestResultCallback(const btCollisionObject* me, const std::vector& targets, const btVector3 &origin) - : mMe(me), mTargets(targets), mOrigin(origin), mLeastDistSqr(std::numeric_limits::max()) + DeepestNotMeContactTestResultCallback::DeepestNotMeContactTestResultCallback( + const btCollisionObject* me, const std::vector& targets, const btVector3& origin) + : mMe(me) + , mTargets(targets) + , mOrigin(origin) + , mLeastDistSqr(std::numeric_limits::max()) { } btScalar DeepestNotMeContactTestResultCallback::addSingleResult(btManifoldPoint& cp, - const btCollisionObjectWrapper* col0Wrap,int partId0,int index0, - const btCollisionObjectWrapper* col1Wrap,int partId1,int index1) + const btCollisionObjectWrapper* col0Wrap, int partId0, int index0, const btCollisionObjectWrapper* col1Wrap, + int partId1, int index1) { const btCollisionObject* collisionObject = col1Wrap->m_collisionObject; if (collisionObject != mMe) { - if (collisionObject->getBroadphaseHandle()->m_collisionFilterGroup == CollisionType_Actor && !mTargets.empty()) + if (collisionObject->getBroadphaseHandle()->m_collisionFilterGroup == CollisionType_Actor + && !mTargets.empty()) { if ((std::find(mTargets.begin(), mTargets.end(), collisionObject) == mTargets.end())) return 0.f; } btScalar distsqr = mOrigin.distance2(cp.getPositionWorldOnA()); - if(!mObject || distsqr < mLeastDistSqr) + if (!mObject || distsqr < mLeastDistSqr) { mObject = collisionObject; mLeastDistSqr = distsqr; diff --git a/apps/openmw/mwphysics/deepestnotmecontacttestresultcallback.hpp b/apps/openmw/mwphysics/deepestnotmecontacttestresultcallback.hpp index 00cb5c01f7..d22a79e643 100644 --- a/apps/openmw/mwphysics/deepestnotmecontacttestresultcallback.hpp +++ b/apps/openmw/mwphysics/deepestnotmecontacttestresultcallback.hpp @@ -18,16 +18,16 @@ namespace MWPhysics btVector3 mOrigin; public: - const btCollisionObject *mObject{nullptr}; - btVector3 mContactPoint{0,0,0}; - btVector3 mContactNormal{0,0,0}; + const btCollisionObject* mObject{ nullptr }; + btVector3 mContactPoint{ 0, 0, 0 }; + btVector3 mContactNormal{ 0, 0, 0 }; btScalar mLeastDistSqr; - DeepestNotMeContactTestResultCallback(const btCollisionObject* me, const std::vector& targets, const btVector3 &origin); + DeepestNotMeContactTestResultCallback( + const btCollisionObject* me, const std::vector& targets, const btVector3& origin); - btScalar addSingleResult(btManifoldPoint& cp, - const btCollisionObjectWrapper* col0Wrap,int partId0,int index0, - const btCollisionObjectWrapper* col1Wrap,int partId1,int index1) override; + btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* col0Wrap, int partId0, int index0, + const btCollisionObjectWrapper* col1Wrap, int partId1, int index1) override; }; } diff --git a/apps/openmw/mwphysics/hasspherecollisioncallback.hpp b/apps/openmw/mwphysics/hasspherecollisioncallback.hpp index 34666e534c..c1fa0ad1ee 100644 --- a/apps/openmw/mwphysics/hasspherecollisioncallback.hpp +++ b/apps/openmw/mwphysics/hasspherecollisioncallback.hpp @@ -1,23 +1,20 @@ #ifndef OPENMW_MWPHYSICS_HASSPHERECOLLISIONCALLBACK_H #define OPENMW_MWPHYSICS_HASSPHERECOLLISIONCALLBACK_H -#include -#include #include +#include +#include #include namespace MWPhysics { // https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_collision_detection - bool testAabbAgainstSphere(const btVector3& aabbMin, const btVector3& aabbMax, - const btVector3& position, const btScalar radius) + bool testAabbAgainstSphere( + const btVector3& aabbMin, const btVector3& aabbMax, const btVector3& position, const btScalar radius) { - const btVector3 nearest( - std::clamp(position.x(), aabbMin.x(), aabbMax.x()), - std::clamp(position.y(), aabbMin.y(), aabbMax.y()), - std::clamp(position.z(), aabbMin.z(), aabbMax.z()) - ); + const btVector3 nearest(std::clamp(position.x(), aabbMin.x(), aabbMax.x()), + std::clamp(position.y(), aabbMin.y(), aabbMax.y()), std::clamp(position.z(), aabbMin.z(), aabbMax.z())); return nearest.distance(position) < radius; } @@ -26,13 +23,13 @@ namespace MWPhysics { public: HasSphereCollisionCallback(const btVector3& position, const btScalar radius, const int mask, const int group, - const Ignore& ignore, OnCollision* onCollision) - : mPosition(position), - mRadius(radius), - mIgnore(ignore), - mCollisionFilterMask(mask), - mCollisionFilterGroup(group), - mOnCollision(onCollision) + const Ignore& ignore, OnCollision* onCollision) + : mPosition(position) + , mRadius(radius) + , mIgnore(ignore) + , mCollisionFilterMask(mask) + , mCollisionFilterGroup(group) + , mOnCollision(onCollision) { } @@ -41,8 +38,7 @@ namespace MWPhysics if (mResult && mOnCollision == nullptr) return false; const auto collisionObject = static_cast(proxy->m_clientObject); - if (mIgnore(collisionObject) - || !needsCollision(*proxy) + if (mIgnore(collisionObject) || !needsCollision(*proxy) || !testAabbAgainstSphere(proxy->m_aabbMin, proxy->m_aabbMax, mPosition, mRadius)) return true; mResult = true; @@ -54,10 +50,7 @@ namespace MWPhysics return !mResult; } - bool getResult() const - { - return mResult; - } + bool getResult() const { return mResult; } private: btVector3 mPosition; diff --git a/apps/openmw/mwphysics/heightfield.cpp b/apps/openmw/mwphysics/heightfield.cpp index d363ddef11..4ec8dda881 100644 --- a/apps/openmw/mwphysics/heightfield.cpp +++ b/apps/openmw/mwphysics/heightfield.cpp @@ -5,8 +5,8 @@ #include -#include #include +#include #include @@ -53,7 +53,7 @@ namespace namespace MWPhysics { HeightField::HeightField(const float* heights, int x, int y, int size, int verts, float minH, float maxH, - const osg::Object* holdObject, PhysicsTaskScheduler* scheduler) + const osg::Object* holdObject, PhysicsTaskScheduler* scheduler) : mHoldObject(holdObject) #if BT_BULLET_VERSION < 310 , mHeights(makeHeights(heights, verts)) @@ -62,15 +62,9 @@ namespace MWPhysics { #if BT_BULLET_VERSION < 310 mShape = std::make_unique( - verts, verts, - getHeights(heights, mHeights), - 1, - minH, maxH, 2, - PHY_FLOAT, false - ); + verts, verts, getHeights(heights, mHeights), 1, minH, maxH, 2, PHY_FLOAT, false); #else - mShape = std::make_unique( - verts, verts, heights, minH, maxH, 2, false); + mShape = std::make_unique(verts, verts, heights, minH, maxH, 2, false); #endif mShape->setUseDiamondSubdivision(true); @@ -86,13 +80,14 @@ namespace MWPhysics mShape->buildAccelerator(); #endif - const btTransform transform(btQuaternion::getIdentity(), - BulletHelpers::getHeightfieldShift(x, y, size, minH, maxH)); + const btTransform transform( + btQuaternion::getIdentity(), BulletHelpers::getHeightfieldShift(x, y, size, minH, maxH)); mCollisionObject = std::make_unique(); mCollisionObject->setCollisionShape(mShape.get()); mCollisionObject->setWorldTransform(transform); - mTaskScheduler->addCollisionObject(mCollisionObject.get(), CollisionType_HeightMap, CollisionType_Actor|CollisionType_Projectile); + mTaskScheduler->addCollisionObject( + mCollisionObject.get(), CollisionType_HeightMap, CollisionType_Actor | CollisionType_Projectile); } HeightField::~HeightField() diff --git a/apps/openmw/mwphysics/heightfield.hpp b/apps/openmw/mwphysics/heightfield.hpp index c320225258..a54685fda1 100644 --- a/apps/openmw/mwphysics/heightfield.hpp +++ b/apps/openmw/mwphysics/heightfield.hpp @@ -24,7 +24,7 @@ namespace MWPhysics { public: HeightField(const float* heights, int x, int y, int size, int verts, float minH, float maxH, - const osg::Object* holdObject, PhysicsTaskScheduler* scheduler); + const osg::Object* holdObject, PhysicsTaskScheduler* scheduler); ~HeightField(); btCollisionObject* getCollisionObject(); diff --git a/apps/openmw/mwphysics/movementsolver.cpp b/apps/openmw/mwphysics/movementsolver.cpp index da07d5975b..58d50cd2ed 100644 --- a/apps/openmw/mwphysics/movementsolver.cpp +++ b/apps/openmw/mwphysics/movementsolver.cpp @@ -8,8 +8,8 @@ #include #include -#include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" #include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" @@ -29,7 +29,7 @@ namespace MWPhysics { - static bool isActor(const btCollisionObject *obj) + static bool isActor(const btCollisionObject* obj) { assert(obj); return obj->getBroadphaseHandle()->m_collisionFilterGroup == CollisionType_Actor; @@ -38,17 +38,20 @@ namespace MWPhysics class ContactCollectionCallback : public btCollisionWorld::ContactResultCallback { public: - ContactCollectionCallback(const btCollisionObject * me, osg::Vec3f velocity) : mMe(me) + ContactCollectionCallback(const btCollisionObject* me, osg::Vec3f velocity) + : mMe(me) { m_collisionFilterGroup = me->getBroadphaseHandle()->m_collisionFilterGroup; m_collisionFilterMask = me->getBroadphaseHandle()->m_collisionFilterMask & ~CollisionType_Projectile; mVelocity = Misc::Convert::toBullet(velocity); } - btScalar addSingleResult(btManifoldPoint & contact, const btCollisionObjectWrapper * colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper * colObj1Wrap, int partId1, int index1) override + btScalar addSingleResult(btManifoldPoint& contact, const btCollisionObjectWrapper* colObj0Wrap, int partId0, + int index0, const btCollisionObjectWrapper* colObj1Wrap, int partId1, int index1) override { if (isActor(colObj0Wrap->getCollisionObject()) && isActor(colObj1Wrap->getCollisionObject())) return 0.0; - // ignore overlap if we're moving in the same direction as it would push us out (don't change this to >=, that would break detection when not moving) + // ignore overlap if we're moving in the same direction as it would push us out (don't change this to >=, + // that would break detection when not moving) if (contact.m_normalWorldOnB.dot(mVelocity) > 0.0) return 0.0; auto delta = contact.m_normalWorldOnB * -contact.m_distance1; @@ -71,21 +74,22 @@ namespace MWPhysics btScalar mMaxX = 0.0; btScalar mMaxY = 0.0; btScalar mMaxZ = 0.0; - btVector3 mContactSum{0.0, 0.0, 0.0}; - btVector3 mNormal{0.0, 0.0, 0.0}; // points towards "me" - btVector3 mDelta{0.0, 0.0, 0.0}; // points towards "me" + btVector3 mContactSum{ 0.0, 0.0, 0.0 }; + btVector3 mNormal{ 0.0, 0.0, 0.0 }; // points towards "me" + btVector3 mDelta{ 0.0, 0.0, 0.0 }; // points towards "me" btScalar mDistance = 0.0; // negative or zero protected: btVector3 mVelocity; - const btCollisionObject * mMe; + const btCollisionObject* mMe; }; - osg::Vec3f MovementSolver::traceDown(const MWWorld::Ptr &ptr, const osg::Vec3f& position, Actor* actor, btCollisionWorld* collisionWorld, float maxHeight) + osg::Vec3f MovementSolver::traceDown(const MWWorld::Ptr& ptr, const osg::Vec3f& position, Actor* actor, + btCollisionWorld* collisionWorld, float maxHeight) { osg::Vec3f offset = actor->getCollisionObjectPosition() - ptr.getRefData().getPosition().asVec3(); ActorTracer tracer; - tracer.findGround(actor, position + offset, position + offset - osg::Vec3f(0,0,maxHeight), collisionWorld); + tracer.findGround(actor, position + offset, position + offset - osg::Vec3f(0, 0, maxHeight), collisionWorld); if (tracer.mFraction >= 1.0f) { actor->setOnGround(false); @@ -98,16 +102,17 @@ namespace MWPhysics // Required for some broken door destinations in Morrowind.esm, where the spawn point // intersects with other geometry if the actor's base is taken into account btVector3 from = Misc::Convert::toBullet(position); - btVector3 to = from - btVector3(0,0,maxHeight); + btVector3 to = from - btVector3(0, 0, maxHeight); btCollisionWorld::ClosestRayResultCallback resultCallback1(from, to); resultCallback1.m_collisionFilterGroup = CollisionType_AnyPhysical; - resultCallback1.m_collisionFilterMask = CollisionType_World|CollisionType_HeightMap; + resultCallback1.m_collisionFilterMask = CollisionType_World | CollisionType_HeightMap; collisionWorld->rayTest(from, to, resultCallback1); - if (resultCallback1.hasHit() && ((Misc::Convert::toOsg(resultCallback1.m_hitPointWorld) - tracer.mEndPos + offset).length2() > 35*35 - || !isWalkableSlope(tracer.mPlaneNormal))) + if (resultCallback1.hasHit() + && ((Misc::Convert::toOsg(resultCallback1.m_hitPointWorld) - tracer.mEndPos + offset).length2() > 35 * 35 + || !isWalkableSlope(tracer.mPlaneNormal))) { actor->setOnSlope(!isWalkableSlope(resultCallback1.m_hitNormalWorld)); return Misc::Convert::toOsg(resultCallback1.m_hitPointWorld) + osg::Vec3f(0.f, 0.f, sGroundOffset); @@ -115,27 +120,28 @@ namespace MWPhysics actor->setOnSlope(!isWalkableSlope(tracer.mPlaneNormal)); - return tracer.mEndPos-offset + osg::Vec3f(0.f, 0.f, sGroundOffset); + return tracer.mEndPos - offset + osg::Vec3f(0.f, 0.f, sGroundOffset); } - void MovementSolver::move(ActorFrameData& actor, float time, const btCollisionWorld* collisionWorld, - const WorldFrameData& worldData) + void MovementSolver::move( + ActorFrameData& actor, float time, const btCollisionWorld* collisionWorld, const WorldFrameData& worldData) { // Reset per-frame data actor.mWalkingOnWater = false; // Anything to collide with? - if(actor.mSkipCollisionDetection) + if (actor.mSkipCollisionDetection) { - actor.mPosition += (osg::Quat(actor.mRotation.x(), osg::Vec3f(-1, 0, 0)) * - osg::Quat(actor.mRotation.y(), osg::Vec3f(0, 0, -1)) - ) * actor.mMovement * time; + actor.mPosition += (osg::Quat(actor.mRotation.x(), osg::Vec3f(-1, 0, 0)) + * osg::Quat(actor.mRotation.y(), osg::Vec3f(0, 0, -1))) + * actor.mMovement * time; return; } // Adjust for collision mesh offset relative to actor's "location" - // (doTrace doesn't take local/interior collision shape translation into account, so we have to do it on our own) - // for compatibility with vanilla assets, we have to derive this from the vertical half extent instead of from internal hull translation - // if not for this hack, the "correct" collision hull position would be physicActor->getScaledMeshTranslation() + // (doTrace doesn't take local/interior collision shape translation into account, so we have to do it on our + // own) for compatibility with vanilla assets, we have to derive this from the vertical half extent instead of + // from internal hull translation if not for this hack, the "correct" collision hull position would be + // physicActor->getScaledMeshTranslation() actor.mPosition.z() += actor.mHalfExtentsZ; // vanilla-accurate float swimlevel = actor.mSwimLevel + actor.mHalfExtentsZ; @@ -148,18 +154,20 @@ namespace MWPhysics // if the CharacterController tells us to do so if (actor.mMovement.z() > 0 && actor.mInert && actor.mPosition.z() < swimlevel) { - velocity = osg::Vec3f(0,0,1) * 25; + velocity = osg::Vec3f(0, 0, 1) * 25; } else if (actor.mPosition.z() < swimlevel || actor.mFlying) { - velocity = (osg::Quat(actor.mRotation.x(), osg::Vec3f(-1, 0, 0)) * osg::Quat(actor.mRotation.y(), osg::Vec3f(0, 0, -1))) * actor.mMovement; + velocity = (osg::Quat(actor.mRotation.x(), osg::Vec3f(-1, 0, 0)) + * osg::Quat(actor.mRotation.y(), osg::Vec3f(0, 0, -1))) + * actor.mMovement; } else { velocity = (osg::Quat(actor.mRotation.y(), osg::Vec3f(0, 0, -1))) * actor.mMovement; if ((velocity.z() > 0.f && actor.mIsOnGround && !actor.mIsOnSlope) - || (velocity.z() > 0.f && velocity.z() + actor.mInertia.z() <= -velocity.z() && actor.mIsOnSlope)) + || (velocity.z() > 0.f && velocity.z() + actor.mInertia.z() <= -velocity.z() && actor.mIsOnSlope)) actor.mInertia = velocity; else if (!actor.mIsOnGround || actor.mIsOnSlope) velocity = velocity + actor.mInertia; @@ -169,9 +177,15 @@ namespace MWPhysics if (worldData.mIsInStorm && velocity.length() > 0) { osg::Vec3f stormDirection = worldData.mStormDirection; - float angleDegrees = osg::RadiansToDegrees(std::acos(stormDirection * velocity / (stormDirection.length() * velocity.length()))); - static const float fStromWalkMult = MWBase::Environment::get().getWorld()->getStore().get().find("fStromWalkMult")->mValue.getFloat(); - velocity *= 1.f-(fStromWalkMult * (angleDegrees/180.f)); + float angleDegrees = osg::RadiansToDegrees( + std::acos(stormDirection * velocity / (stormDirection.length() * velocity.length()))); + static const float fStromWalkMult = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fStromWalkMult") + ->mValue.getFloat(); + velocity *= 1.f - (fStromWalkMult * (angleDegrees / 180.f)); } Stepper stepper(collisionWorld, actor.mCollisionObject); @@ -181,12 +195,12 @@ namespace MWPhysics * A loop to find newPosition using tracer, if successful different from the starting position. * nextpos is the local variable used to find potential newPosition, using velocity and remainingTime * The initial velocity was set earlier (see above). - */ + */ float remainingTime = time; int numTimesSlid = 0; - osg::Vec3f lastSlideNormal(0,0,1); - osg::Vec3f lastSlideNormalFallback(0,0,1); + osg::Vec3f lastSlideNormal(0, 0, 1); + osg::Vec3f lastSlideNormalFallback(0, 0, 1); bool forceGroundTest = false; for (int iterations = 0; iterations < sMaxIterations && remainingTime > 0.0001f; ++iterations) @@ -195,21 +209,21 @@ namespace MWPhysics bool underwater = newPosition.z() < swimlevel; // If not able to fly, don't allow to swim up into the air - if(!actor.mFlying && nextpos.z() > swimlevel && underwater) + if (!actor.mFlying && nextpos.z() > swimlevel && underwater) { - const osg::Vec3f down(0,0,-1); + const osg::Vec3f down(0, 0, -1); velocity = reject(velocity, down); // NOTE: remainingTime is unchanged before the loop continues continue; // velocity updated, calculate nextpos again } - if((newPosition - nextpos).length2() > 0.0001) + if ((newPosition - nextpos).length2() > 0.0001) { // trace to where character would go if there were no obstructions tracer.doTrace(actor.mCollisionObject, newPosition, nextpos, collisionWorld, actor.mIsOnGround); // check for obstructions - if(tracer.mFraction >= 1.0f) + if (tracer.mFraction >= 1.0f) { newPosition = tracer.mEndPos; // ok to move, so set newPosition break; @@ -227,7 +241,8 @@ namespace MWPhysics break; } - bool seenGround = !actor.mFlying && !underwater && ((actor.mIsOnGround && !actor.mIsOnSlope) || isWalkableSlope(tracer.mPlaneNormal)); + bool seenGround = !actor.mFlying && !underwater + && ((actor.mIsOnGround && !actor.mIsOnSlope) || isWalkableSlope(tracer.mPlaneNormal)); // We hit something. Check if we can step up. float hitHeight = tracer.mHitPoint.z() - tracer.mEndPos.z() + actor.mHalfExtentsZ; @@ -243,13 +258,13 @@ namespace MWPhysics { if (actor.mIsAquatic && newPosition.z() + actor.mHalfExtentsZ > actor.mWaterlevel) newPosition = oldPosition; - else if(!actor.mFlying && actor.mPosition.z() >= swimlevel) + else if (!actor.mFlying && actor.mPosition.z() >= swimlevel) forceGroundTest = true; } else { // Can't step up, so slide against what we ran into - remainingTime *= (1.0f-tracer.mFraction); + remainingTime *= (1.0f - tracer.mFraction); auto planeNormal = tracer.mPlaneNormal; // need to know the unadjusted normal to handle certain types of seams properly @@ -257,7 +272,8 @@ namespace MWPhysics // If we touched the ground this frame, and whatever we ran into is a wall of some sort, // pretend that its collision normal is pointing horizontally - // (fixes snagging on slightly downward-facing walls, and crawling up the bases of very steep walls because of the collision margin) + // (fixes snagging on slightly downward-facing walls, and crawling up the bases of very steep walls + // because of the collision margin) if (seenGround && !isWalkableSlope(planeNormal) && planeNormal.z() != 0) { planeNormal.z() = 0; @@ -265,37 +281,39 @@ namespace MWPhysics } // Move up to what we ran into (with a bit of a collision margin) - if ((newPosition-tracer.mEndPos).length2() > sCollisionMargin*sCollisionMargin) + if ((newPosition - tracer.mEndPos).length2() > sCollisionMargin * sCollisionMargin) { auto direction = velocity; direction.normalize(); newPosition = tracer.mEndPos; - newPosition -= direction*sCollisionMargin; + newPosition -= direction * sCollisionMargin; } osg::Vec3f newVelocity = (velocity * planeNormal <= 0.0) ? reject(velocity, planeNormal) : velocity; bool usedSeamLogic = false; - // check for the current and previous collision planes forming an acute angle; slide along the seam if they do - // for this, we want to use the original plane normal, or else certain types of geometry will snag - if(numTimesSlid > 0) + // check for the current and previous collision planes forming an acute angle; slide along the seam if + // they do for this, we want to use the original plane normal, or else certain types of geometry will + // snag + if (numTimesSlid > 0) { auto dotA = lastSlideNormal * origPlaneNormal; auto dotB = lastSlideNormalFallback * origPlaneNormal; - if(numTimesSlid <= 1) // ignore fallback normal if this is only the first or second slide + if (numTimesSlid <= 1) // ignore fallback normal if this is only the first or second slide dotB = 1.0; - if(dotA <= 0.0 || dotB <= 0.0) + if (dotA <= 0.0 || dotB <= 0.0) { osg::Vec3f bestNormal = lastSlideNormal; - // use previous-to-previous collision plane if it's acute with current plane but actual previous plane isn't - if(dotB < dotA) + // use previous-to-previous collision plane if it's acute with current plane but actual previous + // plane isn't + if (dotB < dotA) { bestNormal = lastSlideNormalFallback; lastSlideNormal = lastSlideNormalFallback; } auto constraintVector = bestNormal ^ origPlaneNormal; // cross product - if(constraintVector.length2() > 0) // only if it's not zero length + if (constraintVector.length2() > 0) // only if it's not zero length { constraintVector.normalize(); newVelocity = project(velocity, constraintVector); @@ -303,8 +321,9 @@ namespace MWPhysics // version of surface rejection for acute crevices/seams auto averageNormal = bestNormal + origPlaneNormal; averageNormal.normalize(); - tracer.doTrace(actor.mCollisionObject, newPosition, newPosition + averageNormal*(sCollisionMargin*2.0), collisionWorld); - newPosition = (newPosition + tracer.mEndPos)/2.0; + tracer.doTrace(actor.mCollisionObject, newPosition, + newPosition + averageNormal * (sCollisionMargin * 2.0), collisionWorld); + newPosition = (newPosition + tracer.mEndPos) / 2.0; usedSeamLogic = true; } @@ -313,13 +332,14 @@ namespace MWPhysics // otherwise just keep the normal vector rejection // move away from the collision plane slightly, if possible - // this reduces getting stuck in some concave geometry, like the gaps above the railings in some ald'ruhn buildings - // this is different from the normal collision margin, because the normal collision margin is along the movement path, - // but this is along the collision normal - if(!usedSeamLogic) + // this reduces getting stuck in some concave geometry, like the gaps above the railings in some + // ald'ruhn buildings this is different from the normal collision margin, because the normal collision + // margin is along the movement path, but this is along the collision normal + if (!usedSeamLogic) { - tracer.doTrace(actor.mCollisionObject, newPosition, newPosition + planeNormal*(sCollisionMargin*2.0), collisionWorld); - newPosition = (newPosition + tracer.mEndPos)/2.0; + tracer.doTrace(actor.mCollisionObject, newPosition, + newPosition + planeNormal * (sCollisionMargin * 2.0), collisionWorld); + newPosition = (newPosition + tracer.mEndPos) / 2.0; } // short circuit if we went backwards, but only if it was mostly horizontal and we're on the ground @@ -336,10 +356,10 @@ namespace MWPhysics // Do not allow sliding up steep slopes if there is gravity. // The purpose of this is to prevent air control from letting you slide up tall, unwalkable slopes. - // For that purpose, it is not necessary to do it when trying to slide along acute seams/crevices (i.e. usedSeamLogic) - // and doing so would actually break air control in some situations where vanilla allows air control. - // Vanilla actually allows you to slide up slopes as long as you're in the "walking" animation, which can be true even - // in the air, so allowing this for seams isn't a compatibility break. + // For that purpose, it is not necessary to do it when trying to slide along acute seams/crevices (i.e. + // usedSeamLogic) and doing so would actually break air control in some situations where vanilla allows + // air control. Vanilla actually allows you to slide up slopes as long as you're in the "walking" + // animation, which can be true even in the air, so allowing this for seams isn't a compatibility break. if (newPosition.z() >= swimlevel && !actor.mFlying && !isWalkableSlope(planeNormal) && !usedSeamLogic) newVelocity.z() = std::min(newVelocity.z(), velocity.z()); @@ -355,10 +375,10 @@ namespace MWPhysics if (forceGroundTest || (actor.mInertia.z() <= 0.f && newPosition.z() >= swimlevel)) { osg::Vec3f from = newPosition; - auto dropDistance = 2*sGroundOffset + (actor.mIsOnGround ? sStepSizeDown : 0); - osg::Vec3f to = newPosition - osg::Vec3f(0,0,dropDistance); + auto dropDistance = 2 * sGroundOffset + (actor.mIsOnGround ? sStepSizeDown : 0); + osg::Vec3f to = newPosition - osg::Vec3f(0, 0, dropDistance); tracer.doTrace(actor.mCollisionObject, from, to, collisionWorld, actor.mIsOnGround); - if(tracer.mFraction < 1.0f) + if (tracer.mFraction < 1.0f) { if (!isActor(tracer.mHitObject)) { @@ -370,41 +390,45 @@ namespace MWPhysics actor.mWalkingOnWater = true; if (!actor.mFlying && !isOnSlope) { - if (tracer.mFraction*dropDistance > sGroundOffset) + if (tracer.mFraction * dropDistance > sGroundOffset) newPosition.z() = tracer.mEndPos.z() + sGroundOffset; else { newPosition.z() = tracer.mEndPos.z(); - tracer.doTrace(actor.mCollisionObject, newPosition, newPosition + osg::Vec3f(0, 0, 2*sGroundOffset), collisionWorld); - newPosition = (newPosition+tracer.mEndPos)/2.0; + tracer.doTrace(actor.mCollisionObject, newPosition, + newPosition + osg::Vec3f(0, 0, 2 * sGroundOffset), collisionWorld); + newPosition = (newPosition + tracer.mEndPos) / 2.0; } } } else { // Vanilla allows actors to float on top of other actors. Do not push them off. - if (!actor.mFlying && isWalkableSlope(tracer.mPlaneNormal) && tracer.mEndPos.z()+sGroundOffset <= newPosition.z()) + if (!actor.mFlying && isWalkableSlope(tracer.mPlaneNormal) + && tracer.mEndPos.z() + sGroundOffset <= newPosition.z()) newPosition.z() = tracer.mEndPos.z() + sGroundOffset; isOnGround = false; } } - // forcibly treat stuck actors as if they're on flat ground because buggy collisions when inside of things can/will break ground detection - if(actor.mStuckFrames > 0) + // forcibly treat stuck actors as if they're on flat ground because buggy collisions when inside of things + // can/will break ground detection + if (actor.mStuckFrames > 0) { isOnGround = true; isOnSlope = false; } } - if((isOnGround && !isOnSlope) || newPosition.z() < swimlevel || actor.mFlying) + if ((isOnGround && !isOnSlope) || newPosition.z() < swimlevel || actor.mFlying) actor.mInertia = osg::Vec3f(0.f, 0.f, 0.f); else { actor.mInertia.z() -= time * Constants::GravityConst * Constants::UnitsPerMeter; if (actor.mInertia.z() < 0) actor.mInertia.z() *= actor.mSlowFall; - if (actor.mSlowFall < 1.f) { + if (actor.mSlowFall < 1.f) + { actor.mInertia.x() *= actor.mSlowFall; actor.mInertia.y() *= actor.mSlowFall; } @@ -425,55 +449,60 @@ namespace MWPhysics if (btFrom == btTo) return; - ProjectileConvexCallback resultCallback(projectile.mCaster, projectile.mCollisionObject, btFrom, btTo, projectile.mProjectile); + ProjectileConvexCallback resultCallback( + projectile.mCaster, projectile.mCollisionObject, btFrom, btTo, projectile.mProjectile); resultCallback.m_collisionFilterMask = CollisionType_AnyPhysical; resultCallback.m_collisionFilterGroup = CollisionType_Projectile; const btQuaternion btrot = btQuaternion::getIdentity(); - btTransform from_ (btrot, btFrom); - btTransform to_ (btrot, btTo); + btTransform from_(btrot, btFrom); + btTransform to_(btrot, btTo); const btCollisionShape* shape = projectile.mCollisionObject->getCollisionShape(); assert(shape->isConvex()); collisionWorld->convexSweepTest(static_cast(shape), from_, to_, resultCallback); - projectile.mPosition = Misc::Convert::toOsg(projectile.mProjectile->isActive() ? btTo : resultCallback.m_hitPointWorld); + projectile.mPosition + = Misc::Convert::toOsg(projectile.mProjectile->isActive() ? btTo : resultCallback.m_hitPointWorld); } btVector3 addMarginToDelta(btVector3 delta) { - if(delta.length2() == 0.0) + if (delta.length2() == 0.0) return delta; return delta + delta.normalized() * sCollisionMargin; } void MovementSolver::unstuck(ActorFrameData& actor, const btCollisionWorld* collisionWorld) { - if(actor.mSkipCollisionDetection) // noclipping/tcl + if (actor.mSkipCollisionDetection) // noclipping/tcl return; auto tempPosition = actor.mPosition; - if(actor.mStuckFrames >= 10) + if (actor.mStuckFrames >= 10) { - if((actor.mLastStuckPosition - actor.mPosition).length2() < 100) + if ((actor.mLastStuckPosition - actor.mPosition).length2() < 100) return; else { actor.mStuckFrames = 0; - actor.mLastStuckPosition = {0, 0, 0}; + actor.mLastStuckPosition = { 0, 0, 0 }; } } // use vanilla-accurate collision hull position hack (do same hitbox offset hack as movement solver) - // if vanilla compatibility didn't matter, the "correct" collision hull position would be physicActor->getScaledMeshTranslation() + // if vanilla compatibility didn't matter, the "correct" collision hull position would be + // physicActor->getScaledMeshTranslation() const auto verticalHalfExtent = osg::Vec3f(0.0, 0.0, actor.mHalfExtentsZ); // use a 3d approximation of the movement vector to better judge player intent - auto velocity = (osg::Quat(actor.mRotation.x(), osg::Vec3f(-1, 0, 0)) * osg::Quat(actor.mRotation.y(), osg::Vec3f(0, 0, -1))) * actor.mMovement; + auto velocity = (osg::Quat(actor.mRotation.x(), osg::Vec3f(-1, 0, 0)) + * osg::Quat(actor.mRotation.y(), osg::Vec3f(0, 0, -1))) + * actor.mMovement; // try to pop outside of the world before doing anything else if we're inside of it if (!actor.mIsOnGround || actor.mIsOnSlope) - velocity += actor.mInertia; + velocity += actor.mInertia; // because of the internal collision box offset hack, and the fact that we're moving the collision box manually, // we need to replicate part of the collision box's transform process from scratch @@ -482,59 +511,60 @@ namespace MWPhysics const btTransform oldTransform = actor.mCollisionObject->getWorldTransform(); btTransform newTransform = oldTransform; - auto gatherContacts = [&](btVector3 newOffset) -> ContactCollectionCallback - { + auto gatherContacts = [&](btVector3 newOffset) -> ContactCollectionCallback { goodPosition = refPosition + Misc::Convert::toOsg(addMarginToDelta(newOffset)); newTransform.setOrigin(Misc::Convert::toBullet(goodPosition)); actor.mCollisionObject->setWorldTransform(newTransform); - ContactCollectionCallback callback{actor.mCollisionObject, velocity}; - ContactTestWrapper::contactTest(const_cast(collisionWorld), actor.mCollisionObject, callback); + ContactCollectionCallback callback{ actor.mCollisionObject, velocity }; + ContactTestWrapper::contactTest( + const_cast(collisionWorld), actor.mCollisionObject, callback); return callback; }; // check whether we're inside the world with our collision box with manually-derived offset - auto contactCallback = gatherContacts({0.0, 0.0, 0.0}); - if(contactCallback.mDistance < -sAllowedPenetration) + auto contactCallback = gatherContacts({ 0.0, 0.0, 0.0 }); + if (contactCallback.mDistance < -sAllowedPenetration) { ++actor.mStuckFrames; actor.mLastStuckPosition = actor.mPosition; // we are; try moving it out of the world auto positionDelta = contactCallback.mContactSum; // limit rejection delta to the largest known individual rejections - if(std::abs(positionDelta.x()) > contactCallback.mMaxX) + if (std::abs(positionDelta.x()) > contactCallback.mMaxX) positionDelta *= contactCallback.mMaxX / std::abs(positionDelta.x()); - if(std::abs(positionDelta.y()) > contactCallback.mMaxY) + if (std::abs(positionDelta.y()) > contactCallback.mMaxY) positionDelta *= contactCallback.mMaxY / std::abs(positionDelta.y()); - if(std::abs(positionDelta.z()) > contactCallback.mMaxZ) + if (std::abs(positionDelta.z()) > contactCallback.mMaxZ) positionDelta *= contactCallback.mMaxZ / std::abs(positionDelta.z()); auto contactCallback2 = gatherContacts(positionDelta); - // successfully moved further out from contact (does not have to be in open space, just less inside of things) - if(contactCallback2.mDistance > contactCallback.mDistance) + // successfully moved further out from contact (does not have to be in open space, just less inside of + // things) + if (contactCallback2.mDistance > contactCallback.mDistance) tempPosition = goodPosition - verticalHalfExtent; // try again but only upwards (fixes some bad coc floors) else { // upwards-only offset - auto contactCallback3 = gatherContacts({0.0, 0.0, std::abs(positionDelta.z())}); + auto contactCallback3 = gatherContacts({ 0.0, 0.0, std::abs(positionDelta.z()) }); // success - if(contactCallback3.mDistance > contactCallback.mDistance) + if (contactCallback3.mDistance > contactCallback.mDistance) tempPosition = goodPosition - verticalHalfExtent; else // try again but fixed distance up { - auto contactCallback4 = gatherContacts({0.0, 0.0, 10.0}); + auto contactCallback4 = gatherContacts({ 0.0, 0.0, 10.0 }); // success - if(contactCallback4.mDistance > contactCallback.mDistance) + if (contactCallback4.mDistance > contactCallback.mDistance) tempPosition = goodPosition - verticalHalfExtent; } } } else { - actor.mStuckFrames = 0; - actor.mLastStuckPosition = {0, 0, 0}; + actor.mStuckFrames = 0; + actor.mLastStuckPosition = { 0, 0, 0 }; } actor.mCollisionObject->setWorldTransform(oldTransform); diff --git a/apps/openmw/mwphysics/movementsolver.hpp b/apps/openmw/mwphysics/movementsolver.hpp index 1bbe76cbec..15051f6f8d 100644 --- a/apps/openmw/mwphysics/movementsolver.hpp +++ b/apps/openmw/mwphysics/movementsolver.hpp @@ -17,19 +17,19 @@ namespace MWWorld namespace MWPhysics { /// Vector projection - static inline osg::Vec3f project(const osg::Vec3f& u, const osg::Vec3f &v) + static inline osg::Vec3f project(const osg::Vec3f& u, const osg::Vec3f& v) { return v * (u * v); } /// Vector rejection - static inline osg::Vec3f reject(const osg::Vec3f& direction, const osg::Vec3f &planeNormal) + static inline osg::Vec3f reject(const osg::Vec3f& direction, const osg::Vec3f& planeNormal) { return direction - project(direction, planeNormal); } template - static bool isWalkableSlope(const Vec3 &normal) + static bool isWalkableSlope(const Vec3& normal) { static const float sMaxSlopeCos = std::cos(osg::DegreesToRadians(Constants::sMaxSlope)); return (normal.z() > sMaxSlopeCos); @@ -43,8 +43,10 @@ namespace MWPhysics class MovementSolver { public: - static osg::Vec3f traceDown(const MWWorld::Ptr &ptr, const osg::Vec3f& position, Actor* actor, btCollisionWorld* collisionWorld, float maxHeight); - static void move(ActorFrameData& actor, float time, const btCollisionWorld* collisionWorld, const WorldFrameData& worldData); + static osg::Vec3f traceDown(const MWWorld::Ptr& ptr, const osg::Vec3f& position, Actor* actor, + btCollisionWorld* collisionWorld, float maxHeight); + static void move( + ActorFrameData& actor, float time, const btCollisionWorld* collisionWorld, const WorldFrameData& worldData); static void move(ProjectileFrameData& projectile, float time, const btCollisionWorld* collisionWorld); static void unstuck(ActorFrameData& actor, const btCollisionWorld* collisionWorld); }; diff --git a/apps/openmw/mwphysics/mtphysics.cpp b/apps/openmw/mwphysics/mtphysics.cpp index 46c2574706..e340f25c66 100644 --- a/apps/openmw/mwphysics/mtphysics.cpp +++ b/apps/openmw/mwphysics/mtphysics.cpp @@ -1,9 +1,9 @@ +#include #include -#include +#include #include #include -#include -#include +#include #include #include @@ -11,13 +11,13 @@ #include #include "components/debug/debuglog.hpp" -#include #include "components/misc/convert.hpp" #include "components/settings/settings.hpp" +#include #include "../mwmechanics/actorutil.hpp" -#include "../mwmechanics/movement.hpp" #include "../mwmechanics/creaturestats.hpp" +#include "../mwmechanics/movement.hpp" #include "../mwrender/bulletdebugdraw.hpp" @@ -45,18 +45,19 @@ namespace } /// @brief A scoped lock that is either exclusive or inexistent depending on configuration - template + template class MaybeExclusiveLock { - public: - /// @param mutex a mutex - /// @param threadCount decide wether the excluse lock will be taken - explicit MaybeExclusiveLock(Mutex& mutex, unsigned threadCount) - : mImpl(makeExclusiveLock(mutex, threadCount)) - {} + public: + /// @param mutex a mutex + /// @param threadCount decide wether the excluse lock will be taken + explicit MaybeExclusiveLock(Mutex& mutex, unsigned threadCount) + : mImpl(makeExclusiveLock(mutex, threadCount)) + { + } - private: - std::optional> mImpl; + private: + std::optional> mImpl; }; template @@ -68,42 +69,46 @@ namespace } /// @brief A scoped lock that is either shared or inexistent depending on configuration - template + template class MaybeSharedLock { - public: - /// @param mutex a shared mutex - /// @param threadCount decide wether the shared lock will be taken - explicit MaybeSharedLock(Mutex& mutex, unsigned threadCount) - : mImpl(makeSharedLock(mutex, threadCount)) - {} + public: + /// @param mutex a shared mutex + /// @param threadCount decide wether the shared lock will be taken + explicit MaybeSharedLock(Mutex& mutex, unsigned threadCount) + : mImpl(makeSharedLock(mutex, threadCount)) + { + } - private: - std::optional> mImpl; + private: + std::optional> mImpl; }; template - std::variant, std::shared_lock> makeLock(Mutex& mutex, unsigned threadCount) + std::variant, std::shared_lock> makeLock( + Mutex& mutex, unsigned threadCount) { if (threadCount > 1) return std::shared_lock(mutex); if (threadCount == 1) return std::unique_lock(mutex); - return std::monostate {}; + return std::monostate{}; } /// @brief A scoped lock that is either shared, exclusive or inexistent depending on configuration - template + template class MaybeLock { - public: - /// @param mutex a shared mutex - /// @param threadCount decide wether the lock will be shared, exclusive or inexistent - explicit MaybeLock(Mutex& mutex, unsigned threadCount) - : mImpl(makeLock(mutex, threadCount)) {} + public: + /// @param mutex a shared mutex + /// @param threadCount decide wether the lock will be shared, exclusive or inexistent + explicit MaybeLock(Mutex& mutex, unsigned threadCount) + : mImpl(makeLock(mutex, threadCount)) + { + } - private: - std::variant, std::shared_lock> mImpl; + private: + std::variant, std::shared_lock> mImpl; }; bool isUnderWater(const MWPhysics::ActorFrameData& actorData) @@ -117,14 +122,10 @@ namespace return ptr.getPosition() * interpolationFactor + ptr.getPreviousPosition() * (1.f - interpolationFactor); } - using LockedActorSimulation = std::pair< - std::shared_ptr, - std::reference_wrapper - >; - using LockedProjectileSimulation = std::pair< - std::shared_ptr, - std::reference_wrapper - >; + using LockedActorSimulation + = std::pair, std::reference_wrapper>; + using LockedProjectileSimulation + = std::pair, std::reference_wrapper>; namespace Visitors { @@ -162,7 +163,8 @@ namespace auto& frameData = frameDataRef.get(); actor->applyOffsetChange(); frameData.mPosition = actor->getPosition(); - if (frameData.mWaterCollision && frameData.mPosition.z() < frameData.mWaterlevel && actor->canMoveToWaterSurface(frameData.mWaterlevel, mCollisionWorld)) + if (frameData.mWaterCollision && frameData.mPosition.z() < frameData.mWaterlevel + && actor->canMoveToWaterSurface(frameData.mWaterlevel, mCollisionWorld)) { const auto offset = osg::Vec3f(0, 0, frameData.mWaterlevel - frameData.mPosition.z()); MWBase::Environment::get().getWorld()->moveObjectBy(actor->getPtr(), offset); @@ -176,9 +178,7 @@ namespace frameData.mStuckFrames = actor->getStuckFrames(); frameData.mLastStuckPosition = actor->getLastStuckPosition(); } - void operator()(MWPhysics::ProjectileSimulation& /*sim*/) const - { - } + void operator()(MWPhysics::ProjectileSimulation& /*sim*/) const {} }; struct PreStep @@ -188,9 +188,7 @@ namespace { MWPhysics::MovementSolver::unstuck(sim.second, mCollisionWorld); } - void operator()(const LockedProjectileSimulation& /*sim*/) const - { - } + void operator()(const LockedProjectileSimulation& /*sim*/) const {} }; struct UpdatePosition @@ -263,11 +261,13 @@ namespace if (mAdvanceSimulation) { MWWorld::Ptr standingOn; - auto* ptrHolder = static_cast(scheduler->getUserPointer(frameData.mStandingOn)); + auto* ptrHolder + = static_cast(scheduler->getUserPointer(frameData.mStandingOn)); if (ptrHolder) standingOn = ptrHolder->getPtr(); actor->setStandingOnPtr(standingOn); - // the "on ground" state of an actor might have been updated by a traceDown, don't overwrite the change + // the "on ground" state of an actor might have been updated by a traceDown, don't overwrite the + // change if (actor->getOnGround() == frameData.mWasOnGround) actor->setOnGround(frameData.mIsOnGround); actor->setOnSlope(frameData.mIsOnSlope); @@ -288,7 +288,8 @@ namespace namespace Config { - /// @return either the number of thread as configured by the user, or 1 if Bullet doesn't support multithreading and user requested more than 1 background threads + /// @return either the number of thread as configured by the user, or 1 if Bullet doesn't support multithreading + /// and user requested more than 1 background threads unsigned computeNumThreads() { int wantedThread = Settings::Manager::getInt("async num threads", "Physics"); @@ -298,7 +299,8 @@ namespace auto threadSafeBullet = (maxSupportedThreads > 1); if (!threadSafeBullet && wantedThread > 1) { - Log(Debug::Warning) << "Bullet was not compiled with multithreading support, 1 async thread will be used"; + Log(Debug::Warning) + << "Bullet was not compiled with multithreading support, 1 async thread will be used"; return 1; } return static_cast(std::max(0, wantedThread)); @@ -308,36 +310,37 @@ namespace namespace MWPhysics { - PhysicsTaskScheduler::PhysicsTaskScheduler(float physicsDt, btCollisionWorld *collisionWorld, MWRender::DebugDrawer* debugDrawer) - : mDefaultPhysicsDt(physicsDt) - , mPhysicsDt(physicsDt) - , mTimeAccum(0.f) - , mCollisionWorld(collisionWorld) - , mDebugDrawer(debugDrawer) - , mNumThreads(Config::computeNumThreads()) - , mNumJobs(0) - , mRemainingSteps(0) - , mLOSCacheExpiry(Settings::Manager::getInt("lineofsight keep inactive cache", "Physics")) - , mFrameCounter(0) - , mAdvanceSimulation(false) - , mQuit(false) - , mNextJob(0) - , mNextLOS(0) - , mFrameNumber(0) - , mTimer(osg::Timer::instance()) - , mPrevStepCount(1) - , mBudget(physicsDt) - , mAsyncBudget(0.0f) - , mBudgetCursor(0) - , mAsyncStartTime(0) - , mTimeBegin(0) - , mTimeEnd(0) - , mFrameStart(0) + PhysicsTaskScheduler::PhysicsTaskScheduler( + float physicsDt, btCollisionWorld* collisionWorld, MWRender::DebugDrawer* debugDrawer) + : mDefaultPhysicsDt(physicsDt) + , mPhysicsDt(physicsDt) + , mTimeAccum(0.f) + , mCollisionWorld(collisionWorld) + , mDebugDrawer(debugDrawer) + , mNumThreads(Config::computeNumThreads()) + , mNumJobs(0) + , mRemainingSteps(0) + , mLOSCacheExpiry(Settings::Manager::getInt("lineofsight keep inactive cache", "Physics")) + , mFrameCounter(0) + , mAdvanceSimulation(false) + , mQuit(false) + , mNextJob(0) + , mNextLOS(0) + , mFrameNumber(0) + , mTimer(osg::Timer::instance()) + , mPrevStepCount(1) + , mBudget(physicsDt) + , mAsyncBudget(0.0f) + , mBudgetCursor(0) + , mAsyncStartTime(0) + , mTimeBegin(0) + , mTimeEnd(0) + , mFrameStart(0) { if (mNumThreads >= 1) { for (unsigned i = 0; i < mNumThreads; ++i) - mThreads.emplace_back([&] { worker(); } ); + mThreads.emplace_back([&] { worker(); }); } else { @@ -372,11 +375,11 @@ namespace MWPhysics // adjust maximum step count based on whether we're likely physics bottlenecked or not // if maxAllowedSteps ends up higher than numSteps, we will not invoke delta time - // if it ends up lower than numSteps, but greater than 1, we will run a number of true delta time physics steps that we expect to be within budget - // if it ends up lower than numSteps and also 1, we will run a single delta time physics step - // if we did not do this, and had a fixed step count limit, - // we would have an unnecessarily low render framerate if we were only physics bottlenecked, - // and we would be unnecessarily invoking true delta time if we were only render bottlenecked + // if it ends up lower than numSteps, but greater than 1, we will run a number of true delta time physics steps + // that we expect to be within budget if it ends up lower than numSteps and also 1, we will run a single delta + // time physics step if we did not do this, and had a fixed step count limit, we would have an unnecessarily low + // render framerate if we were only physics bottlenecked, and we would be unnecessarily invoking true delta time + // if we were only render bottlenecked // get physics timing stats float budgetMeasurement = std::max(mBudget.get(), mAsyncBudget.get()); @@ -389,7 +392,7 @@ namespace MWPhysics maxAllowedSteps = 1; // physics is fairly cheap; limit based on expense if (budgetMeasurement < 0.5) - maxAllowedSteps = std::ceil(1.0/budgetMeasurement); + maxAllowedSteps = std::ceil(1.0 / budgetMeasurement); // limit to a reasonable amount maxAllowedSteps = std::min(10, maxAllowedSteps); @@ -401,7 +404,7 @@ namespace MWPhysics // ensure that we do not simulate a frame ahead when doing delta time; this reduces stutter and latency // this causes interpolation to 100% use the most recent physics result when true delta time is happening // and we deliberately simulate up to exactly the timestamp that we want to render - actualDelta = timeAccum/float(numSteps+1); + actualDelta = timeAccum / float(numSteps + 1); // actually: if this results in a per-step delta less than the target physics steptime, clamp it // this might reintroduce some stutter, but only comes into play in obscure cases // (because numSteps is originally based on mDefaultPhysicsDt, this won't cause us to overrun) @@ -411,7 +414,8 @@ namespace MWPhysics return std::make_tuple(numSteps, actualDelta); } - void PhysicsTaskScheduler::applyQueuedMovements(float& timeAccum, std::vector& simulations, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats) + void PhysicsTaskScheduler::applyQueuedMovements(float& timeAccum, std::vector& simulations, + osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats) { assert(mSimulations != &simulations); @@ -429,16 +433,16 @@ namespace MWPhysics { syncWithMainThread(); - if(mAdvanceSimulation) + if (mAdvanceSimulation) mAsyncBudget.update(mTimer->delta_s(mAsyncStartTime, mTimeEnd), mPrevStepCount, mBudgetCursor); updateStats(frameStart, frameNumber, stats); } auto [numSteps, newDelta] = calculateStepConfig(timeAccum); - timeAccum -= numSteps*newDelta; + timeAccum -= numSteps * newDelta; // init - const Visitors::InitPosition vis{mCollisionWorld}; + const Visitors::InitPosition vis{ mCollisionWorld }; for (auto& sim : simulations) { std::visit(vis, sim); @@ -464,7 +468,7 @@ namespace MWPhysics { doSimulation(); syncWithMainThread(); - if(mAdvanceSimulation) + if (mAdvanceSimulation) mBudget.update(mTimer->delta_s(timeStart, mTimer->tick()), numSteps, mBudgetCursor); return; } @@ -493,19 +497,22 @@ namespace MWPhysics } } - void PhysicsTaskScheduler::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const + void PhysicsTaskScheduler::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, + btCollisionWorld::RayResultCallback& resultCallback) const { MaybeLock lock(mCollisionWorldMutex, mNumThreads); mCollisionWorld->rayTest(rayFromWorld, rayToWorld, resultCallback); } - void PhysicsTaskScheduler::convexSweepTest(const btConvexShape* castShape, const btTransform& from, const btTransform& to, btCollisionWorld::ConvexResultCallback& resultCallback) const + void PhysicsTaskScheduler::convexSweepTest(const btConvexShape* castShape, const btTransform& from, + const btTransform& to, btCollisionWorld::ConvexResultCallback& resultCallback) const { MaybeLock lock(mCollisionWorldMutex, mNumThreads); mCollisionWorld->convexSweepTest(castShape, from, to, resultCallback); } - void PhysicsTaskScheduler::contactTest(btCollisionObject* colObj, btCollisionWorld::ContactResultCallback& resultCallback) + void PhysicsTaskScheduler::contactTest( + btCollisionObject* colObj, btCollisionWorld::ContactResultCallback& resultCallback) { MaybeSharedLock lock(mCollisionWorldMutex, mNumThreads); ContactTestWrapper::contactTest(mCollisionWorld, colObj, resultCallback); @@ -521,14 +528,16 @@ namespace MWPhysics btCollisionWorld::ClosestRayResultCallback cb(from.getOrigin(), rayTo.getOrigin()); - mCollisionWorld->rayTestSingle(from, rayTo, target, target->getCollisionShape(), target->getWorldTransform(), cb); + mCollisionWorld->rayTestSingle( + from, rayTo, target, target->getCollisionShape(), target->getWorldTransform(), cb); if (!cb.hasHit()) // didn't hit the target. this could happen if point is already inside the collision box return std::nullopt; - return {cb.m_hitPointWorld}; + return { cb.m_hitPointWorld }; } - void PhysicsTaskScheduler::aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback) + void PhysicsTaskScheduler::aabbTest( + const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback) { MaybeSharedLock lock(mCollisionWorldMutex, mNumThreads); mCollisionWorld->getBroadphase()->aabbTest(aabbMin, aabbMax, callback); @@ -546,7 +555,8 @@ namespace MWPhysics collisionObject->getBroadphaseHandle()->m_collisionFilterMask = collisionFilterMask; } - void PhysicsTaskScheduler::addCollisionObject(btCollisionObject* collisionObject, int collisionFilterGroup, int collisionFilterMask) + void PhysicsTaskScheduler::addCollisionObject( + btCollisionObject* collisionObject, int collisionFilterGroup, int collisionFilterMask) { mCollisionObjects.insert(collisionObject); MaybeExclusiveLock lock(mCollisionWorldMutex, mNumThreads); @@ -573,7 +583,8 @@ namespace MWPhysics } } - bool PhysicsTaskScheduler::getLineOfSight(const std::shared_ptr& actor1, const std::shared_ptr& actor2) + bool PhysicsTaskScheduler::getLineOfSight( + const std::shared_ptr& actor1, const std::shared_ptr& actor2) { MaybeExclusiveLock lock(mLOSCacheMutex, mNumThreads); @@ -605,19 +616,16 @@ namespace MWPhysics else req.mResult = hasLineOfSight(actorPtr1.get(), actorPtr2.get()); } - } void PhysicsTaskScheduler::updateAabbs() { MaybeExclusiveLock lock(mUpdateAabbMutex, mNumThreads); - std::for_each(mUpdateAabb.begin(), mUpdateAabb.end(), - [this](const std::weak_ptr& ptr) - { - auto p = ptr.lock(); - if (p != nullptr) - updatePtrAabb(p); - }); + std::for_each(mUpdateAabb.begin(), mUpdateAabb.end(), [this](const std::weak_ptr& ptr) { + auto p = ptr.lock(); + if (p != nullptr) + updatePtrAabb(p); + }); mUpdateAabb.clear(); } @@ -659,20 +667,23 @@ namespace MWPhysics void PhysicsTaskScheduler::updateActorsPositions() { - const Visitors::UpdatePosition impl{mCollisionWorld}; - const Visitors::WithLockedPtr vis{impl, mCollisionWorldMutex, mNumThreads}; + const Visitors::UpdatePosition impl{ mCollisionWorld }; + const Visitors::WithLockedPtr vis{ impl, mCollisionWorldMutex, + mNumThreads }; for (Simulation& sim : *mSimulations) std::visit(vis, sim); } bool PhysicsTaskScheduler::hasLineOfSight(const Actor* actor1, const Actor* actor2) { - btVector3 pos1 = Misc::Convert::toBullet(actor1->getCollisionObjectPosition() + osg::Vec3f(0,0,actor1->getHalfExtents().z() * 0.9)); // eye level - btVector3 pos2 = Misc::Convert::toBullet(actor2->getCollisionObjectPosition() + osg::Vec3f(0,0,actor2->getHalfExtents().z() * 0.9)); + btVector3 pos1 = Misc::Convert::toBullet( + actor1->getCollisionObjectPosition() + osg::Vec3f(0, 0, actor1->getHalfExtents().z() * 0.9)); // eye level + btVector3 pos2 = Misc::Convert::toBullet( + actor2->getCollisionObjectPosition() + osg::Vec3f(0, 0, actor2->getHalfExtents().z() * 0.9)); btCollisionWorld::ClosestRayResultCallback resultCallback(pos1, pos2); resultCallback.m_collisionFilterGroup = CollisionType_AnyPhysical; - resultCallback.m_collisionFilterMask = CollisionType_World|CollisionType_HeightMap|CollisionType_Door; + resultCallback.m_collisionFilterMask = CollisionType_World | CollisionType_HeightMap | CollisionType_Door; MaybeLock lockColWorld(mCollisionWorldMutex, mNumThreads); mCollisionWorld->rayTest(pos1, pos2, resultCallback); @@ -686,8 +697,8 @@ namespace MWPhysics { mPreStepBarrier->wait([this] { afterPreStep(); }); int job = 0; - const Visitors::Move impl{mPhysicsDt, mCollisionWorld, *mWorldFrameData}; - const Visitors::WithLockedPtr vis{impl, mCollisionWorldMutex, mNumThreads}; + const Visitors::Move impl{ mPhysicsDt, mCollisionWorld, *mWorldFrameData }; + const Visitors::WithLockedPtr vis{ impl, mCollisionWorldMutex, mNumThreads }; while ((job = mNextJob.fetch_add(1, std::memory_order_relaxed)) < mNumJobs) std::visit(vis, (*mSimulations)[job]); @@ -744,8 +755,9 @@ namespace MWPhysics updateAabbs(); if (!mRemainingSteps) return; - const Visitors::PreStep impl{mCollisionWorld}; - const Visitors::WithLockedPtr vis{impl, mCollisionWorldMutex, mNumThreads}; + const Visitors::PreStep impl{ mCollisionWorld }; + const Visitors::WithLockedPtr vis{ impl, mCollisionWorldMutex, + mNumThreads }; for (auto& sim : *mSimulations) std::visit(vis, sim); } @@ -765,9 +777,8 @@ namespace MWPhysics { MaybeExclusiveLock lock(mLOSCacheMutex, mNumThreads); mLOSCache.erase( - std::remove_if(mLOSCache.begin(), mLOSCache.end(), - [](const LOSRequest& req) { return req.mStale; }), - mLOSCache.end()); + std::remove_if(mLOSCache.begin(), mLOSCache.end(), [](const LOSRequest& req) { return req.mStale; }), + mLOSCache.end()); } mTimeEnd = mTimer->tick(); @@ -780,7 +791,7 @@ namespace MWPhysics { if (mSimulations == nullptr) return; - const Visitors::Sync vis{mAdvanceSimulation, mTimeAccum, mPhysicsDt, this}; + const Visitors::Sync vis{ mAdvanceSimulation, mTimeAccum, mPhysicsDt, this }; for (auto& sim : *mSimulations) std::visit(vis, sim); mSimulations->clear(); diff --git a/apps/openmw/mwphysics/mtphysics.hpp b/apps/openmw/mwphysics/mtphysics.hpp index 1e730a5801..20bdffba13 100644 --- a/apps/openmw/mwphysics/mtphysics.hpp +++ b/apps/openmw/mwphysics/mtphysics.hpp @@ -13,9 +13,9 @@ #include +#include "components/misc/budgetmeasurement.hpp" #include "physicssystem.hpp" #include "ptrholder.hpp" -#include "components/misc/budgetmeasurement.hpp" namespace Misc { @@ -31,99 +31,103 @@ namespace MWPhysics { class PhysicsTaskScheduler { - public: - PhysicsTaskScheduler(float physicsDt, btCollisionWorld* collisionWorld, MWRender::DebugDrawer* debugDrawer); - ~PhysicsTaskScheduler(); - - /// @brief move actors taking into account desired movements and collisions - /// @param numSteps how much simulation step to run - /// @param timeAccum accumulated time from previous run to interpolate movements - /// @param actorsData per actor data needed to compute new positions - /// @return new position of each actor - void applyQueuedMovements(float& timeAccum, std::vector& simulations, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats); - - void resetSimulation(const ActorMap& actors); - - // Thread safe wrappers - void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const; - void convexSweepTest(const btConvexShape* castShape, const btTransform& from, const btTransform& to, btCollisionWorld::ConvexResultCallback& resultCallback) const; - void contactTest(btCollisionObject* colObj, btCollisionWorld::ContactResultCallback& resultCallback); - std::optional getHitPoint(const btTransform& from, btCollisionObject* target); - void aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback); - void getAabb(const btCollisionObject* obj, btVector3& min, btVector3& max); - void setCollisionFilterMask(btCollisionObject* collisionObject, int collisionFilterMask); - void addCollisionObject(btCollisionObject* collisionObject, int collisionFilterGroup, int collisionFilterMask); - void removeCollisionObject(btCollisionObject* collisionObject); - void updateSingleAabb(const std::shared_ptr& ptr, bool immediate=false); - bool getLineOfSight(const std::shared_ptr& actor1, const std::shared_ptr& actor2); - void debugDraw(); - void* getUserPointer(const btCollisionObject* object) const; - void releaseSharedStates(); // destroy all objects whose destructor can't be safely called from ~PhysicsTaskScheduler() - - private: - void doSimulation(); - void worker(); - void updateActorsPositions(); - bool hasLineOfSight(const Actor* actor1, const Actor* actor2); - void refreshLOSCache(); - void updateAabbs(); - void updatePtrAabb(const std::shared_ptr& ptr); - void updateStats(osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats); - std::tuple calculateStepConfig(float timeAccum) const; - void afterPreStep(); - void afterPostStep(); - void afterPostSim(); - void syncWithMainThread(); - void waitForWorkers(); - - std::unique_ptr mWorldFrameData; - std::vector* mSimulations = nullptr; - std::unordered_set mCollisionObjects; - float mDefaultPhysicsDt; - float mPhysicsDt; - float mTimeAccum; - btCollisionWorld* mCollisionWorld; - MWRender::DebugDrawer* mDebugDrawer; - std::vector mLOSCache; - std::set, std::owner_less>> mUpdateAabb; - - // TODO: use std::experimental::flex_barrier or std::barrier once it becomes a thing - std::unique_ptr mPreStepBarrier; - std::unique_ptr mPostStepBarrier; - std::unique_ptr mPostSimBarrier; - - unsigned mNumThreads; - int mNumJobs; - int mRemainingSteps; - int mLOSCacheExpiry; - std::size_t mFrameCounter; - bool mAdvanceSimulation; - bool mQuit; - std::atomic mNextJob; - std::atomic mNextLOS; - std::vector mThreads; - - std::size_t mWorkersFrameCounter = 0; - std::condition_variable mWorkersDone; - std::mutex mWorkersDoneMutex; - - mutable std::shared_mutex mSimulationMutex; - mutable std::shared_mutex mCollisionWorldMutex; - mutable std::shared_mutex mLOSCacheMutex; - mutable std::mutex mUpdateAabbMutex; - std::condition_variable_any mHasJob; - - unsigned int mFrameNumber; - const osg::Timer* mTimer; - - int mPrevStepCount; - Misc::BudgetMeasurement mBudget; - Misc::BudgetMeasurement mAsyncBudget; - unsigned int mBudgetCursor; - osg::Timer_t mAsyncStartTime; - osg::Timer_t mTimeBegin; - osg::Timer_t mTimeEnd; - osg::Timer_t mFrameStart; + public: + PhysicsTaskScheduler(float physicsDt, btCollisionWorld* collisionWorld, MWRender::DebugDrawer* debugDrawer); + ~PhysicsTaskScheduler(); + + /// @brief move actors taking into account desired movements and collisions + /// @param numSteps how much simulation step to run + /// @param timeAccum accumulated time from previous run to interpolate movements + /// @param actorsData per actor data needed to compute new positions + /// @return new position of each actor + void applyQueuedMovements(float& timeAccum, std::vector& simulations, osg::Timer_t frameStart, + unsigned int frameNumber, osg::Stats& stats); + + void resetSimulation(const ActorMap& actors); + + // Thread safe wrappers + void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, + btCollisionWorld::RayResultCallback& resultCallback) const; + void convexSweepTest(const btConvexShape* castShape, const btTransform& from, const btTransform& to, + btCollisionWorld::ConvexResultCallback& resultCallback) const; + void contactTest(btCollisionObject* colObj, btCollisionWorld::ContactResultCallback& resultCallback); + std::optional getHitPoint(const btTransform& from, btCollisionObject* target); + void aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback); + void getAabb(const btCollisionObject* obj, btVector3& min, btVector3& max); + void setCollisionFilterMask(btCollisionObject* collisionObject, int collisionFilterMask); + void addCollisionObject(btCollisionObject* collisionObject, int collisionFilterGroup, int collisionFilterMask); + void removeCollisionObject(btCollisionObject* collisionObject); + void updateSingleAabb(const std::shared_ptr& ptr, bool immediate = false); + bool getLineOfSight(const std::shared_ptr& actor1, const std::shared_ptr& actor2); + void debugDraw(); + void* getUserPointer(const btCollisionObject* object) const; + void releaseSharedStates(); // destroy all objects whose destructor can't be safely called from + // ~PhysicsTaskScheduler() + + private: + void doSimulation(); + void worker(); + void updateActorsPositions(); + bool hasLineOfSight(const Actor* actor1, const Actor* actor2); + void refreshLOSCache(); + void updateAabbs(); + void updatePtrAabb(const std::shared_ptr& ptr); + void updateStats(osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats); + std::tuple calculateStepConfig(float timeAccum) const; + void afterPreStep(); + void afterPostStep(); + void afterPostSim(); + void syncWithMainThread(); + void waitForWorkers(); + + std::unique_ptr mWorldFrameData; + std::vector* mSimulations = nullptr; + std::unordered_set mCollisionObjects; + float mDefaultPhysicsDt; + float mPhysicsDt; + float mTimeAccum; + btCollisionWorld* mCollisionWorld; + MWRender::DebugDrawer* mDebugDrawer; + std::vector mLOSCache; + std::set, std::owner_less>> mUpdateAabb; + + // TODO: use std::experimental::flex_barrier or std::barrier once it becomes a thing + std::unique_ptr mPreStepBarrier; + std::unique_ptr mPostStepBarrier; + std::unique_ptr mPostSimBarrier; + + unsigned mNumThreads; + int mNumJobs; + int mRemainingSteps; + int mLOSCacheExpiry; + std::size_t mFrameCounter; + bool mAdvanceSimulation; + bool mQuit; + std::atomic mNextJob; + std::atomic mNextLOS; + std::vector mThreads; + + std::size_t mWorkersFrameCounter = 0; + std::condition_variable mWorkersDone; + std::mutex mWorkersDoneMutex; + + mutable std::shared_mutex mSimulationMutex; + mutable std::shared_mutex mCollisionWorldMutex; + mutable std::shared_mutex mLOSCacheMutex; + mutable std::mutex mUpdateAabbMutex; + std::condition_variable_any mHasJob; + + unsigned int mFrameNumber; + const osg::Timer* mTimer; + + int mPrevStepCount; + Misc::BudgetMeasurement mBudget; + Misc::BudgetMeasurement mAsyncBudget; + unsigned int mBudgetCursor; + osg::Timer_t mAsyncStartTime; + osg::Timer_t mTimeBegin; + osg::Timer_t mTimeEnd; + osg::Timer_t mFrameStart; }; } diff --git a/apps/openmw/mwphysics/object.cpp b/apps/openmw/mwphysics/object.cpp index b646925ab1..6e0e2cdc7f 100644 --- a/apps/openmw/mwphysics/object.cpp +++ b/apps/openmw/mwphysics/object.cpp @@ -1,12 +1,12 @@ #include "object.hpp" #include "mtphysics.hpp" +#include #include +#include #include #include #include -#include -#include #include @@ -14,7 +14,8 @@ namespace MWPhysics { - Object::Object(const MWWorld::Ptr& ptr, osg::ref_ptr shapeInstance, osg::Quat rotation, int collisionType, PhysicsTaskScheduler* scheduler) + Object::Object(const MWWorld::Ptr& ptr, osg::ref_ptr shapeInstance, + osg::Quat rotation, int collisionType, PhysicsTaskScheduler* scheduler) : PtrHolder(ptr, osg::Vec3f()) , mShapeInstance(std::move(shapeInstance)) , mSolid(true) @@ -27,7 +28,8 @@ namespace MWPhysics Misc::Convert::toBullet(mPosition), Misc::Convert::toBullet(rotation)); mCollisionObject->setUserPointer(this); mShapeInstance->setLocalScaling(mScale); - mTaskScheduler->addCollisionObject(mCollisionObject.get(), collisionType, CollisionType_Actor|CollisionType_HeightMap|CollisionType_Projectile); + mTaskScheduler->addCollisionObject(mCollisionObject.get(), collisionType, + CollisionType_Actor | CollisionType_HeightMap | CollisionType_Projectile); } Object::~Object() @@ -43,7 +45,7 @@ namespace MWPhysics void Object::setScale(float scale) { std::unique_lock lock(mPositionMutex); - mScale = { scale,scale,scale }; + mScale = { scale, scale, scale }; mScaleUpdatePending = true; } @@ -108,7 +110,7 @@ namespace MWPhysics if (mShapeInstance->mAnimatedShapes.empty()) return false; - assert (mShapeInstance->mCollisionShape->isCompound()); + assert(mShapeInstance->mCollisionShape->isCompound()); btCompoundShape* compound = static_cast(mShapeInstance->mCollisionShape.get()); bool result = false; @@ -121,7 +123,8 @@ namespace MWPhysics mPtr.getRefData().getBaseNode()->accept(visitor); if (!visitor.mFound) { - Log(Debug::Warning) << "Warning: animateCollisionShapes can't find node " << recIndex << " for " << mPtr.getCellRef().getRefId(); + Log(Debug::Warning) << "Warning: animateCollisionShapes can't find node " << recIndex << " for " + << mPtr.getCellRef().getRefId(); // Remove nonexistent nodes from animated shapes map and early out mShapeInstance->mAnimatedShapes.erase(recIndex); @@ -138,9 +141,9 @@ namespace MWPhysics btTransform transform; transform.setOrigin(Misc::Convert::toBullet(matrix.getTrans()) * compound->getLocalScaling()); - for (int i=0; i<3; ++i) - for (int j=0; j<3; ++j) - transform.getBasis()[i][j] = matrix(j,i); // NB column/row major difference + for (int i = 0; i < 3; ++i) + for (int j = 0; j < 3; ++j) + transform.getBasis()[i][j] = matrix(j, i); // NB column/row major difference // Note: we can not apply scaling here for now since we treat scaled shapes // as new shapes (btScaledBvhTriangleMeshShape) with 1.0 scale for now diff --git a/apps/openmw/mwphysics/object.hpp b/apps/openmw/mwphysics/object.hpp index 520a57a4e8..a143c08548 100644 --- a/apps/openmw/mwphysics/object.hpp +++ b/apps/openmw/mwphysics/object.hpp @@ -25,7 +25,8 @@ namespace MWPhysics class Object final : public PtrHolder { public: - Object(const MWWorld::Ptr& ptr, osg::ref_ptr shapeInstance, osg::Quat rotation, int collisionType, PhysicsTaskScheduler* scheduler); + Object(const MWWorld::Ptr& ptr, osg::ref_ptr shapeInstance, osg::Quat rotation, + int collisionType, PhysicsTaskScheduler* scheduler); ~Object() override; const Resource::BulletShapeInstance* getShapeInstance() const; diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index 6b8f680f08..360a79360d 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -1,68 +1,68 @@ #include "physicssystem.hpp" -#include #include +#include #include #include #include #include -#include -#include -#include +#include #include #include #include -#include +#include +#include +#include -#include #include +#include -#include -#include -#include #include #include -#include +#include #include -#include +#include #include // FindRecIndexVisitor -#include +#include +#include +#include +#include -#include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" -#include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/actorutil.hpp" +#include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/movement.hpp" -#include "../mwworld/esmstore.hpp" #include "../mwworld/cellstore.hpp" +#include "../mwworld/esmstore.hpp" #include "../mwworld/player.hpp" #include "../mwrender/bulletdebugdraw.hpp" #include "../mwworld/class.hpp" -#include "collisiontype.hpp" #include "actor.hpp" +#include "collisiontype.hpp" -#include "projectile.hpp" -#include "trace.h" -#include "object.hpp" -#include "heightfield.hpp" -#include "hasspherecollisioncallback.hpp" -#include "deepestnotmecontacttestresultcallback.hpp" #include "closestnotmerayresultcallback.hpp" #include "contacttestresultcallback.hpp" -#include "projectileconvexcallback.hpp" +#include "deepestnotmecontacttestresultcallback.hpp" +#include "hasspherecollisioncallback.hpp" +#include "heightfield.hpp" #include "movementsolver.hpp" #include "mtphysics.hpp" +#include "object.hpp" +#include "projectile.hpp" +#include "projectileconvexcallback.hpp" +#include "trace.h" namespace { - void handleJump(const MWWorld::Ptr &ptr) + void handleJump(const MWWorld::Ptr& ptr) { if (!ptr.getClass().isActor()) return; @@ -79,7 +79,8 @@ namespace // Decrease fatigue if (!isPlayer || !MWBase::Environment::get().getWorld()->getGodModeState()) { - const MWWorld::Store &gmst = MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& gmst + = MWBase::Environment::get().getWorld()->getStore().get(); const float fFatigueJumpBase = gmst.find("fFatigueJumpBase")->mValue.getFloat(); const float fFatigueJumpMult = gmst.find("fFatigueJumpMult")->mValue.getFloat(); const float normalizedEncumbrance = std::min(1.f, ptr.getClass().getNormalizedEncumbrance(ptr)); @@ -96,7 +97,8 @@ namespace namespace MWPhysics { PhysicsSystem::PhysicsSystem(Resource::ResourceSystem* resourceSystem, osg::ref_ptr parentNode) - : mShapeManager(std::make_unique(resourceSystem->getVFS(), resourceSystem->getSceneManager(), resourceSystem->getNifFileManager())) + : mShapeManager(std::make_unique( + resourceSystem->getVFS(), resourceSystem->getSceneManager(), resourceSystem->getNifFileManager())) , mResourceSystem(resourceSystem) , mDebugDrawEnabled(false) , mTimeAccum(0.0f) @@ -105,7 +107,8 @@ namespace MWPhysics , mWaterEnabled(false) , mParentNode(parentNode) , mPhysicsDt(1.f / 60.f) - , mActorCollisionShapeType(DetourNavigator::toCollisionShapeType(Settings::Manager::getInt("actor collision shape type", "Game"))) + , mActorCollisionShapeType( + DetourNavigator::toCollisionShapeType(Settings::Manager::getInt("actor collision shape type", "Game"))) { mResourceSystem->addResourceManager(mShapeManager.get()); @@ -113,10 +116,12 @@ namespace MWPhysics mDispatcher = std::make_unique(mCollisionConfiguration.get()); mBroadphase = std::make_unique(); - mCollisionWorld = std::make_unique(mDispatcher.get(), mBroadphase.get(), mCollisionConfiguration.get()); + mCollisionWorld + = std::make_unique(mDispatcher.get(), mBroadphase.get(), mCollisionConfiguration.get()); // Don't update AABBs of all objects every frame. Most objects in MW are static, so we don't need this. - // Should a "static" object ever be moved, we have to update its AABB manually using DynamicsWorld::updateSingleAabb. + // Should a "static" object ever be moved, we have to update its AABB manually using + // DynamicsWorld::updateSingleAabb. mCollisionWorld->setForceUpdateAllAabbs(false); // Check if a user decided to override a physics system FPS @@ -149,7 +154,7 @@ namespace MWPhysics mProjectiles.clear(); } - Resource::BulletShapeManager *PhysicsSystem::getShapeManager() + Resource::BulletShapeManager* PhysicsSystem::getShapeManager() { return mShapeManager.get(); } @@ -163,7 +168,7 @@ namespace MWPhysics return mDebugDrawEnabled; } - void PhysicsSystem::markAsNonSolid(const MWWorld::ConstPtr &ptr) + void PhysicsSystem::markAsNonSolid(const MWWorld::ConstPtr& ptr) { ObjectMap::iterator found = mObjects.find(ptr.mRef); if (found == mObjects.end()) @@ -172,7 +177,7 @@ namespace MWPhysics found->second->setSolid(false); } - bool PhysicsSystem::isOnSolidGround (const MWWorld::Ptr& actor) const + bool PhysicsSystem::isOnSolidGround(const MWWorld::Ptr& actor) const { const Actor* physactor = getActor(actor); if (!physactor || !physactor->getOnGround() || !physactor->getCollisionMode()) @@ -193,13 +198,12 @@ namespace MWPhysics } std::pair PhysicsSystem::getHitContact(const MWWorld::ConstPtr& actor, - const osg::Vec3f &origin, - const osg::Quat &orient, - float queryDistance, std::vector& targets) + const osg::Vec3f& origin, const osg::Quat& orient, float queryDistance, std::vector& targets) { // First of all, try to hit where you aim to int hitmask = CollisionType_World | CollisionType_Door | CollisionType_HeightMap | CollisionType_Actor; - RayCastingResult result = castRay(origin, origin + (orient * osg::Vec3f(0.0f, queryDistance, 0.0f)), actor, targets, hitmask, CollisionType_Actor); + RayCastingResult result = castRay(origin, origin + (orient * osg::Vec3f(0.0f, queryDistance, 0.0f)), actor, + targets, hitmask, CollisionType_Actor); if (result.mHit) { @@ -208,15 +212,16 @@ namespace MWPhysics } // Use cone shape as fallback - const MWWorld::Store &store = MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& store + = MWBase::Environment::get().getWorld()->getStore().get(); - btConeShape shape (osg::DegreesToRadians(store.find("fCombatAngleXY")->mValue.getFloat()/2.0f), queryDistance); - shape.setLocalScaling(btVector3(1, 1, osg::DegreesToRadians(store.find("fCombatAngleZ")->mValue.getFloat()/2.0f) / - shape.getRadius())); + btConeShape shape(osg::DegreesToRadians(store.find("fCombatAngleXY")->mValue.getFloat() / 2.0f), queryDistance); + shape.setLocalScaling(btVector3( + 1, 1, osg::DegreesToRadians(store.find("fCombatAngleZ")->mValue.getFloat() / 2.0f) / shape.getRadius())); // The shape origin is its center, so we have to move it forward by half the length. The // real origin will be provided to getFilteredContact to find the closest. - osg::Vec3f center = origin + (orient * osg::Vec3f(0.0f, queryDistance*0.5f, 0.0f)); + osg::Vec3f center = origin + (orient * osg::Vec3f(0.0f, queryDistance * 0.5f, 0.0f)); btCollisionObject object; object.setCollisionShape(&shape); @@ -239,9 +244,11 @@ namespace MWPhysics } } - DeepestNotMeContactTestResultCallback resultCallback(me, targetCollisionObjects, Misc::Convert::toBullet(origin)); + DeepestNotMeContactTestResultCallback resultCallback( + me, targetCollisionObjects, Misc::Convert::toBullet(origin)); resultCallback.m_collisionFilterGroup = CollisionType_Actor; - resultCallback.m_collisionFilterMask = CollisionType_World | CollisionType_Door | CollisionType_HeightMap | CollisionType_Actor; + resultCallback.m_collisionFilterMask + = CollisionType_World | CollisionType_Door | CollisionType_HeightMap | CollisionType_Actor; mTaskScheduler->contactTest(&object, resultCallback); if (resultCallback.mObject) @@ -256,7 +263,7 @@ namespace MWPhysics return std::make_pair(MWWorld::Ptr(), osg::Vec3f()); } - float PhysicsSystem::getHitDistance(const osg::Vec3f &point, const MWWorld::ConstPtr &target) const + float PhysicsSystem::getHitDistance(const osg::Vec3f& point, const MWWorld::ConstPtr& target) const { btCollisionObject* targetCollisionObj = nullptr; const Actor* actor = getActor(target); @@ -277,7 +284,8 @@ namespace MWPhysics return 0.f; } - RayCastingResult PhysicsSystem::castRay(const osg::Vec3f &from, const osg::Vec3f &to, const MWWorld::ConstPtr& ignore, const std::vector& targets, int mask, int group) const + RayCastingResult PhysicsSystem::castRay(const osg::Vec3f& from, const osg::Vec3f& to, + const MWWorld::ConstPtr& ignore, const std::vector& targets, int mask, int group) const { if (from == to) { @@ -332,17 +340,19 @@ namespace MWPhysics return result; } - RayCastingResult PhysicsSystem::castSphere(const osg::Vec3f &from, const osg::Vec3f &to, float radius, int mask, int group) const + RayCastingResult PhysicsSystem::castSphere( + const osg::Vec3f& from, const osg::Vec3f& to, float radius, int mask, int group) const { - btCollisionWorld::ClosestConvexResultCallback callback(Misc::Convert::toBullet(from), Misc::Convert::toBullet(to)); + btCollisionWorld::ClosestConvexResultCallback callback( + Misc::Convert::toBullet(from), Misc::Convert::toBullet(to)); callback.m_collisionFilterGroup = group; callback.m_collisionFilterMask = mask; btSphereShape shape(radius); const btQuaternion btrot = btQuaternion::getIdentity(); - btTransform from_ (btrot, Misc::Convert::toBullet(from)); - btTransform to_ (btrot, Misc::Convert::toBullet(to)); + btTransform from_(btrot, Misc::Convert::toBullet(from)); + btTransform to_(btrot, Misc::Convert::toBullet(to)); mTaskScheduler->convexSweepTest(&shape, from_, to_, callback); @@ -358,9 +368,10 @@ namespace MWPhysics return result; } - bool PhysicsSystem::getLineOfSight(const MWWorld::ConstPtr &actor1, const MWWorld::ConstPtr &actor2) const + bool PhysicsSystem::getLineOfSight(const MWWorld::ConstPtr& actor1, const MWWorld::ConstPtr& actor2) const { - if (actor1 == actor2) return true; + if (actor1 == actor2) + return true; const auto it1 = mActors.find(actor1.mRef); const auto it2 = mActors.find(actor2.mRef); @@ -370,19 +381,19 @@ namespace MWPhysics return mTaskScheduler->getLineOfSight(it1->second, it2->second); } - bool PhysicsSystem::isOnGround(const MWWorld::Ptr &actor) + bool PhysicsSystem::isOnGround(const MWWorld::Ptr& actor) { Actor* physactor = getActor(actor); return physactor && physactor->getOnGround() && physactor->getCollisionMode(); } - bool PhysicsSystem::canMoveToWaterSurface(const MWWorld::ConstPtr &actor, const float waterlevel) + bool PhysicsSystem::canMoveToWaterSurface(const MWWorld::ConstPtr& actor, const float waterlevel) { const auto* physactor = getActor(actor); return physactor && physactor->canMoveToWaterSurface(waterlevel, mCollisionWorld.get()); } - osg::Vec3f PhysicsSystem::getHalfExtents(const MWWorld::ConstPtr &actor) const + osg::Vec3f PhysicsSystem::getHalfExtents(const MWWorld::ConstPtr& actor) const { const Actor* physactor = getActor(actor); if (physactor) @@ -391,7 +402,7 @@ namespace MWPhysics return osg::Vec3f(); } - osg::Vec3f PhysicsSystem::getOriginalHalfExtents(const MWWorld::ConstPtr &actor) const + osg::Vec3f PhysicsSystem::getOriginalHalfExtents(const MWWorld::ConstPtr& actor) const { if (const Actor* physactor = getActor(actor)) return physactor->getOriginalHalfExtents(); @@ -399,7 +410,7 @@ namespace MWPhysics return osg::Vec3f(); } - osg::Vec3f PhysicsSystem::getRenderingHalfExtents(const MWWorld::ConstPtr &actor) const + osg::Vec3f PhysicsSystem::getRenderingHalfExtents(const MWWorld::ConstPtr& actor) const { const Actor* physactor = getActor(actor); if (physactor) @@ -408,16 +419,17 @@ namespace MWPhysics return osg::Vec3f(); } - osg::BoundingBox PhysicsSystem::getBoundingBox(const MWWorld::ConstPtr &object) const + osg::BoundingBox PhysicsSystem::getBoundingBox(const MWWorld::ConstPtr& object) const { - const Object * physobject = getObject(object); - if (!physobject) return osg::BoundingBox(); + const Object* physobject = getObject(object); + if (!physobject) + return osg::BoundingBox(); btVector3 min, max; mTaskScheduler->getAabb(physobject->getCollisionObject(), min, max); return osg::BoundingBox(Misc::Convert::toOsg(min), Misc::Convert::toOsg(max)); } - osg::Vec3f PhysicsSystem::getCollisionObjectPosition(const MWWorld::ConstPtr &actor) const + osg::Vec3f PhysicsSystem::getCollisionObjectPosition(const MWWorld::ConstPtr& actor) const { const Actor* physactor = getActor(actor); if (physactor) @@ -426,7 +438,8 @@ namespace MWPhysics return osg::Vec3f(); } - std::vector PhysicsSystem::getCollisionsPoints(const MWWorld::ConstPtr &ptr, int collisionGroup, int collisionMask) const + std::vector PhysicsSystem::getCollisionsPoints( + const MWWorld::ConstPtr& ptr, int collisionGroup, int collisionMask) const { btCollisionObject* me = nullptr; @@ -436,14 +449,15 @@ namespace MWPhysics else return {}; - ContactTestResultCallback resultCallback (me); + ContactTestResultCallback resultCallback(me); resultCallback.m_collisionFilterGroup = collisionGroup; resultCallback.m_collisionFilterMask = collisionMask; mTaskScheduler->contactTest(me, resultCallback); return resultCallback.mResult; } - std::vector PhysicsSystem::getCollisions(const MWWorld::ConstPtr &ptr, int collisionGroup, int collisionMask) const + std::vector PhysicsSystem::getCollisions( + const MWWorld::ConstPtr& ptr, int collisionGroup, int collisionMask) const { std::vector actors; for (auto& [actor, point, normal] : getCollisionsPoints(ptr, collisionGroup, collisionMask)) @@ -451,23 +465,25 @@ namespace MWPhysics return actors; } - osg::Vec3f PhysicsSystem::traceDown(const MWWorld::Ptr &ptr, const osg::Vec3f& position, float maxHeight) + osg::Vec3f PhysicsSystem::traceDown(const MWWorld::Ptr& ptr, const osg::Vec3f& position, float maxHeight) { ActorMap::iterator found = mActors.find(ptr.mRef); - if (found == mActors.end()) + if (found == mActors.end()) return ptr.getRefData().getPosition().asVec3(); return MovementSolver::traceDown(ptr, position, found->second.get(), mCollisionWorld.get(), maxHeight); } - void PhysicsSystem::addHeightField(const float* heights, int x, int y, int size, int verts, float minH, float maxH, const osg::Object* holdObject) + void PhysicsSystem::addHeightField( + const float* heights, int x, int y, int size, int verts, float minH, float maxH, const osg::Object* holdObject) { - mHeightFields[std::make_pair(x,y)] = std::make_unique(heights, x, y, size, verts, minH, maxH, holdObject, mTaskScheduler.get()); + mHeightFields[std::make_pair(x, y)] + = std::make_unique(heights, x, y, size, verts, minH, maxH, holdObject, mTaskScheduler.get()); } - void PhysicsSystem::removeHeightField (int x, int y) + void PhysicsSystem::removeHeightField(int x, int y) { - HeightFieldMap::iterator heightfield = mHeightFields.find(std::make_pair(x,y)); - if(heightfield != mHeightFields.end()) + HeightFieldMap::iterator heightfield = mHeightFields.find(std::make_pair(x, y)); + if (heightfield != mHeightFields.end()) mHeightFields.erase(heightfield); } @@ -479,7 +495,8 @@ namespace MWPhysics return heightField->second.get(); } - void PhysicsSystem::addObject (const MWWorld::Ptr& ptr, const std::string& mesh, osg::Quat rotation, int collisionType) + void PhysicsSystem::addObject( + const MWWorld::Ptr& ptr, const std::string& mesh, osg::Quat rotation, int collisionType) { if (ptr.mRef->mData.mPhysicsPostponed) return; @@ -509,7 +526,7 @@ namespace MWPhysics mAnimatedObjects.emplace(obj.get(), false); } - void PhysicsSystem::remove(const MWWorld::Ptr &ptr) + void PhysicsSystem::remove(const MWWorld::Ptr& ptr) { if (auto foundObject = mObjects.find(ptr.mRef); foundObject != mObjects.end()) { @@ -530,7 +547,7 @@ namespace MWPhysics mProjectiles.erase(foundProjectile); } - void PhysicsSystem::updatePtr(const MWWorld::Ptr &old, const MWWorld::Ptr &updated) + void PhysicsSystem::updatePtr(const MWWorld::Ptr& old, const MWWorld::Ptr& updated) { if (auto foundObject = mObjects.find(old.mRef); foundObject != mObjects.end()) foundObject->second->updatePtr(updated); @@ -548,10 +565,9 @@ namespace MWPhysics if (projectile->getCaster() == old) projectile->setCaster(updated); } - } - Actor *PhysicsSystem::getActor(const MWWorld::Ptr &ptr) + Actor* PhysicsSystem::getActor(const MWWorld::Ptr& ptr) { ActorMap::iterator found = mActors.find(ptr.mRef); if (found != mActors.end()) @@ -559,7 +575,7 @@ namespace MWPhysics return nullptr; } - const Actor *PhysicsSystem::getActor(const MWWorld::ConstPtr &ptr) const + const Actor* PhysicsSystem::getActor(const MWWorld::ConstPtr& ptr) const { ActorMap::const_iterator found = mActors.find(ptr.mRef); if (found != mActors.end()) @@ -567,7 +583,7 @@ namespace MWPhysics return nullptr; } - const Object* PhysicsSystem::getObject(const MWWorld::ConstPtr &ptr) const + const Object* PhysicsSystem::getObject(const MWWorld::ConstPtr& ptr) const { ObjectMap::const_iterator found = mObjects.find(ptr.mRef); if (found != mObjects.end()) @@ -583,7 +599,7 @@ namespace MWPhysics return nullptr; } - void PhysicsSystem::updateScale(const MWWorld::Ptr &ptr) + void PhysicsSystem::updateScale(const MWWorld::Ptr& ptr) { if (auto foundObject = mObjects.find(ptr.mRef); foundObject != mObjects.end()) { @@ -598,7 +614,7 @@ namespace MWPhysics } } - void PhysicsSystem::updateRotation(const MWWorld::Ptr &ptr, osg::Quat rotate) + void PhysicsSystem::updateRotation(const MWWorld::Ptr& ptr, osg::Quat rotate) { if (auto foundObject = mObjects.find(ptr.mRef); foundObject != mObjects.end()) { @@ -615,7 +631,7 @@ namespace MWPhysics } } - void PhysicsSystem::updatePosition(const MWWorld::Ptr &ptr) + void PhysicsSystem::updatePosition(const MWWorld::Ptr& ptr) { if (auto foundObject = mObjects.find(ptr.mRef); foundObject != mObjects.end()) { @@ -629,7 +645,7 @@ namespace MWPhysics } } - void PhysicsSystem::addActor (const MWWorld::Ptr& ptr, const std::string& mesh) + void PhysicsSystem::addActor(const MWWorld::Ptr& ptr, const std::string& mesh) { osg::ref_ptr shape = mShapeManager->getShape(mesh); @@ -655,7 +671,8 @@ namespace MWPhysics mActors.emplace(ptr.mRef, std::move(actor)); } - int PhysicsSystem::addProjectile (const MWWorld::Ptr& caster, const osg::Vec3f& position, const std::string& mesh, bool computeRadius) + int PhysicsSystem::addProjectile( + const MWWorld::Ptr& caster, const osg::Vec3f& position, const std::string& mesh, bool computeRadius) { osg::ref_ptr shapeInstance = mShapeManager->getInstance(mesh); assert(shapeInstance); @@ -693,7 +710,7 @@ namespace MWPhysics return false; } - void PhysicsSystem::queueObjectMovement(const MWWorld::Ptr &ptr, const osg::Vec3f &velocity) + void PhysicsSystem::queueObjectMovement(const MWWorld::Ptr& ptr, const osg::Vec3f& velocity) { ActorMap::iterator found = mActors.find(ptr.mRef); if (found != mActors.end()) @@ -713,7 +730,7 @@ namespace MWPhysics { assert(simulations.empty()); simulations.reserve(mActors.size() + mProjectiles.size()); - const MWBase::World *world = MWBase::Environment::get().getWorld(); + const MWBase::World* world = MWBase::Environment::get().getWorld(); for (const auto& [ref, physicActor] : mActors) { if (!physicActor->isActive()) @@ -723,8 +740,8 @@ namespace MWPhysics if (!ptr.getClass().isMobile(ptr)) continue; float waterlevel = -std::numeric_limits::max(); - const MWWorld::CellStore *cell = ptr.getCell(); - if(cell->getCell()->hasWater()) + const MWWorld::CellStore* cell = ptr.getCell(); + if (cell->getCell()->hasWater()) waterlevel = cell->getWaterLevel(); const auto& stats = ptr.getClass().getCreatureStats(ptr); @@ -733,18 +750,22 @@ namespace MWPhysics bool waterCollision = false; if (cell->getCell()->hasWater() && effects.get(ESM::MagicEffect::WaterWalking).getMagnitude()) { - if (physicActor->getCollisionMode() || !world->isUnderwater(ptr.getCell(), ptr.getRefData().getPosition().asVec3())) + if (physicActor->getCollisionMode() + || !world->isUnderwater(ptr.getCell(), ptr.getRefData().getPosition().asVec3())) waterCollision = true; } physicActor->setCanWaterWalk(waterCollision); // Slow fall reduces fall speed by a factor of (effect magnitude / 200) - const float slowFall = 1.f - std::clamp(effects.get(ESM::MagicEffect::SlowFall).getMagnitude() * 0.005f, 0.f, 1.f); + const float slowFall + = 1.f - std::clamp(effects.get(ESM::MagicEffect::SlowFall).getMagnitude() * 0.005f, 0.f, 1.f); const bool godmode = ptr == world->getPlayerConstPtr() && world->getGodModeState(); - const bool inert = stats.isDead() || (!godmode && stats.getMagicEffects().get(ESM::MagicEffect::Paralyze).getModifier() > 0); + const bool inert = stats.isDead() + || (!godmode && stats.getMagicEffects().get(ESM::MagicEffect::Paralyze).getModifier() > 0); - simulations.emplace_back(ActorSimulation{physicActor, ActorFrameData{*physicActor, inert, waterCollision, slowFall, waterlevel}}); + simulations.emplace_back(ActorSimulation{ + physicActor, ActorFrameData{ *physicActor, inert, waterCollision, slowFall, waterlevel } }); // if the simulation will run, a jump request will be fulfilled. Update mechanics accordingly. if (willSimulate) @@ -753,11 +774,12 @@ namespace MWPhysics for (const auto& [id, projectile] : mProjectiles) { - simulations.emplace_back(ProjectileSimulation{projectile, ProjectileFrameData{*projectile}}); + simulations.emplace_back(ProjectileSimulation{ projectile, ProjectileFrameData{ *projectile } }); } } - void PhysicsSystem::stepSimulation(float dt, bool skipSimulation, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats) + void PhysicsSystem::stepSimulation( + float dt, bool skipSimulation, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats) { for (auto& [animatedObject, changed] : mAnimatedObjects) { @@ -797,7 +819,8 @@ namespace MWPhysics auto* player = getActor(MWMechanics::getPlayer()); const auto world = MWBase::Environment::get().getWorld(); - // copy new ptr position in temporary vector. player is handled separately as its movement might change active cell. + // copy new ptr position in temporary vector. player is handled separately as its movement might change active + // cell. mActorsPositions.clear(); mActorsPositions.reserve(mActors.size() - 1); for (const auto& [ptr, physicActor] : mActors) @@ -827,7 +850,7 @@ namespace MWPhysics mTaskScheduler->debugDraw(); } - bool PhysicsSystem::isActorStandingOn(const MWWorld::Ptr &actor, const MWWorld::ConstPtr &object) const + bool PhysicsSystem::isActorStandingOn(const MWWorld::Ptr& actor, const MWWorld::ConstPtr& object) const { const auto physActor = mActors.find(actor.mRef); if (physActor != mActors.end()) @@ -835,7 +858,7 @@ namespace MWPhysics return false; } - void PhysicsSystem::getActorsStandingOn(const MWWorld::ConstPtr &object, std::vector &out) const + void PhysicsSystem::getActorsStandingOn(const MWWorld::ConstPtr& object, std::vector& out) const { for (const auto& [_, actor] : mActors) { @@ -844,13 +867,13 @@ namespace MWPhysics } } - bool PhysicsSystem::isActorCollidingWith(const MWWorld::Ptr &actor, const MWWorld::ConstPtr &object) const + bool PhysicsSystem::isActorCollidingWith(const MWWorld::Ptr& actor, const MWWorld::ConstPtr& object) const { std::vector collisions = getCollisions(object, CollisionType_World, CollisionType_Actor); return (std::find(collisions.begin(), collisions.end(), actor) != collisions.end()); } - void PhysicsSystem::getActorsCollidingWith(const MWWorld::ConstPtr &object, std::vector &out) const + void PhysicsSystem::getActorsCollidingWith(const MWWorld::ConstPtr& object, std::vector& out) const { std::vector collisions = getCollisions(object, CollisionType_World, CollisionType_Actor); out.insert(out.end(), collisions.begin(), collisions.end()); @@ -898,10 +921,10 @@ namespace MWPhysics } mWaterCollisionObject = std::make_unique(); - mWaterCollisionShape = std::make_unique(btVector3(0,0,1), mWaterHeight); + mWaterCollisionShape = std::make_unique(btVector3(0, 0, 1), mWaterHeight); mWaterCollisionObject->setCollisionShape(mWaterCollisionShape.get()); - mTaskScheduler->addCollisionObject(mWaterCollisionObject.get(), CollisionType_Water, - CollisionType_Actor|CollisionType_Projectile); + mTaskScheduler->addCollisionObject( + mWaterCollisionObject.get(), CollisionType_Water, CollisionType_Actor | CollisionType_Projectile); } bool PhysicsSystem::isAreaOccupiedByOtherActor(const osg::Vec3f& position, const float radius, @@ -914,8 +937,7 @@ namespace MWPhysics ignoredObjects.push_back(it->second->getCollisionObject()); std::sort(ignoredObjects.begin(), ignoredObjects.end()); ignoredObjects.erase(std::unique(ignoredObjects.begin(), ignoredObjects.end()), ignoredObjects.end()); - const auto ignoreFilter = [&] (const btCollisionObject* v) - { + const auto ignoreFilter = [&](const btCollisionObject* v) { return std::binary_search(ignoredObjects.begin(), ignoredObjects.end(), v); }; const auto bulletPosition = Misc::Convert::toBullet(position); @@ -926,12 +948,11 @@ namespace MWPhysics if (occupyingActors == nullptr) { HasSphereCollisionCallback callback(bulletPosition, radius, mask, group, ignoreFilter, - static_cast(nullptr)); + static_cast(nullptr)); mTaskScheduler->aabbTest(aabbMin, aabbMax, callback); return callback.getResult(); } - const auto onCollision = [&] (const btCollisionObject* object) - { + const auto onCollision = [&](const btCollisionObject* object) { if (PtrHolder* holder = static_cast(object->getUserPointer())) occupyingActors->push_back(holder->getPtr()); }; @@ -962,7 +983,14 @@ namespace MWPhysics , mWalkingOnWater(false) , mInert(inert) , mCollisionObject(actor.getCollisionObject()) - , mSwimLevel(waterlevel - (actor.getRenderingHalfExtents().z() * 2 * MWBase::Environment::get().getWorld()->getStore().get().find("fSwimHeightScale")->mValue.getFloat())) + , mSwimLevel(waterlevel + - (actor.getRenderingHalfExtents().z() * 2 + * MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fSwimHeightScale") + ->mValue.getFloat())) , mSlowFall(slowFall) , mRotation() , mMovement(actor.velocity()) @@ -990,25 +1018,29 @@ namespace MWPhysics WorldFrameData::WorldFrameData() : mIsInStorm(MWBase::Environment::get().getWorld()->isInStorm()) , mStormDirection(MWBase::Environment::get().getWorld()->getStormDirection()) - {} + { + } LOSRequest::LOSRequest(const std::weak_ptr& a1, const std::weak_ptr& a2) - : mResult(false), mStale(false), mAge(0) + : mResult(false) + , mStale(false) + , mAge(0) { // we use raw actor pointer pair to uniquely identify request - // sort the pointer value in ascending order to not duplicate equivalent requests, eg. getLOS(A, B) and getLOS(B, A) + // sort the pointer value in ascending order to not duplicate equivalent requests, eg. getLOS(A, B) and + // getLOS(B, A) auto* raw1 = a1.lock().get(); auto* raw2 = a2.lock().get(); assert(raw1 != raw2); if (raw1 < raw2) { - mActors = {a1, a2}; - mRawActors = {raw1, raw2}; + mActors = { a1, a2 }; + mRawActors = { raw1, raw2 }; } else { - mActors = {a2, a1}; - mRawActors = {raw2, raw1}; + mActors = { a2, a1 }; + mRawActors = { raw2, raw1 }; } } diff --git a/apps/openmw/mwphysics/physicssystem.hpp b/apps/openmw/mwphysics/physicssystem.hpp index 094d4e2230..57dbde1471 100644 --- a/apps/openmw/mwphysics/physicssystem.hpp +++ b/apps/openmw/mwphysics/physicssystem.hpp @@ -1,21 +1,21 @@ #ifndef OPENMW_MWPHYSICS_PHYSICSSYSTEM_H #define OPENMW_MWPHYSICS_PHYSICSSYSTEM_H +#include #include -#include +#include #include +#include +#include #include +#include #include -#include #include -#include -#include -#include -#include #include -#include +#include #include +#include #include @@ -125,19 +125,23 @@ namespace MWPhysics template class SimulationImpl { - public: - explicit SimulationImpl(const std::weak_ptr& ptr, FrameData&& data) : mPtr(ptr), mData(data) {} - - std::optional, std::reference_wrapper>> lock() - { - if (auto locked = mPtr.lock()) - return {{std::move(locked), std::ref(mData)}}; - return std::nullopt; - } - - private: - std::weak_ptr mPtr; - FrameData mData; + public: + explicit SimulationImpl(const std::weak_ptr& ptr, FrameData&& data) + : mPtr(ptr) + , mData(data) + { + } + + std::optional, std::reference_wrapper>> lock() + { + if (auto locked = mPtr.lock()) + return { { std::move(locked), std::ref(mData) } }; + return std::nullopt; + } + + private: + std::weak_ptr mPtr; + FrameData mData; }; using ActorSimulation = SimulationImpl; @@ -146,199 +150,205 @@ namespace MWPhysics class PhysicsSystem : public RayCastingInterface { - public: - PhysicsSystem (Resource::ResourceSystem* resourceSystem, osg::ref_ptr parentNode); - virtual ~PhysicsSystem (); - - Resource::BulletShapeManager* getShapeManager(); - - void enableWater(float height); - void setWaterHeight(float height); - void disableWater(); + public: + PhysicsSystem(Resource::ResourceSystem* resourceSystem, osg::ref_ptr parentNode); + virtual ~PhysicsSystem(); - void addObject (const MWWorld::Ptr& ptr, const std::string& mesh, osg::Quat rotation, int collisionType = CollisionType_World); - void addActor (const MWWorld::Ptr& ptr, const std::string& mesh); + Resource::BulletShapeManager* getShapeManager(); - int addProjectile(const MWWorld::Ptr& caster, const osg::Vec3f& position, const std::string& mesh, bool computeRadius); - void setCaster(int projectileId, const MWWorld::Ptr& caster); - void removeProjectile(const int projectileId); + void enableWater(float height); + void setWaterHeight(float height); + void disableWater(); - void updatePtr (const MWWorld::Ptr& old, const MWWorld::Ptr& updated); + void addObject(const MWWorld::Ptr& ptr, const std::string& mesh, osg::Quat rotation, + int collisionType = CollisionType_World); + void addActor(const MWWorld::Ptr& ptr, const std::string& mesh); - Actor* getActor(const MWWorld::Ptr& ptr); - const Actor* getActor(const MWWorld::ConstPtr& ptr) const; + int addProjectile( + const MWWorld::Ptr& caster, const osg::Vec3f& position, const std::string& mesh, bool computeRadius); + void setCaster(int projectileId, const MWWorld::Ptr& caster); + void removeProjectile(const int projectileId); - const Object* getObject(const MWWorld::ConstPtr& ptr) const; + void updatePtr(const MWWorld::Ptr& old, const MWWorld::Ptr& updated); - Projectile* getProjectile(int projectileId) const; + Actor* getActor(const MWWorld::Ptr& ptr); + const Actor* getActor(const MWWorld::ConstPtr& ptr) const; - // Object or Actor - void remove (const MWWorld::Ptr& ptr); + const Object* getObject(const MWWorld::ConstPtr& ptr) const; - void updateScale (const MWWorld::Ptr& ptr); - void updateRotation (const MWWorld::Ptr& ptr, osg::Quat rotate); - void updatePosition (const MWWorld::Ptr& ptr); + Projectile* getProjectile(int projectileId) const; - void addHeightField(const float* heights, int x, int y, int size, int verts, float minH, float maxH, const osg::Object* holdObject); + // Object or Actor + void remove(const MWWorld::Ptr& ptr); - void removeHeightField (int x, int y); + void updateScale(const MWWorld::Ptr& ptr); + void updateRotation(const MWWorld::Ptr& ptr, osg::Quat rotate); + void updatePosition(const MWWorld::Ptr& ptr); - const HeightField* getHeightField(int x, int y) const; + void addHeightField(const float* heights, int x, int y, int size, int verts, float minH, float maxH, + const osg::Object* holdObject); - bool toggleCollisionMode(); + void removeHeightField(int x, int y); - /// Determine new position based on all queued movements, then clear the list. - void stepSimulation(float dt, bool skipSimulation, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats); + const HeightField* getHeightField(int x, int y) const; - /// Apply new positions to actors - void moveActors(); - void debugDraw(); + bool toggleCollisionMode(); - std::vector getCollisions(const MWWorld::ConstPtr &ptr, int collisionGroup, int collisionMask) const; ///< get handles this object collides with - std::vector getCollisionsPoints(const MWWorld::ConstPtr &ptr, int collisionGroup, int collisionMask) const; - osg::Vec3f traceDown(const MWWorld::Ptr &ptr, const osg::Vec3f& position, float maxHeight); + /// Determine new position based on all queued movements, then clear the list. + void stepSimulation( + float dt, bool skipSimulation, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats); - std::pair getHitContact(const MWWorld::ConstPtr& actor, - const osg::Vec3f &origin, - const osg::Quat &orientation, - float queryDistance, std::vector& targets); + /// Apply new positions to actors + void moveActors(); + void debugDraw(); + std::vector getCollisions(const MWWorld::ConstPtr& ptr, int collisionGroup, + int collisionMask) const; ///< get handles this object collides with + std::vector getCollisionsPoints( + const MWWorld::ConstPtr& ptr, int collisionGroup, int collisionMask) const; + osg::Vec3f traceDown(const MWWorld::Ptr& ptr, const osg::Vec3f& position, float maxHeight); - /// Get distance from \a point to the collision shape of \a target. Uses a raycast to find where the - /// target vector hits the collision shape and then calculates distance from the intersection point. - /// This can be used to find out how much nearer we need to move to the target for a "getHitContact" to be successful. - /// \note Only Actor targets are supported at the moment. - float getHitDistance(const osg::Vec3f& point, const MWWorld::ConstPtr& target) const override; + std::pair getHitContact(const MWWorld::ConstPtr& actor, const osg::Vec3f& origin, + const osg::Quat& orientation, float queryDistance, std::vector& targets); - /// @param me Optional, a Ptr to ignore in the list of results. targets are actors to filter for, ignoring all other actors. - RayCastingResult castRay(const osg::Vec3f &from, const osg::Vec3f &to, const MWWorld::ConstPtr& ignore = MWWorld::ConstPtr(), - const std::vector& targets = std::vector(), - int mask = CollisionType_Default, int group=0xff) const override; + /// Get distance from \a point to the collision shape of \a target. Uses a raycast to find where the + /// target vector hits the collision shape and then calculates distance from the intersection point. + /// This can be used to find out how much nearer we need to move to the target for a "getHitContact" to be + /// successful. \note Only Actor targets are supported at the moment. + float getHitDistance(const osg::Vec3f& point, const MWWorld::ConstPtr& target) const override; - RayCastingResult castSphere(const osg::Vec3f& from, const osg::Vec3f& to, float radius, - int mask = CollisionType_Default, int group=0xff) const override; + /// @param me Optional, a Ptr to ignore in the list of results. targets are actors to filter for, ignoring all + /// other actors. + RayCastingResult castRay(const osg::Vec3f& from, const osg::Vec3f& to, + const MWWorld::ConstPtr& ignore = MWWorld::ConstPtr(), + const std::vector& targets = std::vector(), int mask = CollisionType_Default, + int group = 0xff) const override; - /// Return true if actor1 can see actor2. - bool getLineOfSight(const MWWorld::ConstPtr& actor1, const MWWorld::ConstPtr& actor2) const override; + RayCastingResult castSphere(const osg::Vec3f& from, const osg::Vec3f& to, float radius, + int mask = CollisionType_Default, int group = 0xff) const override; - bool isOnGround (const MWWorld::Ptr& actor); + /// Return true if actor1 can see actor2. + bool getLineOfSight(const MWWorld::ConstPtr& actor1, const MWWorld::ConstPtr& actor2) const override; - bool canMoveToWaterSurface (const MWWorld::ConstPtr &actor, const float waterlevel); + bool isOnGround(const MWWorld::Ptr& actor); - /// Get physical half extents (scaled) of the given actor. - osg::Vec3f getHalfExtents(const MWWorld::ConstPtr& actor) const; + bool canMoveToWaterSurface(const MWWorld::ConstPtr& actor, const float waterlevel); - /// Get physical half extents (not scaled) of the given actor. - osg::Vec3f getOriginalHalfExtents(const MWWorld::ConstPtr& actor) const; + /// Get physical half extents (scaled) of the given actor. + osg::Vec3f getHalfExtents(const MWWorld::ConstPtr& actor) const; - /// @see MWPhysics::Actor::getRenderingHalfExtents - osg::Vec3f getRenderingHalfExtents(const MWWorld::ConstPtr& actor) const; + /// Get physical half extents (not scaled) of the given actor. + osg::Vec3f getOriginalHalfExtents(const MWWorld::ConstPtr& actor) const; - /// Get the position of the collision shape for the actor. Use together with getHalfExtents() to get the collision bounds in world space. - /// @note The collision shape's origin is in its center, so the position returned can be described as center of the actor collision box in world space. - osg::Vec3f getCollisionObjectPosition(const MWWorld::ConstPtr& actor) const; + /// @see MWPhysics::Actor::getRenderingHalfExtents + osg::Vec3f getRenderingHalfExtents(const MWWorld::ConstPtr& actor) const; - /// Get bounding box in world space of the given object. - osg::BoundingBox getBoundingBox(const MWWorld::ConstPtr &object) const; + /// Get the position of the collision shape for the actor. Use together with getHalfExtents() to get the + /// collision bounds in world space. + /// @note The collision shape's origin is in its center, so the position returned can be described as center of + /// the actor collision box in world space. + osg::Vec3f getCollisionObjectPosition(const MWWorld::ConstPtr& actor) const; - /// Queues velocity movement for a Ptr. If a Ptr is already queued, its velocity will - /// be overwritten. Valid until the next call to stepSimulation - void queueObjectMovement(const MWWorld::Ptr &ptr, const osg::Vec3f &velocity); + /// Get bounding box in world space of the given object. + osg::BoundingBox getBoundingBox(const MWWorld::ConstPtr& object) const; - /// Clear the queued movements list without applying. - void clearQueuedMovement(); + /// Queues velocity movement for a Ptr. If a Ptr is already queued, its velocity will + /// be overwritten. Valid until the next call to stepSimulation + void queueObjectMovement(const MWWorld::Ptr& ptr, const osg::Vec3f& velocity); - /// Return true if \a actor has been standing on \a object in this frame - /// This will trigger whenever the object is directly below the actor. - /// It doesn't matter if the actor is stationary or moving. - bool isActorStandingOn(const MWWorld::Ptr& actor, const MWWorld::ConstPtr& object) const; + /// Clear the queued movements list without applying. + void clearQueuedMovement(); - /// Get the handle of all actors standing on \a object in this frame. - void getActorsStandingOn(const MWWorld::ConstPtr& object, std::vector& out) const; + /// Return true if \a actor has been standing on \a object in this frame + /// This will trigger whenever the object is directly below the actor. + /// It doesn't matter if the actor is stationary or moving. + bool isActorStandingOn(const MWWorld::Ptr& actor, const MWWorld::ConstPtr& object) const; - /// Return true if \a actor has collided with \a object in this frame. - /// This will detect running into objects, but will not detect climbing stairs, stepping up a small object, etc. - bool isActorCollidingWith(const MWWorld::Ptr& actor, const MWWorld::ConstPtr& object) const; + /// Get the handle of all actors standing on \a object in this frame. + void getActorsStandingOn(const MWWorld::ConstPtr& object, std::vector& out) const; - /// Get the handle of all actors colliding with \a object in this frame. - void getActorsCollidingWith(const MWWorld::ConstPtr& object, std::vector& out) const; + /// Return true if \a actor has collided with \a object in this frame. + /// This will detect running into objects, but will not detect climbing stairs, stepping up a small object, etc. + bool isActorCollidingWith(const MWWorld::Ptr& actor, const MWWorld::ConstPtr& object) const; - bool toggleDebugRendering(); + /// Get the handle of all actors colliding with \a object in this frame. + void getActorsCollidingWith(const MWWorld::ConstPtr& object, std::vector& out) const; - /// Mark the given object as a 'non-solid' object. A non-solid object means that - /// \a isOnSolidGround will return false for actors standing on that object. - void markAsNonSolid (const MWWorld::ConstPtr& ptr); + bool toggleDebugRendering(); - bool isOnSolidGround (const MWWorld::Ptr& actor) const; + /// Mark the given object as a 'non-solid' object. A non-solid object means that + /// \a isOnSolidGround will return false for actors standing on that object. + void markAsNonSolid(const MWWorld::ConstPtr& ptr); - void updateAnimatedCollisionShape(const MWWorld::Ptr& object); + bool isOnSolidGround(const MWWorld::Ptr& actor) const; - template - void forEachAnimatedObject(Function&& function) const - { - std::for_each(mAnimatedObjects.begin(), mAnimatedObjects.end(), function); - } + void updateAnimatedCollisionShape(const MWWorld::Ptr& object); - bool isAreaOccupiedByOtherActor(const osg::Vec3f& position, const float radius, - std::span ignore, std::vector* occupyingActors) const; + template + void forEachAnimatedObject(Function&& function) const + { + std::for_each(mAnimatedObjects.begin(), mAnimatedObjects.end(), function); + } - void reportStats(unsigned int frameNumber, osg::Stats& stats) const; - void reportCollision(const btVector3& position, const btVector3& normal); + bool isAreaOccupiedByOtherActor(const osg::Vec3f& position, const float radius, + std::span ignore, std::vector* occupyingActors) const; - private: + void reportStats(unsigned int frameNumber, osg::Stats& stats) const; + void reportCollision(const btVector3& position, const btVector3& normal); - void updateWater(); + private: + void updateWater(); - void prepareSimulation(bool willSimulate, std::vector& simulations); + void prepareSimulation(bool willSimulate, std::vector& simulations); - std::unique_ptr mBroadphase; - std::unique_ptr mCollisionConfiguration; - std::unique_ptr mDispatcher; - std::unique_ptr mCollisionWorld; - std::unique_ptr mTaskScheduler; + std::unique_ptr mBroadphase; + std::unique_ptr mCollisionConfiguration; + std::unique_ptr mDispatcher; + std::unique_ptr mCollisionWorld; + std::unique_ptr mTaskScheduler; - std::unique_ptr mShapeManager; - Resource::ResourceSystem* mResourceSystem; + std::unique_ptr mShapeManager; + Resource::ResourceSystem* mResourceSystem; - using ObjectMap = std::unordered_map>; - ObjectMap mObjects; + using ObjectMap = std::unordered_map>; + ObjectMap mObjects; - std::map mAnimatedObjects; // stores pointers to elements in mObjects + std::map mAnimatedObjects; // stores pointers to elements in mObjects - ActorMap mActors; + ActorMap mActors; - using ProjectileMap = std::map>; - ProjectileMap mProjectiles; + using ProjectileMap = std::map>; + ProjectileMap mProjectiles; - using HeightFieldMap = std::map, std::unique_ptr>; - HeightFieldMap mHeightFields; + using HeightFieldMap = std::map, std::unique_ptr>; + HeightFieldMap mHeightFields; - bool mDebugDrawEnabled; + bool mDebugDrawEnabled; - float mTimeAccum; + float mTimeAccum; - unsigned int mProjectileId; + unsigned int mProjectileId; - float mWaterHeight; - bool mWaterEnabled; + float mWaterHeight; + bool mWaterEnabled; - std::unique_ptr mWaterCollisionObject; - std::unique_ptr mWaterCollisionShape; + std::unique_ptr mWaterCollisionObject; + std::unique_ptr mWaterCollisionShape; - std::unique_ptr mDebugDrawer; + std::unique_ptr mDebugDrawer; - osg::ref_ptr mParentNode; + osg::ref_ptr mParentNode; - float mPhysicsDt; + float mPhysicsDt; - DetourNavigator::CollisionShapeType mActorCollisionShapeType; + DetourNavigator::CollisionShapeType mActorCollisionShapeType; - std::size_t mSimulationsCounter = 0; - std::array, 2> mSimulations; - std::vector> mActorsPositions; + std::size_t mSimulationsCounter = 0; + std::array, 2> mSimulations; + std::vector> mActorsPositions; - PhysicsSystem (const PhysicsSystem&); - PhysicsSystem& operator= (const PhysicsSystem&); + PhysicsSystem(const PhysicsSystem&); + PhysicsSystem& operator=(const PhysicsSystem&); }; } diff --git a/apps/openmw/mwphysics/projectile.cpp b/apps/openmw/mwphysics/projectile.cpp index d9bfd74bf5..242549147d 100644 --- a/apps/openmw/mwphysics/projectile.cpp +++ b/apps/openmw/mwphysics/projectile.cpp @@ -14,111 +14,111 @@ namespace MWPhysics { -Projectile::Projectile(const MWWorld::Ptr& caster, const osg::Vec3f& position, float radius, PhysicsTaskScheduler* scheduler, PhysicsSystem* physicssystem) - : PtrHolder(MWWorld::Ptr(), position) - , mHitWater(false) - , mActive(true) - , mHitTarget(nullptr) - , mPhysics(physicssystem) - , mTaskScheduler(scheduler) -{ - mShape = std::make_unique(radius); - mConvexShape = static_cast(mShape.get()); + Projectile::Projectile(const MWWorld::Ptr& caster, const osg::Vec3f& position, float radius, + PhysicsTaskScheduler* scheduler, PhysicsSystem* physicssystem) + : PtrHolder(MWWorld::Ptr(), position) + , mHitWater(false) + , mActive(true) + , mHitTarget(nullptr) + , mPhysics(physicssystem) + , mTaskScheduler(scheduler) + { + mShape = std::make_unique(radius); + mConvexShape = static_cast(mShape.get()); - mCollisionObject = std::make_unique(); - mCollisionObject->setCollisionFlags(btCollisionObject::CF_KINEMATIC_OBJECT); - mCollisionObject->setActivationState(DISABLE_DEACTIVATION); - mCollisionObject->setCollisionShape(mShape.get()); - mCollisionObject->setUserPointer(this); + mCollisionObject = std::make_unique(); + mCollisionObject->setCollisionFlags(btCollisionObject::CF_KINEMATIC_OBJECT); + mCollisionObject->setActivationState(DISABLE_DEACTIVATION); + mCollisionObject->setCollisionShape(mShape.get()); + mCollisionObject->setUserPointer(this); - mPosition = position; - mPreviousPosition = position; - mSimulationPosition = position; - setCaster(caster); + mPosition = position; + mPreviousPosition = position; + mSimulationPosition = position; + setCaster(caster); - const int collisionMask = CollisionType_World | CollisionType_HeightMap | - CollisionType_Actor | CollisionType_Door | CollisionType_Water | CollisionType_Projectile; - mTaskScheduler->addCollisionObject(mCollisionObject.get(), CollisionType_Projectile, collisionMask); + const int collisionMask = CollisionType_World | CollisionType_HeightMap | CollisionType_Actor + | CollisionType_Door | CollisionType_Water | CollisionType_Projectile; + mTaskScheduler->addCollisionObject(mCollisionObject.get(), CollisionType_Projectile, collisionMask); - updateCollisionObjectPosition(); -} + updateCollisionObjectPosition(); + } -Projectile::~Projectile() -{ - if (!mActive) - mPhysics->reportCollision(mHitPosition, mHitNormal); - mTaskScheduler->removeCollisionObject(mCollisionObject.get()); -} + Projectile::~Projectile() + { + if (!mActive) + mPhysics->reportCollision(mHitPosition, mHitNormal); + mTaskScheduler->removeCollisionObject(mCollisionObject.get()); + } -void Projectile::updateCollisionObjectPosition() -{ - std::scoped_lock lock(mMutex); - auto& trans = mCollisionObject->getWorldTransform(); - trans.setOrigin(Misc::Convert::toBullet(mPosition)); - mCollisionObject->setWorldTransform(trans); -} + void Projectile::updateCollisionObjectPosition() + { + std::scoped_lock lock(mMutex); + auto& trans = mCollisionObject->getWorldTransform(); + trans.setOrigin(Misc::Convert::toBullet(mPosition)); + mCollisionObject->setWorldTransform(trans); + } -void Projectile::hit(const btCollisionObject* target, btVector3 pos, btVector3 normal) -{ - bool active = true; - if (!mActive.compare_exchange_strong(active, false, std::memory_order_relaxed) || !active) - return; - mHitTarget = target; - mHitPosition = pos; - mHitNormal = normal; -} + void Projectile::hit(const btCollisionObject* target, btVector3 pos, btVector3 normal) + { + bool active = true; + if (!mActive.compare_exchange_strong(active, false, std::memory_order_relaxed) || !active) + return; + mHitTarget = target; + mHitPosition = pos; + mHitNormal = normal; + } -MWWorld::Ptr Projectile::getTarget() const -{ - assert(!mActive); - auto* target = static_cast(mHitTarget->getUserPointer()); - return target ? target->getPtr() : MWWorld::Ptr(); -} + MWWorld::Ptr Projectile::getTarget() const + { + assert(!mActive); + auto* target = static_cast(mHitTarget->getUserPointer()); + return target ? target->getPtr() : MWWorld::Ptr(); + } -MWWorld::Ptr Projectile::getCaster() const -{ - return mCaster; -} + MWWorld::Ptr Projectile::getCaster() const + { + return mCaster; + } -void Projectile::setCaster(const MWWorld::Ptr& caster) -{ - mCaster = caster; - mCasterColObj = [this,&caster]() -> const btCollisionObject* + void Projectile::setCaster(const MWWorld::Ptr& caster) { - const Actor* actor = mPhysics->getActor(caster); - if (actor) - return actor->getCollisionObject(); - const Object* object = mPhysics->getObject(caster); - if (object) - return object->getCollisionObject(); - return nullptr; - }(); -} + mCaster = caster; + mCasterColObj = [this, &caster]() -> const btCollisionObject* { + const Actor* actor = mPhysics->getActor(caster); + if (actor) + return actor->getCollisionObject(); + const Object* object = mPhysics->getObject(caster); + if (object) + return object->getCollisionObject(); + return nullptr; + }(); + } -void Projectile::setValidTargets(const std::vector& targets) -{ - std::scoped_lock lock(mMutex); - mValidTargets.clear(); - for (const auto& ptr : targets) + void Projectile::setValidTargets(const std::vector& targets) { - const auto* physicActor = mPhysics->getActor(ptr); - if (physicActor) - mValidTargets.push_back(physicActor->getCollisionObject()); + std::scoped_lock lock(mMutex); + mValidTargets.clear(); + for (const auto& ptr : targets) + { + const auto* physicActor = mPhysics->getActor(ptr); + if (physicActor) + mValidTargets.push_back(physicActor->getCollisionObject()); + } } -} -bool Projectile::isValidTarget(const btCollisionObject* target) const -{ - assert(target); - std::scoped_lock lock(mMutex); - if (mCasterColObj == target) - return false; + bool Projectile::isValidTarget(const btCollisionObject* target) const + { + assert(target); + std::scoped_lock lock(mMutex); + if (mCasterColObj == target) + return false; - if (mValidTargets.empty()) - return true; + if (mValidTargets.empty()) + return true; - return std::any_of(mValidTargets.begin(), mValidTargets.end(), + return std::any_of(mValidTargets.begin(), mValidTargets.end(), [target](const btCollisionObject* actor) { return target == actor; }); -} + } } diff --git a/apps/openmw/mwphysics/projectile.hpp b/apps/openmw/mwphysics/projectile.hpp index 44569d29bf..d8eebf3057 100644 --- a/apps/openmw/mwphysics/projectile.hpp +++ b/apps/openmw/mwphysics/projectile.hpp @@ -31,49 +31,34 @@ namespace MWPhysics class Projectile final : public PtrHolder { public: - Projectile(const MWWorld::Ptr& caster, const osg::Vec3f& position, float radius, PhysicsTaskScheduler* scheduler, PhysicsSystem* physicssystem); + Projectile(const MWWorld::Ptr& caster, const osg::Vec3f& position, float radius, + PhysicsTaskScheduler* scheduler, PhysicsSystem* physicssystem); ~Projectile() override; btConvexShape* getConvexShape() const { return mConvexShape; } void updateCollisionObjectPosition(); - bool isActive() const - { - return mActive.load(std::memory_order_acquire); - } + bool isActive() const { return mActive.load(std::memory_order_acquire); } MWWorld::Ptr getTarget() const; MWWorld::Ptr getCaster() const; void setCaster(const MWWorld::Ptr& caster); - const btCollisionObject* getCasterCollisionObject() const - { - return mCasterColObj; - } + const btCollisionObject* getCasterCollisionObject() const { return mCasterColObj; } - void setHitWater() - { - mHitWater = true; - } + void setHitWater() { mHitWater = true; } - bool getHitWater() const - { - return mHitWater; - } + bool getHitWater() const { return mHitWater; } void hit(const btCollisionObject* target, btVector3 pos, btVector3 normal); void setValidTargets(const std::vector& targets); bool isValidTarget(const btCollisionObject* target) const; - btVector3 getHitPosition() const - { - return mHitPosition; - } + btVector3 getHitPosition() const { return mHitPosition; } private: - std::unique_ptr mShape; btConvexShape* mConvexShape; @@ -89,8 +74,8 @@ namespace MWPhysics mutable std::mutex mMutex; - PhysicsSystem *mPhysics; - PhysicsTaskScheduler *mTaskScheduler; + PhysicsSystem* mPhysics; + PhysicsTaskScheduler* mTaskScheduler; Projectile(const Projectile&); Projectile& operator=(const Projectile&); @@ -98,5 +83,4 @@ namespace MWPhysics } - #endif diff --git a/apps/openmw/mwphysics/projectileconvexcallback.cpp b/apps/openmw/mwphysics/projectileconvexcallback.cpp index 6520be787d..d3cbf1f21e 100644 --- a/apps/openmw/mwphysics/projectileconvexcallback.cpp +++ b/apps/openmw/mwphysics/projectileconvexcallback.cpp @@ -10,7 +10,8 @@ namespace MWPhysics { - ProjectileConvexCallback::ProjectileConvexCallback(const btCollisionObject* caster, const btCollisionObject* me, const btVector3& from, const btVector3& to, Projectile* proj) + ProjectileConvexCallback::ProjectileConvexCallback(const btCollisionObject* caster, const btCollisionObject* me, + const btVector3& from, const btVector3& to, Projectile* proj) : btCollisionWorld::ClosestConvexResultCallback(from, to) , mCaster(caster) , mMe(me) @@ -19,7 +20,8 @@ namespace MWPhysics assert(mProjectile); } - btScalar ProjectileConvexCallback::addSingleResult(btCollisionWorld::LocalConvexResult& result, bool normalInWorldSpace) + btScalar ProjectileConvexCallback::addSingleResult( + btCollisionWorld::LocalConvexResult& result, bool normalInWorldSpace) { const auto* hitObject = result.m_hitCollisionObject; // don't hit the caster @@ -34,24 +36,24 @@ namespace MWPhysics switch (hitObject->getBroadphaseHandle()->m_collisionFilterGroup) { case CollisionType_Actor: - { - if (!mProjectile->isValidTarget(hitObject)) - return 1.f; - break; - } + { + if (!mProjectile->isValidTarget(hitObject)) + return 1.f; + break; + } case CollisionType_Projectile: - { - auto* target = static_cast(hitObject->getUserPointer()); - if (!mProjectile->isValidTarget(target->getCasterCollisionObject())) - return 1.f; - target->hit(mMe, m_hitPointWorld, m_hitNormalWorld); - break; - } + { + auto* target = static_cast(hitObject->getUserPointer()); + if (!mProjectile->isValidTarget(target->getCasterCollisionObject())) + return 1.f; + target->hit(mMe, m_hitPointWorld, m_hitNormalWorld); + break; + } case CollisionType_Water: - { - mProjectile->setHitWater(); - break; - } + { + mProjectile->setHitWater(); + break; + } } mProjectile->hit(hitObject, m_hitPointWorld, m_hitNormalWorld); @@ -59,4 +61,3 @@ namespace MWPhysics } } - diff --git a/apps/openmw/mwphysics/projectileconvexcallback.hpp b/apps/openmw/mwphysics/projectileconvexcallback.hpp index f35cfbd3c8..3cd304bab0 100644 --- a/apps/openmw/mwphysics/projectileconvexcallback.hpp +++ b/apps/openmw/mwphysics/projectileconvexcallback.hpp @@ -12,7 +12,8 @@ namespace MWPhysics class ProjectileConvexCallback : public btCollisionWorld::ClosestConvexResultCallback { public: - ProjectileConvexCallback(const btCollisionObject* caster, const btCollisionObject* me, const btVector3& from, const btVector3& to, Projectile* proj); + ProjectileConvexCallback(const btCollisionObject* caster, const btCollisionObject* me, const btVector3& from, + const btVector3& to, Projectile* proj); btScalar addSingleResult(btCollisionWorld::LocalConvexResult& result, bool normalInWorldSpace) override; diff --git a/apps/openmw/mwphysics/ptrholder.hpp b/apps/openmw/mwphysics/ptrholder.hpp index e2ba60518c..fc8fd94c30 100644 --- a/apps/openmw/mwphysics/ptrholder.hpp +++ b/apps/openmw/mwphysics/ptrholder.hpp @@ -1,8 +1,8 @@ #ifndef OPENMW_MWPHYSICS_PTRHOLDER_H #define OPENMW_MWPHYSICS_PTRHOLDER_H -#include #include +#include #include #include @@ -26,40 +26,19 @@ namespace MWPhysics virtual ~PtrHolder() = default; - void updatePtr(const MWWorld::Ptr& updated) - { - mPtr = updated; - } + void updatePtr(const MWWorld::Ptr& updated) { mPtr = updated; } - MWWorld::Ptr getPtr() const - { - return mPtr; - } + MWWorld::Ptr getPtr() const { return mPtr; } - btCollisionObject* getCollisionObject() const - { - return mCollisionObject.get(); - } + btCollisionObject* getCollisionObject() const { return mCollisionObject.get(); } - void setVelocity(osg::Vec3f velocity) - { - mVelocity = velocity; - } + void setVelocity(osg::Vec3f velocity) { mVelocity = velocity; } - osg::Vec3f velocity() - { - return std::exchange(mVelocity, osg::Vec3f()); - } + osg::Vec3f velocity() { return std::exchange(mVelocity, osg::Vec3f()); } - void setSimulationPosition(const osg::Vec3f& position) - { - mSimulationPosition = position; - } + void setSimulationPosition(const osg::Vec3f& position) { mSimulationPosition = position; } - osg::Vec3f getSimulationPosition() const - { - return mSimulationPosition; - } + osg::Vec3f getSimulationPosition() const { return mSimulationPosition; } void setPosition(const osg::Vec3f& position) { @@ -67,15 +46,9 @@ namespace MWPhysics mPosition = position; } - osg::Vec3d getPosition() const - { - return mPosition; - } + osg::Vec3d getPosition() const { return mPosition; } - osg::Vec3d getPreviousPosition() const - { - return mPreviousPosition; - } + osg::Vec3d getPreviousPosition() const { return mPreviousPosition; } protected: MWWorld::Ptr mPtr; diff --git a/apps/openmw/mwphysics/raycasting.hpp b/apps/openmw/mwphysics/raycasting.hpp index 848f17a01a..b46721358d 100644 --- a/apps/openmw/mwphysics/raycasting.hpp +++ b/apps/openmw/mwphysics/raycasting.hpp @@ -11,32 +11,34 @@ namespace MWPhysics { class RayCastingResult { - public: - bool mHit; - osg::Vec3f mHitPos; - osg::Vec3f mHitNormal; - MWWorld::Ptr mHitObject; + public: + bool mHit; + osg::Vec3f mHitPos; + osg::Vec3f mHitNormal; + MWWorld::Ptr mHitObject; }; class RayCastingInterface { - public: - /// Get distance from \a point to the collision shape of \a target. Uses a raycast to find where the - /// target vector hits the collision shape and then calculates distance from the intersection point. - /// This can be used to find out how much nearer we need to move to the target for a "getHitContact" to be successful. - /// \note Only Actor targets are supported at the moment. - virtual float getHitDistance(const osg::Vec3f& point, const MWWorld::ConstPtr& target) const = 0; - - /// @param me Optional, a Ptr to ignore in the list of results. targets are actors to filter for, ignoring all other actors. - virtual RayCastingResult castRay(const osg::Vec3f &from, const osg::Vec3f &to, const MWWorld::ConstPtr& ignore = MWWorld::ConstPtr(), - const std::vector& targets = std::vector(), - int mask = CollisionType_Default, int group=0xff) const = 0; - - virtual RayCastingResult castSphere(const osg::Vec3f& from, const osg::Vec3f& to, float radius, - int mask = CollisionType_Default, int group=0xff) const = 0; - - /// Return true if actor1 can see actor2. - virtual bool getLineOfSight(const MWWorld::ConstPtr& actor1, const MWWorld::ConstPtr& actor2) const = 0; + public: + /// Get distance from \a point to the collision shape of \a target. Uses a raycast to find where the + /// target vector hits the collision shape and then calculates distance from the intersection point. + /// This can be used to find out how much nearer we need to move to the target for a "getHitContact" to be + /// successful. \note Only Actor targets are supported at the moment. + virtual float getHitDistance(const osg::Vec3f& point, const MWWorld::ConstPtr& target) const = 0; + + /// @param me Optional, a Ptr to ignore in the list of results. targets are actors to filter for, ignoring all + /// other actors. + virtual RayCastingResult castRay(const osg::Vec3f& from, const osg::Vec3f& to, + const MWWorld::ConstPtr& ignore = MWWorld::ConstPtr(), + const std::vector& targets = std::vector(), int mask = CollisionType_Default, + int group = 0xff) const = 0; + + virtual RayCastingResult castSphere(const osg::Vec3f& from, const osg::Vec3f& to, float radius, + int mask = CollisionType_Default, int group = 0xff) const = 0; + + /// Return true if actor1 can see actor2. + virtual bool getLineOfSight(const MWWorld::ConstPtr& actor1, const MWWorld::ConstPtr& actor2) const = 0; }; } diff --git a/apps/openmw/mwphysics/stepper.cpp b/apps/openmw/mwphysics/stepper.cpp index 5ef6833701..5b7cde3015 100644 --- a/apps/openmw/mwphysics/stepper.cpp +++ b/apps/openmw/mwphysics/stepper.cpp @@ -11,7 +11,7 @@ namespace MWPhysics { - static bool canStepDown(const ActorTracer &stepper) + static bool canStepDown(const ActorTracer& stepper) { if (!stepper.mHitObject) return false; @@ -22,26 +22,29 @@ namespace MWPhysics return stepper.mHitObject->getBroadphaseHandle()->m_collisionFilterGroup != CollisionType_Actor; } - Stepper::Stepper(const btCollisionWorld *colWorld, const btCollisionObject *colObj) + Stepper::Stepper(const btCollisionWorld* colWorld, const btCollisionObject* colObj) : mColWorld(colWorld) , mColObj(colObj) { } - bool Stepper::step(osg::Vec3f &position, osg::Vec3f &velocity, float &remainingTime, const bool & onGround, bool firstIteration) + bool Stepper::step( + osg::Vec3f& position, osg::Vec3f& velocity, float& remainingTime, const bool& onGround, bool firstIteration) { - if(velocity.x() == 0.0 && velocity.y() == 0.0) + if (velocity.x() == 0.0 && velocity.y() == 0.0) return false; - // Stairstepping algorithms work by moving up to avoid the step, moving forwards, then moving back down onto the ground. - // This algorithm has a couple of minor problems, but they don't cause problems for sane geometry, and just prevent stepping on insane geometry. + // Stairstepping algorithms work by moving up to avoid the step, moving forwards, then moving back down onto the + // ground. This algorithm has a couple of minor problems, but they don't cause problems for sane geometry, and + // just prevent stepping on insane geometry. - mUpStepper.doTrace(mColObj, position, position + osg::Vec3f(0.0f, 0.0f, Constants::sStepSizeUp), mColWorld, onGround); + mUpStepper.doTrace( + mColObj, position, position + osg::Vec3f(0.0f, 0.0f, Constants::sStepSizeUp), mColWorld, onGround); float upDistance = 0; - if(!mUpStepper.mHitObject) + if (!mUpStepper.mHitObject) upDistance = Constants::sStepSizeUp; - else if(mUpStepper.mFraction * Constants::sStepSizeUp > sCollisionMargin) + else if (mUpStepper.mFraction * Constants::sStepSizeUp > sCollisionMargin) upDistance = mUpStepper.mFraction * Constants::sStepSizeUp - sCollisionMargin; else { @@ -56,75 +59,79 @@ namespace MWPhysics auto normalMove = toMove; auto moveDistance = normalMove.normalize(); // attempt 1: normal movement - // attempt 2: fixed distance movement, only happens on the first movement solver iteration/bounce each frame to avoid a glitch - // attempt 3: further, less tall fixed distance movement, same as above - // If you're making a full conversion you should purge the logic for attempts 2 and 3. Attempts 2 and 3 just try to work around problems with vanilla Morrowind assets. + // attempt 2: fixed distance movement, only happens on the first movement solver iteration/bounce each frame to + // avoid a glitch attempt 3: further, less tall fixed distance movement, same as above If you're making a full + // conversion you should purge the logic for attempts 2 and 3. Attempts 2 and 3 just try to work around problems + // with vanilla Morrowind assets. int attempt = 0; float downStepSize = 0; - while(attempt < 3) + while (attempt < 3) { attempt++; - if(attempt == 1) + if (attempt == 1) tracerDest = tracerPos + toMove; else if (!sDoExtraStairHacks) // early out if we have extra hacks disabled { return false; } - else if(attempt == 2) + else if (attempt == 2) { moveDistance = sMinStep; - tracerDest = tracerPos + normalMove*sMinStep; + tracerDest = tracerPos + normalMove * sMinStep; } - else if(attempt == 3) + else if (attempt == 3) { - if(upDistance > Constants::sStepSizeUp) + if (upDistance > Constants::sStepSizeUp) { upDistance = Constants::sStepSizeUp; tracerPos = position + osg::Vec3f(0.0f, 0.0f, upDistance); } moveDistance = sMinStep2; - tracerDest = tracerPos + normalMove*sMinStep2; + tracerDest = tracerPos + normalMove * sMinStep2; } mTracer.doTrace(mColObj, tracerPos, tracerDest, mColWorld); - if(mTracer.mHitObject) + if (mTracer.mHitObject) { // map against what we hit, minus the safety margin moveDistance *= mTracer.mFraction; - if(moveDistance <= sCollisionMargin) // didn't move enough to accomplish anything + if (moveDistance <= sCollisionMargin) // didn't move enough to accomplish anything { return false; } moveDistance -= sCollisionMargin; - tracerDest = tracerPos + normalMove*moveDistance; + tracerDest = tracerPos + normalMove * moveDistance; // safely eject from what we hit by the safety margin - auto tempDest = tracerDest + mTracer.mPlaneNormal*sCollisionMargin*2; + auto tempDest = tracerDest + mTracer.mPlaneNormal * sCollisionMargin * 2; ActorTracer tempTracer; tempTracer.doTrace(mColObj, tracerDest, tempDest, mColWorld); - if(tempTracer.mFraction > 0.5f) // distance to any object is greater than sCollisionMargin (we checked sCollisionMargin*2 distance) + if (tempTracer.mFraction > 0.5f) // distance to any object is greater than sCollisionMargin (we checked + // sCollisionMargin*2 distance) { - auto effectiveFraction = tempTracer.mFraction*2.0f - 1.0f; - tracerDest += mTracer.mPlaneNormal*sCollisionMargin*effectiveFraction; + auto effectiveFraction = tempTracer.mFraction * 2.0f - 1.0f; + tracerDest += mTracer.mPlaneNormal * sCollisionMargin * effectiveFraction; } } - if(attempt > 2) // do not allow stepping down below original height for attempt 3 + if (attempt > 2) // do not allow stepping down below original height for attempt 3 downStepSize = upDistance; else downStepSize = moveDistance + upDistance + sStepSizeDown; - mDownStepper.doTrace(mColObj, tracerDest, tracerDest + osg::Vec3f(0.0f, 0.0f, -downStepSize), mColWorld, onGround); + mDownStepper.doTrace( + mColObj, tracerDest, tracerDest + osg::Vec3f(0.0f, 0.0f, -downStepSize), mColWorld, onGround); // can't step down onto air, non-walkable-slopes, or actors - // NOTE: using a capsule causes isWalkableSlope (used in canStepDown) to fail on certain geometry that were intended to be valid at the bottoms of stairs - // (like the bottoms of the staircases in aldruhn's guild of mages) - // The old code worked around this by trying to do mTracer again with a fixed distance of sMinStep (10.0) but it caused all sorts of other problems. - // Switched back to cylinders to avoid that and similer problems. - if(canStepDown(mDownStepper)) + // NOTE: using a capsule causes isWalkableSlope (used in canStepDown) to fail on certain geometry that were + // intended to be valid at the bottoms of stairs (like the bottoms of the staircases in aldruhn's guild of + // mages) The old code worked around this by trying to do mTracer again with a fixed distance of sMinStep + // (10.0) but it caused all sorts of other problems. Switched back to cylinders to avoid that and similer + // problems. + if (canStepDown(mDownStepper)) { break; } @@ -132,12 +139,12 @@ namespace MWPhysics { // do not try attempt 3 if we just tried attempt 2 and the horizontal distance was rather large // (forces actor to get snug against the defective ledge for attempt 3 to be tried) - if(attempt == 2 && moveDistance > upDistance-(mDownStepper.mFraction*downStepSize)) + if (attempt == 2 && moveDistance > upDistance - (mDownStepper.mFraction * downStepSize)) { return false; } // do next attempt if first iteration of movement solver and not out of attempts - if(firstIteration && attempt < 3) + if (firstIteration && attempt < 3) { continue; } @@ -148,18 +155,18 @@ namespace MWPhysics // note: can't downstep onto actors so no need to pick safety margin float downDistance = 0; - if(mDownStepper.mFraction*downStepSize > sCollisionMargin) - downDistance = mDownStepper.mFraction*downStepSize - sCollisionMargin; + if (mDownStepper.mFraction * downStepSize > sCollisionMargin) + downDistance = mDownStepper.mFraction * downStepSize - sCollisionMargin; - if(downDistance-sCollisionMargin-sGroundOffset > upDistance && !onGround) + if (downDistance - sCollisionMargin - sGroundOffset > upDistance && !onGround) return false; auto newpos = tracerDest + osg::Vec3f(0.0f, 0.0f, -downDistance); - if((position-newpos).length2() < sCollisionMargin*sCollisionMargin) + if ((position - newpos).length2() < sCollisionMargin * sCollisionMargin) return false; - if(mTracer.mHitObject) + if (mTracer.mHitObject) { auto planeNormal = mTracer.mPlaneNormal; if (onGround && !isWalkableSlope(planeNormal) && planeNormal.z() != 0) @@ -173,7 +180,7 @@ namespace MWPhysics position = newpos; - remainingTime *= (1.0f-mTracer.mFraction); // remaining time is proportional to remaining distance + remainingTime *= (1.0f - mTracer.mFraction); // remaining time is proportional to remaining distance return true; } } diff --git a/apps/openmw/mwphysics/stepper.hpp b/apps/openmw/mwphysics/stepper.hpp index 512493c524..d555ef540e 100644 --- a/apps/openmw/mwphysics/stepper.hpp +++ b/apps/openmw/mwphysics/stepper.hpp @@ -16,15 +16,16 @@ namespace MWPhysics class Stepper { private: - const btCollisionWorld *mColWorld; - const btCollisionObject *mColObj; + const btCollisionWorld* mColWorld; + const btCollisionObject* mColObj; ActorTracer mTracer, mUpStepper, mDownStepper; public: - Stepper(const btCollisionWorld *colWorld, const btCollisionObject *colObj); + Stepper(const btCollisionWorld* colWorld, const btCollisionObject* colObj); - bool step(osg::Vec3f &position, osg::Vec3f &velocity, float &remainingTime, const bool & onGround, bool firstIteration); + bool step(osg::Vec3f& position, osg::Vec3f& velocity, float& remainingTime, const bool& onGround, + bool firstIteration); }; } diff --git a/apps/openmw/mwphysics/trace.cpp b/apps/openmw/mwphysics/trace.cpp index b7930bfa53..9e60a7c626 100644 --- a/apps/openmw/mwphysics/trace.cpp +++ b/apps/openmw/mwphysics/trace.cpp @@ -5,114 +5,120 @@ #include #include -#include "collisiontype.hpp" #include "actor.hpp" #include "actorconvexcallback.hpp" +#include "collisiontype.hpp" namespace MWPhysics { -ActorConvexCallback sweepHelper(const btCollisionObject *actor, const btVector3& from, const btVector3& to, const btCollisionWorld* world, bool actorFilter) -{ - const btTransform &trans = actor->getWorldTransform(); - btTransform transFrom(trans); - btTransform transTo(trans); - transFrom.setOrigin(from); - transTo.setOrigin(to); - - const btCollisionShape *shape = actor->getCollisionShape(); - assert(shape->isConvex()); - - const btVector3 motion = from - to; // FIXME: this is backwards; means ActorConvexCallback is doing dot product tests backwards too - ActorConvexCallback traceCallback(actor, motion, btScalar(0.0), world); - // Inherit the actor's collision group and mask - traceCallback.m_collisionFilterGroup = actor->getBroadphaseHandle()->m_collisionFilterGroup; - traceCallback.m_collisionFilterMask = actor->getBroadphaseHandle()->m_collisionFilterMask; - if(actorFilter) - traceCallback.m_collisionFilterMask &= ~CollisionType_Actor; + ActorConvexCallback sweepHelper(const btCollisionObject* actor, const btVector3& from, const btVector3& to, + const btCollisionWorld* world, bool actorFilter) + { + const btTransform& trans = actor->getWorldTransform(); + btTransform transFrom(trans); + btTransform transTo(trans); + transFrom.setOrigin(from); + transTo.setOrigin(to); - world->convexSweepTest(static_cast(shape), transFrom, transTo, traceCallback); - return traceCallback; -} + const btCollisionShape* shape = actor->getCollisionShape(); + assert(shape->isConvex()); -void ActorTracer::doTrace(const btCollisionObject *actor, const osg::Vec3f& start, const osg::Vec3f& end, const btCollisionWorld* world, bool attempt_short_trace) -{ - const btVector3 btstart = Misc::Convert::toBullet(start); - btVector3 btend = Misc::Convert::toBullet(end); + const btVector3 motion + = from - to; // FIXME: this is backwards; means ActorConvexCallback is doing dot product tests backwards too + ActorConvexCallback traceCallback(actor, motion, btScalar(0.0), world); + // Inherit the actor's collision group and mask + traceCallback.m_collisionFilterGroup = actor->getBroadphaseHandle()->m_collisionFilterGroup; + traceCallback.m_collisionFilterMask = actor->getBroadphaseHandle()->m_collisionFilterMask; + if (actorFilter) + traceCallback.m_collisionFilterMask &= ~CollisionType_Actor; - // Because Bullet's collision trace tests touch *all* geometry in its path, a lot of long collision tests - // will unnecessarily test against complex meshes that are dozens of units away. This wouldn't normally be - // a problem, but bullet isn't the fastest in the world when it comes to doing tests against triangle meshes. - // Therefore, we try out a short trace first, then only fall back to the full length trace if needed. - // This trace needs to be at least a couple units long, but there's no one particular ideal length. - // The length of 2.1 chosen here is a "works well in practice after testing a few random lengths" value. - // (Also, we only do this short test if the intended collision trace is long enough for it to make sense.) - const float fallback_length = 2.1f; - bool doing_short_trace = false; - // For some reason, typical scenes perform a little better if we increase the threshold length for the length test. - // (Multiplying by 2 in 'square distance' units gives us about 1.4x the threshold length. In benchmarks this was - // slightly better for the performance of normal scenes than 4.0, and just plain better than 1.0.) - if(attempt_short_trace && (btend-btstart).length2() > fallback_length*fallback_length*2.0) - { - btend = btstart + (btend-btstart).normalized()*fallback_length; - doing_short_trace = true; + world->convexSweepTest(static_cast(shape), transFrom, transTo, traceCallback); + return traceCallback; } - const auto traceCallback = sweepHelper(actor, btstart, btend, world, false); - - // Copy the hit data over to our trace results struct: - if(traceCallback.hasHit()) + void ActorTracer::doTrace(const btCollisionObject* actor, const osg::Vec3f& start, const osg::Vec3f& end, + const btCollisionWorld* world, bool attempt_short_trace) { - mFraction = traceCallback.m_closestHitFraction; - // ensure fraction is correct (covers intended distance traveled instead of actual distance traveled) - if(doing_short_trace && (end-start).length2() > 0.0) - mFraction *= (btend-btstart).length() / (end-start).length(); - mPlaneNormal = Misc::Convert::toOsg(traceCallback.m_hitNormalWorld); - mEndPos = (end-start)*mFraction + start; - mHitPoint = Misc::Convert::toOsg(traceCallback.m_hitPointWorld); - mHitObject = traceCallback.m_hitCollisionObject; - } - else - { - if(doing_short_trace) + const btVector3 btstart = Misc::Convert::toBullet(start); + btVector3 btend = Misc::Convert::toBullet(end); + + // Because Bullet's collision trace tests touch *all* geometry in its path, a lot of long collision tests + // will unnecessarily test against complex meshes that are dozens of units away. This wouldn't normally be + // a problem, but bullet isn't the fastest in the world when it comes to doing tests against triangle meshes. + // Therefore, we try out a short trace first, then only fall back to the full length trace if needed. + // This trace needs to be at least a couple units long, but there's no one particular ideal length. + // The length of 2.1 chosen here is a "works well in practice after testing a few random lengths" value. + // (Also, we only do this short test if the intended collision trace is long enough for it to make sense.) + const float fallback_length = 2.1f; + bool doing_short_trace = false; + // For some reason, typical scenes perform a little better if we increase the threshold length for the length + // test. (Multiplying by 2 in 'square distance' units gives us about 1.4x the threshold length. In benchmarks + // this was + // slightly better for the performance of normal scenes than 4.0, and just plain better than 1.0.) + if (attempt_short_trace && (btend - btstart).length2() > fallback_length * fallback_length * 2.0) { - btend = Misc::Convert::toBullet(end); - const auto newTraceCallback = sweepHelper(actor, btstart, btend, world, false); + btend = btstart + (btend - btstart).normalized() * fallback_length; + doing_short_trace = true; + } - if(newTraceCallback.hasHit()) + const auto traceCallback = sweepHelper(actor, btstart, btend, world, false); + + // Copy the hit data over to our trace results struct: + if (traceCallback.hasHit()) + { + mFraction = traceCallback.m_closestHitFraction; + // ensure fraction is correct (covers intended distance traveled instead of actual distance traveled) + if (doing_short_trace && (end - start).length2() > 0.0) + mFraction *= (btend - btstart).length() / (end - start).length(); + mPlaneNormal = Misc::Convert::toOsg(traceCallback.m_hitNormalWorld); + mEndPos = (end - start) * mFraction + start; + mHitPoint = Misc::Convert::toOsg(traceCallback.m_hitPointWorld); + mHitObject = traceCallback.m_hitCollisionObject; + } + else + { + if (doing_short_trace) { - mFraction = newTraceCallback.m_closestHitFraction; - mPlaneNormal = Misc::Convert::toOsg(newTraceCallback.m_hitNormalWorld); - mEndPos = (end-start)*mFraction + start; - mHitPoint = Misc::Convert::toOsg(newTraceCallback.m_hitPointWorld); - mHitObject = newTraceCallback.m_hitCollisionObject; - return; + btend = Misc::Convert::toBullet(end); + const auto newTraceCallback = sweepHelper(actor, btstart, btend, world, false); + + if (newTraceCallback.hasHit()) + { + mFraction = newTraceCallback.m_closestHitFraction; + mPlaneNormal = Misc::Convert::toOsg(newTraceCallback.m_hitNormalWorld); + mEndPos = (end - start) * mFraction + start; + mHitPoint = Misc::Convert::toOsg(newTraceCallback.m_hitPointWorld); + mHitObject = newTraceCallback.m_hitCollisionObject; + return; + } } + // fallthrough + mEndPos = end; + mPlaneNormal = osg::Vec3f(0.0f, 0.0f, 1.0f); + mFraction = 1.0f; + mHitPoint = end; + mHitObject = nullptr; } - // fallthrough - mEndPos = end; - mPlaneNormal = osg::Vec3f(0.0f, 0.0f, 1.0f); - mFraction = 1.0f; - mHitPoint = end; - mHitObject = nullptr; } -} -void ActorTracer::findGround(const Actor* actor, const osg::Vec3f& start, const osg::Vec3f& end, const btCollisionWorld* world) -{ - const auto traceCallback = sweepHelper(actor->getCollisionObject(), Misc::Convert::toBullet(start), Misc::Convert::toBullet(end), world, true); - if(traceCallback.hasHit()) + void ActorTracer::findGround( + const Actor* actor, const osg::Vec3f& start, const osg::Vec3f& end, const btCollisionWorld* world) { - mFraction = traceCallback.m_closestHitFraction; - mPlaneNormal = Misc::Convert::toOsg(traceCallback.m_hitNormalWorld); - mEndPos = (end-start)*mFraction + start; - } - else - { - mEndPos = end; - mPlaneNormal = osg::Vec3f(0.0f, 0.0f, 1.0f); - mFraction = 1.0f; + const auto traceCallback = sweepHelper( + actor->getCollisionObject(), Misc::Convert::toBullet(start), Misc::Convert::toBullet(end), world, true); + if (traceCallback.hasHit()) + { + mFraction = traceCallback.m_closestHitFraction; + mPlaneNormal = Misc::Convert::toOsg(traceCallback.m_hitNormalWorld); + mEndPos = (end - start) * mFraction + start; + } + else + { + mEndPos = end; + mPlaneNormal = osg::Vec3f(0.0f, 0.0f, 1.0f); + mFraction = 1.0f; + } } -} } diff --git a/apps/openmw/mwphysics/trace.h b/apps/openmw/mwphysics/trace.h index af38756b3e..71475e793c 100644 --- a/apps/openmw/mwphysics/trace.h +++ b/apps/openmw/mwphysics/trace.h @@ -6,7 +6,6 @@ class btCollisionObject; class btCollisionWorld; - namespace MWPhysics { class Actor; @@ -20,8 +19,10 @@ namespace MWPhysics float mFraction; - void doTrace(const btCollisionObject *actor, const osg::Vec3f& start, const osg::Vec3f& end, const btCollisionWorld* world, bool attempt_short_trace = false); - void findGround(const Actor* actor, const osg::Vec3f& start, const osg::Vec3f& end, const btCollisionWorld* world); + void doTrace(const btCollisionObject* actor, const osg::Vec3f& start, const osg::Vec3f& end, + const btCollisionWorld* world, bool attempt_short_trace = false); + void findGround( + const Actor* actor, const osg::Vec3f& start, const osg::Vec3f& end, const btCollisionWorld* world); }; } diff --git a/apps/openmw/mwrender/actoranimation.cpp b/apps/openmw/mwrender/actoranimation.cpp index a6caef852e..ed87d64516 100644 --- a/apps/openmw/mwrender/actoranimation.cpp +++ b/apps/openmw/mwrender/actoranimation.cpp @@ -1,13 +1,13 @@ #include "actoranimation.hpp" #include -#include #include +#include #include -#include -#include #include +#include +#include #include #include @@ -25,557 +25,568 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" -#include "../mwworld/ptr.hpp" -#include "../mwworld/class.hpp" +#include "../mwmechanics/actorutil.hpp" +#include "../mwmechanics/creaturestats.hpp" +#include "../mwmechanics/drawstate.hpp" +#include "../mwmechanics/weapontype.hpp" #include "../mwworld/cellstore.hpp" +#include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" #include "../mwworld/inventorystore.hpp" -#include "../mwmechanics/actorutil.hpp" -#include "../mwmechanics/weapontype.hpp" -#include "../mwmechanics/drawstate.hpp" -#include "../mwmechanics/creaturestats.hpp" +#include "../mwworld/ptr.hpp" #include "vismask.hpp" namespace MWRender { -ActorAnimation::ActorAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr parentNode, Resource::ResourceSystem* resourceSystem) - : Animation(ptr, parentNode, resourceSystem) -{ - MWWorld::ContainerStore& store = mPtr.getClass().getContainerStore(mPtr); - - for (MWWorld::ConstContainerStoreIterator iter = store.cbegin(MWWorld::ContainerStore::Type_Light); - iter != store.cend(); ++iter) + ActorAnimation::ActorAnimation( + const MWWorld::Ptr& ptr, osg::ref_ptr parentNode, Resource::ResourceSystem* resourceSystem) + : Animation(ptr, parentNode, resourceSystem) { - const ESM::Light* light = iter->get()->mBase; - if (!(light->mData.mFlags & ESM::Light::Carry)) + MWWorld::ContainerStore& store = mPtr.getClass().getContainerStore(mPtr); + + for (MWWorld::ConstContainerStoreIterator iter = store.cbegin(MWWorld::ContainerStore::Type_Light); + iter != store.cend(); ++iter) { - addHiddenItemLight(*iter, light); + const ESM::Light* light = iter->get()->mBase; + if (!(light->mData.mFlags & ESM::Light::Carry)) + { + addHiddenItemLight(*iter, light); + } } - } - // Make sure we cleaned object from effects, just in cast if we re-use node - removeEffects(); -} - -ActorAnimation::~ActorAnimation() = default; + // Make sure we cleaned object from effects, just in cast if we re-use node + removeEffects(); + } -PartHolderPtr ActorAnimation::attachMesh(const std::string& model, std::string_view bonename, bool enchantedGlow, osg::Vec4f* glowColor) -{ - osg::Group* parent = getBoneByName(bonename); - if (!parent) - return nullptr; + ActorAnimation::~ActorAnimation() = default; - osg::ref_ptr instance = mResourceSystem->getSceneManager()->getInstance(model, parent); + PartHolderPtr ActorAnimation::attachMesh( + const std::string& model, std::string_view bonename, bool enchantedGlow, osg::Vec4f* glowColor) + { + osg::Group* parent = getBoneByName(bonename); + if (!parent) + return nullptr; - const NodeMap& nodeMap = getNodeMap(); - NodeMap::const_iterator found = nodeMap.find(bonename); - if (found == nodeMap.end()) - return {}; + osg::ref_ptr instance = mResourceSystem->getSceneManager()->getInstance(model, parent); - if (enchantedGlow) - mGlowUpdater = SceneUtil::addEnchantedGlow(instance, mResourceSystem, *glowColor); + const NodeMap& nodeMap = getNodeMap(); + NodeMap::const_iterator found = nodeMap.find(bonename); + if (found == nodeMap.end()) + return {}; - return std::make_unique(instance); -} + if (enchantedGlow) + mGlowUpdater = SceneUtil::addEnchantedGlow(instance, mResourceSystem, *glowColor); -osg::ref_ptr ActorAnimation::attach(const std::string& model, std::string_view bonename, std::string_view bonefilter, bool isLight) -{ - osg::ref_ptr templateNode = mResourceSystem->getSceneManager()->getTemplate(model); + return std::make_unique(instance); + } - const NodeMap& nodeMap = getNodeMap(); - auto found = nodeMap.find(bonename); - if (found == nodeMap.end()) - throw std::runtime_error("Can't find attachment node " + std::string{bonename}); - if(isLight) + osg::ref_ptr ActorAnimation::attach( + const std::string& model, std::string_view bonename, std::string_view bonefilter, bool isLight) { - osg::Quat rotation(osg::DegreesToRadians(-90.f), osg::Vec3f(1,0,0)); - return SceneUtil::attach(templateNode, mObjectRoot, bonefilter, found->second, mResourceSystem->getSceneManager(), &rotation); + osg::ref_ptr templateNode = mResourceSystem->getSceneManager()->getTemplate(model); + + const NodeMap& nodeMap = getNodeMap(); + auto found = nodeMap.find(bonename); + if (found == nodeMap.end()) + throw std::runtime_error("Can't find attachment node " + std::string{ bonename }); + if (isLight) + { + osg::Quat rotation(osg::DegreesToRadians(-90.f), osg::Vec3f(1, 0, 0)); + return SceneUtil::attach( + templateNode, mObjectRoot, bonefilter, found->second, mResourceSystem->getSceneManager(), &rotation); + } + return SceneUtil::attach( + templateNode, mObjectRoot, bonefilter, found->second, mResourceSystem->getSceneManager()); } - return SceneUtil::attach(templateNode, mObjectRoot, bonefilter, found->second, mResourceSystem->getSceneManager()); -} -std::string ActorAnimation::getShieldMesh(const MWWorld::ConstPtr& shield, bool female) const -{ - const ESM::Armor *armor = shield.get()->mBase; - const std::vector& bodyparts = armor->mParts.mParts; - // Try to recover the body part model, use ground model as a fallback otherwise. - if (!bodyparts.empty()) + std::string ActorAnimation::getShieldMesh(const MWWorld::ConstPtr& shield, bool female) const { - const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); - const MWWorld::Store &partStore = store.get(); - for (const auto& part : bodyparts) + const ESM::Armor* armor = shield.get()->mBase; + const std::vector& bodyparts = armor->mParts.mParts; + // Try to recover the body part model, use ground model as a fallback otherwise. + if (!bodyparts.empty()) { - if (part.mPart != ESM::PRT_Shield) - continue; - - std::string_view bodypartName; - if (female && !part.mFemale.empty()) - bodypartName = part.mFemale; - else if (!part.mMale.empty()) - bodypartName = part.mMale; - - if (!bodypartName.empty()) + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + const MWWorld::Store& partStore = store.get(); + for (const auto& part : bodyparts) { - const ESM::BodyPart *bodypart = partStore.search(bodypartName); - if (bodypart == nullptr || bodypart->mData.mType != ESM::BodyPart::MT_Armor) - return std::string(); - if (!bodypart->mModel.empty()) - return Misc::ResourceHelpers::correctMeshPath(bodypart->mModel, - MWBase::Environment::get().getResourceSystem()->getVFS()); + if (part.mPart != ESM::PRT_Shield) + continue; + + std::string_view bodypartName; + if (female && !part.mFemale.empty()) + bodypartName = part.mFemale; + else if (!part.mMale.empty()) + bodypartName = part.mMale; + + if (!bodypartName.empty()) + { + const ESM::BodyPart* bodypart = partStore.search(bodypartName); + if (bodypart == nullptr || bodypart->mData.mType != ESM::BodyPart::MT_Armor) + return std::string(); + if (!bodypart->mModel.empty()) + return Misc::ResourceHelpers::correctMeshPath( + bodypart->mModel, MWBase::Environment::get().getResourceSystem()->getVFS()); + } } } + return shield.getClass().getModel(shield); } - return shield.getClass().getModel(shield); -} -std::string ActorAnimation::getSheathedShieldMesh(const MWWorld::ConstPtr& shield) const -{ - std::string mesh = getShieldMesh(shield, false); + std::string ActorAnimation::getSheathedShieldMesh(const MWWorld::ConstPtr& shield) const + { + std::string mesh = getShieldMesh(shield, false); - if (mesh.empty()) - return mesh; + if (mesh.empty()) + return mesh; - std::string holsteredName = mesh; - holsteredName = holsteredName.replace(holsteredName.size()-4, 4, "_sh.nif"); - if(mResourceSystem->getVFS()->exists(holsteredName)) - { - osg::ref_ptr shieldTemplate = mResourceSystem->getSceneManager()->getInstance(holsteredName); - SceneUtil::FindByNameVisitor findVisitor ("Bip01 Sheath"); - shieldTemplate->accept(findVisitor); - osg::ref_ptr sheathNode = findVisitor.mFoundNode; - if(!sheathNode) - return std::string(); - } + std::string holsteredName = mesh; + holsteredName = holsteredName.replace(holsteredName.size() - 4, 4, "_sh.nif"); + if (mResourceSystem->getVFS()->exists(holsteredName)) + { + osg::ref_ptr shieldTemplate = mResourceSystem->getSceneManager()->getInstance(holsteredName); + SceneUtil::FindByNameVisitor findVisitor("Bip01 Sheath"); + shieldTemplate->accept(findVisitor); + osg::ref_ptr sheathNode = findVisitor.mFoundNode; + if (!sheathNode) + return std::string(); + } - return mesh; -} + return mesh; + } -bool ActorAnimation::updateCarriedLeftVisible(const int weaptype) const -{ - static const bool shieldSheathing = Settings::Manager::getBool("shield sheathing", "Game"); - if (shieldSheathing) + bool ActorAnimation::updateCarriedLeftVisible(const int weaptype) const { - const MWWorld::Class &cls = mPtr.getClass(); - MWMechanics::CreatureStats &stats = cls.getCreatureStats(mPtr); - if (cls.hasInventoryStore(mPtr) && stats.getDrawState() == MWMechanics::DrawState::Nothing) + static const bool shieldSheathing = Settings::Manager::getBool("shield sheathing", "Game"); + if (shieldSheathing) { - SceneUtil::FindByNameVisitor findVisitor ("Bip01 AttachShield"); - mObjectRoot->accept(findVisitor); - if (findVisitor.mFoundNode) + const MWWorld::Class& cls = mPtr.getClass(); + MWMechanics::CreatureStats& stats = cls.getCreatureStats(mPtr); + if (cls.hasInventoryStore(mPtr) && stats.getDrawState() == MWMechanics::DrawState::Nothing) { - const MWWorld::InventoryStore& inv = cls.getInventoryStore(mPtr); - const MWWorld::ConstContainerStoreIterator shield = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); - if (shield != inv.end() && shield->getType() == ESM::Armor::sRecordId && !getSheathedShieldMesh(*shield).empty()) - return false; + SceneUtil::FindByNameVisitor findVisitor("Bip01 AttachShield"); + mObjectRoot->accept(findVisitor); + if (findVisitor.mFoundNode) + { + const MWWorld::InventoryStore& inv = cls.getInventoryStore(mPtr); + const MWWorld::ConstContainerStoreIterator shield + = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); + if (shield != inv.end() && shield->getType() == ESM::Armor::sRecordId + && !getSheathedShieldMesh(*shield).empty()) + return false; + } } } + + return !(MWMechanics::getWeaponType(weaptype)->mFlags & ESM::WeaponType::TwoHanded); } - return !(MWMechanics::getWeaponType(weaptype)->mFlags & ESM::WeaponType::TwoHanded); -} + void ActorAnimation::updateHolsteredShield(bool showCarriedLeft) + { + static const bool shieldSheathing = Settings::Manager::getBool("shield sheathing", "Game"); + if (!shieldSheathing) + return; -void ActorAnimation::updateHolsteredShield(bool showCarriedLeft) -{ - static const bool shieldSheathing = Settings::Manager::getBool("shield sheathing", "Game"); - if (!shieldSheathing) - return; + if (!mPtr.getClass().hasInventoryStore(mPtr)) + return; - if (!mPtr.getClass().hasInventoryStore(mPtr)) - return; + mHolsteredShield.reset(); - mHolsteredShield.reset(); + if (showCarriedLeft) + return; - if (showCarriedLeft) - return; + const MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr); + MWWorld::ConstContainerStoreIterator shield = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); + if (shield == inv.end() || shield->getType() != ESM::Armor::sRecordId) + return; - const MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr); - MWWorld::ConstContainerStoreIterator shield = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); - if (shield == inv.end() || shield->getType() != ESM::Armor::sRecordId) - return; + // Can not show holdstered shields with two-handed weapons at all + const MWWorld::ConstContainerStoreIterator weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); + if (weapon == inv.end()) + return; - // Can not show holdstered shields with two-handed weapons at all - const MWWorld::ConstContainerStoreIterator weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); - if(weapon == inv.end()) - return; + auto type = weapon->getType(); + if (type == ESM::Weapon::sRecordId) + { + const MWWorld::LiveCellRef* ref = weapon->get(); + ESM::Weapon::Type weaponType = (ESM::Weapon::Type)ref->mBase->mData.mType; + if (MWMechanics::getWeaponType(weaponType)->mFlags & ESM::WeaponType::TwoHanded) + return; + } - auto type = weapon->getType(); - if(type == ESM::Weapon::sRecordId) - { - const MWWorld::LiveCellRef *ref = weapon->get(); - ESM::Weapon::Type weaponType = (ESM::Weapon::Type)ref->mBase->mData.mType; - if (MWMechanics::getWeaponType(weaponType)->mFlags & ESM::WeaponType::TwoHanded) + std::string mesh = getSheathedShieldMesh(*shield); + if (mesh.empty()) return; - } - std::string mesh = getSheathedShieldMesh(*shield); - if (mesh.empty()) - return; + std::string_view boneName = "Bip01 AttachShield"; + osg::Vec4f glowColor = shield->getClass().getEnchantmentColor(*shield); + std::string holsteredName = mesh; + holsteredName = holsteredName.replace(holsteredName.size() - 4, 4, "_sh.nif"); + bool isEnchanted = !shield->getClass().getEnchantment(*shield).empty(); - std::string_view boneName = "Bip01 AttachShield"; - osg::Vec4f glowColor = shield->getClass().getEnchantmentColor(*shield); - std::string holsteredName = mesh; - holsteredName = holsteredName.replace(holsteredName.size()-4, 4, "_sh.nif"); - bool isEnchanted = !shield->getClass().getEnchantment(*shield).empty(); + // If we have no dedicated sheath model, use basic shield model as fallback. + if (!mResourceSystem->getVFS()->exists(holsteredName)) + mHolsteredShield = attachMesh(mesh, boneName, isEnchanted, &glowColor); + else + mHolsteredShield = attachMesh(holsteredName, boneName, isEnchanted, &glowColor); - // If we have no dedicated sheath model, use basic shield model as fallback. - if (!mResourceSystem->getVFS()->exists(holsteredName)) - mHolsteredShield = attachMesh(mesh, boneName, isEnchanted, &glowColor); - else - mHolsteredShield = attachMesh(holsteredName, boneName, isEnchanted, &glowColor); + if (!mHolsteredShield) + return; - if (!mHolsteredShield) - return; + SceneUtil::FindByNameVisitor findVisitor("Bip01 Sheath"); + mHolsteredShield->getNode()->accept(findVisitor); + osg::Group* shieldNode = findVisitor.mFoundNode; - SceneUtil::FindByNameVisitor findVisitor ("Bip01 Sheath"); - mHolsteredShield->getNode()->accept(findVisitor); - osg::Group* shieldNode = findVisitor.mFoundNode; + // If mesh author declared an empty sheath node, use transformation from this node, but use the common shield + // mesh. This approach allows to tweak shield position without need to store the whole shield mesh in the _sh + // file. + if (shieldNode && !shieldNode->getNumChildren()) + { + osg::ref_ptr fallbackNode = mResourceSystem->getSceneManager()->getInstance(mesh, shieldNode); + if (isEnchanted) + SceneUtil::addEnchantedGlow(shieldNode, mResourceSystem, glowColor); + } + } - // If mesh author declared an empty sheath node, use transformation from this node, but use the common shield mesh. - // This approach allows to tweak shield position without need to store the whole shield mesh in the _sh file. - if (shieldNode && !shieldNode->getNumChildren()) + bool ActorAnimation::useShieldAnimations() const { - osg::ref_ptr fallbackNode = mResourceSystem->getSceneManager()->getInstance(mesh, shieldNode); - if (isEnchanted) - SceneUtil::addEnchantedGlow(shieldNode, mResourceSystem, glowColor); - } -} + static const bool shieldSheathing = Settings::Manager::getBool("shield sheathing", "Game"); + if (!shieldSheathing) + return false; + + const MWWorld::Class& cls = mPtr.getClass(); + if (!cls.hasInventoryStore(mPtr)) + return false; + + if (getTextKeyTime("shield: equip attach") < 0 || getTextKeyTime("shield: unequip detach") < 0) + return false; + + const MWWorld::InventoryStore& inv = cls.getInventoryStore(mPtr); + const MWWorld::ConstContainerStoreIterator weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); + const MWWorld::ConstContainerStoreIterator shield = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); + if (weapon != inv.end() && shield != inv.end() && shield->getType() == ESM::Armor::sRecordId + && !getSheathedShieldMesh(*shield).empty()) + { + auto type = weapon->getType(); + if (type == ESM::Weapon::sRecordId) + { + const MWWorld::LiveCellRef* ref = weapon->get(); + ESM::Weapon::Type weaponType = (ESM::Weapon::Type)ref->mBase->mData.mType; + return !(MWMechanics::getWeaponType(weaponType)->mFlags & ESM::WeaponType::TwoHanded); + } + else if (type == ESM::Lockpick::sRecordId || type == ESM::Probe::sRecordId) + return true; + } -bool ActorAnimation::useShieldAnimations() const -{ - static const bool shieldSheathing = Settings::Manager::getBool("shield sheathing", "Game"); - if (!shieldSheathing) return false; + } - const MWWorld::Class &cls = mPtr.getClass(); - if (!cls.hasInventoryStore(mPtr)) - return false; + osg::Group* ActorAnimation::getBoneByName(std::string_view boneName) const + { + if (!mObjectRoot) + return nullptr; - if (getTextKeyTime("shield: equip attach") < 0 || getTextKeyTime("shield: unequip detach") < 0) - return false; + SceneUtil::FindByNameVisitor findVisitor(boneName); + mObjectRoot->accept(findVisitor); - const MWWorld::InventoryStore& inv = cls.getInventoryStore(mPtr); - const MWWorld::ConstContainerStoreIterator weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); - const MWWorld::ConstContainerStoreIterator shield = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); - if (weapon != inv.end() && shield != inv.end() && - shield->getType() == ESM::Armor::sRecordId && - !getSheathedShieldMesh(*shield).empty()) + return findVisitor.mFoundNode; + } + + std::string_view ActorAnimation::getHolsteredWeaponBoneName(const MWWorld::ConstPtr& weapon) { - auto type = weapon->getType(); - if(type == ESM::Weapon::sRecordId) + if (weapon.isEmpty()) + return {}; + + auto type = weapon.getClass().getType(); + if (type == ESM::Weapon::sRecordId) { - const MWWorld::LiveCellRef *ref = weapon->get(); - ESM::Weapon::Type weaponType = (ESM::Weapon::Type)ref->mBase->mData.mType; - return !(MWMechanics::getWeaponType(weaponType)->mFlags & ESM::WeaponType::TwoHanded); + const MWWorld::LiveCellRef* ref = weapon.get(); + int weaponType = ref->mBase->mData.mType; + return MWMechanics::getWeaponType(weaponType)->mSheathingBone; } - else if (type == ESM::Lockpick::sRecordId || type == ESM::Probe::sRecordId) - return true; + + return {}; } - return false; -} + void ActorAnimation::resetControllers(osg::Node* node) + { + if (node == nullptr) + return; -osg::Group* ActorAnimation::getBoneByName(std::string_view boneName) const -{ - if (!mObjectRoot) - return nullptr; + SceneUtil::ForceControllerSourcesVisitor removeVisitor(std::make_shared()); + node->accept(removeVisitor); + } - SceneUtil::FindByNameVisitor findVisitor(boneName); - mObjectRoot->accept(findVisitor); + void ActorAnimation::updateHolsteredWeapon(bool showHolsteredWeapons) + { + static const bool weaponSheathing = Settings::Manager::getBool("weapon sheathing", "Game"); + if (!weaponSheathing) + return; - return findVisitor.mFoundNode; -} + if (!mPtr.getClass().hasInventoryStore(mPtr)) + return; -std::string_view ActorAnimation::getHolsteredWeaponBoneName(const MWWorld::ConstPtr& weapon) -{ - if(weapon.isEmpty()) - return {}; + mScabbard.reset(); - auto type = weapon.getClass().getType(); - if(type == ESM::Weapon::sRecordId) - { - const MWWorld::LiveCellRef *ref = weapon.get(); - int weaponType = ref->mBase->mData.mType; - return MWMechanics::getWeaponType(weaponType)->mSheathingBone; - } + const MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr); + MWWorld::ConstContainerStoreIterator weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); + if (weapon == inv.end() || weapon->getType() != ESM::Weapon::sRecordId) + return; - return {}; -} + // Since throwing weapons stack themselves, do not show such weapon itself + int type = weapon->get()->mBase->mData.mType; + if (MWMechanics::getWeaponType(type)->mWeaponClass == ESM::WeaponType::Thrown) + showHolsteredWeapons = false; -void ActorAnimation::resetControllers(osg::Node* node) -{ - if (node == nullptr) - return; + std::string mesh = weapon->getClass().getModel(*weapon); + std::string scabbardName = mesh; - SceneUtil::ForceControllerSourcesVisitor removeVisitor(std::make_shared()); - node->accept(removeVisitor); -} + std::string_view boneName = getHolsteredWeaponBoneName(*weapon); + if (mesh.empty() || boneName.empty()) + return; -void ActorAnimation::updateHolsteredWeapon(bool showHolsteredWeapons) -{ - static const bool weaponSheathing = Settings::Manager::getBool("weapon sheathing", "Game"); - if (!weaponSheathing) - return; - - if (!mPtr.getClass().hasInventoryStore(mPtr)) - return; - - mScabbard.reset(); - - const MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr); - MWWorld::ConstContainerStoreIterator weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); - if (weapon == inv.end() || weapon->getType() != ESM::Weapon::sRecordId) - return; - - // Since throwing weapons stack themselves, do not show such weapon itself - int type = weapon->get()->mBase->mData.mType; - if (MWMechanics::getWeaponType(type)->mWeaponClass == ESM::WeaponType::Thrown) - showHolsteredWeapons = false; - - std::string mesh = weapon->getClass().getModel(*weapon); - std::string scabbardName = mesh; - - std::string_view boneName = getHolsteredWeaponBoneName(*weapon); - if (mesh.empty() || boneName.empty()) - return; - - // If the scabbard is not found, use a weapon mesh as fallback. - // Note: it is unclear how to handle time for controllers attached to bodyparts, so disable them for now. - // We use the similar approach for other bodyparts. - scabbardName = scabbardName.replace(scabbardName.size()-4, 4, "_sh.nif"); - bool isEnchanted = !weapon->getClass().getEnchantment(*weapon).empty(); - if(!mResourceSystem->getVFS()->exists(scabbardName)) - { - if (showHolsteredWeapons) + // If the scabbard is not found, use a weapon mesh as fallback. + // Note: it is unclear how to handle time for controllers attached to bodyparts, so disable them for now. + // We use the similar approach for other bodyparts. + scabbardName = scabbardName.replace(scabbardName.size() - 4, 4, "_sh.nif"); + bool isEnchanted = !weapon->getClass().getEnchantment(*weapon).empty(); + if (!mResourceSystem->getVFS()->exists(scabbardName)) { - osg::Vec4f glowColor = weapon->getClass().getEnchantmentColor(*weapon); - mScabbard = attachMesh(mesh, boneName, isEnchanted, &glowColor); - if (mScabbard) - resetControllers(mScabbard->getNode()); - } + if (showHolsteredWeapons) + { + osg::Vec4f glowColor = weapon->getClass().getEnchantmentColor(*weapon); + mScabbard = attachMesh(mesh, boneName, isEnchanted, &glowColor); + if (mScabbard) + resetControllers(mScabbard->getNode()); + } - return; - } + return; + } - mScabbard = attachMesh(scabbardName, boneName); - if (mScabbard) - resetControllers(mScabbard->getNode()); + mScabbard = attachMesh(scabbardName, boneName); + if (mScabbard) + resetControllers(mScabbard->getNode()); - osg::Group* weaponNode = getBoneByName("Bip01 Weapon"); - if (!weaponNode) - return; + osg::Group* weaponNode = getBoneByName("Bip01 Weapon"); + if (!weaponNode) + return; - // When we draw weapon, hide the Weapon node from sheath model. - // Otherwise add the enchanted glow to it. - if (!showHolsteredWeapons) - { - weaponNode->setNodeMask(0); - } - else - { - // If mesh author declared empty weapon node, use transformation from this node, but use the common weapon mesh. - // This approach allows to tweak weapon position without need to store the whole weapon mesh in the _sh file. - if (!weaponNode->getNumChildren()) + // When we draw weapon, hide the Weapon node from sheath model. + // Otherwise add the enchanted glow to it. + if (!showHolsteredWeapons) { - osg::ref_ptr fallbackNode = mResourceSystem->getSceneManager()->getInstance(mesh, weaponNode); - resetControllers(fallbackNode); + weaponNode->setNodeMask(0); } - - if (isEnchanted) + else { - osg::Vec4f glowColor = weapon->getClass().getEnchantmentColor(*weapon); - mGlowUpdater = SceneUtil::addEnchantedGlow(weaponNode, mResourceSystem, glowColor); + // If mesh author declared empty weapon node, use transformation from this node, but use the common weapon + // mesh. This approach allows to tweak weapon position without need to store the whole weapon mesh in the + // _sh file. + if (!weaponNode->getNumChildren()) + { + osg::ref_ptr fallbackNode + = mResourceSystem->getSceneManager()->getInstance(mesh, weaponNode); + resetControllers(fallbackNode); + } + + if (isEnchanted) + { + osg::Vec4f glowColor = weapon->getClass().getEnchantmentColor(*weapon); + mGlowUpdater = SceneUtil::addEnchantedGlow(weaponNode, mResourceSystem, glowColor); + } } } -} -void ActorAnimation::updateQuiver() -{ - static const bool weaponSheathing = Settings::Manager::getBool("weapon sheathing", "Game"); - if (!weaponSheathing) - return; - - if (!mPtr.getClass().hasInventoryStore(mPtr)) - return; - - const MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr); - MWWorld::ConstContainerStoreIterator weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); - if(weapon == inv.end() || weapon->getType() != ESM::Weapon::sRecordId) - return; - - std::string mesh = weapon->getClass().getModel(*weapon); - std::string_view boneName = getHolsteredWeaponBoneName(*weapon); - if (mesh.empty() || boneName.empty()) - return; - - osg::Group* ammoNode = getBoneByName("Bip01 Ammo"); - if (!ammoNode) - return; - - // Special case for throwing weapons - they do not use ammo, but they stack themselves - bool suitableAmmo = false; - MWWorld::ConstContainerStoreIterator ammo = weapon; - unsigned int ammoCount = 0; - int type = weapon->get()->mBase->mData.mType; - const auto& weaponType = MWMechanics::getWeaponType(type); - if (weaponType->mWeaponClass == ESM::WeaponType::Thrown) + void ActorAnimation::updateQuiver() { - ammoCount = ammo->getRefData().getCount(); - osg::Group* throwingWeaponNode = getBoneByName(weaponType->mAttachBone); - if (throwingWeaponNode && throwingWeaponNode->getNumChildren()) - ammoCount--; + static const bool weaponSheathing = Settings::Manager::getBool("weapon sheathing", "Game"); + if (!weaponSheathing) + return; - suitableAmmo = true; - } - else - { - ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition); - if (ammo == inv.end()) + if (!mPtr.getClass().hasInventoryStore(mPtr)) return; - ammoCount = ammo->getRefData().getCount(); - bool arrowAttached = isArrowAttached(); - if (arrowAttached) - ammoCount--; + const MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr); + MWWorld::ConstContainerStoreIterator weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); + if (weapon == inv.end() || weapon->getType() != ESM::Weapon::sRecordId) + return; - suitableAmmo = ammo->get()->mBase->mData.mType == weaponType->mAmmoType; - } + std::string mesh = weapon->getClass().getModel(*weapon); + std::string_view boneName = getHolsteredWeaponBoneName(*weapon); + if (mesh.empty() || boneName.empty()) + return; - if (!suitableAmmo) - return; + osg::Group* ammoNode = getBoneByName("Bip01 Ammo"); + if (!ammoNode) + return; - // We should not show more ammo than equipped and more than quiver mesh has - ammoCount = std::min(ammoCount, ammoNode->getNumChildren()); + // Special case for throwing weapons - they do not use ammo, but they stack themselves + bool suitableAmmo = false; + MWWorld::ConstContainerStoreIterator ammo = weapon; + unsigned int ammoCount = 0; + int type = weapon->get()->mBase->mData.mType; + const auto& weaponType = MWMechanics::getWeaponType(type); + if (weaponType->mWeaponClass == ESM::WeaponType::Thrown) + { + ammoCount = ammo->getRefData().getCount(); + osg::Group* throwingWeaponNode = getBoneByName(weaponType->mAttachBone); + if (throwingWeaponNode && throwingWeaponNode->getNumChildren()) + ammoCount--; - // Remove existing ammo nodes - for (unsigned int i=0; igetNumChildren(); ++i) - { - osg::ref_ptr arrowNode = ammoNode->getChild(i)->asGroup(); - if (!arrowNode->getNumChildren()) - continue; + suitableAmmo = true; + } + else + { + ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition); + if (ammo == inv.end()) + return; - osg::ref_ptr arrowChildNode = arrowNode->getChild(0); - arrowNode->removeChild(arrowChildNode); - } + ammoCount = ammo->getRefData().getCount(); + bool arrowAttached = isArrowAttached(); + if (arrowAttached) + ammoCount--; - // Add new ones - osg::Vec4f glowColor = ammo->getClass().getEnchantmentColor(*ammo); - std::string model = ammo->getClass().getModel(*ammo); - for (unsigned int i=0; i arrowNode = ammoNode->getChild(i)->asGroup(); - osg::ref_ptr arrow = mResourceSystem->getSceneManager()->getInstance(model, arrowNode); - if (!ammo->getClass().getEnchantment(*ammo).empty()) - mGlowUpdater = SceneUtil::addEnchantedGlow(arrow, mResourceSystem, glowColor); + suitableAmmo = ammo->get()->mBase->mData.mType == weaponType->mAmmoType; + } + + if (!suitableAmmo) + return; + + // We should not show more ammo than equipped and more than quiver mesh has + ammoCount = std::min(ammoCount, ammoNode->getNumChildren()); + + // Remove existing ammo nodes + for (unsigned int i = 0; i < ammoNode->getNumChildren(); ++i) + { + osg::ref_ptr arrowNode = ammoNode->getChild(i)->asGroup(); + if (!arrowNode->getNumChildren()) + continue; + + osg::ref_ptr arrowChildNode = arrowNode->getChild(0); + arrowNode->removeChild(arrowChildNode); + } + + // Add new ones + osg::Vec4f glowColor = ammo->getClass().getEnchantmentColor(*ammo); + std::string model = ammo->getClass().getModel(*ammo); + for (unsigned int i = 0; i < ammoCount; ++i) + { + osg::ref_ptr arrowNode = ammoNode->getChild(i)->asGroup(); + osg::ref_ptr arrow = mResourceSystem->getSceneManager()->getInstance(model, arrowNode); + if (!ammo->getClass().getEnchantment(*ammo).empty()) + mGlowUpdater = SceneUtil::addEnchantedGlow(arrow, mResourceSystem, glowColor); + } } -} -void ActorAnimation::itemAdded(const MWWorld::ConstPtr& item, int /*count*/) -{ - if (item.getType() == ESM::Light::sRecordId) + void ActorAnimation::itemAdded(const MWWorld::ConstPtr& item, int /*count*/) { - const ESM::Light* light = item.get()->mBase; - if (!(light->mData.mFlags & ESM::Light::Carry)) + if (item.getType() == ESM::Light::sRecordId) { - addHiddenItemLight(item, light); + const ESM::Light* light = item.get()->mBase; + if (!(light->mData.mFlags & ESM::Light::Carry)) + { + addHiddenItemLight(item, light); + } } - } - if (!mPtr.getClass().hasInventoryStore(mPtr)) - return; + if (!mPtr.getClass().hasInventoryStore(mPtr)) + return; - // If the count of equipped ammo or throwing weapon was changed, we should update quiver - const MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr); - MWWorld::ConstContainerStoreIterator weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); - if(weapon == inv.end() || weapon->getType() != ESM::Weapon::sRecordId) - return; + // If the count of equipped ammo or throwing weapon was changed, we should update quiver + const MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr); + MWWorld::ConstContainerStoreIterator weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); + if (weapon == inv.end() || weapon->getType() != ESM::Weapon::sRecordId) + return; - MWWorld::ConstContainerStoreIterator ammo = inv.end(); - int type = weapon->get()->mBase->mData.mType; - if (MWMechanics::getWeaponType(type)->mWeaponClass == ESM::WeaponType::Thrown) - ammo = weapon; - else - ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition); + MWWorld::ConstContainerStoreIterator ammo = inv.end(); + int type = weapon->get()->mBase->mData.mType; + if (MWMechanics::getWeaponType(type)->mWeaponClass == ESM::WeaponType::Thrown) + ammo = weapon; + else + ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition); - if(ammo != inv.end() && item.getCellRef().getRefId() == ammo->getCellRef().getRefId()) - updateQuiver(); -} + if (ammo != inv.end() && item.getCellRef().getRefId() == ammo->getCellRef().getRefId()) + updateQuiver(); + } -void ActorAnimation::itemRemoved(const MWWorld::ConstPtr& item, int /*count*/) -{ - if (item.getType() == ESM::Light::sRecordId) + void ActorAnimation::itemRemoved(const MWWorld::ConstPtr& item, int /*count*/) { - ItemLightMap::iterator iter = mItemLights.find(item); - if (iter != mItemLights.end()) + if (item.getType() == ESM::Light::sRecordId) { - if (!item.getRefData().getCount()) + ItemLightMap::iterator iter = mItemLights.find(item); + if (iter != mItemLights.end()) { - removeHiddenItemLight(item); + if (!item.getRefData().getCount()) + { + removeHiddenItemLight(item); + } } } - } - if (!mPtr.getClass().hasInventoryStore(mPtr)) - return; - - // If the count of equipped ammo or throwing weapon was changed, we should update quiver - const MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr); - MWWorld::ConstContainerStoreIterator weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); - if(weapon == inv.end() || weapon->getType() != ESM::Weapon::sRecordId) - return; + if (!mPtr.getClass().hasInventoryStore(mPtr)) + return; - MWWorld::ConstContainerStoreIterator ammo = inv.end(); - int type = weapon->get()->mBase->mData.mType; - if (MWMechanics::getWeaponType(type)->mWeaponClass == ESM::WeaponType::Thrown) - ammo = weapon; - else - ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition); + // If the count of equipped ammo or throwing weapon was changed, we should update quiver + const MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr); + MWWorld::ConstContainerStoreIterator weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); + if (weapon == inv.end() || weapon->getType() != ESM::Weapon::sRecordId) + return; - if(ammo != inv.end() && item.getCellRef().getRefId() == ammo->getCellRef().getRefId()) - updateQuiver(); -} + MWWorld::ConstContainerStoreIterator ammo = inv.end(); + int type = weapon->get()->mBase->mData.mType; + if (MWMechanics::getWeaponType(type)->mWeaponClass == ESM::WeaponType::Thrown) + ammo = weapon; + else + ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition); -void ActorAnimation::addHiddenItemLight(const MWWorld::ConstPtr& item, const ESM::Light* esmLight) -{ - if (mItemLights.find(item) != mItemLights.end()) - return; + if (ammo != inv.end() && item.getCellRef().getRefId() == ammo->getCellRef().getRefId()) + updateQuiver(); + } - bool exterior = mPtr.isInCell() && mPtr.getCell()->getCell()->isExterior(); + void ActorAnimation::addHiddenItemLight(const MWWorld::ConstPtr& item, const ESM::Light* esmLight) + { + if (mItemLights.find(item) != mItemLights.end()) + return; - osg::Vec4f ambient(1,1,1,1); - osg::ref_ptr lightSource = SceneUtil::createLightSource(esmLight, Mask_Lighting, exterior, ambient); + bool exterior = mPtr.isInCell() && mPtr.getCell()->getCell()->isExterior(); - mInsert->addChild(lightSource); + osg::Vec4f ambient(1, 1, 1, 1); + osg::ref_ptr lightSource + = SceneUtil::createLightSource(esmLight, Mask_Lighting, exterior, ambient); - if (mLightListCallback && mPtr == MWMechanics::getPlayer()) - mLightListCallback->getIgnoredLightSources().insert(lightSource.get()); + mInsert->addChild(lightSource); - mItemLights.insert(std::make_pair(item, lightSource)); -} + if (mLightListCallback && mPtr == MWMechanics::getPlayer()) + mLightListCallback->getIgnoredLightSources().insert(lightSource.get()); -void ActorAnimation::removeHiddenItemLight(const MWWorld::ConstPtr& item) -{ - ItemLightMap::iterator iter = mItemLights.find(item); - if (iter == mItemLights.end()) - return; + mItemLights.insert(std::make_pair(item, lightSource)); + } - if (mLightListCallback && mPtr == MWMechanics::getPlayer()) + void ActorAnimation::removeHiddenItemLight(const MWWorld::ConstPtr& item) { - std::set::iterator ignoredIter = mLightListCallback->getIgnoredLightSources().find(iter->second.get()); - if (ignoredIter != mLightListCallback->getIgnoredLightSources().end()) - mLightListCallback->getIgnoredLightSources().erase(ignoredIter); - } + ItemLightMap::iterator iter = mItemLights.find(item); + if (iter == mItemLights.end()) + return; - mInsert->removeChild(iter->second); - mItemLights.erase(iter); -} + if (mLightListCallback && mPtr == MWMechanics::getPlayer()) + { + std::set::iterator ignoredIter + = mLightListCallback->getIgnoredLightSources().find(iter->second.get()); + if (ignoredIter != mLightListCallback->getIgnoredLightSources().end()) + mLightListCallback->getIgnoredLightSources().erase(ignoredIter); + } -void ActorAnimation::removeFromScene() -{ - for (const auto& [k, v] : mItemLights) - mInsert->removeChild(v); - Animation::removeFromScene(); -} + mInsert->removeChild(iter->second); + mItemLights.erase(iter); + } + + void ActorAnimation::removeFromScene() + { + for (const auto& [k, v] : mItemLights) + mInsert->removeChild(v); + Animation::removeFromScene(); + } } diff --git a/apps/openmw/mwrender/actoranimation.hpp b/apps/openmw/mwrender/actoranimation.hpp index 788458ac09..71b9ad89cb 100644 --- a/apps/openmw/mwrender/actoranimation.hpp +++ b/apps/openmw/mwrender/actoranimation.hpp @@ -28,10 +28,11 @@ namespace SceneUtil namespace MWRender { -class ActorAnimation : public Animation, public MWWorld::ContainerStoreListener -{ + class ActorAnimation : public Animation, public MWWorld::ContainerStoreListener + { public: - ActorAnimation(const MWWorld::Ptr &ptr, osg::ref_ptr parentNode, Resource::ResourceSystem* resourceSystem); + ActorAnimation( + const MWWorld::Ptr& ptr, osg::ref_ptr parentNode, Resource::ResourceSystem* resourceSystem); virtual ~ActorAnimation(); void itemAdded(const MWWorld::ConstPtr& item, int count) override; @@ -50,13 +51,15 @@ class ActorAnimation : public Animation, public MWWorld::ContainerStoreListener std::string getShieldMesh(const MWWorld::ConstPtr& shield, bool female) const; virtual std::string getSheathedShieldMesh(const MWWorld::ConstPtr& shield) const; virtual std::string_view getHolsteredWeaponBoneName(const MWWorld::ConstPtr& weapon); - virtual PartHolderPtr attachMesh(const std::string& model, std::string_view bonename, bool enchantedGlow, osg::Vec4f* glowColor); + virtual PartHolderPtr attachMesh( + const std::string& model, std::string_view bonename, bool enchantedGlow, osg::Vec4f* glowColor); virtual PartHolderPtr attachMesh(const std::string& model, std::string_view bonename) { - osg::Vec4f stubColor = osg::Vec4f(0,0,0,0); + osg::Vec4f stubColor = osg::Vec4f(0, 0, 0, 0); return attachMesh(model, bonename, false, &stubColor); }; - osg::ref_ptr attach(const std::string& model, std::string_view bonename, std::string_view bonefilter, bool isLight); + osg::ref_ptr attach( + const std::string& model, std::string_view bonename, std::string_view bonefilter, bool isLight); PartHolderPtr mScabbard; PartHolderPtr mHolsteredShield; @@ -66,9 +69,9 @@ class ActorAnimation : public Animation, public MWWorld::ContainerStoreListener void removeHiddenItemLight(const MWWorld::ConstPtr& item); void resetControllers(osg::Node* node); - typedef std::map > ItemLightMap; + typedef std::map> ItemLightMap; ItemLightMap mItemLights; -}; + }; } diff --git a/apps/openmw/mwrender/actorspaths.cpp b/apps/openmw/mwrender/actorspaths.cpp index 45b35df4b9..68cf73fb52 100644 --- a/apps/openmw/mwrender/actorspaths.cpp +++ b/apps/openmw/mwrender/actorspaths.cpp @@ -1,15 +1,15 @@ #include "actorspaths.hpp" #include "vismask.hpp" -#include +#include #include #include -#include +#include #include -#include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" #include @@ -38,8 +38,8 @@ namespace MWRender } void ActorsPaths::update(const MWWorld::ConstPtr& actor, const std::deque& path, - const DetourNavigator::AgentBounds& agentBounds, const osg::Vec3f& start, const osg::Vec3f& end, - const DetourNavigator::Settings& settings) + const DetourNavigator::AgentBounds& agentBounds, const osg::Vec3f& start, const osg::Vec3f& end, + const DetourNavigator::Settings& settings) { if (!mEnabled) return; @@ -54,7 +54,7 @@ namespace MWRender MWBase::Environment::get().getResourceSystem()->getSceneManager()->recreateShaders(newGroup, "debug"); newGroup->setNodeMask(Mask_Debug); mRootNode->addChild(newGroup); - mGroups[actor.mRef] = Group {actor.mCell, std::move(newGroup)}; + mGroups[actor.mRef] = Group{ actor.mCell, std::move(newGroup) }; } } @@ -70,7 +70,7 @@ namespace MWRender void ActorsPaths::removeCell(const MWWorld::CellStore* const store) { - for (auto it = mGroups.begin(); it != mGroups.end(); ) + for (auto it = mGroups.begin(); it != mGroups.end();) { if (it->second.mCell == store) { @@ -92,15 +92,15 @@ namespace MWRender void ActorsPaths::enable() { - std::for_each(mGroups.begin(), mGroups.end(), - [&] (const Groups::value_type& v) { mRootNode->addChild(v.second.mNode); }); + std::for_each( + mGroups.begin(), mGroups.end(), [&](const Groups::value_type& v) { mRootNode->addChild(v.second.mNode); }); mEnabled = true; } void ActorsPaths::disable() { std::for_each(mGroups.begin(), mGroups.end(), - [&] (const Groups::value_type& v) { mRootNode->removeChild(v.second.mNode); }); + [&](const Groups::value_type& v) { mRootNode->removeChild(v.second.mNode); }); mEnabled = false; } } diff --git a/apps/openmw/mwrender/actorspaths.hpp b/apps/openmw/mwrender/actorspaths.hpp index 304d5c09b3..d18197b974 100644 --- a/apps/openmw/mwrender/actorspaths.hpp +++ b/apps/openmw/mwrender/actorspaths.hpp @@ -5,9 +5,9 @@ #include -#include #include #include +#include namespace osg { @@ -31,8 +31,8 @@ namespace MWRender bool toggle(); void update(const MWWorld::ConstPtr& actor, const std::deque& path, - const DetourNavigator::AgentBounds& agentBounds, const osg::Vec3f& start, const osg::Vec3f& end, - const DetourNavigator::Settings& settings); + const DetourNavigator::AgentBounds& agentBounds, const osg::Vec3f& start, const osg::Vec3f& end, + const DetourNavigator::Settings& settings); void remove(const MWWorld::ConstPtr& actor); diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 55f444b90d..f11d004f11 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -3,57 +3,57 @@ #include #include -#include #include +#include +#include #include +#include #include -#include -#include -#include #include +#include #include -#include #include +#include +#include +#include +#include +#include +#include #include #include #include -#include -#include -#include -#include -#include #include #include #include -#include -#include #include #include -#include #include +#include +#include #include +#include #include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" -#include "../mwworld/esmstore.hpp" -#include "../mwworld/class.hpp" #include "../mwworld/cellstore.hpp" +#include "../mwworld/class.hpp" #include "../mwworld/containerstore.hpp" +#include "../mwworld/esmstore.hpp" #include "../mwmechanics/character.hpp" // FIXME: for MWMechanics::Priority -#include "vismask.hpp" -#include "util.hpp" #include "rotatecontroller.hpp" +#include "util.hpp" +#include "vismask.hpp" namespace { @@ -63,13 +63,11 @@ namespace MarkDrawablesVisitor(osg::Node::NodeMask mask) : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) , mMask(mask) - { } - - void apply(osg::Drawable& drawable) override { - drawable.setNodeMask(mMask); } + void apply(osg::Drawable& drawable) override { drawable.setNodeMask(mMask); } + private: osg::Node::NodeMask mMask = 0; }; @@ -80,9 +78,10 @@ namespace public: RemoveParticlesVisitor() : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) - { } + { + } - void apply(osg::Node &node) override + void apply(osg::Node& node) override { if (dynamic_cast(&node)) mToRemove.emplace_back(&node); @@ -108,13 +107,14 @@ namespace } private: - std::vector > mToRemove; + std::vector> mToRemove; }; class DayNightCallback : public SceneUtil::NodeCallback { public: - DayNightCallback() : mCurrentState(0) + DayNightCallback() + : mCurrentState(0) { } @@ -141,9 +141,10 @@ namespace public: AddSwitchCallbacksVisitor() : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) - { } + { + } - void apply(osg::Switch &switchNode) override + void apply(osg::Switch& switchNode) override { if (switchNode.getName() == Constants::NightDayLabel) switchNode.addUpdateCallback(new DayNightCallback()); @@ -176,14 +177,14 @@ namespace if (value.starts_with(s1)) { value = value.substr(s1.size()); - if(value.starts_with(s2)) + if (value.starts_with(s2)) return value.substr(s2.size()) == s3; } return false; } - float calcAnimVelocity(const SceneUtil::TextKeyMap& keys, SceneUtil::KeyframeController *nonaccumctrl, - const osg::Vec3f& accum, std::string_view groupname) + float calcAnimVelocity(const SceneUtil::TextKeyMap& keys, SceneUtil::KeyframeController* nonaccumctrl, + const osg::Vec3f& accum, std::string_view groupname) { float starttime = std::numeric_limits::max(); float stoptime = 0.0f; @@ -195,9 +196,10 @@ namespace // As result the animation velocity calculation is not correct, and this incorrect velocity must be replicated, // because otherwise the Creature's Speed (dagoth uthol) would not be sufficient to move fast enough. auto keyiter = keys.rbegin(); - while(keyiter != keys.rend()) + while (keyiter != keys.rend()) { - if(equalsParts(keyiter->second, groupname, ": start") || equalsParts(keyiter->second, groupname, ": loop start")) + if (equalsParts(keyiter->second, groupname, ": start") + || equalsParts(keyiter->second, groupname, ": loop start")) { starttime = keyiter->first; break; @@ -205,7 +207,7 @@ namespace ++keyiter; } keyiter = keys.rbegin(); - while(keyiter != keys.rend()) + while (keyiter != keys.rend()) { if (equalsParts(keyiter->second, groupname, ": stop")) stoptime = keyiter->first; @@ -217,12 +219,12 @@ namespace ++keyiter; } - if(stoptime > starttime) + if (stoptime > starttime) { osg::Vec3f startpos = osg::componentMultiply(nonaccumctrl->getTranslation(starttime), accum); osg::Vec3f endpos = osg::componentMultiply(nonaccumctrl->getTranslation(stoptime), accum); - return (startpos-endpos).length() / (stoptime - starttime); + return (startpos - endpos).length() / (stoptime - starttime); } return 0.0f; @@ -247,7 +249,7 @@ namespace traverse(node); } - std::vector > mFoundBones; + std::vector> mFoundBones; }; class RemoveFinishedCallbackVisitor : public SceneUtil::RemoveVisitor @@ -261,12 +263,9 @@ namespace { } - void apply(osg::Node &node) override - { - traverse(node); - } + void apply(osg::Node& node) override { traverse(node); } - void apply(osg::Group &group) override + void apply(osg::Group& group) override { traverse(group); @@ -285,14 +284,9 @@ namespace } } - void apply(osg::MatrixTransform &node) override - { - traverse(node); - } + void apply(osg::MatrixTransform& node) override { traverse(node); } - void apply(osg::Geometry&) override - { - } + void apply(osg::Geometry&) override {} }; class RemoveCallbackVisitor : public SceneUtil::RemoveVisitor @@ -314,12 +308,9 @@ namespace { } - void apply(osg::Node &node) override - { - traverse(node); - } + void apply(osg::Node& node) override { traverse(node); } - void apply(osg::Group &group) override + void apply(osg::Group& group) override { traverse(group); @@ -338,14 +329,9 @@ namespace } } - void apply(osg::MatrixTransform &node) override - { - traverse(node); - } + void apply(osg::MatrixTransform& node) override { traverse(node); } - void apply(osg::Geometry&) override - { - } + void apply(osg::Geometry&) override {} private: int mEffectId; @@ -354,7 +340,6 @@ namespace class FindVfxCallbacksVisitor : public osg::NodeVisitor { public: - std::vector mCallbacks; FindVfxCallbacksVisitor() @@ -369,12 +354,9 @@ namespace { } - void apply(osg::Node &node) override - { - traverse(node); - } + void apply(osg::Node& node) override { traverse(node); } - void apply(osg::Group &group) override + void apply(osg::Group& group) override { osg::Callback* callback = group.getUpdateCallback(); if (callback) @@ -391,14 +373,9 @@ namespace traverse(group); } - void apply(osg::MatrixTransform &node) override - { - traverse(node); - } + void apply(osg::MatrixTransform& node) override { traverse(node); } - void apply(osg::Geometry&) override - { - } + void apply(osg::Geometry&) override {} private: int mEffectId; @@ -411,7 +388,7 @@ namespace if (!lightModel) { lightModel = new osg::LightModel; - lightModel->setAmbientIntensity({1,1,1,1}); + lightModel->setAmbientIntensity({ 1, 1, 1, 1 }); } return lightModel; @@ -428,16 +405,13 @@ namespace MWRender { } - void setAlpha(const float alpha) - { - mAlpha = alpha; - } + void setAlpha(const float alpha) { mAlpha = alpha; } protected: void setDefaults(osg::StateSet* stateset) override { - osg::BlendFunc* blendfunc (new osg::BlendFunc); - stateset->setAttributeAndModes(blendfunc, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); + osg::BlendFunc* blendfunc(new osg::BlendFunc); + stateset->setAttributeAndModes(blendfunc, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); stateset->setRenderBinMode(osg::StateSet::OVERRIDE_RENDERBIN_DETAILS); @@ -445,15 +419,17 @@ namespace MWRender // FIXME: overriding diffuse/ambient/emissive colors osg::Material* material = new osg::Material; material->setColorMode(osg::Material::OFF); - material->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(1,1,1,mAlpha)); - material->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(1,1,1,1)); - stateset->setAttributeAndModes(material, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); - stateset->addUniform(new osg::Uniform("colorMode", 0), osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); + material->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(1, 1, 1, mAlpha)); + material->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(1, 1, 1, 1)); + stateset->setAttributeAndModes(material, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); + stateset->addUniform( + new osg::Uniform("colorMode", 0), osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); } void apply(osg::StateSet* stateset, osg::NodeVisitor* /*nv*/) override { - osg::Material* material = static_cast(stateset->getAttribute(osg::StateAttribute::MATERIAL)); + osg::Material* material + = static_cast(stateset->getAttribute(osg::StateAttribute::MATERIAL)); material->setAlpha(osg::Material::FRONT_AND_BACK, mAlpha); } @@ -465,7 +441,7 @@ namespace MWRender { osg::ref_ptr mKeyframes; - typedef std::map > ControllerMap; + typedef std::map> ControllerMap; ControllerMap mControllerMap[Animation::sNumBlendMasks]; @@ -534,7 +510,8 @@ namespace MWRender osg::Vec3f mResetAxes; }; - Animation::Animation(const MWWorld::Ptr &ptr, osg::ref_ptr parentNode, Resource::ResourceSystem* resourceSystem) + Animation::Animation( + const MWWorld::Ptr& ptr, osg::ref_ptr parentNode, Resource::ResourceSystem* resourceSystem) : mInsert(parentNode) , mSkeleton(nullptr) , mNodeMapCreated(false) @@ -550,7 +527,7 @@ namespace MWRender , mHasMagicEffects(false) , mAlpha(1.f) { - for(size_t i = 0;i < sNumBlendMasks;i++) + for (size_t i = 0; i < sNumBlendMasks; i++) mAnimationTimePtr[i] = std::make_shared(); mLightListCallback = new SceneUtil::LightListCallback; @@ -564,7 +541,7 @@ namespace MWRender mSkeleton->setActive(static_cast(active)); } - void Animation::updatePtr(const MWWorld::Ptr &ptr) + void Animation::updatePtr(const MWWorld::Ptr& ptr) { mPtr = ptr; } @@ -586,12 +563,12 @@ namespace MWRender "Bip01 R Clavicle", /* Right arm */ }; - while(node != mObjectRoot) + while (node != mObjectRoot) { - const std::string &name = node->getName(); - for(size_t i = 1;i < sNumBlendMasks;i++) + const std::string& name = node->getName(); + for (size_t i = 1; i < sNumBlendMasks; i++) { - if(name == sBlendMaskRoots[i]) + if (name == sBlendMaskRoots[i]) return i; } @@ -603,19 +580,19 @@ namespace MWRender return 0; } - const SceneUtil::TextKeyMap &Animation::AnimSource::getTextKeys() const + const SceneUtil::TextKeyMap& Animation::AnimSource::getTextKeys() const { return mKeyframes->mTextKeys; } - void Animation::loadAllAnimationsInFolder(const std::string &model, const std::string &baseModel) + void Animation::loadAllAnimationsInFolder(const std::string& model, const std::string& baseModel) { std::string animationPath = model; if (animationPath.find("meshes") == 0) { animationPath.replace(0, 6, "animations"); } - animationPath.replace(animationPath.size()-3, 3, "/"); + animationPath.replace(animationPath.size() - 3, 3, "/"); for (const auto& name : mResourceSystem->getVFS()->getRecursiveDirectoryIterator(animationPath)) { @@ -628,36 +605,39 @@ namespace MWRender { std::string kfname = Misc::StringUtils::lowerCase(model); - if(kfname.size() > 4 && kfname.compare(kfname.size()-4, 4, ".nif") == 0) - kfname.replace(kfname.size()-4, 4, ".kf"); + if (kfname.size() > 4 && kfname.compare(kfname.size() - 4, 4, ".nif") == 0) + kfname.replace(kfname.size() - 4, 4, ".kf"); addSingleAnimSource(kfname, baseModel); - static const bool useAdditionalSources = Settings::Manager::getBool ("use additional anim sources", "Game"); + static const bool useAdditionalSources = Settings::Manager::getBool("use additional anim sources", "Game"); if (useAdditionalSources) loadAllAnimationsInFolder(kfname, baseModel); } - void Animation::addSingleAnimSource(const std::string &kfname, const std::string& baseModel) + void Animation::addSingleAnimSource(const std::string& kfname, const std::string& baseModel) { - if(!mResourceSystem->getVFS()->exists(kfname)) + if (!mResourceSystem->getVFS()->exists(kfname)) return; auto animsrc = std::make_shared(); animsrc->mKeyframes = mResourceSystem->getKeyframeManager()->get(kfname); - if (!animsrc->mKeyframes || animsrc->mKeyframes->mTextKeys.empty() || animsrc->mKeyframes->mKeyframeControllers.empty()) + if (!animsrc->mKeyframes || animsrc->mKeyframes->mTextKeys.empty() + || animsrc->mKeyframes->mKeyframeControllers.empty()) return; const NodeMap& nodeMap = getNodeMap(); const auto& controllerMap = animsrc->mKeyframes->mKeyframeControllers; - for (SceneUtil::KeyframeHolder::KeyframeControllerMap::const_iterator it = controllerMap.begin(); it != controllerMap.end(); ++it) + for (SceneUtil::KeyframeHolder::KeyframeControllerMap::const_iterator it = controllerMap.begin(); + it != controllerMap.end(); ++it) { std::string bonename = Misc::StringUtils::lowerCase(it->first); NodeMap::const_iterator found = nodeMap.find(bonename); if (found == nodeMap.end()) { - Log(Debug::Warning) << "Warning: addAnimSource: can't find bone '" + bonename << "' in " << baseModel << " (referenced by " << kfname << ")"; + Log(Debug::Warning) << "Warning: addAnimSource: can't find bone '" + bonename << "' in " << baseModel + << " (referenced by " << kfname << ")"; continue; } @@ -666,7 +646,8 @@ namespace MWRender size_t blendMask = detectBlendMask(node); // clone the controller, because each Animation needs its own ControllerSource - osg::ref_ptr cloned = osg::clone(it->second.get(), osg::CopyOp::SHALLOW_COPY); + osg::ref_ptr cloned + = osg::clone(it->second.get(), osg::CopyOp::SHALLOW_COPY); cloned->setSource(mAnimationTimePtr[blendMask]); animsrc->mControllerMap[blendMask].insert(std::make_pair(bonename, cloned)); @@ -681,18 +662,15 @@ namespace MWRender if (!mAccumRoot) { // Priority matters! bip01 is preferred. - static const std::initializer_list accumRootNames = - { - "bip01", - "root bone" - }; + static const std::initializer_list accumRootNames = { "bip01", "root bone" }; NodeMap::const_iterator found = nodeMap.end(); for (const std::string_view& name : accumRootNames) { found = nodeMap.find(name); if (found == nodeMap.end()) continue; - for (SceneUtil::KeyframeHolder::KeyframeControllerMap::const_iterator it = controllerMap.begin(); it != controllerMap.end(); ++it) + for (SceneUtil::KeyframeHolder::KeyframeControllerMap::const_iterator it = controllerMap.begin(); + it != controllerMap.end(); ++it) { if (Misc::StringUtils::ciEqual(it->first, name)) { @@ -710,7 +688,7 @@ namespace MWRender { mStates.clear(); - for(size_t i = 0;i < sNumBlendMasks;i++) + for (size_t i = 0; i < sNumBlendMasks; i++) mAnimationTimePtr[i]->setTimePtr(std::shared_ptr()); mAccumCtrl = nullptr; @@ -723,9 +701,9 @@ namespace MWRender bool Animation::hasAnimation(std::string_view anim) const { AnimSourceList::const_iterator iter(mAnimSources.begin()); - for(;iter != mAnimSources.end();++iter) + for (; iter != mAnimSources.end(); ++iter) { - const SceneUtil::TextKeyMap &keys = (*iter)->getTextKeys(); + const SceneUtil::TextKeyMap& keys = (*iter)->getTextKeys(); if (keys.hasGroupStart(anim)) return true; } @@ -733,14 +711,14 @@ namespace MWRender return false; } - float Animation::getStartTime(const std::string &groupname) const + float Animation::getStartTime(const std::string& groupname) const { - for(AnimSourceList::const_reverse_iterator iter(mAnimSources.rbegin()); iter != mAnimSources.rend(); ++iter) + for (AnimSourceList::const_reverse_iterator iter(mAnimSources.rbegin()); iter != mAnimSources.rend(); ++iter) { - const SceneUtil::TextKeyMap &keys = (*iter)->getTextKeys(); + const SceneUtil::TextKeyMap& keys = (*iter)->getTextKeys(); const auto found = keys.findGroupStart(groupname); - if(found != keys.end()) + if (found != keys.end()) return found->first; } return -1.f; @@ -748,13 +726,13 @@ namespace MWRender float Animation::getTextKeyTime(std::string_view textKey) const { - for(AnimSourceList::const_reverse_iterator iter(mAnimSources.rbegin()); iter != mAnimSources.rend(); ++iter) + for (AnimSourceList::const_reverse_iterator iter(mAnimSources.rbegin()); iter != mAnimSources.rend(); ++iter) { - const SceneUtil::TextKeyMap &keys = (*iter)->getTextKeys(); + const SceneUtil::TextKeyMap& keys = (*iter)->getTextKeys(); - for(auto iterKey = keys.begin(); iterKey != keys.end(); ++iterKey) + for (auto iterKey = keys.begin(); iterKey != keys.end(); ++iterKey) { - if(iterKey->second.starts_with(textKey)) + if (iterKey->second.starts_with(textKey)) return iterKey->first; } } @@ -762,17 +740,17 @@ namespace MWRender return -1.f; } - void Animation::handleTextKey(AnimState &state, std::string_view groupname, SceneUtil::TextKeyMap::ConstIterator key, - const SceneUtil::TextKeyMap& map) + void Animation::handleTextKey(AnimState& state, std::string_view groupname, + SceneUtil::TextKeyMap::ConstIterator key, const SceneUtil::TextKeyMap& map) { std::string_view evt = key->second; - if(evt.starts_with(groupname) && evt.substr(groupname.size()).starts_with(": ")) + if (evt.starts_with(groupname) && evt.substr(groupname.size()).starts_with(": ")) { size_t off = groupname.size() + 2; - if(evt.substr(off) == "loop start") + if (evt.substr(off) == "loop start") state.mLoopStartTime = key->first; - else if(evt.substr(off) == "loop stop") + else if (evt.substr(off) == "loop stop") state.mLoopStopTime = key->first; } @@ -789,29 +767,30 @@ namespace MWRender } } - void Animation::play(std::string_view groupname, const AnimPriority& priority, int blendMask, bool autodisable, float speedmult, - std::string_view start, std::string_view stop, float startpoint, size_t loops, bool loopfallback) + void Animation::play(std::string_view groupname, const AnimPriority& priority, int blendMask, bool autodisable, + float speedmult, std::string_view start, std::string_view stop, float startpoint, size_t loops, + bool loopfallback) { - if(!mObjectRoot || mAnimSources.empty()) + if (!mObjectRoot || mAnimSources.empty()) return; - if(groupname.empty()) + if (groupname.empty()) { resetActiveGroups(); return; } AnimStateMap::iterator stateiter = mStates.begin(); - while(stateiter != mStates.end()) + while (stateiter != mStates.end()) { - if(stateiter->second.mPriority == priority) + if (stateiter->second.mPriority == priority) mStates.erase(stateiter++); else ++stateiter; } stateiter = mStates.find(groupname); - if(stateiter != mStates.end()) + if (stateiter != mStates.end()) { stateiter->second.mPriority = priority; resetActiveGroups(); @@ -821,10 +800,10 @@ namespace MWRender /* Look in reverse; last-inserted source has priority. */ AnimState state; AnimSourceList::reverse_iterator iter(mAnimSources.rbegin()); - for(;iter != mAnimSources.rend();++iter) + for (; iter != mAnimSources.rend(); ++iter) { - const SceneUtil::TextKeyMap &textkeys = (*iter)->getTextKeys(); - if(reset(state, textkeys, groupname, start, stop, startpoint, loopfallback)) + const SceneUtil::TextKeyMap& textkeys = (*iter)->getTextKeys(); + if (reset(state, textkeys, groupname, start, stop, startpoint, loopfallback)) { state.mSource = *iter; state.mSpeedMult = speedmult; @@ -833,28 +812,28 @@ namespace MWRender state.mPriority = priority; state.mBlendMask = blendMask; state.mAutoDisable = autodisable; - mStates[std::string{groupname}] = state; + mStates[std::string{ groupname }] = state; if (state.mPlaying) { auto textkey = textkeys.lowerBound(state.getTime()); - while(textkey != textkeys.end() && textkey->first <= state.getTime()) + while (textkey != textkeys.end() && textkey->first <= state.getTime()) { handleTextKey(state, groupname, textkey, textkeys); ++textkey; } } - if(state.getTime() >= state.mLoopStopTime && state.mLoopCount > 0) + if (state.getTime() >= state.mLoopStopTime && state.mLoopCount > 0) { state.mLoopCount--; state.setTime(state.mLoopStartTime); state.mPlaying = true; - if(state.getTime() >= state.mLoopStopTime) + if (state.getTime() >= state.mLoopStopTime) break; auto textkey = textkeys.lowerBound(state.getTime()); - while(textkey != textkeys.end() && textkey->first <= state.getTime()) + while (textkey != textkeys.end() && textkey->first <= state.getTime()) { handleTextKey(state, groupname, textkey, textkeys); ++textkey; @@ -868,42 +847,42 @@ namespace MWRender resetActiveGroups(); } - bool Animation::reset(AnimState& state, const SceneUtil::TextKeyMap& keys, std::string_view groupname, std::string_view start, std::string_view stop, float startpoint, bool loopfallback) + bool Animation::reset(AnimState& state, const SceneUtil::TextKeyMap& keys, std::string_view groupname, + std::string_view start, std::string_view stop, float startpoint, bool loopfallback) { // Look for text keys in reverse. This normally wouldn't matter, but for some reason undeadwolf_2.nif has two // separate walkforward keys, and the last one is supposed to be used. auto groupend = keys.rbegin(); - for(;groupend != keys.rend();++groupend) + for (; groupend != keys.rend(); ++groupend) { - if(groupend->second.starts_with(groupname) && - groupend->second.compare(groupname.size(), 2, ": ") == 0) + if (groupend->second.starts_with(groupname) && groupend->second.compare(groupname.size(), 2, ": ") == 0) break; } auto startkey = groupend; - while(startkey != keys.rend() && !equalsParts(startkey->second, groupname, ": ", start)) + while (startkey != keys.rend() && !equalsParts(startkey->second, groupname, ": ", start)) ++startkey; - if(startkey == keys.rend() && start == "loop start") + if (startkey == keys.rend() && start == "loop start") { startkey = groupend; - while(startkey != keys.rend() && !equalsParts(startkey->second, groupname, ": start")) + while (startkey != keys.rend() && !equalsParts(startkey->second, groupname, ": start")) ++startkey; } - if(startkey == keys.rend()) + if (startkey == keys.rend()) return false; auto stopkey = groupend; std::size_t checkLength = groupname.size() + 2 + stop.size(); - while(stopkey != keys.rend() - // We have to ignore extra garbage at the end. - // The Scrib's idle3 animation has "Idle3: Stop." instead of "Idle3: Stop". - // Why, just why? :( - && !equalsParts(std::string_view{stopkey->second}.substr(0, checkLength), groupname, ": ", stop)) + while (stopkey != keys.rend() + // We have to ignore extra garbage at the end. + // The Scrib's idle3 animation has "Idle3: Stop." instead of "Idle3: Stop". + // Why, just why? :( + && !equalsParts(std::string_view{ stopkey->second }.substr(0, checkLength), groupname, ": ", stop)) ++stopkey; - if(stopkey == keys.rend()) + if (stopkey == keys.rend()) return false; - if(startkey->first > stopkey->first) + if (startkey->first > stopkey->first) return false; state.mStartTime = startkey->first; @@ -921,8 +900,9 @@ namespace MWRender state.setTime(state.mStartTime + ((state.mStopTime - state.mStartTime) * startpoint)); - // mLoopStartTime and mLoopStopTime normally get assigned when encountering these keys while playing the animation - // (see handleTextKey). But if startpoint is already past these keys, or start time is == stop time, we need to assign them now. + // mLoopStartTime and mLoopStopTime normally get assigned when encountering these keys while playing the + // animation (see handleTextKey). But if startpoint is already past these keys, or start time is == stop time, + // we need to assign them now. auto key = groupend; for (; key != startkey && key != keys.rend(); ++key) @@ -939,12 +919,12 @@ namespace MWRender return true; } - void Animation::setTextKeyListener(Animation::TextKeyListener *listener) + void Animation::setTextKeyListener(Animation::TextKeyListener* listener) { mTextKeyListener = listener; } - const Animation::NodeMap &Animation::getNodeMap() const + const Animation::NodeMap& Animation::getNodeMap() const { if (!mNodeMapCreated && mObjectRoot) { @@ -971,30 +951,34 @@ namespace MWRender mAccumCtrl = nullptr; - for(size_t blendMask = 0;blendMask < sNumBlendMasks;blendMask++) + for (size_t blendMask = 0; blendMask < sNumBlendMasks; blendMask++) { AnimStateMap::const_iterator active = mStates.end(); AnimStateMap::const_iterator state = mStates.begin(); - for(;state != mStates.end();++state) + for (; state != mStates.end(); ++state) { - if(!(state->second.mBlendMask&(1<second.mBlendMask & (1 << blendMask))) continue; - if(active == mStates.end() || active->second.mPriority[(BoneGroup)blendMask] < state->second.mPriority[(BoneGroup)blendMask]) + if (active == mStates.end() + || active->second.mPriority[(BoneGroup)blendMask] < state->second.mPriority[(BoneGroup)blendMask]) active = state; } - mAnimationTimePtr[blendMask]->setTimePtr(active == mStates.end() ? std::shared_ptr() : active->second.mTime); + mAnimationTimePtr[blendMask]->setTimePtr( + active == mStates.end() ? std::shared_ptr() : active->second.mTime); // add external controllers for the AnimSource active in this blend mask if (active != mStates.end()) { std::shared_ptr animsrc = active->second.mSource; - for (AnimSource::ControllerMap::iterator it = animsrc->mControllerMap[blendMask].begin(); it != animsrc->mControllerMap[blendMask].end(); ++it) + for (AnimSource::ControllerMap::iterator it = animsrc->mControllerMap[blendMask].begin(); + it != animsrc->mControllerMap[blendMask].end(); ++it) { - osg::ref_ptr node = getNodeMap().at(it->first); // this should not throw, we already checked for the node existing in addAnimSource + osg::ref_ptr node = getNodeMap().at( + it->first); // this should not throw, we already checked for the node existing in addAnimSource osg::Callback* callback = it->second->getAsCallback(); node->addUpdateCallback(callback); @@ -1019,47 +1003,50 @@ namespace MWRender addControllers(); } - void Animation::adjustSpeedMult(const std::string &groupname, float speedmult) + void Animation::adjustSpeedMult(const std::string& groupname, float speedmult) { AnimStateMap::iterator state(mStates.find(groupname)); - if(state != mStates.end()) + if (state != mStates.end()) state->second.mSpeedMult = speedmult; } bool Animation::isPlaying(std::string_view groupname) const { AnimStateMap::const_iterator state(mStates.find(groupname)); - if(state != mStates.end()) + if (state != mStates.end()) return state->second.mPlaying; return false; } - bool Animation::getInfo(std::string_view groupname, float *complete, float *speedmult) const + bool Animation::getInfo(std::string_view groupname, float* complete, float* speedmult) const { AnimStateMap::const_iterator iter = mStates.find(groupname); - if(iter == mStates.end()) + if (iter == mStates.end()) { - if(complete) *complete = 0.0f; - if(speedmult) *speedmult = 0.0f; + if (complete) + *complete = 0.0f; + if (speedmult) + *speedmult = 0.0f; return false; } - if(complete) + if (complete) { - if(iter->second.mStopTime > iter->second.mStartTime) - *complete = (iter->second.getTime() - iter->second.mStartTime) / - (iter->second.mStopTime - iter->second.mStartTime); + if (iter->second.mStopTime > iter->second.mStartTime) + *complete = (iter->second.getTime() - iter->second.mStartTime) + / (iter->second.mStopTime - iter->second.mStartTime); else *complete = (iter->second.mPlaying ? 0.0f : 1.0f); } - if(speedmult) *speedmult = iter->second.mSpeedMult; + if (speedmult) + *speedmult = iter->second.mSpeedMult; return true; } - float Animation::getCurrentTime(const std::string &groupname) const + float Animation::getCurrentTime(const std::string& groupname) const { AnimStateMap::const_iterator iter = mStates.find(groupname); - if(iter == mStates.end()) + if (iter == mStates.end()) return -1.f; return iter->second.getTime(); @@ -1068,7 +1055,7 @@ namespace MWRender size_t Animation::getCurrentLoopCount(const std::string& groupname) const { AnimStateMap::const_iterator iter = mStates.find(groupname); - if(iter == mStates.end()) + if (iter == mStates.end()) return 0; return iter->second.mLoopCount; @@ -1077,7 +1064,7 @@ namespace MWRender void Animation::disable(std::string_view groupname) { AnimStateMap::iterator iter = mStates.find(groupname); - if(iter != mStates.end()) + if (iter != mStates.end()) mStates.erase(iter); resetActiveGroups(); } @@ -1093,17 +1080,17 @@ namespace MWRender // Look in reverse; last-inserted source has priority. AnimSourceList::const_reverse_iterator animsrc(mAnimSources.rbegin()); - for(;animsrc != mAnimSources.rend();++animsrc) + for (; animsrc != mAnimSources.rend(); ++animsrc) { - const SceneUtil::TextKeyMap &keys = (*animsrc)->getTextKeys(); + const SceneUtil::TextKeyMap& keys = (*animsrc)->getTextKeys(); if (keys.hasGroupStart(groupname)) break; } - if(animsrc == mAnimSources.rend()) + if (animsrc == mAnimSources.rend()) return 0.0f; float velocity = 0.0f; - const SceneUtil::TextKeyMap &keys = (*animsrc)->getTextKeys(); + const SceneUtil::TextKeyMap& keys = (*animsrc)->getTextKeys(); const AnimSource::ControllerMap& ctrls = (*animsrc)->mControllerMap[0]; for (AnimSource::ControllerMap::const_iterator it = ctrls.begin(); it != ctrls.end(); ++it) @@ -1116,15 +1103,15 @@ namespace MWRender } // If there's no velocity, keep looking - if(!(velocity > 1.0f)) + if (!(velocity > 1.0f)) { AnimSourceList::const_reverse_iterator animiter = mAnimSources.rbegin(); - while(*animiter != *animsrc) + while (*animiter != *animsrc) ++animiter; - while(!(velocity > 1.0f) && ++animiter != mAnimSources.rend()) + while (!(velocity > 1.0f) && ++animiter != mAnimSources.rend()) { - const SceneUtil::TextKeyMap &keys2 = (*animiter)->getTextKeys(); + const SceneUtil::TextKeyMap& keys2 = (*animiter)->getTextKeys(); const AnimSource::ControllerMap& ctrls2 = (*animiter)->mControllerMap[0]; for (AnimSource::ControllerMap::const_iterator it = ctrls2.begin(); it != ctrls2.end(); ++it) @@ -1156,7 +1143,8 @@ namespace MWRender bool hasScriptedAnims = false; for (AnimStateMap::iterator stateiter = mStates.begin(); stateiter != mStates.end(); stateiter++) { - if (stateiter->second.mPriority.contains(int(MWMechanics::Priority_Persistent)) && stateiter->second.mPlaying) + if (stateiter->second.mPriority.contains(int(MWMechanics::Priority_Persistent)) + && stateiter->second.mPlaying) { hasScriptedAnims = true; break; @@ -1165,33 +1153,33 @@ namespace MWRender osg::Vec3f movement(0.f, 0.f, 0.f); AnimStateMap::iterator stateiter = mStates.begin(); - while(stateiter != mStates.end()) + while (stateiter != mStates.end()) { - AnimState &state = stateiter->second; + AnimState& state = stateiter->second; if (hasScriptedAnims && !state.mPriority.contains(int(MWMechanics::Priority_Persistent))) { ++stateiter; continue; } - const SceneUtil::TextKeyMap &textkeys = state.mSource->getTextKeys(); + const SceneUtil::TextKeyMap& textkeys = state.mSource->getTextKeys(); auto textkey = textkeys.upperBound(state.getTime()); float timepassed = duration * state.mSpeedMult; - while(state.mPlaying) + while (state.mPlaying) { if (!state.shouldLoop()) { float targetTime = state.getTime() + timepassed; - if(textkey == textkeys.end() || textkey->first > targetTime) + if (textkey == textkeys.end() || textkey->first > targetTime) { - if(mAccumCtrl && state.mTime == mAnimationTimePtr[0]->getTimePtr()) + if (mAccumCtrl && state.mTime == mAnimationTimePtr[0]->getTimePtr()) updatePosition(state.getTime(), targetTime, movement); state.setTime(std::min(targetTime, state.mStopTime)); } else { - if(mAccumCtrl && state.mTime == mAnimationTimePtr[0]->getTimePtr()) + if (mAccumCtrl && state.mTime == mAnimationTimePtr[0]->getTimePtr()) updatePosition(state.getTime(), textkey->first, movement); state.setTime(textkey->first); } @@ -1199,34 +1187,34 @@ namespace MWRender state.mPlaying = (state.getTime() < state.mStopTime); timepassed = targetTime - state.getTime(); - while(textkey != textkeys.end() && textkey->first <= state.getTime()) + while (textkey != textkeys.end() && textkey->first <= state.getTime()) { handleTextKey(state, stateiter->first, textkey, textkeys); ++textkey; } } - if(state.shouldLoop()) + if (state.shouldLoop()) { state.mLoopCount--; state.setTime(state.mLoopStartTime); state.mPlaying = true; textkey = textkeys.lowerBound(state.getTime()); - while(textkey != textkeys.end() && textkey->first <= state.getTime()) + while (textkey != textkeys.end() && textkey->first <= state.getTime()) { handleTextKey(state, stateiter->first, textkey, textkeys); ++textkey; } - if(state.getTime() >= state.mLoopStopTime) + if (state.getTime() >= state.mLoopStopTime) break; } - if(timepassed <= 0.0f) + if (timepassed <= 0.0f) break; } - if(!state.mPlaying && state.mAutoDisable) + if (!state.mPlaying && state.mAutoDisable) { mStates.erase(stateiter++); @@ -1246,7 +1234,8 @@ namespace MWRender mRootController->setEnabled(enable); if (enable) { - mRootController->setRotate(osg::Quat(mLegsYawRadians, osg::Vec3f(0,0,1)) * osg::Quat(mBodyPitchRadians, osg::Vec3f(1,0,0))); + mRootController->setRotate(osg::Quat(mLegsYawRadians, osg::Vec3f(0, 0, 1)) + * osg::Quat(mBodyPitchRadians, osg::Vec3f(1, 0, 0))); yawOffset = mLegsYawRadians; } } @@ -1257,7 +1246,7 @@ namespace MWRender mSpineController->setEnabled(enable); if (enable) { - mSpineController->setRotate(osg::Quat(yaw, osg::Vec3f(0,0,1))); + mSpineController->setRotate(osg::Quat(yaw, osg::Vec3f(0, 0, 1))); yawOffset = mUpperBodyYawRadians; } } @@ -1267,7 +1256,8 @@ namespace MWRender bool enable = (std::abs(mHeadPitchRadians) > epsilon || std::abs(yaw) > epsilon); mHeadController->setEnabled(enable); if (enable) - mHeadController->setRotate(osg::Quat(mHeadPitchRadians, osg::Vec3f(1,0,0)) * osg::Quat(yaw, osg::Vec3f(0,0,1))); + mHeadController->setRotate( + osg::Quat(mHeadPitchRadians, osg::Vec3f(1, 0, 0)) * osg::Quat(yaw, osg::Vec3f(0, 0, 1))); } // Scripted animations should not cause movement @@ -1280,20 +1270,22 @@ namespace MWRender void Animation::setLoopingEnabled(std::string_view groupname, bool enabled) { AnimStateMap::iterator state(mStates.find(groupname)); - if(state != mStates.end()) + if (state != mStates.end()) state->second.mLoopingEnabled = enabled; } - void loadBonesFromFile(osg::ref_ptr& baseNode, const std::string &model, Resource::ResourceSystem* resourceSystem) + void loadBonesFromFile( + osg::ref_ptr& baseNode, const std::string& model, Resource::ResourceSystem* resourceSystem) { const osg::Node* node = resourceSystem->getSceneManager()->getTemplate(model).get(); - osg::ref_ptr sheathSkeleton (const_cast(node)); // const-trickery required because there is no const version of NodeVisitor + osg::ref_ptr sheathSkeleton( + const_cast(node)); // const-trickery required because there is no const version of NodeVisitor GetExtendedBonesVisitor getBonesVisitor; sheathSkeleton->accept(getBonesVisitor); for (auto& nodePair : getBonesVisitor.mFoundBones) { - SceneUtil::FindByNameVisitor findVisitor (nodePair.second->getName()); + SceneUtil::FindByNameVisitor findVisitor(nodePair.second->getName()); baseNode->accept(findVisitor); osg::Group* sheathParent = findVisitor.mFoundNode; @@ -1305,7 +1297,8 @@ namespace MWRender } } - void injectCustomBones(osg::ref_ptr& node, const std::string& model, Resource::ResourceSystem* resourceSystem) + void injectCustomBones( + osg::ref_ptr& node, const std::string& model, Resource::ResourceSystem* resourceSystem) { if (model.empty()) return; @@ -1315,7 +1308,7 @@ namespace MWRender { animationPath.replace(0, 6, "animations"); } - animationPath.replace(animationPath.size()-4, 4, "/"); + animationPath.replace(animationPath.size() - 4, 4, "/"); for (const auto& name : resourceSystem->getVFS()->getRecursiveDirectoryIterator(animationPath)) { @@ -1324,12 +1317,13 @@ namespace MWRender } } - osg::ref_ptr getModelInstance(Resource::ResourceSystem* resourceSystem, const std::string& model, bool baseonly, bool inject, const std::string& defaultSkeleton) + osg::ref_ptr getModelInstance(Resource::ResourceSystem* resourceSystem, const std::string& model, + bool baseonly, bool inject, const std::string& defaultSkeleton) { Resource::SceneManager* sceneMgr = resourceSystem->getSceneManager(); if (baseonly) { - typedef std::map > Cache; + typedef std::map> Cache; static Cache cache; Cache::iterator found = cache.find(model); if (found == cache.end()) @@ -1367,7 +1361,7 @@ namespace MWRender } } - void Animation::setObjectRoot(const std::string &model, bool forceskeleton, bool baseonly, bool isCreature) + void Animation::setObjectRoot(const std::string& model, bool forceskeleton, bool baseonly, bool isCreature) { osg::ref_ptr previousStateset; if (mObjectRoot) @@ -1388,7 +1382,7 @@ namespace MWRender mAccumRoot = nullptr; mAccumCtrl = nullptr; - static const bool useAdditionalSources = Settings::Manager::getBool ("use additional anim sources", "Game"); + static const bool useAdditionalSources = Settings::Manager::getBool("use additional anim sources", "Game"); std::string defaultSkeleton; bool inject = false; @@ -1396,8 +1390,8 @@ namespace MWRender { if (isCreature) { - MWWorld::LiveCellRef *ref = mPtr.get(); - if(ref->mBase->mFlags & ESM::Creature::Bipedal) + MWWorld::LiveCellRef* ref = mPtr.get(); + if (ref->mBase->mFlags & ESM::Creature::Bipedal) { defaultSkeleton = Settings::Manager::getString("xbaseanim", "Models"); inject = true; @@ -1406,27 +1400,30 @@ namespace MWRender else { inject = true; - MWWorld::LiveCellRef *ref = mPtr.get(); + MWWorld::LiveCellRef* ref = mPtr.get(); if (!ref->mBase->mModel.empty()) { - // If NPC has a custom animation model attached, we should inject bones from default skeleton for given race and gender as well - // Since it is a quite rare case, there should not be a noticable performance loss - // Note: consider that player and werewolves have no custom animation files attached for now - const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); - const ESM::Race *race = store.get().find(ref->mBase->mRace); + // If NPC has a custom animation model attached, we should inject bones from default skeleton for + // given race and gender as well Since it is a quite rare case, there should not be a noticable + // performance loss Note: consider that player and werewolves have no custom animation files + // attached for now + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + const ESM::Race* race = store.get().find(ref->mBase->mRace); bool isBeast = (race->mData.mFlags & ESM::Race::Beast) != 0; bool isFemale = !ref->mBase->isMale(); defaultSkeleton = SceneUtil::getActorSkeleton(false, isFemale, isBeast, false); - defaultSkeleton = Misc::ResourceHelpers::correctActorModelPath(defaultSkeleton, mResourceSystem->getVFS()); + defaultSkeleton + = Misc::ResourceHelpers::correctActorModelPath(defaultSkeleton, mResourceSystem->getVFS()); } } } if (!forceskeleton) { - osg::ref_ptr created = getModelInstance(mResourceSystem, model, baseonly, inject, defaultSkeleton); + osg::ref_ptr created + = getModelInstance(mResourceSystem, model, baseonly, inject, defaultSkeleton); mInsert->addChild(created); mObjectRoot = created->asGroup(); if (!mObjectRoot) @@ -1442,7 +1439,8 @@ namespace MWRender } else { - osg::ref_ptr created = getModelInstance(mResourceSystem, model, baseonly, inject, defaultSkeleton); + osg::ref_ptr created + = getModelInstance(mResourceSystem, model, baseonly, inject, defaultSkeleton); osg::ref_ptr skel = dynamic_cast(created.get()); if (!skel) { @@ -1486,9 +1484,9 @@ namespace MWRender return mObjectRoot.get(); } - void Animation::addSpellCastGlow(const ESM::MagicEffect *effect, float glowDuration) + void Animation::addSpellCastGlow(const ESM::MagicEffect* effect, float glowDuration) { - osg::Vec4f glowColor(1,1,1,1); + osg::Vec4f glowColor(1, 1, 1, 1); glowColor.x() = effect->mData.mRed / 255.f; glowColor.y() = effect->mData.mGreen / 255.f; glowColor.z() = effect->mData.mBlue / 255.f; @@ -1508,7 +1506,7 @@ namespace MWRender } } - void Animation::addExtraLight(osg::ref_ptr parent, const ESM::Light *esmLight) + void Animation::addExtraLight(osg::ref_ptr parent, const ESM::Light* esmLight) { bool exterior = mPtr.isInCell() && mPtr.getCell()->getCell()->isExterior(); @@ -1516,7 +1514,8 @@ namespace MWRender mExtraLightSource->setActorFade(mAlpha); } - void Animation::addEffect(const std::string& model, int effectId, bool loop, std::string_view bonename, std::string_view texture) + void Animation::addEffect( + const std::string& model, int effectId, bool loop, std::string_view bonename, std::string_view texture) { if (!mObjectRoot.get()) return; @@ -1525,7 +1524,8 @@ namespace MWRender FindVfxCallbacksVisitor visitor(effectId); mInsert->accept(visitor); - for (std::vector::iterator it = visitor.mCallbacks.begin(); it != visitor.mCallbacks.end(); ++it) + for (std::vector::iterator it = visitor.mCallbacks.begin(); it != visitor.mCallbacks.end(); + ++it) { UpdateVfxCallback* callback = *it; @@ -1542,7 +1542,7 @@ namespace MWRender { NodeMap::const_iterator found = getNodeMap().find(bonename); if (found == getNodeMap().end()) - throw std::runtime_error("Can't find bone " + std::string{bonename}); + throw std::runtime_error("Can't find bone " + std::string{ bonename }); parentNode = found->second; } @@ -1550,8 +1550,8 @@ namespace MWRender osg::ref_ptr trans = new SceneUtil::PositionAttitudeTransform; if (!mPtr.getClass().isNpc()) { - osg::Vec3f bounds (MWBase::Environment::get().getWorld()->getHalfExtents(mPtr) * 2.f); - float scale = std::max({bounds.x(), bounds.y(), bounds.z() / 2.f}) / 64.f; + osg::Vec3f bounds(MWBase::Environment::get().getWorld()->getHalfExtents(mPtr) * 2.f); + float scale = std::max({ bounds.x(), bounds.y(), bounds.z() / 2.f }) / 64.f; if (scale > 1.f) trans->setScale(osg::Vec3f(scale, scale, scale)); float offset = 0.f; @@ -1568,7 +1568,8 @@ namespace MWRender osg::ref_ptr node = mResourceSystem->getSceneManager()->getInstance(model, trans); // Morrowind has a white ambient light attached to the root VFX node of the scenegraph - node->getOrCreateStateSet()->setAttributeAndModes(getVFXLightModelInstance(), osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); + node->getOrCreateStateSet()->setAttributeAndModes( + getVFXLightModelInstance(), osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); if (mResourceSystem->getSceneManager()->getSupportsNormalsRT()) node->getOrCreateStateSet()->setAttribute(new osg::ColorMaski(1, false, false, false, false)); SceneUtil::FindMaxControllerLengthVisitor findMaxLengthVisitor; @@ -1586,7 +1587,8 @@ namespace MWRender params.mAnimTime = std::make_shared(); trans->addUpdateCallback(new UpdateVfxCallback(params)); - SceneUtil::AssignControllerSourcesVisitor assignVisitor(std::shared_ptr(params.mAnimTime)); + SceneUtil::AssignControllerSourcesVisitor assignVisitor( + std::shared_ptr(params.mAnimTime)); node->accept(assignVisitor); // Notify that this animation has attached magic effects @@ -1608,7 +1610,7 @@ namespace MWRender removeEffect(-1); } - void Animation::getLoopingEffects(std::vector &out) const + void Animation::getLoopingEffects(std::vector& out) const { if (!mHasMagicEffects) return; @@ -1616,7 +1618,8 @@ namespace MWRender FindVfxCallbacksVisitor visitor; mInsert->accept(visitor); - for (std::vector::iterator it = visitor.mCallbacks.begin(); it != visitor.mCallbacks.end(); ++it) + for (std::vector::iterator it = visitor.mCallbacks.begin(); it != visitor.mCallbacks.end(); + ++it) { UpdateVfxCallback* callback = *it; @@ -1645,9 +1648,9 @@ namespace MWRender for (AnimStateMap::const_iterator stateiter = mStates.begin(); stateiter != mStates.end(); ++stateiter) { if (stateiter->second.mPriority.contains(int(MWMechanics::Priority_Hit)) - || stateiter->second.mPriority.contains(int(MWMechanics::Priority_Weapon)) - || stateiter->second.mPriority.contains(int(MWMechanics::Priority_Knockdown)) - || stateiter->second.mPriority.contains(int(MWMechanics::Priority_Death))) + || stateiter->second.mPriority.contains(int(MWMechanics::Priority_Weapon)) + || stateiter->second.mPriority.contains(int(MWMechanics::Priority_Knockdown)) + || stateiter->second.mPriority.contains(int(MWMechanics::Priority_Death))) return false; } return true; @@ -1713,10 +1716,10 @@ namespace MWRender mGlowLight = nullptr; } - osg::ref_ptr light (new osg::Light); - light->setDiffuse(osg::Vec4f(0,0,0,0)); - light->setSpecular(osg::Vec4f(0,0,0,0)); - light->setAmbient(osg::Vec4f(1.5f,1.5f,1.5f,1.f)); + osg::ref_ptr light(new osg::Light); + light->setDiffuse(osg::Vec4f(0, 0, 0, 0)); + light->setSpecular(osg::Vec4f(0, 0, 0, 0)); + light->setAmbient(osg::Vec4f(1.5f, 1.5f, 1.5f, 1.f)); bool isExterior = mPtr.isInCell() && mPtr.getCell()->getCell()->isExterior(); SceneUtil::configureLight(light, radius, isExterior); @@ -1827,7 +1830,8 @@ namespace MWRender // -------------------------------------------------------------------------------- - ObjectAnimation::ObjectAnimation(const MWWorld::Ptr &ptr, const std::string &model, Resource::ResourceSystem* resourceSystem, bool animated, bool allowLight) + ObjectAnimation::ObjectAnimation(const MWWorld::Ptr& ptr, const std::string& model, + Resource::ResourceSystem* resourceSystem, bool animated, bool allowLight) : Animation(ptr, osg::ref_ptr(ptr.getRefData().getBaseNode()), resourceSystem) { if (!model.empty()) @@ -1837,7 +1841,8 @@ namespace MWRender addAnimSource(model, model); if (!ptr.getClass().getEnchantment(ptr).empty()) - mGlowUpdater = SceneUtil::addEnchantedGlow(mObjectRoot, mResourceSystem, ptr.getClass().getEnchantmentColor(ptr)); + mGlowUpdater = SceneUtil::addEnchantedGlow( + mObjectRoot, mResourceSystem, ptr.getClass().getEnchantmentColor(ptr)); } if (ptr.getType() == ESM::Light::sRecordId && allowLight) addExtraLight(getOrCreateObjectRoot(), ptr.get()->mBase); @@ -1849,7 +1854,8 @@ namespace MWRender visitor.remove(); } - if (Settings::Manager::getBool("day night switches", "Game") && SceneUtil::hasUserDescription(mObjectRoot, Constants::NightDayLabel)) + if (Settings::Manager::getBool("day night switches", "Game") + && SceneUtil::hasUserDescription(mObjectRoot, Constants::NightDayLabel)) { AddSwitchCallbacksVisitor visitor; mObjectRoot->accept(visitor); @@ -1888,12 +1894,13 @@ namespace MWRender PartHolder::~PartHolder() { if (mNode.get() && !mNode->getNumParents()) - Log(Debug::Verbose) << "Part \"" << mNode->getName() << "\" has no parents" ; + Log(Debug::Verbose) << "Part \"" << mNode->getName() << "\" has no parents"; if (mNode.get() && mNode->getNumParents()) { if (mNode->getNumParents() > 1) - Log(Debug::Verbose) << "Part \"" << mNode->getName() << "\" has multiple (" << mNode->getNumParents() << ") parents"; + Log(Debug::Verbose) << "Part \"" << mNode->getName() << "\" has multiple (" << mNode->getNumParents() + << ") parents"; mNode->getParent(0)->removeChild(mNode); } } diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index 55f15e3a69..b9a8501bdc 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -3,14 +3,14 @@ #include "../mwworld/ptr.hpp" +#include #include +#include #include #include -#include -#include -#include #include +#include namespace ESM { @@ -35,501 +35,505 @@ namespace SceneUtil namespace MWRender { -class ResetAccumRootCallback; -class RotateController; -class TransparencyUpdater; - -class EffectAnimationTime : public SceneUtil::ControllerSource -{ -private: - float mTime; -public: - float getValue(osg::NodeVisitor* nv) override; - - void addTime(float duration); - void resetTime(float time); - float getTime() const; - - EffectAnimationTime() : mTime(0) { } -}; - -/// @brief Detaches the node from its parent when the object goes out of scope. -class PartHolder -{ -public: - PartHolder(osg::ref_ptr node); - - ~PartHolder(); + class ResetAccumRootCallback; + class RotateController; + class TransparencyUpdater; - const osg::ref_ptr& getNode() const + class EffectAnimationTime : public SceneUtil::ControllerSource { - return mNode; - } - -private: - osg::ref_ptr mNode; - - void operator= (const PartHolder&); - PartHolder(const PartHolder&); -}; -using PartHolderPtr = std::unique_ptr; - -struct EffectParams -{ - std::string mModelName; // Just here so we don't add the same effect twice - std::shared_ptr mAnimTime; - float mMaxControllerLength; - int mEffectId; - bool mLoop; - std::string mBoneName; -}; - -class Animation : public osg::Referenced -{ -public: - enum BoneGroup { - BoneGroup_LowerBody = 0, - BoneGroup_Torso, - BoneGroup_LeftArm, - BoneGroup_RightArm - }; - - enum BlendMask { - BlendMask_LowerBody = 1<<0, - BlendMask_Torso = 1<<1, - BlendMask_LeftArm = 1<<2, - BlendMask_RightArm = 1<<3, - - BlendMask_UpperBody = BlendMask_Torso | BlendMask_LeftArm | BlendMask_RightArm, - - BlendMask_All = BlendMask_LowerBody | BlendMask_UpperBody - }; - /* This is the number of *discrete* blend masks. */ - static constexpr size_t sNumBlendMasks = 4; - - /// Holds an animation priority value for each BoneGroup. - struct AnimPriority - { - /// Convenience constructor, initialises all priorities to the same value. - AnimPriority(int priority) - { - for (unsigned int i=0; i node); - virtual ~TextKeyListener() = default; - }; + ~PartHolder(); - void setTextKeyListener(TextKeyListener* listener); + const osg::ref_ptr& getNode() const { return mNode; } - virtual bool updateCarriedLeftVisible(const int weaptype) const { return false; }; - - typedef std::unordered_map, Misc::StringUtils::CiHash, Misc::StringUtils::CiEqual> NodeMap; - -protected: - class AnimationTime : public SceneUtil::ControllerSource - { private: - std::shared_ptr mTimePtr; - - public: + osg::ref_ptr mNode; - void setTimePtr(std::shared_ptr time) - { mTimePtr = time; } - std::shared_ptr getTimePtr() const - { return mTimePtr; } + void operator=(const PartHolder&); + PartHolder(const PartHolder&); + }; + using PartHolderPtr = std::unique_ptr; - float getValue(osg::NodeVisitor* nv) override; + struct EffectParams + { + std::string mModelName; // Just here so we don't add the same effect twice + std::shared_ptr mAnimTime; + float mMaxControllerLength; + int mEffectId; + bool mLoop; + std::string mBoneName; }; - class NullAnimationTime : public SceneUtil::ControllerSource + class Animation : public osg::Referenced { public: - float getValue(osg::NodeVisitor *nv) override + enum BoneGroup { - return 0.f; - } - }; + BoneGroup_LowerBody = 0, + BoneGroup_Torso, + BoneGroup_LeftArm, + BoneGroup_RightArm + }; - struct AnimSource; + enum BlendMask + { + BlendMask_LowerBody = 1 << 0, + BlendMask_Torso = 1 << 1, + BlendMask_LeftArm = 1 << 2, + BlendMask_RightArm = 1 << 3, - struct AnimState { - std::shared_ptr mSource; - float mStartTime; - float mLoopStartTime; - float mLoopStopTime; - float mStopTime; + BlendMask_UpperBody = BlendMask_Torso | BlendMask_LeftArm | BlendMask_RightArm, - typedef std::shared_ptr TimePtr; - TimePtr mTime; - float mSpeedMult; + BlendMask_All = BlendMask_LowerBody | BlendMask_UpperBody + }; + /* This is the number of *discrete* blend masks. */ + static constexpr size_t sNumBlendMasks = 4; - bool mPlaying; - bool mLoopingEnabled; - size_t mLoopCount; + /// Holds an animation priority value for each BoneGroup. + struct AnimPriority + { + /// Convenience constructor, initialises all priorities to the same value. + AnimPriority(int priority) + { + for (unsigned int i = 0; i < sNumBlendMasks; ++i) + mPriority[i] = priority; + } + + bool operator==(const AnimPriority& other) const + { + for (unsigned int i = 0; i < sNumBlendMasks; ++i) + if (other.mPriority[i] != mPriority[i]) + return false; + return true; + } + + int& operator[](BoneGroup n) { return mPriority[n]; } + + const int& operator[](BoneGroup n) const { return mPriority[n]; } + + bool contains(int priority) const + { + for (unsigned int i = 0; i < sNumBlendMasks; ++i) + if (priority == mPriority[i]) + return true; + return false; + } + + int mPriority[sNumBlendMasks]; + }; + + class TextKeyListener + { + public: + virtual void handleTextKey( + std::string_view groupname, SceneUtil::TextKeyMap::ConstIterator key, const SceneUtil::TextKeyMap& map) + = 0; - AnimPriority mPriority; - int mBlendMask; - bool mAutoDisable; + virtual ~TextKeyListener() = default; + }; - AnimState() : mStartTime(0.0f), mLoopStartTime(0.0f), mLoopStopTime(0.0f), mStopTime(0.0f), - mTime(new float), mSpeedMult(1.0f), mPlaying(false), mLoopingEnabled(true), - mLoopCount(0), mPriority(0), mBlendMask(0), mAutoDisable(true) - { - } - ~AnimState() = default; + void setTextKeyListener(TextKeyListener* listener); - float getTime() const - { - return *mTime; - } - void setTime(float time) - { - *mTime = time; - } + virtual bool updateCarriedLeftVisible(const int weaptype) const { return false; }; - bool shouldLoop() const + typedef std::unordered_map, Misc::StringUtils::CiHash, + Misc::StringUtils::CiEqual> + NodeMap; + + protected: + class AnimationTime : public SceneUtil::ControllerSource { - return getTime() >= mLoopStopTime && mLoopingEnabled && mLoopCount > 0; - } - }; - typedef std::map> AnimStateMap; - AnimStateMap mStates; + private: + std::shared_ptr mTimePtr; - typedef std::vector > AnimSourceList; - AnimSourceList mAnimSources; + public: + void setTimePtr(std::shared_ptr time) { mTimePtr = time; } + std::shared_ptr getTimePtr() const { return mTimePtr; } - osg::ref_ptr mInsert; + float getValue(osg::NodeVisitor* nv) override; + }; - osg::ref_ptr mObjectRoot; - SceneUtil::Skeleton* mSkeleton; + class NullAnimationTime : public SceneUtil::ControllerSource + { + public: + float getValue(osg::NodeVisitor* nv) override { return 0.f; } + }; - // The node expected to accumulate movement during movement animations. - osg::ref_ptr mAccumRoot; + struct AnimSource; - // The controller animating that node. - osg::ref_ptr mAccumCtrl; + struct AnimState + { + std::shared_ptr mSource; + float mStartTime; + float mLoopStartTime; + float mLoopStopTime; + float mStopTime; - // Used to reset the position of the accumulation root every frame - the movement should be applied to the physics system - osg::ref_ptr mResetAccumRootCallback; + typedef std::shared_ptr TimePtr; + TimePtr mTime; + float mSpeedMult; - // Keep track of controllers that we added to our scene graph. - // We may need to rebuild these controllers when the active animation groups / sources change. - std::vector, osg::ref_ptr>> mActiveControllers; + bool mPlaying; + bool mLoopingEnabled; + size_t mLoopCount; - std::shared_ptr mAnimationTimePtr[sNumBlendMasks]; + AnimPriority mPriority; + int mBlendMask; + bool mAutoDisable; - mutable NodeMap mNodeMap; - mutable bool mNodeMapCreated; + AnimState() + : mStartTime(0.0f) + , mLoopStartTime(0.0f) + , mLoopStopTime(0.0f) + , mStopTime(0.0f) + , mTime(new float) + , mSpeedMult(1.0f) + , mPlaying(false) + , mLoopingEnabled(true) + , mLoopCount(0) + , mPriority(0) + , mBlendMask(0) + , mAutoDisable(true) + { + } + ~AnimState() = default; - MWWorld::Ptr mPtr; + float getTime() const { return *mTime; } + void setTime(float time) { *mTime = time; } - Resource::ResourceSystem* mResourceSystem; + bool shouldLoop() const { return getTime() >= mLoopStopTime && mLoopingEnabled && mLoopCount > 0; } + }; + typedef std::map> AnimStateMap; + AnimStateMap mStates; - osg::Vec3f mAccumulate; + typedef std::vector> AnimSourceList; + AnimSourceList mAnimSources; + + osg::ref_ptr mInsert; + + osg::ref_ptr mObjectRoot; + SceneUtil::Skeleton* mSkeleton; - TextKeyListener* mTextKeyListener; + // The node expected to accumulate movement during movement animations. + osg::ref_ptr mAccumRoot; - osg::ref_ptr mHeadController; - osg::ref_ptr mSpineController; - osg::ref_ptr mRootController; - float mHeadYawRadians; - float mHeadPitchRadians; - float mUpperBodyYawRadians; - float mLegsYawRadians; - float mBodyPitchRadians; + // The controller animating that node. + osg::ref_ptr mAccumCtrl; + + // Used to reset the position of the accumulation root every frame - the movement should be applied to the + // physics system + osg::ref_ptr mResetAccumRootCallback; + + // Keep track of controllers that we added to our scene graph. + // We may need to rebuild these controllers when the active animation groups / sources change. + std::vector, osg::ref_ptr>> mActiveControllers; + + std::shared_ptr mAnimationTimePtr[sNumBlendMasks]; + + mutable NodeMap mNodeMap; + mutable bool mNodeMapCreated; + + MWWorld::Ptr mPtr; + + Resource::ResourceSystem* mResourceSystem; + + osg::Vec3f mAccumulate; + + TextKeyListener* mTextKeyListener; + + osg::ref_ptr mHeadController; + osg::ref_ptr mSpineController; + osg::ref_ptr mRootController; + float mHeadYawRadians; + float mHeadPitchRadians; + float mUpperBodyYawRadians; + float mLegsYawRadians; + float mBodyPitchRadians; + + osg::ref_ptr addRotateController(std::string_view bone); + + bool mHasMagicEffects; + + osg::ref_ptr mGlowLight; + osg::ref_ptr mGlowUpdater; + osg::ref_ptr mTransparencyUpdater; + osg::ref_ptr mExtraLightSource; + + float mAlpha; + + mutable std::map> mAnimVelocities; + + osg::ref_ptr mLightListCallback; - osg::ref_ptr addRotateController(std::string_view bone); + const NodeMap& getNodeMap() const; - bool mHasMagicEffects; + /* Sets the appropriate animations on the bone groups based on priority. + */ + void resetActiveGroups(); - osg::ref_ptr mGlowLight; - osg::ref_ptr mGlowUpdater; - osg::ref_ptr mTransparencyUpdater; - osg::ref_ptr mExtraLightSource; + size_t detectBlendMask(const osg::Node* node) const; - float mAlpha; + /* Updates the position of the accum root node for the given time, and + * returns the wanted movement vector from the previous time. */ + void updatePosition(float oldtime, float newtime, osg::Vec3f& position); - mutable std::map> mAnimVelocities; + /* Resets the animation to the time of the specified start marker, without + * moving anything, and set the end time to the specified stop marker. If + * the marker is not found, or if the markers are the same, it returns + * false. + */ + bool reset(AnimState& state, const SceneUtil::TextKeyMap& keys, std::string_view groupname, + std::string_view start, std::string_view stop, float startpoint, bool loopfallback); - osg::ref_ptr mLightListCallback; + void handleTextKey(AnimState& state, std::string_view groupname, SceneUtil::TextKeyMap::ConstIterator key, + const SceneUtil::TextKeyMap& map); - const NodeMap& getNodeMap() const; + /** Sets the root model of the object. + * + * Note that you must make sure all animation sources are cleared before resetting the object + * root. All nodes previously retrieved with getNode will also become invalidated. + * @param forceskeleton Wrap the object root in a Skeleton, even if it contains no skinned parts. Use this if + * you intend to add skinned parts manually. + * @param baseonly If true, then any meshes or particle systems in the model are ignored + * (useful for NPCs, where only the skeleton is needed for the root, and the actual NPC parts are then + * assembled from separate files). + */ + void setObjectRoot(const std::string& model, bool forceskeleton, bool baseonly, bool isCreature); - /* Sets the appropriate animations on the bone groups based on priority. - */ - void resetActiveGroups(); + void loadAllAnimationsInFolder(const std::string& model, const std::string& baseModel); - size_t detectBlendMask(const osg::Node* node) const; + /** Adds the keyframe controllers in the specified model as a new animation source. + * @note Later added animation sources have the highest priority when it comes to finding a particular + * animation. + * @param model The file to add the keyframes for. Note that the .nif file extension will be replaced with .kf. + * @param baseModel The filename of the mObjectRoot, only used for error messages. + */ + void addAnimSource(std::string_view model, const std::string& baseModel); + void addSingleAnimSource(const std::string& model, const std::string& baseModel); - /* Updates the position of the accum root node for the given time, and - * returns the wanted movement vector from the previous time. */ - void updatePosition(float oldtime, float newtime, osg::Vec3f& position); + /** Adds an additional light to the given node using the specified ESM record. */ + void addExtraLight(osg::ref_ptr parent, const ESM::Light* light); - /* Resets the animation to the time of the specified start marker, without - * moving anything, and set the end time to the specified stop marker. If - * the marker is not found, or if the markers are the same, it returns - * false. - */ - bool reset(AnimState &state, const SceneUtil::TextKeyMap &keys, - std::string_view groupname, std::string_view start, std::string_view stop, - float startpoint, bool loopfallback); + void clearAnimSources(); - void handleTextKey(AnimState &state, std::string_view groupname, SceneUtil::TextKeyMap::ConstIterator key, - const SceneUtil::TextKeyMap& map); + /** + * Provided to allow derived classes adding their own controllers. Note, the controllers must be added to + * mActiveControllers so they get cleaned up properly on the next controller rebuild. A controller rebuild may + * be necessary to ensure correct ordering. + */ + virtual void addControllers(); - /** Sets the root model of the object. - * - * Note that you must make sure all animation sources are cleared before resetting the object - * root. All nodes previously retrieved with getNode will also become invalidated. - * @param forceskeleton Wrap the object root in a Skeleton, even if it contains no skinned parts. Use this if you intend to add skinned parts manually. - * @param baseonly If true, then any meshes or particle systems in the model are ignored - * (useful for NPCs, where only the skeleton is needed for the root, and the actual NPC parts are then assembled from separate files). - */ - void setObjectRoot(const std::string &model, bool forceskeleton, bool baseonly, bool isCreature); + public: + Animation( + const MWWorld::Ptr& ptr, osg::ref_ptr parentNode, Resource::ResourceSystem* resourceSystem); + + /// Must be thread safe + virtual ~Animation(); + + MWWorld::ConstPtr getPtr() const { return mPtr; } + + MWWorld::Ptr getPtr() { return mPtr; } + + /// Set active flag on the object skeleton, if one exists. + /// @see SceneUtil::Skeleton::setActive + /// 0 = Inactive, 1 = Active in place, 2 = Active + void setActive(int active); + + osg::Group* getOrCreateObjectRoot(); + + osg::Group* getObjectRoot(); + + /** + * @brief Add an effect mesh attached to a bone or the insert scene node + * @param model + * @param effectId An ID for this effect by which you can identify it later. If this is not wanted, set to -1. + * @param loop Loop the effect. If false, it is removed automatically after it finishes playing. If true, + * you need to remove it manually using removeEffect when the effect should end. + * @param bonename Bone to attach to, or empty string to use the scene node instead + * @param texture override the texture specified in the model's materials - if empty, do not override + * @note Will not add an effect twice. + */ + void addEffect(const std::string& model, int effectId, bool loop = false, std::string_view bonename = {}, + std::string_view texture = {}); + void removeEffect(int effectId); + void removeEffects(); + void getLoopingEffects(std::vector& out) const; + + // Add a spell casting glow to an object. From measuring video taken from the original engine, + // the glow seems to be about 1.5 seconds except for telekinesis, which is 1 second. + void addSpellCastGlow(const ESM::MagicEffect* effect, float glowDuration = 1.5); + + virtual void updatePtr(const MWWorld::Ptr& ptr); + + bool hasAnimation(std::string_view anim) const; + + // Specifies the axis' to accumulate on. Non-accumulated axis will just + // move visually, but not affect the actual movement. Each x/y/z value + // should be on the scale of 0 to 1. + void setAccumulation(const osg::Vec3f& accum); + + /** Plays an animation. + * \param groupname Name of the animation group to play. + * \param priority Priority of the animation. The animation will play on + * bone groups that don't have another animation set of a + * higher priority. + * \param blendMask Bone groups to play the animation on. + * \param autodisable Automatically disable the animation when it stops + * playing. + * \param speedmult Speed multiplier for the animation. + * \param start Key marker from which to start. + * \param stop Key marker to stop at. + * \param startpoint How far in between the two markers to start. 0 starts + * at the start marker, 1 starts at the stop marker. + * \param loops How many times to loop the animation. This will use the + * "loop start" and "loop stop" markers if they exist, + * otherwise it may fall back to "start" and "stop", but only if + * the \a loopFallback parameter is true. + * \param loopFallback Allow looping an animation that has no loop keys, i.e. fall back to use + * the "start" and "stop" keys for looping? + */ + void play(std::string_view groupname, const AnimPriority& priority, int blendMask, bool autodisable, + float speedmult, std::string_view start, std::string_view stop, float startpoint, size_t loops, + bool loopfallback = false); + + /** Adjust the speed multiplier of an already playing animation. + */ + void adjustSpeedMult(const std::string& groupname, float speedmult); + + /** Returns true if the named animation group is playing. */ + bool isPlaying(std::string_view groupname) const; + + /// Returns true if no important animations are currently playing on the upper body. + bool upperBodyReady() const; + + /** Gets info about the given animation group. + * \param groupname Animation group to check. + * \param complete Stores completion amount (0 = at start key, 0.5 = half way between start and stop keys), etc. + * \param speedmult Stores the animation speed multiplier + * \return True if the animation is active, false otherwise. + */ + bool getInfo(std::string_view groupname, float* complete = nullptr, float* speedmult = nullptr) const; + + /// Get the absolute position in the animation track of the first text key with the given group. + float getStartTime(const std::string& groupname) const; + + /// Get the absolute position in the animation track of the text key + float getTextKeyTime(std::string_view textKey) const; + + /// Get the current absolute position in the animation track for the animation that is currently playing from + /// the given group. + float getCurrentTime(const std::string& groupname) const; + + size_t getCurrentLoopCount(const std::string& groupname) const; + + /** Disables the specified animation group; + * \param groupname Animation group to disable. + */ + void disable(std::string_view groupname); + + /** Retrieves the velocity (in units per second) that the animation will move. */ + float getVelocity(std::string_view groupname) const; + + virtual osg::Vec3f runAnimation(float duration); + + void setLoopingEnabled(std::string_view groupname, bool enabled); + + /// This is typically called as part of runAnimation, but may be called manually if needed. + void updateEffects(); + + /// Return a node with the specified name, or nullptr if not existing. + /// @note The matching is case-insensitive. + const osg::Node* getNode(std::string_view name) const; + + virtual bool useShieldAnimations() const { return false; } + virtual bool getWeaponsShown() const { return false; } + virtual void showWeapons(bool showWeapon) {} + virtual bool getCarriedLeftShown() const { return false; } + virtual void showCarriedLeft(bool show) {} + virtual void setWeaponGroup(const std::string& group, bool relativeDuration) {} + virtual void setVampire(bool vampire) {} + /// A value < 1 makes the animation translucent, 1.f = fully opaque + void setAlpha(float alpha); + virtual void setPitchFactor(float factor) {} + virtual void attachArrow() {} + virtual void detachArrow() {} + virtual void releaseArrow(float attackStrength) {} + virtual void enableHeadAnimation(bool enable) {} + // TODO: move outside of this class + /// Makes this object glow, by placing a Light in its center. + /// @param effect Controls the radius and intensity of the light. + virtual void setLightEffect(float effect); + + virtual void setHeadPitch(float pitchRadians); + virtual void setHeadYaw(float yawRadians); + virtual float getHeadPitch() const; + virtual float getHeadYaw() const; + + virtual void setUpperBodyYawRadians(float v) { mUpperBodyYawRadians = v; } + virtual void setLegsYawRadians(float v) { mLegsYawRadians = v; } + virtual float getUpperBodyYawRadians() const { return mUpperBodyYawRadians; } + virtual float getLegsYawRadians() const { return mLegsYawRadians; } + virtual void setBodyPitchRadians(float v) { mBodyPitchRadians = v; } + virtual float getBodyPitchRadians() const { return mBodyPitchRadians; } + + virtual void setAccurateAiming(bool enabled) {} + virtual bool canBeHarvested() const { return false; } + + virtual void removeFromScene(); - void loadAllAnimationsInFolder(const std::string &model, const std::string &baseModel); + private: + Animation(const Animation&); + void operator=(Animation&); + }; - /** Adds the keyframe controllers in the specified model as a new animation source. - * @note Later added animation sources have the highest priority when it comes to finding a particular animation. - * @param model The file to add the keyframes for. Note that the .nif file extension will be replaced with .kf. - * @param baseModel The filename of the mObjectRoot, only used for error messages. - */ - void addAnimSource(std::string_view model, const std::string& baseModel); - void addSingleAnimSource(const std::string &model, const std::string& baseModel); - - /** Adds an additional light to the given node using the specified ESM record. */ - void addExtraLight(osg::ref_ptr parent, const ESM::Light *light); - - void clearAnimSources(); - - /** - * Provided to allow derived classes adding their own controllers. Note, the controllers must be added to mActiveControllers - * so they get cleaned up properly on the next controller rebuild. A controller rebuild may be necessary to ensure correct ordering. - */ - virtual void addControllers(); - -public: - - Animation(const MWWorld::Ptr &ptr, osg::ref_ptr parentNode, Resource::ResourceSystem* resourceSystem); - - /// Must be thread safe - virtual ~Animation(); - - MWWorld::ConstPtr getPtr() const { return mPtr; } - - MWWorld::Ptr getPtr() { return mPtr; } - - /// Set active flag on the object skeleton, if one exists. - /// @see SceneUtil::Skeleton::setActive - /// 0 = Inactive, 1 = Active in place, 2 = Active - void setActive(int active); - - osg::Group* getOrCreateObjectRoot(); - - osg::Group* getObjectRoot(); - - /** - * @brief Add an effect mesh attached to a bone or the insert scene node - * @param model - * @param effectId An ID for this effect by which you can identify it later. If this is not wanted, set to -1. - * @param loop Loop the effect. If false, it is removed automatically after it finishes playing. If true, - * you need to remove it manually using removeEffect when the effect should end. - * @param bonename Bone to attach to, or empty string to use the scene node instead - * @param texture override the texture specified in the model's materials - if empty, do not override - * @note Will not add an effect twice. - */ - void addEffect(const std::string& model, int effectId, bool loop = false, std::string_view bonename = {}, std::string_view texture = {}); - void removeEffect (int effectId); - void removeEffects (); - void getLoopingEffects (std::vector& out) const; - - // Add a spell casting glow to an object. From measuring video taken from the original engine, - // the glow seems to be about 1.5 seconds except for telekinesis, which is 1 second. - void addSpellCastGlow(const ESM::MagicEffect *effect, float glowDuration = 1.5); - - virtual void updatePtr(const MWWorld::Ptr &ptr); - - bool hasAnimation(std::string_view anim) const; - - // Specifies the axis' to accumulate on. Non-accumulated axis will just - // move visually, but not affect the actual movement. Each x/y/z value - // should be on the scale of 0 to 1. - void setAccumulation(const osg::Vec3f& accum); - - /** Plays an animation. - * \param groupname Name of the animation group to play. - * \param priority Priority of the animation. The animation will play on - * bone groups that don't have another animation set of a - * higher priority. - * \param blendMask Bone groups to play the animation on. - * \param autodisable Automatically disable the animation when it stops - * playing. - * \param speedmult Speed multiplier for the animation. - * \param start Key marker from which to start. - * \param stop Key marker to stop at. - * \param startpoint How far in between the two markers to start. 0 starts - * at the start marker, 1 starts at the stop marker. - * \param loops How many times to loop the animation. This will use the - * "loop start" and "loop stop" markers if they exist, - * otherwise it may fall back to "start" and "stop", but only if - * the \a loopFallback parameter is true. - * \param loopFallback Allow looping an animation that has no loop keys, i.e. fall back to use - * the "start" and "stop" keys for looping? - */ - void play(std::string_view groupname, const AnimPriority& priority, int blendMask, bool autodisable, - float speedmult, std::string_view start,std::string_view stop, - float startpoint, size_t loops, bool loopfallback=false); - - /** Adjust the speed multiplier of an already playing animation. - */ - void adjustSpeedMult (const std::string& groupname, float speedmult); - - /** Returns true if the named animation group is playing. */ - bool isPlaying(std::string_view groupname) const; - - /// Returns true if no important animations are currently playing on the upper body. - bool upperBodyReady() const; - - /** Gets info about the given animation group. - * \param groupname Animation group to check. - * \param complete Stores completion amount (0 = at start key, 0.5 = half way between start and stop keys), etc. - * \param speedmult Stores the animation speed multiplier - * \return True if the animation is active, false otherwise. - */ - bool getInfo(std::string_view groupname, float *complete=nullptr, float *speedmult=nullptr) const; - - /// Get the absolute position in the animation track of the first text key with the given group. - float getStartTime(const std::string &groupname) const; - - /// Get the absolute position in the animation track of the text key - float getTextKeyTime(std::string_view textKey) const; - - /// Get the current absolute position in the animation track for the animation that is currently playing from the given group. - float getCurrentTime(const std::string& groupname) const; - - size_t getCurrentLoopCount(const std::string& groupname) const; - - /** Disables the specified animation group; - * \param groupname Animation group to disable. - */ - void disable(std::string_view groupname); - - /** Retrieves the velocity (in units per second) that the animation will move. */ - float getVelocity(std::string_view groupname) const; - - virtual osg::Vec3f runAnimation(float duration); - - void setLoopingEnabled(std::string_view groupname, bool enabled); - - /// This is typically called as part of runAnimation, but may be called manually if needed. - void updateEffects(); - - /// Return a node with the specified name, or nullptr if not existing. - /// @note The matching is case-insensitive. - const osg::Node* getNode(std::string_view name) const; - - virtual bool useShieldAnimations() const { return false; } - virtual bool getWeaponsShown() const { return false; } - virtual void showWeapons(bool showWeapon) {} - virtual bool getCarriedLeftShown() const { return false; } - virtual void showCarriedLeft(bool show) {} - virtual void setWeaponGroup(const std::string& group, bool relativeDuration) {} - virtual void setVampire(bool vampire) {} - /// A value < 1 makes the animation translucent, 1.f = fully opaque - void setAlpha(float alpha); - virtual void setPitchFactor(float factor) {} - virtual void attachArrow() {} - virtual void detachArrow() {} - virtual void releaseArrow(float attackStrength) {} - virtual void enableHeadAnimation(bool enable) {} - // TODO: move outside of this class - /// Makes this object glow, by placing a Light in its center. - /// @param effect Controls the radius and intensity of the light. - virtual void setLightEffect(float effect); - - virtual void setHeadPitch(float pitchRadians); - virtual void setHeadYaw(float yawRadians); - virtual float getHeadPitch() const; - virtual float getHeadYaw() const; - - virtual void setUpperBodyYawRadians(float v) { mUpperBodyYawRadians = v; } - virtual void setLegsYawRadians(float v) { mLegsYawRadians = v; } - virtual float getUpperBodyYawRadians() const { return mUpperBodyYawRadians; } - virtual float getLegsYawRadians() const { return mLegsYawRadians; } - virtual void setBodyPitchRadians(float v) { mBodyPitchRadians = v; } - virtual float getBodyPitchRadians() const { return mBodyPitchRadians; } - - virtual void setAccurateAiming(bool enabled) {} - virtual bool canBeHarvested() const { return false; } - - virtual void removeFromScene(); - -private: - Animation(const Animation&); - void operator=(Animation&); -}; - -class ObjectAnimation : public Animation { -public: - ObjectAnimation(const MWWorld::Ptr& ptr, const std::string &model, Resource::ResourceSystem* resourceSystem, bool animated, bool allowLight); - - bool canBeHarvested() const override; -}; - -class UpdateVfxCallback : public SceneUtil::NodeCallback -{ -public: - UpdateVfxCallback(EffectParams& params) - : mFinished(false) - , mParams(params) - , mStartingTime(0) + class ObjectAnimation : public Animation { - } + public: + ObjectAnimation(const MWWorld::Ptr& ptr, const std::string& model, Resource::ResourceSystem* resourceSystem, + bool animated, bool allowLight); - bool mFinished; - EffectParams mParams; + bool canBeHarvested() const override; + }; - void operator()(osg::Node* node, osg::NodeVisitor* nv); + class UpdateVfxCallback : public SceneUtil::NodeCallback + { + public: + UpdateVfxCallback(EffectParams& params) + : mFinished(false) + , mParams(params) + , mStartingTime(0) + { + } -private: - double mStartingTime; -}; + bool mFinished; + EffectParams mParams; + + void operator()(osg::Node* node, osg::NodeVisitor* nv); + + private: + double mStartingTime; + }; } #endif diff --git a/apps/openmw/mwrender/bulletdebugdraw.cpp b/apps/openmw/mwrender/bulletdebugdraw.cpp index b14b64e771..3fd71d21ec 100644 --- a/apps/openmw/mwrender/bulletdebugdraw.cpp +++ b/apps/openmw/mwrender/bulletdebugdraw.cpp @@ -20,200 +20,204 @@ #include #include -#include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" namespace MWRender { -DebugDrawer::DebugDrawer(osg::ref_ptr parentNode, btCollisionWorld *world, int debugMode) - : mParentNode(parentNode), - mWorld(world) -{ - DebugDrawer::setDebugMode(debugMode); -} + DebugDrawer::DebugDrawer(osg::ref_ptr parentNode, btCollisionWorld* world, int debugMode) + : mParentNode(parentNode) + , mWorld(world) + { + DebugDrawer::setDebugMode(debugMode); + } -void DebugDrawer::createGeometry() -{ - if (!mLinesGeometry) + void DebugDrawer::createGeometry() { - mLinesGeometry = new osg::Geometry; - mTrisGeometry = new osg::Geometry; - mLinesGeometry->setNodeMask(Mask_Debug); - mTrisGeometry->setNodeMask(Mask_Debug); - - mLinesVertices = new osg::Vec3Array; - mTrisVertices = new osg::Vec3Array; - mLinesColors = new osg::Vec4Array; - - mLinesDrawArrays = new osg::DrawArrays(osg::PrimitiveSet::LINES); - mTrisDrawArrays = new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES); - - mLinesGeometry->setUseDisplayList(false); - mLinesGeometry->setVertexArray(mLinesVertices); - mLinesGeometry->setColorArray(mLinesColors); - mLinesGeometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX); - mLinesGeometry->setDataVariance(osg::Object::DYNAMIC); - mLinesGeometry->addPrimitiveSet(mLinesDrawArrays); - - mTrisGeometry->setUseDisplayList(false); - mTrisGeometry->setVertexArray(mTrisVertices); - mTrisGeometry->setDataVariance(osg::Object::DYNAMIC); - mTrisGeometry->addPrimitiveSet(mTrisDrawArrays); - - mParentNode->addChild(mLinesGeometry); - mParentNode->addChild(mTrisGeometry); - - auto* stateSet = new osg::StateSet; - stateSet->setAttributeAndModes(new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE), osg::StateAttribute::ON); - stateSet->setAttributeAndModes(new osg::PolygonOffset(SceneUtil::AutoDepth::isReversed() ? 1.0 : -1.0, SceneUtil::AutoDepth::isReversed() ? 1.0 : -1.0)); - osg::ref_ptr material = new osg::Material; - material->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE); - stateSet->setAttribute(material); - mLinesGeometry->setStateSet(stateSet); - mTrisGeometry->setStateSet(stateSet); - mShapesRoot = new osg::Group; - mShapesRoot->setStateSet(stateSet); - mShapesRoot->setDataVariance(osg::Object::DYNAMIC); - mShapesRoot->setNodeMask(Mask_Debug); - mParentNode->addChild(mShapesRoot); - - MWBase::Environment::get().getResourceSystem()->getSceneManager()->recreateShaders(mLinesGeometry, "debug"); - MWBase::Environment::get().getResourceSystem()->getSceneManager()->recreateShaders(mTrisGeometry, "debug"); - MWBase::Environment::get().getResourceSystem()->getSceneManager()->recreateShaders(mShapesRoot, "debug"); + if (!mLinesGeometry) + { + mLinesGeometry = new osg::Geometry; + mTrisGeometry = new osg::Geometry; + mLinesGeometry->setNodeMask(Mask_Debug); + mTrisGeometry->setNodeMask(Mask_Debug); + + mLinesVertices = new osg::Vec3Array; + mTrisVertices = new osg::Vec3Array; + mLinesColors = new osg::Vec4Array; + + mLinesDrawArrays = new osg::DrawArrays(osg::PrimitiveSet::LINES); + mTrisDrawArrays = new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES); + + mLinesGeometry->setUseDisplayList(false); + mLinesGeometry->setVertexArray(mLinesVertices); + mLinesGeometry->setColorArray(mLinesColors); + mLinesGeometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX); + mLinesGeometry->setDataVariance(osg::Object::DYNAMIC); + mLinesGeometry->addPrimitiveSet(mLinesDrawArrays); + + mTrisGeometry->setUseDisplayList(false); + mTrisGeometry->setVertexArray(mTrisVertices); + mTrisGeometry->setDataVariance(osg::Object::DYNAMIC); + mTrisGeometry->addPrimitiveSet(mTrisDrawArrays); + + mParentNode->addChild(mLinesGeometry); + mParentNode->addChild(mTrisGeometry); + + auto* stateSet = new osg::StateSet; + stateSet->setAttributeAndModes( + new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE), + osg::StateAttribute::ON); + stateSet->setAttributeAndModes(new osg::PolygonOffset( + SceneUtil::AutoDepth::isReversed() ? 1.0 : -1.0, SceneUtil::AutoDepth::isReversed() ? 1.0 : -1.0)); + osg::ref_ptr material = new osg::Material; + material->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE); + stateSet->setAttribute(material); + mLinesGeometry->setStateSet(stateSet); + mTrisGeometry->setStateSet(stateSet); + mShapesRoot = new osg::Group; + mShapesRoot->setStateSet(stateSet); + mShapesRoot->setDataVariance(osg::Object::DYNAMIC); + mShapesRoot->setNodeMask(Mask_Debug); + mParentNode->addChild(mShapesRoot); + + MWBase::Environment::get().getResourceSystem()->getSceneManager()->recreateShaders(mLinesGeometry, "debug"); + MWBase::Environment::get().getResourceSystem()->getSceneManager()->recreateShaders(mTrisGeometry, "debug"); + MWBase::Environment::get().getResourceSystem()->getSceneManager()->recreateShaders(mShapesRoot, "debug"); + } } -} -void DebugDrawer::destroyGeometry() -{ - if (mLinesGeometry) + void DebugDrawer::destroyGeometry() { - mParentNode->removeChild(mLinesGeometry); - mParentNode->removeChild(mTrisGeometry); - mParentNode->removeChild(mShapesRoot); - mLinesGeometry = nullptr; - mLinesVertices = nullptr; - mLinesColors = nullptr; - mLinesDrawArrays = nullptr; - mTrisGeometry = nullptr; - mTrisVertices = nullptr; - mTrisDrawArrays = nullptr; + if (mLinesGeometry) + { + mParentNode->removeChild(mLinesGeometry); + mParentNode->removeChild(mTrisGeometry); + mParentNode->removeChild(mShapesRoot); + mLinesGeometry = nullptr; + mLinesVertices = nullptr; + mLinesColors = nullptr; + mLinesDrawArrays = nullptr; + mTrisGeometry = nullptr; + mTrisVertices = nullptr; + mTrisDrawArrays = nullptr; + } } -} -DebugDrawer::~DebugDrawer() -{ - destroyGeometry(); -} + DebugDrawer::~DebugDrawer() + { + destroyGeometry(); + } -void DebugDrawer::step() -{ - if (mDebugOn) + void DebugDrawer::step() { - mLinesVertices->clear(); - mTrisVertices->clear(); - mLinesColors->clear(); - mShapesRoot->removeChildren(0, mShapesRoot->getNumChildren()); - mWorld->debugDrawWorld(); - showCollisions(); - mLinesDrawArrays->setCount(mLinesVertices->size()); - mTrisDrawArrays->setCount(mTrisVertices->size()); - mLinesVertices->dirty(); - mTrisVertices->dirty(); - mLinesColors->dirty(); - mLinesGeometry->dirtyBound(); - mTrisGeometry->dirtyBound(); + if (mDebugOn) + { + mLinesVertices->clear(); + mTrisVertices->clear(); + mLinesColors->clear(); + mShapesRoot->removeChildren(0, mShapesRoot->getNumChildren()); + mWorld->debugDrawWorld(); + showCollisions(); + mLinesDrawArrays->setCount(mLinesVertices->size()); + mTrisDrawArrays->setCount(mTrisVertices->size()); + mLinesVertices->dirty(); + mTrisVertices->dirty(); + mLinesColors->dirty(); + mLinesGeometry->dirtyBound(); + mTrisGeometry->dirtyBound(); + } } -} -void DebugDrawer::drawLine(const btVector3 &from, const btVector3 &to, const btVector3 &color) -{ - mLinesVertices->push_back(Misc::Convert::toOsg(from)); - mLinesVertices->push_back(Misc::Convert::toOsg(to)); - mLinesColors->push_back({1,1,1,1}); - mLinesColors->push_back({1,1,1,1}); + void DebugDrawer::drawLine(const btVector3& from, const btVector3& to, const btVector3& color) + { + mLinesVertices->push_back(Misc::Convert::toOsg(from)); + mLinesVertices->push_back(Misc::Convert::toOsg(to)); + mLinesColors->push_back({ 1, 1, 1, 1 }); + mLinesColors->push_back({ 1, 1, 1, 1 }); #if BT_BULLET_VERSION < 317 - size_t size = mLinesVertices->size(); - if (size >= 6 - && (*mLinesVertices)[size - 1] == (*mLinesVertices)[size - 6] - && (*mLinesVertices)[size - 2] == (*mLinesVertices)[size - 3] - && (*mLinesVertices)[size - 4] == (*mLinesVertices)[size - 5]) - { - mTrisVertices->push_back(mLinesVertices->back()); - mLinesVertices->pop_back(); - mLinesColors->pop_back(); - mTrisVertices->push_back(mLinesVertices->back()); - mLinesVertices->pop_back(); - mLinesColors->pop_back(); - mLinesVertices->pop_back(); - mLinesColors->pop_back(); - mTrisVertices->push_back(mLinesVertices->back()); - mLinesVertices->pop_back(); - mLinesColors->pop_back(); - mLinesVertices->pop_back(); - mLinesColors->pop_back(); - mLinesVertices->pop_back(); - mLinesColors->pop_back(); - } + size_t size = mLinesVertices->size(); + if (size >= 6 && (*mLinesVertices)[size - 1] == (*mLinesVertices)[size - 6] + && (*mLinesVertices)[size - 2] == (*mLinesVertices)[size - 3] + && (*mLinesVertices)[size - 4] == (*mLinesVertices)[size - 5]) + { + mTrisVertices->push_back(mLinesVertices->back()); + mLinesVertices->pop_back(); + mLinesColors->pop_back(); + mTrisVertices->push_back(mLinesVertices->back()); + mLinesVertices->pop_back(); + mLinesColors->pop_back(); + mLinesVertices->pop_back(); + mLinesColors->pop_back(); + mTrisVertices->push_back(mLinesVertices->back()); + mLinesVertices->pop_back(); + mLinesColors->pop_back(); + mLinesVertices->pop_back(); + mLinesColors->pop_back(); + mLinesVertices->pop_back(); + mLinesColors->pop_back(); + } #endif -} + } -void DebugDrawer::drawTriangle(const btVector3& v0, const btVector3& v1, const btVector3& v2, const btVector3& color, btScalar) -{ - mTrisVertices->push_back(Misc::Convert::toOsg(v0)); - mTrisVertices->push_back(Misc::Convert::toOsg(v1)); - mTrisVertices->push_back(Misc::Convert::toOsg(v2)); -} + void DebugDrawer::drawTriangle( + const btVector3& v0, const btVector3& v1, const btVector3& v2, const btVector3& color, btScalar) + { + mTrisVertices->push_back(Misc::Convert::toOsg(v0)); + mTrisVertices->push_back(Misc::Convert::toOsg(v1)); + mTrisVertices->push_back(Misc::Convert::toOsg(v2)); + } -void DebugDrawer::addCollision(const btVector3& orig, const btVector3& normal) -{ - mCollisionViews.emplace_back(orig, normal); -} + void DebugDrawer::addCollision(const btVector3& orig, const btVector3& normal) + { + mCollisionViews.emplace_back(orig, normal); + } -void DebugDrawer::showCollisions() -{ - const auto now = std::chrono::steady_clock::now(); - for (auto& [from, to , created] : mCollisionViews) + void DebugDrawer::showCollisions() { - if (now - created < std::chrono::seconds(2)) + const auto now = std::chrono::steady_clock::now(); + for (auto& [from, to, created] : mCollisionViews) { - mLinesVertices->push_back(Misc::Convert::toOsg(from)); - mLinesVertices->push_back(Misc::Convert::toOsg(to)); - mLinesColors->push_back({1,0,0,1}); - mLinesColors->push_back({1,0,0,1}); + if (now - created < std::chrono::seconds(2)) + { + mLinesVertices->push_back(Misc::Convert::toOsg(from)); + mLinesVertices->push_back(Misc::Convert::toOsg(to)); + mLinesColors->push_back({ 1, 0, 0, 1 }); + mLinesColors->push_back({ 1, 0, 0, 1 }); + } } - } - mCollisionViews.erase(std::remove_if(mCollisionViews.begin(), mCollisionViews.end(), + mCollisionViews.erase( + std::remove_if(mCollisionViews.begin(), mCollisionViews.end(), [&now](const CollisionView& view) { return now - view.mCreated >= std::chrono::seconds(2); }), mCollisionViews.end()); -} + } -void DebugDrawer::drawSphere(btScalar radius, const btTransform& transform, const btVector3& color) -{ - auto* geom = new osg::ShapeDrawable(new osg::Sphere(Misc::Convert::toOsg(transform.getOrigin()), radius)); - geom->setColor(osg::Vec4(1, 1, 1, 1)); - mShapesRoot->addChild(geom); -} + void DebugDrawer::drawSphere(btScalar radius, const btTransform& transform, const btVector3& color) + { + auto* geom = new osg::ShapeDrawable(new osg::Sphere(Misc::Convert::toOsg(transform.getOrigin()), radius)); + geom->setColor(osg::Vec4(1, 1, 1, 1)); + mShapesRoot->addChild(geom); + } -void DebugDrawer::reportErrorWarning(const char *warningString) -{ - Log(Debug::Warning) << warningString; -} + void DebugDrawer::reportErrorWarning(const char* warningString) + { + Log(Debug::Warning) << warningString; + } -void DebugDrawer::setDebugMode(int isOn) -{ - mDebugOn = (isOn != 0); + void DebugDrawer::setDebugMode(int isOn) + { + mDebugOn = (isOn != 0); - if (!mDebugOn) - destroyGeometry(); - else - createGeometry(); -} + if (!mDebugOn) + destroyGeometry(); + else + createGeometry(); + } -int DebugDrawer::getDebugMode() const -{ - return mDebugOn; -} + int DebugDrawer::getDebugMode() const + { + return mDebugOn; + } } diff --git a/apps/openmw/mwrender/bulletdebugdraw.hpp b/apps/openmw/mwrender/bulletdebugdraw.hpp index cea5794ba7..017d3af90a 100644 --- a/apps/openmw/mwrender/bulletdebugdraw.hpp +++ b/apps/openmw/mwrender/bulletdebugdraw.hpp @@ -4,9 +4,9 @@ #include #include -#include #include #include +#include #include @@ -21,65 +21,67 @@ namespace osg namespace MWRender { -class DebugDrawer : public btIDebugDraw -{ -private: - struct CollisionView + class DebugDrawer : public btIDebugDraw { - btVector3 mOrig; - btVector3 mEnd; - std::chrono::time_point mCreated; - CollisionView(btVector3 orig, btVector3 normal) : mOrig(orig), mEnd(orig + normal * 20), mCreated(std::chrono::steady_clock::now()) {}; - }; - std::vector mCollisionViews; - osg::ref_ptr mShapesRoot; + private: + struct CollisionView + { + btVector3 mOrig; + btVector3 mEnd; + std::chrono::time_point mCreated; + CollisionView(btVector3 orig, btVector3 normal) + : mOrig(orig) + , mEnd(orig + normal * 20) + , mCreated(std::chrono::steady_clock::now()){}; + }; + std::vector mCollisionViews; + osg::ref_ptr mShapesRoot; -protected: - osg::ref_ptr mParentNode; - btCollisionWorld *mWorld; - osg::ref_ptr mLinesGeometry; - osg::ref_ptr mTrisGeometry; - osg::ref_ptr mLinesVertices; - osg::ref_ptr mTrisVertices; - osg::ref_ptr mLinesColors; - osg::ref_ptr mLinesDrawArrays; - osg::ref_ptr mTrisDrawArrays; + protected: + osg::ref_ptr mParentNode; + btCollisionWorld* mWorld; + osg::ref_ptr mLinesGeometry; + osg::ref_ptr mTrisGeometry; + osg::ref_ptr mLinesVertices; + osg::ref_ptr mTrisVertices; + osg::ref_ptr mLinesColors; + osg::ref_ptr mLinesDrawArrays; + osg::ref_ptr mTrisDrawArrays; - bool mDebugOn; + bool mDebugOn; - void createGeometry(); - void destroyGeometry(); + void createGeometry(); + void destroyGeometry(); -public: + public: + DebugDrawer(osg::ref_ptr parentNode, btCollisionWorld* world, int debugMode = 1); + ~DebugDrawer(); - DebugDrawer(osg::ref_ptr parentNode, btCollisionWorld *world, int debugMode = 1); - ~DebugDrawer(); + void step(); - void step(); + void drawLine(const btVector3& from, const btVector3& to, const btVector3& color) override; - void drawLine(const btVector3& from,const btVector3& to,const btVector3& color) override; + void drawTriangle( + const btVector3& v0, const btVector3& v1, const btVector3& v2, const btVector3& color, btScalar) override; - void drawTriangle(const btVector3& v0, const btVector3& v1, const btVector3& v2, const btVector3& color, btScalar) override; + void addCollision(const btVector3& orig, const btVector3& normal); - void addCollision(const btVector3& orig, const btVector3& normal); + void showCollisions(); - void showCollisions(); + void drawContactPoint(const btVector3& PointOnB, const btVector3& normalOnB, btScalar distance, int lifeTime, + const btVector3& color) override{}; + void drawSphere(btScalar radius, const btTransform& transform, const btVector3& color) override; - void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color) override {}; - void drawSphere(btScalar radius, const btTransform& transform, const btVector3& color) override; + void reportErrorWarning(const char* warningString) override; - void reportErrorWarning(const char* warningString) override; + void draw3dText(const btVector3& location, const char* textString) override {} - void draw3dText(const btVector3& location,const char* textString) override {} - - //0 for off, anything else for on. - void setDebugMode(int isOn) override; - - //0 for off, anything else for on. - int getDebugMode() const override; - -}; + // 0 for off, anything else for on. + void setDebugMode(int isOn) override; + // 0 for off, anything else for on. + int getDebugMode() const override; + }; } diff --git a/apps/openmw/mwrender/camera.cpp b/apps/openmw/mwrender/camera.cpp index 625b6c3e97..1fe49f0f0f 100644 --- a/apps/openmw/mwrender/camera.cpp +++ b/apps/openmw/mwrender/camera.cpp @@ -3,9 +3,9 @@ #include #include +#include #include #include -#include #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" @@ -26,55 +26,57 @@ namespace { -class UpdateRenderCameraCallback : public SceneUtil::NodeCallback -{ -public: - UpdateRenderCameraCallback(MWRender::Camera* cam) - : mCamera(cam) + class UpdateRenderCameraCallback : public SceneUtil::NodeCallback { - } + public: + UpdateRenderCameraCallback(MWRender::Camera* cam) + : mCamera(cam) + { + } - void operator()(osg::Camera* cam, osg::NodeVisitor* nv) - { - // traverse first to update animations, in case the camera is attached to an animated node - traverse(cam, nv); + void operator()(osg::Camera* cam, osg::NodeVisitor* nv) + { + // traverse first to update animations, in case the camera is attached to an animated node + traverse(cam, nv); - mCamera->updateCamera(cam); - } + mCamera->updateCamera(cam); + } -private: - MWRender::Camera* mCamera; -}; + private: + MWRender::Camera* mCamera; + }; } namespace MWRender { - Camera::Camera (osg::Camera* camera) - : mHeightScale(1.f), - mCollisionType((MWPhysics::CollisionType::CollisionType_Default & ~MWPhysics::CollisionType::CollisionType_Actor) | MWPhysics::CollisionType_CameraOnly), - mCamera(camera), - mAnimation(nullptr), - mFirstPersonView(true), - mMode(Mode::FirstPerson), - mVanityAllowed(true), - mDeferredRotationAllowed(true), - mProcessViewChange(false), - mHeight(124.f), - mPitch(0.f), - mYaw(0.f), - mRoll(0.f), - mCameraDistance(0.f), - mPreferredCameraDistance(0.f), - mFocalPointCurrentOffset(osg::Vec2d()), - mFocalPointTargetOffset(osg::Vec2d()), - mFocalPointTransitionSpeedCoef(1.f), - mSkipFocalPointTransition(true), - mPreviousTransitionInfluence(0.f), - mShowCrosshair(false), - mDeferredRotation(osg::Vec3f()), - mDeferredRotationDisabled(false) + Camera::Camera(osg::Camera* camera) + : mHeightScale(1.f) + , mCollisionType( + (MWPhysics::CollisionType::CollisionType_Default & ~MWPhysics::CollisionType::CollisionType_Actor) + | MWPhysics::CollisionType_CameraOnly) + , mCamera(camera) + , mAnimation(nullptr) + , mFirstPersonView(true) + , mMode(Mode::FirstPerson) + , mVanityAllowed(true) + , mDeferredRotationAllowed(true) + , mProcessViewChange(false) + , mHeight(124.f) + , mPitch(0.f) + , mYaw(0.f) + , mRoll(0.f) + , mCameraDistance(0.f) + , mPreferredCameraDistance(0.f) + , mFocalPointCurrentOffset(osg::Vec2d()) + , mFocalPointTargetOffset(osg::Vec2d()) + , mFocalPointTransitionSpeedCoef(1.f) + , mSkipFocalPointTransition(true) + , mPreviousTransitionInfluence(0.f) + , mShowCrosshair(false) + , mDeferredRotation(osg::Vec3f()) + , mDeferredRotationDisabled(false) { mUpdateCallback = new UpdateRenderCameraCallback(this); mCamera->addUpdateCallback(mUpdateCallback); @@ -108,13 +110,12 @@ namespace MWRender return offset; } - void Camera::updateCamera(osg::Camera *cam) + void Camera::updateCamera(osg::Camera* cam) { - osg::Quat orient = osg::Quat(mRoll + mExtraRoll, osg::Vec3d(0, 1, 0)) * - osg::Quat(mPitch + mExtraPitch, osg::Vec3d(1, 0, 0)) * - osg::Quat(mYaw + mExtraYaw, osg::Vec3d(0, 0, 1)); - osg::Vec3d forward = orient * osg::Vec3d(0,1,0); - osg::Vec3d up = orient * osg::Vec3d(0,0,1); + osg::Quat orient = osg::Quat(mRoll + mExtraRoll, osg::Vec3d(0, 1, 0)) + * osg::Quat(mPitch + mExtraPitch, osg::Vec3d(1, 0, 0)) * osg::Quat(mYaw + mExtraYaw, osg::Vec3d(0, 0, 1)); + osg::Vec3d forward = orient * osg::Vec3d(0, 1, 0); + osg::Vec3d up = orient * osg::Vec3d(0, 0, 1); osg::Vec3d pos = mPosition; if (mMode == Mode::FirstPerson) @@ -143,7 +144,7 @@ namespace MWRender return; // only show the crosshair in game mode - MWBase::WindowManager *wm = MWBase::Environment::get().getWindowManager(); + MWBase::WindowManager* wm = MWBase::Environment::get().getWindowManager(); wm->showCrosshair(!wm->isGuiMode() && mShowCrosshair); updateFocalPointOffset(duration); @@ -153,7 +154,8 @@ namespace MWRender osg::Vec3d Camera::calculateFirstPersonPosition(const osg::Vec3d& trackedPosition) const { osg::Vec3d res = trackedPosition; - osg::Vec2f horizontalOffset = Misc::rotateVec2f(osg::Vec2f(mFirstPersonOffset.x(), mFirstPersonOffset.y()), mYaw); + osg::Vec2f horizontalOffset + = Misc::rotateVec2f(osg::Vec2f(mFirstPersonOffset.x(), mFirstPersonOffset.y()), mYaw); res.x() += horizontalOffset.x(); res.y() += horizontalOffset.y(); res.z() += mFirstPersonOffset.z(); @@ -180,24 +182,28 @@ namespace MWRender // Adjust focal point to prevent clipping. osg::Vec3d focalOffset = getFocalPointOffset(); osg::Vec3d focal = mTrackedPosition + focalOffset; - focalOffset.z() += 10.f; // Needed to avoid camera clipping through the ceiling because - // character's head can be a bit higher than the collision area. + focalOffset.z() += 10.f; // Needed to avoid camera clipping through the ceiling because + // character's head can be a bit higher than the collision area. float offsetLen = focalOffset.length(); if (offsetLen > 0) { - MWPhysics::RayCastingResult result = rayCasting->castSphere(focal - focalOffset, focal, focalObstacleLimit, mCollisionType); + MWPhysics::RayCastingResult result + = rayCasting->castSphere(focal - focalOffset, focal, focalObstacleLimit, mCollisionType); if (result.mHit) { - double adjustmentCoef = -(result.mHitPos + result.mHitNormal * focalObstacleLimit - focal).length() / offsetLen; + double adjustmentCoef + = -(result.mHitPos + result.mHitNormal * focalObstacleLimit - focal).length() / offsetLen; focal += focalOffset * std::max(-1.0, adjustmentCoef); } } // Adjust camera distance. mCameraDistance = mPreferredCameraDistance; - osg::Quat orient = osg::Quat(mPitch + mExtraPitch, osg::Vec3d(1,0,0)) * osg::Quat(mYaw + mExtraYaw, osg::Vec3d(0,0,1)); + osg::Quat orient + = osg::Quat(mPitch + mExtraPitch, osg::Vec3d(1, 0, 0)) * osg::Quat(mYaw + mExtraYaw, osg::Vec3d(0, 0, 1)); osg::Vec3d offset = orient * osg::Vec3d(0.f, -mCameraDistance, 0.f); - MWPhysics::RayCastingResult result = rayCasting->castSphere(focal, focal + offset, cameraObstacleLimit, mCollisionType); + MWPhysics::RayCastingResult result + = rayCasting->castSphere(focal, focal + offset, cameraObstacleLimit, mCollisionType); if (result.mHit) { mCameraDistance = (result.mHitPos + result.mHitNormal * cameraObstacleLimit - focal).length(); @@ -212,7 +218,8 @@ namespace MWRender if (mMode == newMode) return; Mode oldMode = mMode; - if (!force && (newMode == Mode::FirstPerson || oldMode == Mode::FirstPerson) && mAnimation && !mAnimation->upperBodyReady()) + if (!force && (newMode == Mode::FirstPerson || oldMode == Mode::FirstPerson) && mAnimation + && !mAnimation->upperBodyReady()) { // Changing the view will stop all playing animations, so if we are playing // anything important, queue the view change for later @@ -258,9 +265,10 @@ namespace MWRender if (mPreviousTransitionInfluence > 0) { mFocalPointCurrentOffset -= mPreviousExtraOffset; - mPreviousExtraOffset = mPreviousExtraOffset / mPreviousTransitionInfluence + mPreviousTransitionSpeed * duration; - mPreviousTransitionInfluence = - std::max(0.f, mPreviousTransitionInfluence - duration * mFocalPointTransitionSpeedCoef); + mPreviousExtraOffset + = mPreviousExtraOffset / mPreviousTransitionInfluence + mPreviousTransitionSpeed * duration; + mPreviousTransitionInfluence + = std::max(0.f, mPreviousTransitionInfluence - duration * mFocalPointTransitionSpeedCoef); mPreviousExtraOffset *= mPreviousTransitionInfluence; mFocalPointCurrentOffset += mPreviousExtraOffset; } @@ -268,8 +276,8 @@ namespace MWRender osg::Vec2d delta = mFocalPointTargetOffset - mFocalPointCurrentOffset; if (delta.length2() > 0) { - float coef = duration * (1.0 + 5.0 / delta.length()) * - mFocalPointTransitionSpeedCoef * (1.0f - mPreviousTransitionInfluence); + float coef = duration * (1.0 + 5.0 / delta.length()) * mFocalPointTransitionSpeedCoef + * (1.0f - mPreviousTransitionInfluence); mFocalPointCurrentOffset += delta * std::min(coef, 1.0f); } else @@ -297,7 +305,7 @@ namespace MWRender void Camera::setSneakOffset(float offset) { - mAnimation->setFirstPersonOffset(osg::Vec3f(0,0,-offset)); + mAnimation->setFirstPersonOffset(osg::Vec3f(0, 0, -offset)); } void Camera::setYaw(float angle, bool force) @@ -325,7 +333,7 @@ namespace MWRender mPosition = pos; } - void Camera::setAnimation(NpcAnimation *anim) + void Camera::setAnimation(NpcAnimation* anim) { mAnimation = anim; mProcessViewChange = true; @@ -384,7 +392,7 @@ namespace MWRender float c = std::cos(mDeferredRotation.z()); float x = movement.mPosition[0]; float y = movement.mPosition[1]; - movement.mPosition[0] = x * c + y * s; + movement.mPosition[0] = x * c + y * s; movement.mPosition[1] = x * -s + y * c; } } diff --git a/apps/openmw/mwrender/camera.hpp b/apps/openmw/mwrender/camera.hpp index e17e63ddaf..627697620e 100644 --- a/apps/openmw/mwrender/camera.hpp +++ b/apps/openmw/mwrender/camera.hpp @@ -4,10 +4,10 @@ #include #include -#include #include #include #include +#include #include "../mwworld/ptr.hpp" @@ -26,13 +26,20 @@ namespace MWRender class Camera { public: - enum class Mode : int {Static = 0, FirstPerson = 1, ThirdPerson = 2, Vanity = 3, Preview = 4}; + enum class Mode : int + { + Static = 0, + FirstPerson = 1, + ThirdPerson = 2, + Vanity = 3, + Preview = 4 + }; Camera(osg::Camera* camera); ~Camera(); /// Attach camera to object - void attachTo(const MWWorld::Ptr &ptr) { mTrackingPtr = ptr; } + void attachTo(const MWWorld::Ptr& ptr) { mTrackingPtr = ptr; } MWWorld::Ptr getTrackingPtr() const { return mTrackingPtr; } void setFocalPointTransitionSpeed(float v) { mFocalPointTransitionSpeedCoef = v; } @@ -66,7 +73,7 @@ namespace MWRender void setExtraRoll(float angle) { mExtraRoll = angle; } /// @param Force view mode switch, even if currently not allowed by the animation. - void toggleViewMode(bool force=false); + void toggleViewMode(bool force = false); bool toggleVanityMode(bool enable); void applyDeferredPreviewRotationToPlayer(float dt); @@ -77,12 +84,12 @@ namespace MWRender void processViewChange(); - void update(float duration, bool paused=false); + void update(float duration, bool paused = false); float getCameraDistance() const { return mCameraDistance; } void setPreferredCameraDistance(float v) { mPreferredCameraDistance = v; } - void setAnimation(NpcAnimation *anim); + void setAnimation(NpcAnimation* anim); osg::Vec3d getTrackedPosition() const { return mTrackedPosition; } const osg::Vec3d& getPosition() const { return mPosition; } @@ -112,7 +119,7 @@ namespace MWRender osg::ref_ptr mCamera; - NpcAnimation *mAnimation; + NpcAnimation* mAnimation; // Always 'true' if mMode == `FirstPerson`. Also it is 'true' in `Vanity` or `Preview` modes if // the camera should return to `FirstPerson` view after it. @@ -134,7 +141,7 @@ namespace MWRender float mCameraDistance, mPreferredCameraDistance; - osg::Vec3f mFirstPersonOffset{0, 0, 0}; + osg::Vec3f mFirstPersonOffset{ 0, 0, 0 }; osg::Vec2d mFocalPointCurrentOffset; osg::Vec2d mFocalPointTargetOffset; diff --git a/apps/openmw/mwrender/cell.hpp b/apps/openmw/mwrender/cell.hpp index 8fa3f9f0f0..e6175f6ffd 100644 --- a/apps/openmw/mwrender/cell.hpp +++ b/apps/openmw/mwrender/cell.hpp @@ -7,28 +7,27 @@ namespace MWRender { class CellRender { - public: + public: + virtual ~CellRender(){}; - virtual ~CellRender() {}; + /// Make the cell visible. Load the cell if necessary. + virtual void show() = 0; - /// Make the cell visible. Load the cell if necessary. - virtual void show() = 0; + /// Remove the cell from rendering, but don't remove it from + /// memory. + virtual void hide() = 0; - /// Remove the cell from rendering, but don't remove it from - /// memory. - virtual void hide() = 0; + /// Destroy all rendering objects connected with this cell. + virtual void destroy() = 0; - /// Destroy all rendering objects connected with this cell. - virtual void destroy() = 0; + /// Make the reference with the given handle visible. + virtual void enable(const std::string& handle) = 0; - /// Make the reference with the given handle visible. - virtual void enable (const std::string& handle) = 0; + /// Make the reference with the given handle invisible. + virtual void disable(const std::string& handle) = 0; - /// Make the reference with the given handle invisible. - virtual void disable (const std::string& handle) = 0; - - /// Remove the reference with the given handle permanently from the scene. - virtual void deleteObject (const std::string& handle) = 0; + /// Remove the reference with the given handle permanently from the scene. + virtual void deleteObject(const std::string& handle) = 0; }; } diff --git a/apps/openmw/mwrender/characterpreview.cpp b/apps/openmw/mwrender/characterpreview.cpp index 73bd9db484..452fd31188 100644 --- a/apps/openmw/mwrender/characterpreview.cpp +++ b/apps/openmw/mwrender/characterpreview.cpp @@ -2,29 +2,29 @@ #include -#include -#include #include -#include -#include #include -#include +#include #include #include +#include +#include +#include +#include #include #include #include #include #include -#include #include +#include +#include #include -#include +#include #include +#include #include -#include -#include #include #include "../mwbase/world.hpp" @@ -50,7 +50,7 @@ namespace MWRender { } - void operator () (osg::Node* node, osg::NodeVisitor* nv) + void operator()(osg::Node* node, osg::NodeVisitor* nv) { if (!mRendered) { @@ -65,7 +65,8 @@ namespace MWRender nv->setFrameStamp(fs); // Update keyframe controllers in the scene graph first... - // RTTNode does not continue update traversal, so manually continue the update traversal since we need it. + // RTTNode does not continue update traversal, so manually continue the update traversal since we need + // it. mSubgraph->accept(*nv); traverse(node, nv); @@ -77,15 +78,9 @@ namespace MWRender } } - void redrawNextFrame() - { - mRendered = false; - } + void redrawNextFrame() { mRendered = false; } - unsigned int getLastRenderedFrame() const - { - return mLastRenderedFrame; - } + unsigned int getLastRenderedFrame() const { return mLastRenderedFrame; } private: bool mRendered; @@ -93,13 +88,13 @@ namespace MWRender osg::ref_ptr mSubgraph; }; - // Set up alpha blending mode to avoid issues caused by transparent objects writing onto the alpha value of the FBO // This makes the RTT have premultiplied alpha, though, so the source blend factor must be GL_ONE when it's applied class SetUpBlendVisitor : public osg::NodeVisitor { public: - SetUpBlendVisitor(): osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) + SetUpBlendVisitor() + : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) { } @@ -108,9 +103,11 @@ namespace MWRender if (osg::ref_ptr stateset = node.getStateSet()) { osg::ref_ptr newStateSet; - if (stateset->getAttribute(osg::StateAttribute::BLENDFUNC) || stateset->getBinNumber() == osg::StateSet::TRANSPARENT_BIN) + if (stateset->getAttribute(osg::StateAttribute::BLENDFUNC) + || stateset->getBinNumber() == osg::StateSet::TRANSPARENT_BIN) { - osg::BlendFunc* blendFunc = static_cast(stateset->getAttribute(osg::StateAttribute::BLENDFUNC)); + osg::BlendFunc* blendFunc + = static_cast(stateset->getAttribute(osg::StateAttribute::BLENDFUNC)); if (blendFunc) { @@ -118,15 +115,19 @@ namespace MWRender node.setStateSet(newStateSet); osg::ref_ptr newBlendFunc = new osg::BlendFunc(*blendFunc); newStateSet->setAttribute(newBlendFunc, osg::StateAttribute::ON); - // I *think* (based on some by-hand maths) that the RGB and dest alpha factors are unchanged, and only dest determines source alpha factor - // This has the benefit of being idempotent if we assume nothing used glBlendFuncSeparate before we touched it + // I *think* (based on some by-hand maths) that the RGB and dest alpha factors are unchanged, + // and only dest determines source alpha factor This has the benefit of being idempotent if we + // assume nothing used glBlendFuncSeparate before we touched it if (blendFunc->getDestination() == osg::BlendFunc::ONE_MINUS_SRC_ALPHA) newBlendFunc->setSourceAlpha(osg::BlendFunc::ONE); else if (blendFunc->getDestination() == osg::BlendFunc::ONE) newBlendFunc->setSourceAlpha(osg::BlendFunc::ZERO); - // Other setups barely exist in the wild and aren't worth supporting as they're not equippable gear + // Other setups barely exist in the wild and aren't worth supporting as they're not equippable + // gear else - Log(Debug::Info) << "Unable to adjust blend mode for character preview. Source factor 0x" << std::hex << blendFunc->getSource() << ", destination factor 0x" << blendFunc->getDestination() << std::dec; + Log(Debug::Info) << "Unable to adjust blend mode for character preview. Source factor 0x" + << std::hex << blendFunc->getSource() << ", destination factor 0x" + << blendFunc->getDestination() << std::dec; } } if (stateset->getMode(GL_BLEND) & osg::StateAttribute::ON) @@ -153,20 +154,22 @@ namespace MWRender public: CharacterPreviewRTTNode(uint32_t sizeX, uint32_t sizeY) - : RTTNode(sizeX, sizeY, Settings::Manager::getInt("antialiasing", "Video"), false, 0, StereoAwareness::Unaware_MultiViewShaders) + : RTTNode(sizeX, sizeY, Settings::Manager::getInt("antialiasing", "Video"), false, 0, + StereoAwareness::Unaware_MultiViewShaders) , mAspectRatio(static_cast(sizeX) / static_cast(sizeY)) { if (SceneUtil::AutoDepth::isReversed()) - mPerspectiveMatrix = static_cast(SceneUtil::getReversedZProjectionMatrixAsPerspective(fovYDegrees, mAspectRatio, znear, zfar)); + mPerspectiveMatrix = static_cast( + SceneUtil::getReversedZProjectionMatrixAsPerspective(fovYDegrees, mAspectRatio, znear, zfar)); else mPerspectiveMatrix = osg::Matrixf::perspective(fovYDegrees, mAspectRatio, znear, zfar); mGroup->getOrCreateStateSet()->addUniform(new osg::Uniform("projectionMatrix", mPerspectiveMatrix)); mViewMatrix = osg::Matrixf::identity(); setColorBufferInternalFormat(GL_RGBA); setDepthBufferInternalFormat(GL_DEPTH24_STENCIL8); - } + } - void setDefaults(osg::Camera* camera) override + void setDefaults(osg::Camera* camera) override { camera->setName("CharacterPreview"); camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF); @@ -184,9 +187,9 @@ namespace MWRender camera->addChild(mGroup); }; - void apply(osg::Camera* camera) override + void apply(osg::Camera* camera) override { - if(mCameraStateset) + if (mCameraStateset) camera->setStateSet(mCameraStateset); camera->setViewMatrix(mViewMatrix); @@ -194,20 +197,11 @@ namespace MWRender Stereo::setMultiviewMatrices(mGroup->getOrCreateStateSet(), { mPerspectiveMatrix, mPerspectiveMatrix }); }; - void addChild(osg::Node* node) - { - mGroup->addChild(node); - } + void addChild(osg::Node* node) { mGroup->addChild(node); } - void setCameraStateset(osg::StateSet* stateset) - { - mCameraStateset = stateset; - } + void setCameraStateset(osg::StateSet* stateset) { mCameraStateset = stateset; } - void setViewMatrix(const osg::Matrixf& viewMatrix) - { - mViewMatrix = viewMatrix; - } + void setViewMatrix(const osg::Matrixf& viewMatrix) { mViewMatrix = viewMatrix; } osg::ref_ptr mGroup = new osg::Group; osg::Matrixf mPerspectiveMatrix; @@ -217,7 +211,7 @@ namespace MWRender }; CharacterPreview::CharacterPreview(osg::Group* parent, Resource::ResourceSystem* resourceSystem, - const MWWorld::Ptr& character, int sizeX, int sizeY, const osg::Vec3f& position, const osg::Vec3f& lookAt) + const MWWorld::Ptr& character, int sizeX, int sizeY, const osg::Vec3f& position, const osg::Vec3f& lookAt) : mParent(parent) , mResourceSystem(resourceSystem) , mPosition(position) @@ -242,10 +236,10 @@ namespace MWRender stateset->setMode(GL_LIGHTING, osg::StateAttribute::ON); stateset->setMode(GL_NORMALIZE, osg::StateAttribute::ON); stateset->setMode(GL_CULL_FACE, osg::StateAttribute::ON); - osg::ref_ptr defaultMat (new osg::Material); + osg::ref_ptr defaultMat(new osg::Material); defaultMat->setColorMode(osg::Material::OFF); - defaultMat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(1,1,1,1)); - defaultMat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(1,1,1,1)); + defaultMat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(1, 1, 1, 1)); + defaultMat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(1, 1, 1, 1)); defaultMat->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4f(0.f, 0.f, 0.f, 0.f)); stateset->setAttribute(defaultMat); @@ -253,17 +247,17 @@ namespace MWRender // assign large value to effectively turn off fog // shaders don't respect glDisable(GL_FOG) - osg::ref_ptr fog (new osg::Fog); + osg::ref_ptr fog(new osg::Fog); fog->setStart(10000000); fog->setEnd(10000000); - stateset->setAttributeAndModes(fog, osg::StateAttribute::OFF|osg::StateAttribute::OVERRIDE); + stateset->setAttributeAndModes(fog, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE); // TODO: Clean up this mess of loose uniforms that shaders depend on. // turn off sky blending stateset->addUniform(new osg::Uniform("far", 10000000.0f)); stateset->addUniform(new osg::Uniform("skyBlendingStart", 8000000.0f)); stateset->addUniform(new osg::Uniform("sky", 0)); - stateset->addUniform(new osg::Uniform("screenRes", osg::Vec2f{1, 1})); + stateset->addUniform(new osg::Uniform("screenRes", osg::Vec2f{ 1, 1 })); stateset->addUniform(new osg::Uniform("emissiveMult", 1.f)); @@ -299,19 +293,19 @@ namespace MWRender float positionX = -std::cos(azimuth) * std::sin(altitude); float positionY = std::sin(azimuth) * std::sin(altitude); float positionZ = std::cos(altitude); - light->setPosition(osg::Vec4(positionX,positionY,positionZ, 0.0)); - light->setDiffuse(osg::Vec4(diffuseR,diffuseG,diffuseB,1)); - osg::Vec4 ambientRGBA = osg::Vec4(ambientR,ambientG,ambientB,1); + light->setPosition(osg::Vec4(positionX, positionY, positionZ, 0.0)); + light->setDiffuse(osg::Vec4(diffuseR, diffuseG, diffuseB, 1)); + osg::Vec4 ambientRGBA = osg::Vec4(ambientR, ambientG, ambientB, 1); if (mResourceSystem->getSceneManager()->getForceShaders()) { // When using shaders, we now skip the ambient sun calculation as this is the only place it's used. // Using the scene ambient will give identical results. lightmodel->setAmbientIntensity(ambientRGBA); - light->setAmbient(osg::Vec4(0,0,0,1)); + light->setAmbient(osg::Vec4(0, 0, 0, 1)); } else light->setAmbient(ambientRGBA); - light->setSpecular(osg::Vec4(0,0,0,0)); + light->setSpecular(osg::Vec4(0, 0, 0, 0)); light->setLightNum(0); light->setConstantAttenuation(1.f); light->setLinearAttenuation(0.f); @@ -338,7 +332,7 @@ namespace MWRender mCharacter.mCell = nullptr; } - CharacterPreview::~CharacterPreview () + CharacterPreview::~CharacterPreview() { mParent->removeChild(mRTTNode); } @@ -374,7 +368,7 @@ namespace MWRender mAnimation = nullptr; mAnimation = new NpcAnimation(mCharacter, mNode, mResourceSystem, true, - (renderHeadOnly() ? NpcAnimation::VM_HeadOnly : NpcAnimation::VM_Normal)); + (renderHeadOnly() ? NpcAnimation::VM_HeadOnly : NpcAnimation::VM_Normal)); onSetup(); @@ -389,9 +383,9 @@ namespace MWRender // -------------------------------------------------------------------------------------------------- - - InventoryPreview::InventoryPreview(osg::Group* parent, Resource::ResourceSystem* resourceSystem, const MWWorld::Ptr& character) - : CharacterPreview(parent, resourceSystem, character, 512, 1024, osg::Vec3f(0, 700, 71), osg::Vec3f(0,0,71)) + InventoryPreview::InventoryPreview( + osg::Group* parent, Resource::ResourceSystem* resourceSystem, const MWWorld::Ptr& character) + : CharacterPreview(parent, resourceSystem, character, 512, 1024, osg::Vec3f(0, 700, 71), osg::Vec3f(0, 0, 71)) { } @@ -402,7 +396,7 @@ namespace MWRender // NB Camera::setViewport has threading issues osg::ref_ptr stateset = new osg::StateSet; - mViewport = new osg::Viewport(0, mSizeY-sizeY, std::min(mSizeX, sizeX), std::min(mSizeY, sizeY)); + mViewport = new osg::Viewport(0, mSizeY - sizeY, std::min(mSizeX, sizeX), std::min(mSizeY, sizeY)); stateset->setAttributeAndModes(mViewport); mRTTNode->setCameraStateset(stateset); @@ -417,16 +411,16 @@ namespace MWRender mAnimation->showWeapons(true); mAnimation->updateParts(); - MWWorld::InventoryStore &inv = mCharacter.getClass().getInventoryStore(mCharacter); + MWWorld::InventoryStore& inv = mCharacter.getClass().getInventoryStore(mCharacter); MWWorld::ContainerStoreIterator iter = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); std::string groupname = "inventoryhandtohand"; bool showCarriedLeft = true; - if(iter != inv.end()) + if (iter != inv.end()) { groupname = "inventoryweapononehand"; - if(iter->getType() == ESM::Weapon::sRecordId) + if (iter->getType() == ESM::Weapon::sRecordId) { - MWWorld::LiveCellRef *ref = iter->get(); + MWWorld::LiveCellRef* ref = iter->get(); int type = ref->mBase->mData.mType; const ESM::WeaponType* weaponInfo = MWMechanics::getWeaponType(type); showCarriedLeft = !(weaponInfo->mFlags & ESM::WeaponType::TwoHanded); @@ -439,16 +433,19 @@ namespace MWRender groupname = inventoryGroup; else { - static const std::string oneHandFallback = "inventory" + MWMechanics::getWeaponType(ESM::Weapon::LongBladeOneHand)->mLongGroup; - static const std::string twoHandFallback = "inventory" + MWMechanics::getWeaponType(ESM::Weapon::LongBladeTwoHand)->mLongGroup; + static const std::string oneHandFallback + = "inventory" + MWMechanics::getWeaponType(ESM::Weapon::LongBladeOneHand)->mLongGroup; + static const std::string twoHandFallback + = "inventory" + MWMechanics::getWeaponType(ESM::Weapon::LongBladeTwoHand)->mLongGroup; // For real two-handed melee weapons use 2h swords animations as fallback, otherwise use the 1h ones - if (weaponInfo->mFlags & ESM::WeaponType::TwoHanded && weaponInfo->mWeaponClass == ESM::WeaponType::Melee) + if (weaponInfo->mFlags & ESM::WeaponType::TwoHanded + && weaponInfo->mWeaponClass == ESM::WeaponType::Melee) groupname = twoHandFallback; else groupname = oneHandFallback; } - } + } } mAnimation->showCarriedLeft(showCarriedLeft); @@ -457,13 +454,13 @@ namespace MWRender mAnimation->play(mCurrentAnimGroup, 1, Animation::BlendMask_All, false, 1.0f, "start", "stop", 0.0f, 0); MWWorld::ConstContainerStoreIterator torch = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); - if(torch != inv.end() && torch->getType() == ESM::Light::sRecordId && showCarriedLeft) + if (torch != inv.end() && torch->getType() == ESM::Light::sRecordId && showCarriedLeft) { - if(!mAnimation->getInfo("torch")) - mAnimation->play("torch", 2, Animation::BlendMask_LeftArm, false, - 1.0f, "start", "stop", 0.0f, ~0ul, true); + if (!mAnimation->getInfo("torch")) + mAnimation->play( + "torch", 2, Animation::BlendMask_LeftArm, false, 1.0f, "start", "stop", 0.0f, ~0ul, true); } - else if(mAnimation->getInfo("torch")) + else if (mAnimation->getInfo("torch")) mAnimation->disable("torch"); mAnimation->runAnimation(0.0f); @@ -473,7 +470,7 @@ namespace MWRender redraw(); } - int InventoryPreview::getSlotSelected (int posX, int posY) + int InventoryPreview::getSlotSelected(int posX, int posY) { if (!mViewport) return -1; @@ -483,12 +480,14 @@ namespace MWRender // precision issue - compiling with OSG_USE_FLOAT_MATRIX=0, Intersector::WINDOW works ok. // Using Intersector::PROJECTION results in better precision because the start/end points and the model matrices // don't go through as many transformations. - osg::ref_ptr intersector (new osgUtil::LineSegmentIntersector(osgUtil::Intersector::PROJECTION, projX, projY)); + osg::ref_ptr intersector( + new osgUtil::LineSegmentIntersector(osgUtil::Intersector::PROJECTION, projX, projY)); intersector->setIntersectionLimit(osgUtil::LineSegmentIntersector::LIMIT_NEAREST); osgUtil::IntersectionVisitor visitor(intersector); visitor.setTraversalMode(osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN); - // Set the traversal number from the last draw, so that the frame switch used for RigGeometry double buffering works correctly + // Set the traversal number from the last draw, so that the frame switch used for RigGeometry double buffering + // works correctly visitor.setTraversalNumber(mDrawOnceCallback->getLastRenderedFrame()); auto* camera = mRTTNode->getCamera(nullptr); @@ -505,7 +504,7 @@ namespace MWRender return -1; } - void InventoryPreview::updatePtr(const MWWorld::Ptr &ptr) + void InventoryPreview::updatePtr(const MWWorld::Ptr& ptr) { mCharacter = MWWorld::Ptr(ptr.getBase(), nullptr); } @@ -513,7 +512,7 @@ namespace MWRender void InventoryPreview::onSetup() { CharacterPreview::onSetup(); - osg::Vec3f scale (1.f, 1.f, 1.f); + osg::Vec3f scale(1.f, 1.f, 1.f); mCharacter.getClass().adjustScale(mCharacter, scale, true); mNode->setScale(scale); @@ -525,27 +524,24 @@ namespace MWRender // -------------------------------------------------------------------------------------------------- RaceSelectionPreview::RaceSelectionPreview(osg::Group* parent, Resource::ResourceSystem* resourceSystem) - : CharacterPreview(parent, resourceSystem, MWMechanics::getPlayer(), - 512, 512, osg::Vec3f(0, 125, 8), osg::Vec3f(0,0,8)) - , mBase (*mCharacter.get()->mBase) + : CharacterPreview( + parent, resourceSystem, MWMechanics::getPlayer(), 512, 512, osg::Vec3f(0, 125, 8), osg::Vec3f(0, 0, 8)) + , mBase(*mCharacter.get()->mBase) , mRef(&mBase) , mPitchRadians(osg::DegreesToRadians(6.f)) { mCharacter = MWWorld::Ptr(&mRef, nullptr); } - RaceSelectionPreview::~RaceSelectionPreview() - { - } + RaceSelectionPreview::~RaceSelectionPreview() {} void RaceSelectionPreview::setAngle(float angleRadians) { - mNode->setAttitude(osg::Quat(mPitchRadians, osg::Vec3(1,0,0)) - * osg::Quat(angleRadians, osg::Vec3(0,0,1))); + mNode->setAttitude(osg::Quat(mPitchRadians, osg::Vec3(1, 0, 0)) * osg::Quat(angleRadians, osg::Vec3(0, 0, 1))); redraw(); } - void RaceSelectionPreview::setPrototype(const ESM::NPC &proto) + void RaceSelectionPreview::setPrototype(const ESM::NPC& proto) { mBase = proto; mBase.mId = "player"; @@ -555,7 +551,8 @@ namespace MWRender class UpdateCameraCallback : public SceneUtil::NodeCallback { public: - UpdateCameraCallback(osg::ref_ptr nodeToFollow, const osg::Vec3& posOffset, const osg::Vec3& lookAtOffset) + UpdateCameraCallback( + osg::ref_ptr nodeToFollow, const osg::Vec3& posOffset, const osg::Vec3& lookAtOffset) : mNodeToFollow(nodeToFollow) , mPosOffset(posOffset) , mLookAtOffset(lookAtOffset) @@ -574,7 +571,8 @@ namespace MWRender osg::Matrix worldMat = osg::computeLocalToWorld(nodepaths[0]); osg::Vec3 headOffset = worldMat.getTrans(); - auto viewMatrix = osg::Matrixf::lookAt(headOffset + mPosOffset, headOffset + mLookAtOffset, osg::Vec3(0, 0, 1)); + auto viewMatrix + = osg::Matrixf::lookAt(headOffset + mPosOffset, headOffset + mLookAtOffset, osg::Vec3(0, 0, 1)); node->setViewMatrix(viewMatrix); } @@ -584,7 +582,7 @@ namespace MWRender osg::Vec3 mLookAtOffset; }; - void RaceSelectionPreview::onSetup () + void RaceSelectionPreview::onSetup() { CharacterPreview::onSetup(); mAnimation->play("idle", 1, Animation::BlendMask_All, false, 1.0f, "start", "stop", 0.0f, 0); diff --git a/apps/openmw/mwrender/characterpreview.hpp b/apps/openmw/mwrender/characterpreview.hpp index a8777d8548..e2ab53bef6 100644 --- a/apps/openmw/mwrender/characterpreview.hpp +++ b/apps/openmw/mwrender/characterpreview.hpp @@ -1,8 +1,8 @@ #ifndef MWRENDER_CHARACTERPREVIEW_H #define MWRENDER_CHARACTERPREVIEW_H -#include #include +#include #include @@ -31,8 +31,8 @@ namespace MWRender class CharacterPreview { public: - CharacterPreview(osg::Group* parent, Resource::ResourceSystem* resourceSystem, const MWWorld::Ptr& character, int sizeX, int sizeY, - const osg::Vec3f& position, const osg::Vec3f& lookAt); + CharacterPreview(osg::Group* parent, Resource::ResourceSystem* resourceSystem, const MWWorld::Ptr& character, + int sizeX, int sizeY, const osg::Vec3f& position, const osg::Vec3f& lookAt); virtual ~CharacterPreview(); int getTextureWidth() const; @@ -77,7 +77,6 @@ namespace MWRender class InventoryPreview : public CharacterPreview { public: - InventoryPreview(osg::Group* parent, Resource::ResourceSystem* resourceSystem, const MWWorld::Ptr& character); void updatePtr(const MWWorld::Ptr& ptr); @@ -97,11 +96,10 @@ namespace MWRender class RaceSelectionPreview : public CharacterPreview { - ESM::NPC mBase; - MWWorld::LiveCellRef mRef; + ESM::NPC mBase; + MWWorld::LiveCellRef mRef; protected: - bool renderHeadOnly() override { return true; } void onSetup() override; @@ -111,14 +109,11 @@ namespace MWRender void setAngle(float angleRadians); - const ESM::NPC &getPrototype() const { - return mBase; - } + const ESM::NPC& getPrototype() const { return mBase; } - void setPrototype(const ESM::NPC &proto); + void setPrototype(const ESM::NPC& proto); private: - osg::ref_ptr mUpdateCameraCallback; float mPitchRadians; diff --git a/apps/openmw/mwrender/creatureanimation.cpp b/apps/openmw/mwrender/creatureanimation.cpp index e3c777674e..9175cb0f04 100644 --- a/apps/openmw/mwrender/creatureanimation.cpp +++ b/apps/openmw/mwrender/creatureanimation.cpp @@ -2,14 +2,14 @@ #include -#include #include +#include #include #include #include -#include #include #include +#include #include #include "../mwbase/environment.hpp" @@ -23,251 +23,253 @@ namespace MWRender { -CreatureAnimation::CreatureAnimation(const MWWorld::Ptr &ptr, - const std::string& model, Resource::ResourceSystem* resourceSystem) - : ActorAnimation(ptr, osg::ref_ptr(ptr.getRefData().getBaseNode()), resourceSystem) -{ - MWWorld::LiveCellRef *ref = mPtr.get(); - - if(!model.empty()) + CreatureAnimation::CreatureAnimation( + const MWWorld::Ptr& ptr, const std::string& model, Resource::ResourceSystem* resourceSystem) + : ActorAnimation(ptr, osg::ref_ptr(ptr.getRefData().getBaseNode()), resourceSystem) { - setObjectRoot(model, false, false, true); - - if((ref->mBase->mFlags&ESM::Creature::Bipedal)) - addAnimSource(Settings::Manager::getString("xbaseanim", "Models"), model); - addAnimSource(model, model); - } -} + MWWorld::LiveCellRef* ref = mPtr.get(); + if (!model.empty()) + { + setObjectRoot(model, false, false, true); -CreatureWeaponAnimation::CreatureWeaponAnimation(const MWWorld::Ptr &ptr, const std::string& model, Resource::ResourceSystem* resourceSystem) - : ActorAnimation(ptr, osg::ref_ptr(ptr.getRefData().getBaseNode()), resourceSystem) - , mShowWeapons(false) - , mShowCarriedLeft(false) -{ - MWWorld::LiveCellRef *ref = mPtr.get(); + if ((ref->mBase->mFlags & ESM::Creature::Bipedal)) + addAnimSource(Settings::Manager::getString("xbaseanim", "Models"), model); + addAnimSource(model, model); + } + } - if(!model.empty()) + CreatureWeaponAnimation::CreatureWeaponAnimation( + const MWWorld::Ptr& ptr, const std::string& model, Resource::ResourceSystem* resourceSystem) + : ActorAnimation(ptr, osg::ref_ptr(ptr.getRefData().getBaseNode()), resourceSystem) + , mShowWeapons(false) + , mShowCarriedLeft(false) { - setObjectRoot(model, true, false, true); + MWWorld::LiveCellRef* ref = mPtr.get(); - if((ref->mBase->mFlags&ESM::Creature::Bipedal)) + if (!model.empty()) { - addAnimSource(Settings::Manager::getString("xbaseanim", "Models"), model); - } - addAnimSource(model, model); + setObjectRoot(model, true, false, true); - mPtr.getClass().getInventoryStore(mPtr).setInvListener(this, mPtr); + if ((ref->mBase->mFlags & ESM::Creature::Bipedal)) + { + addAnimSource(Settings::Manager::getString("xbaseanim", "Models"), model); + } + addAnimSource(model, model); - updateParts(); - } + mPtr.getClass().getInventoryStore(mPtr).setInvListener(this, mPtr); - mWeaponAnimationTime = std::make_shared(this); -} + updateParts(); + } -void CreatureWeaponAnimation::showWeapons(bool showWeapon) -{ - if (showWeapon != mShowWeapons) - { - mShowWeapons = showWeapon; - updateParts(); + mWeaponAnimationTime = std::make_shared(this); } -} -void CreatureWeaponAnimation::showCarriedLeft(bool show) -{ - if (show != mShowCarriedLeft) + void CreatureWeaponAnimation::showWeapons(bool showWeapon) { - mShowCarriedLeft = show; - updateParts(); + if (showWeapon != mShowWeapons) + { + mShowWeapons = showWeapon; + updateParts(); + } } -} - -void CreatureWeaponAnimation::updateParts() -{ - mAmmunition.reset(); - mWeapon.reset(); - mShield.reset(); - - updateHolsteredWeapon(!mShowWeapons); - updateQuiver(); - updateHolsteredShield(mShowCarriedLeft); - - if (mShowWeapons) - updatePart(mWeapon, MWWorld::InventoryStore::Slot_CarriedRight); - if (mShowCarriedLeft) - updatePart(mShield, MWWorld::InventoryStore::Slot_CarriedLeft); -} -void CreatureWeaponAnimation::updatePart(PartHolderPtr& scene, int slot) -{ - if (!mObjectRoot) - return; - - const MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr); - MWWorld::ConstContainerStoreIterator it = inv.getSlot(slot); + void CreatureWeaponAnimation::showCarriedLeft(bool show) + { + if (show != mShowCarriedLeft) + { + mShowCarriedLeft = show; + updateParts(); + } + } - if (it == inv.end()) + void CreatureWeaponAnimation::updateParts() { - scene.reset(); - return; + mAmmunition.reset(); + mWeapon.reset(); + mShield.reset(); + + updateHolsteredWeapon(!mShowWeapons); + updateQuiver(); + updateHolsteredShield(mShowCarriedLeft); + + if (mShowWeapons) + updatePart(mWeapon, MWWorld::InventoryStore::Slot_CarriedRight); + if (mShowCarriedLeft) + updatePart(mShield, MWWorld::InventoryStore::Slot_CarriedLeft); } - MWWorld::ConstPtr item = *it; - std::string_view bonename; - std::string itemModel = item.getClass().getModel(item); - if (slot == MWWorld::InventoryStore::Slot_CarriedRight) + void CreatureWeaponAnimation::updatePart(PartHolderPtr& scene, int slot) { - if(item.getType() == ESM::Weapon::sRecordId) + if (!mObjectRoot) + return; + + const MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr); + MWWorld::ConstContainerStoreIterator it = inv.getSlot(slot); + + if (it == inv.end()) { - int type = item.get()->mBase->mData.mType; - bonename = MWMechanics::getWeaponType(type)->mAttachBone; - if (bonename != "Weapon Bone") + scene.reset(); + return; + } + MWWorld::ConstPtr item = *it; + + std::string_view bonename; + std::string itemModel = item.getClass().getModel(item); + if (slot == MWWorld::InventoryStore::Slot_CarriedRight) + { + if (item.getType() == ESM::Weapon::sRecordId) { - const NodeMap& nodeMap = getNodeMap(); - NodeMap::const_iterator found = nodeMap.find(bonename); - if (found == nodeMap.end()) - bonename = "Weapon Bone"; + int type = item.get()->mBase->mData.mType; + bonename = MWMechanics::getWeaponType(type)->mAttachBone; + if (bonename != "Weapon Bone") + { + const NodeMap& nodeMap = getNodeMap(); + NodeMap::const_iterator found = nodeMap.find(bonename); + if (found == nodeMap.end()) + bonename = "Weapon Bone"; + } } + else + bonename = "Weapon Bone"; } else - bonename = "Weapon Bone"; - } - else - { - bonename = "Shield Bone"; - if (item.getType() == ESM::Armor::sRecordId) { - itemModel = getShieldMesh(item, false); + bonename = "Shield Bone"; + if (item.getType() == ESM::Armor::sRecordId) + { + itemModel = getShieldMesh(item, false); + } } - } - try - { - osg::ref_ptr attached = attach(itemModel, bonename, bonename, item.getType() == ESM::Light::sRecordId); + try + { + osg::ref_ptr attached + = attach(itemModel, bonename, bonename, item.getType() == ESM::Light::sRecordId); - scene = std::make_unique(attached); + scene = std::make_unique(attached); - if (!item.getClass().getEnchantment(item).empty()) - mGlowUpdater = SceneUtil::addEnchantedGlow(attached, mResourceSystem, item.getClass().getEnchantmentColor(item)); + if (!item.getClass().getEnchantment(item).empty()) + mGlowUpdater + = SceneUtil::addEnchantedGlow(attached, mResourceSystem, item.getClass().getEnchantmentColor(item)); - // Crossbows start out with a bolt attached - // FIXME: code duplicated from NpcAnimation - if (slot == MWWorld::InventoryStore::Slot_CarriedRight && - item.getType() == ESM::Weapon::sRecordId && - item.get()->mBase->mData.mType == ESM::Weapon::MarksmanCrossbow) - { - const ESM::WeaponType* weaponInfo = MWMechanics::getWeaponType(ESM::Weapon::MarksmanCrossbow); - MWWorld::ConstContainerStoreIterator ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition); - if (ammo != inv.end() && ammo->get()->mBase->mData.mType == weaponInfo->mAmmoType) - attachArrow(); + // Crossbows start out with a bolt attached + // FIXME: code duplicated from NpcAnimation + if (slot == MWWorld::InventoryStore::Slot_CarriedRight && item.getType() == ESM::Weapon::sRecordId + && item.get()->mBase->mData.mType == ESM::Weapon::MarksmanCrossbow) + { + const ESM::WeaponType* weaponInfo = MWMechanics::getWeaponType(ESM::Weapon::MarksmanCrossbow); + MWWorld::ConstContainerStoreIterator ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition); + if (ammo != inv.end() && ammo->get()->mBase->mData.mType == weaponInfo->mAmmoType) + attachArrow(); + else + mAmmunition.reset(); + } else mAmmunition.reset(); - } - else - mAmmunition.reset(); - std::shared_ptr source; + std::shared_ptr source; - if (slot == MWWorld::InventoryStore::Slot_CarriedRight) - source = mWeaponAnimationTime; - else - source = std::make_shared(); + if (slot == MWWorld::InventoryStore::Slot_CarriedRight) + source = mWeaponAnimationTime; + else + source = std::make_shared(); - SceneUtil::AssignControllerSourcesVisitor assignVisitor(source); - attached->accept(assignVisitor); + SceneUtil::AssignControllerSourcesVisitor assignVisitor(source); + attached->accept(assignVisitor); + } + catch (std::exception& e) + { + Log(Debug::Error) << "Can not add creature part: " << e.what(); + } } - catch (std::exception& e) + + bool CreatureWeaponAnimation::isArrowAttached() const { - Log(Debug::Error) << "Can not add creature part: " << e.what(); + return mAmmunition != nullptr; } -} -bool CreatureWeaponAnimation::isArrowAttached() const -{ - return mAmmunition != nullptr; -} + void CreatureWeaponAnimation::detachArrow() + { + WeaponAnimation::detachArrow(mPtr); + updateQuiver(); + } -void CreatureWeaponAnimation::detachArrow() -{ - WeaponAnimation::detachArrow(mPtr); - updateQuiver(); -} + void CreatureWeaponAnimation::attachArrow() + { + WeaponAnimation::attachArrow(mPtr); -void CreatureWeaponAnimation::attachArrow() -{ - WeaponAnimation::attachArrow(mPtr); + const MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr); + MWWorld::ConstContainerStoreIterator ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition); + if (ammo != inv.end() && !ammo->getClass().getEnchantment(*ammo).empty()) + { + osg::Group* bone = getArrowBone(); + if (bone != nullptr && bone->getNumChildren()) + SceneUtil::addEnchantedGlow( + bone->getChild(0), mResourceSystem, ammo->getClass().getEnchantmentColor(*ammo)); + } - const MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr); - MWWorld::ConstContainerStoreIterator ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition); - if (ammo != inv.end() && !ammo->getClass().getEnchantment(*ammo).empty()) - { - osg::Group* bone = getArrowBone(); - if (bone != nullptr && bone->getNumChildren()) - SceneUtil::addEnchantedGlow(bone->getChild(0), mResourceSystem, ammo->getClass().getEnchantmentColor(*ammo)); + updateQuiver(); } - updateQuiver(); -} + void CreatureWeaponAnimation::releaseArrow(float attackStrength) + { + WeaponAnimation::releaseArrow(mPtr, attackStrength); + updateQuiver(); + } -void CreatureWeaponAnimation::releaseArrow(float attackStrength) -{ - WeaponAnimation::releaseArrow(mPtr, attackStrength); - updateQuiver(); -} + osg::Group* CreatureWeaponAnimation::getArrowBone() + { + if (!mWeapon) + return nullptr; -osg::Group *CreatureWeaponAnimation::getArrowBone() -{ - if (!mWeapon) - return nullptr; + if (!mPtr.getClass().hasInventoryStore(mPtr)) + return nullptr; - if (!mPtr.getClass().hasInventoryStore(mPtr)) - return nullptr; + const MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr); + MWWorld::ConstContainerStoreIterator weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); + if (weapon == inv.end() || weapon->getType() != ESM::Weapon::sRecordId) + return nullptr; - const MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr); - MWWorld::ConstContainerStoreIterator weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); - if(weapon == inv.end() || weapon->getType() != ESM::Weapon::sRecordId) - return nullptr; + int type = weapon->get()->mBase->mData.mType; + int ammoType = MWMechanics::getWeaponType(type)->mAmmoType; + if (ammoType == ESM::Weapon::None) + return nullptr; - int type = weapon->get()->mBase->mData.mType; - int ammoType = MWMechanics::getWeaponType(type)->mAmmoType; - if (ammoType == ESM::Weapon::None) - return nullptr; + // Try to find and attachment bone in actor's skeleton, otherwise fall back to the ArrowBone in weapon's mesh + osg::Group* bone = getBoneByName(MWMechanics::getWeaponType(ammoType)->mAttachBone); + if (bone == nullptr) + { + SceneUtil::FindByNameVisitor findVisitor("ArrowBone"); + mWeapon->getNode()->accept(findVisitor); + bone = findVisitor.mFoundNode; + } + return bone; + } - // Try to find and attachment bone in actor's skeleton, otherwise fall back to the ArrowBone in weapon's mesh - osg::Group* bone = getBoneByName(MWMechanics::getWeaponType(ammoType)->mAttachBone); - if (bone == nullptr) + osg::Node* CreatureWeaponAnimation::getWeaponNode() { - SceneUtil::FindByNameVisitor findVisitor ("ArrowBone"); - mWeapon->getNode()->accept(findVisitor); - bone = findVisitor.mFoundNode; + return mWeapon ? mWeapon->getNode().get() : nullptr; } - return bone; -} - -osg::Node *CreatureWeaponAnimation::getWeaponNode() -{ - return mWeapon ? mWeapon->getNode().get() : nullptr; -} -Resource::ResourceSystem *CreatureWeaponAnimation::getResourceSystem() -{ - return mResourceSystem; -} + Resource::ResourceSystem* CreatureWeaponAnimation::getResourceSystem() + { + return mResourceSystem; + } -void CreatureWeaponAnimation::addControllers() -{ - Animation::addControllers(); - WeaponAnimation::addControllers(mNodeMap, mActiveControllers, mObjectRoot.get()); -} + void CreatureWeaponAnimation::addControllers() + { + Animation::addControllers(); + WeaponAnimation::addControllers(mNodeMap, mActiveControllers, mObjectRoot.get()); + } -osg::Vec3f CreatureWeaponAnimation::runAnimation(float duration) -{ - osg::Vec3f ret = Animation::runAnimation(duration); + osg::Vec3f CreatureWeaponAnimation::runAnimation(float duration) + { + osg::Vec3f ret = Animation::runAnimation(duration); - WeaponAnimation::configureControllers(mPtr.getRefData().getPosition().rot[0] + getBodyPitchRadians()); + WeaponAnimation::configureControllers(mPtr.getRefData().getPosition().rot[0] + getBodyPitchRadians()); - return ret; -} + return ret; + } } diff --git a/apps/openmw/mwrender/creatureanimation.hpp b/apps/openmw/mwrender/creatureanimation.hpp index 8722539d6b..3342fb3967 100644 --- a/apps/openmw/mwrender/creatureanimation.hpp +++ b/apps/openmw/mwrender/creatureanimation.hpp @@ -1,9 +1,9 @@ #ifndef GAME_RENDER_CREATUREANIMATION_H #define GAME_RENDER_CREATUREANIMATION_H +#include "../mwworld/inventorystore.hpp" #include "actoranimation.hpp" #include "weaponanimation.hpp" -#include "../mwworld/inventorystore.hpp" namespace MWWorld { @@ -15,17 +15,20 @@ namespace MWRender class CreatureAnimation : public ActorAnimation { public: - CreatureAnimation(const MWWorld::Ptr &ptr, const std::string& model, Resource::ResourceSystem* resourceSystem); + CreatureAnimation(const MWWorld::Ptr& ptr, const std::string& model, Resource::ResourceSystem* resourceSystem); virtual ~CreatureAnimation() {} }; // For creatures with weapons and shields // Animation is already virtual anyway, so might as well make a separate class. // Most creatures don't need weapons/shields, so this will save some memory. - class CreatureWeaponAnimation : public ActorAnimation, public WeaponAnimation, public MWWorld::InventoryStoreListener + class CreatureWeaponAnimation : public ActorAnimation, + public WeaponAnimation, + public MWWorld::InventoryStoreListener { public: - CreatureWeaponAnimation(const MWWorld::Ptr &ptr, const std::string& model, Resource::ResourceSystem* resourceSystem); + CreatureWeaponAnimation( + const MWWorld::Ptr& ptr, const std::string& model, Resource::ResourceSystem* resourceSystem); virtual ~CreatureWeaponAnimation() {} void equipmentChanged() override { updateParts(); } @@ -48,7 +51,10 @@ namespace MWRender osg::Node* getWeaponNode() override; Resource::ResourceSystem* getResourceSystem() override; void showWeapon(bool show) override { showWeapons(show); } - void setWeaponGroup(const std::string& group, bool relativeDuration) override { mWeaponAnimationTime->setGroup(group, relativeDuration); } + void setWeaponGroup(const std::string& group, bool relativeDuration) override + { + mWeaponAnimationTime->setGroup(group, relativeDuration); + } void addControllers() override; diff --git a/apps/openmw/mwrender/effectmanager.cpp b/apps/openmw/mwrender/effectmanager.cpp index 6b1543eda9..3ae0c34c7a 100644 --- a/apps/openmw/mwrender/effectmanager.cpp +++ b/apps/openmw/mwrender/effectmanager.cpp @@ -8,83 +8,79 @@ #include #include "animation.hpp" -#include "vismask.hpp" #include "util.hpp" +#include "vismask.hpp" #include namespace MWRender { -EffectManager::EffectManager(osg::ref_ptr parent, Resource::ResourceSystem* resourceSystem) - : mParentNode(parent) - , mResourceSystem(resourceSystem) -{ -} + EffectManager::EffectManager(osg::ref_ptr parent, Resource::ResourceSystem* resourceSystem) + : mParentNode(parent) + , mResourceSystem(resourceSystem) + { + } -EffectManager::~EffectManager() -{ - clear(); -} + EffectManager::~EffectManager() + { + clear(); + } -void EffectManager::addEffect(const std::string& model, std::string_view textureOverride, const osg::Vec3f& worldPosition, float scale, bool isMagicVFX) -{ - osg::ref_ptr node = mResourceSystem->getSceneManager()->getInstance(model); + void EffectManager::addEffect(const std::string& model, std::string_view textureOverride, + const osg::Vec3f& worldPosition, float scale, bool isMagicVFX) + { + osg::ref_ptr node = mResourceSystem->getSceneManager()->getInstance(model); - node->setNodeMask(Mask_Effect); + node->setNodeMask(Mask_Effect); - Effect effect; - effect.mAnimTime = std::make_shared(); + Effect effect; + effect.mAnimTime = std::make_shared(); - SceneUtil::FindMaxControllerLengthVisitor findMaxLengthVisitor; - node->accept(findMaxLengthVisitor); - effect.mMaxControllerLength = findMaxLengthVisitor.getMaxLength(); + SceneUtil::FindMaxControllerLengthVisitor findMaxLengthVisitor; + node->accept(findMaxLengthVisitor); + effect.mMaxControllerLength = findMaxLengthVisitor.getMaxLength(); - osg::ref_ptr trans = new osg::PositionAttitudeTransform; - trans->setPosition(worldPosition); - trans->setScale(osg::Vec3f(scale, scale, scale)); - trans->addChild(node); + osg::ref_ptr trans = new osg::PositionAttitudeTransform; + trans->setPosition(worldPosition); + trans->setScale(osg::Vec3f(scale, scale, scale)); + trans->addChild(node); - effect.mTransform = trans; + effect.mTransform = trans; - SceneUtil::AssignControllerSourcesVisitor assignVisitor(effect.mAnimTime); - node->accept(assignVisitor); + SceneUtil::AssignControllerSourcesVisitor assignVisitor(effect.mAnimTime); + node->accept(assignVisitor); - if (isMagicVFX) - overrideFirstRootTexture(textureOverride, mResourceSystem, node); - else - overrideTexture(textureOverride, mResourceSystem, node); + if (isMagicVFX) + overrideFirstRootTexture(textureOverride, mResourceSystem, node); + else + overrideTexture(textureOverride, mResourceSystem, node); - mParentNode->addChild(trans); + mParentNode->addChild(trans); - mEffects.push_back(std::move(effect)); -} + mEffects.push_back(std::move(effect)); + } -void EffectManager::update(float dt) -{ - mEffects.erase( - std::remove_if( - mEffects.begin(), - mEffects.end(), - [dt, this](Effect& effect) - { - effect.mAnimTime->addTime(dt); - const auto remove = effect.mAnimTime->getTime() >= effect.mMaxControllerLength; - if (remove) - mParentNode->removeChild(effect.mTransform); - return remove; - }), - mEffects.end() - ); -} + void EffectManager::update(float dt) + { + mEffects.erase(std::remove_if(mEffects.begin(), mEffects.end(), + [dt, this](Effect& effect) { + effect.mAnimTime->addTime(dt); + const auto remove = effect.mAnimTime->getTime() >= effect.mMaxControllerLength; + if (remove) + mParentNode->removeChild(effect.mTransform); + return remove; + }), + mEffects.end()); + } -void EffectManager::clear() -{ - for(const auto& effect : mEffects) + void EffectManager::clear() { - mParentNode->removeChild(effect.mTransform); + for (const auto& effect : mEffects) + { + mParentNode->removeChild(effect.mTransform); + } + mEffects.clear(); } - mEffects.clear(); -} } diff --git a/apps/openmw/mwrender/effectmanager.hpp b/apps/openmw/mwrender/effectmanager.hpp index f974a3a01e..2477344fd0 100644 --- a/apps/openmw/mwrender/effectmanager.hpp +++ b/apps/openmw/mwrender/effectmanager.hpp @@ -33,7 +33,8 @@ namespace MWRender ~EffectManager(); /// Add an effect. When it's finished playing, it will be removed automatically. - void addEffect(const std::string& model, std::string_view textureOverride, const osg::Vec3f& worldPosition, float scale, bool isMagicVFX = true); + void addEffect(const std::string& model, std::string_view textureOverride, const osg::Vec3f& worldPosition, + float scale, bool isMagicVFX = true); void update(float dt); diff --git a/apps/openmw/mwrender/fogmanager.cpp b/apps/openmw/mwrender/fogmanager.cpp index b68b846851..cfbad67076 100644 --- a/apps/openmw/mwrender/fogmanager.cpp +++ b/apps/openmw/mwrender/fogmanager.cpp @@ -38,14 +38,14 @@ namespace MWRender DLInteriorFogEnd = Settings::Manager::getFloat("distant interior fog end", "Fog"); } - void FogManager::configure(float viewDistance, const ESM::Cell *cell) + void FogManager::configure(float viewDistance, const ESM::Cell* cell) { osg::Vec4f color = SceneUtil::colourFromRGB(cell->mAmbi.mFog); if (mDistantFog) { float density = std::max(0.2f, cell->mAmbi.mFogDensity); - mLandFogStart = DLInteriorFogEnd * (1.0f - density) + DLInteriorFogStart*density; + mLandFogStart = DLInteriorFogEnd * (1.0f - density) + DLInteriorFogStart * density; mLandFogEnd = DLInteriorFogEnd; mUnderwaterFogStart = DLUnderwaterFogStart; mUnderwaterFogEnd = DLUnderwaterFogEnd; @@ -55,7 +55,8 @@ namespace MWRender configure(viewDistance, cell->mAmbi.mFogDensity, mUnderwaterIndoorFog, 1.0f, 0.0f, color); } - void FogManager::configure(float viewDistance, float fogDepth, float underwaterFog, float dlFactor, float dlOffset, const osg::Vec4f &color) + void FogManager::configure(float viewDistance, float fogDepth, float underwaterFog, float dlFactor, float dlOffset, + const osg::Vec4f& color) { if (mDistantFog) { @@ -96,7 +97,7 @@ namespace MWRender { if (isUnderwater) { - return mUnderwaterColor * mUnderwaterWeight + mFogColor * (1.f-mUnderwaterWeight); + return mUnderwaterColor * mUnderwaterWeight + mFogColor * (1.f - mUnderwaterWeight); } return mFogColor; diff --git a/apps/openmw/mwrender/fogmanager.hpp b/apps/openmw/mwrender/fogmanager.hpp index c3efd06ab7..6f91e2ff30 100644 --- a/apps/openmw/mwrender/fogmanager.hpp +++ b/apps/openmw/mwrender/fogmanager.hpp @@ -15,8 +15,9 @@ namespace MWRender public: FogManager(); - void configure(float viewDistance, const ESM::Cell *cell); - void configure(float viewDistance, float fogDepth, float underwaterFog, float dlFactor, float dlOffset, const osg::Vec4f &color); + void configure(float viewDistance, const ESM::Cell* cell); + void configure(float viewDistance, float fogDepth, float underwaterFog, float dlFactor, float dlOffset, + const osg::Vec4f& color); osg::Vec4f getFogColor(bool isUnderwater) const; float getFogStart(bool isUnderwater) const; diff --git a/apps/openmw/mwrender/globalmap.cpp b/apps/openmw/mwrender/globalmap.cpp index dca26a220f..1d6b881127 100644 --- a/apps/openmw/mwrender/globalmap.cpp +++ b/apps/openmw/mwrender/globalmap.cpp @@ -1,21 +1,21 @@ #include "globalmap.hpp" -#include -#include -#include #include +#include +#include #include +#include #include -#include #include +#include #include -#include -#include #include +#include +#include #include @@ -24,15 +24,16 @@ #include "../mwworld/esmstore.hpp" -#include "vismask.hpp" #include "util.hpp" +#include "vismask.hpp" namespace { // Create a screen-aligned quad with given texture coordinates. // Assumes a top-left origin of the sampled image. - osg::ref_ptr createTexturedQuad(float leftTexCoord, float topTexCoord, float rightTexCoord, float bottomTexCoord) + osg::ref_ptr createTexturedQuad( + float leftTexCoord, float topTexCoord, float rightTexCoord, float bottomTexCoord) { osg::ref_ptr geom = new osg::Geometry; @@ -45,10 +46,10 @@ namespace geom->setVertexArray(verts); osg::ref_ptr texcoords = new osg::Vec2Array; - texcoords->push_back(osg::Vec2f(leftTexCoord, 1.f-bottomTexCoord)); - texcoords->push_back(osg::Vec2f(leftTexCoord, 1.f-topTexCoord)); - texcoords->push_back(osg::Vec2f(rightTexCoord, 1.f-topTexCoord)); - texcoords->push_back(osg::Vec2f(rightTexCoord, 1.f-bottomTexCoord)); + texcoords->push_back(osg::Vec2f(leftTexCoord, 1.f - bottomTexCoord)); + texcoords->push_back(osg::Vec2f(leftTexCoord, 1.f - topTexCoord)); + texcoords->push_back(osg::Vec2f(rightTexCoord, 1.f - topTexCoord)); + texcoords->push_back(osg::Vec2f(rightTexCoord, 1.f - bottomTexCoord)); osg::ref_ptr colors = new osg::Vec4Array; colors->push_back(osg::Vec4(1.f, 1.f, 1.f, 1.f)); @@ -56,12 +57,11 @@ namespace geom->setTexCoordArray(0, texcoords, osg::Array::BIND_PER_VERTEX); - geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4)); + geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4)); return geom; } - class CameraUpdateGlobalCallback : public SceneUtil::NodeCallback { public: @@ -106,7 +106,8 @@ namespace osgDB::ReaderWriter::WriteResult result = readerwriter->writeImage(overlayImage, ostream); if (!result.success()) { - Log(Debug::Warning) << "Error: Can't write map overlay: " << result.message() << " code " << result.status(); + Log(Debug::Warning) << "Error: Can't write map overlay: " << result.message() << " code " + << result.status(); return std::vector(); } @@ -121,8 +122,16 @@ namespace MWRender class CreateMapWorkItem : public SceneUtil::WorkItem { public: - CreateMapWorkItem(int width, int height, int minX, int minY, int maxX, int maxY, int cellSize, const MWWorld::Store& landStore) - : mWidth(width), mHeight(height), mMinX(minX), mMinY(minY), mMaxX(maxX), mMaxY(maxY), mCellSize(cellSize), mLandStore(landStore) + CreateMapWorkItem(int width, int height, int minX, int minY, int maxX, int maxY, int cellSize, + const MWWorld::Store& landStore) + : mWidth(width) + , mHeight(height) + , mMinX(minX) + , mMinY(minY) + , mMaxX(maxX) + , mMaxY(maxY) + , mCellSize(cellSize) + , mLandStore(landStore) { } @@ -140,19 +149,19 @@ namespace MWRender { for (int y = mMinY; y <= mMaxY; ++y) { - const ESM::Land* land = mLandStore.search (x,y); + const ESM::Land* land = mLandStore.search(x, y); - for (int cellY=0; cellY(float(cellX) / float(mCellSize) * 9); int vertexY = static_cast(float(cellY) / float(mCellSize) * 9); - int texelX = (x-mMinX) * mCellSize + cellX; - int texelY = (y-mMinY) * mCellSize + cellY; + int texelX = (x - mMinX) * mCellSize + cellX; + int texelY = (y - mMinY) * mCellSize + cellY; - unsigned char r,g,b; + unsigned char r, g, b; float y2 = 0; if (land && (land->mDataTypes & ESM::Land::DATA_WNAM)) @@ -188,10 +197,11 @@ namespace MWRender } data[texelY * mWidth * 3 + texelX * 3] = r; - data[texelY * mWidth * 3 + texelX * 3+1] = g; - data[texelY * mWidth * 3 + texelX * 3+2] = b; + data[texelY * mWidth * 3 + texelX * 3 + 1] = g; + data[texelY * mWidth * 3 + texelX * 3 + 2] = b; - alphaData[texelY * mWidth+ texelX] = (y2 < 0) ? static_cast(0) : static_cast(255); + alphaData[texelY * mWidth + texelX] + = (y2 < 0) ? static_cast(0) : static_cast(255); } } } @@ -247,12 +257,11 @@ namespace MWRender std::vector mImageData; explicit WritePng(osg::ref_ptr overlayImage) - : mOverlayImage(std::move(overlayImage)) {} - - void doWork() override + : mOverlayImage(std::move(overlayImage)) { - mImageData = writePng(*mOverlayImage); } + + void doWork() override { mImageData = writePng(*mOverlayImage); } }; GlobalMap::GlobalMap(osg::Group* root, SceneUtil::WorkQueue* workQueue) @@ -260,8 +269,10 @@ namespace MWRender , mWorkQueue(workQueue) , mWidth(0) , mHeight(0) - , mMinX(0), mMaxX(0) - , mMinY(0), mMaxY(0) + , mMinX(0) + , mMaxX(0) + , mMinY(0) + , mMaxY(0) { mCellSize = Settings::Manager::getInt("global map cell size", "Map"); @@ -278,10 +289,9 @@ namespace MWRender mWorkItem->waitTillDone(); } - void GlobalMap::render () + void GlobalMap::render() { - const MWWorld::ESMStore &esmStore = - MWBase::Environment::get().getWorld()->getStore(); + const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); // get the size of the world MWWorld::Store::iterator it = esmStore.get().extBegin(); @@ -297,10 +307,11 @@ namespace MWRender mMaxY = it->getGridY(); } - mWidth = mCellSize*(mMaxX-mMinX+1); - mHeight = mCellSize*(mMaxY-mMinY+1); + mWidth = mCellSize * (mMaxX - mMinX + 1); + mHeight = mCellSize * (mMaxY - mMinY + 1); - mWorkItem = new CreateMapWorkItem(mWidth, mHeight, mMinX, mMinY, mMaxX, mMaxY, mCellSize, esmStore.get()); + mWorkItem + = new CreateMapWorkItem(mWidth, mHeight, mMinX, mMinY, mMaxX, mMaxY, mCellSize, esmStore.get()); mWorkQueue->addWorkItem(mWorkItem); } @@ -308,13 +319,14 @@ namespace MWRender { imageX = (float(x / float(Constants::CellSizeInUnits) - mMinX) / (mMaxX - mMinX + 1)) * getWidth(); - imageY = (1.f-float(z / float(Constants::CellSizeInUnits) - mMinY) / (mMaxY - mMinY + 1)) * getHeight(); + imageY = (1.f - float(z / float(Constants::CellSizeInUnits) - mMinY) / (mMaxY - mMinY + 1)) * getHeight(); } - void GlobalMap::requestOverlayTextureUpdate(int x, int y, int width, int height, osg::ref_ptr texture, bool clear, bool cpuCopy, - float srcLeft, float srcTop, float srcRight, float srcBottom) + void GlobalMap::requestOverlayTextureUpdate(int x, int y, int width, int height, + osg::ref_ptr texture, bool clear, bool cpuCopy, float srcLeft, float srcTop, float srcRight, + float srcBottom) { - osg::ref_ptr camera (new osg::Camera); + osg::ref_ptr camera(new osg::Camera); camera->setNodeMask(Mask_RenderToTexture); camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF); camera->setViewMatrix(osg::Matrix::identity()); @@ -327,7 +339,7 @@ namespace MWRender if (clear) { camera->setClearMask(GL_COLOR_BUFFER_BIT); - camera->setClearColor(osg::Vec4(0,0,0,0)); + camera->setClearColor(osg::Vec4(0, 0, 0, 0)); } else camera->setClearMask(GL_NONE); @@ -343,7 +355,7 @@ namespace MWRender if (cpuCopy) { // Attach an image to copy the render back to the CPU when finished - osg::ref_ptr image (new osg::Image); + osg::ref_ptr image(new osg::Image); image->setPixelFormat(mOverlayImage->getPixelFormat()); image->setDataType(mOverlayImage->getDataType()); camera->attach(osg::Camera::COLOR_BUFFER, image); @@ -404,7 +416,8 @@ namespace MWRender return; int originX = (cellX - mMinX) * mCellSize; - int originY = (cellY - mMinY + 1) * mCellSize; // +1 because we want the top left corner of the cell, not the bottom left + int originY = (cellY - mMinY + 1) + * mCellSize; // +1 because we want the top left corner of the cell, not the bottom left if (cellX > mMaxX || cellX < mMinX || cellY > mMaxY || cellY < mMinY) return; @@ -450,10 +463,13 @@ namespace MWRender int mLeft, mTop, mRight, mBottom; Box(int left, int top, int right, int bottom) - : mLeft(left), mTop(top), mRight(right), mBottom(bottom) + : mLeft(left) + , mTop(top) + , mRight(right) + , mBottom(bottom) { } - bool operator == (const Box& other) const + bool operator==(const Box& other) const { return mLeft == other.mLeft && mTop == other.mTop && mRight == other.mRight && mBottom == other.mBottom; } @@ -465,13 +481,12 @@ namespace MWRender const ESM::GlobalMap::Bounds& bounds = map.mBounds; - if (bounds.mMaxX-bounds.mMinX < 0) + if (bounds.mMaxX - bounds.mMinX < 0) return; - if (bounds.mMaxY-bounds.mMinY < 0) + if (bounds.mMaxY - bounds.mMinY < 0) return; - if (bounds.mMinX > bounds.mMaxX - || bounds.mMinY > bounds.mMaxY) + if (bounds.mMinX > bounds.mMaxX || bounds.mMinY > bounds.mMaxY) throw std::runtime_error("invalid map bounds"); if (map.mImageData.empty()) @@ -497,8 +512,8 @@ namespace MWRender int imageWidth = image->s(); int imageHeight = image->t(); - int xLength = (bounds.mMaxX-bounds.mMinX+1); - int yLength = (bounds.mMaxY-bounds.mMinY+1); + int xLength = (bounds.mMaxX - bounds.mMinX + 1); + int yLength = (bounds.mMaxY - bounds.mMinY + 1); // Size of one cell in image space int cellImageSizeSrc = imageWidth / xLength; @@ -511,28 +526,23 @@ namespace MWRender int cellImageSizeDst = mCellSize; // Completely off-screen? -> no need to blit anything - if (bounds.mMaxX < mMinX - || bounds.mMaxY < mMinY - || bounds.mMinX > mMaxX - || bounds.mMinY > mMaxY) + if (bounds.mMaxX < mMinX || bounds.mMaxY < mMinY || bounds.mMinX > mMaxX || bounds.mMinY > mMaxY) return; int leftDiff = (mMinX - bounds.mMinX); int topDiff = (bounds.mMaxY - mMaxY); int rightDiff = (bounds.mMaxX - mMaxX); - int bottomDiff = (mMinY - bounds.mMinY); + int bottomDiff = (mMinY - bounds.mMinY); - Box srcBox ( std::max(0, leftDiff * cellImageSizeSrc), - std::max(0, topDiff * cellImageSizeSrc), - std::min(imageWidth, imageWidth - rightDiff * cellImageSizeSrc), - std::min(imageHeight, imageHeight - bottomDiff * cellImageSizeSrc)); + Box srcBox(std::max(0, leftDiff * cellImageSizeSrc), std::max(0, topDiff * cellImageSizeSrc), + std::min(imageWidth, imageWidth - rightDiff * cellImageSizeSrc), + std::min(imageHeight, imageHeight - bottomDiff * cellImageSizeSrc)); - Box destBox ( std::max(0, -leftDiff * cellImageSizeDst), - std::max(0, -topDiff * cellImageSizeDst), - std::min(mWidth, mWidth + rightDiff * cellImageSizeDst), - std::min(mHeight, mHeight + bottomDiff * cellImageSizeDst)); + Box destBox(std::max(0, -leftDiff * cellImageSizeDst), std::max(0, -topDiff * cellImageSizeDst), + std::min(mWidth, mWidth + rightDiff * cellImageSizeDst), + std::min(mHeight, mHeight + bottomDiff * cellImageSizeDst)); - osg::ref_ptr texture (new osg::Texture2D); + osg::ref_ptr texture(new osg::Texture2D); texture->setImage(image); texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE); texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE); @@ -551,9 +561,10 @@ namespace MWRender // Dimensions don't match. This could mean a changed map region, or a changed map resolution. // In the latter case, we'll want filtering. // Create a RTT Camera and draw the image onto mOverlayImage in the next frame. - requestOverlayTextureUpdate(destBox.mLeft, destBox.mTop, destBox.mRight-destBox.mLeft, destBox.mBottom-destBox.mTop, texture, true, true, - srcBox.mLeft/float(imageWidth), srcBox.mTop/float(imageHeight), - srcBox.mRight/float(imageWidth), srcBox.mBottom/float(imageHeight)); + requestOverlayTextureUpdate(destBox.mLeft, destBox.mTop, destBox.mRight - destBox.mLeft, + destBox.mBottom - destBox.mTop, texture, true, true, srcBox.mLeft / float(imageWidth), + srcBox.mTop / float(imageHeight), srcBox.mRight / float(imageWidth), + srcBox.mBottom / float(imageHeight)); } } @@ -586,7 +597,7 @@ namespace MWRender } } - bool GlobalMap::copyResult(osg::Camera *camera, unsigned int frame) + bool GlobalMap::copyResult(osg::Camera* camera, unsigned int frame) { ImageDestMap::iterator it = mPendingImageDest.find(camera); if (it == mPendingImageDest.end()) @@ -594,7 +605,9 @@ namespace MWRender else { ImageDest& imageDest = it->second; - if (imageDest.mFrameDone == 0) imageDest.mFrameDone = frame+2; // wait an extra frame to ensure the draw thread has completed its frame. + if (imageDest.mFrameDone == 0) + imageDest.mFrameDone + = frame + 2; // wait an extra frame to ensure the draw thread has completed its frame. if (imageDest.mFrameDone > frame) { ++it; @@ -607,7 +620,7 @@ namespace MWRender } } - void GlobalMap::markForRemoval(osg::Camera *camera) + void GlobalMap::markForRemoval(osg::Camera* camera) { CameraVector::iterator found = std::find(mActiveCameras.begin(), mActiveCameras.end(), camera); if (found == mActiveCameras.end()) @@ -627,7 +640,7 @@ namespace MWRender mCamerasPendingRemoval.clear(); } - void GlobalMap::removeCamera(osg::Camera *cam) + void GlobalMap::removeCamera(osg::Camera* cam) { cam->removeChildren(0, cam->getNumChildren()); mRoot->removeChild(cam); diff --git a/apps/openmw/mwrender/globalmap.hpp b/apps/openmw/mwrender/globalmap.hpp index 28531f14df..ad5bd38ab1 100644 --- a/apps/openmw/mwrender/globalmap.hpp +++ b/apps/openmw/mwrender/globalmap.hpp @@ -1,9 +1,9 @@ #ifndef GAME_RENDER_GLOBALMAP_H #define GAME_RENDER_GLOBALMAP_H +#include #include #include -#include #include @@ -43,7 +43,7 @@ namespace MWRender void worldPosToImageSpace(float x, float z, float& imageX, float& imageY); - void exploreCell (int cellX, int cellY, osg::ref_ptr localMapTexture); + void exploreCell(int cellX, int cellY, osg::ref_ptr localMapTexture); /// Clears the overlay void clear(); @@ -64,8 +64,8 @@ namespace MWRender */ void markForRemoval(osg::Camera* camera); - void write (ESM::GlobalMap& map); - void read (ESM::GlobalMap& map); + void write(ESM::GlobalMap& map); + void read(ESM::GlobalMap& map); osg::ref_ptr getBaseTexture(); osg::ref_ptr getOverlayTexture(); @@ -82,14 +82,15 @@ namespace MWRender * x, y, width and height are the destination coordinates (top-left coordinate origin) * @param cpuCopy copy the resulting render onto mOverlayImage as well? */ - void requestOverlayTextureUpdate(int x, int y, int width, int height, osg::ref_ptr texture, bool clear, bool cpuCopy, - float srcLeft = 0.f, float srcTop = 0.f, float srcRight = 1.f, float srcBottom = 1.f); + void requestOverlayTextureUpdate(int x, int y, int width, int height, osg::ref_ptr texture, + bool clear, bool cpuCopy, float srcLeft = 0.f, float srcTop = 0.f, float srcRight = 1.f, + float srcBottom = 1.f); int mCellSize; osg::ref_ptr mRoot; - typedef std::vector > CameraVector; + typedef std::vector> CameraVector; CameraVector mActiveCameras; CameraVector mCamerasPendingRemoval; @@ -97,7 +98,8 @@ namespace MWRender struct ImageDest { ImageDest() - : mX(0), mY(0) + : mX(0) + , mY(0) , mFrameDone(0) { } @@ -111,7 +113,7 @@ namespace MWRender ImageDestMap mPendingImageDest; - std::vector< std::pair > mExploredCells; + std::vector> mExploredCells; osg::ref_ptr mBaseTexture; osg::ref_ptr mAlphaTexture; @@ -136,4 +138,3 @@ namespace MWRender } #endif - diff --git a/apps/openmw/mwrender/groundcover.cpp b/apps/openmw/mwrender/groundcover.cpp index 194227f758..244001923d 100644 --- a/apps/openmw/mwrender/groundcover.cpp +++ b/apps/openmw/mwrender/groundcover.cpp @@ -1,19 +1,19 @@ #include "groundcover.hpp" -#include #include #include +#include #include -#include #include +#include #include +#include +#include #include #include -#include #include -#include -#include +#include #include "../mwworld/groundcoverstore.hpp" @@ -25,9 +25,9 @@ namespace MWRender { public: InstancingVisitor(std::vector& instances, osg::Vec3f& chunkPosition) - : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) - , mInstances(instances) - , mChunkPosition(chunkPosition) + : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) + , mInstances(instances) + , mChunkPosition(chunkPosition) { } @@ -68,6 +68,7 @@ namespace MWRender geom.setVertexAttribArray(6, transforms.get(), osg::Array::BIND_PER_VERTEX); geom.setVertexAttribArray(7, rotations.get(), osg::Array::BIND_PER_VERTEX); } + private: std::vector mInstances; osg::Vec3f mChunkPosition; @@ -83,10 +84,12 @@ namespace MWRender bool isInstanceEnabled() { - if (mDensity >= 1.f) return true; + if (mDensity >= 1.f) + return true; mCurrentGroundcover += mDensity; - if (mCurrentGroundcover < 1.f) return false; + if (mCurrentGroundcover < 1.f) + return false; mCurrentGroundcover -= 1.f; @@ -102,12 +105,17 @@ namespace MWRender class ViewDistanceCallback : public SceneUtil::NodeCallback { public: - ViewDistanceCallback(float dist, const osg::BoundingBox& box) : mViewDistance(dist), mBox(box) {} + ViewDistanceCallback(float dist, const osg::BoundingBox& box) + : mViewDistance(dist) + , mBox(box) + { + } void operator()(osg::Node* node, osg::NodeVisitor* nv) { if (Terrain::distance(mBox, nv->getEyePoint()) <= mViewDistance) traverse(node, nv); } + private: float mViewDistance; osg::BoundingBox mBox; @@ -116,18 +124,22 @@ namespace MWRender inline bool isInChunkBorders(ESM::CellRef& ref, osg::Vec2f& minBound, osg::Vec2f& maxBound) { osg::Vec2f size = maxBound - minBound; - if (size.x() >=1 && size.y() >=1) return true; + if (size.x() >= 1 && size.y() >= 1) + return true; osg::Vec3f pos = ref.mPos.asVec3(); osg::Vec3f cellPos = pos / ESM::Land::REAL_SIZE; - if ((minBound.x() > std::floor(minBound.x()) && cellPos.x() < minBound.x()) || (minBound.y() > std::floor(minBound.y()) && cellPos.y() < minBound.y()) - || (maxBound.x() < std::ceil(maxBound.x()) && cellPos.x() >= maxBound.x()) || (maxBound.y() < std::ceil(maxBound.y()) && cellPos.y() >= maxBound.y())) + if ((minBound.x() > std::floor(minBound.x()) && cellPos.x() < minBound.x()) + || (minBound.y() > std::floor(minBound.y()) && cellPos.y() < minBound.y()) + || (maxBound.x() < std::ceil(maxBound.x()) && cellPos.x() >= maxBound.x()) + || (maxBound.y() < std::ceil(maxBound.y()) && cellPos.y() >= maxBound.y())) return false; return true; } - osg::ref_ptr Groundcover::getChunk(float size, const osg::Vec2f& center, unsigned char lod, unsigned int lodFlags, bool activeGrid, const osg::Vec3f& viewPoint, bool compile) + osg::ref_ptr Groundcover::getChunk(float size, const osg::Vec2f& center, unsigned char lod, + unsigned int lodFlags, bool activeGrid, const osg::Vec3f& viewPoint, bool compile) { if (lod > getMaxLodLevel()) return nullptr; @@ -145,52 +157,55 @@ namespace MWRender } } - Groundcover::Groundcover(Resource::SceneManager* sceneManager, float density, float viewDistance, const MWWorld::GroundcoverStore& store) - : GenericResourceManager(nullptr) - , mSceneManager(sceneManager) - , mDensity(density) - , mStateset(new osg::StateSet) - , mGroundcoverStore(store) + Groundcover::Groundcover( + Resource::SceneManager* sceneManager, float density, float viewDistance, const MWWorld::GroundcoverStore& store) + : GenericResourceManager(nullptr) + , mSceneManager(sceneManager) + , mDensity(density) + , mStateset(new osg::StateSet) + , mGroundcoverStore(store) { - setViewDistance(viewDistance); - // MGE uses default alpha settings for groundcover, so we can not rely on alpha properties - // Force a unified alpha handling instead of data from meshes - osg::ref_ptr alpha = new osg::AlphaFunc(osg::AlphaFunc::GEQUAL, 128.f / 255.f); - mStateset->setAttributeAndModes(alpha.get(), osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); - mStateset->setAttributeAndModes(new osg::BlendFunc, osg::StateAttribute::OFF|osg::StateAttribute::OVERRIDE); - mStateset->setRenderBinDetails(0, "RenderBin", osg::StateSet::OVERRIDE_RENDERBIN_DETAILS); - mStateset->setAttribute(new osg::VertexAttribDivisor(6, 1)); - mStateset->setAttribute(new osg::VertexAttribDivisor(7, 1)); - - mProgramTemplate = mSceneManager->getShaderManager().getProgramTemplate() ? Shader::ShaderManager::cloneProgram(mSceneManager->getShaderManager().getProgramTemplate()) : osg::ref_ptr(new osg::Program); - mProgramTemplate->addBindAttribLocation("aOffset", 6); - mProgramTemplate->addBindAttribLocation("aRotation", 7); + setViewDistance(viewDistance); + // MGE uses default alpha settings for groundcover, so we can not rely on alpha properties + // Force a unified alpha handling instead of data from meshes + osg::ref_ptr alpha = new osg::AlphaFunc(osg::AlphaFunc::GEQUAL, 128.f / 255.f); + mStateset->setAttributeAndModes(alpha.get(), osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); + mStateset->setAttributeAndModes(new osg::BlendFunc, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE); + mStateset->setRenderBinDetails(0, "RenderBin", osg::StateSet::OVERRIDE_RENDERBIN_DETAILS); + mStateset->setAttribute(new osg::VertexAttribDivisor(6, 1)); + mStateset->setAttribute(new osg::VertexAttribDivisor(7, 1)); + + mProgramTemplate = mSceneManager->getShaderManager().getProgramTemplate() + ? Shader::ShaderManager::cloneProgram(mSceneManager->getShaderManager().getProgramTemplate()) + : osg::ref_ptr(new osg::Program); + mProgramTemplate->addBindAttribLocation("aOffset", 6); + mProgramTemplate->addBindAttribLocation("aRotation", 7); } - Groundcover::~Groundcover() - { - } + Groundcover::~Groundcover() {} void Groundcover::collectInstances(InstanceMap& instances, float size, const osg::Vec2f& center) { - if (mDensity <=0.f) return; + if (mDensity <= 0.f) + return; - osg::Vec2f minBound = (center - osg::Vec2f(size/2.f, size/2.f)); - osg::Vec2f maxBound = (center + osg::Vec2f(size/2.f, size/2.f)); + osg::Vec2f minBound = (center - osg::Vec2f(size / 2.f, size / 2.f)); + osg::Vec2f maxBound = (center + osg::Vec2f(size / 2.f, size / 2.f)); DensityCalculator calculator(mDensity); ESM::ReadersCache readers; - osg::Vec2i startCell = osg::Vec2i(std::floor(center.x() - size/2.f), std::floor(center.y() - size/2.f)); + osg::Vec2i startCell = osg::Vec2i(std::floor(center.x() - size / 2.f), std::floor(center.y() - size / 2.f)); for (int cellX = startCell.x(); cellX < startCell.x() + size; ++cellX) { for (int cellY = startCell.y(); cellY < startCell.y() + size; ++cellY) { ESM::Cell cell; mGroundcoverStore.initCell(cell, cellX, cellY); - if (cell.mContextList.empty()) continue; + if (cell.mContextList.empty()) + continue; calculator.reset(); std::map refs; - for (size_t i=0; i(cell.mContextList[i].index); const ESM::ReadersCache::BusyItem reader = readers.get(index); @@ -200,10 +215,16 @@ namespace MWRender bool deleted = false; while (cell.getNextRef(*reader, ref, deleted)) { - if (!deleted && refs.find(ref.mRefNum) == refs.end() && !calculator.isInstanceEnabled()) deleted = true; - if (!deleted && !isInChunkBorders(ref, minBound, maxBound)) deleted = true; - - if (deleted) { refs.erase(ref.mRefNum); continue; } + if (!deleted && refs.find(ref.mRefNum) == refs.end() && !calculator.isInstanceEnabled()) + deleted = true; + if (!deleted && !isInChunkBorders(ref, minBound, maxBound)) + deleted = true; + + if (deleted) + { + refs.erase(ref.mRefNum); + continue; + } refs[ref.mRefNum] = std::move(ref); } } @@ -222,11 +243,13 @@ namespace MWRender osg::ref_ptr Groundcover::createChunk(InstanceMap& instances, const osg::Vec2f& center) { osg::ref_ptr group = new osg::Group; - osg::Vec3f worldCenter = osg::Vec3f(center.x(), center.y(), 0)*ESM::Land::REAL_SIZE; + osg::Vec3f worldCenter = osg::Vec3f(center.x(), center.y(), 0) * ESM::Land::REAL_SIZE; for (auto& pair : instances) { const osg::Node* temp = mSceneManager->getTemplate(pair.first); - osg::ref_ptr node = static_cast(temp->clone(osg::CopyOp::DEEP_COPY_NODES|osg::CopyOp::DEEP_COPY_DRAWABLES|osg::CopyOp::DEEP_COPY_USERDATA|osg::CopyOp::DEEP_COPY_ARRAYS|osg::CopyOp::DEEP_COPY_PRIMITIVES)); + osg::ref_ptr node = static_cast(temp->clone(osg::CopyOp::DEEP_COPY_NODES + | osg::CopyOp::DEEP_COPY_DRAWABLES | osg::CopyOp::DEEP_COPY_USERDATA | osg::CopyOp::DEEP_COPY_ARRAYS + | osg::CopyOp::DEEP_COPY_PRIMITIVES)); // Keep link to original mesh to keep it in cache group->getOrCreateUserDataContainer()->addUserObject(new Resource::TemplateRef(temp)); @@ -256,7 +279,7 @@ namespace MWRender return Mask_Groundcover; } - void Groundcover::reportStats(unsigned int frameNumber, osg::Stats *stats) const + void Groundcover::reportStats(unsigned int frameNumber, osg::Stats* stats) const { stats->setAttribute(frameNumber, "Groundcover Chunk", mCache->getCacheSize()); } diff --git a/apps/openmw/mwrender/groundcover.hpp b/apps/openmw/mwrender/groundcover.hpp index d6d3ac52a7..df40d9d529 100644 --- a/apps/openmw/mwrender/groundcover.hpp +++ b/apps/openmw/mwrender/groundcover.hpp @@ -1,9 +1,9 @@ #ifndef OPENMW_MWRENDER_GROUNDCOVER_H #define OPENMW_MWRENDER_GROUNDCOVER_H -#include -#include #include +#include +#include namespace MWWorld { @@ -18,13 +18,16 @@ namespace osg namespace MWRender { typedef std::tuple GroundcoverChunkId; // Center, Size - class Groundcover : public Resource::GenericResourceManager, public Terrain::QuadTreeWorld::ChunkManager + class Groundcover : public Resource::GenericResourceManager, + public Terrain::QuadTreeWorld::ChunkManager { public: - Groundcover(Resource::SceneManager* sceneManager, float density, float viewDistance, const MWWorld::GroundcoverStore& store); + Groundcover(Resource::SceneManager* sceneManager, float density, float viewDistance, + const MWWorld::GroundcoverStore& store); ~Groundcover(); - osg::ref_ptr getChunk(float size, const osg::Vec2f& center, unsigned char lod, unsigned int lodFlags, bool activeGrid, const osg::Vec3f& viewPoint, bool compile) override; + osg::ref_ptr getChunk(float size, const osg::Vec2f& center, unsigned char lod, unsigned int lodFlags, + bool activeGrid, const osg::Vec3f& viewPoint, bool compile) override; unsigned int getNodeMask() override; @@ -35,8 +38,11 @@ namespace MWRender ESM::Position mPos; float mScale; - GroundcoverEntry(const ESM::CellRef& ref) : mPos(ref.mPos), mScale(ref.mScale) - {} + GroundcoverEntry(const ESM::CellRef& ref) + : mPos(ref.mPos) + , mScale(ref.mScale) + { + } }; private: diff --git a/apps/openmw/mwrender/landmanager.cpp b/apps/openmw/mwrender/landmanager.cpp index 2395eeab69..59b9fdbde4 100644 --- a/apps/openmw/mwrender/landmanager.cpp +++ b/apps/openmw/mwrender/landmanager.cpp @@ -11,36 +11,35 @@ namespace MWRender { -LandManager::LandManager(int loadFlags) - : GenericResourceManager >(nullptr) - , mLoadFlags(loadFlags) -{ - mCache = new CacheType; -} - -osg::ref_ptr LandManager::getLand(int x, int y) -{ - osg::ref_ptr obj = mCache->getRefFromObjectCache(std::make_pair(x,y)); - if (obj) - return static_cast(obj.get()); - else + LandManager::LandManager(int loadFlags) + : GenericResourceManager>(nullptr) + , mLoadFlags(loadFlags) { - const auto world = MWBase::Environment::get().getWorld(); - if (!world) - return nullptr; - const ESM::Land* land = world->getStore().get().search(x,y); - if (!land) - return nullptr; - osg::ref_ptr landObj (new ESMTerrain::LandObject(land, mLoadFlags)); - mCache->addEntryToObjectCache(std::make_pair(x,y), landObj.get()); - return landObj; + mCache = new CacheType; } -} -void LandManager::reportStats(unsigned int frameNumber, osg::Stats *stats) const -{ - stats->setAttribute(frameNumber, "Land", mCache->getCacheSize()); -} + osg::ref_ptr LandManager::getLand(int x, int y) + { + osg::ref_ptr obj = mCache->getRefFromObjectCache(std::make_pair(x, y)); + if (obj) + return static_cast(obj.get()); + else + { + const auto world = MWBase::Environment::get().getWorld(); + if (!world) + return nullptr; + const ESM::Land* land = world->getStore().get().search(x, y); + if (!land) + return nullptr; + osg::ref_ptr landObj(new ESMTerrain::LandObject(land, mLoadFlags)); + mCache->addEntryToObjectCache(std::make_pair(x, y), landObj.get()); + return landObj; + } + } + void LandManager::reportStats(unsigned int frameNumber, osg::Stats* stats) const + { + stats->setAttribute(frameNumber, "Land", mCache->getCacheSize()); + } } diff --git a/apps/openmw/mwrender/landmanager.hpp b/apps/openmw/mwrender/landmanager.hpp index e4b068eb76..4c00cefe9b 100644 --- a/apps/openmw/mwrender/landmanager.hpp +++ b/apps/openmw/mwrender/landmanager.hpp @@ -3,8 +3,8 @@ #include -#include #include +#include namespace ESM { @@ -14,7 +14,7 @@ namespace ESM namespace MWRender { - class LandManager : public Resource::GenericResourceManager > + class LandManager : public Resource::GenericResourceManager> { public: LandManager(int loadFlags); diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index 0f433c4d05..f9a14e5239 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -2,29 +2,29 @@ #include +#include #include #include -#include -#include #include #include +#include #include #include #include #include +#include #include -#include -#include -#include -#include +#include #include #include #include #include -#include -#include +#include +#include +#include +#include #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" @@ -38,7 +38,7 @@ namespace { float square(float val) { - return val*val; + return val * val; } std::pair divideIntoSegments(const osg::BoundingBox& bounds, float mapSize) @@ -48,17 +48,17 @@ namespace osg::Vec2f length = max - min; const int segsX = static_cast(std::ceil(length.x() / mapSize)); const int segsY = static_cast(std::ceil(length.y() / mapSize)); - return {segsX, segsY}; + return { segsX, segsY }; } } namespace MWRender { - class LocalMapRenderToTexture: public SceneUtil::RTTNode + class LocalMapRenderToTexture : public SceneUtil::RTTNode { public: - LocalMapRenderToTexture(osg::Node* sceneRoot, int res, int mapWorldSize, - float x, float y, const osg::Vec3d& upVector, float zmin, float zmax); + LocalMapRenderToTexture(osg::Node* sceneRoot, int res, int mapWorldSize, float x, float y, + const osg::Vec3d& upVector, float zmin, float zmax); void setDefaults(osg::Camera* camera) override; @@ -71,693 +71,702 @@ namespace MWRender bool mActive; }; - class CameraLocalUpdateCallback : public SceneUtil::NodeCallback + class CameraLocalUpdateCallback + : public SceneUtil::NodeCallback { public: void operator()(LocalMapRenderToTexture* node, osg::NodeVisitor* nv); }; -LocalMap::LocalMap(osg::Group* root) - : mRoot(root) - , mMapResolution(Settings::Manager::getInt("local map resolution", "Map")) - , mMapWorldSize(Constants::CellSizeInUnits) - , mCellDistance(Constants::CellGridRadius) - , mAngle(0.f) - , mInterior(false) -{ - // Increase map resolution, if use UI scaling - float uiScale = MWBase::Environment::get().getWindowManager()->getScalingFactor(); - mMapResolution *= uiScale; - - SceneUtil::FindByNameVisitor find("Scene Root"); - mRoot->accept(find); - mSceneRoot = find.mFoundNode; - if (!mSceneRoot) - throw std::runtime_error("no scene root found"); -} - -LocalMap::~LocalMap() -{ - for (auto& rtt : mLocalMapRTTs) - mRoot->removeChild(rtt); -} + LocalMap::LocalMap(osg::Group* root) + : mRoot(root) + , mMapResolution(Settings::Manager::getInt("local map resolution", "Map")) + , mMapWorldSize(Constants::CellSizeInUnits) + , mCellDistance(Constants::CellGridRadius) + , mAngle(0.f) + , mInterior(false) + { + // Increase map resolution, if use UI scaling + float uiScale = MWBase::Environment::get().getWindowManager()->getScalingFactor(); + mMapResolution *= uiScale; + + SceneUtil::FindByNameVisitor find("Scene Root"); + mRoot->accept(find); + mSceneRoot = find.mFoundNode; + if (!mSceneRoot) + throw std::runtime_error("no scene root found"); + } -const osg::Vec2f LocalMap::rotatePoint(const osg::Vec2f& point, const osg::Vec2f& center, const float angle) -{ - return osg::Vec2f( std::cos(angle) * (point.x() - center.x()) - std::sin(angle) * (point.y() - center.y()) + center.x(), - std::sin(angle) * (point.x() - center.x()) + std::cos(angle) * (point.y() - center.y()) + center.y()); -} + LocalMap::~LocalMap() + { + for (auto& rtt : mLocalMapRTTs) + mRoot->removeChild(rtt); + } -void LocalMap::clear() -{ - mExteriorSegments.clear(); - mInteriorSegments.clear(); -} + const osg::Vec2f LocalMap::rotatePoint(const osg::Vec2f& point, const osg::Vec2f& center, const float angle) + { + return osg::Vec2f( + std::cos(angle) * (point.x() - center.x()) - std::sin(angle) * (point.y() - center.y()) + center.x(), + std::sin(angle) * (point.x() - center.x()) + std::cos(angle) * (point.y() - center.y()) + center.y()); + } -void LocalMap::saveFogOfWar(MWWorld::CellStore* cell) -{ - if (!mInterior) + void LocalMap::clear() { - const MapSegment& segment = mExteriorSegments[std::make_pair(cell->getCell()->getGridX(), cell->getCell()->getGridY())]; + mExteriorSegments.clear(); + mInteriorSegments.clear(); + } - if (segment.mFogOfWarImage && segment.mHasFogState) + void LocalMap::saveFogOfWar(MWWorld::CellStore* cell) + { + if (!mInterior) { - auto fog = std::make_unique(); - fog->mFogTextures.emplace_back(); + const MapSegment& segment + = mExteriorSegments[std::make_pair(cell->getCell()->getGridX(), cell->getCell()->getGridY())]; - segment.saveFogOfWar(fog->mFogTextures.back()); + if (segment.mFogOfWarImage && segment.mHasFogState) + { + auto fog = std::make_unique(); + fog->mFogTextures.emplace_back(); - cell->setFog(std::move(fog)); + segment.saveFogOfWar(fog->mFogTextures.back()); + + cell->setFog(std::move(fog)); + } } - } - else - { - auto segments = divideIntoSegments(mBounds, mMapWorldSize); + else + { + auto segments = divideIntoSegments(mBounds, mMapWorldSize); - auto fog = std::make_unique(); + auto fog = std::make_unique(); - fog->mBounds.mMinX = mBounds.xMin(); - fog->mBounds.mMaxX = mBounds.xMax(); - fog->mBounds.mMinY = mBounds.yMin(); - fog->mBounds.mMaxY = mBounds.yMax(); - fog->mNorthMarkerAngle = mAngle; + fog->mBounds.mMinX = mBounds.xMin(); + fog->mBounds.mMaxX = mBounds.xMax(); + fog->mBounds.mMinY = mBounds.yMin(); + fog->mBounds.mMaxY = mBounds.yMax(); + fog->mNorthMarkerAngle = mAngle; - fog->mFogTextures.reserve(segments.first * segments.second); + fog->mFogTextures.reserve(segments.first * segments.second); - for (int x = 0; x < segments.first; ++x) - { - for (int y = 0; y < segments.second; ++y) + for (int x = 0; x < segments.first; ++x) { - const MapSegment& segment = mInteriorSegments[std::make_pair(x,y)]; + for (int y = 0; y < segments.second; ++y) + { + const MapSegment& segment = mInteriorSegments[std::make_pair(x, y)]; - fog->mFogTextures.emplace_back(); + fog->mFogTextures.emplace_back(); - // saving even if !segment.mHasFogState so we don't mess up the segmenting - // plus, older openmw versions can't deal with empty images - segment.saveFogOfWar(fog->mFogTextures.back()); + // saving even if !segment.mHasFogState so we don't mess up the segmenting + // plus, older openmw versions can't deal with empty images + segment.saveFogOfWar(fog->mFogTextures.back()); - fog->mFogTextures.back().mX = x; - fog->mFogTextures.back().mY = y; + fog->mFogTextures.back().mX = x; + fog->mFogTextures.back().mY = y; + } } - } - cell->setFog(std::move(fog)); + cell->setFog(std::move(fog)); + } } -} -void LocalMap::setupRenderToTexture(int segment_x, int segment_y, float left, float top, const osg::Vec3d& upVector, float zmin, float zmax) -{ - mLocalMapRTTs.emplace_back(new LocalMapRenderToTexture(mSceneRoot, mMapResolution, mMapWorldSize, left, top, upVector, zmin, zmax)); + void LocalMap::setupRenderToTexture( + int segment_x, int segment_y, float left, float top, const osg::Vec3d& upVector, float zmin, float zmax) + { + mLocalMapRTTs.emplace_back( + new LocalMapRenderToTexture(mSceneRoot, mMapResolution, mMapWorldSize, left, top, upVector, zmin, zmax)); - mRoot->addChild(mLocalMapRTTs.back()); + mRoot->addChild(mLocalMapRTTs.back()); - MapSegment& segment = mInterior? mInteriorSegments[std::make_pair(segment_x, segment_y)] : mExteriorSegments[std::make_pair(segment_x, segment_y)]; - segment.mMapTexture = static_cast(mLocalMapRTTs.back()->getColorTexture(nullptr)); -} + MapSegment& segment = mInterior ? mInteriorSegments[std::make_pair(segment_x, segment_y)] + : mExteriorSegments[std::make_pair(segment_x, segment_y)]; + segment.mMapTexture = static_cast(mLocalMapRTTs.back()->getColorTexture(nullptr)); + } -void LocalMap::requestMap(const MWWorld::CellStore* cell) -{ - if (cell->isExterior()) + void LocalMap::requestMap(const MWWorld::CellStore* cell) { - int cellX = cell->getCell()->getGridX(); - int cellY = cell->getCell()->getGridY(); - - MapSegment& segment = mExteriorSegments[std::make_pair(cellX, cellY)]; - if (!segment.needUpdate) - return; - else + if (cell->isExterior()) { - requestExteriorMap(cell); - segment.needUpdate = false; + int cellX = cell->getCell()->getGridX(); + int cellY = cell->getCell()->getGridY(); + + MapSegment& segment = mExteriorSegments[std::make_pair(cellX, cellY)]; + if (!segment.needUpdate) + return; + else + { + requestExteriorMap(cell); + segment.needUpdate = false; + } } + else + requestInteriorMap(cell); } - else - requestInteriorMap(cell); -} -void LocalMap::addCell(MWWorld::CellStore *cell) -{ - if (cell->isExterior()) - mExteriorSegments[std::make_pair(cell->getCell()->getGridX(), cell->getCell()->getGridY())].needUpdate = true; -} + void LocalMap::addCell(MWWorld::CellStore* cell) + { + if (cell->isExterior()) + mExteriorSegments[std::make_pair(cell->getCell()->getGridX(), cell->getCell()->getGridY())].needUpdate + = true; + } -void LocalMap::removeExteriorCell(int x, int y) -{ - mExteriorSegments.erase({ x, y }); -} + void LocalMap::removeExteriorCell(int x, int y) + { + mExteriorSegments.erase({ x, y }); + } -void LocalMap::removeCell(MWWorld::CellStore *cell) -{ - saveFogOfWar(cell); + void LocalMap::removeCell(MWWorld::CellStore* cell) + { + saveFogOfWar(cell); - if (!cell->isExterior()) - mInteriorSegments.clear(); -} + if (!cell->isExterior()) + mInteriorSegments.clear(); + } -osg::ref_ptr LocalMap::getMapTexture(int x, int y) -{ - auto& segments(mInterior ? mInteriorSegments : mExteriorSegments); - SegmentMap::iterator found = segments.find(std::make_pair(x, y)); - if (found == segments.end()) - return osg::ref_ptr(); - else - return found->second.mMapTexture; -} + osg::ref_ptr LocalMap::getMapTexture(int x, int y) + { + auto& segments(mInterior ? mInteriorSegments : mExteriorSegments); + SegmentMap::iterator found = segments.find(std::make_pair(x, y)); + if (found == segments.end()) + return osg::ref_ptr(); + else + return found->second.mMapTexture; + } -osg::ref_ptr LocalMap::getFogOfWarTexture(int x, int y) -{ - auto& segments(mInterior ? mInteriorSegments : mExteriorSegments); - SegmentMap::iterator found = segments.find(std::make_pair(x, y)); - if (found == segments.end()) - return osg::ref_ptr(); - else - return found->second.mFogOfWarTexture; -} + osg::ref_ptr LocalMap::getFogOfWarTexture(int x, int y) + { + auto& segments(mInterior ? mInteriorSegments : mExteriorSegments); + SegmentMap::iterator found = segments.find(std::make_pair(x, y)); + if (found == segments.end()) + return osg::ref_ptr(); + else + return found->second.mFogOfWarTexture; + } -void LocalMap::cleanupCameras() -{ - auto it = mLocalMapRTTs.begin(); - while (it != mLocalMapRTTs.end()) + void LocalMap::cleanupCameras() { - if (!(*it)->isActive()) + auto it = mLocalMapRTTs.begin(); + while (it != mLocalMapRTTs.end()) { - mRoot->removeChild(*it); - it = mLocalMapRTTs.erase(it); + if (!(*it)->isActive()) + { + mRoot->removeChild(*it); + it = mLocalMapRTTs.erase(it); + } + else + it++; } - else - it++; } -} -void LocalMap::requestExteriorMap(const MWWorld::CellStore* cell) -{ - mInterior = false; + void LocalMap::requestExteriorMap(const MWWorld::CellStore* cell) + { + mInterior = false; - int x = cell->getCell()->getGridX(); - int y = cell->getCell()->getGridY(); + int x = cell->getCell()->getGridX(); + int y = cell->getCell()->getGridY(); - osg::BoundingSphere bound = mSceneRoot->getBound(); - float zmin = bound.center().z() - bound.radius(); - float zmax = bound.center().z() + bound.radius(); + osg::BoundingSphere bound = mSceneRoot->getBound(); + float zmin = bound.center().z() - bound.radius(); + float zmax = bound.center().z() + bound.radius(); - setupRenderToTexture(cell->getCell()->getGridX(), cell->getCell()->getGridY(), - x * mMapWorldSize + mMapWorldSize / 2.f, y * mMapWorldSize + mMapWorldSize / 2.f, - osg::Vec3d(0, 1, 0), zmin, zmax); + setupRenderToTexture(cell->getCell()->getGridX(), cell->getCell()->getGridY(), + x * mMapWorldSize + mMapWorldSize / 2.f, y * mMapWorldSize + mMapWorldSize / 2.f, osg::Vec3d(0, 1, 0), zmin, + zmax); - MapSegment& segment = mExteriorSegments[std::make_pair(cell->getCell()->getGridX(), cell->getCell()->getGridY())]; - if (!segment.mFogOfWarImage) - { - if (cell->getFog()) - segment.loadFogOfWar(cell->getFog()->mFogTextures.back()); - else - segment.initFogOfWar(); + MapSegment& segment + = mExteriorSegments[std::make_pair(cell->getCell()->getGridX(), cell->getCell()->getGridY())]; + if (!segment.mFogOfWarImage) + { + if (cell->getFog()) + segment.loadFogOfWar(cell->getFog()->mFogTextures.back()); + else + segment.initFogOfWar(); + } } -} - -void LocalMap::requestInteriorMap(const MWWorld::CellStore* cell) -{ - osg::ComputeBoundsVisitor computeBoundsVisitor; - computeBoundsVisitor.setTraversalMask(Mask_Scene | Mask_Terrain | Mask_Object | Mask_Static); - mSceneRoot->accept(computeBoundsVisitor); - osg::BoundingBox bounds = computeBoundsVisitor.getBoundingBox(); + void LocalMap::requestInteriorMap(const MWWorld::CellStore* cell) + { + osg::ComputeBoundsVisitor computeBoundsVisitor; + computeBoundsVisitor.setTraversalMask(Mask_Scene | Mask_Terrain | Mask_Object | Mask_Static); + mSceneRoot->accept(computeBoundsVisitor); - // If we're in an empty cell, bail out - // The operations in this function are only valid for finite bounds - if (!bounds.valid() || bounds.radius2() == 0.0) - return; + osg::BoundingBox bounds = computeBoundsVisitor.getBoundingBox(); - mInterior = true; + // If we're in an empty cell, bail out + // The operations in this function are only valid for finite bounds + if (!bounds.valid() || bounds.radius2() == 0.0) + return; - mBounds = bounds; + mInterior = true; - // Get the cell's NorthMarker rotation. This is used to rotate the entire map. - osg::Vec2f north = MWBase::Environment::get().getWorld()->getNorthVector(cell); + mBounds = bounds; - mAngle = std::atan2(north.x(), north.y()); + // Get the cell's NorthMarker rotation. This is used to rotate the entire map. + osg::Vec2f north = MWBase::Environment::get().getWorld()->getNorthVector(cell); - // Rotate the cell and merge the rotated corners to the bounding box - osg::Vec2f origCenter(bounds.center().x(), bounds.center().y()); - osg::Vec3f origCorners[8]; - for (int i=0; i<8; ++i) - origCorners[i] = mBounds.corner(i); + mAngle = std::atan2(north.x(), north.y()); - for (int i=0; i<8; ++i) - { - osg::Vec3f corner = origCorners[i]; - osg::Vec2f corner2d (corner.x(), corner.y()); - corner2d = rotatePoint(corner2d, origCenter, mAngle); - mBounds.expandBy(osg::Vec3f(corner2d.x(), corner2d.y(), 0)); - } + // Rotate the cell and merge the rotated corners to the bounding box + osg::Vec2f origCenter(bounds.center().x(), bounds.center().y()); + osg::Vec3f origCorners[8]; + for (int i = 0; i < 8; ++i) + origCorners[i] = mBounds.corner(i); - // Do NOT change padding! This will break older savegames. - // If the padding really needs to be changed, then it must be saved in the ESM::FogState and - // assume the old (500) value as default for older savegames. - const float padding = 500.0f; + for (int i = 0; i < 8; ++i) + { + osg::Vec3f corner = origCorners[i]; + osg::Vec2f corner2d(corner.x(), corner.y()); + corner2d = rotatePoint(corner2d, origCenter, mAngle); + mBounds.expandBy(osg::Vec3f(corner2d.x(), corner2d.y(), 0)); + } - // Apply a little padding - mBounds.set(mBounds._min - osg::Vec3f(padding,padding,0.f), - mBounds._max + osg::Vec3f(padding,padding,0.f)); + // Do NOT change padding! This will break older savegames. + // If the padding really needs to be changed, then it must be saved in the ESM::FogState and + // assume the old (500) value as default for older savegames. + const float padding = 500.0f; - float zMin = mBounds.zMin(); - float zMax = mBounds.zMax(); + // Apply a little padding + mBounds.set(mBounds._min - osg::Vec3f(padding, padding, 0.f), mBounds._max + osg::Vec3f(padding, padding, 0.f)); - // If there is fog state in the CellStore (e.g. when it came from a savegame) we need to do some checks - // to see if this state is still valid. - // Both the cell bounds and the NorthMarker rotation could be changed by the content files or exchanged models. - // If they changed by too much then parts of the interior might not be covered by the map anymore. - // The following code detects this, and discards the CellStore's fog state if it needs to. - std::vector> segmentMappings; - if (cell->getFog()) - { - ESM::FogState* fog = cell->getFog(); + float zMin = mBounds.zMin(); + float zMax = mBounds.zMax(); - if (std::abs(mAngle - fog->mNorthMarkerAngle) < osg::DegreesToRadians(5.f)) + // If there is fog state in the CellStore (e.g. when it came from a savegame) we need to do some checks + // to see if this state is still valid. + // Both the cell bounds and the NorthMarker rotation could be changed by the content files or exchanged models. + // If they changed by too much then parts of the interior might not be covered by the map anymore. + // The following code detects this, and discards the CellStore's fog state if it needs to. + std::vector> segmentMappings; + if (cell->getFog()) { - // Expand mBounds so the saved textures fit the same grid - int xOffset = 0; - int yOffset = 0; - if(fog->mBounds.mMinX < mBounds.xMin()) - { - mBounds.xMin() = fog->mBounds.mMinX; - } - else if(fog->mBounds.mMinX > mBounds.xMin()) - { - float diff = fog->mBounds.mMinX - mBounds.xMin(); - xOffset += diff / mMapWorldSize; - xOffset++; - mBounds.xMin() = fog->mBounds.mMinX - xOffset * mMapWorldSize; - } - if(fog->mBounds.mMinY < mBounds.yMin()) - { - mBounds.yMin() = fog->mBounds.mMinY; - } - else if(fog->mBounds.mMinY > mBounds.yMin()) + ESM::FogState* fog = cell->getFog(); + + if (std::abs(mAngle - fog->mNorthMarkerAngle) < osg::DegreesToRadians(5.f)) { - float diff = fog->mBounds.mMinY - mBounds.yMin(); - yOffset += diff / mMapWorldSize; - yOffset++; - mBounds.yMin() = fog->mBounds.mMinY - yOffset * mMapWorldSize; + // Expand mBounds so the saved textures fit the same grid + int xOffset = 0; + int yOffset = 0; + if (fog->mBounds.mMinX < mBounds.xMin()) + { + mBounds.xMin() = fog->mBounds.mMinX; + } + else if (fog->mBounds.mMinX > mBounds.xMin()) + { + float diff = fog->mBounds.mMinX - mBounds.xMin(); + xOffset += diff / mMapWorldSize; + xOffset++; + mBounds.xMin() = fog->mBounds.mMinX - xOffset * mMapWorldSize; + } + if (fog->mBounds.mMinY < mBounds.yMin()) + { + mBounds.yMin() = fog->mBounds.mMinY; + } + else if (fog->mBounds.mMinY > mBounds.yMin()) + { + float diff = fog->mBounds.mMinY - mBounds.yMin(); + yOffset += diff / mMapWorldSize; + yOffset++; + mBounds.yMin() = fog->mBounds.mMinY - yOffset * mMapWorldSize; + } + if (fog->mBounds.mMaxX > mBounds.xMax()) + mBounds.xMax() = fog->mBounds.mMaxX; + if (fog->mBounds.mMaxY > mBounds.yMax()) + mBounds.yMax() = fog->mBounds.mMaxY; + + if (xOffset != 0 || yOffset != 0) + Log(Debug::Warning) << "Warning: expanding fog by " << xOffset << ", " << yOffset; + + const auto& textures = fog->mFogTextures; + segmentMappings.reserve(textures.size()); + osg::BoundingBox savedBounds{ fog->mBounds.mMinX, fog->mBounds.mMinY, 0, fog->mBounds.mMaxX, + fog->mBounds.mMaxY, 0 }; + auto segments = divideIntoSegments(savedBounds, mMapWorldSize); + for (int x = 0; x < segments.first; ++x) + for (int y = 0; y < segments.second; ++y) + segmentMappings.emplace_back(std::make_pair(x + xOffset, y + yOffset)); + + mAngle = fog->mNorthMarkerAngle; } - if (fog->mBounds.mMaxX > mBounds.xMax()) - mBounds.xMax() = fog->mBounds.mMaxX; - if (fog->mBounds.mMaxY > mBounds.yMax()) - mBounds.yMax() = fog->mBounds.mMaxY; - - if(xOffset != 0 || yOffset != 0) - Log(Debug::Warning) << "Warning: expanding fog by " << xOffset << ", " << yOffset; - - const auto& textures = fog->mFogTextures; - segmentMappings.reserve(textures.size()); - osg::BoundingBox savedBounds{ - fog->mBounds.mMinX, fog->mBounds.mMinY, 0, - fog->mBounds.mMaxX, fog->mBounds.mMaxY, 0 - }; - auto segments = divideIntoSegments(savedBounds, mMapWorldSize); - for (int x = 0; x < segments.first; ++x) - for (int y = 0; y < segments.second; ++y) - segmentMappings.emplace_back(std::make_pair(x + xOffset, y + yOffset)); - - mAngle = fog->mNorthMarkerAngle; } - } - osg::Vec2f min(mBounds.xMin(), mBounds.yMin()); + osg::Vec2f min(mBounds.xMin(), mBounds.yMin()); - osg::Vec2f center(mBounds.center().x(), mBounds.center().y()); - osg::Quat cameraOrient (mAngle, osg::Vec3d(0,0,-1)); + osg::Vec2f center(mBounds.center().x(), mBounds.center().y()); + osg::Quat cameraOrient(mAngle, osg::Vec3d(0, 0, -1)); - auto segments = divideIntoSegments(mBounds, mMapWorldSize); - for (int x = 0; x < segments.first; ++x) - { - for (int y = 0; y < segments.second; ++y) + auto segments = divideIntoSegments(mBounds, mMapWorldSize); + for (int x = 0; x < segments.first; ++x) { - osg::Vec2f start = min + osg::Vec2f(mMapWorldSize*x, mMapWorldSize*y); - osg::Vec2f newcenter = start + osg::Vec2f(mMapWorldSize/2.f, mMapWorldSize/2.f); + for (int y = 0; y < segments.second; ++y) + { + osg::Vec2f start = min + osg::Vec2f(mMapWorldSize * x, mMapWorldSize * y); + osg::Vec2f newcenter = start + osg::Vec2f(mMapWorldSize / 2.f, mMapWorldSize / 2.f); - osg::Vec2f a = newcenter - center; - osg::Vec3f rotatedCenter = cameraOrient * (osg::Vec3f(a.x(), a.y(), 0)); + osg::Vec2f a = newcenter - center; + osg::Vec3f rotatedCenter = cameraOrient * (osg::Vec3f(a.x(), a.y(), 0)); - osg::Vec2f pos = osg::Vec2f(rotatedCenter.x(), rotatedCenter.y()) + center; + osg::Vec2f pos = osg::Vec2f(rotatedCenter.x(), rotatedCenter.y()) + center; - setupRenderToTexture(x, y, pos.x(), pos.y(), - osg::Vec3f(north.x(), north.y(), 0.f), zMin, zMax); + setupRenderToTexture(x, y, pos.x(), pos.y(), osg::Vec3f(north.x(), north.y(), 0.f), zMin, zMax); - auto coords = std::make_pair(x,y); - MapSegment& segment = mInteriorSegments[coords]; - if (!segment.mFogOfWarImage) - { - bool loaded = false; - for(size_t index{}; index < segmentMappings.size(); index++) + auto coords = std::make_pair(x, y); + MapSegment& segment = mInteriorSegments[coords]; + if (!segment.mFogOfWarImage) { - if(segmentMappings[index] == coords) + bool loaded = false; + for (size_t index{}; index < segmentMappings.size(); index++) { - ESM::FogState* fog = cell->getFog(); - segment.loadFogOfWar(fog->mFogTextures[index]); - loaded = true; - break; + if (segmentMappings[index] == coords) + { + ESM::FogState* fog = cell->getFog(); + segment.loadFogOfWar(fog->mFogTextures[index]); + loaded = true; + break; + } } + if (!loaded) + segment.initFogOfWar(); } - if(!loaded) - segment.initFogOfWar(); } } } -} -void LocalMap::worldToInteriorMapPosition (osg::Vec2f pos, float& nX, float& nY, int& x, int& y) -{ - pos = rotatePoint(pos, osg::Vec2f(mBounds.center().x(), mBounds.center().y()), mAngle); - - osg::Vec2f min(mBounds.xMin(), mBounds.yMin()); + void LocalMap::worldToInteriorMapPosition(osg::Vec2f pos, float& nX, float& nY, int& x, int& y) + { + pos = rotatePoint(pos, osg::Vec2f(mBounds.center().x(), mBounds.center().y()), mAngle); - x = static_cast(std::ceil((pos.x() - min.x()) / mMapWorldSize) - 1); - y = static_cast(std::ceil((pos.y() - min.y()) / mMapWorldSize) - 1); + osg::Vec2f min(mBounds.xMin(), mBounds.yMin()); - nX = (pos.x() - min.x() - mMapWorldSize*x)/mMapWorldSize; - nY = 1.0f-(pos.y() - min.y() - mMapWorldSize*y)/mMapWorldSize; -} + x = static_cast(std::ceil((pos.x() - min.x()) / mMapWorldSize) - 1); + y = static_cast(std::ceil((pos.y() - min.y()) / mMapWorldSize) - 1); -osg::Vec2f LocalMap::interiorMapToWorldPosition (float nX, float nY, int x, int y) -{ - osg::Vec2f min(mBounds.xMin(), mBounds.yMin()); - osg::Vec2f pos (mMapWorldSize * (nX + x) + min.x(), - mMapWorldSize * (1.0f-nY + y) + min.y()); + nX = (pos.x() - min.x() - mMapWorldSize * x) / mMapWorldSize; + nY = 1.0f - (pos.y() - min.y() - mMapWorldSize * y) / mMapWorldSize; + } - pos = rotatePoint(pos, osg::Vec2f(mBounds.center().x(), mBounds.center().y()), -mAngle); - return pos; -} + osg::Vec2f LocalMap::interiorMapToWorldPosition(float nX, float nY, int x, int y) + { + osg::Vec2f min(mBounds.xMin(), mBounds.yMin()); + osg::Vec2f pos(mMapWorldSize * (nX + x) + min.x(), mMapWorldSize * (1.0f - nY + y) + min.y()); -bool LocalMap::isPositionExplored (float nX, float nY, int x, int y) -{ - auto& segments(mInterior ? mInteriorSegments : mExteriorSegments); - const MapSegment& segment = segments[std::make_pair(x, y)]; - if (!segment.mFogOfWarImage) - return false; + pos = rotatePoint(pos, osg::Vec2f(mBounds.center().x(), mBounds.center().y()), -mAngle); + return pos; + } - nX = std::clamp(nX, 0.f, 1.f); - nY = std::clamp(nY, 0.f, 1.f); + bool LocalMap::isPositionExplored(float nX, float nY, int x, int y) + { + auto& segments(mInterior ? mInteriorSegments : mExteriorSegments); + const MapSegment& segment = segments[std::make_pair(x, y)]; + if (!segment.mFogOfWarImage) + return false; - int texU = static_cast((sFogOfWarResolution - 1) * nX); - int texV = static_cast((sFogOfWarResolution - 1) * nY); + nX = std::clamp(nX, 0.f, 1.f); + nY = std::clamp(nY, 0.f, 1.f); - uint32_t clr = ((const uint32_t*)segment.mFogOfWarImage->data())[texV * sFogOfWarResolution + texU]; - uint8_t alpha = (clr >> 24); - return alpha < 200; -} + int texU = static_cast((sFogOfWarResolution - 1) * nX); + int texV = static_cast((sFogOfWarResolution - 1) * nY); -osg::Group* LocalMap::getRoot() -{ - return mRoot; -} - -void LocalMap::updatePlayer (const osg::Vec3f& position, const osg::Quat& orientation, - float& u, float& v, int& x, int& y, osg::Vec3f& direction) -{ - // retrieve the x,y grid coordinates the player is in - osg::Vec2f pos(position.x(), position.y()); + uint32_t clr = ((const uint32_t*)segment.mFogOfWarImage->data())[texV * sFogOfWarResolution + texU]; + uint8_t alpha = (clr >> 24); + return alpha < 200; + } - if (mInterior) + osg::Group* LocalMap::getRoot() { - worldToInteriorMapPosition(pos, u,v, x,y); - - osg::Quat cameraOrient (mAngle, osg::Vec3(0,0,-1)); - direction = orientation * cameraOrient.inverse() * osg::Vec3f(0,1,0); + return mRoot; } - else + + void LocalMap::updatePlayer(const osg::Vec3f& position, const osg::Quat& orientation, float& u, float& v, int& x, + int& y, osg::Vec3f& direction) { - direction = orientation * osg::Vec3f(0,1,0); + // retrieve the x,y grid coordinates the player is in + osg::Vec2f pos(position.x(), position.y()); - x = static_cast(std::ceil(pos.x() / mMapWorldSize) - 1); - y = static_cast(std::ceil(pos.y() / mMapWorldSize) - 1); + if (mInterior) + { + worldToInteriorMapPosition(pos, u, v, x, y); - // convert from world coordinates to texture UV coordinates - u = std::abs((pos.x() - (mMapWorldSize*x))/mMapWorldSize); - v = 1.0f-std::abs((pos.y() - (mMapWorldSize*y))/mMapWorldSize); - } + osg::Quat cameraOrient(mAngle, osg::Vec3(0, 0, -1)); + direction = orientation * cameraOrient.inverse() * osg::Vec3f(0, 1, 0); + } + else + { + direction = orientation * osg::Vec3f(0, 1, 0); - // explore radius (squared) - const float exploreRadius = 0.17f * (sFogOfWarResolution-1); // explore radius from 0 to sFogOfWarResolution-1 - const float sqrExploreRadius = square(exploreRadius); - const float exploreRadiusUV = exploreRadius / sFogOfWarResolution; // explore radius from 0 to 1 (UV space) + x = static_cast(std::ceil(pos.x() / mMapWorldSize) - 1); + y = static_cast(std::ceil(pos.y() / mMapWorldSize) - 1); - // change the affected fog of war textures (in a 3x3 grid around the player) - for (int mx = -mCellDistance; mx<=mCellDistance; ++mx) - { - for (int my = -mCellDistance; my<=mCellDistance; ++my) + // convert from world coordinates to texture UV coordinates + u = std::abs((pos.x() - (mMapWorldSize * x)) / mMapWorldSize); + v = 1.0f - std::abs((pos.y() - (mMapWorldSize * y)) / mMapWorldSize); + } + + // explore radius (squared) + const float exploreRadius = 0.17f * (sFogOfWarResolution - 1); // explore radius from 0 to sFogOfWarResolution-1 + const float sqrExploreRadius = square(exploreRadius); + const float exploreRadiusUV = exploreRadius / sFogOfWarResolution; // explore radius from 0 to 1 (UV space) + + // change the affected fog of war textures (in a 3x3 grid around the player) + for (int mx = -mCellDistance; mx <= mCellDistance; ++mx) { - // is this texture affected at all? - bool affected = false; - if (mx == 0 && my == 0) // the player is always in the center of the 3x3 grid - affected = true; - else + for (int my = -mCellDistance; my <= mCellDistance; ++my) { - bool affectsX = (mx > 0)? (u + exploreRadiusUV > 1) : (u - exploreRadiusUV < 0); - bool affectsY = (my > 0)? (v + exploreRadiusUV > 1) : (v - exploreRadiusUV < 0); - affected = (affectsX && (my == 0)) || (affectsY && mx == 0) || (affectsX && affectsY); - } + // is this texture affected at all? + bool affected = false; + if (mx == 0 && my == 0) // the player is always in the center of the 3x3 grid + affected = true; + else + { + bool affectsX = (mx > 0) ? (u + exploreRadiusUV > 1) : (u - exploreRadiusUV < 0); + bool affectsY = (my > 0) ? (v + exploreRadiusUV > 1) : (v - exploreRadiusUV < 0); + affected = (affectsX && (my == 0)) || (affectsY && mx == 0) || (affectsX && affectsY); + } - if (!affected) - continue; + if (!affected) + continue; - int texX = x + mx; - int texY = y + my*-1; + int texX = x + mx; + int texY = y + my * -1; - auto& segments(mInterior ? mInteriorSegments : mExteriorSegments); - MapSegment& segment = segments[std::make_pair(texX, texY)]; + auto& segments(mInterior ? mInteriorSegments : mExteriorSegments); + MapSegment& segment = segments[std::make_pair(texX, texY)]; - if (!segment.mFogOfWarImage || !segment.mMapTexture) - continue; + if (!segment.mFogOfWarImage || !segment.mMapTexture) + continue; - uint32_t* data = (uint32_t*)segment.mFogOfWarImage->data(); - bool changed = false; - for (int texV = 0; texVdata(); + bool changed = false; + for (int texV = 0; texV < sFogOfWarResolution; ++texV) { - float sqrDist = square((texU + mx*(sFogOfWarResolution-1)) - u*(sFogOfWarResolution-1)) - + square((texV + my*(sFogOfWarResolution-1)) - v*(sFogOfWarResolution-1)); - - uint32_t clr = *(uint32_t*)data; - uint8_t alpha = (clr >> 24); - alpha = std::min(alpha, (uint8_t)(std::clamp(sqrDist/sqrExploreRadius, 0.f, 1.f) * 255)); - uint32_t val = (uint32_t) (alpha << 24); - if ( *data != val) + for (int texU = 0; texU < sFogOfWarResolution; ++texU) { - *data = val; - changed = true; + float sqrDist = square((texU + mx * (sFogOfWarResolution - 1)) - u * (sFogOfWarResolution - 1)) + + square((texV + my * (sFogOfWarResolution - 1)) - v * (sFogOfWarResolution - 1)); + + uint32_t clr = *(uint32_t*)data; + uint8_t alpha = (clr >> 24); + alpha = std::min(alpha, (uint8_t)(std::clamp(sqrDist / sqrExploreRadius, 0.f, 1.f) * 255)); + uint32_t val = (uint32_t)(alpha << 24); + if (*data != val) + { + *data = val; + changed = true; + } + + ++data; } - - ++data; } - } - if (changed) - { - segment.mHasFogState = true; - segment.mFogOfWarImage->dirty(); + if (changed) + { + segment.mHasFogState = true; + segment.mFogOfWarImage->dirty(); + } } } } -} - -LocalMap::MapSegment::MapSegment() - : mHasFogState(false) -{ -} - -void LocalMap::MapSegment::createFogOfWarTexture() -{ - if (mFogOfWarTexture) - return; - mFogOfWarTexture = new osg::Texture2D; - // TODO: synchronize access? for now, the worst that could happen is the draw thread jumping a frame ahead. - //mFogOfWarTexture->setDataVariance(osg::Object::DYNAMIC); - mFogOfWarTexture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR); - mFogOfWarTexture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR); - mFogOfWarTexture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE); - mFogOfWarTexture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE); - mFogOfWarTexture->setUnRefImageDataAfterApply(false); - mFogOfWarTexture->setImage(mFogOfWarImage); -} - -void LocalMap::MapSegment::initFogOfWar() -{ - mFogOfWarImage = new osg::Image; - // Assign a PixelBufferObject for asynchronous transfer of data to the GPU - mFogOfWarImage->setPixelBufferObject(new osg::PixelBufferObject); - mFogOfWarImage->allocateImage(sFogOfWarResolution, sFogOfWarResolution, 1, GL_RGBA, GL_UNSIGNED_BYTE); - assert(mFogOfWarImage->isDataContiguous()); - std::vector data; - data.resize(sFogOfWarResolution*sFogOfWarResolution, 0xff000000); - - memcpy(mFogOfWarImage->data(), data.data(), data.size()*4); - - createFogOfWarTexture(); -} -void LocalMap::MapSegment::loadFogOfWar(const ESM::FogTexture &esm) -{ - const std::vector& data = esm.mImageData; - if (data.empty()) + LocalMap::MapSegment::MapSegment() + : mHasFogState(false) { - initFogOfWar(); - return; } - osgDB::ReaderWriter* readerwriter = osgDB::Registry::instance()->getReaderWriterForExtension("png"); - if (!readerwriter) + void LocalMap::MapSegment::createFogOfWarTexture() { - Log(Debug::Error) << "Error: Unable to load fog, can't find a png ReaderWriter" ; - return; + if (mFogOfWarTexture) + return; + mFogOfWarTexture = new osg::Texture2D; + // TODO: synchronize access? for now, the worst that could happen is the draw thread jumping a frame ahead. + // mFogOfWarTexture->setDataVariance(osg::Object::DYNAMIC); + mFogOfWarTexture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR); + mFogOfWarTexture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR); + mFogOfWarTexture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE); + mFogOfWarTexture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE); + mFogOfWarTexture->setUnRefImageDataAfterApply(false); + mFogOfWarTexture->setImage(mFogOfWarImage); } - Files::IMemStream in(data.data(), data.size()); - - osgDB::ReaderWriter::ReadResult result = readerwriter->readImage(in); - if (!result.success()) + void LocalMap::MapSegment::initFogOfWar() { - Log(Debug::Error) << "Error: Failed to read fog: " << result.message() << " code " << result.status(); - return; + mFogOfWarImage = new osg::Image; + // Assign a PixelBufferObject for asynchronous transfer of data to the GPU + mFogOfWarImage->setPixelBufferObject(new osg::PixelBufferObject); + mFogOfWarImage->allocateImage(sFogOfWarResolution, sFogOfWarResolution, 1, GL_RGBA, GL_UNSIGNED_BYTE); + assert(mFogOfWarImage->isDataContiguous()); + std::vector data; + data.resize(sFogOfWarResolution * sFogOfWarResolution, 0xff000000); + + memcpy(mFogOfWarImage->data(), data.data(), data.size() * 4); + + createFogOfWarTexture(); } - mFogOfWarImage = result.getImage(); - mFogOfWarImage->flipVertical(); - mFogOfWarImage->dirty(); + void LocalMap::MapSegment::loadFogOfWar(const ESM::FogTexture& esm) + { + const std::vector& data = esm.mImageData; + if (data.empty()) + { + initFogOfWar(); + return; + } - createFogOfWarTexture(); - mHasFogState = true; -} + osgDB::ReaderWriter* readerwriter = osgDB::Registry::instance()->getReaderWriterForExtension("png"); + if (!readerwriter) + { + Log(Debug::Error) << "Error: Unable to load fog, can't find a png ReaderWriter"; + return; + } -void LocalMap::MapSegment::saveFogOfWar(ESM::FogTexture &fog) const -{ - if (!mFogOfWarImage) - return; + Files::IMemStream in(data.data(), data.size()); - std::ostringstream ostream; + osgDB::ReaderWriter::ReadResult result = readerwriter->readImage(in); + if (!result.success()) + { + Log(Debug::Error) << "Error: Failed to read fog: " << result.message() << " code " << result.status(); + return; + } - osgDB::ReaderWriter* readerwriter = osgDB::Registry::instance()->getReaderWriterForExtension("png"); - if (!readerwriter) - { - Log(Debug::Error) << "Error: Unable to write fog, can't find a png ReaderWriter"; - return; + mFogOfWarImage = result.getImage(); + mFogOfWarImage->flipVertical(); + mFogOfWarImage->dirty(); + + createFogOfWarTexture(); + mHasFogState = true; } - // extra flips are unfortunate, but required for compatibility with older versions - mFogOfWarImage->flipVertical(); - osgDB::ReaderWriter::WriteResult result = readerwriter->writeImage(*mFogOfWarImage, ostream); - if (!result.success()) + void LocalMap::MapSegment::saveFogOfWar(ESM::FogTexture& fog) const { - Log(Debug::Error) << "Error: Unable to write fog: " << result.message() << " code " << result.status(); - return; - } - mFogOfWarImage->flipVertical(); + if (!mFogOfWarImage) + return; - std::string data = ostream.str(); - fog.mImageData = std::vector(data.begin(), data.end()); -} + std::ostringstream ostream; -LocalMapRenderToTexture::LocalMapRenderToTexture(osg::Node* sceneRoot, int res, int mapWorldSize, float x, float y, const osg::Vec3d& upVector, float zmin, float zmax) - : RTTNode(res, res, 0, false, 0, StereoAwareness::Unaware_MultiViewShaders) - , mSceneRoot(sceneRoot) - , mActive(true) -{ - setNodeMask(Mask_RenderToTexture); + osgDB::ReaderWriter* readerwriter = osgDB::Registry::instance()->getReaderWriterForExtension("png"); + if (!readerwriter) + { + Log(Debug::Error) << "Error: Unable to write fog, can't find a png ReaderWriter"; + return; + } + + // extra flips are unfortunate, but required for compatibility with older versions + mFogOfWarImage->flipVertical(); + osgDB::ReaderWriter::WriteResult result = readerwriter->writeImage(*mFogOfWarImage, ostream); + if (!result.success()) + { + Log(Debug::Error) << "Error: Unable to write fog: " << result.message() << " code " << result.status(); + return; + } + mFogOfWarImage->flipVertical(); - if (SceneUtil::AutoDepth::isReversed()) - mProjectionMatrix = SceneUtil::getReversedZProjectionMatrixAsOrtho(-mapWorldSize / 2, mapWorldSize / 2, -mapWorldSize / 2, mapWorldSize / 2, 5, (zmax - zmin) + 10); - else - mProjectionMatrix.makeOrtho(-mapWorldSize / 2, mapWorldSize / 2, -mapWorldSize / 2, mapWorldSize / 2, 5, (zmax - zmin) + 10); + std::string data = ostream.str(); + fog.mImageData = std::vector(data.begin(), data.end()); + } - mViewMatrix.makeLookAt(osg::Vec3d(x, y, zmax + 5), osg::Vec3d(x, y, zmin), upVector); + LocalMapRenderToTexture::LocalMapRenderToTexture(osg::Node* sceneRoot, int res, int mapWorldSize, float x, float y, + const osg::Vec3d& upVector, float zmin, float zmax) + : RTTNode(res, res, 0, false, 0, StereoAwareness::Unaware_MultiViewShaders) + , mSceneRoot(sceneRoot) + , mActive(true) + { + setNodeMask(Mask_RenderToTexture); - setUpdateCallback(new CameraLocalUpdateCallback); - setDepthBufferInternalFormat(GL_DEPTH24_STENCIL8); -} + if (SceneUtil::AutoDepth::isReversed()) + mProjectionMatrix = SceneUtil::getReversedZProjectionMatrixAsOrtho( + -mapWorldSize / 2, mapWorldSize / 2, -mapWorldSize / 2, mapWorldSize / 2, 5, (zmax - zmin) + 10); + else + mProjectionMatrix.makeOrtho( + -mapWorldSize / 2, mapWorldSize / 2, -mapWorldSize / 2, mapWorldSize / 2, 5, (zmax - zmin) + 10); -void LocalMapRenderToTexture::setDefaults(osg::Camera* camera) -{ - // Disable small feature culling, it's not going to be reliable for this camera - osg::Camera::CullingMode cullingMode = (osg::Camera::DEFAULT_CULLING | osg::Camera::FAR_PLANE_CULLING) & ~(osg::Camera::SMALL_FEATURE_CULLING); - camera->setCullingMode(cullingMode); - - SceneUtil::setCameraClearDepth(camera); - camera->setComputeNearFarMode(osg::Camera::DO_NOT_COMPUTE_NEAR_FAR); - camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF_INHERIT_VIEWPOINT); - camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT, osg::Camera::PIXEL_BUFFER_RTT); - camera->setClearColor(osg::Vec4(0.f, 0.f, 0.f, 1.f)); - camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - camera->setRenderOrder(osg::Camera::PRE_RENDER); - - camera->setCullMask(Mask_Scene | Mask_SimpleWater | Mask_Terrain | Mask_Object | Mask_Static); - camera->setCullMaskLeft(Mask_Scene | Mask_SimpleWater | Mask_Terrain | Mask_Object | Mask_Static); - camera->setCullMaskRight(Mask_Scene | Mask_SimpleWater | Mask_Terrain | Mask_Object | Mask_Static); - camera->setNodeMask(Mask_RenderToTexture); - camera->setProjectionMatrix(mProjectionMatrix); - camera->setViewMatrix(mViewMatrix); - - auto* stateset = camera->getOrCreateStateSet(); - - stateset->setAttribute(new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::FILL), osg::StateAttribute::OVERRIDE); - stateset->addUniform(new osg::Uniform("projectionMatrix", static_cast(mProjectionMatrix)), osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); - - if (Stereo::getMultiview()) - Stereo::setMultiviewMatrices(stateset, { mProjectionMatrix, mProjectionMatrix }); - - // assign large value to effectively turn off fog - // shaders don't respect glDisable(GL_FOG) - osg::ref_ptr fog(new osg::Fog); - fog->setStart(10000000); - fog->setEnd(10000000); - stateset->setAttributeAndModes(fog, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE); - - // turn of sky blending - stateset->addUniform(new osg::Uniform("far", 10000000.0f)); - stateset->addUniform(new osg::Uniform("skyBlendingStart", 8000000.0f)); - stateset->addUniform(new osg::Uniform("sky", 0)); - stateset->addUniform(new osg::Uniform("screenRes", osg::Vec2f{1, 1})); - - osg::ref_ptr lightmodel = new osg::LightModel; - lightmodel->setAmbientIntensity(osg::Vec4(0.3f, 0.3f, 0.3f, 1.f)); - stateset->setAttributeAndModes(lightmodel, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); - - osg::ref_ptr light = new osg::Light; - light->setPosition(osg::Vec4(-0.3f, -0.3f, 0.7f, 0.f)); - light->setDiffuse(osg::Vec4(0.7f, 0.7f, 0.7f, 1.f)); - light->setAmbient(osg::Vec4(0, 0, 0, 1)); - light->setSpecular(osg::Vec4(0, 0, 0, 0)); - light->setLightNum(0); - light->setConstantAttenuation(1.f); - light->setLinearAttenuation(0.f); - light->setQuadraticAttenuation(0.f); - - osg::ref_ptr lightSource = new osg::LightSource; - lightSource->setLight(light); - - lightSource->setStateSetModes(*stateset, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); - - SceneUtil::ShadowManager::disableShadowsForStateSet(stateset); - - // override sun for local map - SceneUtil::configureStateSetSunOverride(static_cast(mSceneRoot), light, stateset); - - camera->addChild(lightSource); - camera->addChild(mSceneRoot); -} + mViewMatrix.makeLookAt(osg::Vec3d(x, y, zmax + 5), osg::Vec3d(x, y, zmin), upVector); -void CameraLocalUpdateCallback::operator()(LocalMapRenderToTexture* node, osg::NodeVisitor* nv) -{ - if (!node->isActive()) - node->setNodeMask(0); + setUpdateCallback(new CameraLocalUpdateCallback); + setDepthBufferInternalFormat(GL_DEPTH24_STENCIL8); + } - if (node->isActive()) + void LocalMapRenderToTexture::setDefaults(osg::Camera* camera) { - node->setIsActive(false); + // Disable small feature culling, it's not going to be reliable for this camera + osg::Camera::CullingMode cullingMode + = (osg::Camera::DEFAULT_CULLING | osg::Camera::FAR_PLANE_CULLING) & ~(osg::Camera::SMALL_FEATURE_CULLING); + camera->setCullingMode(cullingMode); + + SceneUtil::setCameraClearDepth(camera); + camera->setComputeNearFarMode(osg::Camera::DO_NOT_COMPUTE_NEAR_FAR); + camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF_INHERIT_VIEWPOINT); + camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT, osg::Camera::PIXEL_BUFFER_RTT); + camera->setClearColor(osg::Vec4(0.f, 0.f, 0.f, 1.f)); + camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + camera->setRenderOrder(osg::Camera::PRE_RENDER); + + camera->setCullMask(Mask_Scene | Mask_SimpleWater | Mask_Terrain | Mask_Object | Mask_Static); + camera->setCullMaskLeft(Mask_Scene | Mask_SimpleWater | Mask_Terrain | Mask_Object | Mask_Static); + camera->setCullMaskRight(Mask_Scene | Mask_SimpleWater | Mask_Terrain | Mask_Object | Mask_Static); + camera->setNodeMask(Mask_RenderToTexture); + camera->setProjectionMatrix(mProjectionMatrix); + camera->setViewMatrix(mViewMatrix); + + auto* stateset = camera->getOrCreateStateSet(); + + stateset->setAttribute(new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::FILL), + osg::StateAttribute::OVERRIDE); + stateset->addUniform(new osg::Uniform("projectionMatrix", static_cast(mProjectionMatrix)), + osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); + + if (Stereo::getMultiview()) + Stereo::setMultiviewMatrices(stateset, { mProjectionMatrix, mProjectionMatrix }); + + // assign large value to effectively turn off fog + // shaders don't respect glDisable(GL_FOG) + osg::ref_ptr fog(new osg::Fog); + fog->setStart(10000000); + fog->setEnd(10000000); + stateset->setAttributeAndModes(fog, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE); + + // turn of sky blending + stateset->addUniform(new osg::Uniform("far", 10000000.0f)); + stateset->addUniform(new osg::Uniform("skyBlendingStart", 8000000.0f)); + stateset->addUniform(new osg::Uniform("sky", 0)); + stateset->addUniform(new osg::Uniform("screenRes", osg::Vec2f{ 1, 1 })); + + osg::ref_ptr lightmodel = new osg::LightModel; + lightmodel->setAmbientIntensity(osg::Vec4(0.3f, 0.3f, 0.3f, 1.f)); + stateset->setAttributeAndModes(lightmodel, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); + + osg::ref_ptr light = new osg::Light; + light->setPosition(osg::Vec4(-0.3f, -0.3f, 0.7f, 0.f)); + light->setDiffuse(osg::Vec4(0.7f, 0.7f, 0.7f, 1.f)); + light->setAmbient(osg::Vec4(0, 0, 0, 1)); + light->setSpecular(osg::Vec4(0, 0, 0, 0)); + light->setLightNum(0); + light->setConstantAttenuation(1.f); + light->setLinearAttenuation(0.f); + light->setQuadraticAttenuation(0.f); + + osg::ref_ptr lightSource = new osg::LightSource; + lightSource->setLight(light); + + lightSource->setStateSetModes(*stateset, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); + + SceneUtil::ShadowManager::disableShadowsForStateSet(stateset); + + // override sun for local map + SceneUtil::configureStateSetSunOverride(static_cast(mSceneRoot), light, stateset); + + camera->addChild(lightSource); + camera->addChild(mSceneRoot); } - // Rtt-nodes do not forward update traversal to their cameras so we can traverse safely. - // Traverse in case there are nested callbacks. - traverse(node, nv); -} + void CameraLocalUpdateCallback::operator()(LocalMapRenderToTexture* node, osg::NodeVisitor* nv) + { + if (!node->isActive()) + node->setNodeMask(0); + + if (node->isActive()) + { + node->setIsActive(false); + } + + // Rtt-nodes do not forward update traversal to their cameras so we can traverse safely. + // Traverse in case there are nested callbacks. + traverse(node, nv); + } } diff --git a/apps/openmw/mwrender/localmap.hpp b/apps/openmw/mwrender/localmap.hpp index 911671aee2..f4a856606e 100644 --- a/apps/openmw/mwrender/localmap.hpp +++ b/apps/openmw/mwrender/localmap.hpp @@ -1,9 +1,9 @@ #ifndef GAME_RENDER_LOCALMAP_H #define GAME_RENDER_LOCALMAP_H +#include #include #include -#include #include #include @@ -47,18 +47,19 @@ namespace MWRender void clear(); /** - * Request a map render for the given cell. Render textures will be immediately created and can be retrieved with the getMapTexture function. + * Request a map render for the given cell. Render textures will be immediately created and can be retrieved + * with the getMapTexture function. */ - void requestMap (const MWWorld::CellStore* cell); + void requestMap(const MWWorld::CellStore* cell); void addCell(MWWorld::CellStore* cell); void removeExteriorCell(int x, int y); - void removeCell (MWWorld::CellStore* cell); + void removeCell(MWWorld::CellStore* cell); - osg::ref_ptr getMapTexture (int x, int y); + osg::ref_ptr getMapTexture(int x, int y); - osg::ref_ptr getFogOfWarTexture (int x, int y); + osg::ref_ptr getFogOfWarTexture(int x, int y); /** * Removes cameras that have already been rendered. Should be called every frame to ensure that @@ -68,12 +69,13 @@ namespace MWRender void cleanupCameras(); /** - * Set the position & direction of the player, and returns the position in map space through the reference parameters. + * Set the position & direction of the player, and returns the position in map space through the reference + * parameters. * @remarks This is used to draw a "fog of war" effect * to hide areas on the map the player has not discovered yet. */ - void updatePlayer (const osg::Vec3f& position, const osg::Quat& orientation, - float& u, float& v, int& x, int& y, osg::Vec3f& direction); + void updatePlayer(const osg::Vec3f& position, const osg::Quat& orientation, float& u, float& v, int& x, int& y, + osg::Vec3f& direction); /** * Save the fog of war for this cell to its CellStore. @@ -84,14 +86,14 @@ namespace MWRender /** * Get the interior map texture index and normalized position on this texture, given a world position */ - void worldToInteriorMapPosition (osg::Vec2f pos, float& nX, float& nY, int& x, int& y); + void worldToInteriorMapPosition(osg::Vec2f pos, float& nX, float& nY, int& x, int& y); - osg::Vec2f interiorMapToWorldPosition (float nX, float nY, int x, int y); + osg::Vec2f interiorMapToWorldPosition(float nX, float nY, int x, int y); /** * Check if a given position is explored by the player (i.e. not obscured by fog of war) */ - bool isPositionExplored (float nX, float nY, int x, int y); + bool isPositionExplored(float nX, float nY, int x, int y); osg::Group* getRoot(); @@ -99,10 +101,10 @@ namespace MWRender osg::ref_ptr mRoot; osg::ref_ptr mSceneRoot; - typedef std::vector< osg::ref_ptr > RTTVector; + typedef std::vector> RTTVector; RTTVector mLocalMapRTTs; - typedef std::set > Grid; + typedef std::set> Grid; Grid mCurrentGrid; struct MapSegment @@ -144,7 +146,8 @@ namespace MWRender void requestExteriorMap(const MWWorld::CellStore* cell); void requestInteriorMap(const MWWorld::CellStore* cell); - void setupRenderToTexture(int segment_x, int segment_y, float left, float top, const osg::Vec3d& upVector, float zmin, float zmax); + void setupRenderToTexture( + int segment_x, int segment_y, float left, float top, const osg::Vec3d& upVector, float zmin, float zmax); bool mInterior; osg::BoundingBox mBounds; diff --git a/apps/openmw/mwrender/luminancecalculator.cpp b/apps/openmw/mwrender/luminancecalculator.cpp index 06a0441d0d..6655ae4d8f 100644 --- a/apps/openmw/mwrender/luminancecalculator.cpp +++ b/apps/openmw/mwrender/luminancecalculator.cpp @@ -9,7 +9,8 @@ namespace MWRender { LuminanceCalculator::LuminanceCalculator(Shader::ShaderManager& shaderManager) { - const float hdrExposureTime = std::max(Settings::Manager::getFloat("auto exposure speed", "Post Processing"), 0.0001f); + const float hdrExposureTime + = std::max(Settings::Manager::getFloat("auto exposure speed", "Post Processing"), 0.0001f); constexpr float minLog = -9.0; constexpr float maxLog = 4.0; @@ -18,12 +19,12 @@ namespace MWRender constexpr float epsilon = 0.004; Shader::ShaderManager::DefineMap defines = { - {"minLog", std::to_string(minLog)}, - {"maxLog", std::to_string(maxLog)}, - {"logLumRange", std::to_string(logLumRange)}, - {"invLogLumRange", std::to_string(invLogLumRange)}, - {"hdrExposureTime", std::to_string(hdrExposureTime)}, - {"epsilon", std::to_string(epsilon)}, + { "minLog", std::to_string(minLog) }, + { "maxLog", std::to_string(maxLog) }, + { "logLumRange", std::to_string(logLumRange) }, + { "invLogLumRange", std::to_string(invLogLumRange) }, + { "hdrExposureTime", std::to_string(hdrExposureTime) }, + { "epsilon", std::to_string(epsilon) }, }; auto vertex = shaderManager.getShader("fullscreen_tri_vertex.glsl", {}, osg::Shader::VERTEX); @@ -44,7 +45,8 @@ namespace MWRender buffer.mipmappedSceneLuminanceTex->setInternalFormat(GL_R16F); buffer.mipmappedSceneLuminanceTex->setSourceFormat(GL_RED); buffer.mipmappedSceneLuminanceTex->setSourceType(GL_FLOAT); - buffer.mipmappedSceneLuminanceTex->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR_MIPMAP_NEAREST); + buffer.mipmappedSceneLuminanceTex->setFilter( + osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR_MIPMAP_NEAREST); buffer.mipmappedSceneLuminanceTex->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR); buffer.mipmappedSceneLuminanceTex->setTextureSize(mWidth, mHeight); buffer.mipmappedSceneLuminanceTex->setNumMipmapLevels(mipmapLevels); @@ -60,16 +62,20 @@ namespace MWRender buffer.luminanceProxyTex = new osg::Texture2D(*buffer.luminanceTex); buffer.resolveFbo = new osg::FrameBufferObject; - buffer.resolveFbo->setAttachment(osg::FrameBufferObject::BufferComponent::COLOR_BUFFER0, osg::FrameBufferAttachment(buffer.luminanceTex)); + buffer.resolveFbo->setAttachment(osg::FrameBufferObject::BufferComponent::COLOR_BUFFER0, + osg::FrameBufferAttachment(buffer.luminanceTex)); buffer.luminanceProxyFbo = new osg::FrameBufferObject; - buffer.luminanceProxyFbo->setAttachment(osg::FrameBufferObject::BufferComponent::COLOR_BUFFER0, osg::FrameBufferAttachment(buffer.luminanceProxyTex)); + buffer.luminanceProxyFbo->setAttachment(osg::FrameBufferObject::BufferComponent::COLOR_BUFFER0, + osg::FrameBufferAttachment(buffer.luminanceProxyTex)); buffer.resolveSceneLumFbo = new osg::FrameBufferObject; - buffer.resolveSceneLumFbo->setAttachment(osg::FrameBufferObject::BufferComponent::COLOR_BUFFER0, osg::FrameBufferAttachment(buffer.mipmappedSceneLuminanceTex, mipmapLevels - 1)); + buffer.resolveSceneLumFbo->setAttachment(osg::FrameBufferObject::BufferComponent::COLOR_BUFFER0, + osg::FrameBufferAttachment(buffer.mipmappedSceneLuminanceTex, mipmapLevels - 1)); buffer.sceneLumFbo = new osg::FrameBufferObject; - buffer.sceneLumFbo->setAttachment(osg::FrameBufferObject::BufferComponent::COLOR_BUFFER0, osg::FrameBufferAttachment(buffer.mipmappedSceneLuminanceTex)); + buffer.sceneLumFbo->setAttachment(osg::FrameBufferObject::BufferComponent::COLOR_BUFFER0, + osg::FrameBufferAttachment(buffer.mipmappedSceneLuminanceTex)); buffer.sceneLumSS = new osg::StateSet; buffer.sceneLumSS->setAttributeAndModes(mLuminanceProgram); @@ -88,7 +94,8 @@ namespace MWRender mCompiled = true; } - void LuminanceCalculator::draw(const PingPongCanvas& canvas, osg::RenderInfo& renderInfo, osg::State& state, osg::GLExtensions* ext, size_t frameId) + void LuminanceCalculator::draw(const PingPongCanvas& canvas, osg::RenderInfo& renderInfo, osg::State& state, + osg::GLExtensions* ext, size_t frameId) { if (!mEnabled) return; @@ -112,7 +119,8 @@ namespace MWRender buffer.luminanceProxyFbo->apply(state, osg::FrameBufferObject::DRAW_FRAMEBUFFER); ext->glBlitFramebuffer(0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST); - if (dirty) { + if (dirty) + { // Use current frame data for previous frame to warm up calculations and prevent popin mBuffers[(frameId + 1) % 2].resolveFbo->apply(state, osg::FrameBufferObject::DRAW_FRAMEBUFFER); ext->glBlitFramebuffer(0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST); @@ -124,7 +132,8 @@ namespace MWRender state.apply(buffer.resolveSS); canvas.drawGeometry(renderInfo); - ext->glBindFramebuffer(GL_FRAMEBUFFER_EXT, state.getGraphicsContext() ? state.getGraphicsContext()->getDefaultFboId() : 0); + ext->glBindFramebuffer( + GL_FRAMEBUFFER_EXT, state.getGraphicsContext() ? state.getGraphicsContext()->getDefaultFboId() : 0); } osg::ref_ptr LuminanceCalculator::getLuminanceTexture(size_t frameId) const diff --git a/apps/openmw/mwrender/luminancecalculator.hpp b/apps/openmw/mwrender/luminancecalculator.hpp index 9d17b05653..db823dd900 100644 --- a/apps/openmw/mwrender/luminancecalculator.hpp +++ b/apps/openmw/mwrender/luminancecalculator.hpp @@ -4,8 +4,8 @@ #include #include -#include #include +#include namespace Shader { @@ -20,12 +20,12 @@ namespace MWRender { public: - LuminanceCalculator() = default; LuminanceCalculator(Shader::ShaderManager& shaderManager); - void draw(const PingPongCanvas& canvas, osg::RenderInfo& renderInfo, osg::State& state, osg::GLExtensions* ext, size_t frameId); + void draw(const PingPongCanvas& canvas, osg::RenderInfo& renderInfo, osg::State& state, osg::GLExtensions* ext, + size_t frameId); bool isEnabled() const { return mEnabled; } @@ -43,7 +43,6 @@ namespace MWRender osg::ref_ptr getLuminanceTexture(size_t frameId) const; private: - void compile(); struct Container diff --git a/apps/openmw/mwrender/navmesh.cpp b/apps/openmw/mwrender/navmesh.cpp index 7fd12686ae..bb4a2aa234 100644 --- a/apps/openmw/mwrender/navmesh.cpp +++ b/apps/openmw/mwrender/navmesh.cpp @@ -1,14 +1,14 @@ #include "navmesh.hpp" #include "vismask.hpp" -#include +#include +#include +#include #include #include -#include #include +#include #include -#include -#include #include #include @@ -17,21 +17,21 @@ #include "../mwbase/environment.hpp" -#include #include +#include namespace MWRender { struct NavMesh::LessByTilePosition { bool operator()(const DetourNavigator::TilePosition& lhs, - const std::pair& rhs) const + const std::pair& rhs) const { return lhs < rhs.first; } bool operator()(const std::pair& lhs, - const DetourNavigator::TilePosition& rhs) const + const DetourNavigator::TilePosition& rhs) const { return lhs.first < rhs; } @@ -47,7 +47,7 @@ namespace MWRender const DetourNavigator::Settings mSettings; std::map mTiles; NavMeshMode mMode; - std::atomic_bool mAborted {false}; + std::atomic_bool mAborted{ false }; std::mutex mMutex; bool mStarted = false; std::vector> mUpdatedTiles; @@ -88,12 +88,12 @@ namespace MWRender unsigned minSalt = std::numeric_limits::max(); unsigned maxSalt = 0; - navMeshPtr->lockConst()->forEachUsedTile([&] (const TilePosition& position, const Version& version, const dtMeshTile& meshTile) - { - existingTiles.emplace_back(position, version); - minSalt = std::min(minSalt, meshTile.salt); - maxSalt = std::max(maxSalt, meshTile.salt); - }); + navMeshPtr->lockConst()->forEachUsedTile( + [&](const TilePosition& position, const Version& version, const dtMeshTile& meshTile) { + existingTiles.emplace_back(position, version); + minSalt = std::min(minSalt, meshTile.salt); + maxSalt = std::max(maxSalt, meshTile.salt); + }); if (mAborted.load(std::memory_order_acquire)) return; @@ -103,7 +103,7 @@ namespace MWRender std::vector removedTiles; for (const auto& [position, tile] : mTiles) - if (!std::binary_search(existingTiles.begin(), existingTiles.end(), position, LessByTilePosition {})) + if (!std::binary_search(existingTiles.begin(), existingTiles.end(), position, LessByTilePosition{})) removedTiles.push_back(position); std::vector> updatedTiles; @@ -116,7 +116,7 @@ namespace MWRender { const auto it = mTiles.find(position); if (it != mTiles.end() && it->second.mGroup != nullptr && it->second.mVersion == version - && mMode != NavMeshMode::UpdateFrequency) + && mMode != NavMeshMode::UpdateFrequency) continue; osg::ref_ptr group; @@ -139,7 +139,7 @@ namespace MWRender } MWBase::Environment::get().getResourceSystem()->getSceneManager()->recreateShaders(group, "debug"); group->setNodeMask(Mask_Debug); - updatedTiles.emplace_back(position, Tile {version, std::move(group)}); + updatedTiles.emplace_back(position, Tile{ version, std::move(group) }); } if (mAborted.load(std::memory_order_acquire)) @@ -149,10 +149,7 @@ namespace MWRender mRemovedTiles = std::move(removedTiles); } - void abort() final - { - mAborted.store(true, std::memory_order_release); - } + void abort() final { mAborted.store(true, std::memory_order_release); } }; struct NavMesh::DeallocateCreateNavMeshTileGroups final : SceneUtil::WorkItem @@ -160,11 +157,13 @@ namespace MWRender osg::ref_ptr mWorkItem; explicit DeallocateCreateNavMeshTileGroups(osg::ref_ptr&& workItem) - : mWorkItem(std::move(workItem)) {} + : mWorkItem(std::move(workItem)) + { + } }; NavMesh::NavMesh(const osg::ref_ptr& root, const osg::ref_ptr& workQueue, - bool enabled, NavMeshMode mode) + bool enabled, NavMeshMode mode) : mRootNode(root) , mWorkQueue(workQueue) , mGroupStateSet(SceneUtil::makeNavMeshTileStateSet()) @@ -203,7 +202,7 @@ namespace MWRender return; { - std::pair lastest {0, Version {}}; + std::pair lastest{ 0, Version{} }; osg::ref_ptr latestCandidate; for (auto it = mWorkItems.begin(); it != mWorkItems.end();) { @@ -212,7 +211,7 @@ namespace MWRender ++it; continue; } - const std::pair order {(*it)->mId, (*it)->mVersion}; + const std::pair order{ (*it)->mId, (*it)->mVersion }; if (lastest < order) { lastest = order; @@ -284,8 +283,8 @@ namespace MWRender return; } - osg::ref_ptr workItem = new CreateNavMeshTileGroups(id, version, navMesh, - mGroupStateSet, mDebugDrawStateSet, settings, mTiles, mMode); + osg::ref_ptr workItem = new CreateNavMeshTileGroups( + id, version, navMesh, mGroupStateSet, mDebugDrawStateSet, settings, mTiles, mMode); mWorkQueue->addWorkItem(workItem); mWorkItems.push_back(std::move(workItem)); } diff --git a/apps/openmw/mwrender/navmesh.hpp b/apps/openmw/mwrender/navmesh.hpp index f4d3f07e94..4b4e50f791 100644 --- a/apps/openmw/mwrender/navmesh.hpp +++ b/apps/openmw/mwrender/navmesh.hpp @@ -3,8 +3,8 @@ #include "navmeshmode.hpp" -#include #include +#include #include #include @@ -12,8 +12,8 @@ #include #include #include -#include #include +#include class dtNavMesh; @@ -41,7 +41,7 @@ namespace MWRender { public: explicit NavMesh(const osg::ref_ptr& root, const osg::ref_ptr& workQueue, - bool enabled, NavMeshMode mode); + bool enabled, NavMeshMode mode); ~NavMesh(); bool toggle(); @@ -55,10 +55,7 @@ namespace MWRender void disable(); - bool isEnabled() const - { - return mEnabled; - } + bool isEnabled() const { return mEnabled; } void setMode(NavMeshMode value); diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 940b343792..a0f6cd2b57 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -1,11 +1,11 @@ #include "npcanimation.hpp" -#include -#include #include +#include +#include -#include #include +#include #include @@ -13,1312 +13,1304 @@ #include +#include +#include +#include +#include +#include +#include +#include #include #include #include #include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include #include #include +#include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" #include "../mwworld/inventorystore.hpp" -#include "../mwworld/class.hpp" #include "../mwworld/player.hpp" -#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/actorutil.hpp" +#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/weapontype.hpp" #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/soundmanager.hpp" +#include "../mwbase/world.hpp" #include "camera.hpp" -#include "rotatecontroller.hpp" +#include "postprocessor.hpp" #include "renderbin.hpp" -#include "vismask.hpp" +#include "rotatecontroller.hpp" #include "util.hpp" -#include "postprocessor.hpp" +#include "vismask.hpp" namespace { -std::string getVampireHead(const std::string& race, bool female, const VFS::Manager& vfs) -{ - static std::map , const ESM::BodyPart* > sVampireMapping; + std::string getVampireHead(const std::string& race, bool female, const VFS::Manager& vfs) + { + static std::map, const ESM::BodyPart*> sVampireMapping; - std::pair thisCombination = std::make_pair(race, int(female)); + std::pair thisCombination = std::make_pair(race, int(female)); - if (sVampireMapping.find(thisCombination) == sVampireMapping.end()) - { - const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); - for (const ESM::BodyPart& bodypart : store.get()) + if (sVampireMapping.find(thisCombination) == sVampireMapping.end()) { - if (!bodypart.mData.mVampire) - continue; - if (bodypart.mData.mType != ESM::BodyPart::MT_Skin) - continue; - if (bodypart.mData.mPart != ESM::BodyPart::MP_Head) - continue; - if (female != (bodypart.mData.mFlags & ESM::BodyPart::BPF_Female)) - continue; - if (!Misc::StringUtils::ciEqual(bodypart.mRace, race)) - continue; - sVampireMapping[thisCombination] = &bodypart; + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + for (const ESM::BodyPart& bodypart : store.get()) + { + if (!bodypart.mData.mVampire) + continue; + if (bodypart.mData.mType != ESM::BodyPart::MT_Skin) + continue; + if (bodypart.mData.mPart != ESM::BodyPart::MP_Head) + continue; + if (female != (bodypart.mData.mFlags & ESM::BodyPart::BPF_Female)) + continue; + if (!Misc::StringUtils::ciEqual(bodypart.mRace, race)) + continue; + sVampireMapping[thisCombination] = &bodypart; + } } - } - sVampireMapping.emplace(thisCombination, nullptr); + sVampireMapping.emplace(thisCombination, nullptr); - const ESM::BodyPart* bodyPart = sVampireMapping[thisCombination]; - if (!bodyPart) - return std::string(); - return Misc::ResourceHelpers::correctMeshPath(bodyPart->mModel, &vfs); -} + const ESM::BodyPart* bodyPart = sVampireMapping[thisCombination]; + if (!bodyPart) + return std::string(); + return Misc::ResourceHelpers::correctMeshPath(bodyPart->mModel, &vfs); + } } - namespace MWRender { -class HeadAnimationTime : public SceneUtil::ControllerSource -{ -private: - MWWorld::Ptr mReference; - float mTalkStart; - float mTalkStop; - float mBlinkStart; - float mBlinkStop; + class HeadAnimationTime : public SceneUtil::ControllerSource + { + private: + MWWorld::Ptr mReference; + float mTalkStart; + float mTalkStop; + float mBlinkStart; + float mBlinkStop; - float mBlinkTimer; + float mBlinkTimer; - bool mEnabled; + bool mEnabled; - float mValue; -private: - void resetBlinkTimer(); -public: - HeadAnimationTime(const MWWorld::Ptr& reference); + float mValue; - void updatePtr(const MWWorld::Ptr& updated); + private: + void resetBlinkTimer(); - void update(float dt); + public: + HeadAnimationTime(const MWWorld::Ptr& reference); - void setEnabled(bool enabled); + void updatePtr(const MWWorld::Ptr& updated); - void setTalkStart(float value); - void setTalkStop(float value); - void setBlinkStart(float value); - void setBlinkStop(float value); + void update(float dt); - float getValue(osg::NodeVisitor* nv) override; -}; + void setEnabled(bool enabled); -// -------------------------------------------------------------------------------------------------------------- + void setTalkStart(float value); + void setTalkStop(float value); + void setBlinkStart(float value); + void setBlinkStop(float value); -HeadAnimationTime::HeadAnimationTime(const MWWorld::Ptr& reference) - : mReference(reference), mTalkStart(0), mTalkStop(0), mBlinkStart(0), mBlinkStop(0), mEnabled(true), mValue(0) -{ - resetBlinkTimer(); -} + float getValue(osg::NodeVisitor* nv) override; + }; -void HeadAnimationTime::updatePtr(const MWWorld::Ptr &updated) -{ - mReference = updated; -} + // -------------------------------------------------------------------------------------------------------------- -void HeadAnimationTime::setEnabled(bool enabled) -{ - mEnabled = enabled; -} + HeadAnimationTime::HeadAnimationTime(const MWWorld::Ptr& reference) + : mReference(reference) + , mTalkStart(0) + , mTalkStop(0) + , mBlinkStart(0) + , mBlinkStop(0) + , mEnabled(true) + , mValue(0) + { + resetBlinkTimer(); + } -void HeadAnimationTime::resetBlinkTimer() -{ - auto& prng = MWBase::Environment::get().getWorld()->getPrng(); - mBlinkTimer = -(2.0f + Misc::Rng::rollDice(6, prng)); -} + void HeadAnimationTime::updatePtr(const MWWorld::Ptr& updated) + { + mReference = updated; + } -void HeadAnimationTime::update(float dt) -{ - if (!mEnabled) - return; + void HeadAnimationTime::setEnabled(bool enabled) + { + mEnabled = enabled; + } - if (!MWBase::Environment::get().getSoundManager()->sayActive(mReference)) + void HeadAnimationTime::resetBlinkTimer() { - mBlinkTimer += dt; + auto& prng = MWBase::Environment::get().getWorld()->getPrng(); + mBlinkTimer = -(2.0f + Misc::Rng::rollDice(6, prng)); + } - float duration = mBlinkStop - mBlinkStart; + void HeadAnimationTime::update(float dt) + { + if (!mEnabled) + return; - if (mBlinkTimer >= 0 && mBlinkTimer <= duration) + if (!MWBase::Environment::get().getSoundManager()->sayActive(mReference)) { - mValue = mBlinkStart + mBlinkTimer; + mBlinkTimer += dt; + + float duration = mBlinkStop - mBlinkStart; + + if (mBlinkTimer >= 0 && mBlinkTimer <= duration) + { + mValue = mBlinkStart + mBlinkTimer; + } + else + mValue = mBlinkStop; + + if (mBlinkTimer > duration) + resetBlinkTimer(); } else - mValue = mBlinkStop; + { + // FIXME: would be nice to hold on to the SoundPtr so we don't have to retrieve it every frame + mValue = mTalkStart + + (mTalkStop - mTalkStart) + * std::min(1.f, + MWBase::Environment::get().getSoundManager()->getSaySoundLoudness(mReference) + * 2); // Rescale a bit (most voices are not very loud) + } + } - if (mBlinkTimer > duration) - resetBlinkTimer(); + float HeadAnimationTime::getValue(osg::NodeVisitor*) + { + return mValue; } - else + + void HeadAnimationTime::setTalkStart(float value) { - // FIXME: would be nice to hold on to the SoundPtr so we don't have to retrieve it every frame - mValue = mTalkStart + - (mTalkStop - mTalkStart) * - std::min(1.f, MWBase::Environment::get().getSoundManager()->getSaySoundLoudness(mReference)*2); // Rescale a bit (most voices are not very loud) + mTalkStart = value; } -} -float HeadAnimationTime::getValue(osg::NodeVisitor*) -{ - return mValue; -} + void HeadAnimationTime::setTalkStop(float value) + { + mTalkStop = value; + } -void HeadAnimationTime::setTalkStart(float value) -{ - mTalkStart = value; -} + void HeadAnimationTime::setBlinkStart(float value) + { + mBlinkStart = value; + } -void HeadAnimationTime::setTalkStop(float value) -{ - mTalkStop = value; -} + void HeadAnimationTime::setBlinkStop(float value) + { + mBlinkStop = value; + } -void HeadAnimationTime::setBlinkStart(float value) -{ - mBlinkStart = value; -} + // ---------------------------------------------------- -void HeadAnimationTime::setBlinkStop(float value) -{ - mBlinkStop = value; -} + NpcAnimation::NpcType NpcAnimation::getNpcType() const + { + const MWWorld::Class& cls = mPtr.getClass(); + // Dead vampires should typically stay vampires. + if (mNpcType == Type_Vampire && cls.getNpcStats(mPtr).isDead() && !cls.getNpcStats(mPtr).isWerewolf()) + return mNpcType; + return getNpcType(mPtr); + } -// ---------------------------------------------------- + NpcAnimation::NpcType NpcAnimation::getNpcType(const MWWorld::Ptr& ptr) + { + const MWWorld::Class& cls = ptr.getClass(); + NpcAnimation::NpcType curType = Type_Normal; + if (cls.getCreatureStats(ptr).getMagicEffects().get(ESM::MagicEffect::Vampirism).getMagnitude() > 0) + curType = Type_Vampire; + if (cls.getNpcStats(ptr).isWerewolf()) + curType = Type_Werewolf; + + return curType; + } -NpcAnimation::NpcType NpcAnimation::getNpcType() const -{ - const MWWorld::Class &cls = mPtr.getClass(); - // Dead vampires should typically stay vampires. - if (mNpcType == Type_Vampire && cls.getNpcStats(mPtr).isDead() && !cls.getNpcStats(mPtr).isWerewolf()) - return mNpcType; - return getNpcType(mPtr); -} + static const inline NpcAnimation::PartBoneMap createPartListMap() + { + return { { ESM::PRT_Head, "Head" }, + { ESM::PRT_Hair, "Head" }, // note it uses "Head" as attach bone, but "Hair" as filter + { ESM::PRT_Neck, "Neck" }, { ESM::PRT_Cuirass, "Chest" }, { ESM::PRT_Groin, "Groin" }, + { ESM::PRT_Skirt, "Groin" }, { ESM::PRT_RHand, "Right Hand" }, { ESM::PRT_LHand, "Left Hand" }, + { ESM::PRT_RWrist, "Right Wrist" }, { ESM::PRT_LWrist, "Left Wrist" }, { ESM::PRT_Shield, "Shield Bone" }, + { ESM::PRT_RForearm, "Right Forearm" }, { ESM::PRT_LForearm, "Left Forearm" }, + { ESM::PRT_RUpperarm, "Right Upper Arm" }, { ESM::PRT_LUpperarm, "Left Upper Arm" }, + { ESM::PRT_RFoot, "Right Foot" }, { ESM::PRT_LFoot, "Left Foot" }, { ESM::PRT_RAnkle, "Right Ankle" }, + { ESM::PRT_LAnkle, "Left Ankle" }, { ESM::PRT_RKnee, "Right Knee" }, { ESM::PRT_LKnee, "Left Knee" }, + { ESM::PRT_RLeg, "Right Upper Leg" }, { ESM::PRT_LLeg, "Left Upper Leg" }, + { ESM::PRT_RPauldron, "Right Clavicle" }, { ESM::PRT_LPauldron, "Left Clavicle" }, + { ESM::PRT_Weapon, "Weapon Bone" }, // Fallback. The real node name depends on the current weapon type. + { ESM::PRT_Tail, "Tail" } }; + } + const NpcAnimation::PartBoneMap NpcAnimation::sPartList = createPartListMap(); -NpcAnimation::NpcType NpcAnimation::getNpcType(const MWWorld::Ptr& ptr) -{ - const MWWorld::Class &cls = ptr.getClass(); - NpcAnimation::NpcType curType = Type_Normal; - if (cls.getCreatureStats(ptr).getMagicEffects().get(ESM::MagicEffect::Vampirism).getMagnitude() > 0) - curType = Type_Vampire; - if (cls.getNpcStats(ptr).isWerewolf()) - curType = Type_Werewolf; - - return curType; -} + NpcAnimation::~NpcAnimation() + { + mAmmunition.reset(); + } -static const inline NpcAnimation::PartBoneMap createPartListMap() -{ - return { - {ESM::PRT_Head, "Head"}, - {ESM::PRT_Hair, "Head"}, // note it uses "Head" as attach bone, but "Hair" as filter - {ESM::PRT_Neck, "Neck"}, - {ESM::PRT_Cuirass, "Chest"}, - {ESM::PRT_Groin, "Groin"}, - {ESM::PRT_Skirt, "Groin"}, - {ESM::PRT_RHand, "Right Hand"}, - {ESM::PRT_LHand, "Left Hand"}, - {ESM::PRT_RWrist, "Right Wrist"}, - {ESM::PRT_LWrist, "Left Wrist"}, - {ESM::PRT_Shield, "Shield Bone"}, - {ESM::PRT_RForearm, "Right Forearm"}, - {ESM::PRT_LForearm, "Left Forearm"}, - {ESM::PRT_RUpperarm, "Right Upper Arm"}, - {ESM::PRT_LUpperarm, "Left Upper Arm"}, - {ESM::PRT_RFoot, "Right Foot"}, - {ESM::PRT_LFoot, "Left Foot"}, - {ESM::PRT_RAnkle, "Right Ankle"}, - {ESM::PRT_LAnkle, "Left Ankle"}, - {ESM::PRT_RKnee, "Right Knee"}, - {ESM::PRT_LKnee, "Left Knee"}, - {ESM::PRT_RLeg, "Right Upper Leg"}, - {ESM::PRT_LLeg, "Left Upper Leg"}, - {ESM::PRT_RPauldron, "Right Clavicle"}, - {ESM::PRT_LPauldron, "Left Clavicle"}, - {ESM::PRT_Weapon, "Weapon Bone"}, // Fallback. The real node name depends on the current weapon type. - {ESM::PRT_Tail, "Tail"}}; -} -const NpcAnimation::PartBoneMap NpcAnimation::sPartList = createPartListMap(); + NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr parentNode, + Resource::ResourceSystem* resourceSystem, bool disableSounds, ViewMode viewMode, float firstPersonFieldOfView) + : ActorAnimation(ptr, parentNode, resourceSystem) + , mViewMode(viewMode) + , mShowWeapons(false) + , mShowCarriedLeft(true) + , mNpcType(getNpcType(ptr)) + , mFirstPersonFieldOfView(firstPersonFieldOfView) + , mSoundsDisabled(disableSounds) + , mAccurateAiming(false) + , mAimingFactor(0.f) + { + mNpc = mPtr.get()->mBase; -NpcAnimation::~NpcAnimation() -{ - mAmmunition.reset(); -} + mHeadAnimationTime = std::make_shared(mPtr); + mWeaponAnimationTime = std::make_shared(this); -NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr parentNode, Resource::ResourceSystem* resourceSystem, - bool disableSounds, ViewMode viewMode, float firstPersonFieldOfView) - : ActorAnimation(ptr, parentNode, resourceSystem), - mViewMode(viewMode), - mShowWeapons(false), - mShowCarriedLeft(true), - mNpcType(getNpcType(ptr)), - mFirstPersonFieldOfView(firstPersonFieldOfView), - mSoundsDisabled(disableSounds), - mAccurateAiming(false), - mAimingFactor(0.f) -{ - mNpc = mPtr.get()->mBase; + for (size_t i = 0; i < ESM::PRT_Count; i++) + { + mPartslots[i] = -1; // each slot is empty + mPartPriorities[i] = 0; + } - mHeadAnimationTime = std::make_shared(mPtr); - mWeaponAnimationTime = std::make_shared(this); + std::fill(mSounds.begin(), mSounds.end(), nullptr); - for(size_t i = 0;i < ESM::PRT_Count;i++) - { - mPartslots[i] = -1; //each slot is empty - mPartPriorities[i] = 0; + updateNpcBase(); } - std::fill(mSounds.begin(), mSounds.end(), nullptr); - - updateNpcBase(); -} - -void NpcAnimation::setViewMode(NpcAnimation::ViewMode viewMode) -{ - assert(viewMode != VM_HeadOnly); - if(mViewMode == viewMode) - return; - // FIXME: sheathing state must be consistent if the third person skeleton doesn't have the necessary node, but - // third person skeleton is unavailable in first person view. This is a hack to avoid cosmetic issues. - bool viewChange = mViewMode == VM_FirstPerson || viewMode == VM_FirstPerson; - mViewMode = viewMode; - MWBase::Environment::get().getWorld()->scaleObject(mPtr, mPtr.getCellRef().getScale(), true); // apply race height after view change - - mAmmunition.reset(); - rebuild(); - setRenderBin(); - - static const bool shieldSheathing = Settings::Manager::getBool("shield sheathing", "Game"); - if (viewChange && shieldSheathing) + void NpcAnimation::setViewMode(NpcAnimation::ViewMode viewMode) { - int weaptype = ESM::Weapon::None; - MWMechanics::getActiveWeapon(mPtr, &weaptype); - showCarriedLeft(updateCarriedLeftVisible(weaptype)); + assert(viewMode != VM_HeadOnly); + if (mViewMode == viewMode) + return; + // FIXME: sheathing state must be consistent if the third person skeleton doesn't have the necessary node, but + // third person skeleton is unavailable in first person view. This is a hack to avoid cosmetic issues. + bool viewChange = mViewMode == VM_FirstPerson || viewMode == VM_FirstPerson; + mViewMode = viewMode; + MWBase::Environment::get().getWorld()->scaleObject( + mPtr, mPtr.getCellRef().getScale(), true); // apply race height after view change + + mAmmunition.reset(); + rebuild(); + setRenderBin(); + + static const bool shieldSheathing = Settings::Manager::getBool("shield sheathing", "Game"); + if (viewChange && shieldSheathing) + { + int weaptype = ESM::Weapon::None; + MWMechanics::getActiveWeapon(mPtr, &weaptype); + showCarriedLeft(updateCarriedLeftVisible(weaptype)); + } } -} -/// @brief A RenderBin callback to clear the depth buffer before rendering. -/// Switches depth attachments to a proxy renderbuffer, reattaches original depth then redraws first person root. -/// This gives a complete depth buffer which can be used for postprocessing, buffer resolves as if depth was never cleared. -class DepthClearCallback : public osgUtil::RenderBin::DrawCallback -{ -public: - DepthClearCallback() + /// @brief A RenderBin callback to clear the depth buffer before rendering. + /// Switches depth attachments to a proxy renderbuffer, reattaches original depth then redraws first person root. + /// This gives a complete depth buffer which can be used for postprocessing, buffer resolves as if depth was never + /// cleared. + class DepthClearCallback : public osgUtil::RenderBin::DrawCallback { - mDepth = new SceneUtil::AutoDepth; - mDepth->setWriteMask(true); + public: + DepthClearCallback() + { + mDepth = new SceneUtil::AutoDepth; + mDepth->setWriteMask(true); - mStateSet = new osg::StateSet; - mStateSet->setAttributeAndModes(new osg::ColorMask(false, false, false, false), osg::StateAttribute::ON); - mStateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF|osg::StateAttribute::OVERRIDE); - } + mStateSet = new osg::StateSet; + mStateSet->setAttributeAndModes(new osg::ColorMask(false, false, false, false), osg::StateAttribute::ON); + mStateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE); + } - void drawImplementation(osgUtil::RenderBin* bin, osg::RenderInfo& renderInfo, osgUtil::RenderLeaf*& previous) override - { - osg::State* state = renderInfo.getState(); + void drawImplementation( + osgUtil::RenderBin* bin, osg::RenderInfo& renderInfo, osgUtil::RenderLeaf*& previous) override + { + osg::State* state = renderInfo.getState(); - PostProcessor* postProcessor = dynamic_cast(renderInfo.getCurrentCamera()->getUserData()); + PostProcessor* postProcessor = dynamic_cast(renderInfo.getCurrentCamera()->getUserData()); - state->applyAttribute(mDepth); + state->applyAttribute(mDepth); - unsigned int frameId = state->getFrameStamp()->getFrameNumber() % 2; + unsigned int frameId = state->getFrameStamp()->getFrameNumber() % 2; - if (postProcessor && postProcessor->getFbo(PostProcessor::FBO_FirstPerson, frameId)) - { - postProcessor->getFbo(PostProcessor::FBO_FirstPerson, frameId)->apply(*state); + if (postProcessor && postProcessor->getFbo(PostProcessor::FBO_FirstPerson, frameId)) + { + postProcessor->getFbo(PostProcessor::FBO_FirstPerson, frameId)->apply(*state); - glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - // color accumulation pass - bin->drawImplementation(renderInfo, previous); + glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + // color accumulation pass + bin->drawImplementation(renderInfo, previous); - auto primaryFBO = postProcessor->getPrimaryFbo(frameId); + auto primaryFBO = postProcessor->getPrimaryFbo(frameId); - if (postProcessor->getFbo(PostProcessor::FBO_OpaqueDepth, frameId)) - postProcessor->getFbo(PostProcessor::FBO_OpaqueDepth, frameId)->apply(*state); - else - primaryFBO->apply(*state); + if (postProcessor->getFbo(PostProcessor::FBO_OpaqueDepth, frameId)) + postProcessor->getFbo(PostProcessor::FBO_OpaqueDepth, frameId)->apply(*state); + else + primaryFBO->apply(*state); - // depth accumulation pass - osg::ref_ptr restore = bin->getStateSet(); - bin->setStateSet(mStateSet); - bin->drawImplementation(renderInfo, previous); - bin->setStateSet(restore); + // depth accumulation pass + osg::ref_ptr restore = bin->getStateSet(); + bin->setStateSet(mStateSet); + bin->drawImplementation(renderInfo, previous); + bin->setStateSet(restore); - if (postProcessor->getFbo(PostProcessor::FBO_OpaqueDepth, frameId)) - primaryFBO->apply(*state); - } - else - { - // fallback to standard depth clear when we are not rendering our main scene via an intermediate FBO - glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - bin->drawImplementation(renderInfo, previous); - } + if (postProcessor->getFbo(PostProcessor::FBO_OpaqueDepth, frameId)) + primaryFBO->apply(*state); + } + else + { + // fallback to standard depth clear when we are not rendering our main scene via an intermediate FBO + glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + bin->drawImplementation(renderInfo, previous); + } - state->checkGLErrors("after DepthClearCallback::drawImplementation"); - } + state->checkGLErrors("after DepthClearCallback::drawImplementation"); + } - osg::ref_ptr mDepth; - osg::ref_ptr mStateSet; -}; + osg::ref_ptr mDepth; + osg::ref_ptr mStateSet; + }; -/// Overrides Field of View to given value for rendering the subgraph. -/// Must be added as cull callback. -class OverrideFieldOfViewCallback : public osg::NodeCallback -{ -public: - OverrideFieldOfViewCallback(float fov) - : mFov(fov) + /// Overrides Field of View to given value for rendering the subgraph. + /// Must be added as cull callback. + class OverrideFieldOfViewCallback : public osg::NodeCallback { - } + public: + OverrideFieldOfViewCallback(float fov) + : mFov(fov) + { + } - void operator()(osg::Node* node, osg::NodeVisitor* nv) override - { - osgUtil::CullVisitor* cv = static_cast(nv); - float fov, aspect, zNear, zFar; - if (cv->getProjectionMatrix()->getPerspective(fov, aspect, zNear, zFar) && std::abs(fov-mFov) > 0.001) + void operator()(osg::Node* node, osg::NodeVisitor* nv) override { - fov = mFov; - osg::ref_ptr newProjectionMatrix = new osg::RefMatrix(); - newProjectionMatrix->makePerspective(fov, aspect, zNear, zFar); - osg::ref_ptr invertedOldMatrix = cv->getProjectionMatrix(); - invertedOldMatrix = new osg::RefMatrix(osg::RefMatrix::inverse(*invertedOldMatrix)); - osg::ref_ptr viewMatrix = new osg::RefMatrix(*cv->getModelViewMatrix()); - viewMatrix->postMult(*newProjectionMatrix); - viewMatrix->postMult(*invertedOldMatrix); - cv->pushModelViewMatrix(viewMatrix, osg::Transform::ReferenceFrame::ABSOLUTE_RF); - traverse(node, nv); - cv->popModelViewMatrix(); + osgUtil::CullVisitor* cv = static_cast(nv); + float fov, aspect, zNear, zFar; + if (cv->getProjectionMatrix()->getPerspective(fov, aspect, zNear, zFar) && std::abs(fov - mFov) > 0.001) + { + fov = mFov; + osg::ref_ptr newProjectionMatrix = new osg::RefMatrix(); + newProjectionMatrix->makePerspective(fov, aspect, zNear, zFar); + osg::ref_ptr invertedOldMatrix = cv->getProjectionMatrix(); + invertedOldMatrix = new osg::RefMatrix(osg::RefMatrix::inverse(*invertedOldMatrix)); + osg::ref_ptr viewMatrix = new osg::RefMatrix(*cv->getModelViewMatrix()); + viewMatrix->postMult(*newProjectionMatrix); + viewMatrix->postMult(*invertedOldMatrix); + cv->pushModelViewMatrix(viewMatrix, osg::Transform::ReferenceFrame::ABSOLUTE_RF); + traverse(node, nv); + cv->popModelViewMatrix(); + } + else + traverse(node, nv); } - else - traverse(node, nv); - } -private: - float mFov; -}; + private: + float mFov; + }; -void NpcAnimation::setRenderBin() -{ - if (mViewMode == VM_FirstPerson) + void NpcAnimation::setRenderBin() { - static bool prototypeAdded = false; - if (!prototypeAdded) + if (mViewMode == VM_FirstPerson) { - osg::ref_ptr depthClearBin (new osgUtil::RenderBin); - depthClearBin->setDrawCallback(new DepthClearCallback); - osgUtil::RenderBin::addRenderBinPrototype("DepthClear", depthClearBin); - prototypeAdded = true; + static bool prototypeAdded = false; + if (!prototypeAdded) + { + osg::ref_ptr depthClearBin(new osgUtil::RenderBin); + depthClearBin->setDrawCallback(new DepthClearCallback); + osgUtil::RenderBin::addRenderBinPrototype("DepthClear", depthClearBin); + prototypeAdded = true; + } + mObjectRoot->getOrCreateStateSet()->setRenderBinDetails( + RenderBin_FirstPerson, "DepthClear", osg::StateSet::OVERRIDE_RENDERBIN_DETAILS); } - mObjectRoot->getOrCreateStateSet()->setRenderBinDetails(RenderBin_FirstPerson, "DepthClear", osg::StateSet::OVERRIDE_RENDERBIN_DETAILS); + else if (osg::StateSet* stateset = mObjectRoot->getStateSet()) + stateset->setRenderBinToInherit(); } - else if (osg::StateSet* stateset = mObjectRoot->getStateSet()) - stateset->setRenderBinToInherit(); -} -void NpcAnimation::rebuild() -{ - mScabbard.reset(); - mHolsteredShield.reset(); - updateNpcBase(); + void NpcAnimation::rebuild() + { + mScabbard.reset(); + mHolsteredShield.reset(); + updateNpcBase(); - MWBase::Environment::get().getMechanicsManager()->forceStateUpdate(mPtr); -} + MWBase::Environment::get().getMechanicsManager()->forceStateUpdate(mPtr); + } -int NpcAnimation::getSlot(const osg::NodePath &path) const -{ - for (int i=0; igetNode().get()) != path.end()) + for (int i = 0; i < ESM::PRT_Count; ++i) { - return mPartslots[i]; + const PartHolder* const part = mObjectParts[i].get(); + if (part == nullptr) + continue; + if (std::find(path.begin(), path.end(), part->getNode().get()) != path.end()) + { + return mPartslots[i]; + } } + return -1; } - return -1; -} -void NpcAnimation::updateNpcBase() -{ - clearAnimSources(); - for(size_t i = 0;i < ESM::PRT_Count;i++) - removeIndividualPart((ESM::PartReferenceType)i); + void NpcAnimation::updateNpcBase() + { + clearAnimSources(); + for (size_t i = 0; i < ESM::PRT_Count; i++) + removeIndividualPart((ESM::PartReferenceType)i); - const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); - const ESM::Race *race = store.get().find(mNpc->mRace); - NpcType curType = getNpcType(); - bool isWerewolf = (curType == Type_Werewolf); - bool isVampire = (curType == Type_Vampire); - bool isFemale = !mNpc->isMale(); + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + const ESM::Race* race = store.get().find(mNpc->mRace); + NpcType curType = getNpcType(); + bool isWerewolf = (curType == Type_Werewolf); + bool isVampire = (curType == Type_Vampire); + bool isFemale = !mNpc->isMale(); - mHeadModel.clear(); - mHairModel.clear(); + mHeadModel.clear(); + mHairModel.clear(); - std::string_view headName = isWerewolf ? std::string_view{"WerewolfHead"} : mNpc->mHead; - std::string_view hairName = isWerewolf ? std::string_view{"WerewolfHair"} : mNpc->mHair; + std::string_view headName = isWerewolf ? std::string_view{ "WerewolfHead" } : mNpc->mHead; + std::string_view hairName = isWerewolf ? std::string_view{ "WerewolfHair" } : mNpc->mHair; - if (!headName.empty()) - { - const ESM::BodyPart* bp = store.get().search(headName); - if (bp) - mHeadModel = Misc::ResourceHelpers::correctMeshPath(bp->mModel, mResourceSystem->getVFS()); - else - Log(Debug::Warning) << "Warning: Failed to load body part '" << headName << "'"; - } + if (!headName.empty()) + { + const ESM::BodyPart* bp = store.get().search(headName); + if (bp) + mHeadModel = Misc::ResourceHelpers::correctMeshPath(bp->mModel, mResourceSystem->getVFS()); + else + Log(Debug::Warning) << "Warning: Failed to load body part '" << headName << "'"; + } - if (!hairName.empty()) - { - const ESM::BodyPart* bp = store.get().search(hairName); - if (bp) - mHairModel = Misc::ResourceHelpers::correctMeshPath(bp->mModel, mResourceSystem->getVFS()); - else - Log(Debug::Warning) << "Warning: Failed to load body part '" << hairName << "'"; - } + if (!hairName.empty()) + { + const ESM::BodyPart* bp = store.get().search(hairName); + if (bp) + mHairModel = Misc::ResourceHelpers::correctMeshPath(bp->mModel, mResourceSystem->getVFS()); + else + Log(Debug::Warning) << "Warning: Failed to load body part '" << hairName << "'"; + } - const std::string vampireHead = getVampireHead(mNpc->mRace, isFemale, *mResourceSystem->getVFS()); - if (!isWerewolf && isVampire && !vampireHead.empty()) - mHeadModel = vampireHead; + const std::string vampireHead = getVampireHead(mNpc->mRace, isFemale, *mResourceSystem->getVFS()); + if (!isWerewolf && isVampire && !vampireHead.empty()) + mHeadModel = vampireHead; - bool is1stPerson = mViewMode == VM_FirstPerson; - bool isBeast = (race->mData.mFlags & ESM::Race::Beast) != 0; + bool is1stPerson = mViewMode == VM_FirstPerson; + bool isBeast = (race->mData.mFlags & ESM::Race::Beast) != 0; - std::string defaultSkeleton = SceneUtil::getActorSkeleton(is1stPerson, isFemale, isBeast, isWerewolf); - defaultSkeleton = Misc::ResourceHelpers::correctActorModelPath(defaultSkeleton, mResourceSystem->getVFS()); + std::string defaultSkeleton = SceneUtil::getActorSkeleton(is1stPerson, isFemale, isBeast, isWerewolf); + defaultSkeleton = Misc::ResourceHelpers::correctActorModelPath(defaultSkeleton, mResourceSystem->getVFS()); - std::string smodel = defaultSkeleton; - if (!is1stPerson && !isWerewolf && !mNpc->mModel.empty()) - smodel = Misc::ResourceHelpers::correctActorModelPath( - Misc::ResourceHelpers::correctMeshPath(mNpc->mModel, mResourceSystem->getVFS()), mResourceSystem->getVFS()); + std::string smodel = defaultSkeleton; + if (!is1stPerson && !isWerewolf && !mNpc->mModel.empty()) + smodel = Misc::ResourceHelpers::correctActorModelPath( + Misc::ResourceHelpers::correctMeshPath(mNpc->mModel, mResourceSystem->getVFS()), + mResourceSystem->getVFS()); - setObjectRoot(smodel, true, true, false); + setObjectRoot(smodel, true, true, false); - updateParts(); + updateParts(); - if(!is1stPerson) - { - const std::string& base = Settings::Manager::getString("xbaseanim", "Models"); - if (smodel != base && !isWerewolf) - addAnimSource(base, smodel); + if (!is1stPerson) + { + const std::string& base = Settings::Manager::getString("xbaseanim", "Models"); + if (smodel != base && !isWerewolf) + addAnimSource(base, smodel); - if (smodel != defaultSkeleton && base != defaultSkeleton) - addAnimSource(defaultSkeleton, smodel); + if (smodel != defaultSkeleton && base != defaultSkeleton) + addAnimSource(defaultSkeleton, smodel); - addAnimSource(smodel, smodel); + addAnimSource(smodel, smodel); - if(!isWerewolf && Misc::StringUtils::lowerCase(mNpc->mRace).find("argonian") != std::string::npos) - addAnimSource("meshes\\xargonian_swimkna.nif", smodel); - } - else - { - const std::string& base = Settings::Manager::getString("xbaseanim1st", "Models"); - if (smodel != base && !isWerewolf) - addAnimSource(base, smodel); + if (!isWerewolf && Misc::StringUtils::lowerCase(mNpc->mRace).find("argonian") != std::string::npos) + addAnimSource("meshes\\xargonian_swimkna.nif", smodel); + } + else + { + const std::string& base = Settings::Manager::getString("xbaseanim1st", "Models"); + if (smodel != base && !isWerewolf) + addAnimSource(base, smodel); + + addAnimSource(smodel, smodel); - addAnimSource(smodel, smodel); + mObjectRoot->setNodeMask(Mask_FirstPerson); + mObjectRoot->addCullCallback(new OverrideFieldOfViewCallback(mFirstPersonFieldOfView)); + } - mObjectRoot->setNodeMask(Mask_FirstPerson); - mObjectRoot->addCullCallback(new OverrideFieldOfViewCallback(mFirstPersonFieldOfView)); + mWeaponAnimationTime->updateStartTime(); } - mWeaponAnimationTime->updateStartTime(); -} + std::string NpcAnimation::getSheathedShieldMesh(const MWWorld::ConstPtr& shield) const + { + std::string mesh = getShieldMesh(shield, !mNpc->isMale()); -std::string NpcAnimation::getSheathedShieldMesh(const MWWorld::ConstPtr& shield) const -{ - std::string mesh = getShieldMesh(shield, !mNpc->isMale()); + if (mesh.empty()) + return std::string(); - if (mesh.empty()) - return std::string(); + std::string holsteredName = mesh; + holsteredName = holsteredName.replace(holsteredName.size() - 4, 4, "_sh.nif"); + if (mResourceSystem->getVFS()->exists(holsteredName)) + { + osg::ref_ptr shieldTemplate = mResourceSystem->getSceneManager()->getInstance(holsteredName); + SceneUtil::FindByNameVisitor findVisitor("Bip01 Sheath"); + shieldTemplate->accept(findVisitor); + osg::ref_ptr sheathNode = findVisitor.mFoundNode; + if (!sheathNode) + return std::string(); + } - std::string holsteredName = mesh; - holsteredName = holsteredName.replace(holsteredName.size()-4, 4, "_sh.nif"); - if(mResourceSystem->getVFS()->exists(holsteredName)) - { - osg::ref_ptr shieldTemplate = mResourceSystem->getSceneManager()->getInstance(holsteredName); - SceneUtil::FindByNameVisitor findVisitor ("Bip01 Sheath"); - shieldTemplate->accept(findVisitor); - osg::ref_ptr sheathNode = findVisitor.mFoundNode; - if(!sheathNode) - return std::string(); + return mesh; } - return mesh; -} + void NpcAnimation::updateParts() + { + if (!mObjectRoot.get()) + return; -void NpcAnimation::updateParts() -{ - if (!mObjectRoot.get()) - return; + NpcType curType = getNpcType(); + if (curType != mNpcType) + { + mNpcType = curType; + rebuild(); + return; + } - NpcType curType = getNpcType(); - if (curType != mNpcType) - { - mNpcType = curType; - rebuild(); - return; - } + static const struct + { + int mSlot; + int mBasePriority; + } slotlist[] = { // FIXME: Priority is based on the number of reserved slots. There should be a better way. + { MWWorld::InventoryStore::Slot_Robe, 11 }, { MWWorld::InventoryStore::Slot_Skirt, 3 }, + { MWWorld::InventoryStore::Slot_Helmet, 0 }, { MWWorld::InventoryStore::Slot_Cuirass, 0 }, + { MWWorld::InventoryStore::Slot_Greaves, 0 }, { MWWorld::InventoryStore::Slot_LeftPauldron, 0 }, + { MWWorld::InventoryStore::Slot_RightPauldron, 0 }, { MWWorld::InventoryStore::Slot_Boots, 0 }, + { MWWorld::InventoryStore::Slot_LeftGauntlet, 0 }, { MWWorld::InventoryStore::Slot_RightGauntlet, 0 }, + { MWWorld::InventoryStore::Slot_Shirt, 0 }, { MWWorld::InventoryStore::Slot_Pants, 0 }, + { MWWorld::InventoryStore::Slot_CarriedLeft, 0 }, { MWWorld::InventoryStore::Slot_CarriedRight, 0 } + }; + static const size_t slotlistsize = sizeof(slotlist) / sizeof(slotlist[0]); - static const struct { - int mSlot; - int mBasePriority; - } slotlist[] = { - // FIXME: Priority is based on the number of reserved slots. There should be a better way. - { MWWorld::InventoryStore::Slot_Robe, 11 }, - { MWWorld::InventoryStore::Slot_Skirt, 3 }, - { MWWorld::InventoryStore::Slot_Helmet, 0 }, - { MWWorld::InventoryStore::Slot_Cuirass, 0 }, - { MWWorld::InventoryStore::Slot_Greaves, 0 }, - { MWWorld::InventoryStore::Slot_LeftPauldron, 0 }, - { MWWorld::InventoryStore::Slot_RightPauldron, 0 }, - { MWWorld::InventoryStore::Slot_Boots, 0 }, - { MWWorld::InventoryStore::Slot_LeftGauntlet, 0 }, - { MWWorld::InventoryStore::Slot_RightGauntlet, 0 }, - { MWWorld::InventoryStore::Slot_Shirt, 0 }, - { MWWorld::InventoryStore::Slot_Pants, 0 }, - { MWWorld::InventoryStore::Slot_CarriedLeft, 0 }, - { MWWorld::InventoryStore::Slot_CarriedRight, 0 } - }; - static const size_t slotlistsize = sizeof(slotlist)/sizeof(slotlist[0]); + bool wasArrowAttached = isArrowAttached(); + mAmmunition.reset(); - bool wasArrowAttached = isArrowAttached(); - mAmmunition.reset(); + const MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr); + for (size_t i = 0; i < slotlistsize && mViewMode != VM_HeadOnly; i++) + { + MWWorld::ConstContainerStoreIterator store = inv.getSlot(slotlist[i].mSlot); - const MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr); - for(size_t i = 0;i < slotlistsize && mViewMode != VM_HeadOnly;i++) - { - MWWorld::ConstContainerStoreIterator store = inv.getSlot(slotlist[i].mSlot); + removePartGroup(slotlist[i].mSlot); - removePartGroup(slotlist[i].mSlot); + if (store == inv.end()) + continue; - if(store == inv.end()) - continue; + if (slotlist[i].mSlot == MWWorld::InventoryStore::Slot_Helmet) + removeIndividualPart(ESM::PRT_Hair); - if(slotlist[i].mSlot == MWWorld::InventoryStore::Slot_Helmet) - removeIndividualPart(ESM::PRT_Hair); + int prio = 1; + bool enchantedGlow = !store->getClass().getEnchantment(*store).empty(); + osg::Vec4f glowColor = store->getClass().getEnchantmentColor(*store); + if (store->getType() == ESM::Clothing::sRecordId) + { + prio = ((slotlist[i].mBasePriority + 1) << 1) + 0; + const ESM::Clothing* clothes = store->get()->mBase; + addPartGroup(slotlist[i].mSlot, prio, clothes->mParts.mParts, enchantedGlow, &glowColor); + } + else if (store->getType() == ESM::Armor::sRecordId) + { + prio = ((slotlist[i].mBasePriority + 1) << 1) + 1; + const ESM::Armor* armor = store->get()->mBase; + addPartGroup(slotlist[i].mSlot, prio, armor->mParts.mParts, enchantedGlow, &glowColor); + } - int prio = 1; - bool enchantedGlow = !store->getClass().getEnchantment(*store).empty(); - osg::Vec4f glowColor = store->getClass().getEnchantmentColor(*store); - if(store->getType() == ESM::Clothing::sRecordId) - { - prio = ((slotlist[i].mBasePriority+1)<<1) + 0; - const ESM::Clothing *clothes = store->get()->mBase; - addPartGroup(slotlist[i].mSlot, prio, clothes->mParts.mParts, enchantedGlow, &glowColor); - } - else if(store->getType() == ESM::Armor::sRecordId) - { - prio = ((slotlist[i].mBasePriority+1)<<1) + 1; - const ESM::Armor *armor = store->get()->mBase; - addPartGroup(slotlist[i].mSlot, prio, armor->mParts.mParts, enchantedGlow, &glowColor); + if (slotlist[i].mSlot == MWWorld::InventoryStore::Slot_Robe) + { + ESM::PartReferenceType parts[] = { ESM::PRT_Groin, ESM::PRT_Skirt, ESM::PRT_RLeg, ESM::PRT_LLeg, + ESM::PRT_RUpperarm, ESM::PRT_LUpperarm, ESM::PRT_RKnee, ESM::PRT_LKnee, ESM::PRT_RForearm, + ESM::PRT_LForearm, ESM::PRT_Cuirass }; + size_t parts_size = sizeof(parts) / sizeof(parts[0]); + for (size_t p = 0; p < parts_size; ++p) + reserveIndividualPart(parts[p], slotlist[i].mSlot, prio); + } + else if (slotlist[i].mSlot == MWWorld::InventoryStore::Slot_Skirt) + { + reserveIndividualPart(ESM::PRT_Groin, slotlist[i].mSlot, prio); + reserveIndividualPart(ESM::PRT_RLeg, slotlist[i].mSlot, prio); + reserveIndividualPart(ESM::PRT_LLeg, slotlist[i].mSlot, prio); + } } - if(slotlist[i].mSlot == MWWorld::InventoryStore::Slot_Robe) + if (mViewMode != VM_FirstPerson) { - ESM::PartReferenceType parts[] = { - ESM::PRT_Groin, ESM::PRT_Skirt, ESM::PRT_RLeg, ESM::PRT_LLeg, - ESM::PRT_RUpperarm, ESM::PRT_LUpperarm, ESM::PRT_RKnee, ESM::PRT_LKnee, - ESM::PRT_RForearm, ESM::PRT_LForearm, ESM::PRT_Cuirass - }; - size_t parts_size = sizeof(parts)/sizeof(parts[0]); - for(size_t p = 0;p < parts_size;++p) - reserveIndividualPart(parts[p], slotlist[i].mSlot, prio); + if (mPartPriorities[ESM::PRT_Head] < 1 && !mHeadModel.empty()) + addOrReplaceIndividualPart(ESM::PRT_Head, -1, 1, mHeadModel); + if (mPartPriorities[ESM::PRT_Hair] < 1 && mPartPriorities[ESM::PRT_Head] <= 1 && !mHairModel.empty()) + addOrReplaceIndividualPart(ESM::PRT_Hair, -1, 1, mHairModel); } - else if(slotlist[i].mSlot == MWWorld::InventoryStore::Slot_Skirt) - { - reserveIndividualPart(ESM::PRT_Groin, slotlist[i].mSlot, prio); - reserveIndividualPart(ESM::PRT_RLeg, slotlist[i].mSlot, prio); - reserveIndividualPart(ESM::PRT_LLeg, slotlist[i].mSlot, prio); - } - } + if (mViewMode == VM_HeadOnly) + return; - if(mViewMode != VM_FirstPerson) - { - if(mPartPriorities[ESM::PRT_Head] < 1 && !mHeadModel.empty()) - addOrReplaceIndividualPart(ESM::PRT_Head, -1,1, mHeadModel); - if(mPartPriorities[ESM::PRT_Hair] < 1 && mPartPriorities[ESM::PRT_Head] <= 1 && !mHairModel.empty()) - addOrReplaceIndividualPart(ESM::PRT_Hair, -1,1, mHairModel); - } - if(mViewMode == VM_HeadOnly) - return; - - if(mPartPriorities[ESM::PRT_Shield] < 1) - { - MWWorld::ConstContainerStoreIterator store = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); - MWWorld::ConstPtr part; - if(store != inv.end() && (part=*store).getType() == ESM::Light::sRecordId) + if (mPartPriorities[ESM::PRT_Shield] < 1) { - const ESM::Light *light = part.get()->mBase; - const VFS::Manager* const vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); - addOrReplaceIndividualPart(ESM::PRT_Shield, MWWorld::InventoryStore::Slot_CarriedLeft, 1, - Misc::ResourceHelpers::correctMeshPath(light->mModel, vfs), false, nullptr, true); - if (mObjectParts[ESM::PRT_Shield]) - addExtraLight(mObjectParts[ESM::PRT_Shield]->getNode()->asGroup(), light); + MWWorld::ConstContainerStoreIterator store = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); + MWWorld::ConstPtr part; + if (store != inv.end() && (part = *store).getType() == ESM::Light::sRecordId) + { + const ESM::Light* light = part.get()->mBase; + const VFS::Manager* const vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); + addOrReplaceIndividualPart(ESM::PRT_Shield, MWWorld::InventoryStore::Slot_CarriedLeft, 1, + Misc::ResourceHelpers::correctMeshPath(light->mModel, vfs), false, nullptr, true); + if (mObjectParts[ESM::PRT_Shield]) + addExtraLight(mObjectParts[ESM::PRT_Shield]->getNode()->asGroup(), light); + } } - } - showWeapons(mShowWeapons); - showCarriedLeft(mShowCarriedLeft); + showWeapons(mShowWeapons); + showCarriedLeft(mShowCarriedLeft); - bool isWerewolf = (getNpcType() == Type_Werewolf); - std::string race = (isWerewolf ? "werewolf" : Misc::StringUtils::lowerCase(mNpc->mRace)); + bool isWerewolf = (getNpcType() == Type_Werewolf); + std::string race = (isWerewolf ? "werewolf" : Misc::StringUtils::lowerCase(mNpc->mRace)); - const std::vector &parts = getBodyParts(race, !mNpc->isMale(), mViewMode == VM_FirstPerson, isWerewolf); - for(int part = ESM::PRT_Neck; part < ESM::PRT_Count; ++part) - { - if(mPartPriorities[part] < 1) + const std::vector& parts + = getBodyParts(race, !mNpc->isMale(), mViewMode == VM_FirstPerson, isWerewolf); + for (int part = ESM::PRT_Neck; part < ESM::PRT_Count; ++part) { - const ESM::BodyPart* bodypart = parts[part]; - if(bodypart) + if (mPartPriorities[part] < 1) { - const VFS::Manager* const vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); - addOrReplaceIndividualPart(static_cast(part), -1, 1, - Misc::ResourceHelpers::correctMeshPath(bodypart->mModel, vfs)); + const ESM::BodyPart* bodypart = parts[part]; + if (bodypart) + { + const VFS::Manager* const vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); + addOrReplaceIndividualPart(static_cast(part), -1, 1, + Misc::ResourceHelpers::correctMeshPath(bodypart->mModel, vfs)); + } } } - } - if (wasArrowAttached) - attachArrow(); -} + if (wasArrowAttached) + attachArrow(); + } + PartHolderPtr NpcAnimation::insertBoundedPart(const std::string& model, std::string_view bonename, + std::string_view bonefilter, bool enchantedGlow, osg::Vec4f* glowColor, bool isLight) + { + osg::ref_ptr attached = attach(model, bonename, bonefilter, isLight); + if (enchantedGlow) + mGlowUpdater = SceneUtil::addEnchantedGlow(attached, mResourceSystem, *glowColor); + return std::make_unique(attached); + } -PartHolderPtr NpcAnimation::insertBoundedPart(const std::string& model, std::string_view bonename, std::string_view bonefilter, bool enchantedGlow, osg::Vec4f* glowColor, bool isLight) -{ - osg::ref_ptr attached = attach(model, bonename, bonefilter, isLight); - if (enchantedGlow) - mGlowUpdater = SceneUtil::addEnchantedGlow(attached, mResourceSystem, *glowColor); + osg::Vec3f NpcAnimation::runAnimation(float timepassed) + { + osg::Vec3f ret = Animation::runAnimation(timepassed); - return std::make_unique(attached); -} + mHeadAnimationTime->update(timepassed); -osg::Vec3f NpcAnimation::runAnimation(float timepassed) -{ - osg::Vec3f ret = Animation::runAnimation(timepassed); + if (mFirstPersonNeckController) + { + if (mAccurateAiming) + mAimingFactor = 1.f; + else + mAimingFactor = std::max(0.f, mAimingFactor - timepassed * 0.5f); - mHeadAnimationTime->update(timepassed); + float rotateFactor = 0.75f + 0.25f * mAimingFactor; - if (mFirstPersonNeckController) - { - if (mAccurateAiming) - mAimingFactor = 1.f; - else - mAimingFactor = std::max(0.f, mAimingFactor - timepassed * 0.5f); + mFirstPersonNeckController->setRotate( + osg::Quat(mPtr.getRefData().getPosition().rot[0] * rotateFactor, osg::Vec3f(-1, 0, 0))); + mFirstPersonNeckController->setOffset(mFirstPersonOffset); + } - float rotateFactor = 0.75f + 0.25f * mAimingFactor; + WeaponAnimation::configureControllers(mPtr.getRefData().getPosition().rot[0] + getBodyPitchRadians()); - mFirstPersonNeckController->setRotate(osg::Quat(mPtr.getRefData().getPosition().rot[0] * rotateFactor, osg::Vec3f(-1,0,0))); - mFirstPersonNeckController->setOffset(mFirstPersonOffset); + return ret; } - WeaponAnimation::configureControllers(mPtr.getRefData().getPosition().rot[0] + getBodyPitchRadians()); - - return ret; -} + void NpcAnimation::removeIndividualPart(ESM::PartReferenceType type) + { + mPartPriorities[type] = 0; + mPartslots[type] = -1; -void NpcAnimation::removeIndividualPart(ESM::PartReferenceType type) -{ - mPartPriorities[type] = 0; - mPartslots[type] = -1; + mObjectParts[type].reset(); + if (mSounds[type] != nullptr && !mSoundsDisabled) + { + MWBase::Environment::get().getSoundManager()->stopSound(mSounds[type]); + mSounds[type] = nullptr; + } + } - mObjectParts[type].reset(); - if (mSounds[type] != nullptr && !mSoundsDisabled) + void NpcAnimation::reserveIndividualPart(ESM::PartReferenceType type, int group, int priority) { - MWBase::Environment::get().getSoundManager()->stopSound(mSounds[type]); - mSounds[type] = nullptr; + if (priority > mPartPriorities[type]) + { + removeIndividualPart(type); + mPartPriorities[type] = priority; + mPartslots[type] = group; + } } -} -void NpcAnimation::reserveIndividualPart(ESM::PartReferenceType type, int group, int priority) -{ - if(priority > mPartPriorities[type]) + void NpcAnimation::removePartGroup(int group) { - removeIndividualPart(type); - mPartPriorities[type] = priority; - mPartslots[type] = group; + for (int i = 0; i < ESM::PRT_Count; i++) + { + if (mPartslots[i] == group) + removeIndividualPart((ESM::PartReferenceType)i); + } } -} -void NpcAnimation::removePartGroup(int group) -{ - for(int i = 0; i < ESM::PRT_Count; i++) + bool NpcAnimation::isFirstPersonPart(const ESM::BodyPart* bodypart) { - if(mPartslots[i] == group) - removeIndividualPart((ESM::PartReferenceType)i); + return bodypart->mId.size() >= 3 && bodypart->mId.substr(bodypart->mId.size() - 3, 3) == "1st"; } -} - -bool NpcAnimation::isFirstPersonPart(const ESM::BodyPart* bodypart) -{ - return bodypart->mId.size() >= 3 && bodypart->mId.substr(bodypart->mId.size()-3, 3) == "1st"; -} - -bool NpcAnimation::isFemalePart(const ESM::BodyPart* bodypart) -{ - return bodypart->mData.mFlags & ESM::BodyPart::BPF_Female; -} -bool NpcAnimation::addOrReplaceIndividualPart(ESM::PartReferenceType type, int group, int priority, const std::string &mesh, bool enchantedGlow, osg::Vec4f* glowColor, bool isLight) -{ - if(priority <= mPartPriorities[type]) - return false; + bool NpcAnimation::isFemalePart(const ESM::BodyPart* bodypart) + { + return bodypart->mData.mFlags & ESM::BodyPart::BPF_Female; + } - removeIndividualPart(type); - mPartslots[type] = group; - mPartPriorities[type] = priority; - try + bool NpcAnimation::addOrReplaceIndividualPart(ESM::PartReferenceType type, int group, int priority, + const std::string& mesh, bool enchantedGlow, osg::Vec4f* glowColor, bool isLight) { - std::string_view bonename = sPartList.at(type); - if (type == ESM::PRT_Weapon) + if (priority <= mPartPriorities[type]) + return false; + + removeIndividualPart(type); + mPartslots[type] = group; + mPartPriorities[type] = priority; + try { - const MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr); - MWWorld::ConstContainerStoreIterator weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); - if(weapon != inv.end() && weapon->getType() == ESM::Weapon::sRecordId) + std::string_view bonename = sPartList.at(type); + if (type == ESM::PRT_Weapon) { - int weaponType = weapon->get()->mBase->mData.mType; - const std::string& weaponBonename = MWMechanics::getWeaponType(weaponType)->mAttachBone; - - if (weaponBonename != bonename) + const MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr); + MWWorld::ConstContainerStoreIterator weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); + if (weapon != inv.end() && weapon->getType() == ESM::Weapon::sRecordId) { - const NodeMap& nodeMap = getNodeMap(); - NodeMap::const_iterator found = nodeMap.find(weaponBonename); - if (found != nodeMap.end()) - bonename = weaponBonename; + int weaponType = weapon->get()->mBase->mData.mType; + const std::string& weaponBonename = MWMechanics::getWeaponType(weaponType)->mAttachBone; + + if (weaponBonename != bonename) + { + const NodeMap& nodeMap = getNodeMap(); + NodeMap::const_iterator found = nodeMap.find(weaponBonename); + if (found != nodeMap.end()) + bonename = weaponBonename; + } } } - } - // PRT_Hair seems to be the only type that breaks consistency and uses a filter that's different from the attachment bone - const std::string_view bonefilter = (type == ESM::PRT_Hair) ? std::string_view{"hair"} : bonename; - mObjectParts[type] = insertBoundedPart(mesh, bonename, bonefilter, enchantedGlow, glowColor, isLight); - } - catch (std::exception& e) - { - Log(Debug::Error) << "Error adding NPC part: " << e.what(); - return false; - } + // PRT_Hair seems to be the only type that breaks consistency and uses a filter that's different from the + // attachment bone + const std::string_view bonefilter = (type == ESM::PRT_Hair) ? std::string_view{ "hair" } : bonename; + mObjectParts[type] = insertBoundedPart(mesh, bonename, bonefilter, enchantedGlow, glowColor, isLight); + } + catch (std::exception& e) + { + Log(Debug::Error) << "Error adding NPC part: " << e.what(); + return false; + } - if (!mSoundsDisabled && group == MWWorld::InventoryStore::Slot_CarriedLeft) - { - const MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr); - MWWorld::ConstContainerStoreIterator csi = inv.getSlot(group); - if (csi != inv.end()) + if (!mSoundsDisabled && group == MWWorld::InventoryStore::Slot_CarriedLeft) { - const auto soundId = csi->getClass().getSound(*csi); - if (!soundId.empty()) + const MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr); + MWWorld::ConstContainerStoreIterator csi = inv.getSlot(group); + if (csi != inv.end()) { - mSounds[type] = MWBase::Environment::get().getSoundManager()->playSound3D(mPtr, soundId, - 1.0f, 1.0f, MWSound::Type::Sfx, MWSound::PlayMode::Loop - ); + const auto soundId = csi->getClass().getSound(*csi); + if (!soundId.empty()) + { + mSounds[type] = MWBase::Environment::get().getSoundManager()->playSound3D( + mPtr, soundId, 1.0f, 1.0f, MWSound::Type::Sfx, MWSound::PlayMode::Loop); + } } } - } - osg::Node* node = mObjectParts[type]->getNode(); - if (node->getNumChildrenRequiringUpdateTraversal() > 0) - { - std::shared_ptr src; - if (type == ESM::PRT_Head) + osg::Node* node = mObjectParts[type]->getNode(); + if (node->getNumChildrenRequiringUpdateTraversal() > 0) { - src = mHeadAnimationTime; - - if (node->getUserDataContainer()) + std::shared_ptr src; + if (type == ESM::PRT_Head) { - for (unsigned int i=0; igetUserDataContainer()->getNumUserObjects(); ++i) + src = mHeadAnimationTime; + + if (node->getUserDataContainer()) { - osg::Object* obj = node->getUserDataContainer()->getUserObject(i); - if (SceneUtil::TextKeyMapHolder* keys = dynamic_cast(obj)) + for (unsigned int i = 0; i < node->getUserDataContainer()->getNumUserObjects(); ++i) { - for (const auto &key : keys->mTextKeys) + osg::Object* obj = node->getUserDataContainer()->getUserObject(i); + if (SceneUtil::TextKeyMapHolder* keys = dynamic_cast(obj)) { - if (Misc::StringUtils::ciEqual(key.second, "talk: start")) - mHeadAnimationTime->setTalkStart(key.first); - if (Misc::StringUtils::ciEqual(key.second, "talk: stop")) - mHeadAnimationTime->setTalkStop(key.first); - if (Misc::StringUtils::ciEqual(key.second, "blink: start")) - mHeadAnimationTime->setBlinkStart(key.first); - if (Misc::StringUtils::ciEqual(key.second, "blink: stop")) - mHeadAnimationTime->setBlinkStop(key.first); + for (const auto& key : keys->mTextKeys) + { + if (Misc::StringUtils::ciEqual(key.second, "talk: start")) + mHeadAnimationTime->setTalkStart(key.first); + if (Misc::StringUtils::ciEqual(key.second, "talk: stop")) + mHeadAnimationTime->setTalkStop(key.first); + if (Misc::StringUtils::ciEqual(key.second, "blink: start")) + mHeadAnimationTime->setBlinkStart(key.first); + if (Misc::StringUtils::ciEqual(key.second, "blink: stop")) + mHeadAnimationTime->setBlinkStop(key.first); + } + + break; } - - break; } } + SceneUtil::ForceControllerSourcesVisitor assignVisitor(src); + node->accept(assignVisitor); } - SceneUtil::ForceControllerSourcesVisitor assignVisitor(src); - node->accept(assignVisitor); - } - else - { - if (type == ESM::PRT_Weapon) - src = mWeaponAnimationTime; else - src = std::make_shared(); - SceneUtil::AssignControllerSourcesVisitor assignVisitor(src); - node->accept(assignVisitor); + { + if (type == ESM::PRT_Weapon) + src = mWeaponAnimationTime; + else + src = std::make_shared(); + SceneUtil::AssignControllerSourcesVisitor assignVisitor(src); + node->accept(assignVisitor); + } } - } - return true; -} - -void NpcAnimation::addPartGroup(int group, int priority, const std::vector &parts, bool enchantedGlow, osg::Vec4f* glowColor) -{ - const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); - const MWWorld::Store &partStore = store.get(); + return true; + } - const char *ext = (mViewMode == VM_FirstPerson) ? ".1st" : ""; - for(const ESM::PartReference& part : parts) + void NpcAnimation::addPartGroup(int group, int priority, const std::vector& parts, + bool enchantedGlow, osg::Vec4f* glowColor) { - const ESM::BodyPart *bodypart = nullptr; - if(!mNpc->isMale() && !part.mFemale.empty()) + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + const MWWorld::Store& partStore = store.get(); + + const char* ext = (mViewMode == VM_FirstPerson) ? ".1st" : ""; + for (const ESM::PartReference& part : parts) { - bodypart = partStore.search(part.mFemale+ext); - if(!bodypart && mViewMode == VM_FirstPerson) + const ESM::BodyPart* bodypart = nullptr; + if (!mNpc->isMale() && !part.mFemale.empty()) { - bodypart = partStore.search(part.mFemale); - if(bodypart && !(bodypart->mData.mPart == ESM::BodyPart::MP_Hand || - bodypart->mData.mPart == ESM::BodyPart::MP_Wrist || - bodypart->mData.mPart == ESM::BodyPart::MP_Forearm || - bodypart->mData.mPart == ESM::BodyPart::MP_Upperarm)) - bodypart = nullptr; + bodypart = partStore.search(part.mFemale + ext); + if (!bodypart && mViewMode == VM_FirstPerson) + { + bodypart = partStore.search(part.mFemale); + if (bodypart + && !(bodypart->mData.mPart == ESM::BodyPart::MP_Hand + || bodypart->mData.mPart == ESM::BodyPart::MP_Wrist + || bodypart->mData.mPart == ESM::BodyPart::MP_Forearm + || bodypart->mData.mPart == ESM::BodyPart::MP_Upperarm)) + bodypart = nullptr; + } + else if (!bodypart) + Log(Debug::Warning) << "Warning: Failed to find body part '" << part.mFemale << "'"; } - else if (!bodypart) - Log(Debug::Warning) << "Warning: Failed to find body part '" << part.mFemale << "'"; - } - if(!bodypart && !part.mMale.empty()) - { - bodypart = partStore.search(part.mMale+ext); - if(!bodypart && mViewMode == VM_FirstPerson) + if (!bodypart && !part.mMale.empty()) { - bodypart = partStore.search(part.mMale); - if(bodypart && !(bodypart->mData.mPart == ESM::BodyPart::MP_Hand || - bodypart->mData.mPart == ESM::BodyPart::MP_Wrist || - bodypart->mData.mPart == ESM::BodyPart::MP_Forearm || - bodypart->mData.mPart == ESM::BodyPart::MP_Upperarm)) - bodypart = nullptr; + bodypart = partStore.search(part.mMale + ext); + if (!bodypart && mViewMode == VM_FirstPerson) + { + bodypart = partStore.search(part.mMale); + if (bodypart + && !(bodypart->mData.mPart == ESM::BodyPart::MP_Hand + || bodypart->mData.mPart == ESM::BodyPart::MP_Wrist + || bodypart->mData.mPart == ESM::BodyPart::MP_Forearm + || bodypart->mData.mPart == ESM::BodyPart::MP_Upperarm)) + bodypart = nullptr; + } + else if (!bodypart) + Log(Debug::Warning) << "Warning: Failed to find body part '" << part.mMale << "'"; } - else if (!bodypart) - Log(Debug::Warning) << "Warning: Failed to find body part '" << part.mMale << "'"; - } - if(bodypart) - { - const VFS::Manager* const vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); - addOrReplaceIndividualPart(static_cast(part.mPart), group, priority, - Misc::ResourceHelpers::correctMeshPath(bodypart->mModel, vfs), enchantedGlow, glowColor); + if (bodypart) + { + const VFS::Manager* const vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); + addOrReplaceIndividualPart(static_cast(part.mPart), group, priority, + Misc::ResourceHelpers::correctMeshPath(bodypart->mModel, vfs), enchantedGlow, glowColor); + } + else + reserveIndividualPart((ESM::PartReferenceType)part.mPart, group, priority); } - else - reserveIndividualPart((ESM::PartReferenceType)part.mPart, group, priority); } -} -void NpcAnimation::addControllers() -{ - Animation::addControllers(); + void NpcAnimation::addControllers() + { + Animation::addControllers(); - mFirstPersonNeckController = nullptr; - WeaponAnimation::deleteControllers(); + mFirstPersonNeckController = nullptr; + WeaponAnimation::deleteControllers(); - if (mViewMode == VM_FirstPerson) - { - NodeMap::iterator found = mNodeMap.find("bip01 neck"); - if (found != mNodeMap.end()) + if (mViewMode == VM_FirstPerson) { - osg::MatrixTransform* node = found->second.get(); - mFirstPersonNeckController = new RotateController(mObjectRoot.get()); - node->addUpdateCallback(mFirstPersonNeckController); - mActiveControllers.emplace_back(node, mFirstPersonNeckController); + NodeMap::iterator found = mNodeMap.find("bip01 neck"); + if (found != mNodeMap.end()) + { + osg::MatrixTransform* node = found->second.get(); + mFirstPersonNeckController = new RotateController(mObjectRoot.get()); + node->addUpdateCallback(mFirstPersonNeckController); + mActiveControllers.emplace_back(node, mFirstPersonNeckController); + } + } + else if (mViewMode == VM_Normal) + { + WeaponAnimation::addControllers(mNodeMap, mActiveControllers, mObjectRoot.get()); } } - else if (mViewMode == VM_Normal) - { - WeaponAnimation::addControllers(mNodeMap, mActiveControllers, mObjectRoot.get()); - } -} -void NpcAnimation::showWeapons(bool showWeapon) -{ - mShowWeapons = showWeapon; - mAmmunition.reset(); - if(showWeapon) + void NpcAnimation::showWeapons(bool showWeapon) { - const MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr); - MWWorld::ConstContainerStoreIterator weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); - if(weapon != inv.end()) + mShowWeapons = showWeapon; + mAmmunition.reset(); + if (showWeapon) { - osg::Vec4f glowColor = weapon->getClass().getEnchantmentColor(*weapon); - std::string mesh = weapon->getClass().getModel(*weapon); - addOrReplaceIndividualPart(ESM::PRT_Weapon, MWWorld::InventoryStore::Slot_CarriedRight, 1, - mesh, !weapon->getClass().getEnchantment(*weapon).empty(), &glowColor); - - // Crossbows start out with a bolt attached - if (weapon->getType() == ESM::Weapon::sRecordId && - weapon->get()->mBase->mData.mType == ESM::Weapon::MarksmanCrossbow) + const MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr); + MWWorld::ConstContainerStoreIterator weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); + if (weapon != inv.end()) { - int ammotype = MWMechanics::getWeaponType(ESM::Weapon::MarksmanCrossbow)->mAmmoType; - MWWorld::ConstContainerStoreIterator ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition); - if (ammo != inv.end() && ammo->get()->mBase->mData.mType == ammotype) - attachArrow(); + osg::Vec4f glowColor = weapon->getClass().getEnchantmentColor(*weapon); + std::string mesh = weapon->getClass().getModel(*weapon); + addOrReplaceIndividualPart(ESM::PRT_Weapon, MWWorld::InventoryStore::Slot_CarriedRight, 1, mesh, + !weapon->getClass().getEnchantment(*weapon).empty(), &glowColor); + + // Crossbows start out with a bolt attached + if (weapon->getType() == ESM::Weapon::sRecordId + && weapon->get()->mBase->mData.mType == ESM::Weapon::MarksmanCrossbow) + { + int ammotype = MWMechanics::getWeaponType(ESM::Weapon::MarksmanCrossbow)->mAmmoType; + MWWorld::ConstContainerStoreIterator ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition); + if (ammo != inv.end() && ammo->get()->mBase->mData.mType == ammotype) + attachArrow(); + } } } - } - else - { - removeIndividualPart(ESM::PRT_Weapon); - // If we remove/hide weapon from player, we should reset attack animation as well - if (mPtr == MWMechanics::getPlayer()) - mPtr.getClass().getCreatureStats(mPtr).setAttackingOrSpell(false); - } + else + { + removeIndividualPart(ESM::PRT_Weapon); + // If we remove/hide weapon from player, we should reset attack animation as well + if (mPtr == MWMechanics::getPlayer()) + mPtr.getClass().getCreatureStats(mPtr).setAttackingOrSpell(false); + } - updateHolsteredWeapon(!mShowWeapons); - updateQuiver(); -} + updateHolsteredWeapon(!mShowWeapons); + updateQuiver(); + } -bool NpcAnimation::updateCarriedLeftVisible(const int weaptype) const -{ - static const bool shieldSheathing = Settings::Manager::getBool("shield sheathing", "Game"); - if (shieldSheathing) + bool NpcAnimation::updateCarriedLeftVisible(const int weaptype) const { - const MWWorld::Class &cls = mPtr.getClass(); - MWMechanics::CreatureStats &stats = cls.getCreatureStats(mPtr); - if (stats.getDrawState() == MWMechanics::DrawState::Nothing) + static const bool shieldSheathing = Settings::Manager::getBool("shield sheathing", "Game"); + if (shieldSheathing) { - SceneUtil::FindByNameVisitor findVisitor ("Bip01 AttachShield"); - mObjectRoot->accept(findVisitor); - if (findVisitor.mFoundNode || mViewMode == VM_FirstPerson) + const MWWorld::Class& cls = mPtr.getClass(); + MWMechanics::CreatureStats& stats = cls.getCreatureStats(mPtr); + if (stats.getDrawState() == MWMechanics::DrawState::Nothing) { - const MWWorld::InventoryStore& inv = cls.getInventoryStore(mPtr); - const MWWorld::ConstContainerStoreIterator shield = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); - if (shield != inv.end() && shield->getType() == ESM::Armor::sRecordId && !getSheathedShieldMesh(*shield).empty()) - return false; + SceneUtil::FindByNameVisitor findVisitor("Bip01 AttachShield"); + mObjectRoot->accept(findVisitor); + if (findVisitor.mFoundNode || mViewMode == VM_FirstPerson) + { + const MWWorld::InventoryStore& inv = cls.getInventoryStore(mPtr); + const MWWorld::ConstContainerStoreIterator shield + = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); + if (shield != inv.end() && shield->getType() == ESM::Armor::sRecordId + && !getSheathedShieldMesh(*shield).empty()) + return false; + } } } - } - return !(MWMechanics::getWeaponType(weaptype)->mFlags & ESM::WeaponType::TwoHanded); -} + return !(MWMechanics::getWeaponType(weaptype)->mFlags & ESM::WeaponType::TwoHanded); + } -void NpcAnimation::showCarriedLeft(bool show) -{ - mShowCarriedLeft = show; - const MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr); - MWWorld::ConstContainerStoreIterator iter = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); - if(show && iter != inv.end()) + void NpcAnimation::showCarriedLeft(bool show) { - osg::Vec4f glowColor = iter->getClass().getEnchantmentColor(*iter); - std::string mesh = iter->getClass().getModel(*iter); - // For shields we must try to use the body part model - if (iter->getType() == ESM::Armor::sRecordId) + mShowCarriedLeft = show; + const MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr); + MWWorld::ConstContainerStoreIterator iter = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); + if (show && iter != inv.end()) { - mesh = getShieldMesh(*iter, !mNpc->isMale()); + osg::Vec4f glowColor = iter->getClass().getEnchantmentColor(*iter); + std::string mesh = iter->getClass().getModel(*iter); + // For shields we must try to use the body part model + if (iter->getType() == ESM::Armor::sRecordId) + { + mesh = getShieldMesh(*iter, !mNpc->isMale()); + } + if (mesh.empty() + || addOrReplaceIndividualPart(ESM::PRT_Shield, MWWorld::InventoryStore::Slot_CarriedLeft, 1, mesh, + !iter->getClass().getEnchantment(*iter).empty(), &glowColor, + iter->getType() == ESM::Light::sRecordId)) + { + if (mesh.empty()) + reserveIndividualPart(ESM::PRT_Shield, MWWorld::InventoryStore::Slot_CarriedLeft, 1); + if (iter->getType() == ESM::Light::sRecordId && mObjectParts[ESM::PRT_Shield]) + addExtraLight(mObjectParts[ESM::PRT_Shield]->getNode()->asGroup(), iter->get()->mBase); + } } - if (mesh.empty() || addOrReplaceIndividualPart(ESM::PRT_Shield, MWWorld::InventoryStore::Slot_CarriedLeft, 1, - mesh, !iter->getClass().getEnchantment(*iter).empty(), &glowColor, iter->getType() == ESM::Light::sRecordId)) + else + removeIndividualPart(ESM::PRT_Shield); + + updateHolsteredShield(mShowCarriedLeft); + } + + void NpcAnimation::attachArrow() + { + WeaponAnimation::attachArrow(mPtr); + + const MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr); + MWWorld::ConstContainerStoreIterator ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition); + if (ammo != inv.end() && !ammo->getClass().getEnchantment(*ammo).empty()) { - if (mesh.empty()) - reserveIndividualPart(ESM::PRT_Shield, MWWorld::InventoryStore::Slot_CarriedLeft, 1); - if (iter->getType() == ESM::Light::sRecordId && mObjectParts[ESM::PRT_Shield]) - addExtraLight(mObjectParts[ESM::PRT_Shield]->getNode()->asGroup(), iter->get()->mBase); + osg::Group* bone = getArrowBone(); + if (bone != nullptr && bone->getNumChildren()) + SceneUtil::addEnchantedGlow( + bone->getChild(0), mResourceSystem, ammo->getClass().getEnchantmentColor(*ammo)); } - } - else - removeIndividualPart(ESM::PRT_Shield); - updateHolsteredShield(mShowCarriedLeft); -} + updateQuiver(); + } -void NpcAnimation::attachArrow() -{ - WeaponAnimation::attachArrow(mPtr); + void NpcAnimation::detachArrow() + { + WeaponAnimation::detachArrow(mPtr); + updateQuiver(); + } - const MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr); - MWWorld::ConstContainerStoreIterator ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition); - if (ammo != inv.end() && !ammo->getClass().getEnchantment(*ammo).empty()) + void NpcAnimation::releaseArrow(float attackStrength) { - osg::Group* bone = getArrowBone(); - if (bone != nullptr && bone->getNumChildren()) - SceneUtil::addEnchantedGlow(bone->getChild(0), mResourceSystem, ammo->getClass().getEnchantmentColor(*ammo)); + WeaponAnimation::releaseArrow(mPtr, attackStrength); + updateQuiver(); } - updateQuiver(); -} + osg::Group* NpcAnimation::getArrowBone() + { + const PartHolder* const part = mObjectParts[ESM::PRT_Weapon].get(); + if (part == nullptr) + return nullptr; -void NpcAnimation::detachArrow() -{ - WeaponAnimation::detachArrow(mPtr); - updateQuiver(); -} + const MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr); + MWWorld::ConstContainerStoreIterator weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); + if (weapon == inv.end() || weapon->getType() != ESM::Weapon::sRecordId) + return nullptr; -void NpcAnimation::releaseArrow(float attackStrength) -{ - WeaponAnimation::releaseArrow(mPtr, attackStrength); - updateQuiver(); -} + int type = weapon->get()->mBase->mData.mType; + int ammoType = MWMechanics::getWeaponType(type)->mAmmoType; + if (ammoType == ESM::Weapon::None) + return nullptr; -osg::Group* NpcAnimation::getArrowBone() -{ - const PartHolder* const part = mObjectParts[ESM::PRT_Weapon].get(); - if (part == nullptr) - return nullptr; - - const MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr); - MWWorld::ConstContainerStoreIterator weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); - if(weapon == inv.end() || weapon->getType() != ESM::Weapon::sRecordId) - return nullptr; - - int type = weapon->get()->mBase->mData.mType; - int ammoType = MWMechanics::getWeaponType(type)->mAmmoType; - if (ammoType == ESM::Weapon::None) - return nullptr; - - // Try to find and attachment bone in actor's skeleton, otherwise fall back to the ArrowBone in weapon's mesh - osg::Group* bone = getBoneByName(MWMechanics::getWeaponType(ammoType)->mAttachBone); - if (bone == nullptr) - { - SceneUtil::FindByNameVisitor findVisitor ("ArrowBone"); - part->getNode()->accept(findVisitor); - bone = findVisitor.mFoundNode; + // Try to find and attachment bone in actor's skeleton, otherwise fall back to the ArrowBone in weapon's mesh + osg::Group* bone = getBoneByName(MWMechanics::getWeaponType(ammoType)->mAttachBone); + if (bone == nullptr) + { + SceneUtil::FindByNameVisitor findVisitor("ArrowBone"); + part->getNode()->accept(findVisitor); + bone = findVisitor.mFoundNode; + } + return bone; } - return bone; -} - -osg::Node* NpcAnimation::getWeaponNode() -{ - const PartHolder* const part = mObjectParts[ESM::PRT_Weapon].get(); - if (part == nullptr) - return nullptr; - return part->getNode(); -} -Resource::ResourceSystem* NpcAnimation::getResourceSystem() -{ - return mResourceSystem; -} + osg::Node* NpcAnimation::getWeaponNode() + { + const PartHolder* const part = mObjectParts[ESM::PRT_Weapon].get(); + if (part == nullptr) + return nullptr; + return part->getNode(); + } -void NpcAnimation::enableHeadAnimation(bool enable) -{ - mHeadAnimationTime->setEnabled(enable); -} + Resource::ResourceSystem* NpcAnimation::getResourceSystem() + { + return mResourceSystem; + } -void NpcAnimation::setWeaponGroup(const std::string &group, bool relativeDuration) -{ - mWeaponAnimationTime->setGroup(group, relativeDuration); -} + void NpcAnimation::enableHeadAnimation(bool enable) + { + mHeadAnimationTime->setEnabled(enable); + } -void NpcAnimation::equipmentChanged() -{ - static const bool shieldSheathing = Settings::Manager::getBool("shield sheathing", "Game"); - if (shieldSheathing) + void NpcAnimation::setWeaponGroup(const std::string& group, bool relativeDuration) { - int weaptype = ESM::Weapon::None; - MWMechanics::getActiveWeapon(mPtr, &weaptype); - showCarriedLeft(updateCarriedLeftVisible(weaptype)); + mWeaponAnimationTime->setGroup(group, relativeDuration); } - updateParts(); -} + void NpcAnimation::equipmentChanged() + { + static const bool shieldSheathing = Settings::Manager::getBool("shield sheathing", "Game"); + if (shieldSheathing) + { + int weaptype = ESM::Weapon::None; + MWMechanics::getActiveWeapon(mPtr, &weaptype); + showCarriedLeft(updateCarriedLeftVisible(weaptype)); + } -void NpcAnimation::setVampire(bool vampire) -{ - if (mNpcType == Type_Werewolf) // we can't have werewolf vampires, can we - return; - if ((mNpcType == Type_Vampire) != vampire) + updateParts(); + } + + void NpcAnimation::setVampire(bool vampire) { - if (mPtr == MWMechanics::getPlayer()) - MWBase::Environment::get().getWorld()->reattachPlayerCamera(); - else - rebuild(); + if (mNpcType == Type_Werewolf) // we can't have werewolf vampires, can we + return; + if ((mNpcType == Type_Vampire) != vampire) + { + if (mPtr == MWMechanics::getPlayer()) + MWBase::Environment::get().getWorld()->reattachPlayerCamera(); + else + rebuild(); + } } -} -void NpcAnimation::setFirstPersonOffset(const osg::Vec3f &offset) -{ - mFirstPersonOffset = offset; -} + void NpcAnimation::setFirstPersonOffset(const osg::Vec3f& offset) + { + mFirstPersonOffset = offset; + } -void NpcAnimation::updatePtr(const MWWorld::Ptr &updated) -{ - Animation::updatePtr(updated); - mHeadAnimationTime->updatePtr(updated); -} + void NpcAnimation::updatePtr(const MWWorld::Ptr& updated) + { + Animation::updatePtr(updated); + mHeadAnimationTime->updatePtr(updated); + } -// Remember body parts so we only have to search through the store once for each race/gender/viewmode combination -typedef std::map< std::pair,std::vector > RaceMapping; -static RaceMapping sRaceMapping; + // Remember body parts so we only have to search through the store once for each race/gender/viewmode combination + typedef std::map, std::vector> RaceMapping; + static RaceMapping sRaceMapping; -const std::vector& NpcAnimation::getBodyParts(const std::string &race, bool female, bool firstPerson, bool werewolf) -{ - static const int Flag_FirstPerson = 1<<1; - static const int Flag_Female = 1<<0; - - int flags = (werewolf ? -1 : 0); - if(female) - flags |= Flag_Female; - if(firstPerson) - flags |= Flag_FirstPerson; - - RaceMapping::iterator found = sRaceMapping.find(std::make_pair(race, flags)); - if (found != sRaceMapping.end()) - return found->second; - else + const std::vector& NpcAnimation::getBodyParts( + const std::string& race, bool female, bool firstPerson, bool werewolf) { - std::vector& parts = sRaceMapping[std::make_pair(race, flags)]; - - typedef std::multimap BodyPartMapType; - static const BodyPartMapType sBodyPartMap = + static const int Flag_FirstPerson = 1 << 1; + static const int Flag_Female = 1 << 0; + + int flags = (werewolf ? -1 : 0); + if (female) + flags |= Flag_Female; + if (firstPerson) + flags |= Flag_FirstPerson; + + RaceMapping::iterator found = sRaceMapping.find(std::make_pair(race, flags)); + if (found != sRaceMapping.end()) + return found->second; + else { - {ESM::BodyPart::MP_Neck, ESM::PRT_Neck}, - {ESM::BodyPart::MP_Chest, ESM::PRT_Cuirass}, - {ESM::BodyPart::MP_Groin, ESM::PRT_Groin}, - {ESM::BodyPart::MP_Hand, ESM::PRT_RHand}, - {ESM::BodyPart::MP_Hand, ESM::PRT_LHand}, - {ESM::BodyPart::MP_Wrist, ESM::PRT_RWrist}, - {ESM::BodyPart::MP_Wrist, ESM::PRT_LWrist}, - {ESM::BodyPart::MP_Forearm, ESM::PRT_RForearm}, - {ESM::BodyPart::MP_Forearm, ESM::PRT_LForearm}, - {ESM::BodyPart::MP_Upperarm, ESM::PRT_RUpperarm}, - {ESM::BodyPart::MP_Upperarm, ESM::PRT_LUpperarm}, - {ESM::BodyPart::MP_Foot, ESM::PRT_RFoot}, - {ESM::BodyPart::MP_Foot, ESM::PRT_LFoot}, - {ESM::BodyPart::MP_Ankle, ESM::PRT_RAnkle}, - {ESM::BodyPart::MP_Ankle, ESM::PRT_LAnkle}, - {ESM::BodyPart::MP_Knee, ESM::PRT_RKnee}, - {ESM::BodyPart::MP_Knee, ESM::PRT_LKnee}, - {ESM::BodyPart::MP_Upperleg, ESM::PRT_RLeg}, - {ESM::BodyPart::MP_Upperleg, ESM::PRT_LLeg}, - {ESM::BodyPart::MP_Tail, ESM::PRT_Tail} - }; + std::vector& parts = sRaceMapping[std::make_pair(race, flags)]; - parts.resize(ESM::PRT_Count, nullptr); + typedef std::multimap BodyPartMapType; + static const BodyPartMapType sBodyPartMap = { { ESM::BodyPart::MP_Neck, ESM::PRT_Neck }, + { ESM::BodyPart::MP_Chest, ESM::PRT_Cuirass }, { ESM::BodyPart::MP_Groin, ESM::PRT_Groin }, + { ESM::BodyPart::MP_Hand, ESM::PRT_RHand }, { ESM::BodyPart::MP_Hand, ESM::PRT_LHand }, + { ESM::BodyPart::MP_Wrist, ESM::PRT_RWrist }, { ESM::BodyPart::MP_Wrist, ESM::PRT_LWrist }, + { ESM::BodyPart::MP_Forearm, ESM::PRT_RForearm }, { ESM::BodyPart::MP_Forearm, ESM::PRT_LForearm }, + { ESM::BodyPart::MP_Upperarm, ESM::PRT_RUpperarm }, { ESM::BodyPart::MP_Upperarm, ESM::PRT_LUpperarm }, + { ESM::BodyPart::MP_Foot, ESM::PRT_RFoot }, { ESM::BodyPart::MP_Foot, ESM::PRT_LFoot }, + { ESM::BodyPart::MP_Ankle, ESM::PRT_RAnkle }, { ESM::BodyPart::MP_Ankle, ESM::PRT_LAnkle }, + { ESM::BodyPart::MP_Knee, ESM::PRT_RKnee }, { ESM::BodyPart::MP_Knee, ESM::PRT_LKnee }, + { ESM::BodyPart::MP_Upperleg, ESM::PRT_RLeg }, { ESM::BodyPart::MP_Upperleg, ESM::PRT_LLeg }, + { ESM::BodyPart::MP_Tail, ESM::PRT_Tail } }; - if (werewolf) - return parts; + parts.resize(ESM::PRT_Count, nullptr); - const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); + if (werewolf) + return parts; - for(const ESM::BodyPart& bodypart : store.get()) - { - if (bodypart.mData.mFlags & ESM::BodyPart::BPF_NotPlayable) - continue; - if (bodypart.mData.mType != ESM::BodyPart::MT_Skin) - continue; + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); - if (!Misc::StringUtils::ciEqual(bodypart.mRace, race)) - continue; + for (const ESM::BodyPart& bodypart : store.get()) + { + if (bodypart.mData.mFlags & ESM::BodyPart::BPF_NotPlayable) + continue; + if (bodypart.mData.mType != ESM::BodyPart::MT_Skin) + continue; - bool partFirstPerson = isFirstPersonPart(&bodypart); + if (!Misc::StringUtils::ciEqual(bodypart.mRace, race)) + continue; - bool isHand = bodypart.mData.mPart == ESM::BodyPart::MP_Hand || - bodypart.mData.mPart == ESM::BodyPart::MP_Wrist || - bodypart.mData.mPart == ESM::BodyPart::MP_Forearm || - bodypart.mData.mPart == ESM::BodyPart::MP_Upperarm; + bool partFirstPerson = isFirstPersonPart(&bodypart); - bool isSameGender = isFemalePart(&bodypart) == female; + bool isHand = bodypart.mData.mPart == ESM::BodyPart::MP_Hand + || bodypart.mData.mPart == ESM::BodyPart::MP_Wrist + || bodypart.mData.mPart == ESM::BodyPart::MP_Forearm + || bodypart.mData.mPart == ESM::BodyPart::MP_Upperarm; - /* A fallback for the arms if 1st person is missing: - 1. Try to use 3d person skin for same gender - 2. Try to use 1st person skin for male, if female == true - 3. Try to use 3d person skin for male, if female == true + bool isSameGender = isFemalePart(&bodypart) == female; - A fallback in another cases: allow to use male bodyparts, if female == true - */ - if (firstPerson && isHand && !partFirstPerson) - { - // Allow 3rd person skins as a fallback for the arms if 1st person is missing - BodyPartMapType::const_iterator bIt = sBodyPartMap.lower_bound(BodyPartMapType::key_type(bodypart.mData.mPart)); - while(bIt != sBodyPartMap.end() && bIt->first == bodypart.mData.mPart) + /* A fallback for the arms if 1st person is missing: + 1. Try to use 3d person skin for same gender + 2. Try to use 1st person skin for male, if female == true + 3. Try to use 3d person skin for male, if female == true + + A fallback in another cases: allow to use male bodyparts, if female == true + */ + if (firstPerson && isHand && !partFirstPerson) { - // If we have no fallback bodypart now and bodypart is for same gender (1) - if(!parts[bIt->second] && isSameGender) - parts[bIt->second] = &bodypart; + // Allow 3rd person skins as a fallback for the arms if 1st person is missing + BodyPartMapType::const_iterator bIt + = sBodyPartMap.lower_bound(BodyPartMapType::key_type(bodypart.mData.mPart)); + while (bIt != sBodyPartMap.end() && bIt->first == bodypart.mData.mPart) + { + // If we have no fallback bodypart now and bodypart is for same gender (1) + if (!parts[bIt->second] && isSameGender) + parts[bIt->second] = &bodypart; - // If we have fallback bodypart for other gender and found fallback for current gender (1) - else if(isSameGender && isFemalePart(parts[bIt->second]) != female) - parts[bIt->second] = &bodypart; + // If we have fallback bodypart for other gender and found fallback for current gender (1) + else if (isSameGender && isFemalePart(parts[bIt->second]) != female) + parts[bIt->second] = &bodypart; - // If we have no fallback bodypart and searching for female bodyparts (3) - else if(!parts[bIt->second] && female) - parts[bIt->second] = &bodypart; + // If we have no fallback bodypart and searching for female bodyparts (3) + else if (!parts[bIt->second] && female) + parts[bIt->second] = &bodypart; - ++bIt; - } + ++bIt; + } - continue; - } + continue; + } - // Don't allow to use podyparts for a different view - if (partFirstPerson != firstPerson) - continue; + // Don't allow to use podyparts for a different view + if (partFirstPerson != firstPerson) + continue; - if (female && !isFemalePart(&bodypart)) - { - // Allow male parts as fallback for females if female parts are missing - BodyPartMapType::const_iterator bIt = sBodyPartMap.lower_bound(BodyPartMapType::key_type(bodypart.mData.mPart)); - while(bIt != sBodyPartMap.end() && bIt->first == bodypart.mData.mPart) + if (female && !isFemalePart(&bodypart)) { - // If we have no fallback bodypart now - if(!parts[bIt->second]) - parts[bIt->second] = &bodypart; + // Allow male parts as fallback for females if female parts are missing + BodyPartMapType::const_iterator bIt + = sBodyPartMap.lower_bound(BodyPartMapType::key_type(bodypart.mData.mPart)); + while (bIt != sBodyPartMap.end() && bIt->first == bodypart.mData.mPart) + { + // If we have no fallback bodypart now + if (!parts[bIt->second]) + parts[bIt->second] = &bodypart; - // If we have 3d person fallback bodypart for hand and 1st person fallback found (2) - else if(isHand && !isFirstPersonPart(parts[bIt->second]) && partFirstPerson) - parts[bIt->second] = &bodypart; + // If we have 3d person fallback bodypart for hand and 1st person fallback found (2) + else if (isHand && !isFirstPersonPart(parts[bIt->second]) && partFirstPerson) + parts[bIt->second] = &bodypart; - ++bIt; - } + ++bIt; + } - continue; - } + continue; + } - // Don't allow to use podyparts for another gender - if (female != isFemalePart(&bodypart)) - continue; + // Don't allow to use podyparts for another gender + if (female != isFemalePart(&bodypart)) + continue; - // Use properly found bodypart, replacing fallbacks - BodyPartMapType::const_iterator bIt = sBodyPartMap.lower_bound(BodyPartMapType::key_type(bodypart.mData.mPart)); - while(bIt != sBodyPartMap.end() && bIt->first == bodypart.mData.mPart) - { - parts[bIt->second] = &bodypart; - ++bIt; + // Use properly found bodypart, replacing fallbacks + BodyPartMapType::const_iterator bIt + = sBodyPartMap.lower_bound(BodyPartMapType::key_type(bodypart.mData.mPart)); + while (bIt != sBodyPartMap.end() && bIt->first == bodypart.mData.mPart) + { + parts[bIt->second] = &bodypart; + ++bIt; + } } + return parts; } - return parts; } -} -void NpcAnimation::setAccurateAiming(bool enabled) -{ - mAccurateAiming = enabled; -} + void NpcAnimation::setAccurateAiming(bool enabled) + { + mAccurateAiming = enabled; + } -bool NpcAnimation::isArrowAttached() const -{ - return mAmmunition != nullptr; -} + bool NpcAnimation::isArrowAttached() const + { + return mAmmunition != nullptr; + } } diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index 82b21d556b..bb7b889c1e 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -24,156 +24,160 @@ namespace MWSound namespace MWRender { -class RotateController; -class HeadAnimationTime; + class RotateController; + class HeadAnimationTime; -class NpcAnimation : public ActorAnimation, public WeaponAnimation, public MWWorld::InventoryStoreListener -{ -public: - void equipmentChanged() override; + class NpcAnimation : public ActorAnimation, public WeaponAnimation, public MWWorld::InventoryStoreListener + { + public: + void equipmentChanged() override; -public: - typedef std::map PartBoneMap; + public: + typedef std::map PartBoneMap; - enum ViewMode { - VM_Normal, - VM_FirstPerson, - VM_HeadOnly - }; + enum ViewMode + { + VM_Normal, + VM_FirstPerson, + VM_HeadOnly + }; -private: - static const PartBoneMap sPartList; + private: + static const PartBoneMap sPartList; - // Bounded Parts - PartHolderPtr mObjectParts[ESM::PRT_Count]; - std::array mSounds; + // Bounded Parts + PartHolderPtr mObjectParts[ESM::PRT_Count]; + std::array mSounds; - const ESM::NPC *mNpc; - std::string mHeadModel; - std::string mHairModel; - ViewMode mViewMode; - bool mShowWeapons; - bool mShowCarriedLeft; + const ESM::NPC* mNpc; + std::string mHeadModel; + std::string mHairModel; + ViewMode mViewMode; + bool mShowWeapons; + bool mShowCarriedLeft; - enum NpcType - { - Type_Normal, - Type_Werewolf, - Type_Vampire - }; - NpcType mNpcType; + enum NpcType + { + Type_Normal, + Type_Werewolf, + Type_Vampire + }; + NpcType mNpcType; - int mPartslots[ESM::PRT_Count]; //Each part slot is taken by clothing, armor, or is empty - int mPartPriorities[ESM::PRT_Count]; + int mPartslots[ESM::PRT_Count]; // Each part slot is taken by clothing, armor, or is empty + int mPartPriorities[ESM::PRT_Count]; - osg::Vec3f mFirstPersonOffset; - // Field of view to use when rendering first person meshes - float mFirstPersonFieldOfView; + osg::Vec3f mFirstPersonOffset; + // Field of view to use when rendering first person meshes + float mFirstPersonFieldOfView; - std::shared_ptr mHeadAnimationTime; - std::shared_ptr mWeaponAnimationTime; + std::shared_ptr mHeadAnimationTime; + std::shared_ptr mWeaponAnimationTime; - bool mSoundsDisabled; + bool mSoundsDisabled; - bool mAccurateAiming; - float mAimingFactor; + bool mAccurateAiming; + float mAimingFactor; - void updateNpcBase(); + void updateNpcBase(); - NpcType getNpcType() const; + NpcType getNpcType() const; - PartHolderPtr insertBoundedPart(const std::string &model, std::string_view bonename, - std::string_view bonefilter, bool enchantedGlow, osg::Vec4f* glowColor, bool isLight); + PartHolderPtr insertBoundedPart(const std::string& model, std::string_view bonename, + std::string_view bonefilter, bool enchantedGlow, osg::Vec4f* glowColor, bool isLight); - void removeIndividualPart(ESM::PartReferenceType type); - void reserveIndividualPart(ESM::PartReferenceType type, int group, int priority); + void removeIndividualPart(ESM::PartReferenceType type); + void reserveIndividualPart(ESM::PartReferenceType type, int group, int priority); - bool addOrReplaceIndividualPart(ESM::PartReferenceType type, int group, int priority, const std::string &mesh, - bool enchantedGlow=false, osg::Vec4f* glowColor=nullptr, bool isLight = false); - void removePartGroup(int group); - void addPartGroup(int group, int priority, const std::vector &parts, - bool enchantedGlow=false, osg::Vec4f* glowColor=nullptr); + bool addOrReplaceIndividualPart(ESM::PartReferenceType type, int group, int priority, const std::string& mesh, + bool enchantedGlow = false, osg::Vec4f* glowColor = nullptr, bool isLight = false); + void removePartGroup(int group); + void addPartGroup(int group, int priority, const std::vector& parts, + bool enchantedGlow = false, osg::Vec4f* glowColor = nullptr); - void setRenderBin(); + void setRenderBin(); - osg::ref_ptr mFirstPersonNeckController; + osg::ref_ptr mFirstPersonNeckController; - static bool isFirstPersonPart(const ESM::BodyPart* bodypart); - static bool isFemalePart(const ESM::BodyPart* bodypart); - static NpcType getNpcType(const MWWorld::Ptr& ptr); + static bool isFirstPersonPart(const ESM::BodyPart* bodypart); + static bool isFemalePart(const ESM::BodyPart* bodypart); + static NpcType getNpcType(const MWWorld::Ptr& ptr); -protected: - void addControllers() override; - bool isArrowAttached() const override; - std::string getSheathedShieldMesh(const MWWorld::ConstPtr& shield) const override; + protected: + void addControllers() override; + bool isArrowAttached() const override; + std::string getSheathedShieldMesh(const MWWorld::ConstPtr& shield) const override; -public: - /** - * @param ptr - * @param disableListener Don't listen for equipment changes and magic effects. InventoryStore only supports - * one listener at a time, so you shouldn't do this if creating several NpcAnimations - * for the same Ptr, eg preview dolls for the player. - * Those need to be manually rendered anyway. - * @param disableSounds Same as \a disableListener but for playing items sounds - * @param viewMode - */ - NpcAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr parentNode, Resource::ResourceSystem* resourceSystem, - bool disableSounds = false, ViewMode viewMode=VM_Normal, float firstPersonFieldOfView=55.f); - virtual ~NpcAnimation(); + public: + /** + * @param ptr + * @param disableListener Don't listen for equipment changes and magic effects. InventoryStore only supports + * one listener at a time, so you shouldn't do this if creating several NpcAnimations + * for the same Ptr, eg preview dolls for the player. + * Those need to be manually rendered anyway. + * @param disableSounds Same as \a disableListener but for playing items sounds + * @param viewMode + */ + NpcAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr parentNode, + Resource::ResourceSystem* resourceSystem, bool disableSounds = false, ViewMode viewMode = VM_Normal, + float firstPersonFieldOfView = 55.f); + virtual ~NpcAnimation(); - void enableHeadAnimation(bool enable) override; + void enableHeadAnimation(bool enable) override; - /// 1: the first person meshes follow the camera's rotation completely - /// 0: the first person meshes follow the camera with a reduced factor, so you can look down at your own hands - void setAccurateAiming(bool enabled) override; + /// 1: the first person meshes follow the camera's rotation completely + /// 0: the first person meshes follow the camera with a reduced factor, so you can look down at your own hands + void setAccurateAiming(bool enabled) override; - void setWeaponGroup(const std::string& group, bool relativeDuration) override; + void setWeaponGroup(const std::string& group, bool relativeDuration) override; - osg::Vec3f runAnimation(float timepassed) override; + osg::Vec3f runAnimation(float timepassed) override; - /// A relative factor (0-1) that decides if and how much the skeleton should be pitched - /// to indicate the facing orientation of the character. - void setPitchFactor(float factor) override { mPitchFactor = factor; } + /// A relative factor (0-1) that decides if and how much the skeleton should be pitched + /// to indicate the facing orientation of the character. + void setPitchFactor(float factor) override { mPitchFactor = factor; } - bool getWeaponsShown() const override { return mShowWeapons; } - void showWeapons(bool showWeapon) override; + bool getWeaponsShown() const override { return mShowWeapons; } + void showWeapons(bool showWeapon) override; - bool updateCarriedLeftVisible(const int weaptype) const override; - bool getCarriedLeftShown() const override { return mShowCarriedLeft; } - void showCarriedLeft(bool show) override; + bool updateCarriedLeftVisible(const int weaptype) const override; + bool getCarriedLeftShown() const override { return mShowCarriedLeft; } + void showCarriedLeft(bool show) override; - void attachArrow() override; - void detachArrow() override; - void releaseArrow(float attackStrength) override; + void attachArrow() override; + void detachArrow() override; + void releaseArrow(float attackStrength) override; - osg::Group* getArrowBone() override; - osg::Node* getWeaponNode() override; - Resource::ResourceSystem* getResourceSystem() override; + osg::Group* getArrowBone() override; + osg::Node* getWeaponNode() override; + Resource::ResourceSystem* getResourceSystem() override; - // WeaponAnimation - void showWeapon(bool show) override { showWeapons(show); } + // WeaponAnimation + void showWeapon(bool show) override { showWeapons(show); } - void setViewMode(ViewMode viewMode); + void setViewMode(ViewMode viewMode); - void updateParts(); + void updateParts(); - /// Rebuilds the NPC, updating their root model, animation sources, and equipment. - void rebuild(); + /// Rebuilds the NPC, updating their root model, animation sources, and equipment. + void rebuild(); - /// Get the inventory slot that the given node path leads into, or -1 if not found. - int getSlot(const osg::NodePath& path) const; + /// Get the inventory slot that the given node path leads into, or -1 if not found. + int getSlot(const osg::NodePath& path) const; - void setVampire(bool vampire) override; + void setVampire(bool vampire) override; - /// Set a translation offset (in object root space) to apply to meshes when in first person mode. - void setFirstPersonOffset(const osg::Vec3f& offset); + /// Set a translation offset (in object root space) to apply to meshes when in first person mode. + void setFirstPersonOffset(const osg::Vec3f& offset); - void updatePtr(const MWWorld::Ptr& updated) override; + void updatePtr(const MWWorld::Ptr& updated) override; - /// Get a list of body parts that may be used by an NPC of given race and gender. - /// @note This is a fixed size list, one list item for each ESM::PartReferenceType, may contain nullptr body parts. - static const std::vector& getBodyParts(const std::string& raceId, bool female, bool firstperson, bool werewolf); -}; + /// Get a list of body parts that may be used by an NPC of given race and gender. + /// @note This is a fixed size list, one list item for each ESM::PartReferenceType, may contain nullptr body + /// parts. + static const std::vector& getBodyParts( + const std::string& raceId, bool female, bool firstperson, bool werewolf); + }; } diff --git a/apps/openmw/mwrender/objectpaging.cpp b/apps/openmw/mwrender/objectpaging.cpp index 1426a6d314..77bf4097a0 100644 --- a/apps/openmw/mwrender/objectpaging.cpp +++ b/apps/openmw/mwrender/objectpaging.cpp @@ -4,40 +4,40 @@ #include #include -#include -#include -#include #include +#include +#include +#include #include #include -#include #include #include #include +#include +#include #include #include +#include #include #include -#include #include #include -#include #include #include +#include #include #include -#include #include +#include #include -#include -#include "apps/openmw/mwworld/esmstore.hpp" #include "apps/openmw/mwbase/environment.hpp" #include "apps/openmw/mwbase/world.hpp" +#include "apps/openmw/mwworld/esmstore.hpp" #include "vismask.hpp" @@ -50,15 +50,15 @@ namespace MWRender { switch (type) { - case ESM::REC_STAT: - case ESM::REC_ACTI: - case ESM::REC_DOOR: - return true; - case ESM::REC_CONT: - return !far; + case ESM::REC_STAT: + case ESM::REC_ACTI: + case ESM::REC_DOOR: + return true; + case ESM::REC_CONT: + return !far; - default: - return false; + default: + return false; } } @@ -66,20 +66,21 @@ namespace MWRender { switch (type) { - case ESM::REC_STAT: - return store.get().searchStatic(id)->mModel; - case ESM::REC_ACTI: - return store.get().searchStatic(id)->mModel; - case ESM::REC_DOOR: - return store.get().searchStatic(id)->mModel; - case ESM::REC_CONT: - return store.get().searchStatic(id)->mModel; - default: - return {}; + case ESM::REC_STAT: + return store.get().searchStatic(id)->mModel; + case ESM::REC_ACTI: + return store.get().searchStatic(id)->mModel; + case ESM::REC_DOOR: + return store.get().searchStatic(id)->mModel; + case ESM::REC_CONT: + return store.get().searchStatic(id)->mModel; + default: + return {}; } } - osg::ref_ptr ObjectPaging::getChunk(float size, const osg::Vec2f& center, unsigned char lod, unsigned int lodFlags, bool activeGrid, const osg::Vec3f& viewPoint, bool compile) + osg::ref_ptr ObjectPaging::getChunk(float size, const osg::Vec2f& center, unsigned char lod, + unsigned int lodFlags, bool activeGrid, const osg::Vec3f& viewPoint, bool compile) { lod = static_cast(lodFlags >> (4 * 4)); if (activeGrid && !mActiveGrid) @@ -101,11 +102,13 @@ namespace MWRender class CanOptimizeCallback : public SceneUtil::Optimizer::IsOperationPermissibleForObjectCallback { public: - bool isOperationPermissibleForObjectImplementation(const SceneUtil::Optimizer* optimizer, const osg::Drawable* node,unsigned int option) const override + bool isOperationPermissibleForObjectImplementation( + const SceneUtil::Optimizer* optimizer, const osg::Drawable* node, unsigned int option) const override { return true; } - bool isOperationPermissibleForObjectImplementation(const SceneUtil::Optimizer* optimizer, const osg::Node* node,unsigned int option) const override + bool isOperationPermissibleForObjectImplementation( + const SceneUtil::Optimizer* optimizer, const osg::Node* node, unsigned int option) const override { return (node->getDataVariance() != osg::Object::DYNAMIC); } @@ -127,12 +130,12 @@ namespace MWRender attachTo->addChild(operator()(toCopy)); else { - for (unsigned int i=0; igetNumChildren(); ++i) + for (unsigned int i = 0; i < groupToCopy->getNumChildren(); ++i) attachTo->addChild(operator()(groupToCopy->getChild(i))); } } - osg::Node* operator() (const osg::Node* node) const override + osg::Node* operator()(const osg::Node* node) const override { if (!(node->getNodeMask() & mCopyMask)) return nullptr; @@ -148,7 +151,7 @@ namespace MWRender if (const osg::Switch* sw = node->asSwitch()) { osg::Group* n = new osg::Group; - for (unsigned int i=0; igetNumChildren(); ++i) + for (unsigned int i = 0; i < sw->getNumChildren(); ++i) if (sw->getValue(i)) n->addChild(operator()(sw->getChild(i))); n->setDataVariance(osg::Object::STATIC); @@ -157,8 +160,9 @@ namespace MWRender if (const osg::LOD* lod = dynamic_cast(node)) { osg::Group* n = new osg::Group; - for (unsigned int i=0; igetNumChildren(); ++i) - if (lod->getMinRange(i) * lod->getMinRange(i) <= mSqrDistance && mSqrDistance < lod->getMaxRange(i) * lod->getMaxRange(i)) + for (unsigned int i = 0; i < lod->getNumChildren(); ++i) + if (lod->getMinRange(i) * lod->getMinRange(i) <= mSqrDistance + && mSqrDistance < lod->getMaxRange(i) * lod->getMaxRange(i)) n->addChild(operator()(lod->getChild(i))); n->setDataVariance(osg::Object::STATIC); return n; @@ -184,9 +188,10 @@ namespace MWRender return cloned; } - void handleCallbacks(const osg::Node* node, osg::Node *cloned) const + void handleCallbacks(const osg::Node* node, osg::Node* cloned) const { - for (const osg::Callback* callback = node->getCullCallback(); callback != nullptr; callback = callback->getNestedCallback()) + for (const osg::Callback* callback = node->getCullCallback(); callback != nullptr; + callback = callback->getNestedCallback()) { if (callback->className() == std::string("BillboardCallback")) { @@ -201,7 +206,7 @@ namespace MWRender if (node->getCullCallback()->getNestedCallback()) { - osg::Callback *clonedCallback = osg::clone(callback, osg::CopyOp::SHALLOW_COPY); + osg::Callback* clonedCallback = osg::clone(callback, osg::CopyOp::SHALLOW_COPY); clonedCallback->setNestedCallback(nullptr); cloned->addCullCallback(clonedCallback); } @@ -212,9 +217,11 @@ namespace MWRender void handleBillboard(osg::Node* node) const { osg::Transform* transform = node->asTransform(); - if (!transform) return; + if (!transform) + return; osg::MatrixTransform* matrixTransform = transform->asMatrixTransform(); - if (!matrixTransform) return; + if (!matrixTransform) + return; osg::Matrix worldToLocal = osg::Matrix::identity(); for (auto pathNode : mNodePath) @@ -225,19 +232,20 @@ namespace MWRender osg::Matrix billboardMatrix; osg::Vec3f viewVector = -(mViewVector + worldToLocal.getTrans()); viewVector.normalize(); - osg::Vec3f right = viewVector ^ osg::Vec3f(0,0,1); + osg::Vec3f right = viewVector ^ osg::Vec3f(0, 0, 1); right.normalize(); osg::Vec3f up = right ^ viewVector; up.normalize(); - billboardMatrix.makeLookAt(osg::Vec3f(0,0,0), viewVector, up); + billboardMatrix.makeLookAt(osg::Vec3f(0, 0, 0), viewVector, up); billboardMatrix.invert(billboardMatrix); const osg::Matrix& oldMatrix = matrixTransform->getMatrix(); float mag[3]; // attempt to preserve scale - for (int i=0;i<3;++i) - mag[i] = std::sqrt(oldMatrix(0,i) * oldMatrix(0,i) + oldMatrix(1,i) * oldMatrix(1,i) + oldMatrix(2,i) * oldMatrix(2,i)); + for (int i = 0; i < 3; ++i) + mag[i] = std::sqrt(oldMatrix(0, i) * oldMatrix(0, i) + oldMatrix(1, i) * oldMatrix(1, i) + + oldMatrix(2, i) * oldMatrix(2, i)); osg::Matrix newMatrix; - worldToLocal.setTrans(0,0,0); + worldToLocal.setTrans(0, 0, 0); newMatrix *= worldToLocal; newMatrix.preMult(billboardMatrix); newMatrix.preMultScale(osg::Vec3f(mag[0], mag[1], mag[2])); @@ -245,7 +253,7 @@ namespace MWRender matrixTransform->setMatrix(newMatrix); } - osg::Drawable* operator() (const osg::Drawable* drawable) const override + osg::Drawable* operator()(const osg::Drawable* drawable) const override { if (!(drawable->getNodeMask() & mCopyMask)) return nullptr; @@ -271,17 +279,17 @@ namespace MWRender else return const_cast(drawable); } - osg::Callback* operator() (const osg::Callback* callback) const override - { - return nullptr; - } + osg::Callback* operator()(const osg::Callback* callback) const override { return nullptr; } }; class RefnumSet : public osg::Object { public: - RefnumSet(){} - RefnumSet(const RefnumSet& copy, const osg::CopyOp&) : mRefnums(copy.mRefnums) {} + RefnumSet() {} + RefnumSet(const RefnumSet& copy, const osg::CopyOp&) + : mRefnums(copy.mRefnums) + { + } META_Object(MWRender, RefnumSet) std::vector mRefnums; }; @@ -290,10 +298,12 @@ namespace MWRender { public: AnalyzeVisitor(osg::Node::NodeMask analyzeMask) - : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) - , mCurrentStateSet(nullptr) - , mCurrentDistance(0.f) - { setTraversalMask(analyzeMask); } + : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) + , mCurrentStateSet(nullptr) + , mCurrentDistance(0.f) + { + setTraversalMask(analyzeMask); + } typedef std::unordered_map StateSetCounter; struct Result @@ -309,15 +319,16 @@ namespace MWRender if (osg::Switch* sw = node.asSwitch()) { - for (unsigned int i=0; igetNumChildren(); ++i) + for (unsigned int i = 0; i < sw->getNumChildren(); ++i) if (sw->getValue(i)) traverse(*sw->getChild(i)); return; } if (osg::LOD* lod = dynamic_cast(&node)) { - for (unsigned int i=0; igetNumChildren(); ++i) - if (lod->getMinRange(i) * lod->getMinRange(i) <= mCurrentDistance && mCurrentDistance < lod->getMaxRange(i) * lod->getMaxRange(i)) + for (unsigned int i = 0; i < lod->getNumChildren(); ++i) + if (lod->getMinRange(i) * lod->getMinRange(i) <= mCurrentDistance + && mCurrentDistance < lod->getMaxRange(i) * lod->getMaxRange(i)) traverse(*lod->getChild(i)); return; } @@ -351,7 +362,8 @@ namespace MWRender } float getMergeBenefit(const Result& result) { - if (result.mStateSetCounter.empty()) return 1; + if (result.mStateSetCounter.empty()) + return 1; float mergeBenefit = 0; for (auto pair : result.mStateSetCounter) { @@ -370,17 +382,22 @@ namespace MWRender class DebugVisitor : public osg::NodeVisitor { public: - DebugVisitor() : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) {} + DebugVisitor() + : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) + { + } void apply(osg::Drawable& node) override { - osg::ref_ptr m (new osg::Material); - osg::Vec4f color(Misc::Rng::rollProbability(), Misc::Rng::rollProbability(), Misc::Rng::rollProbability(), 0.f); + osg::ref_ptr m(new osg::Material); + osg::Vec4f color( + Misc::Rng::rollProbability(), Misc::Rng::rollProbability(), Misc::Rng::rollProbability(), 0.f); color.normalize(); - m->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(0.1f,0.1f,0.1f,1.f)); - m->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(0.1f,0.1f,0.1f,1.f)); + m->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(0.1f, 0.1f, 0.1f, 1.f)); + m->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(0.1f, 0.1f, 0.1f, 1.f)); m->setColorMode(osg::Material::OFF); m->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4f(color)); - osg::ref_ptr stateset = node.getStateSet() ? osg::clone(node.getStateSet(), osg::CopyOp::SHALLOW_COPY) : new osg::StateSet; + osg::ref_ptr stateset + = node.getStateSet() ? osg::clone(node.getStateSet(), osg::CopyOp::SHALLOW_COPY) : new osg::StateSet; stateset->setAttribute(m); stateset->addUniform(new osg::Uniform("colorMode", 0)); stateset->addUniform(new osg::Uniform("emissiveMult", 1.f)); @@ -392,11 +409,15 @@ namespace MWRender class AddRefnumMarkerVisitor : public osg::NodeVisitor { public: - AddRefnumMarkerVisitor(const ESM::RefNum &refnum) : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN), mRefnum(refnum) {} + AddRefnumMarkerVisitor(const ESM::RefNum& refnum) + : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) + , mRefnum(refnum) + { + } ESM::RefNum mRefnum; - void apply(osg::Geometry &node) override + void apply(osg::Geometry& node) override { - osg::ref_ptr marker (new RefnumMarker); + osg::ref_ptr marker(new RefnumMarker); marker->mRefnum = mRefnum; if (osg::Array* array = node.getVertexArray()) marker->mNumVertices = array->getNumElements(); @@ -405,9 +426,9 @@ namespace MWRender }; ObjectPaging::ObjectPaging(Resource::SceneManager* sceneManager) - : GenericResourceManager(nullptr) - , mSceneManager(sceneManager) - , mRefTrackerLocked(false) + : GenericResourceManager(nullptr) + , mSceneManager(sceneManager) + , mRefTrackerLocked(false) { mActiveGrid = Settings::Manager::getBool("object paging active grid", "Terrain"); mDebugBatches = Settings::Manager::getBool("debug chunks", "Terrain"); @@ -417,11 +438,12 @@ namespace MWRender mMinSizeCostMultiplier = Settings::Manager::getFloat("object paging min size cost multiplier", "Terrain"); } - osg::ref_ptr ObjectPaging::createChunk(float size, const osg::Vec2f& center, bool activeGrid, const osg::Vec3f& viewPoint, bool compile, unsigned char lod) + osg::ref_ptr ObjectPaging::createChunk(float size, const osg::Vec2f& center, bool activeGrid, + const osg::Vec3f& viewPoint, bool compile, unsigned char lod) { - osg::Vec2i startCell = osg::Vec2i(std::floor(center.x() - size/2.f), std::floor(center.y() - size/2.f)); + osg::Vec2i startCell = osg::Vec2i(std::floor(center.x() - size / 2.f), std::floor(center.y() - size / 2.f)); - osg::Vec3f worldCenter = osg::Vec3f(center.x(), center.y(), 0)*ESM::Land::REAL_SIZE; + osg::Vec3f worldCenter = osg::Vec3f(center.x(), center.y(), 0) * ESM::Land::REAL_SIZE; osg::Vec3f relativeViewPoint = viewPoint - worldCenter; std::map refs; @@ -434,8 +456,9 @@ namespace MWRender for (int cellY = startCell.y(); cellY < startCell.y() + size; ++cellY) { const ESM::Cell* cell = store.get().searchStatic(cellX, cellY); - if (!cell) continue; - for (size_t i=0; imContextList.size(); ++i) + if (!cell) + continue; + for (size_t i = 0; i < cell->mContextList.size(); ++i) { try { @@ -448,18 +471,25 @@ namespace MWRender cMRef.mRefNum.mIndex = 0; bool deleted = false; bool moved = false; - while (ESM::Cell::getNextRef(*reader, ref, deleted, cMRef, moved, ESM::Cell::GetNextRefMode::LoadOnlyNotMoved)) + while (ESM::Cell::getNextRef( + *reader, ref, deleted, cMRef, moved, ESM::Cell::GetNextRefMode::LoadOnlyNotMoved)) { if (moved) continue; - if (std::find(cell->mMovedRefs.begin(), cell->mMovedRefs.end(), ref.mRefNum) != cell->mMovedRefs.end()) + if (std::find(cell->mMovedRefs.begin(), cell->mMovedRefs.end(), ref.mRefNum) + != cell->mMovedRefs.end()) continue; Misc::StringUtils::lowerCaseInPlace(ref.mRefID); int type = store.findStatic(ref.mRefID); - if (!typeFilter(type,size>=2)) continue; - if (deleted) { refs.erase(ref.mRefNum); continue; } + if (!typeFilter(type, size >= 2)) + continue; + if (deleted) + { + refs.erase(ref.mRefNum); + continue; + } refs[ref.mRefNum] = std::move(ref); } } @@ -477,7 +507,8 @@ namespace MWRender } Misc::StringUtils::lowerCaseInPlace(ref.mRefID); int type = store.findStatic(ref.mRefID); - if (!typeFilter(type,size>=2)) continue; + if (!typeFilter(type, size >= 2)) + continue; refs[ref.mRefNum] = std::move(ref); } } @@ -490,8 +521,8 @@ namespace MWRender refs.erase(ref); } - osg::Vec2f minBound = (center - osg::Vec2f(size/2.f, size/2.f)); - osg::Vec2f maxBound = (center + osg::Vec2f(size/2.f, size/2.f)); + osg::Vec2f minBound = (center - osg::Vec2f(size / 2.f, size / 2.f)); + osg::Vec2f maxBound = (center + osg::Vec2f(size / 2.f, size / 2.f)); struct InstanceList { std::vector mInstances; @@ -521,8 +552,10 @@ namespace MWRender if (size < 1.f) { osg::Vec3f cellPos = pos / ESM::Land::REAL_SIZE; - if ((minBound.x() > std::floor(minBound.x()) && cellPos.x() < minBound.x()) || (minBound.y() > std::floor(minBound.y()) && cellPos.y() < minBound.y()) - || (maxBound.x() < std::ceil(maxBound.x()) && cellPos.x() >= maxBound.x()) || (maxBound.y() < std::ceil(maxBound.y()) && cellPos.y() >= maxBound.y())) + if ((minBound.x() > std::floor(minBound.x()) && cellPos.x() < minBound.x()) + || (minBound.y() > std::floor(minBound.y()) && cellPos.y() < minBound.y()) + || (maxBound.x() < std::ceil(maxBound.x()) && cellPos.x() >= maxBound.x()) + || (maxBound.y() < std::ceil(maxBound.y()) && cellPos.y() >= maxBound.y())) continue; } @@ -531,7 +564,7 @@ namespace MWRender { std::lock_guard lock(mSizeCacheMutex); SizeCache::iterator found = mSizeCache.find(pair.first); - if (found != mSizeCache.end() && found->second < dSqr*minSize*minSize) + if (found != mSizeCache.end() && found->second < dSqr * minSize * minSize) continue; } @@ -540,16 +573,17 @@ namespace MWRender int type = store.findStatic(ref.mRefID); std::string model = getModel(type, ref.mRefID, store); - if (model.empty()) continue; + if (model.empty()) + continue; model = Misc::ResourceHelpers::correctMeshPath(model, mSceneManager->getVFS()); if (activeGrid && type != ESM::REC_STAT) { model = Misc::ResourceHelpers::correctActorModelPath(model, mSceneManager->getVFS()); std::string kfname = Misc::StringUtils::lowerCase(model); - if(kfname.size() > 4 && kfname.compare(kfname.size()-4, 4, ".nif") == 0) + if (kfname.size() > 4 && kfname.compare(kfname.size() - 4, 4, ".nif") == 0) { - kfname.replace(kfname.size()-4, 4, ".kf"); + kfname.replace(kfname.size() - 4, 4, ".kf"); if (mSceneManager->getVFS()->exists(kfname)) continue; } @@ -563,14 +597,22 @@ namespace MWRender if (found != mLODNameCache.end() && found->first == key) model = found->second; else - model = mLODNameCache.insert(found, { key, Misc::ResourceHelpers::getLODMeshName(world->getESMVersions()[ref.mRefNum.mContentFile], model, mSceneManager->getVFS(), lod) })->second; + model = mLODNameCache + .insert(found, + { key, + Misc::ResourceHelpers::getLODMeshName( + world->getESMVersions()[ref.mRefNum.mContentFile], model, + mSceneManager->getVFS(), lod) }) + ->second; } osg::ref_ptr cnode = mSceneManager->getTemplate(model, false); if (activeGrid) { - if (cnode->getNumChildrenRequiringUpdateTraversal() > 0 || SceneUtil::hasUserDescription(cnode, Constants::NightDayLabel) || SceneUtil::hasUserDescription(cnode, Constants::HerbalismLabel)) + if (cnode->getNumChildrenRequiringUpdateTraversal() > 0 + || SceneUtil::hasUserDescription(cnode, Constants::NightDayLabel) + || SceneUtil::hasUserDescription(cnode, Constants::HerbalismLabel)) continue; else refnumSet->mRefnums.push_back(pair.first); @@ -582,8 +624,8 @@ namespace MWRender continue; } - float radius2 = cnode->getBound().radius2() * ref.mScale*ref.mScale; - if (radius2 < dSqr*minSize*minSize && !activeGrid) + float radius2 = cnode->getBound().radius2() * ref.mScale * ref.mScale; + if (radius2 < dSqr * minSize * minSize && !activeGrid) { std::lock_guard lock(mSizeCacheMutex); mSizeCache[pair.first] = radius2; @@ -593,7 +635,9 @@ namespace MWRender auto emplaced = nodes.emplace(cnode, InstanceList()); if (emplaced.second) { - const_cast(cnode.get())->accept(analyzeVisitor); // const-trickery required because there is no const version of NodeVisitor + const_cast(cnode.get()) + ->accept( + analyzeVisitor); // const-trickery required because there is no const version of NodeVisitor emplaced.first->second.mAnalyzeResult = analyzeVisitor.retrieveResult(); emplaced.first->second.mNeedCompile = compile && cnode->referenceCount() <= 3; } @@ -620,7 +664,7 @@ namespace MWRender float minSizeMerged = mMinSize; float factor2 = mergeBenefit > 0 ? std::min(1.f, mergeCost * mMinSizeCostMultiplier / mergeBenefit) : 1; - float minSizeMergeFactor2 = (1-factor2) * mMinSizeMergeFactor + factor2; + float minSizeMergeFactor2 = (1 - factor2) * mMinSizeMergeFactor + factor2; if (minSizeMergeFactor2 > 0) minSizeMerged *= minSizeMergeFactor2; @@ -630,13 +674,15 @@ namespace MWRender const ESM::CellRef& ref = *cref; osg::Vec3f pos = ref.mPos.asVec3(); - if (!activeGrid && minSizeMerged != minSize && cnode->getBound().radius2() * cref->mScale*cref->mScale < (viewPoint-pos).length2()*minSizeMerged*minSizeMerged) + if (!activeGrid && minSizeMerged != minSize + && cnode->getBound().radius2() * cref->mScale * cref->mScale + < (viewPoint - pos).length2() * minSizeMerged * minSizeMerged) continue; osg::Vec3f nodePos = pos - worldCenter; - osg::Quat nodeAttitude = osg::Quat(ref.mPos.rot[2], osg::Vec3f(0,0,-1)) * - osg::Quat(ref.mPos.rot[1], osg::Vec3f(0,-1,0)) * - osg::Quat(ref.mPos.rot[0], osg::Vec3f(-1,0,0)); + osg::Quat nodeAttitude = osg::Quat(ref.mPos.rot[2], osg::Vec3f(0, 0, -1)) + * osg::Quat(ref.mPos.rot[1], osg::Vec3f(0, -1, 0)) + * osg::Quat(ref.mPos.rot[0], osg::Vec3f(-1, 0, 0)); osg::Vec3f nodeScale = osg::Vec3f(ref.mScale, ref.mScale, ref.mScale); osg::ref_ptr trans; @@ -653,18 +699,22 @@ namespace MWRender else { trans = new SceneUtil::PositionAttitudeTransform; - SceneUtil::PositionAttitudeTransform* pat = static_cast(trans.get()); + SceneUtil::PositionAttitudeTransform* pat + = static_cast(trans.get()); pat->setPosition(nodePos); pat->setScale(nodeScale); pat->setAttitude(nodeAttitude); } - // DO NOT COPY AND PASTE THIS CODE. Cloning osg::Geometry without also cloning its contained Arrays is generally unsafe. - // In this specific case the operation is safe under the following two assumptions: - // - When Arrays are removed or replaced in the cloned geometry, the original Arrays in their place must outlive the cloned geometry regardless. (ensured by TemplateMultiRef) - // - Arrays that we add or replace in the cloned geometry must be explicitely forbidden from reusing BufferObjects of the original geometry. (ensured by needvbo() in optimizer.cpp) - copyop.setCopyFlags(merge ? osg::CopyOp::DEEP_COPY_NODES|osg::CopyOp::DEEP_COPY_DRAWABLES : osg::CopyOp::DEEP_COPY_NODES); - copyop.mOptimizeBillboards = (size > 1/4.f); + // DO NOT COPY AND PASTE THIS CODE. Cloning osg::Geometry without also cloning its contained Arrays is + // generally unsafe. In this specific case the operation is safe under the following two assumptions: + // - When Arrays are removed or replaced in the cloned geometry, the original Arrays in their place must + // outlive the cloned geometry regardless. (ensured by TemplateMultiRef) + // - Arrays that we add or replace in the cloned geometry must be explicitely forbidden from reusing + // BufferObjects of the original geometry. (ensured by needvbo() in optimizer.cpp) + copyop.setCopyFlags(merge ? osg::CopyOp::DEEP_COPY_NODES | osg::CopyOp::DEEP_COPY_DRAWABLES + : osg::CopyOp::DEEP_COPY_NODES); + copyop.mOptimizeBillboards = (size > 1 / 4.f); copyop.mNodePath.push_back(trans); copyop.mSqrDistance = (viewPoint - pos).length2(); copyop.mViewVector = (viewPoint - worldCenter); @@ -680,7 +730,8 @@ namespace MWRender } else { - osg::ref_ptr marker = new RefnumMarker; marker->mRefnum = ref.mRefNum; + osg::ref_ptr marker = new RefnumMarker; + marker->mRefnum = ref.mRefNum; trans->getOrCreateUserDataContainer()->addUserObject(marker); } } @@ -709,13 +760,14 @@ namespace MWRender if (mergeGroup->getNumChildren()) { SceneUtil::Optimizer optimizer; - if (size > 1/8.f) + if (size > 1 / 8.f) { optimizer.setViewPoint(relativeViewPoint); optimizer.setMergeAlphaBlending(true); } optimizer.setIsOperationPermissibleForObjectCallback(new CanOptimizeCallback); - unsigned int options = SceneUtil::Optimizer::FLATTEN_STATIC_TRANSFORMS|SceneUtil::Optimizer::REMOVE_REDUNDANT_NODES|SceneUtil::Optimizer::MERGE_GEOMETRY; + unsigned int options = SceneUtil::Optimizer::FLATTEN_STATIC_TRANSFORMS + | SceneUtil::Optimizer::REMOVE_REDUNDANT_NODES | SceneUtil::Optimizer::MERGE_GEOMETRY; optimizer.optimize(mergeGroup, options); @@ -747,7 +799,8 @@ namespace MWRender if (activeGrid) { std::sort(refnumSet->mRefnums.begin(), refnumSet->mRefnums.end()); - refnumSet->mRefnums.erase(std::unique(refnumSet->mRefnums.begin(), refnumSet->mRefnums.end()), refnumSet->mRefnums.end()); + refnumSet->mRefnums.erase( + std::unique(refnumSet->mRefnums.begin(), refnumSet->mRefnums.end()), refnumSet->mRefnums.end()); udc->addUserObject(refnumSet); group->addCullCallback(new SceneUtil::LightListCallback); } @@ -770,12 +823,14 @@ namespace MWRender } bool intersects(ChunkId id, osg::Vec3f pos) { - if (mActiveGridOnly && !std::get<2>(id)) return false; + if (mActiveGridOnly && !std::get<2>(id)) + return false; pos /= ESM::Land::REAL_SIZE; clampToCell(pos); osg::Vec2f center = std::get<0>(id); - float halfSize = std::get<1>(id)/2; - return pos.x() >= center.x()-halfSize && pos.y() >= center.y()-halfSize && pos.x() <= center.x()+halfSize && pos.y() <= center.y()+halfSize; + float halfSize = std::get<1>(id) / 2; + return pos.x() >= center.x() - halfSize && pos.y() >= center.y() - halfSize + && pos.x() <= center.x() + halfSize && pos.y() <= center.y() + halfSize; } void clampToCell(osg::Vec3f& cellPos) { @@ -788,37 +843,45 @@ namespace MWRender bool mActiveGridOnly = false; }; - bool ObjectPaging::enableObject(int type, const ESM::RefNum & refnum, const osg::Vec3f& pos, const osg::Vec2i& cell, bool enabled) + bool ObjectPaging::enableObject( + int type, const ESM::RefNum& refnum, const osg::Vec3f& pos, const osg::Vec2i& cell, bool enabled) { if (!typeFilter(type, false)) return false; { std::lock_guard lock(mRefTrackerMutex); - if (enabled && !getWritableRefTracker().mDisabled.erase(refnum)) return false; - if (!enabled && !getWritableRefTracker().mDisabled.insert(refnum).second) return false; - if (mRefTrackerLocked) return false; + if (enabled && !getWritableRefTracker().mDisabled.erase(refnum)) + return false; + if (!enabled && !getWritableRefTracker().mDisabled.insert(refnum).second) + return false; + if (mRefTrackerLocked) + return false; } ClearCacheFunctor ccf; ccf.mPosition = pos; ccf.mCell = cell; mCache->call(ccf); - if (ccf.mToClear.empty()) return false; + if (ccf.mToClear.empty()) + return false; for (const auto& chunk : ccf.mToClear) mCache->removeFromObjectCache(chunk); return true; } - bool ObjectPaging::blacklistObject(int type, const ESM::RefNum & refnum, const osg::Vec3f& pos, const osg::Vec2i& cell) + bool ObjectPaging::blacklistObject( + int type, const ESM::RefNum& refnum, const osg::Vec3f& pos, const osg::Vec2i& cell) { if (!typeFilter(type, false)) return false; { std::lock_guard lock(mRefTrackerMutex); - if (!getWritableRefTracker().mBlacklist.insert(refnum).second) return false; - if (mRefTrackerLocked) return false; + if (!getWritableRefTracker().mBlacklist.insert(refnum).second) + return false; + if (mRefTrackerLocked) + return false; } ClearCacheFunctor ccf; @@ -826,13 +889,13 @@ namespace MWRender ccf.mCell = cell; ccf.mActiveGridOnly = true; mCache->call(ccf); - if (ccf.mToClear.empty()) return false; + if (ccf.mToClear.empty()) + return false; for (const auto& chunk : ccf.mToClear) mCache->removeFromObjectCache(chunk); return true; } - void ObjectPaging::clear() { std::lock_guard lock(mRefTrackerMutex); @@ -843,7 +906,8 @@ namespace MWRender bool ObjectPaging::unlockCache() { - if (!mRefTrackerLocked) return false; + if (!mRefTrackerLocked) + return false; { std::lock_guard lock(mRefTrackerMutex); mRefTrackerLocked = false; @@ -858,19 +922,26 @@ namespace MWRender struct GetRefnumsFunctor { - GetRefnumsFunctor(std::vector& output) : mOutput(output) {} + GetRefnumsFunctor(std::vector& output) + : mOutput(output) + { + } void operator()(MWRender::ChunkId chunkId, osg::Object* obj) { - if (!std::get<2>(chunkId)) return; + if (!std::get<2>(chunkId)) + return; const osg::Vec2f& center = std::get<0>(chunkId); - bool activeGrid = (center.x() > mActiveGrid.x() || center.y() > mActiveGrid.y() || center.x() < mActiveGrid.z() || center.y() < mActiveGrid.w()); - if (!activeGrid) return; + bool activeGrid = (center.x() > mActiveGrid.x() || center.y() > mActiveGrid.y() + || center.x() < mActiveGrid.z() || center.y() < mActiveGrid.w()); + if (!activeGrid) + return; osg::UserDataContainer* udc = obj->getUserDataContainer(); if (udc && udc->getNumUserObjects()) { RefnumSet* refnums = dynamic_cast(udc->getUserObject(0)); - if (!refnums) return; + if (!refnums) + return; mOutput.insert(mOutput.end(), refnums->mRefnums.begin(), refnums->mRefnums.end()); } } @@ -878,7 +949,7 @@ namespace MWRender std::vector& mOutput; }; - void ObjectPaging::getPagedRefnums(const osg::Vec4i &activeGrid, std::vector& out) + void ObjectPaging::getPagedRefnums(const osg::Vec4i& activeGrid, std::vector& out) { GetRefnumsFunctor grf(out); grf.mActiveGrid = activeGrid; @@ -887,7 +958,7 @@ namespace MWRender out.erase(std::unique(out.begin(), out.end()), out.end()); } - void ObjectPaging::reportStats(unsigned int frameNumber, osg::Stats *stats) const + void ObjectPaging::reportStats(unsigned int frameNumber, osg::Stats* stats) const { stats->setAttribute(frameNumber, "Object Chunk", mCache->getCacheSize()); } diff --git a/apps/openmw/mwrender/objectpaging.hpp b/apps/openmw/mwrender/objectpaging.hpp index 246cef178f..da6e94b811 100644 --- a/apps/openmw/mwrender/objectpaging.hpp +++ b/apps/openmw/mwrender/objectpaging.hpp @@ -1,9 +1,9 @@ #ifndef OPENMW_MWRENDER_OBJECTPAGING_H #define OPENMW_MWRENDER_OBJECTPAGING_H -#include -#include #include +#include +#include #include @@ -27,17 +27,20 @@ namespace MWRender ObjectPaging(Resource::SceneManager* sceneManager); ~ObjectPaging() = default; - osg::ref_ptr getChunk(float size, const osg::Vec2f& center, unsigned char lod, unsigned int lodFlags, bool activeGrid, const osg::Vec3f& viewPoint, bool compile) override; + osg::ref_ptr getChunk(float size, const osg::Vec2f& center, unsigned char lod, unsigned int lodFlags, + bool activeGrid, const osg::Vec3f& viewPoint, bool compile) override; - osg::ref_ptr createChunk(float size, const osg::Vec2f& center, bool activeGrid, const osg::Vec3f& viewPoint, bool compile, unsigned char lod); + osg::ref_ptr createChunk(float size, const osg::Vec2f& center, bool activeGrid, + const osg::Vec3f& viewPoint, bool compile, unsigned char lod); unsigned int getNodeMask() override; /// @return true if view needs rebuild - bool enableObject(int type, const ESM::RefNum & refnum, const osg::Vec3f& pos, const osg::Vec2i& cell, bool enabled); + bool enableObject( + int type, const ESM::RefNum& refnum, const osg::Vec3f& pos, const osg::Vec2i& cell, bool enabled); /// @return true if view needs rebuild - bool blacklistObject(int type, const ESM::RefNum & refnum, const osg::Vec3f& pos, const osg::Vec2i& cell); + bool blacklistObject(int type, const ESM::RefNum& refnum, const osg::Vec3f& pos, const osg::Vec2i& cell); void clear(); @@ -47,7 +50,7 @@ namespace MWRender void reportStats(unsigned int frameNumber, osg::Stats* stats) const override; - void getPagedRefnums(const osg::Vec4i &activeGrid, std::vector& out); + void getPagedRefnums(const osg::Vec4i& activeGrid, std::vector& out); private: Resource::SceneManager* mSceneManager; @@ -63,7 +66,10 @@ namespace MWRender { std::set mDisabled; std::set mBlacklist; - bool operator==(const RefTracker&other) const { return mDisabled == other.mDisabled && mBlacklist == other.mBlacklist; } + bool operator==(const RefTracker& other) const + { + return mDisabled == other.mDisabled && mBlacklist == other.mBlacklist; + } }; RefTracker mRefTracker; RefTracker mRefTrackerNew; @@ -77,16 +83,24 @@ namespace MWRender SizeCache mSizeCache; std::mutex mLODNameCacheMutex; - typedef std::pair LODNameCacheKey; //Key: mesh name, lod level - typedef std::map LODNameCache; //Cache: key, mesh name to use + typedef std::pair LODNameCacheKey; // Key: mesh name, lod level + typedef std::map LODNameCache; // Cache: key, mesh name to use LODNameCache mLODNameCache; }; class RefnumMarker : public osg::Object { public: - RefnumMarker() : mNumVertices(0) { mRefnum.unset(); } - RefnumMarker(const RefnumMarker ©, osg::CopyOp co) : mRefnum(copy.mRefnum), mNumVertices(copy.mNumVertices) {} + RefnumMarker() + : mNumVertices(0) + { + mRefnum.unset(); + } + RefnumMarker(const RefnumMarker& copy, osg::CopyOp co) + : mRefnum(copy.mRefnum) + , mNumVertices(copy.mNumVertices) + { + } META_Object(MWRender, RefnumMarker) ESM::RefNum mRefnum; diff --git a/apps/openmw/mwrender/objects.cpp b/apps/openmw/mwrender/objects.cpp index 88b86d8e8a..2d42623bd2 100644 --- a/apps/openmw/mwrender/objects.cpp +++ b/apps/openmw/mwrender/objects.cpp @@ -6,219 +6,221 @@ #include #include -#include "../mwworld/ptr.hpp" #include "../mwworld/class.hpp" +#include "../mwworld/ptr.hpp" #include "animation.hpp" -#include "npcanimation.hpp" #include "creatureanimation.hpp" +#include "npcanimation.hpp" #include "vismask.hpp" - namespace MWRender { -Objects::Objects(Resource::ResourceSystem* resourceSystem, const osg::ref_ptr& rootNode, - SceneUtil::UnrefQueue& unrefQueue) - : mRootNode(rootNode) - , mResourceSystem(resourceSystem) - , mUnrefQueue(unrefQueue) -{ -} - -Objects::~Objects() -{ - mObjects.clear(); - - for (CellMap::iterator iter = mCellSceneNodes.begin(); iter != mCellSceneNodes.end(); ++iter) - iter->second->getParent(0)->removeChild(iter->second); - mCellSceneNodes.clear(); -} - -void Objects::insertBegin(const MWWorld::Ptr& ptr) -{ - assert(mObjects.find(ptr.mRef) == mObjects.end()); - - osg::ref_ptr cellnode; + Objects::Objects(Resource::ResourceSystem* resourceSystem, const osg::ref_ptr& rootNode, + SceneUtil::UnrefQueue& unrefQueue) + : mRootNode(rootNode) + , mResourceSystem(resourceSystem) + , mUnrefQueue(unrefQueue) + { + } - CellMap::iterator found = mCellSceneNodes.find(ptr.getCell()); - if (found == mCellSceneNodes.end()) + Objects::~Objects() { - cellnode = new osg::Group; - cellnode->setName("Cell Root"); - mRootNode->addChild(cellnode); - mCellSceneNodes[ptr.getCell()] = cellnode; + mObjects.clear(); + + for (CellMap::iterator iter = mCellSceneNodes.begin(); iter != mCellSceneNodes.end(); ++iter) + iter->second->getParent(0)->removeChild(iter->second); + mCellSceneNodes.clear(); } - else - cellnode = found->second; - osg::ref_ptr insert (new SceneUtil::PositionAttitudeTransform); - cellnode->addChild(insert); + void Objects::insertBegin(const MWWorld::Ptr& ptr) + { + assert(mObjects.find(ptr.mRef) == mObjects.end()); - insert->getOrCreateUserDataContainer()->addUserObject(new PtrHolder(ptr)); + osg::ref_ptr cellnode; - const float *f = ptr.getRefData().getPosition().pos; + CellMap::iterator found = mCellSceneNodes.find(ptr.getCell()); + if (found == mCellSceneNodes.end()) + { + cellnode = new osg::Group; + cellnode->setName("Cell Root"); + mRootNode->addChild(cellnode); + mCellSceneNodes[ptr.getCell()] = cellnode; + } + else + cellnode = found->second; - insert->setPosition(osg::Vec3(f[0], f[1], f[2])); + osg::ref_ptr insert(new SceneUtil::PositionAttitudeTransform); + cellnode->addChild(insert); - const float scale = ptr.getCellRef().getScale(); - osg::Vec3f scaleVec(scale, scale, scale); - ptr.getClass().adjustScale(ptr, scaleVec, true); - insert->setScale(scaleVec); + insert->getOrCreateUserDataContainer()->addUserObject(new PtrHolder(ptr)); - ptr.getRefData().setBaseNode(insert); -} + const float* f = ptr.getRefData().getPosition().pos; -void Objects::insertModel(const MWWorld::Ptr &ptr, const std::string &mesh, bool animated, bool allowLight) -{ - insertBegin(ptr); - ptr.getRefData().getBaseNode()->setNodeMask(Mask_Object); + insert->setPosition(osg::Vec3(f[0], f[1], f[2])); - osg::ref_ptr anim (new ObjectAnimation(ptr, mesh, mResourceSystem, animated, allowLight)); + const float scale = ptr.getCellRef().getScale(); + osg::Vec3f scaleVec(scale, scale, scale); + ptr.getClass().adjustScale(ptr, scaleVec, true); + insert->setScale(scaleVec); - mObjects.emplace(ptr.mRef, std::move(anim)); -} + ptr.getRefData().setBaseNode(insert); + } -void Objects::insertCreature(const MWWorld::Ptr &ptr, const std::string &mesh, bool weaponsShields) -{ - insertBegin(ptr); - ptr.getRefData().getBaseNode()->setNodeMask(Mask_Actor); + void Objects::insertModel(const MWWorld::Ptr& ptr, const std::string& mesh, bool animated, bool allowLight) + { + insertBegin(ptr); + ptr.getRefData().getBaseNode()->setNodeMask(Mask_Object); - // CreatureAnimation - osg::ref_ptr anim; + osg::ref_ptr anim(new ObjectAnimation(ptr, mesh, mResourceSystem, animated, allowLight)); - if (weaponsShields) - anim = new CreatureWeaponAnimation(ptr, mesh, mResourceSystem); - else - anim = new CreatureAnimation(ptr, mesh, mResourceSystem); + mObjects.emplace(ptr.mRef, std::move(anim)); + } - if (mObjects.emplace(ptr.mRef, anim).second) - ptr.getClass().getContainerStore(ptr).setContListener(static_cast(anim.get())); -} + void Objects::insertCreature(const MWWorld::Ptr& ptr, const std::string& mesh, bool weaponsShields) + { + insertBegin(ptr); + ptr.getRefData().getBaseNode()->setNodeMask(Mask_Actor); -void Objects::insertNPC(const MWWorld::Ptr &ptr) -{ - insertBegin(ptr); - ptr.getRefData().getBaseNode()->setNodeMask(Mask_Actor); + // CreatureAnimation + osg::ref_ptr anim; - osg::ref_ptr anim (new NpcAnimation(ptr, osg::ref_ptr(ptr.getRefData().getBaseNode()), mResourceSystem)); + if (weaponsShields) + anim = new CreatureWeaponAnimation(ptr, mesh, mResourceSystem); + else + anim = new CreatureAnimation(ptr, mesh, mResourceSystem); - if (mObjects.emplace(ptr.mRef, anim).second) - { - ptr.getClass().getInventoryStore(ptr).setInvListener(anim.get(), ptr); - ptr.getClass().getInventoryStore(ptr).setContListener(anim.get()); + if (mObjects.emplace(ptr.mRef, anim).second) + ptr.getClass().getContainerStore(ptr).setContListener(static_cast(anim.get())); } -} - -bool Objects::removeObject (const MWWorld::Ptr& ptr) -{ - if(!ptr.getRefData().getBaseNode()) - return true; - const auto iter = mObjects.find(ptr.mRef); - if(iter != mObjects.end()) + void Objects::insertNPC(const MWWorld::Ptr& ptr) { - iter->second->removeFromScene(); - mUnrefQueue.push(std::move(iter->second)); - mObjects.erase(iter); + insertBegin(ptr); + ptr.getRefData().getBaseNode()->setNodeMask(Mask_Actor); - if (ptr.getClass().isActor()) - { - if (ptr.getClass().hasInventoryStore(ptr)) - ptr.getClass().getInventoryStore(ptr).setInvListener(nullptr, ptr); + osg::ref_ptr anim( + new NpcAnimation(ptr, osg::ref_ptr(ptr.getRefData().getBaseNode()), mResourceSystem)); - ptr.getClass().getContainerStore(ptr).setContListener(nullptr); + if (mObjects.emplace(ptr.mRef, anim).second) + { + ptr.getClass().getInventoryStore(ptr).setInvListener(anim.get(), ptr); + ptr.getClass().getInventoryStore(ptr).setContListener(anim.get()); } - - ptr.getRefData().getBaseNode()->getParent(0)->removeChild(ptr.getRefData().getBaseNode()); - - ptr.getRefData().setBaseNode(nullptr); - return true; } - return false; -} - -void Objects::removeCell(const MWWorld::CellStore* store) -{ - for(PtrAnimationMap::iterator iter = mObjects.begin();iter != mObjects.end();) + bool Objects::removeObject(const MWWorld::Ptr& ptr) { - MWWorld::Ptr ptr = iter->second->getPtr(); - if(ptr.getCell() == store) + if (!ptr.getRefData().getBaseNode()) + return true; + + const auto iter = mObjects.find(ptr.mRef); + if (iter != mObjects.end()) { - if (ptr.getClass().isActor() && ptr.getRefData().getCustomData()) + iter->second->removeFromScene(); + mUnrefQueue.push(std::move(iter->second)); + mObjects.erase(iter); + + if (ptr.getClass().isActor()) { if (ptr.getClass().hasInventoryStore(ptr)) ptr.getClass().getInventoryStore(ptr).setInvListener(nullptr, ptr); + ptr.getClass().getContainerStore(ptr).setContListener(nullptr); } - iter->second->removeFromScene(); - mUnrefQueue.push(std::move(iter->second)); - iter = mObjects.erase(iter); + ptr.getRefData().getBaseNode()->getParent(0)->removeChild(ptr.getRefData().getBaseNode()); + + ptr.getRefData().setBaseNode(nullptr); + return true; } - else - ++iter; + return false; } - CellMap::iterator cell = mCellSceneNodes.find(store); - if(cell != mCellSceneNodes.end()) + void Objects::removeCell(const MWWorld::CellStore* store) { - cell->second->getParent(0)->removeChild(cell->second); - mCellSceneNodes.erase(cell); - } -} + for (PtrAnimationMap::iterator iter = mObjects.begin(); iter != mObjects.end();) + { + MWWorld::Ptr ptr = iter->second->getPtr(); + if (ptr.getCell() == store) + { + if (ptr.getClass().isActor() && ptr.getRefData().getCustomData()) + { + if (ptr.getClass().hasInventoryStore(ptr)) + ptr.getClass().getInventoryStore(ptr).setInvListener(nullptr, ptr); + ptr.getClass().getContainerStore(ptr).setContListener(nullptr); + } + + iter->second->removeFromScene(); + mUnrefQueue.push(std::move(iter->second)); + iter = mObjects.erase(iter); + } + else + ++iter; + } -void Objects::updatePtr(const MWWorld::Ptr &old, const MWWorld::Ptr &cur) -{ - osg::ref_ptr objectNode = cur.getRefData().getBaseNode(); - if (!objectNode) - return; - - MWWorld::CellStore *newCell = cur.getCell(); - - osg::Group* cellnode; - if(mCellSceneNodes.find(newCell) == mCellSceneNodes.end()) { - cellnode = new osg::Group; - mRootNode->addChild(cellnode); - mCellSceneNodes[newCell] = cellnode; - } else { - cellnode = mCellSceneNodes[newCell]; + CellMap::iterator cell = mCellSceneNodes.find(store); + if (cell != mCellSceneNodes.end()) + { + cell->second->getParent(0)->removeChild(cell->second); + mCellSceneNodes.erase(cell); + } } - osg::UserDataContainer* userDataContainer = objectNode->getUserDataContainer(); - if (userDataContainer) - for (unsigned int i=0; igetNumUserObjects(); ++i) + void Objects::updatePtr(const MWWorld::Ptr& old, const MWWorld::Ptr& cur) + { + osg::ref_ptr objectNode = cur.getRefData().getBaseNode(); + if (!objectNode) + return; + + MWWorld::CellStore* newCell = cur.getCell(); + + osg::Group* cellnode; + if (mCellSceneNodes.find(newCell) == mCellSceneNodes.end()) + { + cellnode = new osg::Group; + mRootNode->addChild(cellnode); + mCellSceneNodes[newCell] = cellnode; + } + else { - if (dynamic_cast(userDataContainer->getUserObject(i))) - userDataContainer->setUserObject(i, new PtrHolder(cur)); + cellnode = mCellSceneNodes[newCell]; } - if (objectNode->getNumParents()) - objectNode->getParent(0)->removeChild(objectNode); - cellnode->addChild(objectNode); + osg::UserDataContainer* userDataContainer = objectNode->getUserDataContainer(); + if (userDataContainer) + for (unsigned int i = 0; i < userDataContainer->getNumUserObjects(); ++i) + { + if (dynamic_cast(userDataContainer->getUserObject(i))) + userDataContainer->setUserObject(i, new PtrHolder(cur)); + } - PtrAnimationMap::iterator iter = mObjects.find(old.mRef); - if(iter != mObjects.end()) - iter->second->updatePtr(cur); -} + if (objectNode->getNumParents()) + objectNode->getParent(0)->removeChild(objectNode); + cellnode->addChild(objectNode); -Animation* Objects::getAnimation(const MWWorld::Ptr &ptr) -{ - PtrAnimationMap::const_iterator iter = mObjects.find(ptr.mRef); - if(iter != mObjects.end()) - return iter->second; + PtrAnimationMap::iterator iter = mObjects.find(old.mRef); + if (iter != mObjects.end()) + iter->second->updatePtr(cur); + } - return nullptr; -} + Animation* Objects::getAnimation(const MWWorld::Ptr& ptr) + { + PtrAnimationMap::const_iterator iter = mObjects.find(ptr.mRef); + if (iter != mObjects.end()) + return iter->second; -const Animation* Objects::getAnimation(const MWWorld::ConstPtr &ptr) const -{ - PtrAnimationMap::const_iterator iter = mObjects.find(ptr.mRef); - if(iter != mObjects.end()) - return iter->second; + return nullptr; + } - return nullptr; -} + const Animation* Objects::getAnimation(const MWWorld::ConstPtr& ptr) const + { + PtrAnimationMap::const_iterator iter = mObjects.find(ptr.mRef); + if (iter != mObjects.end()) + return iter->second; + + return nullptr; + } } diff --git a/apps/openmw/mwrender/objects.hpp b/apps/openmw/mwrender/objects.hpp index 2ca3da0c86..339079cb0a 100644 --- a/apps/openmw/mwrender/objects.hpp +++ b/apps/openmw/mwrender/objects.hpp @@ -4,8 +4,8 @@ #include #include -#include #include +#include #include "../mwworld/ptr.hpp" @@ -29,71 +29,71 @@ namespace SceneUtil class UnrefQueue; } -namespace MWRender{ +namespace MWRender +{ -class Animation; + class Animation; -class PtrHolder : public osg::Object -{ -public: - PtrHolder(const MWWorld::Ptr& ptr) - : mPtr(ptr) + class PtrHolder : public osg::Object { - } + public: + PtrHolder(const MWWorld::Ptr& ptr) + : mPtr(ptr) + { + } - PtrHolder() - { - } + PtrHolder() {} - PtrHolder(const PtrHolder& copy, const osg::CopyOp& copyop) - : mPtr(copy.mPtr) - { - } + PtrHolder(const PtrHolder& copy, const osg::CopyOp& copyop) + : mPtr(copy.mPtr) + { + } - META_Object(MWRender, PtrHolder) + META_Object(MWRender, PtrHolder) - MWWorld::Ptr mPtr; -}; + MWWorld::Ptr mPtr; + }; -class Objects -{ - using PtrAnimationMap = std::map>; + class Objects + { + using PtrAnimationMap = std::map>; - typedef std::map > CellMap; - CellMap mCellSceneNodes; - PtrAnimationMap mObjects; - osg::ref_ptr mRootNode; - Resource::ResourceSystem* mResourceSystem; - SceneUtil::UnrefQueue& mUnrefQueue; + typedef std::map> CellMap; + CellMap mCellSceneNodes; + PtrAnimationMap mObjects; + osg::ref_ptr mRootNode; + Resource::ResourceSystem* mResourceSystem; + SceneUtil::UnrefQueue& mUnrefQueue; - void insertBegin(const MWWorld::Ptr& ptr); + void insertBegin(const MWWorld::Ptr& ptr); -public: - Objects(Resource::ResourceSystem* resourceSystem, const osg::ref_ptr& rootNode, - SceneUtil::UnrefQueue& unrefQueue); - ~Objects(); + public: + Objects(Resource::ResourceSystem* resourceSystem, const osg::ref_ptr& rootNode, + SceneUtil::UnrefQueue& unrefQueue); + ~Objects(); - /// @param animated Attempt to load separate keyframes from a .kf file matching the model file? - /// @param allowLight If false, no lights will be created, and particles systems will be removed. - void insertModel(const MWWorld::Ptr& ptr, const std::string &model, bool animated=false, bool allowLight=true); + /// @param animated Attempt to load separate keyframes from a .kf file matching the model file? + /// @param allowLight If false, no lights will be created, and particles systems will be removed. + void insertModel( + const MWWorld::Ptr& ptr, const std::string& model, bool animated = false, bool allowLight = true); - void insertNPC(const MWWorld::Ptr& ptr); - void insertCreature (const MWWorld::Ptr& ptr, const std::string& model, bool weaponsShields); + void insertNPC(const MWWorld::Ptr& ptr); + void insertCreature(const MWWorld::Ptr& ptr, const std::string& model, bool weaponsShields); - Animation* getAnimation(const MWWorld::Ptr &ptr); - const Animation* getAnimation(const MWWorld::ConstPtr &ptr) const; + Animation* getAnimation(const MWWorld::Ptr& ptr); + const Animation* getAnimation(const MWWorld::ConstPtr& ptr) const; - bool removeObject (const MWWorld::Ptr& ptr); - ///< \return found? + bool removeObject(const MWWorld::Ptr& ptr); + ///< \return found? - void removeCell(const MWWorld::CellStore* store); + void removeCell(const MWWorld::CellStore* store); - /// Updates containing cell for object rendering data - void updatePtr(const MWWorld::Ptr &old, const MWWorld::Ptr &cur); + /// Updates containing cell for object rendering data + void updatePtr(const MWWorld::Ptr& old, const MWWorld::Ptr& cur); -private: - void operator = (const Objects&); - Objects(const Objects&); -}; + private: + void operator=(const Objects&); + Objects(const Objects&); + }; } #endif diff --git a/apps/openmw/mwrender/pathgrid.cpp b/apps/openmw/mwrender/pathgrid.cpp index ec7d2c15e0..9ad25bb3b3 100644 --- a/apps/openmw/mwrender/pathgrid.cpp +++ b/apps/openmw/mwrender/pathgrid.cpp @@ -3,155 +3,156 @@ #include #include -#include #include +#include #include -#include -#include #include #include #include +#include +#include -#include "../mwbase/world.hpp" // these includes can be removed once the static-hack is gone #include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" // these includes can be removed once the static-hack is gone +#include "../mwmechanics/pathfinding.hpp" #include "../mwworld/cellstore.hpp" #include "../mwworld/esmstore.hpp" -#include "../mwmechanics/pathfinding.hpp" #include "vismask.hpp" namespace MWRender { -Pathgrid::Pathgrid(osg::ref_ptr root) - : mPathgridEnabled(false) - , mRootNode(root) - , mPathGridRoot(nullptr) - , mInteriorPathgridNode(nullptr) -{ -} - -Pathgrid::~Pathgrid() -{ - if (mPathgridEnabled) + Pathgrid::Pathgrid(osg::ref_ptr root) + : mPathgridEnabled(false) + , mRootNode(root) + , mPathGridRoot(nullptr) + , mInteriorPathgridNode(nullptr) { - togglePathgrid(); } -} - -bool Pathgrid::toggleRenderMode (int mode){ - switch (mode) + Pathgrid::~Pathgrid() { - case Render_Pathgrid: + if (mPathgridEnabled) + { togglePathgrid(); - return mPathgridEnabled; - default: - return false; + } } - return false; -} - -void Pathgrid::addCell(const MWWorld::CellStore *store) -{ - mActiveCells.push_back(store); - if (mPathgridEnabled) - enableCellPathgrid(store); -} + bool Pathgrid::toggleRenderMode(int mode) + { + switch (mode) + { + case Render_Pathgrid: + togglePathgrid(); + return mPathgridEnabled; + default: + return false; + } -void Pathgrid::removeCell(const MWWorld::CellStore *store) -{ - mActiveCells.erase(std::remove(mActiveCells.begin(), mActiveCells.end(), store), mActiveCells.end()); - if (mPathgridEnabled) - disableCellPathgrid(store); -} + return false; + } -void Pathgrid::togglePathgrid() -{ - mPathgridEnabled = !mPathgridEnabled; - if (mPathgridEnabled) + void Pathgrid::addCell(const MWWorld::CellStore* store) { - // add path grid meshes to already loaded cells - mPathGridRoot = new osg::Group; - mPathGridRoot->setNodeMask(Mask_Debug); - mRootNode->addChild(mPathGridRoot); + mActiveCells.push_back(store); + if (mPathgridEnabled) + enableCellPathgrid(store); + } - for(const MWWorld::CellStore* cell : mActiveCells) - { - enableCellPathgrid(cell); - } + void Pathgrid::removeCell(const MWWorld::CellStore* store) + { + mActiveCells.erase(std::remove(mActiveCells.begin(), mActiveCells.end(), store), mActiveCells.end()); + if (mPathgridEnabled) + disableCellPathgrid(store); } - else + + void Pathgrid::togglePathgrid() { - // remove path grid meshes from already loaded cells - for(const MWWorld::CellStore* cell : mActiveCells) + mPathgridEnabled = !mPathgridEnabled; + if (mPathgridEnabled) { - disableCellPathgrid(cell); + // add path grid meshes to already loaded cells + mPathGridRoot = new osg::Group; + mPathGridRoot->setNodeMask(Mask_Debug); + mRootNode->addChild(mPathGridRoot); + + for (const MWWorld::CellStore* cell : mActiveCells) + { + enableCellPathgrid(cell); + } } - - if (mPathGridRoot) + else { - mRootNode->removeChild(mPathGridRoot); - mPathGridRoot = nullptr; + // remove path grid meshes from already loaded cells + for (const MWWorld::CellStore* cell : mActiveCells) + { + disableCellPathgrid(cell); + } + + if (mPathGridRoot) + { + mRootNode->removeChild(mPathGridRoot); + mPathGridRoot = nullptr; + } } } -} -void Pathgrid::enableCellPathgrid(const MWWorld::CellStore *store) -{ - MWBase::World* world = MWBase::Environment::get().getWorld(); - const ESM::Pathgrid *pathgrid = - world->getStore().get().search(*store->getCell()); - if (!pathgrid) return; + void Pathgrid::enableCellPathgrid(const MWWorld::CellStore* store) + { + MWBase::World* world = MWBase::Environment::get().getWorld(); + const ESM::Pathgrid* pathgrid = world->getStore().get().search(*store->getCell()); + if (!pathgrid) + return; - osg::Vec3f cellPathGridPos(0, 0, 0); - Misc::CoordinateConverter(store->getCell()).toWorld(cellPathGridPos); + osg::Vec3f cellPathGridPos(0, 0, 0); + Misc::CoordinateConverter(store->getCell()).toWorld(cellPathGridPos); - osg::ref_ptr cellPathGrid = new osg::PositionAttitudeTransform; - cellPathGrid->setPosition(cellPathGridPos); + osg::ref_ptr cellPathGrid = new osg::PositionAttitudeTransform; + cellPathGrid->setPosition(cellPathGridPos); - osg::ref_ptr geometry = SceneUtil::createPathgridGeometry(*pathgrid); + osg::ref_ptr geometry = SceneUtil::createPathgridGeometry(*pathgrid); - MWBase::Environment::get().getResourceSystem()->getSceneManager()->recreateShaders(geometry, "debug"); + MWBase::Environment::get().getResourceSystem()->getSceneManager()->recreateShaders(geometry, "debug"); - cellPathGrid->addChild(geometry); + cellPathGrid->addChild(geometry); - mPathGridRoot->addChild(cellPathGrid); + mPathGridRoot->addChild(cellPathGrid); - if (store->getCell()->isExterior()) - { - mExteriorPathgridNodes[std::make_pair(store->getCell()->getGridX(), store->getCell()->getGridY())] = cellPathGrid; - } - else - { - assert(mInteriorPathgridNode == nullptr); - mInteriorPathgridNode = cellPathGrid; + if (store->getCell()->isExterior()) + { + mExteriorPathgridNodes[std::make_pair(store->getCell()->getGridX(), store->getCell()->getGridY())] + = cellPathGrid; + } + else + { + assert(mInteriorPathgridNode == nullptr); + mInteriorPathgridNode = cellPathGrid; + } } -} -void Pathgrid::disableCellPathgrid(const MWWorld::CellStore *store) -{ - if (store->getCell()->isExterior()) + void Pathgrid::disableCellPathgrid(const MWWorld::CellStore* store) { - ExteriorPathgridNodes::iterator it = - mExteriorPathgridNodes.find(std::make_pair(store->getCell()->getGridX(), store->getCell()->getGridY())); - if (it != mExteriorPathgridNodes.end()) + if (store->getCell()->isExterior()) { - mPathGridRoot->removeChild(it->second); - mExteriorPathgridNodes.erase(it); + ExteriorPathgridNodes::iterator it = mExteriorPathgridNodes.find( + std::make_pair(store->getCell()->getGridX(), store->getCell()->getGridY())); + if (it != mExteriorPathgridNodes.end()) + { + mPathGridRoot->removeChild(it->second); + mExteriorPathgridNodes.erase(it); + } } - } - else - { - if (mInteriorPathgridNode) + else { - mPathGridRoot->removeChild(mInteriorPathgridNode); - mInteriorPathgridNode = nullptr; + if (mInteriorPathgridNode) + { + mPathGridRoot->removeChild(mInteriorPathgridNode); + mInteriorPathgridNode = nullptr; + } } } -} } diff --git a/apps/openmw/mwrender/pathgrid.hpp b/apps/openmw/mwrender/pathgrid.hpp index 77f1a7f337..ef815d3962 100644 --- a/apps/openmw/mwrender/pathgrid.hpp +++ b/apps/openmw/mwrender/pathgrid.hpp @@ -3,8 +3,8 @@ #include -#include #include +#include #include @@ -33,30 +33,29 @@ namespace MWRender void togglePathgrid(); - typedef std::vector CellList; + typedef std::vector CellList; CellList mActiveCells; osg::ref_ptr mRootNode; osg::ref_ptr mPathGridRoot; - typedef std::map, osg::ref_ptr > ExteriorPathgridNodes; + typedef std::map, osg::ref_ptr> ExteriorPathgridNodes; ExteriorPathgridNodes mExteriorPathgridNodes; osg::ref_ptr mInteriorPathgridNode; - void enableCellPathgrid(const MWWorld::CellStore *store); - void disableCellPathgrid(const MWWorld::CellStore *store); + void enableCellPathgrid(const MWWorld::CellStore* store); + void disableCellPathgrid(const MWWorld::CellStore* store); public: Pathgrid(osg::ref_ptr root); ~Pathgrid(); - bool toggleRenderMode (int mode); + bool toggleRenderMode(int mode); void addCell(const MWWorld::CellStore* store); void removeCell(const MWWorld::CellStore* store); }; - } #endif diff --git a/apps/openmw/mwrender/pingpongcanvas.cpp b/apps/openmw/mwrender/pingpongcanvas.cpp index 16c59787a2..3276b7addc 100644 --- a/apps/openmw/mwrender/pingpongcanvas.cpp +++ b/apps/openmw/mwrender/pingpongcanvas.cpp @@ -1,9 +1,9 @@ #include "pingpongcanvas.hpp" -#include #include -#include +#include #include +#include #include @@ -41,7 +41,8 @@ namespace MWRender mFallbackStateSet->addUniform(new osg::Uniform("omw_SamplerLastShader", 0)); auto multiviewResolveVertex = shaderManager.getShader("multiview_resolve_vertex.glsl", {}, osg::Shader::VERTEX); - auto multiviewResolveFragment = shaderManager.getShader("multiview_resolve_fragment.glsl", {}, osg::Shader::FRAGMENT); + auto multiviewResolveFragment + = shaderManager.getShader("multiview_resolve_fragment.glsl", {}, osg::Shader::FRAGMENT); mMultiviewResolveProgram = shaderManager.getProgram(multiviewResolveVertex, multiviewResolveFragment); mMultiviewResolveStateSet->setAttributeAndModes(mMultiviewResolveProgram); mMultiviewResolveStateSet->addUniform(new osg::Uniform("omw_SamplerLastShader", 0)); @@ -56,8 +57,10 @@ namespace MWRender { mBufferData[frameId].mask = 0; - mBufferData[frameId].mask |= underwater ? fx::Technique::Flag_Disable_Underwater : fx::Technique::Flag_Disable_Abovewater; - mBufferData[frameId].mask |= exterior ? fx::Technique::Flag_Disable_Exteriors : fx::Technique::Flag_Disable_Interiors; + mBufferData[frameId].mask + |= underwater ? fx::Technique::Flag_Disable_Underwater : fx::Technique::Flag_Disable_Abovewater; + mBufferData[frameId].mask + |= exterior ? fx::Technique::Flag_Disable_Exteriors : fx::Technique::Flag_Disable_Interiors; } void PingPongCanvas::drawGeometry(osg::RenderInfo& renderInfo) const @@ -65,7 +68,8 @@ namespace MWRender osg::Geometry::drawImplementation(renderInfo); } - static void attachCloneOfTemplate(osg::FrameBufferObject* fbo, osg::Camera::BufferComponent component, osg::Texture* tex) + static void attachCloneOfTemplate( + osg::FrameBufferObject* fbo, osg::Camera::BufferComponent component, osg::Texture* tex) { osg::ref_ptr clone = static_cast(tex->clone(osg::CopyOp::SHALLOW_COPY)); fbo->setAttachment(component, Stereo::createMultiviewCompatibleAttachment(clone)); @@ -130,7 +134,8 @@ namespace MWRender for (auto& fbo : mFbos) { fbo = new osg::FrameBufferObject; - attachCloneOfTemplate(fbo, osg::FrameBufferObject::BufferComponent::COLOR_BUFFER0, bufferData.sceneTexLDR); + attachCloneOfTemplate( + fbo, osg::FrameBufferObject::BufferComponent::COLOR_BUFFER0, bufferData.sceneTexLDR); fbo->apply(state); glClearColor(0.5, 0.5, 0.5, 1); glClear(GL_COLOR_BUFFER_BIT); @@ -139,33 +144,37 @@ namespace MWRender if (Stereo::getMultiview()) { mMultiviewResolveFramebuffer = new osg::FrameBufferObject(); - attachCloneOfTemplate(mMultiviewResolveFramebuffer, osg::FrameBufferObject::BufferComponent::COLOR_BUFFER0, bufferData.sceneTexLDR); + attachCloneOfTemplate(mMultiviewResolveFramebuffer, + osg::FrameBufferObject::BufferComponent::COLOR_BUFFER0, bufferData.sceneTexLDR); mMultiviewResolveFramebuffer->apply(state); glClearColor(0.5, 0.5, 0.5, 1); glClear(GL_COLOR_BUFFER_BIT); - mMultiviewResolveStateSet->setTextureAttribute(PostProcessor::Unit_LastShader, (osg::Texture*)mMultiviewResolveFramebuffer->getAttachment(osg::Camera::COLOR_BUFFER0).getTexture()); + mMultiviewResolveStateSet->setTextureAttribute(PostProcessor::Unit_LastShader, + (osg::Texture*)mMultiviewResolveFramebuffer->getAttachment(osg::Camera::COLOR_BUFFER0) + .getTexture()); } mLuminanceCalculator.dirty(bufferData.sceneTex->getTextureWidth(), bufferData.sceneTex->getTextureHeight()); if (Stereo::getStereo()) - mRenderViewport = new osg::Viewport(0, 0, bufferData.sceneTex->getTextureWidth(), bufferData.sceneTex->getTextureHeight()); + mRenderViewport = new osg::Viewport( + 0, 0, bufferData.sceneTex->getTextureWidth(), bufferData.sceneTex->getTextureHeight()); else mRenderViewport = nullptr; bufferData.dirty = false; } - constexpr std::array, 3> buffers = {{ - {GL_COLOR_ATTACHMENT1_EXT, GL_COLOR_ATTACHMENT2_EXT}, - {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT2_EXT}, - {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT} - }}; + constexpr std::array, 3> buffers + = { { { GL_COLOR_ATTACHMENT1_EXT, GL_COLOR_ATTACHMENT2_EXT }, + { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT2_EXT }, + { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT } } }; (bufferData.hdr) ? mLuminanceCalculator.enable() : mLuminanceCalculator.disable(); - // A histogram based approach is superior way to calculate scene luminance. Using mipmaps is more broadly supported, so that's what we use for now. + // A histogram based approach is superior way to calculate scene luminance. Using mipmaps is more broadly + // supported, so that's what we use for now. mLuminanceCalculator.draw(*this, renderInfo, state, ext, frameId); auto buffer = buffers[0]; @@ -177,7 +186,8 @@ namespace MWRender const unsigned int cid = state.getContextID(); - const osg::ref_ptr& destinationFbo = bufferData.destination ? bufferData.destination : nullptr; + const osg::ref_ptr& destinationFbo + = bufferData.destination ? bufferData.destination : nullptr; unsigned int destinationHandle = destinationFbo ? destinationFbo->getHandle(cid) : 0; auto bindDestinationFbo = [&]() { @@ -206,10 +216,12 @@ namespace MWRender node.mRootStateSet->setTextureAttribute(PostProcessor::Unit_Depth, bufferData.depthTex); if (bufferData.hdr) - node.mRootStateSet->setTextureAttribute(PostProcessor::TextureUnits::Unit_EyeAdaptation, mLuminanceCalculator.getLuminanceTexture(frameId)); + node.mRootStateSet->setTextureAttribute( + PostProcessor::TextureUnits::Unit_EyeAdaptation, mLuminanceCalculator.getLuminanceTexture(frameId)); if (bufferData.normalsTex) - node.mRootStateSet->setTextureAttribute(PostProcessor::TextureUnits::Unit_Normals, bufferData.normalsTex); + node.mRootStateSet->setTextureAttribute( + PostProcessor::TextureUnits::Unit_Normals, bufferData.normalsTex); state.pushStateSet(node.mRootStateSet); state.apply(); @@ -222,16 +234,22 @@ namespace MWRender bool lastPass = passIndex == node.mPasses.size() - 1; - //VR-TODO: This won't actually work for tex2darrays + // VR-TODO: This won't actually work for tex2darrays if (lastShader == 0) pass.mStateSet->setTextureAttribute(PostProcessor::Unit_LastShader, bufferData.sceneTex); else - pass.mStateSet->setTextureAttribute(PostProcessor::Unit_LastShader, (osg::Texture*)mFbos[lastShader - GL_COLOR_ATTACHMENT0_EXT]->getAttachment(osg::Camera::COLOR_BUFFER0).getTexture()); + pass.mStateSet->setTextureAttribute(PostProcessor::Unit_LastShader, + (osg::Texture*)mFbos[lastShader - GL_COLOR_ATTACHMENT0_EXT] + ->getAttachment(osg::Camera::COLOR_BUFFER0) + .getTexture()); if (lastDraw == 0) pass.mStateSet->setTextureAttribute(PostProcessor::Unit_LastPass, bufferData.sceneTex); else - pass.mStateSet->setTextureAttribute(PostProcessor::Unit_LastPass, (osg::Texture*)mFbos[lastDraw - GL_COLOR_ATTACHMENT0_EXT]->getAttachment(osg::Camera::COLOR_BUFFER0).getTexture()); + pass.mStateSet->setTextureAttribute(PostProcessor::Unit_LastPass, + (osg::Texture*)mFbos[lastDraw - GL_COLOR_ATTACHMENT0_EXT] + ->getAttachment(osg::Camera::COLOR_BUFFER0) + .getTexture()); if (pass.mRenderTarget) { @@ -240,11 +258,14 @@ namespace MWRender if (pass.mRenderTexture->getNumMipmapLevels() > 0) { state.setActiveTextureUnit(0); - state.applyTextureAttribute(0, pass.mRenderTarget->getAttachment(osg::FrameBufferObject::BufferComponent::COLOR_BUFFER0).getTexture()); + state.applyTextureAttribute(0, + pass.mRenderTarget->getAttachment(osg::FrameBufferObject::BufferComponent::COLOR_BUFFER0) + .getTexture()); ext->glGenerateMipmap(GL_TEXTURE_2D); } - lastApplied = pass.mRenderTarget->getHandle(state.getContextID());; + lastApplied = pass.mRenderTarget->getHandle(state.getContextID()); + ; } else if (pass.mResolve && index == filtered.back()) { diff --git a/apps/openmw/mwrender/pingpongcanvas.hpp b/apps/openmw/mwrender/pingpongcanvas.hpp index 4286d10a90..a5557a6d6e 100644 --- a/apps/openmw/mwrender/pingpongcanvas.hpp +++ b/apps/openmw/mwrender/pingpongcanvas.hpp @@ -4,9 +4,9 @@ #include #include +#include #include #include -#include #include @@ -37,17 +37,29 @@ namespace MWRender void setSceneTexture(size_t frameId, osg::ref_ptr tex) { mBufferData[frameId].sceneTex = tex; } - void setLDRSceneTexture(size_t frameId, osg::ref_ptr tex) { mBufferData[frameId].sceneTexLDR = tex; } + void setLDRSceneTexture(size_t frameId, osg::ref_ptr tex) + { + mBufferData[frameId].sceneTexLDR = tex; + } void setDepthTexture(size_t frameId, osg::ref_ptr tex) { mBufferData[frameId].depthTex = tex; } - void setNormalsTexture(size_t frameId, osg::ref_ptr tex) { mBufferData[frameId].normalsTex = tex; } + void setNormalsTexture(size_t frameId, osg::ref_ptr tex) + { + mBufferData[frameId].normalsTex = tex; + } void setHDR(size_t frameId, bool hdr) { mBufferData[frameId].hdr = hdr; } - void setPostProcessing(size_t frameId, bool postprocessing) { mBufferData[frameId].postprocessing = postprocessing; } + void setPostProcessing(size_t frameId, bool postprocessing) + { + mBufferData[frameId].postprocessing = postprocessing; + } - const osg::ref_ptr& getSceneTexture(size_t frameId) const { return mBufferData[frameId].sceneTex; } + const osg::ref_ptr& getSceneTexture(size_t frameId) const + { + return mBufferData[frameId].sceneTex; + } void drawGeometry(osg::RenderInfo& renderInfo) const; diff --git a/apps/openmw/mwrender/pingpongcull.cpp b/apps/openmw/mwrender/pingpongcull.cpp index c3affa531a..4e36c51932 100644 --- a/apps/openmw/mwrender/pingpongcull.cpp +++ b/apps/openmw/mwrender/pingpongcull.cpp @@ -2,15 +2,15 @@ #include #include -#include #include +#include #include -#include #include +#include -#include "postprocessor.hpp" #include "pingpongcanvas.hpp" +#include "postprocessor.hpp" namespace MWRender { @@ -38,7 +38,8 @@ namespace MWRender size_t frame = cv->getTraversalNumber(); size_t frameId = frame % 2; - MWRender::PostProcessor* postProcessor = dynamic_cast(cv->getCurrentCamera()->getUserData()); + MWRender::PostProcessor* postProcessor + = dynamic_cast(cv->getCurrentCamera()->getUserData()); if (!postProcessor) throw std::runtime_error("PingPongCull: failed to get a PostProcessor!"); @@ -69,11 +70,12 @@ namespace MWRender } else { - renderStage->setMultisampleResolveFramebufferObject(postProcessor->getFbo(PostProcessor::FBO_Primary, frameId)); + renderStage->setMultisampleResolveFramebufferObject( + postProcessor->getFbo(PostProcessor::FBO_Primary, frameId)); renderStage->setFrameBufferObject(postProcessor->getFbo(PostProcessor::FBO_Multisample, frameId)); - // The MultiView patch has a bug where it does not update resolve layers if the resolve framebuffer is changed. - // So we do blit manually in this case + // The MultiView patch has a bug where it does not update resolve layers if the resolve framebuffer is + // changed. So we do blit manually in this case if (Stereo::getMultiview() && !renderStage->getDrawCallback()) Stereo::setMultiviewMSAAResolveCallback(renderStage); } diff --git a/apps/openmw/mwrender/pingpongcull.hpp b/apps/openmw/mwrender/pingpongcull.hpp index da6c0c3c68..8886ede9e3 100644 --- a/apps/openmw/mwrender/pingpongcull.hpp +++ b/apps/openmw/mwrender/pingpongcull.hpp @@ -23,6 +23,7 @@ namespace MWRender ~PingPongCull(); void operator()(osg::Node* node, osgUtil::CullVisitor* nv); + private: std::array mLastViewMatrix; osg::ref_ptr mViewportStateset; diff --git a/apps/openmw/mwrender/postprocessor.cpp b/apps/openmw/mwrender/postprocessor.cpp index 555baa7efe..2c1b72c97d 100644 --- a/apps/openmw/mwrender/postprocessor.cpp +++ b/apps/openmw/mwrender/postprocessor.cpp @@ -1,41 +1,41 @@ #include "postprocessor.hpp" +#include #include #include #include -#include #include #include +#include #include #include -#include -#include -#include +#include +#include +#include +#include #include +#include #include #include -#include +#include #include -#include -#include -#include #include #include -#include +#include -#include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" #include "../mwgui/postprocessorhud.hpp" -#include "transparentpass.hpp" #include "pingpongcull.hpp" #include "renderingmanager.hpp" -#include "vismask.hpp" #include "sky.hpp" +#include "transparentpass.hpp" +#include "vismask.hpp" namespace { @@ -43,7 +43,8 @@ namespace { ResizedCallback(MWRender::PostProcessor* postProcessor) : mPostProcessor(postProcessor) - { } + { + } void resizedImplementation(osg::GraphicsContext* gc, int x, int y, int width, int height) override { @@ -65,9 +66,11 @@ namespace auto& sm = Stereo::Manager::instance(); auto* fullViewport = camera->getViewport(); if (sm.getEye(cv) == Stereo::Eye::Left) - stateset->setAttributeAndModes(new osg::Viewport(0, 0, fullViewport->width() / 2, fullViewport->height())); + stateset->setAttributeAndModes( + new osg::Viewport(0, 0, fullViewport->width() / 2, fullViewport->height())); if (sm.getEye(cv) == Stereo::Eye::Right) - stateset->setAttributeAndModes(new osg::Viewport(fullViewport->width() / 2, 0, fullViewport->width() / 2, fullViewport->height())); + stateset->setAttributeAndModes( + new osg::Viewport(fullViewport->width() / 2, 0, fullViewport->width() / 2, fullViewport->height())); cv->pushStateSet(stateset); traverse(camera, cv); @@ -81,11 +84,13 @@ namespace TEXTURE, }; - static osg::FrameBufferAttachment createFrameBufferAttachmentFromTemplate(Usage usage, int width, int height, osg::Texture* template_, int samples) + static osg::FrameBufferAttachment createFrameBufferAttachmentFromTemplate( + Usage usage, int width, int height, osg::Texture* template_, int samples) { if (usage == Usage::RENDER_BUFFER && !Stereo::getMultiview()) { - osg::ref_ptr attachment = new osg::RenderBuffer(width, height, template_->getInternalFormat(), samples); + osg::ref_ptr attachment + = new osg::RenderBuffer(width, height, template_->getInternalFormat(), samples); return osg::FrameBufferAttachment(attachment); } @@ -104,7 +109,8 @@ namespace namespace MWRender { - PostProcessor::PostProcessor(RenderingManager& rendering, osgViewer::Viewer* viewer, osg::Group* rootNode, const VFS::Manager* vfs) + PostProcessor::PostProcessor( + RenderingManager& rendering, osgViewer::Viewer* viewer, osg::Group* rootNode, const VFS::Manager* vfs) : osg::Group() , mEnableLiveReload(false) , mRootNode(rootNode) @@ -211,7 +217,6 @@ namespace MWRender mDirty = true; mDirtyFrameId = !frameId; - } void PostProcessor::populateTechniqueFiles() @@ -243,7 +248,8 @@ namespace MWRender if (!mDisableDepthPasses) { - mTransparentDepthPostPass = new TransparentDepthBinCallback(mRendering.getResourceSystem()->getSceneManager()->getShaderManager(), postPass); + mTransparentDepthPostPass = new TransparentDepthBinCallback( + mRendering.getResourceSystem()->getSceneManager()->getShaderManager(), postPass); osgUtil::RenderBin::getRenderBinPrototype("DepthSortedBin")->setDrawCallback(mTransparentDepthPostPass); } @@ -324,12 +330,12 @@ namespace MWRender mPingPongCanvas->setHDR(frameId, getHDR()); mPingPongCanvas->setSceneTexture(frameId, getTexture(Tex_Scene, frameId)); - if (mDisableDepthPasses) - mPingPongCanvas->setDepthTexture(frameId, getTexture(Tex_Depth, frameId)); - else - mPingPongCanvas->setDepthTexture(frameId, getTexture(Tex_OpaqueDepth, frameId)); + if (mDisableDepthPasses) + mPingPongCanvas->setDepthTexture(frameId, getTexture(Tex_Depth, frameId)); + else + mPingPongCanvas->setDepthTexture(frameId, getTexture(Tex_OpaqueDepth, frameId)); - mPingPongCanvas->setLDRSceneTexture(frameId, getTexture(Tex_Scene_LDR, frameId)); + mPingPongCanvas->setLDRSceneTexture(frameId, getTexture(Tex_Scene_LDR, frameId)); if (mTransparentDepthPostPass) { @@ -370,7 +376,7 @@ namespace MWRender if (!mEnableLiveReload && !mTriggerShaderReload) return; - mTriggerShaderReload = false;//Done only once + mTriggerShaderReload = false; // Done only once for (auto& technique : mTechniques) { @@ -383,7 +389,8 @@ namespace MWRender if (!isDirty) continue; - // TODO: Temporary workaround to avoid conflicts with external programs saving the file, especially problematic on Windows. + // TODO: Temporary workaround to avoid conflicts with external programs saving the file, especially + // problematic on Windows. // If we move to a file watcher using native APIs this should be removed. std::this_thread::sleep_for(std::chrono::milliseconds(5)); @@ -470,50 +477,66 @@ namespace MWRender } fbos[FBO_Primary] = new osg::FrameBufferObject; - fbos[FBO_Primary]->setAttachment(osg::Camera::COLOR_BUFFER0, Stereo::createMultiviewCompatibleAttachment(textures[Tex_Scene])); + fbos[FBO_Primary]->setAttachment( + osg::Camera::COLOR_BUFFER0, Stereo::createMultiviewCompatibleAttachment(textures[Tex_Scene])); if (mNormals && mNormalsSupported) - fbos[FBO_Primary]->setAttachment(osg::Camera::COLOR_BUFFER1, Stereo::createMultiviewCompatibleAttachment(textures[Tex_Normal])); - fbos[FBO_Primary]->setAttachment(osg::Camera::PACKED_DEPTH_STENCIL_BUFFER, Stereo::createMultiviewCompatibleAttachment(textures[Tex_Depth])); + fbos[FBO_Primary]->setAttachment( + osg::Camera::COLOR_BUFFER1, Stereo::createMultiviewCompatibleAttachment(textures[Tex_Normal])); + fbos[FBO_Primary]->setAttachment( + osg::Camera::PACKED_DEPTH_STENCIL_BUFFER, Stereo::createMultiviewCompatibleAttachment(textures[Tex_Depth])); fbos[FBO_FirstPerson] = new osg::FrameBufferObject; - auto fpDepthRb = createFrameBufferAttachmentFromTemplate(Usage::RENDER_BUFFER, width, height, textures[Tex_Depth], mSamples); - fbos[FBO_FirstPerson]->setAttachment(osg::FrameBufferObject::BufferComponent::PACKED_DEPTH_STENCIL_BUFFER, osg::FrameBufferAttachment(fpDepthRb)); + auto fpDepthRb = createFrameBufferAttachmentFromTemplate( + Usage::RENDER_BUFFER, width, height, textures[Tex_Depth], mSamples); + fbos[FBO_FirstPerson]->setAttachment(osg::FrameBufferObject::BufferComponent::PACKED_DEPTH_STENCIL_BUFFER, + osg::FrameBufferAttachment(fpDepthRb)); if (mSamples > 1) { fbos[FBO_Multisample] = new osg::FrameBufferObject; - auto colorRB = createFrameBufferAttachmentFromTemplate(Usage::RENDER_BUFFER, width, height, textures[Tex_Scene], mSamples); + auto colorRB = createFrameBufferAttachmentFromTemplate( + Usage::RENDER_BUFFER, width, height, textures[Tex_Scene], mSamples); if (mNormals && mNormalsSupported) { - auto normalRB = createFrameBufferAttachmentFromTemplate(Usage::RENDER_BUFFER, width, height, textures[Tex_Normal], mSamples); + auto normalRB = createFrameBufferAttachmentFromTemplate( + Usage::RENDER_BUFFER, width, height, textures[Tex_Normal], mSamples); fbos[FBO_Multisample]->setAttachment(osg::FrameBufferObject::BufferComponent::COLOR_BUFFER1, normalRB); } - auto depthRB = createFrameBufferAttachmentFromTemplate(Usage::RENDER_BUFFER, width, height, textures[Tex_Depth], mSamples); + auto depthRB = createFrameBufferAttachmentFromTemplate( + Usage::RENDER_BUFFER, width, height, textures[Tex_Depth], mSamples); fbos[FBO_Multisample]->setAttachment(osg::FrameBufferObject::BufferComponent::COLOR_BUFFER0, colorRB); - fbos[FBO_Multisample]->setAttachment(osg::FrameBufferObject::BufferComponent::PACKED_DEPTH_STENCIL_BUFFER, depthRB); + fbos[FBO_Multisample]->setAttachment( + osg::FrameBufferObject::BufferComponent::PACKED_DEPTH_STENCIL_BUFFER, depthRB); fbos[FBO_FirstPerson]->setAttachment(osg::FrameBufferObject::BufferComponent::COLOR_BUFFER0, colorRB); fbos[FBO_Intercept] = new osg::FrameBufferObject; - fbos[FBO_Intercept]->setAttachment(osg::FrameBufferObject::BufferComponent::COLOR_BUFFER0, Stereo::createMultiviewCompatibleAttachment(textures[Tex_Scene])); - fbos[FBO_Intercept]->setAttachment(osg::FrameBufferObject::BufferComponent::COLOR_BUFFER1, Stereo::createMultiviewCompatibleAttachment(textures[Tex_Normal])); + fbos[FBO_Intercept]->setAttachment(osg::FrameBufferObject::BufferComponent::COLOR_BUFFER0, + Stereo::createMultiviewCompatibleAttachment(textures[Tex_Scene])); + fbos[FBO_Intercept]->setAttachment(osg::FrameBufferObject::BufferComponent::COLOR_BUFFER1, + Stereo::createMultiviewCompatibleAttachment(textures[Tex_Normal])); } else { - fbos[FBO_FirstPerson]->setAttachment(osg::FrameBufferObject::BufferComponent::COLOR_BUFFER0, Stereo::createMultiviewCompatibleAttachment(textures[Tex_Scene])); + fbos[FBO_FirstPerson]->setAttachment(osg::FrameBufferObject::BufferComponent::COLOR_BUFFER0, + Stereo::createMultiviewCompatibleAttachment(textures[Tex_Scene])); if (mNormals && mNormalsSupported) - fbos[FBO_FirstPerson]->setAttachment(osg::FrameBufferObject::BufferComponent::COLOR_BUFFER1, Stereo::createMultiviewCompatibleAttachment(textures[Tex_Normal])); + fbos[FBO_FirstPerson]->setAttachment(osg::FrameBufferObject::BufferComponent::COLOR_BUFFER1, + Stereo::createMultiviewCompatibleAttachment(textures[Tex_Normal])); } if (textures[Tex_OpaqueDepth]) { fbos[FBO_OpaqueDepth] = new osg::FrameBufferObject; - fbos[FBO_OpaqueDepth]->setAttachment(osg::FrameBufferObject::BufferComponent::PACKED_DEPTH_STENCIL_BUFFER, Stereo::createMultiviewCompatibleAttachment(textures[Tex_OpaqueDepth])); + fbos[FBO_OpaqueDepth]->setAttachment(osg::FrameBufferObject::BufferComponent::PACKED_DEPTH_STENCIL_BUFFER, + Stereo::createMultiviewCompatibleAttachment(textures[Tex_OpaqueDepth])); } #ifdef __APPLE__ if (textures[Tex_OpaqueDepth]) - fbos[FBO_OpaqueDepth]->setAttachment(osg::FrameBufferObject::BufferComponent::COLOR_BUFFER, osg::FrameBufferAttachment(new osg::RenderBuffer(textures[Tex_OpaqueDepth]->getTextureWidth(), textures[Tex_OpaqueDepth]->getTextureHeight(), textures[Tex_Scene]->getInternalFormat()))); + fbos[FBO_OpaqueDepth]->setAttachment(osg::FrameBufferObject::BufferComponent::COLOR_BUFFER, + osg::FrameBufferAttachment(new osg::RenderBuffer(textures[Tex_OpaqueDepth]->getTextureWidth(), + textures[Tex_OpaqueDepth]->getTextureHeight(), textures[Tex_Scene]->getInternalFormat()))); #endif } @@ -541,7 +564,8 @@ namespace MWRender if (technique->getGLSLVersion() > mGLSLVersion) { - Log(Debug::Warning) << "Technique " << technique->getName() << " requires GLSL version " << technique->getGLSLVersion() << " which is unsupported by your hardware."; + Log(Debug::Warning) << "Technique " << technique->getName() << " requires GLSL version " + << technique->getGLSLVersion() << " which is unsupported by your hardware."; continue; } @@ -590,10 +614,12 @@ namespace MWRender // user-defined uniforms for (auto& uniform : technique->getUniformMap()) { - if (uniform->mSamplerType) continue; + if (uniform->mSamplerType) + continue; if (auto type = uniform->getType()) - uniform->setUniform(node.mRootStateSet->getOrCreateUniform(uniform->mName.c_str(), *type, uniform->getNumElements())); + uniform->setUniform(node.mRootStateSet->getOrCreateUniform( + uniform->mName.c_str(), *type, uniform->getNumElements())); } std::unordered_map renderTargetCache; @@ -622,7 +648,8 @@ namespace MWRender subPass.mRenderTexture->setNumMipmapLevels(osg::Image::computeNumberOfMipmapLevels(w, h)); subPass.mRenderTarget = new osg::FrameBufferObject; - subPass.mRenderTarget->setAttachment(osg::FrameBufferObject::BufferComponent::COLOR_BUFFER0, osg::FrameBufferAttachment(subPass.mRenderTexture)); + subPass.mRenderTarget->setAttachment(osg::FrameBufferObject::BufferComponent::COLOR_BUFFER0, + osg::FrameBufferAttachment(subPass.mRenderTexture)); subPass.mStateSet->setAttributeAndModes(new osg::Viewport(0, 0, w, h)); } @@ -652,7 +679,8 @@ namespace MWRender mRendering.getSkyManager()->setSunglare(sunglare); } - PostProcessor::Status PostProcessor::enableTechnique(std::shared_ptr technique, std::optional location) + PostProcessor::Status PostProcessor::enableTechnique( + std::shared_ptr technique, std::optional location) { if (!isEnabled()) { @@ -727,7 +755,7 @@ namespace MWRender textures[Tex_Normal]->setSourceFormat(GL_RGB); textures[Tex_Normal]->setInternalFormat(GL_RGB); - auto setupDepth = [] (osg::Texture* tex) { + auto setupDepth = [](osg::Texture* tex) { tex->setSourceFormat(GL_DEPTH_STENCIL_EXT); tex->setSourceType(SceneUtil::AutoDepth::depthSourceType()); tex->setInternalFormat(SceneUtil::AutoDepth::depthInternalFormat()); @@ -785,12 +813,14 @@ namespace MWRender if (Misc::StringUtils::ciEqual(technique->getName(), name)) return technique; - auto technique = std::make_shared(*mVFS, *mRendering.getResourceSystem()->getImageManager(), name, renderWidth(), renderHeight(), mUBO, mNormalsSupported); + auto technique = std::make_shared(*mVFS, *mRendering.getResourceSystem()->getImageManager(), + name, renderWidth(), renderHeight(), mUBO, mNormalsSupported); technique->compile(); if (technique->getStatus() != fx::Technique::Status::File_Not_exists) - technique->setLastModificationTime(std::filesystem::last_write_time(mTechniqueFileMap[technique->getName()])); + technique->setLastModificationTime( + std::filesystem::last_write_time(mTechniqueFileMap[technique->getName()])); if (loadNextFrame) { @@ -827,7 +857,8 @@ namespace MWRender { std::vector chain; - for (const auto& technique : mTechniques) { + for (const auto& technique : mTechniques) + { if (!technique || technique->getDynamic()) continue; chain.push_back(technique->getName()); @@ -870,4 +901,3 @@ namespace MWRender mTriggerShaderReload = true; } } - diff --git a/apps/openmw/mwrender/postprocessor.hpp b/apps/openmw/mwrender/postprocessor.hpp index 23cd0f130b..fa230ec2e8 100644 --- a/apps/openmw/mwrender/postprocessor.hpp +++ b/apps/openmw/mwrender/postprocessor.hpp @@ -2,22 +2,22 @@ #define OPENMW_MWRENDER_POSTPROCESSOR_H #include -#include #include #include +#include #include -#include -#include -#include #include +#include +#include +#include #include +#include #include #include -#include #include "pingpongcanvas.hpp" #include "transparentpass.hpp" @@ -93,17 +93,27 @@ namespace MWRender Status_Unchanged }; - PostProcessor(RenderingManager& rendering, osgViewer::Viewer* viewer, osg::Group* rootNode, const VFS::Manager* vfs); + PostProcessor( + RenderingManager& rendering, osgViewer::Viewer* viewer, osg::Group* rootNode, const VFS::Manager* vfs); ~PostProcessor(); void traverse(osg::NodeVisitor& nv) override; - osg::ref_ptr getFbo(FBOIndex index, unsigned int frameId) { return mFbos[frameId][index]; } + osg::ref_ptr getFbo(FBOIndex index, unsigned int frameId) + { + return mFbos[frameId][index]; + } - osg::ref_ptr getTexture(TextureIndex index, unsigned int frameId) { return mTextures[frameId][index]; } + osg::ref_ptr getTexture(TextureIndex index, unsigned int frameId) + { + return mTextures[frameId][index]; + } - osg::ref_ptr getPrimaryFbo(unsigned int frameId) { return mFbos[frameId][FBO_Multisample] ? mFbos[frameId][FBO_Multisample] : mFbos[frameId][FBO_Primary]; } + osg::ref_ptr getPrimaryFbo(unsigned int frameId) + { + return mFbos[frameId][FBO_Multisample] ? mFbos[frameId][FBO_Multisample] : mFbos[frameId][FBO_Primary]; + } osg::ref_ptr getStateUpdater() { return mStateUpdater; } @@ -161,11 +171,11 @@ namespace MWRender void toggleMode(); - std::shared_ptr loadTechnique(const std::string& name, bool loadNextFrame=false); + std::shared_ptr loadTechnique(const std::string& name, bool loadNextFrame = false); bool isEnabled() const { return mUsePostProcessing && mEnabled; } - bool softParticlesEnabled() const {return mSoftParticles; } + bool softParticlesEnabled() const { return mSoftParticles; } bool getHDR() const { return mHDR; } @@ -173,7 +183,11 @@ namespace MWRender void enable(bool usePostProcessing = true); - void setRenderTargetSize(int width, int height) { mWidth = width; mHeight = height; } + void setRenderTargetSize(int width, int height) + { + mWidth = width; + mHeight = height; + } void disableDynamicShaders(); @@ -187,9 +201,7 @@ namespace MWRender void loadChain(); void saveChain(); - private: - void populateTechniqueFiles(); size_t frame() const { return mViewer->getFrameStamp()->getFrameNumber(); } @@ -256,7 +268,7 @@ namespace MWRender osg::ref_ptr mPingPongCull; osg::ref_ptr mPingPongCanvas; osg::ref_ptr mTransparentDepthPostPass; - + int mWidth; int mHeight; diff --git a/apps/openmw/mwrender/recastmesh.cpp b/apps/openmw/mwrender/recastmesh.cpp index e5f5438dcb..8edbc8568d 100644 --- a/apps/openmw/mwrender/recastmesh.cpp +++ b/apps/openmw/mwrender/recastmesh.cpp @@ -2,11 +2,11 @@ #include -#include +#include +#include #include #include -#include -#include +#include #include @@ -74,26 +74,26 @@ namespace MWRender const auto group = SceneUtil::createRecastMeshGroup(*tile.second, settings.mRecast); MWBase::Environment::get().getResourceSystem()->getSceneManager()->recreateShaders(group, "debug"); group->setNodeMask(Mask_Debug); - mGroups.emplace(tile.first, Group {tile.second->getVersion(), group}); + mGroups.emplace(tile.first, Group{ tile.second->getVersion(), group }); mRootNode->addChild(group); } } void RecastMesh::reset() { - std::for_each(mGroups.begin(), mGroups.end(), [&] (const auto& v) { mRootNode->removeChild(v.second.mValue); }); + std::for_each(mGroups.begin(), mGroups.end(), [&](const auto& v) { mRootNode->removeChild(v.second.mValue); }); mGroups.clear(); } void RecastMesh::enable() { - std::for_each(mGroups.begin(), mGroups.end(), [&] (const auto& v) { mRootNode->addChild(v.second.mValue); }); + std::for_each(mGroups.begin(), mGroups.end(), [&](const auto& v) { mRootNode->addChild(v.second.mValue); }); mEnabled = true; } void RecastMesh::disable() { - std::for_each(mGroups.begin(), mGroups.end(), [&] (const auto& v) { mRootNode->removeChild(v.second.mValue); }); + std::for_each(mGroups.begin(), mGroups.end(), [&](const auto& v) { mRootNode->removeChild(v.second.mValue); }); mEnabled = false; } } diff --git a/apps/openmw/mwrender/recastmesh.hpp b/apps/openmw/mwrender/recastmesh.hpp index 0f0b34423a..2a45d67c6f 100644 --- a/apps/openmw/mwrender/recastmesh.hpp +++ b/apps/openmw/mwrender/recastmesh.hpp @@ -37,10 +37,7 @@ namespace MWRender void disable(); - bool isEnabled() const - { - return mEnabled; - } + bool isEnabled() const { return mEnabled; } private: struct Group diff --git a/apps/openmw/mwrender/renderinginterface.hpp b/apps/openmw/mwrender/renderinginterface.hpp index 63039b612a..0fe7d2506f 100644 --- a/apps/openmw/mwrender/renderinginterface.hpp +++ b/apps/openmw/mwrender/renderinginterface.hpp @@ -5,12 +5,12 @@ namespace MWRender { class Objects; class Actors; - + class RenderingInterface { public: virtual MWRender::Objects& getObjects() = 0; - virtual ~RenderingInterface(){} + virtual ~RenderingInterface() {} }; } #endif diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index f751e59892..5543133ff4 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -1,17 +1,17 @@ #include "renderingmanager.hpp" -#include #include +#include +#include +#include +#include +#include #include #include -#include #include #include -#include #include -#include -#include #include @@ -21,12 +21,12 @@ #include -#include #include +#include -#include #include #include +#include #include #include @@ -34,25 +34,25 @@ #include #include -#include #include -#include #include +#include +#include +#include +#include #include #include -#include -#include #include -#include #include +#include #include +#include #include #include -#include #include "../mwworld/cellstore.hpp" #include "../mwworld/class.hpp" @@ -63,26 +63,26 @@ #include "../mwmechanics/actorutil.hpp" -#include "../mwbase/windowmanager.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/windowmanager.hpp" #include "../mwbase/world.hpp" -#include "sky.hpp" +#include "actorspaths.hpp" +#include "camera.hpp" #include "effectmanager.hpp" +#include "fogmanager.hpp" +#include "groundcover.hpp" +#include "navmesh.hpp" #include "npcanimation.hpp" -#include "vismask.hpp" +#include "objectpaging.hpp" #include "pathgrid.hpp" -#include "camera.hpp" -#include "water.hpp" -#include "terrainstorage.hpp" -#include "navmesh.hpp" -#include "actorspaths.hpp" +#include "postprocessor.hpp" #include "recastmesh.hpp" -#include "fogmanager.hpp" -#include "objectpaging.hpp" #include "screenshotmanager.hpp" -#include "groundcover.hpp" -#include "postprocessor.hpp" +#include "sky.hpp" +#include "terrainstorage.hpp" +#include "vismask.hpp" +#include "water.hpp" namespace MWRender { @@ -92,7 +92,8 @@ namespace MWRender PerViewUniformStateUpdater(Resource::SceneManager* sceneManager) : mSceneManager(sceneManager) { - mOpaqueTextureUnit = mSceneManager->getShaderManager().reserveGlobalTextureUnits(Shader::ShaderManager::Slot::OpaqueDepthTexture); + mOpaqueTextureUnit = mSceneManager->getShaderManager().reserveGlobalTextureUnits( + Shader::ShaderManager::Slot::OpaqueDepthTexture); } void setDefaults(osg::StateSet* stateset) override @@ -110,35 +111,33 @@ namespace MWRender if (mSkyRTT && nv->getVisitorType() == osg::NodeVisitor::CULL_VISITOR) { osg::Texture* skyTexture = mSkyRTT->getColorTexture(static_cast(nv)); - stateset->setTextureAttribute(mSkyTextureUnit, skyTexture, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); + stateset->setTextureAttribute( + mSkyTextureUnit, skyTexture, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); } - stateset->setTextureAttribute(mOpaqueTextureUnit, mSceneManager->getOpaqueDepthTex(nv->getTraversalNumber()), osg::StateAttribute::ON); + stateset->setTextureAttribute(mOpaqueTextureUnit, + mSceneManager->getOpaqueDepthTex(nv->getTraversalNumber()), osg::StateAttribute::ON); } void applyLeft(osg::StateSet* stateset, osgUtil::CullVisitor* nv) override { auto* uProjectionMatrix = stateset->getUniform("projectionMatrix"); if (uProjectionMatrix) - uProjectionMatrix->set(Stereo::Manager::instance().computeEyeViewOffset(0) * Stereo::Manager::instance().computeEyeProjection(0, SceneUtil::AutoDepth::isReversed())); + uProjectionMatrix->set(Stereo::Manager::instance().computeEyeViewOffset(0) + * Stereo::Manager::instance().computeEyeProjection(0, SceneUtil::AutoDepth::isReversed())); } void applyRight(osg::StateSet* stateset, osgUtil::CullVisitor* nv) override { auto* uProjectionMatrix = stateset->getUniform("projectionMatrix"); if (uProjectionMatrix) - uProjectionMatrix->set(Stereo::Manager::instance().computeEyeViewOffset(1) * Stereo::Manager::instance().computeEyeProjection(1, SceneUtil::AutoDepth::isReversed())); + uProjectionMatrix->set(Stereo::Manager::instance().computeEyeViewOffset(1) + * Stereo::Manager::instance().computeEyeProjection(1, SceneUtil::AutoDepth::isReversed())); } - void setProjectionMatrix(const osg::Matrixf& projectionMatrix) - { - mProjectionMatrix = projectionMatrix; - } + void setProjectionMatrix(const osg::Matrixf& projectionMatrix) { mProjectionMatrix = projectionMatrix; } - const osg::Matrixf& getProjectionMatrix() const - { - return mProjectionMatrix; - } + const osg::Matrixf& getProjectionMatrix() const { return mProjectionMatrix; } void enableSkyRTT(int skyTextureUnit, SceneUtil::RTTNode* skyRTT) { @@ -217,35 +216,17 @@ namespace MWRender } } - void setLinearFac(float linearFac) - { - mLinearFac = linearFac; - } + void setLinearFac(float linearFac) { mLinearFac = linearFac; } - void setNear(float near) - { - mNear = near; - } + void setNear(float near) { mNear = near; } - void setFar(float far) - { - mFar = far; - } + void setFar(float far) { mFar = far; } - void setScreenRes(float width, float height) - { - mScreenRes = osg::Vec2f(width, height); - } + void setScreenRes(float width, float height) { mScreenRes = osg::Vec2f(width, height); } - void setWindSpeed(float windSpeed) - { - mWindSpeed = windSpeed; - } + void setWindSpeed(float windSpeed) { mWindSpeed = windSpeed; } - void setPlayerPos(osg::Vec3f playerPos) - { - mPlayerPos = playerPos; - } + void setPlayerPos(osg::Vec3f playerPos) { mPlayerPos = playerPos; } private: float mLinearFac; @@ -267,7 +248,7 @@ namespace MWRender { } - void setDefaults(osg::StateSet *stateset) override + void setDefaults(osg::StateSet* stateset) override { osg::LightModel* lightModel = new osg::LightModel; stateset->setAttribute(lightModel, osg::StateAttribute::ON); @@ -286,7 +267,8 @@ namespace MWRender void apply(osg::StateSet* stateset, osg::NodeVisitor*) override { - osg::LightModel* lightModel = static_cast(stateset->getAttribute(osg::StateAttribute::LIGHTMODEL)); + osg::LightModel* lightModel + = static_cast(stateset->getAttribute(osg::StateAttribute::LIGHTMODEL)); lightModel->setAmbientIntensity(mAmbientColor); osg::Fog* fog = static_cast(stateset->getAttribute(osg::StateAttribute::FOG)); fog->setColor(mFogColor); @@ -294,25 +276,13 @@ namespace MWRender fog->setEnd(mFogEnd); } - void setAmbientColor(const osg::Vec4f& col) - { - mAmbientColor = col; - } + void setAmbientColor(const osg::Vec4f& col) { mAmbientColor = col; } - void setFogColor(const osg::Vec4f& col) - { - mFogColor = col; - } + void setFogColor(const osg::Vec4f& col) { mFogColor = col; } - void setFogStart(float start) - { - mFogStart = start; - } + void setFogStart(float start) { mFogStart = start; } - void setFogEnd(float end) - { - mFogEnd = end; - } + void setFogEnd(float end) { mFogEnd = end; } void setWireframe(bool wireframe) { @@ -323,10 +293,7 @@ namespace MWRender } } - bool getWireframe() const - { - return mWireframe; - } + bool getWireframe() const { return mWireframe; } private: osg::Vec4f mAmbientColor; @@ -370,9 +337,9 @@ namespace MWRender }; RenderingManager::RenderingManager(osgViewer::Viewer* viewer, osg::ref_ptr rootNode, - Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, const std::filesystem::path& resourcePath, - DetourNavigator::Navigator& navigator, const MWWorld::GroundcoverStore& groundcoverStore, - SceneUtil::UnrefQueue& unrefQueue) + Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, + const std::filesystem::path& resourcePath, DetourNavigator::Navigator& navigator, + const MWWorld::GroundcoverStore& groundcoverStore, SceneUtil::UnrefQueue& unrefQueue) : mSkyBlending(Settings::Manager::getBool("sky blending", "Fog")) , mViewer(viewer) , mRootNode(rootNode) @@ -381,46 +348,56 @@ namespace MWRender , mNavigator(navigator) , mMinimumAmbientLuminance(0.f) , mNightEyeFactor(0.f) - // TODO: Near clip should not need to be bounded like this, but too small values break OSG shadow calculations CPU-side. - // See issue: #6072 + // TODO: Near clip should not need to be bounded like this, but too small values break OSG shadow calculations + // CPU-side. See issue: #6072 , mNearClip(std::max(0.005f, Settings::Manager::getFloat("near clip", "Camera"))) , mViewDistance(Settings::Manager::getFloat("viewing distance", "Camera")) , mFieldOfViewOverridden(false) , mFieldOfViewOverride(0.f) , mFieldOfView(std::clamp(Settings::Manager::getFloat("field of view", "Camera"), 1.f, 179.f)) - , mFirstPersonFieldOfView(std::clamp(Settings::Manager::getFloat("first person field of view", "Camera"), 1.f, 179.f)) + , mFirstPersonFieldOfView( + std::clamp(Settings::Manager::getFloat("first person field of view", "Camera"), 1.f, 179.f)) { bool reverseZ = SceneUtil::AutoDepth::isReversed(); - auto lightingMethod = SceneUtil::LightManager::getLightingMethodFromString(Settings::Manager::getString("lighting method", "Shaders")); + auto lightingMethod = SceneUtil::LightManager::getLightingMethodFromString( + Settings::Manager::getString("lighting method", "Shaders")); resourceSystem->getSceneManager()->setParticleSystemMask(MWRender::Mask_ParticleSystem); // Shadows and radial fog have problems with fixed-function mode. bool forceShaders = Settings::Manager::getBool("radial fog", "Fog") - || Settings::Manager::getBool("exponential fog", "Fog") - || Settings::Manager::getBool("soft particles", "Shaders") - || Settings::Manager::getBool("force shaders", "Shaders") - || Settings::Manager::getBool("enable shadows", "Shadows") - || lightingMethod != SceneUtil::LightingMethod::FFP - || reverseZ - || mSkyBlending - || Stereo::getMultiview(); + || Settings::Manager::getBool("exponential fog", "Fog") + || Settings::Manager::getBool("soft particles", "Shaders") + || Settings::Manager::getBool("force shaders", "Shaders") + || Settings::Manager::getBool("enable shadows", "Shadows") + || lightingMethod != SceneUtil::LightingMethod::FFP || reverseZ || mSkyBlending || Stereo::getMultiview(); resourceSystem->getSceneManager()->setForceShaders(forceShaders); // FIXME: calling dummy method because terrain needs to know whether lighting is clamped resourceSystem->getSceneManager()->setClampLighting(Settings::Manager::getBool("clamp lighting", "Shaders")); - resourceSystem->getSceneManager()->setAutoUseNormalMaps(Settings::Manager::getBool("auto use object normal maps", "Shaders")); - resourceSystem->getSceneManager()->setNormalMapPattern(Settings::Manager::getString("normal map pattern", "Shaders")); - resourceSystem->getSceneManager()->setNormalHeightMapPattern(Settings::Manager::getString("normal height map pattern", "Shaders")); - resourceSystem->getSceneManager()->setAutoUseSpecularMaps(Settings::Manager::getBool("auto use object specular maps", "Shaders")); - resourceSystem->getSceneManager()->setSpecularMapPattern(Settings::Manager::getString("specular map pattern", "Shaders")); - resourceSystem->getSceneManager()->setApplyLightingToEnvMaps(Settings::Manager::getBool("apply lighting to environment maps", "Shaders")); - resourceSystem->getSceneManager()->setConvertAlphaTestToAlphaToCoverage(Settings::Manager::getBool("antialias alpha test", "Shaders") && Settings::Manager::getInt("antialiasing", "Video") > 1); - - // Let LightManager choose which backend to use based on our hint. For methods besides legacy lighting, this depends on support for various OpenGL extensions. - osg::ref_ptr sceneRoot = new SceneUtil::LightManager(lightingMethod == SceneUtil::LightingMethod::FFP); + resourceSystem->getSceneManager()->setAutoUseNormalMaps( + Settings::Manager::getBool("auto use object normal maps", "Shaders")); + resourceSystem->getSceneManager()->setNormalMapPattern( + Settings::Manager::getString("normal map pattern", "Shaders")); + resourceSystem->getSceneManager()->setNormalHeightMapPattern( + Settings::Manager::getString("normal height map pattern", "Shaders")); + resourceSystem->getSceneManager()->setAutoUseSpecularMaps( + Settings::Manager::getBool("auto use object specular maps", "Shaders")); + resourceSystem->getSceneManager()->setSpecularMapPattern( + Settings::Manager::getString("specular map pattern", "Shaders")); + resourceSystem->getSceneManager()->setApplyLightingToEnvMaps( + Settings::Manager::getBool("apply lighting to environment maps", "Shaders")); + resourceSystem->getSceneManager()->setConvertAlphaTestToAlphaToCoverage( + Settings::Manager::getBool("antialias alpha test", "Shaders") + && Settings::Manager::getInt("antialiasing", "Video") > 1); + + // Let LightManager choose which backend to use based on our hint. For methods besides legacy lighting, this + // depends on support for various OpenGL extensions. + osg::ref_ptr sceneRoot + = new SceneUtil::LightManager(lightingMethod == SceneUtil::LightingMethod::FFP); resourceSystem->getSceneManager()->setLightingMethod(sceneRoot->getLightingMethod()); resourceSystem->getSceneManager()->setSupportedLightingMethods(sceneRoot->getSupportedLightingMethods()); - mMinimumAmbientLuminance = std::clamp(Settings::Manager::getFloat("minimum interior brightness", "Shaders"), 0.f, 1.f); + mMinimumAmbientLuminance + = std::clamp(Settings::Manager::getFloat("minimum interior brightness", "Shaders"), 0.f, 1.f); sceneRoot->setLightingMask(Mask_Lighting); mSceneRoot = sceneRoot; @@ -436,22 +413,26 @@ namespace MWRender int indoorShadowCastingTraversalMask = shadowCastingTraversalMask; if (Settings::Manager::getBool("object shadows", "Shadows")) - shadowCastingTraversalMask |= (Mask_Object|Mask_Static); + shadowCastingTraversalMask |= (Mask_Object | Mask_Static); if (Settings::Manager::getBool("terrain shadows", "Shadows")) shadowCastingTraversalMask |= Mask_Terrain; - mShadowManager = std::make_unique(sceneRoot, mRootNode, shadowCastingTraversalMask, indoorShadowCastingTraversalMask, Mask_Terrain|Mask_Object|Mask_Static, mResourceSystem->getSceneManager()->getShaderManager()); + mShadowManager = std::make_unique(sceneRoot, mRootNode, shadowCastingTraversalMask, + indoorShadowCastingTraversalMask, Mask_Terrain | Mask_Object | Mask_Static, + mResourceSystem->getSceneManager()->getShaderManager()); Shader::ShaderManager::DefineMap shadowDefines = mShadowManager->getShadowDefines(); Shader::ShaderManager::DefineMap lightDefines = sceneRoot->getLightDefines(); - Shader::ShaderManager::DefineMap globalDefines = mResourceSystem->getSceneManager()->getShaderManager().getGlobalDefines(); + Shader::ShaderManager::DefineMap globalDefines + = mResourceSystem->getSceneManager()->getShaderManager().getGlobalDefines(); for (auto itr = shadowDefines.begin(); itr != shadowDefines.end(); itr++) globalDefines[itr->first] = itr->second; globalDefines["forcePPL"] = Settings::Manager::getBool("force per pixel lighting", "Shaders") ? "1" : "0"; globalDefines["clamp"] = Settings::Manager::getBool("clamp lighting", "Shaders") ? "1" : "0"; - globalDefines["preLightEnv"] = Settings::Manager::getBool("apply lighting to environment maps", "Shaders") ? "1" : "0"; + globalDefines["preLightEnv"] + = Settings::Manager::getBool("apply lighting to environment maps", "Shaders") ? "1" : "0"; bool exponentialFog = Settings::Manager::getBool("exponential fog", "Fog"); globalDefines["radialFog"] = (exponentialFog || Settings::Manager::getBool("radial fog", "Fog")) ? "1" : "0"; globalDefines["exponentialFog"] = exponentialFog ? "1" : "0"; @@ -469,18 +450,23 @@ namespace MWRender float groundcoverDistance = std::max(0.f, Settings::Manager::getFloat("rendering distance", "Groundcover")); globalDefines["groundcoverFadeStart"] = std::to_string(groundcoverDistance * 0.9f); globalDefines["groundcoverFadeEnd"] = std::to_string(groundcoverDistance); - globalDefines["groundcoverStompMode"] = std::to_string(std::clamp(Settings::Manager::getInt("stomp mode", "Groundcover"), 0, 2)); - globalDefines["groundcoverStompIntensity"] = std::to_string(std::clamp(Settings::Manager::getInt("stomp intensity", "Groundcover"), 0, 2)); + globalDefines["groundcoverStompMode"] + = std::to_string(std::clamp(Settings::Manager::getInt("stomp mode", "Groundcover"), 0, 2)); + globalDefines["groundcoverStompIntensity"] + = std::to_string(std::clamp(Settings::Manager::getInt("stomp intensity", "Groundcover"), 0, 2)); globalDefines["reverseZ"] = reverseZ ? "1" : "0"; // It is unnecessary to stop/start the viewer as no frames are being rendered yet. mResourceSystem->getSceneManager()->getShaderManager().setGlobalDefines(globalDefines); - mNavMesh = std::make_unique(mRootNode, mWorkQueue, Settings::Manager::getBool("enable nav mesh render", "Navigator"), - parseNavMeshMode(Settings::Manager::getString("nav mesh render mode", "Navigator"))); - mActorsPaths = std::make_unique(mRootNode, Settings::Manager::getBool("enable agents paths render", "Navigator")); - mRecastMesh = std::make_unique(mRootNode, Settings::Manager::getBool("enable recast mesh render", "Navigator")); + mNavMesh = std::make_unique(mRootNode, mWorkQueue, + Settings::Manager::getBool("enable nav mesh render", "Navigator"), + parseNavMeshMode(Settings::Manager::getString("nav mesh render mode", "Navigator"))); + mActorsPaths = std::make_unique( + mRootNode, Settings::Manager::getBool("enable agents paths render", "Navigator")); + mRecastMesh = std::make_unique( + mRootNode, Settings::Manager::getBool("enable recast mesh render", "Navigator")); mPathgrid = std::make_unique(mRootNode); mObjects = std::make_unique(mResourceSystem, sceneRoot, unrefQueue); @@ -488,10 +474,12 @@ namespace MWRender if (getenv("OPENMW_DONT_PRECOMPILE") == nullptr) { mViewer->setIncrementalCompileOperation(new osgUtil::IncrementalCompileOperation); - mViewer->getIncrementalCompileOperation()->setTargetFrameRate(Settings::Manager::getFloat("target framerate", "Cells")); + mViewer->getIncrementalCompileOperation()->setTargetFrameRate( + Settings::Manager::getFloat("target framerate", "Cells")); } - mDebugDraw = std::make_unique(mResourceSystem->getSceneManager()->getShaderManager(), mRootNode); + mDebugDraw + = std::make_unique(mResourceSystem->getSceneManager()->getShaderManager(), mRootNode); mResourceSystem->getSceneManager()->setIncrementalCompileOperation(mViewer->getIncrementalCompileOperation()); mEffectManager = std::make_unique(sceneRoot, mResourceSystem); @@ -502,7 +490,8 @@ namespace MWRender const bool useTerrainNormalMaps = Settings::Manager::getBool("auto use terrain normal maps", "Shaders"); const bool useTerrainSpecularMaps = Settings::Manager::getBool("auto use terrain specular maps", "Shaders"); - mTerrainStorage = std::make_unique(mResourceSystem, normalMapPattern, heightMapPattern, useTerrainNormalMaps, specularMapPattern, useTerrainSpecularMaps); + mTerrainStorage = std::make_unique(mResourceSystem, normalMapPattern, heightMapPattern, + useTerrainNormalMaps, specularMapPattern, useTerrainSpecularMaps); const float lodFactor = Settings::Manager::getFloat("lod factor", "Terrain"); bool groundcover = Settings::Manager::getBool("enabled", "Groundcover"); @@ -517,9 +506,9 @@ namespace MWRender float maxCompGeometrySize = Settings::Manager::getFloat("max composite geometry size", "Terrain"); maxCompGeometrySize = std::max(maxCompGeometrySize, 1.f); bool debugChunks = Settings::Manager::getBool("debug chunks", "Terrain"); - mTerrain = std::make_unique( - sceneRoot, mRootNode, mResourceSystem, mTerrainStorage.get(), Mask_Terrain, Mask_PreCompile, Mask_Debug, - compMapResolution, compMapLevel, lodFactor, vertexLodMod, maxCompGeometrySize, debugChunks); + mTerrain = std::make_unique(sceneRoot, mRootNode, mResourceSystem, + mTerrainStorage.get(), Mask_Terrain, Mask_PreCompile, Mask_Debug, compMapResolution, compMapLevel, + lodFactor, vertexLodMod, maxCompGeometrySize, debugChunks); if (Settings::Manager::getBool("object paging", "Terrain")) { mObjectPaging = std::make_unique(mResourceSystem->getSceneManager()); @@ -528,7 +517,8 @@ namespace MWRender } } else - mTerrain = std::make_unique(sceneRoot, mRootNode, mResourceSystem, mTerrainStorage.get(), Mask_Terrain, Mask_PreCompile, Mask_Debug); + mTerrain = std::make_unique(sceneRoot, mRootNode, mResourceSystem, + mTerrainStorage.get(), Mask_Terrain, Mask_PreCompile, Mask_Debug); mTerrain->setTargetFrameRate(Settings::Manager::getFloat("target framerate", "Cells")); @@ -537,7 +527,8 @@ namespace MWRender float density = Settings::Manager::getFloat("density", "Groundcover"); density = std::clamp(density, 0.f, 1.f); - mGroundcover = std::make_unique(mResourceSystem->getSceneManager(), density, groundcoverDistance, groundcoverStore); + mGroundcover = std::make_unique( + mResourceSystem->getSceneManager(), density, groundcoverDistance, groundcoverStore); static_cast(mTerrain.get())->addChunkManager(mGroundcover.get()); mResourceSystem->addResourceManager(mGroundcover.get()); } @@ -552,16 +543,20 @@ namespace MWRender rootNode->addCullCallback(mPerViewUniformStateUpdater); mPostProcessor = new PostProcessor(*this, viewer, mRootNode, resourceSystem->getVFS()); - resourceSystem->getSceneManager()->setOpaqueDepthTex(mPostProcessor->getTexture(PostProcessor::Tex_OpaqueDepth, 0), mPostProcessor->getTexture(PostProcessor::Tex_OpaqueDepth, 1)); + resourceSystem->getSceneManager()->setOpaqueDepthTex( + mPostProcessor->getTexture(PostProcessor::Tex_OpaqueDepth, 0), + mPostProcessor->getTexture(PostProcessor::Tex_OpaqueDepth, 1)); resourceSystem->getSceneManager()->setSoftParticles(mPostProcessor->softParticlesEnabled()); resourceSystem->getSceneManager()->setSupportsNormalsRT(mPostProcessor->getSupportsNormalsRT()); // water goes after terrain for correct waterculling order - mWater = std::make_unique(sceneRoot->getParent(0), sceneRoot, mResourceSystem, mViewer->getIncrementalCompileOperation(), resourcePath); + mWater = std::make_unique(sceneRoot->getParent(0), sceneRoot, mResourceSystem, + mViewer->getIncrementalCompileOperation(), resourcePath); mCamera = std::make_unique(mViewer->getCamera()); - mScreenshotManager = std::make_unique(viewer, mRootNode, sceneRoot, mResourceSystem, mWater.get()); + mScreenshotManager + = std::make_unique(viewer, mRootNode, sceneRoot, mResourceSystem, mWater.get()); mViewer->setLightingMode(osgViewer::View::NO_LIGHT); @@ -569,9 +564,9 @@ namespace MWRender source->setNodeMask(Mask_Lighting); mSunLight = new osg::Light; source->setLight(mSunLight); - mSunLight->setDiffuse(osg::Vec4f(0,0,0,1)); - mSunLight->setAmbient(osg::Vec4f(0,0,0,1)); - mSunLight->setSpecular(osg::Vec4f(0,0,0,0)); + mSunLight->setDiffuse(osg::Vec4f(0, 0, 0, 1)); + mSunLight->setAmbient(osg::Vec4f(0, 0, 0, 1)); + mSunLight->setSpecular(osg::Vec4f(0, 0, 0, 0)); mSunLight->setConstantAttenuation(1.f); sceneRoot->setSunlight(mSunLight); sceneRoot->addChild(source); @@ -579,10 +574,10 @@ namespace MWRender sceneRoot->getOrCreateStateSet()->setMode(GL_CULL_FACE, osg::StateAttribute::ON); sceneRoot->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::ON); sceneRoot->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON); - osg::ref_ptr defaultMat (new osg::Material); + osg::ref_ptr defaultMat(new osg::Material); defaultMat->setColorMode(osg::Material::OFF); - defaultMat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(1,1,1,1)); - defaultMat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(1,1,1,1)); + defaultMat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(1, 1, 1, 1)); + defaultMat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(1, 1, 1, 1)); defaultMat->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4f(0.f, 0.f, 0.f, 0.f)); sceneRoot->getOrCreateStateSet()->setAttribute(defaultMat); sceneRoot->getOrCreateStateSet()->addUniform(new osg::Uniform("emissiveMult", 1.f)); @@ -594,20 +589,22 @@ namespace MWRender mSky->setCamera(mViewer->getCamera()); if (mSkyBlending) { - int skyTextureUnit = mResourceSystem->getSceneManager()->getShaderManager().reserveGlobalTextureUnits(Shader::ShaderManager::Slot::SkyTexture); + int skyTextureUnit = mResourceSystem->getSceneManager()->getShaderManager().reserveGlobalTextureUnits( + Shader::ShaderManager::Slot::SkyTexture); Log(Debug::Info) << "Reserving texture unit for sky RTT: " << skyTextureUnit; mPerViewUniformStateUpdater->enableSkyRTT(skyTextureUnit, mSky->getSkyRTT()); } source->setStateSetModes(*mRootNode->getOrCreateStateSet(), osg::StateAttribute::ON); - osg::Camera::CullingMode cullingMode = osg::Camera::DEFAULT_CULLING|osg::Camera::FAR_PLANE_CULLING; + osg::Camera::CullingMode cullingMode = osg::Camera::DEFAULT_CULLING | osg::Camera::FAR_PLANE_CULLING; if (!Settings::Manager::getBool("small feature culling", "Camera")) cullingMode &= ~(osg::CullStack::SMALL_FEATURE_CULLING); else { - mViewer->getCamera()->setSmallFeatureCullingPixelSize(Settings::Manager::getFloat("small feature culling pixel size", "Camera")); + mViewer->getCamera()->setSmallFeatureCullingPixelSize( + Settings::Manager::getFloat("small feature culling pixel size", "Camera")); cullingMode |= osg::CullStack::SMALL_FEATURE_CULLING; } @@ -625,19 +622,20 @@ namespace MWRender // Hopefully, anything genuinely requiring the default alpha func of GL_ALWAYS explicitly sets it mRootNode->getOrCreateStateSet()->setAttribute(Shader::RemovedAlphaFunc::getInstance(GL_ALWAYS)); - // The transparent renderbin sets alpha testing on because that was faster on old GPUs. It's now slower and breaks things. + // The transparent renderbin sets alpha testing on because that was faster on old GPUs. It's now slower and + // breaks things. mRootNode->getOrCreateStateSet()->setMode(GL_ALPHA_TEST, osg::StateAttribute::OFF); if (reverseZ) { - osg::ref_ptr clipcontrol = new osg::ClipControl(osg::ClipControl::LOWER_LEFT, osg::ClipControl::ZERO_TO_ONE); + osg::ref_ptr clipcontrol + = new osg::ClipControl(osg::ClipControl::LOWER_LEFT, osg::ClipControl::ZERO_TO_ONE); mRootNode->getOrCreateStateSet()->setAttributeAndModes(new SceneUtil::AutoDepth, osg::StateAttribute::ON); mRootNode->getOrCreateStateSet()->setAttributeAndModes(clipcontrol, osg::StateAttribute::ON); } SceneUtil::setCameraClearDepth(mViewer->getCamera()); - updateProjectionMatrix(); mViewer->getCamera()->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); @@ -676,7 +674,7 @@ namespace MWRender void RenderingManager::preloadCommonAssets() { - osg::ref_ptr workItem (new PreloadCommonAssetsWorkItem(mResourceSystem)); + osg::ref_ptr workItem(new PreloadCommonAssetsWorkItem(mResourceSystem)); mSky->listAssetsToPreload(workItem->mModels, workItem->mTextures); mWater->listAssetsToPreload(workItem->mTextures); @@ -714,7 +712,7 @@ namespace MWRender } } - void RenderingManager::setAmbientColour(const osg::Vec4f &colour) + void RenderingManager::setAmbientColour(const osg::Vec4f& colour) { mAmbientColor = colour; updateAmbient(); @@ -740,7 +738,7 @@ namespace MWRender mSky->setMoonColour(red); } - void RenderingManager::configureAmbient(const ESM::Cell *cell) + void RenderingManager::configureAmbient(const ESM::Cell* cell) { bool isInterior = !cell->isExterior() && !(cell->mData.mFlags & ESM::Cell::QuasiEx); bool needsAdjusting = false; @@ -756,12 +754,14 @@ namespace MWRender constexpr float pB = 0.0722; // we already work in linear RGB so no conversions are needed for the luminosity function - float relativeLuminance = pR*ambient.r() + pG*ambient.g() + pB*ambient.b(); + float relativeLuminance = pR * ambient.r() + pG * ambient.g() + pB * ambient.b(); if (relativeLuminance < mMinimumAmbientLuminance) { - // brighten ambient so it reaches the minimum threshold but no more, we want to mess with content data as least we can + // brighten ambient so it reaches the minimum threshold but no more, we want to mess with content data + // as least we can if (ambient.r() == 0.f && ambient.g() == 0.f && ambient.b() == 0.f) - ambient = osg::Vec4(mMinimumAmbientLuminance, mMinimumAmbientLuminance, mMinimumAmbientLuminance, ambient.a()); + ambient = osg::Vec4( + mMinimumAmbientLuminance, mMinimumAmbientLuminance, mMinimumAmbientLuminance, ambient.a()); else ambient *= mMinimumAmbientLuminance / relativeLuminance; } @@ -785,7 +785,7 @@ namespace MWRender mPostProcessor->getStateUpdater()->setSunVis(sunVis); } - void RenderingManager::setSunDirection(const osg::Vec3f &direction) + void RenderingManager::setSunDirection(const osg::Vec3f& direction) { osg::Vec3 position = direction * -1; // need to wrap this in a StateUpdater? @@ -796,7 +796,7 @@ namespace MWRender mPostProcessor->getStateUpdater()->setSunPos(mSunLight->getPosition(), mNight); } - void RenderingManager::addCell(const MWWorld::CellStore *store) + void RenderingManager::addCell(const MWWorld::CellStore* store) { mPathgrid->addCell(store); @@ -807,7 +807,7 @@ namespace MWRender mTerrain->loadCell(store->getCell()->getGridX(), store->getCell()->getGridY()); } } - void RenderingManager::removeCell(const MWWorld::CellStore *store) + void RenderingManager::removeCell(const MWWorld::CellStore* store) { mPathgrid->removeCell(store); mActorsPaths->removeCell(store); @@ -863,7 +863,7 @@ namespace MWRender { const auto wm = MWBase::Environment::get().getWindowManager(); unsigned int mask = wm->getCullMask(); - bool enabled = !(mask&sToggleWorldMask); + bool enabled = !(mask & sToggleWorldMask); if (enabled) mask |= sToggleWorldMask; else @@ -887,12 +887,13 @@ namespace MWRender return false; } - void RenderingManager::configureFog(const ESM::Cell *cell) + void RenderingManager::configureFog(const ESM::Cell* cell) { mFog->configure(mViewDistance, cell); } - void RenderingManager::configureFog(float fogDepth, float underwaterFog, float dlFactor, float dlOffset, const osg::Vec4f &color) + void RenderingManager::configureFog( + float fogDepth, float underwaterFog, float dlFactor, float dlOffset, const osg::Vec4f& color) { mFog->configure(mViewDistance, fogDepth, underwaterFog, dlFactor, dlOffset, color); } @@ -960,9 +961,9 @@ namespace MWRender mPostProcessor->setUnderwaterFlag(isUnderwater); } - void RenderingManager::updatePlayerPtr(const MWWorld::Ptr &ptr) + void RenderingManager::updatePlayerPtr(const MWWorld::Ptr& ptr) { - if(mPlayerAnimation.get()) + if (mPlayerAnimation.get()) { setupPlayer(ptr); mPlayerAnimation->updatePtr(ptr); @@ -970,15 +971,14 @@ namespace MWRender mCamera->attachTo(ptr); } - void RenderingManager::removePlayer(const MWWorld::Ptr &player) + void RenderingManager::removePlayer(const MWWorld::Ptr& player) { mWater->removeEmitter(player); } - void RenderingManager::rotateObject(const MWWorld::Ptr &ptr, const osg::Quat& rot) + void RenderingManager::rotateObject(const MWWorld::Ptr& ptr, const osg::Quat& rot) { - if(ptr == mCamera->getTrackingPtr() && - !mCamera->isVanityOrPreviewModeEnabled()) + if (ptr == mCamera->getTrackingPtr() && !mCamera->isVanityOrPreviewModeEnabled()) { mCamera->rotateCameraToTrackingPtr(); } @@ -986,12 +986,12 @@ namespace MWRender ptr.getRefData().getBaseNode()->setAttitude(rot); } - void RenderingManager::moveObject(const MWWorld::Ptr &ptr, const osg::Vec3f &pos) + void RenderingManager::moveObject(const MWWorld::Ptr& ptr, const osg::Vec3f& pos) { ptr.getRefData().getBaseNode()->setPosition(pos); } - void RenderingManager::scaleObject(const MWWorld::Ptr &ptr, const osg::Vec3f &scale) + void RenderingManager::scaleObject(const MWWorld::Ptr& ptr, const osg::Vec3f& scale) { ptr.getRefData().getBaseNode()->setScale(scale); @@ -999,7 +999,7 @@ namespace MWRender mCamera->processViewChange(); } - void RenderingManager::removeObject(const MWWorld::Ptr &ptr) + void RenderingManager::removeObject(const MWWorld::Ptr& ptr) { mActorsPaths->remove(ptr); mObjects->removeObject(ptr); @@ -1041,12 +1041,13 @@ namespace MWRender return true; } - osg::Vec4f RenderingManager::getScreenBounds(const osg::BoundingBox &worldbb) + osg::Vec4f RenderingManager::getScreenBounds(const osg::BoundingBox& worldbb) { - if (!worldbb.valid()) return osg::Vec4f(); + if (!worldbb.valid()) + return osg::Vec4f(); osg::Matrix viewProj = mViewer->getCamera()->getViewMatrix() * mViewer->getCamera()->getProjectionMatrix(); float min_x = 1.0f, max_x = 0.0f, min_y = 1.0f, max_y = 0.0f; - for (int i=0; i<8; ++i) + for (int i = 0; i < 8; ++i) { osg::Vec3f corner = worldbb.corner(i); corner = corner * viewProj; @@ -1055,22 +1056,22 @@ namespace MWRender float y = (corner.y() - 1.f) * (-0.5f); if (x < min_x) - min_x = x; + min_x = x; if (x > max_x) - max_x = x; + max_x = x; if (y < min_y) - min_y = y; + min_y = y; if (y > max_y) - max_y = y; + max_y = y; } return osg::Vec4f(min_x, min_y, max_x, max_y); } - RenderingManager::RayResult getIntersectionResult (osgUtil::LineSegmentIntersector* intersector) + RenderingManager::RayResult getIntersectionResult(osgUtil::LineSegmentIntersector* intersector) { RenderingManager::RayResult result; result.mHit = false; @@ -1087,12 +1088,13 @@ namespace MWRender PtrHolder* ptrHolder = nullptr; std::vector refnumMarkers; - for (osg::NodePath::const_iterator it = intersection.nodePath.begin(); it != intersection.nodePath.end(); ++it) + for (osg::NodePath::const_iterator it = intersection.nodePath.begin(); it != intersection.nodePath.end(); + ++it) { osg::UserDataContainer* userDataContainer = (*it)->getUserDataContainer(); if (!userDataContainer) continue; - for (unsigned int i=0; igetNumUserObjects(); ++i) + for (unsigned int i = 0; i < userDataContainer->getNumUserObjects(); ++i) { if (PtrHolder* p = dynamic_cast(userDataContainer->getUserObject(i))) ptrHolder = p; @@ -1105,10 +1107,12 @@ namespace MWRender result.mHitObject = ptrHolder->mPtr; unsigned int vertexCounter = 0; - for (unsigned int i=0; imNumVertices || (intersectionIndex >= vertexCounter && intersectionIndex < vertexCounter + refnumMarkers[i]->mNumVertices)) + if (!refnumMarkers[i]->mNumVertices + || (intersectionIndex >= vertexCounter + && intersectionIndex < vertexCounter + refnumMarkers[i]->mNumVertices)) { result.mHitRefnum = refnumMarkers[i]->mRefnum; break; @@ -1118,10 +1122,10 @@ namespace MWRender } return result; - } - osg::ref_ptr RenderingManager::getIntersectionVisitor(osgUtil::Intersector *intersector, bool ignorePlayer, bool ignoreActors) + osg::ref_ptr RenderingManager::getIntersectionVisitor( + osgUtil::Intersector* intersector, bool ignorePlayer, bool ignoreActors) { if (!mIntersectionVisitor) mIntersectionVisitor = new osgUtil::IntersectionVisitor; @@ -1131,20 +1135,22 @@ namespace MWRender mIntersectionVisitor->setIntersector(intersector); unsigned int mask = ~0u; - mask &= ~(Mask_RenderToTexture|Mask_Sky|Mask_Debug|Mask_Effect|Mask_Water|Mask_SimpleWater|Mask_Groundcover); + mask &= ~(Mask_RenderToTexture | Mask_Sky | Mask_Debug | Mask_Effect | Mask_Water | Mask_SimpleWater + | Mask_Groundcover); if (ignorePlayer) mask &= ~(Mask_Player); if (ignoreActors) - mask &= ~(Mask_Actor|Mask_Player); + mask &= ~(Mask_Actor | Mask_Player); mIntersectionVisitor->setTraversalMask(mask); return mIntersectionVisitor; } - RenderingManager::RayResult RenderingManager::castRay(const osg::Vec3f& origin, const osg::Vec3f& dest, bool ignorePlayer, bool ignoreActors) + RenderingManager::RayResult RenderingManager::castRay( + const osg::Vec3f& origin, const osg::Vec3f& dest, bool ignorePlayer, bool ignoreActors) { - osg::ref_ptr intersector (new osgUtil::LineSegmentIntersector(osgUtil::LineSegmentIntersector::MODEL, - origin, dest)); + osg::ref_ptr intersector( + new osgUtil::LineSegmentIntersector(osgUtil::LineSegmentIntersector::MODEL, origin, dest)); intersector->setIntersectionLimit(osgUtil::LineSegmentIntersector::LIMIT_NEAREST); mRootNode->accept(*getIntersectionVisitor(intersector, ignorePlayer, ignoreActors)); @@ -1152,12 +1158,13 @@ namespace MWRender return getIntersectionResult(intersector); } - RenderingManager::RayResult RenderingManager::castCameraToViewportRay(const float nX, const float nY, float maxDistance, bool ignorePlayer, bool ignoreActors) + RenderingManager::RayResult RenderingManager::castCameraToViewportRay( + const float nX, const float nY, float maxDistance, bool ignorePlayer, bool ignoreActors) { - osg::ref_ptr intersector (new osgUtil::LineSegmentIntersector(osgUtil::LineSegmentIntersector::PROJECTION, - nX * 2.f - 1.f, nY * (-2.f) + 1.f)); + osg::ref_ptr intersector(new osgUtil::LineSegmentIntersector( + osgUtil::LineSegmentIntersector::PROJECTION, nX * 2.f - 1.f, nY * (-2.f) + 1.f)); - osg::Vec3d dist (0.f, 0.f, -maxDistance); + osg::Vec3d dist(0.f, 0.f, -maxDistance); dist = dist * mViewer->getCamera()->getProjectionMatrix(); @@ -1171,13 +1178,14 @@ namespace MWRender return getIntersectionResult(intersector); } - void RenderingManager::updatePtr(const MWWorld::Ptr &old, const MWWorld::Ptr &updated) + void RenderingManager::updatePtr(const MWWorld::Ptr& old, const MWWorld::Ptr& updated) { mObjects->updatePtr(old, updated); mActorsPaths->updatePtr(old, updated); } - void RenderingManager::spawnEffect(const std::string& model, std::string_view texture, const osg::Vec3f& worldPosition, float scale, bool isMagicVFX) + void RenderingManager::spawnEffect(const std::string& model, std::string_view texture, + const osg::Vec3f& worldPosition, float scale, bool isMagicVFX) { mEffectManager->addEffect(model, texture, worldPosition, scale, isMagicVFX); } @@ -1197,7 +1205,7 @@ namespace MWRender mObjectPaging->clear(); } - MWRender::Animation* RenderingManager::getAnimation(const MWWorld::Ptr &ptr) + MWRender::Animation* RenderingManager::getAnimation(const MWWorld::Ptr& ptr) { if (mPlayerAnimation.get() && ptr == mPlayerAnimation->getPtr()) return mPlayerAnimation.get(); @@ -1205,7 +1213,7 @@ namespace MWRender return mObjects->getAnimation(ptr); } - const MWRender::Animation* RenderingManager::getAnimation(const MWWorld::ConstPtr &ptr) const + const MWRender::Animation* RenderingManager::getAnimation(const MWWorld::ConstPtr& ptr) const { if (mPlayerAnimation.get() && ptr == mPlayerAnimation->getPtr()) return mPlayerAnimation.get(); @@ -1218,7 +1226,7 @@ namespace MWRender return mPostProcessor; } - void RenderingManager::setupPlayer(const MWWorld::Ptr &player) + void RenderingManager::setupPlayer(const MWWorld::Ptr& player) { if (!mPlayerNode) { @@ -1237,26 +1245,26 @@ namespace MWRender mWater->addEmitter(player); } - void RenderingManager::renderPlayer(const MWWorld::Ptr &player) + void RenderingManager::renderPlayer(const MWWorld::Ptr& player) { - mPlayerAnimation = new NpcAnimation(player, player.getRefData().getBaseNode(), mResourceSystem, 0, NpcAnimation::VM_Normal, - mFirstPersonFieldOfView); + mPlayerAnimation = new NpcAnimation(player, player.getRefData().getBaseNode(), mResourceSystem, 0, + NpcAnimation::VM_Normal, mFirstPersonFieldOfView); mCamera->setAnimation(mPlayerAnimation.get()); mCamera->attachTo(player); } - void RenderingManager::rebuildPtr(const MWWorld::Ptr &ptr) + void RenderingManager::rebuildPtr(const MWWorld::Ptr& ptr) { - NpcAnimation *anim = nullptr; - if(ptr == mPlayerAnimation->getPtr()) + NpcAnimation* anim = nullptr; + if (ptr == mPlayerAnimation->getPtr()) anim = mPlayerAnimation.get(); else anim = dynamic_cast(mObjects->getAnimation(ptr)); - if(anim) + if (anim) { anim->rebuild(); - if(mCamera->getTrackingPtr() == ptr) + if (mCamera->getTrackingPtr() == ptr) { mCamera->attachTo(ptr); mCamera->setAnimation(anim); @@ -1264,17 +1272,17 @@ namespace MWRender } } - void RenderingManager::addWaterRippleEmitter(const MWWorld::Ptr &ptr) + void RenderingManager::addWaterRippleEmitter(const MWWorld::Ptr& ptr) { mWater->addEmitter(ptr); } - void RenderingManager::removeWaterRippleEmitter(const MWWorld::Ptr &ptr) + void RenderingManager::removeWaterRippleEmitter(const MWWorld::Ptr& ptr) { mWater->removeEmitter(ptr); } - void RenderingManager::emitWaterRipple(const osg::Vec3f &pos) + void RenderingManager::emitWaterRipple(const osg::Vec3f& pos) { mWater->emitRipple(pos); } @@ -1299,7 +1307,8 @@ namespace MWRender if (SceneUtil::AutoDepth::isReversed()) { mSharedUniformStateUpdater->setLinearFac(-mNearClip / (mViewDistance - mNearClip) - 1.f); - mPerViewUniformStateUpdater->setProjectionMatrix(SceneUtil::getReversedZProjectionMatrixAsPerspective(fov, aspect, mNearClip, mViewDistance)); + mPerViewUniformStateUpdater->setProjectionMatrix( + SceneUtil::getReversedZProjectionMatrixAsPerspective(fov, aspect, mNearClip, mViewDistance)); } else mPerViewUniformStateUpdater->setProjectionMatrix(mViewer->getCamera()->getProjectionMatrix()); @@ -1317,10 +1326,10 @@ namespace MWRender mSharedUniformStateUpdater->setScreenRes(width, height); } - // Since our fog is not radial yet, we should take FOV in account, otherwise terrain near viewing distance may disappear. - // Limit FOV here just for sure, otherwise viewing distance can be too high. - float distanceMult = std::cos(osg::DegreesToRadians(std::min(fov, 140.f))/2.f); - mTerrain->setViewDistance(mViewDistance * (distanceMult ? 1.f/distanceMult : 1.f)); + // Since our fog is not radial yet, we should take FOV in account, otherwise terrain near viewing distance may + // disappear. Limit FOV here just for sure, otherwise viewing distance can be too high. + float distanceMult = std::cos(osg::DegreesToRadians(std::min(fov, 140.f)) / 2.f); + mTerrain->setViewDistance(mViewDistance * (distanceMult ? 1.f / distanceMult : 1.f)); if (mPostProcessor) { @@ -1342,8 +1351,7 @@ namespace MWRender Settings::Manager::getString("texture mag filter", "General"), Settings::Manager::getString("texture min filter", "General"), Settings::Manager::getString("texture mipmap", "General"), - Settings::Manager::getInt("anisotropy", "General") - ); + Settings::Manager::getInt("anisotropy", "General")); mTerrain->updateTextureFiltering(); mWater->processChangedSettings({}); @@ -1361,7 +1369,7 @@ namespace MWRender mStateUpdater->setAmbientColor(color); } - void RenderingManager::setFogColor(const osg::Vec4f &color) + void RenderingManager::setFogColor(const osg::Vec4f& color) { mViewer->getCamera()->setClearColor(color); @@ -1378,7 +1386,7 @@ namespace MWRender } } - void RenderingManager::processChangedSettings(const Settings::CategorySettingVector &changed) + void RenderingManager::processChangedSettings(const Settings::CategorySettingVector& changed) { // Only perform a projection matrix update once if a relevant setting is changed. bool updateProjection = false; @@ -1398,9 +1406,8 @@ namespace MWRender { setViewDistance(Settings::Manager::getFloat("viewing distance", "Camera")); } - else if (it->first == "General" && (it->second == "texture filter" || - it->second == "texture mipmap" || - it->second == "anisotropy")) + else if (it->first == "General" + && (it->second == "texture filter" || it->second == "texture mipmap" || it->second == "anisotropy")) { updateTextureFiltering(); } @@ -1410,14 +1417,14 @@ namespace MWRender } else if (it->first == "Shaders" && it->second == "minimum interior brightness") { - mMinimumAmbientLuminance = std::clamp(Settings::Manager::getFloat("minimum interior brightness", "Shaders"), 0.f, 1.f); + mMinimumAmbientLuminance + = std::clamp(Settings::Manager::getFloat("minimum interior brightness", "Shaders"), 0.f, 1.f); if (MWMechanics::getPlayer().isInCell()) configureAmbient(MWMechanics::getPlayer().getCell()->getCell()); } - else if (it->first == "Shaders" && (it->second == "light bounds multiplier" || - it->second == "maximum light distance" || - it->second == "light fade start" || - it->second == "max lights")) + else if (it->first == "Shaders" + && (it->second == "light bounds multiplier" || it->second == "maximum light distance" + || it->second == "light fade start" || it->second == "max lights")) { auto* lightManager = getLightRoot(); lightManager->processChangedSettings(changed); @@ -1470,7 +1477,7 @@ namespace MWRender updateProjectionMatrix(); } - float RenderingManager::getTerrainHeightAt(const osg::Vec3f &pos) + float RenderingManager::getTerrainHeightAt(const osg::Vec3f& pos) { return mTerrain->getHeightAt(pos); } @@ -1505,7 +1512,7 @@ namespace MWRender osg::ref_ptr node = mResourceSystem->getSceneManager()->getTemplate(modelName); osg::ComputeBoundsVisitor computeBoundsVisitor; - computeBoundsVisitor.setTraversalMask(~(MWRender::Mask_ParticleSystem|MWRender::Mask_Effect)); + computeBoundsVisitor.setTraversalMask(~(MWRender::Mask_ParticleSystem | MWRender::Mask_Effect)); const_cast(node.get())->accept(computeBoundsVisitor); osg::BoundingBox bounds = computeBoundsVisitor.getBoundingBox(); @@ -1528,7 +1535,8 @@ namespace MWRender updateProjectionMatrix(); } } - void RenderingManager::exportSceneGraph(const MWWorld::Ptr &ptr, const std::filesystem::path& filename, const std::string &format) + void RenderingManager::exportSceneGraph( + const MWWorld::Ptr& ptr, const std::filesystem::path& filename, const std::string& format) { osg::Node* node = mViewer->getSceneData(); if (!ptr.isEmpty()) @@ -1537,7 +1545,7 @@ namespace MWRender SceneUtil::writeScene(node, filename, format); } - LandManager *RenderingManager::getLandManager() const + LandManager* RenderingManager::getLandManager() const { return mTerrainStorage->getLandManager(); } @@ -1593,7 +1601,7 @@ namespace MWRender mRecastMesh->update(mNavigator.getRecastMeshTiles(), mNavigator.getSettings()); } - void RenderingManager::setActiveGrid(const osg::Vec4i &grid) + void RenderingManager::setActiveGrid(const osg::Vec4i& grid) { mTerrain->setActiveGrid(grid); } @@ -1601,20 +1609,23 @@ namespace MWRender { if (!ptr.isInCell() || !ptr.getCell()->isExterior() || !mObjectPaging) return false; - if (mObjectPaging->enableObject(type, ptr.getCellRef().getRefNum(), ptr.getCellRef().getPosition().asVec3(), osg::Vec2i(ptr.getCell()->getCell()->getGridX(), ptr.getCell()->getCell()->getGridY()), enabled)) + if (mObjectPaging->enableObject(type, ptr.getCellRef().getRefNum(), ptr.getCellRef().getPosition().asVec3(), + osg::Vec2i(ptr.getCell()->getCell()->getGridX(), ptr.getCell()->getCell()->getGridY()), enabled)) { mTerrain->rebuildViews(); return true; } return false; } - void RenderingManager::pagingBlacklistObject(int type, const MWWorld::ConstPtr &ptr) + void RenderingManager::pagingBlacklistObject(int type, const MWWorld::ConstPtr& ptr) { if (!ptr.isInCell() || !ptr.getCell()->isExterior() || !mObjectPaging) return; - const ESM::RefNum & refnum = ptr.getCellRef().getRefNum(); - if (!refnum.hasContentFile()) return; - if (mObjectPaging->blacklistObject(type, refnum, ptr.getCellRef().getPosition().asVec3(), osg::Vec2i(ptr.getCell()->getCell()->getGridX(), ptr.getCell()->getCell()->getGridY()))) + const ESM::RefNum& refnum = ptr.getCellRef().getRefNum(); + if (!refnum.hasContentFile()) + return; + if (mObjectPaging->blacklistObject(type, refnum, ptr.getCellRef().getPosition().asVec3(), + osg::Vec2i(ptr.getCell()->getCell()->getGridX(), ptr.getCell()->getCell()->getGridY()))) mTerrain->rebuildViews(); } bool RenderingManager::pagingUnlockCache() @@ -1626,7 +1637,7 @@ namespace MWRender } return false; } - void RenderingManager::getPagedRefnums(const osg::Vec4i &activeGrid, std::vector& out) + void RenderingManager::getPagedRefnums(const osg::Vec4i& activeGrid, std::vector& out) { if (mObjectPaging) mObjectPaging->getPagedRefnums(activeGrid, out); diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index eea96d0329..ff1d96adcc 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -1,16 +1,16 @@ #ifndef OPENMW_MWRENDER_RENDERINGMANAGER_H #define OPENMW_MWRENDER_RENDERINGMANAGER_H -#include -#include #include +#include +#include #include #include -#include "objects.hpp" #include "navmeshmode.hpp" +#include "objects.hpp" #include "renderinginterface.hpp" #include "rendermode.hpp" @@ -107,9 +107,9 @@ namespace MWRender { public: RenderingManager(osgViewer::Viewer* viewer, osg::ref_ptr rootNode, - Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, const std::filesystem::path& resourcePath, - DetourNavigator::Navigator& navigator, const MWWorld::GroundcoverStore& groundcoverStore, - SceneUtil::UnrefQueue& unrefQueue); + Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, + const std::filesystem::path& resourcePath, DetourNavigator::Navigator& navigator, + const MWWorld::GroundcoverStore& groundcoverStore, SceneUtil::UnrefQueue& unrefQueue); ~RenderingManager(); osgUtil::IncrementalCompileOperation* getIncrementalCompileOperation(); @@ -142,7 +142,8 @@ namespace MWRender void configureAmbient(const ESM::Cell* cell); void configureFog(const ESM::Cell* cell); - void configureFog(float fogDepth, float underwaterFog, float dlFactor, float dlOffset, const osg::Vec4f& colour); + void configureFog( + float fogDepth, float underwaterFog, float dlFactor, float dlOffset, const osg::Vec4f& colour); void addCell(const MWWorld::CellStore* store); void removeCell(const MWWorld::CellStore* store); @@ -174,14 +175,17 @@ namespace MWRender float mRatio; }; - RayResult castRay(const osg::Vec3f& origin, const osg::Vec3f& dest, bool ignorePlayer, bool ignoreActors=false); + RayResult castRay( + const osg::Vec3f& origin, const osg::Vec3f& dest, bool ignorePlayer, bool ignoreActors = false); - /// Return the object under the mouse cursor / crosshair position, given by nX and nY normalized screen coordinates, - /// where (0,0) is the top left corner. - RayResult castCameraToViewportRay(const float nX, const float nY, float maxDistance, bool ignorePlayer, bool ignoreActors=false); + /// Return the object under the mouse cursor / crosshair position, given by nX and nY normalized screen + /// coordinates, where (0,0) is the top left corner. + RayResult castCameraToViewportRay( + const float nX, const float nY, float maxDistance, bool ignorePlayer, bool ignoreActors = false); - /// Get the bounding box of the given object in screen coordinates as (minX, minY, maxX, maxY), with (0,0) being the top left corner. - osg::Vec4f getScreenBounds(const osg::BoundingBox &worldbb); + /// Get the bounding box of the given object in screen coordinates as (minX, minY, maxX, maxY), with (0,0) being + /// the top left corner. + osg::Vec4f getScreenBounds(const osg::BoundingBox& worldbb); void setSkyEnabled(bool enabled); @@ -189,7 +193,8 @@ namespace MWRender SkyManager* getSkyManager(); - void spawnEffect(const std::string& model, std::string_view texture, const osg::Vec3f& worldPosition, float scale = 1.f, bool isMagicVFX = true); + void spawnEffect(const std::string& model, std::string_view texture, const osg::Vec3f& worldPosition, + float scale = 1.f, bool isMagicVFX = true); /// Clear all savegame-specific data void clear(); @@ -208,7 +213,7 @@ namespace MWRender void removeWaterRippleEmitter(const MWWorld::Ptr& ptr); void emitWaterRipple(const osg::Vec3f& pos); - void updatePlayerPtr(const MWWorld::Ptr &ptr); + void updatePlayerPtr(const MWWorld::Ptr& ptr); void removePlayer(const MWWorld::Ptr& player); void setupPlayer(const MWWorld::Ptr& player); @@ -237,7 +242,8 @@ namespace MWRender osg::Vec3f getHalfExtents(const MWWorld::ConstPtr& object) const; - void exportSceneGraph(const MWWorld::Ptr& ptr, const std::filesystem::path& filename, const std::string& format); + void exportSceneGraph( + const MWWorld::Ptr& ptr, const std::filesystem::path& filename, const std::string& format); Debug::DebugDrawer& getDebugDrawer() const { return *mDebugDraw; } @@ -252,12 +258,12 @@ namespace MWRender void setNavMeshNumber(const std::size_t value); - void setActiveGrid(const osg::Vec4i &grid); + void setActiveGrid(const osg::Vec4i& grid); bool pagingEnableObject(int type, const MWWorld::ConstPtr& ptr, bool enabled); - void pagingBlacklistObject(int type, const MWWorld::ConstPtr &ptr); + void pagingBlacklistObject(int type, const MWWorld::ConstPtr& ptr); bool pagingUnlockCache(); - void getPagedRefnums(const osg::Vec4i &activeGrid, std::vector& out); + void getPagedRefnums(const osg::Vec4i& activeGrid, std::vector& out); void updateProjectionMatrix(); @@ -279,7 +285,8 @@ namespace MWRender const bool mSkyBlending; - osg::ref_ptr getIntersectionVisitor(osgUtil::Intersector* intersector, bool ignorePlayer, bool ignoreActors); + osg::ref_ptr getIntersectionVisitor( + osgUtil::Intersector* intersector, bool ignorePlayer, bool ignoreActors); osg::ref_ptr mIntersectionVisitor; @@ -332,7 +339,7 @@ namespace MWRender bool mUpdateProjectionMatrix = false; bool mNight = false; - void operator = (const RenderingManager&); + void operator=(const RenderingManager&); RenderingManager(const RenderingManager&); }; diff --git a/apps/openmw/mwrender/ripplesimulation.cpp b/apps/openmw/mwrender/ripplesimulation.cpp index 0bb92cdd49..99d0023489 100644 --- a/apps/openmw/mwrender/ripplesimulation.cpp +++ b/apps/openmw/mwrender/ripplesimulation.cpp @@ -3,32 +3,32 @@ #include #include -#include -#include -#include #include +#include +#include #include +#include #include #include +#include #include #include #include #include #include -#include #include #include "vismask.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" #include "../mwmechanics/actorutil.hpp" namespace { - void createWaterRippleStateSet(Resource::ResourceSystem* resourceSystem,osg::Node* node) + void createWaterRippleStateSet(Resource::ResourceSystem* resourceSystem, osg::Node* node) { int rippleFrameCount = Fallback::Map::getInt("Water_RippleFrameCount"); if (rippleFrameCount <= 0) @@ -36,23 +36,25 @@ namespace std::string_view tex = Fallback::Map::getString("Water_RippleTexture"); - std::vector > textures; - for (int i=0; i> textures; + for (int i = 0; i < rippleFrameCount; ++i) { std::ostringstream texname; texname << "textures/water/" << tex << std::setw(2) << std::setfill('0') << i << ".dds"; - osg::ref_ptr tex2 (new osg::Texture2D(resourceSystem->getImageManager()->getImage(texname.str()))); + osg::ref_ptr tex2( + new osg::Texture2D(resourceSystem->getImageManager()->getImage(texname.str()))); tex2->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT); tex2->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT); resourceSystem->getSceneManager()->applyFilterSettings(tex2); textures.push_back(tex2); } - osg::ref_ptr controller (new NifOsg::FlipController(0, 0.3f/rippleFrameCount, textures)); + osg::ref_ptr controller( + new NifOsg::FlipController(0, 0.3f / rippleFrameCount, textures)); controller->setSource(std::make_shared()); node->addUpdateCallback(controller); - osg::ref_ptr stateset (new osg::StateSet); + osg::ref_ptr stateset(new osg::StateSet); stateset->setMode(GL_BLEND, osg::StateAttribute::ON); stateset->setMode(GL_CULL_FACE, osg::StateAttribute::OFF); stateset->setTextureAttributeAndModes(0, textures[0], osg::StateAttribute::ON); @@ -61,14 +63,14 @@ namespace depth->setWriteMask(false); stateset->setAttributeAndModes(depth, osg::StateAttribute::ON); - osg::ref_ptr polygonOffset (new osg::PolygonOffset); + osg::ref_ptr polygonOffset(new osg::PolygonOffset); polygonOffset->setUnits(SceneUtil::AutoDepth::isReversed() ? 1 : -1); polygonOffset->setFactor(SceneUtil::AutoDepth::isReversed() ? 1 : -1); stateset->setAttributeAndModes(polygonOffset, osg::StateAttribute::ON); stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); - osg::ref_ptr mat (new osg::Material); + osg::ref_ptr mat(new osg::Material); mat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(0.f, 0.f, 0.f, 1.f)); mat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(1.f, 1.f, 1.f, 1.f)); mat->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4f(0.f, 0.f, 0.f, 1.f)); @@ -83,143 +85,141 @@ namespace namespace MWRender { -RippleSimulation::RippleSimulation(osg::Group *parent, Resource::ResourceSystem* resourceSystem) - : mParent(parent) -{ - mParticleSystem = new osgParticle::ParticleSystem; + RippleSimulation::RippleSimulation(osg::Group* parent, Resource::ResourceSystem* resourceSystem) + : mParent(parent) + { + mParticleSystem = new osgParticle::ParticleSystem; - mParticleSystem->setParticleAlignment(osgParticle::ParticleSystem::FIXED); - mParticleSystem->setAlignVectorX(osg::Vec3f(1,0,0)); - mParticleSystem->setAlignVectorY(osg::Vec3f(0,1,0)); + mParticleSystem->setParticleAlignment(osgParticle::ParticleSystem::FIXED); + mParticleSystem->setAlignVectorX(osg::Vec3f(1, 0, 0)); + mParticleSystem->setAlignVectorY(osg::Vec3f(0, 1, 0)); - osgParticle::Particle& particleTemplate = mParticleSystem->getDefaultParticleTemplate(); - particleTemplate.setSizeRange(osgParticle::rangef(15, 180)); - particleTemplate.setColorRange(osgParticle::rangev4(osg::Vec4f(1,1,1,0.7), osg::Vec4f(1,1,1,0.7))); - particleTemplate.setAlphaRange(osgParticle::rangef(1.f, 0.f)); - particleTemplate.setAngularVelocity(osg::Vec3f(0,0,Fallback::Map::getFloat("Water_RippleRotSpeed"))); - particleTemplate.setLifeTime(Fallback::Map::getFloat("Water_RippleLifetime")); + osgParticle::Particle& particleTemplate = mParticleSystem->getDefaultParticleTemplate(); + particleTemplate.setSizeRange(osgParticle::rangef(15, 180)); + particleTemplate.setColorRange(osgParticle::rangev4(osg::Vec4f(1, 1, 1, 0.7), osg::Vec4f(1, 1, 1, 0.7))); + particleTemplate.setAlphaRange(osgParticle::rangef(1.f, 0.f)); + particleTemplate.setAngularVelocity(osg::Vec3f(0, 0, Fallback::Map::getFloat("Water_RippleRotSpeed"))); + particleTemplate.setLifeTime(Fallback::Map::getFloat("Water_RippleLifetime")); - osg::ref_ptr updater (new osgParticle::ParticleSystemUpdater); - updater->addParticleSystem(mParticleSystem); + osg::ref_ptr updater(new osgParticle::ParticleSystemUpdater); + updater->addParticleSystem(mParticleSystem); - mParticleNode = new osg::PositionAttitudeTransform; - mParticleNode->setName("Ripple Root"); - mParticleNode->addChild(updater); - mParticleNode->addChild(mParticleSystem); - mParticleNode->setNodeMask(Mask_Water); + mParticleNode = new osg::PositionAttitudeTransform; + mParticleNode->setName("Ripple Root"); + mParticleNode->addChild(updater); + mParticleNode->addChild(mParticleSystem); + mParticleNode->setNodeMask(Mask_Water); - createWaterRippleStateSet(resourceSystem, mParticleNode); + createWaterRippleStateSet(resourceSystem, mParticleNode); - resourceSystem->getSceneManager()->recreateShaders(mParticleNode); + resourceSystem->getSceneManager()->recreateShaders(mParticleNode); - mParent->addChild(mParticleNode); -} + mParent->addChild(mParticleNode); + } -RippleSimulation::~RippleSimulation() -{ - mParent->removeChild(mParticleNode); -} + RippleSimulation::~RippleSimulation() + { + mParent->removeChild(mParticleNode); + } -void RippleSimulation::update(float dt) -{ - const MWBase::World* world = MWBase::Environment::get().getWorld(); - for (Emitter& emitter : mEmitters) + void RippleSimulation::update(float dt) { - MWWorld::ConstPtr& ptr = emitter.mPtr; - if (ptr == MWBase::Environment::get().getWorld ()->getPlayerPtr()) + const MWBase::World* world = MWBase::Environment::get().getWorld(); + for (Emitter& emitter : mEmitters) { - // fetch a new ptr (to handle cell change etc) - // for non-player actors this is done in updateObjectCell - ptr = MWBase::Environment::get().getWorld ()->getPlayerPtr(); - } + MWWorld::ConstPtr& ptr = emitter.mPtr; + if (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr()) + { + // fetch a new ptr (to handle cell change etc) + // for non-player actors this is done in updateObjectCell + ptr = MWBase::Environment::get().getWorld()->getPlayerPtr(); + } - osg::Vec3f currentPos (ptr.getRefData().getPosition().asVec3()); + osg::Vec3f currentPos(ptr.getRefData().getPosition().asVec3()); - bool shouldEmit = (world->isUnderwater(ptr.getCell(), currentPos) && !world->isSubmerged(ptr)) || world->isWalkingOnWater(ptr); - if (shouldEmit && (currentPos - emitter.mLastEmitPosition).length() > 10) - { - emitter.mLastEmitPosition = currentPos; + bool shouldEmit = (world->isUnderwater(ptr.getCell(), currentPos) && !world->isSubmerged(ptr)) + || world->isWalkingOnWater(ptr); + if (shouldEmit && (currentPos - emitter.mLastEmitPosition).length() > 10) + { + emitter.mLastEmitPosition = currentPos; - currentPos.z() = mParticleNode->getPosition().z(); + currentPos.z() = mParticleNode->getPosition().z(); - if (mParticleSystem->numParticles()-mParticleSystem->numDeadParticles() > 500) - continue; // TODO: remove the oldest particle to make room? + if (mParticleSystem->numParticles() - mParticleSystem->numDeadParticles() > 500) + continue; // TODO: remove the oldest particle to make room? - emitRipple(currentPos); + emitRipple(currentPos); + } } } -} + void RippleSimulation::addEmitter(const MWWorld::ConstPtr& ptr, float scale, float force) + { + Emitter newEmitter; + newEmitter.mPtr = ptr; + newEmitter.mScale = scale; + newEmitter.mForce = force; + newEmitter.mLastEmitPosition = osg::Vec3f(0, 0, 0); + mEmitters.push_back(newEmitter); + } -void RippleSimulation::addEmitter(const MWWorld::ConstPtr& ptr, float scale, float force) -{ - Emitter newEmitter; - newEmitter.mPtr = ptr; - newEmitter.mScale = scale; - newEmitter.mForce = force; - newEmitter.mLastEmitPosition = osg::Vec3f(0,0,0); - mEmitters.push_back (newEmitter); -} - -void RippleSimulation::removeEmitter (const MWWorld::ConstPtr& ptr) -{ - for (std::vector::iterator it = mEmitters.begin(); it != mEmitters.end(); ++it) + void RippleSimulation::removeEmitter(const MWWorld::ConstPtr& ptr) { - if (it->mPtr == ptr) + for (std::vector::iterator it = mEmitters.begin(); it != mEmitters.end(); ++it) { - mEmitters.erase(it); - return; + if (it->mPtr == ptr) + { + mEmitters.erase(it); + return; + } } } -} -void RippleSimulation::updateEmitterPtr (const MWWorld::ConstPtr& old, const MWWorld::ConstPtr& ptr) -{ - for (std::vector::iterator it = mEmitters.begin(); it != mEmitters.end(); ++it) + void RippleSimulation::updateEmitterPtr(const MWWorld::ConstPtr& old, const MWWorld::ConstPtr& ptr) { - if (it->mPtr == old) + for (std::vector::iterator it = mEmitters.begin(); it != mEmitters.end(); ++it) { - it->mPtr = ptr; - return; + if (it->mPtr == old) + { + it->mPtr = ptr; + return; + } } } -} -void RippleSimulation::removeCell(const MWWorld::CellStore *store) -{ - for (std::vector::iterator it = mEmitters.begin(); it != mEmitters.end();) + void RippleSimulation::removeCell(const MWWorld::CellStore* store) { - if ((it->mPtr.isInCell() && it->mPtr.getCell() == store) && it->mPtr != MWMechanics::getPlayer()) + for (std::vector::iterator it = mEmitters.begin(); it != mEmitters.end();) { - it = mEmitters.erase(it); + if ((it->mPtr.isInCell() && it->mPtr.getCell() == store) && it->mPtr != MWMechanics::getPlayer()) + { + it = mEmitters.erase(it); + } + else + ++it; } - else - ++it; } -} -void RippleSimulation::emitRipple(const osg::Vec3f &pos) -{ - if (std::abs(pos.z() - mParticleNode->getPosition().z()) < 20) + void RippleSimulation::emitRipple(const osg::Vec3f& pos) { - osgParticle::ParticleSystem::ScopedWriteLock lock(*mParticleSystem->getReadWriteMutex()); - osgParticle::Particle* p = mParticleSystem->createParticle(nullptr); - p->setPosition(osg::Vec3f(pos.x(), pos.y(), 0.f)); - p->setAngle(osg::Vec3f(0,0, Misc::Rng::rollProbability() * osg::PI * 2 - osg::PI)); + if (std::abs(pos.z() - mParticleNode->getPosition().z()) < 20) + { + osgParticle::ParticleSystem::ScopedWriteLock lock(*mParticleSystem->getReadWriteMutex()); + osgParticle::Particle* p = mParticleSystem->createParticle(nullptr); + p->setPosition(osg::Vec3f(pos.x(), pos.y(), 0.f)); + p->setAngle(osg::Vec3f(0, 0, Misc::Rng::rollProbability() * osg::PI * 2 - osg::PI)); + } } -} - -void RippleSimulation::setWaterHeight(float height) -{ - mParticleNode->setPosition(osg::Vec3f(0,0,height)); -} - -void RippleSimulation::clear() -{ - for (int i=0; inumParticles(); ++i) - mParticleSystem->destroyParticle(i); -} + void RippleSimulation::setWaterHeight(float height) + { + mParticleNode->setPosition(osg::Vec3f(0, 0, height)); + } + void RippleSimulation::clear() + { + for (int i = 0; i < mParticleSystem->numParticles(); ++i) + mParticleSystem->destroyParticle(i); + } } diff --git a/apps/openmw/mwrender/ripplesimulation.hpp b/apps/openmw/mwrender/ripplesimulation.hpp index 186a578ba8..7a5b2b8ae1 100644 --- a/apps/openmw/mwrender/ripplesimulation.hpp +++ b/apps/openmw/mwrender/ripplesimulation.hpp @@ -47,9 +47,9 @@ namespace MWRender void update(float dt); /// adds an emitter, position will be tracked automatically - void addEmitter (const MWWorld::ConstPtr& ptr, float scale = 1.f, float force = 1.f); - void removeEmitter (const MWWorld::ConstPtr& ptr); - void updateEmitterPtr (const MWWorld::ConstPtr& old, const MWWorld::ConstPtr& ptr); + void addEmitter(const MWWorld::ConstPtr& ptr, float scale = 1.f, float force = 1.f); + void removeEmitter(const MWWorld::ConstPtr& ptr); + void updateEmitterPtr(const MWWorld::ConstPtr& old, const MWWorld::ConstPtr& ptr); void removeCell(const MWWorld::CellStore* store); void emitRipple(const osg::Vec3f& pos); diff --git a/apps/openmw/mwrender/rotatecontroller.cpp b/apps/openmw/mwrender/rotatecontroller.cpp index d3df4364d0..d7f8bb902c 100644 --- a/apps/openmw/mwrender/rotatecontroller.cpp +++ b/apps/openmw/mwrender/rotatecontroller.cpp @@ -5,59 +5,58 @@ namespace MWRender { -RotateController::RotateController(osg::Node *relativeTo) - : mEnabled(true) - , mRelativeTo(relativeTo) -{ - -} - -void RotateController::setEnabled(bool enabled) -{ - mEnabled = enabled; -} + RotateController::RotateController(osg::Node* relativeTo) + : mEnabled(true) + , mRelativeTo(relativeTo) + { + } -void RotateController::setRotate(const osg::Quat &rotate) -{ - mRotate = rotate; -} + void RotateController::setEnabled(bool enabled) + { + mEnabled = enabled; + } -void RotateController::setOffset(const osg::Vec3f& offset) -{ - mOffset = offset; -} + void RotateController::setRotate(const osg::Quat& rotate) + { + mRotate = rotate; + } -void RotateController::operator()(osg::MatrixTransform *node, osg::NodeVisitor *nv) -{ - if (!mEnabled) + void RotateController::setOffset(const osg::Vec3f& offset) { - traverse(node, nv); - return; + mOffset = offset; } - osg::Matrix matrix = node->getMatrix(); - osg::Quat worldOrient = getWorldOrientation(node); - osg::Quat worldOrientInverse = worldOrient.inverse(); - osg::Quat orient = worldOrient * mRotate * worldOrientInverse * matrix.getRotate(); - matrix.setRotate(orient); - matrix.setTrans(matrix.getTrans() + worldOrientInverse * mOffset); + void RotateController::operator()(osg::MatrixTransform* node, osg::NodeVisitor* nv) + { + if (!mEnabled) + { + traverse(node, nv); + return; + } + osg::Matrix matrix = node->getMatrix(); + osg::Quat worldOrient = getWorldOrientation(node); + osg::Quat worldOrientInverse = worldOrient.inverse(); + + osg::Quat orient = worldOrient * mRotate * worldOrientInverse * matrix.getRotate(); + matrix.setRotate(orient); + matrix.setTrans(matrix.getTrans() + worldOrientInverse * mOffset); - node->setMatrix(matrix); + node->setMatrix(matrix); - traverse(node,nv); -} + traverse(node, nv); + } -osg::Quat RotateController::getWorldOrientation(osg::Node *node) -{ - // this could be optimized later, we just need the world orientation, not the full matrix - osg::NodePathList nodepaths = node->getParentalNodePaths(mRelativeTo); - osg::Quat worldOrient; - if (!nodepaths.empty()) + osg::Quat RotateController::getWorldOrientation(osg::Node* node) { - osg::Matrixf worldMat = osg::computeLocalToWorld(nodepaths[0]); - worldOrient = worldMat.getRotate(); + // this could be optimized later, we just need the world orientation, not the full matrix + osg::NodePathList nodepaths = node->getParentalNodePaths(mRelativeTo); + osg::Quat worldOrient; + if (!nodepaths.empty()) + { + osg::Matrixf worldMat = osg::computeLocalToWorld(nodepaths[0]); + worldOrient = worldMat.getRotate(); + } + return worldOrient; } - return worldOrient; -} } diff --git a/apps/openmw/mwrender/rotatecontroller.hpp b/apps/openmw/mwrender/rotatecontroller.hpp index 1f3ee0f845..87bf0adfe1 100644 --- a/apps/openmw/mwrender/rotatecontroller.hpp +++ b/apps/openmw/mwrender/rotatecontroller.hpp @@ -12,29 +12,28 @@ namespace osg namespace MWRender { -/// Applies a rotation in \a relativeTo's space. -/// @note Assumes that the node being rotated has its "original" orientation set every frame by a different controller. -/// The rotation is then applied on top of that orientation. -class RotateController : public SceneUtil::NodeCallback -{ -public: - RotateController(osg::Node* relativeTo); - - void setEnabled(bool enabled); - void setOffset(const osg::Vec3f& offset); - void setRotate(const osg::Quat& rotate); - - void operator()(osg::MatrixTransform* node, osg::NodeVisitor* nv); - -protected: - osg::Quat getWorldOrientation(osg::Node* node); - - bool mEnabled; - osg::Vec3f mOffset; - osg::Quat mRotate; - osg::Node* mRelativeTo; -}; - + /// Applies a rotation in \a relativeTo's space. + /// @note Assumes that the node being rotated has its "original" orientation set every frame by a different + /// controller. The rotation is then applied on top of that orientation. + class RotateController : public SceneUtil::NodeCallback + { + public: + RotateController(osg::Node* relativeTo); + + void setEnabled(bool enabled); + void setOffset(const osg::Vec3f& offset); + void setRotate(const osg::Quat& rotate); + + void operator()(osg::MatrixTransform* node, osg::NodeVisitor* nv); + + protected: + osg::Quat getWorldOrientation(osg::Node* node); + + bool mEnabled; + osg::Vec3f mOffset; + osg::Quat mRotate; + osg::Node* mRelativeTo; + }; } diff --git a/apps/openmw/mwrender/screenshotmanager.cpp b/apps/openmw/mwrender/screenshotmanager.cpp index f2457fecd8..f43a94a033 100644 --- a/apps/openmw/mwrender/screenshotmanager.cpp +++ b/apps/openmw/mwrender/screenshotmanager.cpp @@ -11,21 +11,21 @@ #include #include #include -#include #include -#include +#include #include +#include #include -#include "../mwgui/loadingscreen.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwgui/loadingscreen.hpp" +#include "postprocessor.hpp" #include "util.hpp" #include "vismask.hpp" #include "water.hpp" -#include "postprocessor.hpp" namespace MWRender { @@ -41,11 +41,12 @@ namespace MWRender { public: NotifyDrawCompletedCallback() - : mDone(false), mFrame(0) + : mDone(false) + , mFrame(0) { } - void operator () (osg::RenderInfo& renderInfo) const override + void operator()(osg::RenderInfo& renderInfo) const override { std::lock_guard lock(mMutex); if (renderInfo.getState()->getFrameStamp()->getFrameNumber() >= mFrame && !mDone) @@ -80,10 +81,12 @@ namespace MWRender { public: ReadImageFromFramebufferCallback(osg::Image* image, int width, int height) - : mWidth(width), mHeight(height), mImage(image) + : mWidth(width) + , mHeight(height) + , mImage(image) { } - void drawImplementation(osg::RenderInfo& renderInfo,const osg::Drawable* /*drawable*/) const override + void drawImplementation(osg::RenderInfo& renderInfo, const osg::Drawable* /*drawable*/) const override { int screenW = renderInfo.getCurrentCamera()->getViewport()->width(); int screenH = renderInfo.getCurrentCamera()->getViewport()->height(); @@ -93,14 +96,15 @@ namespace MWRender screenW = eyeRes.x(); screenH = eyeRes.y(); } - double imageaspect = (double)mWidth/(double)mHeight; + double imageaspect = (double)mWidth / (double)mHeight; int leftPadding = std::max(0, static_cast(screenW - screenH * imageaspect) / 2); int topPadding = std::max(0, static_cast(screenH - screenW / imageaspect) / 2); - int width = screenW - leftPadding*2; - int height = screenH - topPadding*2; + int width = screenW - leftPadding * 2; + int height = screenH - topPadding * 2; - // Ensure we are reading from the resolved framebuffer and not the multisampled render buffer. Also ensure that the readbuffer is set correctly with rendeirng to FBO. - // glReadPixel() cannot read from multisampled targets + // Ensure we are reading from the resolved framebuffer and not the multisampled render buffer. Also ensure + // that the readbuffer is set correctly with rendeirng to FBO. glReadPixel() cannot read from multisampled + // targets PostProcessor* postProcessor = dynamic_cast(renderInfo.getCurrentCamera()->getUserData()); osg::GLExtensions* ext = osg::GLExtensions::Get(renderInfo.getContextID(), false); @@ -119,13 +123,15 @@ namespace MWRender mImage->readPixels(leftPadding, topPadding, width, height, GL_RGB, GL_UNSIGNED_BYTE); mImage->scaleImage(mWidth, mHeight, 1); } + private: int mWidth; int mHeight; osg::ref_ptr mImage; }; - ScreenshotManager::ScreenshotManager(osgViewer::Viewer* viewer, osg::ref_ptr rootNode, osg::ref_ptr sceneRoot, Resource::ResourceSystem* resourceSystem, Water* water) + ScreenshotManager::ScreenshotManager(osgViewer::Viewer* viewer, osg::ref_ptr rootNode, + osg::ref_ptr sceneRoot, Resource::ResourceSystem* resourceSystem, Water* water) : mViewer(viewer) , mRootNode(rootNode) , mSceneRoot(sceneRoot) @@ -135,9 +141,7 @@ namespace MWRender { } - ScreenshotManager::~ScreenshotManager() - { - } + ScreenshotManager::~ScreenshotManager() {} void ScreenshotManager::screenshot(osg::Image* image, int w, int h) { @@ -145,10 +149,12 @@ namespace MWRender osg::ref_ptr tempDrw = new osg::Drawable; tempDrw->setDrawCallback(new ReadImageFromFramebufferCallback(image, w, h)); tempDrw->setCullingActive(false); - tempDrw->getOrCreateStateSet()->setRenderBinDetails(100, "RenderBin", osg::StateSet::USE_RENDERBIN_DETAILS); // so its after all scene bins but before POST_RENDER gui camera + tempDrw->getOrCreateStateSet()->setRenderBinDetails(100, "RenderBin", + osg::StateSet::USE_RENDERBIN_DETAILS); // so its after all scene bins but before POST_RENDER gui camera camera->addChild(tempDrw); traversalsAndWait(mViewer->getFrameStamp()->getFrameNumber()); - // now that we've "used up" the current frame, get a fresh frame number for the next frame() following after the screenshot is completed + // now that we've "used up" the current frame, get a fresh frame number for the next frame() following after the + // screenshot is completed mViewer->advance(mViewer->getFrameStamp()->getSimulationTime()); camera->removeChild(tempDrw); } @@ -165,7 +171,7 @@ namespace MWRender if (settingArgs.size() > 0) { - std::string typeStrings[4] = {"spherical", "cylindrical", "planet", "cubemap"}; + std::string typeStrings[4] = { "spherical", "cylindrical", "planet", "cubemap" }; bool found = false; for (int i = 0; i < 4; ++i) @@ -200,9 +206,9 @@ namespace MWRender bool rawCubemap = screenshotMapping == RawCubemap; if (rawCubemap) - screenshotW = cubeSize * 6; // the image will consist of 6 cube sides in a row + screenshotW = cubeSize * 6; // the image will consist of 6 cube sides in a row else if (screenshotMapping == Planet) - screenshotH = screenshotW; // use square resolution for planet mapping + screenshotH = screenshotW; // use square resolution for planet mapping std::vector> images; images.reserve(6); @@ -210,30 +216,20 @@ namespace MWRender for (int i = 0; i < 6; ++i) images.push_back(new osg::Image); - osg::Vec3 directions[6] = { - rawCubemap ? osg::Vec3(1,0,0) : osg::Vec3(0,0,1), - osg::Vec3(0,0,-1), - osg::Vec3(-1,0,0), - rawCubemap ? osg::Vec3(0,0,1) : osg::Vec3(1,0,0), - osg::Vec3(0,1,0), - osg::Vec3(0,-1,0)}; - - double rotations[] = { - -osg::PI / 2.0, - osg::PI / 2.0, - osg::PI, - 0, - osg::PI / 2.0, - osg::PI / 2.0 }; + osg::Vec3 directions[6] + = { rawCubemap ? osg::Vec3(1, 0, 0) : osg::Vec3(0, 0, 1), osg::Vec3(0, 0, -1), osg::Vec3(-1, 0, 0), + rawCubemap ? osg::Vec3(0, 0, 1) : osg::Vec3(1, 0, 0), osg::Vec3(0, 1, 0), osg::Vec3(0, -1, 0) }; + + double rotations[] = { -osg::PI / 2.0, osg::PI / 2.0, osg::PI, 0, osg::PI / 2.0, osg::PI / 2.0 }; for (int i = 0; i < 6; ++i) // for each cubemap side { - osg::Matrixd transform = osg::Matrixd::rotate(osg::Vec3(0,0,-1), directions[i]); + osg::Matrixd transform = osg::Matrixd::rotate(osg::Vec3(0, 0, -1), directions[i]); if (!rawCubemap) - transform *= osg::Matrixd::rotate(rotations[i],osg::Vec3(0,0,-1)); + transform *= osg::Matrixd::rotate(rotations[i], osg::Vec3(0, 0, -1)); - osg::Image *sideImage = images[i].get(); + osg::Image* sideImage = images[i].get(); makeCubemapScreenshot(sideImage, cubeSize, cubeSize, transform); if (!rawCubemap) @@ -242,20 +238,22 @@ namespace MWRender if (rawCubemap) // for raw cubemap don't run on GPU, just merge the images { - image->allocateImage(cubeSize * 6,cubeSize,images[0]->r(),images[0]->getPixelFormat(),images[0]->getDataType()); + image->allocateImage( + cubeSize * 6, cubeSize, images[0]->r(), images[0]->getPixelFormat(), images[0]->getDataType()); for (int i = 0; i < 6; ++i) - osg::copyImage(images[i].get(),0,0,0,images[i]->s(),images[i]->t(),images[i]->r(),image,i * cubeSize,0,0); + osg::copyImage(images[i].get(), 0, 0, 0, images[i]->s(), images[i]->t(), images[i]->r(), image, + i * cubeSize, 0, 0); return true; } // run on GPU now: - osg::ref_ptr cubeTexture (new osg::TextureCubeMap); + osg::ref_ptr cubeTexture(new osg::TextureCubeMap); cubeTexture->setResizeNonPowerOfTwoHint(false); - cubeTexture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::NEAREST); - cubeTexture->setFilter(osg::Texture::MAG_FILTER,osg::Texture::NEAREST); + cubeTexture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST); + cubeTexture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST); cubeTexture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE); cubeTexture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE); @@ -264,12 +262,13 @@ namespace MWRender cubeTexture->setImage(i, images[i].get()); osg::ref_ptr screenshotCamera(new osg::Camera); - osg::ref_ptr quad(new osg::ShapeDrawable(new osg::Box(osg::Vec3(0,0,0), 2.0))); + osg::ref_ptr quad(new osg::ShapeDrawable(new osg::Box(osg::Vec3(0, 0, 0), 2.0))); std::map defineMap; Shader::ShaderManager& shaderMgr = mResourceSystem->getSceneManager()->getShaderManager(); - osg::ref_ptr fragmentShader(shaderMgr.getShader("s360_fragment.glsl", defineMap,osg::Shader::FRAGMENT)); + osg::ref_ptr fragmentShader( + shaderMgr.getShader("s360_fragment.glsl", defineMap, osg::Shader::FRAGMENT)); osg::ref_ptr vertexShader(shaderMgr.getShader("s360_vertex.glsl", defineMap, osg::Shader::VERTEX)); osg::ref_ptr stateset = quad->getOrCreateStateSet(); @@ -301,24 +300,24 @@ namespace MWRender mDrawCompleteCallback->waitTillDone(); } - void ScreenshotManager::renderCameraToImage(osg::Camera *camera, osg::Image *image, int w, int h) + void ScreenshotManager::renderCameraToImage(osg::Camera* camera, osg::Image* image, int w, int h) { camera->setNodeMask(Mask_RenderToTexture); camera->attach(osg::Camera::COLOR_BUFFER, image); camera->setRenderOrder(osg::Camera::PRE_RENDER); camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF); - camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT,osg::Camera::PIXEL_BUFFER_RTT); + camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT, osg::Camera::PIXEL_BUFFER_RTT); camera->setViewport(0, 0, w, h); SceneUtil::setCameraClearDepth(camera); - osg::ref_ptr texture (new osg::Texture2D); + osg::ref_ptr texture(new osg::Texture2D); texture->setInternalFormat(GL_RGB); - texture->setTextureSize(w,h); + texture->setTextureSize(w, h); texture->setResizeNonPowerOfTwoHint(false); texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR); texture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR); - camera->attach(osg::Camera::COLOR_BUFFER,texture); + camera->attach(osg::Camera::COLOR_BUFFER, texture); image->setDataType(GL_UNSIGNED_BYTE); image->setPixelFormat(texture->getInternalFormat()); @@ -332,23 +331,25 @@ namespace MWRender MWBase::Environment::get().getWindowManager()->getLoadingScreen()->loadingOff(); - // now that we've "used up" the current frame, get a fresh framenumber for the next frame() following after the screenshot is completed + // now that we've "used up" the current frame, get a fresh framenumber for the next frame() following after the + // screenshot is completed mViewer->advance(mViewer->getFrameStamp()->getSimulationTime()); camera->removeChildren(0, camera->getNumChildren()); mRootNode->removeChild(camera); } - void ScreenshotManager::makeCubemapScreenshot(osg::Image *image, int w, int h, const osg::Matrixd& cameraTransform) + void ScreenshotManager::makeCubemapScreenshot(osg::Image* image, int w, int h, const osg::Matrixd& cameraTransform) { - osg::ref_ptr rttCamera (new osg::Camera); + osg::ref_ptr rttCamera(new osg::Camera); float nearClip = Settings::Manager::getFloat("near clip", "Camera"); float viewDistance = Settings::Manager::getFloat("viewing distance", "Camera"); // each cubemap side sees 90 degrees if (SceneUtil::AutoDepth::isReversed()) - rttCamera->setProjectionMatrix(SceneUtil::getReversedZProjectionMatrixAsPerspectiveInf(90.0, w/float(h), nearClip)); + rttCamera->setProjectionMatrix( + SceneUtil::getReversedZProjectionMatrixAsPerspectiveInf(90.0, w / float(h), nearClip)); else - rttCamera->setProjectionMatrixAsPerspective(90.0, w/float(h), nearClip, viewDistance); + rttCamera->setProjectionMatrixAsPerspective(90.0, w / float(h), nearClip, viewDistance); rttCamera->setViewMatrix(mViewer->getCamera()->getViewMatrix() * cameraTransform); rttCamera->setUpdateCallback(new NoTraverseCallback); @@ -357,10 +358,11 @@ namespace MWRender rttCamera->addChild(mWater->getReflectionNode()); rttCamera->addChild(mWater->getRefractionNode()); - rttCamera->setCullMask(MWBase::Environment::get().getWindowManager()->getCullMask() & ~(Mask_GUI|Mask_FirstPerson)); + rttCamera->setCullMask( + MWBase::Environment::get().getWindowManager()->getCullMask() & ~(Mask_GUI | Mask_FirstPerson)); rttCamera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - renderCameraToImage(rttCamera.get(),image,w,h); + renderCameraToImage(rttCamera.get(), image, w, h); } } diff --git a/apps/openmw/mwrender/screenshotmanager.hpp b/apps/openmw/mwrender/screenshotmanager.hpp index 094a4a20f4..72e5b91637 100644 --- a/apps/openmw/mwrender/screenshotmanager.hpp +++ b/apps/openmw/mwrender/screenshotmanager.hpp @@ -21,7 +21,8 @@ namespace MWRender class ScreenshotManager { public: - ScreenshotManager(osgViewer::Viewer* viewer, osg::ref_ptr rootNode, osg::ref_ptr sceneRoot, Resource::ResourceSystem* resourceSystem, Water* water); + ScreenshotManager(osgViewer::Viewer* viewer, osg::ref_ptr rootNode, + osg::ref_ptr sceneRoot, Resource::ResourceSystem* resourceSystem, Water* water); ~ScreenshotManager(); void screenshot(osg::Image* image, int w, int h); @@ -36,8 +37,9 @@ namespace MWRender Water* mWater; void traversalsAndWait(unsigned int frame); - void renderCameraToImage(osg::Camera *camera, osg::Image *image, int w, int h); - void makeCubemapScreenshot(osg::Image* image, int w, int h, const osg::Matrixd &cameraTransform=osg::Matrixd()); + void renderCameraToImage(osg::Camera* camera, osg::Image* image, int w, int h); + void makeCubemapScreenshot( + osg::Image* image, int w, int h, const osg::Matrixd& cameraTransform = osg::Matrixd()); }; } diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index 592f3f7e86..87dfe49999 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -3,27 +3,27 @@ #include #include -#include #include #include #include +#include #include #include #include -#include -#include #include #include +#include +#include -#include #include +#include #include -#include #include +#include #include #include @@ -33,17 +33,17 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" -#include "vismask.hpp" #include "renderbin.hpp" -#include "util.hpp" #include "skyutil.hpp" +#include "util.hpp" +#include "vismask.hpp" namespace { class WrapAroundOperator : public osgParticle::Operator { public: - WrapAroundOperator(osg::Camera *camera, const osg::Vec3 &wrapRange) + WrapAroundOperator(osg::Camera* camera, const osg::Vec3& wrapRange) : osgParticle::Operator() , mCamera(camera) , mWrapRange(wrapRange) @@ -52,21 +52,13 @@ namespace mPreviousCameraPosition = getCameraPosition(); } - osg::Object *cloneType() const override - { - return nullptr; - } + osg::Object* cloneType() const override { return nullptr; } - osg::Object *clone(const osg::CopyOp &op) const override - { - return nullptr; - } + osg::Object* clone(const osg::CopyOp& op) const override { return nullptr; } - void operate(osgParticle::Particle *P, double dt) override - { - } + void operate(osgParticle::Particle* P, double dt) override {} - void operateParticles(osgParticle::ParticleSystem *ps, double dt) override + void operateParticles(osgParticle::ParticleSystem* ps, double dt) override { osg::Vec3 position = getCameraPosition(); osg::Vec3 positionDifference = position - mPreviousCameraPosition; @@ -75,7 +67,6 @@ namespace std::vector worldMatrices = ps->getWorldMatrices(); - if (!worldMatrices.empty()) { toWorld = worldMatrices[0]; @@ -84,18 +75,18 @@ namespace for (int i = 0; i < ps->numParticles(); ++i) { - osgParticle::Particle *p = ps->getParticle(i); + osgParticle::Particle* p = ps->getParticle(i); p->setPosition(toWorld.preMult(p->getPosition())); p->setPosition(p->getPosition() - positionDifference); - for (int j = 0; j < 3; ++j) // wrap-around in all 3 dimensions + for (int j = 0; j < 3; ++j) // wrap-around in all 3 dimensions { osg::Vec3 pos = p->getPosition(); if (pos[j] < -mHalfWrapRange[j]) - pos[j] = mHalfWrapRange[j] + fmod(pos[j] - mHalfWrapRange[j],mWrapRange[j]); + pos[j] = mHalfWrapRange[j] + fmod(pos[j] - mHalfWrapRange[j], mWrapRange[j]); else if (pos[j] > mHalfWrapRange[j]) - pos[j] = fmod(pos[j] + mHalfWrapRange[j],mWrapRange[j]) - mHalfWrapRange[j]; + pos[j] = fmod(pos[j] + mHalfWrapRange[j], mWrapRange[j]) - mHalfWrapRange[j]; p->setPosition(pos); } @@ -107,15 +98,12 @@ namespace } protected: - osg::Camera *mCamera; + osg::Camera* mCamera; osg::Vec3 mPreviousCameraPosition; osg::Vec3 mWrapRange; osg::Vec3 mHalfWrapRange; - osg::Vec3 getCameraPosition() - { - return mCamera->getInverseViewMatrix().getTrans(); - } + osg::Vec3 getCameraPosition() { return mCamera->getInverseViewMatrix().getTrans(); } }; class WeatherAlphaOperator : public osgParticle::Operator @@ -124,19 +112,14 @@ namespace WeatherAlphaOperator(float& alpha, bool rain) : mAlpha(alpha) , mIsRain(rain) - { } - - osg::Object *cloneType() const override { - return nullptr; } - osg::Object *clone(const osg::CopyOp &op) const override - { - return nullptr; - } + osg::Object* cloneType() const override { return nullptr; } + + osg::Object* clone(const osg::CopyOp& op) const override { return nullptr; } - void operate(osgParticle::Particle *particle, double dt) override + void operate(osgParticle::Particle* particle, double dt) override { constexpr float rainThreshold = 0.6f; // Rain_Threshold? float alpha = mIsRain ? mAlpha * rainThreshold : mAlpha; @@ -144,7 +127,7 @@ namespace } private: - float &mAlpha; + float& mAlpha; bool mIsRain; }; @@ -155,7 +138,8 @@ namespace /// @param alpha the variable alpha value is recovered from AlphaFader(const float& alpha) : mAlpha(alpha) - { } + { + } void setDefaults(osg::StateSet* stateset) override { @@ -171,19 +155,20 @@ namespace } protected: - const float &mAlpha; + const float& mAlpha; }; // Helper for adding AlphaFaders to a subgraph class SetupVisitor : public osg::NodeVisitor { public: - SetupVisitor(const float &alpha) + SetupVisitor(const float& alpha) : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) , mAlpha(alpha) - { } + { + } - void apply(osg::Node &node) override + void apply(osg::Node& node) override { if (osg::StateSet* stateset = node.getStateSet()) { @@ -214,15 +199,15 @@ namespace } private: - const float &mAlpha; + const float& mAlpha; }; class SkyRTT : public SceneUtil::RTTNode { public: - SkyRTT(osg::Vec2f size, osg::Group* earlyRenderBinRoot) : - RTTNode(static_cast(size.x()), static_cast(size.y()), 0, false, 1, StereoAwareness::Aware), - mEarlyRenderBinRoot(earlyRenderBinRoot) + SkyRTT(osg::Vec2f size, osg::Group* earlyRenderBinRoot) + : RTTNode(static_cast(size.x()), static_cast(size.y()), 0, false, 1, StereoAwareness::Aware) + , mEarlyRenderBinRoot(earlyRenderBinRoot) { setDepthBufferInternalFormat(GL_DEPTH24_STENCIL8); } @@ -282,7 +267,8 @@ namespace MWRender skyroot->setName("Sky Root"); // Assign empty program to specify we don't want shaders when we are rendering in FFP pipeline if (!mSceneManager->getForceShaders()) - skyroot->getOrCreateStateSet()->setAttributeAndModes(new osg::Program(), osg::StateAttribute::OVERRIDE|osg::StateAttribute::PROTECTED|osg::StateAttribute::ON); + skyroot->getOrCreateStateSet()->setAttributeAndModes(new osg::Program(), + osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON); SceneUtil::ShadowManager::disableShadowsForStateSet(skyroot->getOrCreateStateSet()); parentNode->addChild(skyroot); @@ -313,7 +299,8 @@ namespace MWRender bool forceShaders = mSceneManager->getForceShaders(); - mAtmosphereDay = mSceneManager->getInstance(Settings::Manager::getString("skyatmosphere", "Models"), mEarlyRenderBinRoot); + mAtmosphereDay + = mSceneManager->getInstance(Settings::Manager::getString("skyatmosphere", "Models"), mEarlyRenderBinRoot); ModVertexAlphaVisitor modAtmosphere(ModVertexAlphaVisitor::Atmosphere); mAtmosphereDay->accept(modAtmosphere); @@ -326,10 +313,13 @@ namespace MWRender osg::ref_ptr atmosphereNight; if (mSceneManager->getVFS()->exists(Settings::Manager::getString("skynight02", "Models"))) - atmosphereNight = mSceneManager->getInstance(Settings::Manager::getString("skynight02", "Models"), mAtmosphereNightNode); + atmosphereNight = mSceneManager->getInstance( + Settings::Manager::getString("skynight02", "Models"), mAtmosphereNightNode); else - atmosphereNight = mSceneManager->getInstance(Settings::Manager::getString("skynight01", "Models"), mAtmosphereNightNode); - atmosphereNight->getOrCreateStateSet()->setAttributeAndModes(createAlphaTrackingUnlitMaterial(), osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); + atmosphereNight = mSceneManager->getInstance( + Settings::Manager::getString("skynight01", "Models"), mAtmosphereNightNode); + atmosphereNight->getOrCreateStateSet()->setAttributeAndModes( + createAlphaTrackingUnlitMaterial(), osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); ModVertexAlphaVisitor modStars(ModVertexAlphaVisitor::Stars); atmosphereNight->accept(modStars); @@ -338,21 +328,25 @@ namespace MWRender mSun = std::make_unique(mEarlyRenderBinRoot, *mSceneManager); mSun->setSunglare(mSunglareEnabled); - mMasser = std::make_unique(mEarlyRenderBinRoot, *mSceneManager, Fallback::Map::getFloat("Moons_Masser_Size")/125, Moon::Type_Masser); - mSecunda = std::make_unique(mEarlyRenderBinRoot, *mSceneManager, Fallback::Map::getFloat("Moons_Secunda_Size")/125, Moon::Type_Secunda); + mMasser = std::make_unique( + mEarlyRenderBinRoot, *mSceneManager, Fallback::Map::getFloat("Moons_Masser_Size") / 125, Moon::Type_Masser); + mSecunda = std::make_unique(mEarlyRenderBinRoot, *mSceneManager, + Fallback::Map::getFloat("Moons_Secunda_Size") / 125, Moon::Type_Secunda); mCloudNode = new osg::Group; mEarlyRenderBinRoot->addChild(mCloudNode); mCloudMesh = new osg::PositionAttitudeTransform; - osg::ref_ptr cloudMeshChild = mSceneManager->getInstance(Settings::Manager::getString("skyclouds", "Models"), mCloudMesh); + osg::ref_ptr cloudMeshChild + = mSceneManager->getInstance(Settings::Manager::getString("skyclouds", "Models"), mCloudMesh); mCloudUpdater = new CloudUpdater(forceShaders); mCloudUpdater->setOpacity(1.f); cloudMeshChild->addUpdateCallback(mCloudUpdater); mCloudMesh->addChild(cloudMeshChild); mNextCloudMesh = new osg::PositionAttitudeTransform; - osg::ref_ptr nextCloudMeshChild = mSceneManager->getInstance(Settings::Manager::getString("skyclouds", "Models"), mNextCloudMesh); + osg::ref_ptr nextCloudMeshChild + = mSceneManager->getInstance(Settings::Manager::getString("skyclouds", "Models"), mNextCloudMesh); mNextCloudUpdater = new CloudUpdater(forceShaders); mNextCloudUpdater->setOpacity(0.f); nextCloudMeshChild->addUpdateCallback(mNextCloudUpdater); @@ -371,10 +365,12 @@ namespace MWRender Shader::ShaderManager::DefineMap defines = {}; Stereo::Manager::instance().shaderStereoDefines(defines); auto vertex = mSceneManager->getShaderManager().getShader("sky_vertex.glsl", defines, osg::Shader::VERTEX); - auto fragment = mSceneManager->getShaderManager().getShader("sky_fragment.glsl", defines, osg::Shader::FRAGMENT); + auto fragment + = mSceneManager->getShaderManager().getShader("sky_fragment.glsl", defines, osg::Shader::FRAGMENT); auto program = mSceneManager->getShaderManager().getProgram(vertex, fragment); mEarlyRenderBinRoot->getOrCreateStateSet()->addUniform(new osg::Uniform("pass", -1)); - mEarlyRenderBinRoot->getOrCreateStateSet()->setAttributeAndModes(program, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); + mEarlyRenderBinRoot->getOrCreateStateSet()->setAttributeAndModes( + program, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); } osg::ref_ptr depth = new SceneUtil::AutoDepth; @@ -388,7 +384,7 @@ namespace MWRender mCreated = true; } - void SkyManager::setCamera(osg::Camera *camera) + void SkyManager::setCamera(osg::Camera* camera) { mCamera = camera; } @@ -401,15 +397,16 @@ namespace MWRender mRainNode = new osg::Group; mRainParticleSystem = new NifOsg::ParticleSystem; - osg::Vec3 rainRange = osg::Vec3(mRainDiameter, mRainDiameter, (mRainMinHeight+mRainMaxHeight)/2.f); + osg::Vec3 rainRange = osg::Vec3(mRainDiameter, mRainDiameter, (mRainMinHeight + mRainMaxHeight) / 2.f); mRainParticleSystem->setParticleAlignment(osgParticle::ParticleSystem::FIXED); - mRainParticleSystem->setAlignVectorX(osg::Vec3f(0.1,0,0)); - mRainParticleSystem->setAlignVectorY(osg::Vec3f(0,0,1)); + mRainParticleSystem->setAlignVectorX(osg::Vec3f(0.1, 0, 0)); + mRainParticleSystem->setAlignVectorY(osg::Vec3f(0, 0, 1)); osg::ref_ptr stateset = mRainParticleSystem->getOrCreateStateSet(); - osg::ref_ptr raindropTex = new osg::Texture2D(mSceneManager->getImageManager()->getImage("textures/tx_raindrop_01.dds")); + osg::ref_ptr raindropTex + = new osg::Texture2D(mSceneManager->getImageManager()->getImage("textures/tx_raindrop_01.dds")); raindropTex->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE); raindropTex->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE); @@ -420,8 +417,8 @@ namespace MWRender stateset->setMode(GL_BLEND, osg::StateAttribute::ON); osg::ref_ptr mat = new osg::Material; - mat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(1,1,1,1)); - mat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(1,1,1,1)); + mat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(1, 1, 1, 1)); + mat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(1, 1, 1, 1)); mat->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE); stateset->setAttributeAndModes(mat); @@ -440,11 +437,12 @@ namespace MWRender emitter->setPlacer(placer); mPlacer = placer; - // FIXME: vanilla engine does not use a particle system to handle rain, it uses a NIF-file with 20 raindrops in it. - // It spawns the (maxRaindrops-getParticleSystem()->numParticles())*dt/rainEntranceSpeed batches every frame (near 1-2). - // Since the rain is a regular geometry, it produces water ripples, also in theory it can be removed if collides with something. + // FIXME: vanilla engine does not use a particle system to handle rain, it uses a NIF-file with 20 raindrops in + // it. It spawns the (maxRaindrops-getParticleSystem()->numParticles())*dt/rainEntranceSpeed batches every frame + // (near 1-2). Since the rain is a regular geometry, it produces water ripples, also in theory it can be removed + // if collides with something. osg::ref_ptr counter = new RainCounter; - counter->setNumberOfParticlesPerSecondToCreate(mRainMaxRaindrops/mRainEntranceSpeed*20); + counter->setNumberOfParticlesPerSecondToCreate(mRainMaxRaindrops / mRainEntranceSpeed * 20); emitter->setCounter(counter); mCounter = counter; @@ -456,7 +454,7 @@ namespace MWRender updater->addParticleSystem(mRainParticleSystem); osg::ref_ptr program = new osgParticle::ModularProgram; - program->addOperator(new WrapAroundOperator(mCamera,rainRange)); + program->addOperator(new WrapAroundOperator(mCamera, rainRange)); program->addOperator(new WeatherAlphaOperator(mPrecipitationAlpha, true)); program->setParticleSystem(mRainParticleSystem); mRainNode->addChild(program); @@ -499,13 +497,15 @@ namespace MWRender int SkyManager::getMasserPhase() const { - if (!mCreated) return 0; + if (!mCreated) + return 0; return mMasser->getPhaseInt(); } int SkyManager::getSecundaPhase() const { - if (!mCreated) return 0; + if (!mCreated) + return 0; return mSecunda->getPhaseInt(); } @@ -540,7 +540,7 @@ namespace MWRender quat.makeRotate(MWWorld::Weather::defaultDirection(), mStormParticleDirection); // Morrowind deliberately rotates the blizzard mesh, so so should we. if (mCurrentParticleEffect == Settings::Manager::getString("weatherblizzard", "Models")) - quat.makeRotate(osg::Vec3f(-1,0,0), mStormParticleDirection); + quat.makeRotate(osg::Vec3f(-1, 0, 0), mStormParticleDirection); mParticleNode->setAttitude(quat); } @@ -561,9 +561,10 @@ namespace MWRender } // rotate the stars by 360 degrees every 4 days - mAtmosphereNightRoll += MWBase::Environment::get().getWorld()->getTimeScaleFactor()*duration*osg::DegreesToRadians(360.f) / (3600*96.f); + mAtmosphereNightRoll += MWBase::Environment::get().getWorld()->getTimeScaleFactor() * duration + * osg::DegreesToRadians(360.f) / (3600 * 96.f); if (mAtmosphereNightNode->getNodeMask() != 0) - mAtmosphereNightNode->setAttitude(osg::Quat(mAtmosphereNightRoll, osg::Vec3f(0,0,1))); + mAtmosphereNightNode->setAttitude(osg::Quat(mAtmosphereNightRoll, osg::Vec3f(0, 0, 1))); } void SkyManager::setEnabled(bool enabled) @@ -585,27 +586,28 @@ namespace MWRender mEnabled = enabled; } - void SkyManager::setMoonColour (bool red) + void SkyManager::setMoonColour(bool red) { - if (!mCreated) return; - mSecunda->setColor(red ? mMoonScriptColor : osg::Vec4f(1,1,1,1)); + if (!mCreated) + return; + mSecunda->setColor(red ? mMoonScriptColor : osg::Vec4f(1, 1, 1, 1)); } void SkyManager::updateRainParameters() { if (mRainShooter) { - float angle = -std::atan(mWindSpeed/50.f); - mRainShooter->setVelocity(osg::Vec3f(0, mRainSpeed*std::sin(angle), -mRainSpeed/std::cos(angle))); + float angle = -std::atan(mWindSpeed / 50.f); + mRainShooter->setVelocity(osg::Vec3f(0, mRainSpeed * std::sin(angle), -mRainSpeed / std::cos(angle))); mRainShooter->setAngle(angle); - osg::Vec3 rainRange = osg::Vec3(mRainDiameter, mRainDiameter, (mRainMinHeight+mRainMaxHeight)/2.f); + osg::Vec3 rainRange = osg::Vec3(mRainDiameter, mRainDiameter, (mRainMinHeight + mRainMaxHeight) / 2.f); mPlacer->setXRange(-rainRange.x() / 2, rainRange.x() / 2); mPlacer->setYRange(-rainRange.y() / 2, rainRange.y() / 2); mPlacer->setZRange(-rainRange.z() / 2, rainRange.z() / 2); - mCounter->setNumberOfParticlesPerSecondToCreate(mRainMaxRaindrops/mRainEntranceSpeed*20); + mCounter->setNumberOfParticlesPerSecondToCreate(mRainMaxRaindrops / mRainEntranceSpeed * 20); } } @@ -620,7 +622,8 @@ namespace MWRender void SkyManager::setWeather(const WeatherResult& weather) { - if (!mCreated) return; + if (!mCreated) + return; mRainEntranceSpeed = weather.mRainEntranceSpeed; mRainMaxRaindrops = weather.mRainMaxRaindrops; @@ -694,18 +697,20 @@ namespace MWRender for (unsigned int i = 0; i < findPSVisitor.mFoundNodes.size(); ++i) { - osgParticle::ParticleSystem *ps = static_cast(findPSVisitor.mFoundNodes[i]); + osgParticle::ParticleSystem* ps + = static_cast(findPSVisitor.mFoundNodes[i]); osg::ref_ptr program = new osgParticle::ModularProgram; if (!mIsStorm) - program->addOperator(new WrapAroundOperator(mCamera,osg::Vec3(1024,1024,800))); + program->addOperator(new WrapAroundOperator(mCamera, osg::Vec3(1024, 1024, 800))); program->addOperator(new WeatherAlphaOperator(mPrecipitationAlpha, false)); program->setParticleSystem(ps); mParticleNode->addChild(program); for (int particleIndex = 0; particleIndex < ps->numParticles(); ++particleIndex) { - ps->getParticle(particleIndex)->setAlphaRange(osgParticle::rangef(mPrecipitationAlpha, mPrecipitationAlpha)); + ps->getParticle(particleIndex) + ->setAlphaRange(osgParticle::rangef(mPrecipitationAlpha, mPrecipitationAlpha)); ps->getParticle(particleIndex)->update(0, true); } @@ -722,7 +727,8 @@ namespace MWRender std::string texture = Misc::ResourceHelpers::correctTexturePath(mClouds, mSceneManager->getVFS()); - osg::ref_ptr cloudTex = new osg::Texture2D(mSceneManager->getImageManager()->getImage(texture)); + osg::ref_ptr cloudTex + = new osg::Texture2D(mSceneManager->getImageManager()->getImage(texture)); cloudTex->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT); cloudTex->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT); @@ -743,7 +749,8 @@ namespace MWRender { std::string texture = Misc::ResourceHelpers::correctTexturePath(mNextClouds, mSceneManager->getVFS()); - osg::ref_ptr cloudTex = new osg::Texture2D(mSceneManager->getImageManager()->getImage(texture)); + osg::ref_ptr cloudTex + = new osg::Texture2D(mSceneManager->getImageManager()->getImage(texture)); cloudTex->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT); cloudTex->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT); @@ -763,7 +770,7 @@ namespace MWRender if (mCloudColour != weather.mFogColor) { - osg::Vec4f clr (weather.mFogColor); + osg::Vec4f clr(weather.mFogColor); clr += osg::Vec4f(0.13f, 0.13f, 0.13f, 0.f); mCloudUpdater->setEmissionColor(clr); @@ -809,7 +816,8 @@ namespace MWRender float SkyManager::getBaseWindSpeed() const { - if (!mCreated) return 0.f; + if (!mCreated) + return 0.f; return mBaseWindSpeed; } @@ -824,40 +832,45 @@ namespace MWRender void SkyManager::sunEnable() { - if (!mCreated) return; + if (!mCreated) + return; mSun->setVisible(true); } void SkyManager::sunDisable() { - if (!mCreated) return; + if (!mCreated) + return; mSun->setVisible(false); } - void SkyManager::setStormParticleDirection(const osg::Vec3f &direction) + void SkyManager::setStormParticleDirection(const osg::Vec3f& direction) { mStormParticleDirection = direction; } void SkyManager::setSunDirection(const osg::Vec3f& direction) { - if (!mCreated) return; + if (!mCreated) + return; mSun->setDirection(direction); } void SkyManager::setMasserState(const MoonState& state) { - if(!mCreated) return; + if (!mCreated) + return; mMasser->setState(state); } void SkyManager::setSecundaState(const MoonState& state) { - if(!mCreated) return; + if (!mCreated) + return; mSecunda->setState(state); } diff --git a/apps/openmw/mwrender/sky.hpp b/apps/openmw/mwrender/sky.hpp index 8682a6f17f..a365d32342 100644 --- a/apps/openmw/mwrender/sky.hpp +++ b/apps/openmw/mwrender/sky.hpp @@ -1,12 +1,12 @@ #ifndef OPENMW_MWRENDER_SKY_H #define OPENMW_MWRENDER_SKY_H -#include #include +#include #include -#include #include +#include #include "skyutil.hpp" @@ -37,7 +37,8 @@ namespace SceneUtil namespace MWRender { - ///@brief The SkyManager handles rendering of the sky domes, celestial bodies as well as other objects that need to be rendered + ///@brief The SkyManager handles rendering of the sky domes, celestial bodies as well as other objects that need to + /// be rendered /// relative to the camera (e.g. weather particle effects) class SkyManager { @@ -49,10 +50,10 @@ namespace MWRender void setEnabled(bool enabled); - void setHour (double hour); + void setHour(double hour); ///< will be called even when sky is disabled. - void setDate (int day, int month); + void setDate(int day, int month); ///< will be called even when sky is disabled. int getMasserPhase() const; @@ -63,7 +64,7 @@ namespace MWRender ///< 0 new moon, 1 waxing or waning cresecent, 2 waxing or waning half, /// 3 waxing or waning gibbous, 4 full moon - void setMoonColour (bool red); + void setMoonColour(bool red); ///< change Secunda colour to red void setWeather(const WeatherResult& weather); @@ -97,7 +98,7 @@ namespace MWRender void listAssetsToPreload(std::vector& models, std::vector& textures); - void setCamera(osg::Camera *camera); + void setCamera(osg::Camera* camera); float getBaseWindSpeed() const; @@ -116,7 +117,7 @@ namespace MWRender Resource::SceneManager* mSceneManager; - osg::Camera *mCamera; + osg::Camera* mCamera; osg::ref_ptr mRootNode; osg::ref_ptr mEarlyRenderBinRoot; diff --git a/apps/openmw/mwrender/skyutil.cpp b/apps/openmw/mwrender/skyutil.cpp index 3c2cd1c6e9..9f0d0ec54c 100644 --- a/apps/openmw/mwrender/skyutil.cpp +++ b/apps/openmw/mwrender/skyutil.cpp @@ -2,29 +2,29 @@ #include -#include +#include +#include +#include #include #include #include +#include +#include #include #include -#include -#include -#include -#include +#include #include -#include #include #include #include -#include #include +#include -#include #include +#include #include @@ -37,8 +37,8 @@ #include "../mwworld/weather.hpp" -#include "vismask.hpp" #include "renderbin.hpp" +#include "vismask.hpp" namespace { @@ -75,20 +75,17 @@ namespace colors->push_back(osg::Vec4(1.f, 1.f, 1.f, 1.f)); geom->setColorArray(colors, osg::Array::BIND_OVERALL); - for (int i=0; isetTexCoordArray(i, texcoords, osg::Array::BIND_PER_VERTEX); - geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4)); + geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4)); return geom; } struct DummyComputeBoundCallback : osg::Node::ComputeBoundingSphereCallback { - osg::BoundingSphere computeBound(const osg::Node& node) const override - { - return osg::BoundingSphere(); - } + osg::BoundingSphere computeBound(const osg::Node& node) const override { return osg::BoundingSphere(); } }; } @@ -117,27 +114,27 @@ namespace MWRender SunUpdater() : mColor(1.f, 1.f, 1.f, 1.f) - { } - - void setDefaults(osg::StateSet* stateset) override { - stateset->setAttributeAndModes(createUnlitMaterial()); } + void setDefaults(osg::StateSet* stateset) override { stateset->setAttributeAndModes(createUnlitMaterial()); } + void apply(osg::StateSet* stateset, osg::NodeVisitor*) override { osg::Material* mat = static_cast(stateset->getAttribute(osg::StateAttribute::MATERIAL)); - mat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(0,0,0,mColor.a())); + mat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(0, 0, 0, mColor.a())); mat->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4f(mColor.r(), mColor.g(), mColor.b(), 1)); } }; - OcclusionCallback::OcclusionCallback(osg::ref_ptr oqnVisible, osg::ref_ptr oqnTotal) + OcclusionCallback::OcclusionCallback( + osg::ref_ptr oqnVisible, osg::ref_ptr oqnTotal) : mOcclusionQueryVisiblePixels(oqnVisible) , mOcclusionQueryTotalPixels(oqnTotal) - { } + { + } - float OcclusionCallback::getVisibleRatio (osg::Camera* camera) + float OcclusionCallback::getVisibleRatio(osg::Camera* camera) { int visible = mOcclusionQueryVisiblePixels->getQueryGeometry()->getNumPixels(camera); int total = mOcclusionQueryTotalPixels->getQueryGeometry()->getNumPixels(camera); @@ -150,7 +147,7 @@ namespace MWRender float lastRatio = mLastRatio[osg::observer_ptr(camera)]; - float change = dt*10; + float change = dt * 10; if (visibleRatio > lastRatio) visibleRatio = std::min(visibleRatio, lastRatio + change); @@ -162,14 +159,18 @@ namespace MWRender return visibleRatio; } - /// SunFlashCallback handles fading/scaling of a node depending on occlusion query result. Must be attached as a cull callback. - class SunFlashCallback : public OcclusionCallback, public SceneUtil::NodeCallback + /// SunFlashCallback handles fading/scaling of a node depending on occlusion query result. Must be attached as a + /// cull callback. + class SunFlashCallback : public OcclusionCallback, + public SceneUtil::NodeCallback { public: - SunFlashCallback(osg::ref_ptr oqnVisible, osg::ref_ptr oqnTotal) + SunFlashCallback( + osg::ref_ptr oqnVisible, osg::ref_ptr oqnTotal) : OcclusionCallback(oqnVisible, oqnTotal) , mGlareView(1.f) - { } + { + } void operator()(osg::Node* node, osgUtil::CullVisitor* cv) { @@ -183,10 +184,10 @@ namespace MWRender if (visibleRatio < fadeThreshold) { float fade = 1.f - (fadeThreshold - visibleRatio) / fadeThreshold; - osg::ref_ptr mat (createUnlitMaterial()); - mat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(0,0,0,fade*mGlareView)); + osg::ref_ptr mat(createUnlitMaterial()); + mat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(0, 0, 0, fade * mGlareView)); stateset = new osg::StateSet; - stateset->setAttributeAndModes(mat, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); + stateset->setAttributeAndModes(mat, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); } else if (visibleRatio < 1.f) { @@ -224,22 +225,20 @@ namespace MWRender } } - void setGlareView(float value) - { - mGlareView = value; - } + void setGlareView(float value) { mGlareView = value; } private: float mGlareView; }; - /// SunGlareCallback controls a full-screen glare effect depending on occlusion query result and the angle between sun and camera. - /// Must be attached as a cull callback to the node above the glare node. - class SunGlareCallback : public OcclusionCallback, public SceneUtil::NodeCallback + /// SunGlareCallback controls a full-screen glare effect depending on occlusion query result and the angle between + /// sun and camera. Must be attached as a cull callback to the node above the glare node. + class SunGlareCallback : public OcclusionCallback, + public SceneUtil::NodeCallback { public: - SunGlareCallback(osg::ref_ptr oqnVisible, osg::ref_ptr oqnTotal, - osg::ref_ptr sunTransform) + SunGlareCallback(osg::ref_ptr oqnVisible, + osg::ref_ptr oqnTotal, osg::ref_ptr sunTransform) : OcclusionCallback(oqnVisible, oqnTotal) , mSunTransform(sunTransform) , mTimeOfDayFade(1.f) @@ -249,15 +248,15 @@ namespace MWRender mSunGlareFaderMax = Fallback::Map::getFloat("Weather_Sun_Glare_Fader_Max"); mSunGlareFaderAngleMax = Fallback::Map::getFloat("Weather_Sun_Glare_Fader_Angle_Max"); - // Replicating a design flaw in MW. The color was being set on both ambient and emissive properties, which multiplies the result by two, - // then finally gets clamped by the fixed function pipeline. With the default INI settings, only the red component gets clamped, - // so the resulting color looks more orange than red. + // Replicating a design flaw in MW. The color was being set on both ambient and emissive properties, which + // multiplies the result by two, then finally gets clamped by the fixed function pipeline. With the default + // INI settings, only the red component gets clamped, so the resulting color looks more orange than red. mColor *= 2; - for (int i=0; i<3; ++i) + for (int i = 0; i < 3; ++i) mColor[i] = std::min(1.f, mColor[i]); } - void operator ()(osg::Node* node, osgUtil::CullVisitor* cv) + void operator()(osg::Node* node, osgUtil::CullVisitor* cv) { float angleRadians = getAngleToSunInRadians(*cv->getCurrentRenderStage()->getInitialViewMatrix()); float visibleRatio = getVisibleRatio(cv->getCurrentCamera()); @@ -280,7 +279,7 @@ namespace MWRender osg::ref_ptr mat = createUnlitMaterial(); - mat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(0,0,0,fade)); + mat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(0, 0, 0, fade)); mat->setEmission(osg::Material::FRONT_AND_BACK, mColor); stateset->setAttributeAndModes(mat); @@ -291,15 +290,9 @@ namespace MWRender } } - void setTimeOfDayFade(float val) - { - mTimeOfDayFade = val; - } + void setTimeOfDayFade(float val) { mTimeOfDayFade = val; } - void setGlareView(float glareView) - { - mGlareView = glareView; - } + void setGlareView(float glareView) { mGlareView = glareView; } private: float getAngleToSunInRadians(const osg::Matrix& viewMatrix) const @@ -344,7 +337,8 @@ namespace MWRender , mAtmosphereColor(1.0f, 1.0f, 1.0f, 1.0f) , mMoonColor(1.0f, 1.0f, 1.0f, 1.0f) , mForceShaders(forceShaders) - { } + { + } void setDefaults(osg::StateSet* stateset) override { @@ -353,13 +347,14 @@ namespace MWRender stateset->addUniform(new osg::Uniform("pass", static_cast(Pass::Moon))); stateset->setTextureAttributeAndModes(0, mPhaseTex); stateset->setTextureAttributeAndModes(1, mCircleTex); - stateset->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); - stateset->setTextureMode(1, GL_TEXTURE_2D, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); + stateset->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); + stateset->setTextureMode(1, GL_TEXTURE_2D, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); stateset->addUniform(new osg::Uniform("moonBlend", osg::Vec4f{})); stateset->addUniform(new osg::Uniform("atmosphereFade", osg::Vec4f{})); stateset->addUniform(new osg::Uniform("diffuseMap", 0)); stateset->addUniform(new osg::Uniform("maskMap", 1)); - stateset->setAttributeAndModes(createUnlitMaterial(), osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); + stateset->setAttributeAndModes( + createUnlitMaterial(), osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); } else { @@ -381,7 +376,8 @@ namespace MWRender texEnv2->setSource1_RGB(osg::TexEnvCombine::CONSTANT); texEnv2->setConstantColor(osg::Vec4f(0.f, 0.f, 0.f, 1.f)); // mAtmosphereColor.rgb, mTransparency stateset->setTextureAttributeAndModes(1, texEnv2); - stateset->setAttributeAndModes(createUnlitMaterial(), osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); + stateset->setAttributeAndModes( + createUnlitMaterial(), osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); } } @@ -389,21 +385,25 @@ namespace MWRender { if (mForceShaders) { - stateset->setTextureAttribute(0, mPhaseTex, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); - stateset->setTextureAttribute(1, mCircleTex, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); + stateset->setTextureAttribute(0, mPhaseTex, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); + stateset->setTextureAttribute(1, mCircleTex, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); if (auto* uMoonBlend = stateset->getUniform("moonBlend")) uMoonBlend->set(mMoonColor * mShadowBlend); if (auto* uAtmosphereFade = stateset->getUniform("atmosphereFade")) - uAtmosphereFade->set(osg::Vec4f(mAtmosphereColor.x(), mAtmosphereColor.y(), mAtmosphereColor.z(), mTransparency)); + uAtmosphereFade->set( + osg::Vec4f(mAtmosphereColor.x(), mAtmosphereColor.y(), mAtmosphereColor.z(), mTransparency)); } else { - osg::TexEnvCombine* texEnv = static_cast(stateset->getTextureAttribute(0, osg::StateAttribute::TEXENV)); + osg::TexEnvCombine* texEnv + = static_cast(stateset->getTextureAttribute(0, osg::StateAttribute::TEXENV)); texEnv->setConstantColor(mMoonColor * mShadowBlend); - osg::TexEnvCombine* texEnv2 = static_cast(stateset->getTextureAttribute(1, osg::StateAttribute::TEXENV)); - texEnv2->setConstantColor(osg::Vec4f(mAtmosphereColor.x(), mAtmosphereColor.y(), mAtmosphereColor.z(), mTransparency)); + osg::TexEnvCombine* texEnv2 + = static_cast(stateset->getTextureAttribute(1, osg::StateAttribute::TEXENV)); + texEnv2->setConstantColor( + osg::Vec4f(mAtmosphereColor.x(), mAtmosphereColor.y(), mAtmosphereColor.z(), mTransparency)); } } @@ -420,10 +420,11 @@ namespace MWRender } }; - class CameraRelativeTransformCullCallback : public SceneUtil::NodeCallback + class CameraRelativeTransformCullCallback + : public SceneUtil::NodeCallback { public: - void operator() (osg::Node* node, osgUtil::CullVisitor* cv) + void operator()(osg::Node* node, osgUtil::CullVisitor* cv) { // XXX have to remove unwanted culling plane of the water reflection camera @@ -436,7 +437,7 @@ namespace MWRender unsigned int mask = 0x1; unsigned int resultMask = cv->getProjectionCullingStack().back().getFrustum().getResultMask(); - for (unsigned int i=0; igetProjectionCullingStack().back().getFrustum().getPlaneList().size(); ++i) + for (unsigned int i = 0; i < cv->getProjectionCullingStack().back().getFrustum().getPlaneList().size(); ++i) { if (i >= numPlanes) { @@ -467,7 +468,8 @@ namespace MWRender void AtmosphereUpdater::setDefaults(osg::StateSet* stateset) { - stateset->setAttributeAndModes(createAlphaTrackingUnlitMaterial(), osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); + stateset->setAttributeAndModes( + createAlphaTrackingUnlitMaterial(), osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); stateset->addUniform(new osg::Uniform("pass", static_cast(Pass::Atmosphere))); } @@ -478,10 +480,11 @@ namespace MWRender } AtmosphereNightUpdater::AtmosphereNightUpdater(Resource::ImageManager* imageManager, bool forceShaders) - : mColor(osg::Vec4f(0,0,0,0)) + : mColor(osg::Vec4f(0, 0, 0, 0)) , mTexture(new osg::Texture2D(imageManager->getWarningImage())) , mForceShaders(forceShaders) - { } + { + } void AtmosphereNightUpdater::setFade(float fade) { @@ -504,8 +507,8 @@ namespace MWRender texEnv->setCombine_RGB(osg::TexEnvCombine::REPLACE); texEnv->setSource0_RGB(osg::TexEnvCombine::PREVIOUS); - stateset->setTextureAttributeAndModes(1, mTexture, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); - stateset->setTextureAttributeAndModes(1, texEnv, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); + stateset->setTextureAttributeAndModes(1, mTexture, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); + stateset->setTextureAttributeAndModes(1, texEnv, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); } } @@ -517,7 +520,8 @@ namespace MWRender } else { - osg::TexEnvCombine* texEnv = static_cast(stateset->getTextureAttribute(1, osg::StateAttribute::TEXENV)); + osg::TexEnvCombine* texEnv + = static_cast(stateset->getTextureAttribute(1, osg::StateAttribute::TEXENV)); texEnv->setConstantColor(mColor); } } @@ -525,7 +529,8 @@ namespace MWRender CloudUpdater::CloudUpdater(bool forceShaders) : mOpacity(0.f) , mForceShaders(forceShaders) - { } + { + } void CloudUpdater::setTexture(osg::ref_ptr texture) { @@ -547,16 +552,17 @@ namespace MWRender mTexMat = osg::Matrixf::translate(osg::Vec3f(0.f, -timer, 0.f)); } - void CloudUpdater::setDefaults(osg::StateSet *stateset) + void CloudUpdater::setDefaults(osg::StateSet* stateset) { - stateset->setAttribute(createAlphaTrackingUnlitMaterial(), osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); + stateset->setAttribute( + createAlphaTrackingUnlitMaterial(), osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); osg::ref_ptr texmat = new osg::TexMat; stateset->setTextureAttributeAndModes(0, texmat); if (mForceShaders) { - stateset->setTextureAttribute(0, mTexture, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); + stateset->setTextureAttribute(0, mTexture, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); stateset->addUniform(new osg::Uniform("opacity", 1.f)); stateset->addUniform(new osg::Uniform("pass", static_cast(Pass::Clouds))); @@ -569,20 +575,20 @@ namespace MWRender texEnvCombine->setSource0_RGB(osg::TexEnvCombine::PREVIOUS); texEnvCombine->setSource0_Alpha(osg::TexEnvCombine::PREVIOUS); texEnvCombine->setSource1_Alpha(osg::TexEnvCombine::CONSTANT); - texEnvCombine->setConstantColor(osg::Vec4f(1,1,1,1)); + texEnvCombine->setConstantColor(osg::Vec4f(1, 1, 1, 1)); texEnvCombine->setCombine_Alpha(osg::TexEnvCombine::MODULATE); texEnvCombine->setCombine_RGB(osg::TexEnvCombine::REPLACE); stateset->setTextureAttributeAndModes(1, texEnvCombine); - stateset->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); - stateset->setTextureMode(1, GL_TEXTURE_2D, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); + stateset->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); + stateset->setTextureMode(1, GL_TEXTURE_2D, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); } } - void CloudUpdater::apply(osg::StateSet *stateset, osg::NodeVisitor *nv) + void CloudUpdater::apply(osg::StateSet* stateset, osg::NodeVisitor* nv) { - stateset->setTextureAttribute(0, mTexture, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); + stateset->setTextureAttribute(0, mTexture, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); osg::Material* mat = static_cast(stateset->getAttribute(osg::StateAttribute::MATERIAL)); mat->setEmission(osg::Material::FRONT_AND_BACK, mEmissionColor); @@ -596,27 +602,25 @@ namespace MWRender } else { - stateset->setTextureAttribute(1, mTexture, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); + stateset->setTextureAttribute(1, mTexture, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); - osg::TexEnvCombine* texEnv = static_cast(stateset->getTextureAttribute(1, osg::StateAttribute::TEXENV)); - texEnv->setConstantColor(osg::Vec4f(1,1,1,mOpacity)); + osg::TexEnvCombine* texEnv + = static_cast(stateset->getTextureAttribute(1, osg::StateAttribute::TEXENV)); + texEnv->setConstantColor(osg::Vec4f(1, 1, 1, mOpacity)); } } - class SkyStereoStatesetUpdater : public SceneUtil::StateSetUpdater { public: - SkyStereoStatesetUpdater() - { - } + SkyStereoStatesetUpdater() {} protected: void setDefaults(osg::StateSet* stateset) override { if (!Stereo::getMultiview()) - stateset->addUniform(new osg::Uniform(osg::Uniform::FLOAT_MAT4, "projectionMatrix"), osg::StateAttribute::OVERRIDE); - + stateset->addUniform( + new osg::Uniform(osg::Uniform::FLOAT_MAT4, "projectionMatrix"), osg::StateAttribute::OVERRIDE); } void apply(osg::StateSet* stateset, osg::NodeVisitor* /*nv*/) override @@ -626,11 +630,11 @@ namespace MWRender std::array projectionMatrices; auto& sm = Stereo::Manager::instance(); - for (int view : {0, 1}) + for (int view : { 0, 1 }) { auto projectionMatrix = sm.computeEyeProjection(view, true); auto viewOffsetMatrix = sm.computeEyeViewOffset(view); - for (int col : {0, 1, 2}) + for (int col : { 0, 1, 2 }) viewOffsetMatrix(3, col) = 0; projectionMatrices[view] = viewOffsetMatrix * projectionMatrix; @@ -645,7 +649,7 @@ namespace MWRender auto* projectionMatrixUniform = stateset->getUniform("projectionMatrix"); auto projectionMatrix = sm.computeEyeProjection(0, true); auto viewOffsetMatrix = sm.computeEyeViewOffset(0); - for (int col : {0, 1, 2}) + for (int col : { 0, 1, 2 }) viewOffsetMatrix(3, col) = 0; projectionMatrixUniform->set(viewOffsetMatrix * projectionMatrix); @@ -656,7 +660,7 @@ namespace MWRender auto* projectionMatrixUniform = stateset->getUniform("projectionMatrix"); auto projectionMatrix = sm.computeEyeProjection(1, true); auto viewOffsetMatrix = sm.computeEyeViewOffset(1); - for (int col : {0, 1, 2}) + for (int col : { 0, 1, 2 }) viewOffsetMatrix(3, col) = 0; projectionMatrixUniform->set(viewOffsetMatrix * projectionMatrix); @@ -679,7 +683,8 @@ namespace MWRender CameraRelativeTransform::CameraRelativeTransform(const CameraRelativeTransform& copy, const osg::CopyOp& copyop) : osg::Transform(copy, copyop) - { } + { + } const osg::Vec3f& CameraRelativeTransform::getLastViewPoint() const { @@ -693,9 +698,9 @@ namespace MWRender mViewPoint = static_cast(nv)->getViewPoint(); } - if (_referenceFrame==RELATIVE_RF) + if (_referenceFrame == RELATIVE_RF) { - matrix.setTrans(osg::Vec3f(0.f,0.f,0.f)); + matrix.setTrans(osg::Vec3f(0.f, 0.f, 0.f)); return false; } else // absolute @@ -714,7 +719,8 @@ namespace MWRender : mCameraRelativeTransform(cameraRelativeTransform) , mEnabled(true) , mWaterLevel(0.f) - { } + { + } bool UnderwaterSwitchCallback::isUnderwater() { @@ -748,7 +754,7 @@ namespace MWRender mGeom->getOrCreateStateSet(); mTransform = new osg::PositionAttitudeTransform; mTransform->setNodeMask(mVisibleMask); - mTransform->setScale(osg::Vec3f(450,450,450) * scaleFactor); + mTransform->setScale(osg::Vec3f(450, 450, 450) * scaleFactor); mTransform->addChild(mGeom); parentNode->addChild(mTransform); @@ -780,7 +786,8 @@ namespace MWRender osg::StateSet* stateset = queryNode->getOrCreateStateSet(); stateset->setRenderBinDetails(RenderBin_OcclusionQuery, "RenderBin"); stateset->setNestRenderBins(false); - // Set up alpha testing on the occlusion testing subgraph, that way we can get the occlusion tested fragments to match the circular shape of the sun + // Set up alpha testing on the occlusion testing subgraph, that way we can get the occlusion tested fragments to + // match the circular shape of the sun if (!sceneManager.getForceShaders()) { osg::ref_ptr alphaFunc = new osg::AlphaFunc; @@ -857,15 +864,15 @@ namespace MWRender // With OSG 3.6.5, the method of providing user defined query geometry has been completely replaced osg::ref_ptr queryGeom = new osg::QueryGeometry(oqn->getName()); - // Make it fast! A DYNAMIC query geometry means we can't break frame until the flare is rendered (which is rendered after all the other geometry, - // so that would be pretty bad). STATIC should be safe, since our node's local bounds are static, thus computeBounds() which modifies the queryGeometry - // is only called once. - // Note the debug geometry setDebugDisplay(true) is always DYNAMIC and that can't be changed, not a big deal. + // Make it fast! A DYNAMIC query geometry means we can't break frame until the flare is rendered (which is + // rendered after all the other geometry, so that would be pretty bad). STATIC should be safe, since our node's + // local bounds are static, thus computeBounds() which modifies the queryGeometry is only called once. Note the + // debug geometry setDebugDisplay(true) is always DYNAMIC and that can't be changed, not a big deal. queryGeom->setDataVariance(osg::Object::STATIC); - // Set up the query geometry to match the actual sun's rendering shape. osg::OcclusionQueryNode wasn't originally intended to allow this, - // normally it would automatically adjust the query geometry to match the sub graph's bounding box. The below hack is needed to - // circumvent this. + // Set up the query geometry to match the actual sun's rendering shape. osg::OcclusionQueryNode wasn't + // originally intended to allow this, normally it would automatically adjust the query geometry to match the sub + // graph's bounding box. The below hack is needed to circumvent this. queryGeom->setVertexArray(mGeom->getVertexArray()); queryGeom->setTexCoordArray(0, mGeom->getTexCoordArray(0), osg::Array::BIND_PER_VERTEX); queryGeom->removePrimitiveSet(0, queryGeom->getNumPrimitiveSets()); @@ -905,12 +912,13 @@ namespace MWRender void Sun::createSunFlash(Resource::ImageManager& imageManager) { - osg::ref_ptr tex = new osg::Texture2D(imageManager.getImage("textures/tx_sun_flash_grey_05.dds")); + osg::ref_ptr tex + = new osg::Texture2D(imageManager.getImage("textures/tx_sun_flash_grey_05.dds")); tex->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE); tex->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE); tex->setName("diffuseMap"); - osg::ref_ptr group (new osg::Group); + osg::ref_ptr group(new osg::Group); mTransform->addChild(group); @@ -950,10 +958,12 @@ namespace MWRender camera->setClearMask(0); camera->setRenderOrder(osg::Camera::NESTED_RENDER); camera->setAllowEventFocus(false); - camera->getOrCreateStateSet()->addUniform(new osg::Uniform("projectionMatrix", static_cast(camera->getProjectionMatrix()))); + camera->getOrCreateStateSet()->addUniform( + new osg::Uniform("projectionMatrix", static_cast(camera->getProjectionMatrix()))); SceneUtil::setCameraClearDepth(camera); - osg::ref_ptr geom = osg::createTexturedQuadGeometry(osg::Vec3f(-1,-1,0), osg::Vec3f(2,0,0), osg::Vec3f(0,2,0)); + osg::ref_ptr geom + = osg::createTexturedQuadGeometry(osg::Vec3f(-1, -1, 0), osg::Vec3f(2, 0, 0), osg::Vec3f(0, 2, 0)); camera->addChild(geom); osg::StateSet* stateset = geom->getOrCreateStateSet(); @@ -1066,7 +1076,7 @@ namespace MWRender void Moon::setPhase(const MoonState::Phase& phase) { - if(mPhase == phase) + if (mPhase == phase) return; mPhase = phase; @@ -1126,7 +1136,8 @@ namespace MWRender RainShooter::RainShooter() : mAngle(0.f) - { } + { + } void RainShooter::shoot(osgParticle::Particle* particle) const { @@ -1149,7 +1160,7 @@ namespace MWRender return new RainShooter; } - osg::Object* RainShooter::clone(const osg::CopyOp &) const + osg::Object* RainShooter::clone(const osg::CopyOp&) const { return new RainShooter(*this); } @@ -1157,12 +1168,13 @@ namespace MWRender ModVertexAlphaVisitor::ModVertexAlphaVisitor(ModVertexAlphaVisitor::MeshType type) : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) , mType(type) - { } + { + } void ModVertexAlphaVisitor::apply(osg::Geometry& geometry) { osg::ref_ptr colors = new osg::Vec4Array(geometry.getVertexArray()->getNumElements()); - for (unsigned int i=0; isize(); ++i) + for (unsigned int i = 0; i < colors->size(); ++i) { float alpha = 1.f; @@ -1171,14 +1183,14 @@ namespace MWRender case ModVertexAlphaVisitor::Atmosphere: { // this is a cylinder, so every second vertex belongs to the bottom-most row - alpha = (i%2) ? 0.f : 1.f; + alpha = (i % 2) ? 0.f : 1.f; break; } case ModVertexAlphaVisitor::Clouds: { - if (i>= 49 && i <= 64) + if (i >= 49 && i <= 64) alpha = 0.f; // bottom-most row - else if (i>= 33 && i <= 48) + else if (i >= 33 && i <= 48) alpha = 0.25098; // second row else alpha = 1.f; diff --git a/apps/openmw/mwrender/skyutil.hpp b/apps/openmw/mwrender/skyutil.hpp index 604e5909e8..d2146e5ae6 100644 --- a/apps/openmw/mwrender/skyutil.hpp +++ b/apps/openmw/mwrender/skyutil.hpp @@ -1,17 +1,17 @@ #ifndef OPENMW_MWRENDER_SKYUTIL_H #define OPENMW_MWRENDER_SKYUTIL_H -#include +#include #include #include #include -#include +#include -#include #include +#include -#include #include +#include namespace Resource { @@ -109,10 +109,11 @@ namespace MWRender class OcclusionCallback { public: - OcclusionCallback(osg::ref_ptr oqnVisible, osg::ref_ptr oqnTotal); + OcclusionCallback( + osg::ref_ptr oqnVisible, osg::ref_ptr oqnTotal); protected: - float getVisibleRatio (osg::Camera* camera); + float getVisibleRatio(osg::Camera* camera); private: osg::ref_ptr mOcclusionQueryVisiblePixels; @@ -164,8 +165,8 @@ namespace MWRender void setTextureCoord(float timer); protected: - void setDefaults(osg::StateSet *stateset) override; - void apply(osg::StateSet *stateset, osg::NodeVisitor *nv) override; + void setDefaults(osg::StateSet* stateset) override; + void apply(osg::StateSet* stateset, osg::NodeVisitor* nv) override; private: osg::ref_ptr mTexture; @@ -186,7 +187,7 @@ namespace MWRender META_Node(MWRender, CameraRelativeTransform) - const osg::Vec3f& getLastViewPoint() const; + const osg::Vec3f& getLastViewPoint() const; bool computeLocalToWorldMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const override; @@ -200,7 +201,8 @@ namespace MWRender /// @brief Hides the node subgraph if the eye point is below water. /// @note Must be added as cull callback. /// @note Meant to be used on a node that is child of a CameraRelativeTransform. - /// The current view point must be retrieved by the CameraRelativeTransform since we can't get it anymore once we are in camera-relative space. + /// The current view point must be retrieved by the CameraRelativeTransform since we can't get it anymore once we + /// are in camera-relative space. class UnderwaterSwitchCallback : public SceneUtil::NodeCallback { public: @@ -221,7 +223,7 @@ namespace MWRender class CelestialBody { public: - CelestialBody(osg::Group* parentNode, float scaleFactor, int numUvSets, unsigned int visibleMask=~0u); + CelestialBody(osg::Group* parentNode, float scaleFactor, int numUvSets, unsigned int visibleMask = ~0u); virtual ~CelestialBody() = default; @@ -251,7 +253,8 @@ namespace MWRender void setSunglare(bool enabled); private: - /// @param queryVisible If true, queries the amount of visible pixels. If false, queries the total amount of pixels. + /// @param queryVisible If true, queries the amount of visible pixels. If false, queries the total amount of + /// pixels. osg::ref_ptr createOcclusionQueryNode(osg::Group* parent, bool queryVisible); void createSunFlash(Resource::ImageManager& imageManager); @@ -310,7 +313,7 @@ namespace MWRender osg::Object* cloneType() const override; - osg::Object* clone(const osg::CopyOp &) const override; + osg::Object* clone(const osg::CopyOp&) const override; void shoot(osgParticle::Particle* particle) const override; diff --git a/apps/openmw/mwrender/terrainstorage.cpp b/apps/openmw/mwrender/terrainstorage.cpp index 879a2ef68b..fc3b77a4e6 100644 --- a/apps/openmw/mwrender/terrainstorage.cpp +++ b/apps/openmw/mwrender/terrainstorage.cpp @@ -1,7 +1,7 @@ #include "terrainstorage.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" #include "../mwworld/esmstore.hpp" #include "landmanager.hpp" @@ -9,9 +9,13 @@ namespace MWRender { - TerrainStorage::TerrainStorage(Resource::ResourceSystem* resourceSystem, const std::string& normalMapPattern, const std::string& normalHeightMapPattern, bool autoUseNormalMaps, const std::string& specularMapPattern, bool autoUseSpecularMaps) - : ESMTerrain::Storage(resourceSystem->getVFS(), normalMapPattern, normalHeightMapPattern, autoUseNormalMaps, specularMapPattern, autoUseSpecularMaps) - , mLandManager(new LandManager(ESM::Land::DATA_VCLR|ESM::Land::DATA_VHGT|ESM::Land::DATA_VNML|ESM::Land::DATA_VTEX)) + TerrainStorage::TerrainStorage(Resource::ResourceSystem* resourceSystem, const std::string& normalMapPattern, + const std::string& normalHeightMapPattern, bool autoUseNormalMaps, const std::string& specularMapPattern, + bool autoUseSpecularMaps) + : ESMTerrain::Storage(resourceSystem->getVFS(), normalMapPattern, normalHeightMapPattern, autoUseNormalMaps, + specularMapPattern, autoUseSpecularMaps) + , mLandManager(new LandManager( + ESM::Land::DATA_VCLR | ESM::Land::DATA_VHGT | ESM::Land::DATA_VNML | ESM::Land::DATA_VTEX)) , mResourceSystem(resourceSystem) { mResourceSystem->addResourceManager(mLandManager.get()); @@ -24,8 +28,7 @@ namespace MWRender bool TerrainStorage::hasData(int cellX, int cellY) { - const MWWorld::ESMStore &esmStore = - MWBase::Environment::get().getWorld()->getStore(); + const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); const ESM::Land* land = esmStore.get().search(cellX, cellY); return land != nullptr; @@ -38,8 +41,7 @@ namespace MWRender maxX = 0; maxY = 0; - const MWWorld::ESMStore &esmStore = - MWBase::Environment::get().getWorld()->getStore(); + const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); MWWorld::Store::iterator it = esmStore.get().begin(); for (; it != esmStore.get().end(); ++it) @@ -59,7 +61,7 @@ namespace MWRender maxY += 1; } - LandManager *TerrainStorage::getLandManager() const + LandManager* TerrainStorage::getLandManager() const { return mLandManager.get(); } @@ -71,10 +73,8 @@ namespace MWRender const ESM::LandTexture* TerrainStorage::getLandTexture(int index, short plugin) { - const MWWorld::ESMStore &esmStore = - MWBase::Environment::get().getWorld()->getStore(); + const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); return esmStore.get().search(index, plugin); } - } diff --git a/apps/openmw/mwrender/terrainstorage.hpp b/apps/openmw/mwrender/terrainstorage.hpp index edea556157..f79b195a63 100644 --- a/apps/openmw/mwrender/terrainstorage.hpp +++ b/apps/openmw/mwrender/terrainstorage.hpp @@ -16,11 +16,12 @@ namespace MWRender class TerrainStorage : public ESMTerrain::Storage { public: - - TerrainStorage(Resource::ResourceSystem* resourceSystem, const std::string& normalMapPattern = "", const std::string& normalHeightMapPattern = "", bool autoUseNormalMaps = false, const std::string& specularMapPattern = "", bool autoUseSpecularMaps = false); + TerrainStorage(Resource::ResourceSystem* resourceSystem, const std::string& normalMapPattern = "", + const std::string& normalHeightMapPattern = "", bool autoUseNormalMaps = false, + const std::string& specularMapPattern = "", bool autoUseSpecularMaps = false); ~TerrainStorage(); - osg::ref_ptr getLand (int cellX, int cellY) override; + osg::ref_ptr getLand(int cellX, int cellY) override; const ESM::LandTexture* getLandTexture(int index, short plugin) override; bool hasData(int cellX, int cellY) override; @@ -31,12 +32,11 @@ namespace MWRender LandManager* getLandManager() const; private: - std::unique_ptr mLandManager; + std::unique_ptr mLandManager; - Resource::ResourceSystem* mResourceSystem; + Resource::ResourceSystem* mResourceSystem; }; } - #endif diff --git a/apps/openmw/mwrender/transparentpass.cpp b/apps/openmw/mwrender/transparentpass.cpp index 237ebdf9da..cd72f5b7d6 100644 --- a/apps/openmw/mwrender/transparentpass.cpp +++ b/apps/openmw/mwrender/transparentpass.cpp @@ -1,134 +1,147 @@ #include "transparentpass.hpp" +#include #include +#include #include #include -#include -#include #include +#include #include #include #include -#include #include "vismask.hpp" namespace MWRender { - TransparentDepthBinCallback::TransparentDepthBinCallback(Shader::ShaderManager& shaderManager, bool postPass) - : mStateSet(new osg::StateSet) - , mPostPass(postPass) + TransparentDepthBinCallback::TransparentDepthBinCallback(Shader::ShaderManager& shaderManager, bool postPass) + : mStateSet(new osg::StateSet) + , mPostPass(postPass) + { + osg::ref_ptr image = new osg::Image; + image->allocateImage(1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE); + image->setColor(osg::Vec4(1, 1, 1, 1), 0, 0); + + osg::ref_ptr dummyTexture = new osg::Texture2D(image); + + constexpr osg::StateAttribute::OverrideValue modeOff = osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE; + constexpr osg::StateAttribute::OverrideValue modeOn = osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE; + + mStateSet->setTextureAttributeAndModes(0, dummyTexture); + + Shader::ShaderManager::DefineMap defines; + Stereo::Manager::instance().shaderStereoDefines(defines); + osg::ref_ptr vertex + = shaderManager.getShader("blended_depth_postpass_vertex.glsl", defines, osg::Shader::VERTEX); + osg::ref_ptr fragment + = shaderManager.getShader("blended_depth_postpass_fragment.glsl", defines, osg::Shader::FRAGMENT); + + mStateSet->setAttributeAndModes(new osg::BlendFunc, modeOff); + mStateSet->setAttributeAndModes(shaderManager.getProgram(vertex, fragment), modeOn); + mStateSet->setAttributeAndModes(new SceneUtil::AutoDepth, modeOn); + + for (unsigned int unit = 1; unit < 8; ++unit) + mStateSet->setTextureMode(unit, GL_TEXTURE_2D, modeOff); + } + + void TransparentDepthBinCallback::drawImplementation( + osgUtil::RenderBin* bin, osg::RenderInfo& renderInfo, osgUtil::RenderLeaf*& previous) + { + osg::State& state = *renderInfo.getState(); + osg::GLExtensions* ext = state.get(); + + bool validFbo = false; + unsigned int frameId = state.getFrameStamp()->getFrameNumber() % 2; + + const auto& fbo = mFbo[frameId]; + const auto& msaaFbo = mMsaaFbo[frameId]; + const auto& opaqueFbo = mOpaqueFbo[frameId]; + + if (bin->getStage()->getMultisampleResolveFramebufferObject() + && bin->getStage()->getMultisampleResolveFramebufferObject() == fbo) + validFbo = true; + else if (bin->getStage()->getFrameBufferObject() + && (bin->getStage()->getFrameBufferObject() == fbo || bin->getStage()->getFrameBufferObject() == msaaFbo)) + validFbo = true; + + if (!validFbo) { - osg::ref_ptr image = new osg::Image; - image->allocateImage(1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE); - image->setColor(osg::Vec4(1,1,1,1), 0, 0); - - osg::ref_ptr dummyTexture = new osg::Texture2D(image); - - constexpr osg::StateAttribute::OverrideValue modeOff = osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE; - constexpr osg::StateAttribute::OverrideValue modeOn = osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE; - - mStateSet->setTextureAttributeAndModes(0, dummyTexture); - - Shader::ShaderManager::DefineMap defines; - Stereo::Manager::instance().shaderStereoDefines(defines); - osg::ref_ptr vertex = shaderManager.getShader("blended_depth_postpass_vertex.glsl", defines, osg::Shader::VERTEX); - osg::ref_ptr fragment = shaderManager.getShader("blended_depth_postpass_fragment.glsl", defines, osg::Shader::FRAGMENT); - - mStateSet->setAttributeAndModes(new osg::BlendFunc, modeOff); - mStateSet->setAttributeAndModes(shaderManager.getProgram(vertex, fragment), modeOn); - mStateSet->setAttributeAndModes(new SceneUtil::AutoDepth, modeOn); - - for (unsigned int unit = 1; unit < 8; ++unit) - mStateSet->setTextureMode(unit, GL_TEXTURE_2D, modeOff); + bin->drawImplementation(renderInfo, previous); + return; } - void TransparentDepthBinCallback::drawImplementation(osgUtil::RenderBin* bin, osg::RenderInfo& renderInfo, osgUtil::RenderLeaf*& previous) - { - osg::State& state = *renderInfo.getState(); - osg::GLExtensions* ext = state.get(); + const osg::Texture* tex + = opaqueFbo->getAttachment(osg::FrameBufferObject::BufferComponent::PACKED_DEPTH_STENCIL_BUFFER) + .getTexture(); - bool validFbo = false; - unsigned int frameId = state.getFrameStamp()->getFrameNumber() % 2; - - const auto& fbo = mFbo[frameId]; - const auto& msaaFbo = mMsaaFbo[frameId]; - const auto& opaqueFbo = mOpaqueFbo[frameId]; - - if (bin->getStage()->getMultisampleResolveFramebufferObject() && bin->getStage()->getMultisampleResolveFramebufferObject() == fbo) - validFbo = true; - else if (bin->getStage()->getFrameBufferObject() && (bin->getStage()->getFrameBufferObject() == fbo || bin->getStage()->getFrameBufferObject() == msaaFbo)) - validFbo = true; - - if (!validFbo) + if (Stereo::getMultiview()) + { + if (!mMultiviewResolve[frameId]) { - bin->drawImplementation(renderInfo, previous); - return; + mMultiviewResolve[frameId] = std::make_unique( + msaaFbo ? msaaFbo : fbo, opaqueFbo, GL_DEPTH_BUFFER_BIT); } + mMultiviewResolve[frameId]->resolveImplementation(state); + } + else + { + opaqueFbo->apply(state, osg::FrameBufferObject::DRAW_FRAMEBUFFER); + ext->glBlitFramebuffer(0, 0, tex->getTextureWidth(), tex->getTextureHeight(), 0, 0, tex->getTextureWidth(), + tex->getTextureHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); + } - const osg::Texture* tex = opaqueFbo->getAttachment(osg::FrameBufferObject::BufferComponent::PACKED_DEPTH_STENCIL_BUFFER).getTexture(); + msaaFbo ? msaaFbo->apply(state, osg::FrameBufferObject::DRAW_FRAMEBUFFER) + : fbo->apply(state, osg::FrameBufferObject::DRAW_FRAMEBUFFER); - if (Stereo::getMultiview()) - { - if (!mMultiviewResolve[frameId]) - { - mMultiviewResolve[frameId] = std::make_unique(msaaFbo ? msaaFbo : fbo, opaqueFbo, GL_DEPTH_BUFFER_BIT); - } - mMultiviewResolve[frameId]->resolveImplementation(state); - } - else - { - opaqueFbo->apply(state, osg::FrameBufferObject::DRAW_FRAMEBUFFER); - ext->glBlitFramebuffer(0, 0, tex->getTextureWidth(), tex->getTextureHeight(), 0, 0, tex->getTextureWidth(), tex->getTextureHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); - } + // draws scene into primary attachments + bin->drawImplementation(renderInfo, previous); - msaaFbo ? msaaFbo->apply(state, osg::FrameBufferObject::DRAW_FRAMEBUFFER) : fbo->apply(state, osg::FrameBufferObject::DRAW_FRAMEBUFFER); + if (!mPostPass) + return; - // draws scene into primary attachments - bin->drawImplementation(renderInfo, previous); + opaqueFbo->apply(state, osg::FrameBufferObject::DRAW_FRAMEBUFFER); - if (!mPostPass) - return; + // draw transparent post-pass to populate a postprocess friendly depth texture with alpha-clipped geometry - opaqueFbo->apply(state, osg::FrameBufferObject::DRAW_FRAMEBUFFER); + unsigned int numToPop = previous ? osgUtil::StateGraph::numToPop(previous->_parent) : 0; + if (numToPop > 1) + numToPop--; + unsigned int insertStateSetPosition = state.getStateSetStackSize() - numToPop; - // draw transparent post-pass to populate a postprocess friendly depth texture with alpha-clipped geometry + state.insertStateSet(insertStateSetPosition, mStateSet); + for (auto rit = bin->getRenderLeafList().begin(); rit != bin->getRenderLeafList().end(); rit++) + { + osgUtil::RenderLeaf* rl = *rit; + const osg::StateSet* ss = rl->_parent->getStateSet(); - unsigned int numToPop = previous ? osgUtil::StateGraph::numToPop(previous->_parent) : 0; - if (numToPop > 1) - numToPop--; - unsigned int insertStateSetPosition = state.getStateSetStackSize() - numToPop; + if (rl->_drawable->getNodeMask() == Mask_ParticleSystem || rl->_drawable->getNodeMask() == Mask_Effect) + continue; - state.insertStateSet(insertStateSetPosition, mStateSet); - for(auto rit = bin->getRenderLeafList().begin(); rit != bin->getRenderLeafList().end(); rit++) + if (ss->getAttribute(osg::StateAttribute::MATERIAL)) { - osgUtil::RenderLeaf* rl = *rit; - const osg::StateSet* ss = rl->_parent->getStateSet(); - - if (rl->_drawable->getNodeMask() == Mask_ParticleSystem || rl->_drawable->getNodeMask() == Mask_Effect) + const osg::Material* mat + = static_cast(ss->getAttribute(osg::StateAttribute::MATERIAL)); + if (mat->getDiffuse(osg::Material::FRONT).a() < 0.5) continue; - - if (ss->getAttribute(osg::StateAttribute::MATERIAL)) { - const osg::Material* mat = static_cast(ss->getAttribute(osg::StateAttribute::MATERIAL)); - if (mat->getDiffuse(osg::Material::FRONT).a() < 0.5) - continue; - } - - rl->render(renderInfo,previous); - previous = rl; } - state.removeStateSet(insertStateSetPosition); - - msaaFbo ? msaaFbo->apply(state, osg::FrameBufferObject::DRAW_FRAMEBUFFER) : fbo->apply(state, osg::FrameBufferObject::DRAW_FRAMEBUFFER); - state.checkGLErrors("after TransparentDepthBinCallback::drawImplementation"); - } - void TransparentDepthBinCallback::dirtyFrame(int frameId) - { - if (mMultiviewResolve[frameId]) - mMultiviewResolve[frameId]->dirty(); + rl->render(renderInfo, previous); + previous = rl; } + state.removeStateSet(insertStateSetPosition); + + msaaFbo ? msaaFbo->apply(state, osg::FrameBufferObject::DRAW_FRAMEBUFFER) + : fbo->apply(state, osg::FrameBufferObject::DRAW_FRAMEBUFFER); + state.checkGLErrors("after TransparentDepthBinCallback::drawImplementation"); + } + + void TransparentDepthBinCallback::dirtyFrame(int frameId) + { + if (mMultiviewResolve[frameId]) + mMultiviewResolve[frameId]->dirty(); + } } diff --git a/apps/openmw/mwrender/transparentpass.hpp b/apps/openmw/mwrender/transparentpass.hpp index 0522ee4687..3af6eb5abd 100644 --- a/apps/openmw/mwrender/transparentpass.hpp +++ b/apps/openmw/mwrender/transparentpass.hpp @@ -26,7 +26,8 @@ namespace MWRender public: TransparentDepthBinCallback(Shader::ShaderManager& shaderManager, bool postPass); - void drawImplementation(osgUtil::RenderBin* bin, osg::RenderInfo& renderInfo, osgUtil::RenderLeaf*& previous) override; + void drawImplementation( + osgUtil::RenderBin* bin, osg::RenderInfo& renderInfo, osgUtil::RenderLeaf*& previous) override; void dirtyFrame(int frameId); std::array, 2> mFbo; diff --git a/apps/openmw/mwrender/util.cpp b/apps/openmw/mwrender/util.cpp index 9b0d1b389d..647c1db335 100644 --- a/apps/openmw/mwrender/util.cpp +++ b/apps/openmw/mwrender/util.cpp @@ -3,15 +3,15 @@ #include #include -#include -#include #include +#include +#include #include namespace MWRender { -class TextureOverrideVisitor : public osg::NodeVisitor + class TextureOverrideVisitor : public osg::NodeVisitor { public: TextureOverrideVisitor(std::string_view texture, Resource::ResourceSystem* resourcesystem) @@ -27,41 +27,44 @@ class TextureOverrideVisitor : public osg::NodeVisitor osg::ref_ptr nodePtr(&node); if (node.getUserValue("overrideFx", index)) { - if (index == 1) + if (index == 1) overrideTexture(mTexture, mResourcesystem, nodePtr); } traverse(node); } std::string_view mTexture; Resource::ResourceSystem* mResourcesystem; -}; + }; -void overrideFirstRootTexture(std::string_view texture, Resource::ResourceSystem *resourceSystem, osg::ref_ptr node) -{ - TextureOverrideVisitor overrideVisitor(texture, resourceSystem); - node->accept(overrideVisitor); -} + void overrideFirstRootTexture( + std::string_view texture, Resource::ResourceSystem* resourceSystem, osg::ref_ptr node) + { + TextureOverrideVisitor overrideVisitor(texture, resourceSystem); + node->accept(overrideVisitor); + } -void overrideTexture(std::string_view texture, Resource::ResourceSystem *resourceSystem, osg::ref_ptr node) -{ - if (texture.empty()) - return; - std::string correctedTexture = Misc::ResourceHelpers::correctTexturePath(texture, resourceSystem->getVFS()); - // Not sure if wrap settings should be pulled from the overridden texture? - osg::ref_ptr tex = new osg::Texture2D(resourceSystem->getImageManager()->getImage(correctedTexture)); - tex->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE); - tex->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE); - tex->setName("diffuseMap"); + void overrideTexture( + std::string_view texture, Resource::ResourceSystem* resourceSystem, osg::ref_ptr node) + { + if (texture.empty()) + return; + std::string correctedTexture = Misc::ResourceHelpers::correctTexturePath(texture, resourceSystem->getVFS()); + // Not sure if wrap settings should be pulled from the overridden texture? + osg::ref_ptr tex + = new osg::Texture2D(resourceSystem->getImageManager()->getImage(correctedTexture)); + tex->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE); + tex->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE); + tex->setName("diffuseMap"); - osg::ref_ptr stateset; - if (node->getStateSet()) - stateset = new osg::StateSet(*node->getStateSet(), osg::CopyOp::SHALLOW_COPY); - else - stateset = new osg::StateSet; + osg::ref_ptr stateset; + if (node->getStateSet()) + stateset = new osg::StateSet(*node->getStateSet(), osg::CopyOp::SHALLOW_COPY); + else + stateset = new osg::StateSet; - stateset->setTextureAttribute(0, tex, osg::StateAttribute::OVERRIDE); + stateset->setTextureAttribute(0, tex, osg::StateAttribute::OVERRIDE); - node->setStateSet(stateset); -} + node->setStateSet(stateset); + } } diff --git a/apps/openmw/mwrender/util.hpp b/apps/openmw/mwrender/util.hpp index 559df45c15..457b23f94b 100644 --- a/apps/openmw/mwrender/util.hpp +++ b/apps/openmw/mwrender/util.hpp @@ -17,11 +17,14 @@ namespace Resource namespace MWRender { - // Overrides the texture of nodes in the mesh that had the same NiTexturingProperty as the first NiTexturingProperty of the .NIF file's root node, - // if it had a NiTexturingProperty. Used for applying "particle textures" to magic effects. - void overrideFirstRootTexture(std::string_view texture, Resource::ResourceSystem* resourceSystem, osg::ref_ptr node); + // Overrides the texture of nodes in the mesh that had the same NiTexturingProperty as the first NiTexturingProperty + // of the .NIF file's root node, if it had a NiTexturingProperty. Used for applying "particle textures" to magic + // effects. + void overrideFirstRootTexture( + std::string_view texture, Resource::ResourceSystem* resourceSystem, osg::ref_ptr node); - void overrideTexture(std::string_view texture, Resource::ResourceSystem* resourceSystem, osg::ref_ptr node); + void overrideTexture( + std::string_view texture, Resource::ResourceSystem* resourceSystem, osg::ref_ptr node); // Node callback to entirely skip the traversal. class NoTraverseCallback : public osg::NodeCallback diff --git a/apps/openmw/mwrender/vismask.hpp b/apps/openmw/mwrender/vismask.hpp index a7a28614cb..1b25dfc366 100644 --- a/apps/openmw/mwrender/vismask.hpp +++ b/apps/openmw/mwrender/vismask.hpp @@ -24,42 +24,43 @@ namespace MWRender Mask_UpdateVisitor = 0x1, // reserved for separating UpdateVisitors from CullVisitors // child of Scene - Mask_Effect = (1<<1), - Mask_Debug = (1<<2), - Mask_Actor = (1<<3), - Mask_Player = (1<<4), - Mask_Sky = (1<<5), - Mask_Water = (1<<6), // choose Water or SimpleWater depending on detail required - Mask_SimpleWater = (1<<7), - Mask_Terrain = (1<<8), - Mask_FirstPerson = (1<<9), - Mask_Object = (1<<10), - Mask_Static = (1<<11), + Mask_Effect = (1 << 1), + Mask_Debug = (1 << 2), + Mask_Actor = (1 << 3), + Mask_Player = (1 << 4), + Mask_Sky = (1 << 5), + Mask_Water = (1 << 6), // choose Water or SimpleWater depending on detail required + Mask_SimpleWater = (1 << 7), + Mask_Terrain = (1 << 8), + Mask_FirstPerson = (1 << 9), + Mask_Object = (1 << 10), + Mask_Static = (1 << 11), // child of Sky - Mask_Sun = (1<<12), - Mask_WeatherParticles = (1<<13), + Mask_Sun = (1 << 12), + Mask_WeatherParticles = (1 << 13), // top level masks - Mask_Scene = (1<<14), - Mask_GUI = (1<<15), + Mask_Scene = (1 << 14), + Mask_GUI = (1 << 15), // Set on a ParticleSystem Drawable - Mask_ParticleSystem = (1<<16), + Mask_ParticleSystem = (1 << 16), // Set on cameras within the main scene graph - Mask_RenderToTexture = (1<<17), + Mask_RenderToTexture = (1 << 17), - Mask_PreCompile = (1<<18), + Mask_PreCompile = (1 << 18), // Set on a camera's cull mask to enable the LightManager - Mask_Lighting = (1<<19), + Mask_Lighting = (1 << 19), - Mask_Groundcover = (1<<20), + Mask_Groundcover = (1 << 20), }; // Defines masks to remove when using ToggleWorld command - constexpr static unsigned int sToggleWorldMask = Mask_Debug | Mask_Actor | Mask_Terrain | Mask_Object | Mask_Static | Mask_Groundcover; + constexpr static unsigned int sToggleWorldMask + = Mask_Debug | Mask_Actor | Mask_Terrain | Mask_Object | Mask_Static | Mask_Groundcover; } diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index d57fbe731e..21a4e6cd9b 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -2,34 +2,34 @@ #include -#include +#include #include -#include +#include +#include #include +#include #include #include -#include -#include #include #include #include -#include #include +#include #include -#include #include +#include #include +#include +#include #include #include -#include #include -#include #include #include @@ -46,822 +46,840 @@ #include "../mwbase/environment.hpp" -#include "vismask.hpp" -#include "ripplesimulation.hpp" #include "renderbin.hpp" +#include "ripplesimulation.hpp" #include "util.hpp" +#include "vismask.hpp" namespace MWRender { -// -------------------------------------------------------------------------------------------------------------------------------- + // -------------------------------------------------------------------------------------------------------------------------------- -/// @brief Allows to cull and clip meshes that are below a plane. Useful for reflection & refraction camera effects. -/// Also handles flipping of the plane when the eye point goes below it. -/// To use, simply create the scene as subgraph of this node, then do setPlane(const osg::Plane& plane); -class ClipCullNode : public osg::Group -{ - class PlaneCullCallback : public SceneUtil::NodeCallback + /// @brief Allows to cull and clip meshes that are below a plane. Useful for reflection & refraction camera effects. + /// Also handles flipping of the plane when the eye point goes below it. + /// To use, simply create the scene as subgraph of this node, then do setPlane(const osg::Plane& plane); + class ClipCullNode : public osg::Group { - public: - /// @param cullPlane The culling plane (in world space). - PlaneCullCallback(const osg::Plane* cullPlane) - : mCullPlane(cullPlane) + class PlaneCullCallback : public SceneUtil::NodeCallback { - } + public: + /// @param cullPlane The culling plane (in world space). + PlaneCullCallback(const osg::Plane* cullPlane) + : mCullPlane(cullPlane) + { + } - void operator()(osg::Node* node, osgUtil::CullVisitor* cv) - { - osg::Polytope::PlaneList origPlaneList = cv->getProjectionCullingStack().back().getFrustum().getPlaneList(); + void operator()(osg::Node* node, osgUtil::CullVisitor* cv) + { + osg::Polytope::PlaneList origPlaneList + = cv->getProjectionCullingStack().back().getFrustum().getPlaneList(); - osg::Plane plane = *mCullPlane; - plane.transform(*cv->getCurrentRenderStage()->getInitialViewMatrix()); + osg::Plane plane = *mCullPlane; + plane.transform(*cv->getCurrentRenderStage()->getInitialViewMatrix()); - osg::Vec3d eyePoint = cv->getEyePoint(); - if (mCullPlane->intersect(osg::BoundingSphere(osg::Vec3d(0,0,eyePoint.z()), 0)) > 0) - plane.flip(); + osg::Vec3d eyePoint = cv->getEyePoint(); + if (mCullPlane->intersect(osg::BoundingSphere(osg::Vec3d(0, 0, eyePoint.z()), 0)) > 0) + plane.flip(); - cv->getProjectionCullingStack().back().getFrustum().add(plane); + cv->getProjectionCullingStack().back().getFrustum().add(plane); - traverse(node, cv); + traverse(node, cv); - // undo - cv->getProjectionCullingStack().back().getFrustum().set(origPlaneList); - } + // undo + cv->getProjectionCullingStack().back().getFrustum().set(origPlaneList); + } - private: - const osg::Plane* mCullPlane; - }; + private: + const osg::Plane* mCullPlane; + }; - class FlipCallback : public SceneUtil::NodeCallback - { - public: - FlipCallback(const osg::Plane* cullPlane) - : mCullPlane(cullPlane) + class FlipCallback : public SceneUtil::NodeCallback { - } + public: + FlipCallback(const osg::Plane* cullPlane) + : mCullPlane(cullPlane) + { + } - void operator()(osg::Node* node, osgUtil::CullVisitor* cv) - { - osg::Vec3d eyePoint = cv->getEyePoint(); + void operator()(osg::Node* node, osgUtil::CullVisitor* cv) + { + osg::Vec3d eyePoint = cv->getEyePoint(); - osg::RefMatrix* modelViewMatrix = new osg::RefMatrix(*cv->getModelViewMatrix()); + osg::RefMatrix* modelViewMatrix = new osg::RefMatrix(*cv->getModelViewMatrix()); - // apply the height of the plane - // we can't apply this height in the addClipPlane() since the "flip the below graph" function would otherwise flip the height as well - modelViewMatrix->preMultTranslate(mCullPlane->getNormal() * ((*mCullPlane)[3] * -1)); + // apply the height of the plane + // we can't apply this height in the addClipPlane() since the "flip the below graph" function would + // otherwise flip the height as well + modelViewMatrix->preMultTranslate(mCullPlane->getNormal() * ((*mCullPlane)[3] * -1)); - // flip the below graph if the eye point is above the plane - if (mCullPlane->intersect(osg::BoundingSphere(osg::Vec3d(0,0,eyePoint.z()), 0)) > 0) - { - modelViewMatrix->preMultScale(osg::Vec3(1,1,-1)); + // flip the below graph if the eye point is above the plane + if (mCullPlane->intersect(osg::BoundingSphere(osg::Vec3d(0, 0, eyePoint.z()), 0)) > 0) + { + modelViewMatrix->preMultScale(osg::Vec3(1, 1, -1)); + } + + // move the plane back along its normal a little bit to prevent bleeding at the water shore + const float clipFudge = -5; + modelViewMatrix->preMultTranslate(mCullPlane->getNormal() * clipFudge); + + cv->pushModelViewMatrix(modelViewMatrix, osg::Transform::RELATIVE_RF); + traverse(node, cv); + cv->popModelViewMatrix(); } - // move the plane back along its normal a little bit to prevent bleeding at the water shore - const float clipFudge = -5; - modelViewMatrix->preMultTranslate(mCullPlane->getNormal() * clipFudge); + private: + const osg::Plane* mCullPlane; + }; - cv->pushModelViewMatrix(modelViewMatrix, osg::Transform::RELATIVE_RF); - traverse(node, cv); - cv->popModelViewMatrix(); + public: + ClipCullNode() + { + addCullCallback(new PlaneCullCallback(&mPlane)); + + mClipNodeTransform = new osg::Group; + mClipNodeTransform->addCullCallback(new FlipCallback(&mPlane)); + osg::Group::addChild(mClipNodeTransform); + + mClipNode = new osg::ClipNode; + + mClipNodeTransform->addChild(mClipNode); + } + + void setPlane(const osg::Plane& plane) + { + if (plane == mPlane) + return; + mPlane = plane; + + mClipNode->getClipPlaneList().clear(); + mClipNode->addClipPlane( + new osg::ClipPlane(0, osg::Plane(mPlane.getNormal(), 0))); // mPlane.d() applied in FlipCallback + mClipNode->setStateSetModes(*getOrCreateStateSet(), osg::StateAttribute::ON); + mClipNode->setCullingActive(false); } private: - const osg::Plane* mCullPlane; + osg::ref_ptr mClipNodeTransform; + osg::ref_ptr mClipNode; + + osg::Plane mPlane; }; -public: - ClipCullNode() + /// This callback on the Camera has the effect of a RELATIVE_RF_INHERIT_VIEWPOINT transform mode (which does not + /// exist in OSG). We want to keep the View Point of the parent camera so we will not have to recreate LODs. + class InheritViewPointCallback + : public SceneUtil::NodeCallback { - addCullCallback (new PlaneCullCallback(&mPlane)); + public: + InheritViewPointCallback() {} - mClipNodeTransform = new osg::Group; - mClipNodeTransform->addCullCallback(new FlipCallback(&mPlane)); - osg::Group::addChild(mClipNodeTransform); + void operator()(osg::Node* node, osgUtil::CullVisitor* cv) + { + osg::ref_ptr modelViewMatrix = new osg::RefMatrix(*cv->getModelViewMatrix()); + cv->popModelViewMatrix(); + cv->pushModelViewMatrix(modelViewMatrix, osg::Transform::ABSOLUTE_RF_INHERIT_VIEWPOINT); + traverse(node, cv); + } + }; - mClipNode = new osg::ClipNode; + /// Moves water mesh away from the camera slightly if the camera gets too close on the Z axis. + /// The offset works around graphics artifacts that occurred with the GL_DEPTH_CLAMP when the camera gets extremely + /// close to the mesh (seen on NVIDIA at least). Must be added as a Cull callback. + class FudgeCallback : public SceneUtil::NodeCallback + { + public: + void operator()(osg::Node* node, osgUtil::CullVisitor* cv) + { + const float fudge = 0.2; + if (std::abs(cv->getEyeLocal().z()) < fudge) + { + float diff = fudge - cv->getEyeLocal().z(); + osg::RefMatrix* modelViewMatrix = new osg::RefMatrix(*cv->getModelViewMatrix()); - mClipNodeTransform->addChild(mClipNode); - } + if (cv->getEyeLocal().z() > 0) + modelViewMatrix->preMultTranslate(osg::Vec3f(0, 0, -diff)); + else + modelViewMatrix->preMultTranslate(osg::Vec3f(0, 0, diff)); + + cv->pushModelViewMatrix(modelViewMatrix, osg::Transform::RELATIVE_RF); + traverse(node, cv); + cv->popModelViewMatrix(); + } + else + traverse(node, cv); + } + }; - void setPlane (const osg::Plane& plane) + class RainIntensityUpdater : public SceneUtil::StateSetUpdater { - if (plane == mPlane) - return; - mPlane = plane; + public: + RainIntensityUpdater() + : mRainIntensity(0.f) + { + } - mClipNode->getClipPlaneList().clear(); - mClipNode->addClipPlane(new osg::ClipPlane(0, osg::Plane(mPlane.getNormal(), 0))); // mPlane.d() applied in FlipCallback - mClipNode->setStateSetModes(*getOrCreateStateSet(), osg::StateAttribute::ON); - mClipNode->setCullingActive(false); - } + void setRainIntensity(float rainIntensity) { mRainIntensity = rainIntensity; } -private: - osg::ref_ptr mClipNodeTransform; - osg::ref_ptr mClipNode; + protected: + void setDefaults(osg::StateSet* stateset) override + { + osg::ref_ptr rainIntensityUniform = new osg::Uniform("rainIntensity", 0.0f); + stateset->addUniform(rainIntensityUniform.get()); + } - osg::Plane mPlane; -}; + void apply(osg::StateSet* stateset, osg::NodeVisitor* /*nv*/) override + { + osg::ref_ptr rainIntensityUniform = stateset->getUniform("rainIntensity"); + if (rainIntensityUniform != nullptr) + rainIntensityUniform->set(mRainIntensity); + } -/// This callback on the Camera has the effect of a RELATIVE_RF_INHERIT_VIEWPOINT transform mode (which does not exist in OSG). -/// We want to keep the View Point of the parent camera so we will not have to recreate LODs. -class InheritViewPointCallback : public SceneUtil::NodeCallback -{ -public: - InheritViewPointCallback() {} + private: + float mRainIntensity; + }; - void operator()(osg::Node* node, osgUtil::CullVisitor* cv) + osg::ref_ptr readPngImage(const std::filesystem::path& file) { - osg::ref_ptr modelViewMatrix = new osg::RefMatrix(*cv->getModelViewMatrix()); - cv->popModelViewMatrix(); - cv->pushModelViewMatrix(modelViewMatrix, osg::Transform::ABSOLUTE_RF_INHERIT_VIEWPOINT); - traverse(node, cv); + std::ifstream inStream; + inStream.open(file, std::ios_base::in | std::ios_base::binary); + if (inStream.fail()) + Log(Debug::Error) << "Error: Failed to open " << file; + osgDB::ReaderWriter* reader = osgDB::Registry::instance()->getReaderWriterForExtension("png"); + if (!reader) + { + Log(Debug::Error) << "Error: Failed to read " << file << ", no png readerwriter found"; + return osg::ref_ptr(); + } + osgDB::ReaderWriter::ReadResult result = reader->readImage(inStream); + if (!result.success()) + Log(Debug::Error) << "Error: Failed to read " << file << ": " << result.message() << " code " + << result.status(); + + return result.getImage(); } -}; -/// Moves water mesh away from the camera slightly if the camera gets too close on the Z axis. -/// The offset works around graphics artifacts that occurred with the GL_DEPTH_CLAMP when the camera gets extremely close to the mesh (seen on NVIDIA at least). -/// Must be added as a Cull callback. -class FudgeCallback : public SceneUtil::NodeCallback -{ -public: - void operator()(osg::Node* node, osgUtil::CullVisitor* cv) + class Refraction : public SceneUtil::RTTNode { - const float fudge = 0.2; - if (std::abs(cv->getEyeLocal().z()) < fudge) + public: + Refraction(uint32_t rttSize) + : RTTNode(rttSize, rttSize, 0, false, 1, StereoAwareness::Aware) + , mNodeMask(Refraction::sDefaultCullMask) { - float diff = fudge - cv->getEyeLocal().z(); - osg::RefMatrix* modelViewMatrix = new osg::RefMatrix(*cv->getModelViewMatrix()); + setDepthBufferInternalFormat(GL_DEPTH24_STENCIL8); + mClipCullNode = new ClipCullNode; + } - if (cv->getEyeLocal().z() > 0) - modelViewMatrix->preMultTranslate(osg::Vec3f(0,0,-diff)); - else - modelViewMatrix->preMultTranslate(osg::Vec3f(0,0,diff)); + void setDefaults(osg::Camera* camera) override + { + camera->setReferenceFrame(osg::Camera::RELATIVE_RF); + camera->setSmallFeatureCullingPixelSize( + Settings::Manager::getInt("small feature culling pixel size", "Water")); + camera->setName("RefractionCamera"); + camera->addCullCallback(new InheritViewPointCallback); + camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR); + + // No need for fog here, we are already applying fog on the water surface itself as well as underwater fog + // assign large value to effectively turn off fog + // shaders don't respect glDisable(GL_FOG) + osg::ref_ptr fog(new osg::Fog); + fog->setStart(10000000); + fog->setEnd(10000000); + camera->getOrCreateStateSet()->setAttributeAndModes( + fog, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE); + + camera->addChild(mClipCullNode); + camera->setNodeMask(Mask_RenderToTexture); + + if (Settings::Manager::getFloat("refraction scale", "Water") != 1) // TODO: to be removed with issue #5709 + SceneUtil::ShadowManager::disableShadowsForStateSet(camera->getOrCreateStateSet()); + } - cv->pushModelViewMatrix(modelViewMatrix, osg::Transform::RELATIVE_RF); - traverse(node, cv); - cv->popModelViewMatrix(); + void apply(osg::Camera* camera) override + { + camera->setViewMatrix(mViewMatrix); + camera->setCullMask(mNodeMask); } - else - traverse(node, cv); - } -}; -class RainIntensityUpdater : public SceneUtil::StateSetUpdater -{ -public: - RainIntensityUpdater() - : mRainIntensity(0.f) - { - } + void setScene(osg::Node* scene) + { + if (mScene) + mClipCullNode->removeChild(mScene); + mScene = scene; + mClipCullNode->addChild(scene); + } - void setRainIntensity(float rainIntensity) - { - mRainIntensity = rainIntensity; - } + void setWaterLevel(float waterLevel) + { + const float refractionScale + = std::clamp(Settings::Manager::getFloat("refraction scale", "Water"), 0.f, 1.f); -protected: - void setDefaults(osg::StateSet* stateset) override - { - osg::ref_ptr rainIntensityUniform = new osg::Uniform("rainIntensity", 0.0f); - stateset->addUniform(rainIntensityUniform.get()); - } + mViewMatrix = osg::Matrix::scale(1, 1, refractionScale) + * osg::Matrix::translate(0, 0, (1.0 - refractionScale) * waterLevel); - void apply(osg::StateSet* stateset, osg::NodeVisitor* /*nv*/) override - { - osg::ref_ptr rainIntensityUniform = stateset->getUniform("rainIntensity"); - if (rainIntensityUniform != nullptr) - rainIntensityUniform->set(mRainIntensity); - } + mClipCullNode->setPlane(osg::Plane(osg::Vec3d(0, 0, -1), osg::Vec3d(0, 0, waterLevel))); + } -private: - float mRainIntensity; -}; + void showWorld(bool show) + { + if (show) + mNodeMask = Refraction::sDefaultCullMask; + else + mNodeMask = Refraction::sDefaultCullMask & ~sToggleWorldMask; + } -osg::ref_ptr readPngImage (const std::filesystem::path& file) -{ - std::ifstream inStream; - inStream.open(file, std::ios_base::in | std::ios_base::binary); - if (inStream.fail()) - Log(Debug::Error) << "Error: Failed to open " << file; - osgDB::ReaderWriter* reader = osgDB::Registry::instance()->getReaderWriterForExtension("png"); - if (!reader) - { - Log(Debug::Error) << "Error: Failed to read " << file << ", no png readerwriter found"; - return osg::ref_ptr(); - } - osgDB::ReaderWriter::ReadResult result = reader->readImage(inStream); - if (!result.success()) - Log(Debug::Error) << "Error: Failed to read " << file << ": " << result.message() << " code " << result.status(); + private: + osg::ref_ptr mClipCullNode; + osg::ref_ptr mScene; + osg::Matrix mViewMatrix{ osg::Matrix::identity() }; - return result.getImage(); -} + unsigned int mNodeMask; -class Refraction : public SceneUtil::RTTNode -{ -public: - Refraction(uint32_t rttSize) - : RTTNode(rttSize, rttSize, 0, false, 1, StereoAwareness::Aware) - , mNodeMask(Refraction::sDefaultCullMask) - { - setDepthBufferInternalFormat(GL_DEPTH24_STENCIL8); - mClipCullNode = new ClipCullNode; - } + static constexpr unsigned int sDefaultCullMask = Mask_Effect | Mask_Scene | Mask_Object | Mask_Static + | Mask_Terrain | Mask_Actor | Mask_ParticleSystem | Mask_Sky | Mask_Sun | Mask_Player | Mask_Lighting + | Mask_Groundcover; + }; - void setDefaults(osg::Camera* camera) override + class Reflection : public SceneUtil::RTTNode { - camera->setReferenceFrame(osg::Camera::RELATIVE_RF); - camera->setSmallFeatureCullingPixelSize(Settings::Manager::getInt("small feature culling pixel size", "Water")); - camera->setName("RefractionCamera"); - camera->addCullCallback(new InheritViewPointCallback); - camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR); - - // No need for fog here, we are already applying fog on the water surface itself as well as underwater fog - // assign large value to effectively turn off fog - // shaders don't respect glDisable(GL_FOG) - osg::ref_ptr fog(new osg::Fog); - fog->setStart(10000000); - fog->setEnd(10000000); - camera->getOrCreateStateSet()->setAttributeAndModes(fog, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE); + public: + Reflection(uint32_t rttSize, bool isInterior) + : RTTNode(rttSize, rttSize, 0, false, 0, StereoAwareness::Aware) + { + setInterior(isInterior); + setDepthBufferInternalFormat(GL_DEPTH24_STENCIL8); + mClipCullNode = new ClipCullNode; + } - camera->addChild(mClipCullNode); - camera->setNodeMask(Mask_RenderToTexture); + void setDefaults(osg::Camera* camera) override + { + camera->setReferenceFrame(osg::Camera::RELATIVE_RF); + camera->setSmallFeatureCullingPixelSize( + Settings::Manager::getInt("small feature culling pixel size", "Water")); + camera->setName("ReflectionCamera"); + camera->addCullCallback(new InheritViewPointCallback); - if (Settings::Manager::getFloat("refraction scale", "Water") != 1) // TODO: to be removed with issue #5709 - SceneUtil::ShadowManager::disableShadowsForStateSet(camera->getOrCreateStateSet()); - } + // Inform the shader that we're in a reflection + camera->getOrCreateStateSet()->addUniform(new osg::Uniform("isReflection", true)); - void apply(osg::Camera* camera) override - { - camera->setViewMatrix(mViewMatrix); - camera->setCullMask(mNodeMask); - } + // XXX: should really flip the FrontFace on each renderable instead of forcing clockwise. + osg::ref_ptr frontFace(new osg::FrontFace); + frontFace->setMode(osg::FrontFace::CLOCKWISE); + camera->getOrCreateStateSet()->setAttributeAndModes(frontFace, osg::StateAttribute::ON); - void setScene(osg::Node* scene) - { - if (mScene) - mClipCullNode->removeChild(mScene); - mScene = scene; - mClipCullNode->addChild(scene); - } + camera->addChild(mClipCullNode); + camera->setNodeMask(Mask_RenderToTexture); - void setWaterLevel(float waterLevel) - { - const float refractionScale = std::clamp(Settings::Manager::getFloat("refraction scale", "Water"), 0.f, 1.f); + SceneUtil::ShadowManager::disableShadowsForStateSet(camera->getOrCreateStateSet()); + } - mViewMatrix = osg::Matrix::scale(1, 1, refractionScale) * - osg::Matrix::translate(0, 0, (1.0 - refractionScale) * waterLevel); + void apply(osg::Camera* camera) override + { + camera->setViewMatrix(mViewMatrix); + camera->setCullMask(mNodeMask); + } - mClipCullNode->setPlane(osg::Plane(osg::Vec3d(0, 0, -1), osg::Vec3d(0, 0, waterLevel))); - } + void setInterior(bool isInterior) + { + mInterior = isInterior; + mNodeMask = calcNodeMask(); + } - void showWorld(bool show) - { - if (show) - mNodeMask = Refraction::sDefaultCullMask; - else - mNodeMask = Refraction::sDefaultCullMask & ~sToggleWorldMask; - } + void setWaterLevel(float waterLevel) + { + mViewMatrix = osg::Matrix::scale(1, 1, -1) * osg::Matrix::translate(0, 0, 2 * waterLevel); + mClipCullNode->setPlane(osg::Plane(osg::Vec3d(0, 0, 1), osg::Vec3d(0, 0, waterLevel))); + } -private: - osg::ref_ptr mClipCullNode; - osg::ref_ptr mScene; - osg::Matrix mViewMatrix{ osg::Matrix::identity() }; + void setScene(osg::Node* scene) + { + if (mScene) + mClipCullNode->removeChild(mScene); + mScene = scene; + mClipCullNode->addChild(scene); + } - unsigned int mNodeMask; + void showWorld(bool show) + { + if (show) + mNodeMask = calcNodeMask(); + else + mNodeMask = calcNodeMask() & ~sToggleWorldMask; + } - static constexpr unsigned int sDefaultCullMask = Mask_Effect | Mask_Scene | Mask_Object | Mask_Static | Mask_Terrain | Mask_Actor | Mask_ParticleSystem | Mask_Sky | Mask_Sun | Mask_Player | Mask_Lighting | Mask_Groundcover; -}; + private: + unsigned int calcNodeMask() + { + int reflectionDetail = Settings::Manager::getInt("reflection detail", "Water"); + reflectionDetail = std::clamp(reflectionDetail, mInterior ? 2 : 0, 5); + unsigned int extraMask = 0; + if (reflectionDetail >= 1) + extraMask |= Mask_Terrain; + if (reflectionDetail >= 2) + extraMask |= Mask_Static; + if (reflectionDetail >= 3) + extraMask |= Mask_Effect | Mask_ParticleSystem | Mask_Object; + if (reflectionDetail >= 4) + extraMask |= Mask_Player | Mask_Actor; + if (reflectionDetail >= 5) + extraMask |= Mask_Groundcover; + return Mask_Scene | Mask_Sky | Mask_Lighting | extraMask; + } -class Reflection : public SceneUtil::RTTNode -{ -public: - Reflection(uint32_t rttSize, bool isInterior) - : RTTNode(rttSize, rttSize, 0, false, 0, StereoAwareness::Aware) - { - setInterior(isInterior); - setDepthBufferInternalFormat(GL_DEPTH24_STENCIL8); - mClipCullNode = new ClipCullNode; - } + osg::ref_ptr mClipCullNode; + osg::ref_ptr mScene; + osg::Node::NodeMask mNodeMask; + osg::Matrix mViewMatrix{ osg::Matrix::identity() }; + bool mInterior; + }; - void setDefaults(osg::Camera* camera) override + /// DepthClampCallback enables GL_DEPTH_CLAMP for the current draw, if supported. + class DepthClampCallback : public osg::Drawable::DrawCallback { - camera->setReferenceFrame(osg::Camera::RELATIVE_RF); - camera->setSmallFeatureCullingPixelSize(Settings::Manager::getInt("small feature culling pixel size", "Water")); - camera->setName("ReflectionCamera"); - camera->addCullCallback(new InheritViewPointCallback); - - // Inform the shader that we're in a reflection - camera->getOrCreateStateSet()->addUniform(new osg::Uniform("isReflection", true)); + public: + void drawImplementation(osg::RenderInfo& renderInfo, const osg::Drawable* drawable) const override + { + static bool supported = osg::isGLExtensionOrVersionSupported( + renderInfo.getState()->getContextID(), "GL_ARB_depth_clamp", 3.3); + if (!supported) + { + drawable->drawImplementation(renderInfo); + return; + } - // XXX: should really flip the FrontFace on each renderable instead of forcing clockwise. - osg::ref_ptr frontFace(new osg::FrontFace); - frontFace->setMode(osg::FrontFace::CLOCKWISE); - camera->getOrCreateStateSet()->setAttributeAndModes(frontFace, osg::StateAttribute::ON); + glEnable(GL_DEPTH_CLAMP); - camera->addChild(mClipCullNode); - camera->setNodeMask(Mask_RenderToTexture); + drawable->drawImplementation(renderInfo); - SceneUtil::ShadowManager::disableShadowsForStateSet(camera->getOrCreateStateSet()); - } + // restore default + glDisable(GL_DEPTH_CLAMP); + } + }; - void apply(osg::Camera* camera) override + Water::Water(osg::Group* parent, osg::Group* sceneRoot, Resource::ResourceSystem* resourceSystem, + osgUtil::IncrementalCompileOperation* ico, const std::filesystem::path& resourcePath) + : mRainIntensityUpdater(nullptr) + , mParent(parent) + , mSceneRoot(sceneRoot) + , mResourceSystem(resourceSystem) + , mResourcePath(resourcePath) + , mEnabled(true) + , mToggled(true) + , mTop(0) + , mInterior(false) + , mShowWorld(true) + , mCullCallback(nullptr) + , mShaderWaterStateSetUpdater(nullptr) { - camera->setViewMatrix(mViewMatrix); - camera->setCullMask(mNodeMask); - } + mSimulation = std::make_unique(mSceneRoot, resourceSystem); - void setInterior(bool isInterior) - { - mInterior = isInterior; - mNodeMask = calcNodeMask(); - } + mWaterGeom = SceneUtil::createWaterGeometry(Constants::CellSizeInUnits * 150, 40, 900); + mWaterGeom->setDrawCallback(new DepthClampCallback); + mWaterGeom->setNodeMask(Mask_Water); + mWaterGeom->setDataVariance(osg::Object::STATIC); + mWaterGeom->setName("Water Geometry"); - void setWaterLevel(float waterLevel) - { - mViewMatrix = osg::Matrix::scale(1, 1, -1) * osg::Matrix::translate(0, 0, 2 * waterLevel); - mClipCullNode->setPlane(osg::Plane(osg::Vec3d(0, 0, 1), osg::Vec3d(0, 0, waterLevel))); - } + mWaterNode = new osg::PositionAttitudeTransform; + mWaterNode->setName("Water Root"); + mWaterNode->addChild(mWaterGeom); + mWaterNode->addCullCallback(new FudgeCallback); - void setScene(osg::Node* scene) - { - if (mScene) - mClipCullNode->removeChild(mScene); - mScene = scene; - mClipCullNode->addChild(scene); - } + // simple water fallback for the local map + osg::ref_ptr geom2(osg::clone(mWaterGeom.get(), osg::CopyOp::DEEP_COPY_NODES)); + createSimpleWaterStateSet(geom2, Fallback::Map::getFloat("Water_Map_Alpha")); + geom2->setNodeMask(Mask_SimpleWater); + geom2->setName("Simple Water Geometry"); + mWaterNode->addChild(geom2); - void showWorld(bool show) - { - if (show) - mNodeMask = calcNodeMask(); - else - mNodeMask = calcNodeMask() & ~sToggleWorldMask; - } + mSceneRoot->addChild(mWaterNode); -private: + setHeight(mTop); - unsigned int calcNodeMask() - { - int reflectionDetail = Settings::Manager::getInt("reflection detail", "Water"); - reflectionDetail = std::clamp(reflectionDetail, mInterior ? 2 : 0, 5); - unsigned int extraMask = 0; - if(reflectionDetail >= 1) extraMask |= Mask_Terrain; - if(reflectionDetail >= 2) extraMask |= Mask_Static; - if(reflectionDetail >= 3) extraMask |= Mask_Effect | Mask_ParticleSystem | Mask_Object; - if(reflectionDetail >= 4) extraMask |= Mask_Player | Mask_Actor; - if(reflectionDetail >= 5) extraMask |= Mask_Groundcover; - return Mask_Scene | Mask_Sky | Mask_Lighting | extraMask; - } + updateWaterMaterial(); - osg::ref_ptr mClipCullNode; - osg::ref_ptr mScene; - osg::Node::NodeMask mNodeMask; - osg::Matrix mViewMatrix{ osg::Matrix::identity() }; - bool mInterior; -}; + if (ico) + ico->add(mWaterNode); + } -/// DepthClampCallback enables GL_DEPTH_CLAMP for the current draw, if supported. -class DepthClampCallback : public osg::Drawable::DrawCallback -{ -public: - void drawImplementation(osg::RenderInfo& renderInfo,const osg::Drawable* drawable) const override + void Water::setCullCallback(osg::Callback* callback) { - static bool supported = osg::isGLExtensionOrVersionSupported(renderInfo.getState()->getContextID(), "GL_ARB_depth_clamp", 3.3); - if (!supported) + if (mCullCallback) { - drawable->drawImplementation(renderInfo); - return; + mWaterNode->removeCullCallback(mCullCallback); + if (mReflection) + mReflection->removeCullCallback(mCullCallback); + if (mRefraction) + mRefraction->removeCullCallback(mCullCallback); } - glEnable(GL_DEPTH_CLAMP); - - drawable->drawImplementation(renderInfo); + mCullCallback = callback; - // restore default - glDisable(GL_DEPTH_CLAMP); + if (callback) + { + mWaterNode->addCullCallback(callback); + if (mReflection) + mReflection->addCullCallback(callback); + if (mRefraction) + mRefraction->addCullCallback(callback); + } } -}; - -Water::Water(osg::Group *parent, osg::Group* sceneRoot, Resource::ResourceSystem *resourceSystem, - osgUtil::IncrementalCompileOperation *ico, const std::filesystem::path& resourcePath) - : mRainIntensityUpdater(nullptr) - , mParent(parent) - , mSceneRoot(sceneRoot) - , mResourceSystem(resourceSystem) - , mResourcePath(resourcePath) - , mEnabled(true) - , mToggled(true) - , mTop(0) - , mInterior(false) - , mShowWorld(true) - , mCullCallback(nullptr) - , mShaderWaterStateSetUpdater(nullptr) -{ - mSimulation = std::make_unique(mSceneRoot, resourceSystem); - mWaterGeom = SceneUtil::createWaterGeometry(Constants::CellSizeInUnits*150, 40, 900); - mWaterGeom->setDrawCallback(new DepthClampCallback); - mWaterGeom->setNodeMask(Mask_Water); - mWaterGeom->setDataVariance(osg::Object::STATIC); - mWaterGeom->setName("Water Geometry"); + void Water::updateWaterMaterial() + { + if (mShaderWaterStateSetUpdater) + { + mWaterNode->removeCullCallback(mShaderWaterStateSetUpdater); + mShaderWaterStateSetUpdater = nullptr; + } + if (mReflection) + { + mParent->removeChild(mReflection); + mReflection = nullptr; + } + if (mRefraction) + { + mParent->removeChild(mRefraction); + mRefraction = nullptr; + } - mWaterNode = new osg::PositionAttitudeTransform; - mWaterNode->setName("Water Root"); - mWaterNode->addChild(mWaterGeom); - mWaterNode->addCullCallback(new FudgeCallback); + mWaterNode->setStateSet(nullptr); + mWaterGeom->setStateSet(nullptr); + mWaterGeom->setUpdateCallback(nullptr); - // simple water fallback for the local map - osg::ref_ptr geom2 (osg::clone(mWaterGeom.get(), osg::CopyOp::DEEP_COPY_NODES)); - createSimpleWaterStateSet(geom2, Fallback::Map::getFloat("Water_Map_Alpha")); - geom2->setNodeMask(Mask_SimpleWater); - geom2->setName("Simple Water Geometry"); - mWaterNode->addChild(geom2); + if (Settings::Manager::getBool("shader", "Water")) + { + unsigned int rttSize = Settings::Manager::getInt("rtt size", "Water"); - mSceneRoot->addChild(mWaterNode); + mReflection = new Reflection(rttSize, mInterior); + mReflection->setWaterLevel(mTop); + mReflection->setScene(mSceneRoot); + if (mCullCallback) + mReflection->addCullCallback(mCullCallback); + mParent->addChild(mReflection); - setHeight(mTop); + if (Settings::Manager::getBool("refraction", "Water")) + { + mRefraction = new Refraction(rttSize); + mRefraction->setWaterLevel(mTop); + mRefraction->setScene(mSceneRoot); + if (mCullCallback) + mRefraction->addCullCallback(mCullCallback); + mParent->addChild(mRefraction); + } - updateWaterMaterial(); + showWorld(mShowWorld); - if (ico) - ico->add(mWaterNode); -} + createShaderWaterStateSet(mWaterNode, mReflection, mRefraction); + } + else + createSimpleWaterStateSet(mWaterGeom, Fallback::Map::getFloat("Water_World_Alpha")); -void Water::setCullCallback(osg::Callback* callback) -{ - if (mCullCallback) - { - mWaterNode->removeCullCallback(mCullCallback); - if (mReflection) - mReflection->removeCullCallback(mCullCallback); - if (mRefraction) - mRefraction->removeCullCallback(mCullCallback); + updateVisible(); } - mCullCallback = callback; - - if (callback) + osg::Node* Water::getReflectionNode() { - mWaterNode->addCullCallback(callback); - if (mReflection) - mReflection->addCullCallback(callback); - if (mRefraction) - mRefraction->addCullCallback(callback); + return mReflection; } -} -void Water::updateWaterMaterial() -{ - if (mShaderWaterStateSetUpdater) + osg::Node* Water::getRefractionNode() { - mWaterNode->removeCullCallback(mShaderWaterStateSetUpdater); - mShaderWaterStateSetUpdater = nullptr; + return mRefraction; } - if (mReflection) - { - mParent->removeChild(mReflection); - mReflection = nullptr; - } - if (mRefraction) + + osg::Vec3d Water::getPosition() const { - mParent->removeChild(mRefraction); - mRefraction = nullptr; + return mWaterNode->getPosition(); } - mWaterNode->setStateSet(nullptr); - mWaterGeom->setStateSet(nullptr); - mWaterGeom->setUpdateCallback(nullptr); - - if (Settings::Manager::getBool("shader", "Water")) + void Water::createSimpleWaterStateSet(osg::Node* node, float alpha) { - unsigned int rttSize = Settings::Manager::getInt("rtt size", "Water"); + osg::ref_ptr stateset = SceneUtil::createSimpleWaterStateSet(alpha, MWRender::RenderBin_Water); - mReflection = new Reflection(rttSize, mInterior); - mReflection->setWaterLevel(mTop); - mReflection->setScene(mSceneRoot); - if (mCullCallback) - mReflection->addCullCallback(mCullCallback); - mParent->addChild(mReflection); + node->setStateSet(stateset); + node->setUpdateCallback(nullptr); + mRainIntensityUpdater = nullptr; - if (Settings::Manager::getBool("refraction", "Water")) + // Add animated textures + std::vector> textures; + const int frameCount = std::clamp(Fallback::Map::getInt("Water_SurfaceFrameCount"), 0, 320); + std::string_view texture = Fallback::Map::getString("Water_SurfaceTexture"); + for (int i = 0; i < frameCount; ++i) { - mRefraction = new Refraction(rttSize); - mRefraction->setWaterLevel(mTop); - mRefraction->setScene(mSceneRoot); - if (mCullCallback) - mRefraction->addCullCallback(mCullCallback); - mParent->addChild(mRefraction); + std::ostringstream texname; + texname << "textures/water/" << texture << std::setw(2) << std::setfill('0') << i << ".dds"; + osg::ref_ptr tex( + new osg::Texture2D(mResourceSystem->getImageManager()->getImage(texname.str()))); + tex->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT); + tex->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT); + mResourceSystem->getSceneManager()->applyFilterSettings(tex); + textures.push_back(tex); } - showWorld(mShowWorld); + if (textures.empty()) + return; + + float fps = Fallback::Map::getFloat("Water_SurfaceFPS"); - createShaderWaterStateSet(mWaterNode, mReflection, mRefraction); + osg::ref_ptr controller(new NifOsg::FlipController(0, 1.f / fps, textures)); + controller->setSource(std::make_shared()); + node->setUpdateCallback(controller); + + stateset->setTextureAttributeAndModes(0, textures[0], osg::StateAttribute::ON); + + // use a shader to render the simple water, ensuring that fog is applied per pixel as required. + // this could be removed if a more detailed water mesh, using some sort of paging solution, is implemented. + Resource::SceneManager* sceneManager = mResourceSystem->getSceneManager(); + bool oldValue = sceneManager->getForceShaders(); + sceneManager->setForceShaders(true); + sceneManager->recreateShaders(node); + sceneManager->setForceShaders(oldValue); } - else - createSimpleWaterStateSet(mWaterGeom, Fallback::Map::getFloat("Water_World_Alpha")); - updateVisible(); -} + class ShaderWaterStateSetUpdater : public SceneUtil::StateSetUpdater + { + public: + ShaderWaterStateSetUpdater(Water* water, Reflection* reflection, Refraction* refraction, + osg::ref_ptr program, osg::ref_ptr normalMap) + : mWater(water) + , mReflection(reflection) + , mRefraction(refraction) + , mProgram(program) + , mNormalMap(normalMap) + { + } -osg::Node *Water::getReflectionNode() -{ - return mReflection; -} + void setDefaults(osg::StateSet* stateset) override + { + stateset->addUniform(new osg::Uniform("normalMap", 0)); + stateset->setTextureAttributeAndModes(0, mNormalMap, osg::StateAttribute::ON); + stateset->setMode(GL_CULL_FACE, osg::StateAttribute::OFF); + stateset->setAttributeAndModes(mProgram, osg::StateAttribute::ON); -osg::Node* Water::getRefractionNode() -{ - return mRefraction; -} + stateset->addUniform(new osg::Uniform("reflectionMap", 1)); + if (mRefraction) + { + stateset->addUniform(new osg::Uniform("refractionMap", 2)); + stateset->addUniform(new osg::Uniform("refractionDepthMap", 3)); + stateset->setRenderBinDetails(MWRender::RenderBin_Default, "RenderBin"); + } + else + { + stateset->setMode(GL_BLEND, osg::StateAttribute::ON); + stateset->setRenderBinDetails(MWRender::RenderBin_Water, "RenderBin"); + osg::ref_ptr depth = new SceneUtil::AutoDepth; + depth->setWriteMask(false); + stateset->setAttributeAndModes(depth, osg::StateAttribute::ON); + } + stateset->addUniform(new osg::Uniform("nodePosition", osg::Vec3f(mWater->getPosition()))); + } -osg::Vec3d Water::getPosition() const -{ - return mWaterNode->getPosition(); -} + void apply(osg::StateSet* stateset, osg::NodeVisitor* nv) override + { + osgUtil::CullVisitor* cv = static_cast(nv); + stateset->setTextureAttributeAndModes(1, mReflection->getColorTexture(cv), osg::StateAttribute::ON); -void Water::createSimpleWaterStateSet(osg::Node* node, float alpha) -{ - osg::ref_ptr stateset = SceneUtil::createSimpleWaterStateSet(alpha, MWRender::RenderBin_Water); - - node->setStateSet(stateset); - node->setUpdateCallback(nullptr); - mRainIntensityUpdater = nullptr; - - // Add animated textures - std::vector > textures; - const int frameCount = std::clamp(Fallback::Map::getInt("Water_SurfaceFrameCount"), 0, 320); - std::string_view texture = Fallback::Map::getString("Water_SurfaceTexture"); - for (int i=0; i tex (new osg::Texture2D(mResourceSystem->getImageManager()->getImage(texname.str()))); - tex->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT); - tex->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT); - mResourceSystem->getSceneManager()->applyFilterSettings(tex); - textures.push_back(tex); - } + if (mRefraction) + { + stateset->setTextureAttributeAndModes(2, mRefraction->getColorTexture(cv), osg::StateAttribute::ON); + stateset->setTextureAttributeAndModes(3, mRefraction->getDepthTexture(cv), osg::StateAttribute::ON); + } + stateset->getUniform("nodePosition")->set(osg::Vec3f(mWater->getPosition())); + } - if (textures.empty()) - return; + private: + Water* mWater; + Reflection* mReflection; + Refraction* mRefraction; + osg::ref_ptr mProgram; + osg::ref_ptr mNormalMap; + }; - float fps = Fallback::Map::getFloat("Water_SurfaceFPS"); + void Water::createShaderWaterStateSet(osg::Node* node, Reflection* reflection, Refraction* refraction) + { + // use a define map to conditionally compile the shader + std::map defineMap; + defineMap["refraction_enabled"] = std::string(mRefraction ? "1" : "0"); + const auto rippleDetail = std::clamp(Settings::Manager::getInt("rain ripple detail", "Water"), 0, 2); + defineMap["rain_ripple_detail"] = std::to_string(rippleDetail); - osg::ref_ptr controller (new NifOsg::FlipController(0, 1.f/fps, textures)); - controller->setSource(std::make_shared()); - node->setUpdateCallback(controller); + Stereo::Manager::instance().shaderStereoDefines(defineMap); - stateset->setTextureAttributeAndModes(0, textures[0], osg::StateAttribute::ON); + Shader::ShaderManager& shaderMgr = mResourceSystem->getSceneManager()->getShaderManager(); + osg::ref_ptr vertexShader( + shaderMgr.getShader("water_vertex.glsl", defineMap, osg::Shader::VERTEX)); + osg::ref_ptr fragmentShader( + shaderMgr.getShader("water_fragment.glsl", defineMap, osg::Shader::FRAGMENT)); + osg::ref_ptr program = shaderMgr.getProgram(vertexShader, fragmentShader); - // use a shader to render the simple water, ensuring that fog is applied per pixel as required. - // this could be removed if a more detailed water mesh, using some sort of paging solution, is implemented. - Resource::SceneManager* sceneManager = mResourceSystem->getSceneManager(); - bool oldValue = sceneManager->getForceShaders(); - sceneManager->setForceShaders(true); - sceneManager->recreateShaders(node); - sceneManager->setForceShaders(oldValue); -} + osg::ref_ptr normalMap( + new osg::Texture2D(readPngImage(mResourcePath / "shaders" / "water_nm.png"))); -class ShaderWaterStateSetUpdater : public SceneUtil::StateSetUpdater -{ -public: - ShaderWaterStateSetUpdater(Water* water, Reflection* reflection, Refraction* refraction, osg::ref_ptr program, osg::ref_ptr normalMap) - : mWater(water) - , mReflection(reflection) - , mRefraction(refraction) - , mProgram(program) - , mNormalMap(normalMap) + if (normalMap->getImage()) + normalMap->getImage()->flipVertical(); + normalMap->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT); + normalMap->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT); + normalMap->setMaxAnisotropy(16); + normalMap->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR); + normalMap->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR); + + mRainIntensityUpdater = new RainIntensityUpdater(); + node->setUpdateCallback(mRainIntensityUpdater); + + mShaderWaterStateSetUpdater + = new ShaderWaterStateSetUpdater(this, mReflection, mRefraction, program, normalMap); + node->addCullCallback(mShaderWaterStateSetUpdater); + } + + void Water::processChangedSettings(const Settings::CategorySettingVector& settings) { + updateWaterMaterial(); } - void setDefaults(osg::StateSet* stateset) override + Water::~Water() { - stateset->addUniform(new osg::Uniform("normalMap", 0)); - stateset->setTextureAttributeAndModes(0, mNormalMap, osg::StateAttribute::ON); - stateset->setMode(GL_CULL_FACE, osg::StateAttribute::OFF); - stateset->setAttributeAndModes(mProgram, osg::StateAttribute::ON); + mParent->removeChild(mWaterNode); - stateset->addUniform(new osg::Uniform("reflectionMap", 1)); - if (mRefraction) + if (mReflection) { - stateset->addUniform(new osg::Uniform("refractionMap", 2)); - stateset->addUniform(new osg::Uniform("refractionDepthMap", 3)); - stateset->setRenderBinDetails(MWRender::RenderBin_Default, "RenderBin"); + mParent->removeChild(mReflection); + mReflection = nullptr; } - else + if (mRefraction) { - stateset->setMode(GL_BLEND, osg::StateAttribute::ON); - stateset->setRenderBinDetails(MWRender::RenderBin_Water, "RenderBin"); - osg::ref_ptr depth = new SceneUtil::AutoDepth; - depth->setWriteMask(false); - stateset->setAttributeAndModes(depth, osg::StateAttribute::ON); + mParent->removeChild(mRefraction); + mRefraction = nullptr; } - stateset->addUniform(new osg::Uniform("nodePosition", osg::Vec3f(mWater->getPosition()))); } - void apply(osg::StateSet* stateset, osg::NodeVisitor* nv) override + void Water::listAssetsToPreload(std::vector& textures) { - osgUtil::CullVisitor* cv = static_cast(nv); - stateset->setTextureAttributeAndModes(1, mReflection->getColorTexture(cv), osg::StateAttribute::ON); - - if (mRefraction) + const int frameCount = std::clamp(Fallback::Map::getInt("Water_SurfaceFrameCount"), 0, 320); + std::string_view texture = Fallback::Map::getString("Water_SurfaceTexture"); + for (int i = 0; i < frameCount; ++i) { - stateset->setTextureAttributeAndModes(2, mRefraction->getColorTexture(cv), osg::StateAttribute::ON); - stateset->setTextureAttributeAndModes(3, mRefraction->getDepthTexture(cv), osg::StateAttribute::ON); + std::ostringstream texname; + texname << "textures/water/" << texture << std::setw(2) << std::setfill('0') << i << ".dds"; + textures.push_back(texname.str()); } - stateset->getUniform("nodePosition")->set(osg::Vec3f(mWater->getPosition())); } -private: - Water* mWater; - Reflection* mReflection; - Refraction* mRefraction; - osg::ref_ptr mProgram; - osg::ref_ptr mNormalMap; -}; - -void Water::createShaderWaterStateSet(osg::Node* node, Reflection* reflection, Refraction* refraction) -{ - // use a define map to conditionally compile the shader - std::map defineMap; - defineMap["refraction_enabled"] = std::string(mRefraction ? "1" : "0"); - const auto rippleDetail = std::clamp(Settings::Manager::getInt("rain ripple detail", "Water"), 0, 2); - defineMap["rain_ripple_detail"] = std::to_string(rippleDetail); - - Stereo::Manager::instance().shaderStereoDefines(defineMap); - - Shader::ShaderManager& shaderMgr = mResourceSystem->getSceneManager()->getShaderManager(); - osg::ref_ptr vertexShader(shaderMgr.getShader("water_vertex.glsl", defineMap, osg::Shader::VERTEX)); - osg::ref_ptr fragmentShader(shaderMgr.getShader("water_fragment.glsl", defineMap, osg::Shader::FRAGMENT)); - osg::ref_ptr program = shaderMgr.getProgram(vertexShader, fragmentShader); - - osg::ref_ptr normalMap(new osg::Texture2D(readPngImage(mResourcePath / "shaders" / "water_nm.png"))); - - if (normalMap->getImage()) - normalMap->getImage()->flipVertical(); - normalMap->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT); - normalMap->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT); - normalMap->setMaxAnisotropy(16); - normalMap->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR); - normalMap->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR); + void Water::setEnabled(bool enabled) + { + mEnabled = enabled; + updateVisible(); + } + void Water::changeCell(const MWWorld::CellStore* store) + { + bool isInterior = !store->getCell()->isExterior(); + bool wasInterior = mInterior; + if (!isInterior) + { + mWaterNode->setPosition(getSceneNodeCoordinates(store->getCell()->mData.mX, store->getCell()->mData.mY)); + mInterior = false; + } + else + { + mWaterNode->setPosition(osg::Vec3f(0, 0, mTop)); + mInterior = true; + } + if (mInterior != wasInterior && mReflection) + mReflection->setInterior(mInterior); + } - mRainIntensityUpdater = new RainIntensityUpdater(); - node->setUpdateCallback(mRainIntensityUpdater); + void Water::setHeight(const float height) + { + mTop = height; - mShaderWaterStateSetUpdater = new ShaderWaterStateSetUpdater(this, mReflection, mRefraction, program, normalMap); - node->addCullCallback(mShaderWaterStateSetUpdater); -} + mSimulation->setWaterHeight(height); -void Water::processChangedSettings(const Settings::CategorySettingVector& settings) -{ - updateWaterMaterial(); -} + osg::Vec3f pos = mWaterNode->getPosition(); + pos.z() = height; + mWaterNode->setPosition(pos); -Water::~Water() -{ - mParent->removeChild(mWaterNode); + if (mReflection) + mReflection->setWaterLevel(mTop); + if (mRefraction) + mRefraction->setWaterLevel(mTop); + } - if (mReflection) + void Water::setRainIntensity(float rainIntensity) { - mParent->removeChild(mReflection); - mReflection = nullptr; + if (mRainIntensityUpdater) + mRainIntensityUpdater->setRainIntensity(rainIntensity); } - if (mRefraction) + + void Water::update(float dt) { - mParent->removeChild(mRefraction); - mRefraction = nullptr; + mSimulation->update(dt); } -} -void Water::listAssetsToPreload(std::vector &textures) -{ - const int frameCount = std::clamp(Fallback::Map::getInt("Water_SurfaceFrameCount"), 0, 320); - std::string_view texture = Fallback::Map::getString("Water_SurfaceTexture"); - for (int i=0; isetNodeMask(visible ? ~0u : 0u); + if (mRefraction) + mRefraction->setNodeMask(visible ? Mask_RenderToTexture : 0u); + if (mReflection) + mReflection->setNodeMask(visible ? Mask_RenderToTexture : 0u); } -} -void Water::setEnabled(bool enabled) -{ - mEnabled = enabled; - updateVisible(); -} - -void Water::changeCell(const MWWorld::CellStore* store) -{ - bool isInterior = !store->getCell()->isExterior(); - bool wasInterior = mInterior; - if (!isInterior) + bool Water::toggle() { - mWaterNode->setPosition(getSceneNodeCoordinates(store->getCell()->mData.mX, store->getCell()->mData.mY)); - mInterior = false; + mToggled = !mToggled; + updateVisible(); + return mToggled; } - else + + bool Water::isUnderwater(const osg::Vec3f& pos) const { - mWaterNode->setPosition(osg::Vec3f(0,0,mTop)); - mInterior = true; + return pos.z() < mTop && mToggled && mEnabled; } - if(mInterior != wasInterior && mReflection) - mReflection->setInterior(mInterior); -} - -void Water::setHeight(const float height) -{ - mTop = height; - - mSimulation->setWaterHeight(height); - - osg::Vec3f pos = mWaterNode->getPosition(); - pos.z() = height; - mWaterNode->setPosition(pos); - - if (mReflection) - mReflection->setWaterLevel(mTop); - if (mRefraction) - mRefraction->setWaterLevel(mTop); -} - -void Water::setRainIntensity(float rainIntensity) -{ - if (mRainIntensityUpdater) - mRainIntensityUpdater->setRainIntensity(rainIntensity); -} - -void Water::update(float dt) -{ - mSimulation->update(dt); -} - -void Water::updateVisible() -{ - bool visible = mEnabled && mToggled; - mWaterNode->setNodeMask(visible ? ~0u : 0u); - if (mRefraction) - mRefraction->setNodeMask(visible ? Mask_RenderToTexture : 0u); - if (mReflection) - mReflection->setNodeMask(visible ? Mask_RenderToTexture : 0u); -} - -bool Water::toggle() -{ - mToggled = !mToggled; - updateVisible(); - return mToggled; -} - -bool Water::isUnderwater(const osg::Vec3f &pos) const -{ - return pos.z() < mTop && mToggled && mEnabled; -} -osg::Vec3f Water::getSceneNodeCoordinates(int gridX, int gridY) -{ - return osg::Vec3f(static_cast(gridX * Constants::CellSizeInUnits + (Constants::CellSizeInUnits / 2)), - static_cast(gridY * Constants::CellSizeInUnits + (Constants::CellSizeInUnits / 2)), mTop); -} + osg::Vec3f Water::getSceneNodeCoordinates(int gridX, int gridY) + { + return osg::Vec3f(static_cast(gridX * Constants::CellSizeInUnits + (Constants::CellSizeInUnits / 2)), + static_cast(gridY * Constants::CellSizeInUnits + (Constants::CellSizeInUnits / 2)), mTop); + } -void Water::addEmitter (const MWWorld::Ptr& ptr, float scale, float force) -{ - mSimulation->addEmitter (ptr, scale, force); -} + void Water::addEmitter(const MWWorld::Ptr& ptr, float scale, float force) + { + mSimulation->addEmitter(ptr, scale, force); + } -void Water::removeEmitter (const MWWorld::Ptr& ptr) -{ - mSimulation->removeEmitter (ptr); -} + void Water::removeEmitter(const MWWorld::Ptr& ptr) + { + mSimulation->removeEmitter(ptr); + } -void Water::updateEmitterPtr (const MWWorld::Ptr& old, const MWWorld::Ptr& ptr) -{ - mSimulation->updateEmitterPtr(old, ptr); -} + void Water::updateEmitterPtr(const MWWorld::Ptr& old, const MWWorld::Ptr& ptr) + { + mSimulation->updateEmitterPtr(old, ptr); + } -void Water::emitRipple(const osg::Vec3f &pos) -{ - mSimulation->emitRipple(pos); -} + void Water::emitRipple(const osg::Vec3f& pos) + { + mSimulation->emitRipple(pos); + } -void Water::removeCell(const MWWorld::CellStore *store) -{ - mSimulation->removeCell(store); -} + void Water::removeCell(const MWWorld::CellStore* store) + { + mSimulation->removeCell(store); + } -void Water::clearRipples() -{ - mSimulation->clear(); -} + void Water::clearRipples() + { + mSimulation->clear(); + } -void Water::showWorld(bool show) -{ - if (mReflection) - mReflection->showWorld(show); - if (mRefraction) - mRefraction->showWorld(show); - mShowWorld = show; -} + void Water::showWorld(bool show) + { + if (mReflection) + mReflection->showWorld(show); + if (mRefraction) + mRefraction->showWorld(show); + mShowWorld = show; + } } diff --git a/apps/openmw/mwrender/water.hpp b/apps/openmw/mwrender/water.hpp index 8309566031..cfd311300d 100644 --- a/apps/openmw/mwrender/water.hpp +++ b/apps/openmw/mwrender/water.hpp @@ -4,9 +4,9 @@ #include #include -#include -#include #include +#include +#include #include @@ -88,9 +88,8 @@ namespace MWRender void updateWaterMaterial(); public: - Water(osg::Group* parent, osg::Group* sceneRoot, - Resource::ResourceSystem* resourceSystem, osgUtil::IncrementalCompileOperation* ico, - const std::filesystem::path& resourcePath); + Water(osg::Group* parent, osg::Group* sceneRoot, Resource::ResourceSystem* resourceSystem, + osgUtil::IncrementalCompileOperation* ico, const std::filesystem::path& resourcePath); ~Water(); void setCullCallback(osg::Callback* callback); @@ -104,9 +103,9 @@ namespace MWRender bool isUnderwater(const osg::Vec3f& pos) const; /// adds an emitter, position will be tracked automatically using its scene node - void addEmitter (const MWWorld::Ptr& ptr, float scale = 1.f, float force = 1.f); - void removeEmitter (const MWWorld::Ptr& ptr); - void updateEmitterPtr (const MWWorld::Ptr& old, const MWWorld::Ptr& ptr); + void addEmitter(const MWWorld::Ptr& ptr, float scale = 1.f, float force = 1.f); + void removeEmitter(const MWWorld::Ptr& ptr); + void updateEmitterPtr(const MWWorld::Ptr& old, const MWWorld::Ptr& ptr); void emitRipple(const osg::Vec3f& pos); void removeCell(const MWWorld::CellStore* store); ///< remove all emitters in this cell diff --git a/apps/openmw/mwrender/weaponanimation.cpp b/apps/openmw/mwrender/weaponanimation.cpp index c331235466..e2ce27f23d 100644 --- a/apps/openmw/mwrender/weaponanimation.cpp +++ b/apps/openmw/mwrender/weaponanimation.cpp @@ -5,16 +5,16 @@ #include #include -#include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/soundmanager.hpp" +#include "../mwbase/world.hpp" -#include "../mwworld/inventorystore.hpp" #include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" +#include "../mwworld/inventorystore.hpp" -#include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/combat.hpp" +#include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/weapontype.hpp" #include "animation.hpp" @@ -23,204 +23,206 @@ namespace MWRender { -float WeaponAnimationTime::getValue(osg::NodeVisitor*) -{ - if (mWeaponGroup.empty()) - return 0; - - float current = mAnimation->getCurrentTime(mWeaponGroup); - if (current == -1) - return 0; - return current - mStartTime; -} - -void WeaponAnimationTime::setGroup(const std::string &group, bool relativeTime) -{ - mWeaponGroup = group; - mRelativeTime = relativeTime; - - if (mRelativeTime) - mStartTime = mAnimation->getStartTime(mWeaponGroup); - else - mStartTime = 0; -} - -void WeaponAnimationTime::updateStartTime() -{ - setGroup(mWeaponGroup, mRelativeTime); -} + float WeaponAnimationTime::getValue(osg::NodeVisitor*) + { + if (mWeaponGroup.empty()) + return 0; -WeaponAnimation::WeaponAnimation() - : mPitchFactor(0) -{ -} + float current = mAnimation->getCurrentTime(mWeaponGroup); + if (current == -1) + return 0; + return current - mStartTime; + } -WeaponAnimation::~WeaponAnimation() -{ + void WeaponAnimationTime::setGroup(const std::string& group, bool relativeTime) + { + mWeaponGroup = group; + mRelativeTime = relativeTime; -} + if (mRelativeTime) + mStartTime = mAnimation->getStartTime(mWeaponGroup); + else + mStartTime = 0; + } -void WeaponAnimation::attachArrow(const MWWorld::Ptr& actor) -{ - const MWWorld::InventoryStore& inv = actor.getClass().getInventoryStore(actor); - MWWorld::ConstContainerStoreIterator weaponSlot = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); - if (weaponSlot == inv.end()) - return; - if (weaponSlot->getType() != ESM::Weapon::sRecordId) - return; - - int type = weaponSlot->get()->mBase->mData.mType; - ESM::WeaponType::Class weapclass = MWMechanics::getWeaponType(type)->mWeaponClass; - if (weapclass == ESM::WeaponType::Thrown) + void WeaponAnimationTime::updateStartTime() { - std::string_view soundid = weaponSlot->getClass().getUpSoundId(*weaponSlot); - if(!soundid.empty()) - { - MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); - sndMgr->playSound3D(actor, soundid, 1.0f, 1.0f); - } - showWeapon(true); + setGroup(mWeaponGroup, mRelativeTime); } - else if (weapclass == ESM::WeaponType::Ranged) - { - osg::Group* parent = getArrowBone(); - if (!parent) - return; - - MWWorld::ConstContainerStoreIterator ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition); - if (ammo == inv.end()) - return; - std::string model = ammo->getClass().getModel(*ammo); - - osg::ref_ptr arrow = getResourceSystem()->getSceneManager()->getInstance(model, parent); - mAmmunition = std::make_unique(arrow); + WeaponAnimation::WeaponAnimation() + : mPitchFactor(0) + { } -} - -void WeaponAnimation::detachArrow(MWWorld::Ptr actor) -{ - mAmmunition.reset(); -} - -void WeaponAnimation::releaseArrow(MWWorld::Ptr actor, float attackStrength) -{ - MWWorld::InventoryStore& inv = actor.getClass().getInventoryStore(actor); - MWWorld::ContainerStoreIterator weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); - if (weapon == inv.end()) - return; - if (weapon->getType() != ESM::Weapon::sRecordId) - return; - - // The orientation of the launched projectile. Always the same as the actor orientation, even if the ArrowBone's orientation dictates otherwise. - osg::Quat orient = osg::Quat(actor.getRefData().getPosition().rot[0], osg::Vec3f(-1,0,0)) - * osg::Quat(actor.getRefData().getPosition().rot[2], osg::Vec3f(0,0,-1)); - const MWWorld::Store &gmst = - MWBase::Environment::get().getWorld()->getStore().get(); + WeaponAnimation::~WeaponAnimation() {} - MWMechanics::applyFatigueLoss(actor, *weapon, attackStrength); - - if (MWMechanics::getWeaponType(weapon->get()->mBase->mData.mType)->mWeaponClass == ESM::WeaponType::Thrown) + void WeaponAnimation::attachArrow(const MWWorld::Ptr& actor) { - // Thrown weapons get detached now - osg::Node* weaponNode = getWeaponNode(); - if (!weaponNode) + const MWWorld::InventoryStore& inv = actor.getClass().getInventoryStore(actor); + MWWorld::ConstContainerStoreIterator weaponSlot = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); + if (weaponSlot == inv.end()) return; - osg::NodePathList nodepaths = weaponNode->getParentalNodePaths(); - if (nodepaths.empty()) + if (weaponSlot->getType() != ESM::Weapon::sRecordId) return; - osg::Vec3f launchPos = osg::computeLocalToWorld(nodepaths[0]).getTrans(); - float fThrownWeaponMinSpeed = gmst.find("fThrownWeaponMinSpeed")->mValue.getFloat(); - float fThrownWeaponMaxSpeed = gmst.find("fThrownWeaponMaxSpeed")->mValue.getFloat(); - float speed = fThrownWeaponMinSpeed + (fThrownWeaponMaxSpeed - fThrownWeaponMinSpeed) * attackStrength; + int type = weaponSlot->get()->mBase->mData.mType; + ESM::WeaponType::Class weapclass = MWMechanics::getWeaponType(type)->mWeaponClass; + if (weapclass == ESM::WeaponType::Thrown) + { + std::string_view soundid = weaponSlot->getClass().getUpSoundId(*weaponSlot); + if (!soundid.empty()) + { + MWBase::SoundManager* sndMgr = MWBase::Environment::get().getSoundManager(); + sndMgr->playSound3D(actor, soundid, 1.0f, 1.0f); + } + showWeapon(true); + } + else if (weapclass == ESM::WeaponType::Ranged) + { + osg::Group* parent = getArrowBone(); + if (!parent) + return; - MWWorld::Ptr weaponPtr = *weapon; - MWBase::Environment::get().getWorld()->launchProjectile(actor, weaponPtr, launchPos, orient, weaponPtr, speed, attackStrength); + MWWorld::ConstContainerStoreIterator ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition); + if (ammo == inv.end()) + return; + std::string model = ammo->getClass().getModel(*ammo); - showWeapon(false); + osg::ref_ptr arrow = getResourceSystem()->getSceneManager()->getInstance(model, parent); - inv.remove(*weapon, 1, actor); + mAmmunition = std::make_unique(arrow); + } } - else + + void WeaponAnimation::detachArrow(MWWorld::Ptr actor) { - // With bows and crossbows only the used arrow/bolt gets detached - MWWorld::ContainerStoreIterator ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition); - if (ammo == inv.end()) - return; + mAmmunition.reset(); + } - if (!mAmmunition) + void WeaponAnimation::releaseArrow(MWWorld::Ptr actor, float attackStrength) + { + MWWorld::InventoryStore& inv = actor.getClass().getInventoryStore(actor); + MWWorld::ContainerStoreIterator weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); + if (weapon == inv.end()) return; - - osg::ref_ptr ammoNode = mAmmunition->getNode(); - osg::NodePathList nodepaths = ammoNode->getParentalNodePaths(); - if (nodepaths.empty()) + if (weapon->getType() != ESM::Weapon::sRecordId) return; - osg::Vec3f launchPos = osg::computeLocalToWorld(nodepaths[0]).getTrans(); - float fProjectileMinSpeed = gmst.find("fProjectileMinSpeed")->mValue.getFloat(); - float fProjectileMaxSpeed = gmst.find("fProjectileMaxSpeed")->mValue.getFloat(); - float speed = fProjectileMinSpeed + (fProjectileMaxSpeed - fProjectileMinSpeed) * attackStrength; + // The orientation of the launched projectile. Always the same as the actor orientation, even if the ArrowBone's + // orientation dictates otherwise. + osg::Quat orient = osg::Quat(actor.getRefData().getPosition().rot[0], osg::Vec3f(-1, 0, 0)) + * osg::Quat(actor.getRefData().getPosition().rot[2], osg::Vec3f(0, 0, -1)); - MWWorld::Ptr weaponPtr = *weapon; - MWWorld::Ptr ammoPtr = *ammo; - MWBase::Environment::get().getWorld()->launchProjectile(actor, ammoPtr, launchPos, orient, weaponPtr, speed, attackStrength); + const MWWorld::Store& gmst + = MWBase::Environment::get().getWorld()->getStore().get(); - inv.remove(ammoPtr, 1, actor); - mAmmunition.reset(); + MWMechanics::applyFatigueLoss(actor, *weapon, attackStrength); + + if (MWMechanics::getWeaponType(weapon->get()->mBase->mData.mType)->mWeaponClass + == ESM::WeaponType::Thrown) + { + // Thrown weapons get detached now + osg::Node* weaponNode = getWeaponNode(); + if (!weaponNode) + return; + osg::NodePathList nodepaths = weaponNode->getParentalNodePaths(); + if (nodepaths.empty()) + return; + osg::Vec3f launchPos = osg::computeLocalToWorld(nodepaths[0]).getTrans(); + + float fThrownWeaponMinSpeed = gmst.find("fThrownWeaponMinSpeed")->mValue.getFloat(); + float fThrownWeaponMaxSpeed = gmst.find("fThrownWeaponMaxSpeed")->mValue.getFloat(); + float speed = fThrownWeaponMinSpeed + (fThrownWeaponMaxSpeed - fThrownWeaponMinSpeed) * attackStrength; + + MWWorld::Ptr weaponPtr = *weapon; + MWBase::Environment::get().getWorld()->launchProjectile( + actor, weaponPtr, launchPos, orient, weaponPtr, speed, attackStrength); + + showWeapon(false); + + inv.remove(*weapon, 1, actor); + } + else + { + // With bows and crossbows only the used arrow/bolt gets detached + MWWorld::ContainerStoreIterator ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition); + if (ammo == inv.end()) + return; + + if (!mAmmunition) + return; + + osg::ref_ptr ammoNode = mAmmunition->getNode(); + osg::NodePathList nodepaths = ammoNode->getParentalNodePaths(); + if (nodepaths.empty()) + return; + osg::Vec3f launchPos = osg::computeLocalToWorld(nodepaths[0]).getTrans(); + + float fProjectileMinSpeed = gmst.find("fProjectileMinSpeed")->mValue.getFloat(); + float fProjectileMaxSpeed = gmst.find("fProjectileMaxSpeed")->mValue.getFloat(); + float speed = fProjectileMinSpeed + (fProjectileMaxSpeed - fProjectileMinSpeed) * attackStrength; + + MWWorld::Ptr weaponPtr = *weapon; + MWWorld::Ptr ammoPtr = *ammo; + MWBase::Environment::get().getWorld()->launchProjectile( + actor, ammoPtr, launchPos, orient, weaponPtr, speed, attackStrength); + + inv.remove(ammoPtr, 1, actor); + mAmmunition.reset(); + } } -} -void WeaponAnimation::addControllers(const Animation::NodeMap& nodes, std::vector, osg::ref_ptr>> &map, osg::Node* objectRoot) -{ - for (int i=0; i<2; ++i) + void WeaponAnimation::addControllers(const Animation::NodeMap& nodes, + std::vector, osg::ref_ptr>>& map, osg::Node* objectRoot) { - mSpineControllers[i] = nullptr; - - Animation::NodeMap::const_iterator found = nodes.find(i == 0 ? "bip01 spine1" : "bip01 spine2"); - if (found != nodes.end()) + for (int i = 0; i < 2; ++i) { - osg::Node* node = found->second; - mSpineControllers[i] = new RotateController(objectRoot); - node->addUpdateCallback(mSpineControllers[i]); - map.emplace_back(node, mSpineControllers[i]); + mSpineControllers[i] = nullptr; + + Animation::NodeMap::const_iterator found = nodes.find(i == 0 ? "bip01 spine1" : "bip01 spine2"); + if (found != nodes.end()) + { + osg::Node* node = found->second; + mSpineControllers[i] = new RotateController(objectRoot); + node->addUpdateCallback(mSpineControllers[i]); + map.emplace_back(node, mSpineControllers[i]); + } } } -} -void WeaponAnimation::deleteControllers() -{ - for (int i=0; i<2; ++i) - mSpineControllers[i] = nullptr; -} - -void WeaponAnimation::configureControllers(float characterPitchRadians) -{ - if (mPitchFactor == 0.f || characterPitchRadians == 0.f) + void WeaponAnimation::deleteControllers() { - setControllerEnabled(false); - return; + for (int i = 0; i < 2; ++i) + mSpineControllers[i] = nullptr; } - float pitch = characterPitchRadians * mPitchFactor; - osg::Quat rotate (pitch/2, osg::Vec3f(-1,0,0)); - setControllerRotate(rotate); - setControllerEnabled(true); -} + void WeaponAnimation::configureControllers(float characterPitchRadians) + { + if (mPitchFactor == 0.f || characterPitchRadians == 0.f) + { + setControllerEnabled(false); + return; + } -void WeaponAnimation::setControllerRotate(const osg::Quat& rotate) -{ - for (int i=0; i<2; ++i) - if (mSpineControllers[i]) - mSpineControllers[i]->setRotate(rotate); -} + float pitch = characterPitchRadians * mPitchFactor; + osg::Quat rotate(pitch / 2, osg::Vec3f(-1, 0, 0)); + setControllerRotate(rotate); + setControllerEnabled(true); + } -void WeaponAnimation::setControllerEnabled(bool enabled) -{ - for (int i=0; i<2; ++i) - if (mSpineControllers[i]) - mSpineControllers[i]->setEnabled(enabled); -} + void WeaponAnimation::setControllerRotate(const osg::Quat& rotate) + { + for (int i = 0; i < 2; ++i) + if (mSpineControllers[i]) + mSpineControllers[i]->setRotate(rotate); + } + + void WeaponAnimation::setControllerEnabled(bool enabled) + { + for (int i = 0; i < 2; ++i) + if (mSpineControllers[i]) + mSpineControllers[i]->setEnabled(enabled); + } } diff --git a/apps/openmw/mwrender/weaponanimation.hpp b/apps/openmw/mwrender/weaponanimation.hpp index 125587c1bd..ac9babb85a 100644 --- a/apps/openmw/mwrender/weaponanimation.hpp +++ b/apps/openmw/mwrender/weaponanimation.hpp @@ -18,8 +18,14 @@ namespace MWRender std::string mWeaponGroup; float mStartTime; bool mRelativeTime; + public: - WeaponAnimationTime(Animation* animation) : mAnimation(animation), mStartTime(0), mRelativeTime(false) {} + WeaponAnimationTime(Animation* animation) + : mAnimation(animation) + , mStartTime(0) + , mRelativeTime(false) + { + } void setGroup(const std::string& group, bool relativeTime); void updateStartTime(); @@ -34,7 +40,7 @@ namespace MWRender virtual ~WeaponAnimation(); /// @note If no weapon (or an invalid weapon) is equipped, this function is a no-op. - void attachArrow(const MWWorld::Ptr &actor); + void attachArrow(const MWWorld::Ptr& actor); void detachArrow(MWWorld::Ptr actor); @@ -42,7 +48,8 @@ namespace MWRender void releaseArrow(MWWorld::Ptr actor, float attackStrength); /// Add WeaponAnimation-related controllers to \a nodes and store the added controllers in \a map. - void addControllers(const Animation::NodeMap& nodes, std::vector, osg::ref_ptr>>& map, osg::Node* objectRoot); + void addControllers(const Animation::NodeMap& nodes, + std::vector, osg::ref_ptr>>& map, osg::Node* objectRoot); void deleteControllers(); diff --git a/apps/openmw/mwscript/aiextensions.cpp b/apps/openmw/mwscript/aiextensions.cpp index ef4249b4e9..ea1062e1b2 100644 --- a/apps/openmw/mwscript/aiextensions.cpp +++ b/apps/openmw/mwscript/aiextensions.cpp @@ -8,527 +8,532 @@ #include #include -#include #include +#include #include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" #include "../mwmechanics/actorutil.hpp" -#include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/aiactivate.hpp" #include "../mwmechanics/aiescort.hpp" +#include "../mwmechanics/aiface.hpp" #include "../mwmechanics/aifollow.hpp" #include "../mwmechanics/aitravel.hpp" #include "../mwmechanics/aiwander.hpp" -#include "../mwmechanics/aiface.hpp" +#include "../mwmechanics/creaturestats.hpp" #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/soundmanager.hpp" +#include "../mwbase/world.hpp" #include "interpretercontext.hpp" #include "ref.hpp" - namespace MWScript { namespace Ai { - template + template class OpAiActivate : public Interpreter::Opcode1 { - public: + public: + void execute(Interpreter::Runtime& runtime, unsigned int arg0) override + { + MWWorld::Ptr ptr = R()(runtime); - void execute (Interpreter::Runtime& runtime, unsigned int arg0) override - { - MWWorld::Ptr ptr = R()(runtime); + std::string_view objectID = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - std::string_view objectID = runtime.getStringLiteral(runtime[0].mInteger); + // The value of the reset argument doesn't actually matter + bool repeat = arg0; + for (unsigned int i = 0; i < arg0; ++i) runtime.pop(); - // The value of the reset argument doesn't actually matter - bool repeat = arg0; - for (unsigned int i=0; i + template class OpAiTravel : public Interpreter::Opcode1 { - public: + public: + void execute(Interpreter::Runtime& runtime, unsigned int arg0) override + { + MWWorld::Ptr ptr = R()(runtime); - void execute (Interpreter::Runtime& runtime, unsigned int arg0) override - { - MWWorld::Ptr ptr = R()(runtime); + Interpreter::Type_Float x = runtime[0].mFloat; + runtime.pop(); - Interpreter::Type_Float x = runtime[0].mFloat; - runtime.pop(); + Interpreter::Type_Float y = runtime[0].mFloat; + runtime.pop(); - Interpreter::Type_Float y = runtime[0].mFloat; - runtime.pop(); + Interpreter::Type_Float z = runtime[0].mFloat; + runtime.pop(); - Interpreter::Type_Float z = runtime[0].mFloat; + // The value of the reset argument doesn't actually matter + bool repeat = arg0; + for (unsigned int i = 0; i < arg0; ++i) runtime.pop(); - // The value of the reset argument doesn't actually matter - bool repeat = arg0; - for (unsigned int i=0; i + template class OpAiEscort : public Interpreter::Opcode1 { - public: + public: + void execute(Interpreter::Runtime& runtime, unsigned int arg0) override + { + MWWorld::Ptr ptr = R()(runtime); - void execute (Interpreter::Runtime& runtime, unsigned int arg0) override - { - MWWorld::Ptr ptr = R()(runtime); + std::string_view actorID = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - std::string_view actorID = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + Interpreter::Type_Float duration = runtime[0].mFloat; + runtime.pop(); - Interpreter::Type_Float duration = runtime[0].mFloat; - runtime.pop(); + Interpreter::Type_Float x = runtime[0].mFloat; + runtime.pop(); - Interpreter::Type_Float x = runtime[0].mFloat; - runtime.pop(); + Interpreter::Type_Float y = runtime[0].mFloat; + runtime.pop(); - Interpreter::Type_Float y = runtime[0].mFloat; - runtime.pop(); + Interpreter::Type_Float z = runtime[0].mFloat; + runtime.pop(); - Interpreter::Type_Float z = runtime[0].mFloat; + // The value of the reset argument doesn't actually matter + bool repeat = arg0; + for (unsigned int i = 0; i < arg0; ++i) runtime.pop(); - // The value of the reset argument doesn't actually matter - bool repeat = arg0; - for (unsigned int i=0; i(duration), x, y, z, repeat); - ptr.getClass().getCreatureStats (ptr).getAiSequence().stack(escortPackage, ptr); + MWMechanics::AiEscort escortPackage(actorID, static_cast(duration), x, y, z, repeat); + ptr.getClass().getCreatureStats(ptr).getAiSequence().stack(escortPackage, ptr); - Log(Debug::Info) << "AiEscort: " << x << ", " << y << ", " << z << ", " << duration; - } + Log(Debug::Info) << "AiEscort: " << x << ", " << y << ", " << z << ", " << duration; + } }; - template + template class OpAiEscortCell : public Interpreter::Opcode1 { - public: + public: + void execute(Interpreter::Runtime& runtime, unsigned int arg0) override + { + MWWorld::Ptr ptr = R()(runtime); - void execute (Interpreter::Runtime& runtime, unsigned int arg0) override - { - MWWorld::Ptr ptr = R()(runtime); + std::string_view actorID = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - std::string_view actorID = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + std::string_view cellID = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - std::string_view cellID = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + Interpreter::Type_Float duration = runtime[0].mFloat; + runtime.pop(); - Interpreter::Type_Float duration = runtime[0].mFloat; - runtime.pop(); + Interpreter::Type_Float x = runtime[0].mFloat; + runtime.pop(); - Interpreter::Type_Float x = runtime[0].mFloat; - runtime.pop(); + Interpreter::Type_Float y = runtime[0].mFloat; + runtime.pop(); - Interpreter::Type_Float y = runtime[0].mFloat; - runtime.pop(); + Interpreter::Type_Float z = runtime[0].mFloat; + runtime.pop(); - Interpreter::Type_Float z = runtime[0].mFloat; + // The value of the reset argument doesn't actually matter + bool repeat = arg0; + for (unsigned int i = 0; i < arg0; ++i) runtime.pop(); - // The value of the reset argument doesn't actually matter - bool repeat = arg0; - for (unsigned int i=0; igetStore().get().search(cellID)) - return; + if (!MWBase::Environment::get().getWorld()->getStore().get().search(cellID)) + return; - MWMechanics::AiEscort escortPackage(actorID, cellID, static_cast(duration), x, y, z, repeat); - ptr.getClass().getCreatureStats (ptr).getAiSequence().stack(escortPackage, ptr); + MWMechanics::AiEscort escortPackage(actorID, cellID, static_cast(duration), x, y, z, repeat); + ptr.getClass().getCreatureStats(ptr).getAiSequence().stack(escortPackage, ptr); - Log(Debug::Info) << "AiEscort: " << x << ", " << y << ", " << z << ", " << duration; - } + Log(Debug::Info) << "AiEscort: " << x << ", " << y << ", " << z << ", " << duration; + } }; - template + template class OpGetAiPackageDone : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - bool done = false; - if (ptr.getClass().isActor()) - done = ptr.getClass().getCreatureStats(ptr).getAiSequence().isPackageDone(); + bool done = false; + if (ptr.getClass().isActor()) + done = ptr.getClass().getCreatureStats(ptr).getAiSequence().isPackageDone(); - runtime.push(done); - } + runtime.push(done); + } }; - template + template class OpAiWander : public Interpreter::Opcode1 { - public: + public: + void execute(Interpreter::Runtime& runtime, unsigned int arg0) override + { + MWWorld::Ptr ptr = R()(runtime); - void execute (Interpreter::Runtime& runtime, unsigned int arg0) override - { - MWWorld::Ptr ptr = R()(runtime); + Interpreter::Type_Integer range = static_cast(runtime[0].mFloat); + runtime.pop(); - Interpreter::Type_Integer range = static_cast(runtime[0].mFloat); - runtime.pop(); + Interpreter::Type_Integer duration = static_cast(runtime[0].mFloat); + runtime.pop(); - Interpreter::Type_Integer duration = static_cast(runtime[0].mFloat); - runtime.pop(); + Interpreter::Type_Integer time = static_cast(runtime[0].mFloat); + runtime.pop(); - Interpreter::Type_Integer time = static_cast(runtime[0].mFloat); + // Chance for Idle is unused + if (arg0) + { + --arg0; runtime.pop(); + } - // Chance for Idle is unused - if (arg0) - { - --arg0; - runtime.pop(); - } - - std::vector idleList; - bool repeat = false; + std::vector idleList; + bool repeat = false; - // Chances for Idle2-Idle9 - for(int i=2; i<=9 && arg0; ++i) - { - if(!repeat) - repeat = true; - Interpreter::Type_Integer idleValue = std::clamp(runtime[0].mInteger, 0, 255); - idleList.push_back(idleValue); - runtime.pop(); - --arg0; - } + // Chances for Idle2-Idle9 + for (int i = 2; i <= 9 && arg0; ++i) + { + if (!repeat) + repeat = true; + Interpreter::Type_Integer idleValue = std::clamp(runtime[0].mInteger, 0, 255); + idleList.push_back(idleValue); + runtime.pop(); + --arg0; + } - if(arg0) - { - repeat = runtime[0].mInteger != 0; - runtime.pop(); - --arg0; - } + if (arg0) + { + repeat = runtime[0].mInteger != 0; + runtime.pop(); + --arg0; + } - // discard additional arguments, because we have no idea what they mean. - for (unsigned int i=0; i + template class OpGetAiSetting : public Interpreter::Opcode0 { MWMechanics::AiSetting mIndex; - public: - OpGetAiSetting(MWMechanics::AiSetting index) : mIndex(index) {} - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + OpGetAiSetting(MWMechanics::AiSetting index) + : mIndex(index) + { + } - Interpreter::Type_Integer value = 0; - if (ptr.getClass().isActor()) - value = ptr.getClass().getCreatureStats (ptr).getAiSetting(mIndex).getModified(false); - runtime.push(value); - } + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); + + Interpreter::Type_Integer value = 0; + if (ptr.getClass().isActor()) + value = ptr.getClass().getCreatureStats(ptr).getAiSetting(mIndex).getModified(false); + runtime.push(value); + } }; - template + template class OpModAiSetting : public Interpreter::Opcode0 { MWMechanics::AiSetting mIndex; - public: - OpModAiSetting(MWMechanics::AiSetting index) : mIndex(index) {} - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); - Interpreter::Type_Integer value = runtime[0].mInteger; - runtime.pop(); + public: + OpModAiSetting(MWMechanics::AiSetting index) + : mIndex(index) + { + } - if (!ptr.getClass().isActor()) - return; + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); + Interpreter::Type_Integer value = runtime[0].mInteger; + runtime.pop(); - int modified = ptr.getClass().getCreatureStats (ptr).getAiSetting (mIndex).getBase() + value; + if (!ptr.getClass().isActor()) + return; - ptr.getClass().getCreatureStats (ptr).setAiSetting (mIndex, modified); - ptr.getClass().setBaseAISetting(ptr.getCellRef().getRefId(), mIndex, modified); - } + int modified = ptr.getClass().getCreatureStats(ptr).getAiSetting(mIndex).getBase() + value; + + ptr.getClass().getCreatureStats(ptr).setAiSetting(mIndex, modified); + ptr.getClass().setBaseAISetting(ptr.getCellRef().getRefId(), mIndex, modified); + } }; - template + template class OpSetAiSetting : public Interpreter::Opcode0 { MWMechanics::AiSetting mIndex; - public: - OpSetAiSetting(MWMechanics::AiSetting index) : mIndex(index) {} - void execute (Interpreter::Runtime& runtime) override + public: + OpSetAiSetting(MWMechanics::AiSetting index) + : mIndex(index) + { + } + + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); + Interpreter::Type_Integer value = runtime[0].mInteger; + runtime.pop(); + if (ptr.getClass().isActor()) { - MWWorld::Ptr ptr = R()(runtime); - Interpreter::Type_Integer value = runtime[0].mInteger; - runtime.pop(); - if(ptr.getClass().isActor()) - { - ptr.getClass().getCreatureStats(ptr).setAiSetting(mIndex, value); - ptr.getClass().setBaseAISetting(ptr.getCellRef().getRefId(), mIndex, value); - } + ptr.getClass().getCreatureStats(ptr).setAiSetting(mIndex, value); + ptr.getClass().setBaseAISetting(ptr.getCellRef().getRefId(), mIndex, value); } + } }; - template + template class OpAiFollow : public Interpreter::Opcode1 { - public: + public: + void execute(Interpreter::Runtime& runtime, unsigned int arg0) override + { + MWWorld::Ptr ptr = R()(runtime); - void execute (Interpreter::Runtime& runtime, unsigned int arg0) override - { - MWWorld::Ptr ptr = R()(runtime); + std::string_view actorID = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - std::string_view actorID = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + Interpreter::Type_Float duration = runtime[0].mFloat; + runtime.pop(); - Interpreter::Type_Float duration = runtime[0].mFloat; - runtime.pop(); + Interpreter::Type_Float x = runtime[0].mFloat; + runtime.pop(); - Interpreter::Type_Float x = runtime[0].mFloat; - runtime.pop(); + Interpreter::Type_Float y = runtime[0].mFloat; + runtime.pop(); - Interpreter::Type_Float y = runtime[0].mFloat; - runtime.pop(); + Interpreter::Type_Float z = runtime[0].mFloat; + runtime.pop(); - Interpreter::Type_Float z = runtime[0].mFloat; + // The value of the reset argument doesn't actually matter + bool repeat = arg0; + for (unsigned int i = 0; i < arg0; ++i) runtime.pop(); - // The value of the reset argument doesn't actually matter - bool repeat = arg0; - for (unsigned int i=0; i + template class OpAiFollowCell : public Interpreter::Opcode1 { - public: + public: + void execute(Interpreter::Runtime& runtime, unsigned int arg0) override + { + MWWorld::Ptr ptr = R()(runtime); - void execute (Interpreter::Runtime& runtime, unsigned int arg0) override - { - MWWorld::Ptr ptr = R()(runtime); + std::string_view actorID = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - std::string_view actorID = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + std::string_view cellID = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - std::string_view cellID = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + Interpreter::Type_Float duration = runtime[0].mFloat; + runtime.pop(); - Interpreter::Type_Float duration = runtime[0].mFloat; - runtime.pop(); + Interpreter::Type_Float x = runtime[0].mFloat; + runtime.pop(); - Interpreter::Type_Float x = runtime[0].mFloat; - runtime.pop(); + Interpreter::Type_Float y = runtime[0].mFloat; + runtime.pop(); - Interpreter::Type_Float y = runtime[0].mFloat; - runtime.pop(); + Interpreter::Type_Float z = runtime[0].mFloat; + runtime.pop(); - Interpreter::Type_Float z = runtime[0].mFloat; + // The value of the reset argument doesn't actually matter + bool repeat = arg0; + for (unsigned int i = 0; i < arg0; ++i) runtime.pop(); - // The value of the reset argument doesn't actually matter - bool repeat = arg0; - for (unsigned int i=0; i + template class OpGetCurrentAIPackage : public Interpreter::Opcode0 { - public: + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - void execute (Interpreter::Runtime& runtime) override + Interpreter::Type_Integer value = -1; + if (ptr.getClass().isActor()) { - MWWorld::Ptr ptr = R()(runtime); - - Interpreter::Type_Integer value = -1; - if(ptr.getClass().isActor()) + const auto& stats = ptr.getClass().getCreatureStats(ptr); + if (!stats.isDead() || !stats.isDeathAnimationFinished()) { - const auto& stats = ptr.getClass().getCreatureStats(ptr); - if(!stats.isDead() || !stats.isDeathAnimationFinished()) - { - value = static_cast(stats.getAiSequence().getLastRunTypeId()); - } + value = static_cast(stats.getAiSequence().getLastRunTypeId()); } - - runtime.push (value); } + + runtime.push(value); + } }; - template + template class OpGetDetected : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr observer = R()(runtime, false); // required=false + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr observer = R()(runtime, false); // required=false - std::string_view actorID = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + std::string_view actorID = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - MWWorld::Ptr actor = MWBase::Environment::get().getWorld()->searchPtr(actorID, true, false); + MWWorld::Ptr actor = MWBase::Environment::get().getWorld()->searchPtr(actorID, true, false); - Interpreter::Type_Integer value = 0; - if (!actor.isEmpty()) - value = MWBase::Environment::get().getMechanicsManager()->isActorDetected(actor, observer); + Interpreter::Type_Integer value = 0; + if (!actor.isEmpty()) + value = MWBase::Environment::get().getMechanicsManager()->isActorDetected(actor, observer); - runtime.push (value); - } + runtime.push(value); + } }; - template + template class OpGetLineOfSight : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - - MWWorld::Ptr source = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { - std::string_view actorID = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + MWWorld::Ptr source = R()(runtime); + std::string_view actorID = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - MWWorld::Ptr dest = MWBase::Environment::get().getWorld()->searchPtr(actorID, true, false); - bool value = false; - if (!dest.isEmpty() && source.getClass().isActor() && dest.getClass().isActor()) - { - value = MWBase::Environment::get().getWorld()->getLOS(source,dest); - } - runtime.push (value); + MWWorld::Ptr dest = MWBase::Environment::get().getWorld()->searchPtr(actorID, true, false); + bool value = false; + if (!dest.isEmpty() && source.getClass().isActor() && dest.getClass().isActor()) + { + value = MWBase::Environment::get().getWorld()->getLOS(source, dest); } + runtime.push(value); + } }; - template + template class OpGetTarget : public Interpreter::Opcode0 { - public: - void execute (Interpreter::Runtime &runtime) override - { - MWWorld::Ptr actor = R()(runtime); - std::string_view testedTargetId = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr actor = R()(runtime); + std::string_view testedTargetId = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - bool targetsAreEqual = false; - if (actor.getClass().isActor()) + bool targetsAreEqual = false; + if (actor.getClass().isActor()) + { + const MWMechanics::CreatureStats& creatureStats = actor.getClass().getCreatureStats(actor); + MWWorld::Ptr targetPtr; + if (creatureStats.getAiSequence().getCombatTarget(targetPtr)) + { + if (!targetPtr.isEmpty() && targetPtr.getCellRef().getRefId() == testedTargetId) + targetsAreEqual = true; + } + else if (testedTargetId == "player") // Currently the player ID is hardcoded { - const MWMechanics::CreatureStats& creatureStats = actor.getClass().getCreatureStats(actor); - MWWorld::Ptr targetPtr; - if (creatureStats.getAiSequence().getCombatTarget(targetPtr)) - { - if (!targetPtr.isEmpty() && targetPtr.getCellRef().getRefId() == testedTargetId) - targetsAreEqual = true; - } - else if (testedTargetId == "player") // Currently the player ID is hardcoded - { - MWBase::MechanicsManager* mechMgr = MWBase::Environment::get().getMechanicsManager(); - bool greeting = mechMgr->getGreetingState(actor) == MWMechanics::Greet_InProgress; - bool sayActive = MWBase::Environment::get().getSoundManager()->sayActive(actor); - targetsAreEqual = (greeting && sayActive) || mechMgr->isTurningToPlayer(actor); - } + MWBase::MechanicsManager* mechMgr = MWBase::Environment::get().getMechanicsManager(); + bool greeting = mechMgr->getGreetingState(actor) == MWMechanics::Greet_InProgress; + bool sayActive = MWBase::Environment::get().getSoundManager()->sayActive(actor); + targetsAreEqual = (greeting && sayActive) || mechMgr->isTurningToPlayer(actor); } - runtime.push(targetsAreEqual); } + runtime.push(targetsAreEqual); + } }; - template + template class OpStartCombat : public Interpreter::Opcode0 { - public: - void execute (Interpreter::Runtime &runtime) override - { - MWWorld::Ptr actor = R()(runtime); - std::string_view targetID = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr actor = R()(runtime); + std::string_view targetID = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - MWWorld::Ptr target = MWBase::Environment::get().getWorld()->searchPtr(targetID, true, false); - if (!target.isEmpty()) - MWBase::Environment::get().getMechanicsManager()->startCombat(actor, target); - } + MWWorld::Ptr target = MWBase::Environment::get().getWorld()->searchPtr(targetID, true, false); + if (!target.isEmpty()) + MWBase::Environment::get().getMechanicsManager()->startCombat(actor, target); + } }; - template + template class OpStopCombat : public Interpreter::Opcode0 { - public: - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr actor = R()(runtime); - if (!actor.getClass().isActor()) - return; - MWBase::Environment::get().getMechanicsManager()->stopCombat(actor); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr actor = R()(runtime); + if (!actor.getClass().isActor()) + return; + MWBase::Environment::get().getMechanicsManager()->stopCombat(actor); + } }; class OpToggleAI : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - bool enabled = MWBase::Environment::get().getMechanicsManager()->toggleAI(); + public: + void execute(Interpreter::Runtime& runtime) override + { + bool enabled = MWBase::Environment::get().getMechanicsManager()->toggleAI(); - runtime.getContext().report (enabled ? "AI -> On" : "AI -> Off"); - } + runtime.getContext().report(enabled ? "AI -> On" : "AI -> Off"); + } }; template @@ -573,7 +578,8 @@ namespace MWScript interpreter.installSegment5>(Compiler::Ai::opcodeGetAiPackageDoneExplicit); interpreter.installSegment5>(Compiler::Ai::opcodeGetCurrentAiPackage); - interpreter.installSegment5>(Compiler::Ai::opcodeGetCurrentAiPackageExplicit); + interpreter.installSegment5>( + Compiler::Ai::opcodeGetCurrentAiPackageExplicit); interpreter.installSegment5>(Compiler::Ai::opcodeGetDetected); interpreter.installSegment5>(Compiler::Ai::opcodeGetDetectedExplicit); interpreter.installSegment5>(Compiler::Ai::opcodeGetLineOfSight); @@ -586,32 +592,56 @@ namespace MWScript interpreter.installSegment5>(Compiler::Ai::opcodeStopCombatExplicit); interpreter.installSegment5(Compiler::Ai::opcodeToggleAI); - interpreter.installSegment5>(Compiler::Ai::opcodeSetHello, MWMechanics::AiSetting::Hello); - interpreter.installSegment5>(Compiler::Ai::opcodeSetHelloExplicit, MWMechanics::AiSetting::Hello); - interpreter.installSegment5>(Compiler::Ai::opcodeSetFight, MWMechanics::AiSetting::Fight); - interpreter.installSegment5>(Compiler::Ai::opcodeSetFightExplicit, MWMechanics::AiSetting::Fight); - interpreter.installSegment5>(Compiler::Ai::opcodeSetFlee, MWMechanics::AiSetting::Flee); - interpreter.installSegment5>(Compiler::Ai::opcodeSetFleeExplicit, MWMechanics::AiSetting::Flee); - interpreter.installSegment5>(Compiler::Ai::opcodeSetAlarm, MWMechanics::AiSetting::Alarm); - interpreter.installSegment5>(Compiler::Ai::opcodeSetAlarmExplicit, MWMechanics::AiSetting::Alarm); - - interpreter.installSegment5>(Compiler::Ai::opcodeModHello, MWMechanics::AiSetting::Hello); - interpreter.installSegment5>(Compiler::Ai::opcodeModHelloExplicit, MWMechanics::AiSetting::Hello); - interpreter.installSegment5>(Compiler::Ai::opcodeModFight, MWMechanics::AiSetting::Fight); - interpreter.installSegment5>(Compiler::Ai::opcodeModFightExplicit, MWMechanics::AiSetting::Fight); - interpreter.installSegment5>(Compiler::Ai::opcodeModFlee, MWMechanics::AiSetting::Flee); - interpreter.installSegment5>(Compiler::Ai::opcodeModFleeExplicit, MWMechanics::AiSetting::Flee); - interpreter.installSegment5>(Compiler::Ai::opcodeModAlarm, MWMechanics::AiSetting::Alarm); - interpreter.installSegment5>(Compiler::Ai::opcodeModAlarmExplicit, MWMechanics::AiSetting::Alarm); - - interpreter.installSegment5>(Compiler::Ai::opcodeGetHello, MWMechanics::AiSetting::Hello); - interpreter.installSegment5>(Compiler::Ai::opcodeGetHelloExplicit, MWMechanics::AiSetting::Hello); - interpreter.installSegment5>(Compiler::Ai::opcodeGetFight, MWMechanics::AiSetting::Fight); - interpreter.installSegment5>(Compiler::Ai::opcodeGetFightExplicit, MWMechanics::AiSetting::Fight); - interpreter.installSegment5>(Compiler::Ai::opcodeGetFlee, MWMechanics::AiSetting::Flee); - interpreter.installSegment5>(Compiler::Ai::opcodeGetFleeExplicit, MWMechanics::AiSetting::Flee); - interpreter.installSegment5>(Compiler::Ai::opcodeGetAlarm, MWMechanics::AiSetting::Alarm); - interpreter.installSegment5>(Compiler::Ai::opcodeGetAlarmExplicit, MWMechanics::AiSetting::Alarm); + interpreter.installSegment5>( + Compiler::Ai::opcodeSetHello, MWMechanics::AiSetting::Hello); + interpreter.installSegment5>( + Compiler::Ai::opcodeSetHelloExplicit, MWMechanics::AiSetting::Hello); + interpreter.installSegment5>( + Compiler::Ai::opcodeSetFight, MWMechanics::AiSetting::Fight); + interpreter.installSegment5>( + Compiler::Ai::opcodeSetFightExplicit, MWMechanics::AiSetting::Fight); + interpreter.installSegment5>( + Compiler::Ai::opcodeSetFlee, MWMechanics::AiSetting::Flee); + interpreter.installSegment5>( + Compiler::Ai::opcodeSetFleeExplicit, MWMechanics::AiSetting::Flee); + interpreter.installSegment5>( + Compiler::Ai::opcodeSetAlarm, MWMechanics::AiSetting::Alarm); + interpreter.installSegment5>( + Compiler::Ai::opcodeSetAlarmExplicit, MWMechanics::AiSetting::Alarm); + + interpreter.installSegment5>( + Compiler::Ai::opcodeModHello, MWMechanics::AiSetting::Hello); + interpreter.installSegment5>( + Compiler::Ai::opcodeModHelloExplicit, MWMechanics::AiSetting::Hello); + interpreter.installSegment5>( + Compiler::Ai::opcodeModFight, MWMechanics::AiSetting::Fight); + interpreter.installSegment5>( + Compiler::Ai::opcodeModFightExplicit, MWMechanics::AiSetting::Fight); + interpreter.installSegment5>( + Compiler::Ai::opcodeModFlee, MWMechanics::AiSetting::Flee); + interpreter.installSegment5>( + Compiler::Ai::opcodeModFleeExplicit, MWMechanics::AiSetting::Flee); + interpreter.installSegment5>( + Compiler::Ai::opcodeModAlarm, MWMechanics::AiSetting::Alarm); + interpreter.installSegment5>( + Compiler::Ai::opcodeModAlarmExplicit, MWMechanics::AiSetting::Alarm); + + interpreter.installSegment5>( + Compiler::Ai::opcodeGetHello, MWMechanics::AiSetting::Hello); + interpreter.installSegment5>( + Compiler::Ai::opcodeGetHelloExplicit, MWMechanics::AiSetting::Hello); + interpreter.installSegment5>( + Compiler::Ai::opcodeGetFight, MWMechanics::AiSetting::Fight); + interpreter.installSegment5>( + Compiler::Ai::opcodeGetFightExplicit, MWMechanics::AiSetting::Fight); + interpreter.installSegment5>( + Compiler::Ai::opcodeGetFlee, MWMechanics::AiSetting::Flee); + interpreter.installSegment5>( + Compiler::Ai::opcodeGetFleeExplicit, MWMechanics::AiSetting::Flee); + interpreter.installSegment5>( + Compiler::Ai::opcodeGetAlarm, MWMechanics::AiSetting::Alarm); + interpreter.installSegment5>( + Compiler::Ai::opcodeGetAlarmExplicit, MWMechanics::AiSetting::Alarm); interpreter.installSegment5>(Compiler::Ai::opcodeFace); interpreter.installSegment5>(Compiler::Ai::opcodeFaceExplicit); diff --git a/apps/openmw/mwscript/aiextensions.hpp b/apps/openmw/mwscript/aiextensions.hpp index e9e36113cf..5fd0db7d23 100644 --- a/apps/openmw/mwscript/aiextensions.hpp +++ b/apps/openmw/mwscript/aiextensions.hpp @@ -16,7 +16,7 @@ namespace MWScript /// \brief AI-related script functionality namespace Ai { - void installOpcodes (Interpreter::Interpreter& interpreter); + void installOpcodes(Interpreter::Interpreter& interpreter); } } diff --git a/apps/openmw/mwscript/animationextensions.cpp b/apps/openmw/mwscript/animationextensions.cpp index de715f93ac..caef3e0e88 100644 --- a/apps/openmw/mwscript/animationextensions.cpp +++ b/apps/openmw/mwscript/animationextensions.cpp @@ -1,13 +1,13 @@ #include "animationextensions.hpp" -#include #include +#include #include #include -#include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/mechanicsmanager.hpp" @@ -19,87 +19,84 @@ namespace MWScript { namespace Animation { - template + template class OpSkipAnim : public Interpreter::Opcode0 { - public: + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); - - MWBase::Environment::get().getMechanicsManager()->skipAnimation (ptr); - } + MWBase::Environment::get().getMechanicsManager()->skipAnimation(ptr); + } }; - template + template class OpPlayAnim : public Interpreter::Opcode1 { - public: - - void execute (Interpreter::Runtime& runtime, unsigned int arg0) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime, unsigned int arg0) override + { + MWWorld::Ptr ptr = R()(runtime); - if (!ptr.getRefData().isEnabled()) - return; + if (!ptr.getRefData().isEnabled()) + return; - std::string_view group = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + std::string_view group = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - Interpreter::Type_Integer mode = 0; + Interpreter::Type_Integer mode = 0; - if (arg0==1) - { - mode = runtime[0].mInteger; - runtime.pop(); + if (arg0 == 1) + { + mode = runtime[0].mInteger; + runtime.pop(); - if (mode<0 || mode>2) - throw std::runtime_error ("animation mode out of range"); - } + if (mode < 0 || mode > 2) + throw std::runtime_error("animation mode out of range"); + } - MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(ptr, group, mode, std::numeric_limits::max(), true); - } + MWBase::Environment::get().getMechanicsManager()->playAnimationGroup( + ptr, group, mode, std::numeric_limits::max(), true); + } }; - template + template class OpLoopAnim : public Interpreter::Opcode1 { - public: - - void execute (Interpreter::Runtime& runtime, unsigned int arg0) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime, unsigned int arg0) override + { + MWWorld::Ptr ptr = R()(runtime); - if (!ptr.getRefData().isEnabled()) - return; + if (!ptr.getRefData().isEnabled()) + return; - std::string_view group = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + std::string_view group = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - Interpreter::Type_Integer loops = runtime[0].mInteger; - runtime.pop(); + Interpreter::Type_Integer loops = runtime[0].mInteger; + runtime.pop(); - if (loops<0) - throw std::runtime_error ("number of animation loops must be non-negative"); + if (loops < 0) + throw std::runtime_error("number of animation loops must be non-negative"); - Interpreter::Type_Integer mode = 0; + Interpreter::Type_Integer mode = 0; - if (arg0==1) - { - mode = runtime[0].mInteger; - runtime.pop(); + if (arg0 == 1) + { + mode = runtime[0].mInteger; + runtime.pop(); - if (mode<0 || mode>2) - throw std::runtime_error ("animation mode out of range"); - } + if (mode < 0 || mode > 2) + throw std::runtime_error("animation mode out of range"); + } - MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(ptr, group, mode, loops + 1, true); - } + MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(ptr, group, mode, loops + 1, true); + } }; - - void installOpcodes (Interpreter::Interpreter& interpreter) + void installOpcodes(Interpreter::Interpreter& interpreter) { interpreter.installSegment5>(Compiler::Animation::opcodeSkipAnim); interpreter.installSegment5>(Compiler::Animation::opcodeSkipAnimExplicit); diff --git a/apps/openmw/mwscript/animationextensions.hpp b/apps/openmw/mwscript/animationextensions.hpp index ff619ab73a..a6805f7ee3 100644 --- a/apps/openmw/mwscript/animationextensions.hpp +++ b/apps/openmw/mwscript/animationextensions.hpp @@ -15,9 +15,9 @@ namespace MWScript { namespace Animation { - void registerExtensions (Compiler::Extensions& extensions); + void registerExtensions(Compiler::Extensions& extensions); - void installOpcodes (Interpreter::Interpreter& interpreter); + void installOpcodes(Interpreter::Interpreter& interpreter); } } diff --git a/apps/openmw/mwscript/cellextensions.cpp b/apps/openmw/mwscript/cellextensions.cpp index 444e2dbced..6f5a4c97f0 100644 --- a/apps/openmw/mwscript/cellextensions.cpp +++ b/apps/openmw/mwscript/cellextensions.cpp @@ -7,15 +7,15 @@ #include #include -#include #include +#include -#include "../mwworld/actionteleport.hpp" -#include "../mwworld/cellstore.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/statemanager.hpp" #include "../mwbase/windowmanager.hpp" #include "../mwbase/world.hpp" +#include "../mwworld/actionteleport.hpp" +#include "../mwworld/cellstore.hpp" #include "../mwmechanics/actorutil.hpp" @@ -27,227 +27,217 @@ namespace MWScript { class OpCellChanged : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - runtime.push (MWBase::Environment::get().getWorld()->hasCellChanged() ? 1 : 0); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + runtime.push(MWBase::Environment::get().getWorld()->hasCellChanged() ? 1 : 0); + } }; class OpTestCells : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override + public: + void execute(Interpreter::Runtime& runtime) override + { + if (MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_NoGame) { - if (MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_NoGame) - { - runtime.getContext().report("Use TestCells from the main menu, when there is no active game session."); - return; - } + runtime.getContext().report( + "Use TestCells from the main menu, when there is no active game session."); + return; + } - bool wasConsole = MWBase::Environment::get().getWindowManager()->isConsoleMode(); - if (wasConsole) - MWBase::Environment::get().getWindowManager()->toggleConsole(); + bool wasConsole = MWBase::Environment::get().getWindowManager()->isConsoleMode(); + if (wasConsole) + MWBase::Environment::get().getWindowManager()->toggleConsole(); - MWBase::Environment::get().getWorld()->testExteriorCells(); + MWBase::Environment::get().getWorld()->testExteriorCells(); - if (wasConsole) - MWBase::Environment::get().getWindowManager()->toggleConsole(); - } + if (wasConsole) + MWBase::Environment::get().getWindowManager()->toggleConsole(); + } }; class OpTestInteriorCells : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override + public: + void execute(Interpreter::Runtime& runtime) override + { + if (MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_NoGame) { - if (MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_NoGame) - { - runtime.getContext().report("Use TestInteriorCells from the main menu, when there is no active game session."); - return; - } + runtime.getContext().report( + "Use TestInteriorCells from the main menu, when there is no active game session."); + return; + } - bool wasConsole = MWBase::Environment::get().getWindowManager()->isConsoleMode(); - if (wasConsole) - MWBase::Environment::get().getWindowManager()->toggleConsole(); + bool wasConsole = MWBase::Environment::get().getWindowManager()->isConsoleMode(); + if (wasConsole) + MWBase::Environment::get().getWindowManager()->toggleConsole(); - MWBase::Environment::get().getWorld()->testInteriorCells(); + MWBase::Environment::get().getWorld()->testInteriorCells(); - if (wasConsole) - MWBase::Environment::get().getWindowManager()->toggleConsole(); - } + if (wasConsole) + MWBase::Environment::get().getWindowManager()->toggleConsole(); + } }; class OpCOC : public Interpreter::Opcode0 { - public: + public: + void execute(Interpreter::Runtime& runtime) override + { + std::string_view cell = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - void execute (Interpreter::Runtime& runtime) override + ESM::Position pos; + MWBase::World* world = MWBase::Environment::get().getWorld(); + const MWWorld::Ptr playerPtr = world->getPlayerPtr(); + + if (world->findExteriorPosition(cell, pos)) + { + MWWorld::ActionTeleport({}, pos, false).execute(playerPtr); + world->adjustPosition(playerPtr, false); + } + else { - std::string_view cell = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); - - ESM::Position pos; - MWBase::World *world = MWBase::Environment::get().getWorld(); - const MWWorld::Ptr playerPtr = world->getPlayerPtr(); - - if (world->findExteriorPosition(cell, pos)) - { - MWWorld::ActionTeleport({}, pos, false).execute(playerPtr); - world->adjustPosition(playerPtr, false); - } - else - { - // Change to interior even if findInteriorPosition() - // yields false. In this case position will be zero-point. - world->findInteriorPosition(cell, pos); - MWWorld::ActionTeleport(cell, pos, false).execute(playerPtr); - } + // Change to interior even if findInteriorPosition() + // yields false. In this case position will be zero-point. + world->findInteriorPosition(cell, pos); + MWWorld::ActionTeleport(cell, pos, false).execute(playerPtr); } + } }; class OpCOE : public Interpreter::Opcode0 { - public: + public: + void execute(Interpreter::Runtime& runtime) override + { + Interpreter::Type_Integer x = runtime[0].mInteger; + runtime.pop(); - void execute (Interpreter::Runtime& runtime) override - { - Interpreter::Type_Integer x = runtime[0].mInteger; - runtime.pop(); - - Interpreter::Type_Integer y = runtime[0].mInteger; - runtime.pop(); + Interpreter::Type_Integer y = runtime[0].mInteger; + runtime.pop(); - ESM::Position pos; - MWBase::World *world = MWBase::Environment::get().getWorld(); - const MWWorld::Ptr playerPtr = world->getPlayerPtr(); + ESM::Position pos; + MWBase::World* world = MWBase::Environment::get().getWorld(); + const MWWorld::Ptr playerPtr = world->getPlayerPtr(); - world->indexToPosition (x, y, pos.pos[0], pos.pos[1], true); - pos.pos[2] = 0; + world->indexToPosition(x, y, pos.pos[0], pos.pos[1], true); + pos.pos[2] = 0; - pos.rot[0] = pos.rot[1] = pos.rot[2] = 0; + pos.rot[0] = pos.rot[1] = pos.rot[2] = 0; - MWWorld::ActionTeleport({}, pos, false).execute(playerPtr); - world->adjustPosition(playerPtr, false); - } + MWWorld::ActionTeleport({}, pos, false).execute(playerPtr); + world->adjustPosition(playerPtr, false); + } }; class OpGetInterior : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override + public: + void execute(Interpreter::Runtime& runtime) override + { + if (!MWMechanics::getPlayer().isInCell()) { - if (!MWMechanics::getPlayer().isInCell()) - { - runtime.push (0); - return; - } + runtime.push(0); + return; + } - bool interior = - !MWMechanics::getPlayer().getCell()->getCell()->isExterior(); + bool interior = !MWMechanics::getPlayer().getCell()->getCell()->isExterior(); - runtime.push (interior ? 1 : 0); - } + runtime.push(interior ? 1 : 0); + } }; class OpGetPCCell : public Interpreter::Opcode0 { - public: + public: + void execute(Interpreter::Runtime& runtime) override + { + std::string_view name = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - void execute (Interpreter::Runtime& runtime) override + if (!MWMechanics::getPlayer().isInCell()) { - std::string_view name = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); - - if (!MWMechanics::getPlayer().isInCell()) - { - runtime.push(0); - return; - } - const MWWorld::CellStore *cell = MWMechanics::getPlayer().getCell(); + runtime.push(0); + return; + } + const MWWorld::CellStore* cell = MWMechanics::getPlayer().getCell(); - std::string_view current = MWBase::Environment::get().getWorld()->getCellName(cell); - bool match = Misc::StringUtils::ciCompareLen(name, current, name.length()) == 0; + std::string_view current = MWBase::Environment::get().getWorld()->getCellName(cell); + bool match = Misc::StringUtils::ciCompareLen(name, current, name.length()) == 0; - runtime.push (match ? 1 : 0); - } + runtime.push(match ? 1 : 0); + } }; class OpGetWaterLevel : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override + public: + void execute(Interpreter::Runtime& runtime) override + { + if (!MWMechanics::getPlayer().isInCell()) { - if (!MWMechanics::getPlayer().isInCell()) - { - runtime.push(0.f); - return; - } - MWWorld::CellStore *cell = MWMechanics::getPlayer().getCell(); - if (cell->isExterior()) - runtime.push(0.f); // vanilla oddity, return 0 even though water is actually at -1 - else if (cell->getCell()->hasWater()) - runtime.push (cell->getWaterLevel()); - else - runtime.push (-std::numeric_limits::max()); + runtime.push(0.f); + return; } + MWWorld::CellStore* cell = MWMechanics::getPlayer().getCell(); + if (cell->isExterior()) + runtime.push(0.f); // vanilla oddity, return 0 even though water is actually at -1 + else if (cell->getCell()->hasWater()) + runtime.push(cell->getWaterLevel()); + else + runtime.push(-std::numeric_limits::max()); + } }; class OpSetWaterLevel : public Interpreter::Opcode0 { - public: + public: + void execute(Interpreter::Runtime& runtime) override + { + Interpreter::Type_Float level = runtime[0].mFloat; + runtime.pop(); - void execute (Interpreter::Runtime& runtime) override + if (!MWMechanics::getPlayer().isInCell()) { - Interpreter::Type_Float level = runtime[0].mFloat; - runtime.pop(); - - if (!MWMechanics::getPlayer().isInCell()) - { - return; - } + return; + } - MWWorld::CellStore *cell = MWMechanics::getPlayer().getCell(); + MWWorld::CellStore* cell = MWMechanics::getPlayer().getCell(); - if (cell->getCell()->isExterior()) - throw std::runtime_error("Can't set water level in exterior cell"); + if (cell->getCell()->isExterior()) + throw std::runtime_error("Can't set water level in exterior cell"); - cell->setWaterLevel (level); - MWBase::Environment::get().getWorld()->setWaterHeight (cell->getWaterLevel()); - } + cell->setWaterLevel(level); + MWBase::Environment::get().getWorld()->setWaterHeight(cell->getWaterLevel()); + } }; class OpModWaterLevel : public Interpreter::Opcode0 { - public: + public: + void execute(Interpreter::Runtime& runtime) override + { + Interpreter::Type_Float level = runtime[0].mFloat; + runtime.pop(); - void execute (Interpreter::Runtime& runtime) override + if (!MWMechanics::getPlayer().isInCell()) { - Interpreter::Type_Float level = runtime[0].mFloat; - runtime.pop(); - - if (!MWMechanics::getPlayer().isInCell()) - { - return; - } + return; + } - MWWorld::CellStore *cell = MWMechanics::getPlayer().getCell(); + MWWorld::CellStore* cell = MWMechanics::getPlayer().getCell(); - if (cell->getCell()->isExterior()) - throw std::runtime_error("Can't set water level in exterior cell"); + if (cell->getCell()->isExterior()) + throw std::runtime_error("Can't set water level in exterior cell"); - cell->setWaterLevel (cell->getWaterLevel()+level); - MWBase::Environment::get().getWorld()->setWaterHeight(cell->getWaterLevel()); - } + cell->setWaterLevel(cell->getWaterLevel() + level); + MWBase::Environment::get().getWorld()->setWaterHeight(cell->getWaterLevel()); + } }; - - void installOpcodes (Interpreter::Interpreter& interpreter) + void installOpcodes(Interpreter::Interpreter& interpreter) { interpreter.installSegment5(Compiler::Cell::opcodeCellChanged); interpreter.installSegment5(Compiler::Cell::opcodeTestCells); diff --git a/apps/openmw/mwscript/cellextensions.hpp b/apps/openmw/mwscript/cellextensions.hpp index 0891cb9dc8..d3b8bc00b5 100644 --- a/apps/openmw/mwscript/cellextensions.hpp +++ b/apps/openmw/mwscript/cellextensions.hpp @@ -15,11 +15,9 @@ namespace MWScript { /// \brief cell-related script functionality namespace Cell - { - void installOpcodes (Interpreter::Interpreter& interpreter); + { + void installOpcodes(Interpreter::Interpreter& interpreter); } } #endif - - diff --git a/apps/openmw/mwscript/compilercontext.cpp b/apps/openmw/mwscript/compilercontext.cpp index fcad0dd998..d817b93a23 100644 --- a/apps/openmw/mwscript/compilercontext.cpp +++ b/apps/openmw/mwscript/compilercontext.cpp @@ -2,89 +2,77 @@ #include "../mwworld/esmstore.hpp" +#include +#include #include #include -#include -#include #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/scriptmanager.hpp" +#include "../mwbase/world.hpp" -#include "../mwworld/ptr.hpp" #include "../mwworld/class.hpp" #include "../mwworld/manualref.hpp" +#include "../mwworld/ptr.hpp" namespace MWScript { - CompilerContext::CompilerContext (Type type) - : mType (type) - {} + CompilerContext::CompilerContext(Type type) + : mType(type) + { + } bool CompilerContext::canDeclareLocals() const { - return mType==Type_Full; + return mType == Type_Full; } - char CompilerContext::getGlobalType (const std::string& name) const + char CompilerContext::getGlobalType(const std::string& name) const { - return MWBase::Environment::get().getWorld()->getGlobalVariableType (name); + return MWBase::Environment::get().getWorld()->getGlobalVariableType(name); } - std::pair CompilerContext::getMemberType (const std::string& name, - const std::string& id) const + std::pair CompilerContext::getMemberType(const std::string& name, const std::string& id) const { std::string_view script; bool reference = false; - if (const ESM::Script *scriptRecord = - MWBase::Environment::get().getWorld()->getStore().get().search (id)) + if (const ESM::Script* scriptRecord + = MWBase::Environment::get().getWorld()->getStore().get().search(id)) { script = scriptRecord->mId; } else { - MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), id); + MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), id); - script = ref.getPtr().getClass().getScript (ref.getPtr()); + script = ref.getPtr().getClass().getScript(ref.getPtr()); reference = true; } char type = ' '; if (!script.empty()) - type = MWBase::Environment::get().getScriptManager()->getLocals (script).getType ( - Misc::StringUtils::lowerCase (name)); + type = MWBase::Environment::get().getScriptManager()->getLocals(script).getType( + Misc::StringUtils::lowerCase(name)); - return std::make_pair (type, reference); + return std::make_pair(type, reference); } - bool CompilerContext::isId (const std::string& name) const + bool CompilerContext::isId(const std::string& name) const { - const MWWorld::ESMStore &store = - MWBase::Environment::get().getWorld()->getStore(); + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); - return - store.get().search (name) || - store.get().search (name) || - store.get().search (name) || - store.get().search (name) || - store.get().search (name) || - store.get().search (name) || - store.get().search (name) || - store.get().search (name) || - store.get().search (name) || - store.get().search (name) || - store.get().search (name) || - store.get().search (name) || - store.get().search (name) || - store.get().search (name) || - store.get().search (name) || - store.get().search (name) || - store.get().search (name) || - store.get().search (name) || - store.get().search (name) || - store.get().search (name) || - store.get().search (name); + return store.get().search(name) || store.get().search(name) + || store.get().search(name) || store.get().search(name) + || store.get().search(name) || store.get().search(name) + || store.get().search(name) || store.get().search(name) + || store.get().search(name) || store.get().search(name) + || store.get().search(name) || store.get().search(name) + || store.get().search(name) || store.get().search(name) + || store.get().search(name) || store.get().search(name) + || store.get().search(name) || store.get().search(name) + || store.get().search(name) || store.get().search(name) + || store.get().search(name); } } diff --git a/apps/openmw/mwscript/compilercontext.hpp b/apps/openmw/mwscript/compilercontext.hpp index d800781fd8..7b77f74a40 100644 --- a/apps/openmw/mwscript/compilercontext.hpp +++ b/apps/openmw/mwscript/compilercontext.hpp @@ -7,38 +7,34 @@ namespace MWScript { class CompilerContext : public Compiler::Context { - public: - - enum Type - { - Type_Full, // global, local, targeted - Type_Dialogue, - Type_Console - }; - - private: - - Type mType; - - public: - - CompilerContext (Type type); - - /// Is the compiler allowed to declare local variables? - bool canDeclareLocals() const override; - - /// 'l: long, 's': short, 'f': float, ' ': does not exist. - char getGlobalType (const std::string& name) const override; - - std::pair getMemberType (const std::string& name, - const std::string& id) const override; - ///< Return type of member variable \a name in script \a id or in script of reference of - /// \a id - /// \return first: 'l: long, 's': short, 'f': float, ' ': does not exist. - /// second: true: script of reference - - bool isId (const std::string& name) const override; - ///< Does \a name match an ID, that can be referenced? + public: + enum Type + { + Type_Full, // global, local, targeted + Type_Dialogue, + Type_Console + }; + + private: + Type mType; + + public: + CompilerContext(Type type); + + /// Is the compiler allowed to declare local variables? + bool canDeclareLocals() const override; + + /// 'l: long, 's': short, 'f': float, ' ': does not exist. + char getGlobalType(const std::string& name) const override; + + std::pair getMemberType(const std::string& name, const std::string& id) const override; + ///< Return type of member variable \a name in script \a id or in script of reference of + /// \a id + /// \return first: 'l: long, 's': short, 'f': float, ' ': does not exist. + /// second: true: script of reference + + bool isId(const std::string& name) const override; + ///< Does \a name match an ID, that can be referenced? }; } diff --git a/apps/openmw/mwscript/consoleextensions.cpp b/apps/openmw/mwscript/consoleextensions.cpp index 749ec80969..08a13e43ac 100644 --- a/apps/openmw/mwscript/consoleextensions.cpp +++ b/apps/openmw/mwscript/consoleextensions.cpp @@ -6,9 +6,6 @@ namespace MWScript { namespace Console { - void installOpcodes (Interpreter::Interpreter& interpreter) - { - - } + void installOpcodes(Interpreter::Interpreter& interpreter) {} } } diff --git a/apps/openmw/mwscript/consoleextensions.hpp b/apps/openmw/mwscript/consoleextensions.hpp index 5571a54694..828557271a 100644 --- a/apps/openmw/mwscript/consoleextensions.hpp +++ b/apps/openmw/mwscript/consoleextensions.hpp @@ -16,7 +16,7 @@ namespace MWScript /// \brief Script functionality limited to the console namespace Console { - void installOpcodes (Interpreter::Interpreter& interpreter); + void installOpcodes(Interpreter::Interpreter& interpreter); } } diff --git a/apps/openmw/mwscript/containerextensions.cpp b/apps/openmw/mwscript/containerextensions.cpp index 9f93e5853b..c9ef6785b6 100644 --- a/apps/openmw/mwscript/containerextensions.cpp +++ b/apps/openmw/mwscript/containerextensions.cpp @@ -13,8 +13,8 @@ #include -#include #include +#include #include @@ -27,9 +27,9 @@ #include "../mwworld/action.hpp" #include "../mwworld/class.hpp" #include "../mwworld/containerstore.hpp" +#include "../mwworld/esmstore.hpp" #include "../mwworld/inventorystore.hpp" #include "../mwworld/manualref.hpp" -#include "../mwworld/esmstore.hpp" #include "../mwmechanics/actorutil.hpp" #include "../mwmechanics/levelledlist.hpp" @@ -38,35 +38,38 @@ namespace { - void addToStore(const MWWorld::Ptr& itemPtr, int count, MWWorld::Ptr& ptr, MWWorld::ContainerStore& store, bool resolve = true) + void addToStore( + const MWWorld::Ptr& itemPtr, int count, MWWorld::Ptr& ptr, MWWorld::ContainerStore& store, bool resolve = true) { if (itemPtr.getClass().getScript(itemPtr).empty()) { - store.add (itemPtr, count, ptr, true, resolve); + store.add(itemPtr, count, ptr, true, resolve); } else { // Adding just one item per time to make sure there isn't a stack of scripted items for (int i = 0; i < count; i++) - store.add (itemPtr, 1, ptr, true, resolve); + store.add(itemPtr, 1, ptr, true, resolve); } } - void addRandomToStore(const MWWorld::Ptr& itemPtr, int count, MWWorld::Ptr& owner, MWWorld::ContainerStore& store, bool topLevel = true) + void addRandomToStore(const MWWorld::Ptr& itemPtr, int count, MWWorld::Ptr& owner, MWWorld::ContainerStore& store, + bool topLevel = true) { - if(itemPtr.getType() == ESM::ItemLevList::sRecordId) + if (itemPtr.getType() == ESM::ItemLevList::sRecordId) { const ESM::ItemLevList* levItemList = itemPtr.get()->mBase; - if(topLevel && count > 1 && levItemList->mFlags & ESM::ItemLevList::Each) + if (topLevel && count > 1 && levItemList->mFlags & ESM::ItemLevList::Each) { - for(int i = 0; i < count; i++) + for (int i = 0; i < count; i++) addRandomToStore(itemPtr, 1, owner, store, true); } else { auto& prng = MWBase::Environment::get().getWorld()->getPrng(); - std::string_view itemId = MWMechanics::getLevelledItem(itemPtr.get()->mBase, false, prng); + std::string_view itemId + = MWMechanics::getLevelledItem(itemPtr.get()->mBase, false, prng); if (itemId.empty()) return; MWWorld::ManualRef manualRef(MWBase::Environment::get().getWorld()->getStore(), itemId, 1); @@ -82,425 +85,419 @@ namespace MWScript { namespace Container { - template + template class OpAddItem : public Interpreter::Opcode0 { - public: + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + std::string_view item = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - std::string_view item = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + Interpreter::Type_Integer count = runtime[0].mInteger; + runtime.pop(); - Interpreter::Type_Integer count = runtime[0].mInteger; - runtime.pop(); + if (count < 0) + count = static_cast(count); - if (count<0) - count = static_cast(count); + // no-op + if (count == 0) + return; - // no-op - if (count == 0) - return; + if (::Misc::StringUtils::ciEqual(item, "gold_005") || ::Misc::StringUtils::ciEqual(item, "gold_010") + || ::Misc::StringUtils::ciEqual(item, "gold_025") || ::Misc::StringUtils::ciEqual(item, "gold_100")) + item = "gold_001"; - if(::Misc::StringUtils::ciEqual(item, "gold_005") - || ::Misc::StringUtils::ciEqual(item, "gold_010") - || ::Misc::StringUtils::ciEqual(item, "gold_025") - || ::Misc::StringUtils::ciEqual(item, "gold_100")) - item = "gold_001"; - - // Check if "item" can be placed in a container - MWWorld::ManualRef manualRef(MWBase::Environment::get().getWorld()->getStore(), item, 1); - MWWorld::Ptr itemPtr = manualRef.getPtr(); - bool isLevelledList = itemPtr.getClass().getType() == ESM::ItemLevList::sRecordId; - if(!isLevelledList) - MWWorld::ContainerStore::getType(itemPtr); - - // Explicit calls to non-unique actors affect the base record - if(!R::implicit && ptr.getClass().isActor() && MWBase::Environment::get().getWorld()->getStore().getRefCount(ptr.getCellRef().getRefId()) > 1) - { - ptr.getClass().modifyBaseInventory(ptr.getCellRef().getRefId(), item, count); - return; - } + // Check if "item" can be placed in a container + MWWorld::ManualRef manualRef(MWBase::Environment::get().getWorld()->getStore(), item, 1); + MWWorld::Ptr itemPtr = manualRef.getPtr(); + bool isLevelledList = itemPtr.getClass().getType() == ESM::ItemLevList::sRecordId; + if (!isLevelledList) + MWWorld::ContainerStore::getType(itemPtr); + + // Explicit calls to non-unique actors affect the base record + if (!R::implicit && ptr.getClass().isActor() + && MWBase::Environment::get().getWorld()->getStore().getRefCount(ptr.getCellRef().getRefId()) > 1) + { + ptr.getClass().modifyBaseInventory(ptr.getCellRef().getRefId(), item, count); + return; + } - // Calls to unresolved containers affect the base record - if(ptr.getClass().getType() == ESM::Container::sRecordId && (!ptr.getRefData().getCustomData() || - !ptr.getClass().getContainerStore(ptr).isResolved())) + // Calls to unresolved containers affect the base record + if (ptr.getClass().getType() == ESM::Container::sRecordId + && (!ptr.getRefData().getCustomData() || !ptr.getClass().getContainerStore(ptr).isResolved())) + { + ptr.getClass().modifyBaseInventory(ptr.getCellRef().getRefId(), item, count); + const ESM::Container* baseRecord + = MWBase::Environment::get().getWorld()->getStore().get().find( + ptr.getCellRef().getRefId()); + const auto& ptrs = MWBase::Environment::get().getWorld()->getAll(ptr.getCellRef().getRefId()); + for (const auto& container : ptrs) { - ptr.getClass().modifyBaseInventory(ptr.getCellRef().getRefId(), item, count); - const ESM::Container* baseRecord = MWBase::Environment::get().getWorld()->getStore().get().find(ptr.getCellRef().getRefId()); - const auto& ptrs = MWBase::Environment::get().getWorld()->getAll(ptr.getCellRef().getRefId()); - for(const auto& container : ptrs) + // use the new base record + container.get()->mBase = baseRecord; + if (container.getRefData().getCustomData()) { - // use the new base record - container.get()->mBase = baseRecord; - if(container.getRefData().getCustomData()) + auto& store = container.getClass().getContainerStore(container); + if (isLevelledList) { - auto& store = container.getClass().getContainerStore(container); - if(isLevelledList) + if (store.isResolved()) { - if(store.isResolved()) - { - addRandomToStore(itemPtr, count, ptr, store); - } + addRandomToStore(itemPtr, count, ptr, store); } - else - addToStore(itemPtr, count, ptr, store, store.isResolved()); } + else + addToStore(itemPtr, count, ptr, store, store.isResolved()); } - return; } - MWWorld::ContainerStore& store = ptr.getClass().getContainerStore(ptr); - if(isLevelledList) - addRandomToStore(itemPtr, count, ptr, store); + return; + } + MWWorld::ContainerStore& store = ptr.getClass().getContainerStore(ptr); + if (isLevelledList) + addRandomToStore(itemPtr, count, ptr, store); + else + addToStore(itemPtr, count, ptr, store); + + // Spawn a messagebox (only for items added to player's inventory and if player is talking to someone) + if (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr()) + { + // The two GMST entries below expand to strings informing the player of what, and how many of it has + // been added to their inventory + std::string msgBox; + std::string_view itemName = itemPtr.getClass().getName(itemPtr); + if (count == 1) + { + msgBox = MyGUI::LanguageManager::getInstance().replaceTags("#{sNotifyMessage60}"); + msgBox = ::Misc::StringUtils::format(msgBox, itemName); + } else - addToStore(itemPtr, count, ptr, store); - - // Spawn a messagebox (only for items added to player's inventory and if player is talking to someone) - if (ptr == MWBase::Environment::get().getWorld ()->getPlayerPtr() ) { - // The two GMST entries below expand to strings informing the player of what, and how many of it has been added to their inventory - std::string msgBox; - std::string_view itemName = itemPtr.getClass().getName(itemPtr); - if (count == 1) - { - msgBox = MyGUI::LanguageManager::getInstance().replaceTags("#{sNotifyMessage60}"); - msgBox = ::Misc::StringUtils::format(msgBox, itemName); - } - else - { - msgBox = MyGUI::LanguageManager::getInstance().replaceTags("#{sNotifyMessage61}"); - msgBox = ::Misc::StringUtils::format(msgBox, count, itemName); - } - MWBase::Environment::get().getWindowManager()->messageBox(msgBox, MWGui::ShowInDialogueMode_Only); + msgBox = MyGUI::LanguageManager::getInstance().replaceTags("#{sNotifyMessage61}"); + msgBox = ::Misc::StringUtils::format(msgBox, count, itemName); } + MWBase::Environment::get().getWindowManager()->messageBox(msgBox, MWGui::ShowInDialogueMode_Only); } + } }; - template + template class OpGetItemCount : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - std::string_view item = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + std::string_view item = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - if(::Misc::StringUtils::ciEqual(item, "gold_005") - || ::Misc::StringUtils::ciEqual(item, "gold_010") - || ::Misc::StringUtils::ciEqual(item, "gold_025") - || ::Misc::StringUtils::ciEqual(item, "gold_100")) - item = "gold_001"; + if (::Misc::StringUtils::ciEqual(item, "gold_005") || ::Misc::StringUtils::ciEqual(item, "gold_010") + || ::Misc::StringUtils::ciEqual(item, "gold_025") || ::Misc::StringUtils::ciEqual(item, "gold_100")) + item = "gold_001"; - MWWorld::ContainerStore& store = ptr.getClass().getContainerStore (ptr); + MWWorld::ContainerStore& store = ptr.getClass().getContainerStore(ptr); - runtime.push (store.count(item)); - } + runtime.push(store.count(item)); + } }; - template + template class OpRemoveItem : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - std::string_view item = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + std::string_view item = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - Interpreter::Type_Integer count = runtime[0].mInteger; - runtime.pop(); + Interpreter::Type_Integer count = runtime[0].mInteger; + runtime.pop(); - if (count<0) - count = static_cast(count); + if (count < 0) + count = static_cast(count); - // no-op - if (count == 0) - return; + // no-op + if (count == 0) + return; - if(::Misc::StringUtils::ciEqual(item, "gold_005") - || ::Misc::StringUtils::ciEqual(item, "gold_010") - || ::Misc::StringUtils::ciEqual(item, "gold_025") - || ::Misc::StringUtils::ciEqual(item, "gold_100")) - item = "gold_001"; + if (::Misc::StringUtils::ciEqual(item, "gold_005") || ::Misc::StringUtils::ciEqual(item, "gold_010") + || ::Misc::StringUtils::ciEqual(item, "gold_025") || ::Misc::StringUtils::ciEqual(item, "gold_100")) + item = "gold_001"; - // Explicit calls to non-unique actors affect the base record - if(!R::implicit && ptr.getClass().isActor() && MWBase::Environment::get().getWorld()->getStore().getRefCount(ptr.getCellRef().getRefId()) > 1) - { - ptr.getClass().modifyBaseInventory(ptr.getCellRef().getRefId(), item, -count); - return; - } - // Calls to unresolved containers affect the base record instead - else if(ptr.getClass().getType() == ESM::Container::sRecordId && - (!ptr.getRefData().getCustomData() || !ptr.getClass().getContainerStore(ptr).isResolved())) + // Explicit calls to non-unique actors affect the base record + if (!R::implicit && ptr.getClass().isActor() + && MWBase::Environment::get().getWorld()->getStore().getRefCount(ptr.getCellRef().getRefId()) > 1) + { + ptr.getClass().modifyBaseInventory(ptr.getCellRef().getRefId(), item, -count); + return; + } + // Calls to unresolved containers affect the base record instead + else if (ptr.getClass().getType() == ESM::Container::sRecordId + && (!ptr.getRefData().getCustomData() || !ptr.getClass().getContainerStore(ptr).isResolved())) + { + ptr.getClass().modifyBaseInventory(ptr.getCellRef().getRefId(), item, -count); + const ESM::Container* baseRecord + = MWBase::Environment::get().getWorld()->getStore().get().find( + ptr.getCellRef().getRefId()); + const auto& ptrs = MWBase::Environment::get().getWorld()->getAll(ptr.getCellRef().getRefId()); + for (const auto& container : ptrs) { - ptr.getClass().modifyBaseInventory(ptr.getCellRef().getRefId(), item, -count); - const ESM::Container* baseRecord = MWBase::Environment::get().getWorld()->getStore().get().find(ptr.getCellRef().getRefId()); - const auto& ptrs = MWBase::Environment::get().getWorld()->getAll(ptr.getCellRef().getRefId()); - for(const auto& container : ptrs) + container.get()->mBase = baseRecord; + if (container.getRefData().getCustomData()) { - container.get()->mBase = baseRecord; - if(container.getRefData().getCustomData()) - { - auto& store = container.getClass().getContainerStore(container); - // Note that unlike AddItem, RemoveItem only removes from unresolved containers - if(!store.isResolved()) - store.remove(item, count, ptr, false, false); - } + auto& store = container.getClass().getContainerStore(container); + // Note that unlike AddItem, RemoveItem only removes from unresolved containers + if (!store.isResolved()) + store.remove(item, count, ptr, false, false); } - return; } - MWWorld::ContainerStore& store = ptr.getClass().getContainerStore (ptr); + return; + } + MWWorld::ContainerStore& store = ptr.getClass().getContainerStore(ptr); - std::string_view itemName; - for (MWWorld::ConstContainerStoreIterator iter(store.cbegin()); iter != store.cend(); ++iter) + std::string_view itemName; + for (MWWorld::ConstContainerStoreIterator iter(store.cbegin()); iter != store.cend(); ++iter) + { + if (::Misc::StringUtils::ciEqual(iter->getCellRef().getRefId(), item)) { - if (::Misc::StringUtils::ciEqual(iter->getCellRef().getRefId(), item)) - { - itemName = iter->getClass().getName(*iter); - break; - } + itemName = iter->getClass().getName(*iter); + break; } + } - int numRemoved = store.remove(item, count, ptr); + int numRemoved = store.remove(item, count, ptr); - // Spawn a messagebox (only for items removed from player's inventory) - if ((numRemoved > 0) - && (ptr == MWMechanics::getPlayer())) - { - // The two GMST entries below expand to strings informing the player of what, and how many of it has been removed from their inventory - std::string msgBox; + // Spawn a messagebox (only for items removed from player's inventory) + if ((numRemoved > 0) && (ptr == MWMechanics::getPlayer())) + { + // The two GMST entries below expand to strings informing the player of what, and how many of it has + // been removed from their inventory + std::string msgBox; - if (numRemoved > 1) - { - msgBox = MyGUI::LanguageManager::getInstance().replaceTags("#{sNotifyMessage63}"); - msgBox = ::Misc::StringUtils::format(msgBox, numRemoved, itemName); - } - else - { - msgBox = MyGUI::LanguageManager::getInstance().replaceTags("#{sNotifyMessage62}"); - msgBox = ::Misc::StringUtils::format(msgBox, itemName); - } - MWBase::Environment::get().getWindowManager()->messageBox(msgBox, MWGui::ShowInDialogueMode_Only); + if (numRemoved > 1) + { + msgBox = MyGUI::LanguageManager::getInstance().replaceTags("#{sNotifyMessage63}"); + msgBox = ::Misc::StringUtils::format(msgBox, numRemoved, itemName); + } + else + { + msgBox = MyGUI::LanguageManager::getInstance().replaceTags("#{sNotifyMessage62}"); + msgBox = ::Misc::StringUtils::format(msgBox, itemName); } + MWBase::Environment::get().getWindowManager()->messageBox(msgBox, MWGui::ShowInDialogueMode_Only); } + } }; template class OpEquip : public Interpreter::Opcode0 { - public: - - void execute(Interpreter::Runtime &runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - std::string_view item = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + std::string_view item = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - MWWorld::InventoryStore& invStore = ptr.getClass().getInventoryStore (ptr); - auto found = invStore.end(); - const auto& store = MWBase::Environment::get().getWorld()->getStore(); + MWWorld::InventoryStore& invStore = ptr.getClass().getInventoryStore(ptr); + auto found = invStore.end(); + const auto& store = MWBase::Environment::get().getWorld()->getStore(); - // With soul gems we prefer filled ones. - for (auto it = invStore.begin(); it != invStore.end(); ++it) + // With soul gems we prefer filled ones. + for (auto it = invStore.begin(); it != invStore.end(); ++it) + { + if (Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), item)) { - if (Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), item)) - { - found = it; - const std::string& soul = it->getCellRef().getSoul(); - if (!it->getClass().isSoulGem(*it) || (!soul.empty() && store.get().search(soul))) - break; - } + found = it; + const std::string& soul = it->getCellRef().getSoul(); + if (!it->getClass().isSoulGem(*it) + || (!soul.empty() && store.get().search(soul))) + break; } + } - if (found == invStore.end()) - { - MWWorld::ManualRef ref(store, item, 1); - found = ptr.getClass().getContainerStore(ptr).add(ref.getPtr(), 1, ptr, false); - Log(Debug::Warning) << "Implicitly adding one " << item << - " to the inventory store of " << ptr.getCellRef().getRefId() << - " to fulfill the requirements of Equip instruction"; - } + if (found == invStore.end()) + { + MWWorld::ManualRef ref(store, item, 1); + found = ptr.getClass().getContainerStore(ptr).add(ref.getPtr(), 1, ptr, false); + Log(Debug::Warning) << "Implicitly adding one " << item << " to the inventory store of " + << ptr.getCellRef().getRefId() + << " to fulfill the requirements of Equip instruction"; + } - if (ptr == MWMechanics::getPlayer()) - MWBase::Environment::get().getWindowManager()->useItem(*found, true); - else - { - std::unique_ptr action = found->getClass().use(*found, true); - action->execute(ptr, true); - } + if (ptr == MWMechanics::getPlayer()) + MWBase::Environment::get().getWindowManager()->useItem(*found, true); + else + { + std::unique_ptr action = found->getClass().use(*found, true); + action->execute(ptr, true); } + } }; template class OpGetArmorType : public Interpreter::Opcode0 { - public: + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - void execute(Interpreter::Runtime &runtime) override + Interpreter::Type_Integer location = runtime[0].mInteger; + runtime.pop(); + + int slot; + switch (location) { - MWWorld::Ptr ptr = R()(runtime); + case 0: + slot = MWWorld::InventoryStore::Slot_Helmet; + break; + case 1: + slot = MWWorld::InventoryStore::Slot_Cuirass; + break; + case 2: + slot = MWWorld::InventoryStore::Slot_LeftPauldron; + break; + case 3: + slot = MWWorld::InventoryStore::Slot_RightPauldron; + break; + case 4: + slot = MWWorld::InventoryStore::Slot_Greaves; + break; + case 5: + slot = MWWorld::InventoryStore::Slot_Boots; + break; + case 6: + slot = MWWorld::InventoryStore::Slot_LeftGauntlet; + break; + case 7: + slot = MWWorld::InventoryStore::Slot_RightGauntlet; + break; + case 8: + slot = MWWorld::InventoryStore::Slot_CarriedLeft; // shield + break; + case 9: + slot = MWWorld::InventoryStore::Slot_LeftGauntlet; + break; + case 10: + slot = MWWorld::InventoryStore::Slot_RightGauntlet; + break; + default: + throw std::runtime_error("armor index out of range"); + } - Interpreter::Type_Integer location = runtime[0].mInteger; - runtime.pop(); + const MWWorld::InventoryStore& invStore = ptr.getClass().getInventoryStore(ptr); + MWWorld::ConstContainerStoreIterator it = invStore.getSlot(slot); - int slot; - switch (location) - { - case 0: - slot = MWWorld::InventoryStore::Slot_Helmet; - break; - case 1: - slot = MWWorld::InventoryStore::Slot_Cuirass; - break; - case 2: - slot = MWWorld::InventoryStore::Slot_LeftPauldron; - break; - case 3: - slot = MWWorld::InventoryStore::Slot_RightPauldron; - break; - case 4: - slot = MWWorld::InventoryStore::Slot_Greaves; - break; - case 5: - slot = MWWorld::InventoryStore::Slot_Boots; - break; - case 6: - slot = MWWorld::InventoryStore::Slot_LeftGauntlet; - break; - case 7: - slot = MWWorld::InventoryStore::Slot_RightGauntlet; - break; - case 8: - slot = MWWorld::InventoryStore::Slot_CarriedLeft; // shield - break; - case 9: - slot = MWWorld::InventoryStore::Slot_LeftGauntlet; - break; - case 10: - slot = MWWorld::InventoryStore::Slot_RightGauntlet; - break; - default: - throw std::runtime_error ("armor index out of range"); - } - - const MWWorld::InventoryStore& invStore = ptr.getClass().getInventoryStore (ptr); - MWWorld::ConstContainerStoreIterator it = invStore.getSlot (slot); - - if (it == invStore.end() || it->getType () != ESM::Armor::sRecordId) - { - runtime.push(-1); - return; - } + if (it == invStore.end() || it->getType() != ESM::Armor::sRecordId) + { + runtime.push(-1); + return; + } - int skill = it->getClass().getEquipmentSkill (*it) ; - if (skill == ESM::Skill::HeavyArmor) - runtime.push(2); - else if (skill == ESM::Skill::MediumArmor) - runtime.push(1); - else if (skill == ESM::Skill::LightArmor) - runtime.push(0); - else - runtime.push(-1); + int skill = it->getClass().getEquipmentSkill(*it); + if (skill == ESM::Skill::HeavyArmor) + runtime.push(2); + else if (skill == ESM::Skill::MediumArmor) + runtime.push(1); + else if (skill == ESM::Skill::LightArmor) + runtime.push(0); + else + runtime.push(-1); } }; template class OpHasItemEquipped : public Interpreter::Opcode0 { - public: - - void execute(Interpreter::Runtime &runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - std::string_view item = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + std::string_view item = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - const MWWorld::InventoryStore& invStore = ptr.getClass().getInventoryStore (ptr); - for (int slot = 0; slot < MWWorld::InventoryStore::Slots; ++slot) + const MWWorld::InventoryStore& invStore = ptr.getClass().getInventoryStore(ptr); + for (int slot = 0; slot < MWWorld::InventoryStore::Slots; ++slot) + { + MWWorld::ConstContainerStoreIterator it = invStore.getSlot(slot); + if (it != invStore.end() && ::Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), item)) { - MWWorld::ConstContainerStoreIterator it = invStore.getSlot (slot); - if (it != invStore.end() && ::Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), item)) - { - runtime.push(1); - return; - } + runtime.push(1); + return; } - runtime.push(0); } + runtime.push(0); + } }; template class OpHasSoulGem : public Interpreter::Opcode0 { - public: - - void execute(Interpreter::Runtime &runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - std::string_view name = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + std::string_view name = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - int count = 0; - const MWWorld::InventoryStore& invStore = ptr.getClass().getInventoryStore (ptr); - for (MWWorld::ConstContainerStoreIterator it = invStore.cbegin(MWWorld::ContainerStore::Type_Miscellaneous); - it != invStore.cend(); ++it) - { - if (::Misc::StringUtils::ciEqual(it->getCellRef().getSoul(), name)) - count += it->getRefData().getCount(); - } - runtime.push(count); + int count = 0; + const MWWorld::InventoryStore& invStore = ptr.getClass().getInventoryStore(ptr); + for (MWWorld::ConstContainerStoreIterator it + = invStore.cbegin(MWWorld::ContainerStore::Type_Miscellaneous); + it != invStore.cend(); ++it) + { + if (::Misc::StringUtils::ciEqual(it->getCellRef().getSoul(), name)) + count += it->getRefData().getCount(); } + runtime.push(count); + } }; template class OpGetWeaponType : public Interpreter::Opcode0 { - public: + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - void execute(Interpreter::Runtime &runtime) override + const MWWorld::InventoryStore& invStore = ptr.getClass().getInventoryStore(ptr); + MWWorld::ConstContainerStoreIterator it = invStore.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); + if (it == invStore.end()) { - MWWorld::Ptr ptr = R()(runtime); - - const MWWorld::InventoryStore& invStore = ptr.getClass().getInventoryStore (ptr); - MWWorld::ConstContainerStoreIterator it = invStore.getSlot (MWWorld::InventoryStore::Slot_CarriedRight); - if (it == invStore.end()) + runtime.push(-1); + return; + } + else if (it->getType() != ESM::Weapon::sRecordId) + { + if (it->getType() == ESM::Lockpick::sRecordId) { - runtime.push(-1); - return; + runtime.push(-2); } - else if (it->getType() != ESM::Weapon::sRecordId) + else if (it->getType() == ESM::Probe::sRecordId) { - if (it->getType() == ESM::Lockpick::sRecordId) - { - runtime.push(-2); - } - else if (it->getType() == ESM::Probe::sRecordId) - { - runtime.push(-3); - } - else - { - runtime.push(-1); - } - return; + runtime.push(-3); } - - runtime.push(it->get()->mBase->mData.mType); + else + { + runtime.push(-1); + } + return; } - }; + runtime.push(it->get()->mBase->mData.mType); + } + }; - void installOpcodes (Interpreter::Interpreter& interpreter) + void installOpcodes(Interpreter::Interpreter& interpreter) { interpreter.installSegment5>(Compiler::Container::opcodeAddItem); interpreter.installSegment5>(Compiler::Container::opcodeAddItemExplicit); @@ -513,7 +510,8 @@ namespace MWScript interpreter.installSegment5>(Compiler::Container::opcodeGetArmorType); interpreter.installSegment5>(Compiler::Container::opcodeGetArmorTypeExplicit); interpreter.installSegment5>(Compiler::Container::opcodeHasItemEquipped); - interpreter.installSegment5>(Compiler::Container::opcodeHasItemEquippedExplicit); + interpreter.installSegment5>( + Compiler::Container::opcodeHasItemEquippedExplicit); interpreter.installSegment5>(Compiler::Container::opcodeHasSoulGem); interpreter.installSegment5>(Compiler::Container::opcodeHasSoulGemExplicit); interpreter.installSegment5>(Compiler::Container::opcodeGetWeaponType); diff --git a/apps/openmw/mwscript/containerextensions.hpp b/apps/openmw/mwscript/containerextensions.hpp index d5be8fb2a6..c6b2434f33 100644 --- a/apps/openmw/mwscript/containerextensions.hpp +++ b/apps/openmw/mwscript/containerextensions.hpp @@ -16,7 +16,7 @@ namespace MWScript /// \brief Container-related script functionality (chests, NPCs, creatures) namespace Container { - void installOpcodes (Interpreter::Interpreter& interpreter); + void installOpcodes(Interpreter::Interpreter& interpreter); } } diff --git a/apps/openmw/mwscript/controlextensions.cpp b/apps/openmw/mwscript/controlextensions.cpp index d216474c6d..a69f2cd571 100644 --- a/apps/openmw/mwscript/controlextensions.cpp +++ b/apps/openmw/mwscript/controlextensions.cpp @@ -3,8 +3,8 @@ #include #include -#include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/inputmanager.hpp" @@ -25,205 +25,219 @@ namespace MWScript { class OpSetControl : public Interpreter::Opcode0 { - std::string mControl; - bool mEnable; - - public: + std::string mControl; + bool mEnable; - OpSetControl (const std::string& control, bool enable) - : mControl (control), mEnable (enable) - {} + public: + OpSetControl(const std::string& control, bool enable) + : mControl(control) + , mEnable(enable) + { + } - void execute (Interpreter::Runtime& runtime) override - { - MWBase::Environment::get() - .getInputManager() - ->toggleControlSwitch(mControl, mEnable); - } + void execute(Interpreter::Runtime& runtime) override + { + MWBase::Environment::get().getInputManager()->toggleControlSwitch(mControl, mEnable); + } }; class OpGetDisabled : public Interpreter::Opcode0 { - std::string mControl; - - public: + std::string mControl; - OpGetDisabled (const std::string& control) - : mControl (control) - {} + public: + OpGetDisabled(const std::string& control) + : mControl(control) + { + } - void execute (Interpreter::Runtime& runtime) override - { - runtime.push(!MWBase::Environment::get().getInputManager()->getControlSwitch (mControl)); - } + void execute(Interpreter::Runtime& runtime) override + { + runtime.push(!MWBase::Environment::get().getInputManager()->getControlSwitch(mControl)); + } }; class OpToggleCollision : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - bool enabled = MWBase::Environment::get().getWorld()->toggleCollisionMode(); + public: + void execute(Interpreter::Runtime& runtime) override + { + bool enabled = MWBase::Environment::get().getWorld()->toggleCollisionMode(); - runtime.getContext().report (enabled ? "Collision -> On" : "Collision -> Off"); - } + runtime.getContext().report(enabled ? "Collision -> On" : "Collision -> Off"); + } }; - template + template class OpClearMovementFlag : public Interpreter::Opcode0 { - MWMechanics::CreatureStats::Flag mFlag; - - public: + MWMechanics::CreatureStats::Flag mFlag; - OpClearMovementFlag (MWMechanics::CreatureStats::Flag flag) : mFlag (flag) {} + public: + OpClearMovementFlag(MWMechanics::CreatureStats::Flag flag) + : mFlag(flag) + { + } - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - ptr.getClass().getCreatureStats(ptr).setMovementFlag (mFlag, false); - } + ptr.getClass().getCreatureStats(ptr).setMovementFlag(mFlag, false); + } }; - template + template class OpSetMovementFlag : public Interpreter::Opcode0 { - MWMechanics::CreatureStats::Flag mFlag; - - public: + MWMechanics::CreatureStats::Flag mFlag; - OpSetMovementFlag (MWMechanics::CreatureStats::Flag flag) : mFlag (flag) {} + public: + OpSetMovementFlag(MWMechanics::CreatureStats::Flag flag) + : mFlag(flag) + { + } - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - ptr.getClass().getCreatureStats(ptr).setMovementFlag (mFlag, true); - } + ptr.getClass().getCreatureStats(ptr).setMovementFlag(mFlag, true); + } }; template class OpGetForceRun : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats (ptr); - runtime.push (stats.getMovementFlag (MWMechanics::CreatureStats::Flag_ForceRun)); - } + MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); + runtime.push(stats.getMovementFlag(MWMechanics::CreatureStats::Flag_ForceRun)); + } }; template class OpGetForceJump : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats (ptr); - runtime.push (stats.getMovementFlag (MWMechanics::CreatureStats::Flag_ForceJump)); - } + MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); + runtime.push(stats.getMovementFlag(MWMechanics::CreatureStats::Flag_ForceJump)); + } }; template class OpGetForceMoveJump : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats (ptr); - runtime.push (stats.getMovementFlag (MWMechanics::CreatureStats::Flag_ForceMoveJump)); - } + MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); + runtime.push(stats.getMovementFlag(MWMechanics::CreatureStats::Flag_ForceMoveJump)); + } }; template class OpGetForceSneak : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); - runtime.push (stats.getMovementFlag (MWMechanics::CreatureStats::Flag_ForceSneak)); - } + MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); + runtime.push(stats.getMovementFlag(MWMechanics::CreatureStats::Flag_ForceSneak)); + } }; class OpGetPcRunning : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->getPlayerPtr(); - MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); - MWBase::World* world = MWBase::Environment::get().getWorld(); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->getPlayerPtr(); + MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); + MWBase::World* world = MWBase::Environment::get().getWorld(); - bool stanceOn = stats.getStance(MWMechanics::CreatureStats::Stance_Run); - bool running = MWBase::Environment::get().getMechanicsManager()->isRunning(ptr); - bool inair = !world->isOnGround(ptr) && !world->isSwimming(ptr) && !world->isFlying(ptr); + bool stanceOn = stats.getStance(MWMechanics::CreatureStats::Stance_Run); + bool running = MWBase::Environment::get().getMechanicsManager()->isRunning(ptr); + bool inair = !world->isOnGround(ptr) && !world->isSwimming(ptr) && !world->isFlying(ptr); - runtime.push(stanceOn && (running || inair)); - } + runtime.push(stanceOn && (running || inair)); + } }; class OpGetPcSneaking : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->getPlayerPtr(); - runtime.push(MWBase::Environment::get().getMechanicsManager()->isSneaking(ptr)); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->getPlayerPtr(); + runtime.push(MWBase::Environment::get().getMechanicsManager()->isSneaking(ptr)); + } }; - void installOpcodes(Interpreter::Interpreter& interpreter) { for (int i = 0; i < Compiler::Control::numberOfControls; ++i) { - interpreter.installSegment5(Compiler::Control::opcodeEnable + i, Compiler::Control::controls[i], true); - interpreter.installSegment5(Compiler::Control::opcodeDisable + i, Compiler::Control::controls[i], false); - interpreter.installSegment5(Compiler::Control::opcodeGetDisabled + i, Compiler::Control::controls[i]); + interpreter.installSegment5( + Compiler::Control::opcodeEnable + i, Compiler::Control::controls[i], true); + interpreter.installSegment5( + Compiler::Control::opcodeDisable + i, Compiler::Control::controls[i], false); + interpreter.installSegment5( + Compiler::Control::opcodeGetDisabled + i, Compiler::Control::controls[i]); } interpreter.installSegment5(Compiler::Control::opcodeToggleCollision); - //Force Run - interpreter.installSegment5>(Compiler::Control::opcodeClearForceRun, MWMechanics::CreatureStats::Flag_ForceRun); - interpreter.installSegment5>(Compiler::Control::opcodeClearForceRunExplicit, MWMechanics::CreatureStats::Flag_ForceRun); - interpreter.installSegment5>(Compiler::Control::opcodeForceRun, MWMechanics::CreatureStats::Flag_ForceRun); - interpreter.installSegment5>(Compiler::Control::opcodeForceRunExplicit, MWMechanics::CreatureStats::Flag_ForceRun); - - //Force Jump - interpreter.installSegment5>(Compiler::Control::opcodeClearForceJump, MWMechanics::CreatureStats::Flag_ForceJump); - interpreter.installSegment5>(Compiler::Control::opcodeClearForceJumpExplicit, MWMechanics::CreatureStats::Flag_ForceJump); - interpreter.installSegment5>(Compiler::Control::opcodeForceJump, MWMechanics::CreatureStats::Flag_ForceJump); - interpreter.installSegment5>(Compiler::Control::opcodeForceJumpExplicit, MWMechanics::CreatureStats::Flag_ForceJump); - - //Force MoveJump - interpreter.installSegment5>(Compiler::Control::opcodeClearForceMoveJump, MWMechanics::CreatureStats::Flag_ForceMoveJump); - interpreter.installSegment5>(Compiler::Control::opcodeClearForceMoveJumpExplicit, MWMechanics::CreatureStats::Flag_ForceMoveJump); - interpreter.installSegment5>(Compiler::Control::opcodeForceMoveJump, MWMechanics::CreatureStats::Flag_ForceMoveJump); - interpreter.installSegment5>(Compiler::Control::opcodeForceMoveJumpExplicit, MWMechanics::CreatureStats::Flag_ForceMoveJump); - - //Force Sneak - interpreter.installSegment5>(Compiler::Control::opcodeClearForceSneak, MWMechanics::CreatureStats::Flag_ForceSneak); - interpreter.installSegment5>(Compiler::Control::opcodeClearForceSneakExplicit, MWMechanics::CreatureStats::Flag_ForceSneak); - interpreter.installSegment5>(Compiler::Control::opcodeForceSneak, MWMechanics::CreatureStats::Flag_ForceSneak); - interpreter.installSegment5>(Compiler::Control::opcodeForceSneakExplicit, MWMechanics::CreatureStats::Flag_ForceSneak); + // Force Run + interpreter.installSegment5>( + Compiler::Control::opcodeClearForceRun, MWMechanics::CreatureStats::Flag_ForceRun); + interpreter.installSegment5>( + Compiler::Control::opcodeClearForceRunExplicit, MWMechanics::CreatureStats::Flag_ForceRun); + interpreter.installSegment5>( + Compiler::Control::opcodeForceRun, MWMechanics::CreatureStats::Flag_ForceRun); + interpreter.installSegment5>( + Compiler::Control::opcodeForceRunExplicit, MWMechanics::CreatureStats::Flag_ForceRun); + + // Force Jump + interpreter.installSegment5>( + Compiler::Control::opcodeClearForceJump, MWMechanics::CreatureStats::Flag_ForceJump); + interpreter.installSegment5>( + Compiler::Control::opcodeClearForceJumpExplicit, MWMechanics::CreatureStats::Flag_ForceJump); + interpreter.installSegment5>( + Compiler::Control::opcodeForceJump, MWMechanics::CreatureStats::Flag_ForceJump); + interpreter.installSegment5>( + Compiler::Control::opcodeForceJumpExplicit, MWMechanics::CreatureStats::Flag_ForceJump); + + // Force MoveJump + interpreter.installSegment5>( + Compiler::Control::opcodeClearForceMoveJump, MWMechanics::CreatureStats::Flag_ForceMoveJump); + interpreter.installSegment5>( + Compiler::Control::opcodeClearForceMoveJumpExplicit, MWMechanics::CreatureStats::Flag_ForceMoveJump); + interpreter.installSegment5>( + Compiler::Control::opcodeForceMoveJump, MWMechanics::CreatureStats::Flag_ForceMoveJump); + interpreter.installSegment5>( + Compiler::Control::opcodeForceMoveJumpExplicit, MWMechanics::CreatureStats::Flag_ForceMoveJump); + + // Force Sneak + interpreter.installSegment5>( + Compiler::Control::opcodeClearForceSneak, MWMechanics::CreatureStats::Flag_ForceSneak); + interpreter.installSegment5>( + Compiler::Control::opcodeClearForceSneakExplicit, MWMechanics::CreatureStats::Flag_ForceSneak); + interpreter.installSegment5>( + Compiler::Control::opcodeForceSneak, MWMechanics::CreatureStats::Flag_ForceSneak); + interpreter.installSegment5>( + Compiler::Control::opcodeForceSneakExplicit, MWMechanics::CreatureStats::Flag_ForceSneak); interpreter.installSegment5(Compiler::Control::opcodeGetPcRunning); interpreter.installSegment5(Compiler::Control::opcodeGetPcSneaking); @@ -232,7 +246,8 @@ namespace MWScript interpreter.installSegment5>(Compiler::Control::opcodeGetForceJump); interpreter.installSegment5>(Compiler::Control::opcodeGetForceJumpExplicit); interpreter.installSegment5>(Compiler::Control::opcodeGetForceMoveJump); - interpreter.installSegment5>(Compiler::Control::opcodeGetForceMoveJumpExplicit); + interpreter.installSegment5>( + Compiler::Control::opcodeGetForceMoveJumpExplicit); interpreter.installSegment5>(Compiler::Control::opcodeGetForceSneak); interpreter.installSegment5>(Compiler::Control::opcodeGetForceSneakExplicit); } diff --git a/apps/openmw/mwscript/controlextensions.hpp b/apps/openmw/mwscript/controlextensions.hpp index b9c6654fea..57051cf750 100644 --- a/apps/openmw/mwscript/controlextensions.hpp +++ b/apps/openmw/mwscript/controlextensions.hpp @@ -16,7 +16,7 @@ namespace MWScript /// \brief player controls-related script functionality namespace Control { - void installOpcodes (Interpreter::Interpreter& interpreter); + void installOpcodes(Interpreter::Interpreter& interpreter); } } diff --git a/apps/openmw/mwscript/dialogueextensions.cpp b/apps/openmw/mwscript/dialogueextensions.cpp index f06ee022e2..415a8f6d8b 100644 --- a/apps/openmw/mwscript/dialogueextensions.cpp +++ b/apps/openmw/mwscript/dialogueextensions.cpp @@ -4,17 +4,17 @@ #include #include #include -#include #include +#include -#include "../mwbase/environment.hpp" #include "../mwbase/dialoguemanager.hpp" +#include "../mwbase/environment.hpp" #include "../mwbase/journal.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" -#include "../mwworld/class.hpp" #include "../mwmechanics/npcstats.hpp" +#include "../mwworld/class.hpp" #include "interpretercontext.hpp" #include "ref.hpp" @@ -26,199 +26,186 @@ namespace MWScript template class OpJournal : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime, false); // required=false - if (ptr.isEmpty()) - ptr = MWBase::Environment::get().getWorld()->getPlayerPtr(); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime, false); // required=false + if (ptr.isEmpty()) + ptr = MWBase::Environment::get().getWorld()->getPlayerPtr(); - std::string quest{runtime.getStringLiteral(runtime[0].mInteger)}; - runtime.pop(); + std::string quest{ runtime.getStringLiteral(runtime[0].mInteger) }; + runtime.pop(); - Interpreter::Type_Integer index = runtime[0].mInteger; - runtime.pop(); + Interpreter::Type_Integer index = runtime[0].mInteger; + runtime.pop(); - // Invoking Journal with a non-existing index is allowed, and triggers no errors. Seriously? :( - try - { - MWBase::Environment::get().getJournal()->addEntry (quest, index, ptr); - } - catch (...) - { - if (MWBase::Environment::get().getJournal()->getJournalIndex(quest) < index) - MWBase::Environment::get().getJournal()->setJournalIndex(quest, index); - } + // Invoking Journal with a non-existing index is allowed, and triggers no errors. Seriously? :( + try + { + MWBase::Environment::get().getJournal()->addEntry(quest, index, ptr); + } + catch (...) + { + if (MWBase::Environment::get().getJournal()->getJournalIndex(quest) < index) + MWBase::Environment::get().getJournal()->setJournalIndex(quest, index); } + } }; class OpSetJournalIndex : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - std::string quest{runtime.getStringLiteral(runtime[0].mInteger)}; - runtime.pop(); + public: + void execute(Interpreter::Runtime& runtime) override + { + std::string quest{ runtime.getStringLiteral(runtime[0].mInteger) }; + runtime.pop(); - Interpreter::Type_Integer index = runtime[0].mInteger; - runtime.pop(); + Interpreter::Type_Integer index = runtime[0].mInteger; + runtime.pop(); - MWBase::Environment::get().getJournal()->setJournalIndex (quest, index); - } + MWBase::Environment::get().getJournal()->setJournalIndex(quest, index); + } }; class OpGetJournalIndex : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - std::string quest{runtime.getStringLiteral(runtime[0].mInteger)}; - runtime.pop(); - - int index = MWBase::Environment::get().getJournal()->getJournalIndex (quest); + public: + void execute(Interpreter::Runtime& runtime) override + { + std::string quest{ runtime.getStringLiteral(runtime[0].mInteger) }; + runtime.pop(); - runtime.push (index); + int index = MWBase::Environment::get().getJournal()->getJournalIndex(quest); - } + runtime.push(index); + } }; class OpAddTopic : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - std::string_view topic = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + public: + void execute(Interpreter::Runtime& runtime) override + { + std::string_view topic = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - MWBase::Environment::get().getDialogueManager()->addTopic(topic); - } + MWBase::Environment::get().getDialogueManager()->addTopic(topic); + } }; class OpChoice : public Interpreter::Opcode1 { - public: - - void execute (Interpreter::Runtime& runtime, unsigned int arg0) override + public: + void execute(Interpreter::Runtime& runtime, unsigned int arg0) override + { + MWBase::DialogueManager* dialogue = MWBase::Environment::get().getDialogueManager(); + while (arg0 > 0) { - MWBase::DialogueManager* dialogue = MWBase::Environment::get().getDialogueManager(); - while(arg0>0) + std::string_view question = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); + arg0 = arg0 - 1; + Interpreter::Type_Integer choice = 1; + if (arg0 > 0) { - std::string_view question = runtime.getStringLiteral(runtime[0].mInteger); + choice = runtime[0].mInteger; runtime.pop(); - arg0 = arg0 -1; - Interpreter::Type_Integer choice = 1; - if(arg0>0) - { - choice = runtime[0].mInteger; - runtime.pop(); - arg0 = arg0 -1; - } - dialogue->addChoice(question,choice); + arg0 = arg0 - 1; } + dialogue->addChoice(question, choice); } + } }; - template + template class OpForceGreeting : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); - - if (!ptr.getRefData().isEnabled()) - return; + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - if (!ptr.getClass().isActor()) - { - const std::string error = "Warning: \"forcegreeting\" command works only for actors."; - runtime.getContext().report(error); - Log(Debug::Warning) << error; - return; - } + if (!ptr.getRefData().isEnabled()) + return; - MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Dialogue, ptr); + if (!ptr.getClass().isActor()) + { + const std::string error = "Warning: \"forcegreeting\" command works only for actors."; + runtime.getContext().report(error); + Log(Debug::Warning) << error; + return; } + + MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Dialogue, ptr); + } }; class OpGoodbye : public Interpreter::Opcode0 { - public: - - void execute(Interpreter::Runtime& runtime) override - { - MWBase::Environment::get().getDialogueManager()->goodbye(); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + MWBase::Environment::get().getDialogueManager()->goodbye(); + } }; - template + template class OpModReputation : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); - Interpreter::Type_Integer value = runtime[0].mInteger; - runtime.pop(); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); + Interpreter::Type_Integer value = runtime[0].mInteger; + runtime.pop(); - ptr.getClass().getNpcStats (ptr).setReputation (ptr.getClass().getNpcStats (ptr).getReputation () + value); - } + ptr.getClass().getNpcStats(ptr).setReputation(ptr.getClass().getNpcStats(ptr).getReputation() + value); + } }; - template + template class OpSetReputation : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); - Interpreter::Type_Integer value = runtime[0].mInteger; - runtime.pop(); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); + Interpreter::Type_Integer value = runtime[0].mInteger; + runtime.pop(); - ptr.getClass().getNpcStats (ptr).setReputation (value); - } + ptr.getClass().getNpcStats(ptr).setReputation(value); + } }; - template + template class OpGetReputation : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - runtime.push (ptr.getClass().getNpcStats (ptr).getReputation ()); - } + runtime.push(ptr.getClass().getNpcStats(ptr).getReputation()); + } }; - template + template class OpSameFaction : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); - runtime.push(player.getClass().getNpcStats (player).isInFaction(ptr.getClass().getPrimaryFaction(ptr))); - } + runtime.push(player.getClass().getNpcStats(player).isInFaction(ptr.getClass().getPrimaryFaction(ptr))); + } }; class OpModFactionReaction : public Interpreter::Opcode0 { public: - - void execute (Interpreter::Runtime& runtime) override + void execute(Interpreter::Runtime& runtime) override { std::string_view faction1 = runtime.getStringLiteral(runtime[0].mInteger); runtime.pop(); @@ -236,8 +223,7 @@ namespace MWScript class OpGetFactionReaction : public Interpreter::Opcode0 { public: - - void execute (Interpreter::Runtime& runtime) override + void execute(Interpreter::Runtime& runtime) override { std::string_view faction1 = runtime.getStringLiteral(runtime[0].mInteger); runtime.pop(); @@ -245,16 +231,14 @@ namespace MWScript std::string_view faction2 = runtime.getStringLiteral(runtime[0].mInteger); runtime.pop(); - runtime.push(MWBase::Environment::get().getDialogueManager() - ->getFactionReaction(faction1, faction2)); + runtime.push(MWBase::Environment::get().getDialogueManager()->getFactionReaction(faction1, faction2)); } }; class OpSetFactionReaction : public Interpreter::Opcode0 { public: - - void execute (Interpreter::Runtime& runtime) override + void execute(Interpreter::Runtime& runtime) override { std::string_view faction1 = runtime.getStringLiteral(runtime[0].mInteger); runtime.pop(); @@ -273,7 +257,7 @@ namespace MWScript class OpClearInfoActor : public Interpreter::Opcode0 { public: - void execute (Interpreter::Runtime& runtime) override + void execute(Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -281,8 +265,7 @@ namespace MWScript } }; - - void installOpcodes (Interpreter::Interpreter& interpreter) + void installOpcodes(Interpreter::Interpreter& interpreter) { interpreter.installSegment5>(Compiler::Dialogue::opcodeJournal); interpreter.installSegment5>(Compiler::Dialogue::opcodeJournalExplicit); @@ -305,7 +288,8 @@ namespace MWScript interpreter.installSegment5(Compiler::Dialogue::opcodeSetFactionReaction); interpreter.installSegment5(Compiler::Dialogue::opcodeGetFactionReaction); interpreter.installSegment5>(Compiler::Dialogue::opcodeClearInfoActor); - interpreter.installSegment5>(Compiler::Dialogue::opcodeClearInfoActorExplicit); + interpreter.installSegment5>( + Compiler::Dialogue::opcodeClearInfoActorExplicit); } } diff --git a/apps/openmw/mwscript/dialogueextensions.hpp b/apps/openmw/mwscript/dialogueextensions.hpp index 7b03154dfb..acb4e06838 100644 --- a/apps/openmw/mwscript/dialogueextensions.hpp +++ b/apps/openmw/mwscript/dialogueextensions.hpp @@ -16,7 +16,7 @@ namespace MWScript /// \brief Dialogue/Journal-related script functionality namespace Dialogue { - void installOpcodes (Interpreter::Interpreter& interpreter); + void installOpcodes(Interpreter::Interpreter& interpreter); } } diff --git a/apps/openmw/mwscript/extensions.cpp b/apps/openmw/mwscript/extensions.cpp index 12bf3413a0..0f42b49250 100644 --- a/apps/openmw/mwscript/extensions.cpp +++ b/apps/openmw/mwscript/extensions.cpp @@ -1,45 +1,45 @@ #include "extensions.hpp" -#include #include +#include -#include "soundextensions.hpp" +#include "aiextensions.hpp" +#include "animationextensions.hpp" #include "cellextensions.hpp" -#include "miscextensions.hpp" -#include "guiextensions.hpp" -#include "skyextensions.hpp" -#include "statsextensions.hpp" +#include "consoleextensions.hpp" #include "containerextensions.hpp" -#include "aiextensions.hpp" #include "controlextensions.hpp" #include "dialogueextensions.hpp" -#include "animationextensions.hpp" +#include "guiextensions.hpp" +#include "miscextensions.hpp" +#include "skyextensions.hpp" +#include "soundextensions.hpp" +#include "statsextensions.hpp" #include "transformationextensions.hpp" -#include "consoleextensions.hpp" #include "userextensions.hpp" namespace MWScript { - void installOpcodes (Interpreter::Interpreter& interpreter, bool consoleOnly) + void installOpcodes(Interpreter::Interpreter& interpreter, bool consoleOnly) { - Interpreter::installOpcodes (interpreter); - Cell::installOpcodes (interpreter); - Misc::installOpcodes (interpreter); - Gui::installOpcodes (interpreter); - Sound::installOpcodes (interpreter); - Sky::installOpcodes (interpreter); - Stats::installOpcodes (interpreter); - Container::installOpcodes (interpreter); - Ai::installOpcodes (interpreter); - Control::installOpcodes (interpreter); - Dialogue::installOpcodes (interpreter); - Animation::installOpcodes (interpreter); - Transformation::installOpcodes (interpreter); + Interpreter::installOpcodes(interpreter); + Cell::installOpcodes(interpreter); + Misc::installOpcodes(interpreter); + Gui::installOpcodes(interpreter); + Sound::installOpcodes(interpreter); + Sky::installOpcodes(interpreter); + Stats::installOpcodes(interpreter); + Container::installOpcodes(interpreter); + Ai::installOpcodes(interpreter); + Control::installOpcodes(interpreter); + Dialogue::installOpcodes(interpreter); + Animation::installOpcodes(interpreter); + Transformation::installOpcodes(interpreter); if (consoleOnly) { - Console::installOpcodes (interpreter); - User::installOpcodes (interpreter); + Console::installOpcodes(interpreter); + User::installOpcodes(interpreter); } } } diff --git a/apps/openmw/mwscript/extensions.hpp b/apps/openmw/mwscript/extensions.hpp index 67f6de5c58..43c5bb3b0e 100644 --- a/apps/openmw/mwscript/extensions.hpp +++ b/apps/openmw/mwscript/extensions.hpp @@ -13,7 +13,7 @@ namespace Interpreter namespace MWScript { - void installOpcodes (Interpreter::Interpreter& interpreter, bool consoleOnly = false); + void installOpcodes(Interpreter::Interpreter& interpreter, bool consoleOnly = false); ///< \param consoleOnly include console only opcodes } diff --git a/apps/openmw/mwscript/globalscripts.cpp b/apps/openmw/mwscript/globalscripts.cpp index 17742a0f84..158fc5305b 100644 --- a/apps/openmw/mwscript/globalscripts.cpp +++ b/apps/openmw/mwscript/globalscripts.cpp @@ -1,18 +1,18 @@ #include "globalscripts.hpp" #include -#include #include #include -#include #include +#include +#include #include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/scriptmanager.hpp" +#include "../mwbase/world.hpp" #include "interpretercontext.hpp" @@ -20,7 +20,7 @@ namespace { struct ScriptCreatingVisitor { - ESM::GlobalScript operator()(const MWWorld::Ptr &ptr) const + ESM::GlobalScript operator()(const MWWorld::Ptr& ptr) const { ESM::GlobalScript script; script.mTargetRef.unset(); @@ -38,7 +38,7 @@ namespace return script; } - ESM::GlobalScript operator()(const std::pair &pair) const + ESM::GlobalScript operator()(const std::pair& pair) const { ESM::GlobalScript script; script.mTargetId = pair.second; @@ -50,29 +50,20 @@ namespace struct PtrGettingVisitor { - const MWWorld::Ptr* operator()(const MWWorld::Ptr &ptr) const - { - return &ptr; - } + const MWWorld::Ptr* operator()(const MWWorld::Ptr& ptr) const { return &ptr; } - const MWWorld::Ptr* operator()(const std::pair &pair) const - { - return nullptr; - } + const MWWorld::Ptr* operator()(const std::pair& pair) const { return nullptr; } }; struct PtrResolvingVisitor { - MWWorld::Ptr operator()(const MWWorld::Ptr &ptr) const - { - return ptr; - } + MWWorld::Ptr operator()(const MWWorld::Ptr& ptr) const { return ptr; } - MWWorld::Ptr operator()(const std::pair &pair) const + MWWorld::Ptr operator()(const std::pair& pair) const { if (pair.second.empty()) return MWWorld::Ptr(); - else if(pair.first.hasContentFile()) + else if (pair.first.hasContentFile()) return MWBase::Environment::get().getWorld()->searchPtrViaRefNum(pair.second, pair.first); return MWBase::Environment::get().getWorld()->searchPtr(pair.second, false); } @@ -81,39 +72,37 @@ namespace class MatchPtrVisitor { const MWWorld::Ptr& mPtr; - public: - MatchPtrVisitor(const MWWorld::Ptr& ptr) : mPtr(ptr) {} - bool operator()(const MWWorld::Ptr &ptr) const + public: + MatchPtrVisitor(const MWWorld::Ptr& ptr) + : mPtr(ptr) { - return ptr == mPtr; } - bool operator()(const std::pair &pair) const - { - return false; - } + bool operator()(const MWWorld::Ptr& ptr) const { return ptr == mPtr; } + + bool operator()(const std::pair& pair) const { return false; } }; struct IdGettingVisitor { std::string_view operator()(const MWWorld::Ptr& ptr) const { - if(ptr.isEmpty()) + if (ptr.isEmpty()) return {}; return ptr.mRef->mRef.getRefId(); } - std::string_view operator()(const std::pair& pair) const - { - return pair.second; - } + std::string_view operator()(const std::pair& pair) const { return pair.second; } }; } namespace MWScript { - GlobalScriptDesc::GlobalScriptDesc() : mRunning (false) {} + GlobalScriptDesc::GlobalScriptDesc() + : mRunning(false) + { + } const MWWorld::Ptr* GlobalScriptDesc::getPtrIfPresent() const { @@ -122,36 +111,36 @@ namespace MWScript MWWorld::Ptr GlobalScriptDesc::getPtr() { - MWWorld::Ptr ptr = std::visit(PtrResolvingVisitor {}, mTarget); + MWWorld::Ptr ptr = std::visit(PtrResolvingVisitor{}, mTarget); mTarget = ptr; return ptr; } std::string_view GlobalScriptDesc::getId() const { - return std::visit(IdGettingVisitor {}, mTarget); + return std::visit(IdGettingVisitor{}, mTarget); } - - GlobalScripts::GlobalScripts (const MWWorld::ESMStore& store) - : mStore (store) - {} + GlobalScripts::GlobalScripts(const MWWorld::ESMStore& store) + : mStore(store) + { + } void GlobalScripts::addScript(std::string_view name, const MWWorld::Ptr& target) { std::string lowerName = ::Misc::StringUtils::lowerCase(name); const auto iter = mScripts.find(lowerName); - if (iter==mScripts.end()) + if (iter == mScripts.end()) { - if (const ESM::Script *script = mStore.get().search(lowerName)) + if (const ESM::Script* script = mStore.get().search(lowerName)) { auto desc = std::make_shared(); MWWorld::Ptr ptr = target; desc->mTarget = ptr; desc->mRunning = true; - desc->mLocals.configure (*script); - mScripts.insert (std::make_pair(lowerName, desc)); + desc->mLocals.configure(*script); + mScripts.insert(std::make_pair(lowerName, desc)); } else { @@ -166,19 +155,19 @@ namespace MWScript } } - void GlobalScripts::removeScript (std::string_view name) + void GlobalScripts::removeScript(std::string_view name) { - const auto iter = mScripts.find (::Misc::StringUtils::lowerCase (name)); + const auto iter = mScripts.find(::Misc::StringUtils::lowerCase(name)); - if (iter!=mScripts.end()) + if (iter != mScripts.end()) iter->second->mRunning = false; } - bool GlobalScripts::isRunning (std::string_view name) const + bool GlobalScripts::isRunning(std::string_view name) const { - const auto iter = mScripts.find (::Misc::StringUtils::lowerCase (name)); + const auto iter = mScripts.find(::Misc::StringUtils::lowerCase(name)); - if (iter==mScripts.end()) + if (iter == mScripts.end()) return false; return iter->second->mRunning; @@ -209,26 +198,23 @@ namespace MWScript scripts.emplace_back("main"); - for (MWWorld::Store::iterator iter = - mStore.get().begin(); - iter != mStore.get().end(); ++iter) + for (MWWorld::Store::iterator iter = mStore.get().begin(); + iter != mStore.get().end(); ++iter) { - scripts.push_back (iter->mId); + scripts.push_back(iter->mId); } // add scripts - for (std::vector::const_iterator iter (scripts.begin()); - iter!=scripts.end(); ++iter) + for (std::vector::const_iterator iter(scripts.begin()); iter != scripts.end(); ++iter) { try { - addScript (*iter); + addScript(*iter); } catch (const std::exception& exception) { - Log(Debug::Error) - << "Failed to add start script " << *iter << " because an exception has " - << "been thrown: " << exception.what(); + Log(Debug::Error) << "Failed to add start script " << *iter << " because an exception has " + << "been thrown: " << exception.what(); } } } @@ -238,11 +224,11 @@ namespace MWScript return mScripts.size(); } - void GlobalScripts::write (ESM::ESMWriter& writer, Loading::Listener& progress) const + void GlobalScripts::write(ESM::ESMWriter& writer, Loading::Listener& progress) const { for (const auto& [id, desc] : mScripts) { - ESM::GlobalScript script = std::visit(ScriptCreatingVisitor {}, desc->mTarget); + ESM::GlobalScript script = std::visit(ScriptCreatingVisitor{}, desc->mTarget); script.mId = id; @@ -250,18 +236,18 @@ namespace MWScript script.mRunning = desc->mRunning ? 1 : 0; - writer.startRecord (ESM::REC_GSCR); - script.save (writer); - writer.endRecord (ESM::REC_GSCR); + writer.startRecord(ESM::REC_GSCR); + script.save(writer); + writer.endRecord(ESM::REC_GSCR); } } - bool GlobalScripts::readRecord (ESM::ESMReader& reader, uint32_t type, const std::map& contentFileMap) + bool GlobalScripts::readRecord(ESM::ESMReader& reader, uint32_t type, const std::map& contentFileMap) { - if (type==ESM::REC_GSCR) + if (type == ESM::REC_GSCR) { ESM::GlobalScript script; - script.load (reader); + script.load(reader); if (script.mTargetRef.hasContentFile()) { @@ -270,11 +256,11 @@ namespace MWScript script.mTargetRef.mContentFile = iter->second; } - auto iter = mScripts.find (script.mId); + auto iter = mScripts.find(script.mId); - if (iter==mScripts.end()) + if (iter == mScripts.end()) { - if (const ESM::Script *scriptRecord = mStore.get().search (script.mId)) + if (const ESM::Script* scriptRecord = mStore.get().search(script.mId)) { try { @@ -283,15 +269,14 @@ namespace MWScript { desc->mTarget = std::make_pair(script.mTargetRef, script.mTargetId); } - desc->mLocals.configure (*scriptRecord); + desc->mLocals.configure(*scriptRecord); - iter = mScripts.insert (std::make_pair (script.mId, desc)).first; + iter = mScripts.insert(std::make_pair(script.mId, desc)).first; } catch (const std::exception& exception) { - Log(Debug::Error) - << "Failed to add start script " << script.mId - << " because an exception has been thrown: " << exception.what(); + Log(Debug::Error) << "Failed to add start script " << script.mId + << " because an exception has been thrown: " << exception.what(); return true; } @@ -300,8 +285,8 @@ namespace MWScript return true; } - iter->second->mRunning = script.mRunning!=0; - iter->second->mLocals.read (script.mLocals, script.mId); + iter->second->mRunning = script.mRunning != 0; + iter->second->mLocals.read(script.mLocals, script.mId); return true; } @@ -313,12 +298,12 @@ namespace MWScript { auto iter = mScripts.find(name); - if (iter==mScripts.end()) + if (iter == mScripts.end()) { - const ESM::Script *script = mStore.get().find(name); + const ESM::Script* script = mStore.get().find(name); auto desc = std::make_shared(); - desc->mLocals.configure (*script); + desc->mLocals.configure(*script); iter = mScripts.emplace(name, desc).first; } @@ -329,7 +314,7 @@ namespace MWScript const Locals* GlobalScripts::getLocalsIfPresent(std::string_view name) const { auto iter = mScripts.find(name); - if (iter==mScripts.end()) + if (iter == mScripts.end()) return nullptr; return &iter->second->mLocals; } @@ -339,7 +324,7 @@ namespace MWScript MatchPtrVisitor visitor(base); for (const auto& script : mScripts) { - if (std::visit (visitor, script.second->mTarget)) + if (std::visit(visitor, script.second->mTarget)) script.second->mTarget = updated; } } diff --git a/apps/openmw/mwscript/globalscripts.hpp b/apps/openmw/mwscript/globalscripts.hpp index bd8d879031..7839580090 100644 --- a/apps/openmw/mwscript/globalscripts.hpp +++ b/apps/openmw/mwscript/globalscripts.hpp @@ -1,14 +1,14 @@ #ifndef GAME_SCRIPT_GLOBALSCRIPTS_H #define GAME_SCRIPT_GLOBALSCRIPTS_H -#include -#include +#include #include #include +#include +#include #include #include #include -#include #include @@ -52,44 +52,45 @@ namespace MWScript class GlobalScripts { - const MWWorld::ESMStore& mStore; - std::unordered_map, ::Misc::StringUtils::CiHash, ::Misc::StringUtils::CiEqual> mScripts; - - public: + const MWWorld::ESMStore& mStore; + std::unordered_map, ::Misc::StringUtils::CiHash, + ::Misc::StringUtils::CiEqual> + mScripts; - GlobalScripts (const MWWorld::ESMStore& store); + public: + GlobalScripts(const MWWorld::ESMStore& store); - void addScript(std::string_view name, const MWWorld::Ptr& target = MWWorld::Ptr()); + void addScript(std::string_view name, const MWWorld::Ptr& target = MWWorld::Ptr()); - void removeScript (std::string_view name); + void removeScript(std::string_view name); - bool isRunning (std::string_view name) const; + bool isRunning(std::string_view name) const; - void run(); - ///< run all active global scripts + void run(); + ///< run all active global scripts - void clear(); + void clear(); - void addStartup(); - ///< Add startup script + void addStartup(); + ///< Add startup script - int countSavedGameRecords() const; + int countSavedGameRecords() const; - void write (ESM::ESMWriter& writer, Loading::Listener& progress) const; + void write(ESM::ESMWriter& writer, Loading::Listener& progress) const; - bool readRecord (ESM::ESMReader& reader, uint32_t type, const std::map& contentFileMap); - ///< Records for variables that do not exist are dropped silently. - /// - /// \return Known type? + bool readRecord(ESM::ESMReader& reader, uint32_t type, const std::map& contentFileMap); + ///< Records for variables that do not exist are dropped silently. + /// + /// \return Known type? - Locals& getLocals(std::string_view name); - ///< If the script \a name has not been added as a global script yet, it is added - /// automatically, but is not set to running state. + Locals& getLocals(std::string_view name); + ///< If the script \a name has not been added as a global script yet, it is added + /// automatically, but is not set to running state. - const Locals* getLocalsIfPresent(std::string_view name) const; + const Locals* getLocalsIfPresent(std::string_view name) const; - void updatePtrs(const MWWorld::Ptr& base, const MWWorld::Ptr& updated); - ///< Update the Ptrs stored in mTarget. Should be called after the reference has been moved to a new cell. + void updatePtrs(const MWWorld::Ptr& base, const MWWorld::Ptr& updated); + ///< Update the Ptrs stored in mTarget. Should be called after the reference has been moved to a new cell. }; } diff --git a/apps/openmw/mwscript/guiextensions.cpp b/apps/openmw/mwscript/guiextensions.cpp index 36669f34ac..d183d45915 100644 --- a/apps/openmw/mwscript/guiextensions.cpp +++ b/apps/openmw/mwscript/guiextensions.cpp @@ -3,15 +3,15 @@ #include #include -#include #include +#include #include "../mwworld/esmstore.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/windowmanager.hpp" #include "../mwbase/world.hpp" -#include "../mwbase/mechanicsmanager.hpp" #include "../mwmechanics/actorutil.hpp" @@ -24,106 +24,105 @@ namespace MWScript { class OpEnableWindow : public Interpreter::Opcode0 { - MWGui::GuiWindow mWindow; - - public: + MWGui::GuiWindow mWindow; - OpEnableWindow (MWGui::GuiWindow window) : mWindow (window) {} + public: + OpEnableWindow(MWGui::GuiWindow window) + : mWindow(window) + { + } - void execute (Interpreter::Runtime& runtime) override - { - MWBase::Environment::get().getWindowManager()->allow (mWindow); - } + void execute(Interpreter::Runtime& runtime) override + { + MWBase::Environment::get().getWindowManager()->allow(mWindow); + } }; class OpEnableRest : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWBase::Environment::get().getWindowManager()->enableRest(); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + MWBase::Environment::get().getWindowManager()->enableRest(); + } }; template class OpShowRestMenu : public Interpreter::Opcode0 { public: - void execute (Interpreter::Runtime& runtime) override + void execute(Interpreter::Runtime& runtime) override { MWWorld::Ptr bed = R()(runtime, false); - if (bed.isEmpty() || !MWBase::Environment::get().getMechanicsManager()->sleepInBed(MWMechanics::getPlayer(), - bed)) + if (bed.isEmpty() + || !MWBase::Environment::get().getMechanicsManager()->sleepInBed(MWMechanics::getPlayer(), bed)) MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Rest, bed); } }; class OpShowDialogue : public Interpreter::Opcode0 { - MWGui::GuiMode mDialogue; + MWGui::GuiMode mDialogue; - public: - - OpShowDialogue (MWGui::GuiMode dialogue) - : mDialogue (dialogue) - {} + public: + OpShowDialogue(MWGui::GuiMode dialogue) + : mDialogue(dialogue) + { + } - void execute (Interpreter::Runtime& runtime) override - { - MWBase::Environment::get().getWindowManager()->pushGuiMode(mDialogue); - } + void execute(Interpreter::Runtime& runtime) override + { + MWBase::Environment::get().getWindowManager()->pushGuiMode(mDialogue); + } }; class OpGetButtonPressed : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - runtime.push (MWBase::Environment::get().getWindowManager()->readPressedButton()); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + runtime.push(MWBase::Environment::get().getWindowManager()->readPressedButton()); + } }; class OpToggleFogOfWar : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - runtime.getContext().report(MWBase::Environment::get().getWindowManager()->toggleFogOfWar() ? "Fog of war -> On" - : "Fog of war -> Off"); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + runtime.getContext().report(MWBase::Environment::get().getWindowManager()->toggleFogOfWar() + ? "Fog of war -> On" + : "Fog of war -> Off"); + } }; class OpToggleFullHelp : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - runtime.getContext().report(MWBase::Environment::get().getWindowManager()->toggleFullHelp() ? "Full help -> On" - : "Full help -> Off"); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + runtime.getContext().report(MWBase::Environment::get().getWindowManager()->toggleFullHelp() + ? "Full help -> On" + : "Full help -> Off"); + } }; class OpShowMap : public Interpreter::Opcode0 { public: - - void execute (Interpreter::Runtime& runtime) override + void execute(Interpreter::Runtime& runtime) override { std::string_view cell = runtime.getStringLiteral(runtime[0].mInteger); runtime.pop(); - // "Will match complete or partial cells, so ShowMap, "Vivec" will show cells Vivec and Vivec, Fred's House as well." - // http://www.uesp.net/wiki/Tes3Mod:ShowMap + // "Will match complete or partial cells, so ShowMap, "Vivec" will show cells Vivec and Vivec, Fred's + // House as well." http://www.uesp.net/wiki/Tes3Mod:ShowMap - const MWWorld::Store &cells = - MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& cells + = MWBase::Environment::get().getWorld()->getStore().get(); - MWBase::WindowManager *winMgr = MWBase::Environment::get().getWindowManager(); + MWBase::WindowManager* winMgr = MWBase::Environment::get().getWindowManager(); for (auto it = cells.extBegin(); it != cells.extEnd(); ++it) { @@ -136,21 +135,17 @@ namespace MWScript class OpFillMap : public Interpreter::Opcode0 { public: - - void execute (Interpreter::Runtime& runtime) override + void execute(Interpreter::Runtime& runtime) override { - const MWWorld::Store &cells = - MWBase::Environment::get().getWorld ()->getStore().get(); + const MWWorld::Store& cells + = MWBase::Environment::get().getWorld()->getStore().get(); for (auto it = cells.extBegin(); it != cells.extEnd(); ++it) { const std::string& name = it->mName; if (!name.empty()) - MWBase::Environment::get().getWindowManager()->addVisitedLocation ( - name, - it->getGridX(), - it->getGridY() - ); + MWBase::Environment::get().getWindowManager()->addVisitedLocation( + name, it->getGridX(), it->getGridY()); } } }; @@ -158,22 +153,20 @@ namespace MWScript class OpMenuTest : public Interpreter::Opcode1 { public: - - void execute (Interpreter::Runtime& runtime, unsigned int arg0) override + void execute(Interpreter::Runtime& runtime, unsigned int arg0) override { - int arg=0; - if(arg0>0) + int arg = 0; + if (arg0 > 0) { arg = runtime[0].mInteger; runtime.pop(); } - if (arg == 0) { MWGui::GuiMode modes[] = { MWGui::GM_Inventory, MWGui::GM_Container }; - for (int i=0; i<2; ++i) + for (int i = 0; i < 2; ++i) { if (MWBase::Environment::get().getWindowManager()->containsMode(modes[i])) MWBase::Environment::get().getWindowManager()->removeGuiMode(modes[i]); @@ -199,20 +192,21 @@ namespace MWScript class OpToggleMenus : public Interpreter::Opcode0 { public: - void execute(Interpreter::Runtime &runtime) override + void execute(Interpreter::Runtime& runtime) override { bool state = MWBase::Environment::get().getWindowManager()->toggleHud(); runtime.getContext().report(state ? "GUI -> On" : "GUI -> Off"); if (!state) { - while (MWBase::Environment::get().getWindowManager()->getMode() != MWGui::GM_None) // don't use isGuiMode, or we get an infinite loop for modal message boxes! + while (MWBase::Environment::get().getWindowManager()->getMode() + != MWGui::GM_None) // don't use isGuiMode, or we get an infinite loop for modal message boxes! MWBase::Environment::get().getWindowManager()->popGuiMode(); } } }; - void installOpcodes (Interpreter::Interpreter& interpreter) + void installOpcodes(Interpreter::Interpreter& interpreter) { interpreter.installSegment5(Compiler::Gui::opcodeEnableBirthMenu, MWGui::GM_Birth); interpreter.installSegment5(Compiler::Gui::opcodeEnableClassMenu, MWGui::GM_Class); diff --git a/apps/openmw/mwscript/guiextensions.hpp b/apps/openmw/mwscript/guiextensions.hpp index ec775a51c9..b44f954d6e 100644 --- a/apps/openmw/mwscript/guiextensions.hpp +++ b/apps/openmw/mwscript/guiextensions.hpp @@ -15,10 +15,9 @@ namespace MWScript { /// \brief GUI-related script functionality namespace Gui - { - void installOpcodes (Interpreter::Interpreter& interpreter); + { + void installOpcodes(Interpreter::Interpreter& interpreter); } } #endif - diff --git a/apps/openmw/mwscript/interpretercontext.cpp b/apps/openmw/mwscript/interpretercontext.cpp index 0ca1443656..30eae77529 100644 --- a/apps/openmw/mwscript/interpretercontext.cpp +++ b/apps/openmw/mwscript/interpretercontext.cpp @@ -9,21 +9,21 @@ #include "../mwworld/esmstore.hpp" #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" -#include "../mwbase/scriptmanager.hpp" -#include "../mwbase/windowmanager.hpp" #include "../mwbase/inputmanager.hpp" #include "../mwbase/luamanager.hpp" +#include "../mwbase/scriptmanager.hpp" +#include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" #include "../mwworld/action.hpp" -#include "../mwworld/class.hpp" #include "../mwworld/cellstore.hpp" +#include "../mwworld/class.hpp" #include "../mwworld/containerstore.hpp" #include "../mwmechanics/npcstats.hpp" -#include "locals.hpp" #include "globalscripts.hpp" +#include "locals.hpp" namespace MWScript { @@ -31,7 +31,7 @@ namespace MWScript { if (!id.empty()) { - return MWBase::Environment::get().getWorld()->getPtr (id, activeOnly); + return MWBase::Environment::get().getWorld()->getPtr(id, activeOnly); } else { @@ -45,22 +45,19 @@ namespace MWScript } } - const Locals& InterpreterContext::getMemberLocals(std::string_view& id, bool global) - const + const Locals& InterpreterContext::getMemberLocals(std::string_view& id, bool global) const { if (global) { - return MWBase::Environment::get().getScriptManager()->getGlobalScripts(). - getLocals (id); + return MWBase::Environment::get().getScriptManager()->getGlobalScripts().getLocals(id); } else { - const MWWorld::Ptr ptr = getReferenceImp (id, false); + const MWWorld::Ptr ptr = getReferenceImp(id, false); - id = ptr.getClass().getScript (ptr); + id = ptr.getClass().getScript(ptr); - ptr.getRefData().setLocals ( - *MWBase::Environment::get().getWorld()->getStore().get().find (id)); + ptr.getRefData().setLocals(*MWBase::Environment::get().getWorld()->getStore().get().find(id)); return ptr.getRefData().getLocals(); } @@ -70,30 +67,30 @@ namespace MWScript { if (global) { - return MWBase::Environment::get().getScriptManager()->getGlobalScripts(). - getLocals (id); + return MWBase::Environment::get().getScriptManager()->getGlobalScripts().getLocals(id); } else { - const MWWorld::Ptr ptr = getReferenceImp (id, false); + const MWWorld::Ptr ptr = getReferenceImp(id, false); - id = ptr.getClass().getScript (ptr); + id = ptr.getClass().getScript(ptr); - ptr.getRefData().setLocals ( - *MWBase::Environment::get().getWorld()->getStore().get().find (id)); + ptr.getRefData().setLocals(*MWBase::Environment::get().getWorld()->getStore().get().find(id)); return ptr.getRefData().getLocals(); } } - MissingImplicitRefError::MissingImplicitRefError() : std::runtime_error("no implicit reference") {} + MissingImplicitRefError::MissingImplicitRefError() + : std::runtime_error("no implicit reference") + { + } int InterpreterContext::findLocalVariableIndex(std::string_view scriptId, std::string_view name, char type) const { - int index = MWBase::Environment::get().getScriptManager()->getLocals (scriptId). - searchIndex (type, name); + int index = MWBase::Environment::get().getScriptManager()->getLocals(scriptId).searchIndex(type, name); - if (index!=-1) + if (index != -1) return index; std::ostringstream stream; @@ -102,22 +99,30 @@ namespace MWScript switch (type) { - case 's': stream << "short"; break; - case 'l': stream << "long"; break; - case 'f': stream << "float"; break; + case 's': + stream << "short"; + break; + case 'l': + stream << "long"; + break; + case 'f': + stream << "float"; + break; } stream << " member variable " << name << " in script " << scriptId; - throw std::runtime_error (stream.str().c_str()); + throw std::runtime_error(stream.str().c_str()); } - InterpreterContext::InterpreterContext (MWScript::Locals *locals, const MWWorld::Ptr& reference) - : mLocals (locals), mReference (reference) - {} + InterpreterContext::InterpreterContext(MWScript::Locals* locals, const MWWorld::Ptr& reference) + : mLocals(locals) + , mReference(reference) + { + } - InterpreterContext::InterpreterContext (std::shared_ptr globalScriptDesc) - : mLocals (&(globalScriptDesc->mLocals)) + InterpreterContext::InterpreterContext(std::shared_ptr globalScriptDesc) + : mLocals(&(globalScriptDesc->mLocals)) { const MWWorld::Ptr* ptr = globalScriptDesc->getPtrIfPresent(); // A nullptr here signifies that the script's target has not yet been resolved after loading the game. @@ -131,109 +136,106 @@ namespace MWScript std::string_view InterpreterContext::getTarget() const { - if(!mReference.isEmpty()) + if (!mReference.isEmpty()) return mReference.mRef->mRef.getRefId(); - else if(mGlobalScriptDesc) + else if (mGlobalScriptDesc) return mGlobalScriptDesc->getId(); return {}; } - int InterpreterContext::getLocalShort (int index) const + int InterpreterContext::getLocalShort(int index) const { if (!mLocals) - throw std::runtime_error ("local variables not available in this context"); + throw std::runtime_error("local variables not available in this context"); - return mLocals->mShorts.at (index); + return mLocals->mShorts.at(index); } - int InterpreterContext::getLocalLong (int index) const + int InterpreterContext::getLocalLong(int index) const { if (!mLocals) - throw std::runtime_error ("local variables not available in this context"); + throw std::runtime_error("local variables not available in this context"); - return mLocals->mLongs.at (index); + return mLocals->mLongs.at(index); } - float InterpreterContext::getLocalFloat (int index) const + float InterpreterContext::getLocalFloat(int index) const { if (!mLocals) - throw std::runtime_error ("local variables not available in this context"); + throw std::runtime_error("local variables not available in this context"); - return mLocals->mFloats.at (index); + return mLocals->mFloats.at(index); } - void InterpreterContext::setLocalShort (int index, int value) + void InterpreterContext::setLocalShort(int index, int value) { if (!mLocals) - throw std::runtime_error ("local variables not available in this context"); + throw std::runtime_error("local variables not available in this context"); - mLocals->mShorts.at (index) = value; + mLocals->mShorts.at(index) = value; } - void InterpreterContext::setLocalLong (int index, int value) + void InterpreterContext::setLocalLong(int index, int value) { if (!mLocals) - throw std::runtime_error ("local variables not available in this context"); + throw std::runtime_error("local variables not available in this context"); - mLocals->mLongs.at (index) = value; + mLocals->mLongs.at(index) = value; } - void InterpreterContext::setLocalFloat (int index, float value) + void InterpreterContext::setLocalFloat(int index, float value) { if (!mLocals) - throw std::runtime_error ("local variables not available in this context"); + throw std::runtime_error("local variables not available in this context"); - mLocals->mFloats.at (index) = value; + mLocals->mFloats.at(index) = value; } - void InterpreterContext::messageBox(std::string_view message, - const std::vector& buttons) + void InterpreterContext::messageBox(std::string_view message, const std::vector& buttons) { if (buttons.empty()) - MWBase::Environment::get().getWindowManager()->messageBox (message); + MWBase::Environment::get().getWindowManager()->messageBox(message); else MWBase::Environment::get().getWindowManager()->interactiveMessageBox(message, buttons); } - void InterpreterContext::report (const std::string& message) - { - } + void InterpreterContext::report(const std::string& message) {} int InterpreterContext::getGlobalShort(std::string_view name) const { - return MWBase::Environment::get().getWorld()->getGlobalInt (name); + return MWBase::Environment::get().getWorld()->getGlobalInt(name); } int InterpreterContext::getGlobalLong(std::string_view name) const { // a global long is internally a float. - return MWBase::Environment::get().getWorld()->getGlobalInt (name); + return MWBase::Environment::get().getWorld()->getGlobalInt(name); } float InterpreterContext::getGlobalFloat(std::string_view name) const { - return MWBase::Environment::get().getWorld()->getGlobalFloat (name); + return MWBase::Environment::get().getWorld()->getGlobalFloat(name); } void InterpreterContext::setGlobalShort(std::string_view name, int value) { - MWBase::Environment::get().getWorld()->setGlobalInt (name, value); + MWBase::Environment::get().getWorld()->setGlobalInt(name, value); } void InterpreterContext::setGlobalLong(std::string_view name, int value) { - MWBase::Environment::get().getWorld()->setGlobalInt (name, value); + MWBase::Environment::get().getWorld()->setGlobalInt(name, value); } void InterpreterContext::setGlobalFloat(std::string_view name, float value) { - MWBase::Environment::get().getWorld()->setGlobalFloat (name, value); + MWBase::Environment::get().getWorld()->setGlobalFloat(name, value); } std::vector InterpreterContext::getGlobals() const { - const MWWorld::Store& globals = - MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& globals + = MWBase::Environment::get().getWorld()->getStore().get(); std::vector ids; for (const auto& globalVariable : globals) @@ -246,7 +248,7 @@ namespace MWScript char InterpreterContext::getGlobalType(std::string_view name) const { - MWBase::World *world = MWBase::Environment::get().getWorld(); + MWBase::World* world = MWBase::Environment::get().getWorld(); return world->getGlobalVariableType(name); } @@ -257,12 +259,12 @@ namespace MWScript for (const int action : actions) { std::string_view desc = input->getActionDescription(action); - if(desc.empty()) + if (desc.empty()) continue; - if(desc == targetAction) + if (desc == targetAction) { - if(input->joystickLastUsed()) + if (input->joystickLastUsed()) return input->getActionControllerBindingName(action); else return input->getActionKeyBindingName(action); @@ -295,14 +297,16 @@ namespace MWScript std::string_view InterpreterContext::getNPCClass() const { const ESM::NPC* npc = getReferenceImp().get()->mBase; - const ESM::Class* class_ = MWBase::Environment::get().getWorld()->getStore().get().find(npc->mClass); + const ESM::Class* class_ + = MWBase::Environment::get().getWorld()->getStore().get().find(npc->mClass); return class_->mName; } std::string_view InterpreterContext::getNPCFaction() const { const ESM::NPC* npc = getReferenceImp().get()->mBase; - const ESM::Faction* faction = MWBase::Environment::get().getWorld()->getStore().get().find(npc->mFaction); + const ESM::Faction* faction + = MWBase::Environment::get().getWorld()->getStore().get().find(npc->mFaction); return faction->mName; } @@ -317,42 +321,42 @@ namespace MWScript if (rank < 0 || rank > 9) throw std::runtime_error("getNPCRank(): invalid rank"); - MWBase::World *world = MWBase::Environment::get().getWorld(); - const MWWorld::ESMStore &store = world->getStore(); - const ESM::Faction *fact = store.get().find(faction); + MWBase::World* world = MWBase::Environment::get().getWorld(); + const MWWorld::ESMStore& store = world->getStore(); + const ESM::Faction* fact = store.get().find(faction); return fact->mRanks[rank]; } std::string_view InterpreterContext::getPCName() const { - MWBase::World *world = MWBase::Environment::get().getWorld(); + MWBase::World* world = MWBase::Environment::get().getWorld(); return world->getPlayerPtr().get()->mBase->mName; } std::string_view InterpreterContext::getPCRace() const { - MWBase::World *world = MWBase::Environment::get().getWorld(); + MWBase::World* world = MWBase::Environment::get().getWorld(); const std::string& race = world->getPlayerPtr().get()->mBase->mRace; return world->getStore().get().find(race)->mName; } std::string_view InterpreterContext::getPCClass() const { - MWBase::World *world = MWBase::Environment::get().getWorld(); + MWBase::World* world = MWBase::Environment::get().getWorld(); const std::string& class_ = world->getPlayerPtr().get()->mBase->mClass; return world->getStore().get().find(class_)->mName; } std::string_view InterpreterContext::getPCRank() const { - MWBase::World *world = MWBase::Environment::get().getWorld(); + MWBase::World* world = MWBase::Environment::get().getWorld(); MWWorld::Ptr player = world->getPlayerPtr(); std::string_view factionId = getReferenceImp().getClass().getPrimaryFaction(getReferenceImp()); if (factionId.empty()) throw std::runtime_error("getPCRank(): NPC is not in a faction"); - const std::map& ranks = player.getClass().getNpcStats (player).getFactionRanks(); + const std::map& ranks = player.getClass().getNpcStats(player).getFactionRanks(); std::map::const_iterator it = ranks.find(Misc::StringUtils::lowerCase(factionId)); int rank = -1; if (it != ranks.end()) @@ -363,10 +367,10 @@ namespace MWScript if (rank == -1) rank = 0; - const MWWorld::ESMStore &store = world->getStore(); - const ESM::Faction *faction = store.get().find(factionId); + const MWWorld::ESMStore& store = world->getStore(); + const ESM::Faction* faction = store.get().find(factionId); - if(rank < 0 || rank > 9) // there are only 10 ranks + if (rank < 0 || rank > 9) // there are only 10 ranks return {}; return faction->mRanks[rank]; @@ -374,14 +378,14 @@ namespace MWScript std::string_view InterpreterContext::getPCNextRank() const { - MWBase::World *world = MWBase::Environment::get().getWorld(); + MWBase::World* world = MWBase::Environment::get().getWorld(); MWWorld::Ptr player = world->getPlayerPtr(); std::string_view factionId = getReferenceImp().getClass().getPrimaryFaction(getReferenceImp()); if (factionId.empty()) throw std::runtime_error("getPCNextRank(): NPC is not in a faction"); - const std::map& ranks = player.getClass().getNpcStats (player).getFactionRanks(); + const std::map& ranks = player.getClass().getNpcStats(player).getFactionRanks(); std::map::const_iterator it = ranks.find(Misc::StringUtils::lowerCase(factionId)); int rank = -1; if (it != ranks.end()) @@ -393,10 +397,10 @@ namespace MWScript if (rank > 9) rank = 9; - const MWWorld::ESMStore &store = world->getStore(); - const ESM::Faction *faction = store.get().find(factionId); + const MWWorld::ESMStore& store = world->getStore(); + const ESM::Faction* faction = store.get().find(factionId); - if(rank < 0) + if (rank < 0) return {}; return faction->mRanks[rank]; @@ -404,9 +408,9 @@ namespace MWScript int InterpreterContext::getPCBounty() const { - MWBase::World *world = MWBase::Environment::get().getWorld(); + MWBase::World* world = MWBase::Environment::get().getWorld(); MWWorld::Ptr player = world->getPlayerPtr(); - return player.getClass().getNpcStats (player).getBounty(); + return player.getClass().getNpcStats(player).getBounty(); } std::string_view InterpreterContext::getCurrentCellName() const @@ -418,39 +422,35 @@ namespace MWScript { MWBase::Environment::get().getLuaManager()->objectActivated(ptr, actor); std::unique_ptr action = (ptr.getClass().activate(ptr, actor)); - action->execute (actor); + action->execute(actor); if (action->getTarget() != MWWorld::Ptr() && action->getTarget() != ptr) { updatePtr(ptr, action->getTarget()); } } - int InterpreterContext::getMemberShort(std::string_view id, std::string_view name, - bool global) const + int InterpreterContext::getMemberShort(std::string_view id, std::string_view name, bool global) const { const Locals& locals = getMemberLocals(id, global); return locals.mShorts[findLocalVariableIndex(id, name, 's')]; } - int InterpreterContext::getMemberLong(std::string_view id, std::string_view name, - bool global) const + int InterpreterContext::getMemberLong(std::string_view id, std::string_view name, bool global) const { const Locals& locals = getMemberLocals(id, global); return locals.mLongs[findLocalVariableIndex(id, name, 'l')]; } - float InterpreterContext::getMemberFloat(std::string_view id, std::string_view name, - bool global) const + float InterpreterContext::getMemberFloat(std::string_view id, std::string_view name, bool global) const { const Locals& locals = getMemberLocals(id, global); return locals.mFloats[findLocalVariableIndex(id, name, 'f')]; } - void InterpreterContext::setMemberShort(std::string_view id, std::string_view name, - int value, bool global) + void InterpreterContext::setMemberShort(std::string_view id, std::string_view name, int value, bool global) { Locals& locals = getMemberLocals(id, global); diff --git a/apps/openmw/mwscript/interpretercontext.hpp b/apps/openmw/mwscript/interpretercontext.hpp index d36671a7d2..89b8f626c0 100644 --- a/apps/openmw/mwscript/interpretercontext.hpp +++ b/apps/openmw/mwscript/interpretercontext.hpp @@ -16,119 +16,120 @@ namespace MWScript class MissingImplicitRefError : public std::runtime_error { - public: - MissingImplicitRefError(); + public: + MissingImplicitRefError(); }; class InterpreterContext : public Interpreter::Context { - Locals *mLocals; - mutable MWWorld::Ptr mReference; - std::shared_ptr mGlobalScriptDesc; + Locals* mLocals; + mutable MWWorld::Ptr mReference; + std::shared_ptr mGlobalScriptDesc; - /// If \a id is empty, a reference the script is run from is returned or in case - /// of a non-local script the reference derived from the target ID. - const MWWorld::Ptr getReferenceImp(std::string_view id = {}, bool activeOnly = false, bool doThrow = true) const; + /// If \a id is empty, a reference the script is run from is returned or in case + /// of a non-local script the reference derived from the target ID. + const MWWorld::Ptr getReferenceImp( + std::string_view id = {}, bool activeOnly = false, bool doThrow = true) const; - const Locals& getMemberLocals(std::string_view& id, bool global) const; - ///< \a id is changed to the respective script ID, if \a id wasn't a script ID before + const Locals& getMemberLocals(std::string_view& id, bool global) const; + ///< \a id is changed to the respective script ID, if \a id wasn't a script ID before - Locals& getMemberLocals(std::string_view& id, bool global); - ///< \a id is changed to the respective script ID, if \a id wasn't a script ID before + Locals& getMemberLocals(std::string_view& id, bool global); + ///< \a id is changed to the respective script ID, if \a id wasn't a script ID before - /// Throws an exception if local variable can't be found. - int findLocalVariableIndex(std::string_view scriptId, std::string_view name, char type) const; + /// Throws an exception if local variable can't be found. + int findLocalVariableIndex(std::string_view scriptId, std::string_view name, char type) const; - public: - InterpreterContext (std::shared_ptr globalScriptDesc); + public: + InterpreterContext(std::shared_ptr globalScriptDesc); - InterpreterContext (MWScript::Locals *locals, const MWWorld::Ptr& reference); - ///< The ownership of \a locals is not transferred. 0-pointer allowed. + InterpreterContext(MWScript::Locals* locals, const MWWorld::Ptr& reference); + ///< The ownership of \a locals is not transferred. 0-pointer allowed. - std::string_view getTarget() const override; + std::string_view getTarget() const override; - int getLocalShort (int index) const override; + int getLocalShort(int index) const override; - int getLocalLong (int index) const override; + int getLocalLong(int index) const override; - float getLocalFloat (int index) const override; + float getLocalFloat(int index) const override; - void setLocalShort (int index, int value) override; + void setLocalShort(int index, int value) override; - void setLocalLong (int index, int value) override; + void setLocalLong(int index, int value) override; - void setLocalFloat (int index, float value) override; + void setLocalFloat(int index, float value) override; - using Interpreter::Context::messageBox; + using Interpreter::Context::messageBox; - void messageBox(std::string_view message, - const std::vector& buttons) override; + void messageBox(std::string_view message, const std::vector& buttons) override; - void report (const std::string& message) override; - ///< By default, do nothing. + void report(const std::string& message) override; + ///< By default, do nothing. - int getGlobalShort(std::string_view name) const override; + int getGlobalShort(std::string_view name) const override; - int getGlobalLong(std::string_view name) const override; + int getGlobalLong(std::string_view name) const override; - float getGlobalFloat(std::string_view name) const override; + float getGlobalFloat(std::string_view name) const override; - void setGlobalShort(std::string_view name, int value) override; + void setGlobalShort(std::string_view name, int value) override; - void setGlobalLong(std::string_view name, int value) override; + void setGlobalLong(std::string_view name, int value) override; - void setGlobalFloat(std::string_view name, float value) override; + void setGlobalFloat(std::string_view name, float value) override; - std::vector getGlobals () const override; + std::vector getGlobals() const override; - char getGlobalType(std::string_view name) const override; + char getGlobalType(std::string_view name) const override; - std::string getActionBinding(std::string_view action) const override; + std::string getActionBinding(std::string_view action) const override; - std::string_view getActorName() const override; + std::string_view getActorName() const override; - std::string_view getNPCRace() const override; + std::string_view getNPCRace() const override; - std::string_view getNPCClass() const override; + std::string_view getNPCClass() const override; - std::string_view getNPCFaction() const override; + std::string_view getNPCFaction() const override; - std::string_view getNPCRank() const override; + std::string_view getNPCRank() const override; - std::string_view getPCName() const override; + std::string_view getPCName() const override; - std::string_view getPCRace() const override; + std::string_view getPCRace() const override; - std::string_view getPCClass() const override; + std::string_view getPCClass() const override; - std::string_view getPCRank() const override; + std::string_view getPCRank() const override; - std::string_view getPCNextRank() const override; + std::string_view getPCNextRank() const override; - int getPCBounty() const override; + int getPCBounty() const override; - std::string_view getCurrentCellName() const override; + std::string_view getCurrentCellName() const override; - void executeActivation(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor); - ///< Execute the activation action for this ptr. If ptr is mActivated, mark activation as handled. + void executeActivation(const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor); + ///< Execute the activation action for this ptr. If ptr is mActivated, mark activation as handled. - int getMemberShort(std::string_view id, std::string_view name, bool global) const override; + int getMemberShort(std::string_view id, std::string_view name, bool global) const override; - int getMemberLong(std::string_view id, std::string_view name, bool global) const override; + int getMemberLong(std::string_view id, std::string_view name, bool global) const override; - float getMemberFloat(std::string_view id, std::string_view name, bool global) const override; + float getMemberFloat(std::string_view id, std::string_view name, bool global) const override; - void setMemberShort(std::string_view id, std::string_view name, int value, bool global) override; + void setMemberShort(std::string_view id, std::string_view name, int value, bool global) override; - void setMemberLong(std::string_view id, std::string_view name, int value, bool global) override; + void setMemberLong(std::string_view id, std::string_view name, int value, bool global) override; - void setMemberFloat(std::string_view id, std::string_view name, float value, bool global) override; + void setMemberFloat(std::string_view id, std::string_view name, float value, bool global) override; - MWWorld::Ptr getReference(bool required=true) const; - ///< Reference, that the script is running from (can be empty) + MWWorld::Ptr getReference(bool required = true) const; + ///< Reference, that the script is running from (can be empty) - void updatePtr(const MWWorld::Ptr& base, const MWWorld::Ptr& updated); - ///< Update the Ptr stored in mReference, if there is one stored there. Should be called after the reference has been moved to a new cell. + void updatePtr(const MWWorld::Ptr& base, const MWWorld::Ptr& updated); + ///< Update the Ptr stored in mReference, if there is one stored there. Should be called after the reference has + ///< been moved to a new cell. }; } diff --git a/apps/openmw/mwscript/locals.cpp b/apps/openmw/mwscript/locals.cpp index 3fa91bf5e2..a89d1a3057 100644 --- a/apps/openmw/mwscript/locals.cpp +++ b/apps/openmw/mwscript/locals.cpp @@ -1,11 +1,11 @@ #include "locals.hpp" #include "globalscripts.hpp" +#include +#include #include -#include #include -#include -#include +#include #include "../mwbase/environment.hpp" #include "../mwbase/scriptmanager.hpp" @@ -19,22 +19,26 @@ namespace MWScript { if (!mInitialised) { - const ESM::Script *script = MWBase::Environment::get().getWorld()->getStore(). - get().find (scriptName); + const ESM::Script* script + = MWBase::Environment::get().getWorld()->getStore().get().find(scriptName); - configure (*script); + configure(*script); } } - Locals::Locals() : mInitialised (false) {} + Locals::Locals() + : mInitialised(false) + { + } - bool Locals::configure (const ESM::Script& script) + bool Locals::configure(const ESM::Script& script) { if (mInitialised) return false; - const Locals* global = MWBase::Environment::get().getScriptManager()->getGlobalScripts().getLocalsIfPresent(script.mId); - if(global) + const Locals* global + = MWBase::Environment::get().getScriptManager()->getGlobalScripts().getLocalsIfPresent(script.mId); + if (global) { mShorts = global->mShorts; mLongs = global->mLongs; @@ -42,15 +46,14 @@ namespace MWScript } else { - const Compiler::Locals& locals = - MWBase::Environment::get().getScriptManager()->getLocals (script.mId); + const Compiler::Locals& locals = MWBase::Environment::get().getScriptManager()->getLocals(script.mId); mShorts.clear(); - mShorts.resize (locals.get ('s').size(), 0); + mShorts.resize(locals.get('s').size(), 0); mLongs.clear(); - mLongs.resize (locals.get ('l').size(), 0); + mLongs.resize(locals.get('l').size(), 0); mFloats.clear(); - mFloats.resize (locals.get ('f').size(), 0); + mFloats.resize(locals.get('f').size(), 0); } mInitialised = true; @@ -64,30 +67,29 @@ namespace MWScript bool Locals::hasVar(std::string_view script, std::string_view var) { - ensure (script); + ensure(script); - const Compiler::Locals& locals = - MWBase::Environment::get().getScriptManager()->getLocals(script); + const Compiler::Locals& locals = MWBase::Environment::get().getScriptManager()->getLocals(script); int index = locals.getIndex(var); return (index != -1); } int Locals::getIntVar(std::string_view script, std::string_view var) { - ensure (script); + ensure(script); const Compiler::Locals& locals = MWBase::Environment::get().getScriptManager()->getLocals(script); int index = locals.getIndex(var); char type = locals.getType(var); - if(index != -1) + if (index != -1) { - switch(type) + switch (type) { case 's': - return mShorts.at (index); + return mShorts.at(index); case 'l': - return mLongs.at (index); + return mLongs.at(index); case 'f': return static_cast(mFloats.at(index)); @@ -100,20 +102,20 @@ namespace MWScript float Locals::getFloatVar(std::string_view script, std::string_view var) { - ensure (script); + ensure(script); const Compiler::Locals& locals = MWBase::Environment::get().getScriptManager()->getLocals(script); int index = locals.getIndex(var); char type = locals.getType(var); - if(index != -1) + if (index != -1) { - switch(type) + switch (type) { case 's': - return mShorts.at (index); + return mShorts.at(index); case 'l': - return mLongs.at (index); + return mLongs.at(index); case 'f': return mFloats.at(index); @@ -126,23 +128,26 @@ namespace MWScript bool Locals::setVarByInt(std::string_view script, std::string_view var, int val) { - ensure (script); + ensure(script); const Compiler::Locals& locals = MWBase::Environment::get().getScriptManager()->getLocals(script); int index = locals.getIndex(var); char type = locals.getType(var); - if(index != -1) + if (index != -1) { - switch(type) + switch (type) { case 's': - mShorts.at (index) = val; break; + mShorts.at(index) = val; + break; case 'l': - mLongs.at (index) = val; break; + mLongs.at(index) = val; + break; case 'f': - mFloats.at(index) = static_cast(val); break; + mFloats.at(index) = static_cast(val); + break; } return true; } @@ -154,34 +159,48 @@ namespace MWScript if (!mInitialised) return false; - const Compiler::Locals& declarations = - MWBase::Environment::get().getScriptManager()->getLocals(script); + const Compiler::Locals& declarations = MWBase::Environment::get().getScriptManager()->getLocals(script); - for (int i=0; i<3; ++i) + for (int i = 0; i < 3; ++i) { char type = 0; switch (i) { - case 0: type = 's'; break; - case 1: type = 'l'; break; - case 2: type = 'f'; break; + case 0: + type = 's'; + break; + case 1: + type = 'l'; + break; + case 2: + type = 'f'; + break; } - const std::vector& names = declarations.get (type); + const std::vector& names = declarations.get(type); - for (int i2=0; i2 (names.size()); ++i2) + for (int i2 = 0; i2 < static_cast(names.size()); ++i2) { ESM::Variant value; switch (i) { - case 0: value.setType (ESM::VT_Int); value.setInteger (mShorts.at (i2)); break; - case 1: value.setType (ESM::VT_Int); value.setInteger (mLongs.at (i2)); break; - case 2: value.setType (ESM::VT_Float); value.setFloat (mFloats.at (i2)); break; + case 0: + value.setType(ESM::VT_Int); + value.setInteger(mShorts.at(i2)); + break; + case 1: + value.setType(ESM::VT_Int); + value.setInteger(mLongs.at(i2)); + break; + case 2: + value.setType(ESM::VT_Float); + value.setFloat(mFloats.at(i2)); + break; } - locals.mVariables.emplace_back (names[i2], value); + locals.mVariables.emplace_back(names[i2], value); } } @@ -190,13 +209,12 @@ namespace MWScript void Locals::read(const ESM::Locals& locals, std::string_view script) { - ensure (script); + ensure(script); - const Compiler::Locals& declarations = - MWBase::Environment::get().getScriptManager()->getLocals(script); + const Compiler::Locals& declarations = MWBase::Environment::get().getScriptManager()->getLocals(script); int index = 0, numshorts = 0, numlongs = 0; - for (unsigned int v=0; v >::const_iterator iter - = locals.mVariables.begin(); iter!=locals.mVariables.end(); ++iter,++index) + for (std::vector>::const_iterator iter = locals.mVariables.begin(); + iter != locals.mVariables.end(); ++iter, ++index) { if (iter->first.empty()) { // no variable names available (this will happen for legacy, i.e. ESS-imported savegames only) try { - if (index >= numshorts+numlongs) - mFloats.at(index - (numshorts+numlongs)) = iter->second.getFloat(); + if (index >= numshorts + numlongs) + mFloats.at(index - (numshorts + numlongs)) = iter->second.getFloat(); else if (index >= numshorts) mLongs.at(index - numshorts) = iter->second.getInteger(); else @@ -222,16 +240,15 @@ namespace MWScript } catch (std::exception& e) { - Log(Debug::Error) << "Failed to read local variable state for script '" - << script << "' (legacy format): " << e.what() - << "\nNum shorts: " << numshorts << " / " << mShorts.size() - << " Num longs: " << numlongs << " / " << mLongs.size(); + Log(Debug::Error) << "Failed to read local variable state for script '" << script + << "' (legacy format): " << e.what() << "\nNum shorts: " << numshorts << " / " + << mShorts.size() << " Num longs: " << numlongs << " / " << mLongs.size(); } } else { - char type = declarations.getType (iter->first); - int index2 = declarations.getIndex (iter->first); + char type = declarations.getType(iter->first); + int index2 = declarations.getIndex(iter->first); // silently ignore locals that don't exist anymore if (type == ' ' || index2 == -1) @@ -241,9 +258,15 @@ namespace MWScript { switch (type) { - case 's': mShorts.at (index2) = iter->second.getInteger(); break; - case 'l': mLongs.at (index2) = iter->second.getInteger(); break; - case 'f': mFloats.at (index2) = iter->second.getFloat(); break; + case 's': + mShorts.at(index2) = iter->second.getInteger(); + break; + case 'l': + mLongs.at(index2) = iter->second.getInteger(); + break; + case 'f': + mFloats.at(index2) = iter->second.getFloat(); + break; } } catch (...) diff --git a/apps/openmw/mwscript/locals.hpp b/apps/openmw/mwscript/locals.hpp index 3eac2c71e6..dfb8e32fac 100644 --- a/apps/openmw/mwscript/locals.hpp +++ b/apps/openmw/mwscript/locals.hpp @@ -17,55 +17,55 @@ namespace MWScript { class Locals { - bool mInitialised; - - void ensure(std::string_view scriptName); - - public: - std::vector mShorts; - std::vector mLongs; - std::vector mFloats; - - Locals(); - - /// Are there any locals? - /// - /// \note Will return false, if locals have not been configured yet. - bool isEmpty() const; - - /// \return Did the state of *this change from uninitialised to initialised? - bool configure (const ESM::Script& script); - - /// @note var needs to be in lowercase - /// - /// \note Locals will be automatically configured first, if necessary - bool setVarByInt(std::string_view script, std::string_view var, int val); - - /// \note Locals will be automatically configured first, if necessary - // - // \note If it can not be determined if the variable exists, the error will be - // ignored and false will be returned. - bool hasVar(std::string_view script, std::string_view var); - - /// if var does not exist, returns 0 - /// @note var needs to be in lowercase - /// - /// \note Locals will be automatically configured first, if necessary - int getIntVar(std::string_view script, std::string_view var); - - /// if var does not exist, returns 0 - /// @note var needs to be in lowercase - /// - /// \note Locals will be automatically configured first, if necessary - float getFloatVar(std::string_view script, std::string_view var); - - /// \note If locals have not been configured yet, no data is written. - /// - /// \return Locals written? - bool write(ESM::Locals& locals, std::string_view script) const; - - /// \note Locals will be automatically configured first, if necessary - void read(const ESM::Locals& locals, std::string_view script); + bool mInitialised; + + void ensure(std::string_view scriptName); + + public: + std::vector mShorts; + std::vector mLongs; + std::vector mFloats; + + Locals(); + + /// Are there any locals? + /// + /// \note Will return false, if locals have not been configured yet. + bool isEmpty() const; + + /// \return Did the state of *this change from uninitialised to initialised? + bool configure(const ESM::Script& script); + + /// @note var needs to be in lowercase + /// + /// \note Locals will be automatically configured first, if necessary + bool setVarByInt(std::string_view script, std::string_view var, int val); + + /// \note Locals will be automatically configured first, if necessary + // + // \note If it can not be determined if the variable exists, the error will be + // ignored and false will be returned. + bool hasVar(std::string_view script, std::string_view var); + + /// if var does not exist, returns 0 + /// @note var needs to be in lowercase + /// + /// \note Locals will be automatically configured first, if necessary + int getIntVar(std::string_view script, std::string_view var); + + /// if var does not exist, returns 0 + /// @note var needs to be in lowercase + /// + /// \note Locals will be automatically configured first, if necessary + float getFloatVar(std::string_view script, std::string_view var); + + /// \note If locals have not been configured yet, no data is written. + /// + /// \return Locals written? + bool write(ESM::Locals& locals, std::string_view script) const; + + /// \note Locals will be automatically configured first, if necessary + void read(const ESM::Locals& locals, std::string_view script); }; } diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index 2f2ce1b9b1..604fc06fe4 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -1,54 +1,54 @@ #include "miscextensions.hpp" +#include #include #include -#include #include #include -#include #include +#include #include #include -#include #include +#include -#include #include +#include #include -#include #include -#include #include +#include +#include -#include #include +#include #include "../mwbase/environment.hpp" -#include "../mwbase/windowmanager.hpp" +#include "../mwbase/luamanager.hpp" #include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/scriptmanager.hpp" #include "../mwbase/soundmanager.hpp" +#include "../mwbase/windowmanager.hpp" #include "../mwbase/world.hpp" -#include "../mwbase/luamanager.hpp" +#include "../mwworld/cellstore.hpp" #include "../mwworld/class.hpp" -#include "../mwworld/player.hpp" #include "../mwworld/containerstore.hpp" -#include "../mwworld/inventorystore.hpp" #include "../mwworld/esmstore.hpp" -#include "../mwworld/cellstore.hpp" +#include "../mwworld/inventorystore.hpp" #include "../mwworld/manualref.hpp" +#include "../mwworld/player.hpp" +#include "../mwmechanics/actorutil.hpp" #include "../mwmechanics/aicast.hpp" -#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/creaturestats.hpp" +#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/spellcasting.hpp" -#include "../mwmechanics/actorutil.hpp" #include "../mwrender/animation.hpp" @@ -97,121 +97,110 @@ namespace MWScript { class OpMenuMode : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - runtime.push (MWBase::Environment::get().getWindowManager()->isGuiMode()); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + runtime.push(MWBase::Environment::get().getWindowManager()->isGuiMode()); + } }; class OpRandom : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - Interpreter::Type_Integer limit = runtime[0].mInteger; - runtime.pop(); + public: + void execute(Interpreter::Runtime& runtime) override + { + Interpreter::Type_Integer limit = runtime[0].mInteger; + runtime.pop(); - if (limit<0) - throw std::runtime_error ( - "random: argument out of range (Don't be so negative!)"); + if (limit < 0) + throw std::runtime_error("random: argument out of range (Don't be so negative!)"); - auto& prng = MWBase::Environment::get().getWorld()->getPrng(); - runtime.push (static_cast(::Misc::Rng::rollDice(limit, prng))); // [o, limit) - } + auto& prng = MWBase::Environment::get().getWorld()->getPrng(); + runtime.push(static_cast(::Misc::Rng::rollDice(limit, prng))); // [o, limit) + } }; - template + template class OpStartScript : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr target = R()(runtime, false); - std::string_view name = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); - MWBase::Environment::get().getScriptManager()->getGlobalScripts().addScript (name, target); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr target = R()(runtime, false); + std::string_view name = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); + MWBase::Environment::get().getScriptManager()->getGlobalScripts().addScript(name, target); + } }; class OpScriptRunning : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - std::string_view name = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); - runtime.push(MWBase::Environment::get().getScriptManager()->getGlobalScripts().isRunning (name)); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + std::string_view name = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); + runtime.push(MWBase::Environment::get().getScriptManager()->getGlobalScripts().isRunning(name)); + } }; class OpStopScript : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - std::string_view name = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); - MWBase::Environment::get().getScriptManager()->getGlobalScripts().removeScript (name); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + std::string_view name = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); + MWBase::Environment::get().getScriptManager()->getGlobalScripts().removeScript(name); + } }; class OpGetSecondsPassed : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - runtime.push (MWBase::Environment::get().getFrameDuration()); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + runtime.push(MWBase::Environment::get().getFrameDuration()); + } }; - template + template class OpEnable : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); - MWBase::Environment::get().getWorld()->enable (ptr); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); + MWBase::Environment::get().getWorld()->enable(ptr); + } }; - template + template class OpDisable : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); - MWBase::Environment::get().getWorld()->disable (ptr); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); + MWBase::Environment::get().getWorld()->disable(ptr); + } }; - template + template class OpGetDisabled : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); - runtime.push (!ptr.getRefData().isEnabled()); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); + runtime.push(!ptr.getRefData().isEnabled()); + } }; class OpPlayBink : public Interpreter::Opcode0 { public: - - void execute (Interpreter::Runtime& runtime) override + void execute(Interpreter::Runtime& runtime) override { std::string_view name = runtime.getStringLiteral(runtime[0].mInteger); runtime.pop(); @@ -219,275 +208,244 @@ namespace MWScript bool allowSkipping = runtime[0].mInteger != 0; runtime.pop(); - MWBase::Environment::get().getWindowManager()->playVideo (name, allowSkipping); + MWBase::Environment::get().getWindowManager()->playVideo(name, allowSkipping); } }; class OpGetPcSleep : public Interpreter::Opcode0 { public: - - void execute (Interpreter::Runtime& runtime) override + void execute(Interpreter::Runtime& runtime) override { - runtime.push (MWBase::Environment::get().getWindowManager ()->getPlayerSleeping()); + runtime.push(MWBase::Environment::get().getWindowManager()->getPlayerSleeping()); } }; class OpGetPcJumping : public Interpreter::Opcode0 { public: - - void execute (Interpreter::Runtime& runtime) override + void execute(Interpreter::Runtime& runtime) override { MWBase::World* world = MWBase::Environment::get().getWorld(); - runtime.push (world->getPlayer().getJumping()); + runtime.push(world->getPlayer().getJumping()); } }; class OpWakeUpPc : public Interpreter::Opcode0 { public: - - void execute (Interpreter::Runtime& runtime) override + void execute(Interpreter::Runtime& runtime) override { - MWBase::Environment::get().getWindowManager ()->wakeUpPlayer(); + MWBase::Environment::get().getWindowManager()->wakeUpPlayer(); } }; class OpXBox : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - runtime.push (0); - } + public: + void execute(Interpreter::Runtime& runtime) override { runtime.push(0); } }; template class OpOnActivate : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - runtime.push (ptr.getRefData().onActivate()); - } + runtime.push(ptr.getRefData().onActivate()); + } }; template class OpActivate : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - InterpreterContext& context = - static_cast (runtime.getContext()); + public: + void execute(Interpreter::Runtime& runtime) override + { + InterpreterContext& context = static_cast(runtime.getContext()); - MWWorld::Ptr ptr = R()(runtime); + MWWorld::Ptr ptr = R()(runtime); - if (ptr.getRefData().activateByScript() || ptr.getContainerStore()) - context.executeActivation(ptr, MWMechanics::getPlayer()); - } + if (ptr.getRefData().activateByScript() || ptr.getContainerStore()) + context.executeActivation(ptr, MWMechanics::getPlayer()); + } }; - template + template class OpLock : public Interpreter::Opcode1 { - public: - - void execute (Interpreter::Runtime& runtime, unsigned int arg0) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime, unsigned int arg0) override + { + MWWorld::Ptr ptr = R()(runtime); - Interpreter::Type_Integer lockLevel = ptr.getCellRef().getLockLevel(); - if(lockLevel==0) { //no lock level was ever set, set to 100 as default - lockLevel = 100; - } + Interpreter::Type_Integer lockLevel = ptr.getCellRef().getLockLevel(); + if (lockLevel == 0) + { // no lock level was ever set, set to 100 as default + lockLevel = 100; + } - if (arg0==1) - { - lockLevel = runtime[0].mInteger; - runtime.pop(); - } + if (arg0 == 1) + { + lockLevel = runtime[0].mInteger; + runtime.pop(); + } - ptr.getCellRef().lock (lockLevel); + ptr.getCellRef().lock(lockLevel); - // Instantly reset door to closed state - // This is done when using Lock in scripts, but not when using Lock spells. - if (ptr.getType() == ESM::Door::sRecordId && !ptr.getCellRef().getTeleport()) - { - MWBase::Environment::get().getWorld()->activateDoor(ptr, MWWorld::DoorState::Idle); - } + // Instantly reset door to closed state + // This is done when using Lock in scripts, but not when using Lock spells. + if (ptr.getType() == ESM::Door::sRecordId && !ptr.getCellRef().getTeleport()) + { + MWBase::Environment::get().getWorld()->activateDoor(ptr, MWWorld::DoorState::Idle); } + } }; - template + template class OpUnlock : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - ptr.getCellRef().unlock (); - } + ptr.getCellRef().unlock(); + } }; class OpToggleCollisionDebug : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - bool enabled = - MWBase::Environment::get().getWorld()->toggleRenderMode (MWRender::Render_CollisionDebug); + public: + void execute(Interpreter::Runtime& runtime) override + { + bool enabled = MWBase::Environment::get().getWorld()->toggleRenderMode(MWRender::Render_CollisionDebug); - runtime.getContext().report (enabled ? - "Collision Mesh Rendering -> On" : "Collision Mesh Rendering -> Off"); - } + runtime.getContext().report( + enabled ? "Collision Mesh Rendering -> On" : "Collision Mesh Rendering -> Off"); + } }; - class OpToggleCollisionBoxes : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - bool enabled = - MWBase::Environment::get().getWorld()->toggleRenderMode (MWRender::Render_CollisionDebug); + public: + void execute(Interpreter::Runtime& runtime) override + { + bool enabled = MWBase::Environment::get().getWorld()->toggleRenderMode(MWRender::Render_CollisionDebug); - runtime.getContext().report (enabled ? - "Collision Mesh Rendering -> On" : "Collision Mesh Rendering -> Off"); - } + runtime.getContext().report( + enabled ? "Collision Mesh Rendering -> On" : "Collision Mesh Rendering -> Off"); + } }; class OpToggleWireframe : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - bool enabled = - MWBase::Environment::get().getWorld()->toggleRenderMode (MWRender::Render_Wireframe); + public: + void execute(Interpreter::Runtime& runtime) override + { + bool enabled = MWBase::Environment::get().getWorld()->toggleRenderMode(MWRender::Render_Wireframe); - runtime.getContext().report (enabled ? - "Wireframe Rendering -> On" : "Wireframe Rendering -> Off"); - } + runtime.getContext().report(enabled ? "Wireframe Rendering -> On" : "Wireframe Rendering -> Off"); + } }; class OpToggleBorders : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - bool enabled = - MWBase::Environment::get().getWorld()->toggleBorders(); + public: + void execute(Interpreter::Runtime& runtime) override + { + bool enabled = MWBase::Environment::get().getWorld()->toggleBorders(); - runtime.getContext().report (enabled ? - "Border Rendering -> On" : "Border Rendering -> Off"); - } + runtime.getContext().report(enabled ? "Border Rendering -> On" : "Border Rendering -> Off"); + } }; class OpTogglePathgrid : public Interpreter::Opcode0 { public: - void execute (Interpreter::Runtime& runtime) override + void execute(Interpreter::Runtime& runtime) override { - bool enabled = - MWBase::Environment::get().getWorld()->toggleRenderMode (MWRender::Render_Pathgrid); + bool enabled = MWBase::Environment::get().getWorld()->toggleRenderMode(MWRender::Render_Pathgrid); - runtime.getContext().report (enabled ? - "Path Grid rendering -> On" : "Path Grid Rendering -> Off"); + runtime.getContext().report(enabled ? "Path Grid rendering -> On" : "Path Grid Rendering -> Off"); } }; class OpFadeIn : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - Interpreter::Type_Float time = runtime[0].mFloat; - runtime.pop(); + public: + void execute(Interpreter::Runtime& runtime) override + { + Interpreter::Type_Float time = runtime[0].mFloat; + runtime.pop(); - MWBase::Environment::get().getWindowManager()->fadeScreenIn(time, false); - } + MWBase::Environment::get().getWindowManager()->fadeScreenIn(time, false); + } }; class OpFadeOut : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - Interpreter::Type_Float time = runtime[0].mFloat; - runtime.pop(); + public: + void execute(Interpreter::Runtime& runtime) override + { + Interpreter::Type_Float time = runtime[0].mFloat; + runtime.pop(); - MWBase::Environment::get().getWindowManager()->fadeScreenOut(time, false); - } + MWBase::Environment::get().getWindowManager()->fadeScreenOut(time, false); + } }; class OpFadeTo : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - Interpreter::Type_Float alpha = runtime[0].mFloat; - runtime.pop(); + public: + void execute(Interpreter::Runtime& runtime) override + { + Interpreter::Type_Float alpha = runtime[0].mFloat; + runtime.pop(); - Interpreter::Type_Float time = runtime[0].mFloat; - runtime.pop(); + Interpreter::Type_Float time = runtime[0].mFloat; + runtime.pop(); - MWBase::Environment::get().getWindowManager()->fadeScreenTo(static_cast(alpha), time, false); - } + MWBase::Environment::get().getWindowManager()->fadeScreenTo(static_cast(alpha), time, false); + } }; class OpToggleWater : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - runtime.getContext().report(MWBase::Environment::get().getWorld()->toggleWater() ? "Water -> On" - : "Water -> Off"); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + runtime.getContext().report( + MWBase::Environment::get().getWorld()->toggleWater() ? "Water -> On" : "Water -> Off"); + } }; class OpToggleWorld : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - runtime.getContext().report(MWBase::Environment::get().getWorld()->toggleWorld() ? "World -> On" - : "World -> Off"); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + runtime.getContext().report( + MWBase::Environment::get().getWorld()->toggleWorld() ? "World -> On" : "World -> Off"); + } }; class OpDontSaveObject : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - // We are ignoring the DontSaveObject statement for now. Probably not worth - // bothering with. The incompatibility we are creating should be marginal at most. - } + public: + void execute(Interpreter::Runtime& runtime) override + { + // We are ignoring the DontSaveObject statement for now. Probably not worth + // bothering with. The incompatibility we are creating should be marginal at most. + } }; class OpPcForce1stPerson : public Interpreter::Opcode0 { public: - - void execute (Interpreter::Runtime& runtime) override + void execute(Interpreter::Runtime& runtime) override { if (!MWBase::Environment::get().getWorld()->isFirstPerson()) MWBase::Environment::get().getWorld()->togglePOV(true); @@ -496,7 +454,7 @@ namespace MWScript class OpPcForce3rdPerson : public Interpreter::Opcode0 { - void execute (Interpreter::Runtime& runtime) override + void execute(Interpreter::Runtime& runtime) override { if (MWBase::Environment::get().getWorld()->isFirstPerson()) MWBase::Environment::get().getWorld()->togglePOV(true); @@ -517,16 +475,17 @@ namespace MWScript static bool sActivate; public: - - void execute(Interpreter::Runtime &runtime) override + void execute(Interpreter::Runtime& runtime) override { - MWBase::World *world = - MWBase::Environment::get().getWorld(); + MWBase::World* world = MWBase::Environment::get().getWorld(); - if (world->toggleVanityMode(sActivate)) { + if (world->toggleVanityMode(sActivate)) + { runtime.getContext().report(sActivate ? "Vanity Mode -> On" : "Vanity Mode -> Off"); sActivate = !sActivate; - } else { + } + else + { runtime.getContext().report("Vanity Mode -> No"); } } @@ -536,314 +495,308 @@ namespace MWScript template class OpGetLocked : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - runtime.push (ptr.getCellRef().getLockLevel() > 0); - } + runtime.push(ptr.getCellRef().getLockLevel() > 0); + } }; template class OpGetEffect : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - std::string_view effect = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + std::string_view effect = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - if (!ptr.getClass().isActor()) - { - runtime.push(0); - return; - } + if (!ptr.getClass().isActor()) + { + runtime.push(0); + return; + } - char *end; - long key = strtol(effect.data(), &end, 10); - if(key < 0 || key > 32767 || *end != '\0') - key = ESM::MagicEffect::effectStringToId({effect}); + char* end; + long key = strtol(effect.data(), &end, 10); + if (key < 0 || key > 32767 || *end != '\0') + key = ESM::MagicEffect::effectStringToId({ effect }); - const MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); + const MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); - const MWMechanics::MagicEffects& effects = stats.getMagicEffects(); + const MWMechanics::MagicEffects& effects = stats.getMagicEffects(); - for (const auto& activeEffect : effects) + for (const auto& activeEffect : effects) + { + if (activeEffect.first.mId == key && activeEffect.second.getModifier() > 0) { - if (activeEffect.first.mId == key && activeEffect.second.getModifier() > 0) - { - runtime.push(1); - return; - } + runtime.push(1); + return; } - runtime.push(0); - } + } + runtime.push(0); + } }; - template + template class OpAddSoulGem : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - std::string_view creature = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + std::string_view creature = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - std::string_view gem = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + std::string_view gem = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - if (!ptr.getClass().hasInventoryStore(ptr)) - return; + if (!ptr.getClass().hasInventoryStore(ptr)) + return; - const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); - store.get().find(creature); // This line throws an exception if it can't find the creature + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + store.get().find( + creature); // This line throws an exception if it can't find the creature - MWWorld::Ptr item = *ptr.getClass().getContainerStore(ptr).add(gem, 1, ptr); + MWWorld::Ptr item = *ptr.getClass().getContainerStore(ptr).add(gem, 1, ptr); - // Set the soul on just one of the gems, not the whole stack - item.getContainerStore()->unstack(item, ptr); - item.getCellRef().setSoul(creature); + // Set the soul on just one of the gems, not the whole stack + item.getContainerStore()->unstack(item, ptr); + item.getCellRef().setSoul(creature); - // Restack the gem with other gems with the same soul - item.getContainerStore()->restack(item); - } + // Restack the gem with other gems with the same soul + item.getContainerStore()->restack(item); + } }; - template + template class OpRemoveSoulGem : public Interpreter::Opcode1 { - public: + public: + void execute(Interpreter::Runtime& runtime, unsigned int arg0) override + { + MWWorld::Ptr ptr = R()(runtime); - void execute (Interpreter::Runtime& runtime, unsigned int arg0) override - { - MWWorld::Ptr ptr = R()(runtime); + std::string_view soul = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - std::string_view soul = runtime.getStringLiteral(runtime[0].mInteger); + // throw away additional arguments + for (unsigned int i = 0; i < arg0; ++i) runtime.pop(); - // throw away additional arguments - for (unsigned int i=0; igetCellRef().getSoul(), soul)) { - if (::Misc::StringUtils::ciEqual(it->getCellRef().getSoul(), soul)) - { - store.remove(*it, 1, ptr); - return; - } + store.remove(*it, 1, ptr); + return; } } + } }; - template + template class OpDrop : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { + public: + void execute(Interpreter::Runtime& runtime) override + { - MWWorld::Ptr ptr = R()(runtime); + MWWorld::Ptr ptr = R()(runtime); - std::string_view item = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + std::string_view item = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - Interpreter::Type_Integer amount = runtime[0].mInteger; - runtime.pop(); + Interpreter::Type_Integer amount = runtime[0].mInteger; + runtime.pop(); - if (amount<0) - throw std::runtime_error ("amount must be non-negative"); + if (amount < 0) + throw std::runtime_error("amount must be non-negative"); - // no-op - if (amount == 0) - return; + // no-op + if (amount == 0) + return; - if (!ptr.getClass().isActor()) - return; + if (!ptr.getClass().isActor()) + return; - if (ptr.getClass().hasInventoryStore(ptr)) + if (ptr.getClass().hasInventoryStore(ptr)) + { + // Prefer dropping unequipped items first; re-stack if possible by unequipping items before dropping + // them. + MWWorld::InventoryStore& store = ptr.getClass().getInventoryStore(ptr); + int numNotEquipped = store.count(item); + for (int slot = 0; slot < MWWorld::InventoryStore::Slots; ++slot) { - // Prefer dropping unequipped items first; re-stack if possible by unequipping items before dropping them. - MWWorld::InventoryStore& store = ptr.getClass().getInventoryStore(ptr); - int numNotEquipped = store.count(item); - for (int slot = 0; slot < MWWorld::InventoryStore::Slots; ++slot) + MWWorld::ConstContainerStoreIterator it = store.getSlot(slot); + if (it != store.end() && ::Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), item)) { - MWWorld::ConstContainerStoreIterator it = store.getSlot (slot); - if (it != store.end() && ::Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), item)) - { - numNotEquipped -= it->getRefData().getCount(); - } + numNotEquipped -= it->getRefData().getCount(); } + } - for (int slot = 0; slot < MWWorld::InventoryStore::Slots && amount > numNotEquipped; ++slot) + for (int slot = 0; slot < MWWorld::InventoryStore::Slots && amount > numNotEquipped; ++slot) + { + MWWorld::ContainerStoreIterator it = store.getSlot(slot); + if (it != store.end() && ::Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), item)) { - MWWorld::ContainerStoreIterator it = store.getSlot (slot); - if (it != store.end() && ::Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), item)) - { - int numToRemove = std::min(amount - numNotEquipped, it->getRefData().getCount()); - store.unequipItemQuantity(*it, ptr, numToRemove); - numNotEquipped += numToRemove; - } + int numToRemove = std::min(amount - numNotEquipped, it->getRefData().getCount()); + store.unequipItemQuantity(*it, ptr, numToRemove); + numNotEquipped += numToRemove; } + } - for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter) + for (MWWorld::ContainerStoreIterator iter(store.begin()); iter != store.end(); ++iter) + { + if (::Misc::StringUtils::ciEqual(iter->getCellRef().getRefId(), item) + && !store.isEquipped(*iter)) { - if (::Misc::StringUtils::ciEqual(iter->getCellRef().getRefId(), item) && !store.isEquipped(*iter)) - { - int removed = store.remove(*iter, amount, ptr); - MWWorld::Ptr dropped = MWBase::Environment::get().getWorld()->dropObjectOnGround(ptr, *iter, removed); - dropped.getCellRef().setOwner(""); + int removed = store.remove(*iter, amount, ptr); + MWWorld::Ptr dropped + = MWBase::Environment::get().getWorld()->dropObjectOnGround(ptr, *iter, removed); + dropped.getCellRef().setOwner(""); - amount -= removed; + amount -= removed; - if (amount <= 0) - break; - } + if (amount <= 0) + break; } } + } - MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), item, 1); - MWWorld::Ptr itemPtr(ref.getPtr()); - if (amount > 0) + MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), item, 1); + MWWorld::Ptr itemPtr(ref.getPtr()); + if (amount > 0) + { + if (itemPtr.getClass().getScript(itemPtr).empty()) { - if (itemPtr.getClass().getScript(itemPtr).empty()) - { - MWBase::Environment::get().getWorld()->dropObjectOnGround(ptr, itemPtr, amount); - } - else - { - // Dropping one item per time to prevent making stacks of scripted items - for (int i = 0; i < amount; i++) - MWBase::Environment::get().getWorld()->dropObjectOnGround(ptr, itemPtr, 1); - } + MWBase::Environment::get().getWorld()->dropObjectOnGround(ptr, itemPtr, amount); + } + else + { + // Dropping one item per time to prevent making stacks of scripted items + for (int i = 0; i < amount; i++) + MWBase::Environment::get().getWorld()->dropObjectOnGround(ptr, itemPtr, 1); } - - MWBase::Environment::get().getSoundManager()->playSound3D(ptr, itemPtr.getClass().getDownSoundId(itemPtr), 1.f, 1.f); } + + MWBase::Environment::get().getSoundManager()->playSound3D( + ptr, itemPtr.getClass().getDownSoundId(itemPtr), 1.f, 1.f); + } }; - template + template class OpDropSoulGem : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { + public: + void execute(Interpreter::Runtime& runtime) override + { - MWWorld::Ptr ptr = R()(runtime); + MWWorld::Ptr ptr = R()(runtime); - std::string_view soul = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + std::string_view soul = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - if (!ptr.getClass().hasInventoryStore(ptr)) - return; + if (!ptr.getClass().hasInventoryStore(ptr)) + return; - MWWorld::InventoryStore& store = ptr.getClass().getInventoryStore(ptr); + MWWorld::InventoryStore& store = ptr.getClass().getInventoryStore(ptr); - for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter) + for (MWWorld::ContainerStoreIterator iter(store.begin()); iter != store.end(); ++iter) + { + if (::Misc::StringUtils::ciEqual(iter->getCellRef().getSoul(), soul)) { - if (::Misc::StringUtils::ciEqual(iter->getCellRef().getSoul(), soul)) - { - MWBase::Environment::get().getWorld()->dropObjectOnGround(ptr, *iter, 1); - store.remove(*iter, 1, ptr); - break; - } + MWBase::Environment::get().getWorld()->dropObjectOnGround(ptr, *iter, 1); + store.remove(*iter, 1, ptr); + break; } } + } }; template class OpGetAttacked : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - runtime.push(ptr.getClass().getCreatureStats (ptr).getAttacked ()); - } + runtime.push(ptr.getClass().getCreatureStats(ptr).getAttacked()); + } }; template class OpGetWeaponDrawn : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); + auto& cls = ptr.getClass(); + if (!cls.hasInventoryStore(ptr) && !cls.isBipedal(ptr)) { - MWWorld::Ptr ptr = R()(runtime); - auto& cls = ptr.getClass(); - if (!cls.hasInventoryStore(ptr) && !cls.isBipedal(ptr)) - { - runtime.push(0); - return; - } - - if (cls.getCreatureStats(ptr).getDrawState () != MWMechanics::DrawState::Weapon) - { - runtime.push(0); - return; - } + runtime.push(0); + return; + } - MWRender::Animation* anim = MWBase::Environment::get().getWorld()->getAnimation(ptr); - runtime.push(anim && anim->getWeaponsShown()); + if (cls.getCreatureStats(ptr).getDrawState() != MWMechanics::DrawState::Weapon) + { + runtime.push(0); + return; } + + MWRender::Animation* anim = MWBase::Environment::get().getWorld()->getAnimation(ptr); + runtime.push(anim && anim->getWeaponsShown()); + } }; template class OpGetSpellReadied : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - runtime.push(ptr.getClass().getCreatureStats (ptr).getDrawState () == MWMechanics::DrawState::Spell); - } + runtime.push(ptr.getClass().getCreatureStats(ptr).getDrawState() == MWMechanics::DrawState::Spell); + } }; template class OpGetSpellEffects : public Interpreter::Opcode0 { - public: + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); + std::string_view id = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - void execute (Interpreter::Runtime& runtime) override + if (!ptr.getClass().isActor()) { - MWWorld::Ptr ptr = R()(runtime); - std::string_view id = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); - - if (!ptr.getClass().isActor()) - { - runtime.push(0); - return; - } - - const MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); - runtime.push(stats.getActiveSpells().isSpellActive(id)); + runtime.push(0); + return; } + + const MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); + runtime.push(stats.getActiveSpells().isSpellActive(id)); + } }; class OpGetCurrentTime : public Interpreter::Opcode0 { public: - - void execute (Interpreter::Runtime& runtime) override + void execute(Interpreter::Runtime& runtime) override { runtime.push(MWBase::Environment::get().getWorld()->getTimeStamp().getHour()); } @@ -852,207 +805,190 @@ namespace MWScript template class OpSetDelete : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); - int parameter = runtime[0].mInteger; - runtime.pop(); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); + int parameter = runtime[0].mInteger; + runtime.pop(); - if (parameter == 1) - MWBase::Environment::get().getWorld()->deleteObject(ptr); - else if (parameter == 0) - MWBase::Environment::get().getWorld()->undeleteObject(ptr); - else - throw std::runtime_error("SetDelete: unexpected parameter"); - } + if (parameter == 1) + MWBase::Environment::get().getWorld()->deleteObject(ptr); + else if (parameter == 0) + MWBase::Environment::get().getWorld()->undeleteObject(ptr); + else + throw std::runtime_error("SetDelete: unexpected parameter"); + } }; class OpGetSquareRoot : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - float param = runtime[0].mFloat; - runtime.pop(); + public: + void execute(Interpreter::Runtime& runtime) override + { + float param = runtime[0].mFloat; + runtime.pop(); - if (param < 0) - throw std::runtime_error("square root of negative number (we aren't that imaginary)"); + if (param < 0) + throw std::runtime_error("square root of negative number (we aren't that imaginary)"); - runtime.push(std::sqrt (param)); - } + runtime.push(std::sqrt(param)); + } }; template class OpFall : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - } + public: + void execute(Interpreter::Runtime& runtime) override {} }; template class OpGetStandingPc : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); - runtime.push (MWBase::Environment::get().getWorld()->getPlayerStandingOn(ptr)); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); + runtime.push(MWBase::Environment::get().getWorld()->getPlayerStandingOn(ptr)); + } }; template class OpGetStandingActor : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); - runtime.push (MWBase::Environment::get().getWorld()->getActorStandingOn(ptr)); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); + runtime.push(MWBase::Environment::get().getWorld()->getActorStandingOn(ptr)); + } }; template class OpGetCollidingPc : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); - runtime.push (MWBase::Environment::get().getWorld()->getPlayerCollidingWith(ptr)); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); + runtime.push(MWBase::Environment::get().getWorld()->getPlayerCollidingWith(ptr)); + } }; template class OpGetCollidingActor : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); - runtime.push (MWBase::Environment::get().getWorld()->getActorCollidingWith(ptr)); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); + runtime.push(MWBase::Environment::get().getWorld()->getActorCollidingWith(ptr)); + } }; template class OpHurtStandingActor : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); - float healthDiffPerSecond = runtime[0].mFloat; - runtime.pop(); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); + float healthDiffPerSecond = runtime[0].mFloat; + runtime.pop(); - MWBase::Environment::get().getWorld()->hurtStandingActors(ptr, healthDiffPerSecond); - } + MWBase::Environment::get().getWorld()->hurtStandingActors(ptr, healthDiffPerSecond); + } }; template class OpHurtCollidingActor : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); - float healthDiffPerSecond = runtime[0].mFloat; - runtime.pop(); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); + float healthDiffPerSecond = runtime[0].mFloat; + runtime.pop(); - MWBase::Environment::get().getWorld()->hurtCollidingActors(ptr, healthDiffPerSecond); - } + MWBase::Environment::get().getWorld()->hurtCollidingActors(ptr, healthDiffPerSecond); + } }; class OpGetWindSpeed : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - runtime.push(MWBase::Environment::get().getWorld()->getWindSpeed()); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + runtime.push(MWBase::Environment::get().getWorld()->getWindSpeed()); + } }; template class OpHitOnMe : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - std::string_view objectID = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + std::string_view objectID = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - MWMechanics::CreatureStats &stats = ptr.getClass().getCreatureStats(ptr); - bool hit = ::Misc::StringUtils::ciEqual(objectID, stats.getLastHitObject()); - runtime.push(hit); - if(hit) - stats.clearLastHitObject(); - } + MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); + bool hit = ::Misc::StringUtils::ciEqual(objectID, stats.getLastHitObject()); + runtime.push(hit); + if (hit) + stats.clearLastHitObject(); + } }; template class OpHitAttemptOnMe : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - std::string_view objectID = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + std::string_view objectID = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - MWMechanics::CreatureStats &stats = ptr.getClass().getCreatureStats(ptr); - bool hit = ::Misc::StringUtils::ciEqual(objectID, stats.getLastHitAttemptObject()); - runtime.push(hit); - if(hit) - stats.clearLastHitAttemptObject(); - } + MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); + bool hit = ::Misc::StringUtils::ciEqual(objectID, stats.getLastHitAttemptObject()); + runtime.push(hit); + if (hit) + stats.clearLastHitAttemptObject(); + } }; template class OpEnableTeleporting : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWBase::World *world = MWBase::Environment::get().getWorld(); - world->enableTeleporting(Enable); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + MWBase::World* world = MWBase::Environment::get().getWorld(); + world->enableTeleporting(Enable); + } }; template class OpEnableLevitation : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWBase::World *world = MWBase::Environment::get().getWorld(); - world->enableLevitation(Enable); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + MWBase::World* world = MWBase::Environment::get().getWorld(); + world->enableLevitation(Enable); + } }; template class OpShow : public Interpreter::Opcode0 { public: - - void execute (Interpreter::Runtime& runtime) override + void execute(Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime, false); std::string_view var = runtime.getStringLiteral(runtime[0].mInteger); @@ -1065,42 +1001,44 @@ namespace MWScript std::string_view script = ptr.getClass().getScript(ptr); if (!script.empty()) { - const Compiler::Locals& locals = - MWBase::Environment::get().getScriptManager()->getLocals(script); + const Compiler::Locals& locals + = MWBase::Environment::get().getScriptManager()->getLocals(script); char type = locals.getType(var); std::string refId = ptr.getCellRef().getRefId(); if (refId.find(' ') != std::string::npos) refId = '"' + refId + '"'; switch (type) { - case 'l': - case 's': - output << refId << "." << var << " = " << ptr.getRefData().getLocals().getIntVar(script, var); - break; - case 'f': - output << refId << "." << var << " = " << ptr.getRefData().getLocals().getFloatVar(script, var); - break; + case 'l': + case 's': + output << refId << "." << var << " = " + << ptr.getRefData().getLocals().getIntVar(script, var); + break; + case 'f': + output << refId << "." << var << " = " + << ptr.getRefData().getLocals().getFloatVar(script, var); + break; } } } if (output.rdbuf()->in_avail() == 0) { - MWBase::World *world = MWBase::Environment::get().getWorld(); - char type = world->getGlobalVariableType (var); + MWBase::World* world = MWBase::Environment::get().getWorld(); + char type = world->getGlobalVariableType(var); switch (type) { - case 's': - output << var << " = " << runtime.getContext().getGlobalShort (var); - break; - case 'l': - output << var << " = " << runtime.getContext().getGlobalLong (var); - break; - case 'f': - output << var << " = " << runtime.getContext().getGlobalFloat (var); - break; - default: - output << "unknown variable"; + case 's': + output << var << " = " << runtime.getContext().getGlobalShort(var); + break; + case 'l': + output << var << " = " << runtime.getContext().getGlobalLong(var); + break; + case 'f': + output << var << " = " << runtime.getContext().getGlobalFloat(var); + break; + default: + output << "unknown variable"; } } runtime.getContext().report(output.str()); @@ -1110,73 +1048,74 @@ namespace MWScript template class OpShowVars : public Interpreter::Opcode0 { - void printLocalVars(Interpreter::Runtime &runtime, const MWWorld::Ptr &ptr) + void printLocalVars(Interpreter::Runtime& runtime, const MWWorld::Ptr& ptr) { std::stringstream str; std::string_view script = ptr.getClass().getScript(ptr); - if(script.empty()) - str<< ptr.getCellRef().getRefId()<<" does not have a script."; + if (script.empty()) + str << ptr.getCellRef().getRefId() << " does not have a script."; else { - str<< "Local variables for "<getLocals(script); + const Locals& locals = ptr.getRefData().getLocals(); + const Compiler::Locals& complocals + = MWBase::Environment::get().getScriptManager()->getLocals(script); - const std::vector *names = &complocals.get('s'); - for(size_t i = 0;i < names->size();++i) + const std::vector* names = &complocals.get('s'); + for (size_t i = 0; i < names->size(); ++i) { - if(i >= locals.mShorts.size()) + if (i >= locals.mShorts.size()) break; - str<size();++i) + for (size_t i = 0; i < names->size(); ++i) { - if(i >= locals.mLongs.size()) + if (i >= locals.mLongs.size()) break; - str<size();++i) + for (size_t i = 0; i < names->size(); ++i) { - if(i >= locals.mFloats.size()) + if (i >= locals.mFloats.size()) break; - str< names = runtime.getContext().getGlobals(); - for(size_t i = 0;i < names.size();++i) + for (size_t i = 0; i < names.size(); ++i) { - char type = world->getGlobalVariableType (names[i]); + char type = world->getGlobalVariableType(names[i]); str << std::endl << " " << names[i] << " = "; switch (type) { case 's': - str << runtime.getContext().getGlobalShort (names[i]) << " (short)"; + str << runtime.getContext().getGlobalShort(names[i]) << " (short)"; break; case 'l': - str << runtime.getContext().getGlobalLong (names[i]) << " (long)"; + str << runtime.getContext().getGlobalLong(names[i]) << " (long)"; break; case 'f': - str << runtime.getContext().getGlobalFloat (names[i]) << " (float)"; + str << runtime.getContext().getGlobalFloat(names[i]) << " (float)"; break; default: @@ -1185,7 +1124,7 @@ namespace MWScript } } - runtime.getContext().report (str.str()); + runtime.getContext().report(str.str()); } public: @@ -1205,7 +1144,7 @@ namespace MWScript class OpToggleScripts : public Interpreter::Opcode0 { public: - void execute (Interpreter::Runtime& runtime) override + void execute(Interpreter::Runtime& runtime) override { bool enabled = MWBase::Environment::get().getWorld()->toggleScripts(); @@ -1215,20 +1154,20 @@ namespace MWScript class OpToggleGodMode : public Interpreter::Opcode0 { - public: - void execute (Interpreter::Runtime& runtime) override - { - bool enabled = MWBase::Environment::get().getWorld()->toggleGodMode(); + public: + void execute(Interpreter::Runtime& runtime) override + { + bool enabled = MWBase::Environment::get().getWorld()->toggleGodMode(); - runtime.getContext().report (enabled ? "God Mode -> On" : "God Mode -> Off"); - } + runtime.getContext().report(enabled ? "God Mode -> On" : "God Mode -> Off"); + } }; template class OpCast : public Interpreter::Opcode0 { public: - void execute (Interpreter::Runtime& runtime) override + void execute(Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -1238,10 +1177,12 @@ namespace MWScript std::string targetId = ::Misc::StringUtils::lowerCase(runtime.getStringLiteral(runtime[0].mInteger)); runtime.pop(); - const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get().search(spellId); + const ESM::Spell* spell + = MWBase::Environment::get().getWorld()->getStore().get().search(spellId); if (!spell) { - runtime.getContext().report("spellcasting failed: cannot find spell \""+std::string(spellId)+"\""); + runtime.getContext().report( + "spellcasting failed: cannot find spell \"" + std::string(spellId) + "\""); return; } @@ -1256,7 +1197,7 @@ namespace MWScript if (!MWBase::Environment::get().getMechanicsManager()->isCastingSpell(ptr)) { MWMechanics::AiCast castPackage(targetId, spell->mId, true); - ptr.getClass().getCreatureStats (ptr).getAiSequence().stack(castPackage, ptr); + ptr.getClass().getCreatureStats(ptr).getAiSequence().stack(castPackage, ptr); } return; } @@ -1277,17 +1218,19 @@ namespace MWScript class OpExplodeSpell : public Interpreter::Opcode0 { public: - void execute (Interpreter::Runtime& runtime) override + void execute(Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); std::string_view spellId = runtime.getStringLiteral(runtime[0].mInteger); runtime.pop(); - const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get().search(spellId); + const ESM::Spell* spell + = MWBase::Environment::get().getWorld()->getStore().get().search(spellId); if (!spell) { - runtime.getContext().report("spellcasting failed: cannot find spell \""+std::string(spellId)+"\""); + runtime.getContext().report( + "spellcasting failed: cannot find spell \"" + std::string(spellId) + "\""); return; } @@ -1302,7 +1245,7 @@ namespace MWScript if (!MWBase::Environment::get().getMechanicsManager()->isCastingSpell(ptr)) { MWMechanics::AiCast castPackage(ptr.getCellRef().getRefId(), spell->mId, true); - ptr.getClass().getCreatureStats (ptr).getAiSequence().stack(castPackage, ptr); + ptr.getClass().getCreatureStats(ptr).getAiSequence().stack(castPackage, ptr); } return; } @@ -1317,7 +1260,7 @@ namespace MWScript class OpGoToJail : public Interpreter::Opcode0 { public: - void execute (Interpreter::Runtime& runtime) override + void execute(Interpreter::Runtime& runtime) override { MWBase::World* world = MWBase::Environment::get().getWorld(); world->goToJail(); @@ -1327,7 +1270,7 @@ namespace MWScript class OpPayFine : public Interpreter::Opcode0 { public: - void execute(Interpreter::Runtime &runtime) override + void execute(Interpreter::Runtime& runtime) override { MWWorld::Ptr player = MWMechanics::getPlayer(); player.getClass().getNpcStats(player).setBounty(0); @@ -1339,7 +1282,7 @@ namespace MWScript class OpPayFineThief : public Interpreter::Opcode0 { public: - void execute(Interpreter::Runtime &runtime) override + void execute(Interpreter::Runtime& runtime) override { MWWorld::Ptr player = MWMechanics::getPlayer(); player.getClass().getNpcStats(player).setBounty(0); @@ -1349,29 +1292,27 @@ namespace MWScript class OpGetPcInJail : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime &runtime) override - { - runtime.push (MWBase::Environment::get().getWorld()->isPlayerInJail()); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + runtime.push(MWBase::Environment::get().getWorld()->isPlayerInJail()); + } }; class OpGetPcTraveling : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime &runtime) override - { - runtime.push (MWBase::Environment::get().getWorld()->isPlayerTraveling()); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + runtime.push(MWBase::Environment::get().getWorld()->isPlayerTraveling()); + } }; template class OpBetaComment : public Interpreter::Opcode1 { public: - void execute(Interpreter::Runtime &runtime, unsigned int arg0) override + void execute(Interpreter::Runtime& runtime, unsigned int arg0) override { MWWorld::Ptr ptr = R()(runtime); @@ -1390,7 +1331,7 @@ namespace MWScript { std::vector contentFiles = MWBase::Environment::get().getWorld()->getContentFiles(); - msg << " [" << contentFiles.at (ptr.getCellRef().getRefNum().mContentFile) << "]" << std::endl; + msg << " [" << contentFiles.at(ptr.getCellRef().getRefNum().mContentFile) << "]" << std::endl; } msg << "RefNum: " << ptr.getCellRef().getRefNum().mIndex << std::endl; @@ -1408,16 +1349,18 @@ namespace MWScript MWWorld::CellStore* cell = ptr.getCell(); msg << "Cell: " << MWBase::Environment::get().getWorld()->getCellName(cell) << std::endl; if (cell->getCell()->isExterior()) - msg << "Grid: " << cell->getCell()->getGridX() << " " << cell->getCell()->getGridY() << std::endl; - osg::Vec3f pos (ptr.getRefData().getPosition().asVec3()); + msg << "Grid: " << cell->getCell()->getGridX() << " " << cell->getCell()->getGridY() + << std::endl; + osg::Vec3f pos(ptr.getRefData().getPosition().asVec3()); msg << "Coordinates: " << pos.x() << " " << pos.y() << " " << pos.z() << std::endl; auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); - std::string model = ::Misc::ResourceHelpers::correctActorModelPath(ptr.getClass().getModel(ptr), vfs); + std::string model + = ::Misc::ResourceHelpers::correctActorModelPath(ptr.getClass().getModel(ptr), vfs); msg << "Model: " << model << std::endl; - if(!model.empty()) + if (!model.empty()) { const std::string archive = vfs->getArchive(model); - if(!archive.empty()) + if (!archive.empty()) msg << "(" << archive << ")" << std::endl; } if (!ptr.getClass().getScript(ptr).empty()) @@ -1442,7 +1385,7 @@ namespace MWScript class OpAddToLevCreature : public Interpreter::Opcode0 { public: - void execute(Interpreter::Runtime &runtime) override + void execute(Interpreter::Runtime& runtime) override { std::string_view levId = runtime.getStringLiteral(runtime[0].mInteger); runtime.pop(); @@ -1451,7 +1394,8 @@ namespace MWScript int level = runtime[0].mInteger; runtime.pop(); - ESM::CreatureLevList listCopy = *MWBase::Environment::get().getWorld()->getStore().get().find(levId); + ESM::CreatureLevList listCopy + = *MWBase::Environment::get().getWorld()->getStore().get().find(levId); addToLevList(&listCopy, creatureId, level); MWBase::Environment::get().getWorld()->createOverrideRecord(listCopy); } @@ -1460,7 +1404,7 @@ namespace MWScript class OpRemoveFromLevCreature : public Interpreter::Opcode0 { public: - void execute(Interpreter::Runtime &runtime) override + void execute(Interpreter::Runtime& runtime) override { std::string_view levId = runtime.getStringLiteral(runtime[0].mInteger); runtime.pop(); @@ -1469,7 +1413,8 @@ namespace MWScript int level = runtime[0].mInteger; runtime.pop(); - ESM::CreatureLevList listCopy = *MWBase::Environment::get().getWorld()->getStore().get().find(levId); + ESM::CreatureLevList listCopy + = *MWBase::Environment::get().getWorld()->getStore().get().find(levId); removeFromLevList(&listCopy, creatureId, level); MWBase::Environment::get().getWorld()->createOverrideRecord(listCopy); } @@ -1478,7 +1423,7 @@ namespace MWScript class OpAddToLevItem : public Interpreter::Opcode0 { public: - void execute(Interpreter::Runtime &runtime) override + void execute(Interpreter::Runtime& runtime) override { std::string_view levId = runtime.getStringLiteral(runtime[0].mInteger); runtime.pop(); @@ -1487,7 +1432,8 @@ namespace MWScript int level = runtime[0].mInteger; runtime.pop(); - ESM::ItemLevList listCopy = *MWBase::Environment::get().getWorld()->getStore().get().find(levId); + ESM::ItemLevList listCopy + = *MWBase::Environment::get().getWorld()->getStore().get().find(levId); addToLevList(&listCopy, itemId, level); MWBase::Environment::get().getWorld()->createOverrideRecord(listCopy); } @@ -1496,7 +1442,7 @@ namespace MWScript class OpRemoveFromLevItem : public Interpreter::Opcode0 { public: - void execute(Interpreter::Runtime &runtime) override + void execute(Interpreter::Runtime& runtime) override { std::string_view levId = runtime.getStringLiteral(runtime[0].mInteger); runtime.pop(); @@ -1505,7 +1451,8 @@ namespace MWScript int level = runtime[0].mInteger; runtime.pop(); - ESM::ItemLevList listCopy = *MWBase::Environment::get().getWorld()->getStore().get().find(levId); + ESM::ItemLevList listCopy + = *MWBase::Environment::get().getWorld()->getStore().get().find(levId); removeFromLevList(&listCopy, itemId, level); MWBase::Environment::get().getWorld()->createOverrideRecord(listCopy); } @@ -1515,19 +1462,21 @@ namespace MWScript class OpShowSceneGraph : public Interpreter::Opcode1 { public: - void execute(Interpreter::Runtime &runtime, unsigned int arg0) override + void execute(Interpreter::Runtime& runtime, unsigned int arg0) override { MWWorld::Ptr ptr = R()(runtime, false); int confirmed = 0; - if (arg0==1) + if (arg0 == 1) { confirmed = runtime[0].mInteger; runtime.pop(); } if (ptr.isEmpty() && !confirmed) - runtime.getContext().report("Exporting the entire scene graph will result in a large file. Confirm this action using 'showscenegraph 1' or select an object instead."); + runtime.getContext().report( + "Exporting the entire scene graph will result in a large file. Confirm this action using " + "'showscenegraph 1' or select an object instead."); else { const auto filename = MWBase::Environment::get().getWorld()->exportSceneGraph(ptr); @@ -1538,105 +1487,94 @@ namespace MWScript class OpToggleNavMesh : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - bool enabled = - MWBase::Environment::get().getWorld()->toggleRenderMode (MWRender::Render_NavMesh); + public: + void execute(Interpreter::Runtime& runtime) override + { + bool enabled = MWBase::Environment::get().getWorld()->toggleRenderMode(MWRender::Render_NavMesh); - runtime.getContext().report (enabled ? - "Navigation Mesh Rendering -> On" : "Navigation Mesh Rendering -> Off"); - } + runtime.getContext().report( + enabled ? "Navigation Mesh Rendering -> On" : "Navigation Mesh Rendering -> Off"); + } }; class OpToggleActorsPaths : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - bool enabled = - MWBase::Environment::get().getWorld()->toggleRenderMode (MWRender::Render_ActorsPaths); + public: + void execute(Interpreter::Runtime& runtime) override + { + bool enabled = MWBase::Environment::get().getWorld()->toggleRenderMode(MWRender::Render_ActorsPaths); - runtime.getContext().report (enabled ? - "Agents Paths Rendering -> On" : "Agents Paths Rendering -> Off"); - } + runtime.getContext().report(enabled ? "Agents Paths Rendering -> On" : "Agents Paths Rendering -> Off"); + } }; class OpSetNavMeshNumberToRender : public Interpreter::Opcode0 { - public: + public: + void execute(Interpreter::Runtime& runtime) override + { + const auto navMeshNumber = runtime[0].mInteger; + runtime.pop(); - void execute (Interpreter::Runtime& runtime) override + if (navMeshNumber < 0) { - const auto navMeshNumber = runtime[0].mInteger; - runtime.pop(); - - if (navMeshNumber < 0) - { - runtime.getContext().report("Invalid navmesh number: use not less than zero values"); - return; - } - - MWBase::Environment::get().getWorld()->setNavMeshNumberToRender(static_cast(navMeshNumber)); + runtime.getContext().report("Invalid navmesh number: use not less than zero values"); + return; } + + MWBase::Environment::get().getWorld()->setNavMeshNumberToRender( + static_cast(navMeshNumber)); + } }; template class OpRepairedOnMe : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - // Broken in vanilla and deliberately no-op. - runtime.push(0); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + // Broken in vanilla and deliberately no-op. + runtime.push(0); + } }; class OpToggleRecastMesh : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - bool enabled = - MWBase::Environment::get().getWorld()->toggleRenderMode (MWRender::Render_RecastMesh); + public: + void execute(Interpreter::Runtime& runtime) override + { + bool enabled = MWBase::Environment::get().getWorld()->toggleRenderMode(MWRender::Render_RecastMesh); - runtime.getContext().report (enabled ? - "Recast Mesh Rendering -> On" : "Recast Mesh Rendering -> Off"); - } + runtime.getContext().report(enabled ? "Recast Mesh Rendering -> On" : "Recast Mesh Rendering -> Off"); + } }; class OpHelp : public Interpreter::Opcode0 { - public: - - void execute(Interpreter::Runtime& runtime) override - { - std::stringstream message; - message << MWBase::Environment::get().getWindowManager()->getVersionDescription() << "\n\n"; - std::vector commands; - MWBase::Environment::get().getScriptManager()->getExtensions().listKeywords(commands); - for(const auto& command : commands) - message << command << "\n"; - runtime.getContext().report(message.str()); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + std::stringstream message; + message << MWBase::Environment::get().getWindowManager()->getVersionDescription() << "\n\n"; + std::vector commands; + MWBase::Environment::get().getScriptManager()->getExtensions().listKeywords(commands); + for (const auto& command : commands) + message << command << "\n"; + runtime.getContext().report(message.str()); + } }; class OpReloadLua : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWBase::Environment::get().getLuaManager()->reloadAllScripts(); - runtime.getContext().report("All Lua scripts are reloaded"); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + MWBase::Environment::get().getLuaManager()->reloadAllScripts(); + runtime.getContext().report("All Lua scripts are reloaded"); + } }; - void installOpcodes (Interpreter::Interpreter& interpreter) + void installOpcodes(Interpreter::Interpreter& interpreter) { interpreter.installSegment5(Compiler::Misc::opcodeMenuMode); interpreter.installSegment5(Compiler::Misc::opcodeRandom); @@ -1710,15 +1648,19 @@ namespace MWScript interpreter.installSegment5>(Compiler::Misc::opcodeGetStandingPc); interpreter.installSegment5>(Compiler::Misc::opcodeGetStandingPcExplicit); interpreter.installSegment5>(Compiler::Misc::opcodeGetStandingActor); - interpreter.installSegment5>(Compiler::Misc::opcodeGetStandingActorExplicit); + interpreter.installSegment5>( + Compiler::Misc::opcodeGetStandingActorExplicit); interpreter.installSegment5>(Compiler::Misc::opcodeGetCollidingPc); interpreter.installSegment5>(Compiler::Misc::opcodeGetCollidingPcExplicit); interpreter.installSegment5>(Compiler::Misc::opcodeGetCollidingActor); - interpreter.installSegment5>(Compiler::Misc::opcodeGetCollidingActorExplicit); + interpreter.installSegment5>( + Compiler::Misc::opcodeGetCollidingActorExplicit); interpreter.installSegment5>(Compiler::Misc::opcodeHurtStandingActor); - interpreter.installSegment5>(Compiler::Misc::opcodeHurtStandingActorExplicit); + interpreter.installSegment5>( + Compiler::Misc::opcodeHurtStandingActorExplicit); interpreter.installSegment5>(Compiler::Misc::opcodeHurtCollidingActor); - interpreter.installSegment5>(Compiler::Misc::opcodeHurtCollidingActorExplicit); + interpreter.installSegment5>( + Compiler::Misc::opcodeHurtCollidingActorExplicit); interpreter.installSegment5(Compiler::Misc::opcodeGetWindSpeed); interpreter.installSegment5>(Compiler::Misc::opcodeHitOnMe); interpreter.installSegment5>(Compiler::Misc::opcodeHitOnMeExplicit); diff --git a/apps/openmw/mwscript/miscextensions.hpp b/apps/openmw/mwscript/miscextensions.hpp index 16ed9301ed..0dbdd7ba50 100644 --- a/apps/openmw/mwscript/miscextensions.hpp +++ b/apps/openmw/mwscript/miscextensions.hpp @@ -14,11 +14,9 @@ namespace Interpreter namespace MWScript { namespace Misc - { - void installOpcodes (Interpreter::Interpreter& interpreter); + { + void installOpcodes(Interpreter::Interpreter& interpreter); } } #endif - - diff --git a/apps/openmw/mwscript/ref.cpp b/apps/openmw/mwscript/ref.cpp index 145cd2cd25..c61eb64780 100644 --- a/apps/openmw/mwscript/ref.cpp +++ b/apps/openmw/mwscript/ref.cpp @@ -7,8 +7,7 @@ #include "interpretercontext.hpp" -MWWorld::Ptr MWScript::ExplicitRef::operator() (Interpreter::Runtime& runtime, bool required, - bool activeOnly) const +MWWorld::Ptr MWScript::ExplicitRef::operator()(Interpreter::Runtime& runtime, bool required, bool activeOnly) const { std::string_view id = runtime.getStringLiteral(runtime[0].mInteger); runtime.pop(); @@ -19,11 +18,9 @@ MWWorld::Ptr MWScript::ExplicitRef::operator() (Interpreter::Runtime& runtime, b return MWBase::Environment::get().getWorld()->searchPtr(id, activeOnly); } -MWWorld::Ptr MWScript::ImplicitRef::operator() (Interpreter::Runtime& runtime, bool required, - bool activeOnly) const +MWWorld::Ptr MWScript::ImplicitRef::operator()(Interpreter::Runtime& runtime, bool required, bool activeOnly) const { - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); + MWScript::InterpreterContext& context = static_cast(runtime.getContext()); return context.getReference(required); } diff --git a/apps/openmw/mwscript/ref.hpp b/apps/openmw/mwscript/ref.hpp index 8c7657280f..166435b2c8 100644 --- a/apps/openmw/mwscript/ref.hpp +++ b/apps/openmw/mwscript/ref.hpp @@ -14,16 +14,14 @@ namespace MWScript { static constexpr bool implicit = false; - MWWorld::Ptr operator() (Interpreter::Runtime& runtime, bool required = true, - bool activeOnly = false) const; + MWWorld::Ptr operator()(Interpreter::Runtime& runtime, bool required = true, bool activeOnly = false) const; }; struct ImplicitRef { static constexpr bool implicit = true; - MWWorld::Ptr operator() (Interpreter::Runtime& runtime, bool required = true, - bool activeOnly = false) const; + MWWorld::Ptr operator()(Interpreter::Runtime& runtime, bool required = true, bool activeOnly = false) const; }; } diff --git a/apps/openmw/mwscript/scriptmanagerimp.cpp b/apps/openmw/mwscript/scriptmanagerimp.cpp index 35593efcba..f17b1a1c50 100644 --- a/apps/openmw/mwscript/scriptmanagerimp.cpp +++ b/apps/openmw/mwscript/scriptmanagerimp.cpp @@ -1,9 +1,9 @@ #include "scriptmanagerimp.hpp" +#include #include -#include #include -#include +#include #include @@ -11,10 +11,10 @@ #include -#include #include #include #include +#include #include "../mwworld/esmstore.hpp" @@ -23,20 +23,22 @@ namespace MWScript { - ScriptManager::ScriptManager (const MWWorld::ESMStore& store, - Compiler::Context& compilerContext, int warningsMode, + ScriptManager::ScriptManager(const MWWorld::ESMStore& store, Compiler::Context& compilerContext, int warningsMode, const std::vector& scriptBlacklist) - : mErrorHandler(), mStore (store), - mCompilerContext (compilerContext), mParser (mErrorHandler, mCompilerContext), - mOpcodesInstalled (false), mGlobalScripts (store) + : mErrorHandler() + , mStore(store) + , mCompilerContext(compilerContext) + , mParser(mErrorHandler, mCompilerContext) + , mOpcodesInstalled(false) + , mGlobalScripts(store) { - mErrorHandler.setWarningsMode (warningsMode); + mErrorHandler.setWarningsMode(warningsMode); - mScriptBlacklist.resize (scriptBlacklist.size()); + mScriptBlacklist.resize(scriptBlacklist.size()); - std::transform (scriptBlacklist.begin(), scriptBlacklist.end(), - mScriptBlacklist.begin(), [](const std::string& s) { return Misc::StringUtils::lowerCase(s); }); - std::sort (mScriptBlacklist.begin(), mScriptBlacklist.end()); + std::transform(scriptBlacklist.begin(), scriptBlacklist.end(), mScriptBlacklist.begin(), + [](const std::string& s) { return Misc::StringUtils::lowerCase(s); }); + std::sort(mScriptBlacklist.begin(), mScriptBlacklist.end()); } bool ScriptManager::compile(std::string_view name) @@ -44,18 +46,18 @@ namespace MWScript mParser.reset(); mErrorHandler.reset(); - if (const ESM::Script *script = mStore.get().find (name)) + if (const ESM::Script* script = mStore.get().find(name)) { mErrorHandler.setContext(script->mId); bool Success = true; try { - std::istringstream input (script->mScriptText); + std::istringstream input(script->mScriptText); - Compiler::Scanner scanner (mErrorHandler, input, mCompilerContext.getExtensions()); + Compiler::Scanner scanner(mErrorHandler, input, mCompilerContext.getExtensions()); - scanner.scan (mParser); + scanner.scan(mParser); if (!mErrorHandler.isGood()) Success = false; @@ -94,9 +96,9 @@ namespace MWScript // compile script auto iter = mScripts.find(name); - if (iter==mScripts.end()) + if (iter == mScripts.end()) { - if (!compile (name)) + if (!compile(name)) { // failed -> ignore script from now on. std::vector empty; @@ -104,8 +106,8 @@ namespace MWScript return false; } - iter = mScripts.find (name); - assert (iter!=mScripts.end()); + iter = mScripts.find(name); + assert(iter != mScripts.end()); } // execute script @@ -115,20 +117,20 @@ namespace MWScript { if (!mOpcodesInstalled) { - installOpcodes (mInterpreter); + installOpcodes(mInterpreter); mOpcodesInstalled = true; } - mInterpreter.run (&iter->second.mByteCode[0], iter->second.mByteCode.size(), interpreterContext); + mInterpreter.run(&iter->second.mByteCode[0], iter->second.mByteCode.size(), interpreterContext); return true; } catch (const MissingImplicitRefError& e) { - Log(Debug::Error) << "Execution of script " << name << " failed: " << e.what(); + Log(Debug::Error) << "Execution of script " << name << " failed: " << e.what(); } catch (const std::exception& e) { - Log(Debug::Error) << "Execution of script " << name << " failed: " << e.what(); + Log(Debug::Error) << "Execution of script " << name << " failed: " << e.what(); iter->second.mInactive.insert(target); // don't execute again. } @@ -152,8 +154,8 @@ namespace MWScript for (auto& script : mStore.get()) { - if (!std::binary_search (mScriptBlacklist.begin(), mScriptBlacklist.end(), - Misc::StringUtils::lowerCase(script.mId))) + if (!std::binary_search( + mScriptBlacklist.begin(), mScriptBlacklist.end(), Misc::StringUtils::lowerCase(script.mId))) { ++count; @@ -162,7 +164,7 @@ namespace MWScript } } - return std::make_pair (count, success); + return std::make_pair(count, success); } const Compiler::Locals& ScriptManager::getLocals(std::string_view name) @@ -170,14 +172,14 @@ namespace MWScript { auto iter = mScripts.find(name); - if (iter!=mScripts.end()) + if (iter != mScripts.end()) return iter->second.mLocals; } { auto iter = mOtherLocals.find(name); - if (iter!=mOtherLocals.end()) + if (iter != mOtherLocals.end()) return iter->second; } @@ -185,14 +187,14 @@ namespace MWScript { Compiler::Locals locals; - const Compiler::ContextOverride override(mErrorHandler, std::string{name} + "[local variables]"); + const Compiler::ContextOverride override(mErrorHandler, std::string{ name } + "[local variables]"); - std::istringstream stream (script->mScriptText); - Compiler::QuickFileParser parser (mErrorHandler, mCompilerContext, locals); - Compiler::Scanner scanner (mErrorHandler, stream, mCompilerContext.getExtensions()); + std::istringstream stream(script->mScriptText); + Compiler::QuickFileParser parser(mErrorHandler, mCompilerContext, locals); + Compiler::Scanner scanner(mErrorHandler, stream, mCompilerContext.getExtensions()); try { - scanner.scan (parser); + scanner.scan(parser); } catch (const Compiler::SourceException&) { @@ -210,7 +212,7 @@ namespace MWScript return iter->second; } - throw std::logic_error("script " + std::string{name} + " does not exist"); + throw std::logic_error("script " + std::string{ name } + " does not exist"); } GlobalScripts& ScriptManager::getGlobalScripts() diff --git a/apps/openmw/mwscript/scriptmanagerimp.hpp b/apps/openmw/mwscript/scriptmanagerimp.hpp index 4926f4b61f..7355edf240 100644 --- a/apps/openmw/mwscript/scriptmanagerimp.hpp +++ b/apps/openmw/mwscript/scriptmanagerimp.hpp @@ -5,8 +5,8 @@ #include #include -#include #include +#include #include #include @@ -35,54 +35,56 @@ namespace MWScript { class ScriptManager : public MWBase::ScriptManager { - Compiler::StreamErrorHandler mErrorHandler; - const MWWorld::ESMStore& mStore; - Compiler::Context& mCompilerContext; - Compiler::FileParser mParser; - Interpreter::Interpreter mInterpreter; - bool mOpcodesInstalled; - - struct CompiledScript + Compiler::StreamErrorHandler mErrorHandler; + const MWWorld::ESMStore& mStore; + Compiler::Context& mCompilerContext; + Compiler::FileParser mParser; + Interpreter::Interpreter mInterpreter; + bool mOpcodesInstalled; + + struct CompiledScript + { + std::vector mByteCode; + Compiler::Locals mLocals; + std::set mInactive; + + CompiledScript(const std::vector& code, const Compiler::Locals& locals) + : mByteCode(code) + , mLocals(locals) { - std::vector mByteCode; - Compiler::Locals mLocals; - std::set mInactive; - - CompiledScript(const std::vector& code, const Compiler::Locals& locals): - mByteCode(code), mLocals(locals) - {} - }; - - std::unordered_map mScripts; - GlobalScripts mGlobalScripts; - std::unordered_map mOtherLocals; - std::vector mScriptBlacklist; + } + }; - public: + std::unordered_map + mScripts; + GlobalScripts mGlobalScripts; + std::unordered_map + mOtherLocals; + std::vector mScriptBlacklist; - ScriptManager (const MWWorld::ESMStore& store, - Compiler::Context& compilerContext, int warningsMode, - const std::vector& scriptBlacklist); + public: + ScriptManager(const MWWorld::ESMStore& store, Compiler::Context& compilerContext, int warningsMode, + const std::vector& scriptBlacklist); - void clear() override; + void clear() override; - bool run(std::string_view name, Interpreter::Context& interpreterContext) override; - ///< Run the script with the given name (compile first, if not compiled yet) + bool run(std::string_view name, Interpreter::Context& interpreterContext) override; + ///< Run the script with the given name (compile first, if not compiled yet) - bool compile(std::string_view name) override; - ///< Compile script with the given namen - /// \return Success? + bool compile(std::string_view name) override; + ///< Compile script with the given namen + /// \return Success? - std::pair compileAll() override; - ///< Compile all scripts - /// \return count, success + std::pair compileAll() override; + ///< Compile all scripts + /// \return count, success - const Compiler::Locals& getLocals(std::string_view name) override; - ///< Return locals for script \a name. + const Compiler::Locals& getLocals(std::string_view name) override; + ///< Return locals for script \a name. - GlobalScripts& getGlobalScripts() override; + GlobalScripts& getGlobalScripts() override; - const Compiler::Extensions& getExtensions() const override; + const Compiler::Extensions& getExtensions() const override; }; } diff --git a/apps/openmw/mwscript/skyextensions.cpp b/apps/openmw/mwscript/skyextensions.cpp index 6ade880c7e..26cb1fabca 100644 --- a/apps/openmw/mwscript/skyextensions.cpp +++ b/apps/openmw/mwscript/skyextensions.cpp @@ -4,10 +4,10 @@ #include +#include #include -#include #include -#include +#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" @@ -22,110 +22,102 @@ namespace MWScript { class OpToggleSky : public Interpreter::Opcode0 { - public: + public: + void execute(Interpreter::Runtime& runtime) override + { + bool enabled = MWBase::Environment::get().getWorld()->toggleSky(); - void execute (Interpreter::Runtime& runtime) override - { - bool enabled = MWBase::Environment::get().getWorld()->toggleSky(); - - runtime.getContext().report (enabled ? "Sky -> On" : "Sky -> Off"); - } + runtime.getContext().report(enabled ? "Sky -> On" : "Sky -> Off"); + } }; class OpTurnMoonWhite : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWBase::Environment::get().getWorld()->setMoonColour (false); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + MWBase::Environment::get().getWorld()->setMoonColour(false); + } }; class OpTurnMoonRed : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWBase::Environment::get().getWorld()->setMoonColour (true); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + MWBase::Environment::get().getWorld()->setMoonColour(true); + } }; class OpGetMasserPhase : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - runtime.push (MWBase::Environment::get().getWorld()->getMasserPhase()); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + runtime.push(MWBase::Environment::get().getWorld()->getMasserPhase()); + } }; class OpGetSecundaPhase : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - runtime.push (MWBase::Environment::get().getWorld()->getSecundaPhase()); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + runtime.push(MWBase::Environment::get().getWorld()->getSecundaPhase()); + } }; class OpGetCurrentWeather : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - runtime.push (MWBase::Environment::get().getWorld()->getCurrentWeather()); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + runtime.push(MWBase::Environment::get().getWorld()->getCurrentWeather()); + } }; class OpChangeWeather : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - std::string_view region{runtime.getStringLiteral(runtime[0].mInteger)}; - runtime.pop(); - - Interpreter::Type_Integer id = runtime[0].mInteger; - runtime.pop(); - - const ESM::Region* reg = MWBase::Environment::get().getWorld()->getStore().get().search(region); - if (reg) - MWBase::Environment::get().getWorld()->changeWeather(region, id); - else - runtime.getContext().report("Warning: Region \"" + std::string(region) + "\" was not found"); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + std::string_view region{ runtime.getStringLiteral(runtime[0].mInteger) }; + runtime.pop(); + + Interpreter::Type_Integer id = runtime[0].mInteger; + runtime.pop(); + + const ESM::Region* reg + = MWBase::Environment::get().getWorld()->getStore().get().search(region); + if (reg) + MWBase::Environment::get().getWorld()->changeWeather(region, id); + else + runtime.getContext().report("Warning: Region \"" + std::string(region) + "\" was not found"); + } }; class OpModRegion : public Interpreter::Opcode1 { - public: - - void execute (Interpreter::Runtime& runtime, unsigned int arg0) override + public: + void execute(Interpreter::Runtime& runtime, unsigned int arg0) override + { + std::string_view region{ runtime.getStringLiteral(runtime[0].mInteger) }; + runtime.pop(); + + std::vector chances; + chances.reserve(10); + while (arg0 > 0) { - std::string_view region{runtime.getStringLiteral(runtime[0].mInteger)}; + chances.push_back(std::clamp(runtime[0].mInteger, 0, 127)); runtime.pop(); - - std::vector chances; - chances.reserve(10); - while(arg0 > 0) - { - chances.push_back(std::clamp(runtime[0].mInteger, 0, 127)); - runtime.pop(); - arg0--; - } - - MWBase::Environment::get().getWorld()->modRegion(region, chances); + arg0--; } - }; + MWBase::Environment::get().getWorld()->modRegion(region, chances); + } + }; - void installOpcodes (Interpreter::Interpreter& interpreter) + void installOpcodes(Interpreter::Interpreter& interpreter) { interpreter.installSegment5(Compiler::Sky::opcodeToggleSky); interpreter.installSegment5(Compiler::Sky::opcodeTurnMoonWhite); diff --git a/apps/openmw/mwscript/skyextensions.hpp b/apps/openmw/mwscript/skyextensions.hpp index 003f2fb190..f49aa04c95 100644 --- a/apps/openmw/mwscript/skyextensions.hpp +++ b/apps/openmw/mwscript/skyextensions.hpp @@ -15,8 +15,8 @@ namespace MWScript { /// \brief sky-related script functionality namespace Sky - { - void installOpcodes (Interpreter::Interpreter& interpreter); + { + void installOpcodes(Interpreter::Interpreter& interpreter); } } diff --git a/apps/openmw/mwscript/soundextensions.cpp b/apps/openmw/mwscript/soundextensions.cpp index 744f94b02a..8ea1e89a23 100644 --- a/apps/openmw/mwscript/soundextensions.cpp +++ b/apps/openmw/mwscript/soundextensions.cpp @@ -3,16 +3,16 @@ #include #include -#include #include +#include #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/soundmanager.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" -#include "../mwworld/inventorystore.hpp" #include "../mwworld/class.hpp" +#include "../mwworld/inventorystore.hpp" #include "interpretercontext.hpp" #include "ref.hpp" @@ -21,181 +21,169 @@ namespace MWScript { namespace Sound { - template + template class OpSay : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - MWScript::InterpreterContext& context - = static_cast (runtime.getContext()); + MWScript::InterpreterContext& context + = static_cast(runtime.getContext()); - std::string file{runtime.getStringLiteral(runtime[0].mInteger)}; - runtime.pop(); + std::string file{ runtime.getStringLiteral(runtime[0].mInteger) }; + runtime.pop(); - std::string_view text = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + std::string_view text = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - MWBase::Environment::get().getSoundManager()->say (ptr, file); + MWBase::Environment::get().getSoundManager()->say(ptr, file); - if (MWBase::Environment::get().getWindowManager ()->getSubtitlesEnabled()) - context.messageBox (text); - } + if (MWBase::Environment::get().getWindowManager()->getSubtitlesEnabled()) + context.messageBox(text); + } }; - template + template class OpSayDone : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - runtime.push (MWBase::Environment::get().getSoundManager()->sayDone (ptr)); - } + runtime.push(MWBase::Environment::get().getSoundManager()->sayDone(ptr)); + } }; class OpStreamMusic : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - std::string sound{runtime.getStringLiteral(runtime[0].mInteger)}; - runtime.pop(); - - MWBase::Environment::get().getSoundManager()->streamMusic (sound); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + std::string sound{ runtime.getStringLiteral(runtime[0].mInteger) }; + runtime.pop(); + + MWBase::Environment::get().getSoundManager()->streamMusic(sound); + } }; class OpPlaySound : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - std::string_view sound = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); - - MWBase::Environment::get().getSoundManager()->playSound(sound, 1.0, 1.0, MWSound::Type::Sfx, MWSound::PlayMode::NoEnv); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + std::string_view sound = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); + + MWBase::Environment::get().getSoundManager()->playSound( + sound, 1.0, 1.0, MWSound::Type::Sfx, MWSound::PlayMode::NoEnv); + } }; class OpPlaySoundVP : public Interpreter::Opcode0 { - public: + public: + void execute(Interpreter::Runtime& runtime) override + { + std::string_view sound = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - void execute (Interpreter::Runtime& runtime) override - { - std::string_view sound = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); - - Interpreter::Type_Float volume = runtime[0].mFloat; - runtime.pop(); + Interpreter::Type_Float volume = runtime[0].mFloat; + runtime.pop(); - Interpreter::Type_Float pitch = runtime[0].mFloat; - runtime.pop(); + Interpreter::Type_Float pitch = runtime[0].mFloat; + runtime.pop(); - MWBase::Environment::get().getSoundManager()->playSound(sound, volume, pitch, MWSound::Type::Sfx, MWSound::PlayMode::NoEnv); - } + MWBase::Environment::get().getSoundManager()->playSound( + sound, volume, pitch, MWSound::Type::Sfx, MWSound::PlayMode::NoEnv); + } }; - template + template class OpPlaySound3D : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - std::string_view sound = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + std::string_view sound = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - MWBase::Environment::get().getSoundManager()->playSound3D(ptr, sound, 1.0, 1.0, - MWSound::Type::Sfx, - TLoop ? MWSound::PlayMode::LoopRemoveAtDistance - : MWSound::PlayMode::Normal); - } + MWBase::Environment::get().getSoundManager()->playSound3D(ptr, sound, 1.0, 1.0, MWSound::Type::Sfx, + TLoop ? MWSound::PlayMode::LoopRemoveAtDistance : MWSound::PlayMode::Normal); + } }; - template + template class OpPlaySoundVP3D : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - std::string_view sound = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + std::string_view sound = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - Interpreter::Type_Float volume = runtime[0].mFloat; - runtime.pop(); + Interpreter::Type_Float volume = runtime[0].mFloat; + runtime.pop(); - Interpreter::Type_Float pitch = runtime[0].mFloat; - runtime.pop(); + Interpreter::Type_Float pitch = runtime[0].mFloat; + runtime.pop(); - MWBase::Environment::get().getSoundManager()->playSound3D(ptr, sound, volume, pitch, - MWSound::Type::Sfx, - TLoop ? MWSound::PlayMode::LoopRemoveAtDistance - : MWSound::PlayMode::Normal); - - } + MWBase::Environment::get().getSoundManager()->playSound3D(ptr, sound, volume, pitch, MWSound::Type::Sfx, + TLoop ? MWSound::PlayMode::LoopRemoveAtDistance : MWSound::PlayMode::Normal); + } }; - template + template class OpStopSound : public Interpreter::Opcode0 { - public: + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); - - std::string_view sound = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + std::string_view sound = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - MWBase::Environment::get().getSoundManager()->stopSound3D (ptr, sound); - } + MWBase::Environment::get().getSoundManager()->stopSound3D(ptr, sound); + } }; - template + template class OpGetSoundPlaying : public Interpreter::Opcode0 { - public: + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + int index = runtime[0].mInteger; + runtime.pop(); - int index = runtime[0].mInteger; - runtime.pop(); + bool ret = MWBase::Environment::get().getSoundManager()->getSoundPlaying( + ptr, runtime.getStringLiteral(index)); - bool ret = MWBase::Environment::get().getSoundManager()->getSoundPlaying ( - ptr, runtime.getStringLiteral (index)); + // GetSoundPlaying called on an equipped item should also look for sounds played by the equipping actor. + if (!ret && ptr.getContainerStore()) + { + MWWorld::Ptr cont = MWBase::Environment::get().getWorld()->findContainer(ptr); - // GetSoundPlaying called on an equipped item should also look for sounds played by the equipping actor. - if (!ret && ptr.getContainerStore()) + if (!cont.isEmpty() && cont.getClass().hasInventoryStore(cont) + && cont.getClass().getInventoryStore(cont).isEquipped(ptr)) { - MWWorld::Ptr cont = MWBase::Environment::get().getWorld()->findContainer(ptr); - - if (!cont.isEmpty() && cont.getClass().hasInventoryStore(cont) && cont.getClass().getInventoryStore(cont).isEquipped(ptr)) - { - ret = MWBase::Environment::get().getSoundManager()->getSoundPlaying ( - cont, runtime.getStringLiteral (index)); - } + ret = MWBase::Environment::get().getSoundManager()->getSoundPlaying( + cont, runtime.getStringLiteral(index)); } - - runtime.push(ret); } - }; + runtime.push(ret); + } + }; void installOpcodes(Interpreter::Interpreter& interpreter) { @@ -214,9 +202,12 @@ namespace MWScript interpreter.installSegment5>(Compiler::Sound::opcodeSayExplicit); interpreter.installSegment5>(Compiler::Sound::opcodeSayDoneExplicit); interpreter.installSegment5>(Compiler::Sound::opcodePlaySound3DExplicit); - interpreter.installSegment5>(Compiler::Sound::opcodePlaySound3DVPExplicit); - interpreter.installSegment5>(Compiler::Sound::opcodePlayLoopSound3DExplicit); - interpreter.installSegment5>(Compiler::Sound::opcodePlayLoopSound3DVPExplicit); + interpreter.installSegment5>( + Compiler::Sound::opcodePlaySound3DVPExplicit); + interpreter.installSegment5>( + Compiler::Sound::opcodePlayLoopSound3DExplicit); + interpreter.installSegment5>( + Compiler::Sound::opcodePlayLoopSound3DVPExplicit); interpreter.installSegment5>(Compiler::Sound::opcodeStopSoundExplicit); interpreter.installSegment5>(Compiler::Sound::opcodeGetSoundPlayingExplicit); } diff --git a/apps/openmw/mwscript/soundextensions.hpp b/apps/openmw/mwscript/soundextensions.hpp index b92d7ea1bb..a4aeacad64 100644 --- a/apps/openmw/mwscript/soundextensions.hpp +++ b/apps/openmw/mwscript/soundextensions.hpp @@ -15,10 +15,9 @@ namespace MWScript { namespace Sound { - // Script-extensions related to sound - void installOpcodes (Interpreter::Interpreter& interpreter); + // Script-extensions related to sound + void installOpcodes(Interpreter::Interpreter& interpreter); } } #endif - diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 72f7304803..754d0e1d7b 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -9,10 +9,10 @@ #include #include #include +#include #include -#include #include -#include +#include #include @@ -25,9 +25,9 @@ #include "../mwworld/class.hpp" #include "../mwworld/player.hpp" +#include "../mwmechanics/actorutil.hpp" #include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/npcstats.hpp" -#include "../mwmechanics/actorutil.hpp" #include "../mwmechanics/spellcasting.hpp" #include "ref.hpp" @@ -38,8 +38,7 @@ namespace { std::string_view factionId = actor.getClass().getPrimaryFaction(actor); if (factionId.empty()) - throw std::runtime_error ( - "failed to determine dialogue actors faction (because actor is factionless)"); + throw std::runtime_error("failed to determine dialogue actors faction (because actor is factionless)"); return factionId; } @@ -50,15 +49,15 @@ namespace const float modifier = stat.getModifier() - stat.getDamage(); const float modified = base + modifier; // Clamp to 100 unless base < 100 and we have a fortification going - if((modifier <= 0.f || base >= 100.f) && amount > 0.f) + if ((modifier <= 0.f || base >= 100.f) && amount > 0.f) amount = std::clamp(100.f - modified, 0.f, amount); // Clamp the modified value in a way that doesn't properly account for negative numbers float newModified = modified + amount; - if(newModified < 0.f) + if (newModified < 0.f) { - if(modified >= 0.f) + if (modified >= 0.f) newModified = 0.f; - else if(newModified < modified) + else if (newModified < modified) newModified = modified; } // Calculate damage/fortification based on the clamped base value @@ -71,1130 +70,1091 @@ namespace MWScript { namespace Stats { - template + template class OpGetLevel : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - Interpreter::Type_Integer value = - ptr.getClass() - .getCreatureStats (ptr) - .getLevel(); + Interpreter::Type_Integer value = ptr.getClass().getCreatureStats(ptr).getLevel(); - runtime.push (value); - } + runtime.push(value); + } }; - template + template class OpSetLevel : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - Interpreter::Type_Integer value = runtime[0].mInteger; - runtime.pop(); + Interpreter::Type_Integer value = runtime[0].mInteger; + runtime.pop(); - ptr.getClass() - .getCreatureStats (ptr) - .setLevel(value); - } + ptr.getClass().getCreatureStats(ptr).setLevel(value); + } }; - template + template class OpGetAttribute : public Interpreter::Opcode0 { - int mIndex; - - public: + int mIndex; - OpGetAttribute (int index) : mIndex (index) {} + public: + OpGetAttribute(int index) + : mIndex(index) + { + } - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - Interpreter::Type_Float value = - ptr.getClass() - .getCreatureStats (ptr) - .getAttribute(mIndex) - .getModified(); + Interpreter::Type_Float value = ptr.getClass().getCreatureStats(ptr).getAttribute(mIndex).getModified(); - runtime.push (value); - } + runtime.push(value); + } }; - template + template class OpSetAttribute : public Interpreter::Opcode0 { - int mIndex; + int mIndex; - public: - - OpSetAttribute (int index) : mIndex (index) {} + public: + OpSetAttribute(int index) + : mIndex(index) + { + } - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - Interpreter::Type_Float value = runtime[0].mFloat; - runtime.pop(); + Interpreter::Type_Float value = runtime[0].mFloat; + runtime.pop(); - MWMechanics::AttributeValue attribute = ptr.getClass().getCreatureStats(ptr).getAttribute(mIndex); - attribute.setBase(value, true); - ptr.getClass().getCreatureStats(ptr).setAttribute(mIndex, attribute); - } + MWMechanics::AttributeValue attribute = ptr.getClass().getCreatureStats(ptr).getAttribute(mIndex); + attribute.setBase(value, true); + ptr.getClass().getCreatureStats(ptr).setAttribute(mIndex, attribute); + } }; - template + template class OpModAttribute : public Interpreter::Opcode0 { - int mIndex; - - public: + int mIndex; - OpModAttribute (int index) : mIndex (index) {} + public: + OpModAttribute(int index) + : mIndex(index) + { + } - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - Interpreter::Type_Float value = runtime[0].mFloat; - runtime.pop(); + Interpreter::Type_Float value = runtime[0].mFloat; + runtime.pop(); - MWMechanics::AttributeValue attribute = ptr.getClass() - .getCreatureStats(ptr) - .getAttribute(mIndex); - modStat(attribute, value); - ptr.getClass().getCreatureStats(ptr).setAttribute(mIndex, attribute); - } + MWMechanics::AttributeValue attribute = ptr.getClass().getCreatureStats(ptr).getAttribute(mIndex); + modStat(attribute, value); + ptr.getClass().getCreatureStats(ptr).setAttribute(mIndex, attribute); + } }; - template + template class OpGetDynamic : public Interpreter::Opcode0 { - int mIndex; + int mIndex; - public: + public: + OpGetDynamic(int index) + : mIndex(index) + { + } - OpGetDynamic (int index) : mIndex (index) {} + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); + Interpreter::Type_Float value; - void execute (Interpreter::Runtime& runtime) override + if (mIndex == 0 && ptr.getClass().hasItemHealth(ptr)) { - MWWorld::Ptr ptr = R()(runtime); - Interpreter::Type_Float value; - - if (mIndex==0 && ptr.getClass().hasItemHealth (ptr)) - { - // health is a special case - value = static_cast(ptr.getClass().getItemMaxHealth(ptr)); - } else { - value = - ptr.getClass() - .getCreatureStats(ptr) - .getDynamic(mIndex) - .getCurrent(); - // GetMagicka shouldn't return negative values - if(mIndex == 1 && value < 0) - value = 0; - } - runtime.push (value); + // health is a special case + value = static_cast(ptr.getClass().getItemMaxHealth(ptr)); + } + else + { + value = ptr.getClass().getCreatureStats(ptr).getDynamic(mIndex).getCurrent(); + // GetMagicka shouldn't return negative values + if (mIndex == 1 && value < 0) + value = 0; } + runtime.push(value); + } }; - template + template class OpSetDynamic : public Interpreter::Opcode0 { - int mIndex; - - public: + int mIndex; - OpSetDynamic (int index) : mIndex (index) {} + public: + OpSetDynamic(int index) + : mIndex(index) + { + } - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - Interpreter::Type_Float value = runtime[0].mFloat; - runtime.pop(); + Interpreter::Type_Float value = runtime[0].mFloat; + runtime.pop(); - MWMechanics::DynamicStat stat (ptr.getClass().getCreatureStats (ptr) - .getDynamic (mIndex)); + MWMechanics::DynamicStat stat(ptr.getClass().getCreatureStats(ptr).getDynamic(mIndex)); - stat.setBase(value); - stat.setCurrent(stat.getModified(false), true, true); + stat.setBase(value); + stat.setCurrent(stat.getModified(false), true, true); - ptr.getClass().getCreatureStats (ptr).setDynamic (mIndex, stat); - } + ptr.getClass().getCreatureStats(ptr).setDynamic(mIndex, stat); + } }; - template + template class OpModDynamic : public Interpreter::Opcode0 { - int mIndex; + int mIndex; - public: + public: + OpModDynamic(int index) + : mIndex(index) + { + } - OpModDynamic (int index) : mIndex (index) {} + void execute(Interpreter::Runtime& runtime) override + { + int peek = R::implicit ? 0 : runtime[0].mInteger; - void execute (Interpreter::Runtime& runtime) override - { - int peek = R::implicit ? 0 : runtime[0].mInteger; + MWWorld::Ptr ptr = R()(runtime); - MWWorld::Ptr ptr = R()(runtime); + Interpreter::Type_Float diff = runtime[0].mFloat; + runtime.pop(); - Interpreter::Type_Float diff = runtime[0].mFloat; - runtime.pop(); + // workaround broken endgame scripts that kill dagoth ur + if (!R::implicit && ::Misc::StringUtils::ciEqual(ptr.getCellRef().getRefId(), "dagoth_ur_1")) + { + runtime.push(peek); - // workaround broken endgame scripts that kill dagoth ur - if (!R::implicit && - ::Misc::StringUtils::ciEqual(ptr.getCellRef().getRefId(), "dagoth_ur_1")) + if (R()(runtime, false, true).isEmpty()) { - runtime.push (peek); + Log(Debug::Warning) << "Warning: Compensating for broken script in Morrowind.esm by " + << "ignoring remote access to dagoth_ur_1"; - if (R()(runtime, false, true).isEmpty()) - { - Log(Debug::Warning) - << "Warning: Compensating for broken script in Morrowind.esm by " - << "ignoring remote access to dagoth_ur_1"; - - return; - } + return; } + } - MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); + MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); - MWMechanics::DynamicStat stat = stats.getDynamic(mIndex); + MWMechanics::DynamicStat stat = stats.getDynamic(mIndex); - float current = stat.getCurrent(); - float base = diff + stat.getBase(); - if(mIndex != 2) - base = std::max(base, 0.f); - stat.setBase(base); - stat.setCurrent(diff + current, true, true); + float current = stat.getCurrent(); + float base = diff + stat.getBase(); + if (mIndex != 2) + base = std::max(base, 0.f); + stat.setBase(base); + stat.setCurrent(diff + current, true, true); - stats.setDynamic (mIndex, stat); - } + stats.setDynamic(mIndex, stat); + } }; - template + template class OpModCurrentDynamic : public Interpreter::Opcode0 { - int mIndex; - - public: - - OpModCurrentDynamic (int index) : mIndex (index) {} + int mIndex; - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + OpModCurrentDynamic(int index) + : mIndex(index) + { + } - Interpreter::Type_Float diff = runtime[0].mFloat; - runtime.pop(); + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats (ptr); + Interpreter::Type_Float diff = runtime[0].mFloat; + runtime.pop(); - Interpreter::Type_Float current = stats.getDynamic(mIndex).getCurrent(); + MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); - MWMechanics::DynamicStat stat (ptr.getClass().getCreatureStats (ptr) - .getDynamic (mIndex)); + Interpreter::Type_Float current = stats.getDynamic(mIndex).getCurrent(); - bool allowDecreaseBelowZero = false; - if (mIndex == 2) // Fatigue-specific logic - { - // For fatigue, a negative current value is allowed and means the actor will be knocked down - allowDecreaseBelowZero = true; - // Knock down the actor immediately if a non-positive new value is the case - if (diff + current <= 0.f) - ptr.getClass().getCreatureStats(ptr).setKnockedDown(true); - } - stat.setCurrent (diff + current, allowDecreaseBelowZero); + MWMechanics::DynamicStat stat(ptr.getClass().getCreatureStats(ptr).getDynamic(mIndex)); - ptr.getClass().getCreatureStats (ptr).setDynamic (mIndex, stat); + bool allowDecreaseBelowZero = false; + if (mIndex == 2) // Fatigue-specific logic + { + // For fatigue, a negative current value is allowed and means the actor will be knocked down + allowDecreaseBelowZero = true; + // Knock down the actor immediately if a non-positive new value is the case + if (diff + current <= 0.f) + ptr.getClass().getCreatureStats(ptr).setKnockedDown(true); } + stat.setCurrent(diff + current, allowDecreaseBelowZero); + + ptr.getClass().getCreatureStats(ptr).setDynamic(mIndex, stat); + } }; - template + template class OpGetDynamicGetRatio : public Interpreter::Opcode0 { - int mIndex; - - public: + int mIndex; - OpGetDynamicGetRatio (int index) : mIndex (index) {} + public: + OpGetDynamicGetRatio(int index) + : mIndex(index) + { + } - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); - const MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); + const MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); - runtime.push(stats.getDynamic(mIndex).getRatio()); - } + runtime.push(stats.getDynamic(mIndex).getRatio()); + } }; - template + template class OpGetSkill : public Interpreter::Opcode0 { - int mIndex; - - public: + int mIndex; - OpGetSkill (int index) : mIndex (index) {} + public: + OpGetSkill(int index) + : mIndex(index) + { + } - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - Interpreter::Type_Float value = ptr.getClass().getSkill(ptr, mIndex); + Interpreter::Type_Float value = ptr.getClass().getSkill(ptr, mIndex); - runtime.push (value); - } + runtime.push(value); + } }; - template + template class OpSetSkill : public Interpreter::Opcode0 { - int mIndex; - - public: + int mIndex; - OpSetSkill (int index) : mIndex (index) {} + public: + OpSetSkill(int index) + : mIndex(index) + { + } - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - Interpreter::Type_Float value = runtime[0].mFloat; - runtime.pop(); + Interpreter::Type_Float value = runtime[0].mFloat; + runtime.pop(); - MWMechanics::NpcStats& stats = ptr.getClass().getNpcStats (ptr); + MWMechanics::NpcStats& stats = ptr.getClass().getNpcStats(ptr); - stats.getSkill(mIndex).setBase(value, true); - } + stats.getSkill(mIndex).setBase(value, true); + } }; - template + template class OpModSkill : public Interpreter::Opcode0 { - int mIndex; + int mIndex; - public: - - OpModSkill (int index) : mIndex (index) {} + public: + OpModSkill(int index) + : mIndex(index) + { + } - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - Interpreter::Type_Float value = runtime[0].mFloat; - runtime.pop(); + Interpreter::Type_Float value = runtime[0].mFloat; + runtime.pop(); - MWMechanics::SkillValue &skill = ptr.getClass() - .getNpcStats(ptr) - .getSkill(mIndex); - modStat(skill, value); - } + MWMechanics::SkillValue& skill = ptr.getClass().getNpcStats(ptr).getSkill(mIndex); + modStat(skill, value); + } }; class OpGetPCCrimeLevel : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWBase::World *world = MWBase::Environment::get().getWorld(); - MWWorld::Ptr player = world->getPlayerPtr(); - runtime.push (static_cast (player.getClass().getNpcStats (player).getBounty())); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + MWBase::World* world = MWBase::Environment::get().getWorld(); + MWWorld::Ptr player = world->getPlayerPtr(); + runtime.push(static_cast(player.getClass().getNpcStats(player).getBounty())); + } }; class OpSetPCCrimeLevel : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWBase::World *world = MWBase::Environment::get().getWorld(); - MWWorld::Ptr player = world->getPlayerPtr(); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWBase::World* world = MWBase::Environment::get().getWorld(); + MWWorld::Ptr player = world->getPlayerPtr(); - int bounty = static_cast(runtime[0].mFloat); - runtime.pop(); - player.getClass().getNpcStats (player).setBounty(bounty); + int bounty = static_cast(runtime[0].mFloat); + runtime.pop(); + player.getClass().getNpcStats(player).setBounty(bounty); - if (bounty == 0) - MWBase::Environment::get().getWorld()->getPlayer().recordCrimeId(); - } + if (bounty == 0) + MWBase::Environment::get().getWorld()->getPlayer().recordCrimeId(); + } }; class OpModPCCrimeLevel : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWBase::World *world = MWBase::Environment::get().getWorld(); - MWWorld::Ptr player = world->getPlayerPtr(); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWBase::World* world = MWBase::Environment::get().getWorld(); + MWWorld::Ptr player = world->getPlayerPtr(); - player.getClass().getNpcStats(player).setBounty(static_cast(runtime[0].mFloat) + player.getClass().getNpcStats(player).getBounty()); - runtime.pop(); - } + player.getClass().getNpcStats(player).setBounty( + static_cast(runtime[0].mFloat) + player.getClass().getNpcStats(player).getBounty()); + runtime.pop(); + } }; - template + template class OpAddSpell : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - std::string_view id = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + std::string_view id = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get().find (id); + const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get().find(id); - MWMechanics::CreatureStats& creatureStats = ptr.getClass().getCreatureStats(ptr); - creatureStats.getSpells().add(spell); - ESM::Spell::SpellType type = static_cast(spell->mData.mType); - if (type != ESM::Spell::ST_Spell && type != ESM::Spell::ST_Power) - { - // Add spell effect to *this actor's* queue immediately - creatureStats.getActiveSpells().addSpell(spell, ptr); - // Apply looping particles immediately for constant effects - MWBase::Environment::get().getWorld()->applyLoopingParticles(ptr); - } + MWMechanics::CreatureStats& creatureStats = ptr.getClass().getCreatureStats(ptr); + creatureStats.getSpells().add(spell); + ESM::Spell::SpellType type = static_cast(spell->mData.mType); + if (type != ESM::Spell::ST_Spell && type != ESM::Spell::ST_Power) + { + // Add spell effect to *this actor's* queue immediately + creatureStats.getActiveSpells().addSpell(spell, ptr); + // Apply looping particles immediately for constant effects + MWBase::Environment::get().getWorld()->applyLoopingParticles(ptr); } + } }; - template + template class OpRemoveSpell : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - std::string_view id = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + std::string_view id = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - MWMechanics::CreatureStats& creatureStats = ptr.getClass().getCreatureStats(ptr); - creatureStats.getSpells().remove (id); + MWMechanics::CreatureStats& creatureStats = ptr.getClass().getCreatureStats(ptr); + creatureStats.getSpells().remove(id); - MWBase::WindowManager *wm = MWBase::Environment::get().getWindowManager(); + MWBase::WindowManager* wm = MWBase::Environment::get().getWindowManager(); - if (ptr == MWMechanics::getPlayer() && - id == wm->getSelectedSpell()) - { - wm->unsetSelectedSpell(); - } + if (ptr == MWMechanics::getPlayer() && id == wm->getSelectedSpell()) + { + wm->unsetSelectedSpell(); } + } }; - template + template class OpRemoveSpellEffects : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - std::string_view spellid = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + std::string_view spellid = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - ptr.getClass().getCreatureStats (ptr).getActiveSpells().removeEffects(ptr, spellid); - } + ptr.getClass().getCreatureStats(ptr).getActiveSpells().removeEffects(ptr, spellid); + } }; - template + template class OpRemoveEffects : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - Interpreter::Type_Integer effectId = runtime[0].mInteger; - runtime.pop(); + Interpreter::Type_Integer effectId = runtime[0].mInteger; + runtime.pop(); - ptr.getClass().getCreatureStats (ptr).getActiveSpells().purgeEffect(ptr, effectId); - } + ptr.getClass().getCreatureStats(ptr).getActiveSpells().purgeEffect(ptr, effectId); + } }; - template + template class OpGetSpell : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { + public: + void execute(Interpreter::Runtime& runtime) override + { - MWWorld::Ptr ptr = R()(runtime); + MWWorld::Ptr ptr = R()(runtime); - std::string_view id = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + std::string_view id = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - Interpreter::Type_Integer value = 0; + Interpreter::Type_Integer value = 0; - if (ptr.getClass().isActor() && ptr.getClass().getCreatureStats(ptr).getSpells().hasSpell(id)) - value = 1; + if (ptr.getClass().isActor() && ptr.getClass().getCreatureStats(ptr).getSpells().hasSpell(id)) + value = 1; - runtime.push (value); - } + runtime.push(value); + } }; - template + template class OpPCJoinFaction : public Interpreter::Opcode1 { - public: - - void execute (Interpreter::Runtime& runtime, unsigned int arg0) override - { - MWWorld::ConstPtr actor = R()(runtime, false); + public: + void execute(Interpreter::Runtime& runtime, unsigned int arg0) override + { + MWWorld::ConstPtr actor = R()(runtime, false); - std::string_view factionID; + std::string_view factionID; - if(arg0==0) - { - factionID = getDialogueActorFaction(actor); - } - else - { - factionID = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - } - // Make sure this faction exists - MWBase::Environment::get().getWorld()->getStore().get().find(factionID); + if (arg0 == 0) + { + factionID = getDialogueActorFaction(actor); + } + else + { + factionID = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); + } + // Make sure this faction exists + MWBase::Environment::get().getWorld()->getStore().get().find(factionID); - if(!factionID.empty()) - { - MWWorld::Ptr player = MWMechanics::getPlayer(); - player.getClass().getNpcStats(player).joinFaction(factionID); - } + if (!factionID.empty()) + { + MWWorld::Ptr player = MWMechanics::getPlayer(); + player.getClass().getNpcStats(player).joinFaction(factionID); } + } }; - template + template class OpPCRaiseRank : public Interpreter::Opcode1 { - public: + public: + void execute(Interpreter::Runtime& runtime, unsigned int arg0) override + { + MWWorld::ConstPtr actor = R()(runtime, false); - void execute (Interpreter::Runtime& runtime, unsigned int arg0) override - { - MWWorld::ConstPtr actor = R()(runtime, false); + std::string_view factionID; - std::string_view factionID; + if (arg0 == 0) + { + factionID = getDialogueActorFaction(actor); + } + else + { + factionID = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); + } + // Make sure this faction exists + MWBase::Environment::get().getWorld()->getStore().get().find(factionID); - if(arg0==0) + if (!factionID.empty()) + { + MWWorld::Ptr player = MWMechanics::getPlayer(); + if (!player.getClass().getNpcStats(player).isInFaction(factionID)) { - factionID = getDialogueActorFaction(actor); + player.getClass().getNpcStats(player).joinFaction(factionID); } else { - factionID = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - } - // Make sure this faction exists - MWBase::Environment::get().getWorld()->getStore().get().find(factionID); - - if(!factionID.empty()) - { - MWWorld::Ptr player = MWMechanics::getPlayer(); - if(!player.getClass().getNpcStats(player).isInFaction(factionID)) - { - player.getClass().getNpcStats(player).joinFaction(factionID); - } - else - { - player.getClass().getNpcStats(player).raiseRank(factionID); - } + player.getClass().getNpcStats(player).raiseRank(factionID); } } + } }; - template + template class OpPCLowerRank : public Interpreter::Opcode1 { - public: - - void execute (Interpreter::Runtime& runtime, unsigned int arg0) override - { - MWWorld::ConstPtr actor = R()(runtime, false); + public: + void execute(Interpreter::Runtime& runtime, unsigned int arg0) override + { + MWWorld::ConstPtr actor = R()(runtime, false); - std::string_view factionID; + std::string_view factionID; - if(arg0==0) - { - factionID = getDialogueActorFaction(actor); - } - else - { - factionID = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - } - // Make sure this faction exists - MWBase::Environment::get().getWorld()->getStore().get().find(factionID); + if (arg0 == 0) + { + factionID = getDialogueActorFaction(actor); + } + else + { + factionID = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); + } + // Make sure this faction exists + MWBase::Environment::get().getWorld()->getStore().get().find(factionID); - if(!factionID.empty()) - { - MWWorld::Ptr player = MWMechanics::getPlayer(); - player.getClass().getNpcStats(player).lowerRank(factionID); - } + if (!factionID.empty()) + { + MWWorld::Ptr player = MWMechanics::getPlayer(); + player.getClass().getNpcStats(player).lowerRank(factionID); } + } }; - template + template class OpGetPCRank : public Interpreter::Opcode1 { - public: + public: + void execute(Interpreter::Runtime& runtime, unsigned int arg0) override + { + MWWorld::ConstPtr ptr = R()(runtime, false); - void execute (Interpreter::Runtime& runtime, unsigned int arg0) override + std::string_view factionID; + if (arg0 > 0) { - MWWorld::ConstPtr ptr = R()(runtime, false); - - std::string_view factionID; - if(arg0 >0) - { - factionID = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - } - else - { - factionID = ptr.getClass().getPrimaryFaction(ptr); - } - // Make sure this faction exists - MWBase::Environment::get().getWorld()->getStore().get().find(factionID); + factionID = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); + } + else + { + factionID = ptr.getClass().getPrimaryFaction(ptr); + } + // Make sure this faction exists + MWBase::Environment::get().getWorld()->getStore().get().find(factionID); - if(!factionID.empty()) - { - MWWorld::Ptr player = MWMechanics::getPlayer(); - runtime.push(player.getClass().getNpcStats(player).getFactionRank(factionID)); - } - else - { - runtime.push(-1); - } + if (!factionID.empty()) + { + MWWorld::Ptr player = MWMechanics::getPlayer(); + runtime.push(player.getClass().getNpcStats(player).getFactionRank(factionID)); + } + else + { + runtime.push(-1); } + } }; - template + template class OpModDisposition : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - Interpreter::Type_Integer value = runtime[0].mInteger; - runtime.pop(); + Interpreter::Type_Integer value = runtime[0].mInteger; + runtime.pop(); - if (ptr.getClass().isNpc()) - ptr.getClass().getNpcStats (ptr).setBaseDisposition - (ptr.getClass().getNpcStats (ptr).getBaseDisposition() + value); + if (ptr.getClass().isNpc()) + ptr.getClass().getNpcStats(ptr).setBaseDisposition( + ptr.getClass().getNpcStats(ptr).getBaseDisposition() + value); - // else: must not throw exception (used by an Almalexia dialogue script) - } + // else: must not throw exception (used by an Almalexia dialogue script) + } }; - template + template class OpSetDisposition : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - Interpreter::Type_Integer value = runtime[0].mInteger; - runtime.pop(); + Interpreter::Type_Integer value = runtime[0].mInteger; + runtime.pop(); - if (ptr.getClass().isNpc()) - ptr.getClass().getNpcStats (ptr).setBaseDisposition (value); - } + if (ptr.getClass().isNpc()) + ptr.getClass().getNpcStats(ptr).setBaseDisposition(value); + } }; - template + template class OpGetDisposition : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - if (!ptr.getClass().isNpc()) - runtime.push(0); - else - runtime.push (MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(ptr)); - } + if (!ptr.getClass().isNpc()) + runtime.push(0); + else + runtime.push(MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(ptr)); + } }; class OpGetDeadCount : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - std::string id{runtime.getStringLiteral(runtime[0].mInteger)}; - runtime[0].mInteger = MWBase::Environment::get().getMechanicsManager()->countDeaths (id); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + std::string id{ runtime.getStringLiteral(runtime[0].mInteger) }; + runtime[0].mInteger = MWBase::Environment::get().getMechanicsManager()->countDeaths(id); + } }; - template + template class OpGetPCFacRep : public Interpreter::Opcode1 { - public: - - void execute (Interpreter::Runtime& runtime, unsigned int arg0) override - { - MWWorld::ConstPtr ptr = R()(runtime, false); + public: + void execute(Interpreter::Runtime& runtime, unsigned int arg0) override + { + MWWorld::ConstPtr ptr = R()(runtime, false); - std::string_view factionId; + std::string_view factionId; - if (arg0==1) - { - factionId = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - } - else - { - factionId = getDialogueActorFaction(ptr); - } + if (arg0 == 1) + { + factionId = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); + } + else + { + factionId = getDialogueActorFaction(ptr); + } - if (factionId.empty()) - throw std::runtime_error ("failed to determine faction"); + if (factionId.empty()) + throw std::runtime_error("failed to determine faction"); - MWWorld::Ptr player = MWMechanics::getPlayer(); - runtime.push ( - player.getClass().getNpcStats (player).getFactionReputation (factionId)); - } + MWWorld::Ptr player = MWMechanics::getPlayer(); + runtime.push(player.getClass().getNpcStats(player).getFactionReputation(factionId)); + } }; - template + template class OpSetPCFacRep : public Interpreter::Opcode1 { - public: - - void execute (Interpreter::Runtime& runtime, unsigned int arg0) override - { - MWWorld::ConstPtr ptr = R()(runtime, false); + public: + void execute(Interpreter::Runtime& runtime, unsigned int arg0) override + { + MWWorld::ConstPtr ptr = R()(runtime, false); - Interpreter::Type_Integer value = runtime[0].mInteger; - runtime.pop(); + Interpreter::Type_Integer value = runtime[0].mInteger; + runtime.pop(); - std::string_view factionId; + std::string_view factionId; - if (arg0==1) - { - factionId = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - } - else - { - factionId = getDialogueActorFaction(ptr); - } + if (arg0 == 1) + { + factionId = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); + } + else + { + factionId = getDialogueActorFaction(ptr); + } - if (factionId.empty()) - throw std::runtime_error ("failed to determine faction"); + if (factionId.empty()) + throw std::runtime_error("failed to determine faction"); - MWWorld::Ptr player = MWMechanics::getPlayer(); - player.getClass().getNpcStats (player).setFactionReputation (factionId, value); - } + MWWorld::Ptr player = MWMechanics::getPlayer(); + player.getClass().getNpcStats(player).setFactionReputation(factionId, value); + } }; - template + template class OpModPCFacRep : public Interpreter::Opcode1 { - public: - - void execute (Interpreter::Runtime& runtime, unsigned int arg0) override - { - MWWorld::ConstPtr ptr = R()(runtime, false); + public: + void execute(Interpreter::Runtime& runtime, unsigned int arg0) override + { + MWWorld::ConstPtr ptr = R()(runtime, false); - Interpreter::Type_Integer value = runtime[0].mInteger; - runtime.pop(); + Interpreter::Type_Integer value = runtime[0].mInteger; + runtime.pop(); - std::string_view factionId; + std::string_view factionId; - if (arg0==1) - { - factionId = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - } - else - { - factionId = getDialogueActorFaction(ptr); - } + if (arg0 == 1) + { + factionId = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); + } + else + { + factionId = getDialogueActorFaction(ptr); + } - if (factionId.empty()) - throw std::runtime_error ("failed to determine faction"); + if (factionId.empty()) + throw std::runtime_error("failed to determine faction"); - MWWorld::Ptr player = MWMechanics::getPlayer(); - player.getClass().getNpcStats (player).setFactionReputation (factionId, - player.getClass().getNpcStats (player).getFactionReputation (factionId)+ - value); - } + MWWorld::Ptr player = MWMechanics::getPlayer(); + player.getClass().getNpcStats(player).setFactionReputation( + factionId, player.getClass().getNpcStats(player).getFactionReputation(factionId) + value); + } }; - template + template class OpGetCommonDisease : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - runtime.push (ptr.getClass().getCreatureStats (ptr).hasCommonDisease()); - } + runtime.push(ptr.getClass().getCreatureStats(ptr).hasCommonDisease()); + } }; - template + template class OpGetBlightDisease : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - runtime.push (ptr.getClass().getCreatureStats (ptr).hasBlightDisease()); - } + runtime.push(ptr.getClass().getCreatureStats(ptr).hasBlightDisease()); + } }; - template + template class OpGetRace : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::ConstPtr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::ConstPtr ptr = R()(runtime); - std::string_view race = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + std::string_view race = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - const std::string& npcRace = ptr.get()->mBase->mRace; + const std::string& npcRace = ptr.get()->mBase->mRace; - runtime.push(::Misc::StringUtils::ciEqual(race, npcRace)); + runtime.push(::Misc::StringUtils::ciEqual(race, npcRace)); } }; class OpGetWerewolfKills : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = MWBase::Environment::get().getWorld ()->getPlayerPtr(); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->getPlayerPtr(); - runtime.push (ptr.getClass().getNpcStats (ptr).getWerewolfKills ()); - } + runtime.push(ptr.getClass().getNpcStats(ptr).getWerewolfKills()); + } }; template class OpPcExpelled : public Interpreter::Opcode1 { - public: + public: + void execute(Interpreter::Runtime& runtime, unsigned int arg0) override + { + MWWorld::ConstPtr ptr = R()(runtime, false); - void execute (Interpreter::Runtime& runtime, unsigned int arg0) override + std::string_view factionID; + if (arg0 > 0) { - MWWorld::ConstPtr ptr = R()(runtime, false); - - std::string_view factionID; - if(arg0 >0 ) - { - factionID = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - } - else - { - factionID = ptr.getClass().getPrimaryFaction(ptr); - } - MWWorld::Ptr player = MWMechanics::getPlayer(); - if(!factionID.empty()) - { - runtime.push(player.getClass().getNpcStats(player).getExpelled(factionID)); - } - else - { - runtime.push(0); - } + factionID = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); } + else + { + factionID = ptr.getClass().getPrimaryFaction(ptr); + } + MWWorld::Ptr player = MWMechanics::getPlayer(); + if (!factionID.empty()) + { + runtime.push(player.getClass().getNpcStats(player).getExpelled(factionID)); + } + else + { + runtime.push(0); + } + } }; template class OpPcExpell : public Interpreter::Opcode1 { - public: + public: + void execute(Interpreter::Runtime& runtime, unsigned int arg0) override + { + MWWorld::ConstPtr ptr = R()(runtime, false); - void execute (Interpreter::Runtime& runtime, unsigned int arg0) override + std::string_view factionID; + if (arg0 > 0) { - MWWorld::ConstPtr ptr = R()(runtime, false); - - std::string_view factionID; - if(arg0 >0 ) - { - factionID = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - } - else - { - factionID = ptr.getClass().getPrimaryFaction(ptr); - } - MWWorld::Ptr player = MWMechanics::getPlayer(); - if(!factionID.empty()) - { - player.getClass().getNpcStats(player).expell(factionID); - } + factionID = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); + } + else + { + factionID = ptr.getClass().getPrimaryFaction(ptr); + } + MWWorld::Ptr player = MWMechanics::getPlayer(); + if (!factionID.empty()) + { + player.getClass().getNpcStats(player).expell(factionID); } + } }; template class OpPcClearExpelled : public Interpreter::Opcode1 { - public: + public: + void execute(Interpreter::Runtime& runtime, unsigned int arg0) override + { + MWWorld::ConstPtr ptr = R()(runtime, false); - void execute (Interpreter::Runtime& runtime, unsigned int arg0) override + std::string_view factionID; + if (arg0 > 0) { - MWWorld::ConstPtr ptr = R()(runtime, false); - - std::string_view factionID; - if(arg0 >0 ) - { - factionID = runtime.getStringLiteral (runtime[0].mInteger); - runtime.pop(); - } - else - { - factionID = ptr.getClass().getPrimaryFaction(ptr); - } - MWWorld::Ptr player = MWMechanics::getPlayer(); - if(!factionID.empty()) - player.getClass().getNpcStats(player).clearExpelled(factionID); + factionID = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); } + else + { + factionID = ptr.getClass().getPrimaryFaction(ptr); + } + MWWorld::Ptr player = MWMechanics::getPlayer(); + if (!factionID.empty()) + player.getClass().getNpcStats(player).clearExpelled(factionID); + } }; template class OpRaiseRank : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - std::string_view factionID = ptr.getClass().getPrimaryFaction(ptr); - if(factionID.empty()) - return; + std::string_view factionID = ptr.getClass().getPrimaryFaction(ptr); + if (factionID.empty()) + return; - MWWorld::Ptr player = MWMechanics::getPlayer(); + MWWorld::Ptr player = MWMechanics::getPlayer(); - // no-op when executed on the player - if (ptr == player) - return; + // no-op when executed on the player + if (ptr == player) + return; - // If we already changed rank for this NPC, modify current rank in the NPC stats. - // Otherwise take rank from base NPC record, increase it and put it to NPC data. - int currentRank = ptr.getClass().getNpcStats(ptr).getFactionRank(factionID); - if (currentRank >= 0) + // If we already changed rank for this NPC, modify current rank in the NPC stats. + // Otherwise take rank from base NPC record, increase it and put it to NPC data. + int currentRank = ptr.getClass().getNpcStats(ptr).getFactionRank(factionID); + if (currentRank >= 0) + ptr.getClass().getNpcStats(ptr).raiseRank(factionID); + else + { + int rank = ptr.getClass().getPrimaryFactionRank(ptr); + rank++; + ptr.getClass().getNpcStats(ptr).joinFaction(factionID); + for (int i = 0; i < rank; i++) ptr.getClass().getNpcStats(ptr).raiseRank(factionID); - else - { - int rank = ptr.getClass().getPrimaryFactionRank(ptr); - rank++; - ptr.getClass().getNpcStats(ptr).joinFaction(factionID); - for (int i=0; i class OpLowerRank : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); - - std::string_view factionID = ptr.getClass().getPrimaryFaction(ptr); - if(factionID.empty()) - return; + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - MWWorld::Ptr player = MWMechanics::getPlayer(); + std::string_view factionID = ptr.getClass().getPrimaryFaction(ptr); + if (factionID.empty()) + return; - // no-op when executed on the player - if (ptr == player) - return; + MWWorld::Ptr player = MWMechanics::getPlayer(); - // If we already changed rank for this NPC, modify current rank in the NPC stats. - // Otherwise take rank from base NPC record, decrease it and put it to NPC data. - int currentRank = ptr.getClass().getNpcStats(ptr).getFactionRank(factionID); - if (currentRank == 0) - return; - else if (currentRank > 0) - ptr.getClass().getNpcStats(ptr).lowerRank(factionID); - else - { - int rank = ptr.getClass().getPrimaryFactionRank(ptr); - rank--; - ptr.getClass().getNpcStats(ptr).joinFaction(factionID); - for (int i=0; i 0) + ptr.getClass().getNpcStats(ptr).lowerRank(factionID); + else + { + int rank = ptr.getClass().getPrimaryFactionRank(ptr); + rank--; + ptr.getClass().getNpcStats(ptr).joinFaction(factionID); + for (int i = 0; i < rank; i++) + ptr.getClass().getNpcStats(ptr).raiseRank(factionID); } + } }; template class OpOnDeath : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - Interpreter::Type_Integer value = - ptr.getClass().getCreatureStats (ptr).hasDied(); + Interpreter::Type_Integer value = ptr.getClass().getCreatureStats(ptr).hasDied(); - if (value) - ptr.getClass().getCreatureStats (ptr).clearHasDied(); + if (value) + ptr.getClass().getCreatureStats(ptr).clearHasDied(); - runtime.push (value); - } + runtime.push(value); + } }; template class OpOnMurder : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - Interpreter::Type_Integer value = - ptr.getClass().getCreatureStats (ptr).hasBeenMurdered(); + Interpreter::Type_Integer value = ptr.getClass().getCreatureStats(ptr).hasBeenMurdered(); - if (value) - ptr.getClass().getCreatureStats (ptr).clearHasBeenMurdered(); + if (value) + ptr.getClass().getCreatureStats(ptr).clearHasBeenMurdered(); - runtime.push (value); - } + runtime.push(value); + } }; template class OpOnKnockout : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - Interpreter::Type_Integer value = - ptr.getClass().getCreatureStats (ptr).getKnockedDownOneFrame(); + Interpreter::Type_Integer value = ptr.getClass().getCreatureStats(ptr).getKnockedDownOneFrame(); - runtime.push (value); - } + runtime.push(value); + } }; template class OpIsWerewolf : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); - runtime.push(ptr.getClass().getNpcStats(ptr).isWerewolf()); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); + runtime.push(ptr.getClass().getNpcStats(ptr).isWerewolf()); + } }; template class OpSetWerewolf : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); - MWBase::Environment::get().getMechanicsManager()->setWerewolf(ptr, set); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); + MWBase::Environment::get().getMechanicsManager()->setWerewolf(ptr, set); + } }; template class OpSetWerewolfAcrobatics : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); - MWBase::Environment::get().getMechanicsManager()->applyWerewolfAcrobatics(ptr); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); + MWBase::Environment::get().getMechanicsManager()->applyWerewolfAcrobatics(ptr); + } }; template class OpResurrect : public Interpreter::Opcode0 { - public: + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - void execute (Interpreter::Runtime& runtime) override + if (ptr == MWMechanics::getPlayer()) { - MWWorld::Ptr ptr = R()(runtime); - - if (ptr == MWMechanics::getPlayer()) + MWBase::Environment::get().getMechanicsManager()->resurrect(ptr); + if (MWBase::Environment::get().getStateManager()->getState() == MWBase::StateManager::State_Ended) + MWBase::Environment::get().getStateManager()->resumeGame(); + } + else if (ptr.getClass().getCreatureStats(ptr).isDead()) + { + bool wasEnabled = ptr.getRefData().isEnabled(); + MWBase::Environment::get().getWorld()->undeleteObject(ptr); + auto windowManager = MWBase::Environment::get().getWindowManager(); + bool wasOpen = windowManager->containsMode(MWGui::GM_Container); + windowManager->onDeleteCustomData(ptr); + // HACK: disable/enable object to re-add it to the scene properly (need a new Animation). + MWBase::Environment::get().getWorld()->disable(ptr); + if (wasOpen && !windowManager->containsMode(MWGui::GM_Container)) { + // Reopen the loot GUI if it was closed because we resurrected the actor we were looting MWBase::Environment::get().getMechanicsManager()->resurrect(ptr); - if (MWBase::Environment::get().getStateManager()->getState() == MWBase::StateManager::State_Ended) - MWBase::Environment::get().getStateManager()->resumeGame(); + windowManager->forceLootMode(ptr); } - else if (ptr.getClass().getCreatureStats(ptr).isDead()) + else { - bool wasEnabled = ptr.getRefData().isEnabled(); - MWBase::Environment::get().getWorld()->undeleteObject(ptr); - auto windowManager = MWBase::Environment::get().getWindowManager(); - bool wasOpen = windowManager->containsMode(MWGui::GM_Container); - windowManager->onDeleteCustomData(ptr); - // HACK: disable/enable object to re-add it to the scene properly (need a new Animation). - MWBase::Environment::get().getWorld()->disable(ptr); - if (wasOpen && !windowManager->containsMode(MWGui::GM_Container)) - { - // Reopen the loot GUI if it was closed because we resurrected the actor we were looting - MWBase::Environment::get().getMechanicsManager()->resurrect(ptr); - windowManager->forceLootMode(ptr); - } - else - { - MWBase::Environment::get().getWorld()->removeContainerScripts(ptr); - // resets runtime state such as inventory, stats and AI. does not reset position in the world - ptr.getRefData().setCustomData(nullptr); - } - if (wasEnabled) - MWBase::Environment::get().getWorld()->enable(ptr); + MWBase::Environment::get().getWorld()->removeContainerScripts(ptr); + // resets runtime state such as inventory, stats and AI. does not reset position in the world + ptr.getRefData().setCustomData(nullptr); } + if (wasEnabled) + MWBase::Environment::get().getWorld()->enable(ptr); } + } }; template class OpGetStat : public Interpreter::Opcode0 { public: - void execute (Interpreter::Runtime& runtime) override + void execute(Interpreter::Runtime& runtime) override { // dummy runtime.pop(); @@ -1209,13 +1169,13 @@ namespace MWScript int mNegativeEffect; public: - OpGetMagicEffect (int positiveEffect, int negativeEffect) + OpGetMagicEffect(int positiveEffect, int negativeEffect) : mPositiveEffect(positiveEffect) , mNegativeEffect(negativeEffect) { } - void execute (Interpreter::Runtime& runtime) override + void execute(Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); @@ -1244,13 +1204,13 @@ namespace MWScript int mNegativeEffect; public: - OpSetMagicEffect (int positiveEffect, int negativeEffect) + OpSetMagicEffect(int positiveEffect, int negativeEffect) : mPositiveEffect(positiveEffect) , mNegativeEffect(negativeEffect) { } - void execute(Interpreter::Runtime &runtime) override + void execute(Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); MWMechanics::MagicEffects& effects = ptr.getClass().getCreatureStats(ptr).getMagicEffects(); @@ -1279,13 +1239,13 @@ namespace MWScript int mNegativeEffect; public: - OpModMagicEffect (int positiveEffect, int negativeEffect) + OpModMagicEffect(int positiveEffect, int negativeEffect) : mPositiveEffect(positiveEffect) , mNegativeEffect(negativeEffect) { } - void execute(Interpreter::Runtime &runtime) override + void execute(Interpreter::Runtime& runtime) override { MWWorld::Ptr ptr = R()(runtime); MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); @@ -1302,7 +1262,8 @@ namespace MWScript void execute(Interpreter::Runtime& runtime) override { MWWorld::Ptr player = MWMechanics::getPlayer(); - MWMechanics::EffectParam nightEye = player.getClass().getCreatureStats(player).getMagicEffects().get(ESM::MagicEffect::NightEye); + MWMechanics::EffectParam nightEye + = player.getClass().getCreatureStats(player).getMagicEffects().get(ESM::MagicEffect::NightEye); runtime.push(std::clamp(nightEye.getMagnitude() / 100.f, 0.f, 1.f)); } }; @@ -1316,7 +1277,8 @@ namespace MWScript runtime.pop(); MWWorld::Ptr player = MWMechanics::getPlayer(); auto& effects = player.getClass().getCreatureStats(player).getMagicEffects(); - float delta = std::clamp(arg * 100.f, 0.f, 100.f) - effects.get(ESM::MagicEffect::NightEye).getMagnitude(); + float delta + = std::clamp(arg * 100.f, 0.f, 100.f) - effects.get(ESM::MagicEffect::NightEye).getMagnitude(); effects.modifyBase(ESM::MagicEffect::NightEye, static_cast(delta)); } }; @@ -1344,39 +1306,49 @@ namespace MWScript int mNegativeEffect; }; - void installOpcodes (Interpreter::Interpreter& interpreter) + void installOpcodes(Interpreter::Interpreter& interpreter) { - for (int i=0; i>(Compiler::Stats::opcodeGetAttribute + i, i); - interpreter.installSegment5>(Compiler::Stats::opcodeGetAttributeExplicit + i, i); + interpreter.installSegment5>( + Compiler::Stats::opcodeGetAttributeExplicit + i, i); interpreter.installSegment5>(Compiler::Stats::opcodeSetAttribute + i, i); - interpreter.installSegment5>(Compiler::Stats::opcodeSetAttributeExplicit + i, i); + interpreter.installSegment5>( + Compiler::Stats::opcodeSetAttributeExplicit + i, i); interpreter.installSegment5>(Compiler::Stats::opcodeModAttribute + i, i); - interpreter.installSegment5>(Compiler::Stats::opcodeModAttributeExplicit + i, i); + interpreter.installSegment5>( + Compiler::Stats::opcodeModAttributeExplicit + i, i); } - for (int i=0; i>(Compiler::Stats::opcodeGetDynamic + i, i); - interpreter.installSegment5>(Compiler::Stats::opcodeGetDynamicExplicit + i, i); + interpreter.installSegment5>( + Compiler::Stats::opcodeGetDynamicExplicit + i, i); interpreter.installSegment5>(Compiler::Stats::opcodeSetDynamic + i, i); - interpreter.installSegment5>(Compiler::Stats::opcodeSetDynamicExplicit + i, i); + interpreter.installSegment5>( + Compiler::Stats::opcodeSetDynamicExplicit + i, i); interpreter.installSegment5>(Compiler::Stats::opcodeModDynamic + i, i); - interpreter.installSegment5>(Compiler::Stats::opcodeModDynamicExplicit + i, i); - - interpreter.installSegment5>(Compiler::Stats::opcodeModCurrentDynamic + i, i); - interpreter.installSegment5>(Compiler::Stats::opcodeModCurrentDynamicExplicit + i, i); - - interpreter.installSegment5>(Compiler::Stats::opcodeGetDynamicGetRatio + i, i); - interpreter.installSegment5>(Compiler::Stats::opcodeGetDynamicGetRatioExplicit + i, i); + interpreter.installSegment5>( + Compiler::Stats::opcodeModDynamicExplicit + i, i); + + interpreter.installSegment5>( + Compiler::Stats::opcodeModCurrentDynamic + i, i); + interpreter.installSegment5>( + Compiler::Stats::opcodeModCurrentDynamicExplicit + i, i); + + interpreter.installSegment5>( + Compiler::Stats::opcodeGetDynamicGetRatio + i, i); + interpreter.installSegment5>( + Compiler::Stats::opcodeGetDynamicGetRatioExplicit + i, i); } - for (int i=0; i>(Compiler::Stats::opcodeGetSkill + i, i); interpreter.installSegment5>(Compiler::Stats::opcodeGetSkillExplicit + i, i); @@ -1397,7 +1369,8 @@ namespace MWScript interpreter.installSegment5>(Compiler::Stats::opcodeRemoveSpell); interpreter.installSegment5>(Compiler::Stats::opcodeRemoveSpellExplicit); interpreter.installSegment5>(Compiler::Stats::opcodeRemoveSpellEffects); - interpreter.installSegment5>(Compiler::Stats::opcodeRemoveSpellEffectsExplicit); + interpreter.installSegment5>( + Compiler::Stats::opcodeRemoveSpellEffectsExplicit); interpreter.installSegment5>(Compiler::Stats::opcodeResurrect); interpreter.installSegment5>(Compiler::Stats::opcodeResurrectExplicit); interpreter.installSegment5>(Compiler::Stats::opcodeRemoveEffects); @@ -1437,9 +1410,11 @@ namespace MWScript interpreter.installSegment3>(Compiler::Stats::opcodeModPCFacRepExplicit); interpreter.installSegment5>(Compiler::Stats::opcodeGetCommonDisease); - interpreter.installSegment5>(Compiler::Stats::opcodeGetCommonDiseaseExplicit); + interpreter.installSegment5>( + Compiler::Stats::opcodeGetCommonDiseaseExplicit); interpreter.installSegment5>(Compiler::Stats::opcodeGetBlightDisease); - interpreter.installSegment5>(Compiler::Stats::opcodeGetBlightDiseaseExplicit); + interpreter.installSegment5>( + Compiler::Stats::opcodeGetBlightDiseaseExplicit); interpreter.installSegment5>(Compiler::Stats::opcodeGetRace); interpreter.installSegment5>(Compiler::Stats::opcodeGetRaceExplicit); @@ -1467,11 +1442,14 @@ namespace MWScript interpreter.installSegment5>(Compiler::Stats::opcodeIsWerewolfExplicit); interpreter.installSegment5>(Compiler::Stats::opcodeBecomeWerewolf); - interpreter.installSegment5>(Compiler::Stats::opcodeBecomeWerewolfExplicit); + interpreter.installSegment5>( + Compiler::Stats::opcodeBecomeWerewolfExplicit); interpreter.installSegment5>(Compiler::Stats::opcodeUndoWerewolf); interpreter.installSegment5>(Compiler::Stats::opcodeUndoWerewolfExplicit); - interpreter.installSegment5>(Compiler::Stats::opcodeSetWerewolfAcrobatics); - interpreter.installSegment5>(Compiler::Stats::opcodeSetWerewolfAcrobaticsExplicit); + interpreter.installSegment5>( + Compiler::Stats::opcodeSetWerewolfAcrobatics); + interpreter.installSegment5>( + Compiler::Stats::opcodeSetWerewolfAcrobaticsExplicit); interpreter.installSegment5>(Compiler::Stats::opcodeGetStat); interpreter.installSegment5>(Compiler::Stats::opcodeGetStatExplicit); @@ -1502,19 +1480,25 @@ namespace MWScript { ESM::MagicEffect::Sanctuary, -1 }, }; - for (int i=0; i<24; ++i) + for (int i = 0; i < 24; ++i) { int positive = sMagicEffects[i].mPositiveEffect; int negative = sMagicEffects[i].mNegativeEffect; - interpreter.installSegment5>(Compiler::Stats::opcodeGetMagicEffect + i, positive, negative); - interpreter.installSegment5>(Compiler::Stats::opcodeGetMagicEffectExplicit + i, positive, negative); + interpreter.installSegment5>( + Compiler::Stats::opcodeGetMagicEffect + i, positive, negative); + interpreter.installSegment5>( + Compiler::Stats::opcodeGetMagicEffectExplicit + i, positive, negative); - interpreter.installSegment5>(Compiler::Stats::opcodeSetMagicEffect + i, positive, negative); - interpreter.installSegment5>(Compiler::Stats::opcodeSetMagicEffectExplicit + i, positive, negative); + interpreter.installSegment5>( + Compiler::Stats::opcodeSetMagicEffect + i, positive, negative); + interpreter.installSegment5>( + Compiler::Stats::opcodeSetMagicEffectExplicit + i, positive, negative); - interpreter.installSegment5>(Compiler::Stats::opcodeModMagicEffect + i, positive, negative); - interpreter.installSegment5>(Compiler::Stats::opcodeModMagicEffectExplicit + i, positive, negative); + interpreter.installSegment5>( + Compiler::Stats::opcodeModMagicEffect + i, positive, negative); + interpreter.installSegment5>( + Compiler::Stats::opcodeModMagicEffectExplicit + i, positive, negative); } interpreter.installSegment5(Compiler::Stats::opcodeGetPCVisionBonus); diff --git a/apps/openmw/mwscript/statsextensions.hpp b/apps/openmw/mwscript/statsextensions.hpp index 213b549674..07d6a34f5b 100644 --- a/apps/openmw/mwscript/statsextensions.hpp +++ b/apps/openmw/mwscript/statsextensions.hpp @@ -15,8 +15,8 @@ namespace MWScript { /// \brief stats-related script functionality (creatures and NPCs) namespace Stats - { - void installOpcodes (Interpreter::Interpreter& interpreter); + { + void installOpcodes(Interpreter::Interpreter& interpreter); } } diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp index 412e9fa01e..bf62a276b4 100644 --- a/apps/openmw/mwscript/transformationextensions.cpp +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -7,17 +7,17 @@ #include #include -#include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" #include "../mwworld/cellstore.hpp" +#include "../mwworld/cellutils.hpp" #include "../mwworld/class.hpp" #include "../mwworld/manualref.hpp" #include "../mwworld/player.hpp" -#include "../mwworld/cellutils.hpp" #include "../mwmechanics/actorutil.hpp" @@ -28,777 +28,772 @@ namespace MWScript { namespace Transformation { - void moveStandingActors(const MWWorld::Ptr &ptr, const osg::Vec3f& diff) + void moveStandingActors(const MWWorld::Ptr& ptr, const osg::Vec3f& diff) { std::vector actors; - MWBase::Environment::get().getWorld()->getActorsStandingOn (ptr, actors); + MWBase::Environment::get().getWorld()->getActorsStandingOn(ptr, actors); for (auto& actor : actors) MWBase::Environment::get().getWorld()->moveObjectBy(actor, diff); } - template + template class OpGetDistance : public Interpreter::Opcode0 { - public: + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr from = R()(runtime, !R::implicit); + std::string_view name = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - void execute (Interpreter::Runtime& runtime) override + if (from.isEmpty()) { - MWWorld::Ptr from = R()(runtime, !R::implicit); - std::string_view name = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); - - if (from.isEmpty()) - { - std::string error = "Missing implicit ref"; - runtime.getContext().report(error); - Log(Debug::Error) << error; - runtime.push(0.f); - return; - } + std::string error = "Missing implicit ref"; + runtime.getContext().report(error); + Log(Debug::Error) << error; + runtime.push(0.f); + return; + } - if (from.getContainerStore()) // is the object contained? - { - MWWorld::Ptr container = MWBase::Environment::get().getWorld()->findContainer(from); - - if (!container.isEmpty()) - from = container; - else - { - std::string error = "Failed to find the container of object '" + from.getCellRef().getRefId() + "'"; - runtime.getContext().report(error); - Log(Debug::Error) << error; - runtime.push(0.f); - return; - } - } + if (from.getContainerStore()) // is the object contained? + { + MWWorld::Ptr container = MWBase::Environment::get().getWorld()->findContainer(from); - const MWWorld::Ptr to = MWBase::Environment::get().getWorld()->searchPtr(name, false); - if (to.isEmpty()) + if (!container.isEmpty()) + from = container; + else { - std::string error = "Failed to find an instance of object '" + std::string(name) + "'"; + std::string error + = "Failed to find the container of object '" + from.getCellRef().getRefId() + "'"; runtime.getContext().report(error); Log(Debug::Error) << error; runtime.push(0.f); return; } + } - float distance; - // If the objects are in different worldspaces, return a large value (just like vanilla) - if (!to.isInCell() || !from.isInCell() || to.getCell()->getCell()->getCellId().mWorldspace != from.getCell()->getCell()->getCellId().mWorldspace) - distance = std::numeric_limits::max(); - else - { - double diff[3]; + const MWWorld::Ptr to = MWBase::Environment::get().getWorld()->searchPtr(name, false); + if (to.isEmpty()) + { + std::string error = "Failed to find an instance of object '" + std::string(name) + "'"; + runtime.getContext().report(error); + Log(Debug::Error) << error; + runtime.push(0.f); + return; + } - const float* const pos1 = to.getRefData().getPosition().pos; - const float* const pos2 = from.getRefData().getPosition().pos; - for (int i=0; i<3; ++i) - diff[i] = pos1[i] - pos2[i]; + float distance; + // If the objects are in different worldspaces, return a large value (just like vanilla) + if (!to.isInCell() || !from.isInCell() + || to.getCell()->getCell()->getCellId().mWorldspace + != from.getCell()->getCell()->getCellId().mWorldspace) + distance = std::numeric_limits::max(); + else + { + double diff[3]; - distance = static_cast(std::sqrt(diff[0] * diff[0] + diff[1] * diff[1] + diff[2] * diff[2])); - } + const float* const pos1 = to.getRefData().getPosition().pos; + const float* const pos2 = from.getRefData().getPosition().pos; + for (int i = 0; i < 3; ++i) + diff[i] = pos1[i] - pos2[i]; - runtime.push(distance); + distance = static_cast(std::sqrt(diff[0] * diff[0] + diff[1] * diff[1] + diff[2] * diff[2])); } + + runtime.push(distance); + } }; - template + template class OpSetScale : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - Interpreter::Type_Float scale = runtime[0].mFloat; - runtime.pop(); + Interpreter::Type_Float scale = runtime[0].mFloat; + runtime.pop(); - MWBase::Environment::get().getWorld()->scaleObject(ptr,scale); - } + MWBase::Environment::get().getWorld()->scaleObject(ptr, scale); + } }; - template + template class OpGetScale : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); - runtime.push(ptr.getCellRef().getScale()); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); + runtime.push(ptr.getCellRef().getScale()); + } }; - template + template class OpModScale : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - Interpreter::Type_Float scale = runtime[0].mFloat; - runtime.pop(); + Interpreter::Type_Float scale = runtime[0].mFloat; + runtime.pop(); - // add the parameter to the object's scale. - MWBase::Environment::get().getWorld()->scaleObject(ptr,ptr.getCellRef().getScale() + scale); - } + // add the parameter to the object's scale. + MWBase::Environment::get().getWorld()->scaleObject(ptr, ptr.getCellRef().getScale() + scale); + } }; - template + template class OpSetAngle : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); - - std::string_view axis = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); - Interpreter::Type_Float angle = osg::DegreesToRadians(runtime[0].mFloat); - runtime.pop(); - - float ax = ptr.getRefData().getPosition().rot[0]; - float ay = ptr.getRefData().getPosition().rot[1]; - float az = ptr.getRefData().getPosition().rot[2]; - - // XYZ axis use the inverse (XYZ) rotation order like vanilla SetAngle. - // UWV axis use the standard (ZYX) rotation order like TESCS/OpenMW-CS and the rest of the game. - if (axis == "x") - MWBase::Environment::get().getWorld()->rotateObject(ptr,osg::Vec3f(angle,ay,az),MWBase::RotationFlag_inverseOrder); - else if (axis == "y") - MWBase::Environment::get().getWorld()->rotateObject(ptr,osg::Vec3f(ax,angle,az),MWBase::RotationFlag_inverseOrder); - else if (axis == "z") - MWBase::Environment::get().getWorld()->rotateObject(ptr,osg::Vec3f(ax,ay,angle),MWBase::RotationFlag_inverseOrder); - else if (axis == "u") - MWBase::Environment::get().getWorld()->rotateObject(ptr,osg::Vec3f(angle,ay,az),MWBase::RotationFlag_none); - else if (axis == "w") - MWBase::Environment::get().getWorld()->rotateObject(ptr,osg::Vec3f(ax,angle,az),MWBase::RotationFlag_none); - else if (axis == "v") - MWBase::Environment::get().getWorld()->rotateObject(ptr,osg::Vec3f(ax,ay,angle),MWBase::RotationFlag_none); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); + + std::string_view axis = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); + Interpreter::Type_Float angle = osg::DegreesToRadians(runtime[0].mFloat); + runtime.pop(); + + float ax = ptr.getRefData().getPosition().rot[0]; + float ay = ptr.getRefData().getPosition().rot[1]; + float az = ptr.getRefData().getPosition().rot[2]; + + // XYZ axis use the inverse (XYZ) rotation order like vanilla SetAngle. + // UWV axis use the standard (ZYX) rotation order like TESCS/OpenMW-CS and the rest of the game. + if (axis == "x") + MWBase::Environment::get().getWorld()->rotateObject( + ptr, osg::Vec3f(angle, ay, az), MWBase::RotationFlag_inverseOrder); + else if (axis == "y") + MWBase::Environment::get().getWorld()->rotateObject( + ptr, osg::Vec3f(ax, angle, az), MWBase::RotationFlag_inverseOrder); + else if (axis == "z") + MWBase::Environment::get().getWorld()->rotateObject( + ptr, osg::Vec3f(ax, ay, angle), MWBase::RotationFlag_inverseOrder); + else if (axis == "u") + MWBase::Environment::get().getWorld()->rotateObject( + ptr, osg::Vec3f(angle, ay, az), MWBase::RotationFlag_none); + else if (axis == "w") + MWBase::Environment::get().getWorld()->rotateObject( + ptr, osg::Vec3f(ax, angle, az), MWBase::RotationFlag_none); + else if (axis == "v") + MWBase::Environment::get().getWorld()->rotateObject( + ptr, osg::Vec3f(ax, ay, angle), MWBase::RotationFlag_none); + } }; - template + template class OpGetStartingAngle : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - std::string_view axis = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + std::string_view axis = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - float ret = 0.f; - if (!axis.empty()) + float ret = 0.f; + if (!axis.empty()) + { + if (axis[0] == 'x') + { + ret = osg::RadiansToDegrees(ptr.getCellRef().getPosition().rot[0]); + } + else if (axis[0] == 'y') { - if (axis[0] == 'x') - { - ret = osg::RadiansToDegrees(ptr.getCellRef().getPosition().rot[0]); - } - else if (axis[0] == 'y') - { - ret = osg::RadiansToDegrees(ptr.getCellRef().getPosition().rot[1]); - } - else if (axis[0] == 'z') - { - ret = osg::RadiansToDegrees(ptr.getCellRef().getPosition().rot[2]); - } + ret = osg::RadiansToDegrees(ptr.getCellRef().getPosition().rot[1]); + } + else if (axis[0] == 'z') + { + ret = osg::RadiansToDegrees(ptr.getCellRef().getPosition().rot[2]); } - runtime.push(ret); } + runtime.push(ret); + } }; - template + template class OpGetAngle : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - std::string_view axis = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + std::string_view axis = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - float ret = 0.f; - if (!axis.empty()) + float ret = 0.f; + if (!axis.empty()) + { + if (axis[0] == 'x') { - if (axis[0] == 'x') - { - ret = osg::RadiansToDegrees(ptr.getRefData().getPosition().rot[0]); - } - else if (axis[0] == 'y') - { - ret = osg::RadiansToDegrees(ptr.getRefData().getPosition().rot[1]); - } - else if (axis[0] == 'z') - { - ret = osg::RadiansToDegrees(ptr.getRefData().getPosition().rot[2]); - } + ret = osg::RadiansToDegrees(ptr.getRefData().getPosition().rot[0]); } - runtime.push(ret); - } - }; - - template - class OpGetPos : public Interpreter::Opcode0 - { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); - - std::string_view axis = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); - - float ret = 0.f; - if (!axis.empty()) + else if (axis[0] == 'y') { - if (axis[0] == 'x') - { - ret = ptr.getRefData().getPosition().pos[0]; - } - else if (axis[0] == 'y') - { - ret = ptr.getRefData().getPosition().pos[1]; - } - else if (axis[0] == 'z') - { - ret = ptr.getRefData().getPosition().pos[2]; - } + ret = osg::RadiansToDegrees(ptr.getRefData().getPosition().rot[1]); + } + else if (axis[0] == 'z') + { + ret = osg::RadiansToDegrees(ptr.getRefData().getPosition().rot[2]); } - runtime.push(ret); } + runtime.push(ret); + } }; - template - class OpSetPos : public Interpreter::Opcode0 + template + class OpGetPos : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); - - std::string_view axis = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); - Interpreter::Type_Float pos = runtime[0].mFloat; - runtime.pop(); - - if (!ptr.isInCell()) - return; + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - // Note: SetPos does not skip weather transitions in vanilla engine, so we do not call setTeleported(true) here. + std::string_view axis = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - const auto curPos = ptr.getRefData().getPosition().asVec3(); - auto newPos = curPos; - if(axis == "x") - { - newPos[0] = pos; - } - else if(axis == "y") + float ret = 0.f; + if (!axis.empty()) + { + if (axis[0] == 'x') { - newPos[1] = pos; + ret = ptr.getRefData().getPosition().pos[0]; } - else if(axis == "z") + else if (axis[0] == 'y') { - // We should not place actors under ground - if (ptr.getClass().isActor()) - { - float terrainHeight = -std::numeric_limits::max(); - if (ptr.getCell()->isExterior()) - terrainHeight = MWBase::Environment::get().getWorld()->getTerrainHeightAt(curPos); - - if (pos < terrainHeight) - pos = terrainHeight; - } - - newPos[2] = pos; + ret = ptr.getRefData().getPosition().pos[1]; } - else + else if (axis[0] == 'z') { - return; + ret = ptr.getRefData().getPosition().pos[2]; } - - dynamic_cast(runtime.getContext()).updatePtr(ptr, - MWBase::Environment::get().getWorld()->moveObject(ptr, newPos, true, true)); } + runtime.push(ret); + } }; - template - class OpGetStartingPos : public Interpreter::Opcode0 + template + class OpSetPos : public Interpreter::Opcode0 { - public: + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); + std::string_view axis = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); + Interpreter::Type_Float pos = runtime[0].mFloat; + runtime.pop(); - std::string_view axis = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + if (!ptr.isInCell()) + return; - float ret = 0.f; - if (!axis.empty()) + // Note: SetPos does not skip weather transitions in vanilla engine, so we do not call + // setTeleported(true) here. + + const auto curPos = ptr.getRefData().getPosition().asVec3(); + auto newPos = curPos; + if (axis == "x") + { + newPos[0] = pos; + } + else if (axis == "y") + { + newPos[1] = pos; + } + else if (axis == "z") + { + // We should not place actors under ground + if (ptr.getClass().isActor()) { - if (axis[0] == 'x') - { - ret = ptr.getCellRef().getPosition().pos[0]; - } - else if (axis[0] == 'y') - { - ret = ptr.getCellRef().getPosition().pos[1]; - } - else if (axis[0] == 'z') - { - ret = ptr.getCellRef().getPosition().pos[2]; - } + float terrainHeight = -std::numeric_limits::max(); + if (ptr.getCell()->isExterior()) + terrainHeight = MWBase::Environment::get().getWorld()->getTerrainHeightAt(curPos); + + if (pos < terrainHeight) + pos = terrainHeight; } - runtime.push(ret); + + newPos[2] = pos; + } + else + { + return; } + + dynamic_cast(runtime.getContext()) + .updatePtr(ptr, MWBase::Environment::get().getWorld()->moveObject(ptr, newPos, true, true)); + } }; - template - class OpPositionCell : public Interpreter::Opcode0 + template + class OpGetStartingPos : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); - - Interpreter::Type_Float x = runtime[0].mFloat; - runtime.pop(); - Interpreter::Type_Float y = runtime[0].mFloat; - runtime.pop(); - Interpreter::Type_Float z = runtime[0].mFloat; - runtime.pop(); - Interpreter::Type_Float zRot = runtime[0].mFloat; - runtime.pop(); - std::string_view cellID = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); - - if (ptr.getContainerStore()) - return; + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - bool isPlayer = ptr == MWMechanics::getPlayer(); - if (isPlayer) - { - MWBase::Environment::get().getWorld()->getPlayer().setTeleported(true); - } + std::string_view axis = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - MWWorld::CellStore* store = nullptr; - try + float ret = 0.f; + if (!axis.empty()) + { + if (axis[0] == 'x') { - store = MWBase::Environment::get().getWorld()->getInterior(cellID); + ret = ptr.getCellRef().getPosition().pos[0]; } - catch(std::exception&) + else if (axis[0] == 'y') { - // cell not found, move to exterior instead if moving the player (vanilla PositionCell compatibility) - const ESM::Cell* cell = MWBase::Environment::get().getWorld()->getExterior(cellID); - if(!cell) - { - std::string error = "Warning: PositionCell: unknown interior cell (" + std::string(cellID) + ")"; - if(isPlayer) - error += ", moving to exterior instead"; - runtime.getContext().report (error); - Log(Debug::Warning) << error; - if(!isPlayer) - return; - } - const osg::Vec2i cellIndex = MWWorld::positionToCellIndex(x, y); - store = MWBase::Environment::get().getWorld()->getExterior(cellIndex.x(), cellIndex.y()); + ret = ptr.getCellRef().getPosition().pos[1]; } - if(store) + else if (axis[0] == 'z') { - MWWorld::Ptr base = ptr; - ptr = MWBase::Environment::get().getWorld()->moveObject(ptr,store,osg::Vec3f(x,y,z)); - dynamic_cast(runtime.getContext()).updatePtr(base,ptr); - - auto rot = ptr.getRefData().getPosition().asRotationVec3(); - // Note that you must specify ZRot in minutes (1 degree = 60 minutes; north = 0, east = 5400, south = 10800, west = 16200) - // except for when you position the player, then degrees must be used. - // See "Morrowind Scripting for Dummies (9th Edition)" pages 50 and 54 for reference. - if(!isPlayer) - zRot = zRot/60.0f; - rot.z() = osg::DegreesToRadians(zRot); - MWBase::Environment::get().getWorld()->rotateObject(ptr,rot); - - ptr.getClass().adjustPosition(ptr, true); + ret = ptr.getCellRef().getPosition().pos[2]; } } + runtime.push(ret); + } }; - template - class OpPosition : public Interpreter::Opcode0 + template + class OpPositionCell : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); + + Interpreter::Type_Float x = runtime[0].mFloat; + runtime.pop(); + Interpreter::Type_Float y = runtime[0].mFloat; + runtime.pop(); + Interpreter::Type_Float z = runtime[0].mFloat; + runtime.pop(); + Interpreter::Type_Float zRot = runtime[0].mFloat; + runtime.pop(); + std::string_view cellID = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); + + if (ptr.getContainerStore()) + return; + + bool isPlayer = ptr == MWMechanics::getPlayer(); + if (isPlayer) { - MWWorld::Ptr ptr = R()(runtime); - - Interpreter::Type_Float x = runtime[0].mFloat; - runtime.pop(); - Interpreter::Type_Float y = runtime[0].mFloat; - runtime.pop(); - Interpreter::Type_Float z = runtime[0].mFloat; - runtime.pop(); - Interpreter::Type_Float zRot = runtime[0].mFloat; - runtime.pop(); - - if (!ptr.isInCell()) - return; + MWBase::Environment::get().getWorld()->getPlayer().setTeleported(true); + } - if (ptr == MWMechanics::getPlayer()) + MWWorld::CellStore* store = nullptr; + try + { + store = MWBase::Environment::get().getWorld()->getInterior(cellID); + } + catch (std::exception&) + { + // cell not found, move to exterior instead if moving the player (vanilla PositionCell + // compatibility) + const ESM::Cell* cell = MWBase::Environment::get().getWorld()->getExterior(cellID); + if (!cell) { - MWBase::Environment::get().getWorld()->getPlayer().setTeleported(true); + std::string error + = "Warning: PositionCell: unknown interior cell (" + std::string(cellID) + ")"; + if (isPlayer) + error += ", moving to exterior instead"; + runtime.getContext().report(error); + Log(Debug::Warning) << error; + if (!isPlayer) + return; } const osg::Vec2i cellIndex = MWWorld::positionToCellIndex(x, y); - - // another morrowind oddity: player will be moved to the exterior cell at this location, - // non-player actors will move within the cell they are in. + store = MWBase::Environment::get().getWorld()->getExterior(cellIndex.x(), cellIndex.y()); + } + if (store) + { MWWorld::Ptr base = ptr; - if (ptr == MWMechanics::getPlayer()) - { - MWWorld::CellStore* cell = MWBase::Environment::get().getWorld()->getExterior(cellIndex.x(), cellIndex.y()); - ptr = MWBase::Environment::get().getWorld()->moveObject(ptr, cell, osg::Vec3(x, y, z)); - } - else - { - ptr = MWBase::Environment::get().getWorld()->moveObject(ptr, osg::Vec3f(x, y, z), true, true); - } - dynamic_cast(runtime.getContext()).updatePtr(base,ptr); + ptr = MWBase::Environment::get().getWorld()->moveObject(ptr, store, osg::Vec3f(x, y, z)); + dynamic_cast(runtime.getContext()).updatePtr(base, ptr); auto rot = ptr.getRefData().getPosition().asRotationVec3(); - // Note that you must specify ZRot in minutes (1 degree = 60 minutes; north = 0, east = 5400, south = 10800, west = 16200) - // except for when you position the player, then degrees must be used. - // See "Morrowind Scripting for Dummies (9th Edition)" pages 50 and 54 for reference. - if(ptr != MWMechanics::getPlayer()) - zRot = zRot/60.0f; + // Note that you must specify ZRot in minutes (1 degree = 60 minutes; north = 0, east = 5400, south + // = 10800, west = 16200) except for when you position the player, then degrees must be used. See + // "Morrowind Scripting for Dummies (9th Edition)" pages 50 and 54 for reference. + if (!isPlayer) + zRot = zRot / 60.0f; rot.z() = osg::DegreesToRadians(zRot); - MWBase::Environment::get().getWorld()->rotateObject(ptr,rot); + MWBase::Environment::get().getWorld()->rotateObject(ptr, rot); + ptr.getClass().adjustPosition(ptr, true); } + } }; - class OpPlaceItemCell : public Interpreter::Opcode0 + template + class OpPosition : public Interpreter::Opcode0 { - public: + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - void execute (Interpreter::Runtime& runtime) override + Interpreter::Type_Float x = runtime[0].mFloat; + runtime.pop(); + Interpreter::Type_Float y = runtime[0].mFloat; + runtime.pop(); + Interpreter::Type_Float z = runtime[0].mFloat; + runtime.pop(); + Interpreter::Type_Float zRot = runtime[0].mFloat; + runtime.pop(); + + if (!ptr.isInCell()) + return; + + if (ptr == MWMechanics::getPlayer()) { - std::string_view itemID = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); - std::string_view cellID = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); - - Interpreter::Type_Float x = runtime[0].mFloat; - runtime.pop(); - Interpreter::Type_Float y = runtime[0].mFloat; - runtime.pop(); - Interpreter::Type_Float z = runtime[0].mFloat; - runtime.pop(); - Interpreter::Type_Float zRotDegrees = runtime[0].mFloat; - runtime.pop(); - - MWWorld::CellStore* store = nullptr; - try - { - store = MWBase::Environment::get().getWorld()->getInterior(cellID); - } - catch(std::exception&) - { - const ESM::Cell* cell = MWBase::Environment::get().getWorld()->getExterior(cellID); - const osg::Vec2i cellIndex = MWWorld::positionToCellIndex(x, y); - store = MWBase::Environment::get().getWorld()->getExterior(cellIndex.x(), cellIndex.y()); - if(!cell) - { - runtime.getContext().report("unknown cell (" + std::string(cellID) + ")"); - Log(Debug::Error) << "Error: unknown cell (" << cellID << ")"; - } - } - if(store) - { - ESM::Position pos; - pos.pos[0] = x; - pos.pos[1] = y; - pos.pos[2] = z; - pos.rot[0] = pos.rot[1] = 0; - pos.rot[2] = osg::DegreesToRadians(zRotDegrees); - MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(),itemID); - ref.getPtr().mRef->mData.mPhysicsPostponed = !ref.getPtr().getClass().isActor(); - ref.getPtr().getCellRef().setPosition(pos); - MWWorld::Ptr placed = MWBase::Environment::get().getWorld()->placeObject(ref.getPtr(),store,pos); - placed.getClass().adjustPosition(placed, true); - } + MWBase::Environment::get().getWorld()->getPlayer().setTeleported(true); + } + const osg::Vec2i cellIndex = MWWorld::positionToCellIndex(x, y); + + // another morrowind oddity: player will be moved to the exterior cell at this location, + // non-player actors will move within the cell they are in. + MWWorld::Ptr base = ptr; + if (ptr == MWMechanics::getPlayer()) + { + MWWorld::CellStore* cell + = MWBase::Environment::get().getWorld()->getExterior(cellIndex.x(), cellIndex.y()); + ptr = MWBase::Environment::get().getWorld()->moveObject(ptr, cell, osg::Vec3(x, y, z)); + } + else + { + ptr = MWBase::Environment::get().getWorld()->moveObject(ptr, osg::Vec3f(x, y, z), true, true); } + dynamic_cast(runtime.getContext()).updatePtr(base, ptr); + + auto rot = ptr.getRefData().getPosition().asRotationVec3(); + // Note that you must specify ZRot in minutes (1 degree = 60 minutes; north = 0, east = 5400, south = + // 10800, west = 16200) except for when you position the player, then degrees must be used. See + // "Morrowind Scripting for Dummies (9th Edition)" pages 50 and 54 for reference. + if (ptr != MWMechanics::getPlayer()) + zRot = zRot / 60.0f; + rot.z() = osg::DegreesToRadians(zRot); + MWBase::Environment::get().getWorld()->rotateObject(ptr, rot); + ptr.getClass().adjustPosition(ptr, true); + } }; - class OpPlaceItem : public Interpreter::Opcode0 + class OpPlaceItemCell : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override + public: + void execute(Interpreter::Runtime& runtime) override + { + std::string_view itemID = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); + std::string_view cellID = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); + + Interpreter::Type_Float x = runtime[0].mFloat; + runtime.pop(); + Interpreter::Type_Float y = runtime[0].mFloat; + runtime.pop(); + Interpreter::Type_Float z = runtime[0].mFloat; + runtime.pop(); + Interpreter::Type_Float zRotDegrees = runtime[0].mFloat; + runtime.pop(); + + MWWorld::CellStore* store = nullptr; + try { - std::string_view itemID = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); - - Interpreter::Type_Float x = runtime[0].mFloat; - runtime.pop(); - Interpreter::Type_Float y = runtime[0].mFloat; - runtime.pop(); - Interpreter::Type_Float z = runtime[0].mFloat; - runtime.pop(); - Interpreter::Type_Float zRotDegrees = runtime[0].mFloat; - runtime.pop(); - - MWWorld::Ptr player = MWMechanics::getPlayer(); - - if (!player.isInCell()) - throw std::runtime_error("player not in a cell"); - - MWWorld::CellStore* store = nullptr; - if (player.getCell()->isExterior()) + store = MWBase::Environment::get().getWorld()->getInterior(cellID); + } + catch (std::exception&) + { + const ESM::Cell* cell = MWBase::Environment::get().getWorld()->getExterior(cellID); + const osg::Vec2i cellIndex = MWWorld::positionToCellIndex(x, y); + store = MWBase::Environment::get().getWorld()->getExterior(cellIndex.x(), cellIndex.y()); + if (!cell) { - const osg::Vec2i cellIndex = MWWorld::positionToCellIndex(x, y); - store = MWBase::Environment::get().getWorld()->getExterior(cellIndex.x(), cellIndex.y()); + runtime.getContext().report("unknown cell (" + std::string(cellID) + ")"); + Log(Debug::Error) << "Error: unknown cell (" << cellID << ")"; } - else - store = player.getCell(); - + } + if (store) + { ESM::Position pos; pos.pos[0] = x; pos.pos[1] = y; pos.pos[2] = z; pos.rot[0] = pos.rot[1] = 0; pos.rot[2] = osg::DegreesToRadians(zRotDegrees); - MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(),itemID); + MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), itemID); ref.getPtr().mRef->mData.mPhysicsPostponed = !ref.getPtr().getClass().isActor(); ref.getPtr().getCellRef().setPosition(pos); - MWWorld::Ptr placed = MWBase::Environment::get().getWorld()->placeObject(ref.getPtr(),store,pos); + MWWorld::Ptr placed = MWBase::Environment::get().getWorld()->placeObject(ref.getPtr(), store, pos); placed.getClass().adjustPosition(placed, true); } + } }; - template - class OpPlaceAt : public Interpreter::Opcode0 + class OpPlaceItem : public Interpreter::Opcode0 { - public: + public: + void execute(Interpreter::Runtime& runtime) override + { + std::string_view itemID = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); + + Interpreter::Type_Float x = runtime[0].mFloat; + runtime.pop(); + Interpreter::Type_Float y = runtime[0].mFloat; + runtime.pop(); + Interpreter::Type_Float z = runtime[0].mFloat; + runtime.pop(); + Interpreter::Type_Float zRotDegrees = runtime[0].mFloat; + runtime.pop(); + + MWWorld::Ptr player = MWMechanics::getPlayer(); + + if (!player.isInCell()) + throw std::runtime_error("player not in a cell"); - void execute (Interpreter::Runtime& runtime) override + MWWorld::CellStore* store = nullptr; + if (player.getCell()->isExterior()) { - MWWorld::Ptr actor = pc - ? MWMechanics::getPlayer() - : R()(runtime); + const osg::Vec2i cellIndex = MWWorld::positionToCellIndex(x, y); + store = MWBase::Environment::get().getWorld()->getExterior(cellIndex.x(), cellIndex.y()); + } + else + store = player.getCell(); + + ESM::Position pos; + pos.pos[0] = x; + pos.pos[1] = y; + pos.pos[2] = z; + pos.rot[0] = pos.rot[1] = 0; + pos.rot[2] = osg::DegreesToRadians(zRotDegrees); + MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), itemID); + ref.getPtr().mRef->mData.mPhysicsPostponed = !ref.getPtr().getClass().isActor(); + ref.getPtr().getCellRef().setPosition(pos); + MWWorld::Ptr placed = MWBase::Environment::get().getWorld()->placeObject(ref.getPtr(), store, pos); + placed.getClass().adjustPosition(placed, true); + } + }; - std::string_view itemID = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); + template + class OpPlaceAt : public Interpreter::Opcode0 + { + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr actor = pc ? MWMechanics::getPlayer() : R()(runtime); - Interpreter::Type_Integer count = runtime[0].mInteger; - runtime.pop(); - Interpreter::Type_Float distance = runtime[0].mFloat; - runtime.pop(); - Interpreter::Type_Integer direction = runtime[0].mInteger; - runtime.pop(); + std::string_view itemID = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); - if (direction < 0 || direction > 3) - throw std::runtime_error ("invalid direction"); + Interpreter::Type_Integer count = runtime[0].mInteger; + runtime.pop(); + Interpreter::Type_Float distance = runtime[0].mFloat; + runtime.pop(); + Interpreter::Type_Integer direction = runtime[0].mInteger; + runtime.pop(); - if (count<0) - throw std::runtime_error ("count must be non-negative"); + if (direction < 0 || direction > 3) + throw std::runtime_error("invalid direction"); - if (!actor.isInCell()) - throw std::runtime_error ("actor is not in a cell"); + if (count < 0) + throw std::runtime_error("count must be non-negative"); - for (int i=0; igetStore(), itemID, 1); - ref.getPtr().mRef->mData.mPhysicsPostponed = !ref.getPtr().getClass().isActor(); + if (!actor.isInCell()) + throw std::runtime_error("actor is not in a cell"); - MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(), actor, actor.getCell(), direction, distance); - MWBase::Environment::get().getWorld()->scaleObject(ptr, actor.getCellRef().getScale()); - } + for (int i = 0; i < count; ++i) + { + // create item + MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), itemID, 1); + ref.getPtr().mRef->mData.mPhysicsPostponed = !ref.getPtr().getClass().isActor(); + + MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->safePlaceObject( + ref.getPtr(), actor, actor.getCell(), direction, distance); + MWBase::Environment::get().getWorld()->scaleObject(ptr, actor.getCellRef().getScale()); } + } }; - template + template class OpRotate : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - const MWWorld::Ptr& ptr = R()(runtime); - - std::string_view axis = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); - Interpreter::Type_Float rotation = osg::DegreesToRadians(runtime[0].mFloat*MWBase::Environment::get().getFrameDuration()); - runtime.pop(); - - auto rot = ptr.getRefData().getPosition().asRotationVec3(); - // Regardless of the axis argument, the player may only be rotated on Z - if (axis == "z" || MWMechanics::getPlayer() == ptr) - rot.z() += rotation; - else if (axis == "x") - rot.x() += rotation; - else if (axis == "y") - rot.y() += rotation; - MWBase::Environment::get().getWorld()->rotateObject(ptr,rot); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + const MWWorld::Ptr& ptr = R()(runtime); + + std::string_view axis = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); + Interpreter::Type_Float rotation + = osg::DegreesToRadians(runtime[0].mFloat * MWBase::Environment::get().getFrameDuration()); + runtime.pop(); + + auto rot = ptr.getRefData().getPosition().asRotationVec3(); + // Regardless of the axis argument, the player may only be rotated on Z + if (axis == "z" || MWMechanics::getPlayer() == ptr) + rot.z() += rotation; + else if (axis == "x") + rot.x() += rotation; + else if (axis == "y") + rot.y() += rotation; + MWBase::Environment::get().getWorld()->rotateObject(ptr, rot); + } }; - template + template class OpRotateWorld : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); - - std::string_view axis = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); - Interpreter::Type_Float rotation = osg::DegreesToRadians(runtime[0].mFloat*MWBase::Environment::get().getFrameDuration()); - runtime.pop(); - - if (!ptr.getRefData().getBaseNode()) - return; - - // We can rotate actors only around Z axis - if (ptr.getClass().isActor() && (axis == "x" || axis == "y")) - return; - - osg::Quat rot; - if (axis == "x") - rot = osg::Quat(rotation, -osg::X_AXIS); - else if (axis == "y") - rot = osg::Quat(rotation, -osg::Y_AXIS); - else if (axis == "z") - rot = osg::Quat(rotation, -osg::Z_AXIS); - else - return; - - osg::Quat attitude = ptr.getRefData().getBaseNode()->getAttitude(); - MWBase::Environment::get().getWorld()->rotateWorldObject(ptr, attitude * rot); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); + + std::string_view axis = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); + Interpreter::Type_Float rotation + = osg::DegreesToRadians(runtime[0].mFloat * MWBase::Environment::get().getFrameDuration()); + runtime.pop(); + + if (!ptr.getRefData().getBaseNode()) + return; + + // We can rotate actors only around Z axis + if (ptr.getClass().isActor() && (axis == "x" || axis == "y")) + return; + + osg::Quat rot; + if (axis == "x") + rot = osg::Quat(rotation, -osg::X_AXIS); + else if (axis == "y") + rot = osg::Quat(rotation, -osg::Y_AXIS); + else if (axis == "z") + rot = osg::Quat(rotation, -osg::Z_AXIS); + else + return; + + osg::Quat attitude = ptr.getRefData().getBaseNode()->getAttitude(); + MWBase::Environment::get().getWorld()->rotateWorldObject(ptr, attitude * rot); + } }; - template + template class OpSetAtStart : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); - - if (!ptr.isInCell()) - return; + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); - MWBase::Environment::get().getWorld()->rotateObject(ptr, ptr.getCellRef().getPosition().asRotationVec3()); + if (!ptr.isInCell()) + return; - dynamic_cast(runtime.getContext()).updatePtr(ptr, - MWBase::Environment::get().getWorld()->moveObject(ptr, ptr.getCellRef().getPosition().asVec3())); + MWBase::Environment::get().getWorld()->rotateObject( + ptr, ptr.getCellRef().getPosition().asRotationVec3()); - } + dynamic_cast(runtime.getContext()) + .updatePtr(ptr, + MWBase::Environment::get().getWorld()->moveObject( + ptr, ptr.getCellRef().getPosition().asVec3())); + } }; - template + template class OpMove : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - const MWWorld::Ptr& ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + const MWWorld::Ptr& ptr = R()(runtime); - if (!ptr.isInCell()) - return; + if (!ptr.isInCell()) + return; - std::string_view axis = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); - Interpreter::Type_Float movement = (runtime[0].mFloat*MWBase::Environment::get().getFrameDuration()); - runtime.pop(); + std::string_view axis = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); + Interpreter::Type_Float movement = (runtime[0].mFloat * MWBase::Environment::get().getFrameDuration()); + runtime.pop(); - osg::Vec3f posChange; - if (axis == "x") - { - posChange=osg::Vec3f(movement, 0, 0); - } - else if (axis == "y") - { - posChange=osg::Vec3f(0, movement, 0); - } - else if (axis == "z") - { - posChange=osg::Vec3f(0, 0, movement); - } - else - return; + osg::Vec3f posChange; + if (axis == "x") + { + posChange = osg::Vec3f(movement, 0, 0); + } + else if (axis == "y") + { + posChange = osg::Vec3f(0, movement, 0); + } + else if (axis == "z") + { + posChange = osg::Vec3f(0, 0, movement); + } + else + return; - // is it correct that disabled objects can't be Move-d? - if (!ptr.getRefData().getBaseNode()) - return; + // is it correct that disabled objects can't be Move-d? + if (!ptr.getRefData().getBaseNode()) + return; - osg::Vec3f diff = ptr.getRefData().getBaseNode()->getAttitude() * posChange; + osg::Vec3f diff = ptr.getRefData().getBaseNode()->getAttitude() * posChange; - // We should move actors, standing on moving object, too. - // This approach can be used to create elevators. - moveStandingActors(ptr, diff); - dynamic_cast(runtime.getContext()).updatePtr(ptr, - MWBase::Environment::get().getWorld()->moveObjectBy(ptr, diff)); - } + // We should move actors, standing on moving object, too. + // This approach can be used to create elevators. + moveStandingActors(ptr, diff); + dynamic_cast(runtime.getContext()) + .updatePtr(ptr, MWBase::Environment::get().getWorld()->moveObjectBy(ptr, diff)); + } }; - template + template class OpMoveWorld : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - MWWorld::Ptr ptr = R()(runtime); - - if (!ptr.isInCell()) - return; - - std::string_view axis = runtime.getStringLiteral(runtime[0].mInteger); - runtime.pop(); - Interpreter::Type_Float movement = (runtime[0].mFloat*MWBase::Environment::get().getFrameDuration()); - runtime.pop(); - - osg::Vec3f diff; - - if (axis == "x") - diff.x() = movement; - else if (axis == "y") - diff.y() = movement; - else if (axis == "z") - diff.z() = movement; - else - return; - - // We should move actors, standing on moving object, too. - // This approach can be used to create elevators. - moveStandingActors(ptr, diff); - dynamic_cast(runtime.getContext()).updatePtr(ptr, - MWBase::Environment::get().getWorld()->moveObjectBy(ptr, diff)); - } + public: + void execute(Interpreter::Runtime& runtime) override + { + MWWorld::Ptr ptr = R()(runtime); + + if (!ptr.isInCell()) + return; + + std::string_view axis = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); + Interpreter::Type_Float movement = (runtime[0].mFloat * MWBase::Environment::get().getFrameDuration()); + runtime.pop(); + + osg::Vec3f diff; + + if (axis == "x") + diff.x() = movement; + else if (axis == "y") + diff.y() = movement; + else if (axis == "z") + diff.z() = movement; + else + return; + + // We should move actors, standing on moving object, too. + // This approach can be used to create elevators. + moveStandingActors(ptr, diff); + dynamic_cast(runtime.getContext()) + .updatePtr(ptr, MWBase::Environment::get().getWorld()->moveObjectBy(ptr, diff)); + } }; class OpResetActors : public Interpreter::Opcode0 { public: - - void execute (Interpreter::Runtime& runtime) override + void execute(Interpreter::Runtime& runtime) override { MWBase::Environment::get().getWorld()->resetActors(); } @@ -807,17 +802,17 @@ namespace MWScript class OpFixme : public Interpreter::Opcode0 { public: - - void execute (Interpreter::Runtime& runtime) override + void execute(Interpreter::Runtime& runtime) override { MWBase::Environment::get().getWorld()->fixPosition(); } }; - void installOpcodes (Interpreter::Interpreter& interpreter) + void installOpcodes(Interpreter::Interpreter& interpreter) { interpreter.installSegment5>(Compiler::Transformation::opcodeGetDistance); - interpreter.installSegment5>(Compiler::Transformation::opcodeGetDistanceExplicit); + interpreter.installSegment5>( + Compiler::Transformation::opcodeGetDistanceExplicit); interpreter.installSegment5>(Compiler::Transformation::opcodeSetScale); interpreter.installSegment5>(Compiler::Transformation::opcodeSetScaleExplicit); interpreter.installSegment5>(Compiler::Transformation::opcodeSetAngle); @@ -831,30 +826,36 @@ namespace MWScript interpreter.installSegment5>(Compiler::Transformation::opcodeSetPos); interpreter.installSegment5>(Compiler::Transformation::opcodeSetPosExplicit); interpreter.installSegment5>(Compiler::Transformation::opcodeGetStartingPos); - interpreter.installSegment5>(Compiler::Transformation::opcodeGetStartingPosExplicit); + interpreter.installSegment5>( + Compiler::Transformation::opcodeGetStartingPosExplicit); interpreter.installSegment5>(Compiler::Transformation::opcodePosition); interpreter.installSegment5>(Compiler::Transformation::opcodePositionExplicit); interpreter.installSegment5>(Compiler::Transformation::opcodePositionCell); - interpreter.installSegment5>(Compiler::Transformation::opcodePositionCellExplicit); + interpreter.installSegment5>( + Compiler::Transformation::opcodePositionCellExplicit); interpreter.installSegment5(Compiler::Transformation::opcodePlaceItemCell); interpreter.installSegment5(Compiler::Transformation::opcodePlaceItem); interpreter.installSegment5>(Compiler::Transformation::opcodePlaceAtPc); interpreter.installSegment5>(Compiler::Transformation::opcodePlaceAtMe); - interpreter.installSegment5>(Compiler::Transformation::opcodePlaceAtMeExplicit); + interpreter.installSegment5>( + Compiler::Transformation::opcodePlaceAtMeExplicit); interpreter.installSegment5>(Compiler::Transformation::opcodeModScale); interpreter.installSegment5>(Compiler::Transformation::opcodeModScaleExplicit); interpreter.installSegment5>(Compiler::Transformation::opcodeRotate); interpreter.installSegment5>(Compiler::Transformation::opcodeRotateExplicit); interpreter.installSegment5>(Compiler::Transformation::opcodeRotateWorld); - interpreter.installSegment5>(Compiler::Transformation::opcodeRotateWorldExplicit); + interpreter.installSegment5>( + Compiler::Transformation::opcodeRotateWorldExplicit); interpreter.installSegment5>(Compiler::Transformation::opcodeSetAtStart); interpreter.installSegment5>(Compiler::Transformation::opcodeSetAtStartExplicit); interpreter.installSegment5>(Compiler::Transformation::opcodeMove); interpreter.installSegment5>(Compiler::Transformation::opcodeMoveExplicit); interpreter.installSegment5>(Compiler::Transformation::opcodeMoveWorld); interpreter.installSegment5>(Compiler::Transformation::opcodeMoveWorldExplicit); - interpreter.installSegment5>(Compiler::Transformation::opcodeGetStartingAngle); - interpreter.installSegment5>(Compiler::Transformation::opcodeGetStartingAngleExplicit); + interpreter.installSegment5>( + Compiler::Transformation::opcodeGetStartingAngle); + interpreter.installSegment5>( + Compiler::Transformation::opcodeGetStartingAngleExplicit); interpreter.installSegment5(Compiler::Transformation::opcodeResetActors); interpreter.installSegment5(Compiler::Transformation::opcodeFixme); } diff --git a/apps/openmw/mwscript/transformationextensions.hpp b/apps/openmw/mwscript/transformationextensions.hpp index 7a4d29e06c..949431b109 100644 --- a/apps/openmw/mwscript/transformationextensions.hpp +++ b/apps/openmw/mwscript/transformationextensions.hpp @@ -15,8 +15,8 @@ namespace MWScript { /// \brief stats-related script functionality (creatures and NPCs) namespace Transformation - { - void installOpcodes (Interpreter::Interpreter& interpreter); + { + void installOpcodes(Interpreter::Interpreter& interpreter); } } diff --git a/apps/openmw/mwscript/userextensions.cpp b/apps/openmw/mwscript/userextensions.cpp index f929425a9c..c7dbb46061 100644 --- a/apps/openmw/mwscript/userextensions.cpp +++ b/apps/openmw/mwscript/userextensions.cpp @@ -3,10 +3,10 @@ #include #include +#include #include -#include #include -#include +#include #include "ref.hpp" @@ -19,52 +19,41 @@ namespace MWScript { class OpUser1 : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - runtime.getContext().report ("user1: not in use"); - } + public: + void execute(Interpreter::Runtime& runtime) override { runtime.getContext().report("user1: not in use"); } }; class OpUser2 : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { - runtime.getContext().report ("user2: not in use"); - } + public: + void execute(Interpreter::Runtime& runtime) override { runtime.getContext().report("user2: not in use"); } }; - template + template class OpUser3 : public Interpreter::Opcode0 { - public: + public: + void execute(Interpreter::Runtime& runtime) override + { + // MWWorld::Ptr ptr = R()(runtime); - void execute (Interpreter::Runtime& runtime) override - { -// MWWorld::Ptr ptr = R()(runtime); - - runtime.getContext().report ("user3: not in use"); - } + runtime.getContext().report("user3: not in use"); + } }; - template + template class OpUser4 : public Interpreter::Opcode0 { - public: - - void execute (Interpreter::Runtime& runtime) override - { -// MWWorld::Ptr ptr = R()(runtime); + public: + void execute(Interpreter::Runtime& runtime) override + { + // MWWorld::Ptr ptr = R()(runtime); - runtime.getContext().report ("user4: not in use"); - } + runtime.getContext().report("user4: not in use"); + } }; - - void installOpcodes (Interpreter::Interpreter& interpreter) + void installOpcodes(Interpreter::Interpreter& interpreter) { interpreter.installSegment5(Compiler::User::opcodeUser1); interpreter.installSegment5(Compiler::User::opcodeUser2); diff --git a/apps/openmw/mwscript/userextensions.hpp b/apps/openmw/mwscript/userextensions.hpp index da6e0faa66..2310c2e9a2 100644 --- a/apps/openmw/mwscript/userextensions.hpp +++ b/apps/openmw/mwscript/userextensions.hpp @@ -16,7 +16,7 @@ namespace MWScript /// \brief Temporary script functionality limited to the console namespace User { - void installOpcodes (Interpreter::Interpreter& interpreter); + void installOpcodes(Interpreter::Interpreter& interpreter); } } diff --git a/apps/openmw/mwsound/alext.h b/apps/openmw/mwsound/alext.h index 7162fa955d..9999665416 100644 --- a/apps/openmw/mwsound/alext.h +++ b/apps/openmw/mwsound/alext.h @@ -35,107 +35,109 @@ typedef unsigned __int64 uint64_t; #include #endif -#include "alc.h" #include "al.h" +#include "alc.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif #ifndef AL_LOKI_IMA_ADPCM_format #define AL_LOKI_IMA_ADPCM_format 1 -#define AL_FORMAT_IMA_ADPCM_MONO16_EXT 0x10000 -#define AL_FORMAT_IMA_ADPCM_STEREO16_EXT 0x10001 +#define AL_FORMAT_IMA_ADPCM_MONO16_EXT 0x10000 +#define AL_FORMAT_IMA_ADPCM_STEREO16_EXT 0x10001 #endif #ifndef AL_LOKI_WAVE_format #define AL_LOKI_WAVE_format 1 -#define AL_FORMAT_WAVE_EXT 0x10002 +#define AL_FORMAT_WAVE_EXT 0x10002 #endif #ifndef AL_EXT_vorbis #define AL_EXT_vorbis 1 -#define AL_FORMAT_VORBIS_EXT 0x10003 +#define AL_FORMAT_VORBIS_EXT 0x10003 #endif #ifndef AL_LOKI_quadriphonic #define AL_LOKI_quadriphonic 1 -#define AL_FORMAT_QUAD8_LOKI 0x10004 -#define AL_FORMAT_QUAD16_LOKI 0x10005 +#define AL_FORMAT_QUAD8_LOKI 0x10004 +#define AL_FORMAT_QUAD16_LOKI 0x10005 #endif #ifndef AL_EXT_float32 #define AL_EXT_float32 1 -#define AL_FORMAT_MONO_FLOAT32 0x10010 -#define AL_FORMAT_STEREO_FLOAT32 0x10011 +#define AL_FORMAT_MONO_FLOAT32 0x10010 +#define AL_FORMAT_STEREO_FLOAT32 0x10011 #endif #ifndef AL_EXT_double #define AL_EXT_double 1 -#define AL_FORMAT_MONO_DOUBLE_EXT 0x10012 -#define AL_FORMAT_STEREO_DOUBLE_EXT 0x10013 +#define AL_FORMAT_MONO_DOUBLE_EXT 0x10012 +#define AL_FORMAT_STEREO_DOUBLE_EXT 0x10013 #endif #ifndef AL_EXT_MULAW #define AL_EXT_MULAW 1 -#define AL_FORMAT_MONO_MULAW_EXT 0x10014 -#define AL_FORMAT_STEREO_MULAW_EXT 0x10015 +#define AL_FORMAT_MONO_MULAW_EXT 0x10014 +#define AL_FORMAT_STEREO_MULAW_EXT 0x10015 #endif #ifndef AL_EXT_ALAW #define AL_EXT_ALAW 1 -#define AL_FORMAT_MONO_ALAW_EXT 0x10016 -#define AL_FORMAT_STEREO_ALAW_EXT 0x10017 +#define AL_FORMAT_MONO_ALAW_EXT 0x10016 +#define AL_FORMAT_STEREO_ALAW_EXT 0x10017 #endif #ifndef ALC_LOKI_audio_channel #define ALC_LOKI_audio_channel 1 -#define ALC_CHAN_MAIN_LOKI 0x500001 -#define ALC_CHAN_PCM_LOKI 0x500002 -#define ALC_CHAN_CD_LOKI 0x500003 +#define ALC_CHAN_MAIN_LOKI 0x500001 +#define ALC_CHAN_PCM_LOKI 0x500002 +#define ALC_CHAN_CD_LOKI 0x500003 #endif #ifndef AL_EXT_MCFORMATS #define AL_EXT_MCFORMATS 1 -#define AL_FORMAT_QUAD8 0x1204 -#define AL_FORMAT_QUAD16 0x1205 -#define AL_FORMAT_QUAD32 0x1206 -#define AL_FORMAT_REAR8 0x1207 -#define AL_FORMAT_REAR16 0x1208 -#define AL_FORMAT_REAR32 0x1209 -#define AL_FORMAT_51CHN8 0x120A -#define AL_FORMAT_51CHN16 0x120B -#define AL_FORMAT_51CHN32 0x120C -#define AL_FORMAT_61CHN8 0x120D -#define AL_FORMAT_61CHN16 0x120E -#define AL_FORMAT_61CHN32 0x120F -#define AL_FORMAT_71CHN8 0x1210 -#define AL_FORMAT_71CHN16 0x1211 -#define AL_FORMAT_71CHN32 0x1212 +#define AL_FORMAT_QUAD8 0x1204 +#define AL_FORMAT_QUAD16 0x1205 +#define AL_FORMAT_QUAD32 0x1206 +#define AL_FORMAT_REAR8 0x1207 +#define AL_FORMAT_REAR16 0x1208 +#define AL_FORMAT_REAR32 0x1209 +#define AL_FORMAT_51CHN8 0x120A +#define AL_FORMAT_51CHN16 0x120B +#define AL_FORMAT_51CHN32 0x120C +#define AL_FORMAT_61CHN8 0x120D +#define AL_FORMAT_61CHN16 0x120E +#define AL_FORMAT_61CHN32 0x120F +#define AL_FORMAT_71CHN8 0x1210 +#define AL_FORMAT_71CHN16 0x1211 +#define AL_FORMAT_71CHN32 0x1212 #endif #ifndef AL_EXT_MULAW_MCFORMATS #define AL_EXT_MULAW_MCFORMATS 1 -#define AL_FORMAT_MONO_MULAW 0x10014 -#define AL_FORMAT_STEREO_MULAW 0x10015 -#define AL_FORMAT_QUAD_MULAW 0x10021 -#define AL_FORMAT_REAR_MULAW 0x10022 -#define AL_FORMAT_51CHN_MULAW 0x10023 -#define AL_FORMAT_61CHN_MULAW 0x10024 -#define AL_FORMAT_71CHN_MULAW 0x10025 +#define AL_FORMAT_MONO_MULAW 0x10014 +#define AL_FORMAT_STEREO_MULAW 0x10015 +#define AL_FORMAT_QUAD_MULAW 0x10021 +#define AL_FORMAT_REAR_MULAW 0x10022 +#define AL_FORMAT_51CHN_MULAW 0x10023 +#define AL_FORMAT_61CHN_MULAW 0x10024 +#define AL_FORMAT_71CHN_MULAW 0x10025 #endif #ifndef AL_EXT_IMA4 #define AL_EXT_IMA4 1 -#define AL_FORMAT_MONO_IMA4 0x1300 -#define AL_FORMAT_STEREO_IMA4 0x1301 +#define AL_FORMAT_MONO_IMA4 0x1300 +#define AL_FORMAT_STEREO_IMA4 0x1301 #endif #ifndef AL_EXT_STATIC_BUFFER #define AL_EXT_STATIC_BUFFER 1 -typedef ALvoid (AL_APIENTRY*PFNALBUFFERDATASTATICPROC)(const ALint,ALenum,ALvoid*,ALsizei,ALsizei); + typedef ALvoid(AL_APIENTRY* PFNALBUFFERDATASTATICPROC)(const ALint, ALenum, ALvoid*, ALsizei, ALsizei); #ifdef AL_ALEXT_PROTOTYPES -AL_API ALvoid AL_APIENTRY alBufferDataStatic(const ALint buffer, ALenum format, ALvoid *data, ALsizei len, ALsizei freq); + AL_API ALvoid AL_APIENTRY alBufferDataStatic( + const ALint buffer, ALenum format, ALvoid* data, ALsizei len, ALsizei freq); #endif #endif @@ -146,234 +148,244 @@ AL_API ALvoid AL_APIENTRY alBufferDataStatic(const ALint buffer, ALenum format, #ifndef ALC_EXT_disconnect #define ALC_EXT_disconnect 1 -#define ALC_CONNECTED 0x313 +#define ALC_CONNECTED 0x313 #endif #ifndef ALC_EXT_thread_local_context #define ALC_EXT_thread_local_context 1 -typedef ALCboolean (ALC_APIENTRY*PFNALCSETTHREADCONTEXTPROC)(ALCcontext *context); -typedef ALCcontext* (ALC_APIENTRY*PFNALCGETTHREADCONTEXTPROC)(void); + typedef ALCboolean(ALC_APIENTRY* PFNALCSETTHREADCONTEXTPROC)(ALCcontext* context); + typedef ALCcontext*(ALC_APIENTRY* PFNALCGETTHREADCONTEXTPROC)(void); #ifdef AL_ALEXT_PROTOTYPES -ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context); -ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void); + ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext* context); + ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void); #endif #endif #ifndef AL_EXT_source_distance_model #define AL_EXT_source_distance_model 1 -#define AL_SOURCE_DISTANCE_MODEL 0x200 +#define AL_SOURCE_DISTANCE_MODEL 0x200 #endif #ifndef AL_SOFT_buffer_sub_data #define AL_SOFT_buffer_sub_data 1 -#define AL_BYTE_RW_OFFSETS_SOFT 0x1031 -#define AL_SAMPLE_RW_OFFSETS_SOFT 0x1032 -typedef ALvoid (AL_APIENTRY*PFNALBUFFERSUBDATASOFTPROC)(ALuint,ALenum,const ALvoid*,ALsizei,ALsizei); +#define AL_BYTE_RW_OFFSETS_SOFT 0x1031 +#define AL_SAMPLE_RW_OFFSETS_SOFT 0x1032 + typedef ALvoid(AL_APIENTRY* PFNALBUFFERSUBDATASOFTPROC)(ALuint, ALenum, const ALvoid*, ALsizei, ALsizei); #ifdef AL_ALEXT_PROTOTYPES -AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer,ALenum format,const ALvoid *data,ALsizei offset,ALsizei length); + AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT( + ALuint buffer, ALenum format, const ALvoid* data, ALsizei offset, ALsizei length); #endif #endif #ifndef AL_SOFT_loop_points #define AL_SOFT_loop_points 1 -#define AL_LOOP_POINTS_SOFT 0x2015 +#define AL_LOOP_POINTS_SOFT 0x2015 #endif #ifndef AL_EXT_FOLDBACK #define AL_EXT_FOLDBACK 1 -#define AL_EXT_FOLDBACK_NAME "AL_EXT_FOLDBACK" -#define AL_FOLDBACK_EVENT_BLOCK 0x4112 -#define AL_FOLDBACK_EVENT_START 0x4111 -#define AL_FOLDBACK_EVENT_STOP 0x4113 -#define AL_FOLDBACK_MODE_MONO 0x4101 -#define AL_FOLDBACK_MODE_STEREO 0x4102 -typedef void (AL_APIENTRY*LPALFOLDBACKCALLBACK)(ALenum,ALsizei); -typedef void (AL_APIENTRY*LPALREQUESTFOLDBACKSTART)(ALenum,ALsizei,ALsizei,ALfloat*,LPALFOLDBACKCALLBACK); -typedef void (AL_APIENTRY*LPALREQUESTFOLDBACKSTOP)(void); +#define AL_EXT_FOLDBACK_NAME "AL_EXT_FOLDBACK" +#define AL_FOLDBACK_EVENT_BLOCK 0x4112 +#define AL_FOLDBACK_EVENT_START 0x4111 +#define AL_FOLDBACK_EVENT_STOP 0x4113 +#define AL_FOLDBACK_MODE_MONO 0x4101 +#define AL_FOLDBACK_MODE_STEREO 0x4102 + typedef void(AL_APIENTRY* LPALFOLDBACKCALLBACK)(ALenum, ALsizei); + typedef void(AL_APIENTRY* LPALREQUESTFOLDBACKSTART)(ALenum, ALsizei, ALsizei, ALfloat*, LPALFOLDBACKCALLBACK); + typedef void(AL_APIENTRY* LPALREQUESTFOLDBACKSTOP)(void); #ifdef AL_ALEXT_PROTOTYPES -AL_API void AL_APIENTRY alRequestFoldbackStart(ALenum mode,ALsizei count,ALsizei length,ALfloat *mem,LPALFOLDBACKCALLBACK callback); -AL_API void AL_APIENTRY alRequestFoldbackStop(void); + AL_API void AL_APIENTRY alRequestFoldbackStart( + ALenum mode, ALsizei count, ALsizei length, ALfloat* mem, LPALFOLDBACKCALLBACK callback); + AL_API void AL_APIENTRY alRequestFoldbackStop(void); #endif #endif #ifndef ALC_EXT_DEDICATED #define ALC_EXT_DEDICATED 1 -#define AL_DEDICATED_GAIN 0x0001 -#define AL_EFFECT_DEDICATED_DIALOGUE 0x9001 +#define AL_DEDICATED_GAIN 0x0001 +#define AL_EFFECT_DEDICATED_DIALOGUE 0x9001 #define AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT 0x9000 #endif #ifndef AL_SOFT_buffer_samples #define AL_SOFT_buffer_samples 1 /* Channel configurations */ -#define AL_MONO_SOFT 0x1500 -#define AL_STEREO_SOFT 0x1501 -#define AL_REAR_SOFT 0x1502 -#define AL_QUAD_SOFT 0x1503 -#define AL_5POINT1_SOFT 0x1504 -#define AL_6POINT1_SOFT 0x1505 -#define AL_7POINT1_SOFT 0x1506 +#define AL_MONO_SOFT 0x1500 +#define AL_STEREO_SOFT 0x1501 +#define AL_REAR_SOFT 0x1502 +#define AL_QUAD_SOFT 0x1503 +#define AL_5POINT1_SOFT 0x1504 +#define AL_6POINT1_SOFT 0x1505 +#define AL_7POINT1_SOFT 0x1506 /* Sample types */ -#define AL_BYTE_SOFT 0x1400 -#define AL_UNSIGNED_BYTE_SOFT 0x1401 -#define AL_SHORT_SOFT 0x1402 -#define AL_UNSIGNED_SHORT_SOFT 0x1403 -#define AL_INT_SOFT 0x1404 -#define AL_UNSIGNED_INT_SOFT 0x1405 -#define AL_FLOAT_SOFT 0x1406 -#define AL_DOUBLE_SOFT 0x1407 -#define AL_BYTE3_SOFT 0x1408 -#define AL_UNSIGNED_BYTE3_SOFT 0x1409 +#define AL_BYTE_SOFT 0x1400 +#define AL_UNSIGNED_BYTE_SOFT 0x1401 +#define AL_SHORT_SOFT 0x1402 +#define AL_UNSIGNED_SHORT_SOFT 0x1403 +#define AL_INT_SOFT 0x1404 +#define AL_UNSIGNED_INT_SOFT 0x1405 +#define AL_FLOAT_SOFT 0x1406 +#define AL_DOUBLE_SOFT 0x1407 +#define AL_BYTE3_SOFT 0x1408 +#define AL_UNSIGNED_BYTE3_SOFT 0x1409 /* Storage formats */ -#define AL_MONO8_SOFT 0x1100 -#define AL_MONO16_SOFT 0x1101 -#define AL_MONO32F_SOFT 0x10010 -#define AL_STEREO8_SOFT 0x1102 -#define AL_STEREO16_SOFT 0x1103 -#define AL_STEREO32F_SOFT 0x10011 -#define AL_QUAD8_SOFT 0x1204 -#define AL_QUAD16_SOFT 0x1205 -#define AL_QUAD32F_SOFT 0x1206 -#define AL_REAR8_SOFT 0x1207 -#define AL_REAR16_SOFT 0x1208 -#define AL_REAR32F_SOFT 0x1209 -#define AL_5POINT1_8_SOFT 0x120A -#define AL_5POINT1_16_SOFT 0x120B -#define AL_5POINT1_32F_SOFT 0x120C -#define AL_6POINT1_8_SOFT 0x120D -#define AL_6POINT1_16_SOFT 0x120E -#define AL_6POINT1_32F_SOFT 0x120F -#define AL_7POINT1_8_SOFT 0x1210 -#define AL_7POINT1_16_SOFT 0x1211 -#define AL_7POINT1_32F_SOFT 0x1212 +#define AL_MONO8_SOFT 0x1100 +#define AL_MONO16_SOFT 0x1101 +#define AL_MONO32F_SOFT 0x10010 +#define AL_STEREO8_SOFT 0x1102 +#define AL_STEREO16_SOFT 0x1103 +#define AL_STEREO32F_SOFT 0x10011 +#define AL_QUAD8_SOFT 0x1204 +#define AL_QUAD16_SOFT 0x1205 +#define AL_QUAD32F_SOFT 0x1206 +#define AL_REAR8_SOFT 0x1207 +#define AL_REAR16_SOFT 0x1208 +#define AL_REAR32F_SOFT 0x1209 +#define AL_5POINT1_8_SOFT 0x120A +#define AL_5POINT1_16_SOFT 0x120B +#define AL_5POINT1_32F_SOFT 0x120C +#define AL_6POINT1_8_SOFT 0x120D +#define AL_6POINT1_16_SOFT 0x120E +#define AL_6POINT1_32F_SOFT 0x120F +#define AL_7POINT1_8_SOFT 0x1210 +#define AL_7POINT1_16_SOFT 0x1211 +#define AL_7POINT1_32F_SOFT 0x1212 /* Buffer attributes */ -#define AL_INTERNAL_FORMAT_SOFT 0x2008 -#define AL_BYTE_LENGTH_SOFT 0x2009 -#define AL_SAMPLE_LENGTH_SOFT 0x200A -#define AL_SEC_LENGTH_SOFT 0x200B - -typedef void (AL_APIENTRY*LPALBUFFERSAMPLESSOFT)(ALuint,ALuint,ALenum,ALsizei,ALenum,ALenum,const ALvoid*); -typedef void (AL_APIENTRY*LPALBUFFERSUBSAMPLESSOFT)(ALuint,ALsizei,ALsizei,ALenum,ALenum,const ALvoid*); -typedef void (AL_APIENTRY*LPALGETBUFFERSAMPLESSOFT)(ALuint,ALsizei,ALsizei,ALenum,ALenum,ALvoid*); -typedef ALboolean (AL_APIENTRY*LPALISBUFFERFORMATSUPPORTEDSOFT)(ALenum); +#define AL_INTERNAL_FORMAT_SOFT 0x2008 +#define AL_BYTE_LENGTH_SOFT 0x2009 +#define AL_SAMPLE_LENGTH_SOFT 0x200A +#define AL_SEC_LENGTH_SOFT 0x200B + + typedef void(AL_APIENTRY* LPALBUFFERSAMPLESSOFT)(ALuint, ALuint, ALenum, ALsizei, ALenum, ALenum, const ALvoid*); + typedef void(AL_APIENTRY* LPALBUFFERSUBSAMPLESSOFT)(ALuint, ALsizei, ALsizei, ALenum, ALenum, const ALvoid*); + typedef void(AL_APIENTRY* LPALGETBUFFERSAMPLESSOFT)(ALuint, ALsizei, ALsizei, ALenum, ALenum, ALvoid*); + typedef ALboolean(AL_APIENTRY* LPALISBUFFERFORMATSUPPORTEDSOFT)(ALenum); #ifdef AL_ALEXT_PROTOTYPES -AL_API void AL_APIENTRY alBufferSamplesSOFT(ALuint buffer, ALuint samplerate, ALenum internalformat, ALsizei samples, ALenum channels, ALenum type, const ALvoid *data); -AL_API void AL_APIENTRY alBufferSubSamplesSOFT(ALuint buffer, ALsizei offset, ALsizei samples, ALenum channels, ALenum type, const ALvoid *data); -AL_API void AL_APIENTRY alGetBufferSamplesSOFT(ALuint buffer, ALsizei offset, ALsizei samples, ALenum channels, ALenum type, ALvoid *data); -AL_API ALboolean AL_APIENTRY alIsBufferFormatSupportedSOFT(ALenum format); + AL_API void AL_APIENTRY alBufferSamplesSOFT(ALuint buffer, ALuint samplerate, ALenum internalformat, + ALsizei samples, ALenum channels, ALenum type, const ALvoid* data); + AL_API void AL_APIENTRY alBufferSubSamplesSOFT( + ALuint buffer, ALsizei offset, ALsizei samples, ALenum channels, ALenum type, const ALvoid* data); + AL_API void AL_APIENTRY alGetBufferSamplesSOFT( + ALuint buffer, ALsizei offset, ALsizei samples, ALenum channels, ALenum type, ALvoid* data); + AL_API ALboolean AL_APIENTRY alIsBufferFormatSupportedSOFT(ALenum format); #endif #endif #ifndef AL_SOFT_direct_channels #define AL_SOFT_direct_channels 1 -#define AL_DIRECT_CHANNELS_SOFT 0x1033 +#define AL_DIRECT_CHANNELS_SOFT 0x1033 #endif #ifndef ALC_SOFT_loopback #define ALC_SOFT_loopback 1 -#define ALC_FORMAT_CHANNELS_SOFT 0x1990 -#define ALC_FORMAT_TYPE_SOFT 0x1991 +#define ALC_FORMAT_CHANNELS_SOFT 0x1990 +#define ALC_FORMAT_TYPE_SOFT 0x1991 /* Sample types */ -#define ALC_BYTE_SOFT 0x1400 -#define ALC_UNSIGNED_BYTE_SOFT 0x1401 -#define ALC_SHORT_SOFT 0x1402 -#define ALC_UNSIGNED_SHORT_SOFT 0x1403 -#define ALC_INT_SOFT 0x1404 -#define ALC_UNSIGNED_INT_SOFT 0x1405 -#define ALC_FLOAT_SOFT 0x1406 +#define ALC_BYTE_SOFT 0x1400 +#define ALC_UNSIGNED_BYTE_SOFT 0x1401 +#define ALC_SHORT_SOFT 0x1402 +#define ALC_UNSIGNED_SHORT_SOFT 0x1403 +#define ALC_INT_SOFT 0x1404 +#define ALC_UNSIGNED_INT_SOFT 0x1405 +#define ALC_FLOAT_SOFT 0x1406 /* Channel configurations */ -#define ALC_MONO_SOFT 0x1500 -#define ALC_STEREO_SOFT 0x1501 -#define ALC_QUAD_SOFT 0x1503 -#define ALC_5POINT1_SOFT 0x1504 -#define ALC_6POINT1_SOFT 0x1505 -#define ALC_7POINT1_SOFT 0x1506 - -typedef ALCdevice* (ALC_APIENTRY*LPALCLOOPBACKOPENDEVICESOFT)(const ALCchar*); -typedef ALCboolean (ALC_APIENTRY*LPALCISRENDERFORMATSUPPORTEDSOFT)(ALCdevice*,ALCsizei,ALCenum,ALCenum); -typedef void (ALC_APIENTRY*LPALCRENDERSAMPLESSOFT)(ALCdevice*,ALCvoid*,ALCsizei); +#define ALC_MONO_SOFT 0x1500 +#define ALC_STEREO_SOFT 0x1501 +#define ALC_QUAD_SOFT 0x1503 +#define ALC_5POINT1_SOFT 0x1504 +#define ALC_6POINT1_SOFT 0x1505 +#define ALC_7POINT1_SOFT 0x1506 + + typedef ALCdevice*(ALC_APIENTRY* LPALCLOOPBACKOPENDEVICESOFT)(const ALCchar*); + typedef ALCboolean(ALC_APIENTRY* LPALCISRENDERFORMATSUPPORTEDSOFT)(ALCdevice*, ALCsizei, ALCenum, ALCenum); + typedef void(ALC_APIENTRY* LPALCRENDERSAMPLESSOFT)(ALCdevice*, ALCvoid*, ALCsizei); #ifdef AL_ALEXT_PROTOTYPES -ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName); -ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type); -ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples); + ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar* deviceName); + ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT( + ALCdevice* device, ALCsizei freq, ALCenum channels, ALCenum type); + ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice* device, ALCvoid* buffer, ALCsizei samples); #endif #endif #ifndef AL_EXT_STEREO_ANGLES #define AL_EXT_STEREO_ANGLES 1 -#define AL_STEREO_ANGLES 0x1030 +#define AL_STEREO_ANGLES 0x1030 #endif #ifndef AL_EXT_SOURCE_RADIUS #define AL_EXT_SOURCE_RADIUS 1 -#define AL_SOURCE_RADIUS 0x1031 +#define AL_SOURCE_RADIUS 0x1031 #endif #ifndef AL_SOFT_source_latency #define AL_SOFT_source_latency 1 -#define AL_SAMPLE_OFFSET_LATENCY_SOFT 0x1200 -#define AL_SEC_OFFSET_LATENCY_SOFT 0x1201 -typedef int64_t ALint64SOFT; -typedef uint64_t ALuint64SOFT; -typedef void (AL_APIENTRY*LPALSOURCEDSOFT)(ALuint,ALenum,ALdouble); -typedef void (AL_APIENTRY*LPALSOURCE3DSOFT)(ALuint,ALenum,ALdouble,ALdouble,ALdouble); -typedef void (AL_APIENTRY*LPALSOURCEDVSOFT)(ALuint,ALenum,const ALdouble*); -typedef void (AL_APIENTRY*LPALGETSOURCEDSOFT)(ALuint,ALenum,ALdouble*); -typedef void (AL_APIENTRY*LPALGETSOURCE3DSOFT)(ALuint,ALenum,ALdouble*,ALdouble*,ALdouble*); -typedef void (AL_APIENTRY*LPALGETSOURCEDVSOFT)(ALuint,ALenum,ALdouble*); -typedef void (AL_APIENTRY*LPALSOURCEI64SOFT)(ALuint,ALenum,ALint64SOFT); -typedef void (AL_APIENTRY*LPALSOURCE3I64SOFT)(ALuint,ALenum,ALint64SOFT,ALint64SOFT,ALint64SOFT); -typedef void (AL_APIENTRY*LPALSOURCEI64VSOFT)(ALuint,ALenum,const ALint64SOFT*); -typedef void (AL_APIENTRY*LPALGETSOURCEI64SOFT)(ALuint,ALenum,ALint64SOFT*); -typedef void (AL_APIENTRY*LPALGETSOURCE3I64SOFT)(ALuint,ALenum,ALint64SOFT*,ALint64SOFT*,ALint64SOFT*); -typedef void (AL_APIENTRY*LPALGETSOURCEI64VSOFT)(ALuint,ALenum,ALint64SOFT*); +#define AL_SAMPLE_OFFSET_LATENCY_SOFT 0x1200 +#define AL_SEC_OFFSET_LATENCY_SOFT 0x1201 + typedef int64_t ALint64SOFT; + typedef uint64_t ALuint64SOFT; + typedef void(AL_APIENTRY* LPALSOURCEDSOFT)(ALuint, ALenum, ALdouble); + typedef void(AL_APIENTRY* LPALSOURCE3DSOFT)(ALuint, ALenum, ALdouble, ALdouble, ALdouble); + typedef void(AL_APIENTRY* LPALSOURCEDVSOFT)(ALuint, ALenum, const ALdouble*); + typedef void(AL_APIENTRY* LPALGETSOURCEDSOFT)(ALuint, ALenum, ALdouble*); + typedef void(AL_APIENTRY* LPALGETSOURCE3DSOFT)(ALuint, ALenum, ALdouble*, ALdouble*, ALdouble*); + typedef void(AL_APIENTRY* LPALGETSOURCEDVSOFT)(ALuint, ALenum, ALdouble*); + typedef void(AL_APIENTRY* LPALSOURCEI64SOFT)(ALuint, ALenum, ALint64SOFT); + typedef void(AL_APIENTRY* LPALSOURCE3I64SOFT)(ALuint, ALenum, ALint64SOFT, ALint64SOFT, ALint64SOFT); + typedef void(AL_APIENTRY* LPALSOURCEI64VSOFT)(ALuint, ALenum, const ALint64SOFT*); + typedef void(AL_APIENTRY* LPALGETSOURCEI64SOFT)(ALuint, ALenum, ALint64SOFT*); + typedef void(AL_APIENTRY* LPALGETSOURCE3I64SOFT)(ALuint, ALenum, ALint64SOFT*, ALint64SOFT*, ALint64SOFT*); + typedef void(AL_APIENTRY* LPALGETSOURCEI64VSOFT)(ALuint, ALenum, ALint64SOFT*); #ifdef AL_ALEXT_PROTOTYPES -AL_API void AL_APIENTRY alSourcedSOFT(ALuint source, ALenum param, ALdouble value); -AL_API void AL_APIENTRY alSource3dSOFT(ALuint source, ALenum param, ALdouble value1, ALdouble value2, ALdouble value3); -AL_API void AL_APIENTRY alSourcedvSOFT(ALuint source, ALenum param, const ALdouble *values); -AL_API void AL_APIENTRY alGetSourcedSOFT(ALuint source, ALenum param, ALdouble *value); -AL_API void AL_APIENTRY alGetSource3dSOFT(ALuint source, ALenum param, ALdouble *value1, ALdouble *value2, ALdouble *value3); -AL_API void AL_APIENTRY alGetSourcedvSOFT(ALuint source, ALenum param, ALdouble *values); -AL_API void AL_APIENTRY alSourcei64SOFT(ALuint source, ALenum param, ALint64SOFT value); -AL_API void AL_APIENTRY alSource3i64SOFT(ALuint source, ALenum param, ALint64SOFT value1, ALint64SOFT value2, ALint64SOFT value3); -AL_API void AL_APIENTRY alSourcei64vSOFT(ALuint source, ALenum param, const ALint64SOFT *values); -AL_API void AL_APIENTRY alGetSourcei64SOFT(ALuint source, ALenum param, ALint64SOFT *value); -AL_API void AL_APIENTRY alGetSource3i64SOFT(ALuint source, ALenum param, ALint64SOFT *value1, ALint64SOFT *value2, ALint64SOFT *value3); -AL_API void AL_APIENTRY alGetSourcei64vSOFT(ALuint source, ALenum param, ALint64SOFT *values); + AL_API void AL_APIENTRY alSourcedSOFT(ALuint source, ALenum param, ALdouble value); + AL_API void AL_APIENTRY alSource3dSOFT( + ALuint source, ALenum param, ALdouble value1, ALdouble value2, ALdouble value3); + AL_API void AL_APIENTRY alSourcedvSOFT(ALuint source, ALenum param, const ALdouble* values); + AL_API void AL_APIENTRY alGetSourcedSOFT(ALuint source, ALenum param, ALdouble* value); + AL_API void AL_APIENTRY alGetSource3dSOFT( + ALuint source, ALenum param, ALdouble* value1, ALdouble* value2, ALdouble* value3); + AL_API void AL_APIENTRY alGetSourcedvSOFT(ALuint source, ALenum param, ALdouble* values); + AL_API void AL_APIENTRY alSourcei64SOFT(ALuint source, ALenum param, ALint64SOFT value); + AL_API void AL_APIENTRY alSource3i64SOFT( + ALuint source, ALenum param, ALint64SOFT value1, ALint64SOFT value2, ALint64SOFT value3); + AL_API void AL_APIENTRY alSourcei64vSOFT(ALuint source, ALenum param, const ALint64SOFT* values); + AL_API void AL_APIENTRY alGetSourcei64SOFT(ALuint source, ALenum param, ALint64SOFT* value); + AL_API void AL_APIENTRY alGetSource3i64SOFT( + ALuint source, ALenum param, ALint64SOFT* value1, ALint64SOFT* value2, ALint64SOFT* value3); + AL_API void AL_APIENTRY alGetSourcei64vSOFT(ALuint source, ALenum param, ALint64SOFT* values); #endif #endif #ifndef ALC_EXT_DEFAULT_FILTER_ORDER #define ALC_EXT_DEFAULT_FILTER_ORDER 1 -#define ALC_DEFAULT_FILTER_ORDER 0x1100 +#define ALC_DEFAULT_FILTER_ORDER 0x1100 #endif #ifndef AL_SOFT_deferred_updates #define AL_SOFT_deferred_updates 1 -#define AL_DEFERRED_UPDATES_SOFT 0xC002 -typedef ALvoid (AL_APIENTRY*LPALDEFERUPDATESSOFT)(void); -typedef ALvoid (AL_APIENTRY*LPALPROCESSUPDATESSOFT)(void); +#define AL_DEFERRED_UPDATES_SOFT 0xC002 + typedef ALvoid(AL_APIENTRY* LPALDEFERUPDATESSOFT)(void); + typedef ALvoid(AL_APIENTRY* LPALPROCESSUPDATESSOFT)(void); #ifdef AL_ALEXT_PROTOTYPES -AL_API ALvoid AL_APIENTRY alDeferUpdatesSOFT(void); -AL_API ALvoid AL_APIENTRY alProcessUpdatesSOFT(void); + AL_API ALvoid AL_APIENTRY alDeferUpdatesSOFT(void); + AL_API ALvoid AL_APIENTRY alProcessUpdatesSOFT(void); #endif #endif #ifndef AL_SOFT_block_alignment #define AL_SOFT_block_alignment 1 -#define AL_UNPACK_BLOCK_ALIGNMENT_SOFT 0x200C -#define AL_PACK_BLOCK_ALIGNMENT_SOFT 0x200D +#define AL_UNPACK_BLOCK_ALIGNMENT_SOFT 0x200C +#define AL_PACK_BLOCK_ALIGNMENT_SOFT 0x200D #endif #ifndef AL_SOFT_MSADPCM #define AL_SOFT_MSADPCM 1 -#define AL_FORMAT_MONO_MSADPCM_SOFT 0x1302 -#define AL_FORMAT_STEREO_MSADPCM_SOFT 0x1303 +#define AL_FORMAT_MONO_MSADPCM_SOFT 0x1302 +#define AL_FORMAT_STEREO_MSADPCM_SOFT 0x1303 #endif #ifndef AL_SOFT_source_length @@ -385,78 +397,78 @@ AL_API ALvoid AL_APIENTRY alProcessUpdatesSOFT(void); #ifndef ALC_SOFT_pause_device #define ALC_SOFT_pause_device 1 -typedef void (ALC_APIENTRY*LPALCDEVICEPAUSESOFT)(ALCdevice *device); -typedef void (ALC_APIENTRY*LPALCDEVICERESUMESOFT)(ALCdevice *device); + typedef void(ALC_APIENTRY* LPALCDEVICEPAUSESOFT)(ALCdevice* device); + typedef void(ALC_APIENTRY* LPALCDEVICERESUMESOFT)(ALCdevice* device); #ifdef AL_ALEXT_PROTOTYPES -ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device); -ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device); + ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice* device); + ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice* device); #endif #endif #ifndef AL_EXT_BFORMAT #define AL_EXT_BFORMAT 1 -#define AL_FORMAT_BFORMAT2D_8 0x20021 -#define AL_FORMAT_BFORMAT2D_16 0x20022 -#define AL_FORMAT_BFORMAT2D_FLOAT32 0x20023 -#define AL_FORMAT_BFORMAT3D_8 0x20031 -#define AL_FORMAT_BFORMAT3D_16 0x20032 -#define AL_FORMAT_BFORMAT3D_FLOAT32 0x20033 +#define AL_FORMAT_BFORMAT2D_8 0x20021 +#define AL_FORMAT_BFORMAT2D_16 0x20022 +#define AL_FORMAT_BFORMAT2D_FLOAT32 0x20023 +#define AL_FORMAT_BFORMAT3D_8 0x20031 +#define AL_FORMAT_BFORMAT3D_16 0x20032 +#define AL_FORMAT_BFORMAT3D_FLOAT32 0x20033 #endif #ifndef AL_EXT_MULAW_BFORMAT #define AL_EXT_MULAW_BFORMAT 1 -#define AL_FORMAT_BFORMAT2D_MULAW 0x10031 -#define AL_FORMAT_BFORMAT3D_MULAW 0x10032 +#define AL_FORMAT_BFORMAT2D_MULAW 0x10031 +#define AL_FORMAT_BFORMAT3D_MULAW 0x10032 #endif #ifndef ALC_SOFT_HRTF #define ALC_SOFT_HRTF 1 -#define ALC_HRTF_SOFT 0x1992 -#define ALC_DONT_CARE_SOFT 0x0002 -#define ALC_HRTF_STATUS_SOFT 0x1993 -#define ALC_HRTF_DISABLED_SOFT 0x0000 -#define ALC_HRTF_ENABLED_SOFT 0x0001 -#define ALC_HRTF_DENIED_SOFT 0x0002 -#define ALC_HRTF_REQUIRED_SOFT 0x0003 -#define ALC_HRTF_HEADPHONES_DETECTED_SOFT 0x0004 -#define ALC_HRTF_UNSUPPORTED_FORMAT_SOFT 0x0005 -#define ALC_NUM_HRTF_SPECIFIERS_SOFT 0x1994 -#define ALC_HRTF_SPECIFIER_SOFT 0x1995 -#define ALC_HRTF_ID_SOFT 0x1996 -typedef const ALCchar* (ALC_APIENTRY*LPALCGETSTRINGISOFT)(ALCdevice *device, ALCenum paramName, ALCsizei index); -typedef ALCboolean (ALC_APIENTRY*LPALCRESETDEVICESOFT)(ALCdevice *device, const ALCint *attribs); +#define ALC_HRTF_SOFT 0x1992 +#define ALC_DONT_CARE_SOFT 0x0002 +#define ALC_HRTF_STATUS_SOFT 0x1993 +#define ALC_HRTF_DISABLED_SOFT 0x0000 +#define ALC_HRTF_ENABLED_SOFT 0x0001 +#define ALC_HRTF_DENIED_SOFT 0x0002 +#define ALC_HRTF_REQUIRED_SOFT 0x0003 +#define ALC_HRTF_HEADPHONES_DETECTED_SOFT 0x0004 +#define ALC_HRTF_UNSUPPORTED_FORMAT_SOFT 0x0005 +#define ALC_NUM_HRTF_SPECIFIERS_SOFT 0x1994 +#define ALC_HRTF_SPECIFIER_SOFT 0x1995 +#define ALC_HRTF_ID_SOFT 0x1996 + typedef const ALCchar*(ALC_APIENTRY* LPALCGETSTRINGISOFT)(ALCdevice* device, ALCenum paramName, ALCsizei index); + typedef ALCboolean(ALC_APIENTRY* LPALCRESETDEVICESOFT)(ALCdevice* device, const ALCint* attribs); #ifdef AL_ALEXT_PROTOTYPES -ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALCenum paramName, ALCsizei index); -ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCint *attribs); + ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice* device, ALCenum paramName, ALCsizei index); + ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice* device, const ALCint* attribs); #endif #endif #ifndef AL_SOFT_gain_clamp_ex #define AL_SOFT_gain_clamp_ex 1 -#define AL_GAIN_LIMIT_SOFT 0x200E +#define AL_GAIN_LIMIT_SOFT 0x200E #endif #ifndef AL_SOFT_source_resampler #define AL_SOFT_source_resampler -#define AL_NUM_RESAMPLERS_SOFT 0x1210 -#define AL_DEFAULT_RESAMPLER_SOFT 0x1211 -#define AL_SOURCE_RESAMPLER_SOFT 0x1212 -#define AL_RESAMPLER_NAME_SOFT 0x1213 -typedef const ALchar* (AL_APIENTRY*LPALGETSTRINGISOFT)(ALenum pname, ALsizei index); +#define AL_NUM_RESAMPLERS_SOFT 0x1210 +#define AL_DEFAULT_RESAMPLER_SOFT 0x1211 +#define AL_SOURCE_RESAMPLER_SOFT 0x1212 +#define AL_RESAMPLER_NAME_SOFT 0x1213 + typedef const ALchar*(AL_APIENTRY* LPALGETSTRINGISOFT)(ALenum pname, ALsizei index); #ifdef AL_ALEXT_PROTOTYPES -AL_API const ALchar* AL_APIENTRY alGetStringiSOFT(ALenum pname, ALsizei index); + AL_API const ALchar* AL_APIENTRY alGetStringiSOFT(ALenum pname, ALsizei index); #endif #endif #ifndef AL_SOFT_source_spatialize #define AL_SOFT_source_spatialize -#define AL_SOURCE_SPATIALIZE_SOFT 0x1214 -#define AL_AUTO_SOFT 0x0002 +#define AL_SOURCE_SPATIALIZE_SOFT 0x1214 +#define AL_AUTO_SOFT 0x0002 #endif #ifndef ALC_SOFT_output_limiter #define ALC_SOFT_output_limiter -#define ALC_OUTPUT_LIMITER_SOFT 0x199A +#define ALC_OUTPUT_LIMITER_SOFT 0x199A #endif #ifdef __cplusplus diff --git a/apps/openmw/mwsound/efx-presets.h b/apps/openmw/mwsound/efx-presets.h index 8539fd5178..a9662936d5 100644 --- a/apps/openmw/mwsound/efx-presets.h +++ b/apps/openmw/mwsound/efx-presets.h @@ -5,7 +5,8 @@ #ifndef EFXEAXREVERBPROPERTIES_DEFINED #define EFXEAXREVERBPROPERTIES_DEFINED -typedef struct { +typedef struct +{ float flDensity; float flDiffusion; float flGain; @@ -28,375 +29,827 @@ typedef struct { float flHFReference; float flLFReference; float flRoomRolloffFactor; - int iDecayHFLimit; + int iDecayHFLimit; } EFXEAXREVERBPROPERTIES, *LPEFXEAXREVERBPROPERTIES; #endif /* Default Presets */ -#define EFX_REVERB_PRESET_GENERIC \ - { 1.0000f, 1.0000f, 0.3162f, 0.8913f, 1.0000f, 1.4900f, 0.8300f, 1.0000f, 0.0500f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_PADDEDCELL \ - { 0.1715f, 1.0000f, 0.3162f, 0.0010f, 1.0000f, 0.1700f, 0.1000f, 1.0000f, 0.2500f, 0.0010f, { 0.0000f, 0.0000f, 0.0000f }, 1.2691f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_ROOM \ - { 0.4287f, 1.0000f, 0.3162f, 0.5929f, 1.0000f, 0.4000f, 0.8300f, 1.0000f, 0.1503f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 1.0629f, 0.0030f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_BATHROOM \ - { 0.1715f, 1.0000f, 0.3162f, 0.2512f, 1.0000f, 1.4900f, 0.5400f, 1.0000f, 0.6531f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 3.2734f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_LIVINGROOM \ - { 0.9766f, 1.0000f, 0.3162f, 0.0010f, 1.0000f, 0.5000f, 0.1000f, 1.0000f, 0.2051f, 0.0030f, { 0.0000f, 0.0000f, 0.0000f }, 0.2805f, 0.0040f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_STONEROOM \ - { 1.0000f, 1.0000f, 0.3162f, 0.7079f, 1.0000f, 2.3100f, 0.6400f, 1.0000f, 0.4411f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.1003f, 0.0170f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_AUDITORIUM \ - { 1.0000f, 1.0000f, 0.3162f, 0.5781f, 1.0000f, 4.3200f, 0.5900f, 1.0000f, 0.4032f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.7170f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_CONCERTHALL \ - { 1.0000f, 1.0000f, 0.3162f, 0.5623f, 1.0000f, 3.9200f, 0.7000f, 1.0000f, 0.2427f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.9977f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_CAVE \ - { 1.0000f, 1.0000f, 0.3162f, 1.0000f, 1.0000f, 2.9100f, 1.3000f, 1.0000f, 0.5000f, 0.0150f, { 0.0000f, 0.0000f, 0.0000f }, 0.7063f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } - -#define EFX_REVERB_PRESET_ARENA \ - { 1.0000f, 1.0000f, 0.3162f, 0.4477f, 1.0000f, 7.2400f, 0.3300f, 1.0000f, 0.2612f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.0186f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_HANGAR \ - { 1.0000f, 1.0000f, 0.3162f, 0.3162f, 1.0000f, 10.0500f, 0.2300f, 1.0000f, 0.5000f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.2560f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_CARPETEDHALLWAY \ - { 0.4287f, 1.0000f, 0.3162f, 0.0100f, 1.0000f, 0.3000f, 0.1000f, 1.0000f, 0.1215f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 0.1531f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_HALLWAY \ - { 0.3645f, 1.0000f, 0.3162f, 0.7079f, 1.0000f, 1.4900f, 0.5900f, 1.0000f, 0.2458f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.6615f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_STONECORRIDOR \ - { 1.0000f, 1.0000f, 0.3162f, 0.7612f, 1.0000f, 2.7000f, 0.7900f, 1.0000f, 0.2472f, 0.0130f, { 0.0000f, 0.0000f, 0.0000f }, 1.5758f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_ALLEY \ - { 1.0000f, 0.3000f, 0.3162f, 0.7328f, 1.0000f, 1.4900f, 0.8600f, 1.0000f, 0.2500f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.9954f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1250f, 0.9500f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_FOREST \ - { 1.0000f, 0.3000f, 0.3162f, 0.0224f, 1.0000f, 1.4900f, 0.5400f, 1.0000f, 0.0525f, 0.1620f, { 0.0000f, 0.0000f, 0.0000f }, 0.7682f, 0.0880f, { 0.0000f, 0.0000f, 0.0000f }, 0.1250f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_CITY \ - { 1.0000f, 0.5000f, 0.3162f, 0.3981f, 1.0000f, 1.4900f, 0.6700f, 1.0000f, 0.0730f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.1427f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_MOUNTAINS \ - { 1.0000f, 0.2700f, 0.3162f, 0.0562f, 1.0000f, 1.4900f, 0.2100f, 1.0000f, 0.0407f, 0.3000f, { 0.0000f, 0.0000f, 0.0000f }, 0.1919f, 0.1000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } - -#define EFX_REVERB_PRESET_QUARRY \ - { 1.0000f, 1.0000f, 0.3162f, 0.3162f, 1.0000f, 1.4900f, 0.8300f, 1.0000f, 0.0000f, 0.0610f, { 0.0000f, 0.0000f, 0.0000f }, 1.7783f, 0.0250f, { 0.0000f, 0.0000f, 0.0000f }, 0.1250f, 0.7000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_PLAIN \ - { 1.0000f, 0.2100f, 0.3162f, 0.1000f, 1.0000f, 1.4900f, 0.5000f, 1.0000f, 0.0585f, 0.1790f, { 0.0000f, 0.0000f, 0.0000f }, 0.1089f, 0.1000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_PARKINGLOT \ - { 1.0000f, 1.0000f, 0.3162f, 1.0000f, 1.0000f, 1.6500f, 1.5000f, 1.0000f, 0.2082f, 0.0080f, { 0.0000f, 0.0000f, 0.0000f }, 0.2652f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } - -#define EFX_REVERB_PRESET_SEWERPIPE \ - { 0.3071f, 0.8000f, 0.3162f, 0.3162f, 1.0000f, 2.8100f, 0.1400f, 1.0000f, 1.6387f, 0.0140f, { 0.0000f, 0.0000f, 0.0000f }, 3.2471f, 0.0210f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_UNDERWATER \ - { 0.3645f, 1.0000f, 0.3162f, 0.0100f, 1.0000f, 1.4900f, 0.1000f, 1.0000f, 0.5963f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 7.0795f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 1.1800f, 0.3480f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_DRUGGED \ - { 0.4287f, 0.5000f, 0.3162f, 1.0000f, 1.0000f, 8.3900f, 1.3900f, 1.0000f, 0.8760f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 3.1081f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 1.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } - -#define EFX_REVERB_PRESET_DIZZY \ - { 0.3645f, 0.6000f, 0.3162f, 0.6310f, 1.0000f, 17.2300f, 0.5600f, 1.0000f, 0.1392f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.4937f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.8100f, 0.3100f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } - -#define EFX_REVERB_PRESET_PSYCHOTIC \ - { 0.0625f, 0.5000f, 0.3162f, 0.8404f, 1.0000f, 7.5600f, 0.9100f, 1.0000f, 0.4864f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 2.4378f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 4.0000f, 1.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } +#define EFX_REVERB_PRESET_GENERIC \ + { \ + 1.0000f, 1.0000f, 0.3162f, 0.8913f, 1.0000f, 1.4900f, 0.8300f, 1.0000f, 0.0500f, 0.0070f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_PADDEDCELL \ + { \ + 0.1715f, 1.0000f, 0.3162f, 0.0010f, 1.0000f, 0.1700f, 0.1000f, 1.0000f, 0.2500f, 0.0010f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.2691f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_ROOM \ + { \ + 0.4287f, 1.0000f, 0.3162f, 0.5929f, 1.0000f, 0.4000f, 0.8300f, 1.0000f, 0.1503f, 0.0020f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.0629f, 0.0030f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_BATHROOM \ + { \ + 0.1715f, 1.0000f, 0.3162f, 0.2512f, 1.0000f, 1.4900f, 0.5400f, 1.0000f, 0.6531f, 0.0070f, \ + { 0.0000f, 0.0000f, 0.0000f }, 3.2734f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_LIVINGROOM \ + { \ + 0.9766f, 1.0000f, 0.3162f, 0.0010f, 1.0000f, 0.5000f, 0.1000f, 1.0000f, 0.2051f, 0.0030f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.2805f, 0.0040f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_STONEROOM \ + { \ + 1.0000f, 1.0000f, 0.3162f, 0.7079f, 1.0000f, 2.3100f, 0.6400f, 1.0000f, 0.4411f, 0.0120f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.1003f, 0.0170f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_AUDITORIUM \ + { \ + 1.0000f, 1.0000f, 0.3162f, 0.5781f, 1.0000f, 4.3200f, 0.5900f, 1.0000f, 0.4032f, 0.0200f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.7170f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_CONCERTHALL \ + { \ + 1.0000f, 1.0000f, 0.3162f, 0.5623f, 1.0000f, 3.9200f, 0.7000f, 1.0000f, 0.2427f, 0.0200f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.9977f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_CAVE \ + { \ + 1.0000f, 1.0000f, 0.3162f, 1.0000f, 1.0000f, 2.9100f, 1.3000f, 1.0000f, 0.5000f, 0.0150f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.7063f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 \ + } + +#define EFX_REVERB_PRESET_ARENA \ + { \ + 1.0000f, 1.0000f, 0.3162f, 0.4477f, 1.0000f, 7.2400f, 0.3300f, 1.0000f, 0.2612f, 0.0200f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.0186f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_HANGAR \ + { \ + 1.0000f, 1.0000f, 0.3162f, 0.3162f, 1.0000f, 10.0500f, 0.2300f, 1.0000f, 0.5000f, 0.0200f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.2560f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_CARPETEDHALLWAY \ + { \ + 0.4287f, 1.0000f, 0.3162f, 0.0100f, 1.0000f, 0.3000f, 0.1000f, 1.0000f, 0.1215f, 0.0020f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.1531f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_HALLWAY \ + { \ + 0.3645f, 1.0000f, 0.3162f, 0.7079f, 1.0000f, 1.4900f, 0.5900f, 1.0000f, 0.2458f, 0.0070f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.6615f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_STONECORRIDOR \ + { \ + 1.0000f, 1.0000f, 0.3162f, 0.7612f, 1.0000f, 2.7000f, 0.7900f, 1.0000f, 0.2472f, 0.0130f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.5758f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_ALLEY \ + { \ + 1.0000f, 0.3000f, 0.3162f, 0.7328f, 1.0000f, 1.4900f, 0.8600f, 1.0000f, 0.2500f, 0.0070f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.9954f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1250f, 0.9500f, 0.2500f, \ + 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_FOREST \ + { \ + 1.0000f, 0.3000f, 0.3162f, 0.0224f, 1.0000f, 1.4900f, 0.5400f, 1.0000f, 0.0525f, 0.1620f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.7682f, 0.0880f, { 0.0000f, 0.0000f, 0.0000f }, 0.1250f, 1.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_CITY \ + { \ + 1.0000f, 0.5000f, 0.3162f, 0.3981f, 1.0000f, 1.4900f, 0.6700f, 1.0000f, 0.0730f, 0.0070f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.1427f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_MOUNTAINS \ + { \ + 1.0000f, 0.2700f, 0.3162f, 0.0562f, 1.0000f, 1.4900f, 0.2100f, 1.0000f, 0.0407f, 0.3000f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.1919f, 0.1000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 \ + } + +#define EFX_REVERB_PRESET_QUARRY \ + { \ + 1.0000f, 1.0000f, 0.3162f, 0.3162f, 1.0000f, 1.4900f, 0.8300f, 1.0000f, 0.0000f, 0.0610f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.7783f, 0.0250f, { 0.0000f, 0.0000f, 0.0000f }, 0.1250f, 0.7000f, 0.2500f, \ + 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_PLAIN \ + { \ + 1.0000f, 0.2100f, 0.3162f, 0.1000f, 1.0000f, 1.4900f, 0.5000f, 1.0000f, 0.0585f, 0.1790f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.1089f, 0.1000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_PARKINGLOT \ + { \ + 1.0000f, 1.0000f, 0.3162f, 1.0000f, 1.0000f, 1.6500f, 1.5000f, 1.0000f, 0.2082f, 0.0080f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.2652f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 \ + } + +#define EFX_REVERB_PRESET_SEWERPIPE \ + { \ + 0.3071f, 0.8000f, 0.3162f, 0.3162f, 1.0000f, 2.8100f, 0.1400f, 1.0000f, 1.6387f, 0.0140f, \ + { 0.0000f, 0.0000f, 0.0000f }, 3.2471f, 0.0210f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_UNDERWATER \ + { \ + 0.3645f, 1.0000f, 0.3162f, 0.0100f, 1.0000f, 1.4900f, 0.1000f, 1.0000f, 0.5963f, 0.0070f, \ + { 0.0000f, 0.0000f, 0.0000f }, 7.0795f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 1.1800f, \ + 0.3480f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_DRUGGED \ + { \ + 0.4287f, 0.5000f, 0.3162f, 1.0000f, 1.0000f, 8.3900f, 1.3900f, 1.0000f, 0.8760f, 0.0020f, \ + { 0.0000f, 0.0000f, 0.0000f }, 3.1081f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 1.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 \ + } + +#define EFX_REVERB_PRESET_DIZZY \ + { \ + 0.3645f, 0.6000f, 0.3162f, 0.6310f, 1.0000f, 17.2300f, 0.5600f, 1.0000f, 0.1392f, 0.0200f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.4937f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.8100f, \ + 0.3100f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 \ + } + +#define EFX_REVERB_PRESET_PSYCHOTIC \ + { \ + 0.0625f, 0.5000f, 0.3162f, 0.8404f, 1.0000f, 7.5600f, 0.9100f, 1.0000f, 0.4864f, 0.0200f, \ + { 0.0000f, 0.0000f, 0.0000f }, 2.4378f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 4.0000f, \ + 1.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 \ + } /* Castle Presets */ -#define EFX_REVERB_PRESET_CASTLE_SMALLROOM \ - { 1.0000f, 0.8900f, 0.3162f, 0.3981f, 0.1000f, 1.2200f, 0.8300f, 0.3100f, 0.8913f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 1.9953f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_CASTLE_SHORTPASSAGE \ - { 1.0000f, 0.8900f, 0.3162f, 0.3162f, 0.1000f, 2.3200f, 0.8300f, 0.3100f, 0.8913f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_CASTLE_MEDIUMROOM \ - { 1.0000f, 0.9300f, 0.3162f, 0.2818f, 0.1000f, 2.0400f, 0.8300f, 0.4600f, 0.6310f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 1.5849f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1550f, 0.0300f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_CASTLE_LARGEROOM \ - { 1.0000f, 0.8200f, 0.3162f, 0.2818f, 0.1259f, 2.5300f, 0.8300f, 0.5000f, 0.4467f, 0.0340f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.1850f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_CASTLE_LONGPASSAGE \ - { 1.0000f, 0.8900f, 0.3162f, 0.3981f, 0.1000f, 3.4200f, 0.8300f, 0.3100f, 0.8913f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_CASTLE_HALL \ - { 1.0000f, 0.8100f, 0.3162f, 0.2818f, 0.1778f, 3.1400f, 0.7900f, 0.6200f, 0.1778f, 0.0560f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_CASTLE_CUPBOARD \ - { 1.0000f, 0.8900f, 0.3162f, 0.2818f, 0.1000f, 0.6700f, 0.8700f, 0.3100f, 1.4125f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 3.5481f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_CASTLE_COURTYARD \ - { 1.0000f, 0.4200f, 0.3162f, 0.4467f, 0.1995f, 2.1300f, 0.6100f, 0.2300f, 0.2239f, 0.1600f, { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0360f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.3700f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } - -#define EFX_REVERB_PRESET_CASTLE_ALCOVE \ - { 1.0000f, 0.8900f, 0.3162f, 0.5012f, 0.1000f, 1.6400f, 0.8700f, 0.3100f, 1.0000f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0340f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 } +#define EFX_REVERB_PRESET_CASTLE_SMALLROOM \ + { \ + 1.0000f, 0.8900f, 0.3162f, 0.3981f, 0.1000f, 1.2200f, 0.8300f, 0.3100f, 0.8913f, 0.0220f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.9953f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, \ + 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_CASTLE_SHORTPASSAGE \ + { \ + 1.0000f, 0.8900f, 0.3162f, 0.3162f, 0.1000f, 2.3200f, 0.8300f, 0.3100f, 0.8913f, 0.0070f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, \ + 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_CASTLE_MEDIUMROOM \ + { \ + 1.0000f, 0.9300f, 0.3162f, 0.2818f, 0.1000f, 2.0400f, 0.8300f, 0.4600f, 0.6310f, 0.0220f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.5849f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1550f, 0.0300f, 0.2500f, \ + 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_CASTLE_LARGEROOM \ + { \ + 1.0000f, 0.8200f, 0.3162f, 0.2818f, 0.1259f, 2.5300f, 0.8300f, 0.5000f, 0.4467f, 0.0340f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.1850f, 0.0700f, 0.2500f, \ + 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_CASTLE_LONGPASSAGE \ + { \ + 1.0000f, 0.8900f, 0.3162f, 0.3981f, 0.1000f, 3.4200f, 0.8300f, 0.3100f, 0.8913f, 0.0070f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, \ + 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_CASTLE_HALL \ + { \ + 1.0000f, 0.8100f, 0.3162f, 0.2818f, 0.1778f, 3.1400f, 0.7900f, 0.6200f, 0.1778f, 0.0560f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_CASTLE_CUPBOARD \ + { \ + 1.0000f, 0.8900f, 0.3162f, 0.2818f, 0.1000f, 0.6700f, 0.8700f, 0.3100f, 1.4125f, 0.0100f, \ + { 0.0000f, 0.0000f, 0.0000f }, 3.5481f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, \ + 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_CASTLE_COURTYARD \ + { \ + 1.0000f, 0.4200f, 0.3162f, 0.4467f, 0.1995f, 2.1300f, 0.6100f, 0.2300f, 0.2239f, 0.1600f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0360f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.3700f, 0.2500f, \ + 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 \ + } + +#define EFX_REVERB_PRESET_CASTLE_ALCOVE \ + { \ + 1.0000f, 0.8900f, 0.3162f, 0.5012f, 0.1000f, 1.6400f, 0.8700f, 0.3100f, 1.0000f, 0.0070f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0340f, { 0.0000f, 0.0000f, 0.0000f }, 0.1380f, 0.0800f, 0.2500f, \ + 0.0000f, 0.9943f, 5168.6001f, 139.5000f, 0.0000f, 0x1 \ + } /* Factory Presets */ -#define EFX_REVERB_PRESET_FACTORY_SMALLROOM \ - { 0.3645f, 0.8200f, 0.3162f, 0.7943f, 0.5012f, 1.7200f, 0.6500f, 1.3100f, 0.7079f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.7783f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.1190f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_FACTORY_SHORTPASSAGE \ - { 0.3645f, 0.6400f, 0.2512f, 0.7943f, 0.5012f, 2.5300f, 0.6500f, 1.3100f, 1.0000f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0380f, { 0.0000f, 0.0000f, 0.0000f }, 0.1350f, 0.2300f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_FACTORY_MEDIUMROOM \ - { 0.4287f, 0.8200f, 0.2512f, 0.7943f, 0.5012f, 2.7600f, 0.6500f, 1.3100f, 0.2818f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.1740f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_FACTORY_LARGEROOM \ - { 0.4287f, 0.7500f, 0.2512f, 0.7079f, 0.6310f, 4.2400f, 0.5100f, 1.3100f, 0.1778f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.2310f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_FACTORY_LONGPASSAGE \ - { 0.3645f, 0.6400f, 0.2512f, 0.7943f, 0.5012f, 4.0600f, 0.6500f, 1.3100f, 1.0000f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0370f, { 0.0000f, 0.0000f, 0.0000f }, 0.1350f, 0.2300f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_FACTORY_HALL \ - { 0.4287f, 0.7500f, 0.3162f, 0.7079f, 0.6310f, 7.4300f, 0.5100f, 1.3100f, 0.0631f, 0.0730f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0270f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_FACTORY_CUPBOARD \ - { 0.3071f, 0.6300f, 0.2512f, 0.7943f, 0.5012f, 0.4900f, 0.6500f, 1.3100f, 1.2589f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.9953f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.1070f, 0.0700f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_FACTORY_COURTYARD \ - { 0.3071f, 0.5700f, 0.3162f, 0.3162f, 0.6310f, 2.3200f, 0.2900f, 0.5600f, 0.2239f, 0.1400f, { 0.0000f, 0.0000f, 0.0000f }, 0.3981f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2900f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_FACTORY_ALCOVE \ - { 0.3645f, 0.5900f, 0.2512f, 0.7943f, 0.5012f, 3.1400f, 0.6500f, 1.3100f, 1.4125f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.0000f, 0.0380f, { 0.0000f, 0.0000f, 0.0000f }, 0.1140f, 0.1000f, 0.2500f, 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 } +#define EFX_REVERB_PRESET_FACTORY_SMALLROOM \ + { \ + 0.3645f, 0.8200f, 0.3162f, 0.7943f, 0.5012f, 1.7200f, 0.6500f, 1.3100f, 0.7079f, 0.0100f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.7783f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.1190f, 0.0700f, 0.2500f, \ + 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_FACTORY_SHORTPASSAGE \ + { \ + 0.3645f, 0.6400f, 0.2512f, 0.7943f, 0.5012f, 2.5300f, 0.6500f, 1.3100f, 1.0000f, 0.0100f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0380f, { 0.0000f, 0.0000f, 0.0000f }, 0.1350f, 0.2300f, 0.2500f, \ + 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_FACTORY_MEDIUMROOM \ + { \ + 0.4287f, 0.8200f, 0.2512f, 0.7943f, 0.5012f, 2.7600f, 0.6500f, 1.3100f, 0.2818f, 0.0220f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.1740f, 0.0700f, 0.2500f, \ + 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_FACTORY_LARGEROOM \ + { \ + 0.4287f, 0.7500f, 0.2512f, 0.7079f, 0.6310f, 4.2400f, 0.5100f, 1.3100f, 0.1778f, 0.0390f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.2310f, 0.0700f, 0.2500f, \ + 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_FACTORY_LONGPASSAGE \ + { \ + 0.3645f, 0.6400f, 0.2512f, 0.7943f, 0.5012f, 4.0600f, 0.6500f, 1.3100f, 1.0000f, 0.0200f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0370f, { 0.0000f, 0.0000f, 0.0000f }, 0.1350f, 0.2300f, 0.2500f, \ + 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_FACTORY_HALL \ + { \ + 0.4287f, 0.7500f, 0.3162f, 0.7079f, 0.6310f, 7.4300f, 0.5100f, 1.3100f, 0.0631f, 0.0730f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0270f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0700f, 0.2500f, \ + 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_FACTORY_CUPBOARD \ + { \ + 0.3071f, 0.6300f, 0.2512f, 0.7943f, 0.5012f, 0.4900f, 0.6500f, 1.3100f, 1.2589f, 0.0100f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.9953f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.1070f, 0.0700f, 0.2500f, \ + 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_FACTORY_COURTYARD \ + { \ + 0.3071f, 0.5700f, 0.3162f, 0.3162f, 0.6310f, 2.3200f, 0.2900f, 0.5600f, 0.2239f, 0.1400f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.3981f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2900f, 0.2500f, \ + 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_FACTORY_ALCOVE \ + { \ + 0.3645f, 0.5900f, 0.2512f, 0.7943f, 0.5012f, 3.1400f, 0.6500f, 1.3100f, 1.4125f, 0.0100f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.0000f, 0.0380f, { 0.0000f, 0.0000f, 0.0000f }, 0.1140f, 0.1000f, 0.2500f, \ + 0.0000f, 0.9943f, 3762.6001f, 362.5000f, 0.0000f, 0x1 \ + } /* Ice Palace Presets */ -#define EFX_REVERB_PRESET_ICEPALACE_SMALLROOM \ - { 1.0000f, 0.8400f, 0.3162f, 0.5623f, 0.2818f, 1.5100f, 1.5300f, 0.2700f, 0.8913f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1640f, 0.1400f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_ICEPALACE_SHORTPASSAGE \ - { 1.0000f, 0.7500f, 0.3162f, 0.5623f, 0.2818f, 1.7900f, 1.4600f, 0.2800f, 0.5012f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0190f, { 0.0000f, 0.0000f, 0.0000f }, 0.1770f, 0.0900f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_ICEPALACE_MEDIUMROOM \ - { 1.0000f, 0.8700f, 0.3162f, 0.5623f, 0.4467f, 2.2200f, 1.5300f, 0.3200f, 0.3981f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0270f, { 0.0000f, 0.0000f, 0.0000f }, 0.1860f, 0.1200f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_ICEPALACE_LARGEROOM \ - { 1.0000f, 0.8100f, 0.3162f, 0.5623f, 0.4467f, 3.1400f, 1.5300f, 0.3200f, 0.2512f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 1.0000f, 0.0270f, { 0.0000f, 0.0000f, 0.0000f }, 0.2140f, 0.1100f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_ICEPALACE_LONGPASSAGE \ - { 1.0000f, 0.7700f, 0.3162f, 0.5623f, 0.3981f, 3.0100f, 1.4600f, 0.2800f, 0.7943f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0250f, { 0.0000f, 0.0000f, 0.0000f }, 0.1860f, 0.0400f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_ICEPALACE_HALL \ - { 1.0000f, 0.7600f, 0.3162f, 0.4467f, 0.5623f, 5.4900f, 1.5300f, 0.3800f, 0.1122f, 0.0540f, { 0.0000f, 0.0000f, 0.0000f }, 0.6310f, 0.0520f, { 0.0000f, 0.0000f, 0.0000f }, 0.2260f, 0.1100f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_ICEPALACE_CUPBOARD \ - { 1.0000f, 0.8300f, 0.3162f, 0.5012f, 0.2239f, 0.7600f, 1.5300f, 0.2600f, 1.1220f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.9953f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.1430f, 0.0800f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_ICEPALACE_COURTYARD \ - { 1.0000f, 0.5900f, 0.3162f, 0.2818f, 0.3162f, 2.0400f, 1.2000f, 0.3800f, 0.3162f, 0.1730f, { 0.0000f, 0.0000f, 0.0000f }, 0.3162f, 0.0430f, { 0.0000f, 0.0000f, 0.0000f }, 0.2350f, 0.4800f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_ICEPALACE_ALCOVE \ - { 1.0000f, 0.8400f, 0.3162f, 0.5623f, 0.2818f, 2.7600f, 1.4600f, 0.2800f, 1.1220f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.1610f, 0.0900f, 0.2500f, 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 } +#define EFX_REVERB_PRESET_ICEPALACE_SMALLROOM \ + { \ + 1.0000f, 0.8400f, 0.3162f, 0.5623f, 0.2818f, 1.5100f, 1.5300f, 0.2700f, 0.8913f, 0.0100f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1640f, 0.1400f, 0.2500f, \ + 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_ICEPALACE_SHORTPASSAGE \ + { \ + 1.0000f, 0.7500f, 0.3162f, 0.5623f, 0.2818f, 1.7900f, 1.4600f, 0.2800f, 0.5012f, 0.0100f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0190f, { 0.0000f, 0.0000f, 0.0000f }, 0.1770f, 0.0900f, 0.2500f, \ + 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_ICEPALACE_MEDIUMROOM \ + { \ + 1.0000f, 0.8700f, 0.3162f, 0.5623f, 0.4467f, 2.2200f, 1.5300f, 0.3200f, 0.3981f, 0.0390f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0270f, { 0.0000f, 0.0000f, 0.0000f }, 0.1860f, 0.1200f, 0.2500f, \ + 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_ICEPALACE_LARGEROOM \ + { \ + 1.0000f, 0.8100f, 0.3162f, 0.5623f, 0.4467f, 3.1400f, 1.5300f, 0.3200f, 0.2512f, 0.0390f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.0000f, 0.0270f, { 0.0000f, 0.0000f, 0.0000f }, 0.2140f, 0.1100f, 0.2500f, \ + 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_ICEPALACE_LONGPASSAGE \ + { \ + 1.0000f, 0.7700f, 0.3162f, 0.5623f, 0.3981f, 3.0100f, 1.4600f, 0.2800f, 0.7943f, 0.0120f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0250f, { 0.0000f, 0.0000f, 0.0000f }, 0.1860f, 0.0400f, 0.2500f, \ + 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_ICEPALACE_HALL \ + { \ + 1.0000f, 0.7600f, 0.3162f, 0.4467f, 0.5623f, 5.4900f, 1.5300f, 0.3800f, 0.1122f, 0.0540f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.6310f, 0.0520f, { 0.0000f, 0.0000f, 0.0000f }, 0.2260f, 0.1100f, 0.2500f, \ + 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_ICEPALACE_CUPBOARD \ + { \ + 1.0000f, 0.8300f, 0.3162f, 0.5012f, 0.2239f, 0.7600f, 1.5300f, 0.2600f, 1.1220f, 0.0120f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.9953f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.1430f, 0.0800f, 0.2500f, \ + 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_ICEPALACE_COURTYARD \ + { \ + 1.0000f, 0.5900f, 0.3162f, 0.2818f, 0.3162f, 2.0400f, 1.2000f, 0.3800f, 0.3162f, 0.1730f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.3162f, 0.0430f, { 0.0000f, 0.0000f, 0.0000f }, 0.2350f, 0.4800f, 0.2500f, \ + 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_ICEPALACE_ALCOVE \ + { \ + 1.0000f, 0.8400f, 0.3162f, 0.5623f, 0.2818f, 2.7600f, 1.4600f, 0.2800f, 1.1220f, 0.0100f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.1610f, 0.0900f, 0.2500f, \ + 0.0000f, 0.9943f, 12428.5000f, 99.6000f, 0.0000f, 0x1 \ + } /* Space Station Presets */ -#define EFX_REVERB_PRESET_SPACESTATION_SMALLROOM \ - { 0.2109f, 0.7000f, 0.3162f, 0.7079f, 0.8913f, 1.7200f, 0.8200f, 0.5500f, 0.7943f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0130f, { 0.0000f, 0.0000f, 0.0000f }, 0.1880f, 0.2600f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_SPACESTATION_SHORTPASSAGE \ - { 0.2109f, 0.8700f, 0.3162f, 0.6310f, 0.8913f, 3.5700f, 0.5000f, 0.5500f, 1.0000f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.1720f, 0.2000f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_SPACESTATION_MEDIUMROOM \ - { 0.2109f, 0.7500f, 0.3162f, 0.6310f, 0.8913f, 3.0100f, 0.5000f, 0.5500f, 0.3981f, 0.0340f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0350f, { 0.0000f, 0.0000f, 0.0000f }, 0.2090f, 0.3100f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_SPACESTATION_LARGEROOM \ - { 0.3645f, 0.8100f, 0.3162f, 0.6310f, 0.8913f, 3.8900f, 0.3800f, 0.6100f, 0.3162f, 0.0560f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0350f, { 0.0000f, 0.0000f, 0.0000f }, 0.2330f, 0.2800f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_SPACESTATION_LONGPASSAGE \ - { 0.4287f, 0.8200f, 0.3162f, 0.6310f, 0.8913f, 4.6200f, 0.6200f, 0.5500f, 1.0000f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0310f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2300f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_SPACESTATION_HALL \ - { 0.4287f, 0.8700f, 0.3162f, 0.6310f, 0.8913f, 7.1100f, 0.3800f, 0.6100f, 0.1778f, 0.1000f, { 0.0000f, 0.0000f, 0.0000f }, 0.6310f, 0.0470f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2500f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_SPACESTATION_CUPBOARD \ - { 0.1715f, 0.5600f, 0.3162f, 0.7079f, 0.8913f, 0.7900f, 0.8100f, 0.5500f, 1.4125f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.7783f, 0.0180f, { 0.0000f, 0.0000f, 0.0000f }, 0.1810f, 0.3100f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_SPACESTATION_ALCOVE \ - { 0.2109f, 0.7800f, 0.3162f, 0.7079f, 0.8913f, 1.1600f, 0.8100f, 0.5500f, 1.4125f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.0000f, 0.0180f, { 0.0000f, 0.0000f, 0.0000f }, 0.1920f, 0.2100f, 0.2500f, 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 } +#define EFX_REVERB_PRESET_SPACESTATION_SMALLROOM \ + { \ + 0.2109f, 0.7000f, 0.3162f, 0.7079f, 0.8913f, 1.7200f, 0.8200f, 0.5500f, 0.7943f, 0.0070f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0130f, { 0.0000f, 0.0000f, 0.0000f }, 0.1880f, 0.2600f, 0.2500f, \ + 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_SPACESTATION_SHORTPASSAGE \ + { \ + 0.2109f, 0.8700f, 0.3162f, 0.6310f, 0.8913f, 3.5700f, 0.5000f, 0.5500f, 1.0000f, 0.0120f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.1720f, 0.2000f, 0.2500f, \ + 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_SPACESTATION_MEDIUMROOM \ + { \ + 0.2109f, 0.7500f, 0.3162f, 0.6310f, 0.8913f, 3.0100f, 0.5000f, 0.5500f, 0.3981f, 0.0340f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0350f, { 0.0000f, 0.0000f, 0.0000f }, 0.2090f, 0.3100f, 0.2500f, \ + 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_SPACESTATION_LARGEROOM \ + { \ + 0.3645f, 0.8100f, 0.3162f, 0.6310f, 0.8913f, 3.8900f, 0.3800f, 0.6100f, 0.3162f, 0.0560f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0350f, { 0.0000f, 0.0000f, 0.0000f }, 0.2330f, 0.2800f, 0.2500f, \ + 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_SPACESTATION_LONGPASSAGE \ + { \ + 0.4287f, 0.8200f, 0.3162f, 0.6310f, 0.8913f, 4.6200f, 0.6200f, 0.5500f, 1.0000f, 0.0120f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0310f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2300f, 0.2500f, \ + 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_SPACESTATION_HALL \ + { \ + 0.4287f, 0.8700f, 0.3162f, 0.6310f, 0.8913f, 7.1100f, 0.3800f, 0.6100f, 0.1778f, 0.1000f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.6310f, 0.0470f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2500f, 0.2500f, \ + 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_SPACESTATION_CUPBOARD \ + { \ + 0.1715f, 0.5600f, 0.3162f, 0.7079f, 0.8913f, 0.7900f, 0.8100f, 0.5500f, 1.4125f, 0.0070f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.7783f, 0.0180f, { 0.0000f, 0.0000f, 0.0000f }, 0.1810f, 0.3100f, 0.2500f, \ + 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_SPACESTATION_ALCOVE \ + { \ + 0.2109f, 0.7800f, 0.3162f, 0.7079f, 0.8913f, 1.1600f, 0.8100f, 0.5500f, 1.4125f, 0.0070f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.0000f, 0.0180f, { 0.0000f, 0.0000f, 0.0000f }, 0.1920f, 0.2100f, 0.2500f, \ + 0.0000f, 0.9943f, 3316.1001f, 458.2000f, 0.0000f, 0x1 \ + } /* Wooden Galleon Presets */ -#define EFX_REVERB_PRESET_WOODEN_SMALLROOM \ - { 1.0000f, 1.0000f, 0.3162f, 0.1122f, 0.3162f, 0.7900f, 0.3200f, 0.8700f, 1.0000f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_WOODEN_SHORTPASSAGE \ - { 1.0000f, 1.0000f, 0.3162f, 0.1259f, 0.3162f, 1.7500f, 0.5000f, 0.8700f, 0.8913f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.6310f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_WOODEN_MEDIUMROOM \ - { 1.0000f, 1.0000f, 0.3162f, 0.1000f, 0.2818f, 1.4700f, 0.4200f, 0.8200f, 0.8913f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_WOODEN_LARGEROOM \ - { 1.0000f, 1.0000f, 0.3162f, 0.0891f, 0.2818f, 2.6500f, 0.3300f, 0.8200f, 0.8913f, 0.0660f, { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_WOODEN_LONGPASSAGE \ - { 1.0000f, 1.0000f, 0.3162f, 0.1000f, 0.3162f, 1.9900f, 0.4000f, 0.7900f, 1.0000f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.4467f, 0.0360f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_WOODEN_HALL \ - { 1.0000f, 1.0000f, 0.3162f, 0.0794f, 0.2818f, 3.4500f, 0.3000f, 0.8200f, 0.8913f, 0.0880f, { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0630f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_WOODEN_CUPBOARD \ - { 1.0000f, 1.0000f, 0.3162f, 0.1413f, 0.3162f, 0.5600f, 0.4600f, 0.9100f, 1.1220f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0280f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_WOODEN_COURTYARD \ - { 1.0000f, 0.6500f, 0.3162f, 0.0794f, 0.3162f, 1.7900f, 0.3500f, 0.7900f, 0.5623f, 0.1230f, { 0.0000f, 0.0000f, 0.0000f }, 0.1000f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_WOODEN_ALCOVE \ - { 1.0000f, 1.0000f, 0.3162f, 0.1259f, 0.3162f, 1.2200f, 0.6200f, 0.9100f, 1.1220f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 } +#define EFX_REVERB_PRESET_WOODEN_SMALLROOM \ + { \ + 1.0000f, 1.0000f, 0.3162f, 0.1122f, 0.3162f, 0.7900f, 0.3200f, 0.8700f, 1.0000f, 0.0320f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_WOODEN_SHORTPASSAGE \ + { \ + 1.0000f, 1.0000f, 0.3162f, 0.1259f, 0.3162f, 1.7500f, 0.5000f, 0.8700f, 0.8913f, 0.0120f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.6310f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_WOODEN_MEDIUMROOM \ + { \ + 1.0000f, 1.0000f, 0.3162f, 0.1000f, 0.2818f, 1.4700f, 0.4200f, 0.8200f, 0.8913f, 0.0490f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_WOODEN_LARGEROOM \ + { \ + 1.0000f, 1.0000f, 0.3162f, 0.0891f, 0.2818f, 2.6500f, 0.3300f, 0.8200f, 0.8913f, 0.0660f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_WOODEN_LONGPASSAGE \ + { \ + 1.0000f, 1.0000f, 0.3162f, 0.1000f, 0.3162f, 1.9900f, 0.4000f, 0.7900f, 1.0000f, 0.0200f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.4467f, 0.0360f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_WOODEN_HALL \ + { \ + 1.0000f, 1.0000f, 0.3162f, 0.0794f, 0.2818f, 3.4500f, 0.3000f, 0.8200f, 0.8913f, 0.0880f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0630f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_WOODEN_CUPBOARD \ + { \ + 1.0000f, 1.0000f, 0.3162f, 0.1413f, 0.3162f, 0.5600f, 0.4600f, 0.9100f, 1.1220f, 0.0120f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0280f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_WOODEN_COURTYARD \ + { \ + 1.0000f, 0.6500f, 0.3162f, 0.0794f, 0.3162f, 1.7900f, 0.3500f, 0.7900f, 0.5623f, 0.1230f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.1000f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_WOODEN_ALCOVE \ + { \ + 1.0000f, 1.0000f, 0.3162f, 0.1259f, 0.3162f, 1.2200f, 0.6200f, 0.9100f, 1.1220f, 0.0120f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 4705.0000f, 99.6000f, 0.0000f, 0x1 \ + } /* Sports Presets */ -#define EFX_REVERB_PRESET_SPORT_EMPTYSTADIUM \ - { 1.0000f, 1.0000f, 0.3162f, 0.4467f, 0.7943f, 6.2600f, 0.5100f, 1.1000f, 0.0631f, 0.1830f, { 0.0000f, 0.0000f, 0.0000f }, 0.3981f, 0.0380f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_SPORT_SQUASHCOURT \ - { 1.0000f, 0.7500f, 0.3162f, 0.3162f, 0.7943f, 2.2200f, 0.9100f, 1.1600f, 0.4467f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1260f, 0.1900f, 0.2500f, 0.0000f, 0.9943f, 7176.8999f, 211.2000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_SPORT_SMALLSWIMMINGPOOL \ - { 1.0000f, 0.7000f, 0.3162f, 0.7943f, 0.8913f, 2.7600f, 1.2500f, 1.1400f, 0.6310f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.1790f, 0.1500f, 0.8950f, 0.1900f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } - -#define EFX_REVERB_PRESET_SPORT_LARGESWIMMINGPOOL \ - { 1.0000f, 0.8200f, 0.3162f, 0.7943f, 1.0000f, 5.4900f, 1.3100f, 1.1400f, 0.4467f, 0.0390f, { 0.0000f, 0.0000f, 0.0000f }, 0.5012f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2220f, 0.5500f, 1.1590f, 0.2100f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } - -#define EFX_REVERB_PRESET_SPORT_GYMNASIUM \ - { 1.0000f, 0.8100f, 0.3162f, 0.4467f, 0.8913f, 3.1400f, 1.0600f, 1.3500f, 0.3981f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.5623f, 0.0450f, { 0.0000f, 0.0000f, 0.0000f }, 0.1460f, 0.1400f, 0.2500f, 0.0000f, 0.9943f, 7176.8999f, 211.2000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_SPORT_FULLSTADIUM \ - { 1.0000f, 1.0000f, 0.3162f, 0.0708f, 0.7943f, 5.2500f, 0.1700f, 0.8000f, 0.1000f, 0.1880f, { 0.0000f, 0.0000f, 0.0000f }, 0.2818f, 0.0380f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_SPORT_STADIUMTANNOY \ - { 1.0000f, 0.7800f, 0.3162f, 0.5623f, 0.5012f, 2.5300f, 0.8800f, 0.6800f, 0.2818f, 0.2300f, { 0.0000f, 0.0000f, 0.0000f }, 0.5012f, 0.0630f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } +#define EFX_REVERB_PRESET_SPORT_EMPTYSTADIUM \ + { \ + 1.0000f, 1.0000f, 0.3162f, 0.4467f, 0.7943f, 6.2600f, 0.5100f, 1.1000f, 0.0631f, 0.1830f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.3981f, 0.0380f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_SPORT_SQUASHCOURT \ + { \ + 1.0000f, 0.7500f, 0.3162f, 0.3162f, 0.7943f, 2.2200f, 0.9100f, 1.1600f, 0.4467f, 0.0070f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1260f, 0.1900f, 0.2500f, \ + 0.0000f, 0.9943f, 7176.8999f, 211.2000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_SPORT_SMALLSWIMMINGPOOL \ + { \ + 1.0000f, 0.7000f, 0.3162f, 0.7943f, 0.8913f, 2.7600f, 1.2500f, 1.1400f, 0.6310f, 0.0200f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.1790f, 0.1500f, 0.8950f, \ + 0.1900f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 \ + } + +#define EFX_REVERB_PRESET_SPORT_LARGESWIMMINGPOOL \ + { \ + 1.0000f, 0.8200f, 0.3162f, 0.7943f, 1.0000f, 5.4900f, 1.3100f, 1.1400f, 0.4467f, 0.0390f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.5012f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2220f, 0.5500f, 1.1590f, \ + 0.2100f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 \ + } + +#define EFX_REVERB_PRESET_SPORT_GYMNASIUM \ + { \ + 1.0000f, 0.8100f, 0.3162f, 0.4467f, 0.8913f, 3.1400f, 1.0600f, 1.3500f, 0.3981f, 0.0290f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.5623f, 0.0450f, { 0.0000f, 0.0000f, 0.0000f }, 0.1460f, 0.1400f, 0.2500f, \ + 0.0000f, 0.9943f, 7176.8999f, 211.2000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_SPORT_FULLSTADIUM \ + { \ + 1.0000f, 1.0000f, 0.3162f, 0.0708f, 0.7943f, 5.2500f, 0.1700f, 0.8000f, 0.1000f, 0.1880f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.2818f, 0.0380f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_SPORT_STADIUMTANNOY \ + { \ + 1.0000f, 0.7800f, 0.3162f, 0.5623f, 0.5012f, 2.5300f, 0.8800f, 0.6800f, 0.2818f, 0.2300f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.5012f, 0.0630f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2000f, 0.2500f, \ + 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 \ + } /* Prefab Presets */ -#define EFX_REVERB_PRESET_PREFAB_WORKSHOP \ - { 0.4287f, 1.0000f, 0.3162f, 0.1413f, 0.3981f, 0.7600f, 1.0000f, 1.0000f, 1.0000f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } - -#define EFX_REVERB_PRESET_PREFAB_SCHOOLROOM \ - { 0.4022f, 0.6900f, 0.3162f, 0.6310f, 0.5012f, 0.9800f, 0.4500f, 0.1800f, 1.4125f, 0.0170f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0150f, { 0.0000f, 0.0000f, 0.0000f }, 0.0950f, 0.1400f, 0.2500f, 0.0000f, 0.9943f, 7176.8999f, 211.2000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_PREFAB_PRACTISEROOM \ - { 0.4022f, 0.8700f, 0.3162f, 0.3981f, 0.5012f, 1.1200f, 0.5600f, 0.1800f, 1.2589f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.0950f, 0.1400f, 0.2500f, 0.0000f, 0.9943f, 7176.8999f, 211.2000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_PREFAB_OUTHOUSE \ - { 1.0000f, 0.8200f, 0.3162f, 0.1122f, 0.1585f, 1.3800f, 0.3800f, 0.3500f, 0.8913f, 0.0240f, { 0.0000f, 0.0000f, -0.0000f }, 0.6310f, 0.0440f, { 0.0000f, 0.0000f, 0.0000f }, 0.1210f, 0.1700f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 107.5000f, 0.0000f, 0x0 } - -#define EFX_REVERB_PRESET_PREFAB_CARAVAN \ - { 1.0000f, 1.0000f, 0.3162f, 0.0891f, 0.1259f, 0.4300f, 1.5000f, 1.0000f, 1.0000f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.9953f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } +#define EFX_REVERB_PRESET_PREFAB_WORKSHOP \ + { \ + 0.4287f, 1.0000f, 0.3162f, 0.1413f, 0.3981f, 0.7600f, 1.0000f, 1.0000f, 1.0000f, 0.0120f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 \ + } + +#define EFX_REVERB_PRESET_PREFAB_SCHOOLROOM \ + { \ + 0.4022f, 0.6900f, 0.3162f, 0.6310f, 0.5012f, 0.9800f, 0.4500f, 0.1800f, 1.4125f, 0.0170f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0150f, { 0.0000f, 0.0000f, 0.0000f }, 0.0950f, 0.1400f, 0.2500f, \ + 0.0000f, 0.9943f, 7176.8999f, 211.2000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_PREFAB_PRACTISEROOM \ + { \ + 0.4022f, 0.8700f, 0.3162f, 0.3981f, 0.5012f, 1.1200f, 0.5600f, 0.1800f, 1.2589f, 0.0100f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.0950f, 0.1400f, 0.2500f, \ + 0.0000f, 0.9943f, 7176.8999f, 211.2000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_PREFAB_OUTHOUSE \ + { \ + 1.0000f, 0.8200f, 0.3162f, 0.1122f, 0.1585f, 1.3800f, 0.3800f, 0.3500f, 0.8913f, 0.0240f, \ + { 0.0000f, 0.0000f, -0.0000f }, 0.6310f, 0.0440f, { 0.0000f, 0.0000f, 0.0000f }, 0.1210f, 0.1700f, \ + 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 107.5000f, 0.0000f, 0x0 \ + } + +#define EFX_REVERB_PRESET_PREFAB_CARAVAN \ + { \ + 1.0000f, 1.0000f, 0.3162f, 0.0891f, 0.1259f, 0.4300f, 1.5000f, 1.0000f, 1.0000f, 0.0120f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.9953f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 \ + } /* Dome and Pipe Presets */ -#define EFX_REVERB_PRESET_DOME_TOMB \ - { 1.0000f, 0.7900f, 0.3162f, 0.3548f, 0.2239f, 4.1800f, 0.2100f, 0.1000f, 0.3868f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 1.6788f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 0.1770f, 0.1900f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x0 } - -#define EFX_REVERB_PRESET_PIPE_SMALL \ - { 1.0000f, 1.0000f, 0.3162f, 0.3548f, 0.2239f, 5.0400f, 0.1000f, 0.1000f, 0.5012f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 2.5119f, 0.0150f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_DOME_SAINTPAULS \ - { 1.0000f, 0.8700f, 0.3162f, 0.3548f, 0.2239f, 10.4800f, 0.1900f, 0.1000f, 0.1778f, 0.0900f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0420f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.1200f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_PIPE_LONGTHIN \ - { 0.2560f, 0.9100f, 0.3162f, 0.4467f, 0.2818f, 9.2100f, 0.1800f, 0.1000f, 0.7079f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x0 } - -#define EFX_REVERB_PRESET_PIPE_LARGE \ - { 1.0000f, 1.0000f, 0.3162f, 0.3548f, 0.2239f, 8.4500f, 0.1000f, 0.1000f, 0.3981f, 0.0460f, { 0.0000f, 0.0000f, 0.0000f }, 1.5849f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_PIPE_RESONANT \ - { 0.1373f, 0.9100f, 0.3162f, 0.4467f, 0.2818f, 6.8100f, 0.1800f, 0.1000f, 0.7079f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.0000f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x0 } +#define EFX_REVERB_PRESET_DOME_TOMB \ + { \ + 1.0000f, 0.7900f, 0.3162f, 0.3548f, 0.2239f, 4.1800f, 0.2100f, 0.1000f, 0.3868f, 0.0300f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.6788f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 0.1770f, 0.1900f, 0.2500f, \ + 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x0 \ + } + +#define EFX_REVERB_PRESET_PIPE_SMALL \ + { \ + 1.0000f, 1.0000f, 0.3162f, 0.3548f, 0.2239f, 5.0400f, 0.1000f, 0.1000f, 0.5012f, 0.0320f, \ + { 0.0000f, 0.0000f, 0.0000f }, 2.5119f, 0.0150f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_DOME_SAINTPAULS \ + { \ + 1.0000f, 0.8700f, 0.3162f, 0.3548f, 0.2239f, 10.4800f, 0.1900f, 0.1000f, 0.1778f, 0.0900f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0420f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.1200f, 0.2500f, \ + 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_PIPE_LONGTHIN \ + { \ + 0.2560f, 0.9100f, 0.3162f, 0.4467f, 0.2818f, 9.2100f, 0.1800f, 0.1000f, 0.7079f, 0.0100f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x0 \ + } + +#define EFX_REVERB_PRESET_PIPE_LARGE \ + { \ + 1.0000f, 1.0000f, 0.3162f, 0.3548f, 0.2239f, 8.4500f, 0.1000f, 0.1000f, 0.3981f, 0.0460f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.5849f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_PIPE_RESONANT \ + { \ + 0.1373f, 0.9100f, 0.3162f, 0.4467f, 0.2818f, 6.8100f, 0.1800f, 0.1000f, 0.7079f, 0.0100f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.0000f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 2854.3999f, 20.0000f, 0.0000f, 0x0 \ + } /* Outdoors Presets */ -#define EFX_REVERB_PRESET_OUTDOORS_BACKYARD \ - { 1.0000f, 0.4500f, 0.3162f, 0.2512f, 0.5012f, 1.1200f, 0.3400f, 0.4600f, 0.4467f, 0.0690f, { 0.0000f, 0.0000f, -0.0000f }, 0.7079f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.2180f, 0.3400f, 0.2500f, 0.0000f, 0.9943f, 4399.1001f, 242.9000f, 0.0000f, 0x0 } - -#define EFX_REVERB_PRESET_OUTDOORS_ROLLINGPLAINS \ - { 1.0000f, 0.0000f, 0.3162f, 0.0112f, 0.6310f, 2.1300f, 0.2100f, 0.4600f, 0.1778f, 0.3000f, { 0.0000f, 0.0000f, -0.0000f }, 0.4467f, 0.0190f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 4399.1001f, 242.9000f, 0.0000f, 0x0 } - -#define EFX_REVERB_PRESET_OUTDOORS_DEEPCANYON \ - { 1.0000f, 0.7400f, 0.3162f, 0.1778f, 0.6310f, 3.8900f, 0.2100f, 0.4600f, 0.3162f, 0.2230f, { 0.0000f, 0.0000f, -0.0000f }, 0.3548f, 0.0190f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 4399.1001f, 242.9000f, 0.0000f, 0x0 } - -#define EFX_REVERB_PRESET_OUTDOORS_CREEK \ - { 1.0000f, 0.3500f, 0.3162f, 0.1778f, 0.5012f, 2.1300f, 0.2100f, 0.4600f, 0.3981f, 0.1150f, { 0.0000f, 0.0000f, -0.0000f }, 0.1995f, 0.0310f, { 0.0000f, 0.0000f, 0.0000f }, 0.2180f, 0.3400f, 0.2500f, 0.0000f, 0.9943f, 4399.1001f, 242.9000f, 0.0000f, 0x0 } - -#define EFX_REVERB_PRESET_OUTDOORS_VALLEY \ - { 1.0000f, 0.2800f, 0.3162f, 0.0282f, 0.1585f, 2.8800f, 0.2600f, 0.3500f, 0.1413f, 0.2630f, { 0.0000f, 0.0000f, -0.0000f }, 0.3981f, 0.1000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.3400f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 107.5000f, 0.0000f, 0x0 } +#define EFX_REVERB_PRESET_OUTDOORS_BACKYARD \ + { \ + 1.0000f, 0.4500f, 0.3162f, 0.2512f, 0.5012f, 1.1200f, 0.3400f, 0.4600f, 0.4467f, 0.0690f, \ + { 0.0000f, 0.0000f, -0.0000f }, 0.7079f, 0.0230f, { 0.0000f, 0.0000f, 0.0000f }, 0.2180f, 0.3400f, \ + 0.2500f, 0.0000f, 0.9943f, 4399.1001f, 242.9000f, 0.0000f, 0x0 \ + } + +#define EFX_REVERB_PRESET_OUTDOORS_ROLLINGPLAINS \ + { \ + 1.0000f, 0.0000f, 0.3162f, 0.0112f, 0.6310f, 2.1300f, 0.2100f, 0.4600f, 0.1778f, 0.3000f, \ + { 0.0000f, 0.0000f, -0.0000f }, 0.4467f, 0.0190f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, \ + 0.2500f, 0.0000f, 0.9943f, 4399.1001f, 242.9000f, 0.0000f, 0x0 \ + } + +#define EFX_REVERB_PRESET_OUTDOORS_DEEPCANYON \ + { \ + 1.0000f, 0.7400f, 0.3162f, 0.1778f, 0.6310f, 3.8900f, 0.2100f, 0.4600f, 0.3162f, 0.2230f, \ + { 0.0000f, 0.0000f, -0.0000f }, 0.3548f, 0.0190f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, \ + 0.2500f, 0.0000f, 0.9943f, 4399.1001f, 242.9000f, 0.0000f, 0x0 \ + } + +#define EFX_REVERB_PRESET_OUTDOORS_CREEK \ + { \ + 1.0000f, 0.3500f, 0.3162f, 0.1778f, 0.5012f, 2.1300f, 0.2100f, 0.4600f, 0.3981f, 0.1150f, \ + { 0.0000f, 0.0000f, -0.0000f }, 0.1995f, 0.0310f, { 0.0000f, 0.0000f, 0.0000f }, 0.2180f, 0.3400f, \ + 0.2500f, 0.0000f, 0.9943f, 4399.1001f, 242.9000f, 0.0000f, 0x0 \ + } + +#define EFX_REVERB_PRESET_OUTDOORS_VALLEY \ + { \ + 1.0000f, 0.2800f, 0.3162f, 0.0282f, 0.1585f, 2.8800f, 0.2600f, 0.3500f, 0.1413f, 0.2630f, \ + { 0.0000f, 0.0000f, -0.0000f }, 0.3981f, 0.1000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.3400f, \ + 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 107.5000f, 0.0000f, 0x0 \ + } /* Mood Presets */ -#define EFX_REVERB_PRESET_MOOD_HEAVEN \ - { 1.0000f, 0.9400f, 0.3162f, 0.7943f, 0.4467f, 5.0400f, 1.1200f, 0.5600f, 0.2427f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0800f, 2.7420f, 0.0500f, 0.9977f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_MOOD_HELL \ - { 1.0000f, 0.5700f, 0.3162f, 0.3548f, 0.4467f, 3.5700f, 0.4900f, 2.0000f, 0.0000f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.1100f, 0.0400f, 2.1090f, 0.5200f, 0.9943f, 5000.0000f, 139.5000f, 0.0000f, 0x0 } - -#define EFX_REVERB_PRESET_MOOD_MEMORY \ - { 1.0000f, 0.8500f, 0.3162f, 0.6310f, 0.3548f, 4.0600f, 0.8200f, 0.5600f, 0.0398f, 0.0000f, { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.4740f, 0.4500f, 0.9886f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } +#define EFX_REVERB_PRESET_MOOD_HEAVEN \ + { \ + 1.0000f, 0.9400f, 0.3162f, 0.7943f, 0.4467f, 5.0400f, 1.1200f, 0.5600f, 0.2427f, 0.0200f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0800f, 2.7420f, \ + 0.0500f, 0.9977f, 5000.0000f, 250.0000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_MOOD_HELL \ + { \ + 1.0000f, 0.5700f, 0.3162f, 0.3548f, 0.4467f, 3.5700f, 0.4900f, 2.0000f, 0.0000f, 0.0200f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.1100f, 0.0400f, 2.1090f, \ + 0.5200f, 0.9943f, 5000.0000f, 139.5000f, 0.0000f, 0x0 \ + } + +#define EFX_REVERB_PRESET_MOOD_MEMORY \ + { \ + 1.0000f, 0.8500f, 0.3162f, 0.6310f, 0.3548f, 4.0600f, 0.8200f, 0.5600f, 0.0398f, 0.0000f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.1220f, 0.0000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.4740f, \ + 0.4500f, 0.9886f, 5000.0000f, 250.0000f, 0.0000f, 0x0 \ + } /* Driving Presets */ -#define EFX_REVERB_PRESET_DRIVING_COMMENTATOR \ - { 1.0000f, 0.0000f, 0.3162f, 0.5623f, 0.5012f, 2.4200f, 0.8800f, 0.6800f, 0.1995f, 0.0930f, { 0.0000f, 0.0000f, 0.0000f }, 0.2512f, 0.0170f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9886f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_DRIVING_PITGARAGE \ - { 0.4287f, 0.5900f, 0.3162f, 0.7079f, 0.5623f, 1.7200f, 0.9300f, 0.8700f, 0.5623f, 0.0000f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.1100f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } - -#define EFX_REVERB_PRESET_DRIVING_INCAR_RACER \ - { 0.0832f, 0.8000f, 0.3162f, 1.0000f, 0.7943f, 0.1700f, 2.0000f, 0.4100f, 1.7783f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0150f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 10268.2002f, 251.0000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_DRIVING_INCAR_SPORTS \ - { 0.0832f, 0.8000f, 0.3162f, 0.6310f, 1.0000f, 0.1700f, 0.7500f, 0.4100f, 1.0000f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 0.5623f, 0.0000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 10268.2002f, 251.0000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_DRIVING_INCAR_LUXURY \ - { 0.2560f, 1.0000f, 0.3162f, 0.1000f, 0.5012f, 0.1300f, 0.4100f, 0.4600f, 0.7943f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 1.5849f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 10268.2002f, 251.0000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_DRIVING_FULLGRANDSTAND \ - { 1.0000f, 1.0000f, 0.3162f, 0.2818f, 0.6310f, 3.0100f, 1.3700f, 1.2800f, 0.3548f, 0.0900f, { 0.0000f, 0.0000f, 0.0000f }, 0.1778f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 10420.2002f, 250.0000f, 0.0000f, 0x0 } - -#define EFX_REVERB_PRESET_DRIVING_EMPTYGRANDSTAND \ - { 1.0000f, 1.0000f, 0.3162f, 1.0000f, 0.7943f, 4.6200f, 1.7500f, 1.4000f, 0.2082f, 0.0900f, { 0.0000f, 0.0000f, 0.0000f }, 0.2512f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 10420.2002f, 250.0000f, 0.0000f, 0x0 } - -#define EFX_REVERB_PRESET_DRIVING_TUNNEL \ - { 1.0000f, 0.8100f, 0.3162f, 0.3981f, 0.8913f, 3.4200f, 0.9400f, 1.3100f, 0.7079f, 0.0510f, { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0470f, { 0.0000f, 0.0000f, 0.0000f }, 0.2140f, 0.0500f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 155.3000f, 0.0000f, 0x1 } +#define EFX_REVERB_PRESET_DRIVING_COMMENTATOR \ + { \ + 1.0000f, 0.0000f, 0.3162f, 0.5623f, 0.5012f, 2.4200f, 0.8800f, 0.6800f, 0.1995f, 0.0930f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.2512f, 0.0170f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, \ + 0.0000f, 0.9886f, 5000.0000f, 250.0000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_DRIVING_PITGARAGE \ + { \ + 0.4287f, 0.5900f, 0.3162f, 0.7079f, 0.5623f, 1.7200f, 0.9300f, 0.8700f, 0.5623f, 0.0000f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.1100f, 0.2500f, \ + 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 \ + } + +#define EFX_REVERB_PRESET_DRIVING_INCAR_RACER \ + { \ + 0.0832f, 0.8000f, 0.3162f, 1.0000f, 0.7943f, 0.1700f, 2.0000f, 0.4100f, 1.7783f, 0.0070f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0150f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 10268.2002f, 251.0000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_DRIVING_INCAR_SPORTS \ + { \ + 0.0832f, 0.8000f, 0.3162f, 0.6310f, 1.0000f, 0.1700f, 0.7500f, 0.4100f, 1.0000f, 0.0100f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.5623f, 0.0000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 10268.2002f, 251.0000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_DRIVING_INCAR_LUXURY \ + { \ + 0.2560f, 1.0000f, 0.3162f, 0.1000f, 0.5012f, 0.1300f, 0.4100f, 0.4600f, 0.7943f, 0.0100f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.5849f, 0.0100f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 10268.2002f, 251.0000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_DRIVING_FULLGRANDSTAND \ + { \ + 1.0000f, 1.0000f, 0.3162f, 0.2818f, 0.6310f, 3.0100f, 1.3700f, 1.2800f, 0.3548f, 0.0900f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.1778f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 10420.2002f, 250.0000f, 0.0000f, 0x0 \ + } + +#define EFX_REVERB_PRESET_DRIVING_EMPTYGRANDSTAND \ + { \ + 1.0000f, 1.0000f, 0.3162f, 1.0000f, 0.7943f, 4.6200f, 1.7500f, 1.4000f, 0.2082f, 0.0900f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.2512f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.0000f, 0.9943f, 10420.2002f, 250.0000f, 0.0000f, 0x0 \ + } + +#define EFX_REVERB_PRESET_DRIVING_TUNNEL \ + { \ + 1.0000f, 0.8100f, 0.3162f, 0.3981f, 0.8913f, 3.4200f, 0.9400f, 1.3100f, 0.7079f, 0.0510f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.7079f, 0.0470f, { 0.0000f, 0.0000f, 0.0000f }, 0.2140f, 0.0500f, 0.2500f, \ + 0.0000f, 0.9943f, 5000.0000f, 155.3000f, 0.0000f, 0x1 \ + } /* City Presets */ -#define EFX_REVERB_PRESET_CITY_STREETS \ - { 1.0000f, 0.7800f, 0.3162f, 0.7079f, 0.8913f, 1.7900f, 1.1200f, 0.9100f, 0.2818f, 0.0460f, { 0.0000f, 0.0000f, 0.0000f }, 0.1995f, 0.0280f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_CITY_SUBWAY \ - { 1.0000f, 0.7400f, 0.3162f, 0.7079f, 0.8913f, 3.0100f, 1.2300f, 0.9100f, 0.7079f, 0.0460f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0280f, { 0.0000f, 0.0000f, 0.0000f }, 0.1250f, 0.2100f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_CITY_MUSEUM \ - { 1.0000f, 0.8200f, 0.3162f, 0.1778f, 0.1778f, 3.2800f, 1.4000f, 0.5700f, 0.2512f, 0.0390f, { 0.0000f, 0.0000f, -0.0000f }, 0.8913f, 0.0340f, { 0.0000f, 0.0000f, 0.0000f }, 0.1300f, 0.1700f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 107.5000f, 0.0000f, 0x0 } - -#define EFX_REVERB_PRESET_CITY_LIBRARY \ - { 1.0000f, 0.8200f, 0.3162f, 0.2818f, 0.0891f, 2.7600f, 0.8900f, 0.4100f, 0.3548f, 0.0290f, { 0.0000f, 0.0000f, -0.0000f }, 0.8913f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.1300f, 0.1700f, 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 107.5000f, 0.0000f, 0x0 } - -#define EFX_REVERB_PRESET_CITY_UNDERPASS \ - { 1.0000f, 0.8200f, 0.3162f, 0.4467f, 0.8913f, 3.5700f, 1.1200f, 0.9100f, 0.3981f, 0.0590f, { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0370f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.1400f, 0.2500f, 0.0000f, 0.9920f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_CITY_ABANDONED \ - { 1.0000f, 0.6900f, 0.3162f, 0.7943f, 0.8913f, 3.2800f, 1.1700f, 0.9100f, 0.4467f, 0.0440f, { 0.0000f, 0.0000f, 0.0000f }, 0.2818f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2000f, 0.2500f, 0.0000f, 0.9966f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } +#define EFX_REVERB_PRESET_CITY_STREETS \ + { \ + 1.0000f, 0.7800f, 0.3162f, 0.7079f, 0.8913f, 1.7900f, 1.1200f, 0.9100f, 0.2818f, 0.0460f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.1995f, 0.0280f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2000f, 0.2500f, \ + 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_CITY_SUBWAY \ + { \ + 1.0000f, 0.7400f, 0.3162f, 0.7079f, 0.8913f, 3.0100f, 1.2300f, 0.9100f, 0.7079f, 0.0460f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0280f, { 0.0000f, 0.0000f, 0.0000f }, 0.1250f, 0.2100f, 0.2500f, \ + 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_CITY_MUSEUM \ + { \ + 1.0000f, 0.8200f, 0.3162f, 0.1778f, 0.1778f, 3.2800f, 1.4000f, 0.5700f, 0.2512f, 0.0390f, \ + { 0.0000f, 0.0000f, -0.0000f }, 0.8913f, 0.0340f, { 0.0000f, 0.0000f, 0.0000f }, 0.1300f, 0.1700f, \ + 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 107.5000f, 0.0000f, 0x0 \ + } + +#define EFX_REVERB_PRESET_CITY_LIBRARY \ + { \ + 1.0000f, 0.8200f, 0.3162f, 0.2818f, 0.0891f, 2.7600f, 0.8900f, 0.4100f, 0.3548f, 0.0290f, \ + { 0.0000f, 0.0000f, -0.0000f }, 0.8913f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.1300f, 0.1700f, \ + 0.2500f, 0.0000f, 0.9943f, 2854.3999f, 107.5000f, 0.0000f, 0x0 \ + } + +#define EFX_REVERB_PRESET_CITY_UNDERPASS \ + { \ + 1.0000f, 0.8200f, 0.3162f, 0.4467f, 0.8913f, 3.5700f, 1.1200f, 0.9100f, 0.3981f, 0.0590f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.8913f, 0.0370f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.1400f, 0.2500f, \ + 0.0000f, 0.9920f, 5000.0000f, 250.0000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_CITY_ABANDONED \ + { \ + 1.0000f, 0.6900f, 0.3162f, 0.7943f, 0.8913f, 3.2800f, 1.1700f, 0.9100f, 0.4467f, 0.0440f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.2818f, 0.0240f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.2000f, 0.2500f, \ + 0.0000f, 0.9966f, 5000.0000f, 250.0000f, 0.0000f, 0x1 \ + } /* Misc. Presets */ -#define EFX_REVERB_PRESET_DUSTYROOM \ - { 0.3645f, 0.5600f, 0.3162f, 0.7943f, 0.7079f, 1.7900f, 0.3800f, 0.2100f, 0.5012f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0060f, { 0.0000f, 0.0000f, 0.0000f }, 0.2020f, 0.0500f, 0.2500f, 0.0000f, 0.9886f, 13046.0000f, 163.3000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_CHAPEL \ - { 1.0000f, 0.8400f, 0.3162f, 0.5623f, 1.0000f, 4.6200f, 0.6400f, 1.2300f, 0.4467f, 0.0320f, { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.1100f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } - -#define EFX_REVERB_PRESET_SMALLWATERROOM \ - { 1.0000f, 0.7000f, 0.3162f, 0.4477f, 1.0000f, 1.5100f, 1.2500f, 1.1400f, 0.8913f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.1790f, 0.1500f, 0.8950f, 0.1900f, 0.9920f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } +#define EFX_REVERB_PRESET_DUSTYROOM \ + { \ + 0.3645f, 0.5600f, 0.3162f, 0.7943f, 0.7079f, 1.7900f, 0.3800f, 0.2100f, 0.5012f, 0.0020f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0060f, { 0.0000f, 0.0000f, 0.0000f }, 0.2020f, 0.0500f, 0.2500f, \ + 0.0000f, 0.9886f, 13046.0000f, 163.3000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_CHAPEL \ + { \ + 1.0000f, 0.8400f, 0.3162f, 0.5623f, 1.0000f, 4.6200f, 0.6400f, 1.2300f, 0.4467f, 0.0320f, \ + { 0.0000f, 0.0000f, 0.0000f }, 0.7943f, 0.0490f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, \ + 0.1100f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 \ + } + +#define EFX_REVERB_PRESET_SMALLWATERROOM \ + { \ + 1.0000f, 0.7000f, 0.3162f, 0.4477f, 1.0000f, 1.5100f, 1.2500f, 1.1400f, 0.8913f, 0.0200f, \ + { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.1790f, 0.1500f, 0.8950f, \ + 0.1900f, 0.9920f, 5000.0000f, 250.0000f, 0.0000f, 0x0 \ + } #endif /* EFX_PRESETS_H */ diff --git a/apps/openmw/mwsound/efx.h b/apps/openmw/mwsound/efx.h index 57766983f6..83c827f885 100644 --- a/apps/openmw/mwsound/efx.h +++ b/apps/openmw/mwsound/efx.h @@ -1,761 +1,753 @@ #ifndef AL_EFX_H #define AL_EFX_H - -#include "alc.h" #include "al.h" +#include "alc.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -#define ALC_EXT_EFX_NAME "ALC_EXT_EFX" - -#define ALC_EFX_MAJOR_VERSION 0x20001 -#define ALC_EFX_MINOR_VERSION 0x20002 -#define ALC_MAX_AUXILIARY_SENDS 0x20003 +#define ALC_EXT_EFX_NAME "ALC_EXT_EFX" +#define ALC_EFX_MAJOR_VERSION 0x20001 +#define ALC_EFX_MINOR_VERSION 0x20002 +#define ALC_MAX_AUXILIARY_SENDS 0x20003 /* Listener properties. */ -#define AL_METERS_PER_UNIT 0x20004 +#define AL_METERS_PER_UNIT 0x20004 /* Source properties. */ -#define AL_DIRECT_FILTER 0x20005 -#define AL_AUXILIARY_SEND_FILTER 0x20006 -#define AL_AIR_ABSORPTION_FACTOR 0x20007 -#define AL_ROOM_ROLLOFF_FACTOR 0x20008 -#define AL_CONE_OUTER_GAINHF 0x20009 -#define AL_DIRECT_FILTER_GAINHF_AUTO 0x2000A -#define AL_AUXILIARY_SEND_FILTER_GAIN_AUTO 0x2000B -#define AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO 0x2000C - +#define AL_DIRECT_FILTER 0x20005 +#define AL_AUXILIARY_SEND_FILTER 0x20006 +#define AL_AIR_ABSORPTION_FACTOR 0x20007 +#define AL_ROOM_ROLLOFF_FACTOR 0x20008 +#define AL_CONE_OUTER_GAINHF 0x20009 +#define AL_DIRECT_FILTER_GAINHF_AUTO 0x2000A +#define AL_AUXILIARY_SEND_FILTER_GAIN_AUTO 0x2000B +#define AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO 0x2000C /* Effect properties. */ /* Reverb effect parameters */ -#define AL_REVERB_DENSITY 0x0001 -#define AL_REVERB_DIFFUSION 0x0002 -#define AL_REVERB_GAIN 0x0003 -#define AL_REVERB_GAINHF 0x0004 -#define AL_REVERB_DECAY_TIME 0x0005 -#define AL_REVERB_DECAY_HFRATIO 0x0006 -#define AL_REVERB_REFLECTIONS_GAIN 0x0007 -#define AL_REVERB_REFLECTIONS_DELAY 0x0008 -#define AL_REVERB_LATE_REVERB_GAIN 0x0009 -#define AL_REVERB_LATE_REVERB_DELAY 0x000A -#define AL_REVERB_AIR_ABSORPTION_GAINHF 0x000B -#define AL_REVERB_ROOM_ROLLOFF_FACTOR 0x000C -#define AL_REVERB_DECAY_HFLIMIT 0x000D +#define AL_REVERB_DENSITY 0x0001 +#define AL_REVERB_DIFFUSION 0x0002 +#define AL_REVERB_GAIN 0x0003 +#define AL_REVERB_GAINHF 0x0004 +#define AL_REVERB_DECAY_TIME 0x0005 +#define AL_REVERB_DECAY_HFRATIO 0x0006 +#define AL_REVERB_REFLECTIONS_GAIN 0x0007 +#define AL_REVERB_REFLECTIONS_DELAY 0x0008 +#define AL_REVERB_LATE_REVERB_GAIN 0x0009 +#define AL_REVERB_LATE_REVERB_DELAY 0x000A +#define AL_REVERB_AIR_ABSORPTION_GAINHF 0x000B +#define AL_REVERB_ROOM_ROLLOFF_FACTOR 0x000C +#define AL_REVERB_DECAY_HFLIMIT 0x000D /* EAX Reverb effect parameters */ -#define AL_EAXREVERB_DENSITY 0x0001 -#define AL_EAXREVERB_DIFFUSION 0x0002 -#define AL_EAXREVERB_GAIN 0x0003 -#define AL_EAXREVERB_GAINHF 0x0004 -#define AL_EAXREVERB_GAINLF 0x0005 -#define AL_EAXREVERB_DECAY_TIME 0x0006 -#define AL_EAXREVERB_DECAY_HFRATIO 0x0007 -#define AL_EAXREVERB_DECAY_LFRATIO 0x0008 -#define AL_EAXREVERB_REFLECTIONS_GAIN 0x0009 -#define AL_EAXREVERB_REFLECTIONS_DELAY 0x000A -#define AL_EAXREVERB_REFLECTIONS_PAN 0x000B -#define AL_EAXREVERB_LATE_REVERB_GAIN 0x000C -#define AL_EAXREVERB_LATE_REVERB_DELAY 0x000D -#define AL_EAXREVERB_LATE_REVERB_PAN 0x000E -#define AL_EAXREVERB_ECHO_TIME 0x000F -#define AL_EAXREVERB_ECHO_DEPTH 0x0010 -#define AL_EAXREVERB_MODULATION_TIME 0x0011 -#define AL_EAXREVERB_MODULATION_DEPTH 0x0012 -#define AL_EAXREVERB_AIR_ABSORPTION_GAINHF 0x0013 -#define AL_EAXREVERB_HFREFERENCE 0x0014 -#define AL_EAXREVERB_LFREFERENCE 0x0015 -#define AL_EAXREVERB_ROOM_ROLLOFF_FACTOR 0x0016 -#define AL_EAXREVERB_DECAY_HFLIMIT 0x0017 +#define AL_EAXREVERB_DENSITY 0x0001 +#define AL_EAXREVERB_DIFFUSION 0x0002 +#define AL_EAXREVERB_GAIN 0x0003 +#define AL_EAXREVERB_GAINHF 0x0004 +#define AL_EAXREVERB_GAINLF 0x0005 +#define AL_EAXREVERB_DECAY_TIME 0x0006 +#define AL_EAXREVERB_DECAY_HFRATIO 0x0007 +#define AL_EAXREVERB_DECAY_LFRATIO 0x0008 +#define AL_EAXREVERB_REFLECTIONS_GAIN 0x0009 +#define AL_EAXREVERB_REFLECTIONS_DELAY 0x000A +#define AL_EAXREVERB_REFLECTIONS_PAN 0x000B +#define AL_EAXREVERB_LATE_REVERB_GAIN 0x000C +#define AL_EAXREVERB_LATE_REVERB_DELAY 0x000D +#define AL_EAXREVERB_LATE_REVERB_PAN 0x000E +#define AL_EAXREVERB_ECHO_TIME 0x000F +#define AL_EAXREVERB_ECHO_DEPTH 0x0010 +#define AL_EAXREVERB_MODULATION_TIME 0x0011 +#define AL_EAXREVERB_MODULATION_DEPTH 0x0012 +#define AL_EAXREVERB_AIR_ABSORPTION_GAINHF 0x0013 +#define AL_EAXREVERB_HFREFERENCE 0x0014 +#define AL_EAXREVERB_LFREFERENCE 0x0015 +#define AL_EAXREVERB_ROOM_ROLLOFF_FACTOR 0x0016 +#define AL_EAXREVERB_DECAY_HFLIMIT 0x0017 /* Chorus effect parameters */ -#define AL_CHORUS_WAVEFORM 0x0001 -#define AL_CHORUS_PHASE 0x0002 -#define AL_CHORUS_RATE 0x0003 -#define AL_CHORUS_DEPTH 0x0004 -#define AL_CHORUS_FEEDBACK 0x0005 -#define AL_CHORUS_DELAY 0x0006 +#define AL_CHORUS_WAVEFORM 0x0001 +#define AL_CHORUS_PHASE 0x0002 +#define AL_CHORUS_RATE 0x0003 +#define AL_CHORUS_DEPTH 0x0004 +#define AL_CHORUS_FEEDBACK 0x0005 +#define AL_CHORUS_DELAY 0x0006 /* Distortion effect parameters */ -#define AL_DISTORTION_EDGE 0x0001 -#define AL_DISTORTION_GAIN 0x0002 -#define AL_DISTORTION_LOWPASS_CUTOFF 0x0003 -#define AL_DISTORTION_EQCENTER 0x0004 -#define AL_DISTORTION_EQBANDWIDTH 0x0005 +#define AL_DISTORTION_EDGE 0x0001 +#define AL_DISTORTION_GAIN 0x0002 +#define AL_DISTORTION_LOWPASS_CUTOFF 0x0003 +#define AL_DISTORTION_EQCENTER 0x0004 +#define AL_DISTORTION_EQBANDWIDTH 0x0005 /* Echo effect parameters */ -#define AL_ECHO_DELAY 0x0001 -#define AL_ECHO_LRDELAY 0x0002 -#define AL_ECHO_DAMPING 0x0003 -#define AL_ECHO_FEEDBACK 0x0004 -#define AL_ECHO_SPREAD 0x0005 +#define AL_ECHO_DELAY 0x0001 +#define AL_ECHO_LRDELAY 0x0002 +#define AL_ECHO_DAMPING 0x0003 +#define AL_ECHO_FEEDBACK 0x0004 +#define AL_ECHO_SPREAD 0x0005 /* Flanger effect parameters */ -#define AL_FLANGER_WAVEFORM 0x0001 -#define AL_FLANGER_PHASE 0x0002 -#define AL_FLANGER_RATE 0x0003 -#define AL_FLANGER_DEPTH 0x0004 -#define AL_FLANGER_FEEDBACK 0x0005 -#define AL_FLANGER_DELAY 0x0006 +#define AL_FLANGER_WAVEFORM 0x0001 +#define AL_FLANGER_PHASE 0x0002 +#define AL_FLANGER_RATE 0x0003 +#define AL_FLANGER_DEPTH 0x0004 +#define AL_FLANGER_FEEDBACK 0x0005 +#define AL_FLANGER_DELAY 0x0006 /* Frequency shifter effect parameters */ -#define AL_FREQUENCY_SHIFTER_FREQUENCY 0x0001 -#define AL_FREQUENCY_SHIFTER_LEFT_DIRECTION 0x0002 -#define AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION 0x0003 +#define AL_FREQUENCY_SHIFTER_FREQUENCY 0x0001 +#define AL_FREQUENCY_SHIFTER_LEFT_DIRECTION 0x0002 +#define AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION 0x0003 /* Vocal morpher effect parameters */ -#define AL_VOCAL_MORPHER_PHONEMEA 0x0001 -#define AL_VOCAL_MORPHER_PHONEMEA_COARSE_TUNING 0x0002 -#define AL_VOCAL_MORPHER_PHONEMEB 0x0003 -#define AL_VOCAL_MORPHER_PHONEMEB_COARSE_TUNING 0x0004 -#define AL_VOCAL_MORPHER_WAVEFORM 0x0005 -#define AL_VOCAL_MORPHER_RATE 0x0006 +#define AL_VOCAL_MORPHER_PHONEMEA 0x0001 +#define AL_VOCAL_MORPHER_PHONEMEA_COARSE_TUNING 0x0002 +#define AL_VOCAL_MORPHER_PHONEMEB 0x0003 +#define AL_VOCAL_MORPHER_PHONEMEB_COARSE_TUNING 0x0004 +#define AL_VOCAL_MORPHER_WAVEFORM 0x0005 +#define AL_VOCAL_MORPHER_RATE 0x0006 /* Pitchshifter effect parameters */ -#define AL_PITCH_SHIFTER_COARSE_TUNE 0x0001 -#define AL_PITCH_SHIFTER_FINE_TUNE 0x0002 +#define AL_PITCH_SHIFTER_COARSE_TUNE 0x0001 +#define AL_PITCH_SHIFTER_FINE_TUNE 0x0002 /* Ringmodulator effect parameters */ -#define AL_RING_MODULATOR_FREQUENCY 0x0001 -#define AL_RING_MODULATOR_HIGHPASS_CUTOFF 0x0002 -#define AL_RING_MODULATOR_WAVEFORM 0x0003 +#define AL_RING_MODULATOR_FREQUENCY 0x0001 +#define AL_RING_MODULATOR_HIGHPASS_CUTOFF 0x0002 +#define AL_RING_MODULATOR_WAVEFORM 0x0003 /* Autowah effect parameters */ -#define AL_AUTOWAH_ATTACK_TIME 0x0001 -#define AL_AUTOWAH_RELEASE_TIME 0x0002 -#define AL_AUTOWAH_RESONANCE 0x0003 -#define AL_AUTOWAH_PEAK_GAIN 0x0004 +#define AL_AUTOWAH_ATTACK_TIME 0x0001 +#define AL_AUTOWAH_RELEASE_TIME 0x0002 +#define AL_AUTOWAH_RESONANCE 0x0003 +#define AL_AUTOWAH_PEAK_GAIN 0x0004 /* Compressor effect parameters */ -#define AL_COMPRESSOR_ONOFF 0x0001 +#define AL_COMPRESSOR_ONOFF 0x0001 /* Equalizer effect parameters */ -#define AL_EQUALIZER_LOW_GAIN 0x0001 -#define AL_EQUALIZER_LOW_CUTOFF 0x0002 -#define AL_EQUALIZER_MID1_GAIN 0x0003 -#define AL_EQUALIZER_MID1_CENTER 0x0004 -#define AL_EQUALIZER_MID1_WIDTH 0x0005 -#define AL_EQUALIZER_MID2_GAIN 0x0006 -#define AL_EQUALIZER_MID2_CENTER 0x0007 -#define AL_EQUALIZER_MID2_WIDTH 0x0008 -#define AL_EQUALIZER_HIGH_GAIN 0x0009 -#define AL_EQUALIZER_HIGH_CUTOFF 0x000A +#define AL_EQUALIZER_LOW_GAIN 0x0001 +#define AL_EQUALIZER_LOW_CUTOFF 0x0002 +#define AL_EQUALIZER_MID1_GAIN 0x0003 +#define AL_EQUALIZER_MID1_CENTER 0x0004 +#define AL_EQUALIZER_MID1_WIDTH 0x0005 +#define AL_EQUALIZER_MID2_GAIN 0x0006 +#define AL_EQUALIZER_MID2_CENTER 0x0007 +#define AL_EQUALIZER_MID2_WIDTH 0x0008 +#define AL_EQUALIZER_HIGH_GAIN 0x0009 +#define AL_EQUALIZER_HIGH_CUTOFF 0x000A /* Effect type */ -#define AL_EFFECT_FIRST_PARAMETER 0x0000 -#define AL_EFFECT_LAST_PARAMETER 0x8000 -#define AL_EFFECT_TYPE 0x8001 +#define AL_EFFECT_FIRST_PARAMETER 0x0000 +#define AL_EFFECT_LAST_PARAMETER 0x8000 +#define AL_EFFECT_TYPE 0x8001 /* Effect types, used with the AL_EFFECT_TYPE property */ -#define AL_EFFECT_NULL 0x0000 -#define AL_EFFECT_REVERB 0x0001 -#define AL_EFFECT_CHORUS 0x0002 -#define AL_EFFECT_DISTORTION 0x0003 -#define AL_EFFECT_ECHO 0x0004 -#define AL_EFFECT_FLANGER 0x0005 -#define AL_EFFECT_FREQUENCY_SHIFTER 0x0006 -#define AL_EFFECT_VOCAL_MORPHER 0x0007 -#define AL_EFFECT_PITCH_SHIFTER 0x0008 -#define AL_EFFECT_RING_MODULATOR 0x0009 -#define AL_EFFECT_AUTOWAH 0x000A -#define AL_EFFECT_COMPRESSOR 0x000B -#define AL_EFFECT_EQUALIZER 0x000C -#define AL_EFFECT_EAXREVERB 0x8000 +#define AL_EFFECT_NULL 0x0000 +#define AL_EFFECT_REVERB 0x0001 +#define AL_EFFECT_CHORUS 0x0002 +#define AL_EFFECT_DISTORTION 0x0003 +#define AL_EFFECT_ECHO 0x0004 +#define AL_EFFECT_FLANGER 0x0005 +#define AL_EFFECT_FREQUENCY_SHIFTER 0x0006 +#define AL_EFFECT_VOCAL_MORPHER 0x0007 +#define AL_EFFECT_PITCH_SHIFTER 0x0008 +#define AL_EFFECT_RING_MODULATOR 0x0009 +#define AL_EFFECT_AUTOWAH 0x000A +#define AL_EFFECT_COMPRESSOR 0x000B +#define AL_EFFECT_EQUALIZER 0x000C +#define AL_EFFECT_EAXREVERB 0x8000 /* Auxiliary Effect Slot properties. */ -#define AL_EFFECTSLOT_EFFECT 0x0001 -#define AL_EFFECTSLOT_GAIN 0x0002 -#define AL_EFFECTSLOT_AUXILIARY_SEND_AUTO 0x0003 +#define AL_EFFECTSLOT_EFFECT 0x0001 +#define AL_EFFECTSLOT_GAIN 0x0002 +#define AL_EFFECTSLOT_AUXILIARY_SEND_AUTO 0x0003 /* NULL Auxiliary Slot ID to disable a source send. */ -#define AL_EFFECTSLOT_NULL 0x0000 - +#define AL_EFFECTSLOT_NULL 0x0000 /* Filter properties. */ /* Lowpass filter parameters */ -#define AL_LOWPASS_GAIN 0x0001 -#define AL_LOWPASS_GAINHF 0x0002 +#define AL_LOWPASS_GAIN 0x0001 +#define AL_LOWPASS_GAINHF 0x0002 /* Highpass filter parameters */ -#define AL_HIGHPASS_GAIN 0x0001 -#define AL_HIGHPASS_GAINLF 0x0002 +#define AL_HIGHPASS_GAIN 0x0001 +#define AL_HIGHPASS_GAINLF 0x0002 /* Bandpass filter parameters */ -#define AL_BANDPASS_GAIN 0x0001 -#define AL_BANDPASS_GAINLF 0x0002 -#define AL_BANDPASS_GAINHF 0x0003 +#define AL_BANDPASS_GAIN 0x0001 +#define AL_BANDPASS_GAINLF 0x0002 +#define AL_BANDPASS_GAINHF 0x0003 /* Filter type */ -#define AL_FILTER_FIRST_PARAMETER 0x0000 -#define AL_FILTER_LAST_PARAMETER 0x8000 -#define AL_FILTER_TYPE 0x8001 +#define AL_FILTER_FIRST_PARAMETER 0x0000 +#define AL_FILTER_LAST_PARAMETER 0x8000 +#define AL_FILTER_TYPE 0x8001 /* Filter types, used with the AL_FILTER_TYPE property */ -#define AL_FILTER_NULL 0x0000 -#define AL_FILTER_LOWPASS 0x0001 -#define AL_FILTER_HIGHPASS 0x0002 -#define AL_FILTER_BANDPASS 0x0003 - - -/* Effect object function types. */ -typedef void (AL_APIENTRY *LPALGENEFFECTS)(ALsizei, ALuint*); -typedef void (AL_APIENTRY *LPALDELETEEFFECTS)(ALsizei, const ALuint*); -typedef ALboolean (AL_APIENTRY *LPALISEFFECT)(ALuint); -typedef void (AL_APIENTRY *LPALEFFECTI)(ALuint, ALenum, ALint); -typedef void (AL_APIENTRY *LPALEFFECTIV)(ALuint, ALenum, const ALint*); -typedef void (AL_APIENTRY *LPALEFFECTF)(ALuint, ALenum, ALfloat); -typedef void (AL_APIENTRY *LPALEFFECTFV)(ALuint, ALenum, const ALfloat*); -typedef void (AL_APIENTRY *LPALGETEFFECTI)(ALuint, ALenum, ALint*); -typedef void (AL_APIENTRY *LPALGETEFFECTIV)(ALuint, ALenum, ALint*); -typedef void (AL_APIENTRY *LPALGETEFFECTF)(ALuint, ALenum, ALfloat*); -typedef void (AL_APIENTRY *LPALGETEFFECTFV)(ALuint, ALenum, ALfloat*); - -/* Filter object function types. */ -typedef void (AL_APIENTRY *LPALGENFILTERS)(ALsizei, ALuint*); -typedef void (AL_APIENTRY *LPALDELETEFILTERS)(ALsizei, const ALuint*); -typedef ALboolean (AL_APIENTRY *LPALISFILTER)(ALuint); -typedef void (AL_APIENTRY *LPALFILTERI)(ALuint, ALenum, ALint); -typedef void (AL_APIENTRY *LPALFILTERIV)(ALuint, ALenum, const ALint*); -typedef void (AL_APIENTRY *LPALFILTERF)(ALuint, ALenum, ALfloat); -typedef void (AL_APIENTRY *LPALFILTERFV)(ALuint, ALenum, const ALfloat*); -typedef void (AL_APIENTRY *LPALGETFILTERI)(ALuint, ALenum, ALint*); -typedef void (AL_APIENTRY *LPALGETFILTERIV)(ALuint, ALenum, ALint*); -typedef void (AL_APIENTRY *LPALGETFILTERF)(ALuint, ALenum, ALfloat*); -typedef void (AL_APIENTRY *LPALGETFILTERFV)(ALuint, ALenum, ALfloat*); - -/* Auxiliary Effect Slot object function types. */ -typedef void (AL_APIENTRY *LPALGENAUXILIARYEFFECTSLOTS)(ALsizei, ALuint*); -typedef void (AL_APIENTRY *LPALDELETEAUXILIARYEFFECTSLOTS)(ALsizei, const ALuint*); -typedef ALboolean (AL_APIENTRY *LPALISAUXILIARYEFFECTSLOT)(ALuint); -typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTI)(ALuint, ALenum, ALint); -typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTIV)(ALuint, ALenum, const ALint*); -typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTF)(ALuint, ALenum, ALfloat); -typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTFV)(ALuint, ALenum, const ALfloat*); -typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTI)(ALuint, ALenum, ALint*); -typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTIV)(ALuint, ALenum, ALint*); -typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTF)(ALuint, ALenum, ALfloat*); -typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTFV)(ALuint, ALenum, ALfloat*); +#define AL_FILTER_NULL 0x0000 +#define AL_FILTER_LOWPASS 0x0001 +#define AL_FILTER_HIGHPASS 0x0002 +#define AL_FILTER_BANDPASS 0x0003 + + /* Effect object function types. */ + typedef void(AL_APIENTRY* LPALGENEFFECTS)(ALsizei, ALuint*); + typedef void(AL_APIENTRY* LPALDELETEEFFECTS)(ALsizei, const ALuint*); + typedef ALboolean(AL_APIENTRY* LPALISEFFECT)(ALuint); + typedef void(AL_APIENTRY* LPALEFFECTI)(ALuint, ALenum, ALint); + typedef void(AL_APIENTRY* LPALEFFECTIV)(ALuint, ALenum, const ALint*); + typedef void(AL_APIENTRY* LPALEFFECTF)(ALuint, ALenum, ALfloat); + typedef void(AL_APIENTRY* LPALEFFECTFV)(ALuint, ALenum, const ALfloat*); + typedef void(AL_APIENTRY* LPALGETEFFECTI)(ALuint, ALenum, ALint*); + typedef void(AL_APIENTRY* LPALGETEFFECTIV)(ALuint, ALenum, ALint*); + typedef void(AL_APIENTRY* LPALGETEFFECTF)(ALuint, ALenum, ALfloat*); + typedef void(AL_APIENTRY* LPALGETEFFECTFV)(ALuint, ALenum, ALfloat*); + + /* Filter object function types. */ + typedef void(AL_APIENTRY* LPALGENFILTERS)(ALsizei, ALuint*); + typedef void(AL_APIENTRY* LPALDELETEFILTERS)(ALsizei, const ALuint*); + typedef ALboolean(AL_APIENTRY* LPALISFILTER)(ALuint); + typedef void(AL_APIENTRY* LPALFILTERI)(ALuint, ALenum, ALint); + typedef void(AL_APIENTRY* LPALFILTERIV)(ALuint, ALenum, const ALint*); + typedef void(AL_APIENTRY* LPALFILTERF)(ALuint, ALenum, ALfloat); + typedef void(AL_APIENTRY* LPALFILTERFV)(ALuint, ALenum, const ALfloat*); + typedef void(AL_APIENTRY* LPALGETFILTERI)(ALuint, ALenum, ALint*); + typedef void(AL_APIENTRY* LPALGETFILTERIV)(ALuint, ALenum, ALint*); + typedef void(AL_APIENTRY* LPALGETFILTERF)(ALuint, ALenum, ALfloat*); + typedef void(AL_APIENTRY* LPALGETFILTERFV)(ALuint, ALenum, ALfloat*); + + /* Auxiliary Effect Slot object function types. */ + typedef void(AL_APIENTRY* LPALGENAUXILIARYEFFECTSLOTS)(ALsizei, ALuint*); + typedef void(AL_APIENTRY* LPALDELETEAUXILIARYEFFECTSLOTS)(ALsizei, const ALuint*); + typedef ALboolean(AL_APIENTRY* LPALISAUXILIARYEFFECTSLOT)(ALuint); + typedef void(AL_APIENTRY* LPALAUXILIARYEFFECTSLOTI)(ALuint, ALenum, ALint); + typedef void(AL_APIENTRY* LPALAUXILIARYEFFECTSLOTIV)(ALuint, ALenum, const ALint*); + typedef void(AL_APIENTRY* LPALAUXILIARYEFFECTSLOTF)(ALuint, ALenum, ALfloat); + typedef void(AL_APIENTRY* LPALAUXILIARYEFFECTSLOTFV)(ALuint, ALenum, const ALfloat*); + typedef void(AL_APIENTRY* LPALGETAUXILIARYEFFECTSLOTI)(ALuint, ALenum, ALint*); + typedef void(AL_APIENTRY* LPALGETAUXILIARYEFFECTSLOTIV)(ALuint, ALenum, ALint*); + typedef void(AL_APIENTRY* LPALGETAUXILIARYEFFECTSLOTF)(ALuint, ALenum, ALfloat*); + typedef void(AL_APIENTRY* LPALGETAUXILIARYEFFECTSLOTFV)(ALuint, ALenum, ALfloat*); #ifdef AL_ALEXT_PROTOTYPES -AL_API ALvoid AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects); -AL_API ALvoid AL_APIENTRY alDeleteEffects(ALsizei n, const ALuint *effects); -AL_API ALboolean AL_APIENTRY alIsEffect(ALuint effect); -AL_API ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint iValue); -AL_API ALvoid AL_APIENTRY alEffectiv(ALuint effect, ALenum param, const ALint *piValues); -AL_API ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat flValue); -AL_API ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, const ALfloat *pflValues); -AL_API ALvoid AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *piValue); -AL_API ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *piValues); -AL_API ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *pflValue); -AL_API ALvoid AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *pflValues); - -AL_API ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters); -AL_API ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, const ALuint *filters); -AL_API ALboolean AL_APIENTRY alIsFilter(ALuint filter); -AL_API ALvoid AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint iValue); -AL_API ALvoid AL_APIENTRY alFilteriv(ALuint filter, ALenum param, const ALint *piValues); -AL_API ALvoid AL_APIENTRY alFilterf(ALuint filter, ALenum param, ALfloat flValue); -AL_API ALvoid AL_APIENTRY alFilterfv(ALuint filter, ALenum param, const ALfloat *pflValues); -AL_API ALvoid AL_APIENTRY alGetFilteri(ALuint filter, ALenum param, ALint *piValue); -AL_API ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *piValues); -AL_API ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *pflValue); -AL_API ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *pflValues); - -AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots); -AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint *effectslots); -AL_API ALboolean AL_APIENTRY alIsAuxiliaryEffectSlot(ALuint effectslot); -AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint iValue); -AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, const ALint *piValues); -AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat flValue); -AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, const ALfloat *pflValues); -AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint *piValue); -AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, ALint *piValues); -AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat *pflValue); -AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, ALfloat *pflValues); + AL_API ALvoid AL_APIENTRY alGenEffects(ALsizei n, ALuint* effects); + AL_API ALvoid AL_APIENTRY alDeleteEffects(ALsizei n, const ALuint* effects); + AL_API ALboolean AL_APIENTRY alIsEffect(ALuint effect); + AL_API ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint iValue); + AL_API ALvoid AL_APIENTRY alEffectiv(ALuint effect, ALenum param, const ALint* piValues); + AL_API ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat flValue); + AL_API ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, const ALfloat* pflValues); + AL_API ALvoid AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint* piValue); + AL_API ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint* piValues); + AL_API ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat* pflValue); + AL_API ALvoid AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat* pflValues); + + AL_API ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint* filters); + AL_API ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, const ALuint* filters); + AL_API ALboolean AL_APIENTRY alIsFilter(ALuint filter); + AL_API ALvoid AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint iValue); + AL_API ALvoid AL_APIENTRY alFilteriv(ALuint filter, ALenum param, const ALint* piValues); + AL_API ALvoid AL_APIENTRY alFilterf(ALuint filter, ALenum param, ALfloat flValue); + AL_API ALvoid AL_APIENTRY alFilterfv(ALuint filter, ALenum param, const ALfloat* pflValues); + AL_API ALvoid AL_APIENTRY alGetFilteri(ALuint filter, ALenum param, ALint* piValue); + AL_API ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint* piValues); + AL_API ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat* pflValue); + AL_API ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat* pflValues); + + AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint* effectslots); + AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint* effectslots); + AL_API ALboolean AL_APIENTRY alIsAuxiliaryEffectSlot(ALuint effectslot); + AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint iValue); + AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, const ALint* piValues); + AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat flValue); + AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, const ALfloat* pflValues); + AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint* piValue); + AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, ALint* piValues); + AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat* pflValue); + AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, ALfloat* pflValues); #endif /* Filter ranges and defaults. */ /* Lowpass filter */ -#define AL_LOWPASS_MIN_GAIN (0.0f) -#define AL_LOWPASS_MAX_GAIN (1.0f) -#define AL_LOWPASS_DEFAULT_GAIN (1.0f) +#define AL_LOWPASS_MIN_GAIN (0.0f) +#define AL_LOWPASS_MAX_GAIN (1.0f) +#define AL_LOWPASS_DEFAULT_GAIN (1.0f) -#define AL_LOWPASS_MIN_GAINHF (0.0f) -#define AL_LOWPASS_MAX_GAINHF (1.0f) -#define AL_LOWPASS_DEFAULT_GAINHF (1.0f) +#define AL_LOWPASS_MIN_GAINHF (0.0f) +#define AL_LOWPASS_MAX_GAINHF (1.0f) +#define AL_LOWPASS_DEFAULT_GAINHF (1.0f) /* Highpass filter */ -#define AL_HIGHPASS_MIN_GAIN (0.0f) -#define AL_HIGHPASS_MAX_GAIN (1.0f) -#define AL_HIGHPASS_DEFAULT_GAIN (1.0f) +#define AL_HIGHPASS_MIN_GAIN (0.0f) +#define AL_HIGHPASS_MAX_GAIN (1.0f) +#define AL_HIGHPASS_DEFAULT_GAIN (1.0f) -#define AL_HIGHPASS_MIN_GAINLF (0.0f) -#define AL_HIGHPASS_MAX_GAINLF (1.0f) -#define AL_HIGHPASS_DEFAULT_GAINLF (1.0f) +#define AL_HIGHPASS_MIN_GAINLF (0.0f) +#define AL_HIGHPASS_MAX_GAINLF (1.0f) +#define AL_HIGHPASS_DEFAULT_GAINLF (1.0f) /* Bandpass filter */ -#define AL_BANDPASS_MIN_GAIN (0.0f) -#define AL_BANDPASS_MAX_GAIN (1.0f) -#define AL_BANDPASS_DEFAULT_GAIN (1.0f) - -#define AL_BANDPASS_MIN_GAINHF (0.0f) -#define AL_BANDPASS_MAX_GAINHF (1.0f) -#define AL_BANDPASS_DEFAULT_GAINHF (1.0f) +#define AL_BANDPASS_MIN_GAIN (0.0f) +#define AL_BANDPASS_MAX_GAIN (1.0f) +#define AL_BANDPASS_DEFAULT_GAIN (1.0f) -#define AL_BANDPASS_MIN_GAINLF (0.0f) -#define AL_BANDPASS_MAX_GAINLF (1.0f) -#define AL_BANDPASS_DEFAULT_GAINLF (1.0f) +#define AL_BANDPASS_MIN_GAINHF (0.0f) +#define AL_BANDPASS_MAX_GAINHF (1.0f) +#define AL_BANDPASS_DEFAULT_GAINHF (1.0f) +#define AL_BANDPASS_MIN_GAINLF (0.0f) +#define AL_BANDPASS_MAX_GAINLF (1.0f) +#define AL_BANDPASS_DEFAULT_GAINLF (1.0f) /* Effect parameter ranges and defaults. */ /* Standard reverb effect */ -#define AL_REVERB_MIN_DENSITY (0.0f) -#define AL_REVERB_MAX_DENSITY (1.0f) -#define AL_REVERB_DEFAULT_DENSITY (1.0f) +#define AL_REVERB_MIN_DENSITY (0.0f) +#define AL_REVERB_MAX_DENSITY (1.0f) +#define AL_REVERB_DEFAULT_DENSITY (1.0f) -#define AL_REVERB_MIN_DIFFUSION (0.0f) -#define AL_REVERB_MAX_DIFFUSION (1.0f) -#define AL_REVERB_DEFAULT_DIFFUSION (1.0f) +#define AL_REVERB_MIN_DIFFUSION (0.0f) +#define AL_REVERB_MAX_DIFFUSION (1.0f) +#define AL_REVERB_DEFAULT_DIFFUSION (1.0f) -#define AL_REVERB_MIN_GAIN (0.0f) -#define AL_REVERB_MAX_GAIN (1.0f) -#define AL_REVERB_DEFAULT_GAIN (0.32f) +#define AL_REVERB_MIN_GAIN (0.0f) +#define AL_REVERB_MAX_GAIN (1.0f) +#define AL_REVERB_DEFAULT_GAIN (0.32f) -#define AL_REVERB_MIN_GAINHF (0.0f) -#define AL_REVERB_MAX_GAINHF (1.0f) -#define AL_REVERB_DEFAULT_GAINHF (0.89f) +#define AL_REVERB_MIN_GAINHF (0.0f) +#define AL_REVERB_MAX_GAINHF (1.0f) +#define AL_REVERB_DEFAULT_GAINHF (0.89f) -#define AL_REVERB_MIN_DECAY_TIME (0.1f) -#define AL_REVERB_MAX_DECAY_TIME (20.0f) -#define AL_REVERB_DEFAULT_DECAY_TIME (1.49f) +#define AL_REVERB_MIN_DECAY_TIME (0.1f) +#define AL_REVERB_MAX_DECAY_TIME (20.0f) +#define AL_REVERB_DEFAULT_DECAY_TIME (1.49f) -#define AL_REVERB_MIN_DECAY_HFRATIO (0.1f) -#define AL_REVERB_MAX_DECAY_HFRATIO (2.0f) -#define AL_REVERB_DEFAULT_DECAY_HFRATIO (0.83f) +#define AL_REVERB_MIN_DECAY_HFRATIO (0.1f) +#define AL_REVERB_MAX_DECAY_HFRATIO (2.0f) +#define AL_REVERB_DEFAULT_DECAY_HFRATIO (0.83f) -#define AL_REVERB_MIN_REFLECTIONS_GAIN (0.0f) -#define AL_REVERB_MAX_REFLECTIONS_GAIN (3.16f) -#define AL_REVERB_DEFAULT_REFLECTIONS_GAIN (0.05f) +#define AL_REVERB_MIN_REFLECTIONS_GAIN (0.0f) +#define AL_REVERB_MAX_REFLECTIONS_GAIN (3.16f) +#define AL_REVERB_DEFAULT_REFLECTIONS_GAIN (0.05f) -#define AL_REVERB_MIN_REFLECTIONS_DELAY (0.0f) -#define AL_REVERB_MAX_REFLECTIONS_DELAY (0.3f) -#define AL_REVERB_DEFAULT_REFLECTIONS_DELAY (0.007f) +#define AL_REVERB_MIN_REFLECTIONS_DELAY (0.0f) +#define AL_REVERB_MAX_REFLECTIONS_DELAY (0.3f) +#define AL_REVERB_DEFAULT_REFLECTIONS_DELAY (0.007f) -#define AL_REVERB_MIN_LATE_REVERB_GAIN (0.0f) -#define AL_REVERB_MAX_LATE_REVERB_GAIN (10.0f) -#define AL_REVERB_DEFAULT_LATE_REVERB_GAIN (1.26f) +#define AL_REVERB_MIN_LATE_REVERB_GAIN (0.0f) +#define AL_REVERB_MAX_LATE_REVERB_GAIN (10.0f) +#define AL_REVERB_DEFAULT_LATE_REVERB_GAIN (1.26f) -#define AL_REVERB_MIN_LATE_REVERB_DELAY (0.0f) -#define AL_REVERB_MAX_LATE_REVERB_DELAY (0.1f) -#define AL_REVERB_DEFAULT_LATE_REVERB_DELAY (0.011f) +#define AL_REVERB_MIN_LATE_REVERB_DELAY (0.0f) +#define AL_REVERB_MAX_LATE_REVERB_DELAY (0.1f) +#define AL_REVERB_DEFAULT_LATE_REVERB_DELAY (0.011f) -#define AL_REVERB_MIN_AIR_ABSORPTION_GAINHF (0.892f) -#define AL_REVERB_MAX_AIR_ABSORPTION_GAINHF (1.0f) -#define AL_REVERB_DEFAULT_AIR_ABSORPTION_GAINHF (0.994f) +#define AL_REVERB_MIN_AIR_ABSORPTION_GAINHF (0.892f) +#define AL_REVERB_MAX_AIR_ABSORPTION_GAINHF (1.0f) +#define AL_REVERB_DEFAULT_AIR_ABSORPTION_GAINHF (0.994f) -#define AL_REVERB_MIN_ROOM_ROLLOFF_FACTOR (0.0f) -#define AL_REVERB_MAX_ROOM_ROLLOFF_FACTOR (10.0f) -#define AL_REVERB_DEFAULT_ROOM_ROLLOFF_FACTOR (0.0f) +#define AL_REVERB_MIN_ROOM_ROLLOFF_FACTOR (0.0f) +#define AL_REVERB_MAX_ROOM_ROLLOFF_FACTOR (10.0f) +#define AL_REVERB_DEFAULT_ROOM_ROLLOFF_FACTOR (0.0f) -#define AL_REVERB_MIN_DECAY_HFLIMIT AL_FALSE -#define AL_REVERB_MAX_DECAY_HFLIMIT AL_TRUE -#define AL_REVERB_DEFAULT_DECAY_HFLIMIT AL_TRUE +#define AL_REVERB_MIN_DECAY_HFLIMIT AL_FALSE +#define AL_REVERB_MAX_DECAY_HFLIMIT AL_TRUE +#define AL_REVERB_DEFAULT_DECAY_HFLIMIT AL_TRUE /* EAX reverb effect */ -#define AL_EAXREVERB_MIN_DENSITY (0.0f) -#define AL_EAXREVERB_MAX_DENSITY (1.0f) -#define AL_EAXREVERB_DEFAULT_DENSITY (1.0f) +#define AL_EAXREVERB_MIN_DENSITY (0.0f) +#define AL_EAXREVERB_MAX_DENSITY (1.0f) +#define AL_EAXREVERB_DEFAULT_DENSITY (1.0f) -#define AL_EAXREVERB_MIN_DIFFUSION (0.0f) -#define AL_EAXREVERB_MAX_DIFFUSION (1.0f) -#define AL_EAXREVERB_DEFAULT_DIFFUSION (1.0f) +#define AL_EAXREVERB_MIN_DIFFUSION (0.0f) +#define AL_EAXREVERB_MAX_DIFFUSION (1.0f) +#define AL_EAXREVERB_DEFAULT_DIFFUSION (1.0f) -#define AL_EAXREVERB_MIN_GAIN (0.0f) -#define AL_EAXREVERB_MAX_GAIN (1.0f) -#define AL_EAXREVERB_DEFAULT_GAIN (0.32f) +#define AL_EAXREVERB_MIN_GAIN (0.0f) +#define AL_EAXREVERB_MAX_GAIN (1.0f) +#define AL_EAXREVERB_DEFAULT_GAIN (0.32f) -#define AL_EAXREVERB_MIN_GAINHF (0.0f) -#define AL_EAXREVERB_MAX_GAINHF (1.0f) -#define AL_EAXREVERB_DEFAULT_GAINHF (0.89f) +#define AL_EAXREVERB_MIN_GAINHF (0.0f) +#define AL_EAXREVERB_MAX_GAINHF (1.0f) +#define AL_EAXREVERB_DEFAULT_GAINHF (0.89f) -#define AL_EAXREVERB_MIN_GAINLF (0.0f) -#define AL_EAXREVERB_MAX_GAINLF (1.0f) -#define AL_EAXREVERB_DEFAULT_GAINLF (1.0f) +#define AL_EAXREVERB_MIN_GAINLF (0.0f) +#define AL_EAXREVERB_MAX_GAINLF (1.0f) +#define AL_EAXREVERB_DEFAULT_GAINLF (1.0f) -#define AL_EAXREVERB_MIN_DECAY_TIME (0.1f) -#define AL_EAXREVERB_MAX_DECAY_TIME (20.0f) -#define AL_EAXREVERB_DEFAULT_DECAY_TIME (1.49f) +#define AL_EAXREVERB_MIN_DECAY_TIME (0.1f) +#define AL_EAXREVERB_MAX_DECAY_TIME (20.0f) +#define AL_EAXREVERB_DEFAULT_DECAY_TIME (1.49f) -#define AL_EAXREVERB_MIN_DECAY_HFRATIO (0.1f) -#define AL_EAXREVERB_MAX_DECAY_HFRATIO (2.0f) -#define AL_EAXREVERB_DEFAULT_DECAY_HFRATIO (0.83f) +#define AL_EAXREVERB_MIN_DECAY_HFRATIO (0.1f) +#define AL_EAXREVERB_MAX_DECAY_HFRATIO (2.0f) +#define AL_EAXREVERB_DEFAULT_DECAY_HFRATIO (0.83f) -#define AL_EAXREVERB_MIN_DECAY_LFRATIO (0.1f) -#define AL_EAXREVERB_MAX_DECAY_LFRATIO (2.0f) -#define AL_EAXREVERB_DEFAULT_DECAY_LFRATIO (1.0f) +#define AL_EAXREVERB_MIN_DECAY_LFRATIO (0.1f) +#define AL_EAXREVERB_MAX_DECAY_LFRATIO (2.0f) +#define AL_EAXREVERB_DEFAULT_DECAY_LFRATIO (1.0f) -#define AL_EAXREVERB_MIN_REFLECTIONS_GAIN (0.0f) -#define AL_EAXREVERB_MAX_REFLECTIONS_GAIN (3.16f) -#define AL_EAXREVERB_DEFAULT_REFLECTIONS_GAIN (0.05f) +#define AL_EAXREVERB_MIN_REFLECTIONS_GAIN (0.0f) +#define AL_EAXREVERB_MAX_REFLECTIONS_GAIN (3.16f) +#define AL_EAXREVERB_DEFAULT_REFLECTIONS_GAIN (0.05f) -#define AL_EAXREVERB_MIN_REFLECTIONS_DELAY (0.0f) -#define AL_EAXREVERB_MAX_REFLECTIONS_DELAY (0.3f) -#define AL_EAXREVERB_DEFAULT_REFLECTIONS_DELAY (0.007f) +#define AL_EAXREVERB_MIN_REFLECTIONS_DELAY (0.0f) +#define AL_EAXREVERB_MAX_REFLECTIONS_DELAY (0.3f) +#define AL_EAXREVERB_DEFAULT_REFLECTIONS_DELAY (0.007f) #define AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ (0.0f) -#define AL_EAXREVERB_MIN_LATE_REVERB_GAIN (0.0f) -#define AL_EAXREVERB_MAX_LATE_REVERB_GAIN (10.0f) -#define AL_EAXREVERB_DEFAULT_LATE_REVERB_GAIN (1.26f) +#define AL_EAXREVERB_MIN_LATE_REVERB_GAIN (0.0f) +#define AL_EAXREVERB_MAX_LATE_REVERB_GAIN (10.0f) +#define AL_EAXREVERB_DEFAULT_LATE_REVERB_GAIN (1.26f) -#define AL_EAXREVERB_MIN_LATE_REVERB_DELAY (0.0f) -#define AL_EAXREVERB_MAX_LATE_REVERB_DELAY (0.1f) -#define AL_EAXREVERB_DEFAULT_LATE_REVERB_DELAY (0.011f) +#define AL_EAXREVERB_MIN_LATE_REVERB_DELAY (0.0f) +#define AL_EAXREVERB_MAX_LATE_REVERB_DELAY (0.1f) +#define AL_EAXREVERB_DEFAULT_LATE_REVERB_DELAY (0.011f) #define AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ (0.0f) -#define AL_EAXREVERB_MIN_ECHO_TIME (0.075f) -#define AL_EAXREVERB_MAX_ECHO_TIME (0.25f) -#define AL_EAXREVERB_DEFAULT_ECHO_TIME (0.25f) +#define AL_EAXREVERB_MIN_ECHO_TIME (0.075f) +#define AL_EAXREVERB_MAX_ECHO_TIME (0.25f) +#define AL_EAXREVERB_DEFAULT_ECHO_TIME (0.25f) -#define AL_EAXREVERB_MIN_ECHO_DEPTH (0.0f) -#define AL_EAXREVERB_MAX_ECHO_DEPTH (1.0f) -#define AL_EAXREVERB_DEFAULT_ECHO_DEPTH (0.0f) +#define AL_EAXREVERB_MIN_ECHO_DEPTH (0.0f) +#define AL_EAXREVERB_MAX_ECHO_DEPTH (1.0f) +#define AL_EAXREVERB_DEFAULT_ECHO_DEPTH (0.0f) -#define AL_EAXREVERB_MIN_MODULATION_TIME (0.04f) -#define AL_EAXREVERB_MAX_MODULATION_TIME (4.0f) -#define AL_EAXREVERB_DEFAULT_MODULATION_TIME (0.25f) +#define AL_EAXREVERB_MIN_MODULATION_TIME (0.04f) +#define AL_EAXREVERB_MAX_MODULATION_TIME (4.0f) +#define AL_EAXREVERB_DEFAULT_MODULATION_TIME (0.25f) -#define AL_EAXREVERB_MIN_MODULATION_DEPTH (0.0f) -#define AL_EAXREVERB_MAX_MODULATION_DEPTH (1.0f) -#define AL_EAXREVERB_DEFAULT_MODULATION_DEPTH (0.0f) +#define AL_EAXREVERB_MIN_MODULATION_DEPTH (0.0f) +#define AL_EAXREVERB_MAX_MODULATION_DEPTH (1.0f) +#define AL_EAXREVERB_DEFAULT_MODULATION_DEPTH (0.0f) -#define AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF (0.892f) -#define AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF (1.0f) +#define AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF (0.892f) +#define AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF (1.0f) #define AL_EAXREVERB_DEFAULT_AIR_ABSORPTION_GAINHF (0.994f) -#define AL_EAXREVERB_MIN_HFREFERENCE (1000.0f) -#define AL_EAXREVERB_MAX_HFREFERENCE (20000.0f) -#define AL_EAXREVERB_DEFAULT_HFREFERENCE (5000.0f) +#define AL_EAXREVERB_MIN_HFREFERENCE (1000.0f) +#define AL_EAXREVERB_MAX_HFREFERENCE (20000.0f) +#define AL_EAXREVERB_DEFAULT_HFREFERENCE (5000.0f) -#define AL_EAXREVERB_MIN_LFREFERENCE (20.0f) -#define AL_EAXREVERB_MAX_LFREFERENCE (1000.0f) -#define AL_EAXREVERB_DEFAULT_LFREFERENCE (250.0f) +#define AL_EAXREVERB_MIN_LFREFERENCE (20.0f) +#define AL_EAXREVERB_MAX_LFREFERENCE (1000.0f) +#define AL_EAXREVERB_DEFAULT_LFREFERENCE (250.0f) -#define AL_EAXREVERB_MIN_ROOM_ROLLOFF_FACTOR (0.0f) -#define AL_EAXREVERB_MAX_ROOM_ROLLOFF_FACTOR (10.0f) +#define AL_EAXREVERB_MIN_ROOM_ROLLOFF_FACTOR (0.0f) +#define AL_EAXREVERB_MAX_ROOM_ROLLOFF_FACTOR (10.0f) #define AL_EAXREVERB_DEFAULT_ROOM_ROLLOFF_FACTOR (0.0f) -#define AL_EAXREVERB_MIN_DECAY_HFLIMIT AL_FALSE -#define AL_EAXREVERB_MAX_DECAY_HFLIMIT AL_TRUE -#define AL_EAXREVERB_DEFAULT_DECAY_HFLIMIT AL_TRUE +#define AL_EAXREVERB_MIN_DECAY_HFLIMIT AL_FALSE +#define AL_EAXREVERB_MAX_DECAY_HFLIMIT AL_TRUE +#define AL_EAXREVERB_DEFAULT_DECAY_HFLIMIT AL_TRUE /* Chorus effect */ -#define AL_CHORUS_WAVEFORM_SINUSOID (0) -#define AL_CHORUS_WAVEFORM_TRIANGLE (1) +#define AL_CHORUS_WAVEFORM_SINUSOID (0) +#define AL_CHORUS_WAVEFORM_TRIANGLE (1) -#define AL_CHORUS_MIN_WAVEFORM (0) -#define AL_CHORUS_MAX_WAVEFORM (1) -#define AL_CHORUS_DEFAULT_WAVEFORM (1) +#define AL_CHORUS_MIN_WAVEFORM (0) +#define AL_CHORUS_MAX_WAVEFORM (1) +#define AL_CHORUS_DEFAULT_WAVEFORM (1) -#define AL_CHORUS_MIN_PHASE (-180) -#define AL_CHORUS_MAX_PHASE (180) -#define AL_CHORUS_DEFAULT_PHASE (90) +#define AL_CHORUS_MIN_PHASE (-180) +#define AL_CHORUS_MAX_PHASE (180) +#define AL_CHORUS_DEFAULT_PHASE (90) -#define AL_CHORUS_MIN_RATE (0.0f) -#define AL_CHORUS_MAX_RATE (10.0f) -#define AL_CHORUS_DEFAULT_RATE (1.1f) +#define AL_CHORUS_MIN_RATE (0.0f) +#define AL_CHORUS_MAX_RATE (10.0f) +#define AL_CHORUS_DEFAULT_RATE (1.1f) -#define AL_CHORUS_MIN_DEPTH (0.0f) -#define AL_CHORUS_MAX_DEPTH (1.0f) -#define AL_CHORUS_DEFAULT_DEPTH (0.1f) +#define AL_CHORUS_MIN_DEPTH (0.0f) +#define AL_CHORUS_MAX_DEPTH (1.0f) +#define AL_CHORUS_DEFAULT_DEPTH (0.1f) -#define AL_CHORUS_MIN_FEEDBACK (-1.0f) -#define AL_CHORUS_MAX_FEEDBACK (1.0f) -#define AL_CHORUS_DEFAULT_FEEDBACK (0.25f) +#define AL_CHORUS_MIN_FEEDBACK (-1.0f) +#define AL_CHORUS_MAX_FEEDBACK (1.0f) +#define AL_CHORUS_DEFAULT_FEEDBACK (0.25f) -#define AL_CHORUS_MIN_DELAY (0.0f) -#define AL_CHORUS_MAX_DELAY (0.016f) -#define AL_CHORUS_DEFAULT_DELAY (0.016f) +#define AL_CHORUS_MIN_DELAY (0.0f) +#define AL_CHORUS_MAX_DELAY (0.016f) +#define AL_CHORUS_DEFAULT_DELAY (0.016f) /* Distortion effect */ -#define AL_DISTORTION_MIN_EDGE (0.0f) -#define AL_DISTORTION_MAX_EDGE (1.0f) -#define AL_DISTORTION_DEFAULT_EDGE (0.2f) +#define AL_DISTORTION_MIN_EDGE (0.0f) +#define AL_DISTORTION_MAX_EDGE (1.0f) +#define AL_DISTORTION_DEFAULT_EDGE (0.2f) -#define AL_DISTORTION_MIN_GAIN (0.01f) -#define AL_DISTORTION_MAX_GAIN (1.0f) -#define AL_DISTORTION_DEFAULT_GAIN (0.05f) +#define AL_DISTORTION_MIN_GAIN (0.01f) +#define AL_DISTORTION_MAX_GAIN (1.0f) +#define AL_DISTORTION_DEFAULT_GAIN (0.05f) -#define AL_DISTORTION_MIN_LOWPASS_CUTOFF (80.0f) -#define AL_DISTORTION_MAX_LOWPASS_CUTOFF (24000.0f) -#define AL_DISTORTION_DEFAULT_LOWPASS_CUTOFF (8000.0f) +#define AL_DISTORTION_MIN_LOWPASS_CUTOFF (80.0f) +#define AL_DISTORTION_MAX_LOWPASS_CUTOFF (24000.0f) +#define AL_DISTORTION_DEFAULT_LOWPASS_CUTOFF (8000.0f) -#define AL_DISTORTION_MIN_EQCENTER (80.0f) -#define AL_DISTORTION_MAX_EQCENTER (24000.0f) -#define AL_DISTORTION_DEFAULT_EQCENTER (3600.0f) +#define AL_DISTORTION_MIN_EQCENTER (80.0f) +#define AL_DISTORTION_MAX_EQCENTER (24000.0f) +#define AL_DISTORTION_DEFAULT_EQCENTER (3600.0f) -#define AL_DISTORTION_MIN_EQBANDWIDTH (80.0f) -#define AL_DISTORTION_MAX_EQBANDWIDTH (24000.0f) -#define AL_DISTORTION_DEFAULT_EQBANDWIDTH (3600.0f) +#define AL_DISTORTION_MIN_EQBANDWIDTH (80.0f) +#define AL_DISTORTION_MAX_EQBANDWIDTH (24000.0f) +#define AL_DISTORTION_DEFAULT_EQBANDWIDTH (3600.0f) /* Echo effect */ -#define AL_ECHO_MIN_DELAY (0.0f) -#define AL_ECHO_MAX_DELAY (0.207f) -#define AL_ECHO_DEFAULT_DELAY (0.1f) +#define AL_ECHO_MIN_DELAY (0.0f) +#define AL_ECHO_MAX_DELAY (0.207f) +#define AL_ECHO_DEFAULT_DELAY (0.1f) -#define AL_ECHO_MIN_LRDELAY (0.0f) -#define AL_ECHO_MAX_LRDELAY (0.404f) -#define AL_ECHO_DEFAULT_LRDELAY (0.1f) +#define AL_ECHO_MIN_LRDELAY (0.0f) +#define AL_ECHO_MAX_LRDELAY (0.404f) +#define AL_ECHO_DEFAULT_LRDELAY (0.1f) -#define AL_ECHO_MIN_DAMPING (0.0f) -#define AL_ECHO_MAX_DAMPING (0.99f) -#define AL_ECHO_DEFAULT_DAMPING (0.5f) +#define AL_ECHO_MIN_DAMPING (0.0f) +#define AL_ECHO_MAX_DAMPING (0.99f) +#define AL_ECHO_DEFAULT_DAMPING (0.5f) -#define AL_ECHO_MIN_FEEDBACK (0.0f) -#define AL_ECHO_MAX_FEEDBACK (1.0f) -#define AL_ECHO_DEFAULT_FEEDBACK (0.5f) +#define AL_ECHO_MIN_FEEDBACK (0.0f) +#define AL_ECHO_MAX_FEEDBACK (1.0f) +#define AL_ECHO_DEFAULT_FEEDBACK (0.5f) -#define AL_ECHO_MIN_SPREAD (-1.0f) -#define AL_ECHO_MAX_SPREAD (1.0f) -#define AL_ECHO_DEFAULT_SPREAD (-1.0f) +#define AL_ECHO_MIN_SPREAD (-1.0f) +#define AL_ECHO_MAX_SPREAD (1.0f) +#define AL_ECHO_DEFAULT_SPREAD (-1.0f) /* Flanger effect */ -#define AL_FLANGER_WAVEFORM_SINUSOID (0) -#define AL_FLANGER_WAVEFORM_TRIANGLE (1) +#define AL_FLANGER_WAVEFORM_SINUSOID (0) +#define AL_FLANGER_WAVEFORM_TRIANGLE (1) -#define AL_FLANGER_MIN_WAVEFORM (0) -#define AL_FLANGER_MAX_WAVEFORM (1) -#define AL_FLANGER_DEFAULT_WAVEFORM (1) +#define AL_FLANGER_MIN_WAVEFORM (0) +#define AL_FLANGER_MAX_WAVEFORM (1) +#define AL_FLANGER_DEFAULT_WAVEFORM (1) -#define AL_FLANGER_MIN_PHASE (-180) -#define AL_FLANGER_MAX_PHASE (180) -#define AL_FLANGER_DEFAULT_PHASE (0) +#define AL_FLANGER_MIN_PHASE (-180) +#define AL_FLANGER_MAX_PHASE (180) +#define AL_FLANGER_DEFAULT_PHASE (0) -#define AL_FLANGER_MIN_RATE (0.0f) -#define AL_FLANGER_MAX_RATE (10.0f) -#define AL_FLANGER_DEFAULT_RATE (0.27f) +#define AL_FLANGER_MIN_RATE (0.0f) +#define AL_FLANGER_MAX_RATE (10.0f) +#define AL_FLANGER_DEFAULT_RATE (0.27f) -#define AL_FLANGER_MIN_DEPTH (0.0f) -#define AL_FLANGER_MAX_DEPTH (1.0f) -#define AL_FLANGER_DEFAULT_DEPTH (1.0f) +#define AL_FLANGER_MIN_DEPTH (0.0f) +#define AL_FLANGER_MAX_DEPTH (1.0f) +#define AL_FLANGER_DEFAULT_DEPTH (1.0f) -#define AL_FLANGER_MIN_FEEDBACK (-1.0f) -#define AL_FLANGER_MAX_FEEDBACK (1.0f) -#define AL_FLANGER_DEFAULT_FEEDBACK (-0.5f) +#define AL_FLANGER_MIN_FEEDBACK (-1.0f) +#define AL_FLANGER_MAX_FEEDBACK (1.0f) +#define AL_FLANGER_DEFAULT_FEEDBACK (-0.5f) -#define AL_FLANGER_MIN_DELAY (0.0f) -#define AL_FLANGER_MAX_DELAY (0.004f) -#define AL_FLANGER_DEFAULT_DELAY (0.002f) +#define AL_FLANGER_MIN_DELAY (0.0f) +#define AL_FLANGER_MAX_DELAY (0.004f) +#define AL_FLANGER_DEFAULT_DELAY (0.002f) /* Frequency shifter effect */ -#define AL_FREQUENCY_SHIFTER_MIN_FREQUENCY (0.0f) -#define AL_FREQUENCY_SHIFTER_MAX_FREQUENCY (24000.0f) -#define AL_FREQUENCY_SHIFTER_DEFAULT_FREQUENCY (0.0f) +#define AL_FREQUENCY_SHIFTER_MIN_FREQUENCY (0.0f) +#define AL_FREQUENCY_SHIFTER_MAX_FREQUENCY (24000.0f) +#define AL_FREQUENCY_SHIFTER_DEFAULT_FREQUENCY (0.0f) -#define AL_FREQUENCY_SHIFTER_MIN_LEFT_DIRECTION (0) -#define AL_FREQUENCY_SHIFTER_MAX_LEFT_DIRECTION (2) +#define AL_FREQUENCY_SHIFTER_MIN_LEFT_DIRECTION (0) +#define AL_FREQUENCY_SHIFTER_MAX_LEFT_DIRECTION (2) #define AL_FREQUENCY_SHIFTER_DEFAULT_LEFT_DIRECTION (0) -#define AL_FREQUENCY_SHIFTER_DIRECTION_DOWN (0) -#define AL_FREQUENCY_SHIFTER_DIRECTION_UP (1) -#define AL_FREQUENCY_SHIFTER_DIRECTION_OFF (2) +#define AL_FREQUENCY_SHIFTER_DIRECTION_DOWN (0) +#define AL_FREQUENCY_SHIFTER_DIRECTION_UP (1) +#define AL_FREQUENCY_SHIFTER_DIRECTION_OFF (2) #define AL_FREQUENCY_SHIFTER_MIN_RIGHT_DIRECTION (0) #define AL_FREQUENCY_SHIFTER_MAX_RIGHT_DIRECTION (2) #define AL_FREQUENCY_SHIFTER_DEFAULT_RIGHT_DIRECTION (0) /* Vocal morpher effect */ -#define AL_VOCAL_MORPHER_MIN_PHONEMEA (0) -#define AL_VOCAL_MORPHER_MAX_PHONEMEA (29) -#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEA (0) +#define AL_VOCAL_MORPHER_MIN_PHONEMEA (0) +#define AL_VOCAL_MORPHER_MAX_PHONEMEA (29) +#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEA (0) #define AL_VOCAL_MORPHER_MIN_PHONEMEA_COARSE_TUNING (-24) #define AL_VOCAL_MORPHER_MAX_PHONEMEA_COARSE_TUNING (24) #define AL_VOCAL_MORPHER_DEFAULT_PHONEMEA_COARSE_TUNING (0) -#define AL_VOCAL_MORPHER_MIN_PHONEMEB (0) -#define AL_VOCAL_MORPHER_MAX_PHONEMEB (29) -#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEB (10) +#define AL_VOCAL_MORPHER_MIN_PHONEMEB (0) +#define AL_VOCAL_MORPHER_MAX_PHONEMEB (29) +#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEB (10) #define AL_VOCAL_MORPHER_MIN_PHONEMEB_COARSE_TUNING (-24) #define AL_VOCAL_MORPHER_MAX_PHONEMEB_COARSE_TUNING (24) #define AL_VOCAL_MORPHER_DEFAULT_PHONEMEB_COARSE_TUNING (0) -#define AL_VOCAL_MORPHER_PHONEME_A (0) -#define AL_VOCAL_MORPHER_PHONEME_E (1) -#define AL_VOCAL_MORPHER_PHONEME_I (2) -#define AL_VOCAL_MORPHER_PHONEME_O (3) -#define AL_VOCAL_MORPHER_PHONEME_U (4) -#define AL_VOCAL_MORPHER_PHONEME_AA (5) -#define AL_VOCAL_MORPHER_PHONEME_AE (6) -#define AL_VOCAL_MORPHER_PHONEME_AH (7) -#define AL_VOCAL_MORPHER_PHONEME_AO (8) -#define AL_VOCAL_MORPHER_PHONEME_EH (9) -#define AL_VOCAL_MORPHER_PHONEME_ER (10) -#define AL_VOCAL_MORPHER_PHONEME_IH (11) -#define AL_VOCAL_MORPHER_PHONEME_IY (12) -#define AL_VOCAL_MORPHER_PHONEME_UH (13) -#define AL_VOCAL_MORPHER_PHONEME_UW (14) -#define AL_VOCAL_MORPHER_PHONEME_B (15) -#define AL_VOCAL_MORPHER_PHONEME_D (16) -#define AL_VOCAL_MORPHER_PHONEME_F (17) -#define AL_VOCAL_MORPHER_PHONEME_G (18) -#define AL_VOCAL_MORPHER_PHONEME_J (19) -#define AL_VOCAL_MORPHER_PHONEME_K (20) -#define AL_VOCAL_MORPHER_PHONEME_L (21) -#define AL_VOCAL_MORPHER_PHONEME_M (22) -#define AL_VOCAL_MORPHER_PHONEME_N (23) -#define AL_VOCAL_MORPHER_PHONEME_P (24) -#define AL_VOCAL_MORPHER_PHONEME_R (25) -#define AL_VOCAL_MORPHER_PHONEME_S (26) -#define AL_VOCAL_MORPHER_PHONEME_T (27) -#define AL_VOCAL_MORPHER_PHONEME_V (28) -#define AL_VOCAL_MORPHER_PHONEME_Z (29) - -#define AL_VOCAL_MORPHER_WAVEFORM_SINUSOID (0) -#define AL_VOCAL_MORPHER_WAVEFORM_TRIANGLE (1) -#define AL_VOCAL_MORPHER_WAVEFORM_SAWTOOTH (2) - -#define AL_VOCAL_MORPHER_MIN_WAVEFORM (0) -#define AL_VOCAL_MORPHER_MAX_WAVEFORM (2) -#define AL_VOCAL_MORPHER_DEFAULT_WAVEFORM (0) - -#define AL_VOCAL_MORPHER_MIN_RATE (0.0f) -#define AL_VOCAL_MORPHER_MAX_RATE (10.0f) -#define AL_VOCAL_MORPHER_DEFAULT_RATE (1.41f) +#define AL_VOCAL_MORPHER_PHONEME_A (0) +#define AL_VOCAL_MORPHER_PHONEME_E (1) +#define AL_VOCAL_MORPHER_PHONEME_I (2) +#define AL_VOCAL_MORPHER_PHONEME_O (3) +#define AL_VOCAL_MORPHER_PHONEME_U (4) +#define AL_VOCAL_MORPHER_PHONEME_AA (5) +#define AL_VOCAL_MORPHER_PHONEME_AE (6) +#define AL_VOCAL_MORPHER_PHONEME_AH (7) +#define AL_VOCAL_MORPHER_PHONEME_AO (8) +#define AL_VOCAL_MORPHER_PHONEME_EH (9) +#define AL_VOCAL_MORPHER_PHONEME_ER (10) +#define AL_VOCAL_MORPHER_PHONEME_IH (11) +#define AL_VOCAL_MORPHER_PHONEME_IY (12) +#define AL_VOCAL_MORPHER_PHONEME_UH (13) +#define AL_VOCAL_MORPHER_PHONEME_UW (14) +#define AL_VOCAL_MORPHER_PHONEME_B (15) +#define AL_VOCAL_MORPHER_PHONEME_D (16) +#define AL_VOCAL_MORPHER_PHONEME_F (17) +#define AL_VOCAL_MORPHER_PHONEME_G (18) +#define AL_VOCAL_MORPHER_PHONEME_J (19) +#define AL_VOCAL_MORPHER_PHONEME_K (20) +#define AL_VOCAL_MORPHER_PHONEME_L (21) +#define AL_VOCAL_MORPHER_PHONEME_M (22) +#define AL_VOCAL_MORPHER_PHONEME_N (23) +#define AL_VOCAL_MORPHER_PHONEME_P (24) +#define AL_VOCAL_MORPHER_PHONEME_R (25) +#define AL_VOCAL_MORPHER_PHONEME_S (26) +#define AL_VOCAL_MORPHER_PHONEME_T (27) +#define AL_VOCAL_MORPHER_PHONEME_V (28) +#define AL_VOCAL_MORPHER_PHONEME_Z (29) + +#define AL_VOCAL_MORPHER_WAVEFORM_SINUSOID (0) +#define AL_VOCAL_MORPHER_WAVEFORM_TRIANGLE (1) +#define AL_VOCAL_MORPHER_WAVEFORM_SAWTOOTH (2) + +#define AL_VOCAL_MORPHER_MIN_WAVEFORM (0) +#define AL_VOCAL_MORPHER_MAX_WAVEFORM (2) +#define AL_VOCAL_MORPHER_DEFAULT_WAVEFORM (0) + +#define AL_VOCAL_MORPHER_MIN_RATE (0.0f) +#define AL_VOCAL_MORPHER_MAX_RATE (10.0f) +#define AL_VOCAL_MORPHER_DEFAULT_RATE (1.41f) /* Pitch shifter effect */ -#define AL_PITCH_SHIFTER_MIN_COARSE_TUNE (-12) -#define AL_PITCH_SHIFTER_MAX_COARSE_TUNE (12) -#define AL_PITCH_SHIFTER_DEFAULT_COARSE_TUNE (12) +#define AL_PITCH_SHIFTER_MIN_COARSE_TUNE (-12) +#define AL_PITCH_SHIFTER_MAX_COARSE_TUNE (12) +#define AL_PITCH_SHIFTER_DEFAULT_COARSE_TUNE (12) -#define AL_PITCH_SHIFTER_MIN_FINE_TUNE (-50) -#define AL_PITCH_SHIFTER_MAX_FINE_TUNE (50) -#define AL_PITCH_SHIFTER_DEFAULT_FINE_TUNE (0) +#define AL_PITCH_SHIFTER_MIN_FINE_TUNE (-50) +#define AL_PITCH_SHIFTER_MAX_FINE_TUNE (50) +#define AL_PITCH_SHIFTER_DEFAULT_FINE_TUNE (0) /* Ring modulator effect */ -#define AL_RING_MODULATOR_MIN_FREQUENCY (0.0f) -#define AL_RING_MODULATOR_MAX_FREQUENCY (8000.0f) -#define AL_RING_MODULATOR_DEFAULT_FREQUENCY (440.0f) +#define AL_RING_MODULATOR_MIN_FREQUENCY (0.0f) +#define AL_RING_MODULATOR_MAX_FREQUENCY (8000.0f) +#define AL_RING_MODULATOR_DEFAULT_FREQUENCY (440.0f) -#define AL_RING_MODULATOR_MIN_HIGHPASS_CUTOFF (0.0f) -#define AL_RING_MODULATOR_MAX_HIGHPASS_CUTOFF (24000.0f) +#define AL_RING_MODULATOR_MIN_HIGHPASS_CUTOFF (0.0f) +#define AL_RING_MODULATOR_MAX_HIGHPASS_CUTOFF (24000.0f) #define AL_RING_MODULATOR_DEFAULT_HIGHPASS_CUTOFF (800.0f) -#define AL_RING_MODULATOR_SINUSOID (0) -#define AL_RING_MODULATOR_SAWTOOTH (1) -#define AL_RING_MODULATOR_SQUARE (2) +#define AL_RING_MODULATOR_SINUSOID (0) +#define AL_RING_MODULATOR_SAWTOOTH (1) +#define AL_RING_MODULATOR_SQUARE (2) -#define AL_RING_MODULATOR_MIN_WAVEFORM (0) -#define AL_RING_MODULATOR_MAX_WAVEFORM (2) -#define AL_RING_MODULATOR_DEFAULT_WAVEFORM (0) +#define AL_RING_MODULATOR_MIN_WAVEFORM (0) +#define AL_RING_MODULATOR_MAX_WAVEFORM (2) +#define AL_RING_MODULATOR_DEFAULT_WAVEFORM (0) /* Autowah effect */ -#define AL_AUTOWAH_MIN_ATTACK_TIME (0.0001f) -#define AL_AUTOWAH_MAX_ATTACK_TIME (1.0f) -#define AL_AUTOWAH_DEFAULT_ATTACK_TIME (0.06f) +#define AL_AUTOWAH_MIN_ATTACK_TIME (0.0001f) +#define AL_AUTOWAH_MAX_ATTACK_TIME (1.0f) +#define AL_AUTOWAH_DEFAULT_ATTACK_TIME (0.06f) -#define AL_AUTOWAH_MIN_RELEASE_TIME (0.0001f) -#define AL_AUTOWAH_MAX_RELEASE_TIME (1.0f) -#define AL_AUTOWAH_DEFAULT_RELEASE_TIME (0.06f) +#define AL_AUTOWAH_MIN_RELEASE_TIME (0.0001f) +#define AL_AUTOWAH_MAX_RELEASE_TIME (1.0f) +#define AL_AUTOWAH_DEFAULT_RELEASE_TIME (0.06f) -#define AL_AUTOWAH_MIN_RESONANCE (2.0f) -#define AL_AUTOWAH_MAX_RESONANCE (1000.0f) -#define AL_AUTOWAH_DEFAULT_RESONANCE (1000.0f) +#define AL_AUTOWAH_MIN_RESONANCE (2.0f) +#define AL_AUTOWAH_MAX_RESONANCE (1000.0f) +#define AL_AUTOWAH_DEFAULT_RESONANCE (1000.0f) -#define AL_AUTOWAH_MIN_PEAK_GAIN (0.00003f) -#define AL_AUTOWAH_MAX_PEAK_GAIN (31621.0f) -#define AL_AUTOWAH_DEFAULT_PEAK_GAIN (11.22f) +#define AL_AUTOWAH_MIN_PEAK_GAIN (0.00003f) +#define AL_AUTOWAH_MAX_PEAK_GAIN (31621.0f) +#define AL_AUTOWAH_DEFAULT_PEAK_GAIN (11.22f) /* Compressor effect */ -#define AL_COMPRESSOR_MIN_ONOFF (0) -#define AL_COMPRESSOR_MAX_ONOFF (1) -#define AL_COMPRESSOR_DEFAULT_ONOFF (1) +#define AL_COMPRESSOR_MIN_ONOFF (0) +#define AL_COMPRESSOR_MAX_ONOFF (1) +#define AL_COMPRESSOR_DEFAULT_ONOFF (1) /* Equalizer effect */ -#define AL_EQUALIZER_MIN_LOW_GAIN (0.126f) -#define AL_EQUALIZER_MAX_LOW_GAIN (7.943f) -#define AL_EQUALIZER_DEFAULT_LOW_GAIN (1.0f) - -#define AL_EQUALIZER_MIN_LOW_CUTOFF (50.0f) -#define AL_EQUALIZER_MAX_LOW_CUTOFF (800.0f) -#define AL_EQUALIZER_DEFAULT_LOW_CUTOFF (200.0f) +#define AL_EQUALIZER_MIN_LOW_GAIN (0.126f) +#define AL_EQUALIZER_MAX_LOW_GAIN (7.943f) +#define AL_EQUALIZER_DEFAULT_LOW_GAIN (1.0f) -#define AL_EQUALIZER_MIN_MID1_GAIN (0.126f) -#define AL_EQUALIZER_MAX_MID1_GAIN (7.943f) -#define AL_EQUALIZER_DEFAULT_MID1_GAIN (1.0f) +#define AL_EQUALIZER_MIN_LOW_CUTOFF (50.0f) +#define AL_EQUALIZER_MAX_LOW_CUTOFF (800.0f) +#define AL_EQUALIZER_DEFAULT_LOW_CUTOFF (200.0f) -#define AL_EQUALIZER_MIN_MID1_CENTER (200.0f) -#define AL_EQUALIZER_MAX_MID1_CENTER (3000.0f) -#define AL_EQUALIZER_DEFAULT_MID1_CENTER (500.0f) +#define AL_EQUALIZER_MIN_MID1_GAIN (0.126f) +#define AL_EQUALIZER_MAX_MID1_GAIN (7.943f) +#define AL_EQUALIZER_DEFAULT_MID1_GAIN (1.0f) -#define AL_EQUALIZER_MIN_MID1_WIDTH (0.01f) -#define AL_EQUALIZER_MAX_MID1_WIDTH (1.0f) -#define AL_EQUALIZER_DEFAULT_MID1_WIDTH (1.0f) +#define AL_EQUALIZER_MIN_MID1_CENTER (200.0f) +#define AL_EQUALIZER_MAX_MID1_CENTER (3000.0f) +#define AL_EQUALIZER_DEFAULT_MID1_CENTER (500.0f) -#define AL_EQUALIZER_MIN_MID2_GAIN (0.126f) -#define AL_EQUALIZER_MAX_MID2_GAIN (7.943f) -#define AL_EQUALIZER_DEFAULT_MID2_GAIN (1.0f) +#define AL_EQUALIZER_MIN_MID1_WIDTH (0.01f) +#define AL_EQUALIZER_MAX_MID1_WIDTH (1.0f) +#define AL_EQUALIZER_DEFAULT_MID1_WIDTH (1.0f) -#define AL_EQUALIZER_MIN_MID2_CENTER (1000.0f) -#define AL_EQUALIZER_MAX_MID2_CENTER (8000.0f) -#define AL_EQUALIZER_DEFAULT_MID2_CENTER (3000.0f) +#define AL_EQUALIZER_MIN_MID2_GAIN (0.126f) +#define AL_EQUALIZER_MAX_MID2_GAIN (7.943f) +#define AL_EQUALIZER_DEFAULT_MID2_GAIN (1.0f) -#define AL_EQUALIZER_MIN_MID2_WIDTH (0.01f) -#define AL_EQUALIZER_MAX_MID2_WIDTH (1.0f) -#define AL_EQUALIZER_DEFAULT_MID2_WIDTH (1.0f) +#define AL_EQUALIZER_MIN_MID2_CENTER (1000.0f) +#define AL_EQUALIZER_MAX_MID2_CENTER (8000.0f) +#define AL_EQUALIZER_DEFAULT_MID2_CENTER (3000.0f) -#define AL_EQUALIZER_MIN_HIGH_GAIN (0.126f) -#define AL_EQUALIZER_MAX_HIGH_GAIN (7.943f) -#define AL_EQUALIZER_DEFAULT_HIGH_GAIN (1.0f) +#define AL_EQUALIZER_MIN_MID2_WIDTH (0.01f) +#define AL_EQUALIZER_MAX_MID2_WIDTH (1.0f) +#define AL_EQUALIZER_DEFAULT_MID2_WIDTH (1.0f) -#define AL_EQUALIZER_MIN_HIGH_CUTOFF (4000.0f) -#define AL_EQUALIZER_MAX_HIGH_CUTOFF (16000.0f) -#define AL_EQUALIZER_DEFAULT_HIGH_CUTOFF (6000.0f) +#define AL_EQUALIZER_MIN_HIGH_GAIN (0.126f) +#define AL_EQUALIZER_MAX_HIGH_GAIN (7.943f) +#define AL_EQUALIZER_DEFAULT_HIGH_GAIN (1.0f) +#define AL_EQUALIZER_MIN_HIGH_CUTOFF (4000.0f) +#define AL_EQUALIZER_MAX_HIGH_CUTOFF (16000.0f) +#define AL_EQUALIZER_DEFAULT_HIGH_CUTOFF (6000.0f) /* Source parameter value ranges and defaults. */ -#define AL_MIN_AIR_ABSORPTION_FACTOR (0.0f) -#define AL_MAX_AIR_ABSORPTION_FACTOR (10.0f) -#define AL_DEFAULT_AIR_ABSORPTION_FACTOR (0.0f) +#define AL_MIN_AIR_ABSORPTION_FACTOR (0.0f) +#define AL_MAX_AIR_ABSORPTION_FACTOR (10.0f) +#define AL_DEFAULT_AIR_ABSORPTION_FACTOR (0.0f) -#define AL_MIN_ROOM_ROLLOFF_FACTOR (0.0f) -#define AL_MAX_ROOM_ROLLOFF_FACTOR (10.0f) -#define AL_DEFAULT_ROOM_ROLLOFF_FACTOR (0.0f) +#define AL_MIN_ROOM_ROLLOFF_FACTOR (0.0f) +#define AL_MAX_ROOM_ROLLOFF_FACTOR (10.0f) +#define AL_DEFAULT_ROOM_ROLLOFF_FACTOR (0.0f) -#define AL_MIN_CONE_OUTER_GAINHF (0.0f) -#define AL_MAX_CONE_OUTER_GAINHF (1.0f) -#define AL_DEFAULT_CONE_OUTER_GAINHF (1.0f) +#define AL_MIN_CONE_OUTER_GAINHF (0.0f) +#define AL_MAX_CONE_OUTER_GAINHF (1.0f) +#define AL_DEFAULT_CONE_OUTER_GAINHF (1.0f) -#define AL_MIN_DIRECT_FILTER_GAINHF_AUTO AL_FALSE -#define AL_MAX_DIRECT_FILTER_GAINHF_AUTO AL_TRUE -#define AL_DEFAULT_DIRECT_FILTER_GAINHF_AUTO AL_TRUE +#define AL_MIN_DIRECT_FILTER_GAINHF_AUTO AL_FALSE +#define AL_MAX_DIRECT_FILTER_GAINHF_AUTO AL_TRUE +#define AL_DEFAULT_DIRECT_FILTER_GAINHF_AUTO AL_TRUE -#define AL_MIN_AUXILIARY_SEND_FILTER_GAIN_AUTO AL_FALSE -#define AL_MAX_AUXILIARY_SEND_FILTER_GAIN_AUTO AL_TRUE +#define AL_MIN_AUXILIARY_SEND_FILTER_GAIN_AUTO AL_FALSE +#define AL_MAX_AUXILIARY_SEND_FILTER_GAIN_AUTO AL_TRUE #define AL_DEFAULT_AUXILIARY_SEND_FILTER_GAIN_AUTO AL_TRUE #define AL_MIN_AUXILIARY_SEND_FILTER_GAINHF_AUTO AL_FALSE #define AL_MAX_AUXILIARY_SEND_FILTER_GAINHF_AUTO AL_TRUE #define AL_DEFAULT_AUXILIARY_SEND_FILTER_GAINHF_AUTO AL_TRUE - /* Listener parameter value ranges and defaults. */ -#define AL_MIN_METERS_PER_UNIT FLT_MIN -#define AL_MAX_METERS_PER_UNIT FLT_MAX -#define AL_DEFAULT_METERS_PER_UNIT (1.0f) - +#define AL_MIN_METERS_PER_UNIT FLT_MIN +#define AL_MAX_METERS_PER_UNIT FLT_MAX +#define AL_DEFAULT_METERS_PER_UNIT (1.0f) #ifdef __cplusplus -} /* extern "C" */ +} /* extern "C" */ #endif #endif /* AL_EFX_H */ diff --git a/apps/openmw/mwsound/ffmpeg_decoder.cpp b/apps/openmw/mwsound/ffmpeg_decoder.cpp index 997b4e30c6..74b4fcaad0 100644 --- a/apps/openmw/mwsound/ffmpeg_decoder.cpp +++ b/apps/openmw/mwsound/ffmpeg_decoder.cpp @@ -2,8 +2,8 @@ #include -#include #include +#include #include #include @@ -11,463 +11,463 @@ namespace MWSound { -int FFmpeg_Decoder::readPacket(void *user_data, uint8_t *buf, int buf_size) -{ - try + int FFmpeg_Decoder::readPacket(void* user_data, uint8_t* buf, int buf_size) { - std::istream& stream = *static_cast(user_data)->mDataStream; - stream.clear(); - stream.read((char*)buf, buf_size); - std::streamsize count = stream.gcount(); - if (count == 0) - return AVERROR_EOF; - return count; - } - catch (std::exception& ) - { - return AVERROR_UNKNOWN; + try + { + std::istream& stream = *static_cast(user_data)->mDataStream; + stream.clear(); + stream.read((char*)buf, buf_size); + std::streamsize count = stream.gcount(); + if (count == 0) + return AVERROR_EOF; + return count; + } + catch (std::exception&) + { + return AVERROR_UNKNOWN; + } } -} - -int FFmpeg_Decoder::writePacket(void *, uint8_t *, int) -{ - Log(Debug::Error) << "can't write to read-only stream"; - return -1; -} - -int64_t FFmpeg_Decoder::seek(void *user_data, int64_t offset, int whence) -{ - std::istream& stream = *static_cast(user_data)->mDataStream; - - whence &= ~AVSEEK_FORCE; - - stream.clear(); - if(whence == AVSEEK_SIZE) + int FFmpeg_Decoder::writePacket(void*, uint8_t*, int) { - size_t prev = stream.tellg(); - stream.seekg(0, std::ios_base::end); - size_t size = stream.tellg(); - stream.seekg(prev, std::ios_base::beg); - return size; - } - - if(whence == SEEK_SET) - stream.seekg(offset, std::ios_base::beg); - else if(whence == SEEK_CUR) - stream.seekg(offset, std::ios_base::cur); - else if(whence == SEEK_END) - stream.seekg(offset, std::ios_base::end); - else + Log(Debug::Error) << "can't write to read-only stream"; return -1; + } - return stream.tellg(); -} + int64_t FFmpeg_Decoder::seek(void* user_data, int64_t offset, int whence) + { + std::istream& stream = *static_cast(user_data)->mDataStream; + whence &= ~AVSEEK_FORCE; -/* Used by getAV*Data to search for more compressed data, and buffer it in the - * correct stream. It won't buffer data for streams that the app doesn't have a - * handle for. */ -bool FFmpeg_Decoder::getNextPacket() -{ - if(!mStream) - return false; + stream.clear(); - int stream_idx = mStream - mFormatCtx->streams; - while(av_read_frame(mFormatCtx, &mPacket) >= 0) - { - /* Check if the packet belongs to this stream */ - if(stream_idx == mPacket.stream_index) + if (whence == AVSEEK_SIZE) { - if(mPacket.pts != (int64_t)AV_NOPTS_VALUE) - mNextPts = av_q2d((*mStream)->time_base)*mPacket.pts; - return true; + size_t prev = stream.tellg(); + stream.seekg(0, std::ios_base::end); + size_t size = stream.tellg(); + stream.seekg(prev, std::ios_base::beg); + return size; } - /* Free the packet and look for another */ - av_packet_unref(&mPacket); - } - - return false; -} + if (whence == SEEK_SET) + stream.seekg(offset, std::ios_base::beg); + else if (whence == SEEK_CUR) + stream.seekg(offset, std::ios_base::cur); + else if (whence == SEEK_END) + stream.seekg(offset, std::ios_base::end); + else + return -1; -bool FFmpeg_Decoder::getAVAudioData() -{ - bool got_frame = false; + return stream.tellg(); + } - if(mCodecCtx->codec_type != AVMEDIA_TYPE_AUDIO) - return false; + /* Used by getAV*Data to search for more compressed data, and buffer it in the + * correct stream. It won't buffer data for streams that the app doesn't have a + * handle for. */ + bool FFmpeg_Decoder::getNextPacket() + { + if (!mStream) + return false; - do { - /* Decode some data, and check for errors */ - int ret = avcodec_receive_frame(mCodecCtx, mFrame); - if (ret == AVERROR(EAGAIN)) + int stream_idx = mStream - mFormatCtx->streams; + while (av_read_frame(mFormatCtx, &mPacket) >= 0) { - if (mPacket.size == 0 && !getNextPacket()) - return false; - ret = avcodec_send_packet(mCodecCtx, &mPacket); + /* Check if the packet belongs to this stream */ + if (stream_idx == mPacket.stream_index) + { + if (mPacket.pts != (int64_t)AV_NOPTS_VALUE) + mNextPts = av_q2d((*mStream)->time_base) * mPacket.pts; + return true; + } + + /* Free the packet and look for another */ av_packet_unref(&mPacket); - if (ret == 0) - continue; } - if (ret != 0) - return false; - av_packet_unref(&mPacket); + return false; + } - if (mFrame->nb_samples == 0) - continue; - got_frame = true; + bool FFmpeg_Decoder::getAVAudioData() + { + bool got_frame = false; + + if (mCodecCtx->codec_type != AVMEDIA_TYPE_AUDIO) + return false; - if(mSwr) + do { - if(!mDataBuf || mDataBufLen < mFrame->nb_samples) + /* Decode some data, and check for errors */ + int ret = avcodec_receive_frame(mCodecCtx, mFrame); + if (ret == AVERROR(EAGAIN)) { - av_freep(&mDataBuf); - if(av_samples_alloc(&mDataBuf, nullptr, av_get_channel_layout_nb_channels(mOutputChannelLayout), - mFrame->nb_samples, mOutputSampleFormat, 0) < 0) + if (mPacket.size == 0 && !getNextPacket()) return false; - else - mDataBufLen = mFrame->nb_samples; + ret = avcodec_send_packet(mCodecCtx, &mPacket); + av_packet_unref(&mPacket); + if (ret == 0) + continue; } + if (ret != 0) + return false; - if(swr_convert(mSwr, (uint8_t**)&mDataBuf, mFrame->nb_samples, - (const uint8_t**)mFrame->extended_data, mFrame->nb_samples) < 0) + av_packet_unref(&mPacket); + + if (mFrame->nb_samples == 0) + continue; + got_frame = true; + + if (mSwr) { - return false; - } - mFrameData = &mDataBuf; - } - else - mFrameData = &mFrame->data[0]; + if (!mDataBuf || mDataBufLen < mFrame->nb_samples) + { + av_freep(&mDataBuf); + if (av_samples_alloc(&mDataBuf, nullptr, av_get_channel_layout_nb_channels(mOutputChannelLayout), + mFrame->nb_samples, mOutputSampleFormat, 0) + < 0) + return false; + else + mDataBufLen = mFrame->nb_samples; + } - } while(!got_frame); - mNextPts += (double)mFrame->nb_samples / mCodecCtx->sample_rate; + if (swr_convert(mSwr, (uint8_t**)&mDataBuf, mFrame->nb_samples, (const uint8_t**)mFrame->extended_data, + mFrame->nb_samples) + < 0) + { + return false; + } + mFrameData = &mDataBuf; + } + else + mFrameData = &mFrame->data[0]; - return true; -} + } while (!got_frame); + mNextPts += (double)mFrame->nb_samples / mCodecCtx->sample_rate; -size_t FFmpeg_Decoder::readAVAudioData(void *data, size_t length) -{ - size_t dec = 0; + return true; + } - while(dec < length) + size_t FFmpeg_Decoder::readAVAudioData(void* data, size_t length) { - /* If there's no decoded data, find some */ - if(mFramePos >= mFrameSize) + size_t dec = 0; + + while (dec < length) { - if(!getAVAudioData()) - break; - mFramePos = 0; - mFrameSize = mFrame->nb_samples * av_get_channel_layout_nb_channels(mOutputChannelLayout) * - av_get_bytes_per_sample(mOutputSampleFormat); - } + /* If there's no decoded data, find some */ + if (mFramePos >= mFrameSize) + { + if (!getAVAudioData()) + break; + mFramePos = 0; + mFrameSize = mFrame->nb_samples * av_get_channel_layout_nb_channels(mOutputChannelLayout) + * av_get_bytes_per_sample(mOutputSampleFormat); + } - /* Get the amount of bytes remaining to be written, and clamp to - * the amount of decoded data we have */ - size_t rem = std::min(length-dec, mFrameSize-mFramePos); + /* Get the amount of bytes remaining to be written, and clamp to + * the amount of decoded data we have */ + size_t rem = std::min(length - dec, mFrameSize - mFramePos); - /* Copy the data to the app's buffer and increment */ - memcpy(data, mFrameData[0]+mFramePos, rem); - data = (char*)data + rem; - dec += rem; - mFramePos += rem; - } + /* Copy the data to the app's buffer and increment */ + memcpy(data, mFrameData[0] + mFramePos, rem); + data = (char*)data + rem; + dec += rem; + mFramePos += rem; + } - /* Return the number of bytes we were able to get */ - return dec; -} + /* Return the number of bytes we were able to get */ + return dec; + } -void FFmpeg_Decoder::open(const std::string &fname) -{ - close(); - mDataStream = mResourceMgr->get(fname); + void FFmpeg_Decoder::open(const std::string& fname) + { + close(); + mDataStream = mResourceMgr->get(fname); - if((mFormatCtx=avformat_alloc_context()) == nullptr) - throw std::runtime_error("Failed to allocate context"); + if ((mFormatCtx = avformat_alloc_context()) == nullptr) + throw std::runtime_error("Failed to allocate context"); - try - { - mFormatCtx->pb = avio_alloc_context(nullptr, 0, 0, this, readPacket, writePacket, seek); - if(!mFormatCtx->pb || avformat_open_input(&mFormatCtx, fname.c_str(), nullptr, nullptr) != 0) + try { - // "Note that a user-supplied AVFormatContext will be freed on failure". - if (mFormatCtx) + mFormatCtx->pb = avio_alloc_context(nullptr, 0, 0, this, readPacket, writePacket, seek); + if (!mFormatCtx->pb || avformat_open_input(&mFormatCtx, fname.c_str(), nullptr, nullptr) != 0) { - if (mFormatCtx->pb != nullptr) + // "Note that a user-supplied AVFormatContext will be freed on failure". + if (mFormatCtx) { - if (mFormatCtx->pb->buffer != nullptr) + if (mFormatCtx->pb != nullptr) { - av_free(mFormatCtx->pb->buffer); - mFormatCtx->pb->buffer = nullptr; + if (mFormatCtx->pb->buffer != nullptr) + { + av_free(mFormatCtx->pb->buffer); + mFormatCtx->pb->buffer = nullptr; + } + av_free(mFormatCtx->pb); + mFormatCtx->pb = nullptr; } - av_free(mFormatCtx->pb); - mFormatCtx->pb = nullptr; + avformat_free_context(mFormatCtx); } - avformat_free_context(mFormatCtx); + mFormatCtx = nullptr; + throw std::runtime_error("Failed to allocate input stream"); } - mFormatCtx = nullptr; - throw std::runtime_error("Failed to allocate input stream"); - } - if(avformat_find_stream_info(mFormatCtx, nullptr) < 0) - throw std::runtime_error("Failed to find stream info in "+fname); + if (avformat_find_stream_info(mFormatCtx, nullptr) < 0) + throw std::runtime_error("Failed to find stream info in " + fname); - for(size_t j = 0;j < mFormatCtx->nb_streams;j++) - { - if(mFormatCtx->streams[j]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) + for (size_t j = 0; j < mFormatCtx->nb_streams; j++) { - mStream = &mFormatCtx->streams[j]; - break; + if (mFormatCtx->streams[j]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) + { + mStream = &mFormatCtx->streams[j]; + break; + } } - } - if(!mStream) - throw std::runtime_error("No audio streams in "+fname); + if (!mStream) + throw std::runtime_error("No audio streams in " + fname); - const AVCodec *codec = avcodec_find_decoder((*mStream)->codecpar->codec_id); - if(!codec) - { - std::string ss = "No codec found for id " + - std::to_string((*mStream)->codecpar->codec_id); - throw std::runtime_error(ss); - } + const AVCodec* codec = avcodec_find_decoder((*mStream)->codecpar->codec_id); + if (!codec) + { + std::string ss = "No codec found for id " + std::to_string((*mStream)->codecpar->codec_id); + throw std::runtime_error(ss); + } - AVCodecContext *avctx = avcodec_alloc_context3(codec); - avcodec_parameters_to_context(avctx, (*mStream)->codecpar); + AVCodecContext* avctx = avcodec_alloc_context3(codec); + avcodec_parameters_to_context(avctx, (*mStream)->codecpar); // This is not needed anymore above FFMpeg version 4.0 #if LIBAVCODEC_VERSION_INT < 3805796 - av_codec_set_pkt_timebase(avctx, (*mStream)->time_base); + av_codec_set_pkt_timebase(avctx, (*mStream)->time_base); #endif - mCodecCtx = avctx; + mCodecCtx = avctx; - if(avcodec_open2(mCodecCtx, codec, nullptr) < 0) - throw std::runtime_error(std::string("Failed to open audio codec ") + codec->long_name); + if (avcodec_open2(mCodecCtx, codec, nullptr) < 0) + throw std::runtime_error(std::string("Failed to open audio codec ") + codec->long_name); - mFrame = av_frame_alloc(); + mFrame = av_frame_alloc(); - if(mCodecCtx->sample_fmt == AV_SAMPLE_FMT_FLT || mCodecCtx->sample_fmt == AV_SAMPLE_FMT_FLTP) - mOutputSampleFormat = AV_SAMPLE_FMT_S16; // FIXME: Check for AL_EXT_FLOAT32 support - else if(mCodecCtx->sample_fmt == AV_SAMPLE_FMT_U8P) - mOutputSampleFormat = AV_SAMPLE_FMT_U8; - else if(mCodecCtx->sample_fmt == AV_SAMPLE_FMT_S16P) - mOutputSampleFormat = AV_SAMPLE_FMT_S16; - else - mOutputSampleFormat = AV_SAMPLE_FMT_S16; + if (mCodecCtx->sample_fmt == AV_SAMPLE_FMT_FLT || mCodecCtx->sample_fmt == AV_SAMPLE_FMT_FLTP) + mOutputSampleFormat = AV_SAMPLE_FMT_S16; // FIXME: Check for AL_EXT_FLOAT32 support + else if (mCodecCtx->sample_fmt == AV_SAMPLE_FMT_U8P) + mOutputSampleFormat = AV_SAMPLE_FMT_U8; + else if (mCodecCtx->sample_fmt == AV_SAMPLE_FMT_S16P) + mOutputSampleFormat = AV_SAMPLE_FMT_S16; + else + mOutputSampleFormat = AV_SAMPLE_FMT_S16; - mOutputChannelLayout = (*mStream)->codecpar->channel_layout; - if(mOutputChannelLayout == 0) - mOutputChannelLayout = av_get_default_channel_layout(mCodecCtx->channels); + mOutputChannelLayout = (*mStream)->codecpar->channel_layout; + if (mOutputChannelLayout == 0) + mOutputChannelLayout = av_get_default_channel_layout(mCodecCtx->channels); - mCodecCtx->channel_layout = mOutputChannelLayout; - } - catch(...) - { - if(mStream) - avcodec_free_context(&mCodecCtx); - mStream = nullptr; - - if (mFormatCtx != nullptr) + mCodecCtx->channel_layout = mOutputChannelLayout; + } + catch (...) { - if (mFormatCtx->pb->buffer != nullptr) + if (mStream) + avcodec_free_context(&mCodecCtx); + mStream = nullptr; + + if (mFormatCtx != nullptr) { - av_free(mFormatCtx->pb->buffer); - mFormatCtx->pb->buffer = nullptr; - } - av_free(mFormatCtx->pb); - mFormatCtx->pb = nullptr; + if (mFormatCtx->pb->buffer != nullptr) + { + av_free(mFormatCtx->pb->buffer); + mFormatCtx->pb->buffer = nullptr; + } + av_free(mFormatCtx->pb); + mFormatCtx->pb = nullptr; - avformat_close_input(&mFormatCtx); + avformat_close_input(&mFormatCtx); + } } } -} -void FFmpeg_Decoder::close() -{ - if(mStream) - avcodec_free_context(&mCodecCtx); - mStream = nullptr; + void FFmpeg_Decoder::close() + { + if (mStream) + avcodec_free_context(&mCodecCtx); + mStream = nullptr; - av_packet_unref(&mPacket); - av_freep(&mDataBuf); - av_frame_free(&mFrame); - swr_free(&mSwr); + av_packet_unref(&mPacket); + av_freep(&mDataBuf); + av_frame_free(&mFrame); + swr_free(&mSwr); - if(mFormatCtx) - { - if (mFormatCtx->pb != nullptr) + if (mFormatCtx) { - // mFormatCtx->pb->buffer must be freed by hand, - // if not, valgrind will show memleak, see: - // - // https://trac.ffmpeg.org/ticket/1357 - // - if (mFormatCtx->pb->buffer != nullptr) + if (mFormatCtx->pb != nullptr) { - av_freep(&mFormatCtx->pb->buffer); - } + // mFormatCtx->pb->buffer must be freed by hand, + // if not, valgrind will show memleak, see: + // + // https://trac.ffmpeg.org/ticket/1357 + // + if (mFormatCtx->pb->buffer != nullptr) + { + av_freep(&mFormatCtx->pb->buffer); + } #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 80, 100) - avio_context_free(&mFormatCtx->pb); + avio_context_free(&mFormatCtx->pb); #else - av_freep(&mFormatCtx->pb); + av_freep(&mFormatCtx->pb); #endif + } + avformat_close_input(&mFormatCtx); } - avformat_close_input(&mFormatCtx); - } - mDataStream.reset(); -} + mDataStream.reset(); + } -std::string FFmpeg_Decoder::getName() -{ + std::string FFmpeg_Decoder::getName() + { // In the FFMpeg 4.0 a "filename" field was replaced by "url" #if LIBAVCODEC_VERSION_INT < 3805796 - return mFormatCtx->filename; + return mFormatCtx->filename; #else - return mFormatCtx->url; + return mFormatCtx->url; #endif -} - -void FFmpeg_Decoder::getInfo(int *samplerate, ChannelConfig *chans, SampleType *type) -{ - if(!mStream) - throw std::runtime_error("No audio stream info"); - - if(mOutputSampleFormat == AV_SAMPLE_FMT_U8) - *type = SampleType_UInt8; - else if(mOutputSampleFormat == AV_SAMPLE_FMT_S16) - *type = SampleType_Int16; - else if(mOutputSampleFormat == AV_SAMPLE_FMT_FLT) - *type = SampleType_Float32; - else - { - mOutputSampleFormat = AV_SAMPLE_FMT_S16; - *type = SampleType_Int16; } - if(mOutputChannelLayout == AV_CH_LAYOUT_MONO) - *chans = ChannelConfig_Mono; - else if(mOutputChannelLayout == AV_CH_LAYOUT_STEREO) - *chans = ChannelConfig_Stereo; - else if(mOutputChannelLayout == AV_CH_LAYOUT_QUAD) - *chans = ChannelConfig_Quad; - else if(mOutputChannelLayout == AV_CH_LAYOUT_5POINT1) - *chans = ChannelConfig_5point1; - else if(mOutputChannelLayout == AV_CH_LAYOUT_7POINT1) - *chans = ChannelConfig_7point1; - else + void FFmpeg_Decoder::getInfo(int* samplerate, ChannelConfig* chans, SampleType* type) { - char str[1024]; - av_get_channel_layout_string(str, sizeof(str), mCodecCtx->channels, mCodecCtx->channel_layout); - Log(Debug::Error) << "Unsupported channel layout: "<< str; - - if(mCodecCtx->channels == 1) + if (!mStream) + throw std::runtime_error("No audio stream info"); + + if (mOutputSampleFormat == AV_SAMPLE_FMT_U8) + *type = SampleType_UInt8; + else if (mOutputSampleFormat == AV_SAMPLE_FMT_S16) + *type = SampleType_Int16; + else if (mOutputSampleFormat == AV_SAMPLE_FMT_FLT) + *type = SampleType_Float32; + else { - mOutputChannelLayout = AV_CH_LAYOUT_MONO; - *chans = ChannelConfig_Mono; + mOutputSampleFormat = AV_SAMPLE_FMT_S16; + *type = SampleType_Int16; } + + if (mOutputChannelLayout == AV_CH_LAYOUT_MONO) + *chans = ChannelConfig_Mono; + else if (mOutputChannelLayout == AV_CH_LAYOUT_STEREO) + *chans = ChannelConfig_Stereo; + else if (mOutputChannelLayout == AV_CH_LAYOUT_QUAD) + *chans = ChannelConfig_Quad; + else if (mOutputChannelLayout == AV_CH_LAYOUT_5POINT1) + *chans = ChannelConfig_5point1; + else if (mOutputChannelLayout == AV_CH_LAYOUT_7POINT1) + *chans = ChannelConfig_7point1; else { - mOutputChannelLayout = AV_CH_LAYOUT_STEREO; - *chans = ChannelConfig_Stereo; + char str[1024]; + av_get_channel_layout_string(str, sizeof(str), mCodecCtx->channels, mCodecCtx->channel_layout); + Log(Debug::Error) << "Unsupported channel layout: " << str; + + if (mCodecCtx->channels == 1) + { + mOutputChannelLayout = AV_CH_LAYOUT_MONO; + *chans = ChannelConfig_Mono; + } + else + { + mOutputChannelLayout = AV_CH_LAYOUT_STEREO; + *chans = ChannelConfig_Stereo; + } } - } - *samplerate = mCodecCtx->sample_rate; - int64_t ch_layout = mCodecCtx->channel_layout; - if(ch_layout == 0) - ch_layout = av_get_default_channel_layout(mCodecCtx->channels); + *samplerate = mCodecCtx->sample_rate; + int64_t ch_layout = mCodecCtx->channel_layout; + if (ch_layout == 0) + ch_layout = av_get_default_channel_layout(mCodecCtx->channels); - if(mOutputSampleFormat != mCodecCtx->sample_fmt || - mOutputChannelLayout != ch_layout) - { - mSwr = swr_alloc_set_opts(mSwr, // SwrContext - mOutputChannelLayout, // output ch layout - mOutputSampleFormat, // output sample format - mCodecCtx->sample_rate, // output sample rate - ch_layout, // input ch layout - mCodecCtx->sample_fmt, // input sample format - mCodecCtx->sample_rate, // input sample rate - 0, // logging level offset - nullptr); // log context - if(!mSwr) - throw std::runtime_error("Couldn't allocate SwrContext"); - int init=swr_init(mSwr); - if(init < 0) - throw std::runtime_error("Couldn't initialize SwrContext: "+std::to_string(init)); + if (mOutputSampleFormat != mCodecCtx->sample_fmt || mOutputChannelLayout != ch_layout) + { + mSwr = swr_alloc_set_opts(mSwr, // SwrContext + mOutputChannelLayout, // output ch layout + mOutputSampleFormat, // output sample format + mCodecCtx->sample_rate, // output sample rate + ch_layout, // input ch layout + mCodecCtx->sample_fmt, // input sample format + mCodecCtx->sample_rate, // input sample rate + 0, // logging level offset + nullptr); // log context + if (!mSwr) + throw std::runtime_error("Couldn't allocate SwrContext"); + int init = swr_init(mSwr); + if (init < 0) + throw std::runtime_error("Couldn't initialize SwrContext: " + std::to_string(init)); + } } -} -size_t FFmpeg_Decoder::read(char *buffer, size_t bytes) -{ - if(!mStream) + size_t FFmpeg_Decoder::read(char* buffer, size_t bytes) { - Log(Debug::Error) << "No audio stream"; - return 0; + if (!mStream) + { + Log(Debug::Error) << "No audio stream"; + return 0; + } + return readAVAudioData(buffer, bytes); } - return readAVAudioData(buffer, bytes); -} -void FFmpeg_Decoder::readAll(std::vector &output) -{ - if(!mStream) + void FFmpeg_Decoder::readAll(std::vector& output) { - Log(Debug::Error) << "No audio stream"; - return; + if (!mStream) + { + Log(Debug::Error) << "No audio stream"; + return; + } + + while (getAVAudioData()) + { + size_t got = mFrame->nb_samples * av_get_channel_layout_nb_channels(mOutputChannelLayout) + * av_get_bytes_per_sample(mOutputSampleFormat); + const char* inbuf = reinterpret_cast(mFrameData[0]); + output.insert(output.end(), inbuf, inbuf + got); + } } - while(getAVAudioData()) + size_t FFmpeg_Decoder::getSampleOffset() { - size_t got = mFrame->nb_samples * av_get_channel_layout_nb_channels(mOutputChannelLayout) * - av_get_bytes_per_sample(mOutputSampleFormat); - const char *inbuf = reinterpret_cast(mFrameData[0]); - output.insert(output.end(), inbuf, inbuf+got); + int delay = (mFrameSize - mFramePos) / av_get_channel_layout_nb_channels(mOutputChannelLayout) + / av_get_bytes_per_sample(mOutputSampleFormat); + return (int)(mNextPts * mCodecCtx->sample_rate) - delay; } -} - -size_t FFmpeg_Decoder::getSampleOffset() -{ - int delay = (mFrameSize-mFramePos) / av_get_channel_layout_nb_channels(mOutputChannelLayout) / - av_get_bytes_per_sample(mOutputSampleFormat); - return (int)(mNextPts*mCodecCtx->sample_rate) - delay; -} -FFmpeg_Decoder::FFmpeg_Decoder(const VFS::Manager* vfs) - : Sound_Decoder(vfs) - , mFormatCtx(nullptr) - , mCodecCtx(nullptr) - , mStream(nullptr) - , mFrame(nullptr) - , mFrameSize(0) - , mFramePos(0) - , mNextPts(0.0) - , mSwr(nullptr) - , mOutputSampleFormat(AV_SAMPLE_FMT_NONE) - , mOutputChannelLayout(0) - , mDataBuf(nullptr) - , mFrameData(nullptr) - , mDataBufLen(0) -{ - memset(&mPacket, 0, sizeof(mPacket)); - - /* We need to make sure ffmpeg is initialized. Optionally silence warning - * output from the lib */ - static bool done_init = false; - if(!done_init) + FFmpeg_Decoder::FFmpeg_Decoder(const VFS::Manager* vfs) + : Sound_Decoder(vfs) + , mFormatCtx(nullptr) + , mCodecCtx(nullptr) + , mStream(nullptr) + , mFrame(nullptr) + , mFrameSize(0) + , mFramePos(0) + , mNextPts(0.0) + , mSwr(nullptr) + , mOutputSampleFormat(AV_SAMPLE_FMT_NONE) + , mOutputChannelLayout(0) + , mDataBuf(nullptr) + , mFrameData(nullptr) + , mDataBufLen(0) { + memset(&mPacket, 0, sizeof(mPacket)); + + /* We need to make sure ffmpeg is initialized. Optionally silence warning + * output from the lib */ + static bool done_init = false; + if (!done_init) + { // This is not needed anymore above FFMpeg version 4.0 #if LIBAVCODEC_VERSION_INT < 3805796 - av_register_all(); + av_register_all(); #endif - av_log_set_level(AV_LOG_ERROR); - done_init = true; + av_log_set_level(AV_LOG_ERROR); + done_init = true; + } } -} -FFmpeg_Decoder::~FFmpeg_Decoder() -{ - close(); -} + FFmpeg_Decoder::~FFmpeg_Decoder() + { + close(); + } } diff --git a/apps/openmw/mwsound/ffmpeg_decoder.hpp b/apps/openmw/mwsound/ffmpeg_decoder.hpp index c51639a972..88dd3316f5 100644 --- a/apps/openmw/mwsound/ffmpeg_decoder.hpp +++ b/apps/openmw/mwsound/ffmpeg_decoder.hpp @@ -4,8 +4,8 @@ #include #if defined(_MSC_VER) - #pragma warning (push) - #pragma warning (disable : 4244) +#pragma warning(push) +#pragma warning(disable : 4244) #endif extern "C" @@ -21,7 +21,7 @@ extern "C" } #if defined(_MSC_VER) - #pragma warning (pop) +#pragma warning(pop) #endif #include @@ -30,53 +30,52 @@ extern "C" #include "sound_decoder.hpp" - namespace MWSound { class FFmpeg_Decoder final : public Sound_Decoder { - AVFormatContext *mFormatCtx; - AVCodecContext *mCodecCtx; - AVStream **mStream; + AVFormatContext* mFormatCtx; + AVCodecContext* mCodecCtx; + AVStream** mStream; AVPacket mPacket; - AVFrame *mFrame; + AVFrame* mFrame; int mFrameSize; int mFramePos; double mNextPts; - SwrContext *mSwr; + SwrContext* mSwr; enum AVSampleFormat mOutputSampleFormat; int64_t mOutputChannelLayout; - uint8_t *mDataBuf; - uint8_t **mFrameData; + uint8_t* mDataBuf; + uint8_t** mFrameData; int mDataBufLen; bool getNextPacket(); Files::IStreamPtr mDataStream; - static int readPacket(void *user_data, uint8_t *buf, int buf_size); - static int writePacket(void *user_data, uint8_t *buf, int buf_size); - static int64_t seek(void *user_data, int64_t offset, int whence); + static int readPacket(void* user_data, uint8_t* buf, int buf_size); + static int writePacket(void* user_data, uint8_t* buf, int buf_size); + static int64_t seek(void* user_data, int64_t offset, int whence); bool getAVAudioData(); - size_t readAVAudioData(void *data, size_t length); + size_t readAVAudioData(void* data, size_t length); - void open(const std::string &fname) override; + void open(const std::string& fname) override; void close() override; std::string getName() override; - void getInfo(int *samplerate, ChannelConfig *chans, SampleType *type) override; + void getInfo(int* samplerate, ChannelConfig* chans, SampleType* type) override; - size_t read(char *buffer, size_t bytes) override; - void readAll(std::vector &output) override; + size_t read(char* buffer, size_t bytes) override; + void readAll(std::vector& output) override; size_t getSampleOffset() override; - FFmpeg_Decoder& operator=(const FFmpeg_Decoder &rhs); - FFmpeg_Decoder(const FFmpeg_Decoder &rhs); + FFmpeg_Decoder& operator=(const FFmpeg_Decoder& rhs); + FFmpeg_Decoder(const FFmpeg_Decoder& rhs); public: explicit FFmpeg_Decoder(const VFS::Manager* vfs); diff --git a/apps/openmw/mwsound/loudness.cpp b/apps/openmw/mwsound/loudness.cpp index ac44d1b40e..6a5c14730f 100644 --- a/apps/openmw/mwsound/loudness.cpp +++ b/apps/openmw/mwsound/loudness.cpp @@ -1,71 +1,69 @@ #include "loudness.hpp" +#include #include #include -#include #include "soundmanagerimp.hpp" namespace MWSound { -void Sound_Loudness::analyzeLoudness(const std::vector< char >& data) -{ - mQueue.insert( mQueue.end(), data.begin(), data.end() ); - if (!mQueue.size()) - return; - - int samplesPerSegment = static_cast(mSampleRate / mSamplesPerSec); - int numSamples = bytesToFrames(mQueue.size(), mChannelConfig, mSampleType); - int advance = framesToBytes(1, mChannelConfig, mSampleType); + void Sound_Loudness::analyzeLoudness(const std::vector& data) + { + mQueue.insert(mQueue.end(), data.begin(), data.end()); + if (!mQueue.size()) + return; + int samplesPerSegment = static_cast(mSampleRate / mSamplesPerSec); + int numSamples = bytesToFrames(mQueue.size(), mChannelConfig, mSampleType); + int advance = framesToBytes(1, mChannelConfig, mSampleType); - int segment=0; - int sample=0; - while (segment < numSamples/samplesPerSegment) - { - float sum=0; - int samplesAdded = 0; - while (sample < numSamples && sample < (segment+1)*samplesPerSegment) + int segment = 0; + int sample = 0; + while (segment < numSamples / samplesPerSegment) { - // get sample on a scale from -1 to 1 - float value = 0; - if (mSampleType == SampleType_UInt8) - value = ((char)(mQueue[sample*advance]^0x80))/128.f; - else if (mSampleType == SampleType_Int16) - { - value = *reinterpret_cast(&mQueue[sample*advance]); - value /= float(std::numeric_limits::max()); - } - else if (mSampleType == SampleType_Float32) + float sum = 0; + int samplesAdded = 0; + while (sample < numSamples && sample < (segment + 1) * samplesPerSegment) { - value = *reinterpret_cast(&mQueue[sample*advance]); - value = std::clamp(value, -1.f, 1.f); // Float samples *should* be scaled to [-1,1] already. + // get sample on a scale from -1 to 1 + float value = 0; + if (mSampleType == SampleType_UInt8) + value = ((char)(mQueue[sample * advance] ^ 0x80)) / 128.f; + else if (mSampleType == SampleType_Int16) + { + value = *reinterpret_cast(&mQueue[sample * advance]); + value /= float(std::numeric_limits::max()); + } + else if (mSampleType == SampleType_Float32) + { + value = *reinterpret_cast(&mQueue[sample * advance]); + value = std::clamp(value, -1.f, 1.f); // Float samples *should* be scaled to [-1,1] already. + } + + sum += value * value; + ++samplesAdded; + ++sample; } - sum += value*value; - ++samplesAdded; - ++sample; + float rms = 0; // root mean square + if (samplesAdded > 0) + rms = std::sqrt(sum / samplesAdded); + mSamples.push_back(rms); + ++segment; } - float rms = 0; // root mean square - if (samplesAdded > 0) - rms = std::sqrt(sum / samplesAdded); - mSamples.push_back(rms); - ++segment; + mQueue.erase(mQueue.begin(), mQueue.begin() + sample * advance); } - mQueue.erase(mQueue.begin(), mQueue.begin() + sample*advance); -} - - -float Sound_Loudness::getLoudnessAtTime(float sec) const -{ - if(mSamplesPerSec <= 0.0f || mSamples.empty() || sec < 0.0f) - return 0.0f; + float Sound_Loudness::getLoudnessAtTime(float sec) const + { + if (mSamplesPerSec <= 0.0f || mSamples.empty() || sec < 0.0f) + return 0.0f; - size_t index = std::clamp(sec * mSamplesPerSec, 0, mSamples.size() - 1); - return mSamples[index]; -} + size_t index = std::clamp(sec * mSamplesPerSec, 0, mSamples.size() - 1); + return mSamples[index]; + } } diff --git a/apps/openmw/mwsound/loudness.hpp b/apps/openmw/mwsound/loudness.hpp index 939d83dee3..1800ec246f 100644 --- a/apps/openmw/mwsound/loudness.hpp +++ b/apps/openmw/mwsound/loudness.hpp @@ -1,56 +1,59 @@ #ifndef GAME_SOUND_LOUDNESS_H #define GAME_SOUND_LOUDNESS_H -#include #include +#include #include "sound_decoder.hpp" namespace MWSound { -class Sound_Loudness { - float mSamplesPerSec; - int mSampleRate; - ChannelConfig mChannelConfig; - SampleType mSampleType; - - // Loudness sample info - std::vector mSamples; - - std::deque mQueue; - -public: - /** - * @param samplesPerSecond How many loudness values per second of audio to compute. - * @param sampleRate the sample rate of the sound buffer - * @param chans channel layout of the buffer - * @param type sample type of the buffer - */ - Sound_Loudness(float samplesPerSecond, int sampleRate, ChannelConfig chans, SampleType type) - : mSamplesPerSec(samplesPerSecond) - , mSampleRate(sampleRate) - , mChannelConfig(chans) - , mSampleType(type) - { } - - /** - * Analyzes the energy (closely related to loudness) of a sound buffer. - * The buffer will be divided into segments according to \a valuesPerSecond, - * and for each segment a loudness value in the range of [0,1] will be computed. - * The computed values are then added to the mSamples vector. This method should be called continuously - * with chunks of audio until the whole audio file is processed. - * If the size of \a data does not exactly fit a number of loudness samples, the remainder - * will be kept in the mQueue and used in the next call to analyzeLoudness. - * @param data the sound buffer to analyze, containing raw samples - */ - void analyzeLoudness(const std::vector& data); - - /** - * Get loudness at a particular time. Before calling this, the stream has to be analyzed up to that point in time (see analyzeLoudness()). - */ - float getLoudnessAtTime(float sec) const; -}; + class Sound_Loudness + { + float mSamplesPerSec; + int mSampleRate; + ChannelConfig mChannelConfig; + SampleType mSampleType; + + // Loudness sample info + std::vector mSamples; + + std::deque mQueue; + + public: + /** + * @param samplesPerSecond How many loudness values per second of audio to compute. + * @param sampleRate the sample rate of the sound buffer + * @param chans channel layout of the buffer + * @param type sample type of the buffer + */ + Sound_Loudness(float samplesPerSecond, int sampleRate, ChannelConfig chans, SampleType type) + : mSamplesPerSec(samplesPerSecond) + , mSampleRate(sampleRate) + , mChannelConfig(chans) + , mSampleType(type) + { + } + + /** + * Analyzes the energy (closely related to loudness) of a sound buffer. + * The buffer will be divided into segments according to \a valuesPerSecond, + * and for each segment a loudness value in the range of [0,1] will be computed. + * The computed values are then added to the mSamples vector. This method should be called continuously + * with chunks of audio until the whole audio file is processed. + * If the size of \a data does not exactly fit a number of loudness samples, the remainder + * will be kept in the mQueue and used in the next call to analyzeLoudness. + * @param data the sound buffer to analyze, containing raw samples + */ + void analyzeLoudness(const std::vector& data); + + /** + * Get loudness at a particular time. Before calling this, the stream has to be analyzed up to that point in + * time (see analyzeLoudness()). + */ + float getLoudnessAtTime(float sec) const; + }; } diff --git a/apps/openmw/mwsound/movieaudiofactory.cpp b/apps/openmw/mwsound/movieaudiofactory.cpp index aef8f7fe93..b770a9ffcc 100644 --- a/apps/openmw/mwsound/movieaudiofactory.cpp +++ b/apps/openmw/mwsound/movieaudiofactory.cpp @@ -6,8 +6,8 @@ #include "../mwbase/environment.hpp" #include "../mwbase/soundmanager.hpp" -#include "sound_decoder.hpp" #include "sound.hpp" +#include "sound_decoder.hpp" namespace MWSound { @@ -25,42 +25,40 @@ namespace MWSound private: MWSound::MovieAudioDecoder* mDecoder; - void open(const std::string &fname) override; + void open(const std::string& fname) override; void close() override; std::string getName() override; - void getInfo(int *samplerate, ChannelConfig *chans, SampleType *type) override; - size_t read(char *buffer, size_t bytes) override; + void getInfo(int* samplerate, ChannelConfig* chans, SampleType* type) override; + size_t read(char* buffer, size_t bytes) override; size_t getSampleOffset() override; }; class MovieAudioDecoder : public Video::MovieAudioDecoder { public: - MovieAudioDecoder(Video::VideoState *videoState) - : Video::MovieAudioDecoder(videoState), mAudioTrack(nullptr) + MovieAudioDecoder(Video::VideoState* videoState) + : Video::MovieAudioDecoder(videoState) + , mAudioTrack(nullptr) , mDecoderBridge(std::make_shared(this)) { } size_t getSampleOffset() { - ssize_t clock_delay = (mFrameSize-mFramePos) / av_get_channel_layout_nb_channels(mOutputChannelLayout) / - av_get_bytes_per_sample(mOutputSampleFormat); - return (size_t)(mAudioClock*mAudioContext->sample_rate) - clock_delay; + ssize_t clock_delay = (mFrameSize - mFramePos) / av_get_channel_layout_nb_channels(mOutputChannelLayout) + / av_get_bytes_per_sample(mOutputSampleFormat); + return (size_t)(mAudioClock * mAudioContext->sample_rate) - clock_delay; } - std::string getStreamName() - { - return std::string(); - } + std::string getStreamName() { return std::string(); } private: // MovieAudioDecoder overrides double getAudioClock() override { - return (double)getSampleOffset()/(double)mAudioContext->sample_rate - - MWBase::Environment::get().getSoundManager()->getTrackTimeDelay(mAudioTrack); + return (double)getSampleOffset() / (double)mAudioContext->sample_rate + - MWBase::Environment::get().getSoundManager()->getTrackTimeDelay(mAudioTrack); } void adjustAudioSettings(AVSampleFormat& sampleFormat, uint64_t& channelLayout, int& sampleRate) override @@ -75,28 +73,26 @@ namespace MWSound sampleFormat = AV_SAMPLE_FMT_S16; if (channelLayout == AV_CH_LAYOUT_5POINT1 || channelLayout == AV_CH_LAYOUT_7POINT1 - || channelLayout == AV_CH_LAYOUT_QUAD) // FIXME: check for AL_EXT_MCFORMATS support + || channelLayout == AV_CH_LAYOUT_QUAD) // FIXME: check for AL_EXT_MCFORMATS support channelLayout = AV_CH_LAYOUT_STEREO; - else if (channelLayout != AV_CH_LAYOUT_MONO - && channelLayout != AV_CH_LAYOUT_STEREO) + else if (channelLayout != AV_CH_LAYOUT_MONO && channelLayout != AV_CH_LAYOUT_STEREO) channelLayout = AV_CH_LAYOUT_STEREO; } public: ~MovieAudioDecoder() { - if(mAudioTrack) + if (mAudioTrack) MWBase::Environment::get().getSoundManager()->stopTrack(mAudioTrack); mAudioTrack = nullptr; mDecoderBridge.reset(); } - MWBase::SoundStream *mAudioTrack; + MWBase::SoundStream* mAudioTrack; std::shared_ptr mDecoderBridge; }; - - void MWSoundDecoderBridge::open(const std::string &fname) + void MWSoundDecoderBridge::open(const std::string& fname) { throw std::runtime_error("Method not implemented"); } @@ -107,7 +103,7 @@ namespace MWSound return mDecoder->getStreamName(); } - void MWSoundDecoderBridge::getInfo(int *samplerate, ChannelConfig *chans, SampleType *type) + void MWSoundDecoderBridge::getInfo(int* samplerate, ChannelConfig* chans, SampleType* type) { *samplerate = mDecoder->getOutputSampleRate(); @@ -123,8 +119,7 @@ namespace MWSound else if (outputChannelLayout == AV_CH_LAYOUT_QUAD) *chans = ChannelConfig_Quad; else - throw std::runtime_error("Unsupported channel layout: "+ - std::to_string(outputChannelLayout)); + throw std::runtime_error("Unsupported channel layout: " + std::to_string(outputChannelLayout)); AVSampleFormat outputSampleFormat = mDecoder->getOutputSampleFormat(); if (outputSampleFormat == AV_SAMPLE_FMT_U8) @@ -137,11 +132,11 @@ namespace MWSound { char str[1024]; av_get_sample_fmt_string(str, sizeof(str), outputSampleFormat); - throw std::runtime_error(std::string("Unsupported sample format: ")+str); + throw std::runtime_error(std::string("Unsupported sample format: ") + str); } } - size_t MWSoundDecoderBridge::read(char *buffer, size_t bytes) + size_t MWSoundDecoderBridge::read(char* buffer, size_t bytes) { return mDecoder->read(buffer, bytes); } @@ -151,15 +146,13 @@ namespace MWSound return mDecoder->getSampleOffset(); } - - std::unique_ptr MovieAudioFactory::createDecoder(Video::VideoState* videoState) { auto decoder = std::make_unique(videoState); decoder->setupFormat(); - MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); - MWBase::SoundStream *sound = sndMgr->playTrack(decoder->mDecoderBridge, MWSound::Type::Movie); + MWBase::SoundManager* sndMgr = MWBase::Environment::get().getSoundManager(); + MWBase::SoundStream* sound = sndMgr->playTrack(decoder->mDecoderBridge, MWSound::Type::Movie); if (!sound) { decoder.reset(); diff --git a/apps/openmw/mwsound/openal_output.cpp b/apps/openmw/mwsound/openal_output.cpp index 47f90bbcf3..a1679d0501 100644 --- a/apps/openmw/mwsound/openal_output.cpp +++ b/apps/openmw/mwsound/openal_output.cpp @@ -1,12 +1,12 @@ #include -#include -#include -#include #include #include +#include #include +#include +#include #include -#include +#include #include @@ -15,11 +15,11 @@ #include #include +#include "loudness.hpp" #include "openal_output.hpp" -#include "sound_decoder.hpp" #include "sound.hpp" +#include "sound_decoder.hpp" #include "soundmanagerimp.hpp" -#include "loudness.hpp" #include "efx-presets.h" @@ -27,1493 +27,1512 @@ #define ALC_ALL_DEVICES_SPECIFIER 0x1013 #endif - #define MAKE_PTRID(id) ((void*)(uintptr_t)id) #define GET_PTRID(ptr) ((ALuint)(uintptr_t)ptr) namespace { -const int sLoudnessFPS = 20; // loudness values per second of audio + const int sLoudnessFPS = 20; // loudness values per second of audio -ALCenum checkALCError(ALCdevice *device, const char *func, int line) -{ - ALCenum err = alcGetError(device); - if(err != ALC_NO_ERROR) - Log(Debug::Error) << "ALC error "<< alcGetString(device, err) << " (" << err << ") @ " << func << ":" << line; - return err; -} + ALCenum checkALCError(ALCdevice* device, const char* func, int line) + { + ALCenum err = alcGetError(device); + if (err != ALC_NO_ERROR) + Log(Debug::Error) << "ALC error " << alcGetString(device, err) << " (" << err << ") @ " << func << ":" + << line; + return err; + } #define getALCError(d) checkALCError((d), __FUNCTION__, __LINE__) -ALenum checkALError(const char *func, int line) -{ - ALenum err = alGetError(); - if(err != AL_NO_ERROR) - Log(Debug::Error) << "AL error " << alGetString(err) << " (" << err << ") @ " << func << ":" << line; - return err; -} + ALenum checkALError(const char* func, int line) + { + ALenum err = alGetError(); + if (err != AL_NO_ERROR) + Log(Debug::Error) << "AL error " << alGetString(err) << " (" << err << ") @ " << func << ":" << line; + return err; + } #define getALError() checkALError(__FUNCTION__, __LINE__) -// Helper to get an OpenAL extension function -template -void convertPointer(T& dest, R src) -{ - memcpy(&dest, &src, sizeof(src)); -} - -template -void getALCFunc(T& func, ALCdevice *device, const char *name) -{ - void* funcPtr = alcGetProcAddress(device, name); - convertPointer(func, funcPtr); -} - -template -void getALFunc(T& func, const char *name) -{ - void* funcPtr = alGetProcAddress(name); - convertPointer(func, funcPtr); -} + // Helper to get an OpenAL extension function + template + void convertPointer(T& dest, R src) + { + memcpy(&dest, &src, sizeof(src)); + } -// Effect objects -LPALGENEFFECTS alGenEffects; -LPALDELETEEFFECTS alDeleteEffects; -LPALISEFFECT alIsEffect; -LPALEFFECTI alEffecti; -LPALEFFECTIV alEffectiv; -LPALEFFECTF alEffectf; -LPALEFFECTFV alEffectfv; -LPALGETEFFECTI alGetEffecti; -LPALGETEFFECTIV alGetEffectiv; -LPALGETEFFECTF alGetEffectf; -LPALGETEFFECTFV alGetEffectfv; -// Filter objects -LPALGENFILTERS alGenFilters; -LPALDELETEFILTERS alDeleteFilters; -LPALISFILTER alIsFilter; -LPALFILTERI alFilteri; -LPALFILTERIV alFilteriv; -LPALFILTERF alFilterf; -LPALFILTERFV alFilterfv; -LPALGETFILTERI alGetFilteri; -LPALGETFILTERIV alGetFilteriv; -LPALGETFILTERF alGetFilterf; -LPALGETFILTERFV alGetFilterfv; -// Auxiliary slot objects -LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots; -LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots; -LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot; -LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti; -LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv; -LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf; -LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv; -LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti; -LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv; -LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf; -LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv; - - -void LoadEffect(ALuint effect, const EFXEAXREVERBPROPERTIES &props) -{ - ALint type = AL_NONE; - alGetEffecti(effect, AL_EFFECT_TYPE, &type); - if(type == AL_EFFECT_EAXREVERB) + template + void getALCFunc(T& func, ALCdevice* device, const char* name) { - alEffectf(effect, AL_EAXREVERB_DIFFUSION, props.flDiffusion); - alEffectf(effect, AL_EAXREVERB_DENSITY, props.flDensity); - alEffectf(effect, AL_EAXREVERB_GAIN, props.flGain); - alEffectf(effect, AL_EAXREVERB_GAINHF, props.flGainHF); - alEffectf(effect, AL_EAXREVERB_GAINLF, props.flGainLF); - alEffectf(effect, AL_EAXREVERB_DECAY_TIME, props.flDecayTime); - alEffectf(effect, AL_EAXREVERB_DECAY_HFRATIO, props.flDecayHFRatio); - alEffectf(effect, AL_EAXREVERB_DECAY_LFRATIO, props.flDecayLFRatio); - alEffectf(effect, AL_EAXREVERB_REFLECTIONS_GAIN, props.flReflectionsGain); - alEffectf(effect, AL_EAXREVERB_REFLECTIONS_DELAY, props.flReflectionsDelay); - alEffectfv(effect, AL_EAXREVERB_REFLECTIONS_PAN, props.flReflectionsPan); - alEffectf(effect, AL_EAXREVERB_LATE_REVERB_GAIN, props.flLateReverbGain); - alEffectf(effect, AL_EAXREVERB_LATE_REVERB_DELAY, props.flLateReverbDelay); - alEffectfv(effect, AL_EAXREVERB_LATE_REVERB_PAN, props.flLateReverbPan); - alEffectf(effect, AL_EAXREVERB_ECHO_TIME, props.flEchoTime); - alEffectf(effect, AL_EAXREVERB_ECHO_DEPTH, props.flEchoDepth); - alEffectf(effect, AL_EAXREVERB_MODULATION_TIME, props.flModulationTime); - alEffectf(effect, AL_EAXREVERB_MODULATION_DEPTH, props.flModulationDepth); - alEffectf(effect, AL_EAXREVERB_AIR_ABSORPTION_GAINHF, props.flAirAbsorptionGainHF); - alEffectf(effect, AL_EAXREVERB_HFREFERENCE, props.flHFReference); - alEffectf(effect, AL_EAXREVERB_LFREFERENCE, props.flLFReference); - alEffectf(effect, AL_EAXREVERB_ROOM_ROLLOFF_FACTOR, props.flRoomRolloffFactor); - alEffecti(effect, AL_EAXREVERB_DECAY_HFLIMIT, props.iDecayHFLimit ? AL_TRUE : AL_FALSE); + void* funcPtr = alcGetProcAddress(device, name); + convertPointer(func, funcPtr); } - else if(type == AL_EFFECT_REVERB) + + template + void getALFunc(T& func, const char* name) + { + void* funcPtr = alGetProcAddress(name); + convertPointer(func, funcPtr); + } + + // Effect objects + LPALGENEFFECTS alGenEffects; + LPALDELETEEFFECTS alDeleteEffects; + LPALISEFFECT alIsEffect; + LPALEFFECTI alEffecti; + LPALEFFECTIV alEffectiv; + LPALEFFECTF alEffectf; + LPALEFFECTFV alEffectfv; + LPALGETEFFECTI alGetEffecti; + LPALGETEFFECTIV alGetEffectiv; + LPALGETEFFECTF alGetEffectf; + LPALGETEFFECTFV alGetEffectfv; + // Filter objects + LPALGENFILTERS alGenFilters; + LPALDELETEFILTERS alDeleteFilters; + LPALISFILTER alIsFilter; + LPALFILTERI alFilteri; + LPALFILTERIV alFilteriv; + LPALFILTERF alFilterf; + LPALFILTERFV alFilterfv; + LPALGETFILTERI alGetFilteri; + LPALGETFILTERIV alGetFilteriv; + LPALGETFILTERF alGetFilterf; + LPALGETFILTERFV alGetFilterfv; + // Auxiliary slot objects + LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots; + LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots; + LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot; + LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti; + LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv; + LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf; + LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv; + LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti; + LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv; + LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf; + LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv; + + void LoadEffect(ALuint effect, const EFXEAXREVERBPROPERTIES& props) { - alEffectf(effect, AL_REVERB_DIFFUSION, props.flDiffusion); - alEffectf(effect, AL_REVERB_DENSITY, props.flDensity); - alEffectf(effect, AL_REVERB_GAIN, props.flGain); - alEffectf(effect, AL_REVERB_GAINHF, props.flGainHF); - alEffectf(effect, AL_REVERB_DECAY_TIME, props.flDecayTime); - alEffectf(effect, AL_REVERB_DECAY_HFRATIO, props.flDecayHFRatio); - alEffectf(effect, AL_REVERB_REFLECTIONS_GAIN, props.flReflectionsGain); - alEffectf(effect, AL_REVERB_REFLECTIONS_DELAY, props.flReflectionsDelay); - alEffectf(effect, AL_REVERB_LATE_REVERB_GAIN, props.flLateReverbGain); - alEffectf(effect, AL_REVERB_LATE_REVERB_DELAY, props.flLateReverbDelay); - alEffectf(effect, AL_REVERB_AIR_ABSORPTION_GAINHF, props.flAirAbsorptionGainHF); - alEffectf(effect, AL_REVERB_ROOM_ROLLOFF_FACTOR, props.flRoomRolloffFactor); - alEffecti(effect, AL_REVERB_DECAY_HFLIMIT, props.iDecayHFLimit ? AL_TRUE : AL_FALSE); + ALint type = AL_NONE; + alGetEffecti(effect, AL_EFFECT_TYPE, &type); + if (type == AL_EFFECT_EAXREVERB) + { + alEffectf(effect, AL_EAXREVERB_DIFFUSION, props.flDiffusion); + alEffectf(effect, AL_EAXREVERB_DENSITY, props.flDensity); + alEffectf(effect, AL_EAXREVERB_GAIN, props.flGain); + alEffectf(effect, AL_EAXREVERB_GAINHF, props.flGainHF); + alEffectf(effect, AL_EAXREVERB_GAINLF, props.flGainLF); + alEffectf(effect, AL_EAXREVERB_DECAY_TIME, props.flDecayTime); + alEffectf(effect, AL_EAXREVERB_DECAY_HFRATIO, props.flDecayHFRatio); + alEffectf(effect, AL_EAXREVERB_DECAY_LFRATIO, props.flDecayLFRatio); + alEffectf(effect, AL_EAXREVERB_REFLECTIONS_GAIN, props.flReflectionsGain); + alEffectf(effect, AL_EAXREVERB_REFLECTIONS_DELAY, props.flReflectionsDelay); + alEffectfv(effect, AL_EAXREVERB_REFLECTIONS_PAN, props.flReflectionsPan); + alEffectf(effect, AL_EAXREVERB_LATE_REVERB_GAIN, props.flLateReverbGain); + alEffectf(effect, AL_EAXREVERB_LATE_REVERB_DELAY, props.flLateReverbDelay); + alEffectfv(effect, AL_EAXREVERB_LATE_REVERB_PAN, props.flLateReverbPan); + alEffectf(effect, AL_EAXREVERB_ECHO_TIME, props.flEchoTime); + alEffectf(effect, AL_EAXREVERB_ECHO_DEPTH, props.flEchoDepth); + alEffectf(effect, AL_EAXREVERB_MODULATION_TIME, props.flModulationTime); + alEffectf(effect, AL_EAXREVERB_MODULATION_DEPTH, props.flModulationDepth); + alEffectf(effect, AL_EAXREVERB_AIR_ABSORPTION_GAINHF, props.flAirAbsorptionGainHF); + alEffectf(effect, AL_EAXREVERB_HFREFERENCE, props.flHFReference); + alEffectf(effect, AL_EAXREVERB_LFREFERENCE, props.flLFReference); + alEffectf(effect, AL_EAXREVERB_ROOM_ROLLOFF_FACTOR, props.flRoomRolloffFactor); + alEffecti(effect, AL_EAXREVERB_DECAY_HFLIMIT, props.iDecayHFLimit ? AL_TRUE : AL_FALSE); + } + else if (type == AL_EFFECT_REVERB) + { + alEffectf(effect, AL_REVERB_DIFFUSION, props.flDiffusion); + alEffectf(effect, AL_REVERB_DENSITY, props.flDensity); + alEffectf(effect, AL_REVERB_GAIN, props.flGain); + alEffectf(effect, AL_REVERB_GAINHF, props.flGainHF); + alEffectf(effect, AL_REVERB_DECAY_TIME, props.flDecayTime); + alEffectf(effect, AL_REVERB_DECAY_HFRATIO, props.flDecayHFRatio); + alEffectf(effect, AL_REVERB_REFLECTIONS_GAIN, props.flReflectionsGain); + alEffectf(effect, AL_REVERB_REFLECTIONS_DELAY, props.flReflectionsDelay); + alEffectf(effect, AL_REVERB_LATE_REVERB_GAIN, props.flLateReverbGain); + alEffectf(effect, AL_REVERB_LATE_REVERB_DELAY, props.flLateReverbDelay); + alEffectf(effect, AL_REVERB_AIR_ABSORPTION_GAINHF, props.flAirAbsorptionGainHF); + alEffectf(effect, AL_REVERB_ROOM_ROLLOFF_FACTOR, props.flRoomRolloffFactor); + alEffecti(effect, AL_REVERB_DECAY_HFLIMIT, props.iDecayHFLimit ? AL_TRUE : AL_FALSE); + } + getALError(); } - getALError(); -} } namespace MWSound { -static ALenum getALFormat(ChannelConfig chans, SampleType type) -{ - struct FormatEntry { - ALenum format; - ChannelConfig chans; - SampleType type; - }; - struct FormatEntryExt { - const char name[32]; - ChannelConfig chans; - SampleType type; - }; - static const std::array fmtlist{{ - { AL_FORMAT_MONO16, ChannelConfig_Mono, SampleType_Int16 }, - { AL_FORMAT_MONO8, ChannelConfig_Mono, SampleType_UInt8 }, - { AL_FORMAT_STEREO16, ChannelConfig_Stereo, SampleType_Int16 }, - { AL_FORMAT_STEREO8, ChannelConfig_Stereo, SampleType_UInt8 }, - }}; - - for(auto &fmt : fmtlist) - { - if(fmt.chans == chans && fmt.type == type) - return fmt.format; - } - - if(alIsExtensionPresent("AL_EXT_MCFORMATS")) + static ALenum getALFormat(ChannelConfig chans, SampleType type) { - static const std::array mcfmtlist{{ - { "AL_FORMAT_QUAD16", ChannelConfig_Quad, SampleType_Int16 }, - { "AL_FORMAT_QUAD8", ChannelConfig_Quad, SampleType_UInt8 }, - { "AL_FORMAT_51CHN16", ChannelConfig_5point1, SampleType_Int16 }, - { "AL_FORMAT_51CHN8", ChannelConfig_5point1, SampleType_UInt8 }, - { "AL_FORMAT_71CHN16", ChannelConfig_7point1, SampleType_Int16 }, - { "AL_FORMAT_71CHN8", ChannelConfig_7point1, SampleType_UInt8 }, - }}; - - for(auto &fmt : mcfmtlist) - { - if(fmt.chans == chans && fmt.type == type) - { - ALenum format = alGetEnumValue(fmt.name); - if(format != 0 && format != -1) - return format; - } + struct FormatEntry + { + ALenum format; + ChannelConfig chans; + SampleType type; + }; + struct FormatEntryExt + { + const char name[32]; + ChannelConfig chans; + SampleType type; + }; + static const std::array fmtlist{ { + { AL_FORMAT_MONO16, ChannelConfig_Mono, SampleType_Int16 }, + { AL_FORMAT_MONO8, ChannelConfig_Mono, SampleType_UInt8 }, + { AL_FORMAT_STEREO16, ChannelConfig_Stereo, SampleType_Int16 }, + { AL_FORMAT_STEREO8, ChannelConfig_Stereo, SampleType_UInt8 }, + } }; + + for (auto& fmt : fmtlist) + { + if (fmt.chans == chans && fmt.type == type) + return fmt.format; } - } - if(alIsExtensionPresent("AL_EXT_FLOAT32")) - { - static const std::array fltfmtlist{{ - { "AL_FORMAT_MONO_FLOAT32", ChannelConfig_Mono, SampleType_Float32 }, - { "AL_FORMAT_STEREO_FLOAT32", ChannelConfig_Stereo, SampleType_Float32 }, - }}; - for(auto &fmt : fltfmtlist) + if (alIsExtensionPresent("AL_EXT_MCFORMATS")) { - if(fmt.chans == chans && fmt.type == type) + static const std::array mcfmtlist{ { + { "AL_FORMAT_QUAD16", ChannelConfig_Quad, SampleType_Int16 }, + { "AL_FORMAT_QUAD8", ChannelConfig_Quad, SampleType_UInt8 }, + { "AL_FORMAT_51CHN16", ChannelConfig_5point1, SampleType_Int16 }, + { "AL_FORMAT_51CHN8", ChannelConfig_5point1, SampleType_UInt8 }, + { "AL_FORMAT_71CHN16", ChannelConfig_7point1, SampleType_Int16 }, + { "AL_FORMAT_71CHN8", ChannelConfig_7point1, SampleType_UInt8 }, + } }; + + for (auto& fmt : mcfmtlist) { - ALenum format = alGetEnumValue(fmt.name); - if(format != 0 && format != -1) - return format; + if (fmt.chans == chans && fmt.type == type) + { + ALenum format = alGetEnumValue(fmt.name); + if (format != 0 && format != -1) + return format; + } } } - - if(alIsExtensionPresent("AL_EXT_MCFORMATS")) + if (alIsExtensionPresent("AL_EXT_FLOAT32")) { - static const std::array fltmcfmtlist{{ - { "AL_FORMAT_QUAD32", ChannelConfig_Quad, SampleType_Float32 }, - { "AL_FORMAT_51CHN32", ChannelConfig_5point1, SampleType_Float32 }, - { "AL_FORMAT_71CHN32", ChannelConfig_7point1, SampleType_Float32 }, - }}; + static const std::array fltfmtlist{ { + { "AL_FORMAT_MONO_FLOAT32", ChannelConfig_Mono, SampleType_Float32 }, + { "AL_FORMAT_STEREO_FLOAT32", ChannelConfig_Stereo, SampleType_Float32 }, + } }; - for(auto &fmt : fltmcfmtlist) + for (auto& fmt : fltfmtlist) { - if(fmt.chans == chans && fmt.type == type) + if (fmt.chans == chans && fmt.type == type) { ALenum format = alGetEnumValue(fmt.name); - if(format != 0 && format != -1) + if (format != 0 && format != -1) return format; } } + + if (alIsExtensionPresent("AL_EXT_MCFORMATS")) + { + static const std::array fltmcfmtlist{ { + { "AL_FORMAT_QUAD32", ChannelConfig_Quad, SampleType_Float32 }, + { "AL_FORMAT_51CHN32", ChannelConfig_5point1, SampleType_Float32 }, + { "AL_FORMAT_71CHN32", ChannelConfig_7point1, SampleType_Float32 }, + } }; + + for (auto& fmt : fltmcfmtlist) + { + if (fmt.chans == chans && fmt.type == type) + { + ALenum format = alGetEnumValue(fmt.name); + if (format != 0 && format != -1) + return format; + } + } + } } - } - Log(Debug::Warning) << "Unsupported sound format (" << getChannelConfigName(chans) << ", " << getSampleTypeName(type) << ")"; - return AL_NONE; -} + Log(Debug::Warning) << "Unsupported sound format (" << getChannelConfigName(chans) << ", " + << getSampleTypeName(type) << ")"; + return AL_NONE; + } + // + // A streaming OpenAL sound. + // + class OpenAL_SoundStream + { + static const ALfloat sBufferLength; -// -// A streaming OpenAL sound. -// -class OpenAL_SoundStream -{ - static const ALfloat sBufferLength; + private: + ALuint mSource; -private: - ALuint mSource; + std::array mBuffers; + ALint mCurrentBufIdx; - std::array mBuffers; - ALint mCurrentBufIdx; + ALenum mFormat; + ALsizei mSampleRate; + ALuint mBufferSize; + ALuint mFrameSize; + ALint mSilence; - ALenum mFormat; - ALsizei mSampleRate; - ALuint mBufferSize; - ALuint mFrameSize; - ALint mSilence; + DecoderPtr mDecoder; - DecoderPtr mDecoder; + std::unique_ptr mLoudnessAnalyzer; - std::unique_ptr mLoudnessAnalyzer; + std::atomic mIsFinished; - std::atomic mIsFinished; + void updateAll(bool local); - void updateAll(bool local); + OpenAL_SoundStream(const OpenAL_SoundStream& rhs); + OpenAL_SoundStream& operator=(const OpenAL_SoundStream& rhs); - OpenAL_SoundStream(const OpenAL_SoundStream &rhs); - OpenAL_SoundStream& operator=(const OpenAL_SoundStream &rhs); + friend class OpenAL_Output; - friend class OpenAL_Output; + public: + OpenAL_SoundStream(ALuint src, DecoderPtr decoder); + ~OpenAL_SoundStream(); -public: - OpenAL_SoundStream(ALuint src, DecoderPtr decoder); - ~OpenAL_SoundStream(); + bool init(bool getLoudnessData = false); - bool init(bool getLoudnessData=false); + bool isPlaying(); + double getStreamDelay() const; + double getStreamOffset() const; - bool isPlaying(); - double getStreamDelay() const; - double getStreamOffset() const; + float getCurrentLoudness() const; - float getCurrentLoudness() const; + bool process(); + ALint refillQueue(); + }; + const ALfloat OpenAL_SoundStream::sBufferLength = 0.125f; - bool process(); - ALint refillQueue(); -}; -const ALfloat OpenAL_SoundStream::sBufferLength = 0.125f; + // + // A background streaming thread (keeps active streams processed) + // + struct OpenAL_Output::StreamThread + { + typedef std::vector StreamVec; + StreamVec mStreams; + std::atomic mQuitNow; + std::mutex mMutex; + std::condition_variable mCondVar; + std::thread mThread; -// -// A background streaming thread (keeps active streams processed) -// -struct OpenAL_Output::StreamThread -{ - typedef std::vector StreamVec; - StreamVec mStreams; + StreamThread() + : mQuitNow(false) + , mThread([this] { run(); }) + { + } + ~StreamThread() + { + mQuitNow = true; + mMutex.lock(); + mMutex.unlock(); + mCondVar.notify_all(); + mThread.join(); + } - std::atomic mQuitNow; - std::mutex mMutex; - std::condition_variable mCondVar; - std::thread mThread; + // thread entry point + void run() + { + std::unique_lock lock(mMutex); + while (!mQuitNow) + { + StreamVec::iterator iter = mStreams.begin(); + while (iter != mStreams.end()) + { + if ((*iter)->process() == false) + iter = mStreams.erase(iter); + else + ++iter; + } - StreamThread() - : mQuitNow(false) - , mThread([this] { run(); }) - { - } - ~StreamThread() - { - mQuitNow = true; - mMutex.lock(); mMutex.unlock(); - mCondVar.notify_all(); - mThread.join(); - } + mCondVar.wait_for(lock, std::chrono::milliseconds(50)); + } + } - // thread entry point - void run() - { - std::unique_lock lock(mMutex); - while(!mQuitNow) + void add(OpenAL_SoundStream* stream) { - StreamVec::iterator iter = mStreams.begin(); - while(iter != mStreams.end()) + std::lock_guard lock(mMutex); + if (std::find(mStreams.begin(), mStreams.end(), stream) == mStreams.end()) { - if((*iter)->process() == false) - iter = mStreams.erase(iter); - else - ++iter; + mStreams.push_back(stream); + mCondVar.notify_all(); } + } - mCondVar.wait_for(lock, std::chrono::milliseconds(50)); + void remove(OpenAL_SoundStream* stream) + { + std::lock_guard lock(mMutex); + StreamVec::iterator iter = std::find(mStreams.begin(), mStreams.end(), stream); + if (iter != mStreams.end()) + mStreams.erase(iter); } - } - void add(OpenAL_SoundStream *stream) - { - std::lock_guard lock(mMutex); - if(std::find(mStreams.begin(), mStreams.end(), stream) == mStreams.end()) + void removeAll() { - mStreams.push_back(stream); - mCondVar.notify_all(); + std::lock_guard lock(mMutex); + mStreams.clear(); } - } - void remove(OpenAL_SoundStream *stream) - { - std::lock_guard lock(mMutex); - StreamVec::iterator iter = std::find(mStreams.begin(), mStreams.end(), stream); - if(iter != mStreams.end()) mStreams.erase(iter); - } + private: + StreamThread(const StreamThread& rhs); + StreamThread& operator=(const StreamThread& rhs); + }; - void removeAll() + OpenAL_SoundStream::OpenAL_SoundStream(ALuint src, DecoderPtr decoder) + : mSource(src) + , mCurrentBufIdx(0) + , mFormat(AL_NONE) + , mSampleRate(0) + , mBufferSize(0) + , mFrameSize(0) + , mSilence(0) + , mDecoder(std::move(decoder)) + , mLoudnessAnalyzer(nullptr) + , mIsFinished(true) { - std::lock_guard lock(mMutex); - mStreams.clear(); + mBuffers.fill(0); } -private: - StreamThread(const StreamThread &rhs); - StreamThread& operator=(const StreamThread &rhs); -}; - - -OpenAL_SoundStream::OpenAL_SoundStream(ALuint src, DecoderPtr decoder) - : mSource(src), mCurrentBufIdx(0), mFormat(AL_NONE), mSampleRate(0) - , mBufferSize(0), mFrameSize(0), mSilence(0), mDecoder(std::move(decoder)) - , mLoudnessAnalyzer(nullptr), mIsFinished(true) -{ - mBuffers.fill(0); -} - -OpenAL_SoundStream::~OpenAL_SoundStream() -{ - if(mBuffers[0] && alIsBuffer(mBuffers[0])) - alDeleteBuffers(mBuffers.size(), mBuffers.data()); - alGetError(); - - mDecoder->close(); -} - -bool OpenAL_SoundStream::init(bool getLoudnessData) -{ - alGenBuffers(mBuffers.size(), mBuffers.data()); - ALenum err = getALError(); - if(err != AL_NO_ERROR) - return false; - - ChannelConfig chans; - SampleType type; - - try { - mDecoder->getInfo(&mSampleRate, &chans, &type); - mFormat = getALFormat(chans, type); - } - catch(std::exception &e) + OpenAL_SoundStream::~OpenAL_SoundStream() { - Log(Debug::Error) << "Failed to get stream info: " << e.what(); - return false; + if (mBuffers[0] && alIsBuffer(mBuffers[0])) + alDeleteBuffers(mBuffers.size(), mBuffers.data()); + alGetError(); + + mDecoder->close(); } - switch(type) + bool OpenAL_SoundStream::init(bool getLoudnessData) { - case SampleType_UInt8: mSilence = 0x80; break; - case SampleType_Int16: mSilence = 0x00; break; - case SampleType_Float32: mSilence = 0x00; break; - } + alGenBuffers(mBuffers.size(), mBuffers.data()); + ALenum err = getALError(); + if (err != AL_NO_ERROR) + return false; - mFrameSize = framesToBytes(1, chans, type); - mBufferSize = static_cast(sBufferLength*mSampleRate); - mBufferSize *= mFrameSize; + ChannelConfig chans; + SampleType type; - if (getLoudnessData) - mLoudnessAnalyzer = std::make_unique(sLoudnessFPS, mSampleRate, chans, type); + try + { + mDecoder->getInfo(&mSampleRate, &chans, &type); + mFormat = getALFormat(chans, type); + } + catch (std::exception& e) + { + Log(Debug::Error) << "Failed to get stream info: " << e.what(); + return false; + } - mIsFinished = false; - return true; -} + switch (type) + { + case SampleType_UInt8: + mSilence = 0x80; + break; + case SampleType_Int16: + mSilence = 0x00; + break; + case SampleType_Float32: + mSilence = 0x00; + break; + } -bool OpenAL_SoundStream::isPlaying() -{ - ALint state; + mFrameSize = framesToBytes(1, chans, type); + mBufferSize = static_cast(sBufferLength * mSampleRate); + mBufferSize *= mFrameSize; - alGetSourcei(mSource, AL_SOURCE_STATE, &state); - getALError(); + if (getLoudnessData) + mLoudnessAnalyzer = std::make_unique(sLoudnessFPS, mSampleRate, chans, type); - if(state == AL_PLAYING || state == AL_PAUSED) + mIsFinished = false; return true; - return !mIsFinished; -} - -double OpenAL_SoundStream::getStreamDelay() const -{ - ALint state = AL_STOPPED; - double d = 0.0; - ALint offset; - - alGetSourcei(mSource, AL_SAMPLE_OFFSET, &offset); - alGetSourcei(mSource, AL_SOURCE_STATE, &state); - if(state == AL_PLAYING || state == AL_PAUSED) - { - ALint queued; - alGetSourcei(mSource, AL_BUFFERS_QUEUED, &queued); - ALint inqueue = mBufferSize/mFrameSize*queued - offset; - d = (double)inqueue / (double)mSampleRate; } - getALError(); - return d; -} + bool OpenAL_SoundStream::isPlaying() + { + ALint state; -double OpenAL_SoundStream::getStreamOffset() const -{ - ALint state = AL_STOPPED; - ALint offset; - double t; + alGetSourcei(mSource, AL_SOURCE_STATE, &state); + getALError(); - alGetSourcei(mSource, AL_SAMPLE_OFFSET, &offset); - alGetSourcei(mSource, AL_SOURCE_STATE, &state); - if(state == AL_PLAYING || state == AL_PAUSED) - { - ALint queued; - alGetSourcei(mSource, AL_BUFFERS_QUEUED, &queued); - ALint inqueue = mBufferSize/mFrameSize*queued - offset; - t = (double)(mDecoder->getSampleOffset() - inqueue) / (double)mSampleRate; + if (state == AL_PLAYING || state == AL_PAUSED) + return true; + return !mIsFinished; } - else + + double OpenAL_SoundStream::getStreamDelay() const { - /* Underrun, or not started yet. The decoder offset is where we'll play - * next. */ - t = (double)mDecoder->getSampleOffset() / (double)mSampleRate; - } + ALint state = AL_STOPPED; + double d = 0.0; + ALint offset; - getALError(); - return t; -} + alGetSourcei(mSource, AL_SAMPLE_OFFSET, &offset); + alGetSourcei(mSource, AL_SOURCE_STATE, &state); + if (state == AL_PLAYING || state == AL_PAUSED) + { + ALint queued; + alGetSourcei(mSource, AL_BUFFERS_QUEUED, &queued); + ALint inqueue = mBufferSize / mFrameSize * queued - offset; + d = (double)inqueue / (double)mSampleRate; + } -float OpenAL_SoundStream::getCurrentLoudness() const -{ - if (!mLoudnessAnalyzer.get()) - return 0.f; + getALError(); + return d; + } - float time = getStreamOffset(); - return mLoudnessAnalyzer->getLoudnessAtTime(time); -} + double OpenAL_SoundStream::getStreamOffset() const + { + ALint state = AL_STOPPED; + ALint offset; + double t; -bool OpenAL_SoundStream::process() -{ - try { - if(refillQueue() > 0) + alGetSourcei(mSource, AL_SAMPLE_OFFSET, &offset); + alGetSourcei(mSource, AL_SOURCE_STATE, &state); + if (state == AL_PLAYING || state == AL_PAUSED) { - ALint state; - alGetSourcei(mSource, AL_SOURCE_STATE, &state); - if(state != AL_PLAYING && state != AL_PAUSED) - { - // Ensure all processed buffers are removed so we don't replay them. - refillQueue(); - - alSourcePlay(mSource); - } + ALint queued; + alGetSourcei(mSource, AL_BUFFERS_QUEUED, &queued); + ALint inqueue = mBufferSize / mFrameSize * queued - offset; + t = (double)(mDecoder->getSampleOffset() - inqueue) / (double)mSampleRate; } + else + { + /* Underrun, or not started yet. The decoder offset is where we'll play + * next. */ + t = (double)mDecoder->getSampleOffset() / (double)mSampleRate; + } + + getALError(); + return t; } - catch(std::exception&) { - Log(Debug::Error) << "Error updating stream \"" << mDecoder->getName() << "\""; - mIsFinished = true; - } - return !mIsFinished; -} -ALint OpenAL_SoundStream::refillQueue() -{ - ALint processed; - alGetSourcei(mSource, AL_BUFFERS_PROCESSED, &processed); - while(processed > 0) + float OpenAL_SoundStream::getCurrentLoudness() const { - ALuint buf; - alSourceUnqueueBuffers(mSource, 1, &buf); - --processed; + if (!mLoudnessAnalyzer.get()) + return 0.f; + + float time = getStreamOffset(); + return mLoudnessAnalyzer->getLoudnessAtTime(time); } - ALint queued; - alGetSourcei(mSource, AL_BUFFERS_QUEUED, &queued); - if(!mIsFinished && (ALuint)queued < mBuffers.size()) + bool OpenAL_SoundStream::process() { - std::vector data(mBufferSize); - for(;!mIsFinished && (ALuint)queued < mBuffers.size();++queued) + try { - size_t got = mDecoder->read(data.data(), data.size()); - if(got < data.size()) - { - mIsFinished = true; - std::fill(data.begin()+got, data.end(), mSilence); - } - if(got > 0) + if (refillQueue() > 0) { - if (mLoudnessAnalyzer.get()) - mLoudnessAnalyzer->analyzeLoudness(data); + ALint state; + alGetSourcei(mSource, AL_SOURCE_STATE, &state); + if (state != AL_PLAYING && state != AL_PAUSED) + { + // Ensure all processed buffers are removed so we don't replay them. + refillQueue(); - ALuint bufid = mBuffers[mCurrentBufIdx]; - alBufferData(bufid, mFormat, data.data(), data.size(), mSampleRate); - alSourceQueueBuffers(mSource, 1, &bufid); - mCurrentBufIdx = (mCurrentBufIdx+1) % mBuffers.size(); + alSourcePlay(mSource); + } } } + catch (std::exception&) + { + Log(Debug::Error) << "Error updating stream \"" << mDecoder->getName() << "\""; + mIsFinished = true; + } + return !mIsFinished; } - return queued; -} - - -// -// An OpenAL output device -// -std::vector OpenAL_Output::enumerate() -{ - std::vector devlist; - const ALCchar *devnames; - - if(alcIsExtensionPresent(nullptr, "ALC_ENUMERATE_ALL_EXT")) - devnames = alcGetString(nullptr, ALC_ALL_DEVICES_SPECIFIER); - else - devnames = alcGetString(nullptr, ALC_DEVICE_SPECIFIER); - while(devnames && *devnames) - { - devlist.emplace_back(devnames); - devnames += strlen(devnames)+1; - } - return devlist; -} - -bool OpenAL_Output::init(const std::string &devname, const std::string &hrtfname, HrtfMode hrtfmode) -{ - deinit(); - - Log(Debug::Info) << "Initializing OpenAL..."; - - mDevice = alcOpenDevice(devname.c_str()); - if(!mDevice && !devname.empty()) - { - Log(Debug::Warning) << "Failed to open \"" << devname << "\", trying default"; - mDevice = alcOpenDevice(nullptr); - } - - if(!mDevice) - { - Log(Debug::Error) << "Failed to open default audio device"; - return false; - } - - const ALCchar *name = nullptr; - if(alcIsExtensionPresent(mDevice, "ALC_ENUMERATE_ALL_EXT")) - name = alcGetString(mDevice, ALC_ALL_DEVICES_SPECIFIER); - if(alcGetError(mDevice) != AL_NO_ERROR || !name) - name = alcGetString(mDevice, ALC_DEVICE_SPECIFIER); - Log(Debug::Info) << "Opened \"" << name << "\""; - - ALCint major=0, minor=0; - alcGetIntegerv(mDevice, ALC_MAJOR_VERSION, 1, &major); - alcGetIntegerv(mDevice, ALC_MINOR_VERSION, 1, &minor); - Log(Debug::Info) << " ALC Version: " << major << "." << minor <<"\n" << - " ALC Extensions: " << alcGetString(mDevice, ALC_EXTENSIONS); - - ALC.EXT_EFX = alcIsExtensionPresent(mDevice, "ALC_EXT_EFX"); - ALC.SOFT_HRTF = alcIsExtensionPresent(mDevice, "ALC_SOFT_HRTF"); - - std::vector attrs; - attrs.reserve(15); - if(ALC.SOFT_HRTF) + ALint OpenAL_SoundStream::refillQueue() { - LPALCGETSTRINGISOFT alcGetStringiSOFT = nullptr; - getALCFunc(alcGetStringiSOFT, mDevice, "alcGetStringiSOFT"); + ALint processed; + alGetSourcei(mSource, AL_BUFFERS_PROCESSED, &processed); + while (processed > 0) + { + ALuint buf; + alSourceUnqueueBuffers(mSource, 1, &buf); + --processed; + } - attrs.push_back(ALC_HRTF_SOFT); - attrs.push_back(hrtfmode == HrtfMode::Disable ? ALC_FALSE : - hrtfmode == HrtfMode::Enable ? ALC_TRUE : - /*hrtfmode == HrtfMode::Auto ?*/ ALC_DONT_CARE_SOFT); - if(!hrtfname.empty()) + ALint queued; + alGetSourcei(mSource, AL_BUFFERS_QUEUED, &queued); + if (!mIsFinished && (ALuint)queued < mBuffers.size()) { - ALCint index = -1; - ALCint num_hrtf; - alcGetIntegerv(mDevice, ALC_NUM_HRTF_SPECIFIERS_SOFT, 1, &num_hrtf); - for(ALCint i = 0;i < num_hrtf;++i) + std::vector data(mBufferSize); + for (; !mIsFinished && (ALuint)queued < mBuffers.size(); ++queued) { - const ALCchar *entry = alcGetStringiSOFT(mDevice, ALC_HRTF_SPECIFIER_SOFT, i); - if(hrtfname == entry) + size_t got = mDecoder->read(data.data(), data.size()); + if (got < data.size()) { - index = i; - break; + mIsFinished = true; + std::fill(data.begin() + got, data.end(), mSilence); } - } + if (got > 0) + { + if (mLoudnessAnalyzer.get()) + mLoudnessAnalyzer->analyzeLoudness(data); - if(index < 0) - Log(Debug::Warning) << "Failed to find HRTF \"" << hrtfname << "\", using default"; - else - { - attrs.push_back(ALC_HRTF_ID_SOFT); - attrs.push_back(index); + ALuint bufid = mBuffers[mCurrentBufIdx]; + alBufferData(bufid, mFormat, data.data(), data.size(), mSampleRate); + alSourceQueueBuffers(mSource, 1, &bufid); + mCurrentBufIdx = (mCurrentBufIdx + 1) % mBuffers.size(); + } } } - } - attrs.push_back(0); - mContext = alcCreateContext(mDevice, attrs.data()); - if(!mContext || alcMakeContextCurrent(mContext) == ALC_FALSE) - { - Log(Debug::Error) << "Failed to setup audio context: "< OpenAL_Output::enumerate() { - ALCint hrtf_state; - alcGetIntegerv(mDevice, ALC_HRTF_SOFT, 1, &hrtf_state); - if(!hrtf_state) - Log(Debug::Info) << "HRTF disabled"; + std::vector devlist; + const ALCchar* devnames; + + if (alcIsExtensionPresent(nullptr, "ALC_ENUMERATE_ALL_EXT")) + devnames = alcGetString(nullptr, ALC_ALL_DEVICES_SPECIFIER); else + devnames = alcGetString(nullptr, ALC_DEVICE_SPECIFIER); + while (devnames && *devnames) { - const ALCchar *hrtf = alcGetString(mDevice, ALC_HRTF_SPECIFIER_SOFT); - Log(Debug::Info) << "Enabled HRTF " << hrtf; + devlist.emplace_back(devnames); + devnames += strlen(devnames) + 1; } + return devlist; } - AL.SOFT_source_spatialize = alIsExtensionPresent("AL_SOFT_source_spatialize"); - - ALCuint maxtotal; - ALCint maxmono = 0, maxstereo = 0; - alcGetIntegerv(mDevice, ALC_MONO_SOURCES, 1, &maxmono); - alcGetIntegerv(mDevice, ALC_STEREO_SOURCES, 1, &maxstereo); - if(getALCError(mDevice) != ALC_NO_ERROR) - maxtotal = 256; - else + bool OpenAL_Output::init(const std::string& devname, const std::string& hrtfname, HrtfMode hrtfmode) { - maxtotal = std::min(maxmono+maxstereo, 256); - if (maxtotal == 0) // workaround for broken implementations - maxtotal = 256; - } - for(size_t i = 0;i < maxtotal;i++) - { - ALuint src = 0; - alGenSources(1, &src); - if(alGetError() != AL_NO_ERROR) - break; - mFreeSources.push_back(src); - } - if(mFreeSources.empty()) - { - Log(Debug::Warning) << "Could not allocate any sound sourcess"; - alcMakeContextCurrent(nullptr); - alcDestroyContext(mContext); - mContext = nullptr; - alcCloseDevice(mDevice); - mDevice = nullptr; - return false; - } - Log(Debug::Info) << "Allocated " << mFreeSources.size() << " sound sources"; + deinit(); - if(ALC.EXT_EFX) - { -#define LOAD_FUNC(x) getALFunc(x, #x) - LOAD_FUNC(alGenEffects); - LOAD_FUNC(alDeleteEffects); - LOAD_FUNC(alIsEffect); - LOAD_FUNC(alEffecti); - LOAD_FUNC(alEffectiv); - LOAD_FUNC(alEffectf); - LOAD_FUNC(alEffectfv); - LOAD_FUNC(alGetEffecti); - LOAD_FUNC(alGetEffectiv); - LOAD_FUNC(alGetEffectf); - LOAD_FUNC(alGetEffectfv); - LOAD_FUNC(alGenFilters); - LOAD_FUNC(alDeleteFilters); - LOAD_FUNC(alIsFilter); - LOAD_FUNC(alFilteri); - LOAD_FUNC(alFilteriv); - LOAD_FUNC(alFilterf); - LOAD_FUNC(alFilterfv); - LOAD_FUNC(alGetFilteri); - LOAD_FUNC(alGetFilteriv); - LOAD_FUNC(alGetFilterf); - LOAD_FUNC(alGetFilterfv); - LOAD_FUNC(alGenAuxiliaryEffectSlots); - LOAD_FUNC(alDeleteAuxiliaryEffectSlots); - LOAD_FUNC(alIsAuxiliaryEffectSlot); - LOAD_FUNC(alAuxiliaryEffectSloti); - LOAD_FUNC(alAuxiliaryEffectSlotiv); - LOAD_FUNC(alAuxiliaryEffectSlotf); - LOAD_FUNC(alAuxiliaryEffectSlotfv); - LOAD_FUNC(alGetAuxiliaryEffectSloti); - LOAD_FUNC(alGetAuxiliaryEffectSlotiv); - LOAD_FUNC(alGetAuxiliaryEffectSlotf); - LOAD_FUNC(alGetAuxiliaryEffectSlotfv); -#undef LOAD_FUNC - if(getALError() != AL_NO_ERROR) + Log(Debug::Info) << "Initializing OpenAL..."; + + mDevice = alcOpenDevice(devname.c_str()); + if (!mDevice && !devname.empty()) { - ALC.EXT_EFX = false; - goto skip_efx; + Log(Debug::Warning) << "Failed to open \"" << devname << "\", trying default"; + mDevice = alcOpenDevice(nullptr); } - alGenFilters(1, &mWaterFilter); - if(alGetError() == AL_NO_ERROR) + if (!mDevice) { - alFilteri(mWaterFilter, AL_FILTER_TYPE, AL_FILTER_LOWPASS); - if(alGetError() == AL_NO_ERROR) - { - Log(Debug::Info) << "Low-pass filter supported"; - alFilterf(mWaterFilter, AL_LOWPASS_GAIN, 0.9f); - alFilterf(mWaterFilter, AL_LOWPASS_GAINHF, 0.125f); - } - else + Log(Debug::Error) << "Failed to open default audio device"; + return false; + } + + const ALCchar* name = nullptr; + if (alcIsExtensionPresent(mDevice, "ALC_ENUMERATE_ALL_EXT")) + name = alcGetString(mDevice, ALC_ALL_DEVICES_SPECIFIER); + if (alcGetError(mDevice) != AL_NO_ERROR || !name) + name = alcGetString(mDevice, ALC_DEVICE_SPECIFIER); + Log(Debug::Info) << "Opened \"" << name << "\""; + + ALCint major = 0, minor = 0; + alcGetIntegerv(mDevice, ALC_MAJOR_VERSION, 1, &major); + alcGetIntegerv(mDevice, ALC_MINOR_VERSION, 1, &minor); + Log(Debug::Info) << " ALC Version: " << major << "." << minor << "\n" + << " ALC Extensions: " << alcGetString(mDevice, ALC_EXTENSIONS); + + ALC.EXT_EFX = alcIsExtensionPresent(mDevice, "ALC_EXT_EFX"); + ALC.SOFT_HRTF = alcIsExtensionPresent(mDevice, "ALC_SOFT_HRTF"); + + std::vector attrs; + attrs.reserve(15); + if (ALC.SOFT_HRTF) + { + LPALCGETSTRINGISOFT alcGetStringiSOFT = nullptr; + getALCFunc(alcGetStringiSOFT, mDevice, "alcGetStringiSOFT"); + + attrs.push_back(ALC_HRTF_SOFT); + attrs.push_back(hrtfmode == HrtfMode::Disable ? ALC_FALSE + : hrtfmode == HrtfMode::Enable ? ALC_TRUE + : + /*hrtfmode == HrtfMode::Auto ?*/ ALC_DONT_CARE_SOFT); + if (!hrtfname.empty()) { - alDeleteFilters(1, &mWaterFilter); - mWaterFilter = 0; + ALCint index = -1; + ALCint num_hrtf; + alcGetIntegerv(mDevice, ALC_NUM_HRTF_SPECIFIERS_SOFT, 1, &num_hrtf); + for (ALCint i = 0; i < num_hrtf; ++i) + { + const ALCchar* entry = alcGetStringiSOFT(mDevice, ALC_HRTF_SPECIFIER_SOFT, i); + if (hrtfname == entry) + { + index = i; + break; + } + } + + if (index < 0) + Log(Debug::Warning) << "Failed to find HRTF \"" << hrtfname << "\", using default"; + else + { + attrs.push_back(ALC_HRTF_ID_SOFT); + attrs.push_back(index); + } } - alGetError(); } + attrs.push_back(0); - alGenAuxiliaryEffectSlots(1, &mEffectSlot); - alGetError(); + mContext = alcCreateContext(mDevice, attrs.data()); + if (!mContext || alcMakeContextCurrent(mContext) == ALC_FALSE) + { + Log(Debug::Error) << "Failed to setup audio context: " << alcGetString(mDevice, alcGetError(mDevice)); + if (mContext) + alcDestroyContext(mContext); + mContext = nullptr; + alcCloseDevice(mDevice); + mDevice = nullptr; + return false; + } + + Log(Debug::Info) << " Vendor: " << alGetString(AL_VENDOR) << "\n" + << " Renderer: " << alGetString(AL_RENDERER) << "\n" + << " Version: " << alGetString(AL_VERSION) << "\n" + << " Extensions: " << alGetString(AL_EXTENSIONS); - alGenEffects(1, &mDefaultEffect); - if(alGetError() == AL_NO_ERROR) + if (!ALC.SOFT_HRTF) + Log(Debug::Warning) << "HRTF status unavailable"; + else { - alEffecti(mDefaultEffect, AL_EFFECT_TYPE, AL_EFFECT_EAXREVERB); - if(alGetError() == AL_NO_ERROR) - Log(Debug::Info) << "EAX Reverb supported"; + ALCint hrtf_state; + alcGetIntegerv(mDevice, ALC_HRTF_SOFT, 1, &hrtf_state); + if (!hrtf_state) + Log(Debug::Info) << "HRTF disabled"; else { - alEffecti(mDefaultEffect, AL_EFFECT_TYPE, AL_EFFECT_REVERB); - if(alGetError() == AL_NO_ERROR) - Log(Debug::Info) << "Standard Reverb supported"; + const ALCchar* hrtf = alcGetString(mDevice, ALC_HRTF_SPECIFIER_SOFT); + Log(Debug::Info) << "Enabled HRTF " << hrtf; } - EFXEAXREVERBPROPERTIES props = EFX_REVERB_PRESET_LIVINGROOM; - props.flGain = 0.0f; - LoadEffect(mDefaultEffect, props); } - alGenEffects(1, &mWaterEffect); - if(alGetError() == AL_NO_ERROR) - { - alEffecti(mWaterEffect, AL_EFFECT_TYPE, AL_EFFECT_EAXREVERB); - if(alGetError() != AL_NO_ERROR) + AL.SOFT_source_spatialize = alIsExtensionPresent("AL_SOFT_source_spatialize"); + + ALCuint maxtotal; + ALCint maxmono = 0, maxstereo = 0; + alcGetIntegerv(mDevice, ALC_MONO_SOURCES, 1, &maxmono); + alcGetIntegerv(mDevice, ALC_STEREO_SOURCES, 1, &maxstereo); + if (getALCError(mDevice) != ALC_NO_ERROR) + maxtotal = 256; + else + { + maxtotal = std::min(maxmono + maxstereo, 256); + if (maxtotal == 0) // workaround for broken implementations + maxtotal = 256; + } + for (size_t i = 0; i < maxtotal; i++) + { + ALuint src = 0; + alGenSources(1, &src); + if (alGetError() != AL_NO_ERROR) + break; + mFreeSources.push_back(src); + } + if (mFreeSources.empty()) + { + Log(Debug::Warning) << "Could not allocate any sound sourcess"; + alcMakeContextCurrent(nullptr); + alcDestroyContext(mContext); + mContext = nullptr; + alcCloseDevice(mDevice); + mDevice = nullptr; + return false; + } + Log(Debug::Info) << "Allocated " << mFreeSources.size() << " sound sources"; + + if (ALC.EXT_EFX) + { +#define LOAD_FUNC(x) getALFunc(x, #x) + LOAD_FUNC(alGenEffects); + LOAD_FUNC(alDeleteEffects); + LOAD_FUNC(alIsEffect); + LOAD_FUNC(alEffecti); + LOAD_FUNC(alEffectiv); + LOAD_FUNC(alEffectf); + LOAD_FUNC(alEffectfv); + LOAD_FUNC(alGetEffecti); + LOAD_FUNC(alGetEffectiv); + LOAD_FUNC(alGetEffectf); + LOAD_FUNC(alGetEffectfv); + LOAD_FUNC(alGenFilters); + LOAD_FUNC(alDeleteFilters); + LOAD_FUNC(alIsFilter); + LOAD_FUNC(alFilteri); + LOAD_FUNC(alFilteriv); + LOAD_FUNC(alFilterf); + LOAD_FUNC(alFilterfv); + LOAD_FUNC(alGetFilteri); + LOAD_FUNC(alGetFilteriv); + LOAD_FUNC(alGetFilterf); + LOAD_FUNC(alGetFilterfv); + LOAD_FUNC(alGenAuxiliaryEffectSlots); + LOAD_FUNC(alDeleteAuxiliaryEffectSlots); + LOAD_FUNC(alIsAuxiliaryEffectSlot); + LOAD_FUNC(alAuxiliaryEffectSloti); + LOAD_FUNC(alAuxiliaryEffectSlotiv); + LOAD_FUNC(alAuxiliaryEffectSlotf); + LOAD_FUNC(alAuxiliaryEffectSlotfv); + LOAD_FUNC(alGetAuxiliaryEffectSloti); + LOAD_FUNC(alGetAuxiliaryEffectSlotiv); + LOAD_FUNC(alGetAuxiliaryEffectSlotf); + LOAD_FUNC(alGetAuxiliaryEffectSlotfv); +#undef LOAD_FUNC + if (getALError() != AL_NO_ERROR) { - alEffecti(mWaterEffect, AL_EFFECT_TYPE, AL_EFFECT_REVERB); - alGetError(); + ALC.EXT_EFX = false; + goto skip_efx; } - LoadEffect(mWaterEffect, EFX_REVERB_PRESET_UNDERWATER); - } - alListenerf(AL_METERS_PER_UNIT, 1.0f / Constants::UnitsPerMeter); - } -skip_efx: - alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED); - // Speed of sound is in units per second. Take the sound speed in air (assumed - // meters per second), multiply by the units per meter to get the speed in u/s. - alSpeedOfSound(Constants::SoundSpeedInAir * Constants::UnitsPerMeter); - alGetError(); - - mInitialized = true; - return true; -} + alGenFilters(1, &mWaterFilter); + if (alGetError() == AL_NO_ERROR) + { + alFilteri(mWaterFilter, AL_FILTER_TYPE, AL_FILTER_LOWPASS); + if (alGetError() == AL_NO_ERROR) + { + Log(Debug::Info) << "Low-pass filter supported"; + alFilterf(mWaterFilter, AL_LOWPASS_GAIN, 0.9f); + alFilterf(mWaterFilter, AL_LOWPASS_GAINHF, 0.125f); + } + else + { + alDeleteFilters(1, &mWaterFilter); + mWaterFilter = 0; + } + alGetError(); + } -void OpenAL_Output::deinit() -{ - mStreamThread->removeAll(); - - for(ALuint source : mFreeSources) - alDeleteSources(1, &source); - mFreeSources.clear(); - - if(mEffectSlot) - alDeleteAuxiliaryEffectSlots(1, &mEffectSlot); - mEffectSlot = 0; - if(mDefaultEffect) - alDeleteEffects(1, &mDefaultEffect); - mDefaultEffect = 0; - if(mWaterEffect) - alDeleteEffects(1, &mWaterEffect); - mWaterEffect = 0; - if(mWaterFilter) - alDeleteFilters(1, &mWaterFilter); - mWaterFilter = 0; - - alcMakeContextCurrent(nullptr); - if(mContext) - alcDestroyContext(mContext); - mContext = nullptr; - if(mDevice) - alcCloseDevice(mDevice); - mDevice = nullptr; - - mInitialized = false; -} + alGenAuxiliaryEffectSlots(1, &mEffectSlot); + alGetError(); + alGenEffects(1, &mDefaultEffect); + if (alGetError() == AL_NO_ERROR) + { + alEffecti(mDefaultEffect, AL_EFFECT_TYPE, AL_EFFECT_EAXREVERB); + if (alGetError() == AL_NO_ERROR) + Log(Debug::Info) << "EAX Reverb supported"; + else + { + alEffecti(mDefaultEffect, AL_EFFECT_TYPE, AL_EFFECT_REVERB); + if (alGetError() == AL_NO_ERROR) + Log(Debug::Info) << "Standard Reverb supported"; + } + EFXEAXREVERBPROPERTIES props = EFX_REVERB_PRESET_LIVINGROOM; + props.flGain = 0.0f; + LoadEffect(mDefaultEffect, props); + } -std::vector OpenAL_Output::enumerateHrtf() -{ - std::vector ret; + alGenEffects(1, &mWaterEffect); + if (alGetError() == AL_NO_ERROR) + { + alEffecti(mWaterEffect, AL_EFFECT_TYPE, AL_EFFECT_EAXREVERB); + if (alGetError() != AL_NO_ERROR) + { + alEffecti(mWaterEffect, AL_EFFECT_TYPE, AL_EFFECT_REVERB); + alGetError(); + } + LoadEffect(mWaterEffect, EFX_REVERB_PRESET_UNDERWATER); + } - if(!mDevice || !ALC.SOFT_HRTF) - return ret; + alListenerf(AL_METERS_PER_UNIT, 1.0f / Constants::UnitsPerMeter); + } + skip_efx: + alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED); + // Speed of sound is in units per second. Take the sound speed in air (assumed + // meters per second), multiply by the units per meter to get the speed in u/s. + alSpeedOfSound(Constants::SoundSpeedInAir * Constants::UnitsPerMeter); + alGetError(); - LPALCGETSTRINGISOFT alcGetStringiSOFT = nullptr; - getALCFunc(alcGetStringiSOFT, mDevice, "alcGetStringiSOFT"); + mInitialized = true; + return true; + } - ALCint num_hrtf; - alcGetIntegerv(mDevice, ALC_NUM_HRTF_SPECIFIERS_SOFT, 1, &num_hrtf); - ret.reserve(num_hrtf); - for(ALCint i = 0;i < num_hrtf;++i) + void OpenAL_Output::deinit() { - const ALCchar *entry = alcGetStringiSOFT(mDevice, ALC_HRTF_SPECIFIER_SOFT, i); - ret.emplace_back(entry); - } + mStreamThread->removeAll(); + + for (ALuint source : mFreeSources) + alDeleteSources(1, &source); + mFreeSources.clear(); + + if (mEffectSlot) + alDeleteAuxiliaryEffectSlots(1, &mEffectSlot); + mEffectSlot = 0; + if (mDefaultEffect) + alDeleteEffects(1, &mDefaultEffect); + mDefaultEffect = 0; + if (mWaterEffect) + alDeleteEffects(1, &mWaterEffect); + mWaterEffect = 0; + if (mWaterFilter) + alDeleteFilters(1, &mWaterFilter); + mWaterFilter = 0; - return ret; -} + alcMakeContextCurrent(nullptr); + if (mContext) + alcDestroyContext(mContext); + mContext = nullptr; + if (mDevice) + alcCloseDevice(mDevice); + mDevice = nullptr; -void OpenAL_Output::setHrtf(const std::string &hrtfname, HrtfMode hrtfmode) -{ - if(!mDevice || !ALC.SOFT_HRTF) - { - Log(Debug::Info) << "HRTF extension not present"; - return; + mInitialized = false; } - LPALCGETSTRINGISOFT alcGetStringiSOFT = nullptr; - getALCFunc(alcGetStringiSOFT, mDevice, "alcGetStringiSOFT"); + std::vector OpenAL_Output::enumerateHrtf() + { + std::vector ret; - LPALCRESETDEVICESOFT alcResetDeviceSOFT = nullptr; - getALCFunc(alcResetDeviceSOFT, mDevice, "alcResetDeviceSOFT"); + if (!mDevice || !ALC.SOFT_HRTF) + return ret; - std::vector attrs; - attrs.reserve(15); + LPALCGETSTRINGISOFT alcGetStringiSOFT = nullptr; + getALCFunc(alcGetStringiSOFT, mDevice, "alcGetStringiSOFT"); - attrs.push_back(ALC_HRTF_SOFT); - attrs.push_back(hrtfmode == HrtfMode::Disable ? ALC_FALSE : - hrtfmode == HrtfMode::Enable ? ALC_TRUE : - /*hrtfmode == HrtfMode::Auto ?*/ ALC_DONT_CARE_SOFT); - if(!hrtfname.empty()) - { - ALCint index = -1; ALCint num_hrtf; alcGetIntegerv(mDevice, ALC_NUM_HRTF_SPECIFIERS_SOFT, 1, &num_hrtf); - for(ALCint i = 0;i < num_hrtf;++i) + ret.reserve(num_hrtf); + for (ALCint i = 0; i < num_hrtf; ++i) + { + const ALCchar* entry = alcGetStringiSOFT(mDevice, ALC_HRTF_SPECIFIER_SOFT, i); + ret.emplace_back(entry); + } + + return ret; + } + + void OpenAL_Output::setHrtf(const std::string& hrtfname, HrtfMode hrtfmode) + { + if (!mDevice || !ALC.SOFT_HRTF) { - const ALCchar *entry = alcGetStringiSOFT(mDevice, ALC_HRTF_SPECIFIER_SOFT, i); - if(hrtfname == entry) + Log(Debug::Info) << "HRTF extension not present"; + return; + } + + LPALCGETSTRINGISOFT alcGetStringiSOFT = nullptr; + getALCFunc(alcGetStringiSOFT, mDevice, "alcGetStringiSOFT"); + + LPALCRESETDEVICESOFT alcResetDeviceSOFT = nullptr; + getALCFunc(alcResetDeviceSOFT, mDevice, "alcResetDeviceSOFT"); + + std::vector attrs; + attrs.reserve(15); + + attrs.push_back(ALC_HRTF_SOFT); + attrs.push_back(hrtfmode == HrtfMode::Disable ? ALC_FALSE + : hrtfmode == HrtfMode::Enable ? ALC_TRUE + : + /*hrtfmode == HrtfMode::Auto ?*/ ALC_DONT_CARE_SOFT); + if (!hrtfname.empty()) + { + ALCint index = -1; + ALCint num_hrtf; + alcGetIntegerv(mDevice, ALC_NUM_HRTF_SPECIFIERS_SOFT, 1, &num_hrtf); + for (ALCint i = 0; i < num_hrtf; ++i) { - index = i; - break; + const ALCchar* entry = alcGetStringiSOFT(mDevice, ALC_HRTF_SPECIFIER_SOFT, i); + if (hrtfname == entry) + { + index = i; + break; + } + } + + if (index < 0) + Log(Debug::Warning) << "Failed to find HRTF name \"" << hrtfname << "\", using default"; + else + { + attrs.push_back(ALC_HRTF_ID_SOFT); + attrs.push_back(index); } } + attrs.push_back(0); + alcResetDeviceSOFT(mDevice, attrs.data()); - if(index < 0) - Log(Debug::Warning) << "Failed to find HRTF name \"" << hrtfname << "\", using default"; + ALCint hrtf_state; + alcGetIntegerv(mDevice, ALC_HRTF_SOFT, 1, &hrtf_state); + if (!hrtf_state) + Log(Debug::Info) << "HRTF disabled"; else { - attrs.push_back(ALC_HRTF_ID_SOFT); - attrs.push_back(index); + const ALCchar* hrtf = alcGetString(mDevice, ALC_HRTF_SPECIFIER_SOFT); + Log(Debug::Info) << "Enabled HRTF " << hrtf; } } - attrs.push_back(0); - alcResetDeviceSOFT(mDevice, attrs.data()); - - ALCint hrtf_state; - alcGetIntegerv(mDevice, ALC_HRTF_SOFT, 1, &hrtf_state); - if(!hrtf_state) - Log(Debug::Info) << "HRTF disabled"; - else - { - const ALCchar *hrtf = alcGetString(mDevice, ALC_HRTF_SPECIFIER_SOFT); - Log(Debug::Info) << "Enabled HRTF " << hrtf; - } -} + std::pair OpenAL_Output::loadSound(const std::string& fname) + { + getALError(); -std::pair OpenAL_Output::loadSound(const std::string &fname) -{ - getALError(); + std::vector data; + ALenum format = AL_NONE; + int srate = 0; - std::vector data; - ALenum format = AL_NONE; - int srate = 0; + try + { + DecoderPtr decoder = mManager.getDecoder(); + decoder->open(Misc::ResourceHelpers::correctSoundPath(fname, decoder->mResourceMgr)); + + ChannelConfig chans; + SampleType type; + decoder->getInfo(&srate, &chans, &type); + format = getALFormat(chans, type); + if (format) + decoder->readAll(data); + } + catch (std::exception& e) + { + Log(Debug::Error) << "Failed to load audio from " << fname << ": " << e.what(); + } - try - { - DecoderPtr decoder = mManager.getDecoder(); - decoder->open(Misc::ResourceHelpers::correctSoundPath(fname, decoder->mResourceMgr)); + if (data.empty()) + { + // If we failed to get any usable audio, substitute with silence. + format = AL_FORMAT_MONO8; + srate = 8000; + data.assign(8000, -128); + } - ChannelConfig chans; - SampleType type; - decoder->getInfo(&srate, &chans, &type); - format = getALFormat(chans, type); - if(format) decoder->readAll(data); - } - catch(std::exception &e) - { - Log(Debug::Error) << "Failed to load audio from " << fname << ": " << e.what(); + ALint size; + ALuint buf = 0; + alGenBuffers(1, &buf); + alBufferData(buf, format, data.data(), data.size(), srate); + alGetBufferi(buf, AL_SIZE, &size); + if (getALError() != AL_NO_ERROR) + { + if (buf && alIsBuffer(buf)) + alDeleteBuffers(1, &buf); + getALError(); + return std::make_pair(nullptr, 0); + } + return std::make_pair(MAKE_PTRID(buf), size); } - if(data.empty()) + size_t OpenAL_Output::unloadSound(Sound_Handle data) { - // If we failed to get any usable audio, substitute with silence. - format = AL_FORMAT_MONO8; - srate = 8000; - data.assign(8000, -128); - } + ALuint buffer = GET_PTRID(data); + if (!buffer) + return 0; - ALint size; - ALuint buf = 0; - alGenBuffers(1, &buf); - alBufferData(buf, format, data.data(), data.size(), srate); - alGetBufferi(buf, AL_SIZE, &size); - if(getALError() != AL_NO_ERROR) - { - if(buf && alIsBuffer(buf)) - alDeleteBuffers(1, &buf); + // Make sure no sources are playing this buffer before unloading it. + SoundVec::const_iterator iter = mActiveSounds.begin(); + for (; iter != mActiveSounds.end(); ++iter) + { + if (!(*iter)->mHandle) + continue; + + ALuint source = GET_PTRID((*iter)->mHandle); + ALint srcbuf; + alGetSourcei(source, AL_BUFFER, &srcbuf); + if ((ALuint)srcbuf == buffer) + { + alSourceStop(source); + alSourcei(source, AL_BUFFER, 0); + } + } + ALint size = 0; + alGetBufferi(buffer, AL_SIZE, &size); + alDeleteBuffers(1, &buffer); getALError(); - return std::make_pair(nullptr, 0); + return size; } - return std::make_pair(MAKE_PTRID(buf), size); -} -size_t OpenAL_Output::unloadSound(Sound_Handle data) -{ - ALuint buffer = GET_PTRID(data); - if(!buffer) return 0; - - // Make sure no sources are playing this buffer before unloading it. - SoundVec::const_iterator iter = mActiveSounds.begin(); - for(;iter != mActiveSounds.end();++iter) + void OpenAL_Output::initCommon2D( + ALuint source, const osg::Vec3f& pos, ALfloat gain, ALfloat pitch, bool loop, bool useenv) { - if(!(*iter)->mHandle) - continue; - - ALuint source = GET_PTRID((*iter)->mHandle); - ALint srcbuf; - alGetSourcei(source, AL_BUFFER, &srcbuf); - if((ALuint)srcbuf == buffer) + alSourcef(source, AL_REFERENCE_DISTANCE, 1.0f); + alSourcef(source, AL_MAX_DISTANCE, 1000.0f); + alSourcef(source, AL_ROLLOFF_FACTOR, 0.0f); + alSourcei(source, AL_SOURCE_RELATIVE, AL_TRUE); + alSourcei(source, AL_LOOPING, loop ? AL_TRUE : AL_FALSE); + if (AL.SOFT_source_spatialize) + alSourcei(source, AL_SOURCE_SPATIALIZE_SOFT, AL_FALSE); + + if (useenv) { - alSourceStop(source); - alSourcei(source, AL_BUFFER, 0); + if (mWaterFilter) + alSourcei(source, AL_DIRECT_FILTER, (mListenerEnv == Env_Underwater) ? mWaterFilter : AL_FILTER_NULL); + else if (mListenerEnv == Env_Underwater) + { + gain *= 0.9f; + pitch *= 0.7f; + } + if (mEffectSlot) + alSource3i(source, AL_AUXILIARY_SEND_FILTER, mEffectSlot, 0, AL_FILTER_NULL); + } + else + { + if (mWaterFilter) + alSourcei(source, AL_DIRECT_FILTER, AL_FILTER_NULL); + if (mEffectSlot) + alSource3i(source, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL); } - } - ALint size = 0; - alGetBufferi(buffer, AL_SIZE, &size); - alDeleteBuffers(1, &buffer); - getALError(); - return size; -} + alSourcef(source, AL_GAIN, gain); + alSourcef(source, AL_PITCH, pitch); + alSourcefv(source, AL_POSITION, pos.ptr()); + alSource3f(source, AL_DIRECTION, 0.0f, 0.0f, 0.0f); + alSource3f(source, AL_VELOCITY, 0.0f, 0.0f, 0.0f); + } -void OpenAL_Output::initCommon2D(ALuint source, const osg::Vec3f &pos, ALfloat gain, ALfloat pitch, bool loop, bool useenv) -{ - alSourcef(source, AL_REFERENCE_DISTANCE, 1.0f); - alSourcef(source, AL_MAX_DISTANCE, 1000.0f); - alSourcef(source, AL_ROLLOFF_FACTOR, 0.0f); - alSourcei(source, AL_SOURCE_RELATIVE, AL_TRUE); - alSourcei(source, AL_LOOPING, loop ? AL_TRUE : AL_FALSE); - if(AL.SOFT_source_spatialize) - alSourcei(source, AL_SOURCE_SPATIALIZE_SOFT, AL_FALSE); - - if(useenv) + void OpenAL_Output::initCommon3D(ALuint source, const osg::Vec3f& pos, ALfloat mindist, ALfloat maxdist, + ALfloat gain, ALfloat pitch, bool loop, bool useenv) { - if(mWaterFilter) - alSourcei(source, AL_DIRECT_FILTER, - (mListenerEnv == Env_Underwater) ? mWaterFilter : AL_FILTER_NULL - ); - else if(mListenerEnv == Env_Underwater) + alSourcef(source, AL_REFERENCE_DISTANCE, mindist); + alSourcef(source, AL_MAX_DISTANCE, maxdist); + alSourcef(source, AL_ROLLOFF_FACTOR, 1.0f); + alSourcei(source, AL_SOURCE_RELATIVE, AL_FALSE); + alSourcei(source, AL_LOOPING, loop ? AL_TRUE : AL_FALSE); + if (AL.SOFT_source_spatialize) + alSourcei(source, AL_SOURCE_SPATIALIZE_SOFT, AL_TRUE); + + if ((pos - mListenerPos).length2() > maxdist * maxdist) + gain = 0.0f; + if (useenv) { - gain *= 0.9f; - pitch *= 0.7f; + if (mWaterFilter) + alSourcei(source, AL_DIRECT_FILTER, (mListenerEnv == Env_Underwater) ? mWaterFilter : AL_FILTER_NULL); + else if (mListenerEnv == Env_Underwater) + { + gain *= 0.9f; + pitch *= 0.7f; + } + if (mEffectSlot) + alSource3i(source, AL_AUXILIARY_SEND_FILTER, mEffectSlot, 0, AL_FILTER_NULL); + } + else + { + if (mWaterFilter) + alSourcei(source, AL_DIRECT_FILTER, AL_FILTER_NULL); + if (mEffectSlot) + alSource3i(source, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL); } - if(mEffectSlot) - alSource3i(source, AL_AUXILIARY_SEND_FILTER, mEffectSlot, 0, AL_FILTER_NULL); - } - else - { - if(mWaterFilter) - alSourcei(source, AL_DIRECT_FILTER, AL_FILTER_NULL); - if(mEffectSlot) - alSource3i(source, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL); - } - alSourcef(source, AL_GAIN, gain); - alSourcef(source, AL_PITCH, pitch); - alSourcefv(source, AL_POSITION, pos.ptr()); - alSource3f(source, AL_DIRECTION, 0.0f, 0.0f, 0.0f); - alSource3f(source, AL_VELOCITY, 0.0f, 0.0f, 0.0f); -} + alSourcef(source, AL_GAIN, gain); + alSourcef(source, AL_PITCH, pitch); + alSourcefv(source, AL_POSITION, pos.ptr()); + alSource3f(source, AL_DIRECTION, 0.0f, 0.0f, 0.0f); + alSource3f(source, AL_VELOCITY, 0.0f, 0.0f, 0.0f); + } -void OpenAL_Output::initCommon3D(ALuint source, const osg::Vec3f &pos, ALfloat mindist, ALfloat maxdist, ALfloat gain, ALfloat pitch, bool loop, bool useenv) -{ - alSourcef(source, AL_REFERENCE_DISTANCE, mindist); - alSourcef(source, AL_MAX_DISTANCE, maxdist); - alSourcef(source, AL_ROLLOFF_FACTOR, 1.0f); - alSourcei(source, AL_SOURCE_RELATIVE, AL_FALSE); - alSourcei(source, AL_LOOPING, loop ? AL_TRUE : AL_FALSE); - if(AL.SOFT_source_spatialize) - alSourcei(source, AL_SOURCE_SPATIALIZE_SOFT, AL_TRUE); - - if((pos - mListenerPos).length2() > maxdist*maxdist) - gain = 0.0f; - if(useenv) + void OpenAL_Output::updateCommon( + ALuint source, const osg::Vec3f& pos, ALfloat maxdist, ALfloat gain, ALfloat pitch, bool useenv) { - if(mWaterFilter) - alSourcei(source, AL_DIRECT_FILTER, - (mListenerEnv == Env_Underwater) ? mWaterFilter : AL_FILTER_NULL - ); - else if(mListenerEnv == Env_Underwater) + if (useenv && mListenerEnv == Env_Underwater && !mWaterFilter) { gain *= 0.9f; pitch *= 0.7f; } - if(mEffectSlot) - alSource3i(source, AL_AUXILIARY_SEND_FILTER, mEffectSlot, 0, AL_FILTER_NULL); - } - else - { - if(mWaterFilter) - alSourcei(source, AL_DIRECT_FILTER, AL_FILTER_NULL); - if(mEffectSlot) - alSource3i(source, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, AL_FILTER_NULL); - } - alSourcef(source, AL_GAIN, gain); - alSourcef(source, AL_PITCH, pitch); - alSourcefv(source, AL_POSITION, pos.ptr()); - alSource3f(source, AL_DIRECTION, 0.0f, 0.0f, 0.0f); - alSource3f(source, AL_VELOCITY, 0.0f, 0.0f, 0.0f); -} + alSourcef(source, AL_GAIN, gain); + alSourcef(source, AL_PITCH, pitch); + alSourcefv(source, AL_POSITION, pos.ptr()); + alSource3f(source, AL_DIRECTION, 0.0f, 0.0f, 0.0f); + alSource3f(source, AL_VELOCITY, 0.0f, 0.0f, 0.0f); + } -void OpenAL_Output::updateCommon(ALuint source, const osg::Vec3f& pos, ALfloat maxdist, ALfloat gain, ALfloat pitch, bool useenv) -{ - if(useenv && mListenerEnv == Env_Underwater && !mWaterFilter) + bool OpenAL_Output::playSound(Sound* sound, Sound_Handle data, float offset) { - gain *= 0.9f; - pitch *= 0.7f; - } + ALuint source; - alSourcef(source, AL_GAIN, gain); - alSourcef(source, AL_PITCH, pitch); - alSourcefv(source, AL_POSITION, pos.ptr()); - alSource3f(source, AL_DIRECTION, 0.0f, 0.0f, 0.0f); - alSource3f(source, AL_VELOCITY, 0.0f, 0.0f, 0.0f); -} + if (mFreeSources.empty()) + { + Log(Debug::Warning) << "No free sources!"; + return false; + } + source = mFreeSources.front(); + initCommon2D(source, sound->getPosition(), sound->getRealVolume(), getTimeScaledPitch(sound), + sound->getIsLooping(), sound->getUseEnv()); + alSourcei(source, AL_BUFFER, GET_PTRID(data)); + alSourcef(source, AL_SEC_OFFSET, offset); + if (getALError() != AL_NO_ERROR) + { + alSourceRewind(source); + alSourcei(source, AL_BUFFER, 0); + alGetError(); + return false; + } -bool OpenAL_Output::playSound(Sound *sound, Sound_Handle data, float offset) -{ - ALuint source; + alSourcePlay(source); + if (getALError() != AL_NO_ERROR) + { + alSourceRewind(source); + alSourcei(source, AL_BUFFER, 0); + alGetError(); + return false; + } - if(mFreeSources.empty()) - { - Log(Debug::Warning) << "No free sources!"; - return false; - } - source = mFreeSources.front(); + mFreeSources.pop_front(); + sound->mHandle = MAKE_PTRID(source); + mActiveSounds.push_back(sound); - initCommon2D(source, sound->getPosition(), sound->getRealVolume(), getTimeScaledPitch(sound), - sound->getIsLooping(), sound->getUseEnv()); - alSourcei(source, AL_BUFFER, GET_PTRID(data)); - alSourcef(source, AL_SEC_OFFSET, offset); - if(getALError() != AL_NO_ERROR) - { - alSourceRewind(source); - alSourcei(source, AL_BUFFER, 0); - alGetError(); - return false; + return true; } - alSourcePlay(source); - if(getALError() != AL_NO_ERROR) + bool OpenAL_Output::playSound3D(Sound* sound, Sound_Handle data, float offset) { - alSourceRewind(source); - alSourcei(source, AL_BUFFER, 0); - alGetError(); - return false; - } + ALuint source; - mFreeSources.pop_front(); - sound->mHandle = MAKE_PTRID(source); - mActiveSounds.push_back(sound); + if (mFreeSources.empty()) + { + Log(Debug::Warning) << "No free sources!"; + return false; + } + source = mFreeSources.front(); - return true; -} + initCommon3D(source, sound->getPosition(), sound->getMinDistance(), sound->getMaxDistance(), + sound->getRealVolume(), getTimeScaledPitch(sound), sound->getIsLooping(), sound->getUseEnv()); + alSourcei(source, AL_BUFFER, GET_PTRID(data)); + alSourcef(source, AL_SEC_OFFSET, offset); + if (getALError() != AL_NO_ERROR) + { + alSourceRewind(source); + alSourcei(source, AL_BUFFER, 0); + alGetError(); + return false; + } -bool OpenAL_Output::playSound3D(Sound *sound, Sound_Handle data, float offset) -{ - ALuint source; + alSourcePlay(source); + if (getALError() != AL_NO_ERROR) + { + alSourceRewind(source); + alSourcei(source, AL_BUFFER, 0); + alGetError(); + return false; + } - if(mFreeSources.empty()) - { - Log(Debug::Warning) << "No free sources!"; - return false; - } - source = mFreeSources.front(); - - initCommon3D(source, sound->getPosition(), sound->getMinDistance(), sound->getMaxDistance(), - sound->getRealVolume(), getTimeScaledPitch(sound), sound->getIsLooping(), - sound->getUseEnv()); - alSourcei(source, AL_BUFFER, GET_PTRID(data)); - alSourcef(source, AL_SEC_OFFSET, offset); - if(getALError() != AL_NO_ERROR) - { - alSourceRewind(source); - alSourcei(source, AL_BUFFER, 0); - alGetError(); - return false; + mFreeSources.pop_front(); + sound->mHandle = MAKE_PTRID(source); + mActiveSounds.push_back(sound); + + return true; } - alSourcePlay(source); - if(getALError() != AL_NO_ERROR) + void OpenAL_Output::finishSound(Sound* sound) { + if (!sound->mHandle) + return; + ALuint source = GET_PTRID(sound->mHandle); + sound->mHandle = nullptr; + + // Rewind the stream to put the source back into an AL_INITIAL state, for + // the next time it's used. alSourceRewind(source); alSourcei(source, AL_BUFFER, 0); - alGetError(); - return false; - } - - mFreeSources.pop_front(); - sound->mHandle = MAKE_PTRID(source); - mActiveSounds.push_back(sound); - - return true; -} - -void OpenAL_Output::finishSound(Sound *sound) -{ - if(!sound->mHandle) return; - ALuint source = GET_PTRID(sound->mHandle); - sound->mHandle = nullptr; - - // Rewind the stream to put the source back into an AL_INITIAL state, for - // the next time it's used. - alSourceRewind(source); - alSourcei(source, AL_BUFFER, 0); - getALError(); - - mFreeSources.push_back(source); - mActiveSounds.erase(std::find(mActiveSounds.begin(), mActiveSounds.end(), sound)); -} - -bool OpenAL_Output::isSoundPlaying(Sound *sound) -{ - if(!sound->mHandle) return false; - ALuint source = GET_PTRID(sound->mHandle); - ALint state = AL_STOPPED; - - alGetSourcei(source, AL_SOURCE_STATE, &state); - getALError(); - - return state == AL_PLAYING || state == AL_PAUSED; -} + getALError(); -void OpenAL_Output::updateSound(Sound *sound) -{ - if(!sound->mHandle) return; - ALuint source = GET_PTRID(sound->mHandle); + mFreeSources.push_back(source); + mActiveSounds.erase(std::find(mActiveSounds.begin(), mActiveSounds.end(), sound)); + } - updateCommon(source, sound->getPosition(), sound->getMaxDistance(), sound->getRealVolume(), - getTimeScaledPitch(sound), sound->getUseEnv()); - getALError(); -} + bool OpenAL_Output::isSoundPlaying(Sound* sound) + { + if (!sound->mHandle) + return false; + ALuint source = GET_PTRID(sound->mHandle); + ALint state = AL_STOPPED; + alGetSourcei(source, AL_SOURCE_STATE, &state); + getALError(); -bool OpenAL_Output::streamSound(DecoderPtr decoder, Stream *sound, bool getLoudnessData) -{ - if(mFreeSources.empty()) - { - Log(Debug::Warning) << "No free sources!"; - return false; + return state == AL_PLAYING || state == AL_PAUSED; } - ALuint source = mFreeSources.front(); - if(sound->getIsLooping()) - Log(Debug::Warning) << "Warning: cannot loop stream \"" << decoder->getName() << "\""; + void OpenAL_Output::updateSound(Sound* sound) + { + if (!sound->mHandle) + return; + ALuint source = GET_PTRID(sound->mHandle); - initCommon2D(source, sound->getPosition(), sound->getRealVolume(), getTimeScaledPitch(sound), - false, sound->getUseEnv()); - if(getALError() != AL_NO_ERROR) - return false; + updateCommon(source, sound->getPosition(), sound->getMaxDistance(), sound->getRealVolume(), + getTimeScaledPitch(sound), sound->getUseEnv()); + getALError(); + } - OpenAL_SoundStream *stream = new OpenAL_SoundStream(source, std::move(decoder)); - if(!stream->init(getLoudnessData)) + bool OpenAL_Output::streamSound(DecoderPtr decoder, Stream* sound, bool getLoudnessData) { - delete stream; - return false; - } - mStreamThread->add(stream); + if (mFreeSources.empty()) + { + Log(Debug::Warning) << "No free sources!"; + return false; + } + ALuint source = mFreeSources.front(); - mFreeSources.pop_front(); - sound->mHandle = stream; - mActiveStreams.push_back(sound); - return true; -} + if (sound->getIsLooping()) + Log(Debug::Warning) << "Warning: cannot loop stream \"" << decoder->getName() << "\""; -bool OpenAL_Output::streamSound3D(DecoderPtr decoder, Stream *sound, bool getLoudnessData) -{ - if(mFreeSources.empty()) - { - Log(Debug::Warning) << "No free sources!"; - return false; - } - ALuint source = mFreeSources.front(); + initCommon2D( + source, sound->getPosition(), sound->getRealVolume(), getTimeScaledPitch(sound), false, sound->getUseEnv()); + if (getALError() != AL_NO_ERROR) + return false; - if(sound->getIsLooping()) - Log(Debug::Warning) << "Warning: cannot loop stream \"" << decoder->getName() << "\""; + OpenAL_SoundStream* stream = new OpenAL_SoundStream(source, std::move(decoder)); + if (!stream->init(getLoudnessData)) + { + delete stream; + return false; + } + mStreamThread->add(stream); - initCommon3D(source, sound->getPosition(), sound->getMinDistance(), sound->getMaxDistance(), - sound->getRealVolume(), getTimeScaledPitch(sound), false, sound->getUseEnv()); - if(getALError() != AL_NO_ERROR) - return false; + mFreeSources.pop_front(); + sound->mHandle = stream; + mActiveStreams.push_back(sound); + return true; + } - OpenAL_SoundStream *stream = new OpenAL_SoundStream(source, std::move(decoder)); - if(!stream->init(getLoudnessData)) + bool OpenAL_Output::streamSound3D(DecoderPtr decoder, Stream* sound, bool getLoudnessData) { - delete stream; - return false; - } - mStreamThread->add(stream); + if (mFreeSources.empty()) + { + Log(Debug::Warning) << "No free sources!"; + return false; + } + ALuint source = mFreeSources.front(); - mFreeSources.pop_front(); - sound->mHandle = stream; - mActiveStreams.push_back(sound); - return true; -} + if (sound->getIsLooping()) + Log(Debug::Warning) << "Warning: cannot loop stream \"" << decoder->getName() << "\""; -void OpenAL_Output::finishStream(Stream *sound) -{ - if(!sound->mHandle) return; - OpenAL_SoundStream *stream = reinterpret_cast(sound->mHandle); - ALuint source = stream->mSource; + initCommon3D(source, sound->getPosition(), sound->getMinDistance(), sound->getMaxDistance(), + sound->getRealVolume(), getTimeScaledPitch(sound), false, sound->getUseEnv()); + if (getALError() != AL_NO_ERROR) + return false; - sound->mHandle = nullptr; - mStreamThread->remove(stream); + OpenAL_SoundStream* stream = new OpenAL_SoundStream(source, std::move(decoder)); + if (!stream->init(getLoudnessData)) + { + delete stream; + return false; + } + mStreamThread->add(stream); - // Rewind the stream to put the source back into an AL_INITIAL state, for - // the next time it's used. - alSourceRewind(source); - alSourcei(source, AL_BUFFER, 0); - getALError(); + mFreeSources.pop_front(); + sound->mHandle = stream; + mActiveStreams.push_back(sound); + return true; + } - mFreeSources.push_back(source); - mActiveStreams.erase(std::find(mActiveStreams.begin(), mActiveStreams.end(), sound)); + void OpenAL_Output::finishStream(Stream* sound) + { + if (!sound->mHandle) + return; + OpenAL_SoundStream* stream = reinterpret_cast(sound->mHandle); + ALuint source = stream->mSource; - delete stream; -} + sound->mHandle = nullptr; + mStreamThread->remove(stream); -double OpenAL_Output::getStreamDelay(Stream *sound) -{ - if(!sound->mHandle) return 0.0; - OpenAL_SoundStream *stream = reinterpret_cast(sound->mHandle); - return stream->getStreamDelay(); -} + // Rewind the stream to put the source back into an AL_INITIAL state, for + // the next time it's used. + alSourceRewind(source); + alSourcei(source, AL_BUFFER, 0); + getALError(); -double OpenAL_Output::getStreamOffset(Stream *sound) -{ - if(!sound->mHandle) return 0.0; - OpenAL_SoundStream *stream = reinterpret_cast(sound->mHandle); - std::lock_guard lock(mStreamThread->mMutex); - return stream->getStreamOffset(); -} + mFreeSources.push_back(source); + mActiveStreams.erase(std::find(mActiveStreams.begin(), mActiveStreams.end(), sound)); -float OpenAL_Output::getStreamLoudness(Stream *sound) -{ - if(!sound->mHandle) return 0.0; - OpenAL_SoundStream *stream = reinterpret_cast(sound->mHandle); - std::lock_guard lock(mStreamThread->mMutex); - return stream->getCurrentLoudness(); -} + delete stream; + } -bool OpenAL_Output::isStreamPlaying(Stream *sound) -{ - if(!sound->mHandle) return false; - OpenAL_SoundStream *stream = reinterpret_cast(sound->mHandle); - std::lock_guard lock(mStreamThread->mMutex); - return stream->isPlaying(); -} + double OpenAL_Output::getStreamDelay(Stream* sound) + { + if (!sound->mHandle) + return 0.0; + OpenAL_SoundStream* stream = reinterpret_cast(sound->mHandle); + return stream->getStreamDelay(); + } -void OpenAL_Output::updateStream(Stream *sound) -{ - if(!sound->mHandle) return; - OpenAL_SoundStream *stream = reinterpret_cast(sound->mHandle); - ALuint source = stream->mSource; + double OpenAL_Output::getStreamOffset(Stream* sound) + { + if (!sound->mHandle) + return 0.0; + OpenAL_SoundStream* stream = reinterpret_cast(sound->mHandle); + std::lock_guard lock(mStreamThread->mMutex); + return stream->getStreamOffset(); + } - updateCommon(source, sound->getPosition(), sound->getMaxDistance(), sound->getRealVolume(), - getTimeScaledPitch(sound), sound->getUseEnv()); - getALError(); -} + float OpenAL_Output::getStreamLoudness(Stream* sound) + { + if (!sound->mHandle) + return 0.0; + OpenAL_SoundStream* stream = reinterpret_cast(sound->mHandle); + std::lock_guard lock(mStreamThread->mMutex); + return stream->getCurrentLoudness(); + } + bool OpenAL_Output::isStreamPlaying(Stream* sound) + { + if (!sound->mHandle) + return false; + OpenAL_SoundStream* stream = reinterpret_cast(sound->mHandle); + std::lock_guard lock(mStreamThread->mMutex); + return stream->isPlaying(); + } -void OpenAL_Output::startUpdate() -{ - alcSuspendContext(alcGetCurrentContext()); -} + void OpenAL_Output::updateStream(Stream* sound) + { + if (!sound->mHandle) + return; + OpenAL_SoundStream* stream = reinterpret_cast(sound->mHandle); + ALuint source = stream->mSource; -void OpenAL_Output::finishUpdate() -{ - alcProcessContext(alcGetCurrentContext()); -} + updateCommon(source, sound->getPosition(), sound->getMaxDistance(), sound->getRealVolume(), + getTimeScaledPitch(sound), sound->getUseEnv()); + getALError(); + } + void OpenAL_Output::startUpdate() + { + alcSuspendContext(alcGetCurrentContext()); + } -void OpenAL_Output::updateListener(const osg::Vec3f &pos, const osg::Vec3f &atdir, const osg::Vec3f &updir, Environment env) -{ - if(mContext) + void OpenAL_Output::finishUpdate() { - ALfloat orient[6] = { - atdir.x(), atdir.y(), atdir.z(), - updir.x(), updir.y(), updir.z() - }; - alListenerfv(AL_POSITION, pos.ptr()); - alListenerfv(AL_ORIENTATION, orient); + alcProcessContext(alcGetCurrentContext()); + } - if(env != mListenerEnv) + void OpenAL_Output::updateListener( + const osg::Vec3f& pos, const osg::Vec3f& atdir, const osg::Vec3f& updir, Environment env) + { + if (mContext) { - alSpeedOfSound(((env == Env_Underwater) ? Constants::SoundSpeedUnderwater : Constants::SoundSpeedInAir) * Constants::UnitsPerMeter); + ALfloat orient[6] = { atdir.x(), atdir.y(), atdir.z(), updir.x(), updir.y(), updir.z() }; + alListenerfv(AL_POSITION, pos.ptr()); + alListenerfv(AL_ORIENTATION, orient); - // Update active sources with the environment's direct filter - if(mWaterFilter) + if (env != mListenerEnv) { - ALuint filter = (env == Env_Underwater) ? mWaterFilter : AL_FILTER_NULL; - for(Sound *sound : mActiveSounds) - { - if(sound->getUseEnv()) - alSourcei(GET_PTRID(sound->mHandle), AL_DIRECT_FILTER, filter); - } - for(Stream *sound : mActiveStreams) + alSpeedOfSound(((env == Env_Underwater) ? Constants::SoundSpeedUnderwater : Constants::SoundSpeedInAir) + * Constants::UnitsPerMeter); + + // Update active sources with the environment's direct filter + if (mWaterFilter) { - if(sound->getUseEnv()) - alSourcei( - reinterpret_cast(sound->mHandle)->mSource, - AL_DIRECT_FILTER, filter - ); + ALuint filter = (env == Env_Underwater) ? mWaterFilter : AL_FILTER_NULL; + for (Sound* sound : mActiveSounds) + { + if (sound->getUseEnv()) + alSourcei(GET_PTRID(sound->mHandle), AL_DIRECT_FILTER, filter); + } + for (Stream* sound : mActiveStreams) + { + if (sound->getUseEnv()) + alSourcei(reinterpret_cast(sound->mHandle)->mSource, AL_DIRECT_FILTER, + filter); + } } + // Update the environment effect + if (mEffectSlot) + alAuxiliaryEffectSloti( + mEffectSlot, AL_EFFECTSLOT_EFFECT, (env == Env_Underwater) ? mWaterEffect : mDefaultEffect); } - // Update the environment effect - if(mEffectSlot) - alAuxiliaryEffectSloti(mEffectSlot, AL_EFFECTSLOT_EFFECT, - (env == Env_Underwater) ? mWaterEffect : mDefaultEffect - ); + getALError(); } - getALError(); - } - mListenerPos = pos; - mListenerEnv = env; -} - - -void OpenAL_Output::pauseSounds(int types) -{ - std::vector sources; - for(Sound *sound : mActiveSounds) - { - if((types&sound->getPlayType())) - sources.push_back(GET_PTRID(sound->mHandle)); + mListenerPos = pos; + mListenerEnv = env; } - for(Stream *sound : mActiveStreams) + + void OpenAL_Output::pauseSounds(int types) { - if((types&sound->getPlayType())) + std::vector sources; + for (Sound* sound : mActiveSounds) { - OpenAL_SoundStream *stream = reinterpret_cast(sound->mHandle); - sources.push_back(stream->mSource); + if ((types & sound->getPlayType())) + sources.push_back(GET_PTRID(sound->mHandle)); + } + for (Stream* sound : mActiveStreams) + { + if ((types & sound->getPlayType())) + { + OpenAL_SoundStream* stream = reinterpret_cast(sound->mHandle); + sources.push_back(stream->mSource); + } + } + if (!sources.empty()) + { + alSourcePausev(sources.size(), sources.data()); + getALError(); } } - if(!sources.empty()) - { - alSourcePausev(sources.size(), sources.data()); - getALError(); - } -} -void OpenAL_Output::pauseActiveDevice() -{ - if (mDevice == nullptr) - return; - - if(alcIsExtensionPresent(mDevice, "ALC_SOFT_PAUSE_DEVICE")) + void OpenAL_Output::pauseActiveDevice() { - LPALCDEVICEPAUSESOFT alcDevicePauseSOFT = nullptr; - getALCFunc(alcDevicePauseSOFT, mDevice, "alcDevicePauseSOFT"); - alcDevicePauseSOFT(mDevice); - getALCError(mDevice); - } + if (mDevice == nullptr) + return; - alListenerf(AL_GAIN, 0.0f); -} + if (alcIsExtensionPresent(mDevice, "ALC_SOFT_PAUSE_DEVICE")) + { + LPALCDEVICEPAUSESOFT alcDevicePauseSOFT = nullptr; + getALCFunc(alcDevicePauseSOFT, mDevice, "alcDevicePauseSOFT"); + alcDevicePauseSOFT(mDevice); + getALCError(mDevice); + } -void OpenAL_Output::resumeActiveDevice() -{ - if (mDevice == nullptr) - return; + alListenerf(AL_GAIN, 0.0f); + } - if(alcIsExtensionPresent(mDevice, "ALC_SOFT_PAUSE_DEVICE")) + void OpenAL_Output::resumeActiveDevice() { - LPALCDEVICERESUMESOFT alcDeviceResumeSOFT = nullptr; - getALCFunc(alcDeviceResumeSOFT, mDevice, "alcDeviceResumeSOFT"); - alcDeviceResumeSOFT(mDevice); - getALCError(mDevice); - } + if (mDevice == nullptr) + return; - alListenerf(AL_GAIN, 1.0f); -} + if (alcIsExtensionPresent(mDevice, "ALC_SOFT_PAUSE_DEVICE")) + { + LPALCDEVICERESUMESOFT alcDeviceResumeSOFT = nullptr; + getALCFunc(alcDeviceResumeSOFT, mDevice, "alcDeviceResumeSOFT"); + alcDeviceResumeSOFT(mDevice); + getALCError(mDevice); + } -void OpenAL_Output::resumeSounds(int types) -{ - std::vector sources; - for(Sound *sound : mActiveSounds) - { - if((types&sound->getPlayType())) - sources.push_back(GET_PTRID(sound->mHandle)); + alListenerf(AL_GAIN, 1.0f); } - for(Stream *sound : mActiveStreams) + + void OpenAL_Output::resumeSounds(int types) { - if((types&sound->getPlayType())) + std::vector sources; + for (Sound* sound : mActiveSounds) { - OpenAL_SoundStream *stream = reinterpret_cast(sound->mHandle); - sources.push_back(stream->mSource); + if ((types & sound->getPlayType())) + sources.push_back(GET_PTRID(sound->mHandle)); + } + for (Stream* sound : mActiveStreams) + { + if ((types & sound->getPlayType())) + { + OpenAL_SoundStream* stream = reinterpret_cast(sound->mHandle); + sources.push_back(stream->mSource); + } + } + if (!sources.empty()) + { + alSourcePlayv(sources.size(), sources.data()); + getALError(); } } - if(!sources.empty()) + + OpenAL_Output::OpenAL_Output(SoundManager& mgr) + : Sound_Output(mgr) + , mDevice(nullptr) + , mContext(nullptr) + , mListenerPos(0.0f, 0.0f, 0.0f) + , mListenerEnv(Env_Normal) + , mWaterFilter(0) + , mWaterEffect(0) + , mDefaultEffect(0) + , mEffectSlot(0) + , mStreamThread(std::make_unique()) { - alSourcePlayv(sources.size(), sources.data()); - getALError(); } -} + OpenAL_Output::~OpenAL_Output() + { + OpenAL_Output::deinit(); + } -OpenAL_Output::OpenAL_Output(SoundManager &mgr) - : Sound_Output(mgr) - , mDevice(nullptr), mContext(nullptr) - , mListenerPos(0.0f, 0.0f, 0.0f), mListenerEnv(Env_Normal) - , mWaterFilter(0), mWaterEffect(0), mDefaultEffect(0), mEffectSlot(0) - , mStreamThread(std::make_unique()) -{ -} - -OpenAL_Output::~OpenAL_Output() -{ - OpenAL_Output::deinit(); -} - -float OpenAL_Output::getTimeScaledPitch(SoundBase *sound) -{ - const bool shouldScale = !(sound->mParams.mFlags & PlayMode::NoScaling); - return shouldScale ? sound->getPitch() * mManager.getSimulationTimeScale() : sound->getPitch(); -} + float OpenAL_Output::getTimeScaledPitch(SoundBase* sound) + { + const bool shouldScale = !(sound->mParams.mFlags & PlayMode::NoScaling); + return shouldScale ? sound->getPitch() * mManager.getSimulationTimeScale() : sound->getPitch(); + } } diff --git a/apps/openmw/mwsound/openal_output.hpp b/apps/openmw/mwsound/openal_output.hpp index c68c65c165..b2d85f43a4 100644 --- a/apps/openmw/mwsound/openal_output.hpp +++ b/apps/openmw/mwsound/openal_output.hpp @@ -1,13 +1,13 @@ #ifndef GAME_SOUND_OPENAL_OUTPUT_H #define GAME_SOUND_OPENAL_OUTPUT_H +#include +#include #include #include -#include -#include -#include "alc.h" #include "al.h" +#include "alc.h" #include "alext.h" #include "sound_output.hpp" @@ -21,16 +21,18 @@ namespace MWSound class OpenAL_Output : public Sound_Output { - ALCdevice *mDevice; - ALCcontext *mContext; + ALCdevice* mDevice; + ALCcontext* mContext; - struct { + struct + { bool EXT_EFX : 1; bool SOFT_HRTF : 1; - } ALC = {false, false}; - struct { + } ALC = { false, false }; + struct + { bool SOFT_source_spatialize : 1; - } AL = {false}; + } AL = { false }; typedef std::deque IDDq; IDDq mFreeSources; @@ -51,46 +53,49 @@ namespace MWSound struct StreamThread; std::unique_ptr mStreamThread; - void initCommon2D(ALuint source, const osg::Vec3f &pos, ALfloat gain, ALfloat pitch, bool loop, bool useenv); - void initCommon3D(ALuint source, const osg::Vec3f &pos, ALfloat mindist, ALfloat maxdist, ALfloat gain, ALfloat pitch, bool loop, bool useenv); + void initCommon2D(ALuint source, const osg::Vec3f& pos, ALfloat gain, ALfloat pitch, bool loop, bool useenv); + void initCommon3D(ALuint source, const osg::Vec3f& pos, ALfloat mindist, ALfloat maxdist, ALfloat gain, + ALfloat pitch, bool loop, bool useenv); - void updateCommon(ALuint source, const osg::Vec3f &pos, ALfloat maxdist, ALfloat gain, ALfloat pitch, bool useenv); + void updateCommon( + ALuint source, const osg::Vec3f& pos, ALfloat maxdist, ALfloat gain, ALfloat pitch, bool useenv); - float getTimeScaledPitch(SoundBase *sound); + float getTimeScaledPitch(SoundBase* sound); - OpenAL_Output& operator=(const OpenAL_Output &rhs); - OpenAL_Output(const OpenAL_Output &rhs); + OpenAL_Output& operator=(const OpenAL_Output& rhs); + OpenAL_Output(const OpenAL_Output& rhs); public: std::vector enumerate() override; - bool init(const std::string &devname, const std::string &hrtfname, HrtfMode hrtfmode) override; + bool init(const std::string& devname, const std::string& hrtfname, HrtfMode hrtfmode) override; void deinit() override; std::vector enumerateHrtf() override; - void setHrtf(const std::string &hrtfname, HrtfMode hrtfmode) override; + void setHrtf(const std::string& hrtfname, HrtfMode hrtfmode) override; - std::pair loadSound(const std::string &fname) override; + std::pair loadSound(const std::string& fname) override; size_t unloadSound(Sound_Handle data) override; - bool playSound(Sound *sound, Sound_Handle data, float offset) override; - bool playSound3D(Sound *sound, Sound_Handle data, float offset) override; - void finishSound(Sound *sound) override; - bool isSoundPlaying(Sound *sound) override; - void updateSound(Sound *sound) override; - - bool streamSound(DecoderPtr decoder, Stream *sound, bool getLoudnessData=false) override; - bool streamSound3D(DecoderPtr decoder, Stream *sound, bool getLoudnessData) override; - void finishStream(Stream *sound) override; - double getStreamDelay(Stream *sound) override; - double getStreamOffset(Stream *sound) override; - float getStreamLoudness(Stream *sound) override; - bool isStreamPlaying(Stream *sound) override; - void updateStream(Stream *sound) override; + bool playSound(Sound* sound, Sound_Handle data, float offset) override; + bool playSound3D(Sound* sound, Sound_Handle data, float offset) override; + void finishSound(Sound* sound) override; + bool isSoundPlaying(Sound* sound) override; + void updateSound(Sound* sound) override; + + bool streamSound(DecoderPtr decoder, Stream* sound, bool getLoudnessData = false) override; + bool streamSound3D(DecoderPtr decoder, Stream* sound, bool getLoudnessData) override; + void finishStream(Stream* sound) override; + double getStreamDelay(Stream* sound) override; + double getStreamOffset(Stream* sound) override; + float getStreamLoudness(Stream* sound) override; + bool isStreamPlaying(Stream* sound) override; + void updateStream(Stream* sound) override; void startUpdate() override; void finishUpdate() override; - void updateListener(const osg::Vec3f &pos, const osg::Vec3f &atdir, const osg::Vec3f &updir, Environment env) override; + void updateListener( + const osg::Vec3f& pos, const osg::Vec3f& atdir, const osg::Vec3f& updir, Environment env) override; void pauseSounds(int types) override; void resumeSounds(int types) override; @@ -98,7 +103,7 @@ namespace MWSound void pauseActiveDevice() override; void resumeActiveDevice() override; - OpenAL_Output(SoundManager &mgr); + OpenAL_Output(SoundManager& mgr); virtual ~OpenAL_Output(); }; } diff --git a/apps/openmw/mwsound/regionsoundselector.cpp b/apps/openmw/mwsound/regionsoundselector.cpp index 1553344913..fd5f6f521c 100644 --- a/apps/openmw/mwsound/regionsoundselector.cpp +++ b/apps/openmw/mwsound/regionsoundselector.cpp @@ -1,8 +1,8 @@ #include "regionsoundselector.hpp" +#include #include #include -#include #include #include @@ -14,19 +14,20 @@ namespace MWSound { namespace { - int addChance(int result, const ESM::Region::SoundRef &v) + int addChance(int result, const ESM::Region::SoundRef& v) { return result + v.mChance; } } RegionSoundSelector::RegionSoundSelector() - : mMinTimeBetweenSounds(Fallback::Map::getFloat("Weather_Minimum_Time_Between_Environmental_Sounds")) - , mMaxTimeBetweenSounds(Fallback::Map::getFloat("Weather_Maximum_Time_Between_Environmental_Sounds")) - {} + : mMinTimeBetweenSounds(Fallback::Map::getFloat("Weather_Minimum_Time_Between_Environmental_Sounds")) + , mMaxTimeBetweenSounds(Fallback::Map::getFloat("Weather_Maximum_Time_Between_Environmental_Sounds")) + { + } - std::optional RegionSoundSelector::getNextRandom(float duration, const std::string& regionName, - const MWBase::World& world) + std::optional RegionSoundSelector::getNextRandom( + float duration, const std::string& regionName, const MWBase::World& world) { mTimePassed += duration; @@ -58,8 +59,7 @@ namespace MWSound const int r = Misc::Rng::rollDice(std::max(mSumChance, 100)); int pos = 0; - const auto isSelected = [&] (const ESM::Region::SoundRef& sound) - { + const auto isSelected = [&](const ESM::Region::SoundRef& sound) { if (r - pos < sound.mChance) return true; pos += sound.mChance; diff --git a/apps/openmw/mwsound/regionsoundselector.hpp b/apps/openmw/mwsound/regionsoundselector.hpp index 35df8a531b..586c3b07ea 100644 --- a/apps/openmw/mwsound/regionsoundselector.hpp +++ b/apps/openmw/mwsound/regionsoundselector.hpp @@ -13,19 +13,19 @@ namespace MWSound { class RegionSoundSelector { - public: - std::optional getNextRandom(float duration, const std::string& regionName, - const MWBase::World& world); + public: + std::optional getNextRandom( + float duration, const std::string& regionName, const MWBase::World& world); - RegionSoundSelector(); + RegionSoundSelector(); - private: - float mTimeToNextEnvSound = 0.0f; - int mSumChance = 0; - std::string mLastRegionName; - float mTimePassed = 0.0; - float mMinTimeBetweenSounds; - float mMaxTimeBetweenSounds; + private: + float mTimeToNextEnvSound = 0.0f; + int mSumChance = 0; + std::string mLastRegionName; + float mTimePassed = 0.0; + float mMinTimeBetweenSounds; + float mMaxTimeBetweenSounds; }; } diff --git a/apps/openmw/mwsound/sound.hpp b/apps/openmw/mwsound/sound.hpp index 2a07f05779..48e8975340 100644 --- a/apps/openmw/mwsound/sound.hpp +++ b/apps/openmw/mwsound/sound.hpp @@ -19,8 +19,14 @@ namespace MWSound }; // For testing individual PlayMode flags - inline int operator&(int a, PlayMode b) { return a & static_cast(b); } - inline int operator&(PlayMode a, PlayMode b) { return static_cast(a) & static_cast(b); } + inline int operator&(int a, PlayMode b) + { + return a & static_cast(b); + } + inline int operator&(PlayMode a, PlayMode b) + { + return static_cast(a) & static_cast(b); + } struct SoundParams { @@ -36,7 +42,8 @@ namespace MWSound float mFadeStep = 0.0f; }; - class SoundBase { + class SoundBase + { SoundBase& operator=(const SoundBase&) = delete; SoundBase(const SoundBase&) = delete; SoundBase(SoundBase&&) = delete; @@ -49,7 +56,7 @@ namespace MWSound friend class OpenAL_Output; public: - void setPosition(const osg::Vec3f &pos) { mParams.mPos = pos; } + void setPosition(const osg::Vec3f& pos) { mParams.mPos = pos; } void setVolume(float volume) { mParams.mVolume = volume; } void setBaseVolume(float volume) { mParams.mBaseVolume = volume; } void setFadeout(float duration) { setFade(duration, 0.0, Play_StopAtFadeEnd); } @@ -85,7 +92,8 @@ namespace MWSound /// once the fade duration has passed or the target volume has been /// reached. If Play_FadeExponential is set, enables the exponential /// fade mode (see above). - void setFade(float duration, float targetVolume, int flags = 0) { + void setFade(float duration, float targetVolume, int flags = 0) + { // Approximation of log(1%) (i.e., -40 dB). constexpr float minus40Decibel = -4.6f; @@ -141,14 +149,13 @@ namespace MWSound return getInFade() || !(mParams.mFlags & Play_StopAtFadeEnd); } - const osg::Vec3f &getPosition() const { return mParams.mPos; } + const osg::Vec3f& getPosition() const { return mParams.mPos; } float getRealVolume() const { return mParams.mVolume * mParams.mBaseVolume * mParams.mFadeVolume; } float getPitch() const { return mParams.mPitch; } float getMinDistance() const { return mParams.mMinDistance; } float getMaxDistance() const { return mParams.mMaxDistance; } - MWSound::Type getPlayType() const - { return static_cast(mParams.mFlags & MWSound::Type::Mask); } + MWSound::Type getPlayType() const { return static_cast(mParams.mFlags & MWSound::Type::Mask); } bool getUseEnv() const { return !(mParams.mFlags & MWSound::PlayMode::NoEnv); } bool getIsLooping() const { return mParams.mFlags & MWSound::PlayMode::Loop; } bool getDistanceCull() const { return mParams.mFlags & MWSound::PlayMode::RemoveAtDistance; } @@ -164,7 +171,8 @@ namespace MWSound SoundBase() = default; }; - class Sound : public SoundBase { + class Sound : public SoundBase + { Sound& operator=(const Sound&) = delete; Sound(const Sound&) = delete; Sound(Sound&&) = delete; @@ -173,7 +181,8 @@ namespace MWSound Sound() = default; }; - class Stream : public SoundBase { + class Stream : public SoundBase + { Stream& operator=(const Stream&) = delete; Stream(const Stream&) = delete; Stream(Stream&&) = delete; diff --git a/apps/openmw/mwsound/sound_buffer.cpp b/apps/openmw/mwsound/sound_buffer.cpp index 814e400305..0a1058f16e 100644 --- a/apps/openmw/mwsound/sound_buffer.cpp +++ b/apps/openmw/mwsound/sound_buffer.cpp @@ -5,9 +5,9 @@ #include "../mwworld/esmstore.hpp" #include +#include #include #include -#include #include #include @@ -36,11 +36,14 @@ namespace MWSound } } - SoundBufferPool::SoundBufferPool(const VFS::Manager& vfs, Sound_Output& output) : - mVfs(&vfs), - mOutput(&output), - mBufferCacheMax(std::max(Settings::Manager::getInt("buffer cache max", "Sound"), 1) * 1024 * 1024), - mBufferCacheMin(std::min(static_cast(std::max(Settings::Manager::getInt("buffer cache min", "Sound"), 1)) * 1024 * 1024, mBufferCacheMax)) + SoundBufferPool::SoundBufferPool(const VFS::Manager& vfs, Sound_Output& output) + : mVfs(&vfs) + , mOutput(&output) + , mBufferCacheMax(std::max(Settings::Manager::getInt("buffer cache max", "Sound"), 1) * 1024 * 1024) + , mBufferCacheMin( + std::min(static_cast(std::max(Settings::Manager::getInt("buffer cache min", "Sound"), 1)) + * 1024 * 1024, + mBufferCacheMax)) { } @@ -75,7 +78,8 @@ namespace MWSound sfx = it->second; else { - const ESM::Sound *sound = MWBase::Environment::get().getWorld()->getStore().get().search(soundId); + const ESM::Sound* sound + = MWBase::Environment::get().getWorld()->getStore().get().search(soundId); if (sound == nullptr) return {}; sfx = insertSound(soundId, *sound); @@ -104,9 +108,9 @@ namespace MWSound void SoundBufferPool::clear() { - for (auto &sfx : mSoundBuffers) + for (auto& sfx : mSoundBuffers) { - if(sfx.mHandle) + if (sfx.mHandle) mOutput->unloadSound(sfx.mHandle); sfx.mHandle = nullptr; } diff --git a/apps/openmw/mwsound/sound_buffer.hpp b/apps/openmw/mwsound/sound_buffer.hpp index 5c45ac08aa..1b9960eded 100644 --- a/apps/openmw/mwsound/sound_buffer.hpp +++ b/apps/openmw/mwsound/sound_buffer.hpp @@ -2,8 +2,8 @@ #define GAME_SOUND_SOUND_BUFFER_H #include -#include #include +#include #include #include "sound_output.hpp" @@ -24,82 +24,86 @@ namespace MWSound class Sound_Buffer { - public: - template - Sound_Buffer(T&& resname, float volume, float mindist, float maxdist) - : mResourceName(std::forward(resname)), mVolume(volume), mMinDist(mindist), mMaxDist(maxdist) - {} + public: + template + Sound_Buffer(T&& resname, float volume, float mindist, float maxdist) + : mResourceName(std::forward(resname)) + , mVolume(volume) + , mMinDist(mindist) + , mMaxDist(maxdist) + { + } - const std::string& getResourceName() const noexcept { return mResourceName; } + const std::string& getResourceName() const noexcept { return mResourceName; } - Sound_Handle getHandle() const noexcept { return mHandle; } + Sound_Handle getHandle() const noexcept { return mHandle; } - float getVolume() const noexcept { return mVolume; } + float getVolume() const noexcept { return mVolume; } - float getMinDist() const noexcept { return mMinDist; } + float getMinDist() const noexcept { return mMinDist; } - float getMaxDist() const noexcept { return mMaxDist; } + float getMaxDist() const noexcept { return mMaxDist; } - private: - std::string mResourceName; - float mVolume; - float mMinDist; - float mMaxDist; - Sound_Handle mHandle = nullptr; - std::size_t mUses = 0; + private: + std::string mResourceName; + float mVolume; + float mMinDist; + float mMaxDist; + Sound_Handle mHandle = nullptr; + std::size_t mUses = 0; - friend class SoundBufferPool; + friend class SoundBufferPool; }; class SoundBufferPool { - public: - SoundBufferPool(const VFS::Manager& vfs, Sound_Output& output); - - SoundBufferPool(const SoundBufferPool&) = delete; + public: + SoundBufferPool(const VFS::Manager& vfs, Sound_Output& output); - ~SoundBufferPool(); + SoundBufferPool(const SoundBufferPool&) = delete; - /// Lookup a soundId for its sound data (resource name, local volume, - /// minRange, and maxRange) - Sound_Buffer* lookup(const std::string& soundId) const; + ~SoundBufferPool(); - /// Lookup a soundId for its sound data (resource name, local volume, - /// minRange, and maxRange), and ensure it's ready for use. - Sound_Buffer* load(const std::string& soundId); + /// Lookup a soundId for its sound data (resource name, local volume, + /// minRange, and maxRange) + Sound_Buffer* lookup(const std::string& soundId) const; - void use(Sound_Buffer& sfx) - { - if (sfx.mUses++ == 0) - { - const auto it = std::find(mUnusedBuffers.begin(), mUnusedBuffers.end(), &sfx); - if (it != mUnusedBuffers.end()) - mUnusedBuffers.erase(it); - } - } + /// Lookup a soundId for its sound data (resource name, local volume, + /// minRange, and maxRange), and ensure it's ready for use. + Sound_Buffer* load(const std::string& soundId); - void release(Sound_Buffer& sfx) + void use(Sound_Buffer& sfx) + { + if (sfx.mUses++ == 0) { - if (--sfx.mUses == 0) - mUnusedBuffers.push_front(&sfx); + const auto it = std::find(mUnusedBuffers.begin(), mUnusedBuffers.end(), &sfx); + if (it != mUnusedBuffers.end()) + mUnusedBuffers.erase(it); } - - void clear(); - - private: - const VFS::Manager* const mVfs; - Sound_Output* mOutput; - std::deque mSoundBuffers; - std::unordered_map mBufferNameMap; - std::size_t mBufferCacheMax; - std::size_t mBufferCacheMin; - std::size_t mBufferCacheSize = 0; - // NOTE: unused buffers are stored in front-newest order. - std::deque mUnusedBuffers; - - inline Sound_Buffer* insertSound(const std::string& soundId, const ESM::Sound& sound); - - inline void unloadUnused(); + } + + void release(Sound_Buffer& sfx) + { + if (--sfx.mUses == 0) + mUnusedBuffers.push_front(&sfx); + } + + void clear(); + + private: + const VFS::Manager* const mVfs; + Sound_Output* mOutput; + std::deque mSoundBuffers; + std::unordered_map mBufferNameMap; + std::size_t mBufferCacheMax; + std::size_t mBufferCacheMin; + std::size_t mBufferCacheSize = 0; + // NOTE: unused buffers are stored in front-newest order. + std::deque mUnusedBuffers; + + inline Sound_Buffer* insertSound(const std::string& soundId, const ESM::Sound& sound); + + inline void unloadUnused(); }; } diff --git a/apps/openmw/mwsound/sound_decoder.hpp b/apps/openmw/mwsound/sound_decoder.hpp index 34bae87d74..f6dcdb7032 100644 --- a/apps/openmw/mwsound/sound_decoder.hpp +++ b/apps/openmw/mwsound/sound_decoder.hpp @@ -11,21 +11,23 @@ namespace VFS namespace MWSound { - enum SampleType { + enum SampleType + { SampleType_UInt8, SampleType_Int16, SampleType_Float32 }; - const char *getSampleTypeName(SampleType type); + const char* getSampleTypeName(SampleType type); - enum ChannelConfig { + enum ChannelConfig + { ChannelConfig_Mono, ChannelConfig_Stereo, ChannelConfig_Quad, ChannelConfig_5point1, ChannelConfig_7point1 }; - const char *getChannelConfigName(ChannelConfig config); + const char* getChannelConfigName(ChannelConfig config); size_t framesToBytes(size_t frames, ChannelConfig config, SampleType type); size_t bytesToFrames(size_t bytes, ChannelConfig config, SampleType type); @@ -34,23 +36,25 @@ namespace MWSound { const VFS::Manager* mResourceMgr; - virtual void open(const std::string &fname) = 0; + virtual void open(const std::string& fname) = 0; virtual void close() = 0; virtual std::string getName() = 0; - virtual void getInfo(int *samplerate, ChannelConfig *chans, SampleType *type) = 0; + virtual void getInfo(int* samplerate, ChannelConfig* chans, SampleType* type) = 0; - virtual size_t read(char *buffer, size_t bytes) = 0; - virtual void readAll(std::vector &output); + virtual size_t read(char* buffer, size_t bytes) = 0; + virtual void readAll(std::vector& output); virtual size_t getSampleOffset() = 0; - Sound_Decoder(const VFS::Manager* resourceMgr) : mResourceMgr(resourceMgr) - { } - virtual ~Sound_Decoder() { } + Sound_Decoder(const VFS::Manager* resourceMgr) + : mResourceMgr(resourceMgr) + { + } + virtual ~Sound_Decoder() {} private: - Sound_Decoder(const Sound_Decoder &rhs); - Sound_Decoder& operator=(const Sound_Decoder &rhs); + Sound_Decoder(const Sound_Decoder& rhs); + Sound_Decoder& operator=(const Sound_Decoder& rhs); }; } diff --git a/apps/openmw/mwsound/sound_output.hpp b/apps/openmw/mwsound/sound_output.hpp index 9ec8b17dc9..d7c35fbbc6 100644 --- a/apps/openmw/mwsound/sound_output.hpp +++ b/apps/openmw/mwsound/sound_output.hpp @@ -1,8 +1,8 @@ #ifndef GAME_SOUND_SOUND_OUTPUT_H #define GAME_SOUND_SOUND_OUTPUT_H -#include #include +#include #include #include "../mwbase/soundmanager.hpp" @@ -15,11 +15,12 @@ namespace MWSound class Stream; // An opaque handle for the implementation's sound buffers. - typedef void *Sound_Handle; + typedef void* Sound_Handle; // An opaque handle for the implementation's sound instances. - typedef void *Sound_Instance; + typedef void* Sound_Instance; - enum class HrtfMode { + enum class HrtfMode + { Disable, Enable, Auto @@ -33,37 +34,39 @@ namespace MWSound class Sound_Output { - SoundManager &mManager; + SoundManager& mManager; virtual std::vector enumerate() = 0; - virtual bool init(const std::string &devname, const std::string &hrtfname, HrtfMode hrtfmode) = 0; + virtual bool init(const std::string& devname, const std::string& hrtfname, HrtfMode hrtfmode) = 0; virtual void deinit() = 0; virtual std::vector enumerateHrtf() = 0; - virtual void setHrtf(const std::string &hrtfname, HrtfMode hrtfmode) = 0; + virtual void setHrtf(const std::string& hrtfname, HrtfMode hrtfmode) = 0; - virtual std::pair loadSound(const std::string &fname) = 0; + virtual std::pair loadSound(const std::string& fname) = 0; virtual size_t unloadSound(Sound_Handle data) = 0; - virtual bool playSound(Sound *sound, Sound_Handle data, float offset) = 0; - virtual bool playSound3D(Sound *sound, Sound_Handle data, float offset) = 0; - virtual void finishSound(Sound *sound) = 0; - virtual bool isSoundPlaying(Sound *sound) = 0; - virtual void updateSound(Sound *sound) = 0; - - virtual bool streamSound(DecoderPtr decoder, Stream *sound, bool getLoudnessData=false) = 0; - virtual bool streamSound3D(DecoderPtr decoder, Stream *sound, bool getLoudnessData) = 0; - virtual void finishStream(Stream *sound) = 0; - virtual double getStreamDelay(Stream *sound) = 0; - virtual double getStreamOffset(Stream *sound) = 0; - virtual float getStreamLoudness(Stream *sound) = 0; - virtual bool isStreamPlaying(Stream *sound) = 0; - virtual void updateStream(Stream *sound) = 0; + virtual bool playSound(Sound* sound, Sound_Handle data, float offset) = 0; + virtual bool playSound3D(Sound* sound, Sound_Handle data, float offset) = 0; + virtual void finishSound(Sound* sound) = 0; + virtual bool isSoundPlaying(Sound* sound) = 0; + virtual void updateSound(Sound* sound) = 0; + + virtual bool streamSound(DecoderPtr decoder, Stream* sound, bool getLoudnessData = false) = 0; + virtual bool streamSound3D(DecoderPtr decoder, Stream* sound, bool getLoudnessData) = 0; + virtual void finishStream(Stream* sound) = 0; + virtual double getStreamDelay(Stream* sound) = 0; + virtual double getStreamOffset(Stream* sound) = 0; + virtual float getStreamLoudness(Stream* sound) = 0; + virtual bool isStreamPlaying(Stream* sound) = 0; + virtual void updateStream(Stream* sound) = 0; virtual void startUpdate() = 0; virtual void finishUpdate() = 0; - virtual void updateListener(const osg::Vec3f &pos, const osg::Vec3f &atdir, const osg::Vec3f &updir, Environment env) = 0; + virtual void updateListener( + const osg::Vec3f& pos, const osg::Vec3f& atdir, const osg::Vec3f& updir, Environment env) + = 0; virtual void pauseSounds(int types) = 0; virtual void resumeSounds(int types) = 0; @@ -71,17 +74,20 @@ namespace MWSound virtual void pauseActiveDevice() = 0; virtual void resumeActiveDevice() = 0; - Sound_Output& operator=(const Sound_Output &rhs); - Sound_Output(const Sound_Output &rhs); + Sound_Output& operator=(const Sound_Output& rhs); + Sound_Output(const Sound_Output& rhs); protected: bool mInitialized; - Sound_Output(SoundManager &mgr) - : mManager(mgr), mInitialized(false) - { } + Sound_Output(SoundManager& mgr) + : mManager(mgr) + , mInitialized(false) + { + } + public: - virtual ~Sound_Output() { } + virtual ~Sound_Output() {} bool isInitialized() const { return mInitialized; } diff --git a/apps/openmw/mwsound/soundmanagerimp.cpp b/apps/openmw/mwsound/soundmanagerimp.cpp index 3bd371ef8f..c19908b255 100644 --- a/apps/openmw/mwsound/soundmanagerimp.cpp +++ b/apps/openmw/mwsound/soundmanagerimp.cpp @@ -7,28 +7,27 @@ #include +#include #include #include -#include #include #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/statemanager.hpp" +#include "../mwbase/world.hpp" -#include "../mwworld/esmstore.hpp" #include "../mwworld/cellstore.hpp" +#include "../mwworld/esmstore.hpp" #include "../mwmechanics/actorutil.hpp" +#include "sound.hpp" #include "sound_buffer.hpp" #include "sound_decoder.hpp" #include "sound_output.hpp" -#include "sound.hpp" -#include "openal_output.hpp" #include "ffmpeg_decoder.hpp" - +#include "openal_output.hpp" namespace MWSound { @@ -46,13 +45,15 @@ namespace MWSound settings.mNearWaterPoints = Fallback::Map::getInt("Water_NearWaterPoints"); settings.mNearWaterIndoorTolerance = Fallback::Map::getFloat("Water_NearWaterIndoorTolerance"); settings.mNearWaterOutdoorTolerance = Fallback::Map::getFloat("Water_NearWaterOutdoorTolerance"); - settings.mNearWaterIndoorID = Misc::StringUtils::lowerCase(Fallback::Map::getString("Water_NearWaterIndoorID")); - settings.mNearWaterOutdoorID = Misc::StringUtils::lowerCase(Fallback::Map::getString("Water_NearWaterOutdoorID")); + settings.mNearWaterIndoorID + = Misc::StringUtils::lowerCase(Fallback::Map::getString("Water_NearWaterIndoorID")); + settings.mNearWaterOutdoorID + = Misc::StringUtils::lowerCase(Fallback::Map::getString("Water_NearWaterOutdoorID")); return settings; } - float initialFadeVolume(float squaredDist, Sound_Buffer *sfx, Type type, PlayMode mode) + float initialFadeVolume(float squaredDist, Sound_Buffer* sfx, Type type, PlayMode mode) { // If a sound is farther away than its maximum distance, start playing it with a zero fade volume. // It can still become audible once the player moves closer. @@ -72,7 +73,10 @@ namespace MWSound } // For combining PlayMode and Type flags - inline int operator|(PlayMode a, Type b) { return static_cast(a) | static_cast(b); } + inline int operator|(PlayMode a, Type b) + { + return static_cast(a) | static_cast(b); + } SoundManager::SoundManager(const VFS::Manager* vfs, bool useSound) : mVFS(vfs) @@ -80,9 +84,9 @@ namespace MWSound , mWaterSoundUpdater(makeWaterSoundUpdaterSettings()) , mSoundBuffers(*vfs, *mOutput) , mListenerUnderwater(false) - , mListenerPos(0,0,0) - , mListenerDir(1,0,0) - , mListenerUp(0,0,1) + , mListenerPos(0, 0, 0) + , mListenerDir(1, 0, 0) + , mListenerUp(0, 0, 1) , mUnderwaterSound(nullptr) , mNearWaterSound(nullptr) , mPlaybackPaused(false) @@ -90,7 +94,7 @@ namespace MWSound , mLastCell(nullptr) , mCurrentRegionSound(nullptr) { - if(!useSound) + if (!useSound) { Log(Debug::Info) << "Sound disabled."; return; @@ -98,11 +102,10 @@ namespace MWSound const std::string& hrtfname = Settings::Manager::getString("hrtf", "Sound"); int hrtfstate = Settings::Manager::getInt("hrtf enable", "Sound"); - HrtfMode hrtfmode = hrtfstate < 0 ? HrtfMode::Auto : - hrtfstate > 0 ? HrtfMode::Enable : HrtfMode::Disable; + HrtfMode hrtfmode = hrtfstate < 0 ? HrtfMode::Auto : hrtfstate > 0 ? HrtfMode::Enable : HrtfMode::Disable; const std::string& devname = Settings::Manager::getString("device", "Sound"); - if(!mOutput->init(devname, hrtfname, hrtfmode)) + if (!mOutput->init(devname, hrtfname, hrtfmode)) { Log(Debug::Error) << "Failed to initialize audio output, sound disabled"; return; @@ -112,17 +115,17 @@ namespace MWSound std::stringstream stream; stream << "Enumerated output devices:\n"; - for(const std::string &name : names) + for (const std::string& name : names) stream << " " << name; Log(Debug::Info) << stream.str(); stream.str(""); names = mOutput->enumerateHrtf(); - if(!names.empty()) + if (!names.empty()) { stream << "Enumerated HRTF names:\n"; - for(const std::string &name : names) + for (const std::string& name : names) stream << " " << name; Log(Debug::Info) << stream.str(); @@ -142,7 +145,7 @@ namespace MWSound return std::make_shared(mVFS); } - DecoderPtr SoundManager::loadVoice(const std::string &voicefile) + DecoderPtr SoundManager::loadVoice(const std::string& voicefile) { try { @@ -150,7 +153,7 @@ namespace MWSound decoder->open(Misc::ResourceHelpers::correctSoundPath(voicefile, decoder->mResourceMgr)); return decoder; } - catch(std::exception &e) + catch (std::exception& e) { Log(Debug::Error) << "Failed to load audio from " << voicefile << ": " << e.what(); } @@ -168,27 +171,31 @@ namespace MWSound return mStreams.get(); } - StreamPtr SoundManager::playVoice(DecoderPtr decoder, const osg::Vec3f &pos, bool playlocal) + StreamPtr SoundManager::playVoice(DecoderPtr decoder, const osg::Vec3f& pos, bool playlocal) { MWBase::World* world = MWBase::Environment::get().getWorld(); - static const float fAudioMinDistanceMult = world->getStore().get().find("fAudioMinDistanceMult")->mValue.getFloat(); - static const float fAudioMaxDistanceMult = world->getStore().get().find("fAudioMaxDistanceMult")->mValue.getFloat(); - static const float fAudioVoiceDefaultMinDistance = world->getStore().get().find("fAudioVoiceDefaultMinDistance")->mValue.getFloat(); - static const float fAudioVoiceDefaultMaxDistance = world->getStore().get().find("fAudioVoiceDefaultMaxDistance")->mValue.getFloat(); + static const float fAudioMinDistanceMult + = world->getStore().get().find("fAudioMinDistanceMult")->mValue.getFloat(); + static const float fAudioMaxDistanceMult + = world->getStore().get().find("fAudioMaxDistanceMult")->mValue.getFloat(); + static const float fAudioVoiceDefaultMinDistance + = world->getStore().get().find("fAudioVoiceDefaultMinDistance")->mValue.getFloat(); + static const float fAudioVoiceDefaultMaxDistance + = world->getStore().get().find("fAudioVoiceDefaultMaxDistance")->mValue.getFloat(); static float minDistance = std::max(fAudioVoiceDefaultMinDistance * fAudioMinDistanceMult, 1.0f); static float maxDistance = std::max(fAudioVoiceDefaultMaxDistance * fAudioMaxDistanceMult, minDistance); bool played; float basevol = volumeFromType(Type::Voice); StreamPtr sound = getStreamRef(); - if(playlocal) + if (playlocal) { sound->init([&] { SoundParams params; params.mBaseVolume = basevol; params.mFlags = PlayMode::NoEnv | Type::Voice | Play_2D; return params; - } ()); + }()); played = mOutput->streamSound(decoder, sound.get(), true); } else @@ -201,10 +208,10 @@ namespace MWSound params.mMaxDistance = maxDistance; params.mFlags = PlayMode::Normal | Type::Voice | Play_3D; return params; - } ()); + }()); played = mOutput->streamSound3D(decoder, sound.get(), true); } - if(!played) + if (!played) return nullptr; return sound; } @@ -217,7 +224,7 @@ namespace MWSound void SoundManager::stopMusic() { - if(mMusic) + if (mMusic) { mOutput->finishStream(mMusic.get()); mMusic = nullptr; @@ -226,7 +233,7 @@ namespace MWSound void SoundManager::streamMusicFull(const std::string& filename) { - if(!mOutput->isInitialized()) + if (!mOutput->isInitialized()) return; Log(Debug::Info) << "Playing " << filename; mLastPlayedMusic = filename; @@ -238,20 +245,19 @@ namespace MWSound { decoder->open(filename); } - catch(std::exception &e) + catch (std::exception& e) { Log(Debug::Error) << "Failed to load audio from " << filename << ": " << e.what(); return; } - mMusic = getStreamRef(); mMusic->init([&] { SoundParams params; params.mBaseVolume = volumeFromType(Type::Music); params.mFlags = PlayMode::NoEnvNoScaling | Type::Music | Play_2D; return params; - } ()); + }()); mOutput->streamSound(decoder, mMusic.get()); } @@ -270,13 +276,13 @@ namespace MWSound void SoundManager::startRandomTitle() { - const std::vector &filelist = mMusicFiles[mCurrentPlaylist]; - auto &tracklist = mMusicToPlay[mCurrentPlaylist]; + const std::vector& filelist = mMusicFiles[mCurrentPlaylist]; + auto& tracklist = mMusicToPlay[mCurrentPlaylist]; // Do a Fisher-Yates shuffle // Repopulate if playlist is empty - if(tracklist.empty()) + if (tracklist.empty()) { tracklist.resize(filelist.size()); std::iota(tracklist.begin(), tracklist.end(), 0); @@ -285,8 +291,8 @@ namespace MWSound int i = Misc::Rng::rollDice(tracklist.size()); // Reshuffle if last played music is the same after a repopulation - if(filelist[tracklist[i]] == mLastPlayedMusic) - i = (i+1) % tracklist.size(); + if (filelist[tracklist[i]] == mLastPlayedMusic) + i = (i + 1) % tracklist.size(); // Remove music from list after advancing music advanceMusic(filelist[tracklist[i]]); @@ -294,10 +300,9 @@ namespace MWSound tracklist.pop_back(); } - void SoundManager::streamMusic(const std::string& filename) { - advanceMusic("Music/"+filename); + advanceMusic("Music/" + filename); } bool SoundManager::isMusicPlaying() @@ -305,7 +310,7 @@ namespace MWSound return mMusic && mOutput->isStreamPlaying(mMusic.get()); } - void SoundManager::playPlaylist(const std::string &playlist) + void SoundManager::playPlaylist(const std::string& playlist) { if (mCurrentPlaylist == playlist) return; @@ -356,31 +361,32 @@ namespace MWSound startRandomTitle(); } - void SoundManager::say(const MWWorld::ConstPtr &ptr, const std::string &filename) + void SoundManager::say(const MWWorld::ConstPtr& ptr, const std::string& filename) { - if(!mOutput->isInitialized()) + if (!mOutput->isInitialized()) return; DecoderPtr decoder = loadVoice(mVFS->normalizeFilename("Sound/" + filename)); if (!decoder) return; - MWBase::World *world = MWBase::Environment::get().getWorld(); + MWBase::World* world = MWBase::Environment::get().getWorld(); const osg::Vec3f pos = world->getActorHeadTransform(ptr).getTrans(); stopSay(ptr); StreamPtr sound = playVoice(decoder, pos, (ptr == MWMechanics::getPlayer())); - if(!sound) return; + if (!sound) + return; - mSaySoundsQueue.emplace(ptr.mRef, SaySound {ptr.mCell, std::move(sound)}); + mSaySoundsQueue.emplace(ptr.mRef, SaySound{ ptr.mCell, std::move(sound) }); } - float SoundManager::getSaySoundLoudness(const MWWorld::ConstPtr &ptr) const + float SoundManager::getSaySoundLoudness(const MWWorld::ConstPtr& ptr) const { SaySoundMap::const_iterator snditer = mActiveSaySounds.find(ptr.mRef); - if(snditer != mActiveSaySounds.end()) + if (snditer != mActiveSaySounds.end()) { - Stream *sound = snditer->second.mStream.get(); + Stream* sound = snditer->second.mStream.get(); return mOutput->getStreamLoudness(sound); } @@ -389,7 +395,7 @@ namespace MWSound void SoundManager::say(const std::string& filename) { - if(!mOutput->isInitialized()) + if (!mOutput->isInitialized()) return; DecoderPtr decoder = loadVoice(mVFS->normalizeFilename("Sound/" + filename)); @@ -398,37 +404,38 @@ namespace MWSound stopSay(MWWorld::ConstPtr()); StreamPtr sound = playVoice(decoder, osg::Vec3f(), true); - if(!sound) return; + if (!sound) + return; - mActiveSaySounds.emplace(nullptr, SaySound {nullptr, std::move(sound)}); + mActiveSaySounds.emplace(nullptr, SaySound{ nullptr, std::move(sound) }); } - bool SoundManager::sayDone(const MWWorld::ConstPtr &ptr) const + bool SoundManager::sayDone(const MWWorld::ConstPtr& ptr) const { SaySoundMap::const_iterator snditer = mActiveSaySounds.find(ptr.mRef); - if(snditer != mActiveSaySounds.end()) + if (snditer != mActiveSaySounds.end()) { - if(mOutput->isStreamPlaying(snditer->second.mStream.get())) + if (mOutput->isStreamPlaying(snditer->second.mStream.get())) return false; return true; } return true; } - bool SoundManager::sayActive(const MWWorld::ConstPtr &ptr) const + bool SoundManager::sayActive(const MWWorld::ConstPtr& ptr) const { SaySoundMap::const_iterator snditer = mSaySoundsQueue.find(ptr.mRef); - if(snditer != mSaySoundsQueue.end()) + if (snditer != mSaySoundsQueue.end()) { - if(mOutput->isStreamPlaying(snditer->second.mStream.get())) + if (mOutput->isStreamPlaying(snditer->second.mStream.get())) return true; return false; } snditer = mActiveSaySounds.find(ptr.mRef); - if(snditer != mActiveSaySounds.end()) + if (snditer != mActiveSaySounds.end()) { - if(mOutput->isStreamPlaying(snditer->second.mStream.get())) + if (mOutput->isStreamPlaying(snditer->second.mStream.get())) return true; return false; } @@ -436,27 +443,26 @@ namespace MWSound return false; } - void SoundManager::stopSay(const MWWorld::ConstPtr &ptr) + void SoundManager::stopSay(const MWWorld::ConstPtr& ptr) { SaySoundMap::iterator snditer = mSaySoundsQueue.find(ptr.mRef); - if(snditer != mSaySoundsQueue.end()) + if (snditer != mSaySoundsQueue.end()) { mOutput->finishStream(snditer->second.mStream.get()); mSaySoundsQueue.erase(snditer); } snditer = mActiveSaySounds.find(ptr.mRef); - if(snditer != mActiveSaySounds.end()) + if (snditer != mActiveSaySounds.end()) { mOutput->finishStream(snditer->second.mStream.get()); mActiveSaySounds.erase(snditer); } } - - Stream *SoundManager::playTrack(const DecoderPtr& decoder, Type type) + Stream* SoundManager::playTrack(const DecoderPtr& decoder, Type type) { - if(!mOutput->isInitialized()) + if (!mOutput->isInitialized()) return nullptr; StreamPtr track = getStreamRef(); @@ -465,8 +471,8 @@ namespace MWSound params.mBaseVolume = volumeFromType(type); params.mFlags = PlayMode::NoEnvNoScaling | type | Play_2D; return params; - } ()); - if(!mOutput->streamSound(decoder, track.get())) + }()); + if (!mOutput->streamSound(decoder, track.get())) return nullptr; Stream* result = track.get(); @@ -475,28 +481,29 @@ namespace MWSound return result; } - void SoundManager::stopTrack(Stream *stream) + void SoundManager::stopTrack(Stream* stream) { mOutput->finishStream(stream); TrackList::iterator iter = std::lower_bound(mActiveTracks.begin(), mActiveTracks.end(), stream, - [] (const StreamPtr& lhs, Stream* rhs) { return lhs.get() < rhs; }); - if(iter != mActiveTracks.end() && iter->get() == stream) + [](const StreamPtr& lhs, Stream* rhs) { return lhs.get() < rhs; }); + if (iter != mActiveTracks.end() && iter->get() == stream) mActiveTracks.erase(iter); } - double SoundManager::getTrackTimeDelay(Stream *stream) + double SoundManager::getTrackTimeDelay(Stream* stream) { return mOutput->getStreamDelay(stream); } - - Sound* SoundManager::playSound(std::string_view soundId, float volume, float pitch, Type type, PlayMode mode, float offset) + Sound* SoundManager::playSound( + std::string_view soundId, float volume, float pitch, Type type, PlayMode mode, float offset) { - if(!mOutput->isInitialized()) + if (!mOutput->isInitialized()) return nullptr; - Sound_Buffer *sfx = mSoundBuffers.load(Misc::StringUtils::lowerCase(soundId)); - if(!sfx) return nullptr; + Sound_Buffer* sfx = mSoundBuffers.load(Misc::StringUtils::lowerCase(soundId)); + if (!sfx) + return nullptr; // Only one copy of given sound can be played at time, so stop previous copy stopSound(sfx, MWWorld::ConstPtr()); @@ -509,8 +516,8 @@ namespace MWSound params.mPitch = pitch; params.mFlags = mode | type | Play_2D; return params; - } ()); - if(!mOutput->playSound(sound.get(), sfx->getHandle(), offset)) + }()); + if (!mOutput->playSound(sound.get(), sfx->getHandle(), offset)) return nullptr; Sound* result = sound.get(); @@ -519,11 +526,10 @@ namespace MWSound return result; } - Sound *SoundManager::playSound3D(const MWWorld::ConstPtr &ptr, std::string_view soundId, - float volume, float pitch, Type type, PlayMode mode, - float offset) + Sound* SoundManager::playSound3D(const MWWorld::ConstPtr& ptr, std::string_view soundId, float volume, float pitch, + Type type, PlayMode mode, float offset) { - if(!mOutput->isInitialized()) + if (!mOutput->isInitialized()) return nullptr; const osg::Vec3f objpos(ptr.getRefData().getPosition().asVec3()); @@ -532,15 +538,16 @@ namespace MWSound return nullptr; // Look up the sound in the ESM data - Sound_Buffer *sfx = mSoundBuffers.load(Misc::StringUtils::lowerCase(soundId)); - if(!sfx) return nullptr; + Sound_Buffer* sfx = mSoundBuffers.load(Misc::StringUtils::lowerCase(soundId)); + if (!sfx) + return nullptr; // Only one copy of given sound can be played at time on ptr, so stop previous copy stopSound(sfx, ptr); bool played; SoundPtr sound = getSoundRef(); - if(!(mode&PlayMode::NoPlayerLocal) && ptr == MWMechanics::getPlayer()) + if (!(mode & PlayMode::NoPlayerLocal) && ptr == MWMechanics::getPlayer()) { sound->init([&] { SoundParams params; @@ -549,7 +556,7 @@ namespace MWSound params.mPitch = pitch; params.mFlags = mode | type | Play_2D; return params; - } ()); + }()); played = mOutput->playSound(sound.get(), sfx->getHandle(), offset); } else @@ -565,31 +572,31 @@ namespace MWSound params.mMaxDistance = sfx->getMaxDist(); params.mFlags = mode | type | Play_3D; return params; - } ()); + }()); played = mOutput->playSound3D(sound.get(), sfx->getHandle(), offset); } - if(!played) + if (!played) return nullptr; Sound* result = sound.get(); auto it = mActiveSounds.find(ptr.mRef); if (it == mActiveSounds.end()) - it = mActiveSounds.emplace(ptr.mRef, ActiveSound {ptr.mCell, {}}).first; + it = mActiveSounds.emplace(ptr.mRef, ActiveSound{ ptr.mCell, {} }).first; it->second.mList.emplace_back(std::move(sound), sfx); mSoundBuffers.use(*sfx); return result; } - Sound *SoundManager::playSound3D(const osg::Vec3f& initialPos, std::string_view soundId, - float volume, float pitch, Type type, PlayMode mode, - float offset) + Sound* SoundManager::playSound3D(const osg::Vec3f& initialPos, std::string_view soundId, float volume, float pitch, + Type type, PlayMode mode, float offset) { - if(!mOutput->isInitialized()) + if (!mOutput->isInitialized()) return nullptr; // Look up the sound in the ESM data - Sound_Buffer *sfx = mSoundBuffers.load(Misc::StringUtils::lowerCase(soundId)); - if(!sfx) return nullptr; + Sound_Buffer* sfx = mSoundBuffers.load(Misc::StringUtils::lowerCase(soundId)); + if (!sfx) + return nullptr; const float squaredDist = (mListenerPos - initialPos).length2(); @@ -605,8 +612,8 @@ namespace MWSound params.mMaxDistance = sfx->getMaxDist(); params.mFlags = mode | type | Play_3D; return params; - } ()); - if(!mOutput->playSound3D(sound.get(), sfx->getHandle(), offset)) + }()); + if (!mOutput->playSound3D(sound.get(), sfx->getHandle(), offset)) return nullptr; Sound* result = sound.get(); @@ -615,53 +622,54 @@ namespace MWSound return result; } - void SoundManager::stopSound(Sound *sound) + void SoundManager::stopSound(Sound* sound) { - if(sound) + if (sound) mOutput->finishSound(sound); } - void SoundManager::stopSound(Sound_Buffer *sfx, const MWWorld::ConstPtr &ptr) + void SoundManager::stopSound(Sound_Buffer* sfx, const MWWorld::ConstPtr& ptr) { SoundMap::iterator snditer = mActiveSounds.find(ptr.mRef); - if(snditer != mActiveSounds.end()) + if (snditer != mActiveSounds.end()) { - for (SoundBufferRefPair &snd : snditer->second.mList) + for (SoundBufferRefPair& snd : snditer->second.mList) { - if(snd.second == sfx) + if (snd.second == sfx) mOutput->finishSound(snd.first.get()); } } } - void SoundManager::stopSound3D(const MWWorld::ConstPtr &ptr, std::string_view soundId) + void SoundManager::stopSound3D(const MWWorld::ConstPtr& ptr, std::string_view soundId) { - if(!mOutput->isInitialized()) + if (!mOutput->isInitialized()) return; - Sound_Buffer *sfx = mSoundBuffers.lookup(Misc::StringUtils::lowerCase(soundId)); - if (!sfx) return; + Sound_Buffer* sfx = mSoundBuffers.lookup(Misc::StringUtils::lowerCase(soundId)); + if (!sfx) + return; stopSound(sfx, ptr); } - void SoundManager::stopSound3D(const MWWorld::ConstPtr &ptr) + void SoundManager::stopSound3D(const MWWorld::ConstPtr& ptr) { SoundMap::iterator snditer = mActiveSounds.find(ptr.mRef); - if(snditer != mActiveSounds.end()) + if (snditer != mActiveSounds.end()) { - for (SoundBufferRefPair &snd : snditer->second.mList) + for (SoundBufferRefPair& snd : snditer->second.mList) mOutput->finishSound(snd.first.get()); } SaySoundMap::iterator sayiter = mSaySoundsQueue.find(ptr.mRef); - if(sayiter != mSaySoundsQueue.end()) + if (sayiter != mSaySoundsQueue.end()) mOutput->finishStream(sayiter->second.mStream.get()); sayiter = mActiveSaySounds.find(ptr.mRef); - if(sayiter != mActiveSaySounds.end()) + if (sayiter != mActiveSaySounds.end()) mOutput->finishStream(sayiter->second.mStream.get()); } - void SoundManager::stopSound(const MWWorld::CellStore *cell) + void SoundManager::stopSound(const MWWorld::CellStore* cell) { for (auto& [ref, sound] : mActiveSounds) { @@ -678,47 +686,47 @@ namespace MWSound mOutput->finishStream(sound.mStream.get()); } - for (const auto& [ref, sound]: mActiveSaySounds) + for (const auto& [ref, sound] : mActiveSaySounds) { if (ref != nullptr && ref != MWMechanics::getPlayer().mRef && sound.mCell == cell) mOutput->finishStream(sound.mStream.get()); } } - void SoundManager::fadeOutSound3D(const MWWorld::ConstPtr &ptr, - std::string_view soundId, float duration) + void SoundManager::fadeOutSound3D(const MWWorld::ConstPtr& ptr, std::string_view soundId, float duration) { SoundMap::iterator snditer = mActiveSounds.find(ptr.mRef); - if(snditer != mActiveSounds.end()) + if (snditer != mActiveSounds.end()) { - Sound_Buffer *sfx = mSoundBuffers.lookup(Misc::StringUtils::lowerCase(soundId)); + Sound_Buffer* sfx = mSoundBuffers.lookup(Misc::StringUtils::lowerCase(soundId)); if (sfx == nullptr) return; - for (SoundBufferRefPair &sndbuf : snditer->second.mList) + for (SoundBufferRefPair& sndbuf : snditer->second.mList) { - if(sndbuf.second == sfx) + if (sndbuf.second == sfx) sndbuf.first->setFadeout(duration); } } } - bool SoundManager::getSoundPlaying(const MWWorld::ConstPtr &ptr, std::string_view soundId) const + bool SoundManager::getSoundPlaying(const MWWorld::ConstPtr& ptr, std::string_view soundId) const { SoundMap::const_iterator snditer = mActiveSounds.find(ptr.mRef); - if(snditer != mActiveSounds.end()) + if (snditer != mActiveSounds.end()) { - Sound_Buffer *sfx = mSoundBuffers.lookup(Misc::StringUtils::lowerCase(soundId)); + Sound_Buffer* sfx = mSoundBuffers.lookup(Misc::StringUtils::lowerCase(soundId)); return std::find_if(snditer->second.mList.cbegin(), snditer->second.mList.cend(), - [this,sfx](const SoundBufferRefPair &snd) -> bool - { return snd.second == sfx && mOutput->isSoundPlaying(snd.first.get()); } - ) != snditer->second.mList.cend(); + [this, sfx](const SoundBufferRefPair& snd) -> bool { + return snd.second == sfx && mOutput->isSoundPlaying(snd.first.get()); + }) + != snditer->second.mList.cend(); } return false; } void SoundManager::pauseSounds(BlockerType blocker, int types) { - if(mOutput->isInitialized()) + if (mOutput->isInitialized()) { if (mPausedSoundTypes[blocker] != 0) resumeSounds(blocker); @@ -731,7 +739,7 @@ namespace MWSound void SoundManager::resumeSounds(BlockerType blocker) { - if(mOutput->isInitialized()) + if (mOutput->isInitialized()) { mPausedSoundTypes[blocker] = 0; int types = int(Type::Mask); @@ -765,9 +773,9 @@ namespace MWSound void SoundManager::updateRegionSound(float duration) { - MWBase::World *world = MWBase::Environment::get().getWorld(); + MWBase::World* world = MWBase::Environment::get().getWorld(); const MWWorld::ConstPtr player = world->getPlayerPtr(); - const ESM::Cell *cell = player.getCell()->getCell(); + const ESM::Cell* cell = player.getCell()->getCell(); if (!cell->isExterior()) return; @@ -782,7 +790,7 @@ namespace MWSound { MWBase::World* world = MWBase::Environment::get().getWorld(); const MWWorld::ConstPtr player = world->getPlayerPtr(); - const ESM::Cell *curcell = player.getCell()->getCell(); + const ESM::Cell* curcell = player.getCell()->getCell(); const auto update = mWaterSoundUpdater.update(player, *world); WaterSoundAction action; @@ -811,12 +819,12 @@ namespace MWSound } std::pair SoundManager::getWaterSoundAction( - const WaterSoundUpdate& update, const ESM::Cell* cell) const + const WaterSoundUpdate& update, const ESM::Cell* cell) const { if (mNearWaterSound) { if (update.mVolume == 0.0f) - return {WaterSoundAction::FinishSound, nullptr}; + return { WaterSoundAction::FinishSound, nullptr }; bool soundIdChanged = false; @@ -826,29 +834,28 @@ namespace MWSound const auto snditer = mActiveSounds.find(nullptr); if (snditer != mActiveSounds.end()) { - const auto pairiter = std::find_if( - snditer->second.mList.begin(), snditer->second.mList.end(), - [this](const SoundBufferRefPairList::value_type &item) -> bool - { return mNearWaterSound == item.first.get(); } - ); + const auto pairiter = std::find_if(snditer->second.mList.begin(), snditer->second.mList.end(), + [this](const SoundBufferRefPairList::value_type& item) -> bool { + return mNearWaterSound == item.first.get(); + }); if (pairiter != snditer->second.mList.end() && pairiter->second != sfx) soundIdChanged = true; } } if (soundIdChanged) - return {WaterSoundAction::PlaySound, nullptr}; + return { WaterSoundAction::PlaySound, nullptr }; if (sfx) - return {WaterSoundAction::SetVolume, sfx}; + return { WaterSoundAction::SetVolume, sfx }; } else if (update.mVolume > 0.0f) - return {WaterSoundAction::PlaySound, nullptr}; + return { WaterSoundAction::PlaySound, nullptr }; - return {WaterSoundAction::DoNothing, nullptr}; + return { WaterSoundAction::DoNothing, nullptr }; } - void SoundManager::cull3DSound(SoundBase *sound) + void SoundManager::cull3DSound(SoundBase* sound) { // Hard-coded distance of 2000.0f is from vanilla Morrowind const float maxDist = sound->getDistanceCull() ? 2000.0f : sound->getMaxDistance(); @@ -860,7 +867,8 @@ namespace MWSound if (squaredDist > squaredMaxDist) { // If getDistanceCull() is set, delete the sound after it has faded out - sound->setFade(sSfxFadeOutDuration, 0.0f, Play_FadeExponential | (sound->getDistanceCull() ? Play_StopAtFadeEnd : 0)); + sound->setFade( + sSfxFadeOutDuration, 0.0f, Play_FadeExponential | (sound->getDistanceCull() ? Play_StopAtFadeEnd : 0)); } else { @@ -869,7 +877,6 @@ namespace MWSound } } - void SoundManager::updateSounds(float duration) { // We update active say sounds map for specific actors here @@ -892,37 +899,32 @@ namespace MWSound mTimePassed = 0.0f; // Make sure music is still playing - if(!isMusicPlaying() && !mCurrentPlaylist.empty()) + if (!isMusicPlaying() && !mCurrentPlaylist.empty()) startRandomTitle(); Environment env = Env_Normal; if (mListenerUnderwater) env = Env_Underwater; - else if(mUnderwaterSound) + else if (mUnderwaterSound) { mOutput->finishSound(mUnderwaterSound); mUnderwaterSound = nullptr; } mOutput->startUpdate(); - mOutput->updateListener( - mListenerPos, - mListenerDir, - mListenerUp, - env - ); + mOutput->updateListener(mListenerPos, mListenerDir, mListenerUp, env); updateMusic(duration); // Check if any sounds are finished playing, and trash them SoundMap::iterator snditer = mActiveSounds.begin(); - while(snditer != mActiveSounds.end()) + while (snditer != mActiveSounds.end()) { MWWorld::ConstPtr ptr = snditer->first; SoundBufferRefPairList::iterator sndidx = snditer->second.mList.begin(); - while(sndidx != snditer->second.mList.end()) + while (sndidx != snditer->second.mList.end()) { - Sound *sound = sndidx->first.get(); + Sound* sound = sndidx->first.get(); if (sound->getIs3D()) { @@ -932,7 +934,7 @@ namespace MWSound cull3DSound(sound); } - if(!sound->updateFade(duration) || !mOutput->isSoundPlaying(sound)) + if (!sound->updateFade(duration) || !mOutput->isSoundPlaying(sound)) { mOutput->finishSound(sound); if (sound == mUnderwaterSound) @@ -948,29 +950,29 @@ namespace MWSound ++sndidx; } } - if(snditer->second.mList.empty()) + if (snditer->second.mList.empty()) snditer = mActiveSounds.erase(snditer); else ++snditer; } SaySoundMap::iterator sayiter = mActiveSaySounds.begin(); - while(sayiter != mActiveSaySounds.end()) + while (sayiter != mActiveSaySounds.end()) { MWWorld::ConstPtr ptr = sayiter->first; - Stream *sound = sayiter->second.mStream.get(); + Stream* sound = sayiter->second.mStream.get(); if (sound->getIs3D()) { if (!ptr.isEmpty()) { - MWBase::World *world = MWBase::Environment::get().getWorld(); + MWBase::World* world = MWBase::Environment::get().getWorld(); sound->setPosition(world->getActorHeadTransform(ptr).getTrans()); } cull3DSound(sound); } - if(!sound->updateFade(duration) || !mOutput->isStreamPlaying(sound)) + if (!sound->updateFade(duration) || !mOutput->isStreamPlaying(sound)) { mOutput->finishStream(sound); sayiter = mActiveSaySounds.erase(sayiter); @@ -985,8 +987,8 @@ namespace MWSound TrackList::iterator trkiter = mActiveTracks.begin(); while (trkiter != mActiveTracks.end()) { - Stream *sound = trkiter->get(); - if(!mOutput->isStreamPlaying(sound)) + Stream* sound = trkiter->get(); + if (!mOutput->isStreamPlaying(sound)) { mOutput->finishStream(sound); trkiter = mActiveTracks.erase(trkiter); @@ -1000,16 +1002,15 @@ namespace MWSound } } - if(mListenerUnderwater) + if (mListenerUnderwater) { // Play underwater sound (after updating sounds) - if(!mUnderwaterSound) + if (!mUnderwaterSound) mUnderwaterSound = playSound("Underwater", 1.0f, 1.0f, Type::Sfx, PlayMode::LoopNoEnv); } mOutput->finishUpdate(); } - void SoundManager::updateMusic(float duration) { if (!mNextMusic.empty()) @@ -1026,47 +1027,44 @@ namespace MWSound } } - void SoundManager::update(float duration) { - if(!mOutput->isInitialized() || mPlaybackPaused) + if (!mOutput->isInitialized() || mPlaybackPaused) return; updateSounds(duration); - if (MWBase::Environment::get().getStateManager()->getState()!= - MWBase::StateManager::State_NoGame) + if (MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_NoGame) { updateRegionSound(duration); updateWaterSound(); } } - void SoundManager::processChangedSettings(const Settings::CategorySettingVector& settings) { mVolumeSettings.update(); - if(!mOutput->isInitialized()) + if (!mOutput->isInitialized()) return; mOutput->startUpdate(); - for(SoundMap::value_type &snd : mActiveSounds) + for (SoundMap::value_type& snd : mActiveSounds) { for (SoundBufferRefPair& sndbuf : snd.second.mList) { - Sound *sound = sndbuf.first.get(); + Sound* sound = sndbuf.first.get(); sound->setBaseVolume(volumeFromType(sound->getPlayType())); mOutput->updateSound(sound); } } - for(SaySoundMap::value_type &snd : mActiveSaySounds) + for (SaySoundMap::value_type& snd : mActiveSaySounds) { - Stream *sound = snd.second.mStream.get(); + Stream* sound = snd.second.mStream.get(); sound->setBaseVolume(volumeFromType(sound->getPlayType())); mOutput->updateStream(sound); } - for(SaySoundMap::value_type &snd : mSaySoundsQueue) + for (SaySoundMap::value_type& snd : mSaySoundsQueue) { - Stream *sound = snd.second.mStream.get(); + Stream* sound = snd.second.mStream.get(); sound->setBaseVolume(volumeFromType(sound->getPlayType())); mOutput->updateStream(sound); } @@ -1075,7 +1073,7 @@ namespace MWSound sound->setBaseVolume(volumeFromType(sound->getPlayType())); mOutput->updateStream(sound.get()); } - if(mMusic) + if (mMusic) { mMusic->setBaseVolume(volumeFromType(mMusic->getPlayType())); mOutput->updateStream(mMusic.get()); @@ -1083,21 +1081,22 @@ namespace MWSound mOutput->finishUpdate(); } - void SoundManager::setListenerPosDir(const osg::Vec3f &pos, const osg::Vec3f &dir, const osg::Vec3f &up, bool underwater) + void SoundManager::setListenerPosDir( + const osg::Vec3f& pos, const osg::Vec3f& dir, const osg::Vec3f& up, bool underwater) { mListenerPos = pos; mListenerDir = dir; - mListenerUp = up; + mListenerUp = up; mListenerUnderwater = underwater; mWaterSoundUpdater.setUnderwater(underwater); } - void SoundManager::updatePtr(const MWWorld::ConstPtr &old, const MWWorld::ConstPtr &updated) + void SoundManager::updatePtr(const MWWorld::ConstPtr& old, const MWWorld::ConstPtr& updated) { SoundMap::iterator snditer = mActiveSounds.find(old.mRef); - if(snditer != mActiveSounds.end()) + if (snditer != mActiveSounds.end()) snditer->second.mCell = updated.mCell; if (const auto it = mSaySoundsQueue.find(old.mRef); it != mSaySoundsQueue.end()) @@ -1109,60 +1108,83 @@ namespace MWSound // Default readAll implementation, for decoders that can't do anything // better - void Sound_Decoder::readAll(std::vector &output) + void Sound_Decoder::readAll(std::vector& output) { size_t total = output.size(); size_t got; - output.resize(total+32768); - while((got=read(&output[total], output.size()-total)) > 0) + output.resize(total + 32768); + while ((got = read(&output[total], output.size() - total)) > 0) { total += got; - output.resize(total*2); + output.resize(total * 2); } output.resize(total); } - - const char *getSampleTypeName(SampleType type) + const char* getSampleTypeName(SampleType type) { - switch(type) + switch (type) { - case SampleType_UInt8: return "U8"; - case SampleType_Int16: return "S16"; - case SampleType_Float32: return "Float32"; + case SampleType_UInt8: + return "U8"; + case SampleType_Int16: + return "S16"; + case SampleType_Float32: + return "Float32"; } return "(unknown sample type)"; } - const char *getChannelConfigName(ChannelConfig config) + const char* getChannelConfigName(ChannelConfig config) { - switch(config) + switch (config) { - case ChannelConfig_Mono: return "Mono"; - case ChannelConfig_Stereo: return "Stereo"; - case ChannelConfig_Quad: return "Quad"; - case ChannelConfig_5point1: return "5.1 Surround"; - case ChannelConfig_7point1: return "7.1 Surround"; + case ChannelConfig_Mono: + return "Mono"; + case ChannelConfig_Stereo: + return "Stereo"; + case ChannelConfig_Quad: + return "Quad"; + case ChannelConfig_5point1: + return "5.1 Surround"; + case ChannelConfig_7point1: + return "7.1 Surround"; } return "(unknown channel config)"; } size_t framesToBytes(size_t frames, ChannelConfig config, SampleType type) { - switch(config) + switch (config) { - case ChannelConfig_Mono: frames *= 1; break; - case ChannelConfig_Stereo: frames *= 2; break; - case ChannelConfig_Quad: frames *= 4; break; - case ChannelConfig_5point1: frames *= 6; break; - case ChannelConfig_7point1: frames *= 8; break; + case ChannelConfig_Mono: + frames *= 1; + break; + case ChannelConfig_Stereo: + frames *= 2; + break; + case ChannelConfig_Quad: + frames *= 4; + break; + case ChannelConfig_5point1: + frames *= 6; + break; + case ChannelConfig_7point1: + frames *= 8; + break; } - switch(type) + switch (type) { - case SampleType_UInt8: frames *= 1; break; - case SampleType_Int16: frames *= 2; break; - case SampleType_Float32: frames *= 4; break; + case SampleType_UInt8: + frames *= 1; + break; + case SampleType_Int16: + frames *= 2; + break; + case SampleType_Float32: + frames *= 4; + break; } return frames; } @@ -1176,9 +1198,9 @@ namespace MWSound { SoundManager::stopMusic(); - for(SoundMap::value_type &snd : mActiveSounds) + for (SoundMap::value_type& snd : mActiveSounds) { - for (SoundBufferRefPair &sndbuf : snd.second.mList) + for (SoundBufferRefPair& sndbuf : snd.second.mList) { mOutput->finishSound(sndbuf.first.get()); mSoundBuffers.release(*sndbuf.second); @@ -1188,15 +1210,15 @@ namespace MWSound mUnderwaterSound = nullptr; mNearWaterSound = nullptr; - for(SaySoundMap::value_type &snd : mSaySoundsQueue) + for (SaySoundMap::value_type& snd : mSaySoundsQueue) mOutput->finishStream(snd.second.mStream.get()); mSaySoundsQueue.clear(); - for(SaySoundMap::value_type &snd : mActiveSaySounds) + for (SaySoundMap::value_type& snd : mActiveSaySounds) mOutput->finishStream(snd.second.mStream.get()); mActiveSaySounds.clear(); - for(StreamPtr& sound : mActiveTracks) + for (StreamPtr& sound : mActiveTracks) mOutput->finishStream(sound.get()); mActiveTracks.clear(); mPlaybackPaused = false; diff --git a/apps/openmw/mwsound/soundmanagerimp.hpp b/apps/openmw/mwsound/soundmanagerimp.hpp index ab74d4acd3..64ff8117fb 100644 --- a/apps/openmw/mwsound/soundmanagerimp.hpp +++ b/apps/openmw/mwsound/soundmanagerimp.hpp @@ -1,23 +1,23 @@ #ifndef GAME_SOUND_SOUNDMANAGER_H #define GAME_SOUND_SOUNDMANAGER_H +#include #include #include -#include -#include #include +#include -#include -#include #include +#include +#include #include "../mwbase/soundmanager.hpp" #include "regionsoundselector.hpp" -#include "watersoundupdater.hpp" +#include "sound_buffer.hpp" #include "type.hpp" #include "volumesettings.hpp" -#include "sound_buffer.hpp" +#include "watersoundupdater.hpp" namespace VFS { @@ -97,8 +97,8 @@ namespace MWSound int mPausedSoundTypes[BlockerType::MaxCount] = {}; - Sound *mUnderwaterSound; - Sound *mNearWaterSound; + Sound* mUnderwaterSound; + Sound* mNearWaterSound; std::string mNextMusic; bool mPlaybackPaused; @@ -107,25 +107,25 @@ namespace MWSound float mTimePassed; - const ESM::Cell *mLastCell; + const ESM::Cell* mLastCell; Sound* mCurrentRegionSound; - Sound_Buffer *insertSound(const std::string &soundId, const ESM::Sound *sound); + Sound_Buffer* insertSound(const std::string& soundId, const ESM::Sound* sound); // returns a decoder to start streaming, or nullptr if the sound was not found - DecoderPtr loadVoice(const std::string &voicefile); + DecoderPtr loadVoice(const std::string& voicefile); SoundPtr getSoundRef(); StreamPtr getStreamRef(); - StreamPtr playVoice(DecoderPtr decoder, const osg::Vec3f &pos, bool playlocal); + StreamPtr playVoice(DecoderPtr decoder, const osg::Vec3f& pos, bool playlocal); void streamMusicFull(const std::string& filename); void advanceMusic(const std::string& filename); void startRandomTitle(); - void cull3DSound(SoundBase *sound); + void cull3DSound(SoundBase* sound); void updateSounds(float duration); void updateRegionSound(float duration); @@ -142,17 +142,17 @@ namespace MWSound PlaySound, }; - std::pair getWaterSoundAction(const WaterSoundUpdate& update, - const ESM::Cell* cell) const; + std::pair getWaterSoundAction( + const WaterSoundUpdate& update, const ESM::Cell* cell) const; - SoundManager(const SoundManager &rhs); - SoundManager& operator=(const SoundManager &rhs); + SoundManager(const SoundManager& rhs); + SoundManager& operator=(const SoundManager& rhs); protected: DecoderPtr getDecoder(); friend class OpenAL_Output; - void stopSound(Sound_Buffer *sfx, const MWWorld::ConstPtr &ptr); + void stopSound(Sound_Buffer* sfx, const MWWorld::ConstPtr& ptr); ///< Stop the given object from playing given sound buffer. public: @@ -171,14 +171,14 @@ namespace MWSound bool isMusicPlaying() override; ///< Returns true if music is playing - void playPlaylist(const std::string &playlist) override; + void playPlaylist(const std::string& playlist) override; ///< Start playing music from the selected folder /// \param name of the folder that contains the playlist void playTitleMusic() override; ///< Start playing title music - void say(const MWWorld::ConstPtr &reference, const std::string& filename) override; + void say(const MWWorld::ConstPtr& reference, const std::string& filename) override; ///< Make an actor say some text. /// \param filename name of a sound file in "Sound/" in the data directory. @@ -186,13 +186,13 @@ namespace MWSound ///< Say some text, without an actor ref /// \param filename name of a sound file in "Sound/" in the data directory. - bool sayActive(const MWWorld::ConstPtr &reference=MWWorld::ConstPtr()) const override; + bool sayActive(const MWWorld::ConstPtr& reference = MWWorld::ConstPtr()) const override; ///< Is actor not speaking? - bool sayDone(const MWWorld::ConstPtr &reference=MWWorld::ConstPtr()) const override; + bool sayDone(const MWWorld::ConstPtr& reference = MWWorld::ConstPtr()) const override; ///< For scripting backward compatibility - void stopSay(const MWWorld::ConstPtr &reference=MWWorld::ConstPtr()) override; + void stopSay(const MWWorld::ConstPtr& reference = MWWorld::ConstPtr()) override; ///< Stop an actor speaking float getSaySoundLoudness(const MWWorld::ConstPtr& reference) const override; @@ -200,55 +200,57 @@ namespace MWSound /// and get an average loudness value (scale [0,1]) at the current time position. /// If the actor is not saying anything, returns 0. - Stream *playTrack(const DecoderPtr& decoder, Type type) override; + Stream* playTrack(const DecoderPtr& decoder, Type type) override; ///< Play a 2D audio track, using a custom decoder - void stopTrack(Stream *stream) override; + void stopTrack(Stream* stream) override; ///< Stop the given audio track from playing - double getTrackTimeDelay(Stream *stream) override; + double getTrackTimeDelay(Stream* stream) override; ///< Retives the time delay, in seconds, of the audio track (must be a sound /// returned by \ref playTrack). Only intended to be called by the track /// decoder's read method. - Sound *playSound(std::string_view soundId, float volume, float pitch, Type type=Type::Sfx, PlayMode mode=PlayMode::Normal, float offset=0) override; + Sound* playSound(std::string_view soundId, float volume, float pitch, Type type = Type::Sfx, + PlayMode mode = PlayMode::Normal, float offset = 0) override; ///< Play a sound, independently of 3D-position ///< @param offset Number of seconds into the sound to start playback. - Sound *playSound3D(const MWWorld::ConstPtr &reference, std::string_view soundId, - float volume, float pitch, Type type=Type::Sfx, - PlayMode mode=PlayMode::Normal, float offset=0) override; - ///< Play a 3D sound attached to an MWWorld::Ptr. Will be updated automatically with the Ptr's position, unless Play_NoTrack is specified. + Sound* playSound3D(const MWWorld::ConstPtr& reference, std::string_view soundId, float volume, float pitch, + Type type = Type::Sfx, PlayMode mode = PlayMode::Normal, float offset = 0) override; + ///< Play a 3D sound attached to an MWWorld::Ptr. Will be updated automatically with the Ptr's position, unless + ///< Play_NoTrack is specified. ///< @param offset Number of seconds into the sound to start playback. - Sound *playSound3D(const osg::Vec3f& initialPos, std::string_view soundId, - float volume, float pitch, Type type, PlayMode mode, float offset=0) override; - ///< Play a 3D sound at \a initialPos. If the sound should be moving, it must be updated using Sound::setPosition. + Sound* playSound3D(const osg::Vec3f& initialPos, std::string_view soundId, float volume, float pitch, Type type, + PlayMode mode, float offset = 0) override; + ///< Play a 3D sound at \a initialPos. If the sound should be moving, it must be updated using + ///< Sound::setPosition. ///< @param offset Number of seconds into the sound to start playback. - void stopSound(Sound *sound) override; + void stopSound(Sound* sound) override; ///< Stop the given sound from playing /// @note no-op if \a sound is null - void stopSound3D(const MWWorld::ConstPtr &reference, std::string_view soundId) override; + void stopSound3D(const MWWorld::ConstPtr& reference, std::string_view soundId) override; ///< Stop the given object from playing the given sound, - void stopSound3D(const MWWorld::ConstPtr &reference) override; + void stopSound3D(const MWWorld::ConstPtr& reference) override; ///< Stop the given object from playing all sounds. - void stopSound(const MWWorld::CellStore *cell) override; + void stopSound(const MWWorld::CellStore* cell) override; ///< Stop all sounds for the given cell. - void fadeOutSound3D(const MWWorld::ConstPtr &reference, std::string_view soundId, float duration) override; + void fadeOutSound3D(const MWWorld::ConstPtr& reference, std::string_view soundId, float duration) override; ///< Fade out given sound (that is already playing) of given object ///< @param reference Reference to object, whose sound is faded out ///< @param soundId ID of the sound to fade out. ///< @param duration Time until volume reaches 0. - bool getSoundPlaying(const MWWorld::ConstPtr &reference, std::string_view soundId) const override; + bool getSoundPlaying(const MWWorld::ConstPtr& reference, std::string_view soundId) const override; ///< Is the given sound currently playing on the given object? - void pauseSounds(MWSound::BlockerType blocker, int types=int(Type::Mask)) override; + void pauseSounds(MWSound::BlockerType blocker, int types = int(Type::Mask)) override; ///< Pauses all currently playing sounds, including music. void resumeSounds(MWSound::BlockerType blocker) override; @@ -259,9 +261,10 @@ namespace MWSound void update(float duration); - void setListenerPosDir(const osg::Vec3f &pos, const osg::Vec3f &dir, const osg::Vec3f &up, bool underwater) override; + void setListenerPosDir( + const osg::Vec3f& pos, const osg::Vec3f& dir, const osg::Vec3f& up, bool underwater) override; - void updatePtr (const MWWorld::ConstPtr& old, const MWWorld::ConstPtr& updated) override; + void updatePtr(const MWWorld::ConstPtr& old, const MWWorld::ConstPtr& updated) override; void clear() override; }; diff --git a/apps/openmw/mwsound/type.hpp b/apps/openmw/mwsound/type.hpp index 5f063c3954..d7bc6dd05c 100644 --- a/apps/openmw/mwsound/type.hpp +++ b/apps/openmw/mwsound/type.hpp @@ -5,12 +5,12 @@ namespace MWSound { enum class Type { - Sfx = 1 << 5, /* Normal SFX sound */ + Sfx = 1 << 5, /* Normal SFX sound */ Voice = 1 << 6, /* Voice sound */ - Foot = 1 << 7, /* Footstep sound */ + Foot = 1 << 7, /* Footstep sound */ Music = 1 << 8, /* Music track */ Movie = 1 << 9, /* Movie audio track */ - Mask = Sfx | Voice | Foot | Music | Movie + Mask = Sfx | Voice | Foot | Music | Movie }; } diff --git a/apps/openmw/mwsound/volumesettings.cpp b/apps/openmw/mwsound/volumesettings.cpp index fd79b97e9b..4306bc5268 100644 --- a/apps/openmw/mwsound/volumesettings.cpp +++ b/apps/openmw/mwsound/volumesettings.cpp @@ -15,11 +15,11 @@ namespace MWSound } VolumeSettings::VolumeSettings() - : mMasterVolume(clamp(Settings::Manager::getFloat("master volume", "Sound"))), - mSFXVolume(clamp(Settings::Manager::getFloat("sfx volume", "Sound"))), - mMusicVolume(clamp(Settings::Manager::getFloat("music volume", "Sound"))), - mVoiceVolume(clamp(Settings::Manager::getFloat("voice volume", "Sound"))), - mFootstepsVolume(clamp(Settings::Manager::getFloat("footsteps volume", "Sound"))) + : mMasterVolume(clamp(Settings::Manager::getFloat("master volume", "Sound"))) + , mSFXVolume(clamp(Settings::Manager::getFloat("sfx volume", "Sound"))) + , mMusicVolume(clamp(Settings::Manager::getFloat("music volume", "Sound"))) + , mVoiceVolume(clamp(Settings::Manager::getFloat("voice volume", "Sound"))) + , mFootstepsVolume(clamp(Settings::Manager::getFloat("footsteps volume", "Sound"))) { } @@ -27,7 +27,7 @@ namespace MWSound { float volume = mMasterVolume; - switch(type) + switch (type) { case Type::Sfx: volume *= mSFXVolume; diff --git a/apps/openmw/mwsound/volumesettings.hpp b/apps/openmw/mwsound/volumesettings.hpp index eec5f5c1bf..884a3e1bca 100644 --- a/apps/openmw/mwsound/volumesettings.hpp +++ b/apps/openmw/mwsound/volumesettings.hpp @@ -7,19 +7,19 @@ namespace MWSound { class VolumeSettings { - public: - VolumeSettings(); + public: + VolumeSettings(); - float getVolumeFromType(Type type) const; + float getVolumeFromType(Type type) const; - void update(); + void update(); - private: - float mMasterVolume; - float mSFXVolume; - float mMusicVolume; - float mVoiceVolume; - float mFootstepsVolume; + private: + float mMasterVolume; + float mSFXVolume; + float mMusicVolume; + float mVoiceVolume; + float mFootstepsVolume; }; } diff --git a/apps/openmw/mwsound/watersoundupdater.hpp b/apps/openmw/mwsound/watersoundupdater.hpp index b20b9db6c0..3994cb4af5 100644 --- a/apps/openmw/mwsound/watersoundupdater.hpp +++ b/apps/openmw/mwsound/watersoundupdater.hpp @@ -33,21 +33,18 @@ namespace MWSound class WaterSoundUpdater { - public: - explicit WaterSoundUpdater(const WaterSoundUpdaterSettings& settings); + public: + explicit WaterSoundUpdater(const WaterSoundUpdaterSettings& settings); - WaterSoundUpdate update(const MWWorld::ConstPtr& player, const MWBase::World& world) const; + WaterSoundUpdate update(const MWWorld::ConstPtr& player, const MWBase::World& world) const; - void setUnderwater(bool value) - { - mListenerUnderwater = value; - } + void setUnderwater(bool value) { mListenerUnderwater = value; } - private: - const WaterSoundUpdaterSettings mSettings; - bool mListenerUnderwater = false; + private: + const WaterSoundUpdaterSettings mSettings; + bool mListenerUnderwater = false; - float getVolume(const MWWorld::ConstPtr& player, const MWBase::World& world) const; + float getVolume(const MWWorld::ConstPtr& player, const MWBase::World& world) const; }; } diff --git a/apps/openmw/mwstate/character.cpp b/apps/openmw/mwstate/character.cpp index 842a6f967d..847f82942d 100644 --- a/apps/openmw/mwstate/character.cpp +++ b/apps/openmw/mwstate/character.cpp @@ -1,11 +1,11 @@ #include "character.hpp" +#include #include #include #include -#include -#include #include +#include #include #include @@ -13,9 +13,9 @@ #include -bool MWState::operator< (const Slot& left, const Slot& right) +bool MWState::operator<(const Slot& left, const Slot& right) { - return left.mTimeStamp& contentFiles) @@ -28,29 +28,29 @@ std::string MWState::getFirstGameFile(const std::vector& contentFil return ""; } -void MWState::Character::addSlot (const std::filesystem::path& path, const std::string& game) +void MWState::Character::addSlot(const std::filesystem::path& path, const std::string& game) { Slot slot; slot.mPath = path; - slot.mTimeStamp = std::filesystem::last_write_time (path); + slot.mTimeStamp = std::filesystem::last_write_time(path); ESM::ESMReader reader; - reader.open (slot.mPath); + reader.open(slot.mPath); - if (reader.getRecName()!=ESM::REC_SAVE) + if (reader.getRecName() != ESM::REC_SAVE) return; // invalid save file -> ignore reader.getRecHeader(); - slot.mProfile.load (reader); + slot.mProfile.load(reader); if (!Misc::StringUtils::ciEqual(getFirstGameFile(slot.mProfile.mContentFiles), game)) return; // this file is for a different game -> ignore - mSlots.push_back (slot); + mSlots.push_back(slot); } -void MWState::Character::addSlot (const ESM::SavedGame& profile) +void MWState::Character::addSlot(const ESM::SavedGame& profile) { Slot slot; @@ -58,10 +58,10 @@ void MWState::Character::addSlot (const ESM::SavedGame& profile) // The profile description is user-supplied, so we need to escape the path Utf8Stream description(profile.mDescription); - while(!description.eof()) + while (!description.eof()) { auto c = description.consume(); - if(c <= 0x7F && std::isalnum(c)) // Ignore multibyte characters and non alphanumeric characters + if (c <= 0x7F && std::isalnum(c)) // Ignore multibyte characters and non alphanumeric characters stream << static_cast(c); else stream << '_'; @@ -71,7 +71,7 @@ void MWState::Character::addSlot (const ESM::SavedGame& profile) slot.mPath = mPath / (stream.str() + ext); // Append an index if necessary to ensure a unique file - int i=0; + int i = 0; while (std::filesystem::exists(slot.mPath)) { const std::string test = stream.str() + " - " + std::to_string(++i); @@ -79,30 +79,32 @@ void MWState::Character::addSlot (const ESM::SavedGame& profile) } slot.mProfile = profile; - slot.mTimeStamp = std::filesystem::file_time_type (); + slot.mTimeStamp = std::filesystem::file_time_type(); - mSlots.push_back (slot); + mSlots.push_back(slot); } -MWState::Character::Character (std::filesystem::path saves, const std::string& game) -: mPath (std::move(saves)) +MWState::Character::Character(std::filesystem::path saves, const std::string& game) + : mPath(std::move(saves)) { - if (!std::filesystem::is_directory (mPath)) + if (!std::filesystem::is_directory(mPath)) { - std::filesystem::create_directories (mPath); + std::filesystem::create_directories(mPath); } else { - for (const auto& iter : std::filesystem::directory_iterator (mPath)) + for (const auto& iter : std::filesystem::directory_iterator(mPath)) { try { - addSlot (iter, game); + addSlot(iter, game); } - catch (...) {} // ignoring bad saved game files for now + catch (...) + { + } // ignoring bad saved game files for now } - std::sort (mSlots.begin(), mSlots.end()); + std::sort(mSlots.begin(), mSlots.end()); } } @@ -111,7 +113,7 @@ void MWState::Character::cleanup() if (mSlots.empty()) { // All slots are gone, no need to keep the empty directory - if (std::filesystem::is_directory (mPath)) + if (std::filesystem::is_directory(mPath)) { // Extra safety check to make sure the directory is empty (e.g. slots failed to parse header) std::filesystem::directory_iterator it(mPath); @@ -121,45 +123,45 @@ void MWState::Character::cleanup() } } -const MWState::Slot *MWState::Character::createSlot (const ESM::SavedGame& profile) +const MWState::Slot* MWState::Character::createSlot(const ESM::SavedGame& profile) { - addSlot (profile); + addSlot(profile); return &mSlots.back(); } -void MWState::Character::deleteSlot (const Slot *slot) +void MWState::Character::deleteSlot(const Slot* slot) { int index = slot - mSlots.data(); - if (index<0 || index>=static_cast (mSlots.size())) + if (index < 0 || index >= static_cast(mSlots.size())) { // sanity check; not entirely reliable - throw std::logic_error ("slot not found"); + throw std::logic_error("slot not found"); } std::filesystem::remove(slot->mPath); - mSlots.erase (mSlots.begin()+index); + mSlots.erase(mSlots.begin() + index); } -const MWState::Slot *MWState::Character::updateSlot (const Slot *slot, const ESM::SavedGame& profile) +const MWState::Slot* MWState::Character::updateSlot(const Slot* slot, const ESM::SavedGame& profile) { int index = slot - mSlots.data(); - if (index<0 || index>=static_cast (mSlots.size())) + if (index < 0 || index >= static_cast(mSlots.size())) { // sanity check; not entirely reliable - throw std::logic_error ("slot not found"); + throw std::logic_error("slot not found"); } Slot newSlot = *slot; newSlot.mProfile = profile; - newSlot.mTimeStamp = std::filesystem::file_time_type (); + newSlot.mTimeStamp = std::filesystem::file_time_type(); - mSlots.erase (mSlots.begin()+index); + mSlots.erase(mSlots.begin() + index); - mSlots.push_back (newSlot); + mSlots.push_back(newSlot); return &mSlots.back(); } @@ -177,17 +179,13 @@ MWState::Character::SlotIterator MWState::Character::end() const const ESM::SavedGame& MWState::Character::getSignature() const { if (mSlots.empty()) - throw std::logic_error ("character signature not available"); + throw std::logic_error("character signature not available"); - const auto tiePlayerLevelAndTimeStamp = [] (const Slot& v) - { - return std::tie(v.mProfile.mPlayerLevel, v.mTimeStamp); - }; + const auto tiePlayerLevelAndTimeStamp + = [](const Slot& v) { return std::tie(v.mProfile.mPlayerLevel, v.mTimeStamp); }; - const auto lessByPlayerLevelAndTimeStamp = [&] (const Slot& l, const Slot& r) - { - return tiePlayerLevelAndTimeStamp(l) < tiePlayerLevelAndTimeStamp(r); - }; + const auto lessByPlayerLevelAndTimeStamp + = [&](const Slot& l, const Slot& r) { return tiePlayerLevelAndTimeStamp(l) < tiePlayerLevelAndTimeStamp(r); }; return std::max_element(mSlots.begin(), mSlots.end(), lessByPlayerLevelAndTimeStamp)->mProfile; } diff --git a/apps/openmw/mwstate/character.hpp b/apps/openmw/mwstate/character.hpp index 1f3f6debf5..7b9eba2fee 100644 --- a/apps/openmw/mwstate/character.hpp +++ b/apps/openmw/mwstate/character.hpp @@ -14,58 +14,55 @@ namespace MWState std::filesystem::file_time_type mTimeStamp; }; - bool operator< (const Slot& left, const Slot& right); + bool operator<(const Slot& left, const Slot& right); std::string getFirstGameFile(const std::vector& contentFiles); class Character { - public: + public: + typedef std::vector::const_reverse_iterator SlotIterator; - typedef std::vector::const_reverse_iterator SlotIterator; - - private: - - std::filesystem::path mPath; - std::vector mSlots; - - void addSlot (const std::filesystem::path& path, const std::string& game); + private: + std::filesystem::path mPath; + std::vector mSlots; - void addSlot (const ESM::SavedGame& profile); + void addSlot(const std::filesystem::path& path, const std::string& game); - public: + void addSlot(const ESM::SavedGame& profile); - Character (std::filesystem::path saves, const std::string& game); + public: + Character(std::filesystem::path saves, const std::string& game); - void cleanup(); - ///< Delete the directory we used, if it is empty + void cleanup(); + ///< Delete the directory we used, if it is empty - const Slot *createSlot (const ESM::SavedGame& profile); - ///< Create new slot. - /// - /// \attention The ownership of the slot is not transferred. + const Slot* createSlot(const ESM::SavedGame& profile); + ///< Create new slot. + /// + /// \attention The ownership of the slot is not transferred. - /// \note Slot must belong to this character. - /// - /// \attention The \a slot pointer will be invalidated by this call. - void deleteSlot (const Slot *slot); + /// \note Slot must belong to this character. + /// + /// \attention The \a slot pointer will be invalidated by this call. + void deleteSlot(const Slot* slot); - const Slot *updateSlot (const Slot *slot, const ESM::SavedGame& profile); - /// \note Slot must belong to this character. - /// - /// \attention The \a slot pointer will be invalidated by this call. + const Slot* updateSlot(const Slot* slot, const ESM::SavedGame& profile); + /// \note Slot must belong to this character. + /// + /// \attention The \a slot pointer will be invalidated by this call. - SlotIterator begin() const; - ///< Any call to createSlot and updateSlot can invalidate the returned iterator. + SlotIterator begin() const; + ///< Any call to createSlot and updateSlot can invalidate the returned iterator. - SlotIterator end() const; + SlotIterator end() const; - const std::filesystem::path& getPath() const; + const std::filesystem::path& getPath() const; - const ESM::SavedGame& getSignature() const; - ///< Return signature information for this character. - /// - /// \attention This function must not be called if there are no slots. + const ESM::SavedGame& getSignature() const; + ///< Return signature information for this character. + /// + /// \attention This function must not be called if there are no slots. }; } diff --git a/apps/openmw/mwstate/charactermanager.cpp b/apps/openmw/mwstate/charactermanager.cpp index c9bcb0b139..c41ddd42c0 100644 --- a/apps/openmw/mwstate/charactermanager.cpp +++ b/apps/openmw/mwstate/charactermanager.cpp @@ -1,44 +1,44 @@ #include "charactermanager.hpp" #include -#include #include +#include #include #include -MWState::CharacterManager::CharacterManager (std::filesystem::path saves, - const std::vector& contentFiles) -: mPath (std::move(saves)), mCurrent (nullptr), mGame (getFirstGameFile(contentFiles)) +MWState::CharacterManager::CharacterManager(std::filesystem::path saves, const std::vector& contentFiles) + : mPath(std::move(saves)) + , mCurrent(nullptr) + , mGame(getFirstGameFile(contentFiles)) { - if (!std::filesystem::is_directory (mPath)) + if (!std::filesystem::is_directory(mPath)) { - std::filesystem::create_directories (mPath); + std::filesystem::create_directories(mPath); } else { - for (std::filesystem::directory_iterator iter (mPath); - iter!=std::filesystem::directory_iterator(); ++iter) + for (std::filesystem::directory_iterator iter(mPath); iter != std::filesystem::directory_iterator(); ++iter) { std::filesystem::path characterDir = *iter; - if (std::filesystem::is_directory (characterDir)) + if (std::filesystem::is_directory(characterDir)) { - Character character (characterDir, mGame); + Character character(characterDir, mGame); - if (character.begin()!=character.end()) - mCharacters.push_back (character); + if (character.begin() != character.end()) + mCharacters.push_back(character); } } } } -MWState::Character *MWState::CharacterManager::getCurrentCharacter () +MWState::Character* MWState::CharacterManager::getCurrentCharacter() { return mCurrent; } -void MWState::CharacterManager::deleteSlot(const MWState::Character *character, const MWState::Slot *slot) +void MWState::CharacterManager::deleteSlot(const MWState::Character* character, const MWState::Slot* slot) { std::list::iterator it = findCharacter(character); @@ -60,10 +60,10 @@ MWState::Character* MWState::CharacterManager::createCharacter(const std::string // The character name is user-supplied, so we need to escape the path Utf8Stream nameStream(name); - while(!nameStream.eof()) + while (!nameStream.eof()) { auto c = nameStream.consume(); - if(c <= 0x7F && std::isalnum(c)) // Ignore multibyte characters and non alphanumeric characters + if (c <= 0x7F && std::isalnum(c)) // Ignore multibyte characters and non alphanumeric characters stream << static_cast(c); else stream << '_'; @@ -72,13 +72,13 @@ MWState::Character* MWState::CharacterManager::createCharacter(const std::string std::filesystem::path path = mPath / stream.str(); // Append an index if necessary to ensure a unique directory - int i=0; + int i = 0; while (std::filesystem::exists(path)) { - std::ostringstream test; - test << stream.str(); - test << " - " << ++i; - path = mPath / test.str(); + std::ostringstream test; + test << stream.str(); + test << " - " << ++i; + path = mPath / test.str(); } mCharacters.emplace_back(path, mGame); @@ -94,11 +94,11 @@ std::list::iterator MWState::CharacterManager::findCharacter break; } if (it == mCharacters.end()) - throw std::logic_error ("invalid character"); + throw std::logic_error("invalid character"); return it; } -void MWState::CharacterManager::setCurrentCharacter (const Character *character) +void MWState::CharacterManager::setCurrentCharacter(const Character* character) { if (!character) mCurrent = nullptr; @@ -110,7 +110,6 @@ void MWState::CharacterManager::setCurrentCharacter (const Character *character) } } - std::list::const_iterator MWState::CharacterManager::begin() const { return mCharacters.begin(); diff --git a/apps/openmw/mwstate/charactermanager.hpp b/apps/openmw/mwstate/charactermanager.hpp index f2cd45cd10..dac189e68a 100644 --- a/apps/openmw/mwstate/charactermanager.hpp +++ b/apps/openmw/mwstate/charactermanager.hpp @@ -10,42 +10,40 @@ namespace MWState { class CharacterManager { - std::filesystem::path mPath; + std::filesystem::path mPath; - // Uses std::list, so that mCurrent stays valid when characters are deleted - std::list mCharacters; + // Uses std::list, so that mCurrent stays valid when characters are deleted + std::list mCharacters; - Character *mCurrent; - std::string mGame; + Character* mCurrent; + std::string mGame; - private: + private: + CharacterManager(const CharacterManager&); + ///< Not implemented - CharacterManager (const CharacterManager&); - ///< Not implemented + CharacterManager& operator=(const CharacterManager&); + ///< Not implemented - CharacterManager& operator= (const CharacterManager&); - ///< Not implemented + std::list::iterator findCharacter(const MWState::Character* character); - std::list::iterator findCharacter(const MWState::Character* character); + public: + CharacterManager(std::filesystem::path saves, const std::vector& contentFiles); - public: + Character* getCurrentCharacter(); + ///< @note May return null - CharacterManager (std::filesystem::path saves, const std::vector& contentFiles); + void deleteSlot(const MWState::Character* character, const MWState::Slot* slot); - Character *getCurrentCharacter (); - ///< @note May return null + Character* createCharacter(const std::string& name); + ///< Create new character within saved game management + /// \param name Name for the character (does not need to be unique) - void deleteSlot(const MWState::Character *character, const MWState::Slot *slot); + void setCurrentCharacter(const Character* character); - Character* createCharacter(const std::string& name); - ///< Create new character within saved game management - /// \param name Name for the character (does not need to be unique) + std::list::const_iterator begin() const; - void setCurrentCharacter (const Character *character); - - std::list::const_iterator begin() const; - - std::list::const_iterator end() const; + std::list::const_iterator end() const; }; } diff --git a/apps/openmw/mwstate/quicksavemanager.cpp b/apps/openmw/mwstate/quicksavemanager.cpp index bf17815207..1028866aac 100644 --- a/apps/openmw/mwstate/quicksavemanager.cpp +++ b/apps/openmw/mwstate/quicksavemanager.cpp @@ -1,26 +1,26 @@ #include "quicksavemanager.hpp" -MWState::QuickSaveManager::QuickSaveManager(std::string &saveName, unsigned int maxSaves) - : mSaveName(saveName) - , mMaxSaves(maxSaves) - , mSlotsVisited(0) - , mOldestSlotVisited(nullptr) +MWState::QuickSaveManager::QuickSaveManager(std::string& saveName, unsigned int maxSaves) + : mSaveName(saveName) + , mMaxSaves(maxSaves) + , mSlotsVisited(0) + , mOldestSlotVisited(nullptr) { } -void MWState::QuickSaveManager::visitSave(const Slot *saveSlot) +void MWState::QuickSaveManager::visitSave(const Slot* saveSlot) { - if(mSaveName == saveSlot->mProfile.mDescription) + if (mSaveName == saveSlot->mProfile.mDescription) { ++mSlotsVisited; - if(isOldestSave(saveSlot)) + if (isOldestSave(saveSlot)) mOldestSlotVisited = saveSlot; } } -bool MWState::QuickSaveManager::isOldestSave(const Slot *compare) const +bool MWState::QuickSaveManager::isOldestSave(const Slot* compare) const { - if(mOldestSlotVisited == nullptr) + if (mOldestSlotVisited == nullptr) return true; return (compare->mTimeStamp <= mOldestSlotVisited->mTimeStamp); } @@ -30,9 +30,9 @@ bool MWState::QuickSaveManager::shouldCreateNewSlot() const return (mSlotsVisited < mMaxSaves); } -const MWState::Slot *MWState::QuickSaveManager::getNextQuickSaveSlot() +const MWState::Slot* MWState::QuickSaveManager::getNextQuickSaveSlot() { - if(shouldCreateNewSlot()) + if (shouldCreateNewSlot()) return nullptr; return mOldestSlotVisited; } diff --git a/apps/openmw/mwstate/quicksavemanager.hpp b/apps/openmw/mwstate/quicksavemanager.hpp index 3272b24b51..3fa24d34d4 100644 --- a/apps/openmw/mwstate/quicksavemanager.hpp +++ b/apps/openmw/mwstate/quicksavemanager.hpp @@ -5,26 +5,30 @@ #include "character.hpp" -namespace MWState{ - class QuickSaveManager{ +namespace MWState +{ + class QuickSaveManager + { std::string mSaveName; unsigned int mMaxSaves; unsigned int mSlotsVisited; - const Slot *mOldestSlotVisited; + const Slot* mOldestSlotVisited; + private: bool shouldCreateNewSlot() const; - bool isOldestSave(const Slot *compare) const; + bool isOldestSave(const Slot* compare) const; + public: - QuickSaveManager(std::string &saveName, unsigned int maxSaves); + QuickSaveManager(std::string& saveName, unsigned int maxSaves); ///< A utility class to manage multiple quicksave slots /// /// \param saveName The name of the save ("QuickSave", "AutoSave", etc) /// \param maxSaves The maximum number of save slots to create before recycling old ones - void visitSave(const Slot *saveSlot); + void visitSave(const Slot* saveSlot); ///< Visits the given \a slot \a - const Slot *getNextQuickSaveSlot(); + const Slot* getNextQuickSaveSlot(); ///< Get the slot that the next quicksave should use. /// ///\return Either the oldest quicksave slot visited, or nullptr if a new slot can be made diff --git a/apps/openmw/mwstate/statemanagerimp.cpp b/apps/openmw/mwstate/statemanagerimp.cpp index 814535489e..2f29771eef 100644 --- a/apps/openmw/mwstate/statemanagerimp.cpp +++ b/apps/openmw/mwstate/statemanagerimp.cpp @@ -4,47 +4,47 @@ #include -#include -#include #include +#include +#include #include #include #include -#include #include +#include #include #include +#include "../mwbase/dialoguemanager.hpp" #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" +#include "../mwbase/inputmanager.hpp" #include "../mwbase/journal.hpp" -#include "../mwbase/dialoguemanager.hpp" -#include "../mwbase/windowmanager.hpp" +#include "../mwbase/luamanager.hpp" #include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/scriptmanager.hpp" #include "../mwbase/soundmanager.hpp" -#include "../mwbase/inputmanager.hpp" -#include "../mwbase/luamanager.hpp" +#include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" -#include "../mwworld/player.hpp" -#include "../mwworld/class.hpp" #include "../mwworld/cellstore.hpp" +#include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" +#include "../mwworld/player.hpp" -#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/actorutil.hpp" +#include "../mwmechanics/npcstats.hpp" #include "../mwscript/globalscripts.hpp" #include "quicksavemanager.hpp" -void MWState::StateManager::cleanup (bool force) +void MWState::StateManager::cleanup(bool force) { - if (mState!=State_NoGame || force) + if (mState != State_NoGame || force) { MWBase::Environment::get().getSoundManager()->clear(); MWBase::Environment::get().getDialogueManager()->clear(); @@ -64,24 +64,22 @@ void MWState::StateManager::cleanup (bool force) MWBase::Environment::get().getLuaManager()->clear(); } -std::map MWState::StateManager::buildContentFileIndexMap (const ESM::ESMReader& reader) - const +std::map MWState::StateManager::buildContentFileIndexMap(const ESM::ESMReader& reader) const { - const std::vector& current = - MWBase::Environment::get().getWorld()->getContentFiles(); + const std::vector& current = MWBase::Environment::get().getWorld()->getContentFiles(); const std::vector& prev = reader.getGameFiles(); std::map map; - for (int iPrev = 0; iPrev (prev.size()); ++iPrev) + for (int iPrev = 0; iPrev < static_cast(prev.size()); ++iPrev) { - std::string id = Misc::StringUtils::lowerCase (prev[iPrev].name); + std::string id = Misc::StringUtils::lowerCase(prev[iPrev].name); - for (int iCurrent = 0; iCurrent (current.size()); ++iCurrent) - if (id==Misc::StringUtils::lowerCase (current[iCurrent])) + for (int iCurrent = 0; iCurrent < static_cast(current.size()); ++iCurrent) + if (id == Misc::StringUtils::lowerCase(current[iCurrent])) { - map.insert (std::make_pair (iPrev, iCurrent)); + map.insert(std::make_pair(iPrev, iCurrent)); break; } } @@ -89,10 +87,13 @@ std::map MWState::StateManager::buildContentFileIndexMap (const ESM::E return map; } -MWState::StateManager::StateManager (const std::filesystem::path& saves, const std::vector& contentFiles) -: mQuitRequest (false), mAskLoadRecent(false), mState (State_NoGame), mCharacterManager (saves, contentFiles), mTimePlayed (0) +MWState::StateManager::StateManager(const std::filesystem::path& saves, const std::vector& contentFiles) + : mQuitRequest(false) + , mAskLoadRecent(false) + , mState(State_NoGame) + , mCharacterManager(saves, contentFiles) + , mTimePlayed(0) { - } void MWState::StateManager::requestQuit() @@ -110,12 +111,12 @@ void MWState::StateManager::askLoadRecent() if (MWBase::Environment::get().getWindowManager()->getMode() == MWGui::GM_MainMenu) return; - if( !mAskLoadRecent ) + if (!mAskLoadRecent) { const MWState::Character* character = getCurrentCharacter(); - if(!character || character->begin() == character->end())//no saves + if (!character || character->begin() == character->end()) // no saves { - MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu); + MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_MainMenu); } else { @@ -124,7 +125,8 @@ void MWState::StateManager::askLoadRecent() buttons.emplace_back("#{sYes}"); buttons.emplace_back("#{sNo}"); std::string_view tag = "%s"; - std::string message{MWBase::Environment::get().getWindowManager()->getGameSettingString("sLoadLastSaveMsg", tag)}; + std::string message{ MWBase::Environment::get().getWindowManager()->getGameSettingString( + "sLoadLastSaveMsg", tag) }; size_t pos = message.find(tag); message.replace(pos, tag.length(), lastSave.mProfile.mDescription); MWBase::Environment::get().getWindowManager()->interactiveMessageBox(message, buttons); @@ -138,19 +140,19 @@ MWState::StateManager::State MWState::StateManager::getState() const return mState; } -void MWState::StateManager::newGame (bool bypass) +void MWState::StateManager::newGame(bool bypass) { cleanup(); if (!bypass) - MWBase::Environment::get().getWindowManager()->setNewGame (true); + MWBase::Environment::get().getWindowManager()->setNewGame(true); try { Log(Debug::Info) << "Starting a new game"; MWBase::Environment::get().getScriptManager()->getGlobalScripts().addStartup(); MWBase::Environment::get().getLuaManager()->newGameStarted(); - MWBase::Environment::get().getWorld()->startNewGame (bypass); + MWBase::Environment::get().getWorld()->startNewGame(bypass); mState = State_Running; @@ -163,9 +165,9 @@ void MWState::StateManager::newGame (bool bypass) error << "Failed to start new game: " << e.what(); Log(Debug::Error) << error.str(); - cleanup (true); + cleanup(true); - MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu); + MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_MainMenu); std::vector buttons; buttons.emplace_back("#{sOk}"); @@ -183,7 +185,7 @@ void MWState::StateManager::resumeGame() mState = State_Running; } -void MWState::StateManager::saveGame (const std::string& description, const Slot *slot) +void MWState::StateManager::saveGame(const std::string& description, const Slot* slot) { MWState::Character* character = getCurrentCharacter(); @@ -211,7 +213,7 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot profile.mContentFiles = world.getContentFiles(); profile.mPlayerName = player.get()->mBase->mName; - profile.mPlayerLevel = player.getClass().getNpcStats (player).getLevel(); + profile.mPlayerLevel = player.getClass().getNpcStats(player).getLevel(); const std::string& classId = player.get()->mBase->mClass; if (world.getStore().get().isDynamic(classId)) @@ -228,9 +230,9 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot writeScreenshot(profile.mScreenshot); if (!slot) - slot = character->createSlot (profile); + slot = character->createSlot(profile); else - slot = character->updateSlot (slot, profile); + slot = character->updateSlot(slot, profile); // Make sure the animation state held by references is up to date before saving the game. MWBase::Environment::get().getMechanicsManager()->persistAnimationStates(); @@ -246,7 +248,7 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot for (const std::string& contentFile : MWBase::Environment::get().getWorld()->getContentFiles()) writer.addMaster(contentFile, 0); // not using the size information anyway -> use value of 0 - writer.setFormat (ESM::SavedGame::sCurrentFormat); + writer.setFormat(ESM::SavedGame::sCurrentFormat); // all unused writer.setVersion(0); @@ -254,18 +256,18 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot writer.setAuthor(""); writer.setDescription(""); - int recordCount = 1 // saved game header - +MWBase::Environment::get().getJournal()->countSavedGameRecords() - +MWBase::Environment::get().getLuaManager()->countSavedGameRecords() - +MWBase::Environment::get().getWorld()->countSavedGameRecords() - +MWBase::Environment::get().getScriptManager()->getGlobalScripts().countSavedGameRecords() - +MWBase::Environment::get().getDialogueManager()->countSavedGameRecords() - +MWBase::Environment::get().getMechanicsManager()->countSavedGameRecords() - +MWBase::Environment::get().getInputManager()->countSavedGameRecords() - +MWBase::Environment::get().getWindowManager()->countSavedGameRecords(); - writer.setRecordCount (recordCount); + int recordCount = 1 // saved game header + + MWBase::Environment::get().getJournal()->countSavedGameRecords() + + MWBase::Environment::get().getLuaManager()->countSavedGameRecords() + + MWBase::Environment::get().getWorld()->countSavedGameRecords() + + MWBase::Environment::get().getScriptManager()->getGlobalScripts().countSavedGameRecords() + + MWBase::Environment::get().getDialogueManager()->countSavedGameRecords() + + MWBase::Environment::get().getMechanicsManager()->countSavedGameRecords() + + MWBase::Environment::get().getInputManager()->countSavedGameRecords() + + MWBase::Environment::get().getWindowManager()->countSavedGameRecords(); + writer.setRecordCount(recordCount); - writer.save (stream); + writer.save(stream); Loading::Listener& listener = *MWBase::Environment::get().getWindowManager()->getLoadingScreen(); // Using only Cells for progress information, since they typically have the largest records by far @@ -274,24 +276,25 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot Loading::ScopedLoad load(&listener); - writer.startRecord (ESM::REC_SAVE); - slot->mProfile.save (writer); - writer.endRecord (ESM::REC_SAVE); + writer.startRecord(ESM::REC_SAVE); + slot->mProfile.save(writer); + writer.endRecord(ESM::REC_SAVE); - MWBase::Environment::get().getJournal()->write (writer, listener); - MWBase::Environment::get().getDialogueManager()->write (writer, listener); + MWBase::Environment::get().getJournal()->write(writer, listener); + MWBase::Environment::get().getDialogueManager()->write(writer, listener); // LuaManager::write should be called before World::write because world also saves // local scripts that depend on LuaManager. MWBase::Environment::get().getLuaManager()->write(writer, listener); - MWBase::Environment::get().getWorld()->write (writer, listener); - MWBase::Environment::get().getScriptManager()->getGlobalScripts().write (writer, listener); + MWBase::Environment::get().getWorld()->write(writer, listener); + MWBase::Environment::get().getScriptManager()->getGlobalScripts().write(writer, listener); MWBase::Environment::get().getMechanicsManager()->write(writer, listener); MWBase::Environment::get().getInputManager()->write(writer, listener); MWBase::Environment::get().getWindowManager()->write(writer, listener); // Ensure we have written the number of records that was estimated - if (writer.getRecordCount() != recordCount+1) // 1 extra for TES3 record - Log(Debug::Warning) << "Warning: number of written savegame records does not match. Estimated: " << recordCount+1 << ", written: " << writer.getRecordCount(); + if (writer.getRecordCount() != recordCount + 1) // 1 extra for TES3 record + Log(Debug::Warning) << "Warning: number of written savegame records does not match. Estimated: " + << recordCount + 1 << ", written: " << writer.getRecordCount(); writer.close(); @@ -299,19 +302,20 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot throw std::runtime_error("Write operation failed (memory stream)"); // All good, write to file - std::ofstream filestream (slot->mPath, std::ios::binary); + std::ofstream filestream(slot->mPath, std::ios::binary); filestream << stream.rdbuf(); if (filestream.fail()) throw std::runtime_error("Write operation failed (file stream)"); - Settings::Manager::setString ("character", "Saves", - Files::pathToUnicodeString(slot->mPath.parent_path().filename())); + Settings::Manager::setString( + "character", "Saves", Files::pathToUnicodeString(slot->mPath.parent_path().filename())); const auto finish = std::chrono::steady_clock::now(); Log(Debug::Info) << '\'' << description << "' is saved in " - << std::chrono::duration_cast>(finish - start).count() << "ms"; + << std::chrono::duration_cast>(finish - start).count() + << "ms"; } catch (const std::exception& e) { @@ -333,39 +337,39 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot } } -void MWState::StateManager::quickSave (std::string name) +void MWState::StateManager::quickSave(std::string name) { - if (!(mState==State_Running && - MWBase::Environment::get().getWorld()->getGlobalInt ("chargenstate")==-1 // char gen + if (!(mState == State_Running + && MWBase::Environment::get().getWorld()->getGlobalInt("chargenstate") == -1 // char gen && MWBase::Environment::get().getWindowManager()->isSavingAllowed())) { - //You can not save your game right now + // You can not save your game right now MWBase::Environment::get().getWindowManager()->messageBox("#{sSaveGameDenied}"); return; } int maxSaves = Settings::Manager::getInt("max quicksaves", "Saves"); - if(maxSaves < 1) + if (maxSaves < 1) maxSaves = 1; - Character* currentCharacter = getCurrentCharacter(); //Get current character + Character* currentCharacter = getCurrentCharacter(); // Get current character QuickSaveManager saveFinder = QuickSaveManager(name, maxSaves); if (currentCharacter) { for (auto& save : *currentCharacter) { - //Visiting slots allows the quicksave finder to find the oldest quicksave + // Visiting slots allows the quicksave finder to find the oldest quicksave saveFinder.visitSave(&save); } } - //Once all the saves have been visited, the save finder can tell us which - //one to replace (or create) + // Once all the saves have been visited, the save finder can tell us which + // one to replace (or create) saveGame(name, saveFinder.getNextQuickSaveSlot()); } -void MWState::StateManager::loadGame(const std::filesystem::path &filepath) +void MWState::StateManager::loadGame(const std::filesystem::path& filepath) { for (const auto& character : mCharacterManager) { @@ -383,7 +387,7 @@ void MWState::StateManager::loadGame(const std::filesystem::path &filepath) loadGame(character, filepath); } -void MWState::StateManager::loadGame (const Character *character, const std::filesystem::path &filepath) +void MWState::StateManager::loadGame(const Character* character, const std::filesystem::path& filepath) { try { @@ -392,12 +396,14 @@ void MWState::StateManager::loadGame (const Character *character, const std::fil Log(Debug::Info) << "Reading save file " << filepath.filename(); ESM::ESMReader reader; - reader.open (filepath); + reader.open(filepath); if (reader.getFormat() > ESM::SavedGame::sCurrentFormat) - throw std::runtime_error("This save file was created using a newer version of OpenMW and is thus not supported. Please upgrade to the newest OpenMW version to load this file."); + throw std::runtime_error( + "This save file was created using a newer version of OpenMW and is thus not supported. Please upgrade " + "to the newest OpenMW version to load this file."); - std::map contentFileMap = buildContentFileIndexMap (reader); + std::map contentFileMap = buildContentFileIndexMap(reader); MWBase::Environment::get().getLuaManager()->setContentFileMapping(contentFileMap); Loading::Listener& listener = *MWBase::Environment::get().getWindowManager()->getLoadingScreen(); @@ -419,30 +425,31 @@ void MWState::StateManager::loadGame (const Character *character, const std::fil switch (n.toInt()) { case ESM::REC_SAVE: + { + ESM::SavedGame profile; + profile.load(reader); + if (!verifyProfile(profile)) { - ESM::SavedGame profile; - profile.load(reader); - if (!verifyProfile(profile)) - { - cleanup (true); - MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu); - return; - } - mTimePlayed = profile.mTimePlayed; - Log(Debug::Info) << "Loading saved game '" << profile.mDescription << "' for character '" << profile.mPlayerName << "'"; + cleanup(true); + MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_MainMenu); + return; } - break; + mTimePlayed = profile.mTimePlayed; + Log(Debug::Info) << "Loading saved game '" << profile.mDescription << "' for character '" + << profile.mPlayerName << "'"; + } + break; case ESM::REC_JOUR: case ESM::REC_JOUR_LEGACY: case ESM::REC_QUES: - MWBase::Environment::get().getJournal()->readRecord (reader, n.toInt()); + MWBase::Environment::get().getJournal()->readRecord(reader, n.toInt()); break; case ESM::REC_DIAS: - MWBase::Environment::get().getDialogueManager()->readRecord (reader, n.toInt()); + MWBase::Environment::get().getDialogueManager()->readRecord(reader, n.toInt()); break; case ESM::REC_ALCH: @@ -477,7 +484,8 @@ void MWState::StateManager::loadGame (const Character *character, const std::fil case ESM::REC_GSCR: - MWBase::Environment::get().getScriptManager()->getGlobalScripts().readRecord (reader, n.toInt(), contentFileMap); + MWBase::Environment::get().getScriptManager()->getGlobalScripts().readRecord( + reader, n.toInt(), contentFileMap); break; case ESM::REC_GMAP: @@ -508,10 +516,10 @@ void MWState::StateManager::loadGame (const Character *character, const std::fil Log(Debug::Warning) << "Warning: Ignoring unknown record: " << n.toStringView(); reader.skipRecord(); } - int progressPercent = static_cast(float(reader.getFileOffset())/total*100); + int progressPercent = static_cast(float(reader.getFileOffset()) / total * 100); if (progressPercent > currentPercent) { - listener.increaseProgress(progressPercent-currentPercent); + listener.increaseProgress(progressPercent - currentPercent); currentPercent = progressPercent; } } @@ -521,8 +529,8 @@ void MWState::StateManager::loadGame (const Character *character, const std::fil mState = State_Running; if (character) - Settings::Manager::setString ("character", "Saves", - Files::pathToUnicodeString(character->getPath().filename())); + Settings::Manager::setString( + "character", "Saves", Files::pathToUnicodeString(character->getPath().filename())); MWBase::Environment::get().getWindowManager()->setNewGame(false); MWBase::Environment::get().getWorld()->saveLoaded(); @@ -541,15 +549,15 @@ void MWState::StateManager::loadGame (const Character *character, const std::fil const ESM::CellId& cellId = ptr.getCell()->getCell()->getCellId(); // Use detectWorldSpaceChange=false, otherwise some of the data we just loaded would be cleared again - MWBase::Environment::get().getWorld()->changeToCell (cellId, ptr.getRefData().getPosition(), false, false); + MWBase::Environment::get().getWorld()->changeToCell(cellId, ptr.getRefData().getPosition(), false, false); } else { // Cell no longer exists (i.e. changed game files), choose a default cell Log(Debug::Warning) << "Warning: Player character's cell no longer exists, changing to the default cell"; - MWWorld::CellStore* cell = MWBase::Environment::get().getWorld()->getExterior(0,0); - float x,y; - MWBase::Environment::get().getWorld()->indexToPosition(0,0,x,y,false); + MWWorld::CellStore* cell = MWBase::Environment::get().getWorld()->getExterior(0, 0); + float x, y; + MWBase::Environment::get().getWorld()->indexToPosition(0, 0, x, y, false); ESM::Position pos; pos.pos[0] = x; pos.pos[1] = y; @@ -578,9 +586,9 @@ void MWState::StateManager::loadGame (const Character *character, const std::fil error << "Failed to load saved game: " << e.what(); Log(Debug::Error) << error.str(); - cleanup (true); + cleanup(true); - MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu); + MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_MainMenu); std::vector buttons; buttons.emplace_back("#{sOk}"); @@ -590,20 +598,20 @@ void MWState::StateManager::loadGame (const Character *character, const std::fil void MWState::StateManager::quickLoad() { - if (Character* currentCharacter = getCurrentCharacter ()) + if (Character* currentCharacter = getCurrentCharacter()) { if (currentCharacter->begin() == currentCharacter->end()) return; - loadGame (currentCharacter, currentCharacter->begin()->mPath); //Get newest save + loadGame(currentCharacter, currentCharacter->begin()->mPath); // Get newest save } } -void MWState::StateManager::deleteGame(const MWState::Character *character, const MWState::Slot *slot) +void MWState::StateManager::deleteGame(const MWState::Character* character, const MWState::Slot* slot) { mCharacterManager.deleteSlot(character, slot); } -MWState::Character *MWState::StateManager::getCurrentCharacter () +MWState::Character* MWState::StateManager::getCurrentCharacter() { return mCharacterManager.getCurrentCharacter(); } @@ -618,7 +626,7 @@ MWState::StateManager::CharacterIterator MWState::StateManager::characterEnd() return mCharacterManager.end(); } -void MWState::StateManager::update (float duration) +void MWState::StateManager::update(float duration) { mTimePlayed += duration; @@ -626,19 +634,19 @@ void MWState::StateManager::update (float duration) if (mAskLoadRecent) { int iButton = MWBase::Environment::get().getWindowManager()->readPressedButton(); - MWState::Character *curCharacter = getCurrentCharacter(); - if(iButton==0 && curCharacter) + MWState::Character* curCharacter = getCurrentCharacter(); + if (iButton == 0 && curCharacter) { mAskLoadRecent = false; - //Load last saved game for current character + // Load last saved game for current character MWState::Slot lastSave = *curCharacter->begin(); loadGame(curCharacter, lastSave.mPath); } - else if(iButton==1) + else if (iButton == 1) { mAskLoadRecent = false; - MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu); + MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_MainMenu); } } } @@ -650,7 +658,7 @@ bool MWState::StateManager::verifyProfile(const ESM::SavedGame& profile) const for (const std::string& contentFile : profile.mContentFiles) { if (std::find(selectedContentFiles.begin(), selectedContentFiles.end(), contentFile) - == selectedContentFiles.end()) + == selectedContentFiles.end()) { Log(Debug::Warning) << "Warning: Saved game dependency " << contentFile << " is missing."; notFound = true; @@ -669,11 +677,11 @@ bool MWState::StateManager::verifyProfile(const ESM::SavedGame& profile) const return true; } -void MWState::StateManager::writeScreenshot(std::vector &imageData) const +void MWState::StateManager::writeScreenshot(std::vector& imageData) const { - int screenshotW = 259*2, screenshotH = 133*2; // *2 to get some nice antialiasing + int screenshotW = 259 * 2, screenshotH = 133 * 2; // *2 to get some nice antialiasing - osg::ref_ptr screenshot (new osg::Image); + osg::ref_ptr screenshot(new osg::Image); MWBase::Environment::get().getWorld()->screenshot(screenshot.get(), screenshotW, screenshotH); @@ -694,5 +702,4 @@ void MWState::StateManager::writeScreenshot(std::vector &imageData) const std::string data = ostream.str(); imageData = std::vector(data.begin(), data.end()); - } diff --git a/apps/openmw/mwstate/statemanagerimp.hpp b/apps/openmw/mwstate/statemanagerimp.hpp index 0097a9c490..f9ba51d456 100644 --- a/apps/openmw/mwstate/statemanagerimp.hpp +++ b/apps/openmw/mwstate/statemanagerimp.hpp @@ -1,8 +1,8 @@ #ifndef GAME_STATE_STATEMANAGER_H #define GAME_STATE_STATEMANAGER_H -#include #include +#include #include "../mwbase/statemanager.hpp" @@ -12,78 +12,77 @@ namespace MWState { class StateManager : public MWBase::StateManager { - bool mQuitRequest; - bool mAskLoadRecent; - State mState; - CharacterManager mCharacterManager; - double mTimePlayed; - - private: - - void cleanup (bool force = false); + bool mQuitRequest; + bool mAskLoadRecent; + State mState; + CharacterManager mCharacterManager; + double mTimePlayed; - bool verifyProfile (const ESM::SavedGame& profile) const; + private: + void cleanup(bool force = false); - void writeScreenshot (std::vector& imageData) const; + bool verifyProfile(const ESM::SavedGame& profile) const; - std::map buildContentFileIndexMap (const ESM::ESMReader& reader) const; + void writeScreenshot(std::vector& imageData) const; - public: + std::map buildContentFileIndexMap(const ESM::ESMReader& reader) const; - StateManager (const std::filesystem::path& saves, const std::vector& contentFiles); + public: + StateManager(const std::filesystem::path& saves, const std::vector& contentFiles); - void requestQuit() override; + void requestQuit() override; - bool hasQuitRequest() const override; + bool hasQuitRequest() const override; - void askLoadRecent() override; + void askLoadRecent() override; - State getState() const override; + State getState() const override; - void newGame (bool bypass = false) override; - ///< Start a new game. - /// - /// \param bypass Skip new game mechanics. + void newGame(bool bypass = false) override; + ///< Start a new game. + /// + /// \param bypass Skip new game mechanics. - void endGame(); + void endGame(); - void resumeGame() override; + void resumeGame() override; - void deleteGame (const MWState::Character *character, const MWState::Slot *slot) override; - ///< Delete a saved game slot from this character. If all save slots are deleted, the character will be deleted too. + void deleteGame(const MWState::Character* character, const MWState::Slot* slot) override; + ///< Delete a saved game slot from this character. If all save slots are deleted, the character will be deleted + ///< too. - void saveGame (const std::string& description, const Slot *slot = nullptr) override; - ///< Write a saved game to \a slot or create a new slot if \a slot == 0. - /// - /// \note Slot must belong to the current character. + void saveGame(const std::string& description, const Slot* slot = nullptr) override; + ///< Write a saved game to \a slot or create a new slot if \a slot == 0. + /// + /// \note Slot must belong to the current character. - ///Saves a file, using supplied filename, overwritting if needed - /** This is mostly used for quicksaving and autosaving, for they use the same name over and over again - \param name Name of save, defaults to "Quicksave"**/ - void quickSave(std::string name = "Quicksave") override; + /// Saves a file, using supplied filename, overwritting if needed + /** This is mostly used for quicksaving and autosaving, for they use the same name over and over again + \param name Name of save, defaults to "Quicksave"**/ + void quickSave(std::string name = "Quicksave") override; - ///Loads the last saved file - /** Used for quickload **/ - void quickLoad() override; + /// Loads the last saved file + /** Used for quickload **/ + void quickLoad() override; - void loadGame (const std::filesystem::path &filepath) override; - ///< Load a saved game directly from the given file path. This will search the CharacterManager - /// for a Character containing this save file, and set this Character current if one was found. - /// Otherwise, a new Character will be created. + void loadGame(const std::filesystem::path& filepath) override; + ///< Load a saved game directly from the given file path. This will search the CharacterManager + /// for a Character containing this save file, and set this Character current if one was found. + /// Otherwise, a new Character will be created. - void loadGame (const Character *character, const std::filesystem::path &filepath) override; - ///< Load a saved game file belonging to the given character. + void loadGame(const Character* character, const std::filesystem::path& filepath) override; + ///< Load a saved game file belonging to the given character. - Character *getCurrentCharacter () override; - ///< @note May return null. + Character* getCurrentCharacter() override; + ///< @note May return null. - CharacterIterator characterBegin() override; - ///< Any call to SaveGame and getCurrentCharacter can invalidate the returned - /// iterator. + CharacterIterator characterBegin() override; + ///< Any call to SaveGame and getCurrentCharacter can invalidate the returned + /// iterator. - CharacterIterator characterEnd() override; + CharacterIterator characterEnd() override; - void update(float duration); + void update(float duration); }; } diff --git a/apps/openmw/mwworld/action.cpp b/apps/openmw/mwworld/action.cpp index 16edea93d6..ce73039ca5 100644 --- a/apps/openmw/mwworld/action.cpp +++ b/apps/openmw/mwworld/action.cpp @@ -17,14 +17,18 @@ void MWWorld::Action::setTarget(const MWWorld::Ptr& target) mTarget = target; } -MWWorld::Action::Action (bool keepSound, const Ptr& target) : mKeepSound (keepSound), mSoundOffset(0), mTarget (target) -{} +MWWorld::Action::Action(bool keepSound, const Ptr& target) + : mKeepSound(keepSound) + , mSoundOffset(0) + , mTarget(target) +{ +} MWWorld::Action::~Action() {} -void MWWorld::Action::execute (const Ptr& actor, bool noSound) +void MWWorld::Action::execute(const Ptr& actor, bool noSound) { - if(!mSoundId.empty() && !noSound) + if (!mSoundId.empty() && !noSound) { MWSound::PlayMode envType = MWSound::PlayMode::Normal; @@ -35,26 +39,23 @@ void MWWorld::Action::execute (const Ptr& actor, bool noSound) envType = MWSound::PlayMode::NoEnv; } - if(mKeepSound && actor == MWMechanics::getPlayer()) - MWBase::Environment::get().getSoundManager()->playSound(mSoundId, 1.0, 1.0, - MWSound::Type::Sfx, envType, mSoundOffset - ); + if (mKeepSound && actor == MWMechanics::getPlayer()) + MWBase::Environment::get().getSoundManager()->playSound( + mSoundId, 1.0, 1.0, MWSound::Type::Sfx, envType, mSoundOffset); else { bool local = mTarget.isEmpty() || !mTarget.isInCell(); // no usable target - if(mKeepSound) + if (mKeepSound) MWBase::Environment::get().getSoundManager()->playSound3D( - (local ? actor : mTarget).getRefData().getPosition().asVec3(), - mSoundId, 1.0, 1.0, MWSound::Type::Sfx, envType, mSoundOffset - ); + (local ? actor : mTarget).getRefData().getPosition().asVec3(), mSoundId, 1.0, 1.0, + MWSound::Type::Sfx, envType, mSoundOffset); else - MWBase::Environment::get().getSoundManager()->playSound3D(local ? actor : mTarget, - mSoundId, 1.0, 1.0, MWSound::Type::Sfx, envType, mSoundOffset - ); + MWBase::Environment::get().getSoundManager()->playSound3D( + local ? actor : mTarget, mSoundId, 1.0, 1.0, MWSound::Type::Sfx, envType, mSoundOffset); } } - executeImp (actor); + executeImp(actor); } void MWWorld::Action::setSound(std::string_view id) @@ -64,5 +65,5 @@ void MWWorld::Action::setSound(std::string_view id) void MWWorld::Action::setSoundOffset(float offset) { - mSoundOffset=offset; + mSoundOffset = offset; } diff --git a/apps/openmw/mwworld/action.hpp b/apps/openmw/mwworld/action.hpp index df1f848a47..01e036c0ba 100644 --- a/apps/openmw/mwworld/action.hpp +++ b/apps/openmw/mwworld/action.hpp @@ -11,37 +11,35 @@ namespace MWWorld /// \brief Abstract base for actions class Action { - std::string mSoundId; - bool mKeepSound; - float mSoundOffset; - Ptr mTarget; + std::string mSoundId; + bool mKeepSound; + float mSoundOffset; + Ptr mTarget; - // not implemented - Action (const Action& action); - Action& operator= (const Action& action); + // not implemented + Action(const Action& action); + Action& operator=(const Action& action); - virtual void executeImp (const Ptr& actor) = 0; + virtual void executeImp(const Ptr& actor) = 0; - protected: + protected: + void setTarget(const Ptr&); - void setTarget(const Ptr&); + public: + const Ptr& getTarget() const; - public: + Action(bool keepSound = false, const Ptr& target = Ptr()); + ///< \param keepSound Keep playing the sound even if the object the sound is played on is removed. - const Ptr& getTarget() const; + virtual ~Action(); - Action (bool keepSound = false, const Ptr& target = Ptr()); - ///< \param keepSound Keep playing the sound even if the object the sound is played on is removed. + virtual bool isNullAction() { return false; } + ///< Is running this action a no-op? (default false) - virtual ~Action(); + void execute(const Ptr& actor, bool noSound = false); - virtual bool isNullAction() { return false; } - ///< Is running this action a no-op? (default false) - - void execute (const Ptr& actor, bool noSound = false); - - void setSound(std::string_view id); - void setSoundOffset(float offset); + void setSound(std::string_view id); + void setSoundOffset(float offset); }; } diff --git a/apps/openmw/mwworld/actionalchemy.cpp b/apps/openmw/mwworld/actionalchemy.cpp index 62b673dd23..3348dbbfb3 100644 --- a/apps/openmw/mwworld/actionalchemy.cpp +++ b/apps/openmw/mwworld/actionalchemy.cpp @@ -8,18 +8,18 @@ namespace MWWorld { ActionAlchemy::ActionAlchemy(bool force) - : Action (false) - , mForce(force) + : Action(false) + , mForce(force) { } - void ActionAlchemy::executeImp (const Ptr& actor) + void ActionAlchemy::executeImp(const Ptr& actor) { if (actor != MWMechanics::getPlayer()) return; - if(!mForce && MWMechanics::isPlayerInCombat()) - { //Ensure we're not in combat + if (!mForce && MWMechanics::isPlayerInCombat()) + { // Ensure we're not in combat MWBase::Environment::get().getWindowManager()->messageBox("#{sInventoryMessage3}"); return; } diff --git a/apps/openmw/mwworld/actionalchemy.hpp b/apps/openmw/mwworld/actionalchemy.hpp index 194ef308b9..d37850e6ae 100644 --- a/apps/openmw/mwworld/actionalchemy.hpp +++ b/apps/openmw/mwworld/actionalchemy.hpp @@ -8,10 +8,10 @@ namespace MWWorld class ActionAlchemy : public Action { bool mForce; - void executeImp (const Ptr& actor) override; + void executeImp(const Ptr& actor) override; public: - ActionAlchemy(bool force=false); + ActionAlchemy(bool force = false); }; } diff --git a/apps/openmw/mwworld/actionapply.cpp b/apps/openmw/mwworld/actionapply.cpp index 1699a6aa53..a05d29bc59 100644 --- a/apps/openmw/mwworld/actionapply.cpp +++ b/apps/openmw/mwworld/actionapply.cpp @@ -11,25 +11,29 @@ namespace MWWorld { - ActionApply::ActionApply (const Ptr& object, const std::string& id) - : Action (false, object), mId (id) - {} + ActionApply::ActionApply(const Ptr& object, const std::string& id) + : Action(false, object) + , mId(id) + { + } - void ActionApply::executeImp (const Ptr& actor) + void ActionApply::executeImp(const Ptr& actor) { actor.getClass().consume(getTarget(), actor); } + ActionApplyWithSkill::ActionApplyWithSkill(const Ptr& object, const std::string& id, int skillIndex, int usageType) + : Action(false, object) + , mId(id) + , mSkillIndex(skillIndex) + , mUsageType(usageType) + { + } - ActionApplyWithSkill::ActionApplyWithSkill (const Ptr& object, const std::string& id, - int skillIndex, int usageType) - : Action (false, object), mId (id), mSkillIndex (skillIndex), mUsageType (usageType) - {} - - void ActionApplyWithSkill::executeImp (const Ptr& actor) + void ActionApplyWithSkill::executeImp(const Ptr& actor) { bool consumed = actor.getClass().consume(getTarget(), actor); if (consumed && mUsageType != -1 && actor == MWMechanics::getPlayer()) - actor.getClass().skillUsageSucceeded (actor, mSkillIndex, mUsageType); + actor.getClass().skillUsageSucceeded(actor, mSkillIndex, mUsageType); } } diff --git a/apps/openmw/mwworld/actionapply.hpp b/apps/openmw/mwworld/actionapply.hpp index 4350b7af4f..02862bd3f3 100644 --- a/apps/openmw/mwworld/actionapply.hpp +++ b/apps/openmw/mwworld/actionapply.hpp @@ -9,27 +9,24 @@ namespace MWWorld { class ActionApply : public Action { - std::string mId; + std::string mId; - void executeImp (const Ptr& actor) override; + void executeImp(const Ptr& actor) override; - public: - - ActionApply (const Ptr& object, const std::string& id); + public: + ActionApply(const Ptr& object, const std::string& id); }; class ActionApplyWithSkill : public Action { - std::string mId; - int mSkillIndex; - int mUsageType; - - void executeImp (const Ptr& actor) override; + std::string mId; + int mSkillIndex; + int mUsageType; - public: + void executeImp(const Ptr& actor) override; - ActionApplyWithSkill (const Ptr& object, const std::string& id, - int skillIndex, int usageType); + public: + ActionApplyWithSkill(const Ptr& object, const std::string& id, int skillIndex, int usageType); }; } diff --git a/apps/openmw/mwworld/actiondoor.cpp b/apps/openmw/mwworld/actiondoor.cpp index 6e3441e220..be0d5f3298 100644 --- a/apps/openmw/mwworld/actiondoor.cpp +++ b/apps/openmw/mwworld/actiondoor.cpp @@ -5,11 +5,12 @@ namespace MWWorld { - ActionDoor::ActionDoor (const MWWorld::Ptr& object) : Action (false, object) + ActionDoor::ActionDoor(const MWWorld::Ptr& object) + : Action(false, object) { } - void ActionDoor::executeImp (const MWWorld::Ptr& actor) + void ActionDoor::executeImp(const MWWorld::Ptr& actor) { MWBase::Environment::get().getWorld()->activateDoor(getTarget()); } diff --git a/apps/openmw/mwworld/actiondoor.hpp b/apps/openmw/mwworld/actiondoor.hpp index 4be61f5760..16b85b90ae 100644 --- a/apps/openmw/mwworld/actiondoor.hpp +++ b/apps/openmw/mwworld/actiondoor.hpp @@ -8,10 +8,10 @@ namespace MWWorld { class ActionDoor : public Action { - void executeImp (const MWWorld::Ptr& actor) override; + void executeImp(const MWWorld::Ptr& actor) override; - public: - ActionDoor (const Ptr& object); + public: + ActionDoor(const Ptr& object); }; } diff --git a/apps/openmw/mwworld/actioneat.cpp b/apps/openmw/mwworld/actioneat.cpp index c97c83c0c2..e7921bf4e6 100644 --- a/apps/openmw/mwworld/actioneat.cpp +++ b/apps/openmw/mwworld/actioneat.cpp @@ -10,11 +10,14 @@ namespace MWWorld { - void ActionEat::executeImp (const Ptr& actor) + void ActionEat::executeImp(const Ptr& actor) { if (actor.getClass().consume(getTarget(), actor) && actor == MWMechanics::getPlayer()) - actor.getClass().skillUsageSucceeded (actor, ESM::Skill::Alchemy, 1); + actor.getClass().skillUsageSucceeded(actor, ESM::Skill::Alchemy, 1); } - ActionEat::ActionEat (const MWWorld::Ptr& object) : Action (false, object) {} + ActionEat::ActionEat(const MWWorld::Ptr& object) + : Action(false, object) + { + } } diff --git a/apps/openmw/mwworld/actioneat.hpp b/apps/openmw/mwworld/actioneat.hpp index ddc231d99a..428635e4d6 100644 --- a/apps/openmw/mwworld/actioneat.hpp +++ b/apps/openmw/mwworld/actioneat.hpp @@ -7,11 +7,10 @@ namespace MWWorld { class ActionEat : public Action { - void executeImp (const Ptr& actor) override; + void executeImp(const Ptr& actor) override; - public: - - ActionEat (const MWWorld::Ptr& object); + public: + ActionEat(const MWWorld::Ptr& object); }; } diff --git a/apps/openmw/mwworld/actionequip.cpp b/apps/openmw/mwworld/actionequip.cpp index 426f4dd7b8..352a8fa2b5 100644 --- a/apps/openmw/mwworld/actionequip.cpp +++ b/apps/openmw/mwworld/actionequip.cpp @@ -7,19 +7,19 @@ #include +#include "class.hpp" #include "inventorystore.hpp" #include "player.hpp" -#include "class.hpp" namespace MWWorld { - ActionEquip::ActionEquip (const MWWorld::Ptr& object, bool force) - : Action (false, object) - , mForce(force) + ActionEquip::ActionEquip(const MWWorld::Ptr& object, bool force) + : Action(false, object) + , mForce(force) { } - void ActionEquip::executeImp (const Ptr& actor) + void ActionEquip::executeImp(const Ptr& actor) { MWWorld::Ptr object = getTarget(); MWWorld::InventoryStore& invStore = actor.getClass().getInventoryStore(actor); @@ -34,13 +34,13 @@ namespace MWWorld if (!mForce) { - auto result = object.getClass().canBeEquipped (object, actor); + auto result = object.getClass().canBeEquipped(object, actor); // display error message if the player tried to equip something if (!result.second.empty() && actor == MWMechanics::getPlayer()) MWBase::Environment::get().getWindowManager()->messageBox(result.second); - switch(result.first) + switch (result.first) { case 0: return; @@ -68,8 +68,8 @@ namespace MWWorld throw std::runtime_error("ActionEquip can't find item " + object.getCellRef().getRefId()); // equip the item in the first free slot - std::vector::const_iterator slot=slots_.first.begin(); - for (;slot!=slots_.first.end(); ++slot) + std::vector::const_iterator slot = slots_.first.begin(); + for (; slot != slots_.first.end(); ++slot) { // if the item is equipped already, nothing to do if (invStore.getSlot(*slot) == it) @@ -101,7 +101,7 @@ namespace MWWorld invStore.equip(*slot, it, actor); } - //Fix for issue of selected enchated item getting remmoved on cycle + // Fix for issue of selected enchated item getting remmoved on cycle if (invStore.getSlot(*slot) == enchItem) { reEquip = true; diff --git a/apps/openmw/mwworld/actionequip.hpp b/apps/openmw/mwworld/actionequip.hpp index 1ac3cb2360..863d281644 100644 --- a/apps/openmw/mwworld/actionequip.hpp +++ b/apps/openmw/mwworld/actionequip.hpp @@ -9,11 +9,11 @@ namespace MWWorld { bool mForce; - void executeImp (const Ptr& actor) override; + void executeImp(const Ptr& actor) override; public: /// @param item to equip - ActionEquip (const Ptr& object, bool force=false); + ActionEquip(const Ptr& object, bool force = false); }; } diff --git a/apps/openmw/mwworld/actionharvest.cpp b/apps/openmw/mwworld/actionharvest.cpp index aecb62a3ff..e14bd43aac 100644 --- a/apps/openmw/mwworld/actionharvest.cpp +++ b/apps/openmw/mwworld/actionharvest.cpp @@ -16,19 +16,19 @@ namespace MWWorld { - ActionHarvest::ActionHarvest (const MWWorld::Ptr& container) - : Action (true, container) + ActionHarvest::ActionHarvest(const MWWorld::Ptr& container) + : Action(true, container) { setSound("Item Ingredient Up"); } - void ActionHarvest::executeImp (const MWWorld::Ptr& actor) + void ActionHarvest::executeImp(const MWWorld::Ptr& actor) { if (!MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Inventory)) return; MWWorld::Ptr target = getTarget(); - MWWorld::ContainerStore& store = target.getClass().getContainerStore (target); + MWWorld::ContainerStore& store = target.getClass().getContainerStore(target); store.resolve(); MWWorld::ContainerStore& actorStore = actor.getClass().getContainerStore(actor); std::map takenMap; @@ -38,13 +38,14 @@ namespace MWWorld continue; int itemCount = it->getRefData().getCount(); - // Note: it is important to check for crime before move an item from container. Otherwise owner check will not work - // for a last item in the container - empty harvested containers are considered as "allowed to use". + // Note: it is important to check for crime before move an item from container. Otherwise owner check will + // not work for a last item in the container - empty harvested containers are considered as "allowed to + // use". MWBase::Environment::get().getMechanicsManager()->itemTaken(actor, *it, target, itemCount); actorStore.add(*it, itemCount, actor); store.remove(*it, itemCount, getTarget()); - std::string name{it->getClass().getName(*it)}; - takenMap[name]+=itemCount; + std::string name{ it->getClass().getName(*it) }; + takenMap[name] += itemCount; } // Spawn a messagebox (only for items added to player's inventory) @@ -63,7 +64,8 @@ namespace MWWorld else if (lineCount > maxLines) break; - // The two GMST entries below expand to strings informing the player of what, and how many of it has been added to their inventory + // The two GMST entries below expand to strings informing the player of what, and how many of it has + // been added to their inventory std::string msgBox; if (itemCount == 1) { diff --git a/apps/openmw/mwworld/actionharvest.hpp b/apps/openmw/mwworld/actionharvest.hpp index 2edc2f34e5..0c0596a691 100644 --- a/apps/openmw/mwworld/actionharvest.hpp +++ b/apps/openmw/mwworld/actionharvest.hpp @@ -8,11 +8,11 @@ namespace MWWorld { class ActionHarvest : public Action { - void executeImp (const MWWorld::Ptr& actor) override; + void executeImp(const MWWorld::Ptr& actor) override; - public: - ActionHarvest (const Ptr& container); - ///< \param container The Container the Player has activated. + public: + ActionHarvest(const Ptr& container); + ///< \param container The Container the Player has activated. }; } diff --git a/apps/openmw/mwworld/actionopen.cpp b/apps/openmw/mwworld/actionopen.cpp index 61f2f3e30c..f0d101be99 100644 --- a/apps/openmw/mwworld/actionopen.cpp +++ b/apps/openmw/mwworld/actionopen.cpp @@ -4,17 +4,17 @@ #include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/windowmanager.hpp" -#include "../mwmechanics/disease.hpp" #include "../mwmechanics/actorutil.hpp" +#include "../mwmechanics/disease.hpp" namespace MWWorld { - ActionOpen::ActionOpen (const MWWorld::Ptr& container) - : Action (false, container) + ActionOpen::ActionOpen(const MWWorld::Ptr& container) + : Action(false, container) { } - void ActionOpen::executeImp (const MWWorld::Ptr& actor) + void ActionOpen::executeImp(const MWWorld::Ptr& actor) { if (!MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Inventory)) return; diff --git a/apps/openmw/mwworld/actionopen.hpp b/apps/openmw/mwworld/actionopen.hpp index e9f76c4d71..b6d41f9a3d 100644 --- a/apps/openmw/mwworld/actionopen.hpp +++ b/apps/openmw/mwworld/actionopen.hpp @@ -7,12 +7,11 @@ namespace MWWorld { class ActionOpen : public Action { - void executeImp (const MWWorld::Ptr& actor) override; - - public: - ActionOpen (const Ptr& container); - ///< \param container The Container the Player has activated. + void executeImp(const MWWorld::Ptr& actor) override; + public: + ActionOpen(const Ptr& container); + ///< \param container The Container the Player has activated. }; } diff --git a/apps/openmw/mwworld/actionread.cpp b/apps/openmw/mwworld/actionread.cpp index 442078b18c..52ca77c528 100644 --- a/apps/openmw/mwworld/actionread.cpp +++ b/apps/openmw/mwworld/actionread.cpp @@ -7,58 +7,57 @@ #include "../mwbase/windowmanager.hpp" #include "../mwbase/world.hpp" -#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/actorutil.hpp" +#include "../mwmechanics/npcstats.hpp" -#include "player.hpp" #include "class.hpp" #include "esmstore.hpp" +#include "player.hpp" namespace MWWorld { - ActionRead::ActionRead (const MWWorld::Ptr& object) : Action (false, object) + ActionRead::ActionRead(const MWWorld::Ptr& object) + : Action(false, object) { } - void ActionRead::executeImp (const MWWorld::Ptr& actor) { + void ActionRead::executeImp(const MWWorld::Ptr& actor) + { if (actor != MWMechanics::getPlayer()) return; - //Ensure we're not in combat - if(MWMechanics::isPlayerInCombat() - // Reading in combat is still allowed if the scroll/book is not in the player inventory yet - // (since otherwise, there would be no way to pick it up) - && getTarget().getContainerStore() == &actor.getClass().getContainerStore(actor) - ) { + // Ensure we're not in combat + if (MWMechanics::isPlayerInCombat() + // Reading in combat is still allowed if the scroll/book is not in the player inventory yet + // (since otherwise, there would be no way to pick it up) + && getTarget().getContainerStore() == &actor.getClass().getContainerStore(actor)) + { MWBase::Environment::get().getWindowManager()->messageBox("#{sInventoryMessage4}"); return; } - LiveCellRef *ref = getTarget().get(); + LiveCellRef* ref = getTarget().get(); if (ref->mBase->mData.mIsScroll) MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Scroll, getTarget()); else MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Book, getTarget()); - MWMechanics::NpcStats& npcStats = actor.getClass().getNpcStats (actor); + MWMechanics::NpcStats& npcStats = actor.getClass().getNpcStats(actor); // Skill gain from books if (ref->mBase->mData.mSkillId >= 0 && ref->mBase->mData.mSkillId < ESM::Skill::Length - && !npcStats.hasBeenUsed (ref->mBase->mId)) + && !npcStats.hasBeenUsed(ref->mBase->mId)) { - MWWorld::LiveCellRef *playerRef = actor.get(); + MWWorld::LiveCellRef* playerRef = actor.get(); - const ESM::Class *class_ = - MWBase::Environment::get().getWorld()->getStore().get().find ( - playerRef->mBase->mClass - ); + const ESM::Class* class_ + = MWBase::Environment::get().getWorld()->getStore().get().find(playerRef->mBase->mClass); - npcStats.increaseSkill (ref->mBase->mData.mSkillId, *class_, true, true); + npcStats.increaseSkill(ref->mBase->mData.mSkillId, *class_, true, true); - npcStats.flagAsUsed (ref->mBase->mId); + npcStats.flagAsUsed(ref->mBase->mId); } - } } diff --git a/apps/openmw/mwworld/actionread.hpp b/apps/openmw/mwworld/actionread.hpp index 6387933eba..194aca9f59 100644 --- a/apps/openmw/mwworld/actionread.hpp +++ b/apps/openmw/mwworld/actionread.hpp @@ -7,11 +7,11 @@ namespace MWWorld { class ActionRead : public Action { - void executeImp (const MWWorld::Ptr& actor) override; + void executeImp(const MWWorld::Ptr& actor) override; - public: - /// @param book or scroll to read - ActionRead (const Ptr& object); + public: + /// @param book or scroll to read + ActionRead(const Ptr& object); }; } diff --git a/apps/openmw/mwworld/actionrepair.cpp b/apps/openmw/mwworld/actionrepair.cpp index 4fe48b4b4c..132587cc3e 100644 --- a/apps/openmw/mwworld/actionrepair.cpp +++ b/apps/openmw/mwworld/actionrepair.cpp @@ -8,17 +8,17 @@ namespace MWWorld { ActionRepair::ActionRepair(const Ptr& item, bool force) - : Action (false, item) + : Action(false, item) , mForce(force) { } - void ActionRepair::executeImp (const Ptr& actor) + void ActionRepair::executeImp(const Ptr& actor) { if (actor != MWMechanics::getPlayer()) return; - if(!mForce && MWMechanics::isPlayerInCombat()) + if (!mForce && MWMechanics::isPlayerInCombat()) { MWBase::Environment::get().getWindowManager()->messageBox("#{sInventoryMessage2}"); return; diff --git a/apps/openmw/mwworld/actionrepair.hpp b/apps/openmw/mwworld/actionrepair.hpp index 218077f5de..54611ff320 100644 --- a/apps/openmw/mwworld/actionrepair.hpp +++ b/apps/openmw/mwworld/actionrepair.hpp @@ -9,11 +9,11 @@ namespace MWWorld { bool mForce; - void executeImp (const Ptr& actor) override; + void executeImp(const Ptr& actor) override; public: /// @param item repair hammer - ActionRepair(const Ptr& item, bool force=false); + ActionRepair(const Ptr& item, bool force = false); }; } diff --git a/apps/openmw/mwworld/actionsoulgem.cpp b/apps/openmw/mwworld/actionsoulgem.cpp index 161d923358..187f399e09 100644 --- a/apps/openmw/mwworld/actionsoulgem.cpp +++ b/apps/openmw/mwworld/actionsoulgem.cpp @@ -3,8 +3,8 @@ #include #include -#include "../mwbase/windowmanager.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/windowmanager.hpp" #include "../mwbase/world.hpp" #include "../mwmechanics/actorutil.hpp" @@ -14,18 +14,18 @@ namespace MWWorld { - ActionSoulgem::ActionSoulgem(const Ptr &object) + ActionSoulgem::ActionSoulgem(const Ptr& object) : Action(false, object) { - } - void ActionSoulgem::executeImp(const Ptr &actor) + void ActionSoulgem::executeImp(const Ptr& actor) { if (actor != MWMechanics::getPlayer()) return; - if(MWMechanics::isPlayerInCombat()) { //Ensure we're not in combat + if (MWMechanics::isPlayerInCombat()) + { // Ensure we're not in combat MWBase::Environment::get().getWindowManager()->messageBox("#{sInventoryMessage5}"); return; } @@ -41,12 +41,12 @@ namespace MWWorld if (!MWBase::Environment::get().getWorld()->getStore().get().search(targetSoul)) { - Log(Debug::Warning) << "Soul '" << targetSoul << "' not found (item: '" << target.getCellRef().getRefId() << "')"; + Log(Debug::Warning) << "Soul '" << targetSoul << "' not found (item: '" << target.getCellRef().getRefId() + << "')"; return; } MWBase::Environment::get().getWindowManager()->showSoulgemDialog(target); } - } diff --git a/apps/openmw/mwworld/actionsoulgem.hpp b/apps/openmw/mwworld/actionsoulgem.hpp index d2b14c9122..f17ddb7bdc 100644 --- a/apps/openmw/mwworld/actionsoulgem.hpp +++ b/apps/openmw/mwworld/actionsoulgem.hpp @@ -7,11 +7,11 @@ namespace MWWorld { class ActionSoulgem : public Action { - void executeImp (const MWWorld::Ptr& actor) override; + void executeImp(const MWWorld::Ptr& actor) override; - public: - /// @param soulgem to use - ActionSoulgem (const Ptr& object); + public: + /// @param soulgem to use + ActionSoulgem(const Ptr& object); }; } diff --git a/apps/openmw/mwworld/actiontake.cpp b/apps/openmw/mwworld/actiontake.cpp index a173e87fbc..c8db98e1fe 100644 --- a/apps/openmw/mwworld/actiontake.cpp +++ b/apps/openmw/mwworld/actiontake.cpp @@ -1,9 +1,9 @@ #include "actiontake.hpp" #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" -#include "../mwbase/windowmanager.hpp" #include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" #include "../mwgui/inventorywindow.hpp" @@ -12,9 +12,12 @@ namespace MWWorld { - ActionTake::ActionTake (const MWWorld::Ptr& object) : Action (true, object) {} + ActionTake::ActionTake(const MWWorld::Ptr& object) + : Action(true, object) + { + } - void ActionTake::executeImp (const Ptr& actor) + void ActionTake::executeImp(const Ptr& actor) { // When in GUI mode, we should use drag and drop if (actor == MWBase::Environment::get().getWorld()->getPlayerPtr()) @@ -28,9 +31,10 @@ namespace MWWorld } MWBase::Environment::get().getMechanicsManager()->itemTaken( - actor, getTarget(), MWWorld::Ptr(), getTarget().getRefData().getCount()); - MWWorld::Ptr newitem = *actor.getClass().getContainerStore (actor).add (getTarget(), getTarget().getRefData().getCount(), actor); - MWBase::Environment::get().getWorld()->deleteObject (getTarget()); + actor, getTarget(), MWWorld::Ptr(), getTarget().getRefData().getCount()); + MWWorld::Ptr newitem + = *actor.getClass().getContainerStore(actor).add(getTarget(), getTarget().getRefData().getCount(), actor); + MWBase::Environment::get().getWorld()->deleteObject(getTarget()); setTarget(newitem); } } diff --git a/apps/openmw/mwworld/actiontake.hpp b/apps/openmw/mwworld/actiontake.hpp index bb9c0d3800..7cb0e03dd2 100644 --- a/apps/openmw/mwworld/actiontake.hpp +++ b/apps/openmw/mwworld/actiontake.hpp @@ -7,11 +7,10 @@ namespace MWWorld { class ActionTake : public Action { - void executeImp (const Ptr& actor) override; + void executeImp(const Ptr& actor) override; - public: - - ActionTake (const MWWorld::Ptr& object); + public: + ActionTake(const MWWorld::Ptr& object); }; } diff --git a/apps/openmw/mwworld/actiontalk.cpp b/apps/openmw/mwworld/actiontalk.cpp index 7fe623b8e4..e17c0830a8 100644 --- a/apps/openmw/mwworld/actiontalk.cpp +++ b/apps/openmw/mwworld/actiontalk.cpp @@ -7,9 +7,12 @@ namespace MWWorld { - ActionTalk::ActionTalk (const Ptr& actor) : Action (false, actor) {} + ActionTalk::ActionTalk(const Ptr& actor) + : Action(false, actor) + { + } - void ActionTalk::executeImp (const Ptr& actor) + void ActionTalk::executeImp(const Ptr& actor) { if (actor == MWMechanics::getPlayer()) MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Dialogue, getTarget()); diff --git a/apps/openmw/mwworld/actiontalk.hpp b/apps/openmw/mwworld/actiontalk.hpp index 6dd70380ff..f2d2843a64 100644 --- a/apps/openmw/mwworld/actiontalk.hpp +++ b/apps/openmw/mwworld/actiontalk.hpp @@ -7,12 +7,11 @@ namespace MWWorld { class ActionTalk : public Action { - void executeImp (const Ptr& actor) override; + void executeImp(const Ptr& actor) override; - public: - - ActionTalk (const Ptr& actor); - ///< \param actor The actor the player is talking to + public: + ActionTalk(const Ptr& actor); + ///< \param actor The actor the player is talking to }; } diff --git a/apps/openmw/mwworld/actionteleport.cpp b/apps/openmw/mwworld/actionteleport.cpp index 17370671a1..8754e2ba0e 100644 --- a/apps/openmw/mwworld/actionteleport.cpp +++ b/apps/openmw/mwworld/actionteleport.cpp @@ -3,26 +3,28 @@ #include #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/world.hpp" #include "../mwmechanics/creaturestats.hpp" #include "../mwworld/cellstore.hpp" -#include "../mwworld/class.hpp" #include "../mwworld/cellutils.hpp" +#include "../mwworld/class.hpp" #include "player.hpp" namespace MWWorld { - ActionTeleport::ActionTeleport(std::string_view cellName, - const ESM::Position& position, bool teleportFollowers) - : Action (true), mCellName (cellName), mPosition (position), mTeleportFollowers(teleportFollowers) + ActionTeleport::ActionTeleport(std::string_view cellName, const ESM::Position& position, bool teleportFollowers) + : Action(true) + , mCellName(cellName) + , mPosition(position) + , mTeleportFollowers(teleportFollowers) { } - void ActionTeleport::executeImp (const Ptr& actor) + void ActionTeleport::executeImp(const Ptr& actor) { if (mTeleportFollowers) { @@ -37,17 +39,17 @@ namespace MWWorld teleport(actor); } - void ActionTeleport::teleport(const Ptr &actor) + void ActionTeleport::teleport(const Ptr& actor) { MWBase::World* world = MWBase::Environment::get().getWorld(); actor.getClass().getCreatureStats(actor).land(actor == world->getPlayerPtr()); - if(actor == world->getPlayerPtr()) + if (actor == world->getPlayerPtr()) { world->getPlayer().setTeleported(true); if (mCellName.empty()) - world->changeToExteriorCell (mPosition, true); + world->changeToExteriorCell(mPosition, true); else - world->changeToInteriorCell (mCellName, mPosition, true); + world->changeToInteriorCell(mCellName, mPosition, true); } else { @@ -59,15 +61,17 @@ namespace MWWorld world->moveObject(actor, world->getExterior(index.x(), index.y()), mPosition.asVec3(), true, true); } else - world->moveObject(actor,world->getInterior(mCellName),mPosition.asVec3(), true, true); + world->moveObject(actor, world->getInterior(mCellName), mPosition.asVec3(), true, true); } } - void ActionTeleport::getFollowers(const MWWorld::Ptr& actor, std::set& out, bool toExterior, bool includeHostiles) { + void ActionTeleport::getFollowers( + const MWWorld::Ptr& actor, std::set& out, bool toExterior, bool includeHostiles) + { std::set followers; MWBase::Environment::get().getMechanicsManager()->getActorsFollowing(actor, followers); - for(std::set::iterator it = followers.begin();it != followers.end();++it) + for (std::set::iterator it = followers.begin(); it != followers.end(); ++it) { MWWorld::Ptr follower = *it; @@ -76,10 +80,13 @@ namespace MWWorld if (!includeHostiles && follower.getClass().getCreatureStats(follower).getAiSequence().isInCombat(actor)) continue; - if (!toExterior && !script.empty() && follower.getRefData().getLocals().getIntVar(script, "stayoutside") == 1 && follower.getCell()->getCell()->isExterior()) + if (!toExterior && !script.empty() + && follower.getRefData().getLocals().getIntVar(script, "stayoutside") == 1 + && follower.getCell()->getCell()->isExterior()) continue; - if ((follower.getRefData().getPosition().asVec3() - actor.getRefData().getPosition().asVec3()).length2() > 800 * 800) + if ((follower.getRefData().getPosition().asVec3() - actor.getRefData().getPosition().asVec3()).length2() + > 800 * 800) continue; out.emplace(follower); diff --git a/apps/openmw/mwworld/actionteleport.hpp b/apps/openmw/mwworld/actionteleport.hpp index b467e1db0f..cbdd59cc87 100644 --- a/apps/openmw/mwworld/actionteleport.hpp +++ b/apps/openmw/mwworld/actionteleport.hpp @@ -13,25 +13,26 @@ namespace MWWorld { class ActionTeleport : public Action { - std::string mCellName; - ESM::Position mPosition; - bool mTeleportFollowers; - - /// Teleports this actor and also teleports anyone following that actor. - void executeImp (const Ptr& actor) override; - - /// Teleports only the given actor (internal use). - void teleport(const Ptr &actor); - - public: - - /// If cellName is empty, an exterior cell is assumed. - /// @param teleportFollowers Whether to teleport any following actors of the target actor as well. - ActionTeleport(std::string_view cellName, const ESM::Position& position, bool teleportFollowers); - - /// @param includeHostiles If true, include hostile followers (which won't actually be teleported) in the output, - /// e.g. so that the teleport action can calm them. - static void getFollowers(const MWWorld::Ptr& actor, std::set& out, bool toExterior, bool includeHostiles = false); + std::string mCellName; + ESM::Position mPosition; + bool mTeleportFollowers; + + /// Teleports this actor and also teleports anyone following that actor. + void executeImp(const Ptr& actor) override; + + /// Teleports only the given actor (internal use). + void teleport(const Ptr& actor); + + public: + /// If cellName is empty, an exterior cell is assumed. + /// @param teleportFollowers Whether to teleport any following actors of the target actor as well. + ActionTeleport(std::string_view cellName, const ESM::Position& position, bool teleportFollowers); + + /// @param includeHostiles If true, include hostile followers (which won't actually be teleported) in the + /// output, + /// e.g. so that the teleport action can calm them. + static void getFollowers( + const MWWorld::Ptr& actor, std::set& out, bool toExterior, bool includeHostiles = false); }; } diff --git a/apps/openmw/mwworld/actiontrap.cpp b/apps/openmw/mwworld/actiontrap.cpp index cdabaf8c84..e7dd0d98f9 100644 --- a/apps/openmw/mwworld/actiontrap.cpp +++ b/apps/openmw/mwworld/actiontrap.cpp @@ -7,7 +7,7 @@ namespace MWWorld { - void ActionTrap::executeImp(const Ptr &actor) + void ActionTrap::executeImp(const Ptr& actor) { osg::Vec3f actorPosition(actor.getRefData().getPosition().asVec3()); osg::Vec3f trapPosition(mTrapSource.getRefData().getPosition().asVec3()); @@ -17,7 +17,9 @@ namespace MWWorld // radius, because for most trap spells this is 1 foot, much less than the activation distance. // Using activation distance as the trap range. - if (actor == MWBase::Environment::get().getWorld()->getPlayerPtr() && MWBase::Environment::get().getWorld()->getDistanceToFacedObject() > trapRange) // player activated object outside range of trap + if (actor == MWBase::Environment::get().getWorld()->getPlayerPtr() + && MWBase::Environment::get().getWorld()->getDistanceToFacedObject() + > trapRange) // player activated object outside range of trap { MWMechanics::CastSpell cast(mTrapSource, mTrapSource); cast.mHitPosition = trapPosition; @@ -28,7 +30,7 @@ namespace MWWorld MWMechanics::CastSpell cast(mTrapSource, actor); cast.mHitPosition = actorPosition; cast.cast(mSpellId); - } + } mTrapSource.getCellRef().setTrap(""); } } diff --git a/apps/openmw/mwworld/actiontrap.hpp b/apps/openmw/mwworld/actiontrap.hpp index fe51959d1b..6119856708 100644 --- a/apps/openmw/mwworld/actiontrap.hpp +++ b/apps/openmw/mwworld/actiontrap.hpp @@ -9,19 +9,21 @@ namespace MWWorld { class ActionTrap : public Action { - std::string mSpellId; - MWWorld::Ptr mTrapSource; - - void executeImp (const Ptr& actor) override; - - public: - - /// @param spellId - /// @param trapSource - ActionTrap (const std::string& spellId, const Ptr& trapSource) - : Action(false, trapSource), mSpellId(spellId), mTrapSource(trapSource) {} + std::string mSpellId; + MWWorld::Ptr mTrapSource; + + void executeImp(const Ptr& actor) override; + + public: + /// @param spellId + /// @param trapSource + ActionTrap(const std::string& spellId, const Ptr& trapSource) + : Action(false, trapSource) + , mSpellId(spellId) + , mTrapSource(trapSource) + { + } }; } - #endif diff --git a/apps/openmw/mwworld/cellpreloader.cpp b/apps/openmw/mwworld/cellpreloader.cpp index daaab46c8f..713fbbf05f 100644 --- a/apps/openmw/mwworld/cellpreloader.cpp +++ b/apps/openmw/mwworld/cellpreloader.cpp @@ -4,17 +4,17 @@ #include #include -#include -#include -#include -#include -#include +#include +#include #include #include -#include +#include +#include +#include +#include #include -#include -#include +#include +#include #include "../mwrender/landmanager.hpp" @@ -24,21 +24,22 @@ namespace { template - bool contains(const std::vector& container, - const Contained& contained, float tolerance) + bool contains(const std::vector& container, const Contained& contained, + float tolerance) { for (const auto& pos : contained) { bool found = false; for (const auto& pos2 : container) { - if ((pos.first-pos2.first).length2() < tolerance*tolerance && pos.second == pos2.second) + if ((pos.first - pos2.first).length2() < tolerance * tolerance && pos.second == pos2.second) { found = true; break; } } - if (!found) return false; + if (!found) + return false; } return true; } @@ -71,7 +72,9 @@ namespace MWWorld { public: /// Constructor to be called from the main thread. - PreloadItem(MWWorld::CellStore* cell, Resource::SceneManager* sceneManager, Resource::BulletShapeManager* bulletShapeManager, Resource::KeyframeManager* keyframeManager, Terrain::World* terrain, MWRender::LandManager* landManager, bool preloadInstances) + PreloadItem(MWWorld::CellStore* cell, Resource::SceneManager* sceneManager, + Resource::BulletShapeManager* bulletShapeManager, Resource::KeyframeManager* keyframeManager, + Terrain::World* terrain, MWRender::LandManager* landManager, bool preloadInstances) : mIsExterior(cell->getCell()->isExterior()) , mX(cell->getCell()->getGridX()) , mY(cell->getCell()->getGridY()) @@ -85,14 +88,11 @@ namespace MWWorld { mTerrainView = mTerrain->createView(); - ListModelsVisitor visitor (mMeshes); + ListModelsVisitor visitor(mMeshes); cell->forEach(visitor); } - void abort() override - { - mAbort = true; - } + void abort() override { mAbort = true; } /// Preload work to be called from the worker thread. void doWork() override @@ -104,12 +104,12 @@ namespace MWWorld mTerrain->cacheCell(mTerrainView.get(), mX, mY); mPreloadedObjects.insert(mLandManager->getLand(mX, mY)); } - catch(std::exception&) + catch (std::exception&) { } } - for (std::string& mesh: mMeshes) + for (std::string& mesh : mMeshes) { if (mAbort) break; @@ -119,15 +119,15 @@ namespace MWWorld mesh = Misc::ResourceHelpers::correctActorModelPath(mesh, mSceneManager->getVFS()); size_t slashpos = mesh.find_last_of("/\\"); - if (slashpos != std::string::npos && slashpos != mesh.size()-1) + if (slashpos != std::string::npos && slashpos != mesh.size() - 1) { Misc::StringUtils::lowerCaseInPlace(mesh); - if (mesh[slashpos+1] == 'x') + if (mesh[slashpos + 1] == 'x') { std::string kfname = mesh; - if(kfname.size() > 4 && kfname.compare(kfname.size()-4, 4, ".nif") == 0) + if (kfname.size() > 4 && kfname.compare(kfname.size() - 4, 4, ".nif") == 0) { - kfname.replace(kfname.size()-4, 4, ".kf"); + kfname.replace(kfname.size() - 4, 4, ".kf"); if (mSceneManager->getVFS()->exists(kfname)) mPreloadedObjects.insert(mKeyframeManager->get(kfname)); } @@ -138,7 +138,6 @@ namespace MWWorld mPreloadedObjects.insert(mBulletShapeManager->cacheInstance(mesh)); else mPreloadedObjects.insert(mBulletShapeManager->getShape(mesh)); - } catch (std::exception&) { @@ -166,13 +165,14 @@ namespace MWWorld osg::ref_ptr mTerrainView; // keep a ref to the loaded objects to make sure it stays loaded as long as this cell is in the preloaded state - std::set > mPreloadedObjects; + std::set> mPreloadedObjects; }; class TerrainPreloadItem : public SceneUtil::WorkItem { public: - TerrainPreloadItem(const std::vector >& views, Terrain::World* world, const std::vector& preloadPositions) + TerrainPreloadItem(const std::vector>& views, Terrain::World* world, + const std::vector& preloadPositions) : mAbort(false) , mTerrainViews(views) , mWorld(world) @@ -182,27 +182,22 @@ namespace MWWorld void doWork() override { - for (unsigned int i=0; ireset(); - mWorld->preload(mTerrainViews[i], mPreloadPositions[i].first, mPreloadPositions[i].second, mAbort, mLoadingReporter); + mWorld->preload(mTerrainViews[i], mPreloadPositions[i].first, mPreloadPositions[i].second, mAbort, + mLoadingReporter); } mLoadingReporter.complete(); } - void abort() override - { - mAbort = true; - } + void abort() override { mAbort = true; } - void wait(Loading::Listener& listener) const - { - mLoadingReporter.wait(listener); - } + void wait(Loading::Listener& listener) const { mLoadingReporter.wait(listener); } private: std::atomic mAbort; - std::vector > mTerrainViews; + std::vector> mTerrainViews; Terrain::World* mWorld; std::vector mPreloadPositions; Loading::Reporter mLoadingReporter; @@ -218,17 +213,15 @@ namespace MWWorld { } - void doWork() override - { - mResourceSystem->updateCache(mReferenceTime); - } + void doWork() override { mResourceSystem->updateCache(mReferenceTime); } private: double mReferenceTime; Resource::ResourceSystem* mResourceSystem; }; - CellPreloader::CellPreloader(Resource::ResourceSystem* resourceSystem, Resource::BulletShapeManager* bulletShapeManager, Terrain::World* terrain, MWRender::LandManager* landManager) + CellPreloader::CellPreloader(Resource::ResourceSystem* resourceSystem, + Resource::BulletShapeManager* bulletShapeManager, Terrain::World* terrain, MWRender::LandManager* landManager) : mResourceSystem(resourceSystem) , mBulletShapeManager(bulletShapeManager) , mTerrain(terrain) @@ -257,16 +250,16 @@ namespace MWWorld mUpdateCacheItem = nullptr; } - for (PreloadMap::iterator it = mPreloadCells.begin(); it != mPreloadCells.end();++it) + for (PreloadMap::iterator it = mPreloadCells.begin(); it != mPreloadCells.end(); ++it) it->second.mWorkItem->abort(); - for (PreloadMap::iterator it = mPreloadCells.begin(); it != mPreloadCells.end();++it) + for (PreloadMap::iterator it = mPreloadCells.begin(); it != mPreloadCells.end(); ++it) it->second.mWorkItem->waitTillDone(); mPreloadCells.clear(); } - void CellPreloader::preload(CellStore *cell, double timestamp) + void CellPreloader::preload(CellStore* cell, double timestamp) { if (!mWorkQueue) { @@ -311,13 +304,14 @@ namespace MWWorld return; } - osg::ref_ptr item (new PreloadItem(cell, mResourceSystem->getSceneManager(), mBulletShapeManager, mResourceSystem->getKeyframeManager(), mTerrain, mLandManager, mPreloadInstances)); + osg::ref_ptr item(new PreloadItem(cell, mResourceSystem->getSceneManager(), mBulletShapeManager, + mResourceSystem->getKeyframeManager(), mTerrain, mLandManager, mPreloadInstances)); mWorkQueue->addWorkItem(item); mPreloadCells[cell] = PreloadEntry(timestamp, item); } - void CellPreloader::notifyLoaded(CellStore *cell) + void CellPreloader::notifyLoaded(CellStore* cell) { PreloadMap::iterator found = mPreloadCells.find(cell); if (found != mPreloadCells.end()) @@ -365,7 +359,8 @@ namespace MWWorld if (timestamp - mLastResourceCacheUpdate > 1.0 && (!mUpdateCacheItem || mUpdateCacheItem->isDone())) { - // the resource cache is cleared from the worker thread so that we're not holding up the main thread with delete operations + // the resource cache is cleared from the worker thread so that we're not holding up the main thread with + // delete operations mUpdateCacheItem = new UpdateCacheItem(mResourceSystem, timestamp); mWorkQueue->addWorkItem(mUpdateCacheItem, true); mLastResourceCacheUpdate = timestamp; @@ -408,7 +403,8 @@ namespace MWWorld mWorkQueue = workQueue; } - bool CellPreloader::syncTerrainLoad(const std::vector &positions, double timestamp, Loading::Listener& listener) + bool CellPreloader::syncTerrainLoad( + const std::vector& positions, double timestamp, Loading::Listener& listener) { if (!mTerrainPreloadItem) return true; @@ -423,9 +419,9 @@ namespace MWWorld } } - void CellPreloader::abortTerrainPreloadExcept(const CellPreloader::PositionCellGrid *exceptPos) + void CellPreloader::abortTerrainPreloadExcept(const CellPreloader::PositionCellGrid* exceptPos) { - if (exceptPos && contains(mTerrainPreloadPositions, std::array {*exceptPos}, ESM::Land::REAL_SIZE)) + if (exceptPos && contains(mTerrainPreloadPositions, std::array{ *exceptPos }, ESM::Land::REAL_SIZE)) return; if (mTerrainPreloadItem && !mTerrainPreloadItem->isDone()) { @@ -435,7 +431,7 @@ namespace MWWorld setTerrainPreloadPositions(std::vector()); } - void CellPreloader::setTerrainPreloadPositions(const std::vector &positions) + void CellPreloader::setTerrainPreloadPositions(const std::vector& positions) { if (positions.empty()) { @@ -452,7 +448,7 @@ namespace MWWorld mTerrainViews.resize(positions.size()); else if (mTerrainViews.size() < positions.size()) { - for (unsigned int i=mTerrainViews.size(); icreateView()); } @@ -464,10 +460,11 @@ namespace MWWorld } } } - - bool CellPreloader::isTerrainLoaded(const CellPreloader::PositionCellGrid &position, double referenceTime) const + + bool CellPreloader::isTerrainLoaded(const CellPreloader::PositionCellGrid& position, double referenceTime) const { - return mLoadedTerrainTimestamp + mResourceSystem->getSceneManager()->getExpiryDelay() > referenceTime && contains(mLoadedTerrainPositions, std::array {position}, ESM::Land::REAL_SIZE); + return mLoadedTerrainTimestamp + mResourceSystem->getSceneManager()->getExpiryDelay() > referenceTime + && contains(mLoadedTerrainPositions, std::array{ position }, ESM::Land::REAL_SIZE); } } diff --git a/apps/openmw/mwworld/cellpreloader.hpp b/apps/openmw/mwworld/cellpreloader.hpp index 185a25276b..bd4d712c39 100644 --- a/apps/openmw/mwworld/cellpreloader.hpp +++ b/apps/openmw/mwworld/cellpreloader.hpp @@ -1,11 +1,11 @@ #ifndef OPENMW_MWWORLD_CELLPRELOADER_H #define OPENMW_MWWORLD_CELLPRELOADER_H +#include #include -#include #include #include -#include +#include namespace Resource { @@ -37,7 +37,8 @@ namespace MWWorld class CellPreloader { public: - CellPreloader(Resource::ResourceSystem* resourceSystem, Resource::BulletShapeManager* bulletShapeManager, Terrain::World* terrain, MWRender::LandManager* landManager); + CellPreloader(Resource::ResourceSystem* resourceSystem, Resource::BulletShapeManager* bulletShapeManager, + Terrain::World* terrain, MWRender::LandManager* landManager); ~CellPreloader(); /// Ask a background thread to preload rendering meshes and collision shapes for objects in this cell. @@ -70,9 +71,10 @@ namespace MWWorld typedef std::pair PositionCellGrid; void setTerrainPreloadPositions(const std::vector& positions); - bool syncTerrainLoad(const std::vector &positions, double timestamp, Loading::Listener& listener); - void abortTerrainPreloadExcept(const PositionCellGrid *exceptPos); - bool isTerrainLoaded(const CellPreloader::PositionCellGrid &position, double referenceTime) const; + bool syncTerrainLoad(const std::vector& positions, double timestamp, + Loading::Listener& listener); + void abortTerrainPreloadExcept(const PositionCellGrid* exceptPos); + bool isTerrainLoaded(const CellPreloader::PositionCellGrid& position, double referenceTime) const; private: Resource::ResourceSystem* mResourceSystem; @@ -107,7 +109,7 @@ namespace MWWorld // Cells that are currently being preloaded, or have already finished preloading PreloadMap mPreloadCells; - std::vector > mTerrainViews; + std::vector> mTerrainViews; std::vector mTerrainPreloadPositions; osg::ref_ptr mTerrainPreloadItem; osg::ref_ptr mUpdateCacheItem; diff --git a/apps/openmw/mwworld/cellref.cpp b/apps/openmw/mwworld/cellref.cpp index 6e0e5351dd..b18e4b5a66 100644 --- a/apps/openmw/mwworld/cellref.cpp +++ b/apps/openmw/mwworld/cellref.cpp @@ -15,7 +15,7 @@ namespace MWWorld // Generated RefNums have negative mContentFile assert(lastAssignedRefNum.mContentFile < 0); lastAssignedRefNum.mIndex++; - if (lastAssignedRefNum.mIndex == 0) // mIndex overflow, so mContentFile should be changed + if (lastAssignedRefNum.mIndex == 0) // mIndex overflow, so mContentFile should be changed { if (lastAssignedRefNum.mContentFile > std::numeric_limits::min()) lastAssignedRefNum.mContentFile--; @@ -42,7 +42,7 @@ namespace MWWorld } } - void CellRef::setPosition(const ESM::Position &position) + void CellRef::setPosition(const ESM::Position& position) { mChanged = true; mCellRef.mPos = position; @@ -127,7 +127,7 @@ namespace MWWorld } } - void CellRef::setOwner(const std::string &owner) + void CellRef::setOwner(const std::string& owner) { if (owner != mCellRef.mOwner) { @@ -145,7 +145,7 @@ namespace MWWorld } } - void CellRef::setFaction(const std::string &faction) + void CellRef::setFaction(const std::string& faction) { if (faction != mCellRef.mFaction) { @@ -165,15 +165,15 @@ namespace MWWorld void CellRef::lock(int lockLevel) { - if(lockLevel != 0) - setLockLevel(abs(lockLevel)); //Changes lock to locklevel, if positive + if (lockLevel != 0) + setLockLevel(abs(lockLevel)); // Changes lock to locklevel, if positive else setLockLevel(ESM::UnbreakableLock); // If zero, set to max lock level } void CellRef::unlock() { - setLockLevel(-abs(mCellRef.mLockLevel)); //Makes lockLevel negative + setLockLevel(-abs(mCellRef.mLockLevel)); // Makes lockLevel negative } void CellRef::setTrap(const std::string& trap) @@ -194,7 +194,7 @@ namespace MWWorld } } - void CellRef::writeState(ESM::ObjectState &state) const + void CellRef::writeState(ESM::ObjectState& state) const { state.mRef = mCellRef; } diff --git a/apps/openmw/mwworld/cellref.hpp b/apps/openmw/mwworld/cellref.hpp index 8f11542187..e8fa03a093 100644 --- a/apps/openmw/mwworld/cellref.hpp +++ b/apps/openmw/mwworld/cellref.hpp @@ -17,8 +17,7 @@ namespace MWWorld class CellRef { public: - - CellRef (const ESM::CellRef& ref) + CellRef(const ESM::CellRef& ref) : mCellRef(ref) { mChanged = false; @@ -57,7 +56,7 @@ namespace MWWorld // The *original* position and rotation as it was given in the Construction Set. // Current position and rotation of the object is stored in RefData. const ESM::Position& getPosition() const { return mCellRef.mPos; } - void setPosition (const ESM::Position& position); + void setPosition(const ESM::Position& position); // Remaining enchantment charge. This could be -1 if the charge was not touched yet (i.e. full). float getEnchantmentCharge() const { return mCellRef.mEnchantmentCharge; } @@ -94,7 +93,7 @@ namespace MWWorld // The faction that owns this object (and will get angry if // you take it and are not a faction member) const std::string& getFaction() const { return mCellRef.mFaction; } - void setFaction (const std::string& faction); + void setFaction(const std::string& faction); // PC faction rank required to use the item. Sometimes is -1, which means "any rank". void setFactionRank(int factionRank); @@ -107,7 +106,7 @@ namespace MWWorld void setLockLevel(int lockLevel); void lock(int lockLevel); void unlock(); - // Key and trap ID names, if any + // Key and trap ID names, if any const std::string& getKey() const { return mCellRef.mKey; } const std::string& getTrap() const { return mCellRef.mTrap; } void setTrap(const std::string& trap); @@ -117,7 +116,7 @@ namespace MWWorld void setGoldValue(int value); // Write the content of this CellRef into the given ObjectState - void writeState (ESM::ObjectState& state) const; + void writeState(ESM::ObjectState& state) const; // Has this CellRef changed since it was originally loaded? bool hasChanged() const { return mChanged; } diff --git a/apps/openmw/mwworld/cellreflist.hpp b/apps/openmw/mwworld/cellreflist.hpp index 9d6d63fb4f..8f0a31b5e3 100644 --- a/apps/openmw/mwworld/cellreflist.hpp +++ b/apps/openmw/mwworld/cellreflist.hpp @@ -7,7 +7,9 @@ namespace MWWorld { - struct CellRefListBase {}; + struct CellRefListBase + { + }; /// \brief Collection of references of one type template @@ -24,16 +26,16 @@ namespace MWWorld /// and the build will fail with an ugly three-way cyclic header dependence /// so we need to pass the instantiation of the method to the linker, when /// all methods are known. - void load (ESM::CellRef &ref, bool deleted, const MWWorld::ESMStore &esmStore); + void load(ESM::CellRef& ref, bool deleted, const MWWorld::ESMStore& esmStore); - LiveRef &insert (const LiveRef &item) + LiveRef& insert(const LiveRef& item) { mList.push_back(item); return mList.back(); } /// Remove all references with the given refNum from this list. - void remove (const ESM::RefNum &refNum) + void remove(const ESM::RefNum& refNum) { for (typename List::iterator it = mList.begin(); it != mList.end();) { diff --git a/apps/openmw/mwworld/cells.cpp b/apps/openmw/mwworld/cells.cpp index 3ad8a1ee38..9c1fc97f30 100644 --- a/apps/openmw/mwworld/cells.cpp +++ b/apps/openmw/mwworld/cells.cpp @@ -1,48 +1,47 @@ #include "cells.hpp" #include -#include -#include #include -#include #include +#include +#include +#include #include #include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" -#include "esmstore.hpp" -#include "containerstore.hpp" #include "cellstore.hpp" +#include "containerstore.hpp" +#include "esmstore.hpp" namespace { - template + template bool forEachInStore(const std::string& id, Visitor&& visitor, std::map& cellStore) { - for(auto& cell : cellStore) + for (auto& cell : cellStore) { - if(cell.second.getState() == MWWorld::CellStore::State_Unloaded) + if (cell.second.getState() == MWWorld::CellStore::State_Unloaded) cell.second.preload(); - if(cell.second.getState() == MWWorld::CellStore::State_Preloaded) + if (cell.second.getState() == MWWorld::CellStore::State_Preloaded) { - if(cell.second.hasId(id)) + if (cell.second.hasId(id)) { cell.second.load(); } else continue; } - bool cont = cell.second.forEach([&] (MWWorld::Ptr ptr) - { + bool cont = cell.second.forEach([&](MWWorld::Ptr ptr) { if (ptr.getCellRef().getRefId() == id) { return visitor(ptr); } return true; }); - if(!cont) + if (!cont) return false; } return true; @@ -60,26 +59,27 @@ namespace }; } -MWWorld::CellStore *MWWorld::Cells::getCellStore (const ESM::Cell *cell) +MWWorld::CellStore* MWWorld::Cells::getCellStore(const ESM::Cell* cell) { if (cell->mData.mFlags & ESM::Cell::Interior) { std::string lowerName(Misc::StringUtils::lowerCase(cell->mName)); - std::map::iterator result = mInteriors.find (lowerName); + std::map::iterator result = mInteriors.find(lowerName); - if (result==mInteriors.end()) + if (result == mInteriors.end()) result = mInteriors.emplace(std::move(lowerName), CellStore(cell, mStore, mReaders)).first; return &result->second; } else { - std::map, CellStore>::iterator result = - mExteriors.find (std::make_pair (cell->getGridX(), cell->getGridY())); + std::map, CellStore>::iterator result + = mExteriors.find(std::make_pair(cell->getGridX(), cell->getGridY())); - if (result==mExteriors.end()) - result = mExteriors.emplace(std::make_pair(cell->getGridX(), cell->getGridY()), - CellStore(cell, mStore, mReaders)).first; + if (result == mExteriors.end()) + result = mExteriors + .emplace(std::make_pair(cell->getGridX(), cell->getGridY()), CellStore(cell, mStore, mReaders)) + .first; return &result->second; } @@ -95,53 +95,52 @@ void MWWorld::Cells::clear() MWWorld::Ptr MWWorld::Cells::getPtrAndCache(std::string_view name, CellStore& cellStore) { - Ptr ptr = getPtr (name, cellStore); + Ptr ptr = getPtr(name, cellStore); if (!ptr.isEmpty() && ptr.isInCell()) { mIdCache[mIdCacheIndex].first = name; mIdCache[mIdCacheIndex].second = &cellStore; - if (++mIdCacheIndex>=mIdCache.size()) + if (++mIdCacheIndex >= mIdCache.size()) mIdCacheIndex = 0; } return ptr; } -void MWWorld::Cells::writeCell (ESM::ESMWriter& writer, CellStore& cell) const +void MWWorld::Cells::writeCell(ESM::ESMWriter& writer, CellStore& cell) const { - if (cell.getState()!=CellStore::State_Loaded) - cell.load (); + if (cell.getState() != CellStore::State_Loaded) + cell.load(); ESM::CellState cellState; - cell.saveState (cellState); + cell.saveState(cellState); - writer.startRecord (ESM::REC_CSTA); - cellState.mId.save (writer); - cellState.save (writer); + writer.startRecord(ESM::REC_CSTA); + cellState.mId.save(writer); + cellState.save(writer); cell.writeFog(writer); - cell.writeReferences (writer); - writer.endRecord (ESM::REC_CSTA); + cell.writeReferences(writer); + writer.endRecord(ESM::REC_CSTA); } -MWWorld::Cells::Cells (const MWWorld::ESMStore& store, ESM::ReadersCache& readers) +MWWorld::Cells::Cells(const MWWorld::ESMStore& store, ESM::ReadersCache& readers) : mStore(store) , mReaders(readers) , mIdCacheIndex(0) { int cacheSize = std::clamp(Settings::Manager::getInt("pointers cache size", "Cells"), 40, 1000); - mIdCache = IdCache(cacheSize, std::pair ("", (CellStore*)nullptr)); + mIdCache = IdCache(cacheSize, std::pair("", (CellStore*)nullptr)); } -MWWorld::CellStore *MWWorld::Cells::getExterior (int x, int y) +MWWorld::CellStore* MWWorld::Cells::getExterior(int x, int y) { - std::map, CellStore>::iterator result = - mExteriors.find (std::make_pair (x, y)); + std::map, CellStore>::iterator result = mExteriors.find(std::make_pair(x, y)); - if (result==mExteriors.end()) + if (result == mExteriors.end()) { - const ESM::Cell *cell = mStore.get().search(x, y); + const ESM::Cell* cell = mStore.get().search(x, y); if (!cell) { @@ -158,15 +157,15 @@ MWWorld::CellStore *MWWorld::Cells::getExterior (int x, int y) record.mWater = 0; record.mMapColor = 0; - cell = MWBase::Environment::get().getWorld()->createRecord (record); + cell = MWBase::Environment::get().getWorld()->createRecord(record); } result = mExteriors.emplace(std::make_pair(x, y), CellStore(cell, mStore, mReaders)).first; } - if (result->second.getState()!=CellStore::State_Loaded) + if (result->second.getState() != CellStore::State_Loaded) { - result->second.load (); + result->second.load(); } return &result->second; @@ -175,91 +174,90 @@ MWWorld::CellStore *MWWorld::Cells::getExterior (int x, int y) MWWorld::CellStore* MWWorld::Cells::getInterior(std::string_view name) { std::string lowerName = Misc::StringUtils::lowerCase(name); - std::map::iterator result = mInteriors.find (lowerName); + std::map::iterator result = mInteriors.find(lowerName); - if (result==mInteriors.end()) + if (result == mInteriors.end()) { - const ESM::Cell *cell = mStore.get().find(lowerName); + const ESM::Cell* cell = mStore.get().find(lowerName); result = mInteriors.emplace(std::move(lowerName), CellStore(cell, mStore, mReaders)).first; } - if (result->second.getState()!=CellStore::State_Loaded) + if (result->second.getState() != CellStore::State_Loaded) { - result->second.load (); + result->second.load(); } return &result->second; } -void MWWorld::Cells::rest (double hours) +void MWWorld::Cells::rest(double hours) { - for (auto &interior : mInteriors) + for (auto& interior : mInteriors) { interior.second.rest(hours); } - for (auto &exterior : mExteriors) + for (auto& exterior : mExteriors) { exterior.second.rest(hours); } } -void MWWorld::Cells::recharge (float duration) +void MWWorld::Cells::recharge(float duration) { - for (auto &interior : mInteriors) + for (auto& interior : mInteriors) { interior.second.recharge(duration); } - for (auto &exterior : mExteriors) + for (auto& exterior : mExteriors) { exterior.second.recharge(duration); } } -MWWorld::CellStore *MWWorld::Cells::getCell (const ESM::CellId& id) +MWWorld::CellStore* MWWorld::Cells::getCell(const ESM::CellId& id) { if (id.mPaged) - return getExterior (id.mIndex.mX, id.mIndex.mY); + return getExterior(id.mIndex.mX, id.mIndex.mY); - return getInterior (id.mWorldspace); + return getInterior(id.mWorldspace); } -MWWorld::Ptr MWWorld::Cells::getPtr(std::string_view name, CellStore& cell, - bool searchInContainers) +MWWorld::Ptr MWWorld::Cells::getPtr(std::string_view name, CellStore& cell, bool searchInContainers) { - if (cell.getState()==CellStore::State_Unloaded) - cell.preload (); + if (cell.getState() == CellStore::State_Unloaded) + cell.preload(); - if (cell.getState()==CellStore::State_Preloaded) + if (cell.getState() == CellStore::State_Preloaded) { - if (cell.hasId (name)) + if (cell.hasId(name)) { - cell.load (); + cell.load(); } else return Ptr(); } - Ptr ptr = cell.search (name); + Ptr ptr = cell.search(name); if (!ptr.isEmpty() && MWWorld::CellStore::isAccessible(ptr.getRefData(), ptr.getCellRef())) return ptr; if (searchInContainers) - return cell.searchInContainer (name); + return cell.searchInContainer(name); return Ptr(); } -MWWorld::Ptr MWWorld::Cells::getPtr (const std::string& name) +MWWorld::Ptr MWWorld::Cells::getPtr(const std::string& name) { // First check the cache - for (IdCache::iterator iter (mIdCache.begin()); iter!=mIdCache.end(); ++iter) - if (iter->first==name && iter->second) + for (IdCache::iterator iter(mIdCache.begin()); iter != mIdCache.end(); ++iter) + if (iter->first == name && iter->second) { - Ptr ptr = getPtr (name, *iter->second); + Ptr ptr = getPtr(name, *iter->second); if (!ptr.isEmpty()) return ptr; } @@ -268,30 +266,29 @@ MWWorld::Ptr MWWorld::Cells::getPtr (const std::string& name) // Search in reverse, this is a workaround for an ambiguous chargen_plank reference in the vanilla game. // there is one at -22,16 and one at -2,-9, the latter should be used. for (std::map, CellStore>::reverse_iterator iter = mExteriors.rbegin(); - iter!=mExteriors.rend(); ++iter) + iter != mExteriors.rend(); ++iter) { - Ptr ptr = getPtrAndCache (name, iter->second); + Ptr ptr = getPtrAndCache(name, iter->second); if (!ptr.isEmpty()) return ptr; } - for (std::map::iterator iter = mInteriors.begin(); - iter!=mInteriors.end(); ++iter) + for (std::map::iterator iter = mInteriors.begin(); iter != mInteriors.end(); ++iter) { - Ptr ptr = getPtrAndCache (name, iter->second); + Ptr ptr = getPtrAndCache(name, iter->second); if (!ptr.isEmpty()) return ptr; } // Now try the other cells - const MWWorld::Store &cells = mStore.get(); + const MWWorld::Store& cells = mStore.get(); MWWorld::Store::iterator iter; for (iter = cells.extBegin(); iter != cells.extEnd(); ++iter) { - CellStore *cellStore = getCellStore (&(*iter)); + CellStore* cellStore = getCellStore(&(*iter)); - Ptr ptr = getPtrAndCache (name, *cellStore); + Ptr ptr = getPtrAndCache(name, *cellStore); if (!ptr.isEmpty()) return ptr; @@ -299,9 +296,9 @@ MWWorld::Ptr MWWorld::Cells::getPtr (const std::string& name) for (iter = cells.intBegin(); iter != cells.intEnd(); ++iter) { - CellStore *cellStore = getCellStore (&(*iter)); + CellStore* cellStore = getCellStore(&(*iter)); - Ptr ptr = getPtrAndCache (name, *cellStore); + Ptr ptr = getPtrAndCache(name, *cellStore); if (!ptr.isEmpty()) return ptr; @@ -311,7 +308,7 @@ MWWorld::Ptr MWWorld::Cells::getPtr (const std::string& name) return Ptr(); } -MWWorld::Ptr MWWorld::Cells::getPtr (const std::string& id, const ESM::RefNum& refNum) +MWWorld::Ptr MWWorld::Cells::getPtr(const std::string& id, const ESM::RefNum& refNum) { for (auto& pair : mInteriors) { @@ -344,26 +341,26 @@ MWWorld::Ptr MWWorld::Cells::getPtr(CellStore& cellStore, const std::string& id, void MWWorld::Cells::getExteriorPtrs(std::string_view name, std::vector& out) { - const MWWorld::Store &cells = mStore.get(); + const MWWorld::Store& cells = mStore.get(); for (MWWorld::Store::iterator iter = cells.extBegin(); iter != cells.extEnd(); ++iter) { - CellStore *cellStore = getCellStore (&(*iter)); + CellStore* cellStore = getCellStore(&(*iter)); - Ptr ptr = getPtrAndCache (name, *cellStore); + Ptr ptr = getPtrAndCache(name, *cellStore); if (!ptr.isEmpty()) out.push_back(ptr); } } -void MWWorld::Cells::getInteriorPtrs(const std::string &name, std::vector &out) +void MWWorld::Cells::getInteriorPtrs(const std::string& name, std::vector& out) { - const MWWorld::Store &cells = mStore.get(); + const MWWorld::Store& cells = mStore.get(); for (MWWorld::Store::iterator iter = cells.intBegin(); iter != cells.intEnd(); ++iter) { - CellStore *cellStore = getCellStore (&(*iter)); + CellStore* cellStore = getCellStore(&(*iter)); - Ptr ptr = getPtrAndCache (name, *cellStore); + Ptr ptr = getPtrAndCache(name, *cellStore); if (!ptr.isEmpty()) out.push_back(ptr); @@ -373,7 +370,7 @@ void MWWorld::Cells::getInteriorPtrs(const std::string &name, std::vector MWWorld::Cells::getAll(const std::string& id) { PtrCollector visitor; - if(forEachInStore(id, visitor, mInteriors)) + if (forEachInStore(id, visitor, mInteriors)) forEachInStore(id, visitor, mExteriors); return visitor.mPtrs; } @@ -382,34 +379,31 @@ int MWWorld::Cells::countSavedGameRecords() const { int count = 0; - for (std::map::const_iterator iter (mInteriors.begin()); - iter!=mInteriors.end(); ++iter) + for (std::map::const_iterator iter(mInteriors.begin()); iter != mInteriors.end(); ++iter) if (iter->second.hasState()) ++count; - for (std::map, CellStore>::const_iterator iter (mExteriors.begin()); - iter!=mExteriors.end(); ++iter) + for (std::map, CellStore>::const_iterator iter(mExteriors.begin()); iter != mExteriors.end(); + ++iter) if (iter->second.hasState()) ++count; return count; } -void MWWorld::Cells::write (ESM::ESMWriter& writer, Loading::Listener& progress) const +void MWWorld::Cells::write(ESM::ESMWriter& writer, Loading::Listener& progress) const { - for (std::map, CellStore>::iterator iter (mExteriors.begin()); - iter!=mExteriors.end(); ++iter) + for (std::map, CellStore>::iterator iter(mExteriors.begin()); iter != mExteriors.end(); ++iter) if (iter->second.hasState()) { - writeCell (writer, iter->second); + writeCell(writer, iter->second); progress.increaseProgress(); } - for (std::map::iterator iter (mInteriors.begin()); - iter!=mInteriors.end(); ++iter) + for (std::map::iterator iter(mInteriors.begin()); iter != mInteriors.end(); ++iter) if (iter->second.hasState()) { - writeCell (writer, iter->second); + writeCell(writer, iter->second); progress.increaseProgress(); } } @@ -437,40 +431,40 @@ public: } }; -bool MWWorld::Cells::readRecord (ESM::ESMReader& reader, uint32_t type, - const std::map& contentFileMap) +bool MWWorld::Cells::readRecord(ESM::ESMReader& reader, uint32_t type, const std::map& contentFileMap) { - if (type==ESM::REC_CSTA) + if (type == ESM::REC_CSTA) { ESM::CellState state; - state.mId.load (reader); + state.mId.load(reader); - CellStore *cellStore = nullptr; + CellStore* cellStore = nullptr; try { - cellStore = getCell (state.mId); + cellStore = getCell(state.mId); } catch (...) { // silently drop cells that don't exist anymore - Log(Debug::Warning) << "Warning: Dropping state for cell " << state.mId.mWorldspace << " (cell no longer exists)"; + Log(Debug::Warning) << "Warning: Dropping state for cell " << state.mId.mWorldspace + << " (cell no longer exists)"; reader.skipRecord(); return true; } - state.load (reader); - cellStore->loadState (state); + state.load(reader); + cellStore->loadState(state); if (state.mHasFogOfWar) cellStore->readFog(reader); - if (cellStore->getState()!=CellStore::State_Loaded) - cellStore->load (); + if (cellStore->getState() != CellStore::State_Loaded) + cellStore->load(); GetCellStoreCallback callback(*this); - cellStore->readReferences (reader, contentFileMap, &callback); + cellStore->readReferences(reader, contentFileMap, &callback); return true; } diff --git a/apps/openmw/mwworld/cells.hpp b/apps/openmw/mwworld/cells.hpp index 65567912f3..d35ecc9b79 100644 --- a/apps/openmw/mwworld/cells.hpp +++ b/apps/openmw/mwworld/cells.hpp @@ -1,8 +1,8 @@ #ifndef GAME_MWWORLD_CELLS_H #define GAME_MWWORLD_CELLS_H -#include #include +#include #include #include "ptr.hpp" @@ -29,67 +29,65 @@ namespace MWWorld /// \brief Cell container class Cells { - typedef std::vector > IdCache; - const MWWorld::ESMStore& mStore; - ESM::ReadersCache& mReaders; - mutable std::map mInteriors; - mutable std::map, CellStore> mExteriors; - IdCache mIdCache; - std::size_t mIdCacheIndex; - - Cells (const Cells&); - Cells& operator= (const Cells&); + typedef std::vector> IdCache; + const MWWorld::ESMStore& mStore; + ESM::ReadersCache& mReaders; + mutable std::map mInteriors; + mutable std::map, CellStore> mExteriors; + IdCache mIdCache; + std::size_t mIdCacheIndex; - CellStore *getCellStore (const ESM::Cell *cell); + Cells(const Cells&); + Cells& operator=(const Cells&); - Ptr getPtrAndCache(std::string_view name, CellStore& cellStore); + CellStore* getCellStore(const ESM::Cell* cell); - Ptr getPtr(CellStore& cellStore, const std::string& id, const ESM::RefNum& refNum); + Ptr getPtrAndCache(std::string_view name, CellStore& cellStore); - void writeCell (ESM::ESMWriter& writer, CellStore& cell) const; + Ptr getPtr(CellStore& cellStore, const std::string& id, const ESM::RefNum& refNum); - public: + void writeCell(ESM::ESMWriter& writer, CellStore& cell) const; - void clear(); + public: + void clear(); - explicit Cells(const MWWorld::ESMStore& store, ESM::ReadersCache& reader); + explicit Cells(const MWWorld::ESMStore& store, ESM::ReadersCache& reader); - CellStore *getExterior (int x, int y); + CellStore* getExterior(int x, int y); - CellStore* getInterior(std::string_view name); + CellStore* getInterior(std::string_view name); - CellStore *getCell (const ESM::CellId& id); + CellStore* getCell(const ESM::CellId& id); - Ptr getPtr(std::string_view name, CellStore& cellStore, bool searchInContainers = false); - ///< \param searchInContainers Only affect loaded cells. - /// @note name must be lower case + Ptr getPtr(std::string_view name, CellStore& cellStore, bool searchInContainers = false); + ///< \param searchInContainers Only affect loaded cells. + /// @note name must be lower case - /// @note name must be lower case - Ptr getPtr (const std::string& name); + /// @note name must be lower case + Ptr getPtr(const std::string& name); - Ptr getPtr(const std::string& id, const ESM::RefNum& refNum); + Ptr getPtr(const std::string& id, const ESM::RefNum& refNum); - void rest (double hours); - void recharge (float duration); + void rest(double hours); + void recharge(float duration); - /// Get all Ptrs referencing \a name in exterior cells - /// @note Due to the current implementation of getPtr this only supports one Ptr per cell. - /// @note name must be lower case - void getExteriorPtrs(std::string_view name, std::vector& out); + /// Get all Ptrs referencing \a name in exterior cells + /// @note Due to the current implementation of getPtr this only supports one Ptr per cell. + /// @note name must be lower case + void getExteriorPtrs(std::string_view name, std::vector& out); - /// Get all Ptrs referencing \a name in interior cells - /// @note Due to the current implementation of getPtr this only supports one Ptr per cell. - /// @note name must be lower case - void getInteriorPtrs (const std::string& name, std::vector& out); + /// Get all Ptrs referencing \a name in interior cells + /// @note Due to the current implementation of getPtr this only supports one Ptr per cell. + /// @note name must be lower case + void getInteriorPtrs(const std::string& name, std::vector& out); - std::vector getAll(const std::string& id); + std::vector getAll(const std::string& id); - int countSavedGameRecords() const; + int countSavedGameRecords() const; - void write (ESM::ESMWriter& writer, Loading::Listener& progress) const; + void write(ESM::ESMWriter& writer, Loading::Listener& progress) const; - bool readRecord (ESM::ESMReader& reader, uint32_t type, - const std::map& contentFileMap); + bool readRecord(ESM::ESMReader& reader, uint32_t type, const std::map& contentFileMap); }; } diff --git a/apps/openmw/mwworld/cellstore.cpp b/apps/openmw/mwworld/cellstore.cpp index bfd7cf966c..c4430fbc2a 100644 --- a/apps/openmw/mwworld/cellstore.cpp +++ b/apps/openmw/mwworld/cellstore.cpp @@ -5,41 +5,41 @@ #include -#include -#include #include #include -#include -#include -#include +#include #include -#include -#include -#include #include +#include #include -#include +#include +#include +#include #include #include #include #include +#include #include #include #include #include #include +#include #include #include #include #include +#include +#include #include #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include "../mwbase/environment.hpp" #include "../mwbase/luamanager.hpp" @@ -49,11 +49,11 @@ #include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/recharge.hpp" -#include "ptr.hpp" -#include "esmloader.hpp" -#include "esmstore.hpp" #include "class.hpp" #include "containerstore.hpp" +#include "esmloader.hpp" +#include "esmstore.hpp" +#include "ptr.hpp" namespace { @@ -90,19 +90,18 @@ namespace using StateType = ESM::CreatureLevListState; }; - template + template MWWorld::Ptr searchInContainerList(MWWorld::CellRefList& containerList, std::string_view id) { - for (typename MWWorld::CellRefList::List::iterator iter (containerList.mList.begin()); - iter!=containerList.mList.end(); ++iter) + for (typename MWWorld::CellRefList::List::iterator iter(containerList.mList.begin()); + iter != containerList.mList.end(); ++iter) { - MWWorld::Ptr container (&*iter, nullptr); + MWWorld::Ptr container(&*iter, nullptr); if (container.getRefData().getCustomData() == nullptr) continue; - MWWorld::Ptr ptr = - container.getClass().getContainerStore (container).search (id); + MWWorld::Ptr ptr = container.getClass().getContainerStore(container).search(id); if (!ptr.isEmpty()) return ptr; @@ -111,100 +110,99 @@ namespace return MWWorld::Ptr(); } - template - MWWorld::Ptr searchViaActorId (MWWorld::CellRefList& actorList, int actorId, - MWWorld::CellStore *cell, const std::map& toIgnore) + template + MWWorld::Ptr searchViaActorId(MWWorld::CellRefList& actorList, int actorId, MWWorld::CellStore* cell, + const std::map& toIgnore) { - for (typename MWWorld::CellRefList::List::iterator iter (actorList.mList.begin()); - iter!=actorList.mList.end(); ++iter) + for (typename MWWorld::CellRefList::List::iterator iter(actorList.mList.begin()); + iter != actorList.mList.end(); ++iter) { - MWWorld::Ptr actor (&*iter, cell); + MWWorld::Ptr actor(&*iter, cell); if (toIgnore.find(&*iter) != toIgnore.end()) continue; - if (actor.getClass().getCreatureStats (actor).matchesActorId (actorId) && actor.getRefData().getCount() > 0) + if (actor.getClass().getCreatureStats(actor).matchesActorId(actorId) && actor.getRefData().getCount() > 0) return actor; } return MWWorld::Ptr(); } - template - void writeReferenceCollection (ESM::ESMWriter& writer, - const MWWorld::CellRefList& collection) + template + void writeReferenceCollection(ESM::ESMWriter& writer, const MWWorld::CellRefList& collection) { if (!collection.mList.empty()) { // references - for (typename MWWorld::CellRefList::List::const_iterator - iter (collection.mList.begin()); - iter!=collection.mList.end(); ++iter) + for (typename MWWorld::CellRefList::List::const_iterator iter(collection.mList.begin()); + iter != collection.mList.end(); ++iter) { if (!iter->mData.hasChanged() && !iter->mRef.hasChanged() && iter->mRef.hasContentFile()) { // Reference that came from a content file and has not been changed -> ignore continue; } - if (iter->mData.getCount()==0 && !iter->mRef.hasContentFile()) + if (iter->mData.getCount() == 0 && !iter->mRef.hasContentFile()) { // Deleted reference that did not come from a content file -> ignore continue; } using StateType = typename RecordToState::StateType; StateType state; - iter->save (state); + iter->save(state); // recordId currently unused - writer.writeHNT ("OBJE", collection.mList.front().mBase->sRecordId); + writer.writeHNT("OBJE", collection.mList.front().mBase->sRecordId); - state.save (writer); + state.save(writer); } } } - template + template void fixRestockingImpl(const T* base, RecordType& state) { // Workaround for old saves not containing negative quantities - for(const auto& baseItem : base->mInventory.mList) + for (const auto& baseItem : base->mInventory.mList) { - if(baseItem.mCount < 0) + if (baseItem.mCount < 0) { - for(auto& item : state.mInventory.mItems) + for (auto& item : state.mInventory.mItems) { - if(item.mCount > 0 && Misc::StringUtils::ciEqual(baseItem.mItem, item.mRef.mRefID)) + if (item.mCount > 0 && Misc::StringUtils::ciEqual(baseItem.mItem, item.mRef.mRefID)) item.mCount = -item.mCount; } } } } - template + template void fixRestocking(const T* base, RecordType& state) - {} + { + } - template<> + template <> void fixRestocking<>(const ESM::Creature* base, ESM::CreatureState& state) { fixRestockingImpl(base, state); } - template<> + template <> void fixRestocking<>(const ESM::NPC* base, ESM::NpcState& state) { fixRestockingImpl(base, state); } - template<> + template <> void fixRestocking<>(const ESM::Container* base, ESM::ContainerState& state) { fixRestockingImpl(base, state); } - template - void readReferenceCollection (ESM::ESMReader& reader, - MWWorld::CellRefList& collection, const ESM::CellRef& cref, const std::map& contentFileMap, MWWorld::CellStore* cellstore) + template + void readReferenceCollection(ESM::ESMReader& reader, MWWorld::CellRefList& collection, const ESM::CellRef& cref, + const std::map& contentFileMap, MWWorld::CellStore* cellstore) { const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); @@ -216,19 +214,18 @@ namespace // If the reference came from a content file, make sure this content file is loaded if (state.mRef.mRefNum.hasContentFile()) { - std::map::const_iterator iter = - contentFileMap.find (state.mRef.mRefNum.mContentFile); + std::map::const_iterator iter = contentFileMap.find(state.mRef.mRefNum.mContentFile); - if (iter==contentFileMap.end()) + if (iter == contentFileMap.end()) return; // content file has been removed -> skip state.mRef.mRefNum.mContentFile = iter->second; } - if (!MWWorld::LiveCellRef::checkState (state)) + if (!MWWorld::LiveCellRef::checkState(state)) return; // not valid anymore with current content files -> skip - const T *record = esmStore.get().search (state.mRef.mRefID); + const T* record = esmStore.get().search(state.mRef.mRefID); if (!record) return; @@ -242,7 +239,7 @@ namespace else if constexpr (std::is_same_v) MWWorld::convertMagicEffects(state.mCreatureStats, state.mInventory, &state.mNpcStats); } - else if(state.mVersion < 20) + else if (state.mVersion < 20) { if constexpr (std::is_same_v || std::is_same_v) MWWorld::convertStats(state.mCreatureStats); @@ -250,17 +247,20 @@ namespace if (state.mRef.mRefNum.hasContentFile()) { - for (typename MWWorld::CellRefList::List::iterator iter (collection.mList.begin()); - iter!=collection.mList.end(); ++iter) - if (iter->mRef.getRefNum()==state.mRef.mRefNum && iter->mRef.getRefId() == state.mRef.mRefID) + for (typename MWWorld::CellRefList::List::iterator iter(collection.mList.begin()); + iter != collection.mList.end(); ++iter) + if (iter->mRef.getRefNum() == state.mRef.mRefNum && iter->mRef.getRefId() == state.mRef.mRefID) { // overwrite existing reference float oldscale = iter->mRef.getScale(); - iter->load (state); - const ESM::Position & oldpos = iter->mRef.getPosition(); - const ESM::Position & newpos = iter->mData.getPosition(); + iter->load(state); + const ESM::Position& oldpos = iter->mRef.getPosition(); + const ESM::Position& newpos = iter->mData.getPosition(); const MWWorld::Ptr ptr(&*iter, cellstore); - if ((oldscale != iter->mRef.getScale() || oldpos.asVec3() != newpos.asVec3() || oldpos.rot[0] != newpos.rot[0] || oldpos.rot[1] != newpos.rot[1] || oldpos.rot[2] != newpos.rot[2]) && !ptr.getClass().isActor()) + if ((oldscale != iter->mRef.getScale() || oldpos.asVec3() != newpos.asVec3() + || oldpos.rot[0] != newpos.rot[0] || oldpos.rot[1] != newpos.rot[1] + || oldpos.rot[2] != newpos.rot[2]) + && !ptr.getClass().isActor()) MWBase::Environment::get().getWorld()->moveObject(ptr, newpos.asVec3()); if (!iter->mData.isEnabled()) { @@ -272,21 +272,22 @@ namespace return; } - Log(Debug::Warning) << "Warning: Dropping reference to " << state.mRef.mRefID << " (invalid content file link)"; + Log(Debug::Warning) << "Warning: Dropping reference to " << state.mRef.mRefID + << " (invalid content file link)"; return; } // new reference - MWWorld::LiveCellRef ref (record); - ref.load (state); - collection.mList.push_back (ref); + MWWorld::LiveCellRef ref(record); + ref.load(state); + collection.mList.push_back(ref); MWWorld::LiveCellRefBase* base = &collection.mList.back(); MWBase::Environment::get().getLuaManager()->registerObject(MWWorld::Ptr(base, cellstore)); } - //this function allows us to link a CellRefList to the associated recNameInt, and apply a function - template + // this function allows us to link a CellRefList to the associated recNameInt, and apply a function + template static void recNameSwitcher(MWWorld::CellRefList& store, ESM::RecNameInts recnNameInt, Callable&& f) { if (RecordType::sRecordId == recnNameInt) @@ -296,15 +297,14 @@ namespace } // helper function for forEachInternal - template - bool forEachImp (Visitor& visitor, List& list, MWWorld::CellStore* cellStore) + template + bool forEachImp(Visitor& visitor, List& list, MWWorld::CellStore* cellStore) { - for (typename List::List::iterator iter (list.mList.begin()); iter!=list.mList.end(); - ++iter) + for (typename List::List::iterator iter(list.mList.begin()); iter != list.mList.end(); ++iter) { if (!MWWorld::CellStore::isAccessible(iter->mData, iter->mRef)) continue; - if (!visitor (MWWorld::Ptr(&*iter, cellStore))) + if (!visitor(MWWorld::Ptr(&*iter, cellStore))) return false; } return true; @@ -315,9 +315,9 @@ namespace MWWorld { struct CellStoreImp { - CellStoreTuple mRefLists; + CellStoreTuple mRefLists; - template + template static void assignStoreToIndex(CellStore& stores, CellRefList& refList) { const std::size_t storeIndex = CellStore::getTypeIndex(); @@ -329,30 +329,31 @@ namespace MWWorld stores.mCellRefLists[storeIndex] = &refList; } - - // listing only objects owned by this cell. Internal use only, you probably want to use forEach() so that moved objects are accounted for. - template - static bool forEachInternal (Visitor& visitor, MWWorld::CellStore& cellStore) + // listing only objects owned by this cell. Internal use only, you probably want to use forEach() so that moved + // objects are accounted for. + template + static bool forEachInternal(Visitor& visitor, MWWorld::CellStore& cellStore) { bool returnValue = true; - Misc::tupleForEach(cellStore.mCellStoreImp->mRefLists, [&visitor, &returnValue, &cellStore](auto& store) { returnValue = returnValue && forEachImp(visitor, store, &cellStore); }); + Misc::tupleForEach(cellStore.mCellStoreImp->mRefLists, [&visitor, &returnValue, &cellStore](auto& store) { + returnValue = returnValue && forEachImp(visitor, store, &cellStore); + }); return returnValue; } }; template - void CellRefList::load(ESM::CellRef &ref, bool deleted, const MWWorld::ESMStore &esmStore) + void CellRefList::load(ESM::CellRef& ref, bool deleted, const MWWorld::ESMStore& esmStore) { - const MWWorld::Store &store = esmStore.get(); + const MWWorld::Store& store = esmStore.get(); - if (const X *ptr = store.search (ref.mRefID)) + if (const X* ptr = store.search(ref.mRefID)) { - typename std::list::iterator iter = - std::find(mList.begin(), mList.end(), ref.mRefNum); + typename std::list::iterator iter = std::find(mList.begin(), mList.end(), ref.mRefNum); - LiveRef liveCellRef (ref, ptr); + LiveRef liveCellRef(ref, ptr); if (deleted) liveCellRef.mData.setDeletedByContentFile(true); @@ -360,22 +361,22 @@ namespace MWWorld if (iter != mList.end()) *iter = liveCellRef; else - mList.push_back (liveCellRef); + mList.push_back(liveCellRef); } else { - Log(Debug::Warning) - << "Warning: could not resolve cell reference '" << ref.mRefID << "'" - << " (dropping reference)"; + Log(Debug::Warning) << "Warning: could not resolve cell reference '" << ref.mRefID << "'" + << " (dropping reference)"; } } - template bool operator==(const LiveCellRef& ref, int pRefnum) + template + bool operator==(const LiveCellRef& ref, int pRefnum) { return (ref.mRef.mRefnum == pRefnum); } - Ptr CellStore::getCurrentPtr(LiveCellRefBase *ref) + Ptr CellStore::getCurrentPtr(LiveCellRefBase* ref) { MovedRefTracker::iterator found = mMovedToAnotherCell.find(ref); if (found != mMovedToAnotherCell.end()) @@ -383,7 +384,7 @@ namespace MWWorld return Ptr(ref, this); } - void CellStore::moveFrom(const Ptr &object, CellStore *from) + void CellStore::moveFrom(const Ptr& object, CellStore* from) { if (mState != State_Loaded) load(); @@ -393,7 +394,7 @@ namespace MWWorld if (found != mMovedToAnotherCell.end()) { // A cell we had previously moved an object to is returning it to us. - assert (found->second == from); + assert(found->second == from); mMovedToAnotherCell.erase(found); } else @@ -403,14 +404,15 @@ namespace MWWorld updateMergedRefs(); } - MWWorld::Ptr CellStore::moveTo(const Ptr &object, CellStore *cellToMoveTo) + MWWorld::Ptr CellStore::moveTo(const Ptr& object, CellStore* cellToMoveTo) { if (cellToMoveTo == this) throw std::runtime_error("moveTo: object is already in this cell"); // We assume that *this is in State_Loaded since we could hardly have reference to a live object otherwise. if (mState != State_Loaded) - throw std::runtime_error("moveTo: can't move object from a non-loaded cell (how did you get this object anyway?)"); + throw std::runtime_error( + "moveTo: can't move object from a non-loaded cell (how did you get this object anyway?)"); // Ensure that the object actually exists in the cell if (searchViaRefNum(object.getCellRef().getRefNum()).isEmpty()) @@ -424,7 +426,7 @@ namespace MWWorld // Special case - object didn't originate in this cell // Move it back to its original cell first CellStore* originalCell = found->second; - assert (originalCell != this); + assert(originalCell != this); originalCell->moveFrom(object, this); mMovedHere.erase(found); @@ -448,15 +450,16 @@ namespace MWWorld struct MergeVisitor { - MergeVisitor(std::vector& mergeTo, const std::map& movedHere, - const std::map& movedToAnotherCell) + MergeVisitor(std::vector& mergeTo, + const std::map& movedHere, + const std::map& movedToAnotherCell) : mMergeTo(mergeTo) , mMovedHere(movedHere) , mMovedToAnotherCell(movedToAnotherCell) { } - bool operator() (const MWWorld::Ptr& ptr) + bool operator()(const MWWorld::Ptr& ptr) { if (mMovedToAnotherCell.find(ptr.getBase()) != mMovedToAnotherCell.end()) return true; @@ -466,7 +469,7 @@ namespace MWWorld void merge() { - for (const auto & [base, _] : mMovedHere) + for (const auto& [base, _] : mMovedHere) mMergeTo.push_back(base); } @@ -507,14 +510,14 @@ namespace MWWorld , mCellStoreImp(std::make_unique()) , mRechargingItemsUpToDate(false) { - std::apply([this](auto& ...x) {(CellStoreImp::assignStoreToIndex(*this, x), ...); }, mCellStoreImp->mRefLists); + std::apply([this](auto&... x) { (CellStoreImp::assignStoreToIndex(*this, x), ...); }, mCellStoreImp->mRefLists); mWaterLevel = cell->mWater; } CellStore::~CellStore() = default; CellStore::CellStore(CellStore&&) = default; - const ESM::Cell *CellStore::getCell() const + const ESM::Cell* CellStore::getCell() const { return mCell; } @@ -524,7 +527,7 @@ namespace MWWorld return mState; } - const std::vector &CellStore::getPreloadedIds() const + const std::vector& CellStore::getPreloadedIds() const { return mIds; } @@ -536,13 +539,13 @@ namespace MWWorld bool CellStore::hasId(std::string_view id) const { - if (mState==State_Unloaded) + if (mState == State_Unloaded) return false; - if (mState==State_Preloaded) - return std::binary_search (mIds.begin(), mIds.end(), id); + if (mState == State_Preloaded) + return std::binary_search(mIds.begin(), mIds.end(), id); - return searchConst (id).isEmpty(); + return searchConst(id).isEmpty(); } template @@ -577,20 +580,20 @@ namespace MWWorld return searchVisitor.mFound; } - Ptr CellStore::searchViaActorId (int id) + Ptr CellStore::searchViaActorId(int id) { - if (Ptr ptr = ::searchViaActorId (get(), id, this, mMovedToAnotherCell)) + if (Ptr ptr = ::searchViaActorId(get(), id, this, mMovedToAnotherCell)) return ptr; - if (Ptr ptr = ::searchViaActorId (get(), id, this, mMovedToAnotherCell)) + if (Ptr ptr = ::searchViaActorId(get(), id, this, mMovedToAnotherCell)) return ptr; for (const auto& [base, _] : mMovedHere) { - MWWorld::Ptr actor (base, this); + MWWorld::Ptr actor(base, this); if (!actor.getClass().isActor()) continue; - if (actor.getClass().getCreatureStats (actor).matchesActorId (id) && actor.getRefData().getCount() > 0) + if (actor.getClass().getCreatureStats(actor).matchesActorId(id) && actor.getRefData().getCount() > 0) return actor; } @@ -600,8 +603,12 @@ namespace MWWorld class RefNumSearchVisitor { const ESM::RefNum& mRefNum; + public: - RefNumSearchVisitor(const ESM::RefNum& refNum) : mRefNum(refNum) {} + RefNumSearchVisitor(const ESM::RefNum& refNum) + : mRefNum(refNum) + { + } Ptr mFound; @@ -616,7 +623,7 @@ namespace MWWorld } }; - Ptr CellStore::searchViaRefNum (const ESM::RefNum& refNum) + Ptr CellStore::searchViaRefNum(const ESM::RefNum& refNum) { RefNumSearchVisitor searchVisitor(refNum); forEach(searchVisitor); @@ -630,7 +637,7 @@ namespace MWWorld return mWaterLevel; } - void CellStore::setWaterLevel (float level) + void CellStore::setWaterLevel(float level) { mWaterLevel = level; mHasState = true; @@ -641,24 +648,24 @@ namespace MWWorld return mMergedRefs.size(); } - void CellStore::load () + void CellStore::load() { - if (mState!=State_Loaded) + if (mState != State_Loaded) { - if (mState==State_Preloaded) + if (mState == State_Preloaded) mIds.clear(); - loadRefs (); + loadRefs(); mState = State_Loaded; } } - void CellStore::preload () + void CellStore::preload() { - if (mState==State_Unloaded) + if (mState == State_Unloaded) { - listRefs (); + listRefs(); mState = State_Preloaded; } @@ -666,7 +673,7 @@ namespace MWWorld void CellStore::listRefs() { - assert (mCell); + assert(mCell); if (mCell->mContextList.empty()) return; // this is a dynamically generated cell -> skipping. @@ -688,15 +695,17 @@ namespace MWWorld cMRef.mRefNum.mIndex = 0; bool deleted = false; bool moved = false; - while (ESM::Cell::getNextRef(*reader, ref, deleted, cMRef, moved, ESM::Cell::GetNextRefMode::LoadOnlyNotMoved)) + while (ESM::Cell::getNextRef( + *reader, ref, deleted, cMRef, moved, ESM::Cell::GetNextRefMode::LoadOnlyNotMoved)) { if (deleted || moved) continue; // Don't list reference if it was moved to a different cell. - ESM::MovedCellRefTracker::const_iterator iter = - std::find(mCell->mMovedRefs.begin(), mCell->mMovedRefs.end(), ref.mRefNum); - if (iter != mCell->mMovedRefs.end()) { + ESM::MovedCellRefTracker::const_iterator iter + = std::find(mCell->mMovedRefs.begin(), mCell->mMovedRefs.end(), ref.mRefNum); + if (iter != mCell->mMovedRefs.end()) + { continue; } @@ -706,23 +715,24 @@ namespace MWWorld } catch (std::exception& e) { - Log(Debug::Error) << "An error occurred listing references for cell " << getCell()->getDescription() << ": " << e.what(); + Log(Debug::Error) << "An error occurred listing references for cell " << getCell()->getDescription() + << ": " << e.what(); } } // List moved references, from separately tracked list. - for (const auto& [ref, deleted]: mCell->mLeasedRefs) + for (const auto& [ref, deleted] : mCell->mLeasedRefs) { if (!deleted) mIds.push_back(Misc::StringUtils::lowerCase(ref.mRefID)); } - std::sort (mIds.begin(), mIds.end()); + std::sort(mIds.begin(), mIds.end()); } void CellStore::loadRefs() { - assert (mCell); + assert(mCell); if (mCell->mContextList.empty()) return; // this is a dynamically generated cell -> skipping. @@ -747,34 +757,37 @@ namespace MWWorld cMRef.mRefNum.mIndex = 0; bool deleted = false; bool moved = false; - while (ESM::Cell::getNextRef(*reader, ref, deleted, cMRef, moved, ESM::Cell::GetNextRefMode::LoadOnlyNotMoved)) + while (ESM::Cell::getNextRef( + *reader, ref, deleted, cMRef, moved, ESM::Cell::GetNextRefMode::LoadOnlyNotMoved)) { if (moved) continue; // Don't load reference if it was moved to a different cell. - ESM::MovedCellRefTracker::const_iterator iter = - std::find(mCell->mMovedRefs.begin(), mCell->mMovedRefs.end(), ref.mRefNum); - if (iter != mCell->mMovedRefs.end()) { + ESM::MovedCellRefTracker::const_iterator iter + = std::find(mCell->mMovedRefs.begin(), mCell->mMovedRefs.end(), ref.mRefNum); + if (iter != mCell->mMovedRefs.end()) + { continue; } - loadRef (ref, deleted, refNumToID); + loadRef(ref, deleted, refNumToID); } } catch (std::exception& e) { - Log(Debug::Error) << "An error occurred loading references for cell " << getCell()->getDescription() << ": " << e.what(); + Log(Debug::Error) << "An error occurred loading references for cell " << getCell()->getDescription() + << ": " << e.what(); } } // Load moved references, from separately tracked list. for (const auto& leasedRef : mCell->mLeasedRefs) { - ESM::CellRef &ref = const_cast(leasedRef.first); + ESM::CellRef& ref = const_cast(leasedRef.first); bool deleted = leasedRef.second; - loadRef (ref, deleted, refNumToID); + loadRef(ref, deleted, refNumToID); } updateMergedRefs(); @@ -796,13 +809,13 @@ namespace MWWorld mHasState = true; - if (Ptr ptr = searchInContainerList (get(), id)) + if (Ptr ptr = searchInContainerList(get(), id)) return ptr; - if (Ptr ptr = searchInContainerList (get(), id)) + if (Ptr ptr = searchInContainerList(get(), id)) return ptr; - if (Ptr ptr = searchInContainerList (get(), id)) + if (Ptr ptr = searchInContainerList(get(), id)) return ptr; mHasState = oldState; @@ -810,9 +823,9 @@ namespace MWWorld return Ptr(); } - void CellStore::loadRef (ESM::CellRef& ref, bool deleted, std::map& refNumToID) + void CellStore::loadRef(ESM::CellRef& ref, bool deleted, std::map& refNumToID) { - Misc::StringUtils::lowerCaseInPlace (ref.mRefID); + Misc::StringUtils::lowerCaseInPlace(ref.mRefID); const MWWorld::ESMStore& store = mStore; @@ -825,8 +838,9 @@ namespace MWWorld ESM::RecNameInts foundType = static_cast(store.find(it->second)); if (foundType != 0) { - Misc::tupleForEach(this->mCellStoreImp->mRefLists, - [&ref, foundType](auto& x) { recNameSwitcher(x, foundType, [&ref](auto& storeIn) { storeIn.remove(ref.mRefNum); }); }); + Misc::tupleForEach(this->mCellStoreImp->mRefLists, [&ref, foundType](auto& x) { + recNameSwitcher(x, foundType, [&ref](auto& storeIn) { storeIn.remove(ref.mRefNum); }); + }); } } } @@ -835,16 +849,18 @@ namespace MWWorld bool handledType = false; if (foundType != 0) { - Misc::tupleForEach(this->mCellStoreImp->mRefLists, [&ref, &deleted, &store, foundType, &handledType](auto& x) { - recNameSwitcher(x, foundType, [&ref, &deleted, &store, &handledType](auto& storeIn) { - handledType = true; - storeIn.load(ref, deleted, store); + Misc::tupleForEach( + this->mCellStoreImp->mRefLists, [&ref, &deleted, &store, foundType, &handledType](auto& x) { + recNameSwitcher(x, foundType, [&ref, &deleted, &store, &handledType](auto& storeIn) { + handledType = true; + storeIn.load(ref, deleted, store); + }); }); - }); } else { - Log(Debug::Error) << "Cell reference '" + ref.mRefID + "' not found!"; return; + Log(Debug::Error) << "Cell reference '" + ref.mRefID + "' not found!"; + return; } if (!handledType) @@ -856,7 +872,7 @@ namespace MWWorld refNumToID[ref.mRefNum] = ref.mRefID; } - void CellStore::loadState (const ESM::CellState& state) + void CellStore::loadState(const ESM::CellState& state) { mHasState = true; @@ -866,7 +882,7 @@ namespace MWWorld mLastRespawn = MWWorld::TimeStamp(state.mLastRespawn); } - void CellStore::saveState (ESM::CellState& state) const + void CellStore::saveState(ESM::CellState& state) const { state.mId = mCell->getCellId(); @@ -877,7 +893,7 @@ namespace MWWorld state.mLastRespawn = mLastRespawn.toEsm(); } - void CellStore::writeFog(ESM::ESMWriter &writer) const + void CellStore::writeFog(ESM::ESMWriter& writer) const { if (mFogState.get()) { @@ -885,15 +901,16 @@ namespace MWWorld } } - void CellStore::readFog(ESM::ESMReader &reader) + void CellStore::readFog(ESM::ESMReader& reader) { mFogState = std::make_unique(); mFogState->load(reader); } - void CellStore::writeReferences (ESM::ESMWriter& writer) const + void CellStore::writeReferences(ESM::ESMWriter& writer) const { - Misc::tupleForEach(this->mCellStoreImp->mRefLists, [&writer](auto& cellRefList) { writeReferenceCollection(writer, cellRefList); }); + Misc::tupleForEach(this->mCellStoreImp->mRefLists, + [&writer](auto& cellRefList) { writeReferenceCollection(writer, cellRefList); }); for (const auto& [base, store] : mMovedToAnotherCell) { @@ -905,14 +922,15 @@ namespace MWWorld } } - void CellStore::readReferences (ESM::ESMReader& reader, const std::map& contentFileMap, GetCellStoreCallback* callback) + void CellStore::readReferences( + ESM::ESMReader& reader, const std::map& contentFileMap, GetCellStoreCallback* callback) { mHasState = true; - while (reader.isNextSub ("OBJE")) + while (reader.isNextSub("OBJE")) { unsigned int unused; - reader.getHT (unused); + reader.getHT(unused); // load the RefID first so we know what type of object it is ESM::CellRef cref; @@ -923,7 +941,7 @@ namespace MWWorld { Log(Debug::Warning) << "Dropping reference to '" << cref.mRefID << "' (object no longer exists)"; // Skip until the next OBJE or MVRF - while(reader.hasMoreSubs() && !reader.peekNextSub("OBJE") && !reader.peekNextSub("MVRF")) + while (reader.hasMoreSubs() && !reader.peekNextSub("OBJE") && !reader.peekNextSub("MVRF")) { reader.getSubName(); reader.skipHSub(); @@ -934,11 +952,13 @@ namespace MWWorld if (type != 0) { bool foundCorrespondingStore = false; - Misc::tupleForEach(this->mCellStoreImp->mRefLists, [&reader, this, &cref, &contentFileMap, &foundCorrespondingStore, type](auto&& x) { - recNameSwitcher(x, static_cast(type), [&reader, this, &cref, &contentFileMap, &foundCorrespondingStore](auto& store) { - foundCorrespondingStore = true; - readReferenceCollection(reader, store, cref, contentFileMap, this); - }); + Misc::tupleForEach(this->mCellStoreImp->mRefLists, + [&reader, this, &cref, &contentFileMap, &foundCorrespondingStore, type](auto&& x) { + recNameSwitcher(x, static_cast(type), + [&reader, this, &cref, &contentFileMap, &foundCorrespondingStore](auto& store) { + foundCorrespondingStore = true; + readReferenceCollection(reader, store, cref, contentFileMap, this); + }); }); if (!foundCorrespondingStore) @@ -969,7 +989,8 @@ namespace MWWorld Ptr movedRef = searchViaRefNum(refnum); if (movedRef.isEmpty()) { - Log(Debug::Warning) << "Warning: Dropping moved ref tag for " << refnum.mIndex << " (moved object no longer exists)"; + Log(Debug::Warning) << "Warning: Dropping moved ref tag for " << refnum.mIndex + << " (moved object no longer exists)"; continue; } @@ -978,9 +999,10 @@ namespace MWWorld if (otherCell == nullptr) { Log(Debug::Warning) << "Warning: Dropping moved ref tag for " << movedRef.getCellRef().getRefId() - << " (target cell " << movedTo.mWorldspace << " no longer exists). Reference moved back to its original location."; - // Note by dropping tag the object will automatically re-appear in its original cell, though potentially at inapproriate coordinates. - // Restore original coordinates: + << " (target cell " << movedTo.mWorldspace + << " no longer exists). Reference moved back to its original location."; + // Note by dropping tag the object will automatically re-appear in its original cell, though potentially + // at inapproriate coordinates. Restore original coordinates: movedRef.getRefData().setPosition(movedRef.getCellRef().getPosition()); continue; } @@ -996,14 +1018,14 @@ namespace MWWorld } } - bool operator== (const CellStore& left, const CellStore& right) + bool operator==(const CellStore& left, const CellStore& right) { - return left.getCell()->getCellId()==right.getCell()->getCellId(); + return left.getCell()->getCellId() == right.getCell()->getCellId(); } - bool operator!= (const CellStore& left, const CellStore& right) + bool operator!=(const CellStore& left, const CellStore& right) { - return !(left==right); + return !(left == right); } void CellStore::setFog(std::unique_ptr&& fog) @@ -1019,11 +1041,15 @@ namespace MWWorld void clearCorpse(const MWWorld::Ptr& ptr) { const MWMechanics::CreatureStats& creatureStats = ptr.getClass().getCreatureStats(ptr); - static const float fCorpseClearDelay = MWBase::Environment::get().getWorld()->getStore().get().find("fCorpseClearDelay")->mValue.getFloat(); - if (creatureStats.isDead() && - creatureStats.isDeathAnimationFinished() && - !ptr.getClass().isPersistent(ptr) && - creatureStats.getTimeOfDeath() + fCorpseClearDelay <= MWBase::Environment::get().getWorld()->getTimeStamp()) + static const float fCorpseClearDelay = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("fCorpseClearDelay") + ->mValue.getFloat(); + if (creatureStats.isDead() && creatureStats.isDeathAnimationFinished() && !ptr.getClass().isPersistent(ptr) + && creatureStats.getTimeOfDeath() + fCorpseClearDelay + <= MWBase::Environment::get().getWorld()->getTimeStamp()) { MWBase::Environment::get().getWorld()->deleteObject(ptr); } @@ -1033,7 +1059,8 @@ namespace MWWorld { if (mState == State_Loaded) { - for (CellRefList::List::iterator it (get().mList.begin()); it!=get().mList.end(); ++it) + for (CellRefList::List::iterator it(get().mList.begin()); + it != get().mList.end(); ++it) { Ptr ptr = getCurrentPtr(&*it); if (!ptr.isEmpty() && ptr.getRefData().getCount() > 0) @@ -1041,7 +1068,8 @@ namespace MWWorld MWBase::Environment::get().getMechanicsManager()->restoreDynamicStats(ptr, hours, true); } } - for (CellRefList::List::iterator it (get().mList.begin()); it!=get().mList.end(); ++it) + for (CellRefList::List::iterator it(get().mList.begin()); + it != get().mList.end(); ++it) { Ptr ptr = getCurrentPtr(&*it); if (!ptr.isEmpty() && ptr.getRefData().getCount() > 0) @@ -1059,7 +1087,8 @@ namespace MWWorld if (mState == State_Loaded) { - for (CellRefList::List::iterator it (get().mList.begin()); it!=get().mList.end(); ++it) + for (CellRefList::List::iterator it(get().mList.begin()); + it != get().mList.end(); ++it) { Ptr ptr = getCurrentPtr(&*it); if (!ptr.isEmpty() && ptr.getRefData().getCount() > 0) @@ -1067,7 +1096,8 @@ namespace MWWorld ptr.getClass().getContainerStore(ptr).rechargeItems(duration); } } - for (CellRefList::List::iterator it (get().mList.begin()); it!=get().mList.end(); ++it) + for (CellRefList::List::iterator it(get().mList.begin()); + it != get().mList.end(); ++it) { Ptr ptr = getCurrentPtr(&*it); if (!ptr.isEmpty() && ptr.getRefData().getCount() > 0) @@ -1075,11 +1105,12 @@ namespace MWWorld ptr.getClass().getContainerStore(ptr).rechargeItems(duration); } } - for (CellRefList::List::iterator it (get().mList.begin()); it!=get().mList.end(); ++it) + for (CellRefList::List::iterator it(get().mList.begin()); + it != get().mList.end(); ++it) { Ptr ptr = getCurrentPtr(&*it); if (!ptr.isEmpty() && ptr.getRefData().getCustomData() != nullptr && ptr.getRefData().getCount() > 0 - && ptr.getClass().getContainerStore(ptr).isResolved()) + && ptr.getClass().getContainerStore(ptr).isResolved()) { ptr.getClass().getContainerStore(ptr).rechargeItems(duration); } @@ -1093,30 +1124,39 @@ namespace MWWorld { if (mState == State_Loaded) { - static const int iMonthsToRespawn = MWBase::Environment::get().getWorld()->getStore().get().find("iMonthsToRespawn")->mValue.getInteger(); - if (MWBase::Environment::get().getWorld()->getTimeStamp() - mLastRespawn > 24*30*iMonthsToRespawn) + static const int iMonthsToRespawn = MWBase::Environment::get() + .getWorld() + ->getStore() + .get() + .find("iMonthsToRespawn") + ->mValue.getInteger(); + if (MWBase::Environment::get().getWorld()->getTimeStamp() - mLastRespawn > 24 * 30 * iMonthsToRespawn) { mLastRespawn = MWBase::Environment::get().getWorld()->getTimeStamp(); - for (CellRefList::List::iterator it (get().mList.begin()); it!=get().mList.end(); ++it) + for (CellRefList::List::iterator it(get().mList.begin()); + it != get().mList.end(); ++it) { Ptr ptr = getCurrentPtr(&*it); ptr.getClass().respawn(ptr); } } - for (CellRefList::List::iterator it (get().mList.begin()); it!=get().mList.end(); ++it) + for (CellRefList::List::iterator it(get().mList.begin()); + it != get().mList.end(); ++it) { Ptr ptr = getCurrentPtr(&*it); clearCorpse(ptr); ptr.getClass().respawn(ptr); } - for (CellRefList::List::iterator it (get().mList.begin()); it!=get().mList.end(); ++it) + for (CellRefList::List::iterator it(get().mList.begin()); + it != get().mList.end(); ++it) { Ptr ptr = getCurrentPtr(&*it); clearCorpse(ptr); ptr.getClass().respawn(ptr); } - for (CellRefList::List::iterator it (get().mList.begin()); it!=get().mList.end(); ++it) + for (CellRefList::List::iterator it(get().mList.begin()); + it != get().mList.end(); ++it) { Ptr ptr = getCurrentPtr(&*it); // no need to clearCorpse, handled as part of get() @@ -1142,9 +1182,8 @@ namespace MWWorld { mRechargingItems.clear(); - const auto update = [this](auto& list) - { - for (auto & item : list) + const auto update = [this](auto& list) { + for (auto& item : list) { Ptr ptr = getCurrentPtr(&item); if (!ptr.isEmpty() && ptr.getRefData().getCount() > 0) @@ -1166,26 +1205,28 @@ namespace MWWorld if (enchantmentId.empty()) return; - const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get().search(enchantmentId); + const ESM::Enchantment* enchantment + = MWBase::Environment::get().getWorld()->getStore().get().search(enchantmentId); if (!enchantment) { - Log(Debug::Warning) << "Warning: Can't find enchantment '" << enchantmentId << "' on item " << ptr.getCellRef().getRefId(); + Log(Debug::Warning) << "Warning: Can't find enchantment '" << enchantmentId << "' on item " + << ptr.getCellRef().getRefId(); return; } if (enchantment->mData.mType == ESM::Enchantment::WhenUsed - || enchantment->mData.mType == ESM::Enchantment::WhenStrikes) + || enchantment->mData.mType == ESM::Enchantment::WhenStrikes) mRechargingItems.emplace_back(ptr.getBase(), static_cast(enchantment->mData.mCharge)); } Ptr MWWorld::CellStore::getMovedActor(int actorId) const { - for(const auto& [cellRef, cell] : mMovedToAnotherCell) + for (const auto& [cellRef, cell] : mMovedToAnotherCell) { - if(cellRef->mClass->isActor() && cellRef->mData.getCustomData()) + if (cellRef->mClass->isActor() && cellRef->mData.getCustomData()) { Ptr actor(cellRef, cell); - if(actor.getClass().getCreatureStats(actor).getActorId() == actorId) + if (actor.getClass().getCreatureStats(actor).getActorId() == actorId) return actor; } } diff --git a/apps/openmw/mwworld/cellstore.hpp b/apps/openmw/mwworld/cellstore.hpp index 7897d8587c..dc0d6140c3 100644 --- a/apps/openmw/mwworld/cellstore.hpp +++ b/apps/openmw/mwworld/cellstore.hpp @@ -2,23 +2,23 @@ #define GAME_MWWORLD_CELLSTORE_H #include -#include +#include +#include #include #include #include +#include #include -#include -#include #include -#include "livecellref.hpp" #include "cellreflist.hpp" +#include "livecellref.hpp" -#include #include +#include -#include "timestamp.hpp" #include "ptr.hpp" +#include "timestamp.hpp" namespace ESM { @@ -55,352 +55,330 @@ namespace MWWorld class ESMStore; struct CellStoreImp; - using CellStoreTuple = std::tuple < - CellRefList, - CellRefList, - CellRefList, - CellRefList, - CellRefList, - CellRefList, - CellRefList, - CellRefList, - CellRefList, - CellRefList, - CellRefList, - CellRefList, - CellRefList, - CellRefList, - CellRefList, - CellRefList, - CellRefList, - CellRefList, - CellRefList, - CellRefList, - CellRefList>; + using CellStoreTuple = std::tuple, CellRefList, + CellRefList, CellRefList, CellRefList, CellRefList, + CellRefList, CellRefList, CellRefList, CellRefList, + CellRefList, CellRefList, CellRefList, + CellRefList, CellRefList, CellRefList, CellRefList, + CellRefList, CellRefList, CellRefList, CellRefList>; /// \brief Mutable state of a cell class CellStore { friend struct CellStoreImp; - public: - - enum State - { - State_Unloaded, State_Preloaded, State_Loaded - }; - - private: - - const MWWorld::ESMStore& mStore; - ESM::ReadersCache& mReaders; - - // Even though fog actually belongs to the player and not cells, - // it makes sense to store it here since we need it once for each cell. - // Note this is nullptr until the cell is explored to save some memory - std::unique_ptr mFogState; - - const ESM::Cell *mCell; - State mState; - bool mHasState; - std::vector mIds; - float mWaterLevel; - - MWWorld::TimeStamp mLastRespawn; - - template - static constexpr std::size_t getTypeIndex() - { - static_assert(Misc::TupleHasType, CellStoreTuple>::value); - return Misc::TupleTypeIndex, CellStoreTuple>::value; - } - - std::unique_ptr mCellStoreImp; - std::vector mCellRefLists; + public: + enum State + { + State_Unloaded, + State_Preloaded, + State_Loaded + }; + + private: + const MWWorld::ESMStore& mStore; + ESM::ReadersCache& mReaders; + + // Even though fog actually belongs to the player and not cells, + // it makes sense to store it here since we need it once for each cell. + // Note this is nullptr until the cell is explored to save some memory + std::unique_ptr mFogState; + + const ESM::Cell* mCell; + State mState; + bool mHasState; + std::vector mIds; + float mWaterLevel; + + MWWorld::TimeStamp mLastRespawn; + + template + static constexpr std::size_t getTypeIndex() + { + static_assert(Misc::TupleHasType, CellStoreTuple>::value); + return Misc::TupleTypeIndex, CellStoreTuple>::value; + } + + std::unique_ptr mCellStoreImp; + std::vector mCellRefLists; + + template + CellRefList& get() + { + mHasState = true; + return static_cast&>(*mCellRefLists[getTypeIndex()]); + } + + template + const CellRefList& get() const + { + return static_cast&>(*mCellRefLists[getTypeIndex()]); + } + + typedef std::map MovedRefTracker; + // References owned by a different cell that have been moved here. + // + MovedRefTracker mMovedHere; + // References owned by this cell that have been moved to another cell. + // + MovedRefTracker mMovedToAnotherCell; + + // Merged list of ref's currently in this cell - i.e. with added refs from mMovedHere, removed refs from + // mMovedToAnotherCell + std::vector mMergedRefs; + + // Get the Ptr for the given ref which originated from this cell (possibly moved to another cell at this point). + Ptr getCurrentPtr(MWWorld::LiveCellRefBase* ref); + + /// Moves object from the given cell to this cell. + void moveFrom(const MWWorld::Ptr& object, MWWorld::CellStore* from); + + /// Repopulate mMergedRefs. + void updateMergedRefs(); + + // (item, max charge) + typedef std::vector> TRechargingItems; + TRechargingItems mRechargingItems; + + bool mRechargingItemsUpToDate; + + void updateRechargingItems(); + void rechargeItems(float duration); + void checkItem(const Ptr& ptr); + + public: + /// Should this reference be accessible to the outside world (i.e. to scripts / game logic)? + /// Determined based on the deletion flags. By default, objects deleted by content files are never accessible; + /// objects deleted by setCount(0) are still accessible *if* they came from a content file (needed for vanilla + /// scripting compatibility, and the fact that objects may be "un-deleted" in the original game). + static bool isAccessible(const MWWorld::RefData& refdata, const MWWorld::CellRef& cref) + { + return !refdata.isDeletedByContentFile() && (cref.hasContentFile() || refdata.getCount() > 0); + } + + /// Moves object from this cell to the given cell. + /// @note automatically updates given cell by calling cellToMoveTo->moveFrom(...) + /// @note throws exception if cellToMoveTo == this + /// @return updated MWWorld::Ptr with the new CellStore pointer set. + MWWorld::Ptr moveTo(const MWWorld::Ptr& object, MWWorld::CellStore* cellToMoveTo); + + void rest(double hours); + void recharge(float duration); + + /// Make a copy of the given object and insert it into this cell. + /// @note If you get a linker error here, this means the given type can not be inserted into a cell. + /// The supported types are defined at the bottom of this file. + template + LiveCellRefBase* insert(const LiveCellRef* ref) + { + mHasState = true; + CellRefList& list = get(); + LiveCellRefBase* ret = &list.insert(*ref); + updateMergedRefs(); + return ret; + } + + /// @param readerList The readers to use for loading of the cell on-demand. + CellStore(const ESM::Cell* cell, const MWWorld::ESMStore& store, ESM::ReadersCache& readers); + CellStore(CellStore&&); + ~CellStore(); + + const ESM::Cell* getCell() const; + + State getState() const; + + const std::vector& getPreloadedIds() const; + ///< Get Ids of objects in this cell, only valid in State_Preloaded + + bool hasState() const; + ///< Does this cell have state that needs to be stored in a saved game file? + + bool hasId(std::string_view id) const; + ///< May return true for deleted IDs when in preload state. Will return false, if cell is + /// unloaded. + /// @note Will not account for moved references which may exist in Loaded state. Use search() instead if the + /// cell is loaded. + + Ptr search(std::string_view id); + ///< Will return an empty Ptr if cell is not loaded. Does not check references in + /// containers. + /// @note Triggers CellStore hasState flag. + + ConstPtr searchConst(std::string_view id) const; + ///< Will return an empty Ptr if cell is not loaded. Does not check references in + /// containers. + /// @note Does not trigger CellStore hasState flag. + + Ptr searchViaActorId(int id); + ///< Will return an empty Ptr if cell is not loaded. + + Ptr searchViaRefNum(const ESM::RefNum& refNum); + ///< Will return an empty Ptr if cell is not loaded. Does not check references in + /// containers. + /// @note Triggers CellStore hasState flag. + + float getWaterLevel() const; + + bool movedHere(const MWWorld::Ptr& ptr) const; + + void setWaterLevel(float level); + + void setFog(std::unique_ptr&& fog); + ///< \note Takes ownership of the pointer + + ESM::FogState* getFog() const; + + std::size_t count() const; + ///< Return total number of references, including deleted ones. + + void load(); + ///< Load references from content file. + + void preload(); + ///< Build ID list from content file. + + /// Call visitor (MWWorld::Ptr) for each reference. visitor must return a bool. Returning + /// false will abort the iteration. + /// \note Prefer using forEachConst when possible. + /// \note Do not modify this cell (i.e. remove/add objects) during the forEach, doing this may result in + /// unintended behaviour. \attention This function also lists deleted (count 0) objects! \return Iteration + /// completed? + template + bool forEach(Visitor&& visitor) + { + if (mState != State_Loaded) + return false; + + if (mMergedRefs.empty()) + return true; - template - CellRefList& get() - { - mHasState = true; - return static_cast&>(*mCellRefLists[getTypeIndex()]); - } + mHasState = true; - template - const CellRefList& get() const + for (unsigned int i = 0; i < mMergedRefs.size(); ++i) { - return static_cast&>(*mCellRefLists[getTypeIndex()]); - } - - typedef std::map MovedRefTracker; - // References owned by a different cell that have been moved here. - // - MovedRefTracker mMovedHere; - // References owned by this cell that have been moved to another cell. - // - MovedRefTracker mMovedToAnotherCell; - - // Merged list of ref's currently in this cell - i.e. with added refs from mMovedHere, removed refs from mMovedToAnotherCell - std::vector mMergedRefs; - - // Get the Ptr for the given ref which originated from this cell (possibly moved to another cell at this point). - Ptr getCurrentPtr(MWWorld::LiveCellRefBase* ref); - - /// Moves object from the given cell to this cell. - void moveFrom(const MWWorld::Ptr& object, MWWorld::CellStore* from); - - /// Repopulate mMergedRefs. - void updateMergedRefs(); - - // (item, max charge) - typedef std::vector > TRechargingItems; - TRechargingItems mRechargingItems; + if (!isAccessible(mMergedRefs[i]->mData, mMergedRefs[i]->mRef)) + continue; - bool mRechargingItemsUpToDate; - - void updateRechargingItems(); - void rechargeItems(float duration); - void checkItem(const Ptr& ptr); - - - public: - - /// Should this reference be accessible to the outside world (i.e. to scripts / game logic)? - /// Determined based on the deletion flags. By default, objects deleted by content files are never accessible; - /// objects deleted by setCount(0) are still accessible *if* they came from a content file (needed for vanilla - /// scripting compatibility, and the fact that objects may be "un-deleted" in the original game). - static bool isAccessible(const MWWorld::RefData& refdata, const MWWorld::CellRef& cref) - { - return !refdata.isDeletedByContentFile() && (cref.hasContentFile() || refdata.getCount() > 0); + if (!visitor(MWWorld::Ptr(mMergedRefs[i], this))) + return false; } - - /// Moves object from this cell to the given cell. - /// @note automatically updates given cell by calling cellToMoveTo->moveFrom(...) - /// @note throws exception if cellToMoveTo == this - /// @return updated MWWorld::Ptr with the new CellStore pointer set. - MWWorld::Ptr moveTo(const MWWorld::Ptr& object, MWWorld::CellStore* cellToMoveTo); - - void rest(double hours); - void recharge(float duration); - - /// Make a copy of the given object and insert it into this cell. - /// @note If you get a linker error here, this means the given type can not be inserted into a cell. - /// The supported types are defined at the bottom of this file. - template - LiveCellRefBase* insert(const LiveCellRef* ref) + return true; + } + + /// Call visitor (MWWorld::ConstPtr) for each reference. visitor must return a bool. Returning + /// false will abort the iteration. + /// \note Do not modify this cell (i.e. remove/add objects) during the forEach, doing this may result in + /// unintended behaviour. \attention This function also lists deleted (count 0) objects! \return Iteration + /// completed? + template + bool forEachConst(Visitor&& visitor) const + { + if (mState != State_Loaded) + return false; + + for (unsigned int i = 0; i < mMergedRefs.size(); ++i) { - mHasState = true; - CellRefList& list = get(); - LiveCellRefBase* ret = &list.insert(*ref); - updateMergedRefs(); - return ret; - } + if (!isAccessible(mMergedRefs[i]->mData, mMergedRefs[i]->mRef)) + continue; - /// @param readerList The readers to use for loading of the cell on-demand. - CellStore(const ESM::Cell* cell, const MWWorld::ESMStore& store, ESM::ReadersCache& readers); - CellStore(CellStore&&); - ~CellStore(); - - const ESM::Cell *getCell() const; - - State getState() const; - - const std::vector& getPreloadedIds() const; - ///< Get Ids of objects in this cell, only valid in State_Preloaded - - bool hasState() const; - ///< Does this cell have state that needs to be stored in a saved game file? - - bool hasId(std::string_view id) const; - ///< May return true for deleted IDs when in preload state. Will return false, if cell is - /// unloaded. - /// @note Will not account for moved references which may exist in Loaded state. Use search() instead if the cell is loaded. - - Ptr search(std::string_view id); - ///< Will return an empty Ptr if cell is not loaded. Does not check references in - /// containers. - /// @note Triggers CellStore hasState flag. - - ConstPtr searchConst(std::string_view id) const; - ///< Will return an empty Ptr if cell is not loaded. Does not check references in - /// containers. - /// @note Does not trigger CellStore hasState flag. - - Ptr searchViaActorId (int id); - ///< Will return an empty Ptr if cell is not loaded. - - Ptr searchViaRefNum (const ESM::RefNum& refNum); - ///< Will return an empty Ptr if cell is not loaded. Does not check references in - /// containers. - /// @note Triggers CellStore hasState flag. - - float getWaterLevel() const; - - bool movedHere(const MWWorld::Ptr& ptr) const; - - void setWaterLevel (float level); - - void setFog(std::unique_ptr&& fog); - ///< \note Takes ownership of the pointer - - ESM::FogState* getFog () const; - - std::size_t count() const; - ///< Return total number of references, including deleted ones. - - void load (); - ///< Load references from content file. - - void preload (); - ///< Build ID list from content file. - - /// Call visitor (MWWorld::Ptr) for each reference. visitor must return a bool. Returning - /// false will abort the iteration. - /// \note Prefer using forEachConst when possible. - /// \note Do not modify this cell (i.e. remove/add objects) during the forEach, doing this may result in unintended behaviour. - /// \attention This function also lists deleted (count 0) objects! - /// \return Iteration completed? - template - bool forEach (Visitor&& visitor) - { - if (mState != State_Loaded) + if (!visitor(MWWorld::ConstPtr(mMergedRefs[i], this))) return false; + } + return true; + } + + /// Call visitor (ref) for each reference of given type. visitor must return a bool. Returning + /// false will abort the iteration. + /// \note Do not modify this cell (i.e. remove/add objects) during the forEach, doing this may result in + /// unintended behaviour. \attention This function also lists deleted (count 0) objects! \return Iteration + /// completed? + template + bool forEachType(Visitor& visitor) + { + if (mState != State_Loaded) + return false; + + if (mMergedRefs.empty()) + return true; - if (mMergedRefs.empty()) - return true; - - mHasState = true; - - for (unsigned int i=0; imData, mMergedRefs[i]->mRef)) - continue; + mHasState = true; - if (!visitor(MWWorld::Ptr(mMergedRefs[i], this))) - return false; - } - return true; - } + CellRefList& list = get(); - /// Call visitor (MWWorld::ConstPtr) for each reference. visitor must return a bool. Returning - /// false will abort the iteration. - /// \note Do not modify this cell (i.e. remove/add objects) during the forEach, doing this may result in unintended behaviour. - /// \attention This function also lists deleted (count 0) objects! - /// \return Iteration completed? - template - bool forEachConst (Visitor&& visitor) const + for (typename CellRefList::List::iterator it(list.mList.begin()); it != list.mList.end(); ++it) { - if (mState != State_Loaded) + LiveCellRefBase* base = &*it; + if (mMovedToAnotherCell.find(base) != mMovedToAnotherCell.end()) + continue; + if (!isAccessible(base->mData, base->mRef)) + continue; + if (!visitor(MWWorld::Ptr(base, this))) return false; - - for (unsigned int i=0; imData, mMergedRefs[i]->mRef)) - continue; - - if (!visitor(MWWorld::ConstPtr(mMergedRefs[i], this))) - return false; - } - return true; } - - /// Call visitor (ref) for each reference of given type. visitor must return a bool. Returning - /// false will abort the iteration. - /// \note Do not modify this cell (i.e. remove/add objects) during the forEach, doing this may result in unintended behaviour. - /// \attention This function also lists deleted (count 0) objects! - /// \return Iteration completed? - template - bool forEachType(Visitor& visitor) + for (MovedRefTracker::const_iterator it = mMovedHere.begin(); it != mMovedHere.end(); ++it) { - if (mState != State_Loaded) - return false; - - if (mMergedRefs.empty()) - return true; - - mHasState = true; - - CellRefList& list = get(); - - for (typename CellRefList::List::iterator it (list.mList.begin()); it!=list.mList.end(); ++it) - { - LiveCellRefBase* base = &*it; - if (mMovedToAnotherCell.find(base) != mMovedToAnotherCell.end()) - continue; - if (!isAccessible(base->mData, base->mRef)) - continue; + LiveCellRefBase* base = it->first; + if (dynamic_cast*>(base)) if (!visitor(MWWorld::Ptr(base, this))) return false; - } - - for (MovedRefTracker::const_iterator it = mMovedHere.begin(); it != mMovedHere.end(); ++it) - { - LiveCellRefBase* base = it->first; - if (dynamic_cast*>(base)) - if (!visitor(MWWorld::Ptr(base, this))) - return false; - } - return true; } + return true; + } - // NOTE: does not account for moved references - // Should be phased out when we have const version of forEach - inline const CellRefList& getReadOnlyDoors() const - { - return get(); - } - inline const CellRefList& getReadOnlyStatics() const - { - return get(); - } + // NOTE: does not account for moved references + // Should be phased out when we have const version of forEach + inline const CellRefList& getReadOnlyDoors() const { return get(); } + inline const CellRefList& getReadOnlyStatics() const { return get(); } - bool isExterior() const; + bool isExterior() const; - bool isQuasiExterior() const; + bool isQuasiExterior() const; - Ptr searchInContainer(std::string_view id); + Ptr searchInContainer(std::string_view id); - void loadState (const ESM::CellState& state); + void loadState(const ESM::CellState& state); - void saveState (ESM::CellState& state) const; + void saveState(ESM::CellState& state) const; - void writeFog (ESM::ESMWriter& writer) const; + void writeFog(ESM::ESMWriter& writer) const; - void readFog (ESM::ESMReader& reader); + void readFog(ESM::ESMReader& reader); - void writeReferences (ESM::ESMWriter& writer) const; + void writeReferences(ESM::ESMWriter& writer) const; - struct GetCellStoreCallback - { - public: - ///@note must return nullptr if the cell is not found - virtual CellStore* getCellStore(const ESM::CellId& cellId) = 0; - virtual ~GetCellStoreCallback() = default; - }; - - /// @param callback to use for retrieving of additional CellStore objects by ID (required for resolving moved references) - void readReferences (ESM::ESMReader& reader, const std::map& contentFileMap, GetCellStoreCallback* callback); + struct GetCellStoreCallback + { + public: + ///@note must return nullptr if the cell is not found + virtual CellStore* getCellStore(const ESM::CellId& cellId) = 0; + virtual ~GetCellStoreCallback() = default; + }; - void respawn (); - ///< Check mLastRespawn and respawn references if necessary. This is a no-op if the cell is not loaded. + /// @param callback to use for retrieving of additional CellStore objects by ID (required for resolving moved + /// references) + void readReferences( + ESM::ESMReader& reader, const std::map& contentFileMap, GetCellStoreCallback* callback); - Ptr getMovedActor(int actorId) const; + void respawn(); + ///< Check mLastRespawn and respawn references if necessary. This is a no-op if the cell is not loaded. - private: + Ptr getMovedActor(int actorId) const; - /// Run through references and store IDs - void listRefs(); + private: + /// Run through references and store IDs + void listRefs(); - void loadRefs(); + void loadRefs(); - void loadRef (ESM::CellRef& ref, bool deleted, std::map& refNumToID); - ///< Make case-adjustments to \a ref and insert it into the respective container. - /// - /// Invalid \a ref objects are silently dropped. + void loadRef(ESM::CellRef& ref, bool deleted, std::map& refNumToID); + ///< Make case-adjustments to \a ref and insert it into the respective container. + /// + /// Invalid \a ref objects are silently dropped. }; - bool operator== (const CellStore& left, const CellStore& right); - bool operator!= (const CellStore& left, const CellStore& right); + bool operator==(const CellStore& left, const CellStore& right); + bool operator!=(const CellStore& left, const CellStore& right); } #endif diff --git a/apps/openmw/mwworld/cellutils.hpp b/apps/openmw/mwworld/cellutils.hpp index c827974c35..a7e8e88c78 100644 --- a/apps/openmw/mwworld/cellutils.hpp +++ b/apps/openmw/mwworld/cellutils.hpp @@ -11,10 +11,8 @@ namespace MWWorld { inline osg::Vec2i positionToCellIndex(float x, float y) { - return { - static_cast(std::floor(x / Constants::CellSizeInUnits)), - static_cast(std::floor(y / Constants::CellSizeInUnits)) - }; + return { static_cast(std::floor(x / Constants::CellSizeInUnits)), + static_cast(std::floor(y / Constants::CellSizeInUnits)) }; } } diff --git a/apps/openmw/mwworld/cellvisitors.hpp b/apps/openmw/mwworld/cellvisitors.hpp index 77f33fa84b..f4d606d02d 100644 --- a/apps/openmw/mwworld/cellvisitors.hpp +++ b/apps/openmw/mwworld/cellvisitors.hpp @@ -1,25 +1,24 @@ #ifndef GAME_MWWORLD_CELLVISITORS_H #define GAME_MWWORLD_CELLVISITORS_H -#include #include +#include #include "ptr.hpp" - namespace MWWorld { struct ListAndResetObjectsVisitor { std::vector mObjects; - bool operator() (const MWWorld::Ptr& ptr) + bool operator()(const MWWorld::Ptr& ptr) { if (ptr.getRefData().getBaseNode()) { ptr.getRefData().setBaseNode(nullptr); } - mObjects.push_back (ptr); + mObjects.push_back(ptr); return true; } diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index 46c5bb81ab..0798d72e11 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -3,20 +3,20 @@ #include #include -#include #include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" #include "../mwbase/world.hpp" #include "../mwworld/esmstore.hpp" -#include "ptr.hpp" -#include "nullaction.hpp" -#include "failedaction.hpp" #include "actiontake.hpp" #include "containerstore.hpp" +#include "failedaction.hpp" +#include "nullaction.hpp" +#include "ptr.hpp" #include "../mwgui/tooltips.hpp" @@ -30,55 +30,57 @@ namespace MWWorld return values; } - void Class::insertObjectRendering (const Ptr& ptr, const std::string& mesh, MWRender::RenderingInterface& renderingInterface) const + void Class::insertObjectRendering( + const Ptr& ptr, const std::string& mesh, MWRender::RenderingInterface& renderingInterface) const { - } - void Class::insertObject(const Ptr& ptr, const std::string& mesh, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const + void Class::insertObject( + const Ptr& ptr, const std::string& mesh, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const { - } - void Class::insertObjectPhysics(const Ptr& ptr, const std::string& mesh, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const - {} + void Class::insertObjectPhysics( + const Ptr& ptr, const std::string& mesh, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const + { + } bool Class::consume(const MWWorld::Ptr& consumable, const MWWorld::Ptr& actor) const { return false; } - void Class::skillUsageSucceeded (const MWWorld::Ptr& ptr, int skill, int usageType, float extraFactor) const + void Class::skillUsageSucceeded(const MWWorld::Ptr& ptr, int skill, int usageType, float extraFactor) const { - throw std::runtime_error ("class does not represent an actor"); + throw std::runtime_error("class does not represent an actor"); } - bool Class::canSell (const MWWorld::ConstPtr& item, int npcServices) const + bool Class::canSell(const MWWorld::ConstPtr& item, int npcServices) const { return false; } - int Class::getServices(const ConstPtr &actor) const + int Class::getServices(const ConstPtr& actor) const { - throw std::runtime_error ("class does not have services"); + throw std::runtime_error("class does not have services"); } - MWMechanics::CreatureStats& Class::getCreatureStats (const Ptr& ptr) const + MWMechanics::CreatureStats& Class::getCreatureStats(const Ptr& ptr) const { - throw std::runtime_error ("class does not have creature stats"); + throw std::runtime_error("class does not have creature stats"); } - MWMechanics::NpcStats& Class::getNpcStats (const Ptr& ptr) const + MWMechanics::NpcStats& Class::getNpcStats(const Ptr& ptr) const { - throw std::runtime_error ("class does not have NPC stats"); + throw std::runtime_error("class does not have NPC stats"); } - bool Class::hasItemHealth (const ConstPtr& ptr) const + bool Class::hasItemHealth(const ConstPtr& ptr) const { return false; } - int Class::getItemHealth(const ConstPtr &ptr) const + int Class::getItemHealth(const ConstPtr& ptr) const { if (ptr.getCellRef().getCharge() == -1) return getItemMaxHealth(ptr); @@ -86,7 +88,7 @@ namespace MWWorld return ptr.getCellRef().getCharge(); } - float Class::getItemNormalizedHealth (const ConstPtr& ptr) const + float Class::getItemNormalizedHealth(const ConstPtr& ptr) const { if (getItemMaxHealth(ptr) == 0) { @@ -98,9 +100,9 @@ namespace MWWorld } } - int Class::getItemMaxHealth (const ConstPtr& ptr) const + int Class::getItemMaxHealth(const ConstPtr& ptr) const { - throw std::runtime_error ("class does not have item health"); + throw std::runtime_error("class does not have item health"); } bool Class::evaluateHit(const Ptr& ptr, Ptr& victim, osg::Vec3f& hitPosition) const @@ -108,57 +110,59 @@ namespace MWWorld throw std::runtime_error("class cannot hit"); } - void Class::hit(const Ptr& ptr, float attackStrength, int type, const Ptr& victim, const osg::Vec3f& hitPosition, bool success) const + void Class::hit(const Ptr& ptr, float attackStrength, int type, const Ptr& victim, const osg::Vec3f& hitPosition, + bool success) const { throw std::runtime_error("class cannot hit"); } - void Class::block(const Ptr &ptr) const + void Class::block(const Ptr& ptr) const { throw std::runtime_error("class cannot block"); } - void Class::onHit(const Ptr& ptr, float damage, bool ishealth, const Ptr& object, const Ptr& attacker, const osg::Vec3f& hitPosition, bool successful) const + void Class::onHit(const Ptr& ptr, float damage, bool ishealth, const Ptr& object, const Ptr& attacker, + const osg::Vec3f& hitPosition, bool successful) const { throw std::runtime_error("class cannot be hit"); } - std::unique_ptr Class::activate (const Ptr& ptr, const Ptr& actor) const + std::unique_ptr Class::activate(const Ptr& ptr, const Ptr& actor) const { return std::make_unique(); } - std::unique_ptr Class::use (const Ptr& ptr, bool force) const + std::unique_ptr Class::use(const Ptr& ptr, bool force) const { return std::make_unique(); } - ContainerStore& Class::getContainerStore (const Ptr& ptr) const + ContainerStore& Class::getContainerStore(const Ptr& ptr) const { - throw std::runtime_error ("class does not have a container store"); + throw std::runtime_error("class does not have a container store"); } - InventoryStore& Class::getInventoryStore (const Ptr& ptr) const + InventoryStore& Class::getInventoryStore(const Ptr& ptr) const { - throw std::runtime_error ("class does not have an inventory store"); + throw std::runtime_error("class does not have an inventory store"); } - bool Class::hasInventoryStore(const Ptr &ptr) const + bool Class::hasInventoryStore(const Ptr& ptr) const { return false; } - bool Class::canLock(const ConstPtr &ptr) const + bool Class::canLock(const ConstPtr& ptr) const { return false; } - void Class::setRemainingUsageTime (const Ptr& ptr, float duration) const + void Class::setRemainingUsageTime(const Ptr& ptr, float duration) const { - throw std::runtime_error ("class does not support time-based uses"); + throw std::runtime_error("class does not support time-based uses"); } - float Class::getRemainingUsageTime (const ConstPtr& ptr) const + float Class::getRemainingUsageTime(const ConstPtr& ptr) const { return -1; } @@ -168,90 +172,90 @@ namespace MWWorld return {}; } - float Class::getMaxSpeed (const Ptr& ptr) const + float Class::getMaxSpeed(const Ptr& ptr) const { return 0; } - - float Class::getCurrentSpeed (const Ptr& ptr) const + + float Class::getCurrentSpeed(const Ptr& ptr) const { return 0; } - float Class::getJump (const Ptr& ptr) const + float Class::getJump(const Ptr& ptr) const { return 0; } - int Class::getEnchantmentPoints (const MWWorld::ConstPtr& ptr) const + int Class::getEnchantmentPoints(const MWWorld::ConstPtr& ptr) const { - throw std::runtime_error ("class does not support enchanting"); + throw std::runtime_error("class does not support enchanting"); } - MWMechanics::Movement& Class::getMovementSettings (const Ptr& ptr) const + MWMechanics::Movement& Class::getMovementSettings(const Ptr& ptr) const { - throw std::runtime_error ("movement settings not supported by class"); + throw std::runtime_error("movement settings not supported by class"); } - osg::Vec3f Class::getRotationVector (const Ptr& ptr) const + osg::Vec3f Class::getRotationVector(const Ptr& ptr) const { - return osg::Vec3f (0, 0, 0); + return osg::Vec3f(0, 0, 0); } - std::pair, bool> Class::getEquipmentSlots (const ConstPtr& ptr) const + std::pair, bool> Class::getEquipmentSlots(const ConstPtr& ptr) const { - return std::make_pair (std::vector(), false); + return std::make_pair(std::vector(), false); } - int Class::getEquipmentSkill (const ConstPtr& ptr) const + int Class::getEquipmentSkill(const ConstPtr& ptr) const { return -1; } - int Class::getValue (const ConstPtr& ptr) const + int Class::getValue(const ConstPtr& ptr) const { - throw std::logic_error ("value not supported by this class"); + throw std::logic_error("value not supported by this class"); } - float Class::getCapacity (const MWWorld::Ptr& ptr) const + float Class::getCapacity(const MWWorld::Ptr& ptr) const { - throw std::runtime_error ("capacity not supported by this class"); + throw std::runtime_error("capacity not supported by this class"); } - float Class::getWeight(const ConstPtr &ptr) const + float Class::getWeight(const ConstPtr& ptr) const { - throw std::runtime_error ("weight not supported by this class"); + throw std::runtime_error("weight not supported by this class"); } - float Class::getEncumbrance (const MWWorld::Ptr& ptr) const + float Class::getEncumbrance(const MWWorld::Ptr& ptr) const { - throw std::runtime_error ("encumbrance not supported by class"); + throw std::runtime_error("encumbrance not supported by class"); } - bool Class::isEssential (const MWWorld::ConstPtr& ptr) const + bool Class::isEssential(const MWWorld::ConstPtr& ptr) const { return false; } - float Class::getArmorRating (const MWWorld::Ptr& ptr) const + float Class::getArmorRating(const MWWorld::Ptr& ptr) const { throw std::runtime_error("Class does not support armor rating"); } - const Class& Class::get (unsigned int key) + const Class& Class::get(unsigned int key) { const auto& classes = getClasses(); auto iter = classes.find(key); if (iter == classes.end()) - throw std::logic_error ("Class::get(): unknown class key: " + std::to_string(key)); + throw std::logic_error("Class::get(): unknown class key: " + std::to_string(key)); return *iter->second; } - bool Class::isPersistent(const ConstPtr &ptr) const + bool Class::isPersistent(const ConstPtr& ptr) const { - throw std::runtime_error ("class does not support persistence"); + throw std::runtime_error("class does not support persistence"); } void Class::registerClass(Class& instance) @@ -259,14 +263,14 @@ namespace MWWorld getClasses().emplace(instance.getType(), &instance); } - std::string_view Class::getUpSoundId (const ConstPtr& ptr) const + std::string_view Class::getUpSoundId(const ConstPtr& ptr) const { - throw std::runtime_error ("class does not have an up sound"); + throw std::runtime_error("class does not have an up sound"); } - std::string_view Class::getDownSoundId (const ConstPtr& ptr) const + std::string_view Class::getDownSoundId(const ConstPtr& ptr) const { - throw std::runtime_error ("class does not have an down sound"); + throw std::runtime_error("class does not have an down sound"); } std::string_view Class::getSoundIdFromSndGen(const Ptr& ptr, std::string_view type) const @@ -276,15 +280,15 @@ namespace MWWorld const std::string& Class::getInventoryIcon(const MWWorld::ConstPtr& ptr) const { - throw std::runtime_error ("class does not have any inventory icon"); + throw std::runtime_error("class does not have any inventory icon"); } - MWGui::ToolTipInfo Class::getToolTipInfo (const ConstPtr& ptr, int count) const + MWGui::ToolTipInfo Class::getToolTipInfo(const ConstPtr& ptr, int count) const { - throw std::runtime_error ("class does not have a tool tip"); + throw std::runtime_error("class does not have a tool tip"); } - bool Class::showsInInventory (const ConstPtr& ptr) const + bool Class::showsInInventory(const ConstPtr& ptr) const { // NOTE: Don't show WerewolfRobe objects in the inventory, or allow them to be taken. // Vanilla likely uses a hack like this since there's no other way to prevent it from @@ -292,7 +296,7 @@ namespace MWWorld return (ptr.getCellRef().getRefId() != "werewolfrobe"); } - bool Class::hasToolTip (const ConstPtr& ptr) const + bool Class::hasToolTip(const ConstPtr& ptr) const { return true; } @@ -302,11 +306,9 @@ namespace MWWorld return {}; } - void Class::adjustScale(const MWWorld::ConstPtr& ptr, osg::Vec3f& scale, bool rendering) const - { - } + void Class::adjustScale(const MWWorld::ConstPtr& ptr, osg::Vec3f& scale, bool rendering) const {} - std::string Class::getModel(const MWWorld::ConstPtr &ptr) const + std::string Class::getModel(const MWWorld::ConstPtr& ptr) const { return {}; } @@ -316,40 +318,40 @@ namespace MWWorld return false; } - void Class::getModelsToPreload(const Ptr &ptr, std::vector &models) const + void Class::getModelsToPreload(const Ptr& ptr, std::vector& models) const { std::string model = getModel(ptr); if (!model.empty()) models.push_back(model); } - const std::string& Class::applyEnchantment(const MWWorld::ConstPtr& ptr, const std::string& enchId, int enchCharge, const std::string& newName) const + const std::string& Class::applyEnchantment( + const MWWorld::ConstPtr& ptr, const std::string& enchId, int enchCharge, const std::string& newName) const { - throw std::runtime_error ("class can't be enchanted"); + throw std::runtime_error("class can't be enchanted"); } std::pair Class::canBeEquipped(const MWWorld::ConstPtr& ptr, const MWWorld::Ptr& npc) const { - return {1, {}}; + return { 1, {} }; } - void Class::adjustPosition(const MWWorld::Ptr& ptr, bool force) const - { - } + void Class::adjustPosition(const MWWorld::Ptr& ptr, bool force) const {} - std::unique_ptr Class::defaultItemActivate(const Ptr &ptr, const Ptr &actor) const + std::unique_ptr Class::defaultItemActivate(const Ptr& ptr, const Ptr& actor) const { - if(!MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Inventory)) + if (!MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Inventory)) return std::make_unique(); - if(actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf()) + if (actor.getClass().isNpc() && actor.getClass().getNpcStats(actor).isWerewolf()) { - const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); auto& prng = MWBase::Environment::get().getWorld()->getPrng(); - const ESM::Sound *sound = store.get().searchRandom("WolfItem", prng); + const ESM::Sound* sound = store.get().searchRandom("WolfItem", prng); std::unique_ptr action = std::make_unique("#{sWerewolfRefusal}"); - if(sound) action->setSound(sound->mId); + if (sound) + action->setSound(sound->mId); return action; } @@ -360,14 +362,12 @@ namespace MWWorld return action; } - MWWorld::Ptr - Class::copyToCellImpl(const ConstPtr &ptr, CellStore &cell) const + MWWorld::Ptr Class::copyToCellImpl(const ConstPtr& ptr, CellStore& cell) const { throw std::runtime_error("unable to copy class to cell"); } - MWWorld::Ptr - Class::copyToCell(const ConstPtr &ptr, CellStore &cell, int count) const + MWWorld::Ptr Class::copyToCell(const ConstPtr& ptr, CellStore& cell, int count) const { Ptr newPtr = copyToCellImpl(ptr, cell); newPtr.getCellRef().unsetRefNum(); // This RefNum is only valid within the original cell of the reference @@ -375,8 +375,7 @@ namespace MWWorld return newPtr; } - MWWorld::Ptr - Class::copyToCell(const ConstPtr &ptr, CellStore &cell, const ESM::Position &pos, int count) const + MWWorld::Ptr Class::copyToCell(const ConstPtr& ptr, CellStore& cell, const ESM::Position& pos, int count) const { Ptr newPtr = copyToCell(ptr, cell, count); newPtr.getRefData().setPosition(pos); @@ -384,48 +383,39 @@ namespace MWWorld return newPtr; } - bool Class::isBipedal(const ConstPtr &ptr) const + bool Class::isBipedal(const ConstPtr& ptr) const { return false; } - bool Class::canFly(const ConstPtr &ptr) const + bool Class::canFly(const ConstPtr& ptr) const { return false; } - bool Class::canSwim(const ConstPtr &ptr) const + bool Class::canSwim(const ConstPtr& ptr) const { return false; } - bool Class::canWalk(const ConstPtr &ptr) const + bool Class::canWalk(const ConstPtr& ptr) const { return false; } bool Class::isPureWaterCreature(const ConstPtr& ptr) const { - return canSwim(ptr) - && !isBipedal(ptr) - && !canFly(ptr) - && !canWalk(ptr); + return canSwim(ptr) && !isBipedal(ptr) && !canFly(ptr) && !canWalk(ptr); } bool Class::isPureFlyingCreature(const ConstPtr& ptr) const { - return canFly(ptr) - && !isBipedal(ptr) - && !canSwim(ptr) - && !canWalk(ptr); + return canFly(ptr) && !isBipedal(ptr) && !canSwim(ptr) && !canWalk(ptr); } bool Class::isPureLandCreature(const Ptr& ptr) const { - return canWalk(ptr) - && !isBipedal(ptr) - && !canFly(ptr) - && !canSwim(ptr); + return canWalk(ptr) && !isBipedal(ptr) && !canFly(ptr) && !canSwim(ptr); } bool Class::isMobile(const MWWorld::Ptr& ptr) const @@ -438,14 +428,14 @@ namespace MWWorld throw std::runtime_error("class does not support skills"); } - int Class::getBloodTexture (const MWWorld::ConstPtr& ptr) const + int Class::getBloodTexture(const MWWorld::ConstPtr& ptr) const { throw std::runtime_error("class does not support gore"); } - void Class::readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state) const {} + void Class::readAdditionalState(const MWWorld::Ptr& ptr, const ESM::ObjectState& state) const {} - void Class::writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const {} + void Class::writeAdditionalState(const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const {} int Class::getBaseGold(const MWWorld::ConstPtr& ptr) const { @@ -457,17 +447,17 @@ namespace MWWorld return false; } - MWWorld::DoorState Class::getDoorState (const MWWorld::ConstPtr &ptr) const + MWWorld::DoorState Class::getDoorState(const MWWorld::ConstPtr& ptr) const { throw std::runtime_error("this is not a door"); } - void Class::setDoorState (const MWWorld::Ptr &ptr, MWWorld::DoorState state) const + void Class::setDoorState(const MWWorld::Ptr& ptr, MWWorld::DoorState state) const { throw std::runtime_error("this is not a door"); } - float Class::getNormalizedEncumbrance(const Ptr &ptr) const + float Class::getNormalizedEncumbrance(const Ptr& ptr) const { float capacity = getCapacity(ptr); float encumbrance = getEncumbrance(ptr); @@ -483,10 +473,10 @@ namespace MWWorld std::string_view Class::getSound(const MWWorld::ConstPtr&) const { - return {}; + return {}; } - int Class::getBaseFightRating(const ConstPtr &ptr) const + int Class::getBaseFightRating(const ConstPtr& ptr) const { throw std::runtime_error("class does not support fight rating"); } @@ -495,30 +485,32 @@ namespace MWWorld { return {}; } - int Class::getPrimaryFactionRank (const MWWorld::ConstPtr& ptr) const + int Class::getPrimaryFactionRank(const MWWorld::ConstPtr& ptr) const { return -1; } - float Class::getEffectiveArmorRating(const ConstPtr &armor, const Ptr &actor) const + float Class::getEffectiveArmorRating(const ConstPtr& armor, const Ptr& actor) const { throw std::runtime_error("class does not support armor ratings"); } osg::Vec4f Class::getEnchantmentColor(const MWWorld::ConstPtr& item) const { - osg::Vec4f result(1,1,1,1); + osg::Vec4f result(1, 1, 1, 1); std::string_view enchantmentName = item.getClass().getEnchantment(item); if (enchantmentName.empty()) return result; - const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get().search(enchantmentName); + const ESM::Enchantment* enchantment + = MWBase::Environment::get().getWorld()->getStore().get().search(enchantmentName); if (!enchantment) return result; - assert (enchantment->mEffects.mList.size()); + assert(enchantment->mEffects.mList.size()); - const ESM::MagicEffect* magicEffect = MWBase::Environment::get().getWorld()->getStore().get().search( + const ESM::MagicEffect* magicEffect + = MWBase::Environment::get().getWorld()->getStore().get().search( enchantment->mEffects.mList.front().mEffectID); if (!magicEffect) return result; @@ -531,12 +523,12 @@ namespace MWWorld void Class::setBaseAISetting(const std::string& id, MWMechanics::AiSetting setting, int value) const { - throw std::runtime_error ("class does not have creature stats"); + throw std::runtime_error("class does not have creature stats"); } void Class::modifyBaseInventory(std::string_view actorId, std::string_view itemId, int amount) const { - throw std::runtime_error ("class does not have an inventory store"); + throw std::runtime_error("class does not have an inventory store"); } float Class::getWalkSpeed(const Ptr& /*ptr*/) const diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index 7921cda0dc..a48cf90e4b 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -9,8 +9,8 @@ #include #include -#include "ptr.hpp" #include "doorstate.hpp" +#include "ptr.hpp" #include "../mwmechanics/aisetting.hpp" @@ -56,321 +56,320 @@ namespace MWWorld /// \brief Base class for referenceable esm records class Class { - const unsigned mType; - - static std::map& getClasses(); - - protected: - - explicit Class(unsigned type) : mType(type) {} + const unsigned mType; - std::unique_ptr defaultItemActivate(const Ptr &ptr, const Ptr &actor) const; - ///< Generate default action for activating inventory items + static std::map& getClasses(); + + protected: + explicit Class(unsigned type) + : mType(type) + { + } - virtual Ptr copyToCellImpl(const ConstPtr &ptr, CellStore &cell) const; + std::unique_ptr defaultItemActivate(const Ptr& ptr, const Ptr& actor) const; + ///< Generate default action for activating inventory items - public: + virtual Ptr copyToCellImpl(const ConstPtr& ptr, CellStore& cell) const; - virtual ~Class() = default; - Class (const Class&) = delete; - Class& operator= (const Class&) = delete; + public: + virtual ~Class() = default; + Class(const Class&) = delete; + Class& operator=(const Class&) = delete; - unsigned int getType() const { - return mType; - } + unsigned int getType() const { return mType; } - virtual void insertObjectRendering (const Ptr& ptr, const std::string& mesh, MWRender::RenderingInterface& renderingInterface) const; - virtual void insertObject(const Ptr& ptr, const std::string& mesh, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const; - ///< Add reference into a cell for rendering (default implementation: don't render anything). - virtual void insertObjectPhysics(const Ptr& ptr, const std::string& mesh, const osg::Quat& rotation, MWPhysics::PhysicsSystem& physics) const; + virtual void insertObjectRendering( + const Ptr& ptr, const std::string& mesh, MWRender::RenderingInterface& renderingInterface) const; + virtual void insertObject(const Ptr& ptr, const std::string& mesh, const osg::Quat& rotation, + MWPhysics::PhysicsSystem& physics) const; + ///< Add reference into a cell for rendering (default implementation: don't render anything). + virtual void insertObjectPhysics(const Ptr& ptr, const std::string& mesh, const osg::Quat& rotation, + MWPhysics::PhysicsSystem& physics) const; - virtual std::string_view getName(const ConstPtr& ptr) const = 0; - ///< \return name or ID; can return an empty string. + virtual std::string_view getName(const ConstPtr& ptr) const = 0; + ///< \return name or ID; can return an empty string. - virtual void adjustPosition(const MWWorld::Ptr& ptr, bool force) const; - ///< Adjust position to stand on ground. Must be called post model load - /// @param force do this even if the ptr is flying + virtual void adjustPosition(const MWWorld::Ptr& ptr, bool force) const; + ///< Adjust position to stand on ground. Must be called post model load + /// @param force do this even if the ptr is flying - virtual MWMechanics::CreatureStats& getCreatureStats (const Ptr& ptr) const; - ///< Return creature stats or throw an exception, if class does not have creature stats - /// (default implementation: throw an exception) + virtual MWMechanics::CreatureStats& getCreatureStats(const Ptr& ptr) const; + ///< Return creature stats or throw an exception, if class does not have creature stats + /// (default implementation: throw an exception) - virtual bool hasToolTip (const ConstPtr& ptr) const; - ///< @return true if this object has a tooltip when focused (default implementation: true) + virtual bool hasToolTip(const ConstPtr& ptr) const; + ///< @return true if this object has a tooltip when focused (default implementation: true) - virtual MWGui::ToolTipInfo getToolTipInfo (const ConstPtr& ptr, int count) const; - ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. + virtual MWGui::ToolTipInfo getToolTipInfo(const ConstPtr& ptr, int count) const; + ///< @return the content of the tool tip to be displayed. raises exception if the object has no tooltip. - virtual bool showsInInventory (const ConstPtr& ptr) const; - ///< Return whether ptr shows in inventory views. - /// Hidden items are not displayed and cannot be (re)moved by the user. - /// \return True if shown, false if hidden. + virtual bool showsInInventory(const ConstPtr& ptr) const; + ///< Return whether ptr shows in inventory views. + /// Hidden items are not displayed and cannot be (re)moved by the user. + /// \return True if shown, false if hidden. - virtual MWMechanics::NpcStats& getNpcStats (const Ptr& ptr) const; - ///< Return NPC stats or throw an exception, if class does not have NPC stats - /// (default implementation: throw an exception) + virtual MWMechanics::NpcStats& getNpcStats(const Ptr& ptr) const; + ///< Return NPC stats or throw an exception, if class does not have NPC stats + /// (default implementation: throw an exception) - virtual bool hasItemHealth (const ConstPtr& ptr) const; - ///< \return Item health data available? (default implementation: false) + virtual bool hasItemHealth(const ConstPtr& ptr) const; + ///< \return Item health data available? (default implementation: false) - virtual int getItemHealth (const ConstPtr& ptr) const; - ///< Return current item health or throw an exception if class does not have item health + virtual int getItemHealth(const ConstPtr& ptr) const; + ///< Return current item health or throw an exception if class does not have item health - virtual float getItemNormalizedHealth (const ConstPtr& ptr) const; - ///< Return current item health re-scaled to maximum health + virtual float getItemNormalizedHealth(const ConstPtr& ptr) const; + ///< Return current item health re-scaled to maximum health - virtual int getItemMaxHealth (const ConstPtr& ptr) const; - ///< Return item max health or throw an exception, if class does not have item health - /// (default implementation: throw an exception) + virtual int getItemMaxHealth(const ConstPtr& ptr) const; + ///< Return item max health or throw an exception, if class does not have item health + /// (default implementation: throw an exception) - virtual bool evaluateHit(const Ptr& ptr, Ptr& victim, osg::Vec3f& hitPosition) const; - ///< Evaluate the victim of a melee hit produced by ptr in the current circumstances and return dice roll success. - /// (default implementation: throw an exception) + virtual bool evaluateHit(const Ptr& ptr, Ptr& victim, osg::Vec3f& hitPosition) const; + ///< Evaluate the victim of a melee hit produced by ptr in the current circumstances and return dice roll + ///< success. + /// (default implementation: throw an exception) - virtual void hit(const Ptr& ptr, float attackStrength, int type=-1, const Ptr& victim = Ptr(), const osg::Vec3f& hitPosition = osg::Vec3f(), bool success = false) const; - ///< Execute a melee hit on the victim at hitPosition, using the current weapon. If the hit was successful, apply damage and process corresponding events. - /// \param attackStrength how long the attack was charged for, a value in 0-1 range. - /// \param type - type of attack, one of the MWMechanics::CreatureStats::AttackType - /// enums. ignored for creature attacks. - /// (default implementation: throw an exception) + virtual void hit(const Ptr& ptr, float attackStrength, int type = -1, const Ptr& victim = Ptr(), + const osg::Vec3f& hitPosition = osg::Vec3f(), bool success = false) const; + ///< Execute a melee hit on the victim at hitPosition, using the current weapon. If the hit was successful, + ///< apply damage and process corresponding events. + /// \param attackStrength how long the attack was charged for, a value in 0-1 range. + /// \param type - type of attack, one of the MWMechanics::CreatureStats::AttackType + /// enums. ignored for creature attacks. + /// (default implementation: throw an exception) - virtual void onHit(const MWWorld::Ptr &ptr, float damage, bool ishealth, const MWWorld::Ptr &object, const MWWorld::Ptr &attacker, const osg::Vec3f &hitPosition, bool successful) const; - ///< Alerts \a ptr that it's being hit for \a damage points to health if \a ishealth is - /// true (else fatigue) by \a object (sword, arrow, etc). \a attacker specifies the - /// actor responsible for the attack, and \a successful specifies if the hit is - /// successful or not. + virtual void onHit(const MWWorld::Ptr& ptr, float damage, bool ishealth, const MWWorld::Ptr& object, + const MWWorld::Ptr& attacker, const osg::Vec3f& hitPosition, bool successful) const; + ///< Alerts \a ptr that it's being hit for \a damage points to health if \a ishealth is + /// true (else fatigue) by \a object (sword, arrow, etc). \a attacker specifies the + /// actor responsible for the attack, and \a successful specifies if the hit is + /// successful or not. - virtual void block (const Ptr& ptr) const; - ///< Play the appropriate sound for a blocked attack, depending on the currently equipped shield - /// (default implementation: throw an exception) + virtual void block(const Ptr& ptr) const; + ///< Play the appropriate sound for a blocked attack, depending on the currently equipped shield + /// (default implementation: throw an exception) - virtual std::unique_ptr activate (const Ptr& ptr, const Ptr& actor) const; - ///< Generate action for activation (default implementation: return a null action). + virtual std::unique_ptr activate(const Ptr& ptr, const Ptr& actor) const; + ///< Generate action for activation (default implementation: return a null action). - virtual std::unique_ptr use (const Ptr& ptr, bool force=false) - const; - ///< Generate action for using via inventory menu (default implementation: return a - /// null action). + virtual std::unique_ptr use(const Ptr& ptr, bool force = false) const; + ///< Generate action for using via inventory menu (default implementation: return a + /// null action). - virtual ContainerStore& getContainerStore (const Ptr& ptr) const; - ///< Return container store or throw an exception, if class does not have a - /// container store (default implementation: throw an exception) + virtual ContainerStore& getContainerStore(const Ptr& ptr) const; + ///< Return container store or throw an exception, if class does not have a + /// container store (default implementation: throw an exception) - virtual InventoryStore& getInventoryStore (const Ptr& ptr) const; - ///< Return inventory store or throw an exception, if class does not have a - /// inventory store (default implementation: throw an exception) + virtual InventoryStore& getInventoryStore(const Ptr& ptr) const; + ///< Return inventory store or throw an exception, if class does not have a + /// inventory store (default implementation: throw an exception) - virtual bool hasInventoryStore (const Ptr& ptr) const; - ///< Does this object have an inventory store, i.e. equipment slots? (default implementation: false) + virtual bool hasInventoryStore(const Ptr& ptr) const; + ///< Does this object have an inventory store, i.e. equipment slots? (default implementation: false) - virtual bool canLock (const ConstPtr& ptr) const; + virtual bool canLock(const ConstPtr& ptr) const; - virtual void setRemainingUsageTime (const Ptr& ptr, float duration) const; - ///< Sets the remaining duration of the object, such as an equippable light - /// source. (default implementation: throw an exception) + virtual void setRemainingUsageTime(const Ptr& ptr, float duration) const; + ///< Sets the remaining duration of the object, such as an equippable light + /// source. (default implementation: throw an exception) - virtual float getRemainingUsageTime (const ConstPtr& ptr) const; - ///< Returns the remaining duration of the object, such as an equippable light - /// source. (default implementation: -1, i.e. infinite) + virtual float getRemainingUsageTime(const ConstPtr& ptr) const; + ///< Returns the remaining duration of the object, such as an equippable light + /// source. (default implementation: -1, i.e. infinite) - virtual std::string_view getScript(const ConstPtr& ptr) const; - ///< Return name of the script attached to ptr (default implementation: return an empty - /// string). + virtual std::string_view getScript(const ConstPtr& ptr) const; + ///< Return name of the script attached to ptr (default implementation: return an empty + /// string). - virtual float getWalkSpeed(const Ptr& ptr) const; - virtual float getRunSpeed(const Ptr& ptr) const; - virtual float getSwimSpeed(const Ptr& ptr) const; + virtual float getWalkSpeed(const Ptr& ptr) const; + virtual float getRunSpeed(const Ptr& ptr) const; + virtual float getSwimSpeed(const Ptr& ptr) const; - /// Return maximal movement speed for the current state. - virtual float getMaxSpeed(const Ptr& ptr) const; + /// Return maximal movement speed for the current state. + virtual float getMaxSpeed(const Ptr& ptr) const; - /// Return current movement speed. - virtual float getCurrentSpeed(const Ptr& ptr) const; + /// Return current movement speed. + virtual float getCurrentSpeed(const Ptr& ptr) const; - virtual float getJump(const MWWorld::Ptr &ptr) const; - ///< Return jump velocity (not accounting for movement) + virtual float getJump(const MWWorld::Ptr& ptr) const; + ///< Return jump velocity (not accounting for movement) - virtual MWMechanics::Movement& getMovementSettings (const Ptr& ptr) const; - ///< Return desired movement. + virtual MWMechanics::Movement& getMovementSettings(const Ptr& ptr) const; + ///< Return desired movement. - virtual osg::Vec3f getRotationVector (const Ptr& ptr) const; - ///< Return desired rotations, as euler angles. Sets getMovementSettings(ptr).mRotation to zero. + virtual osg::Vec3f getRotationVector(const Ptr& ptr) const; + ///< Return desired rotations, as euler angles. Sets getMovementSettings(ptr).mRotation to zero. - virtual std::pair, bool> getEquipmentSlots (const ConstPtr& ptr) const; - ///< \return first: Return IDs of the slot this object can be equipped in; second: can object - /// stay stacked when equipped? - /// - /// Default implementation: return (empty vector, false). + virtual std::pair, bool> getEquipmentSlots(const ConstPtr& ptr) const; + ///< \return first: Return IDs of the slot this object can be equipped in; second: can object + /// stay stacked when equipped? + /// + /// Default implementation: return (empty vector, false). - virtual int getEquipmentSkill (const ConstPtr& ptr) - const; - /// Return the index of the skill this item corresponds to when equipped or -1, if there is - /// no such skill. - /// (default implementation: return -1) + virtual int getEquipmentSkill(const ConstPtr& ptr) const; + /// Return the index of the skill this item corresponds to when equipped or -1, if there is + /// no such skill. + /// (default implementation: return -1) - virtual int getValue (const ConstPtr& ptr) const; - ///< Return trade value of the object. Throws an exception, if the object can't be traded. - /// (default implementation: throws an exception) + virtual int getValue(const ConstPtr& ptr) const; + ///< Return trade value of the object. Throws an exception, if the object can't be traded. + /// (default implementation: throws an exception) - virtual float getCapacity (const MWWorld::Ptr& ptr) const; - ///< Return total weight that fits into the object. Throws an exception, if the object can't - /// hold other objects. - /// (default implementation: throws an exception) + virtual float getCapacity(const MWWorld::Ptr& ptr) const; + ///< Return total weight that fits into the object. Throws an exception, if the object can't + /// hold other objects. + /// (default implementation: throws an exception) - virtual float getEncumbrance (const MWWorld::Ptr& ptr) const; - ///< Returns total weight of objects inside this object (including modifications from magic - /// effects). Throws an exception, if the object can't hold other objects. - /// (default implementation: throws an exception) + virtual float getEncumbrance(const MWWorld::Ptr& ptr) const; + ///< Returns total weight of objects inside this object (including modifications from magic + /// effects). Throws an exception, if the object can't hold other objects. + /// (default implementation: throws an exception) - virtual float getNormalizedEncumbrance (const MWWorld::Ptr& ptr) const; - ///< Returns encumbrance re-scaled to capacity + virtual float getNormalizedEncumbrance(const MWWorld::Ptr& ptr) const; + ///< Returns encumbrance re-scaled to capacity - virtual bool consume(const MWWorld::Ptr& consumable, const MWWorld::Ptr& actor) const; - ///< Consume an item, e. g. a potion. + virtual bool consume(const MWWorld::Ptr& consumable, const MWWorld::Ptr& actor) const; + ///< Consume an item, e. g. a potion. - virtual void skillUsageSucceeded (const MWWorld::Ptr& ptr, int skill, int usageType, float extraFactor=1.f) const; - ///< Inform actor \a ptr that a skill use has succeeded. - /// - /// (default implementations: throws an exception) + virtual void skillUsageSucceeded( + const MWWorld::Ptr& ptr, int skill, int usageType, float extraFactor = 1.f) const; + ///< Inform actor \a ptr that a skill use has succeeded. + /// + /// (default implementations: throws an exception) - virtual bool isEssential (const MWWorld::ConstPtr& ptr) const; - ///< Is \a ptr essential? (i.e. may losing \a ptr make the game unwinnable) - /// - /// (default implementation: return false) + virtual bool isEssential(const MWWorld::ConstPtr& ptr) const; + ///< Is \a ptr essential? (i.e. may losing \a ptr make the game unwinnable) + /// + /// (default implementation: return false) - virtual std::string_view getUpSoundId(const ConstPtr& ptr) const; - ///< Return the up sound ID of \a ptr or throw an exception, if class does not support ID retrieval - /// (default implementation: throw an exception) + virtual std::string_view getUpSoundId(const ConstPtr& ptr) const; + ///< Return the up sound ID of \a ptr or throw an exception, if class does not support ID retrieval + /// (default implementation: throw an exception) - virtual std::string_view getDownSoundId(const ConstPtr& ptr) const; - ///< Return the down sound ID of \a ptr or throw an exception, if class does not support ID retrieval - /// (default implementation: throw an exception) + virtual std::string_view getDownSoundId(const ConstPtr& ptr) const; + ///< Return the down sound ID of \a ptr or throw an exception, if class does not support ID retrieval + /// (default implementation: throw an exception) - virtual std::string_view getSoundIdFromSndGen(const Ptr& ptr, std::string_view type) const; - ///< Returns the sound ID for \a ptr of the given soundgen \a type. + virtual std::string_view getSoundIdFromSndGen(const Ptr& ptr, std::string_view type) const; + ///< Returns the sound ID for \a ptr of the given soundgen \a type. - virtual float getArmorRating (const MWWorld::Ptr& ptr) const; - ///< @return combined armor rating of this actor + virtual float getArmorRating(const MWWorld::Ptr& ptr) const; + ///< @return combined armor rating of this actor - virtual const std::string& getInventoryIcon(const MWWorld::ConstPtr& ptr) const; - ///< Return name of inventory icon. + virtual const std::string& getInventoryIcon(const MWWorld::ConstPtr& ptr) const; + ///< Return name of inventory icon. - virtual std::string_view getEnchantment(const MWWorld::ConstPtr& ptr) const; - ///< @return the enchantment ID if the object is enchanted, otherwise an empty string - /// (default implementation: return empty string) + virtual std::string_view getEnchantment(const MWWorld::ConstPtr& ptr) const; + ///< @return the enchantment ID if the object is enchanted, otherwise an empty string + /// (default implementation: return empty string) - virtual int getEnchantmentPoints (const MWWorld::ConstPtr& ptr) const; - ///< @return the number of enchantment points available for possible enchanting + virtual int getEnchantmentPoints(const MWWorld::ConstPtr& ptr) const; + ///< @return the number of enchantment points available for possible enchanting - virtual void adjustScale(const MWWorld::ConstPtr& ptr, osg::Vec3f& scale, bool rendering) const; - /// @param rendering Indicates if the scale to adjust is for the rendering mesh, or for the collision mesh + virtual void adjustScale(const MWWorld::ConstPtr& ptr, osg::Vec3f& scale, bool rendering) const; + /// @param rendering Indicates if the scale to adjust is for the rendering mesh, or for the collision mesh - virtual bool canSell (const MWWorld::ConstPtr& item, int npcServices) const; - ///< Determine whether or not \a item can be sold to an npc with the given \a npcServices + virtual bool canSell(const MWWorld::ConstPtr& item, int npcServices) const; + ///< Determine whether or not \a item can be sold to an npc with the given \a npcServices - virtual int getServices (const MWWorld::ConstPtr& actor) const; + virtual int getServices(const MWWorld::ConstPtr& actor) const; - virtual std::string getModel(const MWWorld::ConstPtr &ptr) const; + virtual std::string getModel(const MWWorld::ConstPtr& ptr) const; - virtual bool useAnim() const; - ///< Whether or not to use animated variant of model (default false) + virtual bool useAnim() const; + ///< Whether or not to use animated variant of model (default false) - virtual void getModelsToPreload(const MWWorld::Ptr& ptr, std::vector& models) const; - ///< Get a list of models to preload that this object may use (directly or indirectly). default implementation: list getModel(). + virtual void getModelsToPreload(const MWWorld::Ptr& ptr, std::vector& models) const; + ///< Get a list of models to preload that this object may use (directly or indirectly). default implementation: + ///< list getModel(). - virtual const std::string& applyEnchantment(const MWWorld::ConstPtr& ptr, const std::string& enchId, int enchCharge, const std::string& newName) const; - ///< Creates a new record using \a ptr as template, with the given name and the given enchantment applied to it. + virtual const std::string& applyEnchantment( + const MWWorld::ConstPtr& ptr, const std::string& enchId, int enchCharge, const std::string& newName) const; + ///< Creates a new record using \a ptr as template, with the given name and the given enchantment applied to it. - virtual std::pair canBeEquipped(const MWWorld::ConstPtr& ptr, const MWWorld::Ptr& npc) const; - ///< Return 0 if player cannot equip item. 1 if can equip. 2 if it's twohanded weapon. 3 if twohanded weapon conflicts with that. - /// Second item in the pair specifies the error message + virtual std::pair canBeEquipped( + const MWWorld::ConstPtr& ptr, const MWWorld::Ptr& npc) const; + ///< Return 0 if player cannot equip item. 1 if can equip. 2 if it's twohanded weapon. 3 if twohanded weapon + ///< conflicts with that. + /// Second item in the pair specifies the error message - virtual float getWeight (const MWWorld::ConstPtr& ptr) const; + virtual float getWeight(const MWWorld::ConstPtr& ptr) const; - virtual bool isPersistent (const MWWorld::ConstPtr& ptr) const; + virtual bool isPersistent(const MWWorld::ConstPtr& ptr) const; - virtual bool isKey (const MWWorld::ConstPtr& ptr) const { return false; } + virtual bool isKey(const MWWorld::ConstPtr& ptr) const { return false; } - virtual bool isGold(const MWWorld::ConstPtr& ptr) const { return false; } + virtual bool isGold(const MWWorld::ConstPtr& ptr) const { return false; } - virtual bool isSoulGem(const MWWorld::ConstPtr& ptr) const { return false; } + virtual bool isSoulGem(const MWWorld::ConstPtr& ptr) const { return false; } - virtual bool allowTelekinesis(const MWWorld::ConstPtr& ptr) const { return true; } - ///< Return whether this class of object can be activated with telekinesis + virtual bool allowTelekinesis(const MWWorld::ConstPtr& ptr) const { return true; } + ///< Return whether this class of object can be activated with telekinesis - /// Get a blood texture suitable for \a ptr (see Blood Texture 0-2 in Morrowind.ini) - virtual int getBloodTexture (const MWWorld::ConstPtr& ptr) const; + /// Get a blood texture suitable for \a ptr (see Blood Texture 0-2 in Morrowind.ini) + virtual int getBloodTexture(const MWWorld::ConstPtr& ptr) const; - virtual Ptr copyToCell(const ConstPtr &ptr, CellStore &cell, int count) const; + virtual Ptr copyToCell(const ConstPtr& ptr, CellStore& cell, int count) const; - virtual Ptr copyToCell(const ConstPtr &ptr, CellStore &cell, const ESM::Position &pos, int count) const; + virtual Ptr copyToCell(const ConstPtr& ptr, CellStore& cell, const ESM::Position& pos, int count) const; - virtual bool isActivator() const { - return false; - } + virtual bool isActivator() const { return false; } - virtual bool isActor() const { - return false; - } + virtual bool isActor() const { return false; } - virtual bool isNpc() const { - return false; - } + virtual bool isNpc() const { return false; } - virtual bool isDoor() const { - return false; - } + virtual bool isDoor() const { return false; } - virtual bool isBipedal(const MWWorld::ConstPtr& ptr) const; - virtual bool canFly(const MWWorld::ConstPtr& ptr) const; - virtual bool canSwim(const MWWorld::ConstPtr& ptr) const; - virtual bool canWalk(const MWWorld::ConstPtr& ptr) const; - bool isPureWaterCreature(const MWWorld::ConstPtr& ptr) const; - bool isPureFlyingCreature(const MWWorld::ConstPtr& ptr) const; - bool isPureLandCreature(const MWWorld::Ptr& ptr) const; - bool isMobile(const MWWorld::Ptr& ptr) const; + virtual bool isBipedal(const MWWorld::ConstPtr& ptr) const; + virtual bool canFly(const MWWorld::ConstPtr& ptr) const; + virtual bool canSwim(const MWWorld::ConstPtr& ptr) const; + virtual bool canWalk(const MWWorld::ConstPtr& ptr) const; + bool isPureWaterCreature(const MWWorld::ConstPtr& ptr) const; + bool isPureFlyingCreature(const MWWorld::ConstPtr& ptr) const; + bool isPureLandCreature(const MWWorld::Ptr& ptr) const; + bool isMobile(const MWWorld::Ptr& ptr) const; - virtual float getSkill(const MWWorld::Ptr& ptr, int skill) const; + virtual float getSkill(const MWWorld::Ptr& ptr, int skill) const; - virtual void readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state) - const; - ///< Read additional state from \a state into \a ptr. + virtual void readAdditionalState(const MWWorld::Ptr& ptr, const ESM::ObjectState& state) const; + ///< Read additional state from \a state into \a ptr. - virtual void writeAdditionalState (const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) - const; - ///< Write additional state from \a ptr into \a state. + virtual void writeAdditionalState(const MWWorld::ConstPtr& ptr, ESM::ObjectState& state) const; + ///< Write additional state from \a ptr into \a state. - static const Class& get (unsigned int key); - ///< If there is no class for this \a key, an exception is thrown. + static const Class& get(unsigned int key); + ///< If there is no class for this \a key, an exception is thrown. - static void registerClass(Class& instance); + static void registerClass(Class& instance); - virtual int getBaseGold(const MWWorld::ConstPtr& ptr) const; + virtual int getBaseGold(const MWWorld::ConstPtr& ptr) const; - virtual bool isClass(const MWWorld::ConstPtr& ptr, std::string_view className) const; + virtual bool isClass(const MWWorld::ConstPtr& ptr, std::string_view className) const; - virtual DoorState getDoorState (const MWWorld::ConstPtr &ptr) const; - /// This does not actually cause the door to move. Use World::activateDoor instead. - virtual void setDoorState (const MWWorld::Ptr &ptr, DoorState state) const; + virtual DoorState getDoorState(const MWWorld::ConstPtr& ptr) const; + /// This does not actually cause the door to move. Use World::activateDoor instead. + virtual void setDoorState(const MWWorld::Ptr& ptr, DoorState state) const; - virtual void respawn (const MWWorld::Ptr& ptr) const {} + virtual void respawn(const MWWorld::Ptr& ptr) const {} - /// Returns sound id - virtual std::string_view getSound(const MWWorld::ConstPtr& ptr) const; + /// Returns sound id + virtual std::string_view getSound(const MWWorld::ConstPtr& ptr) const; - virtual int getBaseFightRating (const MWWorld::ConstPtr& ptr) const; + virtual int getBaseFightRating(const MWWorld::ConstPtr& ptr) const; - virtual std::string_view getPrimaryFaction(const MWWorld::ConstPtr& ptr) const; - virtual int getPrimaryFactionRank (const MWWorld::ConstPtr& ptr) const; + virtual std::string_view getPrimaryFaction(const MWWorld::ConstPtr& ptr) const; + virtual int getPrimaryFactionRank(const MWWorld::ConstPtr& ptr) const; - /// Get the effective armor rating, factoring in the actor's skills, for the given armor. - virtual float getEffectiveArmorRating(const MWWorld::ConstPtr& armor, const MWWorld::Ptr& actor) const; + /// Get the effective armor rating, factoring in the actor's skills, for the given armor. + virtual float getEffectiveArmorRating(const MWWorld::ConstPtr& armor, const MWWorld::Ptr& actor) const; - virtual osg::Vec4f getEnchantmentColor(const MWWorld::ConstPtr& item) const; + virtual osg::Vec4f getEnchantmentColor(const MWWorld::ConstPtr& item) const; - virtual void setBaseAISetting(const std::string& id, MWMechanics::AiSetting setting, int value) const; + virtual void setBaseAISetting(const std::string& id, MWMechanics::AiSetting setting, int value) const; - virtual void modifyBaseInventory(std::string_view actorId, std::string_view itemId, int amount) const; + virtual void modifyBaseInventory(std::string_view actorId, std::string_view itemId, int amount) const; }; } diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index 91b0c9e9cb..1124267caa 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -5,35 +5,35 @@ #include #include +#include #include #include #include -#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwmechanics/actorutil.hpp" #include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/levelledlist.hpp" -#include "../mwmechanics/actorutil.hpp" #include "../mwmechanics/recharge.hpp" -#include "manualref.hpp" -#include "refdata.hpp" #include "class.hpp" +#include "esmstore.hpp" #include "localscripts.hpp" +#include "manualref.hpp" #include "player.hpp" -#include "esmstore.hpp" +#include "refdata.hpp" namespace { void addScripts(MWWorld::ContainerStore& store, MWWorld::CellStore* cell) { auto& scripts = MWBase::Environment::get().getWorld()->getLocalScripts(); - for(const auto&& ptr : store) + for (const auto&& ptr : store) { std::string_view script = ptr.getClass().getScript(ptr); - if(!script.empty()) + if (!script.empty()) { MWWorld::Ptr item = ptr; item.mCell = cell; @@ -42,8 +42,8 @@ namespace } } - template - float getTotalWeight (const MWWorld::CellRefList& cellRefList) + template + float getTotalWeight(const MWWorld::CellRefList& cellRefList) { float sum = 0; @@ -56,7 +56,7 @@ namespace return sum; } - template + template MWWorld::Ptr searchId(MWWorld::CellRefList& list, std::string_view id, MWWorld::ContainerStore* store) { store->resolve(); @@ -66,7 +66,7 @@ namespace if (Misc::StringUtils::ciEqual(liveCellRef.mBase->mId, id) && liveCellRef.mData.getCount()) { MWWorld::Ptr ptr(&liveCellRef, nullptr); - ptr.setContainerStore (store); + ptr.setContainerStore(store); return ptr; } } @@ -81,49 +81,50 @@ MWWorld::ResolutionListener::~ResolutionListener() { mStore.unresolve(); } - catch(const std::exception& e) + catch (const std::exception& e) { Log(Debug::Error) << "Failed to clear temporary container contents: " << e.what(); } } -template -MWWorld::ContainerStoreIterator MWWorld::ContainerStore::getState (CellRefList& collection, - const ESM::ObjectState& state) +template +MWWorld::ContainerStoreIterator MWWorld::ContainerStore::getState( + CellRefList& collection, const ESM::ObjectState& state) { - if (!LiveCellRef::checkState (state)) - return ContainerStoreIterator (this); // not valid anymore with current content files -> skip + if (!LiveCellRef::checkState(state)) + return ContainerStoreIterator(this); // not valid anymore with current content files -> skip - const T *record = MWBase::Environment::get().getWorld()->getStore(). - get().search (state.mRef.mRefID); + const T* record = MWBase::Environment::get().getWorld()->getStore().get().search(state.mRef.mRefID); if (!record) - return ContainerStoreIterator (this); + return ContainerStoreIterator(this); - LiveCellRef ref (record); - ref.load (state); - collection.mList.push_back (ref); + LiveCellRef ref(record); + ref.load(state); + collection.mList.push_back(ref); - return ContainerStoreIterator (this, --collection.mList.end()); + return ContainerStoreIterator(this, --collection.mList.end()); } -void MWWorld::ContainerStore::storeEquipmentState(const MWWorld::LiveCellRefBase &ref, int index, ESM::InventoryState &inventory) const +void MWWorld::ContainerStore::storeEquipmentState( + const MWWorld::LiveCellRefBase& ref, int index, ESM::InventoryState& inventory) const { } -void MWWorld::ContainerStore::readEquipmentState(const MWWorld::ContainerStoreIterator& iter, int index, const ESM::InventoryState &inventory) +void MWWorld::ContainerStore::readEquipmentState( + const MWWorld::ContainerStoreIterator& iter, int index, const ESM::InventoryState& inventory) { } -template -void MWWorld::ContainerStore::storeState (const LiveCellRef& ref, ESM::ObjectState& state) const +template +void MWWorld::ContainerStore::storeState(const LiveCellRef& ref, ESM::ObjectState& state) const { - ref.save (state); + ref.save(state); } -template -void MWWorld::ContainerStore::storeStates (const CellRefList& collection, - ESM::InventoryState& inventory, int& index, bool equipable) const +template +void MWWorld::ContainerStore::storeStates( + const CellRefList& collection, ESM::InventoryState& inventory, int& index, bool equipable) const { for (const LiveCellRef& liveCellRef : collection.mList) { @@ -143,26 +144,28 @@ const std::string_view MWWorld::ContainerStore::sGoldId = "gold_001"; MWWorld::ContainerStore::ContainerStore() : mListener(nullptr) , mRechargingItemsUpToDate(false) - , mCachedWeight (0) - , mWeightUpToDate (false) + , mCachedWeight(0) + , mWeightUpToDate(false) , mModified(false) , mResolved(false) , mSeed() - , mPtr() {} + , mPtr() +{ +} MWWorld::ContainerStore::~ContainerStore() {} -MWWorld::ConstContainerStoreIterator MWWorld::ContainerStore::cbegin (int mask) const +MWWorld::ConstContainerStoreIterator MWWorld::ContainerStore::cbegin(int mask) const { - return ConstContainerStoreIterator (mask, this); + return ConstContainerStoreIterator(mask, this); } MWWorld::ConstContainerStoreIterator MWWorld::ContainerStore::cend() const { - return ConstContainerStoreIterator (this); + return ConstContainerStoreIterator(this); } -MWWorld::ConstContainerStoreIterator MWWorld::ContainerStore::begin (int mask) const +MWWorld::ConstContainerStoreIterator MWWorld::ContainerStore::begin(int mask) const { return cbegin(mask); } @@ -172,19 +175,19 @@ MWWorld::ConstContainerStoreIterator MWWorld::ContainerStore::end() const return cend(); } -MWWorld::ContainerStoreIterator MWWorld::ContainerStore::begin (int mask) +MWWorld::ContainerStoreIterator MWWorld::ContainerStore::begin(int mask) { - return ContainerStoreIterator (mask, this); + return ContainerStoreIterator(mask, this); } MWWorld::ContainerStoreIterator MWWorld::ContainerStore::end() { - return ContainerStoreIterator (this); + return ContainerStoreIterator(this); } int MWWorld::ContainerStore::count(std::string_view id) const { - int total=0; + int total = 0; for (const auto&& iter : *this) if (Misc::StringUtils::ciEqual(iter.getCellRef().getRefId(), id)) total += iter.getRefData().getCount(); @@ -196,13 +199,12 @@ MWWorld::ContainerStoreListener* MWWorld::ContainerStore::getContListener() cons return mListener; } - void MWWorld::ContainerStore::setContListener(MWWorld::ContainerStoreListener* listener) { mListener = listener; } -MWWorld::ContainerStoreIterator MWWorld::ContainerStore::unstack(const Ptr &ptr, const Ptr& container, int count) +MWWorld::ContainerStoreIterator MWWorld::ContainerStore::unstack(const Ptr& ptr, const Ptr& container, int count) { resolve(); if (ptr.getRefData().getCount() <= count) @@ -212,7 +214,7 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::unstack(const Ptr &ptr, if (!script.empty()) MWBase::Environment::get().getWorld()->getLocalScripts().add(script, *it); - remove(ptr, ptr.getRefData().getCount()-count, container); + remove(ptr, ptr.getRefData().getCount() - count, container); return it; } @@ -221,7 +223,7 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::restack(const MWWorld:: { resolve(); MWWorld::ContainerStoreIterator retval = end(); - for (MWWorld::ContainerStoreIterator iter (begin()); iter != end(); ++iter) + for (MWWorld::ContainerStoreIterator iter(begin()); iter != end(); ++iter) { if (item == *iter) { @@ -233,11 +235,12 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::restack(const MWWorld:: if (retval == end()) throw std::runtime_error("item is not from this container"); - for (MWWorld::ContainerStoreIterator iter (begin()); iter != end(); ++iter) + for (MWWorld::ContainerStoreIterator iter(begin()); iter != end(); ++iter) { if (stacks(*iter, item)) { - iter->getRefData().setCount(addItems(iter->getRefData().getCount(false), item.getRefData().getCount(false))); + iter->getRefData().setCount( + addItems(iter->getRefData().getCount(false), item.getRefData().getCount(false))); item.getRefData().setCount(0); retval = iter; break; @@ -257,11 +260,14 @@ bool MWWorld::ContainerStore::stacks(const ConstPtr& ptr1, const ConstPtr& ptr2) // If it has an enchantment, don't stack when some of the charge is already used if (!ptr1.getClass().getEnchantment(ptr1).empty()) { - const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get().find( - ptr1.getClass().getEnchantment(ptr1)); + const ESM::Enchantment* enchantment + = MWBase::Environment::get().getWorld()->getStore().get().find( + ptr1.getClass().getEnchantment(ptr1)); float maxCharge = static_cast(enchantment->mData.mCharge); - float enchantCharge1 = ptr1.getCellRef().getEnchantmentCharge() == -1 ? maxCharge : ptr1.getCellRef().getEnchantmentCharge(); - float enchantCharge2 = ptr2.getCellRef().getEnchantmentCharge() == -1 ? maxCharge : ptr2.getCellRef().getEnchantmentCharge(); + float enchantCharge1 + = ptr1.getCellRef().getEnchantmentCharge() == -1 ? maxCharge : ptr1.getCellRef().getEnchantmentCharge(); + float enchantCharge2 + = ptr2.getCellRef().getEnchantmentCharge() == -1 ? maxCharge : ptr2.getCellRef().getEnchantmentCharge(); if (enchantCharge1 != maxCharge || enchantCharge2 != maxCharge) return false; } @@ -276,20 +282,21 @@ bool MWWorld::ContainerStore::stacks(const ConstPtr& ptr1, const ConstPtr& ptr2) && cls2.getScript(ptr2).empty() // item that is already partly used up never stacks - && (!cls1.hasItemHealth(ptr1) || ( - cls1.getItemHealth(ptr1) == cls1.getItemMaxHealth(ptr1) - && cls2.getItemHealth(ptr2) == cls2.getItemMaxHealth(ptr2))); + && (!cls1.hasItemHealth(ptr1) + || (cls1.getItemHealth(ptr1) == cls1.getItemMaxHealth(ptr1) + && cls2.getItemHealth(ptr2) == cls2.getItemMaxHealth(ptr2))); } -MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add(std::string_view id, int count, const Ptr &actorPtr) +MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add(std::string_view id, int count, const Ptr& actorPtr) { MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), id, count); return add(ref.getPtr(), count, actorPtr); } -MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& itemPtr, int count, const Ptr& actorPtr, bool /*allowAutoEquip*/, bool resolve) +MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add( + const Ptr& itemPtr, int count, const Ptr& actorPtr, bool /*allowAutoEquip*/, bool resolve) { - Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); + Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWWorld::ContainerStoreIterator it = addImp(itemPtr, count, resolve); @@ -297,7 +304,8 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& itemPtr MWWorld::Ptr item = *it; // we may have copied an item from the world, so reset a few things first - item.getRefData().setBaseNode(nullptr); // Especially important, otherwise scripts on the item could think that it's actually in a cell + item.getRefData().setBaseNode( + nullptr); // Especially important, otherwise scripts on the item could think that it's actually in a cell ESM::Position pos; pos.rot[0] = 0; pos.rot[1] = 0; @@ -349,22 +357,22 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& itemPtr return it; } -MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addImp (const Ptr& ptr, int count, bool markModified) +MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addImp(const Ptr& ptr, int count, bool markModified) { - if(markModified) + if (markModified) resolve(); int type = getType(ptr); - const MWWorld::ESMStore &esmStore = - MWBase::Environment::get().getWorld()->getStore(); + const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); // gold needs special handling: when it is inserted into a container, the base object automatically becomes Gold_001 - // this ensures that gold piles of different sizes stack with each other (also, several scripts rely on Gold_001 for detecting player gold) - if(ptr.getClass().isGold(ptr)) + // this ensures that gold piles of different sizes stack with each other (also, several scripts rely on Gold_001 for + // detecting player gold) + if (ptr.getClass().isGold(ptr)) { int realCount = count * ptr.getClass().getValue(ptr); - for (MWWorld::ContainerStoreIterator iter (begin(type)); iter!=end(); ++iter) + for (MWWorld::ContainerStoreIterator iter(begin(type)); iter != end(); ++iter) { if (Misc::StringUtils::ciEqual(iter->getCellRef().getRefId(), MWWorld::ContainerStore::sGoldId)) { @@ -379,7 +387,7 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addImp (const Ptr& ptr, } // determine whether to stack or not - for (MWWorld::ContainerStoreIterator iter (begin(type)); iter!=end(); ++iter) + for (MWWorld::ContainerStoreIterator iter(begin(type)); iter != end(); ++iter) { if (stacks(*iter, ptr)) { @@ -394,24 +402,60 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addImp (const Ptr& ptr, return addNewStack(ptr, count); } -MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addNewStack (const ConstPtr& ptr, int count) +MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addNewStack(const ConstPtr& ptr, int count) { ContainerStoreIterator it = begin(); switch (getType(ptr)) { - case Type_Potion: potions.mList.push_back (*ptr.get()); it = ContainerStoreIterator(this, --potions.mList.end()); break; - case Type_Apparatus: appas.mList.push_back (*ptr.get()); it = ContainerStoreIterator(this, --appas.mList.end()); break; - case Type_Armor: armors.mList.push_back (*ptr.get()); it = ContainerStoreIterator(this, --armors.mList.end()); break; - case Type_Book: books.mList.push_back (*ptr.get()); it = ContainerStoreIterator(this, --books.mList.end()); break; - case Type_Clothing: clothes.mList.push_back (*ptr.get()); it = ContainerStoreIterator(this, --clothes.mList.end()); break; - case Type_Ingredient: ingreds.mList.push_back (*ptr.get()); it = ContainerStoreIterator(this, --ingreds.mList.end()); break; - case Type_Light: lights.mList.push_back (*ptr.get()); it = ContainerStoreIterator(this, --lights.mList.end()); break; - case Type_Lockpick: lockpicks.mList.push_back (*ptr.get()); it = ContainerStoreIterator(this, --lockpicks.mList.end()); break; - case Type_Miscellaneous: miscItems.mList.push_back (*ptr.get()); it = ContainerStoreIterator(this, --miscItems.mList.end()); break; - case Type_Probe: probes.mList.push_back (*ptr.get()); it = ContainerStoreIterator(this, --probes.mList.end()); break; - case Type_Repair: repairs.mList.push_back (*ptr.get()); it = ContainerStoreIterator(this, --repairs.mList.end()); break; - case Type_Weapon: weapons.mList.push_back (*ptr.get()); it = ContainerStoreIterator(this, --weapons.mList.end()); break; + case Type_Potion: + potions.mList.push_back(*ptr.get()); + it = ContainerStoreIterator(this, --potions.mList.end()); + break; + case Type_Apparatus: + appas.mList.push_back(*ptr.get()); + it = ContainerStoreIterator(this, --appas.mList.end()); + break; + case Type_Armor: + armors.mList.push_back(*ptr.get()); + it = ContainerStoreIterator(this, --armors.mList.end()); + break; + case Type_Book: + books.mList.push_back(*ptr.get()); + it = ContainerStoreIterator(this, --books.mList.end()); + break; + case Type_Clothing: + clothes.mList.push_back(*ptr.get()); + it = ContainerStoreIterator(this, --clothes.mList.end()); + break; + case Type_Ingredient: + ingreds.mList.push_back(*ptr.get()); + it = ContainerStoreIterator(this, --ingreds.mList.end()); + break; + case Type_Light: + lights.mList.push_back(*ptr.get()); + it = ContainerStoreIterator(this, --lights.mList.end()); + break; + case Type_Lockpick: + lockpicks.mList.push_back(*ptr.get()); + it = ContainerStoreIterator(this, --lockpicks.mList.end()); + break; + case Type_Miscellaneous: + miscItems.mList.push_back(*ptr.get()); + it = ContainerStoreIterator(this, --miscItems.mList.end()); + break; + case Type_Probe: + probes.mList.push_back(*ptr.get()); + it = ContainerStoreIterator(this, --probes.mList.end()); + break; + case Type_Repair: + repairs.mList.push_back(*ptr.get()); + it = ContainerStoreIterator(this, --repairs.mList.end()); + break; + case Type_Weapon: + weapons.mList.push_back(*ptr.get()); + it = ContainerStoreIterator(this, --weapons.mList.end()); + break; } it->getRefData().setCount(count); @@ -446,23 +490,26 @@ void MWWorld::ContainerStore::updateRechargingItems() std::string_view enchantmentId = it->getClass().getEnchantment(*it); if (!enchantmentId.empty()) { - const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get().search(enchantmentId); + const ESM::Enchantment* enchantment + = MWBase::Environment::get().getWorld()->getStore().get().search(enchantmentId); if (!enchantment) { - Log(Debug::Warning) << "Warning: Can't find enchantment '" << enchantmentId << "' on item " << it->getCellRef().getRefId(); + Log(Debug::Warning) << "Warning: Can't find enchantment '" << enchantmentId << "' on item " + << it->getCellRef().getRefId(); continue; } if (enchantment->mData.mType == ESM::Enchantment::WhenUsed - || enchantment->mData.mType == ESM::Enchantment::WhenStrikes) + || enchantment->mData.mType == ESM::Enchantment::WhenStrikes) mRechargingItems.emplace_back(it, static_cast(enchantment->mData.mCharge)); } } } -int MWWorld::ContainerStore::remove(std::string_view itemId, int count, const Ptr& actor, bool equipReplacement, bool resolveFirst) +int MWWorld::ContainerStore::remove( + std::string_view itemId, int count, const Ptr& actor, bool equipReplacement, bool resolveFirst) { - if(resolveFirst) + if (resolveFirst) resolve(); int toRemove = count; @@ -487,10 +534,11 @@ bool MWWorld::ContainerStore::hasVisibleItems() const return false; } -int MWWorld::ContainerStore::remove(const Ptr& item, int count, const Ptr& actor, bool equipReplacement, bool resolveFirst) +int MWWorld::ContainerStore::remove( + const Ptr& item, int count, const Ptr& actor, bool equipReplacement, bool resolveFirst) { assert(this == item.getContainerStore()); - if(resolveFirst) + if (resolveFirst) resolve(); int toRemove = count; @@ -517,7 +565,8 @@ int MWWorld::ContainerStore::remove(const Ptr& item, int count, const Ptr& actor return count - toRemove; } -void MWWorld::ContainerStore::fill (const ESM::InventoryList& items, const std::string& owner, Misc::Rng::Generator& prng) +void MWWorld::ContainerStore::fill( + const ESM::InventoryList& items, const std::string& owner, Misc::Rng::Generator& prng) { for (const ESM::ContItem& iter : items.mList) { @@ -529,7 +578,8 @@ void MWWorld::ContainerStore::fill (const ESM::InventoryList& items, const std:: mResolved = true; } -void MWWorld::ContainerStore::fillNonRandom (const ESM::InventoryList& items, const std::string& owner, unsigned int seed) +void MWWorld::ContainerStore::fillNonRandom( + const ESM::InventoryList& items, const std::string& owner, unsigned int seed) { mSeed = seed; for (const ESM::ContItem& iter : items.mList) @@ -542,13 +592,14 @@ void MWWorld::ContainerStore::fillNonRandom (const ESM::InventoryList& items, co mResolved = false; } -void MWWorld::ContainerStore::addInitialItem(std::string_view id, const std::string& owner, int count, - Misc::Rng::Generator* prng, bool topLevel) +void MWWorld::ContainerStore::addInitialItem( + std::string_view id, const std::string& owner, int count, Misc::Rng::Generator* prng, bool topLevel) { - if (count == 0) return; //Don't restock with nothing. + if (count == 0) + return; // Don't restock with nothing. try { - ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), id, count); + ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), id, count); if (ref.getPtr().getClass().getScript(ref.getPtr()).empty()) { addInitialItemImp(ref.getPtr(), owner, count, prng, topLevel); @@ -566,18 +617,18 @@ void MWWorld::ContainerStore::addInitialItem(std::string_view id, const std::str } } -void MWWorld::ContainerStore::addInitialItemImp(const MWWorld::Ptr& ptr, const std::string& owner, int count, - Misc::Rng::Generator* prng, bool topLevel) +void MWWorld::ContainerStore::addInitialItemImp( + const MWWorld::Ptr& ptr, const std::string& owner, int count, Misc::Rng::Generator* prng, bool topLevel) { - if (ptr.getType()==ESM::ItemLevList::sRecordId) + if (ptr.getType() == ESM::ItemLevList::sRecordId) { - if(!prng) + if (!prng) return; const ESM::ItemLevList* levItemList = ptr.get()->mBase; if (topLevel && std::abs(count) > 1 && levItemList->mFlags & ESM::ItemLevList::Each) { - for (int i=0; i 0 ? 1 : -1, prng, true); return; } @@ -592,14 +643,14 @@ void MWWorld::ContainerStore::addInitialItemImp(const MWWorld::Ptr& ptr, const s else { ptr.getCellRef().setOwner(owner); - addImp (ptr, count, false); + addImp(ptr, count, false); } } void MWWorld::ContainerStore::clear() { for (auto&& iter : *this) - iter.getRefData().setCount (0); + iter.getRefData().setCount(0); flagAsModified(); mModified = true; @@ -618,11 +669,11 @@ bool MWWorld::ContainerStore::isResolved() const void MWWorld::ContainerStore::resolve() { - if(!mResolved && !mPtr.isEmpty()) + if (!mResolved && !mPtr.isEmpty()) { - for(const auto&& ptr : *this) + for (const auto&& ptr : *this) ptr.getRefData().setCount(0); - Misc::Rng::Generator prng{mSeed}; + Misc::Rng::Generator prng{ mSeed }; fill(mPtr.get()->mBase->mInventory, "", prng); addScripts(*this, mPtr.mCell); } @@ -631,23 +682,23 @@ void MWWorld::ContainerStore::resolve() MWWorld::ResolutionHandle MWWorld::ContainerStore::resolveTemporarily() { - if(mModified) + if (mModified) return {}; std::shared_ptr listener = mResolutionListener.lock(); - if(!listener) + if (!listener) { listener = std::make_shared(*this); mResolutionListener = listener; } - if(!mResolved && !mPtr.isEmpty()) + if (!mResolved && !mPtr.isEmpty()) { - for(const auto&& ptr : *this) + for (const auto&& ptr : *this) ptr.getRefData().setCount(0); - Misc::Rng::Generator prng{mSeed}; + Misc::Rng::Generator prng{ mSeed }; fill(mPtr.get()->mBase->mInventory, "", prng); addScripts(*this, mPtr.mCell); } - return {listener}; + return { listener }; } void MWWorld::ContainerStore::unresolve() @@ -657,7 +708,7 @@ void MWWorld::ContainerStore::unresolve() if (mResolved && !mPtr.isEmpty()) { - for(const auto&& ptr : *this) + for (const auto&& ptr : *this) ptr.getRefData().setCount(0); fillNonRandom(mPtr.get()->mBase->mInventory, "", mSeed); addScripts(*this, mPtr.mCell); @@ -671,18 +722,18 @@ float MWWorld::ContainerStore::getWeight() const { mCachedWeight = 0; - mCachedWeight += getTotalWeight (potions); - mCachedWeight += getTotalWeight (appas); - mCachedWeight += getTotalWeight (armors); - mCachedWeight += getTotalWeight (books); - mCachedWeight += getTotalWeight (clothes); - mCachedWeight += getTotalWeight (ingreds); - mCachedWeight += getTotalWeight (lights); - mCachedWeight += getTotalWeight (lockpicks); - mCachedWeight += getTotalWeight (miscItems); - mCachedWeight += getTotalWeight (probes); - mCachedWeight += getTotalWeight (repairs); - mCachedWeight += getTotalWeight (weapons); + mCachedWeight += getTotalWeight(potions); + mCachedWeight += getTotalWeight(appas); + mCachedWeight += getTotalWeight(armors); + mCachedWeight += getTotalWeight(books); + mCachedWeight += getTotalWeight(clothes); + mCachedWeight += getTotalWeight(ingreds); + mCachedWeight += getTotalWeight(lights); + mCachedWeight += getTotalWeight(lockpicks); + mCachedWeight += getTotalWeight(miscItems); + mCachedWeight += getTotalWeight(probes); + mCachedWeight += getTotalWeight(repairs); + mCachedWeight += getTotalWeight(weapons); mWeightUpToDate = true; } @@ -690,49 +741,49 @@ float MWWorld::ContainerStore::getWeight() const return mCachedWeight; } -int MWWorld::ContainerStore::getType (const ConstPtr& ptr) +int MWWorld::ContainerStore::getType(const ConstPtr& ptr) { if (ptr.isEmpty()) - throw std::runtime_error ("can't put a non-existent object into a container"); + throw std::runtime_error("can't put a non-existent object into a container"); - if (ptr.getType()==ESM::Potion::sRecordId) + if (ptr.getType() == ESM::Potion::sRecordId) return Type_Potion; - if (ptr.getType()==ESM::Apparatus::sRecordId) + if (ptr.getType() == ESM::Apparatus::sRecordId) return Type_Apparatus; - if (ptr.getType()==ESM::Armor::sRecordId) + if (ptr.getType() == ESM::Armor::sRecordId) return Type_Armor; - if (ptr.getType()==ESM::Book::sRecordId) + if (ptr.getType() == ESM::Book::sRecordId) return Type_Book; - if (ptr.getType()==ESM::Clothing::sRecordId) + if (ptr.getType() == ESM::Clothing::sRecordId) return Type_Clothing; - if (ptr.getType()==ESM::Ingredient::sRecordId) + if (ptr.getType() == ESM::Ingredient::sRecordId) return Type_Ingredient; - if (ptr.getType()==ESM::Light::sRecordId) + if (ptr.getType() == ESM::Light::sRecordId) return Type_Light; - if (ptr.getType()==ESM::Lockpick::sRecordId) + if (ptr.getType() == ESM::Lockpick::sRecordId) return Type_Lockpick; - if (ptr.getType()==ESM::Miscellaneous::sRecordId) + if (ptr.getType() == ESM::Miscellaneous::sRecordId) return Type_Miscellaneous; - if (ptr.getType()==ESM::Probe::sRecordId) + if (ptr.getType() == ESM::Probe::sRecordId) return Type_Probe; - if (ptr.getType()==ESM::Repair::sRecordId) + if (ptr.getType() == ESM::Repair::sRecordId) return Type_Repair; - if (ptr.getType()==ESM::Weapon::sRecordId) + if (ptr.getType() == ESM::Weapon::sRecordId) return Type_Weapon; - throw std::runtime_error("Object '" + ptr.getCellRef().getRefId() + "' of type " + - std::string(ptr.getTypeDescription()) + " can not be placed into a container"); + throw std::runtime_error("Object '" + ptr.getCellRef().getRefId() + "' of type " + + std::string(ptr.getTypeDescription()) + " can not be placed into a container"); } MWWorld::Ptr MWWorld::ContainerStore::findReplacement(const std::string& id) @@ -746,9 +797,7 @@ MWWorld::Ptr MWWorld::ContainerStore::findReplacement(const std::string& id) { // Prefer the stack with the lowest remaining uses // Try to get item with zero durability only if there are no other items found - if (item.isEmpty() || - (iterHealth > 0 && iterHealth < itemHealth) || - (itemHealth <= 0 && iterHealth > 0)) + if (item.isEmpty() || (iterHealth > 0 && iterHealth < itemHealth) || (itemHealth <= 0 && iterHealth > 0)) { item = iter; itemHealth = iterHealth; @@ -763,73 +812,73 @@ MWWorld::Ptr MWWorld::ContainerStore::search(std::string_view id) { resolve(); { - Ptr ptr = searchId (potions, id, this); + Ptr ptr = searchId(potions, id, this); if (!ptr.isEmpty()) return ptr; } { - Ptr ptr = searchId (appas, id, this); + Ptr ptr = searchId(appas, id, this); if (!ptr.isEmpty()) return ptr; } { - Ptr ptr = searchId (armors, id, this); + Ptr ptr = searchId(armors, id, this); if (!ptr.isEmpty()) return ptr; } { - Ptr ptr = searchId (books, id, this); + Ptr ptr = searchId(books, id, this); if (!ptr.isEmpty()) return ptr; } { - Ptr ptr = searchId (clothes, id, this); + Ptr ptr = searchId(clothes, id, this); if (!ptr.isEmpty()) return ptr; } { - Ptr ptr = searchId (ingreds, id, this); + Ptr ptr = searchId(ingreds, id, this); if (!ptr.isEmpty()) return ptr; } { - Ptr ptr = searchId (lights, id, this); + Ptr ptr = searchId(lights, id, this); if (!ptr.isEmpty()) return ptr; } { - Ptr ptr = searchId (lockpicks, id, this); + Ptr ptr = searchId(lockpicks, id, this); if (!ptr.isEmpty()) return ptr; } { - Ptr ptr = searchId (miscItems, id, this); + Ptr ptr = searchId(miscItems, id, this); if (!ptr.isEmpty()) return ptr; } { - Ptr ptr = searchId (probes, id, this); + Ptr ptr = searchId(probes, id, this); if (!ptr.isEmpty()) return ptr; } { - Ptr ptr = searchId (repairs, id, this); + Ptr ptr = searchId(repairs, id, this); if (!ptr.isEmpty()) return ptr; } { - Ptr ptr = searchId (weapons, id, this); + Ptr ptr = searchId(weapons, id, this); if (!ptr.isEmpty()) return ptr; } @@ -840,7 +889,7 @@ MWWorld::Ptr MWWorld::ContainerStore::search(std::string_view id) int MWWorld::ContainerStore::addItems(int count1, int count2) { int sum = std::abs(count1) + std::abs(count2); - if(count1 < 0 || count2 < 0) + if (count1 < 0 || count2 < 0) return -sum; return sum; } @@ -848,31 +897,31 @@ int MWWorld::ContainerStore::addItems(int count1, int count2) int MWWorld::ContainerStore::subtractItems(int count1, int count2) { int sum = std::abs(count1) - std::abs(count2); - if(count1 < 0 || count2 < 0) + if (count1 < 0 || count2 < 0) return -sum; return sum; } -void MWWorld::ContainerStore::writeState (ESM::InventoryState& state) const +void MWWorld::ContainerStore::writeState(ESM::InventoryState& state) const { state.mItems.clear(); int index = 0; - storeStates (potions, state, index); - storeStates (appas, state, index); - storeStates (armors, state, index, true); - storeStates (books, state, index, true); // not equipable as such, but for selectedEnchantItem - storeStates (clothes, state, index, true); - storeStates (ingreds, state, index); - storeStates (lockpicks, state, index, true); - storeStates (miscItems, state, index); - storeStates (probes, state, index, true); - storeStates (repairs, state, index); - storeStates (weapons, state, index, true); - storeStates (lights, state, index, true); -} - -void MWWorld::ContainerStore::readState (const ESM::InventoryState& inventory) + storeStates(potions, state, index); + storeStates(appas, state, index); + storeStates(armors, state, index, true); + storeStates(books, state, index, true); // not equipable as such, but for selectedEnchantItem + storeStates(clothes, state, index, true); + storeStates(ingreds, state, index); + storeStates(lockpicks, state, index, true); + storeStates(miscItems, state, index); + storeStates(probes, state, index, true); + storeStates(repairs, state, index); + storeStates(weapons, state, index, true); + storeStates(lights, state, index, true); +} + +void MWWorld::ContainerStore::readState(const ESM::InventoryState& inventory) { clear(); mModified = true; @@ -887,20 +936,45 @@ void MWWorld::ContainerStore::readState (const ESM::InventoryState& inventory) switch (type) { - case ESM::REC_ALCH: getState (potions, state); break; - case ESM::REC_APPA: getState (appas, state); break; - case ESM::REC_ARMO: readEquipmentState (getState (armors, state), thisIndex, inventory); break; - case ESM::REC_BOOK: readEquipmentState (getState (books, state), thisIndex, inventory); break; // not equipable as such, but for selectedEnchantItem - case ESM::REC_CLOT: readEquipmentState (getState (clothes, state), thisIndex, inventory); break; - case ESM::REC_INGR: getState (ingreds, state); break; - case ESM::REC_LOCK: readEquipmentState (getState (lockpicks, state), thisIndex, inventory); break; - case ESM::REC_MISC: getState (miscItems, state); break; - case ESM::REC_PROB: readEquipmentState (getState (probes, state), thisIndex, inventory); break; - case ESM::REC_REPA: getState (repairs, state); break; - case ESM::REC_WEAP: readEquipmentState (getState (weapons, state), thisIndex, inventory); break; - case ESM::REC_LIGH: readEquipmentState (getState (lights, state), thisIndex, inventory); break; + case ESM::REC_ALCH: + getState(potions, state); + break; + case ESM::REC_APPA: + getState(appas, state); + break; + case ESM::REC_ARMO: + readEquipmentState(getState(armors, state), thisIndex, inventory); + break; + case ESM::REC_BOOK: + readEquipmentState(getState(books, state), thisIndex, inventory); + break; // not equipable as such, but for selectedEnchantItem + case ESM::REC_CLOT: + readEquipmentState(getState(clothes, state), thisIndex, inventory); + break; + case ESM::REC_INGR: + getState(ingreds, state); + break; + case ESM::REC_LOCK: + readEquipmentState(getState(lockpicks, state), thisIndex, inventory); + break; + case ESM::REC_MISC: + getState(miscItems, state); + break; + case ESM::REC_PROB: + readEquipmentState(getState(probes, state), thisIndex, inventory); + break; + case ESM::REC_REPA: + getState(repairs, state); + break; + case ESM::REC_WEAP: + readEquipmentState(getState(weapons, state), thisIndex, inventory); + break; + case ESM::REC_LIGH: + readEquipmentState(getState(lights, state), thisIndex, inventory); + break; case 0: - Log(Debug::Warning) << "Dropping inventory reference to '" << state.mRef.mRefID << "' (object no longer exists)"; + Log(Debug::Warning) << "Dropping inventory reference to '" << state.mRef.mRefID + << "' (object no longer exists)"; break; default: Log(Debug::Warning) << "Warning: Invalid item type in inventory state, refid " << state.mRef.mRefID; @@ -909,9 +983,9 @@ void MWWorld::ContainerStore::readState (const ESM::InventoryState& inventory) } } -template -template -void MWWorld::ContainerStoreIteratorBase::copy (const ContainerStoreIteratorBase& src) +template +template +void MWWorld::ContainerStoreIteratorBase::copy(const ContainerStoreIteratorBase& src) { mType = src.mType; mMask = src.mMask; @@ -920,51 +994,77 @@ void MWWorld::ContainerStoreIteratorBase::copy (const ContainerStoreIte switch (src.mType) { - case MWWorld::ContainerStore::Type_Potion: mPotion = src.mPotion; break; - case MWWorld::ContainerStore::Type_Apparatus: mApparatus = src.mApparatus; break; - case MWWorld::ContainerStore::Type_Armor: mArmor = src.mArmor; break; - case MWWorld::ContainerStore::Type_Book: mBook = src.mBook; break; - case MWWorld::ContainerStore::Type_Clothing: mClothing = src.mClothing; break; - case MWWorld::ContainerStore::Type_Ingredient: mIngredient = src.mIngredient; break; - case MWWorld::ContainerStore::Type_Light: mLight = src.mLight; break; - case MWWorld::ContainerStore::Type_Lockpick: mLockpick = src.mLockpick; break; - case MWWorld::ContainerStore::Type_Miscellaneous: mMiscellaneous = src.mMiscellaneous; break; - case MWWorld::ContainerStore::Type_Probe: mProbe = src.mProbe; break; - case MWWorld::ContainerStore::Type_Repair: mRepair = src.mRepair; break; - case MWWorld::ContainerStore::Type_Weapon: mWeapon = src.mWeapon; break; - case -1: break; - default: assert(0); + case MWWorld::ContainerStore::Type_Potion: + mPotion = src.mPotion; + break; + case MWWorld::ContainerStore::Type_Apparatus: + mApparatus = src.mApparatus; + break; + case MWWorld::ContainerStore::Type_Armor: + mArmor = src.mArmor; + break; + case MWWorld::ContainerStore::Type_Book: + mBook = src.mBook; + break; + case MWWorld::ContainerStore::Type_Clothing: + mClothing = src.mClothing; + break; + case MWWorld::ContainerStore::Type_Ingredient: + mIngredient = src.mIngredient; + break; + case MWWorld::ContainerStore::Type_Light: + mLight = src.mLight; + break; + case MWWorld::ContainerStore::Type_Lockpick: + mLockpick = src.mLockpick; + break; + case MWWorld::ContainerStore::Type_Miscellaneous: + mMiscellaneous = src.mMiscellaneous; + break; + case MWWorld::ContainerStore::Type_Probe: + mProbe = src.mProbe; + break; + case MWWorld::ContainerStore::Type_Repair: + mRepair = src.mRepair; + break; + case MWWorld::ContainerStore::Type_Weapon: + mWeapon = src.mWeapon; + break; + case -1: + break; + default: + assert(0); } } -template +template void MWWorld::ContainerStoreIteratorBase::incType() { - if (mType==0) + if (mType == 0) mType = 1; - else if (mType!=-1) + else if (mType != -1) { mType <<= 1; - if (mType>ContainerStore::Type_Last) + if (mType > ContainerStore::Type_Last) mType = -1; } } -template +template void MWWorld::ContainerStoreIteratorBase::nextType() { - while (mType!=-1) + while (mType != -1) { incType(); - if ((mType & mMask) && mType>0) + if ((mType & mMask) && mType > 0) if (resetIterator()) break; } } -template +template bool MWWorld::ContainerStoreIteratorBase::resetIterator() { switch (mType) @@ -972,68 +1072,68 @@ bool MWWorld::ContainerStoreIteratorBase::resetIterator() case ContainerStore::Type_Potion: mPotion = mContainer->potions.mList.begin(); - return mPotion!=mContainer->potions.mList.end(); + return mPotion != mContainer->potions.mList.end(); case ContainerStore::Type_Apparatus: mApparatus = mContainer->appas.mList.begin(); - return mApparatus!=mContainer->appas.mList.end(); + return mApparatus != mContainer->appas.mList.end(); case ContainerStore::Type_Armor: mArmor = mContainer->armors.mList.begin(); - return mArmor!=mContainer->armors.mList.end(); + return mArmor != mContainer->armors.mList.end(); case ContainerStore::Type_Book: mBook = mContainer->books.mList.begin(); - return mBook!=mContainer->books.mList.end(); + return mBook != mContainer->books.mList.end(); case ContainerStore::Type_Clothing: mClothing = mContainer->clothes.mList.begin(); - return mClothing!=mContainer->clothes.mList.end(); + return mClothing != mContainer->clothes.mList.end(); case ContainerStore::Type_Ingredient: mIngredient = mContainer->ingreds.mList.begin(); - return mIngredient!=mContainer->ingreds.mList.end(); + return mIngredient != mContainer->ingreds.mList.end(); case ContainerStore::Type_Light: mLight = mContainer->lights.mList.begin(); - return mLight!=mContainer->lights.mList.end(); + return mLight != mContainer->lights.mList.end(); case ContainerStore::Type_Lockpick: mLockpick = mContainer->lockpicks.mList.begin(); - return mLockpick!=mContainer->lockpicks.mList.end(); + return mLockpick != mContainer->lockpicks.mList.end(); case ContainerStore::Type_Miscellaneous: mMiscellaneous = mContainer->miscItems.mList.begin(); - return mMiscellaneous!=mContainer->miscItems.mList.end(); + return mMiscellaneous != mContainer->miscItems.mList.end(); case ContainerStore::Type_Probe: mProbe = mContainer->probes.mList.begin(); - return mProbe!=mContainer->probes.mList.end(); + return mProbe != mContainer->probes.mList.end(); case ContainerStore::Type_Repair: mRepair = mContainer->repairs.mList.begin(); - return mRepair!=mContainer->repairs.mList.end(); + return mRepair != mContainer->repairs.mList.end(); case ContainerStore::Type_Weapon: mWeapon = mContainer->weapons.mList.begin(); - return mWeapon!=mContainer->weapons.mList.end(); + return mWeapon != mContainer->weapons.mList.end(); } return false; } -template +template bool MWWorld::ContainerStoreIteratorBase::incIterator() { switch (mType) @@ -1041,267 +1141,388 @@ bool MWWorld::ContainerStoreIteratorBase::incIterator() case ContainerStore::Type_Potion: ++mPotion; - return mPotion==mContainer->potions.mList.end(); + return mPotion == mContainer->potions.mList.end(); case ContainerStore::Type_Apparatus: ++mApparatus; - return mApparatus==mContainer->appas.mList.end(); + return mApparatus == mContainer->appas.mList.end(); case ContainerStore::Type_Armor: ++mArmor; - return mArmor==mContainer->armors.mList.end(); + return mArmor == mContainer->armors.mList.end(); case ContainerStore::Type_Book: ++mBook; - return mBook==mContainer->books.mList.end(); + return mBook == mContainer->books.mList.end(); case ContainerStore::Type_Clothing: ++mClothing; - return mClothing==mContainer->clothes.mList.end(); + return mClothing == mContainer->clothes.mList.end(); case ContainerStore::Type_Ingredient: ++mIngredient; - return mIngredient==mContainer->ingreds.mList.end(); + return mIngredient == mContainer->ingreds.mList.end(); case ContainerStore::Type_Light: ++mLight; - return mLight==mContainer->lights.mList.end(); + return mLight == mContainer->lights.mList.end(); case ContainerStore::Type_Lockpick: ++mLockpick; - return mLockpick==mContainer->lockpicks.mList.end(); + return mLockpick == mContainer->lockpicks.mList.end(); case ContainerStore::Type_Miscellaneous: ++mMiscellaneous; - return mMiscellaneous==mContainer->miscItems.mList.end(); + return mMiscellaneous == mContainer->miscItems.mList.end(); case ContainerStore::Type_Probe: ++mProbe; - return mProbe==mContainer->probes.mList.end(); + return mProbe == mContainer->probes.mList.end(); case ContainerStore::Type_Repair: ++mRepair; - return mRepair==mContainer->repairs.mList.end(); + return mRepair == mContainer->repairs.mList.end(); case ContainerStore::Type_Weapon: ++mWeapon; - return mWeapon==mContainer->weapons.mList.end(); + return mWeapon == mContainer->weapons.mList.end(); } return true; } - -template -template -bool MWWorld::ContainerStoreIteratorBase::isEqual (const ContainerStoreIteratorBase& other) const +template +template +bool MWWorld::ContainerStoreIteratorBase::isEqual(const ContainerStoreIteratorBase& other) const { - if (mContainer!=other.mContainer) + if (mContainer != other.mContainer) return false; - if (mType!=other.mType) + if (mType != other.mType) return false; switch (mType) { - case ContainerStore::Type_Potion: return mPotion==other.mPotion; - case ContainerStore::Type_Apparatus: return mApparatus==other.mApparatus; - case ContainerStore::Type_Armor: return mArmor==other.mArmor; - case ContainerStore::Type_Book: return mBook==other.mBook; - case ContainerStore::Type_Clothing: return mClothing==other.mClothing; - case ContainerStore::Type_Ingredient: return mIngredient==other.mIngredient; - case ContainerStore::Type_Light: return mLight==other.mLight; - case ContainerStore::Type_Lockpick: return mLockpick==other.mLockpick; - case ContainerStore::Type_Miscellaneous: return mMiscellaneous==other.mMiscellaneous; - case ContainerStore::Type_Probe: return mProbe==other.mProbe; - case ContainerStore::Type_Repair: return mRepair==other.mRepair; - case ContainerStore::Type_Weapon: return mWeapon==other.mWeapon; - case -1: return true; + case ContainerStore::Type_Potion: + return mPotion == other.mPotion; + case ContainerStore::Type_Apparatus: + return mApparatus == other.mApparatus; + case ContainerStore::Type_Armor: + return mArmor == other.mArmor; + case ContainerStore::Type_Book: + return mBook == other.mBook; + case ContainerStore::Type_Clothing: + return mClothing == other.mClothing; + case ContainerStore::Type_Ingredient: + return mIngredient == other.mIngredient; + case ContainerStore::Type_Light: + return mLight == other.mLight; + case ContainerStore::Type_Lockpick: + return mLockpick == other.mLockpick; + case ContainerStore::Type_Miscellaneous: + return mMiscellaneous == other.mMiscellaneous; + case ContainerStore::Type_Probe: + return mProbe == other.mProbe; + case ContainerStore::Type_Repair: + return mRepair == other.mRepair; + case ContainerStore::Type_Weapon: + return mWeapon == other.mWeapon; + case -1: + return true; } - return false; + return false; } -template -PtrType *MWWorld::ContainerStoreIteratorBase::operator->() const +template +PtrType* MWWorld::ContainerStoreIteratorBase::operator->() const { mPtr = **this; return &mPtr; } -template +template PtrType MWWorld::ContainerStoreIteratorBase::operator*() const { PtrType ptr; switch (mType) { - case ContainerStore::Type_Potion: ptr = PtrType (&*mPotion, nullptr); break; - case ContainerStore::Type_Apparatus: ptr = PtrType (&*mApparatus, nullptr); break; - case ContainerStore::Type_Armor: ptr = PtrType (&*mArmor, nullptr); break; - case ContainerStore::Type_Book: ptr = PtrType (&*mBook, nullptr); break; - case ContainerStore::Type_Clothing: ptr = PtrType (&*mClothing, nullptr); break; - case ContainerStore::Type_Ingredient: ptr = PtrType (&*mIngredient, nullptr); break; - case ContainerStore::Type_Light: ptr = PtrType (&*mLight, nullptr); break; - case ContainerStore::Type_Lockpick: ptr = PtrType (&*mLockpick, nullptr); break; - case ContainerStore::Type_Miscellaneous: ptr = PtrType (&*mMiscellaneous, nullptr); break; - case ContainerStore::Type_Probe: ptr = PtrType (&*mProbe, nullptr); break; - case ContainerStore::Type_Repair: ptr = PtrType (&*mRepair, nullptr); break; - case ContainerStore::Type_Weapon: ptr = PtrType (&*mWeapon, nullptr); break; + case ContainerStore::Type_Potion: + ptr = PtrType(&*mPotion, nullptr); + break; + case ContainerStore::Type_Apparatus: + ptr = PtrType(&*mApparatus, nullptr); + break; + case ContainerStore::Type_Armor: + ptr = PtrType(&*mArmor, nullptr); + break; + case ContainerStore::Type_Book: + ptr = PtrType(&*mBook, nullptr); + break; + case ContainerStore::Type_Clothing: + ptr = PtrType(&*mClothing, nullptr); + break; + case ContainerStore::Type_Ingredient: + ptr = PtrType(&*mIngredient, nullptr); + break; + case ContainerStore::Type_Light: + ptr = PtrType(&*mLight, nullptr); + break; + case ContainerStore::Type_Lockpick: + ptr = PtrType(&*mLockpick, nullptr); + break; + case ContainerStore::Type_Miscellaneous: + ptr = PtrType(&*mMiscellaneous, nullptr); + break; + case ContainerStore::Type_Probe: + ptr = PtrType(&*mProbe, nullptr); + break; + case ContainerStore::Type_Repair: + ptr = PtrType(&*mRepair, nullptr); + break; + case ContainerStore::Type_Weapon: + ptr = PtrType(&*mWeapon, nullptr); + break; } if (ptr.isEmpty()) - throw std::runtime_error ("invalid iterator"); + throw std::runtime_error("invalid iterator"); - ptr.setContainerStore (mContainer); + ptr.setContainerStore(mContainer); return ptr; } -template +template MWWorld::ContainerStoreIteratorBase& MWWorld::ContainerStoreIteratorBase::operator++() { do { if (incIterator()) nextType(); - } - while (mType!=-1 && !(**this).getRefData().getCount()); + } while (mType != -1 && !(**this).getRefData().getCount()); return *this; } -template -MWWorld::ContainerStoreIteratorBase MWWorld::ContainerStoreIteratorBase::operator++ (int) +template +MWWorld::ContainerStoreIteratorBase MWWorld::ContainerStoreIteratorBase::operator++(int) { - ContainerStoreIteratorBase iter (*this); + ContainerStoreIteratorBase iter(*this); ++*this; return iter; } -template -MWWorld::ContainerStoreIteratorBase& MWWorld::ContainerStoreIteratorBase::operator= (const ContainerStoreIteratorBase& rhs) +template +MWWorld::ContainerStoreIteratorBase& MWWorld::ContainerStoreIteratorBase::operator=( + const ContainerStoreIteratorBase& rhs) { - if (this!=&rhs) + if (this != &rhs) { copy(rhs); } return *this; } -template +template int MWWorld::ContainerStoreIteratorBase::getType() const { return mType; } -template -const MWWorld::ContainerStore *MWWorld::ContainerStoreIteratorBase::getContainerStore() const +template +const MWWorld::ContainerStore* MWWorld::ContainerStoreIteratorBase::getContainerStore() const { return mContainer; } -template -MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase (ContainerStoreType container) -: mType (-1), mMask (0), mContainer (container) -{} +template +MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase(ContainerStoreType container) + : mType(-1) + , mMask(0) + , mContainer(container) +{ +} -template -MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase (int mask, ContainerStoreType container) -: mType (0), mMask (mask), mContainer (container) +template +MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase(int mask, ContainerStoreType container) + : mType(0) + , mMask(mask) + , mContainer(container) { nextType(); - if (mType==-1 || (**this).getRefData().getCount()) + if (mType == -1 || (**this).getRefData().getCount()) return; ++*this; } -template -MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type iterator) - : mType(MWWorld::ContainerStore::Type_Potion), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mPotion(iterator){} - -template -MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type iterator) - : mType(MWWorld::ContainerStore::Type_Apparatus), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mApparatus(iterator){} +template +MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase( + ContainerStoreType container, typename Iterator::type iterator) + : mType(MWWorld::ContainerStore::Type_Potion) + , mMask(MWWorld::ContainerStore::Type_All) + , mContainer(container) + , mPotion(iterator) +{ +} -template -MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type iterator) - : mType(MWWorld::ContainerStore::Type_Armor), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mArmor(iterator){} +template +MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase( + ContainerStoreType container, typename Iterator::type iterator) + : mType(MWWorld::ContainerStore::Type_Apparatus) + , mMask(MWWorld::ContainerStore::Type_All) + , mContainer(container) + , mApparatus(iterator) +{ +} -template -MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type iterator) - : mType(MWWorld::ContainerStore::Type_Book), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mBook(iterator){} +template +MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase( + ContainerStoreType container, typename Iterator::type iterator) + : mType(MWWorld::ContainerStore::Type_Armor) + , mMask(MWWorld::ContainerStore::Type_All) + , mContainer(container) + , mArmor(iterator) +{ +} -template -MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type iterator) - : mType(MWWorld::ContainerStore::Type_Clothing), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mClothing(iterator){} +template +MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase( + ContainerStoreType container, typename Iterator::type iterator) + : mType(MWWorld::ContainerStore::Type_Book) + , mMask(MWWorld::ContainerStore::Type_All) + , mContainer(container) + , mBook(iterator) +{ +} -template -MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type iterator) - : mType(MWWorld::ContainerStore::Type_Ingredient), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mIngredient(iterator){} +template +MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase( + ContainerStoreType container, typename Iterator::type iterator) + : mType(MWWorld::ContainerStore::Type_Clothing) + , mMask(MWWorld::ContainerStore::Type_All) + , mContainer(container) + , mClothing(iterator) +{ +} -template -MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type iterator) - : mType(MWWorld::ContainerStore::Type_Light), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mLight(iterator){} +template +MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase( + ContainerStoreType container, typename Iterator::type iterator) + : mType(MWWorld::ContainerStore::Type_Ingredient) + , mMask(MWWorld::ContainerStore::Type_All) + , mContainer(container) + , mIngredient(iterator) +{ +} -template -MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type iterator) - : mType(MWWorld::ContainerStore::Type_Lockpick), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mLockpick(iterator){} +template +MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase( + ContainerStoreType container, typename Iterator::type iterator) + : mType(MWWorld::ContainerStore::Type_Light) + , mMask(MWWorld::ContainerStore::Type_All) + , mContainer(container) + , mLight(iterator) +{ +} -template -MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type iterator) - : mType(MWWorld::ContainerStore::Type_Miscellaneous), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mMiscellaneous(iterator){} +template +MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase( + ContainerStoreType container, typename Iterator::type iterator) + : mType(MWWorld::ContainerStore::Type_Lockpick) + , mMask(MWWorld::ContainerStore::Type_All) + , mContainer(container) + , mLockpick(iterator) +{ +} -template -MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type iterator) - : mType(MWWorld::ContainerStore::Type_Probe), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mProbe(iterator){} +template +MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase( + ContainerStoreType container, typename Iterator::type iterator) + : mType(MWWorld::ContainerStore::Type_Miscellaneous) + , mMask(MWWorld::ContainerStore::Type_All) + , mContainer(container) + , mMiscellaneous(iterator) +{ +} -template -MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type iterator) - : mType(MWWorld::ContainerStore::Type_Repair), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mRepair(iterator){} +template +MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase( + ContainerStoreType container, typename Iterator::type iterator) + : mType(MWWorld::ContainerStore::Type_Probe) + , mMask(MWWorld::ContainerStore::Type_All) + , mContainer(container) + , mProbe(iterator) +{ +} -template -MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type iterator) - : mType(MWWorld::ContainerStore::Type_Weapon), mMask(MWWorld::ContainerStore::Type_All), mContainer(container), mWeapon(iterator){} +template +MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase( + ContainerStoreType container, typename Iterator::type iterator) + : mType(MWWorld::ContainerStore::Type_Repair) + , mMask(MWWorld::ContainerStore::Type_All) + , mContainer(container) + , mRepair(iterator) +{ +} +template +MWWorld::ContainerStoreIteratorBase::ContainerStoreIteratorBase( + ContainerStoreType container, typename Iterator::type iterator) + : mType(MWWorld::ContainerStore::Type_Weapon) + , mMask(MWWorld::ContainerStore::Type_All) + , mContainer(container) + , mWeapon(iterator) +{ +} -template -bool MWWorld::operator== (const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right) +template +bool MWWorld::operator==(const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right) { - return left.isEqual (right); + return left.isEqual(right); } -template -bool MWWorld::operator!= (const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right) +template +bool MWWorld::operator!=(const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right) { - return !(left==right); + return !(left == right); } template class MWWorld::ContainerStoreIteratorBase; template class MWWorld::ContainerStoreIteratorBase; -template bool MWWorld::operator== (const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right); -template bool MWWorld::operator!= (const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right); -template bool MWWorld::operator== (const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right); -template bool MWWorld::operator!= (const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right); -template bool MWWorld::operator== (const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right); -template bool MWWorld::operator!= (const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right); -template bool MWWorld::operator== (const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right); -template bool MWWorld::operator!= (const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right); +template bool MWWorld::operator==( + const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right); +template bool MWWorld::operator!=( + const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right); +template bool MWWorld::operator==( + const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right); +template bool MWWorld::operator!=( + const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right); +template bool MWWorld::operator==( + const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right); +template bool MWWorld::operator!=( + const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right); +template bool MWWorld::operator==( + const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right); +template bool MWWorld::operator!=( + const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right); template void MWWorld::ContainerStoreIteratorBase::copy(const ContainerStoreIteratorBase& src); template void MWWorld::ContainerStoreIteratorBase::copy(const ContainerStoreIteratorBase& src); -template void MWWorld::ContainerStoreIteratorBase::copy(const ContainerStoreIteratorBase& src); +template void MWWorld::ContainerStoreIteratorBase::copy( + const ContainerStoreIteratorBase& src); diff --git a/apps/openmw/mwworld/containerstore.hpp b/apps/openmw/mwworld/containerstore.hpp index 94207e1df2..486993c308 100644 --- a/apps/openmw/mwworld/containerstore.hpp +++ b/apps/openmw/mwworld/containerstore.hpp @@ -12,8 +12,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -21,8 +21,8 @@ #include -#include "ptr.hpp" #include "cellreflist.hpp" +#include "ptr.hpp" namespace ESM { @@ -39,7 +39,7 @@ namespace MWWorld { class ContainerStore; - template + template class ContainerStoreIteratorBase; typedef ContainerStoreIteratorBase ContainerStoreIterator; @@ -47,256 +47,269 @@ namespace MWWorld class ResolutionListener { - ContainerStore& mStore; - public: - ResolutionListener(ContainerStore& store) : mStore(store) {} - ~ResolutionListener(); + ContainerStore& mStore; + + public: + ResolutionListener(ContainerStore& store) + : mStore(store) + { + } + ~ResolutionListener(); }; class ResolutionHandle { - std::shared_ptr mListener; - public: - ResolutionHandle(std::shared_ptr listener) : mListener(listener) {} - ResolutionHandle() = default; + std::shared_ptr mListener; + + public: + ResolutionHandle(std::shared_ptr listener) + : mListener(listener) + { + } + ResolutionHandle() = default; }; - + class ContainerStoreListener { - public: - virtual void itemAdded(const ConstPtr& item, int count) {} - virtual void itemRemoved(const ConstPtr& item, int count) {} - virtual ~ContainerStoreListener() = default; + public: + virtual void itemAdded(const ConstPtr& item, int count) {} + virtual void itemRemoved(const ConstPtr& item, int count) {} + virtual ~ContainerStoreListener() = default; }; class ContainerStore { - public: - - static constexpr int Type_Potion = 0x0001; - static constexpr int Type_Apparatus = 0x0002; - static constexpr int Type_Armor = 0x0004; - static constexpr int Type_Book = 0x0008; - static constexpr int Type_Clothing = 0x0010; - static constexpr int Type_Ingredient = 0x0020; - static constexpr int Type_Light = 0x0040; - static constexpr int Type_Lockpick = 0x0080; - static constexpr int Type_Miscellaneous = 0x0100; - static constexpr int Type_Probe = 0x0200; - static constexpr int Type_Repair = 0x0400; - static constexpr int Type_Weapon = 0x0800; - - static constexpr int Type_Last = Type_Weapon; - - static constexpr int Type_All = 0xffff; - - static const std::string_view sGoldId; - - protected: - ContainerStoreListener* mListener; - - // (item, max charge) - typedef std::vector > TRechargingItems; - TRechargingItems mRechargingItems; - - bool mRechargingItemsUpToDate; - - private: - - MWWorld::CellRefList potions; - MWWorld::CellRefList appas; - MWWorld::CellRefList armors; - MWWorld::CellRefList books; - MWWorld::CellRefList clothes; - MWWorld::CellRefList ingreds; - MWWorld::CellRefList lights; - MWWorld::CellRefList lockpicks; - MWWorld::CellRefList miscItems; - MWWorld::CellRefList probes; - MWWorld::CellRefList repairs; - MWWorld::CellRefList weapons; - - mutable float mCachedWeight; - mutable bool mWeightUpToDate; - - bool mModified; - bool mResolved; - unsigned int mSeed; - MWWorld::Ptr mPtr; - std::weak_ptr mResolutionListener; - - ContainerStoreIterator addImp (const Ptr& ptr, int count, bool markModified = true); - void addInitialItem(std::string_view id, const std::string& owner, int count, Misc::Rng::Generator* prng, bool topLevel=true); - void addInitialItemImp (const MWWorld::Ptr& ptr, const std::string& owner, int count, Misc::Rng::Generator* prng, bool topLevel=true); - - template - ContainerStoreIterator getState (CellRefList& collection, - const ESM::ObjectState& state); - - template - void storeState (const LiveCellRef& ref, ESM::ObjectState& state) const; - - template - void storeStates (const CellRefList& collection, - ESM::InventoryState& inventory, int& index, - bool equipable = false) const; - - void updateRechargingItems(); - - virtual void storeEquipmentState (const MWWorld::LiveCellRefBase& ref, int index, ESM::InventoryState& inventory) const; - - virtual void readEquipmentState (const MWWorld::ContainerStoreIterator& iter, int index, const ESM::InventoryState& inventory); - - public: - - ContainerStore(); - - virtual ~ContainerStore(); - - virtual std::unique_ptr clone() { return std::make_unique(*this); } - - ConstContainerStoreIterator cbegin (int mask = Type_All) const; - ConstContainerStoreIterator cend() const; - ConstContainerStoreIterator begin (int mask = Type_All) const; - ConstContainerStoreIterator end() const; - - ContainerStoreIterator begin (int mask = Type_All); - ContainerStoreIterator end(); - - bool hasVisibleItems() const; + public: + static constexpr int Type_Potion = 0x0001; + static constexpr int Type_Apparatus = 0x0002; + static constexpr int Type_Armor = 0x0004; + static constexpr int Type_Book = 0x0008; + static constexpr int Type_Clothing = 0x0010; + static constexpr int Type_Ingredient = 0x0020; + static constexpr int Type_Light = 0x0040; + static constexpr int Type_Lockpick = 0x0080; + static constexpr int Type_Miscellaneous = 0x0100; + static constexpr int Type_Probe = 0x0200; + static constexpr int Type_Repair = 0x0400; + static constexpr int Type_Weapon = 0x0800; + + static constexpr int Type_Last = Type_Weapon; + + static constexpr int Type_All = 0xffff; + + static const std::string_view sGoldId; + + protected: + ContainerStoreListener* mListener; + + // (item, max charge) + typedef std::vector> TRechargingItems; + TRechargingItems mRechargingItems; + + bool mRechargingItemsUpToDate; + + private: + MWWorld::CellRefList potions; + MWWorld::CellRefList appas; + MWWorld::CellRefList armors; + MWWorld::CellRefList books; + MWWorld::CellRefList clothes; + MWWorld::CellRefList ingreds; + MWWorld::CellRefList lights; + MWWorld::CellRefList lockpicks; + MWWorld::CellRefList miscItems; + MWWorld::CellRefList probes; + MWWorld::CellRefList repairs; + MWWorld::CellRefList weapons; + + mutable float mCachedWeight; + mutable bool mWeightUpToDate; + + bool mModified; + bool mResolved; + unsigned int mSeed; + MWWorld::Ptr mPtr; + std::weak_ptr mResolutionListener; + + ContainerStoreIterator addImp(const Ptr& ptr, int count, bool markModified = true); + void addInitialItem( + std::string_view id, const std::string& owner, int count, Misc::Rng::Generator* prng, bool topLevel = true); + void addInitialItemImp(const MWWorld::Ptr& ptr, const std::string& owner, int count, Misc::Rng::Generator* prng, + bool topLevel = true); + + template + ContainerStoreIterator getState(CellRefList& collection, const ESM::ObjectState& state); + + template + void storeState(const LiveCellRef& ref, ESM::ObjectState& state) const; + + template + void storeStates( + const CellRefList& collection, ESM::InventoryState& inventory, int& index, bool equipable = false) const; + + void updateRechargingItems(); + + virtual void storeEquipmentState( + const MWWorld::LiveCellRefBase& ref, int index, ESM::InventoryState& inventory) const; + + virtual void readEquipmentState( + const MWWorld::ContainerStoreIterator& iter, int index, const ESM::InventoryState& inventory); + + public: + ContainerStore(); + + virtual ~ContainerStore(); + + virtual std::unique_ptr clone() { return std::make_unique(*this); } + + ConstContainerStoreIterator cbegin(int mask = Type_All) const; + ConstContainerStoreIterator cend() const; + ConstContainerStoreIterator begin(int mask = Type_All) const; + ConstContainerStoreIterator end() const; + + ContainerStoreIterator begin(int mask = Type_All); + ContainerStoreIterator end(); + + bool hasVisibleItems() const; + + virtual ContainerStoreIterator add( + const Ptr& itemPtr, int count, const Ptr& actorPtr, bool allowAutoEquip = true, bool resolve = true); + ///< Add the item pointed to by \a ptr to this container. (Stacks automatically if needed) + /// + /// \note The item pointed to is not required to exist beyond this function call. + /// + /// \attention Do not add items to an existing stack by increasing the count instead of + /// calling this function! + /// + /// @return if stacking happened, return iterator to the item that was stacked against, otherwise iterator to + /// the newly inserted item. - virtual ContainerStoreIterator add (const Ptr& itemPtr, int count, const Ptr& actorPtr, bool allowAutoEquip = true, bool resolve = true); - ///< Add the item pointed to by \a ptr to this container. (Stacks automatically if needed) - /// - /// \note The item pointed to is not required to exist beyond this function call. - /// - /// \attention Do not add items to an existing stack by increasing the count instead of - /// calling this function! - /// - /// @return if stacking happened, return iterator to the item that was stacked against, otherwise iterator to the newly inserted item. + ContainerStoreIterator add(std::string_view id, int count, const Ptr& actorPtr); + ///< Utility to construct a ManualRef and call add(ptr, count, actorPtr, true) - ContainerStoreIterator add(std::string_view id, int count, const Ptr& actorPtr); - ///< Utility to construct a ManualRef and call add(ptr, count, actorPtr, true) + int remove( + std::string_view itemId, int count, const Ptr& actor, bool equipReplacement = 0, bool resolve = true); + ///< Remove \a count item(s) designated by \a itemId from this container. + /// + /// @return the number of items actually removed - int remove(std::string_view itemId, int count, const Ptr& actor, bool equipReplacement = 0, bool resolve = true); - ///< Remove \a count item(s) designated by \a itemId from this container. - /// - /// @return the number of items actually removed + virtual int remove( + const Ptr& item, int count, const Ptr& actor, bool equipReplacement = 0, bool resolve = true); + ///< Remove \a count item(s) designated by \a item from this inventory. + /// + /// @return the number of items actually removed - virtual int remove(const Ptr& item, int count, const Ptr& actor, bool equipReplacement = 0, bool resolve = true); - ///< Remove \a count item(s) designated by \a item from this inventory. - /// - /// @return the number of items actually removed + void rechargeItems(float duration); + ///< Restore charge on enchanted items. Note this should only be done for the player. - void rechargeItems (float duration); - ///< Restore charge on enchanted items. Note this should only be done for the player. + ContainerStoreIterator unstack(const Ptr& ptr, const Ptr& container, int count = 1); + ///< Unstack an item in this container. The item's count will be set to count, then a new stack will be added + ///< with (origCount-count). + /// + /// @return an iterator to the new stack, or end() if no new stack was created. - ContainerStoreIterator unstack (const Ptr& ptr, const Ptr& container, int count = 1); - ///< Unstack an item in this container. The item's count will be set to count, then a new stack will be added with (origCount-count). - /// - /// @return an iterator to the new stack, or end() if no new stack was created. + MWWorld::ContainerStoreIterator restack(const MWWorld::Ptr& item); + ///< Attempt to re-stack an item in this container. + /// If a compatible stack is found, the item's count is added to that stack, then the original is deleted. + /// @return If the item was stacked, return the stack, otherwise return the old (untouched) item. - MWWorld::ContainerStoreIterator restack (const MWWorld::Ptr& item); - ///< Attempt to re-stack an item in this container. - /// If a compatible stack is found, the item's count is added to that stack, then the original is deleted. - /// @return If the item was stacked, return the stack, otherwise return the old (untouched) item. + int count(std::string_view id) const; + ///< @return How many items with refID \a id are in this container? - int count(std::string_view id) const; - ///< @return How many items with refID \a id are in this container? + ContainerStoreListener* getContListener() const; + void setContListener(ContainerStoreListener* listener); - ContainerStoreListener* getContListener() const; - void setContListener(ContainerStoreListener* listener); - protected: - ContainerStoreIterator addNewStack (const ConstPtr& ptr, int count); - ///< Add the item to this container (do not try to stack it onto existing items) + protected: + ContainerStoreIterator addNewStack(const ConstPtr& ptr, int count); + ///< Add the item to this container (do not try to stack it onto existing items) - virtual void flagAsModified(); + virtual void flagAsModified(); - /// + and - operations that can deal with negative stacks - /// Note that negativity is infectious - static int addItems(int count1, int count2); - static int subtractItems(int count1, int count2); - public: + /// + and - operations that can deal with negative stacks + /// Note that negativity is infectious + static int addItems(int count1, int count2); + static int subtractItems(int count1, int count2); - virtual bool stacks (const ConstPtr& ptr1, const ConstPtr& ptr2) const; - ///< @return true if the two specified objects can stack with each other + public: + virtual bool stacks(const ConstPtr& ptr1, const ConstPtr& ptr2) const; + ///< @return true if the two specified objects can stack with each other - void fill (const ESM::InventoryList& items, const std::string& owner, Misc::Rng::Generator& seed); - ///< Insert items into *this. + void fill(const ESM::InventoryList& items, const std::string& owner, Misc::Rng::Generator& seed); + ///< Insert items into *this. - void fillNonRandom (const ESM::InventoryList& items, const std::string& owner, unsigned int seed); - ///< Insert items into *this, excluding leveled items + void fillNonRandom(const ESM::InventoryList& items, const std::string& owner, unsigned int seed); + ///< Insert items into *this, excluding leveled items - virtual void clear(); - ///< Empty container. + virtual void clear(); + ///< Empty container. - float getWeight() const; - ///< Return total weight of the items contained in *this. + float getWeight() const; + ///< Return total weight of the items contained in *this. - static int getType (const ConstPtr& ptr); - ///< This function throws an exception, if ptr does not point to an object, that can be - /// put into a container. + static int getType(const ConstPtr& ptr); + ///< This function throws an exception, if ptr does not point to an object, that can be + /// put into a container. - Ptr findReplacement(const std::string& id); - ///< Returns replacement for object with given id. Prefer used items (with low durability left). + Ptr findReplacement(const std::string& id); + ///< Returns replacement for object with given id. Prefer used items (with low durability left). - Ptr search(std::string_view id); + Ptr search(std::string_view id); - virtual void writeState (ESM::InventoryState& state) const; + virtual void writeState(ESM::InventoryState& state) const; - virtual void readState (const ESM::InventoryState& state); + virtual void readState(const ESM::InventoryState& state); - bool isResolved() const; + bool isResolved() const; - void resolve(); - ResolutionHandle resolveTemporarily(); - void unresolve(); + void resolve(); + ResolutionHandle resolveTemporarily(); + void unresolve(); - friend class ContainerStoreIteratorBase; - friend class ContainerStoreIteratorBase; - friend class ResolutionListener; - friend class MWClass::Container; + friend class ContainerStoreIteratorBase; + friend class ContainerStoreIteratorBase; + friend class ResolutionListener; + friend class MWClass::Container; }; - template + template class ContainerStoreIteratorBase { - template + template struct IsConvertible { static constexpr bool value = true; }; - template + template struct IsConvertible { static constexpr bool value = false; }; - template + template struct IteratorTrait { typedef typename MWWorld::CellRefList::List::iterator type; }; - template + template struct IteratorTrait { typedef typename MWWorld::CellRefList::List::const_iterator type; }; - template + template struct Iterator : IteratorTrait { }; - template + template struct ContainerStoreTrait { typedef ContainerStore* type; }; - - template + + template struct ContainerStoreTrait { typedef const ContainerStore* type; @@ -322,80 +335,80 @@ namespace MWWorld typename Iterator::type mRepair; typename Iterator::type mWeapon; - ContainerStoreIteratorBase (ContainerStoreType container); + ContainerStoreIteratorBase(ContainerStoreType container); ///< End-iterator - ContainerStoreIteratorBase (int mask, ContainerStoreType container); + ContainerStoreIteratorBase(int mask, ContainerStoreType container); ///< Begin-iterator // construct iterator using a CellRefList iterator - ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type); - ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type); - ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type); - ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type); - ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type); - ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type); - ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type); - ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type); - ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type); - ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type); - ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type); - ContainerStoreIteratorBase (ContainerStoreType container, typename Iterator::type); - - template - void copy (const ContainerStoreIteratorBase& src); - - void incType (); - - void nextType (); - - bool resetIterator (); + ContainerStoreIteratorBase(ContainerStoreType container, typename Iterator::type); + ContainerStoreIteratorBase(ContainerStoreType container, typename Iterator::type); + ContainerStoreIteratorBase(ContainerStoreType container, typename Iterator::type); + ContainerStoreIteratorBase(ContainerStoreType container, typename Iterator::type); + ContainerStoreIteratorBase(ContainerStoreType container, typename Iterator::type); + ContainerStoreIteratorBase(ContainerStoreType container, typename Iterator::type); + ContainerStoreIteratorBase(ContainerStoreType container, typename Iterator::type); + ContainerStoreIteratorBase(ContainerStoreType container, typename Iterator::type); + ContainerStoreIteratorBase(ContainerStoreType container, typename Iterator::type); + ContainerStoreIteratorBase(ContainerStoreType container, typename Iterator::type); + ContainerStoreIteratorBase(ContainerStoreType container, typename Iterator::type); + ContainerStoreIteratorBase(ContainerStoreType container, typename Iterator::type); + + template + void copy(const ContainerStoreIteratorBase& src); + + void incType(); + + void nextType(); + + bool resetIterator(); ///< Reset iterator for selected type. /// /// \return Type not empty? - bool incIterator (); + bool incIterator(); ///< Increment iterator for selected type. /// /// \return reached the end? - public: - using iterator_category = std::forward_iterator_tag; - using value_type = PtrType; - using difference_type = std::ptrdiff_t; - using pointer = PtrType*; - using reference = PtrType&; - - template - ContainerStoreIteratorBase (const ContainerStoreIteratorBase& other) - { - char CANNOT_CONVERT_CONST_ITERATOR_TO_ITERATOR[IsConvertible::value ? 1 : -1]; - ((void)CANNOT_CONVERT_CONST_ITERATOR_TO_ITERATOR); - copy (other); - } - - template - bool isEqual(const ContainerStoreIteratorBase& other) const; - - PtrType *operator->() const; - PtrType operator*() const; - - ContainerStoreIteratorBase& operator++ (); - ContainerStoreIteratorBase operator++ (int); - ContainerStoreIteratorBase& operator= (const ContainerStoreIteratorBase& rhs); - ContainerStoreIteratorBase (const ContainerStoreIteratorBase& rhs) = default; - - int getType() const; - const ContainerStore *getContainerStore() const; - - friend class ContainerStore; - friend class ContainerStoreIteratorBase; - friend class ContainerStoreIteratorBase; + public: + using iterator_category = std::forward_iterator_tag; + using value_type = PtrType; + using difference_type = std::ptrdiff_t; + using pointer = PtrType*; + using reference = PtrType&; + + template + ContainerStoreIteratorBase(const ContainerStoreIteratorBase& other) + { + char CANNOT_CONVERT_CONST_ITERATOR_TO_ITERATOR[IsConvertible::value ? 1 : -1]; + ((void)CANNOT_CONVERT_CONST_ITERATOR_TO_ITERATOR); + copy(other); + } + + template + bool isEqual(const ContainerStoreIteratorBase& other) const; + + PtrType* operator->() const; + PtrType operator*() const; + + ContainerStoreIteratorBase& operator++(); + ContainerStoreIteratorBase operator++(int); + ContainerStoreIteratorBase& operator=(const ContainerStoreIteratorBase& rhs); + ContainerStoreIteratorBase(const ContainerStoreIteratorBase& rhs) = default; + + int getType() const; + const ContainerStore* getContainerStore() const; + + friend class ContainerStore; + friend class ContainerStoreIteratorBase; + friend class ContainerStoreIteratorBase; }; - template - bool operator== (const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right); - template - bool operator!= (const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right); + template + bool operator==(const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right); + template + bool operator!=(const ContainerStoreIteratorBase& left, const ContainerStoreIteratorBase& right); } #endif diff --git a/apps/openmw/mwworld/contentloader.hpp b/apps/openmw/mwworld/contentloader.hpp index cb228a9ecb..70150ec33a 100644 --- a/apps/openmw/mwworld/contentloader.hpp +++ b/apps/openmw/mwworld/contentloader.hpp @@ -11,12 +11,12 @@ namespace Loading namespace MWWorld { -struct ContentLoader -{ - virtual ~ContentLoader() = default; + struct ContentLoader + { + virtual ~ContentLoader() = default; - virtual void load(const std::filesystem::path& filepath, int& index, Loading::Listener* listener) = 0; -}; + virtual void load(const std::filesystem::path& filepath, int& index, Loading::Listener* listener) = 0; + }; } /* namespace MWWorld */ diff --git a/apps/openmw/mwworld/customdata.cpp b/apps/openmw/mwworld/customdata.cpp index 5080c09230..395d230a1a 100644 --- a/apps/openmw/mwworld/customdata.cpp +++ b/apps/openmw/mwworld/customdata.cpp @@ -1,81 +1,80 @@ #include "customdata.hpp" -#include #include +#include #include namespace MWWorld { -MWClass::CreatureCustomData &CustomData::asCreatureCustomData() -{ - std::stringstream error; - error << "bad cast " << typeid(this).name() << " to CreatureCustomData"; - throw std::logic_error(error.str()); -} + MWClass::CreatureCustomData& CustomData::asCreatureCustomData() + { + std::stringstream error; + error << "bad cast " << typeid(this).name() << " to CreatureCustomData"; + throw std::logic_error(error.str()); + } -const MWClass::CreatureCustomData &CustomData::asCreatureCustomData() const -{ - std::stringstream error; - error << "bad cast " << typeid(this).name() << " to CreatureCustomData"; - throw std::logic_error(error.str()); -} + const MWClass::CreatureCustomData& CustomData::asCreatureCustomData() const + { + std::stringstream error; + error << "bad cast " << typeid(this).name() << " to CreatureCustomData"; + throw std::logic_error(error.str()); + } -MWClass::NpcCustomData &CustomData::asNpcCustomData() -{ - std::stringstream error; - error << "bad cast " << typeid(this).name() << " to NpcCustomData"; - throw std::logic_error(error.str()); -} + MWClass::NpcCustomData& CustomData::asNpcCustomData() + { + std::stringstream error; + error << "bad cast " << typeid(this).name() << " to NpcCustomData"; + throw std::logic_error(error.str()); + } -const MWClass::NpcCustomData &CustomData::asNpcCustomData() const -{ - std::stringstream error; - error << "bad cast " << typeid(this).name() << " to NpcCustomData"; - throw std::logic_error(error.str()); -} + const MWClass::NpcCustomData& CustomData::asNpcCustomData() const + { + std::stringstream error; + error << "bad cast " << typeid(this).name() << " to NpcCustomData"; + throw std::logic_error(error.str()); + } -MWClass::ContainerCustomData &CustomData::asContainerCustomData() -{ - std::stringstream error; - error << "bad cast " << typeid(this).name() << " to ContainerCustomData"; - throw std::logic_error(error.str()); -} + MWClass::ContainerCustomData& CustomData::asContainerCustomData() + { + std::stringstream error; + error << "bad cast " << typeid(this).name() << " to ContainerCustomData"; + throw std::logic_error(error.str()); + } -const MWClass::ContainerCustomData &CustomData::asContainerCustomData() const -{ - std::stringstream error; - error << "bad cast " << typeid(this).name() << " to ContainerCustomData"; - throw std::logic_error(error.str()); -} + const MWClass::ContainerCustomData& CustomData::asContainerCustomData() const + { + std::stringstream error; + error << "bad cast " << typeid(this).name() << " to ContainerCustomData"; + throw std::logic_error(error.str()); + } -MWClass::DoorCustomData &CustomData::asDoorCustomData() -{ - std::stringstream error; - error << "bad cast " << typeid(this).name() << " to DoorCustomData"; - throw std::logic_error(error.str()); -} + MWClass::DoorCustomData& CustomData::asDoorCustomData() + { + std::stringstream error; + error << "bad cast " << typeid(this).name() << " to DoorCustomData"; + throw std::logic_error(error.str()); + } -const MWClass::DoorCustomData &CustomData::asDoorCustomData() const -{ - std::stringstream error; - error << "bad cast " << typeid(this).name() << " to DoorCustomData"; - throw std::logic_error(error.str()); -} + const MWClass::DoorCustomData& CustomData::asDoorCustomData() const + { + std::stringstream error; + error << "bad cast " << typeid(this).name() << " to DoorCustomData"; + throw std::logic_error(error.str()); + } -MWClass::CreatureLevListCustomData &CustomData::asCreatureLevListCustomData() -{ - std::stringstream error; - error << "bad cast " << typeid(this).name() << " to CreatureLevListCustomData"; - throw std::logic_error(error.str()); -} - -const MWClass::CreatureLevListCustomData &CustomData::asCreatureLevListCustomData() const -{ - std::stringstream error; - error << "bad cast " << typeid(this).name() << " to CreatureLevListCustomData"; - throw std::logic_error(error.str()); -} + MWClass::CreatureLevListCustomData& CustomData::asCreatureLevListCustomData() + { + std::stringstream error; + error << "bad cast " << typeid(this).name() << " to CreatureLevListCustomData"; + throw std::logic_error(error.str()); + } + const MWClass::CreatureLevListCustomData& CustomData::asCreatureLevListCustomData() const + { + std::stringstream error; + error << "bad cast " << typeid(this).name() << " to CreatureLevListCustomData"; + throw std::logic_error(error.str()); + } } diff --git a/apps/openmw/mwworld/customdata.hpp b/apps/openmw/mwworld/customdata.hpp index 7200e7684c..9d9283f085 100644 --- a/apps/openmw/mwworld/customdata.hpp +++ b/apps/openmw/mwworld/customdata.hpp @@ -17,37 +17,33 @@ namespace MWWorld /// \brief Base class for the MW-class-specific part of RefData class CustomData { - public: + public: + virtual ~CustomData() {} - virtual ~CustomData() {} + virtual std::unique_ptr clone() const = 0; - virtual std::unique_ptr clone() const = 0; + // Fast version of dynamic_cast. Needs to be overridden in the respective class. - // Fast version of dynamic_cast. Needs to be overridden in the respective class. + virtual MWClass::CreatureCustomData& asCreatureCustomData(); + virtual const MWClass::CreatureCustomData& asCreatureCustomData() const; - virtual MWClass::CreatureCustomData& asCreatureCustomData(); - virtual const MWClass::CreatureCustomData& asCreatureCustomData() const; + virtual MWClass::NpcCustomData& asNpcCustomData(); + virtual const MWClass::NpcCustomData& asNpcCustomData() const; - virtual MWClass::NpcCustomData& asNpcCustomData(); - virtual const MWClass::NpcCustomData& asNpcCustomData() const; + virtual MWClass::ContainerCustomData& asContainerCustomData(); + virtual const MWClass::ContainerCustomData& asContainerCustomData() const; - virtual MWClass::ContainerCustomData& asContainerCustomData(); - virtual const MWClass::ContainerCustomData& asContainerCustomData() const; + virtual MWClass::DoorCustomData& asDoorCustomData(); + virtual const MWClass::DoorCustomData& asDoorCustomData() const; - virtual MWClass::DoorCustomData& asDoorCustomData(); - virtual const MWClass::DoorCustomData& asDoorCustomData() const; - - virtual MWClass::CreatureLevListCustomData& asCreatureLevListCustomData(); - virtual const MWClass::CreatureLevListCustomData& asCreatureLevListCustomData() const; + virtual MWClass::CreatureLevListCustomData& asCreatureLevListCustomData(); + virtual const MWClass::CreatureLevListCustomData& asCreatureLevListCustomData() const; }; template struct TypedCustomData : CustomData { - std::unique_ptr clone() const final - { - return std::make_unique(*static_cast(this)); - } + std::unique_ptr clone() const final { return std::make_unique(*static_cast(this)); } }; } diff --git a/apps/openmw/mwworld/datetimemanager.cpp b/apps/openmw/mwworld/datetimemanager.cpp index 1f62a016fd..2d137518cf 100644 --- a/apps/openmw/mwworld/datetimemanager.cpp +++ b/apps/openmw/mwworld/datetimemanager.cpp @@ -13,21 +13,33 @@ namespace { switch (month) { - case 0: return 31; - case 1: return 28; - case 2: return 31; - case 3: return 30; - case 4: return 31; - case 5: return 30; - case 6: return 31; - case 7: return 31; - case 8: return 30; - case 9: return 31; - case 10: return 30; - case 11: return 31; + case 0: + return 31; + case 1: + return 28; + case 2: + return 31; + case 3: + return 30; + case 4: + return 31; + case 5: + return 30; + case 6: + return 31; + case 7: + return 31; + case 8: + return 30; + case 9: + return 31; + case 10: + return 30; + case 11: + return 31; } - throw std::runtime_error ("month out of range"); + throw std::runtime_error("month out of range"); } } @@ -148,43 +160,41 @@ namespace MWWorld if (month < 0 || month >= months) return {}; - static const std::string_view monthNames[months] = - { - "sMonthMorningstar", "sMonthSunsdawn", "sMonthFirstseed", "sMonthRainshand", - "sMonthSecondseed", "sMonthMidyear", "sMonthSunsheight", "sMonthLastseed", - "sMonthHeartfire", "sMonthFrostfall", "sMonthSunsdusk", "sMonthEveningstar" - }; + static const std::string_view monthNames[months] = { "sMonthMorningstar", "sMonthSunsdawn", "sMonthFirstseed", + "sMonthRainshand", "sMonthSecondseed", "sMonthMidyear", "sMonthSunsheight", "sMonthLastseed", + "sMonthHeartfire", "sMonthFrostfall", "sMonthSunsdusk", "sMonthEveningstar" }; - const ESM::GameSetting *setting = MWBase::Environment::get().getWorld()->getStore().get().find(monthNames[month]); + const ESM::GameSetting* setting + = MWBase::Environment::get().getWorld()->getStore().get().find(monthNames[month]); return setting->mValue.getString(); } bool DateTimeManager::updateGlobalFloat(std::string_view name, float value) { - if (name=="gamehour") + if (name == "gamehour") { setHour(value); return true; } - else if (name=="day") + else if (name == "day") { setDay(static_cast(value)); return true; } - else if (name=="month") + else if (name == "month") { setMonth(static_cast(value)); return true; } - else if (name=="year") + else if (name == "year") { mYear = static_cast(value); } - else if (name=="timescale") + else if (name == "timescale") { mTimeScale = value; } - else if (name=="dayspassed") + else if (name == "dayspassed") { mDaysPassed = static_cast(value); } @@ -194,30 +204,30 @@ namespace MWWorld bool DateTimeManager::updateGlobalInt(std::string_view name, int value) { - if (name=="gamehour") + if (name == "gamehour") { setHour(static_cast(value)); return true; } - else if (name=="day") + else if (name == "day") { setDay(value); return true; } - else if (name=="month") + else if (name == "month") { setMonth(value); return true; } - else if (name=="year") + else if (name == "year") { mYear = value; } - else if (name=="timescale") + else if (name == "timescale") { mTimeScale = static_cast(value); } - else if (name=="dayspassed") + else if (name == "dayspassed") { mDaysPassed = value; } diff --git a/apps/openmw/mwworld/esmloader.cpp b/apps/openmw/mwworld/esmloader.cpp index 66dd5b856e..3c1b6acc47 100644 --- a/apps/openmw/mwworld/esmloader.cpp +++ b/apps/openmw/mwworld/esmloader.cpp @@ -8,38 +8,41 @@ namespace MWWorld { -EsmLoader::EsmLoader(MWWorld::ESMStore& store, ESM::ReadersCache& readers, ToUTF8::Utf8Encoder* encoder, std::vector& esmVersions) - : mReaders(readers) - , mStore(store) - , mEncoder(encoder) - , mDialogue(nullptr) // A content file containing INFO records without a DIAL record appends them to the previous file's dialogue - , mESMVersions(esmVersions) -{ -} - -void EsmLoader::load(const std::filesystem::path& filepath, int& index, Loading::Listener* listener) -{ - const ESM::ReadersCache::BusyItem reader = mReaders.get(static_cast(index)); - - reader->setEncoder(mEncoder); - reader->setIndex(index); - reader->open(filepath); - reader->resolveParentFileIndices(mReaders); - - assert(reader->getGameFiles().size() == reader->getParentFileIndices().size()); - for (std::size_t i = 0, n = reader->getParentFileIndices().size(); i < n; ++i) - if (i == static_cast(reader->getIndex())) - throw std::runtime_error("File " + Files::pathToUnicodeString(reader->getName()) + " asks for parent file " + EsmLoader::EsmLoader(MWWorld::ESMStore& store, ESM::ReadersCache& readers, ToUTF8::Utf8Encoder* encoder, + std::vector& esmVersions) + : mReaders(readers) + , mStore(store) + , mEncoder(encoder) + , mDialogue(nullptr) // A content file containing INFO records without a DIAL record appends them to the + // previous file's dialogue + , mESMVersions(esmVersions) + { + } + + void EsmLoader::load(const std::filesystem::path& filepath, int& index, Loading::Listener* listener) + { + const ESM::ReadersCache::BusyItem reader = mReaders.get(static_cast(index)); + + reader->setEncoder(mEncoder); + reader->setIndex(index); + reader->open(filepath); + reader->resolveParentFileIndices(mReaders); + + assert(reader->getGameFiles().size() == reader->getParentFileIndices().size()); + for (std::size_t i = 0, n = reader->getParentFileIndices().size(); i < n; ++i) + if (i == static_cast(reader->getIndex())) + throw std::runtime_error("File " + Files::pathToUnicodeString(reader->getName()) + " asks for parent file " + reader->getGameFiles()[i].name + ", but it is not available or has been loaded in the wrong order. " "Please run the launcher to fix this issue."); - mESMVersions[index] = reader->getVer(); - mStore.load(*reader, listener, mDialogue); + mESMVersions[index] = reader->getVer(); + mStore.load(*reader, listener, mDialogue); - if (!mMasterFileFormat.has_value() && (Misc::StringUtils::ciEndsWith(reader->getName().u8string(), u8".esm") - || Misc::StringUtils::ciEndsWith(reader->getName().u8string(), u8".omwgame"))) - mMasterFileFormat = reader->getFormat(); -} + if (!mMasterFileFormat.has_value() + && (Misc::StringUtils::ciEndsWith(reader->getName().u8string(), u8".esm") + || Misc::StringUtils::ciEndsWith(reader->getName().u8string(), u8".omwgame"))) + mMasterFileFormat = reader->getFormat(); + } } /* namespace MWWorld */ diff --git a/apps/openmw/mwworld/esmloader.hpp b/apps/openmw/mwworld/esmloader.hpp index 5f2fc94bf4..253c58db70 100644 --- a/apps/openmw/mwworld/esmloader.hpp +++ b/apps/openmw/mwworld/esmloader.hpp @@ -8,7 +8,7 @@ namespace ToUTF8 { - class Utf8Encoder; + class Utf8Encoder; } namespace ESM @@ -20,15 +20,16 @@ namespace ESM namespace MWWorld { -class ESMStore; + class ESMStore; -struct EsmLoader : public ContentLoader -{ - explicit EsmLoader(MWWorld::ESMStore& store, ESM::ReadersCache& readers, ToUTF8::Utf8Encoder* encoder, std::vector& esmVersions); + struct EsmLoader : public ContentLoader + { + explicit EsmLoader(MWWorld::ESMStore& store, ESM::ReadersCache& readers, ToUTF8::Utf8Encoder* encoder, + std::vector& esmVersions); - std::optional getMasterFileFormat() const { return mMasterFileFormat; } + std::optional getMasterFileFormat() const { return mMasterFileFormat; } - void load(const std::filesystem::path& filepath, int& index, Loading::Listener* listener) override; + void load(const std::filesystem::path& filepath, int& index, Loading::Listener* listener) override; private: ESM::ReadersCache& mReaders; @@ -37,7 +38,7 @@ struct EsmLoader : public ContentLoader ESM::Dialogue* mDialogue; std::optional mMasterFileFormat; std::vector& mESMVersions; -}; + }; } /* namespace MWWorld */ diff --git a/apps/openmw/mwworld/esmstore.cpp b/apps/openmw/mwworld/esmstore.cpp index d133efd2ac..3fd5980abe 100644 --- a/apps/openmw/mwworld/esmstore.cpp +++ b/apps/openmw/mwworld/esmstore.cpp @@ -5,16 +5,16 @@ #include #include +#include #include #include +#include #include #include #include -#include -#include -#include #include +#include #include "../mwmechanics/spelllist.hpp" @@ -25,12 +25,17 @@ namespace ESM::RefNum mRefNum; std::size_t mRefID; - Ref(ESM::RefNum refNum, std::size_t refID) : mRefNum(refNum), mRefID(refID) {} + Ref(ESM::RefNum refNum, std::size_t refID) + : mRefNum(refNum) + , mRefID(refID) + { + } }; constexpr std::size_t deletedRefID = std::numeric_limits::max(); - void readRefs(const ESM::Cell& cell, std::vector& refs, std::vector& refIDs, ESM::ReadersCache& readers) + void readRefs( + const ESM::Cell& cell, std::vector& refs, std::vector& refIDs, ESM::ReadersCache& readers) { // TODO: we have many similar copies of this code. for (size_t i = 0; i < cell.mContextList.size(); i++) @@ -43,18 +48,19 @@ namespace bool deleted = false; while (cell.getNextRef(*reader, ref, deleted)) { - if(deleted) + if (deleted) refs.emplace_back(ref.mRefNum, deletedRefID); - else if (std::find(cell.mMovedRefs.begin(), cell.mMovedRefs.end(), ref.mRefNum) == cell.mMovedRefs.end()) + else if (std::find(cell.mMovedRefs.begin(), cell.mMovedRefs.end(), ref.mRefNum) + == cell.mMovedRefs.end()) { refs.emplace_back(ref.mRefNum, refIDs.size()); refIDs.push_back(std::move(ref.mRefID)); } } } - for(const auto& [value, deleted] : cell.mLeasedRefs) + for (const auto& [value, deleted] : cell.mLeasedRefs) { - if(deleted) + if (deleted) refs.emplace_back(value.mRefNum, deletedRefID); else { @@ -72,7 +78,9 @@ namespace throw std::runtime_error("List of NPC classes is empty!"); } - std::vector getNPCsToReplace(const MWWorld::Store& factions, const MWWorld::Store& classes, const std::unordered_map& npcs) + std::vector getNPCsToReplace(const MWWorld::Store& factions, + const MWWorld::Store& classes, + const std::unordered_map& npcs) { // Cache first class from store - we will use it if current class is not found const std::string& defaultCls = getDefaultClass(classes); @@ -89,10 +97,11 @@ namespace const std::string& npcFaction = npc.mFaction; if (!npcFaction.empty()) { - const ESM::Faction *fact = factions.search(npcFaction); + const ESM::Faction* fact = factions.search(npcFaction); if (!fact) { - Log(Debug::Verbose) << "NPC '" << npc.mId << "' (" << npc.mName << ") has nonexistent faction '" << npc.mFaction << "', ignoring it."; + Log(Debug::Verbose) << "NPC '" << npc.mId << "' (" << npc.mName << ") has nonexistent faction '" + << npc.mFaction << "', ignoring it."; npc.mFaction.clear(); npc.mNpdt.mRank = 0; changed = true; @@ -100,10 +109,11 @@ namespace } const std::string& npcClass = npc.mClass; - const ESM::Class *cls = classes.search(npcClass); + const ESM::Class* cls = classes.search(npcClass); if (!cls) { - Log(Debug::Verbose) << "NPC '" << npc.mId << "' (" << npc.mName << ") has nonexistent class '" << npc.mClass << "', using '" << defaultCls << "' class as replacement."; + Log(Debug::Verbose) << "NPC '" << npc.mId << "' (" << npc.mName << ") has nonexistent class '" + << npc.mClass << "', using '" << defaultCls << "' class as replacement."; npc.mClass = defaultCls; changed = true; } @@ -115,17 +125,18 @@ namespace return npcsToReplace; } - // Custom enchanted items can reference scripts that no longer exist, this doesn't necessarily mean the base item no longer exists however. - // So instead of removing the item altogether, we're only removing the script. - template + // Custom enchanted items can reference scripts that no longer exist, this doesn't necessarily mean the base item no + // longer exists however. So instead of removing the item altogether, we're only removing the script. + template void removeMissingScripts(const MWWorld::Store& scripts, MapT& items) { - for(auto& [id, item] : items) + for (auto& [id, item] : items) { - if(!item.mScript.empty() && !scripts.search(item.mScript)) + if (!item.mScript.empty() && !scripts.search(item.mScript)) { item.mScript.clear(); - Log(Debug::Verbose) << "Item '" << id << "' (" << item.mName << ") has nonexistent script '" << item.mScript << "', ignoring it."; + Log(Debug::Verbose) << "Item '" << id << "' (" << item.mName << ") has nonexistent script '" + << item.mScript << "', ignoring it."; } } } @@ -139,14 +150,14 @@ namespace MWWorld { ESMStore::StoreTuple mStores; - std::map mRecNameToStore; + std::map mRecNameToStore; // Lookup of all IDs. Makes looking up references faster. Just // maps the id name to the record type. IDMap mIds; IDMap mStaticIds; - template + template static void assignStoreToIndex(ESMStore& stores, Store& store) { const std::size_t storeIndex = ESMStore::getTypeIndex(); @@ -168,11 +179,11 @@ namespace MWWorld } }; - int ESMStore::find(const std::string_view id) const { IDMap::const_iterator it = mStoreImp->mIds.find(id); - if (it == mStoreImp->mIds.end()) { + if (it == mStoreImp->mIds.end()) + { return 0; } return it->second; @@ -180,8 +191,9 @@ namespace MWWorld int ESMStore::findStatic(const std::string_view id) const { - IDMap::const_iterator it = mStoreImp-> mStaticIds.find(id); - if (it == mStoreImp->mStaticIds.end()) { + IDMap::const_iterator it = mStoreImp->mStaticIds.find(id); + if (it == mStoreImp->mStaticIds.end()) + { return 0; } return it->second; @@ -190,7 +202,7 @@ namespace MWWorld ESMStore::ESMStore() { mStoreImp = std::make_unique(); - std::apply([this](auto& ...x) {(ESMStoreImp::assignStoreToIndex(*this, x), ...); }, mStoreImp->mStores); + std::apply([this](auto&... x) { (ESMStoreImp::assignStoreToIndex(*this, x), ...); }, mStoreImp->mStores); mDynamicCount = 0; getWritable().setCells(getWritable()); } @@ -205,355 +217,371 @@ namespace MWWorld movePlayerRecord(); } -static bool isCacheableRecord(int id) -{ - switch (id) + static bool isCacheableRecord(int id) { - case ESM::REC_ACTI: - case ESM::REC_ALCH: - case ESM::REC_APPA: - case ESM::REC_ARMO: - case ESM::REC_BOOK: - case ESM::REC_CLOT: - case ESM::REC_CONT: - case ESM::REC_CREA: - case ESM::REC_DOOR: - case ESM::REC_INGR: - case ESM::REC_LEVC: - case ESM::REC_LEVI: - case ESM::REC_LIGH: - case ESM::REC_LOCK: - case ESM::REC_MISC: - case ESM::REC_NPC_: - case ESM::REC_PROB: - case ESM::REC_REPA: - case ESM::REC_STAT: - case ESM::REC_WEAP: - case ESM::REC_BODY: - return true; - break; + switch (id) + { + case ESM::REC_ACTI: + case ESM::REC_ALCH: + case ESM::REC_APPA: + case ESM::REC_ARMO: + case ESM::REC_BOOK: + case ESM::REC_CLOT: + case ESM::REC_CONT: + case ESM::REC_CREA: + case ESM::REC_DOOR: + case ESM::REC_INGR: + case ESM::REC_LEVC: + case ESM::REC_LEVI: + case ESM::REC_LIGH: + case ESM::REC_LOCK: + case ESM::REC_MISC: + case ESM::REC_NPC_: + case ESM::REC_PROB: + case ESM::REC_REPA: + case ESM::REC_STAT: + case ESM::REC_WEAP: + case ESM::REC_BODY: + return true; + break; + } + return false; } - return false; -} -void ESMStore::load(ESM::ESMReader &esm, Loading::Listener* listener, ESM::Dialogue*& dialogue) -{ - if (listener != nullptr) - listener->setProgressRange(::EsmLoader::fileProgress); + void ESMStore::load(ESM::ESMReader& esm, Loading::Listener* listener, ESM::Dialogue*& dialogue) + { + if (listener != nullptr) + listener->setProgressRange(::EsmLoader::fileProgress); - // Land texture loading needs to use a separate internal store for each plugin. - // We set the number of plugins here so we can properly verify if valid plugin - // indices are being passed to the LandTexture Store retrieval methods. - getWritable().resize(esm.getIndex()+1); + // Land texture loading needs to use a separate internal store for each plugin. + // We set the number of plugins here so we can properly verify if valid plugin + // indices are being passed to the LandTexture Store retrieval methods. + getWritable().resize(esm.getIndex() + 1); - // Loop through all records - while(esm.hasMoreRecs()) - { - ESM::NAME n = esm.getRecName(); - esm.getRecHeader(); - if (esm.getRecordFlags() & ESM::FLAG_Ignored) + // Loop through all records + while (esm.hasMoreRecs()) { - esm.skipRecord(); - continue; - } + ESM::NAME n = esm.getRecName(); + esm.getRecHeader(); + if (esm.getRecordFlags() & ESM::FLAG_Ignored) + { + esm.skipRecord(); + continue; + } - // Look up the record type. - ESM::RecNameInts recName = static_cast(n.toInt()); - const auto& it = mStoreImp->mRecNameToStore.find(recName); + // Look up the record type. + ESM::RecNameInts recName = static_cast(n.toInt()); + const auto& it = mStoreImp->mRecNameToStore.find(recName); - if (it == mStoreImp->mRecNameToStore.end()) { - if (recName == ESM::REC_INFO) { - if (dialogue) + if (it == mStoreImp->mRecNameToStore.end()) + { + if (recName == ESM::REC_INFO) { - dialogue->readInfo(esm, esm.getIndex() != 0); + if (dialogue) + { + dialogue->readInfo(esm, esm.getIndex() != 0); + } + else + { + Log(Debug::Error) << "Error: info record without dialog"; + esm.skipRecord(); + } } - else + else if (n.toInt() == ESM::REC_MGEF) + { + getWritable().load(esm); + } + else if (n.toInt() == ESM::REC_SKIL) { - Log(Debug::Error) << "Error: info record without dialog"; + getWritable().load(esm); + } + else if (n.toInt() == ESM::REC_FILT || n.toInt() == ESM::REC_DBGP) + { + // ignore project file only records esm.skipRecord(); } - } else if (n.toInt() == ESM::REC_MGEF) { - getWritable().load (esm); - } else if (n.toInt() == ESM::REC_SKIL) { - getWritable().load (esm); - } - else if (n.toInt() == ESM::REC_FILT || n.toInt() == ESM::REC_DBGP) - { - // ignore project file only records - esm.skipRecord(); - } - else if (n.toInt() == ESM::REC_LUAL) - { - ESM::LuaScriptsCfg cfg; - cfg.load(esm); - cfg.adjustRefNums(esm); - mLuaContent.push_back(std::move(cfg)); - } - else { - throw std::runtime_error("Unknown record: " + n.toString()); + else if (n.toInt() == ESM::REC_LUAL) + { + ESM::LuaScriptsCfg cfg; + cfg.load(esm); + cfg.adjustRefNums(esm); + mLuaContent.push_back(std::move(cfg)); + } + else + { + throw std::runtime_error("Unknown record: " + n.toString()); + } } - } else { - RecordId id = it->second->load(esm); - if (id.mIsDeleted) + else { - it->second->eraseStatic(id.mId); - continue; - } + RecordId id = it->second->load(esm); + if (id.mIsDeleted) + { + it->second->eraseStatic(id.mId); + continue; + } - if (n.toInt() == ESM::REC_DIAL) { - dialogue = const_cast(getWritable().find(id.mId)); - } else { - dialogue = nullptr; + if (n.toInt() == ESM::REC_DIAL) + { + dialogue = const_cast(getWritable().find(id.mId)); + } + else + { + dialogue = nullptr; + } } + if (listener != nullptr) + listener->setProgress(::EsmLoader::fileProgress * esm.getFileOffset() / esm.getFileSize()); } - if (listener != nullptr) - listener->setProgress(::EsmLoader::fileProgress * esm.getFileOffset() / esm.getFileSize()); } -} -void ESMStore::setIdType(const std::string& id, ESM::RecNameInts type) -{ - mStoreImp->mIds[id] = type; -} + void ESMStore::setIdType(const std::string& id, ESM::RecNameInts type) + { + mStoreImp->mIds[id] = type; + } -ESM::LuaScriptsCfg ESMStore::getLuaScriptsCfg() const -{ - ESM::LuaScriptsCfg cfg; - for (const LuaContent& c : mLuaContent) + ESM::LuaScriptsCfg ESMStore::getLuaScriptsCfg() const { - if (std::holds_alternative(c)) + ESM::LuaScriptsCfg cfg; + for (const LuaContent& c : mLuaContent) { - // *.omwscripts are intentionally reloaded every time when `getLuaScriptsCfg` is called. - // It is important for the `reloadlua` console command. - try + if (std::holds_alternative(c)) { - auto file = std::ifstream(std::get(c)); - std::string fileContent(std::istreambuf_iterator(file), {}); - LuaUtil::parseOMWScripts(cfg, fileContent); + // *.omwscripts are intentionally reloaded every time when `getLuaScriptsCfg` is called. + // It is important for the `reloadlua` console command. + try + { + auto file = std::ifstream(std::get(c)); + std::string fileContent(std::istreambuf_iterator(file), {}); + LuaUtil::parseOMWScripts(cfg, fileContent); + } + catch (std::exception& e) + { + Log(Debug::Error) << e.what(); + } + } + else + { + const ESM::LuaScriptsCfg& addition = std::get(c); + cfg.mScripts.insert(cfg.mScripts.end(), addition.mScripts.begin(), addition.mScripts.end()); } - catch (std::exception& e) { Log(Debug::Error) << e.what(); } - } - else - { - const ESM::LuaScriptsCfg& addition = std::get(c); - cfg.mScripts.insert(cfg.mScripts.end(), addition.mScripts.begin(), addition.mScripts.end()); } + return cfg; } - return cfg; -} -void ESMStore::setUp() -{ - mStoreImp->mIds.clear(); - - std::map::iterator storeIt = mStoreImp->mRecNameToStore.begin(); - for (; storeIt != mStoreImp->mRecNameToStore.end(); ++storeIt) { - storeIt->second->setUp(); + void ESMStore::setUp() + { + mStoreImp->mIds.clear(); - if (isCacheableRecord(storeIt->first)) + std::map::iterator storeIt = mStoreImp->mRecNameToStore.begin(); + for (; storeIt != mStoreImp->mRecNameToStore.end(); ++storeIt) { - std::vector identifiers; - storeIt->second->listIdentifier(identifiers); + storeIt->second->setUp(); - for (std::vector::const_iterator record = identifiers.begin(); record != identifiers.end(); ++record) - mStoreImp->mIds[*record] = storeIt->first; + if (isCacheableRecord(storeIt->first)) + { + std::vector identifiers; + storeIt->second->listIdentifier(identifiers); + + for (std::vector::const_iterator record = identifiers.begin(); record != identifiers.end(); + ++record) + mStoreImp->mIds[*record] = storeIt->first; + } } - } - if (mStoreImp->mStaticIds.empty()) - for (const auto& [k, v] : mStoreImp->mIds) - mStoreImp->mStaticIds.emplace(Misc::StringUtils::lowerCase(k), v); + if (mStoreImp->mStaticIds.empty()) + for (const auto& [k, v] : mStoreImp->mIds) + mStoreImp->mStaticIds.emplace(Misc::StringUtils::lowerCase(k), v); - getWritable().setUp(); - getWritable().setUp();; - getWritable().setUp(); - getWritable().setUp(); -} - -void ESMStore::validateRecords(ESM::ReadersCache& readers) -{ - validate(); - countAllCellRefs(readers); -} + getWritable().setUp(); + getWritable().setUp(); + ; + getWritable().setUp(); + getWritable().setUp(); + } -void ESMStore::countAllCellRefs(ESM::ReadersCache& readers) -{ - // TODO: We currently need to read entire files here again. - // We should consider consolidating or deferring this reading. - if(!mRefCount.empty()) - return; - std::vector refs; - std::vector refIDs; - Store Cells = getWritable < ESM::Cell>(); - for(auto it = Cells.intBegin(); it != Cells.intEnd(); ++it) - readRefs(*it, refs, refIDs, readers); - for(auto it = Cells.extBegin(); it != Cells.extEnd(); ++it) - readRefs(*it, refs, refIDs, readers); - const auto lessByRefNum = [] (const Ref& l, const Ref& r) { return l.mRefNum < r.mRefNum; }; - std::stable_sort(refs.begin(), refs.end(), lessByRefNum); - const auto equalByRefNum = [] (const Ref& l, const Ref& r) { return l.mRefNum == r.mRefNum; }; - const auto incrementRefCount = [&] (const Ref& value) + void ESMStore::validateRecords(ESM::ReadersCache& readers) { - if (value.mRefID != deletedRefID) - { - std::string& refId = refIDs[value.mRefID]; - // We manually lower case IDs here for the time being to improve performance. - Misc::StringUtils::lowerCaseInPlace(refId); - ++mRefCount[std::move(refId)]; - } - }; - Misc::forEachUnique(refs.rbegin(), refs.rend(), equalByRefNum, incrementRefCount); -} - -int ESMStore::getRefCount(std::string_view id) const -{ - const std::string lowerId = Misc::StringUtils::lowerCase(id); - auto it = mRefCount.find(lowerId); - if(it == mRefCount.end()) - return 0; - return it->second; -} + validate(); + countAllCellRefs(readers); + } -void ESMStore::validate() -{ - auto& npcs = getWritable(); - std::vector npcsToReplace = getNPCsToReplace(getWritable(), getWritable(), npcs.mStatic); + void ESMStore::countAllCellRefs(ESM::ReadersCache& readers) + { + // TODO: We currently need to read entire files here again. + // We should consider consolidating or deferring this reading. + if (!mRefCount.empty()) + return; + std::vector refs; + std::vector refIDs; + Store Cells = getWritable(); + for (auto it = Cells.intBegin(); it != Cells.intEnd(); ++it) + readRefs(*it, refs, refIDs, readers); + for (auto it = Cells.extBegin(); it != Cells.extEnd(); ++it) + readRefs(*it, refs, refIDs, readers); + const auto lessByRefNum = [](const Ref& l, const Ref& r) { return l.mRefNum < r.mRefNum; }; + std::stable_sort(refs.begin(), refs.end(), lessByRefNum); + const auto equalByRefNum = [](const Ref& l, const Ref& r) { return l.mRefNum == r.mRefNum; }; + const auto incrementRefCount = [&](const Ref& value) { + if (value.mRefID != deletedRefID) + { + std::string& refId = refIDs[value.mRefID]; + // We manually lower case IDs here for the time being to improve performance. + Misc::StringUtils::lowerCaseInPlace(refId); + ++mRefCount[std::move(refId)]; + } + }; + Misc::forEachUnique(refs.rbegin(), refs.rend(), equalByRefNum, incrementRefCount); + } - for (const ESM::NPC &npc : npcsToReplace) + int ESMStore::getRefCount(std::string_view id) const { - npcs.eraseStatic(npc.mId); - npcs.insertStatic(npc); + const std::string lowerId = Misc::StringUtils::lowerCase(id); + auto it = mRefCount.find(lowerId); + if (it == mRefCount.end()) + return 0; + return it->second; } - // Validate spell effects for invalid arguments - std::vector spellsToReplace; - auto& spells = getWritable(); - for (ESM::Spell spell : spells) + void ESMStore::validate() { - if (spell.mEffects.mList.empty()) - continue; + auto& npcs = getWritable(); + std::vector npcsToReplace + = getNPCsToReplace(getWritable(), getWritable(), npcs.mStatic); - bool changed = false; - auto iter = spell.mEffects.mList.begin(); - while (iter != spell.mEffects.mList.end()) + for (const ESM::NPC& npc : npcsToReplace) { - const ESM::MagicEffect* mgef = getWritable().search(iter->mEffectID); - if (!mgef) - { - Log(Debug::Verbose) << "Spell '" << spell.mId << "' has an invalid effect (index " << iter->mEffectID << ") present. Dropping the effect."; - iter = spell.mEffects.mList.erase(iter); - changed = true; + npcs.eraseStatic(npc.mId); + npcs.insertStatic(npc); + } + + // Validate spell effects for invalid arguments + std::vector spellsToReplace; + auto& spells = getWritable(); + for (ESM::Spell spell : spells) + { + if (spell.mEffects.mList.empty()) continue; - } - if (mgef->mData.mFlags & ESM::MagicEffect::TargetSkill) + bool changed = false; + auto iter = spell.mEffects.mList.begin(); + while (iter != spell.mEffects.mList.end()) { - if (iter->mAttribute != -1) + const ESM::MagicEffect* mgef = getWritable().search(iter->mEffectID); + if (!mgef) { - iter->mAttribute = -1; - Log(Debug::Verbose) << ESM::MagicEffect::effectIdToString(iter->mEffectID) << - " effect of spell '" << spell.mId << "' has an attribute argument present. Dropping the argument."; + Log(Debug::Verbose) << "Spell '" << spell.mId << "' has an invalid effect (index " + << iter->mEffectID << ") present. Dropping the effect."; + iter = spell.mEffects.mList.erase(iter); changed = true; + continue; } - } - else if (mgef->mData.mFlags & ESM::MagicEffect::TargetAttribute) - { - if (iter->mSkill != -1) + + if (mgef->mData.mFlags & ESM::MagicEffect::TargetSkill) + { + if (iter->mAttribute != -1) + { + iter->mAttribute = -1; + Log(Debug::Verbose) + << ESM::MagicEffect::effectIdToString(iter->mEffectID) << " effect of spell '" << spell.mId + << "' has an attribute argument present. Dropping the argument."; + changed = true; + } + } + else if (mgef->mData.mFlags & ESM::MagicEffect::TargetAttribute) + { + if (iter->mSkill != -1) + { + iter->mSkill = -1; + Log(Debug::Verbose) + << ESM::MagicEffect::effectIdToString(iter->mEffectID) << " effect of spell '" << spell.mId + << "' has a skill argument present. Dropping the argument."; + changed = true; + } + } + else if (iter->mSkill != -1 || iter->mAttribute != -1) { iter->mSkill = -1; - Log(Debug::Verbose) << ESM::MagicEffect::effectIdToString(iter->mEffectID) << - " effect of spell '" << spell.mId << "' has a skill argument present. Dropping the argument."; + iter->mAttribute = -1; + Log(Debug::Verbose) << ESM::MagicEffect::effectIdToString(iter->mEffectID) << " effect of spell '" + << spell.mId << "' has argument(s) present. Dropping the argument(s)."; changed = true; } - } - else if (iter->mSkill != -1 || iter->mAttribute != -1) - { - iter->mSkill = -1; - iter->mAttribute = -1; - Log(Debug::Verbose) << ESM::MagicEffect::effectIdToString(iter->mEffectID) << - " effect of spell '" << spell.mId << "' has argument(s) present. Dropping the argument(s)."; - changed = true; + + ++iter; } - ++iter; + if (changed) + spellsToReplace.emplace_back(spell); } - if (changed) - spellsToReplace.emplace_back(spell); + for (const ESM::Spell& spell : spellsToReplace) + { + spells.eraseStatic(spell.mId); + spells.insertStatic(spell); + } } - for (const ESM::Spell &spell : spellsToReplace) + void ESMStore::movePlayerRecord() { - spells.eraseStatic(spell.mId); - spells.insertStatic(spell); + auto& npcs = getWritable(); + auto player = npcs.find("player"); + npcs.insert(*player); } -} - -void ESMStore::movePlayerRecord() -{ - auto& npcs = getWritable(); - auto player = npcs.find("player"); - npcs.insert(*player); -} -void ESMStore::validateDynamic() -{ - auto& npcs = getWritable(); - auto& scripts = getWritable(); + void ESMStore::validateDynamic() + { + auto& npcs = getWritable(); + auto& scripts = getWritable(); - std::vector npcsToReplace = getNPCsToReplace(getWritable(), getWritable(), npcs.mDynamic); + std::vector npcsToReplace + = getNPCsToReplace(getWritable(), getWritable(), npcs.mDynamic); - for (const ESM::NPC &npc : npcsToReplace) - npcs.insert(npc); + for (const ESM::NPC& npc : npcsToReplace) + npcs.insert(npc); - removeMissingScripts(scripts, getWritable().mDynamic); - removeMissingScripts(scripts, getWritable().mDynamic); - removeMissingScripts(scripts, getWritable().mDynamic); - removeMissingScripts(scripts, getWritable().mDynamic); + removeMissingScripts(scripts, getWritable().mDynamic); + removeMissingScripts(scripts, getWritable().mDynamic); + removeMissingScripts(scripts, getWritable().mDynamic); + removeMissingScripts(scripts, getWritable().mDynamic); - removeMissingObjects(getWritable()); - removeMissingObjects(getWritable()); -} + removeMissingObjects(getWritable()); + removeMissingObjects(getWritable()); + } -// Leveled lists can be modified by scripts. This removes items that no longer exist (presumably because the plugin was removed) from modified lists -template -void ESMStore::removeMissingObjects(Store& store) -{ - for(auto& entry : store.mDynamic) + // Leveled lists can be modified by scripts. This removes items that no longer exist (presumably because the plugin + // was removed) from modified lists + template + void ESMStore::removeMissingObjects(Store& store) { - auto first = std::remove_if(entry.second.mList.begin(), entry.second.mList.end(), [&] (const auto& item) + for (auto& entry : store.mDynamic) { - if(!find(item.mId)) - { - Log(Debug::Verbose) << "Leveled list '" << entry.first << "' has nonexistent object '" << item.mId << "', ignoring it."; - return true; - } - return false; - }); - entry.second.mList.erase(first, entry.second.mList.end()); + auto first = std::remove_if(entry.second.mList.begin(), entry.second.mList.end(), [&](const auto& item) { + if (!find(item.mId)) + { + Log(Debug::Verbose) << "Leveled list '" << entry.first << "' has nonexistent object '" << item.mId + << "', ignoring it."; + return true; + } + return false; + }); + entry.second.mList.erase(first, entry.second.mList.end()); + } } -} int ESMStore::countSavedGameRecords() const { return 1 // DYNA (dynamic name counter) - + get().getDynamicSize() - + get().getDynamicSize() - + get().getDynamicSize() - + get().getDynamicSize() - + get().getDynamicSize() - + get().getDynamicSize() - + get().getDynamicSize() - + get().getDynamicSize() - + get().getDynamicSize() - + get().getDynamicSize() - + get().getDynamicSize() - + get().getDynamicSize() + + get().getDynamicSize() + get().getDynamicSize() + + get().getDynamicSize() + get().getDynamicSize() + + get().getDynamicSize() + get().getDynamicSize() + + get().getDynamicSize() + get().getDynamicSize() + + get().getDynamicSize() + get().getDynamicSize() + + get().getDynamicSize() + get().getDynamicSize() + get().getDynamicSize(); - } - void ESMStore::write (ESM::ESMWriter& writer, Loading::Listener& progress) const + void ESMStore::write(ESM::ESMWriter& writer, Loading::Listener& progress) const { writer.startRecord(ESM::REC_DYNA); writer.startSubRecord("COUN"); @@ -561,22 +589,22 @@ void ESMStore::removeMissingObjects(Store& store) writer.endRecord("COUN"); writer.endRecord(ESM::REC_DYNA); - get().write (writer, progress); - get().write (writer, progress); - get().write (writer, progress); - get().write (writer, progress); - get().write (writer, progress); - get().write (writer, progress); - get().write (writer, progress); - get().write (writer, progress); - get().write (writer, progress); - get().write (writer, progress); - get().write (writer, progress); - get().write (writer, progress); - get().write (writer, progress); + get().write(writer, progress); + get().write(writer, progress); + get().write(writer, progress); + get().write(writer, progress); + get().write(writer, progress); + get().write(writer, progress); + get().write(writer, progress); + get().write(writer, progress); + get().write(writer, progress); + get().write(writer, progress); + get().write(writer, progress); + get().write(writer, progress); + get().write(writer, progress); } - bool ESMStore::readRecord (ESM::ESMReader& reader, uint32_t type_id) + bool ESMStore::readRecord(ESM::ESMReader& reader, uint32_t type_id) { ESM::RecNameInts type = (ESM::RecNameInts)type_id; switch (type) @@ -591,12 +619,12 @@ void ESMStore::removeMissingObjects(Store& store) case ESM::REC_WEAP: case ESM::REC_LEVI: case ESM::REC_LEVC: - mStoreImp->mRecNameToStore[type]->read (reader); + mStoreImp->mRecNameToStore[type]->read(reader); return true; case ESM::REC_NPC_: case ESM::REC_CREA: case ESM::REC_CONT: - mStoreImp->mRecNameToStore[type]->read (reader, true); + mStoreImp->mRecNameToStore[type]->read(reader, true); return true; case ESM::REC_DYNA: @@ -614,11 +642,10 @@ void ESMStore::removeMissingObjects(Store& store) { setUp(); - const ESM::NPC *player = get().find ("player"); + const ESM::NPC* player = get().find("player"); - if (!get().find (player->mRace) || - !get().find (player->mClass)) - throw std::runtime_error ("Invalid player record (race or class unavailable"); + if (!get().find(player->mRace) || !get().find(player->mClass)) + throw std::runtime_error("Invalid player record (race or class unavailable"); } std::pair, bool> ESMStore::getSpellList(const std::string& id) const @@ -634,21 +661,22 @@ void ESMStore::removeMissingObjects(Store& store) if (result != mSpellListCache.end()) result->second = ptr; else - mSpellListCache.insert({id, ptr}); - return {ptr, false}; + mSpellListCache.insert({ id, ptr }); + return { ptr, false }; } - return {ptr, true}; + return { ptr, true }; } template <> - const ESM::Cell *ESMStore::insert(const ESM::Cell &cell) { + const ESM::Cell* ESMStore::insert(const ESM::Cell& cell) + { return getWritable().insert(cell); } template <> - const ESM::NPC *ESMStore::insert(const ESM::NPC &npc) + const ESM::NPC* ESMStore::insert(const ESM::NPC& npc) { - + auto& npcs = getWritable(); if (Misc::StringUtils::ciEqual(npc.mId, "player")) { @@ -664,7 +692,7 @@ void ESMStore::removeMissingObjects(Store& store) record.mId = id; - ESM::NPC *ptr = npcs.insert(record); + ESM::NPC* ptr = npcs.insert(record); mStoreImp->mIds[ptr->mId] = ESM::REC_NPC_; return ptr; } diff --git a/apps/openmw/mwworld/esmstore.hpp b/apps/openmw/mwworld/esmstore.hpp index c5a860a823..d41312ac4e 100644 --- a/apps/openmw/mwworld/esmstore.hpp +++ b/apps/openmw/mwworld/esmstore.hpp @@ -1,11 +1,11 @@ #ifndef OPENMW_MWWORLD_ESMSTORE_H #define OPENMW_MWWORLD_ESMSTORE_H +#include #include #include -#include #include -#include +#include #include #include @@ -76,58 +76,27 @@ namespace MWWorld class ESMStore { - friend struct ESMStoreImp; //This allows StoreImp to extend esmstore without beeing included everywhere - - using StoreTuple = std::tuple < - Store, - Store, - Store, - Store, - Store, - Store, - Store, - Store, - Store, - Store, - Store, - Store, - Store, - Store, - Store, - Store, - Store, - Store, - Store, - Store, - Store, - Store, - Store, - Store, - Store, - Store, - Store, - Store, - Store, - Store, - Store, - Store, - Store, - Store, + friend struct ESMStoreImp; // This allows StoreImp to extend esmstore without beeing included everywhere + + using StoreTuple = std::tuple, Store, Store, + Store, Store, Store, Store, Store, + Store, Store, Store, Store, Store, + Store, Store, Store, Store, + Store, Store, Store, Store, + Store, Store, Store, Store, Store, + Store, Store, Store, Store, + Store, Store, Store, Store, Store, // Lists that need special rules - Store, - Store, - Store, - Store, + Store, Store, Store, Store, - Store, - Store, + Store, Store, // Special entry which is hardcoded and not loaded from an ESM - Store>; + Store>; - template + template static constexpr std::size_t getTypeIndex() { static_assert(Misc::TupleHasType, StoreTuple>::value); @@ -143,24 +112,28 @@ namespace MWWorld unsigned int mDynamicCount; - mutable std::unordered_map, Misc::StringUtils::CiHash, Misc::StringUtils::CiEqual> mSpellListCache; + mutable std::unordered_map, Misc::StringUtils::CiHash, + Misc::StringUtils::CiEqual> + mSpellListCache; template - Store& getWritable() {return static_cast&>(*mStores[getTypeIndex()]);} + Store& getWritable() + { + return static_cast&>(*mStores[getTypeIndex()]); + } /// Validate entries in store after setup void validate(); void countAllCellRefs(ESM::ReadersCache& readers); - template + template void removeMissingObjects(Store& store); void setIdType(const std::string& id, ESM::RecNameInts type); - using LuaContent = std::variant< - ESM::LuaScriptsCfg, // data from an omwaddon - std::filesystem::path>; // path to an omwscripts file + using LuaContent = std::variant; // path to an omwscripts file std::vector mLuaContent; public: @@ -170,20 +143,15 @@ namespace MWWorld /// \todo replace with SharedIterator typedef std::vector::const_iterator iterator; - iterator begin() const { - return mDynamicStores.begin(); - } + iterator begin() const { return mDynamicStores.begin(); } - iterator end() const { - return mDynamicStores.end(); - } + iterator end() const { return mDynamicStores.end(); } /// Look up the given ID in 'all'. Returns 0 if not found. int find(const std::string_view id) const; int findStatic(const std::string_view id) const; - ESMStore(); ~ESMStore(); @@ -194,18 +162,21 @@ namespace MWWorld /// Validate entries in store after loading a save void validateDynamic(); - void load(ESM::ESMReader &esm, Loading::Listener* listener, ESM::Dialogue*& dialogue); + void load(ESM::ESMReader& esm, Loading::Listener* listener, ESM::Dialogue*& dialogue); template - const Store& get() const {return static_cast&>(*mStores[getTypeIndex()]);} + const Store& get() const + { + return static_cast&>(*mStores[getTypeIndex()]); + } /// Insert a custom record (i.e. with a generated ID that will not clash will pre-existing records) template - const T *insert(const T &x) + const T* insert(const T& x) { const std::string id = "$dynamic" + std::to_string(mDynamicCount++); - Store &store = getWritable(); + Store& store = getWritable(); if (store.search(id) != nullptr) { const std::string msg = "Try to override existing record '" + id + "'"; @@ -215,7 +186,7 @@ namespace MWWorld record.mId = id; - T *ptr = store.insert(record); + T* ptr = store.insert(record); if constexpr (std::is_convertible_v*, DynamicStore*>) { setIdType(ptr->mId, T::sRecordId); @@ -225,10 +196,11 @@ namespace MWWorld /// Insert a record with set ID, and allow it to override a pre-existing static record. template - const T *overrideRecord(const T &x) { - Store &store = getWritable(); + const T* overrideRecord(const T& x) + { + Store& store = getWritable(); - T *ptr = store.insert(x); + T* ptr = store.insert(x); if constexpr (std::is_convertible_v*, DynamicStore*>) { setIdType(ptr->mId, T::sRecordId); @@ -237,7 +209,7 @@ namespace MWWorld } template - const T *insertStatic(const T &x) + const T* insertStatic(const T& x) { Store& store = getWritable(); if (store.search(x.mId) != nullptr) @@ -246,7 +218,7 @@ namespace MWWorld throw std::runtime_error(msg); } - T *ptr = store.insertStatic(x); + T* ptr = store.insertStatic(x); if constexpr (std::is_convertible_v*, DynamicStore*>) { setIdType(ptr->mId, T::sRecordId); @@ -261,9 +233,9 @@ namespace MWWorld int countSavedGameRecords() const; - void write (ESM::ESMWriter& writer, Loading::Listener& progress) const; + void write(ESM::ESMWriter& writer, Loading::Listener& progress) const; - bool readRecord (ESM::ESMReader& reader, uint32_t type); + bool readRecord(ESM::ESMReader& reader, uint32_t type); ///< \return Known type? // To be called when we are done with dynamic record loading @@ -275,7 +247,6 @@ namespace MWWorld /// Actors with the same ID share spells, abilities, etc. /// @return The shared spell list to use for this actor and whether or not it has already been initialized. std::pair, bool> getSpellList(const std::string& id) const; - }; template <> const ESM::Cell* ESMStore::insert(const ESM::Cell& cell); diff --git a/apps/openmw/mwworld/failedaction.cpp b/apps/openmw/mwworld/failedaction.cpp index 3d5ca55690..05bec12074 100644 --- a/apps/openmw/mwworld/failedaction.cpp +++ b/apps/openmw/mwworld/failedaction.cpp @@ -8,12 +8,14 @@ namespace MWWorld { FailedAction::FailedAction(std::string_view msg, const Ptr& target) - : Action(false, target), mMessage(msg) - { } + : Action(false, target) + , mMessage(msg) + { + } - void FailedAction::executeImp(const Ptr &actor) + void FailedAction::executeImp(const Ptr& actor) { - if(actor == MWMechanics::getPlayer() && !mMessage.empty()) + if (actor == MWMechanics::getPlayer() && !mMessage.empty()) MWBase::Environment::get().getWindowManager()->messageBox(mMessage); } } diff --git a/apps/openmw/mwworld/failedaction.hpp b/apps/openmw/mwworld/failedaction.hpp index 80fd53cc79..329a59443a 100644 --- a/apps/openmw/mwworld/failedaction.hpp +++ b/apps/openmw/mwworld/failedaction.hpp @@ -10,7 +10,7 @@ namespace MWWorld { std::string_view mMessage; - void executeImp(const Ptr &actor) override; + void executeImp(const Ptr& actor) override; public: FailedAction(std::string_view message = {}, const Ptr& target = Ptr()); diff --git a/apps/openmw/mwworld/globals.cpp b/apps/openmw/mwworld/globals.cpp index cbf2600e0e..485d03b071 100644 --- a/apps/openmw/mwworld/globals.cpp +++ b/apps/openmw/mwworld/globals.cpp @@ -2,35 +2,35 @@ #include -#include #include +#include #include #include "esmstore.hpp" namespace MWWorld { - Globals::Collection::const_iterator Globals::find (std::string_view name) const + Globals::Collection::const_iterator Globals::find(std::string_view name) const { - Collection::const_iterator iter = mVariables.find (Misc::StringUtils::lowerCase (name)); + Collection::const_iterator iter = mVariables.find(Misc::StringUtils::lowerCase(name)); - if (iter==mVariables.end()) - throw std::runtime_error ("unknown global variable: " + std::string{name}); + if (iter == mVariables.end()) + throw std::runtime_error("unknown global variable: " + std::string{ name }); return iter; } - Globals::Collection::iterator Globals::find (std::string_view name) + Globals::Collection::iterator Globals::find(std::string_view name) { - Collection::iterator iter = mVariables.find (Misc::StringUtils::lowerCase (name)); + Collection::iterator iter = mVariables.find(Misc::StringUtils::lowerCase(name)); - if (iter==mVariables.end()) - throw std::runtime_error ("unknown global variable: " + std::string{name}); + if (iter == mVariables.end()) + throw std::runtime_error("unknown global variable: " + std::string{ name }); return iter; } - void Globals::fill (const MWWorld::ESMStore& store) + void Globals::fill(const MWWorld::ESMStore& store) { mVariables.clear(); @@ -38,34 +38,38 @@ namespace MWWorld for (const ESM::Global& esmGlobal : globals) { - mVariables.insert (std::make_pair (Misc::StringUtils::lowerCase (esmGlobal.mId), esmGlobal)); + mVariables.insert(std::make_pair(Misc::StringUtils::lowerCase(esmGlobal.mId), esmGlobal)); } } - const ESM::Variant& Globals::operator[] (std::string_view name) const + const ESM::Variant& Globals::operator[](std::string_view name) const { - return find (Misc::StringUtils::lowerCase (name))->second.mValue; + return find(Misc::StringUtils::lowerCase(name))->second.mValue; } - ESM::Variant& Globals::operator[] (std::string_view name) + ESM::Variant& Globals::operator[](std::string_view name) { - return find (Misc::StringUtils::lowerCase (name))->second.mValue; + return find(Misc::StringUtils::lowerCase(name))->second.mValue; } - char Globals::getType (std::string_view name) const + char Globals::getType(std::string_view name) const { - Collection::const_iterator iter = mVariables.find (Misc::StringUtils::lowerCase (name)); + Collection::const_iterator iter = mVariables.find(Misc::StringUtils::lowerCase(name)); - if (iter==mVariables.end()) + if (iter == mVariables.end()) return ' '; switch (iter->second.mValue.getType()) { - case ESM::VT_Short: return 's'; - case ESM::VT_Long: return 'l'; - case ESM::VT_Float: return 'f'; - - default: return ' '; + case ESM::VT_Short: + return 's'; + case ESM::VT_Long: + return 'l'; + case ESM::VT_Float: + return 'f'; + + default: + return ' '; } } @@ -74,19 +78,19 @@ namespace MWWorld return mVariables.size(); } - void Globals::write (ESM::ESMWriter& writer, Loading::Listener& progress) const + void Globals::write(ESM::ESMWriter& writer, Loading::Listener& progress) const { - for (Collection::const_iterator iter (mVariables.begin()); iter!=mVariables.end(); ++iter) + for (Collection::const_iterator iter(mVariables.begin()); iter != mVariables.end(); ++iter) { - writer.startRecord (ESM::REC_GLOB); - iter->second.save (writer); - writer.endRecord (ESM::REC_GLOB); + writer.startRecord(ESM::REC_GLOB); + iter->second.save(writer); + writer.endRecord(ESM::REC_GLOB); } } - bool Globals::readRecord (ESM::ESMReader& reader, uint32_t type) + bool Globals::readRecord(ESM::ESMReader& reader, uint32_t type) { - if (type==ESM::REC_GLOB) + if (type == ESM::REC_GLOB) { ESM::Global global; bool isDeleted = false; @@ -96,8 +100,8 @@ namespace MWWorld global.load(reader, isDeleted); Misc::StringUtils::lowerCaseInPlace(global.mId); - Collection::iterator iter = mVariables.find (global.mId); - if (iter!=mVariables.end()) + Collection::iterator iter = mVariables.find(global.mId); + if (iter != mVariables.end()) iter->second = global; return true; diff --git a/apps/openmw/mwworld/globals.hpp b/apps/openmw/mwworld/globals.hpp index ff9caadd73..337226ce8e 100644 --- a/apps/openmw/mwworld/globals.hpp +++ b/apps/openmw/mwworld/globals.hpp @@ -1,9 +1,9 @@ #ifndef GAME_MWWORLD_GLOBALS_H #define GAME_MWWORLD_GLOBALS_H -#include -#include #include +#include +#include #include @@ -26,37 +26,34 @@ namespace MWWorld class Globals { - private: - - typedef std::map Collection; - - Collection mVariables; // type, value - - Collection::const_iterator find (std::string_view name) const; + private: + typedef std::map Collection; - Collection::iterator find (std::string_view name); + Collection mVariables; // type, value - public: + Collection::const_iterator find(std::string_view name) const; - const ESM::Variant& operator[] (std::string_view name) const; + Collection::iterator find(std::string_view name); - ESM::Variant& operator[] (std::string_view name); + public: + const ESM::Variant& operator[](std::string_view name) const; - char getType (std::string_view name) const; - ///< If there is no global variable with this name, ' ' is returned. + ESM::Variant& operator[](std::string_view name); - void fill (const MWWorld::ESMStore& store); - ///< Replace variables with variables from \a store with default values. + char getType(std::string_view name) const; + ///< If there is no global variable with this name, ' ' is returned. - int countSavedGameRecords() const; + void fill(const MWWorld::ESMStore& store); + ///< Replace variables with variables from \a store with default values. - void write (ESM::ESMWriter& writer, Loading::Listener& progress) const; + int countSavedGameRecords() const; - bool readRecord (ESM::ESMReader& reader, uint32_t type); - ///< Records for variables that do not exist are dropped silently. - /// - /// \return Known type? + void write(ESM::ESMWriter& writer, Loading::Listener& progress) const; + bool readRecord(ESM::ESMReader& reader, uint32_t type); + ///< Records for variables that do not exist are dropped silently. + /// + /// \return Known type? }; } diff --git a/apps/openmw/mwworld/groundcoverstore.cpp b/apps/openmw/mwworld/groundcoverstore.cpp index 251e05225a..acf7fa7915 100644 --- a/apps/openmw/mwworld/groundcoverstore.cpp +++ b/apps/openmw/mwworld/groundcoverstore.cpp @@ -1,13 +1,13 @@ #include "groundcoverstore.hpp" -#include -#include -#include +#include +#include #include +#include +#include #include +#include #include -#include -#include #include @@ -23,8 +23,8 @@ namespace MWWorld query.mLoadCells = true; ESM::ReadersCache readers; - const ::EsmLoader::EsmData content = ::EsmLoader::loadEsmData(query, groundcoverFiles, fileCollections, - readers, encoder, listener); + const ::EsmLoader::EsmData content + = ::EsmLoader::loadEsmData(query, groundcoverFiles, fileCollections, readers, encoder, listener); const VFS::Manager* const vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); @@ -51,7 +51,8 @@ namespace MWWorld for (const ESM::Cell& cell : content.mCells) { - if (!cell.isExterior()) continue; + if (!cell.isExterior()) + continue; auto cellIndex = std::make_pair(cell.getCellId().mIndex.mX, cell.getCellId().mIndex.mY); mCellContexts[cellIndex] = std::move(cell.mContextList); } @@ -61,7 +62,8 @@ namespace MWWorld { std::string idLower = Misc::StringUtils::lowerCase(id); auto search = mMeshCache.find(idLower); - if (search == mMeshCache.end()) return std::string(); + if (search == mMeshCache.end()) + return std::string(); return search->second; } diff --git a/apps/openmw/mwworld/groundcoverstore.hpp b/apps/openmw/mwworld/groundcoverstore.hpp index d955f731fc..55cc232b50 100644 --- a/apps/openmw/mwworld/groundcoverstore.hpp +++ b/apps/openmw/mwworld/groundcoverstore.hpp @@ -1,9 +1,9 @@ #ifndef GAME_MWWORLD_GROUNDCOVER_STORE_H #define GAME_MWWORLD_GROUNDCOVER_STORE_H -#include -#include #include +#include +#include namespace ESM { @@ -34,17 +34,17 @@ namespace MWWorld class GroundcoverStore { - private: - std::map mMeshCache; - std::map, std::vector> mCellContexts; + private: + std::map mMeshCache; + std::map, std::vector> mCellContexts; - public: - void init(const Store& statics, const Files::Collections& fileCollections, - const std::vector& groundcoverFiles, ToUTF8::Utf8Encoder* encoder, - Loading::Listener* listener); + public: + void init(const Store& statics, const Files::Collections& fileCollections, + const std::vector& groundcoverFiles, ToUTF8::Utf8Encoder* encoder, + Loading::Listener* listener); - std::string getGroundcoverModel(const std::string& id) const; - void initCell(ESM::Cell& cell, int cellX, int cellY) const; + std::string getGroundcoverModel(const std::string& id) const; + void initCell(ESM::Cell& cell, int cellX, int cellY) const; }; } diff --git a/apps/openmw/mwworld/inventorystore.cpp b/apps/openmw/mwworld/inventorystore.cpp index 3a46e022fb..78d4a460cf 100644 --- a/apps/openmw/mwworld/inventorystore.cpp +++ b/apps/openmw/mwworld/inventorystore.cpp @@ -1,70 +1,72 @@ #include "inventorystore.hpp" -#include #include +#include #include -#include #include +#include #include #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/world.hpp" +#include "../mwmechanics/actorutil.hpp" #include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/spellresistance.hpp" #include "../mwmechanics/spellutil.hpp" -#include "../mwmechanics/actorutil.hpp" #include "../mwmechanics/weapontype.hpp" -#include "esmstore.hpp" #include "class.hpp" +#include "esmstore.hpp" -void MWWorld::InventoryStore::copySlots (const InventoryStore& store) +void MWWorld::InventoryStore::copySlots(const InventoryStore& store) { // some const-trickery, required because of a flaw in the handling of MW-references and the // resulting workarounds - for (std::vector::const_iterator iter ( - const_cast (store).mSlots.begin()); - iter!=const_cast (store).mSlots.end(); ++iter) + for (std::vector::const_iterator iter(const_cast(store).mSlots.begin()); + iter != const_cast(store).mSlots.end(); ++iter) { - std::size_t distance = std::distance (const_cast (store).begin(), *iter); + std::size_t distance = std::distance(const_cast(store).begin(), *iter); ContainerStoreIterator slot = begin(); - std::advance (slot, distance); + std::advance(slot, distance); - mSlots.push_back (slot); + mSlots.push_back(slot); } // some const-trickery, required because of a flaw in the handling of MW-references and the // resulting workarounds - std::size_t distance = std::distance (const_cast (store).begin(), const_cast (store).mSelectedEnchantItem); + std::size_t distance = std::distance( + const_cast(store).begin(), const_cast(store).mSelectedEnchantItem); ContainerStoreIterator slot = begin(); - std::advance (slot, distance); + std::advance(slot, distance); mSelectedEnchantItem = slot; } -void MWWorld::InventoryStore::initSlots (TSlots& slots_) +void MWWorld::InventoryStore::initSlots(TSlots& slots_) { - for (int i=0; i (mSlots.size()); ++i) - if (mSlots[i].getType()!=-1 && mSlots[i]->getBase()==&ref) + for (int i = 0; i < static_cast(mSlots.size()); ++i) + if (mSlots[i].getType() != -1 && mSlots[i]->getBase() == &ref) { inventory.mEquipmentSlots[index] = i; } - if (mSelectedEnchantItem.getType()!=-1 && mSelectedEnchantItem->getBase() == &ref) + if (mSelectedEnchantItem.getType() != -1 && mSelectedEnchantItem->getBase() == &ref) inventory.mSelectedEnchantItem = index; } -void MWWorld::InventoryStore::readEquipmentState(const MWWorld::ContainerStoreIterator &iter, int index, const ESM::InventoryState &inventory) +void MWWorld::InventoryStore::readEquipmentState( + const MWWorld::ContainerStoreIterator& iter, int index, const ESM::InventoryState& inventory) { if (index == inventory.mSelectedEnchantItem) mSelectedEnchantItem = iter; @@ -97,26 +99,26 @@ void MWWorld::InventoryStore::readEquipmentState(const MWWorld::ContainerStoreIt } MWWorld::InventoryStore::InventoryStore() - : ContainerStore() - , mInventoryListener(nullptr) - , mUpdatesEnabled (true) - , mFirstAutoEquip(true) - , mSelectedEnchantItem(end()) + : ContainerStore() + , mInventoryListener(nullptr) + , mUpdatesEnabled(true) + , mFirstAutoEquip(true) + , mSelectedEnchantItem(end()) { - initSlots (mSlots); + initSlots(mSlots); } -MWWorld::InventoryStore::InventoryStore (const InventoryStore& store) - : ContainerStore (store) - , mInventoryListener(store.mInventoryListener) - , mUpdatesEnabled(store.mUpdatesEnabled) - , mFirstAutoEquip(store.mFirstAutoEquip) - , mSelectedEnchantItem(end()) +MWWorld::InventoryStore::InventoryStore(const InventoryStore& store) + : ContainerStore(store) + , mInventoryListener(store.mInventoryListener) + , mUpdatesEnabled(store.mUpdatesEnabled) + , mFirstAutoEquip(store.mFirstAutoEquip) + , mSelectedEnchantItem(end()) { - copySlots (store); + copySlots(store); } -MWWorld::InventoryStore& MWWorld::InventoryStore::operator= (const InventoryStore& store) +MWWorld::InventoryStore& MWWorld::InventoryStore::operator=(const InventoryStore& store) { if (this == &store) return *this; @@ -125,19 +127,21 @@ MWWorld::InventoryStore& MWWorld::InventoryStore::operator= (const InventoryStor mInventoryListener = store.mInventoryListener; mFirstAutoEquip = store.mFirstAutoEquip; mRechargingItemsUpToDate = false; - ContainerStore::operator= (store); + ContainerStore::operator=(store); mSlots.clear(); - copySlots (store); + copySlots(store); return *this; } -MWWorld::ContainerStoreIterator MWWorld::InventoryStore::add(const Ptr& itemPtr, int count, const Ptr& actorPtr, bool allowAutoEquip, bool resolve) +MWWorld::ContainerStoreIterator MWWorld::InventoryStore::add( + const Ptr& itemPtr, int count, const Ptr& actorPtr, bool allowAutoEquip, bool resolve) { - const MWWorld::ContainerStoreIterator& retVal = MWWorld::ContainerStore::add(itemPtr, count, actorPtr, allowAutoEquip, resolve); + const MWWorld::ContainerStoreIterator& retVal + = MWWorld::ContainerStore::add(itemPtr, count, actorPtr, allowAutoEquip, resolve); // Auto-equip items if an armor/clothing item is added, but not for the player nor werewolves - if (allowAutoEquip && actorPtr != MWMechanics::getPlayer() - && actorPtr.getClass().isNpc() && !actorPtr.getClass().getNpcStats(actorPtr).isWerewolf()) + if (allowAutoEquip && actorPtr != MWMechanics::getPlayer() && actorPtr.getClass().isNpc() + && !actorPtr.getClass().getNpcStats(actorPtr).isWerewolf()) { auto type = itemPtr.getType(); if (type == ESM::Armor::sRecordId || type == ESM::Clothing::sRecordId) @@ -150,29 +154,30 @@ MWWorld::ContainerStoreIterator MWWorld::InventoryStore::add(const Ptr& itemPtr, return retVal; } -void MWWorld::InventoryStore::equip (int slot, const ContainerStoreIterator& iterator, const Ptr& actor) +void MWWorld::InventoryStore::equip(int slot, const ContainerStoreIterator& iterator, const Ptr& actor) { if (iterator == end()) - throw std::runtime_error ("can't equip end() iterator, use unequip function instead"); + throw std::runtime_error("can't equip end() iterator, use unequip function instead"); - if (slot<0 || slot>=static_cast (mSlots.size())) - throw std::runtime_error ("slot number out of range"); + if (slot < 0 || slot >= static_cast(mSlots.size())) + throw std::runtime_error("slot number out of range"); - if (iterator.getContainerStore()!=this) - throw std::runtime_error ("attempt to equip an item that is not in the inventory"); + if (iterator.getContainerStore() != this) + throw std::runtime_error("attempt to equip an item that is not in the inventory"); std::pair, bool> slots_; - slots_ = iterator->getClass().getEquipmentSlots (*iterator); + slots_ = iterator->getClass().getEquipmentSlots(*iterator); - if (std::find (slots_.first.begin(), slots_.first.end(), slot)==slots_.first.end()) - throw std::runtime_error ("invalid slot"); + if (std::find(slots_.first.begin(), slots_.first.end(), slot) == slots_.first.end()) + throw std::runtime_error("invalid slot"); if (mSlots[slot] != end()) unequipSlot(slot, actor); // unstack item pointed to by iterator if required - if (iterator!=end() && !slots_.second && iterator->getRefData().getCount() > 1) // if slots.second is true, item can stay stacked when equipped + if (iterator != end() && !slots_.second + && iterator->getRefData().getCount() > 1) // if slots.second is true, item can stay stacked when equipped { unstack(*iterator, actor); } @@ -187,7 +192,7 @@ void MWWorld::InventoryStore::equip (int slot, const ContainerStoreIterator& ite void MWWorld::InventoryStore::unequipAll(const MWWorld::Ptr& actor) { mUpdatesEnabled = false; - for (int slot=0; slot < MWWorld::InventoryStore::Slots; ++slot) + for (int slot = 0; slot < MWWorld::InventoryStore::Slots; ++slot) unequipSlot(slot, actor); mUpdatesEnabled = true; @@ -195,35 +200,36 @@ void MWWorld::InventoryStore::unequipAll(const MWWorld::Ptr& actor) fireEquipmentChangedEvent(actor); } -MWWorld::ContainerStoreIterator MWWorld::InventoryStore::getSlot (int slot) +MWWorld::ContainerStoreIterator MWWorld::InventoryStore::getSlot(int slot) { - return findSlot (slot); + return findSlot(slot); } -MWWorld::ConstContainerStoreIterator MWWorld::InventoryStore::getSlot (int slot) const +MWWorld::ConstContainerStoreIterator MWWorld::InventoryStore::getSlot(int slot) const { - return findSlot (slot); + return findSlot(slot); } -MWWorld::ContainerStoreIterator MWWorld::InventoryStore::findSlot (int slot) const +MWWorld::ContainerStoreIterator MWWorld::InventoryStore::findSlot(int slot) const { - if (slot<0 || slot>=static_cast (mSlots.size())) - throw std::runtime_error ("slot number out of range"); + if (slot < 0 || slot >= static_cast(mSlots.size())) + throw std::runtime_error("slot number out of range"); - if (mSlots[slot]==end()) + if (mSlots[slot] == end()) return mSlots[slot]; - if (mSlots[slot]->getRefData().getCount()<1) + if (mSlots[slot]->getRefData().getCount() < 1) { // Object has been deleted // This should no longer happen, since the new remove function will unequip first - throw std::runtime_error("Invalid slot, make sure you are not calling RefData::setCount for a container object"); + throw std::runtime_error( + "Invalid slot, make sure you are not calling RefData::setCount for a container object"); } return mSlots[slot]; } -void MWWorld::InventoryStore::autoEquipWeapon (const MWWorld::Ptr& actor, TSlots& slots_) +void MWWorld::InventoryStore::autoEquipWeapon(const MWWorld::Ptr& actor, TSlots& slots_) { if (!actor.getClass().isNpc()) { @@ -231,13 +237,12 @@ void MWWorld::InventoryStore::autoEquipWeapon (const MWWorld::Ptr& actor, TSlots // The only case when the difference is noticable - when this creature sells weapon. // So just disable weapon autoequipping for creatures which sells weapon. int services = actor.getClass().getServices(actor); - bool sellsWeapon = services & (ESM::NPC::Weapon|ESM::NPC::MagicItems); + bool sellsWeapon = services & (ESM::NPC::Weapon | ESM::NPC::MagicItems); if (sellsWeapon) return; } - static const ESM::Skill::SkillEnum weaponSkills[] = - { + static const ESM::Skill::SkillEnum weaponSkills[] = { ESM::Skill::LongBlade, ESM::Skill::Axe, ESM::Skill::Spear, @@ -256,7 +261,7 @@ void MWWorld::InventoryStore::autoEquipWeapon (const MWWorld::Ptr& actor, TSlots ContainerStoreIterator bolt(end()); // rate ammo - for (ContainerStoreIterator iter(begin(ContainerStore::Type_Weapon)); iter!=end(); ++iter) + for (ContainerStoreIterator iter(begin(ContainerStore::Type_Weapon)); iter != end(); ++iter) { const ESM::Weapon* esmWeapon = iter->get()->mBase; @@ -300,7 +305,7 @@ void MWWorld::InventoryStore::autoEquipWeapon (const MWWorld::Ptr& actor, TSlots max = 0; ContainerStoreIterator weapon(end()); - for (ContainerStoreIterator iter(begin(ContainerStore::Type_Weapon)); iter!=end(); ++iter) + for (ContainerStoreIterator iter(begin(ContainerStore::Type_Weapon)); iter != end(); ++iter) { const ESM::Weapon* esmWeapon = iter->get()->mBase; @@ -333,7 +338,7 @@ void MWWorld::InventoryStore::autoEquipWeapon (const MWWorld::Ptr& actor, TSlots { // Do not equip ranged weapons, if there is no suitable ammo bool hasAmmo = true; - const MWWorld::LiveCellRef *ref = weapon->get(); + const MWWorld::LiveCellRef* ref = weapon->get(); int type = ref->mBase->mData.mType; int ammotype = MWMechanics::getWeaponType(type)->mAmmoType; if (ammotype == ESM::Weapon::Arrow) @@ -353,7 +358,7 @@ void MWWorld::InventoryStore::autoEquipWeapon (const MWWorld::Ptr& actor, TSlots if (hasAmmo) { - std::pair, bool> itemsSlots = weapon->getClass().getEquipmentSlots (*weapon); + std::pair, bool> itemsSlots = weapon->getClass().getEquipmentSlots(*weapon); if (!itemsSlots.first.empty()) { @@ -380,7 +385,7 @@ void MWWorld::InventoryStore::autoEquipWeapon (const MWWorld::Ptr& actor, TSlots } } -void MWWorld::InventoryStore::autoEquipArmor (const MWWorld::Ptr& actor, TSlots& slots_) +void MWWorld::InventoryStore::autoEquipArmor(const MWWorld::Ptr& actor, TSlots& slots_) { // Only NPCs can wear armor for now. // For creatures we equip only shields. @@ -390,8 +395,8 @@ void MWWorld::InventoryStore::autoEquipArmor (const MWWorld::Ptr& actor, TSlots& return; } - const MWBase::World *world = MWBase::Environment::get().getWorld(); - const MWWorld::Store &store = world->getStore().get(); + const MWBase::World* world = MWBase::Environment::get().getWorld(); + const MWWorld::Store& store = world->getStore().get(); static float fUnarmoredBase1 = store.find("fUnarmoredBase1")->mValue.getFloat(); static float fUnarmoredBase2 = store.find("fUnarmoredBase2")->mValue.getFloat(); @@ -399,11 +404,12 @@ void MWWorld::InventoryStore::autoEquipArmor (const MWWorld::Ptr& actor, TSlots& float unarmoredSkill = actor.getClass().getSkill(actor, ESM::Skill::Unarmored); float unarmoredRating = (fUnarmoredBase1 * unarmoredSkill) * (fUnarmoredBase2 * unarmoredSkill); - for (ContainerStoreIterator iter (begin(ContainerStore::Type_Clothing | ContainerStore::Type_Armor)); iter!=end(); ++iter) + for (ContainerStoreIterator iter(begin(ContainerStore::Type_Clothing | ContainerStore::Type_Armor)); iter != end(); + ++iter) { Ptr test = *iter; - switch(test.getClass().canBeEquipped (test, actor).first) + switch (test.getClass().canBeEquipped(test, actor).first) { case 0: continue; @@ -411,23 +417,22 @@ void MWWorld::InventoryStore::autoEquipArmor (const MWWorld::Ptr& actor, TSlots& break; } - if (iter.getType() == ContainerStore::Type_Armor && - test.getClass().getEffectiveArmorRating(test, actor) <= std::max(unarmoredRating, 0.f)) + if (iter.getType() == ContainerStore::Type_Armor + && test.getClass().getEffectiveArmorRating(test, actor) <= std::max(unarmoredRating, 0.f)) { continue; } - std::pair, bool> itemsSlots = - iter->getClass().getEquipmentSlots (*iter); + std::pair, bool> itemsSlots = iter->getClass().getEquipmentSlots(*iter); // checking if current item pointed by iter can be equipped for (int slot : itemsSlots.first) { // if true then it means slot is equipped already // check if slot may require swapping if current item is more valuable - if (slots_.at (slot)!=end()) + if (slots_.at(slot) != end()) { - Ptr old = *slots_.at (slot); + Ptr old = *slots_.at(slot); if (iter.getType() == ContainerStore::Type_Armor) { @@ -438,7 +443,8 @@ void MWWorld::InventoryStore::autoEquipArmor (const MWWorld::Ptr& actor, TSlots& if (old.get()->mBase->mData.mType == test.get()->mBase->mData.mType) { - if (old.getClass().getEffectiveArmorRating(old, actor) >= test.getClass().getEffectiveArmorRating(test, actor)) + if (old.getClass().getEffectiveArmorRating(old, actor) + >= test.getClass().getEffectiveArmorRating(test, actor)) // old armor had better armor rating continue; } @@ -460,7 +466,7 @@ void MWWorld::InventoryStore::autoEquipArmor (const MWWorld::Ptr& actor, TSlots& Ptr rightRing = *slots_.at(Slot_RightRing); // we want to swap cheaper ring only if both are equipped - if (old.getClass().getValue (old) >= rightRing.getClass().getValue (rightRing)) + if (old.getClass().getValue(old) >= rightRing.getClass().getValue(rightRing)) continue; } } @@ -468,7 +474,7 @@ void MWWorld::InventoryStore::autoEquipArmor (const MWWorld::Ptr& actor, TSlots& if (old.getType() == ESM::Clothing::sRecordId) { // check value - if (old.getClass().getValue (old) >= test.getClass().getValue (test)) + if (old.getClass().getValue(old) >= test.getClass().getValue(test)) // old clothing was more valuable continue; } @@ -502,12 +508,11 @@ void MWWorld::InventoryStore::autoEquipShield(const MWWorld::Ptr& actor, TSlots& continue; if (iter->getClass().canBeEquipped(*iter, actor).first != 1) continue; - std::pair, bool> shieldSlots = - iter->getClass().getEquipmentSlots(*iter); + std::pair, bool> shieldSlots = iter->getClass().getEquipmentSlots(*iter); int slot = shieldSlots.first[0]; const ContainerStoreIterator& shield = slots_[slot]; - if (shield != end() - && shield.getType() == Type_Armor && shield->get()->mBase->mData.mType == ESM::Armor::Shield) + if (shield != end() && shield.getType() == Type_Armor + && shield->get()->mBase->mData.mType == ESM::Armor::Shield) { if (shield->getClass().getItemHealth(*shield) >= iter->getClass().getItemHealth(*iter)) continue; @@ -516,10 +521,10 @@ void MWWorld::InventoryStore::autoEquipShield(const MWWorld::Ptr& actor, TSlots& } } -void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor) +void MWWorld::InventoryStore::autoEquip(const MWWorld::Ptr& actor) { TSlots slots_; - initSlots (slots_); + initSlots(slots_); // Disable model update during auto-equip mUpdatesEnabled = false; @@ -533,7 +538,7 @@ void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor) bool changed = false; - for (std::size_t i=0; i=static_cast (mSlots.size())) - throw std::runtime_error ("slot number out of range"); + if (slot < 0 || slot >= static_cast(mSlots.size())) + throw std::runtime_error("slot number out of range"); ContainerStoreIterator it = mSlots[slot]; @@ -677,33 +681,35 @@ MWWorld::ContainerStoreIterator MWWorld::InventoryStore::unequipSlot(int slot, c return it; } -MWWorld::ContainerStoreIterator MWWorld::InventoryStore::unequipItem(const MWWorld::Ptr& item, const MWWorld::Ptr& actor) +MWWorld::ContainerStoreIterator MWWorld::InventoryStore::unequipItem( + const MWWorld::Ptr& item, const MWWorld::Ptr& actor) { - for (int slot=0; slot item.getRefData().getCount()) - throw std::runtime_error ("attempt to unequip more items than equipped"); + throw std::runtime_error("attempt to unequip more items than equipped"); if (count == item.getRefData().getCount()) return unequipItem(item, actor); // Move items to an existing stack if possible, otherwise split count items out into a new stack. // Moving counts manually here, since ContainerStore's restack can't target unequipped stacks. - for (MWWorld::ContainerStoreIterator iter (begin()); iter != end(); ++iter) + for (MWWorld::ContainerStoreIterator iter(begin()); iter != end(); ++iter) { if (stacks(*iter, item) && !isEquipped(*iter)) { @@ -721,7 +727,7 @@ MWWorld::InventoryStoreListener* MWWorld::InventoryStore::getInvListener() const return mInventoryListener; } -void MWWorld::InventoryStore::setInvListener(InventoryStoreListener *listener, const Ptr& actor) +void MWWorld::InventoryStore::setInvListener(InventoryStoreListener* listener, const Ptr& actor) { mInventoryListener = listener; } @@ -745,13 +751,13 @@ void MWWorld::InventoryStore::fireEquipmentChangedEvent(const Ptr& actor) void MWWorld::InventoryStore::clear() { mSlots.clear(); - initSlots (mSlots); + initSlots(mSlots); ContainerStore::clear(); } -bool MWWorld::InventoryStore::isEquipped(const MWWorld::ConstPtr &item) +bool MWWorld::InventoryStore::isEquipped(const MWWorld::ConstPtr& item) { - for (int i=0; i < MWWorld::InventoryStore::Slots; ++i) + for (int i = 0; i < MWWorld::InventoryStore::Slots; ++i) { if (getSlot(i) != end() && *getSlot(i) == item) return true; diff --git a/apps/openmw/mwworld/inventorystore.hpp b/apps/openmw/mwworld/inventorystore.hpp index 51eea3129d..53ca58440a 100644 --- a/apps/openmw/mwworld/inventorystore.hpp +++ b/apps/openmw/mwworld/inventorystore.hpp @@ -21,7 +21,7 @@ namespace MWWorld /** * Fired when items are equipped or unequipped */ - virtual void equipmentChanged () {} + virtual void equipmentChanged() {} virtual ~InventoryStoreListener() = default; }; @@ -29,150 +29,152 @@ namespace MWWorld ///< \brief Variant of the ContainerStore for NPCs class InventoryStore : public ContainerStore { - public: - - static constexpr int Slot_Helmet = 0; - static constexpr int Slot_Cuirass = 1; - static constexpr int Slot_Greaves = 2; - static constexpr int Slot_LeftPauldron = 3; - static constexpr int Slot_RightPauldron = 4; - static constexpr int Slot_LeftGauntlet = 5; - static constexpr int Slot_RightGauntlet = 6; - static constexpr int Slot_Boots = 7; - static constexpr int Slot_Shirt = 8; - static constexpr int Slot_Pants = 9; - static constexpr int Slot_Skirt = 10; - static constexpr int Slot_Robe = 11; - static constexpr int Slot_LeftRing = 12; - static constexpr int Slot_RightRing = 13; - static constexpr int Slot_Amulet = 14; - static constexpr int Slot_Belt = 15; - static constexpr int Slot_CarriedRight = 16; - static constexpr int Slot_CarriedLeft = 17; - static constexpr int Slot_Ammunition = 18; - - static constexpr int Slots = 19; - - static constexpr int Slot_NoSlot = -1; + public: + static constexpr int Slot_Helmet = 0; + static constexpr int Slot_Cuirass = 1; + static constexpr int Slot_Greaves = 2; + static constexpr int Slot_LeftPauldron = 3; + static constexpr int Slot_RightPauldron = 4; + static constexpr int Slot_LeftGauntlet = 5; + static constexpr int Slot_RightGauntlet = 6; + static constexpr int Slot_Boots = 7; + static constexpr int Slot_Shirt = 8; + static constexpr int Slot_Pants = 9; + static constexpr int Slot_Skirt = 10; + static constexpr int Slot_Robe = 11; + static constexpr int Slot_LeftRing = 12; + static constexpr int Slot_RightRing = 13; + static constexpr int Slot_Amulet = 14; + static constexpr int Slot_Belt = 15; + static constexpr int Slot_CarriedRight = 16; + static constexpr int Slot_CarriedLeft = 17; + static constexpr int Slot_Ammunition = 18; - private: + static constexpr int Slots = 19; - InventoryStoreListener* mInventoryListener; + static constexpr int Slot_NoSlot = -1; - // Enables updates of magic effects and actor model whenever items are equipped or unequipped. - // This is disabled during autoequip to avoid excessive updates - bool mUpdatesEnabled; + private: + InventoryStoreListener* mInventoryListener; - bool mFirstAutoEquip; + // Enables updates of magic effects and actor model whenever items are equipped or unequipped. + // This is disabled during autoequip to avoid excessive updates + bool mUpdatesEnabled; - typedef std::vector TSlots; + bool mFirstAutoEquip; - TSlots mSlots; + typedef std::vector TSlots; - void autoEquipWeapon(const MWWorld::Ptr& actor, TSlots& slots_); - void autoEquipArmor(const MWWorld::Ptr& actor, TSlots& slots_); - void autoEquipShield(const MWWorld::Ptr& actor, TSlots& slots_); + TSlots mSlots; - // selected magic item (for using enchantments of type "Cast once" or "Cast when used") - ContainerStoreIterator mSelectedEnchantItem; + void autoEquipWeapon(const MWWorld::Ptr& actor, TSlots& slots_); + void autoEquipArmor(const MWWorld::Ptr& actor, TSlots& slots_); + void autoEquipShield(const MWWorld::Ptr& actor, TSlots& slots_); - void copySlots (const InventoryStore& store); + // selected magic item (for using enchantments of type "Cast once" or "Cast when used") + ContainerStoreIterator mSelectedEnchantItem; - void initSlots (TSlots& slots_); + void copySlots(const InventoryStore& store); - void fireEquipmentChangedEvent(const Ptr& actor); + void initSlots(TSlots& slots_); - void storeEquipmentState (const MWWorld::LiveCellRefBase& ref, int index, ESM::InventoryState& inventory) const override; - void readEquipmentState (const MWWorld::ContainerStoreIterator& iter, int index, const ESM::InventoryState& inventory) override; + void fireEquipmentChangedEvent(const Ptr& actor); - ContainerStoreIterator findSlot (int slot) const; + void storeEquipmentState( + const MWWorld::LiveCellRefBase& ref, int index, ESM::InventoryState& inventory) const override; + void readEquipmentState( + const MWWorld::ContainerStoreIterator& iter, int index, const ESM::InventoryState& inventory) override; - public: + ContainerStoreIterator findSlot(int slot) const; - InventoryStore(); + public: + InventoryStore(); - InventoryStore (const InventoryStore& store); + InventoryStore(const InventoryStore& store); - InventoryStore& operator= (const InventoryStore& store); + InventoryStore& operator=(const InventoryStore& store); - std::unique_ptr clone() override { return std::make_unique(*this); } + std::unique_ptr clone() override { return std::make_unique(*this); } - ContainerStoreIterator add (const Ptr& itemPtr, int count, const Ptr& actorPtr, bool allowAutoEquip = true, bool resolve = true) override; - ///< Add the item pointed to by \a ptr to this container. (Stacks automatically if needed) - /// Auto-equip items if specific conditions are fulfilled and allowAutoEquip is true (see the implementation). - /// - /// \note The item pointed to is not required to exist beyond this function call. - /// - /// \attention Do not add items to an existing stack by increasing the count instead of - /// calling this function! - /// - /// @return if stacking happened, return iterator to the item that was stacked against, otherwise iterator to the newly inserted item. + ContainerStoreIterator add(const Ptr& itemPtr, int count, const Ptr& actorPtr, bool allowAutoEquip = true, + bool resolve = true) override; + ///< Add the item pointed to by \a ptr to this container. (Stacks automatically if needed) + /// Auto-equip items if specific conditions are fulfilled and allowAutoEquip is true (see the implementation). + /// + /// \note The item pointed to is not required to exist beyond this function call. + /// + /// \attention Do not add items to an existing stack by increasing the count instead of + /// calling this function! + /// + /// @return if stacking happened, return iterator to the item that was stacked against, otherwise iterator to + /// the newly inserted item. - void equip (int slot, const ContainerStoreIterator& iterator, const Ptr& actor); - ///< \warning \a iterator can not be an end()-iterator, use unequip function instead + void equip(int slot, const ContainerStoreIterator& iterator, const Ptr& actor); + ///< \warning \a iterator can not be an end()-iterator, use unequip function instead - bool isEquipped(const MWWorld::ConstPtr& item); - ///< Utility function, returns true if the given item is equipped in any slot + bool isEquipped(const MWWorld::ConstPtr& item); + ///< Utility function, returns true if the given item is equipped in any slot - void setSelectedEnchantItem(const ContainerStoreIterator& iterator); - ///< set the selected magic item (for using enchantments of type "Cast once" or "Cast when used") - /// \note to unset the selected item, call this method with end() iterator + void setSelectedEnchantItem(const ContainerStoreIterator& iterator); + ///< set the selected magic item (for using enchantments of type "Cast once" or "Cast when used") + /// \note to unset the selected item, call this method with end() iterator - ContainerStoreIterator getSelectedEnchantItem(); - ///< @return selected magic item (for using enchantments of type "Cast once" or "Cast when used") - /// \note if no item selected, return end() iterator + ContainerStoreIterator getSelectedEnchantItem(); + ///< @return selected magic item (for using enchantments of type "Cast once" or "Cast when used") + /// \note if no item selected, return end() iterator - ContainerStoreIterator getSlot (int slot); - ConstContainerStoreIterator getSlot(int slot) const; + ContainerStoreIterator getSlot(int slot); + ConstContainerStoreIterator getSlot(int slot) const; - ContainerStoreIterator getPreferredShield(const MWWorld::Ptr& actor); + ContainerStoreIterator getPreferredShield(const MWWorld::Ptr& actor); - void unequipAll(const MWWorld::Ptr& actor); - ///< Unequip all currently equipped items. + void unequipAll(const MWWorld::Ptr& actor); + ///< Unequip all currently equipped items. - void autoEquip (const MWWorld::Ptr& actor); - ///< Auto equip items according to stats and item value. + void autoEquip(const MWWorld::Ptr& actor); + ///< Auto equip items according to stats and item value. - bool stacks (const ConstPtr& ptr1, const ConstPtr& ptr2) const override; - ///< @return true if the two specified objects can stack with each other + bool stacks(const ConstPtr& ptr1, const ConstPtr& ptr2) const override; + ///< @return true if the two specified objects can stack with each other - using ContainerStore::remove; - int remove(const Ptr& item, int count, const Ptr& actor, bool equipReplacement = 0, bool resolve = true) override; - ///< Remove \a count item(s) designated by \a item from this inventory. - /// - /// @return the number of items actually removed + using ContainerStore::remove; + int remove( + const Ptr& item, int count, const Ptr& actor, bool equipReplacement = 0, bool resolve = true) override; + ///< Remove \a count item(s) designated by \a item from this inventory. + /// + /// @return the number of items actually removed - ContainerStoreIterator unequipSlot(int slot, const Ptr& actor, bool applyUpdates = true); - ///< Unequip \a slot. - /// - /// @return an iterator to the item that was previously in the slot + ContainerStoreIterator unequipSlot(int slot, const Ptr& actor, bool applyUpdates = true); + ///< Unequip \a slot. + /// + /// @return an iterator to the item that was previously in the slot - ContainerStoreIterator unequipItem(const Ptr& item, const Ptr& actor); - ///< Unequip an item identified by its Ptr. An exception is thrown - /// if the item is not currently equipped. - /// - /// @return an iterator to the item that was previously in the slot - /// (it can be re-stacked so its count may be different than when it - /// was equipped). + ContainerStoreIterator unequipItem(const Ptr& item, const Ptr& actor); + ///< Unequip an item identified by its Ptr. An exception is thrown + /// if the item is not currently equipped. + /// + /// @return an iterator to the item that was previously in the slot + /// (it can be re-stacked so its count may be different than when it + /// was equipped). - ContainerStoreIterator unequipItemQuantity(const Ptr& item, const Ptr& actor, int count); - ///< Unequip a specific quantity of an item identified by its Ptr. - /// An exception is thrown if the item is not currently equipped, - /// if count <= 0, or if count > the item stack size. - /// - /// @return an iterator to the unequipped items that were previously - /// in the slot (they can be re-stacked so its count may be different - /// than the requested count). + ContainerStoreIterator unequipItemQuantity(const Ptr& item, const Ptr& actor, int count); + ///< Unequip a specific quantity of an item identified by its Ptr. + /// An exception is thrown if the item is not currently equipped, + /// if count <= 0, or if count > the item stack size. + /// + /// @return an iterator to the unequipped items that were previously + /// in the slot (they can be re-stacked so its count may be different + /// than the requested count). - void setInvListener (InventoryStoreListener* listener, const Ptr& actor); - ///< Set a listener for various events, see \a InventoryStoreListener + void setInvListener(InventoryStoreListener* listener, const Ptr& actor); + ///< Set a listener for various events, see \a InventoryStoreListener - InventoryStoreListener* getInvListener() const; + InventoryStoreListener* getInvListener() const; - void clear() override; - ///< Empty container. + void clear() override; + ///< Empty container. - bool isFirstEquip(); + bool isFirstEquip(); }; } diff --git a/apps/openmw/mwworld/livecellref.cpp b/apps/openmw/mwworld/livecellref.cpp index d69f314ef3..fd5343ba96 100644 --- a/apps/openmw/mwworld/livecellref.cpp +++ b/apps/openmw/mwworld/livecellref.cpp @@ -3,30 +3,32 @@ #include #include -#include -#include #include +#include #include +#include #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/luamanager.hpp" +#include "../mwbase/world.hpp" -#include "ptr.hpp" #include "class.hpp" #include "esmstore.hpp" +#include "ptr.hpp" -MWWorld::LiveCellRefBase::LiveCellRefBase(unsigned int type, const ESM::CellRef &cref) - : mClass(&Class::get(type)), mRef(cref), mData(cref) +MWWorld::LiveCellRefBase::LiveCellRefBase(unsigned int type, const ESM::CellRef& cref) + : mClass(&Class::get(type)) + , mRef(cref) + , mData(cref) { } -void MWWorld::LiveCellRefBase::loadImp (const ESM::ObjectState& state) +void MWWorld::LiveCellRefBase::loadImp(const ESM::ObjectState& state) { mRef = state.mRef; - mData = RefData (state, mData.isDeletedByContentFile()); + mData = RefData(state, mData.isDeletedByContentFile()); - Ptr ptr (this); + Ptr ptr(this); if (state.mHasLocals) { @@ -34,26 +36,27 @@ void MWWorld::LiveCellRefBase::loadImp (const ESM::ObjectState& state) // Make sure we still have a script. It could have been coming from a content file that is no longer active. if (!scriptId.empty()) { - if (const ESM::Script* script = MWBase::Environment::get().getWorld()->getStore().get().search (scriptId)) + if (const ESM::Script* script + = MWBase::Environment::get().getWorld()->getStore().get().search(scriptId)) { try { - mData.setLocals (*script); - mData.getLocals().read (state.mLocals, scriptId); + mData.setLocals(*script); + mData.getLocals().read(state.mLocals, scriptId); } catch (const std::exception& exception) { - Log(Debug::Error) - << "Error: failed to load state for local script " << scriptId - << " because an exception has been thrown: " << exception.what(); + Log(Debug::Error) << "Error: failed to load state for local script " << scriptId + << " because an exception has been thrown: " << exception.what(); } } } } - mClass->readAdditionalState (ptr, state); + mClass->readAdditionalState(ptr, state); - if (!mRef.getSoul().empty() && !MWBase::Environment::get().getWorld()->getStore().get().search(mRef.getSoul())) + if (!mRef.getSoul().empty() + && !MWBase::Environment::get().getWorld()->getStore().get().search(mRef.getSoul())) { Log(Debug::Warning) << "Soul '" << mRef.getSoul() << "' not found, removing the soul from soul gem"; mRef.setSoul(std::string()); @@ -62,19 +65,20 @@ void MWWorld::LiveCellRefBase::loadImp (const ESM::ObjectState& state) MWBase::Environment::get().getLuaManager()->loadLocalScripts(ptr, state.mLuaScripts); } -void MWWorld::LiveCellRefBase::saveImp (ESM::ObjectState& state) const +void MWWorld::LiveCellRefBase::saveImp(ESM::ObjectState& state) const { mRef.writeState(state); - ConstPtr ptr (this); + ConstPtr ptr(this); - mData.write (state, mClass->getScript (ptr)); - MWBase::Environment::get().getLuaManager()->saveLocalScripts(Ptr(const_cast(this)), state.mLuaScripts); + mData.write(state, mClass->getScript(ptr)); + MWBase::Environment::get().getLuaManager()->saveLocalScripts( + Ptr(const_cast(this)), state.mLuaScripts); - mClass->writeAdditionalState (ptr, state); + mClass->writeAdditionalState(ptr, state); } -bool MWWorld::LiveCellRefBase::checkStateImp (const ESM::ObjectState& state) +bool MWWorld::LiveCellRefBase::checkStateImp(const ESM::ObjectState& state) { return true; } diff --git a/apps/openmw/mwworld/livecellref.hpp b/apps/openmw/mwworld/livecellref.hpp index bee6f2ba57..128546bb65 100644 --- a/apps/openmw/mwworld/livecellref.hpp +++ b/apps/openmw/mwworld/livecellref.hpp @@ -24,7 +24,7 @@ namespace MWWorld /// Used to create pointers to hold any type of LiveCellRef<> object. struct LiveCellRefBase { - const Class *mClass; + const Class* mClass; /** Information about this instance, such as 3D location and rotation * and individual type-dependent data. @@ -34,16 +34,16 @@ namespace MWWorld /** runtime-data */ RefData mData; - LiveCellRefBase(unsigned int type, const ESM::CellRef &cref=ESM::CellRef()); + LiveCellRefBase(unsigned int type, const ESM::CellRef& cref = ESM::CellRef()); /* Need this for the class to be recognized as polymorphic */ - virtual ~LiveCellRefBase() { } + virtual ~LiveCellRefBase() {} - virtual void load (const ESM::ObjectState& state) = 0; + virtual void load(const ESM::ObjectState& state) = 0; ///< Load state into a LiveCellRef, that has already been initialised with base and class. /// /// \attention Must not be called with an invalid \a state. - virtual void save (ESM::ObjectState& state) const = 0; + virtual void save(ESM::ObjectState& state) const = 0; ///< Save LiveCellRef state into \a state. virtual std::string_view getTypeDescription() const = 0; @@ -57,28 +57,27 @@ namespace MWWorld template static LiveCellRef* dynamicCast(LiveCellRefBase* value); - protected: - - void loadImp (const ESM::ObjectState& state); - ///< Load state into a LiveCellRef, that has already been initialised with base and - /// class. - /// - /// \attention Must not be called with an invalid \a state. + protected: + void loadImp(const ESM::ObjectState& state); + ///< Load state into a LiveCellRef, that has already been initialised with base and + /// class. + /// + /// \attention Must not be called with an invalid \a state. - void saveImp (ESM::ObjectState& state) const; - ///< Save LiveCellRef state into \a state. + void saveImp(ESM::ObjectState& state) const; + ///< Save LiveCellRef state into \a state. - static bool checkStateImp (const ESM::ObjectState& state); - ///< Check if state is valid and report errors. - /// - /// \return Valid? - /// - /// \note Does not check if the RefId exists. + static bool checkStateImp(const ESM::ObjectState& state); + ///< Check if state is valid and report errors. + /// + /// \return Valid? + /// + /// \note Does not check if the RefId exists. }; - inline bool operator== (const LiveCellRefBase& cellRef, const ESM::RefNum refNum) + inline bool operator==(const LiveCellRefBase& cellRef, const ESM::RefNum refNum) { - return cellRef.mRef.getRefNum()==refNum; + return cellRef.mRef.getRefNum() == refNum; } std::string makeDynamicCastErrorMessage(const LiveCellRefBase* value, std::string_view recordType); @@ -109,27 +108,31 @@ namespace MWWorld struct LiveCellRef : public LiveCellRefBase { LiveCellRef(const ESM::CellRef& cref, const X* b = nullptr) - : LiveCellRefBase(X::sRecordId, cref), mBase(b) - {} + : LiveCellRefBase(X::sRecordId, cref) + , mBase(b) + { + } LiveCellRef(const X* b = nullptr) - : LiveCellRefBase(X::sRecordId), mBase(b) - {} + : LiveCellRefBase(X::sRecordId) + , mBase(b) + { + } // The object that this instance is based on. const X* mBase; - void load (const ESM::ObjectState& state) override; + void load(const ESM::ObjectState& state) override; ///< Load state into a LiveCellRef, that has already been initialised with base and class. /// /// \attention Must not be called with an invalid \a state. - void save (ESM::ObjectState& state) const override; + void save(ESM::ObjectState& state) const override; ///< Save LiveCellRef state into \a state. std::string_view getTypeDescription() const override { return X::getRecordType(); } - static bool checkState (const ESM::ObjectState& state); + static bool checkState(const ESM::ObjectState& state); ///< Check if state is valid and report errors. /// /// \return Valid? @@ -138,21 +141,21 @@ namespace MWWorld }; template - void LiveCellRef::load (const ESM::ObjectState& state) + void LiveCellRef::load(const ESM::ObjectState& state) { - loadImp (state); + loadImp(state); } template - void LiveCellRef::save (ESM::ObjectState& state) const + void LiveCellRef::save(ESM::ObjectState& state) const { - saveImp (state); + saveImp(state); } template - bool LiveCellRef::checkState (const ESM::ObjectState& state) + bool LiveCellRef::checkState(const ESM::ObjectState& state) { - return checkStateImp (state); + return checkStateImp(state); } } diff --git a/apps/openmw/mwworld/localscripts.cpp b/apps/openmw/mwworld/localscripts.cpp index ec8706320a..297ef3fa2b 100644 --- a/apps/openmw/mwworld/localscripts.cpp +++ b/apps/openmw/mwworld/localscripts.cpp @@ -1,15 +1,15 @@ #include "localscripts.hpp" #include -#include #include #include #include +#include -#include "esmstore.hpp" #include "cellstore.hpp" #include "class.hpp" #include "containerstore.hpp" +#include "esmstore.hpp" namespace { @@ -47,19 +47,19 @@ namespace bool operator()(const MWWorld::Ptr& containerPtr) { // Ignore containers without generated content - if (containerPtr.getType() == ESM::Container::sRecordId && - containerPtr.getRefData().getCustomData() == nullptr) + if (containerPtr.getType() == ESM::Container::sRecordId + && containerPtr.getRefData().getCustomData() == nullptr) return true; MWWorld::ContainerStore& container = containerPtr.getClass().getContainerStore(containerPtr); - for(const auto& ptr : container) + for (const auto& ptr : container) { std::string_view script = ptr.getClass().getScript(ptr); - if(!script.empty()) + if (!script.empty()) { MWWorld::Ptr item = ptr; item.mCell = containerPtr.getCell(); - mScripts.add (script, item); + mScripts.add(script, item); } } return true; @@ -68,7 +68,8 @@ namespace } -MWWorld::LocalScripts::LocalScripts (const MWWorld::ESMStore& store) : mStore (store) +MWWorld::LocalScripts::LocalScripts(const MWWorld::ESMStore& store) + : mStore(store) { mIter = mScripts.end(); } @@ -80,9 +81,9 @@ void MWWorld::LocalScripts::startIteration() bool MWWorld::LocalScripts::getNext(std::pair& script) { - if (mIter!=mScripts.end()) + if (mIter != mScripts.end()) { - std::list >::iterator iter = mIter++; + std::list>::iterator iter = mIter++; script = *iter; return true; } @@ -91,36 +92,34 @@ bool MWWorld::LocalScripts::getNext(std::pair& script) void MWWorld::LocalScripts::add(std::string_view scriptName, const Ptr& ptr) { - if (const ESM::Script *script = mStore.get().search (scriptName)) + if (const ESM::Script* script = mStore.get().search(scriptName)) { try { - ptr.getRefData().setLocals (*script); + ptr.getRefData().setLocals(*script); - for (std::list >::iterator iter = mScripts.begin(); iter!=mScripts.end(); ++iter) - if (iter->second==ptr) + for (std::list>::iterator iter = mScripts.begin(); iter != mScripts.end(); + ++iter) + if (iter->second == ptr) { Log(Debug::Warning) << "Error: tried to add local script twice for " << ptr.getCellRef().getRefId(); remove(ptr); break; } - mScripts.emplace_back (scriptName, ptr); + mScripts.emplace_back(scriptName, ptr); } catch (const std::exception& exception) { - Log(Debug::Error) - << "failed to add local script " << scriptName - << " because an exception has been thrown: " << exception.what(); + Log(Debug::Error) << "failed to add local script " << scriptName + << " because an exception has been thrown: " << exception.what(); } } else - Log(Debug::Warning) - << "failed to add local script " << scriptName - << " because the script does not exist."; + Log(Debug::Warning) << "failed to add local script " << scriptName << " because the script does not exist."; } -void MWWorld::LocalScripts::addCell (CellStore *cell) +void MWWorld::LocalScripts::addCell(CellStore* cell) { AddScriptsVisitor addScriptsVisitor(*this); cell->forEach(addScriptsVisitor); @@ -136,48 +135,46 @@ void MWWorld::LocalScripts::clear() mScripts.clear(); } -void MWWorld::LocalScripts::clearCell (CellStore *cell) +void MWWorld::LocalScripts::clearCell(CellStore* cell) { - std::list >::iterator iter = mScripts.begin(); + std::list>::iterator iter = mScripts.begin(); - while (iter!=mScripts.end()) + while (iter != mScripts.end()) { - if (iter->second.mCell==cell) + if (iter->second.mCell == cell) { - if (iter==mIter) - ++mIter; + if (iter == mIter) + ++mIter; - mScripts.erase (iter++); + mScripts.erase(iter++); } else ++iter; } } -void MWWorld::LocalScripts::remove (RefData *ref) +void MWWorld::LocalScripts::remove(RefData* ref) { - for (std::list >::iterator iter = mScripts.begin(); - iter!=mScripts.end(); ++iter) + for (std::list>::iterator iter = mScripts.begin(); iter != mScripts.end(); ++iter) if (&(iter->second.getRefData()) == ref) { - if (iter==mIter) + if (iter == mIter) ++mIter; - mScripts.erase (iter); + mScripts.erase(iter); break; } } -void MWWorld::LocalScripts::remove (const Ptr& ptr) +void MWWorld::LocalScripts::remove(const Ptr& ptr) { - for (std::list >::iterator iter = mScripts.begin(); - iter!=mScripts.end(); ++iter) - if (iter->second==ptr) + for (std::list>::iterator iter = mScripts.begin(); iter != mScripts.end(); ++iter) + if (iter->second == ptr) { - if (iter==mIter) + if (iter == mIter) ++mIter; - mScripts.erase (iter); + mScripts.erase(iter); break; } } diff --git a/apps/openmw/mwworld/localscripts.hpp b/apps/openmw/mwworld/localscripts.hpp index cc4b5376e6..0266d921f6 100644 --- a/apps/openmw/mwworld/localscripts.hpp +++ b/apps/openmw/mwworld/localscripts.hpp @@ -15,37 +15,36 @@ namespace MWWorld /// \brief List of active local scripts class LocalScripts { - std::list > mScripts; - std::list >::iterator mIter; - const MWWorld::ESMStore& mStore; + std::list> mScripts; + std::list>::iterator mIter; + const MWWorld::ESMStore& mStore; - public: + public: + LocalScripts(const MWWorld::ESMStore& store); - LocalScripts (const MWWorld::ESMStore& store); + void startIteration(); + ///< Set the iterator to the begin of the script list. - void startIteration(); - ///< Set the iterator to the begin of the script list. + bool getNext(std::pair& script); + ///< Get next local script + /// @return Did we get a script? - bool getNext(std::pair& script); - ///< Get next local script - /// @return Did we get a script? + void add(std::string_view scriptName, const Ptr& ptr); + ///< Add script to collection of active local scripts. - void add(std::string_view scriptName, const Ptr& ptr); - ///< Add script to collection of active local scripts. + void addCell(CellStore* cell); + ///< Add all local scripts in a cell. - void addCell (CellStore *cell); - ///< Add all local scripts in a cell. + void clear(); + ///< Clear active local scripts collection. - void clear(); - ///< Clear active local scripts collection. + void clearCell(CellStore* cell); + ///< Remove all scripts belonging to \a cell. - void clearCell (CellStore *cell); - ///< Remove all scripts belonging to \a cell. - - void remove (RefData *ref); + void remove(RefData* ref); - void remove (const Ptr& ptr); - ///< Remove script for given reference (ignored if reference does not have a script listed). + void remove(const Ptr& ptr); + ///< Remove script for given reference (ignored if reference does not have a script listed). }; } diff --git a/apps/openmw/mwworld/magiceffects.cpp b/apps/openmw/mwworld/magiceffects.cpp index e5e42b1a2d..b1ea8e5a0e 100644 --- a/apps/openmw/mwworld/magiceffects.cpp +++ b/apps/openmw/mwworld/magiceffects.cpp @@ -1,14 +1,14 @@ #include "magiceffects.hpp" #include "esmstore.hpp" -#include -#include -#include -#include -#include #include #include +#include +#include +#include +#include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" @@ -17,11 +17,11 @@ namespace { - template + template void getEnchantedItem(const std::string& id, std::string& enchantment, std::string& itemName) { const T* item = MWBase::Environment::get().getWorld()->getStore().get().search(id); - if(item) + if (item) { enchantment = item->mEnchant; itemName = item->mName; @@ -43,7 +43,7 @@ namespace MWWorld ESM::CreatureStats::CorprusStats stats; stats.mNextWorsening = oldStats.mNextWorsening; - for (int i=0; imEffects.mList) @@ -54,7 +54,7 @@ namespace MWWorld creatureStats.mCorprusSpells[id] = stats; } // Convert to format 17 - for(const auto& [id, oldParams] : creatureStats.mSpells.mSpellParams) + for (const auto& [id, oldParams] : creatureStats.mSpells.mSpellParams) { const ESM::Spell* spell = store.get().search(id); if (!spell || spell->mData.mType == ESM::Spell::ST_Spell || spell->mData.mType == ESM::Spell::ST_Power) @@ -64,16 +64,16 @@ namespace MWWorld params.mDisplayName = spell->mName; params.mItem.unset(); params.mCasterActorId = creatureStats.mActorId; - if(spell->mData.mType == ESM::Spell::ST_Ability) + if (spell->mData.mType == ESM::Spell::ST_Ability) params.mType = ESM::ActiveSpells::Type_Ability; else params.mType = ESM::ActiveSpells::Type_Permanent; params.mWorsenings = -1; params.mNextWorsening = ESM::TimeStamp(); int effectIndex = 0; - for(const auto& enam : spell->mEffects.mList) + for (const auto& enam : spell->mEffects.mList) { - if(oldParams.mPurgedEffects.find(effectIndex) == oldParams.mPurgedEffects.end()) + if (oldParams.mPurgedEffects.find(effectIndex) == oldParams.mPurgedEffects.end()) { ESM::ActiveEffect effect; effect.mEffectId = enam.mEffectID; @@ -82,14 +82,15 @@ namespace MWWorld effect.mTimeLeft = -1; effect.mEffectIndex = effectIndex; auto rand = oldParams.mEffectRands.find(effectIndex); - if(rand != oldParams.mEffectRands.end()) + if (rand != oldParams.mEffectRands.end()) { float magnitude = (enam.mMagnMax - enam.mMagnMin) * rand->second + enam.mMagnMin; effect.mMagnitude = magnitude; effect.mMinMagnitude = magnitude; effect.mMaxMagnitude = magnitude; // Prevent recalculation of resistances and don't reflect or absorb the effect - effect.mFlags = ESM::ActiveEffect::Flag_Ignore_Resistances | ESM::ActiveEffect::Flag_Ignore_Reflect | ESM::ActiveEffect::Flag_Ignore_SpellAbsorption; + effect.mFlags = ESM::ActiveEffect::Flag_Ignore_Resistances + | ESM::ActiveEffect::Flag_Ignore_Reflect | ESM::ActiveEffect::Flag_Ignore_SpellAbsorption; } else { @@ -105,18 +106,18 @@ namespace MWWorld creatureStats.mActiveSpells.mSpells.emplace_back(params); } std::multimap equippedItems; - for(std::size_t i = 0; i < inventory.mItems.size(); ++i) + for (std::size_t i = 0; i < inventory.mItems.size(); ++i) { const ESM::ObjectState& item = inventory.mItems[i]; auto slot = inventory.mEquipmentSlots.find(i); - if(slot != inventory.mEquipmentSlots.end()) + if (slot != inventory.mEquipmentSlots.end()) equippedItems.emplace(item.mRef.mRefID, slot->second); } - for(const auto& [id, oldMagnitudes] : inventory.mPermanentMagicEffectMagnitudes) + for (const auto& [id, oldMagnitudes] : inventory.mPermanentMagicEffectMagnitudes) { std::string eId; std::string name; - switch(store.find(id)) + switch (store.find(id)) { case ESM::REC_ARMO: getEnchantedItem(id, eId, name); @@ -128,10 +129,10 @@ namespace MWWorld getEnchantedItem(id, eId, name); break; } - if(eId.empty()) + if (eId.empty()) continue; const ESM::Enchantment* enchantment = store.get().search(eId); - if(!enchantment) + if (!enchantment) continue; ESM::ActiveSpells::ActiveSpellParams params; params.mId = id; @@ -140,13 +141,14 @@ namespace MWWorld params.mType = ESM::ActiveSpells::Type_Enchantment; params.mWorsenings = -1; params.mNextWorsening = ESM::TimeStamp(); - for(std::size_t effectIndex = 0; effectIndex < oldMagnitudes.size() && effectIndex < enchantment->mEffects.mList.size(); ++effectIndex) + for (std::size_t effectIndex = 0; + effectIndex < oldMagnitudes.size() && effectIndex < enchantment->mEffects.mList.size(); ++effectIndex) { const auto& enam = enchantment->mEffects.mList[effectIndex]; auto [random, multiplier] = oldMagnitudes[effectIndex]; float magnitude = (enam.mMagnMax - enam.mMagnMin) * random + enam.mMagnMin; magnitude *= multiplier; - if(magnitude <= 0) + if (magnitude <= 0) continue; ESM::ActiveEffect effect; effect.mEffectId = enam.mEffectID; @@ -158,40 +160,43 @@ namespace MWWorld effect.mTimeLeft = -1; effect.mEffectIndex = static_cast(effectIndex); // Prevent recalculation of resistances and don't reflect or absorb the effect - effect.mFlags = ESM::ActiveEffect::Flag_Ignore_Resistances | ESM::ActiveEffect::Flag_Ignore_Reflect | ESM::ActiveEffect::Flag_Ignore_SpellAbsorption; + effect.mFlags = ESM::ActiveEffect::Flag_Ignore_Resistances | ESM::ActiveEffect::Flag_Ignore_Reflect + | ESM::ActiveEffect::Flag_Ignore_SpellAbsorption; params.mEffects.emplace_back(effect); } auto [begin, end] = equippedItems.equal_range(id); - for(auto it = begin; it != end; ++it) + for (auto it = begin; it != end; ++it) { params.mItem = { static_cast(it->second), 0 }; creatureStats.mActiveSpells.mSpells.emplace_back(params); } } - for(const auto& spell : creatureStats.mCorprusSpells) + for (const auto& spell : creatureStats.mCorprusSpells) { - auto it = std::find_if(creatureStats.mActiveSpells.mSpells.begin(), creatureStats.mActiveSpells.mSpells.end(), [&] (const auto& params) { return params.mId == spell.first; }); - if(it != creatureStats.mActiveSpells.mSpells.end()) + auto it + = std::find_if(creatureStats.mActiveSpells.mSpells.begin(), creatureStats.mActiveSpells.mSpells.end(), + [&](const auto& params) { return params.mId == spell.first; }); + if (it != creatureStats.mActiveSpells.mSpells.end()) { it->mNextWorsening = spell.second.mNextWorsening; int worsenings = 0; - for(int i = 0; i < ESM::Attribute::Length; ++i) + for (int i = 0; i < ESM::Attribute::Length; ++i) worsenings = std::max(spell.second.mWorsenings[i], worsenings); it->mWorsenings = worsenings; } } - for(const auto& [key, actorId] : creatureStats.mSummonedCreatureMap) + for (const auto& [key, actorId] : creatureStats.mSummonedCreatureMap) { - if(actorId == -1) + if (actorId == -1) continue; - for(auto& params : creatureStats.mActiveSpells.mSpells) + for (auto& params : creatureStats.mActiveSpells.mSpells) { - if(params.mId == key.mSourceId) + if (params.mId == key.mSourceId) { bool found = false; - for(auto& effect : params.mEffects) + for (auto& effect : params.mEffects) { - if(effect.mEffectId == key.mEffectId && effect.mEffectIndex == key.mEffectIndex) + if (effect.mEffectId == key.mEffectId && effect.mEffectIndex == key.mEffectIndex) { effect.mArg = actorId; effect.mFlags |= ESM::ActiveEffect::Flag_Applied | ESM::ActiveEffect::Flag_Remove; @@ -199,35 +204,36 @@ namespace MWWorld break; } } - if(found) + if (found) break; } } } // Reset modifiers that were previously recalculated each frame - for(std::size_t i = 0; i < ESM::Attribute::Length; ++i) + for (std::size_t i = 0; i < ESM::Attribute::Length; ++i) creatureStats.mAttributes[i].mMod = 0.f; - for(std::size_t i = 0; i < 3; ++i) + for (std::size_t i = 0; i < 3; ++i) { auto& dynamic = creatureStats.mDynamic[i]; dynamic.mCurrent -= dynamic.mMod - dynamic.mBase; dynamic.mMod = 0.f; } - for(std::size_t i = 0; i < 4; ++i) + for (std::size_t i = 0; i < 4; ++i) creatureStats.mAiSettings[i].mMod = 0.f; - if(npcStats) + if (npcStats) { - for(std::size_t i = 0; i < ESM::Skill::Length; ++i) + for (std::size_t i = 0; i < ESM::Skill::Length; ++i) npcStats->mSkills[i].mMod = 0.f; } } - // Versions 17-19 wrote different modifiers to the savegame depending on whether the save had upgraded from a pre-17 version or not + // Versions 17-19 wrote different modifiers to the savegame depending on whether the save had upgraded from a pre-17 + // version or not void convertStats(ESM::CreatureStats& creatureStats) { - for(std::size_t i = 0; i < 3; ++i) + for (std::size_t i = 0; i < 3; ++i) creatureStats.mDynamic[i].mMod = 0.f; - for(std::size_t i = 0; i < 4; ++i) + for (std::size_t i = 0; i < 4; ++i) creatureStats.mAiSettings[i].mMod = 0.f; } } diff --git a/apps/openmw/mwworld/magiceffects.hpp b/apps/openmw/mwworld/magiceffects.hpp index fdcc578e53..aefcd056e0 100644 --- a/apps/openmw/mwworld/magiceffects.hpp +++ b/apps/openmw/mwworld/magiceffects.hpp @@ -10,8 +10,8 @@ namespace ESM namespace MWWorld { - void convertMagicEffects(ESM::CreatureStats& creatureStats, ESM::InventoryState& inventory, - ESM::NpcStats* npcStats = nullptr); + void convertMagicEffects( + ESM::CreatureStats& creatureStats, ESM::InventoryState& inventory, ESM::NpcStats* npcStats = nullptr); void convertStats(ESM::CreatureStats& creatureStats); } diff --git a/apps/openmw/mwworld/manualref.cpp b/apps/openmw/mwworld/manualref.cpp index 5c822483c5..89c8c91051 100644 --- a/apps/openmw/mwworld/manualref.cpp +++ b/apps/openmw/mwworld/manualref.cpp @@ -6,7 +6,7 @@ namespace { - template + template void create(const MWWorld::Store& list, const std::string& name, std::any& refValue, MWWorld::Ptr& ptrValue) { const T* base = list.find(name); @@ -27,33 +27,75 @@ MWWorld::ManualRef::ManualRef(const MWWorld::ESMStore& store, std::string_view n std::string lowerName = Misc::StringUtils::lowerCase(name); switch (store.find(lowerName)) { - case ESM::REC_ACTI: create(store.get(), lowerName, mRef, mPtr); break; - case ESM::REC_ALCH: create(store.get(), lowerName, mRef, mPtr); break; - case ESM::REC_APPA: create(store.get(), lowerName, mRef, mPtr); break; - case ESM::REC_ARMO: create(store.get(), lowerName, mRef, mPtr); break; - case ESM::REC_BOOK: create(store.get(), lowerName, mRef, mPtr); break; - case ESM::REC_CLOT: create(store.get(), lowerName, mRef, mPtr); break; - case ESM::REC_CONT: create(store.get(), lowerName, mRef, mPtr); break; - case ESM::REC_CREA: create(store.get(), lowerName, mRef, mPtr); break; - case ESM::REC_DOOR: create(store.get(), lowerName, mRef, mPtr); break; - case ESM::REC_INGR: create(store.get(), lowerName, mRef, mPtr); break; - case ESM::REC_LEVC: create(store.get(), lowerName, mRef, mPtr); break; - case ESM::REC_LEVI: create(store.get(), lowerName, mRef, mPtr); break; - case ESM::REC_LIGH: create(store.get(), lowerName, mRef, mPtr); break; - case ESM::REC_LOCK: create(store.get(), lowerName, mRef, mPtr); break; - case ESM::REC_MISC: create(store.get(), lowerName, mRef, mPtr); break; - case ESM::REC_NPC_: create(store.get(), lowerName, mRef, mPtr); break; - case ESM::REC_PROB: create(store.get(), lowerName, mRef, mPtr); break; - case ESM::REC_REPA: create(store.get(), lowerName, mRef, mPtr); break; - case ESM::REC_STAT: create(store.get(), lowerName, mRef, mPtr); break; - case ESM::REC_WEAP: create(store.get(), lowerName, mRef, mPtr); break; - case ESM::REC_BODY: create(store.get(), lowerName, mRef, mPtr); break; - - case 0: - throw std::logic_error("failed to create manual cell ref for " + lowerName + " (unknown ID)"); - - default: - throw std::logic_error("failed to create manual cell ref for " + lowerName + " (unknown type)"); + case ESM::REC_ACTI: + create(store.get(), lowerName, mRef, mPtr); + break; + case ESM::REC_ALCH: + create(store.get(), lowerName, mRef, mPtr); + break; + case ESM::REC_APPA: + create(store.get(), lowerName, mRef, mPtr); + break; + case ESM::REC_ARMO: + create(store.get(), lowerName, mRef, mPtr); + break; + case ESM::REC_BOOK: + create(store.get(), lowerName, mRef, mPtr); + break; + case ESM::REC_CLOT: + create(store.get(), lowerName, mRef, mPtr); + break; + case ESM::REC_CONT: + create(store.get(), lowerName, mRef, mPtr); + break; + case ESM::REC_CREA: + create(store.get(), lowerName, mRef, mPtr); + break; + case ESM::REC_DOOR: + create(store.get(), lowerName, mRef, mPtr); + break; + case ESM::REC_INGR: + create(store.get(), lowerName, mRef, mPtr); + break; + case ESM::REC_LEVC: + create(store.get(), lowerName, mRef, mPtr); + break; + case ESM::REC_LEVI: + create(store.get(), lowerName, mRef, mPtr); + break; + case ESM::REC_LIGH: + create(store.get(), lowerName, mRef, mPtr); + break; + case ESM::REC_LOCK: + create(store.get(), lowerName, mRef, mPtr); + break; + case ESM::REC_MISC: + create(store.get(), lowerName, mRef, mPtr); + break; + case ESM::REC_NPC_: + create(store.get(), lowerName, mRef, mPtr); + break; + case ESM::REC_PROB: + create(store.get(), lowerName, mRef, mPtr); + break; + case ESM::REC_REPA: + create(store.get(), lowerName, mRef, mPtr); + break; + case ESM::REC_STAT: + create(store.get(), lowerName, mRef, mPtr); + break; + case ESM::REC_WEAP: + create(store.get(), lowerName, mRef, mPtr); + break; + case ESM::REC_BODY: + create(store.get(), lowerName, mRef, mPtr); + break; + + case 0: + throw std::logic_error("failed to create manual cell ref for " + lowerName + " (unknown ID)"); + + default: + throw std::logic_error("failed to create manual cell ref for " + lowerName + " (unknown type)"); } mPtr.getRefData().setCount(count); diff --git a/apps/openmw/mwworld/manualref.hpp b/apps/openmw/mwworld/manualref.hpp index 593df9f24f..7f056bb681 100644 --- a/apps/openmw/mwworld/manualref.hpp +++ b/apps/openmw/mwworld/manualref.hpp @@ -10,19 +10,16 @@ namespace MWWorld /// \brief Manually constructed live cell ref class ManualRef { - std::any mRef; - Ptr mPtr; + std::any mRef; + Ptr mPtr; - ManualRef (const ManualRef&); - ManualRef& operator= (const ManualRef&); + ManualRef(const ManualRef&); + ManualRef& operator=(const ManualRef&); - public: - ManualRef(const MWWorld::ESMStore& store, std::string_view name, const int count = 1); + public: + ManualRef(const MWWorld::ESMStore& store, std::string_view name, const int count = 1); - const Ptr& getPtr() const - { - return mPtr; - } + const Ptr& getPtr() const { return mPtr; } }; } diff --git a/apps/openmw/mwworld/nullaction.hpp b/apps/openmw/mwworld/nullaction.hpp index 4ee1115e50..2499655eff 100644 --- a/apps/openmw/mwworld/nullaction.hpp +++ b/apps/openmw/mwworld/nullaction.hpp @@ -8,9 +8,9 @@ namespace MWWorld /// \brief Action: do nothing class NullAction : public Action { - void executeImp (const Ptr& actor) override {} + void executeImp(const Ptr& actor) override {} - bool isNullAction() override { return true; } + bool isNullAction() override { return true; } }; } diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index 45ae53712b..200f97e543 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -4,29 +4,29 @@ #include +#include #include #include -#include -#include #include -#include #include +#include +#include #include "../mwworld/esmstore.hpp" #include "../mwworld/inventorystore.hpp" #include "../mwworld/magiceffects.hpp" #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" -#include "../mwbase/windowmanager.hpp" #include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" #include "../mwmechanics/movement.hpp" #include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/spellutil.hpp" -#include "../mwrender/renderingmanager.hpp" #include "../mwrender/camera.hpp" +#include "../mwrender/renderingmanager.hpp" #include "cellstore.hpp" #include "class.hpp" @@ -34,17 +34,17 @@ namespace MWWorld { - Player::Player (const ESM::NPC *player) - : mCellStore(nullptr), - mLastKnownExteriorPosition(0,0,0), - mMarkedPosition(ESM::Position()), - mMarkedCell(nullptr), - mAutoMove(false), - mForwardBackward(0), - mTeleported(false), - mCurrentCrimeId(-1), - mPaidCrimeId(-1), - mJumping(false) + Player::Player(const ESM::NPC* player) + : mCellStore(nullptr) + , mLastKnownExteriorPosition(0, 0, 0) + , mMarkedPosition(ESM::Position()) + , mMarkedCell(nullptr) + , mAutoMove(false) + , mForwardBackward(0) + , mTeleported(false) + , mCurrentCrimeId(-1) + , mPaidCrimeId(-1) + , mJumping(false) { ESM::CellRef cellRef; cellRef.blank(); @@ -60,26 +60,27 @@ namespace MWWorld { MWMechanics::NpcStats& stats = getPlayer().getClass().getNpcStats(getPlayer()); - for (int i=0; i& gmst = MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& gmst + = MWBase::Environment::get().getWorld()->getStore().get(); MWMechanics::CreatureStats& creatureStats = getPlayer().getClass().getCreatureStats(getPlayer()); MWMechanics::NpcStats& npcStats = getPlayer().getClass().getNpcStats(getPlayer()); MWMechanics::DynamicStat health = creatureStats.getDynamic(0); creatureStats.setHealth(health.getBase() / gmst.find("fWereWolfHealth")->mValue.getFloat()); - for (int i=0; i& gmst = MWBase::Environment::get().getWorld()->getStore().get(); + const MWWorld::Store& gmst + = MWBase::Environment::get().getWorld()->getStore().get(); MWMechanics::CreatureStats& creatureStats = getPlayer().getClass().getCreatureStats(getPlayer()); MWMechanics::NpcStats& npcStats = getPlayer().getClass().getNpcStats(getPlayer()); MWMechanics::DynamicStat health = creatureStats.getDynamic(0); creatureStats.setHealth(health.getBase() * gmst.find("fWereWolfHealth")->mValue.getFloat()); - for(size_t i = 0;i < ESM::Attribute::Length;++i) + for (size_t i = 0; i < ESM::Attribute::Length; ++i) { // Oh, Bethesda. It's "Intelligence". - std::string name = "fWerewolf"+((i==ESM::Attribute::Intelligence) ? std::string("Intellegence") : - ESM::Attribute::sAttributeNames[i]); + std::string name = "fWerewolf" + + ((i == ESM::Attribute::Intelligence) ? std::string("Intellegence") + : ESM::Attribute::sAttributeNames[i]); MWMechanics::AttributeValue value = npcStats.getAttribute(i); value.setModifier(gmst.find(name)->mValue.getFloat() - value.getModified()); npcStats.setAttribute(i, value); } - for(size_t i = 0;i < ESM::Skill::Length;i++) + for (size_t i = 0; i < ESM::Skill::Length; i++) { // Acrobatics is set separately for some reason. - if(i == ESM::Skill::Acrobatics) + if (i == ESM::Skill::Acrobatics) continue; // "Mercantile"! >_< - std::string name = "fWerewolf"+((i==ESM::Skill::Mercantile) ? std::string("Merchantile") : - ESM::Skill::sSkillNames[i]); + std::string name = "fWerewolf" + + ((i == ESM::Skill::Mercantile) ? std::string("Merchantile") : ESM::Skill::sSkillNames[i]); MWMechanics::SkillValue& value = npcStats.getSkill(i); value.setModifier(gmst.find(name)->mValue.getFloat() - value.getModified()); } } - void Player::set(const ESM::NPC *player) + void Player::set(const ESM::NPC* player) { mPlayer.mBase = player; } - void Player::setCell (MWWorld::CellStore *cellStore) + void Player::setCell(MWWorld::CellStore* cellStore) { mCellStore = cellStore; } MWWorld::Ptr Player::getPlayer() { - MWWorld::Ptr ptr (&mPlayer, mCellStore); + MWWorld::Ptr ptr(&mPlayer, mCellStore); return ptr; } MWWorld::ConstPtr Player::getConstPlayer() const { - MWWorld::ConstPtr ptr (&mPlayer, mCellStore); + MWWorld::ConstPtr ptr(&mPlayer, mCellStore); return ptr; } - void Player::setBirthSign (const std::string &sign) + void Player::setBirthSign(const std::string& sign) { mSign = sign; } @@ -153,10 +156,10 @@ namespace MWWorld return mSign; } - void Player::setDrawState (MWMechanics::DrawState state) + void Player::setDrawState(MWMechanics::DrawState state) { - MWWorld::Ptr ptr = getPlayer(); - ptr.getClass().getNpcStats(ptr).setDrawState (state); + MWWorld::Ptr ptr = getPlayer(); + ptr.getClass().getNpcStats(ptr).setDrawState(state); } bool Player::getAutoMove() const @@ -164,7 +167,7 @@ namespace MWWorld return mAutoMove; } - void Player::setAutoMove (bool enable) + void Player::setAutoMove(bool enable) { MWWorld::Ptr ptr = getPlayer(); @@ -178,13 +181,13 @@ namespace MWWorld ptr.getClass().getMovementSettings(ptr).mPosition[1] = value; } - void Player::setLeftRight (float value) + void Player::setLeftRight(float value) { MWWorld::Ptr ptr = getPlayer(); ptr.getClass().getMovementSettings(ptr).mPosition[0] = value; } - void Player::setForwardBackward (float value) + void Player::setForwardBackward(float value) { MWWorld::Ptr ptr = getPlayer(); @@ -232,8 +235,8 @@ namespace MWWorld MWMechanics::DrawState Player::getDrawState() { - MWWorld::Ptr ptr = getPlayer(); - return ptr.getClass().getNpcStats(ptr).getDrawState(); + MWWorld::Ptr ptr = getPlayer(); + return ptr.getClass().getNpcStats(ptr).getDrawState(); } void Player::activate() @@ -242,7 +245,7 @@ namespace MWWorld return; MWWorld::Ptr player = getPlayer(); - const MWMechanics::NpcStats &playerStats = player.getClass().getNpcStats(player); + const MWMechanics::NpcStats& playerStats = player.getClass().getNpcStats(player); bool godmode = MWBase::Environment::get().getWorld()->getGodModeState(); if ((!godmode && playerStats.isParalyzed()) || playerStats.getKnockedDown() || playerStats.isDead()) return; @@ -283,7 +286,8 @@ namespace MWWorld return mJumping; } - bool Player::isInCombat() { + bool Player::isInCombat() + { return MWBase::Environment::get().getMechanicsManager()->getActorsFighting(getPlayer()).size() != 0; } @@ -292,13 +296,13 @@ namespace MWWorld return MWBase::Environment::get().getMechanicsManager()->getEnemiesNearby(getPlayer()).size() != 0; } - void Player::markPosition(CellStore *markedCell, const ESM::Position& markedPosition) + void Player::markPosition(CellStore* markedCell, const ESM::Position& markedPosition) { mMarkedCell = markedCell; mMarkedPosition = markedPosition; } - void Player::getMarkedPosition(CellStore*& markedCell, ESM::Position &markedPosition) const + void Player::getMarkedPosition(CellStore*& markedCell, ESM::Position& markedPosition) const { markedCell = mMarkedCell; if (mMarkedCell) @@ -317,14 +321,14 @@ namespace MWWorld mCurrentCrimeId = -1; mPaidCrimeId = -1; mPreviousItems.clear(); - mLastKnownExteriorPosition = osg::Vec3f(0,0,0); + mLastKnownExteriorPosition = osg::Vec3f(0, 0, 0); - for (int i=0; igetCell()->getCellId(); player.mCurrentCrimeId = mCurrentCrimeId; @@ -362,33 +366,34 @@ namespace MWWorld else player.mHasMark = false; - for (int i=0; i().search (player.mBirthsign); + const ESM::BirthSign* sign = world.getStore().get().search(player.mBirthsign); if (!sign) - throw std::runtime_error ("invalid player state record (birthsign does not exist)"); + throw std::runtime_error("invalid player state record (birthsign does not exist)"); } mCurrentCrimeId = player.mCurrentCrimeId; @@ -455,14 +460,14 @@ namespace MWWorld // interior cell -> need to check if it exists (exterior cell will be // generated on the fly) - if (!world.getStore().get().search (player.mMarkedCell.mWorldspace)) + if (!world.getStore().get().search(player.mMarkedCell.mWorldspace)) player.mHasMark = false; // drop mark silently } if (player.mHasMark) { mMarkedPosition = player.mMarkedPosition; - mMarkedCell = world.getCell (player.mMarkedCell); + mMarkedCell = world.getCell(player.mMarkedCell); } else { @@ -555,7 +560,8 @@ namespace MWWorld bool swimming = world->isSwimming(player); bool flying = world->isFlying(player); - static const float i1stPersonSneakDelta = store.get().find("i1stPersonSneakDelta")->mValue.getFloat(); + static const float i1stPersonSneakDelta + = store.get().find("i1stPersonSneakDelta")->mValue.getFloat(); if (sneaking && !swimming && !flying) rendering->getCamera()->setSneakOffset(i1stPersonSneakDelta); else diff --git a/apps/openmw/mwworld/player.hpp b/apps/openmw/mwworld/player.hpp index 6efdc2e00b..ea8c53bc19 100644 --- a/apps/openmw/mwworld/player.hpp +++ b/apps/openmw/mwworld/player.hpp @@ -7,9 +7,9 @@ #include "../mwmechanics/drawstate.hpp" -#include #include #include +#include namespace ESM { @@ -30,22 +30,22 @@ namespace MWWorld /// \brief NPC object representing the player and additional player data class Player { - LiveCellRef mPlayer; - MWWorld::CellStore *mCellStore; - std::string mSign; + LiveCellRef mPlayer; + MWWorld::CellStore* mCellStore; + std::string mSign; osg::Vec3f mLastKnownExteriorPosition; - ESM::Position mMarkedPosition; + ESM::Position mMarkedPosition; // If no position was marked, this is nullptr - CellStore* mMarkedCell; + CellStore* mMarkedCell; - bool mAutoMove; - float mForwardBackward; - bool mTeleported; + bool mAutoMove; + float mForwardBackward; + bool mTeleported; - int mCurrentCrimeId; // the id assigned witnesses - int mPaidCrimeId; // the last id paid off (0 bounty) + int mCurrentCrimeId; // the id assigned witnesses + int mPaidCrimeId; // the last id paid off (0 bounty) typedef std::map PreviousItems; // previous equipped items, needed for bound spells PreviousItems mPreviousItems; @@ -57,45 +57,44 @@ namespace MWWorld bool mJumping; public: - - Player(const ESM::NPC *player); + Player(const ESM::NPC* player); void saveStats(); void restoreStats(); void setWerewolfStats(); // For mark/recall magic effects - void markPosition (CellStore* markedCell, const ESM::Position& markedPosition); - void getMarkedPosition (CellStore*& markedCell, ESM::Position& markedPosition) const; + void markPosition(CellStore* markedCell, const ESM::Position& markedPosition); + void getMarkedPosition(CellStore*& markedCell, ESM::Position& markedPosition) const; /// Interiors can not always be mapped to a world position. However /// world position is still required for divine / almsivi magic effects /// and the player arrow on the global map. - void setLastKnownExteriorPosition (const osg::Vec3f& position) { mLastKnownExteriorPosition = position; } + void setLastKnownExteriorPosition(const osg::Vec3f& position) { mLastKnownExteriorPosition = position; } osg::Vec3f getLastKnownExteriorPosition() const { return mLastKnownExteriorPosition; } - void set (const ESM::NPC *player); + void set(const ESM::NPC* player); - void setCell (MWWorld::CellStore *cellStore); + void setCell(MWWorld::CellStore* cellStore); MWWorld::Ptr getPlayer(); MWWorld::ConstPtr getConstPlayer() const; - void setBirthSign(const std::string &sign); - const std::string &getBirthSign() const; + void setBirthSign(const std::string& sign); + const std::string& getBirthSign() const; - void setDrawState (MWMechanics::DrawState state); + void setDrawState(MWMechanics::DrawState state); MWMechanics::DrawState getDrawState(); /// \todo constness /// Activate the object under the crosshair, if any void activate(); bool getAutoMove() const; - void setAutoMove (bool enable); + void setAutoMove(bool enable); - void setLeftRight (float value); + void setLeftRight(float value); - void setForwardBackward (float value); + void setForwardBackward(float value); void setUpDown(int value); void setRunState(bool run); @@ -113,20 +112,20 @@ namespace MWWorld void setJumping(bool jumping); bool getJumping() const; - ///Checks all nearby actors to see if anyone has an aipackage against you + /// Checks all nearby actors to see if anyone has an aipackage against you bool isInCombat(); bool enemiesNearby(); void clear(); - void write (ESM::ESMWriter& writer, Loading::Listener& progress) const; + void write(ESM::ESMWriter& writer, Loading::Listener& progress) const; - bool readRecord (ESM::ESMReader& reader, uint32_t type); + bool readRecord(ESM::ESMReader& reader, uint32_t type); - int getNewCrimeId(); // get new id for witnesses + int getNewCrimeId(); // get new id for witnesses void recordCrimeId(); // record the paid crime id when bounty is 0 - int getCrimeId() const; // get the last paid crime id + int getCrimeId() const; // get the last paid crime id void setPreviousItem(const std::string& boundItemId, const std::string& previousItemId); std::string getPreviousItem(const std::string& boundItemId); diff --git a/apps/openmw/mwworld/projectilemanager.cpp b/apps/openmw/mwworld/projectilemanager.cpp index d11cf47ce0..1bcc8e7560 100644 --- a/apps/openmw/mwworld/projectilemanager.cpp +++ b/apps/openmw/mwworld/projectilemanager.cpp @@ -1,19 +1,19 @@ #include "projectilemanager.hpp" #include -#include #include #include +#include #include #include #include -#include -#include -#include #include +#include +#include +#include #include #include @@ -23,33 +23,33 @@ #include #include -#include #include #include +#include #include -#include "../mwworld/manualref.hpp" #include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" #include "../mwworld/inventorystore.hpp" +#include "../mwworld/manualref.hpp" -#include "../mwbase/soundmanager.hpp" -#include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" +#include "../mwmechanics/actorutil.hpp" +#include "../mwmechanics/aipackage.hpp" #include "../mwmechanics/combat.hpp" #include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/spellcasting.hpp" -#include "../mwmechanics/actorutil.hpp" -#include "../mwmechanics/aipackage.hpp" #include "../mwmechanics/weapontype.hpp" #include "../mwrender/animation.hpp" -#include "../mwrender/vismask.hpp" #include "../mwrender/renderingmanager.hpp" #include "../mwrender/util.hpp" +#include "../mwrender/vismask.hpp" #include "../mwsound/sound.hpp" @@ -58,7 +58,8 @@ namespace { - ESM::EffectList getMagicBoltData(std::vector& projectileIDs, std::set& sounds, float& speed, std::string& texture, std::string& sourceName, const std::string& id) + ESM::EffectList getMagicBoltData(std::vector& projectileIDs, std::set& sounds, + float& speed, std::string& texture, std::string& sourceName, const std::string& id) { const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); const ESM::EffectList* effects; @@ -79,11 +80,11 @@ namespace int count = 0; speed = 0.0f; ESM::EffectList projectileEffects; - for (std::vector::const_iterator iter (effects->mList.begin()); - iter!=effects->mList.end(); ++iter) + for (std::vector::const_iterator iter(effects->mList.begin()); iter != effects->mList.end(); + ++iter) { - const ESM::MagicEffect *magicEffect = MWBase::Environment::get().getWorld()->getStore().get().find ( - iter->mEffectID); + const ESM::MagicEffect* magicEffect + = MWBase::Environment::get().getWorld()->getStore().get().find(iter->mEffectID); // Speed of multi-effect projectiles should be the average of the constituent effects, // based on observation of the original engine. @@ -98,28 +99,29 @@ namespace else projectileIDs.push_back(magicEffect->mBolt); - static const std::string schools[] = { - "alteration", "conjuration", "destruction", "illusion", "mysticism", "restoration" - }; + static const std::string schools[] + = { "alteration", "conjuration", "destruction", "illusion", "mysticism", "restoration" }; if (!magicEffect->mBoltSound.empty()) sounds.emplace(magicEffect->mBoltSound); else sounds.emplace(schools[magicEffect->mData.mSchool] + " bolt"); projectileEffects.mList.push_back(*iter); } - + if (count != 0) speed /= count; // the particle texture is only used if there is only one projectile - if (projectileEffects.mList.size() == 1) + if (projectileEffects.mList.size() == 1) { - const ESM::MagicEffect *magicEffect = MWBase::Environment::get().getWorld()->getStore().get().find ( - effects->mList.begin()->mEffectID); + const ESM::MagicEffect* magicEffect + = MWBase::Environment::get().getWorld()->getStore().get().find( + effects->mList.begin()->mEffectID); texture = magicEffect->mParticle; } - - if (projectileEffects.mList.size() > 1) // insert a VFX_Multiple projectile if there are multiple projectile effects + + if (projectileEffects.mList.size() + > 1) // insert a VFX_Multiple projectile if there are multiple projectile effects { const std::string ID = "VFX_Multiple" + std::to_string(effects->mList.size()); std::vector::iterator it; @@ -136,20 +138,18 @@ namespace float lightDiffuseRed = 0.0f; float lightDiffuseGreen = 0.0f; float lightDiffuseBlue = 0.0f; - for (std::vector::const_iterator iter(effects.mList.begin()); - iter != effects.mList.end(); ++iter) + for (std::vector::const_iterator iter(effects.mList.begin()); iter != effects.mList.end(); + ++iter) { - const ESM::MagicEffect *magicEffect = MWBase::Environment::get().getWorld()->getStore().get().find( - iter->mEffectID); + const ESM::MagicEffect* magicEffect + = MWBase::Environment::get().getWorld()->getStore().get().find(iter->mEffectID); lightDiffuseRed += (static_cast(magicEffect->mData.mRed) / 255.f); lightDiffuseGreen += (static_cast(magicEffect->mData.mGreen) / 255.f); lightDiffuseBlue += (static_cast(magicEffect->mData.mBlue) / 255.f); } int numberOfEffects = effects.mList.size(); - lightDiffuseColor = osg::Vec4(lightDiffuseRed / numberOfEffects - , lightDiffuseGreen / numberOfEffects - , lightDiffuseBlue / numberOfEffects - , 1.0f); + lightDiffuseColor = osg::Vec4(lightDiffuseRed / numberOfEffects, lightDiffuseGreen / numberOfEffects, + lightDiffuseBlue / numberOfEffects, 1.0f); return lightDiffuseColor; } @@ -159,21 +159,20 @@ namespace MWWorld { ProjectileManager::ProjectileManager(osg::Group* parent, Resource::ResourceSystem* resourceSystem, - MWRender::RenderingManager* rendering, MWPhysics::PhysicsSystem* physics) + MWRender::RenderingManager* rendering, MWPhysics::PhysicsSystem* physics) : mParent(parent) , mResourceSystem(resourceSystem) , mRendering(rendering) , mPhysics(physics) , mCleanupTimer(0.0f) { - } /// Rotates an osg::PositionAttitudeTransform over time. class RotateCallback : public SceneUtil::NodeCallback { public: - RotateCallback(const osg::Vec3f& axis = osg::Vec3f(0,-1,0), float rotateSpeed = osg::PI*2) + RotateCallback(const osg::Vec3f& axis = osg::Vec3f(0, -1, 0), float rotateSpeed = osg::PI * 2) : mAxis(axis) , mRotateSpeed(rotateSpeed) { @@ -194,9 +193,8 @@ namespace MWWorld float mRotateSpeed; }; - - void ProjectileManager::createModel(State &state, const std::string &model, const osg::Vec3f& pos, const osg::Quat& orient, - bool rotate, bool createLight, osg::Vec4 lightDiffuseColor, std::string texture) + void ProjectileManager::createModel(State& state, const std::string& model, const osg::Vec3f& pos, + const osg::Quat& orient, bool rotate, bool createLight, osg::Vec4 lightDiffuseColor, std::string texture) { state.mNode = new osg::PositionAttitudeTransform; state.mNode->setNodeMask(MWRender::Mask_Effect); @@ -207,7 +205,7 @@ namespace MWWorld if (rotate) { - osg::ref_ptr rotateNode (new osg::PositionAttitudeTransform); + osg::ref_ptr rotateNode(new osg::PositionAttitudeTransform); rotateNode->addUpdateCallback(new RotateCallback()); state.mNode->addChild(rotateNode); attachTo = rotateNode; @@ -223,7 +221,8 @@ namespace MWWorld { std::ostringstream nodeName; nodeName << "Dummy" << std::setw(2) << std::setfill('0') << iter; - const ESM::Weapon* weapon = MWBase::Environment::get().getWorld()->getStore().get().find (state.mIdMagic.at(iter)); + const ESM::Weapon* weapon = MWBase::Environment::get().getWorld()->getStore().get().find( + state.mIdMagic.at(iter)); std::string nameToFind = nodeName.str(); SceneUtil::FindByNameVisitor findVisitor(nameToFind); attachTo->accept(findVisitor); @@ -243,11 +242,11 @@ namespace MWWorld projectileLight->setLinearAttenuation(0.1f); projectileLight->setQuadraticAttenuation(0.f); projectileLight->setPosition(osg::Vec4(pos, 1.0)); - + SceneUtil::LightSource* projectileLightSource = new SceneUtil::LightSource; projectileLightSource->setNodeMask(MWRender::Mask_Lighting); projectileLightSource->setRadius(66.f); - + state.mNode->addChild(projectileLightSource); projectileLightSource->setLight(projectileLight); } @@ -258,7 +257,7 @@ namespace MWWorld state.mEffectAnimationTime = std::make_shared(); - SceneUtil::AssignControllerSourcesVisitor assignVisitor (state.mEffectAnimationTime); + SceneUtil::AssignControllerSourcesVisitor assignVisitor(state.mEffectAnimationTime); state.mNode->accept(assignVisitor); MWRender::overrideFirstRootTexture(texture, mResourceSystem, projectile); @@ -269,24 +268,27 @@ namespace MWWorld state.mEffectAnimationTime->addTime(duration); } - void ProjectileManager::launchMagicBolt(const std::string &spellId, const Ptr &caster, const osg::Vec3f& fallbackDirection, int slot) + void ProjectileManager::launchMagicBolt( + const std::string& spellId, const Ptr& caster, const osg::Vec3f& fallbackDirection, int slot) { osg::Vec3f pos = caster.getRefData().getPosition().asVec3(); if (caster.getClass().isActor()) { - // Note: we ignore the collision box offset, this is required to make some flying creatures work as intended. + // Note: we ignore the collision box offset, this is required to make some flying creatures work as + // intended. pos.z() += mPhysics->getRenderingHalfExtents(caster).z() * 2 * Constants::TorsoHeight; } - if (MWBase::Environment::get().getWorld()->isUnderwater(caster.getCell(), pos)) // Underwater casting not possible + if (MWBase::Environment::get().getWorld()->isUnderwater( + caster.getCell(), pos)) // Underwater casting not possible return; osg::Quat orient; if (caster.getClass().isActor()) - orient = osg::Quat(caster.getRefData().getPosition().rot[0], osg::Vec3f(-1,0,0)) - * osg::Quat(caster.getRefData().getPosition().rot[2], osg::Vec3f(0,0,-1)); + orient = osg::Quat(caster.getRefData().getPosition().rot[0], osg::Vec3f(-1, 0, 0)) + * osg::Quat(caster.getRefData().getPosition().rot[2], osg::Vec3f(0, 0, -1)); else - orient.makeRotate(osg::Vec3f(0,1,0), osg::Vec3f(fallbackDirection)); + orient.makeRotate(osg::Vec3f(0, 1, 0), osg::Vec3f(fallbackDirection)); MagicBoltState state; state.mSpellId = spellId; @@ -299,7 +301,8 @@ namespace MWWorld std::string texture; - state.mEffects = getMagicBoltData(state.mIdMagic, state.mSoundIds, state.mSpeed, texture, state.mSourceName, state.mSpellId); + state.mEffects = getMagicBoltData( + state.mIdMagic, state.mSoundIds, state.mSpeed, texture, state.mSourceName, state.mSpellId); // Non-projectile should have been removed by getMagicBoltData if (state.mEffects.mList.empty()) @@ -319,16 +322,17 @@ namespace MWWorld auto model = ptr.getClass().getModel(ptr); createModel(state, model, pos, orient, true, true, lightDiffuseColor, texture); - MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); - for (const std::string &soundid : state.mSoundIds) + MWBase::SoundManager* sndMgr = MWBase::Environment::get().getSoundManager(); + for (const std::string& soundid : state.mSoundIds) { - MWBase::Sound *sound = sndMgr->playSound3D(pos, soundid, 1.0f, 1.0f, - MWSound::Type::Sfx, MWSound::PlayMode::Loop); + MWBase::Sound* sound + = sndMgr->playSound3D(pos, soundid, 1.0f, 1.0f, MWSound::Type::Sfx, MWSound::PlayMode::Loop); if (sound) state.mSounds.push_back(sound); } - // in case there are multiple effects, the model is a dummy without geometry. Use the second effect for physics shape + // in case there are multiple effects, the model is a dummy without geometry. Use the second effect for physics + // shape if (state.mIdMagic.size() > 1) { model = Misc::ResourceHelpers::correctMeshPath( @@ -340,12 +344,13 @@ namespace MWWorld mMagicBolts.push_back(state); } - void ProjectileManager::launchProjectile(const Ptr& actor, const ConstPtr& projectile, const osg::Vec3f &pos, const osg::Quat &orient, const Ptr& bow, float speed, float attackStrength) + void ProjectileManager::launchProjectile(const Ptr& actor, const ConstPtr& projectile, const osg::Vec3f& pos, + const osg::Quat& orient, const Ptr& bow, float speed, float attackStrength) { ProjectileState state; state.mActorId = actor.getClass().getCreatureStats(actor).getActorId(); state.mBowId = bow.getCellRef().getRefId(); - state.mVelocity = orient * osg::Vec3f(0,1,0) * speed; + state.mVelocity = orient * osg::Vec3f(0, 1, 0) * speed; state.mIdArrow = projectile.getCellRef().getRefId(); state.mCasterHandle = actor; state.mAttackStrength = attackStrength; @@ -356,7 +361,7 @@ namespace MWWorld MWWorld::Ptr ptr = ref.getPtr(); const auto model = ptr.getClass().getModel(ptr); - createModel(state, model, pos, orient, false, false, osg::Vec4(0,0,0,0)); + createModel(state, model, pos, orient, false, false, osg::Vec4(0, 0, 0, 0)); if (!ptr.getClass().getEnchantment(ptr).empty()) SceneUtil::addEnchantedGlow(state.mNode, mResourceSystem, ptr.getClass().getEnchantmentColor(ptr)); @@ -372,7 +377,8 @@ namespace MWWorld for (auto& state : mMagicBolts) { - // casters are identified by actor id in the savegame. objects doesn't have one so they can't be identified back. + // casters are identified by actor id in the savegame. objects doesn't have one so they can't be identified + // back. // TODO: should object-type caster be restored from savegame? if (state.mActorId == -1) continue; @@ -402,11 +408,10 @@ namespace MWWorld { mCleanupTimer = 2.0f; - auto isCleanable = [](const ProjectileManager::State& state) -> bool - { + auto isCleanable = [](const ProjectileManager::State& state) -> bool { const float farawayThreshold = 72000.0f; osg::Vec3 playerPos = MWMechanics::getPlayer().getRefData().getPosition().asVec3(); - return (state.mNode->getPosition() - playerPos).length2() >= farawayThreshold*farawayThreshold; + return (state.mNode->getPosition() - playerPos).length2() >= farawayThreshold * farawayThreshold; }; for (auto& projectileState : mProjectiles) @@ -447,7 +452,8 @@ namespace MWWorld const auto& store = MWBase::Environment::get().getWorld()->getStore(); osg::Quat orient = magicBoltState.mNode->getAttitude(); - static float fTargetSpellMaxSpeed = store.get().find("fTargetSpellMaxSpeed")->mValue.getFloat(); + static float fTargetSpellMaxSpeed + = store.get().find("fTargetSpellMaxSpeed")->mValue.getFloat(); float speed = fTargetSpellMaxSpeed * magicBoltState.mSpeed; if (!normaliseRaceSpeed && !caster.isEmpty() && caster.getClass().isNpc()) { @@ -455,13 +461,14 @@ namespace MWWorld const auto race = store.get().find(npc->mRace); speed *= npc->isMale() ? race->mData.mWeight.mMale : race->mData.mWeight.mFemale; } - osg::Vec3f direction = orient * osg::Vec3f(0,1,0); + osg::Vec3f direction = orient * osg::Vec3f(0, 1, 0); direction.normalize(); projectile->setVelocity(direction * speed); update(magicBoltState, duration); - // For AI actors, get combat targets to use in the ray cast. Only those targets will return a positive hit result. + // For AI actors, get combat targets to use in the ray cast. Only those targets will return a positive hit + // result. std::vector targetActors; if (!caster.isEmpty() && caster.getClass().isActor() && caster != MWMechanics::getPlayer()) caster.getClass().getCreatureStats(caster).getAiSequence().getCombatTargets(targetActors); @@ -481,15 +488,17 @@ namespace MWWorld continue; // gravity constant - must be way lower than the gravity affecting actors, since we're not // simulating aerodynamics at all - projectileState.mVelocity -= osg::Vec3f(0, 0, Constants::GravityConst * Constants::UnitsPerMeter * 0.1f) * duration; + projectileState.mVelocity + -= osg::Vec3f(0, 0, Constants::GravityConst * Constants::UnitsPerMeter * 0.1f) * duration; projectile->setVelocity(projectileState.mVelocity); - // rotation does not work well for throwing projectiles - their roll angle will depend on shooting direction. + // rotation does not work well for throwing projectiles - their roll angle will depend on shooting + // direction. if (!projectileState.mThrown) { osg::Quat orient; - orient.makeRotate(osg::Vec3f(0,1,0), projectileState.mVelocity); + orient.makeRotate(osg::Vec3f(0, 1, 0), projectileState.mVelocity); projectileState.mNode->setAttitude(orient); } @@ -497,7 +506,8 @@ namespace MWWorld MWWorld::Ptr caster = projectileState.getCaster(); - // For AI actors, get combat targets to use in the ray cast. Only those targets will return a positive hit result. + // For AI actors, get combat targets to use in the ray cast. Only those targets will return a positive hit + // result. std::vector targetActors; if (!caster.isEmpty() && caster.getClass().isActor() && caster != MWMechanics::getPlayer()) caster.getClass().getCreatureStats(caster).getAiSequence().getCombatTargets(targetActors); @@ -528,19 +538,22 @@ namespace MWWorld caster = target; // Try to get a Ptr to the bow that was used. It might no longer exist. - MWWorld::ManualRef projectileRef(MWBase::Environment::get().getWorld()->getStore(), projectileState.mIdArrow); + MWWorld::ManualRef projectileRef( + MWBase::Environment::get().getWorld()->getStore(), projectileState.mIdArrow); MWWorld::Ptr bow = projectileRef.getPtr(); if (!caster.isEmpty() && projectileState.mIdArrow != projectileState.mBowId) { MWWorld::InventoryStore& inv = caster.getClass().getInventoryStore(caster); MWWorld::ContainerStoreIterator invIt = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); - if (invIt != inv.end() && Misc::StringUtils::ciEqual(invIt->getCellRef().getRefId(), projectileState.mBowId)) + if (invIt != inv.end() + && Misc::StringUtils::ciEqual(invIt->getCellRef().getRefId(), projectileState.mBowId)) bow = *invIt; } if (projectile->getHitWater()) mRendering->emitWaterRipple(pos); - MWMechanics::projectileHit(caster, target, bow, projectileRef.getPtr(), pos, projectileState.mAttackStrength); + MWMechanics::projectileHit( + caster, target, bow, projectileRef.getPtr(), pos, projectileState.mAttackStrength); projectileState.mToDelete = true; } const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); @@ -594,10 +607,12 @@ namespace MWWorld if (magicBoltState.mToDelete) cleanupMagicBolt(magicBoltState); } - mProjectiles.erase(std::remove_if(mProjectiles.begin(), mProjectiles.end(), [](const State& state) { return state.mToDelete; }), - mProjectiles.end()); - mMagicBolts.erase(std::remove_if(mMagicBolts.begin(), mMagicBolts.end(), [](const State& state) { return state.mToDelete; }), - mMagicBolts.end()); + mProjectiles.erase(std::remove_if(mProjectiles.begin(), mProjectiles.end(), + [](const State& state) { return state.mToDelete; }), + mProjectiles.end()); + mMagicBolts.erase( + std::remove_if(mMagicBolts.begin(), mMagicBolts.end(), [](const State& state) { return state.mToDelete; }), + mMagicBolts.end()); } void ProjectileManager::cleanupProjectile(ProjectileManager::ProjectileState& state) @@ -629,7 +644,7 @@ namespace MWWorld mMagicBolts.clear(); } - void ProjectileManager::write(ESM::ESMWriter &writer, Loading::Listener &progress) const + void ProjectileManager::write(ESM::ESMWriter& writer, Loading::Listener& progress) const { for (std::vector::const_iterator it = mProjectiles.begin(); it != mProjectiles.end(); ++it) { @@ -669,7 +684,7 @@ namespace MWWorld } } - bool ProjectileManager::readRecord(ESM::ESMReader &reader, uint32_t type) + bool ProjectileManager::readRecord(ESM::ESMReader& reader, uint32_t type) { if (type == ESM::REC_PROJ) { @@ -693,14 +708,16 @@ namespace MWWorld int weaponType = ptr.get()->mBase->mData.mType; state.mThrown = MWMechanics::getWeaponType(weaponType)->mWeaponClass == ESM::WeaponType::Thrown; - state.mProjectileId = mPhysics->addProjectile(state.getCaster(), osg::Vec3f(esm.mPosition), model, false); + state.mProjectileId + = mPhysics->addProjectile(state.getCaster(), osg::Vec3f(esm.mPosition), model, false); } - catch(...) + catch (...) { return true; } - createModel(state, model, osg::Vec3f(esm.mPosition), osg::Quat(esm.mOrientation), false, false, osg::Vec4(0,0,0,0)); + createModel(state, model, osg::Vec3f(esm.mPosition), osg::Quat(esm.mOrientation), false, false, + osg::Vec4(0, 0, 0, 0)); mProjectiles.push_back(state); return true; @@ -720,11 +737,13 @@ namespace MWWorld try { - state.mEffects = getMagicBoltData(state.mIdMagic, state.mSoundIds, state.mSpeed, texture, state.mSourceName, state.mSpellId); + state.mEffects = getMagicBoltData( + state.mIdMagic, state.mSoundIds, state.mSpeed, texture, state.mSourceName, state.mSpellId); } - catch(...) + catch (...) { - Log(Debug::Warning) << "Warning: Failed to recreate magic projectile from saved data (id \"" << state.mSpellId << "\" no longer exists?)"; + Log(Debug::Warning) << "Warning: Failed to recreate magic projectile from saved data (id \"" + << state.mSpellId << "\" no longer exists?)"; return true; } @@ -740,20 +759,21 @@ namespace MWWorld MWWorld::Ptr ptr = ref.getPtr(); model = ptr.getClass().getModel(ptr); } - catch(...) + catch (...) { return true; } osg::Vec4 lightDiffuseColor = getMagicBoltLightDiffuseColor(state.mEffects); - createModel(state, model, osg::Vec3f(esm.mPosition), osg::Quat(esm.mOrientation), true, true, lightDiffuseColor, texture); + createModel(state, model, osg::Vec3f(esm.mPosition), osg::Quat(esm.mOrientation), true, true, + lightDiffuseColor, texture); state.mProjectileId = mPhysics->addProjectile(state.getCaster(), osg::Vec3f(esm.mPosition), model, true); - MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); - for (const std::string &soundid : state.mSoundIds) + MWBase::SoundManager* sndMgr = MWBase::Environment::get().getSoundManager(); + for (const std::string& soundid : state.mSoundIds) { - MWBase::Sound *sound = sndMgr->playSound3D(esm.mPosition, soundid, 1.0f, 1.0f, - MWSound::Type::Sfx, MWSound::PlayMode::Loop); + MWBase::Sound* sound = sndMgr->playSound3D( + esm.mPosition, soundid, 1.0f, 1.0f, MWSound::Type::Sfx, MWSound::PlayMode::Loop); if (sound) state.mSounds.push_back(sound); } diff --git a/apps/openmw/mwworld/projectilemanager.hpp b/apps/openmw/mwworld/projectilemanager.hpp index 63a0dacc71..602d254046 100644 --- a/apps/openmw/mwworld/projectilemanager.hpp +++ b/apps/openmw/mwworld/projectilemanager.hpp @@ -3,8 +3,8 @@ #include -#include #include +#include #include @@ -45,14 +45,15 @@ namespace MWWorld class ProjectileManager { public: - ProjectileManager (osg::Group* parent, Resource::ResourceSystem* resourceSystem, - MWRender::RenderingManager* rendering, MWPhysics::PhysicsSystem* physics); + ProjectileManager(osg::Group* parent, Resource::ResourceSystem* resourceSystem, + MWRender::RenderingManager* rendering, MWPhysics::PhysicsSystem* physics); /// If caster is an actor, the actor's facing orientation is used. Otherwise fallbackDirection is used. - void launchMagicBolt (const std::string &spellId, const MWWorld::Ptr& caster, const osg::Vec3f& fallbackDirection, int slot); + void launchMagicBolt( + const std::string& spellId, const MWWorld::Ptr& caster, const osg::Vec3f& fallbackDirection, int slot); - void launchProjectile (const MWWorld::Ptr& actor, const MWWorld::ConstPtr& projectile, - const osg::Vec3f& pos, const osg::Quat& orient, const MWWorld::Ptr& bow, float speed, float attackStrength); + void launchProjectile(const MWWorld::Ptr& actor, const MWWorld::ConstPtr& projectile, const osg::Vec3f& pos, + const osg::Quat& orient, const MWWorld::Ptr& bow, float speed, float attackStrength); void updateCasters(); @@ -63,8 +64,8 @@ namespace MWWorld /// Removes all current projectiles. Should be called when switching to a new worldspace. void clear(); - void write (ESM::ESMWriter& writer, Loading::Listener& progress) const; - bool readRecord (ESM::ESMReader& reader, uint32_t type); + void write(ESM::ESMWriter& writer, Loading::Listener& progress) const; + bool readRecord(ESM::ESMReader& reader, uint32_t type); int countSavedGameRecords() const; private: @@ -133,9 +134,9 @@ namespace MWWorld void moveProjectiles(float dt); void moveMagicBolts(float dt); - void createModel (State& state, const std::string& model, const osg::Vec3f& pos, const osg::Quat& orient, - bool rotate, bool createLight, osg::Vec4 lightDiffuseColor, std::string texture = ""); - void update (State& state, float duration); + void createModel(State& state, const std::string& model, const osg::Vec3f& pos, const osg::Quat& orient, + bool rotate, bool createLight, osg::Vec4 lightDiffuseColor, std::string texture = ""); + void update(State& state, float duration); void operator=(const ProjectileManager&); ProjectileManager(const ProjectileManager&); diff --git a/apps/openmw/mwworld/ptr.hpp b/apps/openmw/mwworld/ptr.hpp index 0b8db5ac75..5dd6cf6b7b 100644 --- a/apps/openmw/mwworld/ptr.hpp +++ b/apps/openmw/mwworld/ptr.hpp @@ -2,9 +2,9 @@ #define GAME_MWWORLD_PTR_H #include -#include #include #include +#include #include "livecellref.hpp" @@ -16,111 +16,112 @@ namespace MWWorld /// \brief Pointer to a LiveCellRef /// @note PtrBase is never used directly and needed only to define Ptr and ConstPtr - template class TypeTransform> + template